patch-1.3.75 linux/net/core/skbuff.c

Next file: linux/net/ipv4/af_inet.c
Previous file: linux/net/ax25/ax25_timer.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v1.3.74/linux/net/core/skbuff.c linux/net/core/skbuff.c
@@ -12,6 +12,15 @@
  *		Alan Cox	:	destructor hook for AF_UNIX etc.
  *		Linus Torvalds	:	Better skb_clone.
  *		Alan Cox	:	Added skb_copy.
+ *		Alan Cox	:	Added all the changed routines Linus
+ *					only put in the headers
+ *		Ray VanTassle	:	Fixed --skb->lock in free
+ *
+ *	TO FIX:
+ *		The __skb_ routines ought to check interrupts are disabled
+ *	when called, and bitch like crazy if not. Unfortunately I don't think
+ *	we currently have a portable way to check if interrupts are off - 
+ *	Linus ???
  *
  *	This program is free software; you can redistribute it and/or
  *	modify it under the terms of the GNU General Public License
@@ -20,9 +29,7 @@
  */
 
 /*
- *	Note: There are a load of cli()/sti() pairs protecting the net_memory type
- *	variables. Without them for some reason the ++/-- operators do not come out
- *	atomic. Also with gcc 2.4.5 these counts can come out wrong anyway - use 2.5.8!!
+ *	The functions in this file will not compile correctly with gcc 2.4.x
  */
 
 #include <linux/config.h>
@@ -224,6 +231,26 @@
 	restore_flags(flags);
 }
 
+void __skb_queue_head(struct sk_buff_head *list_,struct sk_buff *newsk)
+{
+	struct sk_buff *list = (struct sk_buff *)list_;
+
+
+	IS_SKB(newsk);
+	IS_SKB_HEAD(list);
+	if (newsk->next || newsk->prev)
+		printk("Suspicious queue head: sk_buff on list!\n");
+
+	newsk->next = list->next;
+	newsk->prev = list;
+
+	newsk->next->prev = newsk;
+	newsk->prev->next = newsk;
+	newsk->list = list_;
+	list_->qlen++;
+
+}
+
 /*
  *	Insert an sk_buff at the end of a list.
  */
@@ -252,6 +279,26 @@
 	restore_flags(flags);
 }
 
+void __skb_queue_tail(struct sk_buff_head *list_, struct sk_buff *newsk)
+{
+	unsigned long flags;
+	struct sk_buff *list = (struct sk_buff *)list_;
+
+	if (newsk->next || newsk->prev)
+		printk("Suspicious queue tail: sk_buff on list!\n");
+	IS_SKB(newsk);
+	IS_SKB_HEAD(list);
+
+	newsk->next = list;
+	newsk->prev = list->prev;
+
+	newsk->next->prev = newsk;
+	newsk->prev->next = newsk;
+	
+	newsk->list = list_;
+	list_->qlen++;
+}
+
 /*
  *	Remove an sk_buff from a list. This routine is also interrupt safe
  *	so you can grab read and free buffers as another process adds them.
@@ -288,6 +335,30 @@
 	return result;
 }
 
+struct sk_buff *__skb_dequeue(struct sk_buff_head *list_)
+{
+	struct sk_buff *result;
+	struct sk_buff *list = (struct sk_buff *)list_;
+
+	IS_SKB_HEAD(list);
+
+	result = list->next;
+	if (result == list) {
+		return NULL;
+	}
+
+	result->next->prev = list;
+	list->next = result->next;
+
+	result->next = NULL;
+	result->prev = NULL;
+	list_->qlen--;
+	result->list = NULL;
+	
+	IS_SKB(result);
+	return result;
+}
+
 /*
  *	Insert a packet before another one in a list.
  */
@@ -316,6 +387,29 @@
 }
 
 /*
+ *	Insert a packet before another one in a list.
+ */
+
+void __skb_insert(struct sk_buff *old, struct sk_buff *newsk)
+{
+	IS_SKB(old);
+	IS_SKB(newsk);
+
+	if(!old->next || !old->prev)
+		printk("insert before unlisted item!\n");
+	if(newsk->next || newsk->prev)
+		printk("inserted item is already on a list.\n");
+
+	newsk->next = old;
+	newsk->prev = old->prev;
+	old->prev = newsk;
+	newsk->prev->next = newsk;
+	newsk->list = old->list;
+	newsk->list->qlen++;
+
+}
+
+/*
  *	Place a packet after a given packet in a list.
  */
 void skb_append(struct sk_buff *old, struct sk_buff *newsk)
@@ -343,6 +437,25 @@
 	restore_flags(flags);
 }
 
+void __skb_append(struct sk_buff *old, struct sk_buff *newsk)
+{
+	IS_SKB(old);
+	IS_SKB(newsk);
+
+	if(!old->next || !old->prev)
+		printk("append before unlisted item!\n");
+	if(newsk->next || newsk->prev)
+		printk("append item is already on a list.\n");
+
+	newsk->prev = old;
+	newsk->next = old->next;
+	newsk->next->prev = newsk;
+	old->next = newsk;
+	newsk->list = old->list;
+	newsk->list->qlen++;
+
+}
+
 /*
  *	Remove an sk_buff from its list. Works even without knowing the list it
  *	is sitting on, which can be handy at times. It also means that THE LIST
@@ -374,6 +487,25 @@
 	restore_flags(flags);
 }
 
+void __skb_unlink(struct sk_buff *skb)
+{
+	IS_SKB(skb);
+
+	if(skb->list)
+	{
+		skb->list->qlen--;
+		skb->next->prev = skb->prev;
+		skb->prev->next = skb->next;
+		skb->next = NULL;
+		skb->prev = NULL;
+		skb->list = NULL;
+	}
+#ifdef PARANOID_BUGHUNT_MODE	/* This is legal but we sometimes want to watch it */
+	else
+		printk("skb_unlink: not a linked element\n");
+#endif
+}
+
 /*
  *	Add data to an sk_buff
  */
@@ -649,7 +781,6 @@
 	n->next = n->prev = n->link3 = NULL;
 	n->list = NULL;
 	n->sk = NULL;
-	n->truesize = sizeof(*n);
 	n->free = 1;
 	n->tries = 0;
 	n->lock = 0;
@@ -745,10 +876,12 @@
 
 	save_flags(flags);
 	cli();
-	if(skb->lock==1)
+	if(skb->lock)
+	{
 		net_locked--;
-
-	if (!--skb->lock && (skb->free == 1 || skb->free == 3))
+		skb->lock--;
+	}
+	if (!skb->lock && (skb->free == 1 || skb->free == 3))
 	{
 		restore_flags(flags);
 		kfree_skb(skb,mode);

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov with Sam's (original) version
of this