[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>
This commit is contained in:
parent
f4921aff5b
commit
dec18810c5
net/core
|
@ -362,6 +362,44 @@ void kfree_skb(struct sk_buff *skb)
|
||||||
__kfree_skb(skb);
|
__kfree_skb(skb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
|
||||||
|
{
|
||||||
|
new->tstamp = old->tstamp;
|
||||||
|
new->dev = old->dev;
|
||||||
|
new->transport_header = old->transport_header;
|
||||||
|
new->network_header = old->network_header;
|
||||||
|
new->mac_header = old->mac_header;
|
||||||
|
new->dst = dst_clone(old->dst);
|
||||||
|
#ifdef CONFIG_INET
|
||||||
|
new->sp = secpath_get(old->sp);
|
||||||
|
#endif
|
||||||
|
memcpy(new->cb, old->cb, sizeof(old->cb));
|
||||||
|
new->csum_start = old->csum_start;
|
||||||
|
new->csum_offset = old->csum_offset;
|
||||||
|
new->local_df = old->local_df;
|
||||||
|
new->pkt_type = old->pkt_type;
|
||||||
|
new->ip_summed = old->ip_summed;
|
||||||
|
skb_copy_queue_mapping(new, old);
|
||||||
|
new->priority = old->priority;
|
||||||
|
#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
|
||||||
|
new->ipvs_property = old->ipvs_property;
|
||||||
|
#endif
|
||||||
|
new->protocol = old->protocol;
|
||||||
|
new->mark = old->mark;
|
||||||
|
__nf_copy(new, old);
|
||||||
|
#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
|
||||||
|
defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
|
||||||
|
new->nf_trace = old->nf_trace;
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_NET_SCHED
|
||||||
|
new->tc_index = old->tc_index;
|
||||||
|
#ifdef CONFIG_NET_CLS_ACT
|
||||||
|
new->tc_verd = old->tc_verd;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
skb_copy_secmark(new, old);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* skb_clone - duplicate an sk_buff
|
* skb_clone - duplicate an sk_buff
|
||||||
* @skb: buffer to clone
|
* @skb: buffer to clone
|
||||||
|
@ -397,51 +435,22 @@ struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask)
|
||||||
|
|
||||||
n->next = n->prev = NULL;
|
n->next = n->prev = NULL;
|
||||||
n->sk = NULL;
|
n->sk = NULL;
|
||||||
C(tstamp);
|
__copy_skb_header(n, skb);
|
||||||
C(dev);
|
|
||||||
C(transport_header);
|
|
||||||
C(network_header);
|
|
||||||
C(mac_header);
|
|
||||||
C(dst);
|
|
||||||
dst_clone(skb->dst);
|
|
||||||
C(sp);
|
|
||||||
#ifdef CONFIG_INET
|
|
||||||
secpath_get(skb->sp);
|
|
||||||
#endif
|
|
||||||
memcpy(n->cb, skb->cb, sizeof(skb->cb));
|
|
||||||
C(len);
|
C(len);
|
||||||
C(data_len);
|
C(data_len);
|
||||||
C(mac_len);
|
C(mac_len);
|
||||||
C(csum);
|
|
||||||
C(local_df);
|
|
||||||
n->cloned = 1;
|
n->cloned = 1;
|
||||||
n->hdr_len = skb->nohdr ? skb_headroom(skb) : skb->hdr_len;
|
n->hdr_len = skb->nohdr ? skb_headroom(skb) : skb->hdr_len;
|
||||||
n->nohdr = 0;
|
n->nohdr = 0;
|
||||||
C(pkt_type);
|
|
||||||
C(ip_summed);
|
|
||||||
skb_copy_queue_mapping(n, skb);
|
|
||||||
C(priority);
|
|
||||||
#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
|
|
||||||
C(ipvs_property);
|
|
||||||
#endif
|
|
||||||
C(protocol);
|
|
||||||
n->destructor = NULL;
|
n->destructor = NULL;
|
||||||
C(mark);
|
|
||||||
__nf_copy(n, skb);
|
|
||||||
#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
|
|
||||||
defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
|
|
||||||
C(nf_trace);
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_NET_SCHED
|
|
||||||
C(tc_index);
|
|
||||||
#ifdef CONFIG_NET_CLS_ACT
|
#ifdef CONFIG_NET_CLS_ACT
|
||||||
n->tc_verd = SET_TC_VERD(skb->tc_verd,0);
|
/* FIXME What is this and why don't we do it in copy_skb_header? */
|
||||||
|
n->tc_verd = SET_TC_VERD(n->tc_verd,0);
|
||||||
n->tc_verd = CLR_TC_OK2MUNGE(n->tc_verd);
|
n->tc_verd = CLR_TC_OK2MUNGE(n->tc_verd);
|
||||||
n->tc_verd = CLR_TC_MUNGED(n->tc_verd);
|
n->tc_verd = CLR_TC_MUNGED(n->tc_verd);
|
||||||
C(iif);
|
C(iif);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
skb_copy_secmark(n, skb);
|
|
||||||
C(truesize);
|
C(truesize);
|
||||||
atomic_set(&n->users, 1);
|
atomic_set(&n->users, 1);
|
||||||
C(head);
|
C(head);
|
||||||
|
@ -463,50 +472,15 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
|
||||||
*/
|
*/
|
||||||
unsigned long offset = new->data - old->data;
|
unsigned long offset = new->data - old->data;
|
||||||
#endif
|
#endif
|
||||||
new->sk = NULL;
|
|
||||||
new->dev = old->dev;
|
__copy_skb_header(new, old);
|
||||||
skb_copy_queue_mapping(new, old);
|
|
||||||
new->priority = old->priority;
|
|
||||||
new->protocol = old->protocol;
|
|
||||||
new->dst = dst_clone(old->dst);
|
|
||||||
#ifdef CONFIG_INET
|
|
||||||
new->sp = secpath_get(old->sp);
|
|
||||||
#endif
|
|
||||||
new->csum_start = old->csum_start;
|
|
||||||
new->csum_offset = old->csum_offset;
|
|
||||||
new->ip_summed = old->ip_summed;
|
|
||||||
new->transport_header = old->transport_header;
|
|
||||||
new->network_header = old->network_header;
|
|
||||||
new->mac_header = old->mac_header;
|
|
||||||
#ifndef NET_SKBUFF_DATA_USES_OFFSET
|
#ifndef NET_SKBUFF_DATA_USES_OFFSET
|
||||||
/* {transport,network,mac}_header are relative to skb->head */
|
/* {transport,network,mac}_header are relative to skb->head */
|
||||||
new->transport_header += offset;
|
new->transport_header += offset;
|
||||||
new->network_header += offset;
|
new->network_header += offset;
|
||||||
new->mac_header += offset;
|
new->mac_header += offset;
|
||||||
#endif
|
#endif
|
||||||
memcpy(new->cb, old->cb, sizeof(old->cb));
|
|
||||||
new->local_df = old->local_df;
|
|
||||||
new->fclone = SKB_FCLONE_UNAVAILABLE;
|
|
||||||
new->pkt_type = old->pkt_type;
|
|
||||||
new->tstamp = old->tstamp;
|
|
||||||
new->destructor = NULL;
|
|
||||||
new->mark = old->mark;
|
|
||||||
__nf_copy(new, old);
|
|
||||||
#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
|
|
||||||
defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
|
|
||||||
new->nf_trace = old->nf_trace;
|
|
||||||
#endif
|
|
||||||
#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
|
|
||||||
new->ipvs_property = old->ipvs_property;
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_NET_SCHED
|
|
||||||
#ifdef CONFIG_NET_CLS_ACT
|
|
||||||
new->tc_verd = old->tc_verd;
|
|
||||||
#endif
|
|
||||||
new->tc_index = old->tc_index;
|
|
||||||
#endif
|
|
||||||
skb_copy_secmark(new, old);
|
|
||||||
atomic_set(&new->users, 1);
|
|
||||||
skb_shinfo(new)->gso_size = skb_shinfo(old)->gso_size;
|
skb_shinfo(new)->gso_size = skb_shinfo(old)->gso_size;
|
||||||
skb_shinfo(new)->gso_segs = skb_shinfo(old)->gso_segs;
|
skb_shinfo(new)->gso_segs = skb_shinfo(old)->gso_segs;
|
||||||
skb_shinfo(new)->gso_type = skb_shinfo(old)->gso_type;
|
skb_shinfo(new)->gso_type = skb_shinfo(old)->gso_type;
|
||||||
|
|
Loading…
Reference in New Issue