diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2007-10-14 03:37:30 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-10-15 15:26:24 -0400 |
commit | dec18810c52ed564c1aedc7f93dbf278b7fdf6d5 (patch) | |
tree | a703e90e3dc901fdb55ada142011f1815189b0b8 /net | |
parent | f4921aff5b174349bc36551f142a5dbac782ea3f (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')
-rw-r--r-- | net/core/skbuff.c | 116 |
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 | ||
365 | static 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; |