From: Daniel Borkmann <daniel@xxxxxxxxxxxxx> Date: Thu, 13 Apr 2017 17:57:06 +0200 > On 04/12/2017 08:54 PM, David Miller wrote: > [...] >> +static u32 netif_receive_generic_xdp(struct sk_buff *skb, >> + struct bpf_prog *xdp_prog) >> +{ >> + struct xdp_buff xdp; >> + u32 act = XDP_DROP; >> + void *orig_data; >> + int hlen, off; >> + >> + if (skb_linearize(skb)) > > Btw, given the skb can come from all kind of points in the stack, > it could also be a clone at this point. One example is act_mirred > which in fact does skb_clone() and can push the skb back to > ingress path through netif_receive_skb() and thus could then go > into generic xdp processing, where skb can be mangled. > > Instead of skb_linearize() we would therefore need to use something > like skb_ensure_writable(skb, skb->len) as equivalent, which also > makes sure that we unclone whenever needed. We could use skb_cow() for this purpose, which deals with cloning as well as enforcing headroom. However, thinking further about this, the goal is to make generic XDP match precisely how in-driver-XDP behaves. Therefore, such redirects from act_mirred would never flow through the XDP path. No other possibility can cause us to see a cloned packet here, we are before network taps are processed, etc. So in my opinion the thing to do is to elide generic XDP if the SKB is cloned.