aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/skbuff.c
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2007-10-14 03:37:30 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-15 15:26:24 -0400
commitdec18810c52ed564c1aedc7f93dbf278b7fdf6d5 (patch)
treea703e90e3dc901fdb55ada142011f1815189b0b8 /net/core/skbuff.c
parentf4921aff5b174349bc36551f142a5dbac782ea3f (diff)
[SKBUFF]: Merge common code between copy_skb_header and skb_clone
This patch creates a new function __copy_skb_header to merge the common code between copy_skb_header and skb_clone. Having two functions which are largely the same is a source of wasted labour as well as confusion. In fact the tc_verd stuff is almost certainly a bug since it's treated differently in skb_clone compared to the callers of copy_skb_header (skb_copy/pskb_copy/skb_copy_expand). I've kept that difference in tact with a comment added asking for clarification. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core/skbuff.c')
-rw-r--r--net/core/skbuff.c116
1 files changed, 45 insertions, 71 deletions
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 944189d96323..758bbef506d3 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -362,6 +362,44 @@ void kfree_skb(struct sk_buff *skb)
362 __kfree_skb(skb); 362 __kfree_skb(skb);
363} 363}
364 364
365static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
366{
367 new->tstamp = old->tstamp;
368 new->dev = old->dev;
369 new->transport_header = old->transport_header;
370 new->network_header = old->network_header;
371 new->mac_header = old->mac_header;
372 new->dst = dst_clone(old->dst);
373#ifdef CONFIG_INET
374 new->sp = secpath_get(old->sp);
375#endif
376 memcpy(new->cb, old->cb, sizeof(old->cb));
377 new->csum_start = old->csum_start;
378 new->csum_offset = old->csum_offset;
379 new->local_df = old->local_df;
380 new->pkt_type = old->pkt_type;
381 new->ip_summed = old->ip_summed;
382 skb_copy_queue_mapping(new, old);
383 new->priority = old->priority;
384#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
385 new->ipvs_property = old->ipvs_property;
386#endif
387 new->protocol = old->protocol;
388 new->mark = old->mark;
389 __nf_copy(new, old);
390#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
391 defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
392 new->nf_trace = old->nf_trace;
393#endif
394#ifdef CONFIG_NET_SCHED
395 new->tc_index = old->tc_index;
396#ifdef CONFIG_NET_CLS_ACT
397 new->tc_verd = old->tc_verd;
398#endif
399#endif
400 skb_copy_secmark(new, old);
401}
402
365/** 403/**
366 * skb_clone - duplicate an sk_buff 404 * skb_clone - duplicate an sk_buff
367 * @skb: buffer to clone 405 * @skb: buffer to clone
@@ -397,51 +435,22 @@ struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask)
397 435
398 n->next = n->prev = NULL; 436 n->next = n->prev = NULL;
399 n->sk = NULL; 437 n->sk = NULL;
400 C(tstamp); 438 __copy_skb_header(n, skb);
401 C(dev); 439
402 C(transport_header);
403 C(network_header);
404 C(mac_header);
405 C(dst);
406 dst_clone(skb->dst);
407 C(sp);
408#ifdef CONFIG_INET
409 secpath_get(skb->sp);
410#endif
411 memcpy(n->cb, skb->cb, sizeof(skb->cb));
412 C(len); 440 C(len);
413 C(data_len); 441 C(data_len);
414 C(mac_len); 442 C(mac_len);
415 C(csum);
416 C(local_df);
417 n->cloned = 1; 443 n->cloned = 1;
418 n->hdr_len = skb->nohdr ? skb_headroom(skb) : skb->hdr_len; 444 n->hdr_len = skb->nohdr ? skb_headroom(skb) : skb->hdr_len;
419 n->nohdr = 0; 445 n->nohdr = 0;
420 C(pkt_type);
421 C(ip_summed);
422 skb_copy_queue_mapping(n, skb);
423 C(priority);
424#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
425 C(ipvs_property);
426#endif
427 C(protocol);
428 n->destructor = NULL; 446 n->destructor = NULL;
429 C(mark);
430 __nf_copy(n, skb);
431#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
432 defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
433 C(nf_trace);
434#endif
435#ifdef CONFIG_NET_SCHED
436 C(tc_index);
437#ifdef CONFIG_NET_CLS_ACT 447#ifdef CONFIG_NET_CLS_ACT
438 n->tc_verd = SET_TC_VERD(skb->tc_verd,0); 448 /* FIXME What is this and why don't we do it in copy_skb_header? */
449 n->tc_verd = SET_TC_VERD(n->tc_verd,0);
439 n->tc_verd = CLR_TC_OK2MUNGE(n->tc_verd); 450 n->tc_verd = CLR_TC_OK2MUNGE(n->tc_verd);
440 n->tc_verd = CLR_TC_MUNGED(n->tc_verd); 451 n->tc_verd = CLR_TC_MUNGED(n->tc_verd);
441 C(iif); 452 C(iif);
442#endif 453#endif
443#endif
444 skb_copy_secmark(n, skb);
445 C(truesize); 454 C(truesize);
446 atomic_set(&n->users, 1); 455 atomic_set(&n->users, 1);
447 C(head); 456 C(head);
@@ -463,50 +472,15 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
463 */ 472 */
464 unsigned long offset = new->data - old->data; 473 unsigned long offset = new->data - old->data;
465#endif 474#endif
466 new->sk = NULL; 475
467 new->dev = old->dev; 476 __copy_skb_header(new, old);
468 skb_copy_queue_mapping(new, old); 477
469 new->priority = old->priority;
470 new->protocol = old->protocol;
471 new->dst = dst_clone(old->dst);
472#ifdef CONFIG_INET
473 new->sp = secpath_get(old->sp);
474#endif
475 new->csum_start = old->csum_start;
476 new->csum_offset = old->csum_offset;
477 new->ip_summed = old->ip_summed;
478 new->transport_header = old->transport_header;
479 new->network_header = old->network_header;
480 new->mac_header = old->mac_header;
481#ifndef NET_SKBUFF_DATA_USES_OFFSET 478#ifndef NET_SKBUFF_DATA_USES_OFFSET
482 /* {transport,network,mac}_header are relative to skb->head */ 479 /* {transport,network,mac}_header are relative to skb->head */
483 new->transport_header += offset; 480 new->transport_header += offset;
484 new->network_header += offset; 481 new->network_header += offset;
485 new->mac_header += offset; 482 new->mac_header += offset;
486#endif 483#endif
487 memcpy(new->cb, old->cb, sizeof(old->cb));
488 new->local_df = old->local_df;
489 new->fclone = SKB_FCLONE_UNAVAILABLE;
490 new->pkt_type = old->pkt_type;
491 new->tstamp = old->tstamp;
492 new->destructor = NULL;
493 new->mark = old->mark;
494 __nf_copy(new, old);
495#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
496 defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
497 new->nf_trace = old->nf_trace;
498#endif
499#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
500 new->ipvs_property = old->ipvs_property;
501#endif
502#ifdef CONFIG_NET_SCHED
503#ifdef CONFIG_NET_CLS_ACT
504 new->tc_verd = old->tc_verd;
505#endif
506 new->tc_index = old->tc_index;
507#endif
508 skb_copy_secmark(new, old);
509 atomic_set(&new->users, 1);
510 skb_shinfo(new)->gso_size = skb_shinfo(old)->gso_size; 484 skb_shinfo(new)->gso_size = skb_shinfo(old)->gso_size;
511 skb_shinfo(new)->gso_segs = skb_shinfo(old)->gso_segs; 485 skb_shinfo(new)->gso_segs = skb_shinfo(old)->gso_segs;
512 skb_shinfo(new)->gso_type = skb_shinfo(old)->gso_type; 486 skb_shinfo(new)->gso_type = skb_shinfo(old)->gso_type;