Socket buffers - SK_BUFF
One of the problems of having many layers of network protocols, each one using the services of another, is that each protocol needs to add protocol headers and tails to data as it is transmitted and to remove them as it processes received data [Cox96] [ Rus96]. This make passing data buffers between the protocols difficult as each layer needs to find where its particular protocol headers and tails are. One solution is to copy buffers at each layer but would be inefficient. Instead, Linux uses socket buffers or sk_buffs that to pass data between the protocol layers and the network device drivers. sk_buffs contain pointer and length fields that allow each protocol layer to manipulate the application data via standard functions or "methods".
[Image] Figure: Network socket buffers
Figure (fig [*]) shows the sk_buff data structure, each sk_buff has a block of data associated with it. The sk_buff has four data pointers, which are used to manipulate and manage the socket buffer's data. (The reader is referred to include /Linux/skbuff.h of the linux source for details.
...................... ..
.
.
End Points at the end of the data area in memory. this is fixed when sk_buff is allocated.
There are two length fields len and truesize, which describe the length of the current protocol packet and the total size of the data buffer respectively. The sk_buff handling code provides standard mechanisms for adding and removing protocol headers and tails to the application data. These safely manipulate the data, tail and len fields in the sk_buff. (The reader is advised to refer to net / core / skbuff.c for more details) .push This moves the data pointer towards the start of the data area and increments the len field This is used when adding data or protocol headers to the start of the data to be transfer.
pull This moves the data pointer away from the start, towards the end of the data area and decrements the len field. This is used when removing data or protocol headers from the start of the data that has been received.
Put this Moves The Tail Pointer Towards The end of the data area and increments the len field. this is buy to the end of the data to be transmitted.
Town Moves The Tail Pointer Towards The Start of The THEA AND DECREMENTS The Len Field. This is used.
The sk_buff data structure also contains pointers that are used as it is stored in doubly linked circular lists of sk_buff's during processing. There are generic sk_buff routines for adding sk_buffs to the front and back of these lists and for removing them.
The primary goal of the sk_buff routines is to provide a consistent and efficient buffer handling method for all of the network layers, and by being consistent to make it possible to provide higher level sk_buff and socket handling facilities to all the protocols.
Several buffer functions of the buffer operation ========================== Package buffer by SK_BUFF structure, the package buffer data area is from its Head And the END member is defined, and the package data body is described by the sub-area defined by the package data area, which can make the operation added or removed to the header. Skb_put (SKB, LEN) in the package The tail length extension length is the data block of the LEN, returns the address of the expansion block, __ SKB_PUT () is an unselected version SKB_PUSH (SKB, LEN) to extend the length of the length of the length of the Package, returns the address of the expansion block, __ SKB_PUSH () For unsatisfactory SKB_PULL (SKB, LEN) to remove data blocks of the encapsulation, return to the start address of the new encapsulation, __ SKB_PULL () is before the unsatisfactory SKB_HEADROOM (SKB) returns The length SKB_TAILROOM (SKB) starting from the packet area SKB_RESERVE (SKB, LEN) sets the length SKB_RESERVE (SKB, LEN) to the end of the package area to set the encapsulation of the Len byte SKB_TRIM (SKB, LEN) that starts at the packet area. The truncation is the len byte, __skb_trim () is an untrue version; include / linux / skbuff.h: struct SK_BUFF {... unsigned int Len; / * length of actual data * / unsigned char * head; / * head of Buffer * / unsigned char * / unsigned char * tail; / * tail pointer * / unsigned char * end; / * end pointer * / ...} / * Add data to an SK_BUFF * / static inline unsigned char * __ SKB_PUT (STRUCT SK_BUFF * SKB, UNSIGNED INT LEN) {Unsigned Char * TMP = SKB-> Tail; SKB-> Tail = LEN; SKB-> LEN = LEN; RETURN TMP;} / ** * SKB_PUT - Add Data TO A Buffer * @skb: buffer to use * @len: Amount of data to add * * This function extends the used data area of the buffer. If this would * exceed the total buffer size the kernel will panic. A pointer to the * first byte of the extra data is returned. * / static inline unsigned Char * SKB_PUT (STRUCT SK_BUFF * SKB, UNSIGNED INT LEN) {Unsigned Char * TMP = SKB-> Tail; SKB-> Tail = Len; SKB-> LEN = LEN; IF (SKB-> Tail> SKB-> END) {skb_over_panic (skb, len, current_text_addr ());} return tmp;} static inline unsigned char * __ skb_push (struct sk_buff * skb, unsigned int len) {skb-> data- = len; skb-> len = len;
Return SKB-> DATA;} / ** * SKB_PUSH - Add Data To The Start of a buffer * @SKB: Buffer to use * @len: Amount of data to add * * This function extends the buyd data area of the buffer AT the buffer * start. If this would exceed the total buffer headroom the kernel will * panic. A pointer to the first byte of the extra data is returned. * / static inline unsigned char * skb_push (struct sk_buff * skb, unsigned int len) {SKB-> DATA- = LEN; SKB-> LEN = LEN; if (SKB-> DATAHEAD) {
SKB_UNDER_PANIC (SKB, LEN, CURRENT_TEXT_ADDR ());
}
Return SKB-> DATA;
}
Static inline char * __ SKB_PULL (Struct Sk_buff * SKB, Unsigned Int Len)
{
SKB-> len- = len;
Return SKB-> DATA = LEN;
}
/ **
* SKB_PULL - REMOVE DATA from The Start of A Buffer
* @skb: buffer to use
* @LEN: Amount of Data To Remove
*
* This function Removes Data from the start of a buffer, returnning
* The memory to the next data in the buffer
* is returned. Once The Data Has Been Pulled Future Pushes Will Overwrite
* The old data.
* /
Static inline unsigned char * SKB_PULL (STRUCT SK_BUFF * SKB, UNSIGNED INT LEN)
{
IF (Len> SKB-> LEN)
Return NULL;
Return __skb_pull (SKB, LEN);
}
/ **
* SKB_HEADROOM - BYTES AT BUFFER HEAD
* @SKB: Buffer to Check
*
* Return the number of bytes of free space at the head of an AN & SK_BUFF.
* /
Static inline int SKB_HEADROOM (Const struct SK_Buff * SKB)
{
Return SKB-> DATA-SKB-> HEAD;
}
/ **
* SKB_TAILROOM - BYTES AT BUFFER END
* @SKB: Buffer to Check
*
* RETURN THE NUBER of BYTES OF FREE SPACE AT The Tail of An SK_BUFF
* /
Static Inline int SKB_TAILROOM (Const struct SK_Buff * SKB)
{
Return SKB-> end-SKB-> TAIL;
}
/ **
* SKB_RESERVE - Adjust headroom * @skb: buffer to alter
* @LEN: bytes to move
*
* Increase the headroom of an empty & sk_buff by reducing the tail
* Room. This is only allowed for an empty buffer.
* /
Static Inline Void SKB_RESERVE (Struct SK_Buff * SKB, Unsigned Int Len)
{
SKB-> DATA = LEN;
SKB-> TAIL = LEN;
}
Static inline void __skb_trim (struct SK_Buff * SKB, Unsigned Int Len)
{
SKB-> LEN = LEN;
SKB-> Tail = SKB-> DATA LEN;
}
/ **
* SKB_TRIM - REMOVE End from A Buffer
* @skb: buffer to alter
* @LEN: New Length
*
* Cut The Length of a buffer down by removing data from the tail. If
* The Buffer Is Already Under The Length Specified It Is Not Modified.
* /
Static Inline Void SKB_TRIM (Struct SK_Buff * SKB, Unsigned Int Len)
{
IF (SKB-> LEN> LEN) {
__skb_trim (SKB, LEN);
}
}
Gopinath (9711107) THU APR 15 09:44:10 IST 1999