00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include <linux/config.h>
00040 #include <linux/types.h>
00041 #include <linux/kernel.h>
00042 #include <linux/sched.h>
00043 #include <linux/mm.h>
00044 #include <linux/interrupt.h>
00045 #include <linux/in.h>
00046 #include <linux/inet.h>
00047 #include <linux/malloc.h>
00048 #include <linux/netdevice.h>
00049 #include <linux/string.h>
00050 #include <linux/skbuff.h>
00051 #include <linux/slab.h>
00052 #include <linux/init.h>
00053
00054 #include <net/ip.h>
00055 #include <net/protocol.h>
00056 #include <net/dst.h>
00057 #include <net/tcp.h>
00058 #include <net/udp.h>
00059 #include <net/sock.h>
00060
00061 #include <asm/uaccess.h>
00062 #include <asm/system.h>
00063
00064
00065
00066
00067 spinlock_t skb_queue_lock = SPIN_LOCK_UNLOCKED;
00068
00069
00070
00071
00072
00073 static atomic_t net_skbcount = ATOMIC_INIT(0);
00074 static atomic_t net_allocs = ATOMIC_INIT(0);
00075 static atomic_t net_fails = ATOMIC_INIT(0);
00076
00077 extern atomic_t ip_frag_mem;
00078
00079 static kmem_cache_t *skbuff_head_cache;
00080
00081
00082
00083
00084
00085
00086
00087 void skb_over_panic(struct sk_buff *skb, int sz, void *here)
00088 {
00089 panic("skput:over: %p:%d put:%d dev:%s",
00090 here, skb->len, sz, skb->dev ? skb->dev->name : "<NULL>");
00091 }
00092
00093 void skb_under_panic(struct sk_buff *skb, int sz, void *here)
00094 {
00095 panic("skput:under: %p:%d put:%d dev:%s",
00096 here, skb->len, sz, skb->dev ? skb->dev->name : "<NULL>");
00097 }
00098
00099 void show_net_buffers(void)
00100 {
00101 printk("Networking buffers in use : %u\n",
00102 atomic_read(&net_skbcount));
00103 printk("Total network buffer allocations : %u\n",
00104 atomic_read(&net_allocs));
00105 printk("Total failed network buffer allocs : %u\n",
00106 atomic_read(&net_fails));
00107 #ifdef CONFIG_INET
00108 printk("IP fragment buffer size : %u\n",
00109 atomic_read(&ip_frag_mem));
00110 #endif
00111 }
00112
00113
00114
00115
00116
00117
00118
00119 struct sk_buff *alloc_skb(unsigned int size,int gfp_mask)
00120 {
00121 struct sk_buff *skb;
00122 u8 *data;
00123
00124 if (in_interrupt() && (gfp_mask & __GFP_WAIT)) {
00125 static int count = 0;
00126 if (++count < 5) {
00127 printk(KERN_ERR "alloc_skb called nonatomically "
00128 "from interrupt %p\n", __builtin_return_address(0));
00129 }
00130 gfp_mask &= ~__GFP_WAIT;
00131 }
00132
00133
00134 skb = kmem_cache_alloc(skbuff_head_cache, gfp_mask);
00135 if (skb == NULL)
00136 goto nohead;
00137
00138
00139 if (size > 131072 - 32)
00140 goto nodata;
00141 size = ((size + 15) & ~15);
00142 data = kmalloc(size + sizeof(atomic_t), gfp_mask);
00143 if (data == NULL)
00144 goto nodata;
00145
00146
00147
00148
00149
00150 atomic_inc(&net_allocs);
00151
00152 skb->truesize = size;
00153
00154 atomic_inc(&net_skbcount);
00155
00156
00157 skb->head = data;
00158 skb->data = data;
00159 skb->tail = data;
00160 skb->end = data + size;
00161
00162
00163 skb->len = 0;
00164 skb->is_clone = 0;
00165 skb->cloned = 0;
00166
00167 atomic_set(&skb->users, 1);
00168 atomic_set(skb_datarefp(skb), 1);
00169 return skb;
00170
00171 nodata:
00172 kmem_cache_free(skbuff_head_cache, skb);
00173 nohead:
00174 atomic_inc(&net_fails);
00175 return NULL;
00176 }
00177
00178
00179
00180
00181
00182 static inline void skb_headerinit(void *p, kmem_cache_t *cache,
00183 unsigned long flags)
00184 {
00185 struct sk_buff *skb = p;
00186
00187 skb->destructor = NULL;
00188 skb->pkt_type = PACKET_HOST;
00189 skb->pkt_bridged = 0;
00190 skb->prev = skb->next = NULL;
00191 skb->list = NULL;
00192 skb->sk = NULL;
00193 skb->stamp.tv_sec=0;
00194 skb->ip_summed = 0;
00195 skb->security = 0;
00196 skb->dst = NULL;
00197 #ifdef CONFIG_IP_FIREWALL
00198 skb->fwmark = 0;
00199 #endif
00200 memset(skb->cb, 0, sizeof(skb->cb));
00201 skb->priority = 0;
00202 }
00203
00204
00205
00206
00207 void kfree_skbmem(struct sk_buff *skb)
00208 {
00209 if (!skb->cloned || atomic_dec_and_test(skb_datarefp(skb)))
00210 kfree(skb->head);
00211
00212 kmem_cache_free(skbuff_head_cache, skb);
00213 atomic_dec(&net_skbcount);
00214 }
00215
00216
00217
00218
00219
00220 void __kfree_skb(struct sk_buff *skb)
00221 {
00222 if (skb->list)
00223 printk(KERN_WARNING "Warning: kfree_skb passed an skb still "
00224 "on a list (from %p).\n", __builtin_return_address(0));
00225
00226 dst_release(skb->dst);
00227 if(skb->destructor)
00228 skb->destructor(skb);
00229 skb_headerinit(skb, NULL, 0);
00230 kfree_skbmem(skb);
00231 }
00232
00233
00234
00235
00236
00237 struct sk_buff *skb_clone(struct sk_buff *skb, int gfp_mask)
00238 {
00239 struct sk_buff *n;
00240
00241 n = kmem_cache_alloc(skbuff_head_cache, gfp_mask);
00242 if (!n)
00243 return NULL;
00244
00245 memcpy(n, skb, sizeof(*n));
00246 atomic_inc(skb_datarefp(skb));
00247 skb->cloned = 1;
00248
00249 atomic_inc(&net_allocs);
00250 atomic_inc(&net_skbcount);
00251 dst_clone(n->dst);
00252 n->cloned = 1;
00253 n->next = n->prev = NULL;
00254 n->list = NULL;
00255 n->sk = NULL;
00256 n->is_clone = 1;
00257 atomic_set(&n->users, 1);
00258 n->destructor = NULL;
00259 return n;
00260 }
00261
00262
00263
00264
00265
00266 struct sk_buff *skb_copy(struct sk_buff *skb, int gfp_mask)
00267 {
00268 struct sk_buff *n;
00269 unsigned long offset;
00270
00271
00272
00273
00274
00275 n=alloc_skb(skb->end - skb->head, gfp_mask);
00276 if(n==NULL)
00277 return NULL;
00278
00279
00280
00281
00282
00283 offset=n->head-skb->head;
00284
00285
00286 skb_reserve(n,skb->data-skb->head);
00287
00288 skb_put(n,skb->len);
00289
00290 memcpy(n->head,skb->head,skb->end-skb->head);
00291 n->csum = skb->csum;
00292 n->list=NULL;
00293 n->sk=NULL;
00294 n->dev=skb->dev;
00295 n->priority=skb->priority;
00296 n->protocol=skb->protocol;
00297 n->dst=dst_clone(skb->dst);
00298 n->h.raw=skb->h.raw+offset;
00299 n->nh.raw=skb->nh.raw+offset;
00300 n->mac.raw=skb->mac.raw+offset;
00301 memcpy(n->cb, skb->cb, sizeof(skb->cb));
00302 n->used=skb->used;
00303 n->is_clone=0;
00304 atomic_set(&n->users, 1);
00305 n->pkt_type=skb->pkt_type;
00306 n->stamp=skb->stamp;
00307 n->destructor = NULL;
00308 n->security=skb->security;
00309 #ifdef CONFIG_IP_FIREWALL
00310 n->fwmark = skb->fwmark;
00311 #endif
00312 return n;
00313 }
00314
00315 struct sk_buff *skb_copy_grow(struct sk_buff *skb, int pad, int gfp_mask)
00316 {
00317 struct sk_buff *n;
00318 unsigned long offset;
00319
00320
00321
00322
00323
00324 n=alloc_skb(skb->end - skb->head + pad, gfp_mask);
00325 if(n==NULL)
00326 return NULL;
00327
00328
00329
00330
00331
00332 offset=n->head-skb->head;
00333
00334
00335 skb_reserve(n,skb->data-skb->head);
00336
00337 skb_put(n,skb->len);
00338
00339 memcpy(n->head,skb->head,skb->end-skb->head);
00340 n->csum = skb->csum;
00341 n->list=NULL;
00342 n->sk=NULL;
00343 n->dev=skb->dev;
00344 n->priority=skb->priority;
00345 n->protocol=skb->protocol;
00346 n->dst=dst_clone(skb->dst);
00347 n->h.raw=skb->h.raw+offset;
00348 n->nh.raw=skb->nh.raw+offset;
00349 n->mac.raw=skb->mac.raw+offset;
00350 memcpy(n->cb, skb->cb, sizeof(skb->cb));
00351 n->used=skb->used;
00352 n->is_clone=0;
00353 atomic_set(&n->users, 1);
00354 n->pkt_type=skb->pkt_type;
00355 n->stamp=skb->stamp;
00356 n->destructor = NULL;
00357 n->security=skb->security;
00358 #ifdef CONFIG_IP_FIREWALL
00359 n->fwmark = skb->fwmark;
00360 #endif
00361 return n;
00362 }
00363
00364 struct sk_buff *skb_realloc_headroom(struct sk_buff *skb, int newheadroom)
00365 {
00366 struct sk_buff *n;
00367 unsigned long offset;
00368 int headroom = skb_headroom(skb);
00369
00370
00371
00372
00373
00374 n=alloc_skb(skb->truesize+newheadroom-headroom, GFP_ATOMIC);
00375 if(n==NULL)
00376 return NULL;
00377
00378 skb_reserve(n,newheadroom);
00379
00380
00381
00382
00383
00384 offset=n->data-skb->data;
00385
00386
00387 skb_put(n,skb->len);
00388
00389 memcpy(n->data,skb->data,skb->len);
00390 n->list=NULL;
00391 n->sk=NULL;
00392 n->priority=skb->priority;
00393 n->protocol=skb->protocol;
00394 n->dev=skb->dev;
00395 n->dst=dst_clone(skb->dst);
00396 n->h.raw=skb->h.raw+offset;
00397 n->nh.raw=skb->nh.raw+offset;
00398 n->mac.raw=skb->mac.raw+offset;
00399 memcpy(n->cb, skb->cb, sizeof(skb->cb));
00400 n->used=skb->used;
00401 n->is_clone=0;
00402 atomic_set(&n->users, 1);
00403 n->pkt_type=skb->pkt_type;
00404 n->stamp=skb->stamp;
00405 n->destructor = NULL;
00406 n->security=skb->security;
00407 #ifdef CONFIG_IP_FIREWALL
00408 n->fwmark = skb->fwmark;
00409 #endif
00410
00411 return n;
00412 }
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426 struct sk_buff *skb_pad(struct sk_buff *skb, int pad)
00427 {
00428 struct sk_buff *nskb;
00429
00430
00431 if(skb_tailroom(skb) >= pad)
00432 {
00433 memset(skb->data+skb->len, 0, pad);
00434 return skb;
00435 }
00436
00437 nskb = skb_copy_grow(skb, pad, GFP_ATOMIC);
00438 kfree_skb(skb);
00439 if(nskb)
00440 memset(nskb->data+nskb->len, 0, pad);
00441 return nskb;
00442 }
00443
00444 #if 0
00445
00446
00447
00448 void skb_add_mtu(int mtu)
00449 {
00450
00451 mtu = ((mtu + 15) & ~15) + sizeof(atomic_t);
00452
00453 kmem_add_cache_size(mtu);
00454 }
00455 #endif
00456
00457 void __init skb_init(void)
00458 {
00459 skbuff_head_cache = kmem_cache_create("skbuff_head_cache",
00460 sizeof(struct sk_buff),
00461 0,
00462 SLAB_HWCACHE_ALIGN,
00463 skb_headerinit, NULL);
00464 if (!skbuff_head_cache)
00465 panic("cannot create skbuff cache");
00466 }