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
- Lines: 218
- Date:
Sat Mar 16 13:52:11 1996
- Orig file:
v1.3.74/linux/net/core/skbuff.c
- Orig date:
Wed Feb 14 14:37:20 1996
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