📄 skbuff.c
字号:
/** Routines having to do with the 'struct sk_buff' memory handlers.** Authors: Alan Cox <iiitac@pyr.swan.ac.uk>* Florian La Roche <rzsfl@rz.uni-sb.de>** Version: $Id: skbuff.c,v 1.5 2008/07/30 05:03:25 huangzhiwei Exp $** Fixes:* Alan Cox : Fixed the worst of the load balancer bugs** NOTE:* The __skb_ routines should be called with interrupts* disabled, or you better be *real* sure that the operation is atomic* with respect to whatever list is being frobbed (e.g. via lock_sock()* or via disabling bottom half handlers, etc).** This program is free software; you can redistribute it and/or* modify it under the terms of the GNU General Public License* as published by the Free Software Foundation; either version* 2 of the License, or (at your option) any later version.*//** The functions in this file will not compile correctly with gcc 2.4.x*/#include "netdevice.h"#include "string.h"#include "skbuff.h"#include "af_irda.h"/*** __alloc_skb - allocate a network buffer* @size: size to allocate* @gfp_mask: allocation mask* @fclone: allocate from fclone cache instead of head cache* and allocate a cloned (child) skb* @node: numa node to allocate memory on** Allocate a new &sk_buff. The returned buffer has no headroom and a* tail room of size bytes. The object has a reference count of one.* The return is the buffer. On a failure the return is %NULL.** Buffers may only be allocated from interrupts using a @gfp_mask of* %GFP_ATOMIC.*/extern struct irda_cb* irda_self;struct sk_buff *skb_alloc(D_UINT32 size){ struct sk_buff *skb; D_UINT8 *data; /* Get the HEAD */ skb = (struct sk_buff *)malloc(sizeof(struct sk_buff)); if (!skb) { IRDA_ERROR("%s: can't allocate memory\n", __FUNCTION__); goto out; } memset(skb,0,sizeof(struct sk_buff)); skb->users = 0; data = (D_UINT8 *)malloc(size); if (!data) { IRDA_ERROR("%s: can't allocate memory\n", __FUNCTION__); goto nodata; } memset(data,0,size); /* * See comment in sk_buff definition, just before the 'tail' member */ skb->truesize = size + sizeof(struct sk_buff); //atomic_set(&skb->users, 1); skb->head = data; skb->data = data; skb_reset_tail_pointer(skb); skb->end = skb->tail + size; out: return skb;nodata: free(skb); skb = NULL; goto out;}void skb_free(struct sk_buff *skb){ if (!skb) { return; } //add by xugangan if (--skb->users >=0) { return; } if(skb->head != NULL) { free(skb->head); } free(skb); skb = NULL; }/*** skb_dequeue - remove from the head of the queue* @list: list to dequeue from** Remove the head of the list. The list lock is taken so the function* may be used safely with other locking list functions. The head item is* returned or %NULL if the list is empty.*/struct sk_buff *skb_dequeue(struct sk_buff_head *list){ struct sk_buff *next, *prev, *result; prev = (struct sk_buff *) list; next = prev->next; result = NULL; if (next != prev) { result = next; next = next->next; list->qlen--; next->prev = prev; prev->next = next; result->next = result->prev = NULL; } return result;}/*** skb_dequeue_tail - remove from the tail of the queue* @list: list to dequeue from** Remove the tail of the list. The list lock is taken so the function* may be used safely with other locking list functions. The tail item is* returned or %NULL if the list is empty.*/struct sk_buff *skb_dequeue_tail(struct sk_buff_head *list){ //unsigned long flags; struct sk_buff *skb = skb_peek_tail(list); if (skb) skb_unlink(skb, list); return skb;}/*** skb_queue_purge - empty a list* @list: list to empty** Delete all buffers on an &sk_buff list. Each buffer is removed from* the list and one reference dropped. This function takes the list* lock and is atomic with respect to other list locking functions.*/void skb_queue_purge(void){ struct sk_buff_head *list = &(irda_self->sk_receive_queue); struct sk_buff *skb; while ((skb = skb_dequeue(list)) != NULL) { skb_free(skb); }}/*** skb_queue_head - queue a buffer at the list head* @list: list to use* @newsk: buffer to queue** Queue a buffer at the start of the list. This function takes the* list lock and can be used safely with other locking &sk_buff functions* safely.** A buffer cannot be placed on two lists at the same time.*/void skb_queue_head(struct sk_buff_head *list, struct sk_buff *newsk){ struct sk_buff *prev,*next; list->qlen++; prev = (struct sk_buff *)list; next = prev->next; newsk->next = next; newsk->prev = prev; next->prev = prev->next = newsk;}/*** skb_queue_tail - queue a buffer at the list tail* @list: list to use* @newsk: buffer to queue** Queue a buffer at the tail of the list. This function takes the* list lock and can be used safely with other locking &sk_buff functions* safely.** A buffer cannot be placed on two lists at the same time.*/void skb_queue_tail(struct sk_buff_head *list, struct sk_buff *newsk){ IRDA_DEBUG(1, "%s()\n", __FUNCTION__ ); struct sk_buff *prev, *next; list->qlen++; next = (struct sk_buff *)list; prev = next->prev; newsk->next = next; newsk->prev = prev; next->prev = prev->next = newsk;}/*** skb_unlink - remove a buffer from a list* @skb: buffer to remove* @list: list to use* remove sk_buff from list* Remove a packet from a list. The list locks are taken and this* function is atomic with respect to other list locked calls** You must know what list the SKB is on.*/void skb_unlink(struct sk_buff *skb, struct sk_buff_head *list){ struct sk_buff *next, *prev; list->qlen--; next = skb->next; prev = skb->prev; skb->next = skb->prev = NULL; next->prev = prev; prev->next = next; }/*** skb_insert - insert a buffer* @old: buffer to insert before* @newsk: buffer to insert* @list: list to use* * Insert a packet on a list.* Place a packet before a given packet in a list. The list locks are* taken and this function is atomic with respect to other list locked* calls.** A buffer cannot be placed on two lists at the same time.*/void skb_insert(struct sk_buff *old, struct sk_buff *newsk, struct sk_buff_head *list){ struct sk_buff *prev, *next; //__skb_insert(newsk, old->prev, old, list); prev = old->prev; next = old; newsk->next = next; newsk->prev = prev; next->prev = prev->next = newsk; list->qlen++; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -