Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
COMS W6998
Spring 2010
Erich Nahum
Outline
Introto socket buffers
The sk_buff data structure
socket buffers.
APIs for manipulating parameters within
socket buffers.
APIs for manipulating parameters within
Packet data
sk_buff
...
head
data
tailroom size
tail
end
...
Packet data
sk_buff
headroom len
...
head
data size
tail
end
... tailroom
data += len
tail += len
sk_buff after skb_put(len)
Packet data
sk_buff
headroom
...
head
data
tail size
data len
end
...
tailroom
tail += len
len += len
sk_buff after skb_push(len)
Packet data
headroom
sk_buff
... new data len
head
data size
tail old data
end
...
tailroom
data -= len
len += len
Changes in sk_buff as a Packet
Traverses Across the Stack
IP-Header
UDP-Header UDP-Header
UDP-Data UDP-Data UDP-Data
socket buffers.
APIs for manipulating parameters within
IP-Header IP-Header
UDP-Header UDP-Header
UDP-Data UDP-Data
dataref: 1 dataref: 2
Releasing Socket Buffers
kfree_skb(): decrements reference count for skb. If
null, free the memory.
Used by the kernel, not meant to be used by drivers
dev_free_skb():
For use by drivers in non-interrupt context
dev_free_skb_irq():
For use by drivers in interrupt context
dev_free_skb_any():
For use by drivers in any context
Outline
Introto socket buffers
The sk_buff data structure
socket buffers.
APIs for manipulating parameters within
socket buffers.
APIs for manipulating parameters within
Packetdata Packetdata
Packetdata
Managing Socket Buffer Queues
skb_queue_head_init(list): initializes an
skb_queue_head structure
prev = next = self; qlen = 0;
skb_queue_empty(list): checks whether the queue list is
empty; checks if list == list->next
skb_queue_len(list): returns length of the queue.
skb_queue_head(list, skb): inserts the socket buffer skb
at the head of the queue and increment listqlen by
one.
skb_queue_tail(list, skb): appends the socket buffer skb
to the end of the queue and increment listqlen by one.
Managing Socket Buffer Queues
skb_dequeue(list): removes the top skb from the
queue and returns the pointer to the skb.
skb_dequeue_tail(list): removes the last packet
from the queue and returns the pointer to the
packet.
skb_queue_purge(): empties the queue list; all
packets are removed via kfree_skb().
skb_insert(oldskb, newskb, list): inserts newskb in
front of oldskb in the queue of list.
skb_append(oldskb, newskb, list): inserts newskb
behind oldskb in the queue of list.
Managing Socket Buffer Queues
skb_unlink(skb, list): removes the socket buffer
skb from queue list and decrement the queue
length.
skb_peek(list): returns a pointer to the first
element of a list, if this list is not empty;
otherwise, returns NULL.
Leaves buffer on the list
skb_peek_tail(list): returns a pointer to the last
element of a queue; if the list is empty, returns
NULL.
Leaves buffer on the list
Backup
sk_buff Alignment
CPUs often take a performance hit when accessing
unaligned memory locations.
Since an Ethernet header is 14 bytes, network
drivers often end up with the IP header at an
unaligned offset.
The IP header can be aligned by shifting the start of
the packet by 2 bytes. Drivers should do this with:
skb_reserve(NET_IP_ALIGN);
The downside is that the DMA is now unaligned. On
some architectures the cost of an unaligned DMA
outweighs the gains so NET_IP_ALIGN is set on a
per arch basis.