On Tue, Apr 18, 2017 at 03:29:16PM -0400, David Miller wrote: > From: David Miller <davem@xxxxxxxxxxxxx> > Date: Tue, 18 Apr 2017 15:07:08 -0400 (EDT) > > > From: Andy Gospodarek <andy@xxxxxxxxxxxxx> > > Date: Tue, 18 Apr 2017 15:05:35 -0400 > > > >> On Fri, Apr 14, 2017 at 05:59:51PM -0700, Alexei Starovoitov wrote: > >>> On Thu, Apr 13, 2017 at 04:23:15PM -0400, David Miller wrote: > >>> > + > >>> > + switch (act) { > >>> > + case XDP_TX: > >>> > + __skb_push(skb, skb->mac_len); > >>> > >>> s/skb->mac_len/mac_len/ > >>> > >> > >> I was away from my keyboard for a few days, but was able to get some > >> time to test this today. > >> > >> When using this change above suggested by Alexei, XDP_DROP and XDP_TX > >> actions appear to work well with xdp1 and xdp2. > >> > >> I'm seeing some rather odd behavior with xdp_tx_tunnel so it might be > >> good to hold off on committing this just yet. > >> > >> At first glance, it looks like there is enough headroom for the new > >> frame, but the resulting packet data do not look right and I'm actually > >> seeing some data that may be left on the stack from a previous caller. > > > > Thanks for testing Andy, I'll take a look and see if I can figure it out. > > Andy, I think we might be getting burnt by signedness issues in the > offset handling when the XDP program adjusts the packet data pointer. I completely agree -- I just noted that the offset would be -20 in the tx_tunnel case and it's easy to get confused since a positive int for the second arg in skb_pull() does go 'back' with a positive value and was just rebuilding and testing just this case with: - off = xdp.data - orig_data; + /* note that offset is negative */ + off = orig_data - xdp.data; > In netif_receive_generic_xdp(), try changing the offset handling code to > read something like: > > off = xdp.data - orig_data; > if (off > 0) > __skb_pull(skb, off); > else if (off < 0) > __skb_push(skb, -off); This should do it. I'll give that run, too. > If that doesn't work try adding: > > __skb_cow(skb, XDP_PACKET_HEADROOM, 0); > > right after the skb_linearize() call in that same function.