bpf: fix xdp_generic for bpf_adjust_tail usecase
Subsystems (2)
PATCH 1/1 bpf: fix xdp_generic for bpf_adjust_tail usecase
when bpf_adjust_tail was introduced for generic xdp, it changed skb's tail pointer, so it was pointing to the new "end of the packet". however skb's len field wasn't properly modified, so on the wire ethernet frame had original (or even bigger, if adjust_head was used) size. this diff is fixing this.
bpf_xdp_adjust_tail")
---
Notes:
original tests missed this because it looks like tap interface ignores incorrect ethernet FCS (all tests were done in VM) and even w/ missaligned l3 and l2 lengths, kernel still were accepting this ICMP packet
output was generated w/ bpf_adjust_tail prog from samples before this fix (see lengths field of the ethernet layer):
tehnerd@maindev:~$ sudo tcpdump -ni tap0 icmp -vvv -eee
tcpdump: listening on tap0, link-type EN10MB (Ethernet), capture size 262144 bytes
06:38:15.546782 52:54:00:12:34:57 > 12:0e:a3:cc:78:b8, ethertype IPv4 (0x0800), length 1454: (tos 0x0, ttl 64, id 0, offset 0, flags [none], proto ICMP (1), length 112)
172.16.0.2 > 172.16.0.1: ICMP 172.16.0.2 unreachable - need to frag (mtu 586), length 92
(tos 0x0, ttl 64, id 48021, offset 0, flags [DF], proto TCP (6), length 1412)
172.16.0.1.50916 > 172.16.0.2.22: Flags [P.], seq 427401155:427402515, ack 3567613893, win 229, options [nop,nop,TS val 1287434011 ecr 2176566223], length 1360
after:
tehnerd@maindev:~$ sudo tcpdump -ni tap0 icmp -vvv -eee
tcpdump: listening on tap0, link-type EN10MB (Ethernet), capture size 262144 bytes
06:47:37.226843 52:54:00:12:34:57 > 32:45:9f:69:35:ba, ethertype IPv4 (0x0800), length 126: (tos 0x0, ttl 64, id 0, offset 0, flags [none], proto ICMP (1), length 112)
172.16.0.2 > 172.16.0.1: ICMP 172.16.0.2 unreachable - need to frag (mtu 586), length 92
(tos 0x0, ttl 64, id 29964, offset 0, flags [DF], proto TCP (6), length 1412)
172.16.0.1.50918 > 172.16.0.2.22: Flags [P.], seq 14171614:14172974, ack 1433043471, win 229, options [nop,nop,TS val 1287995744 ecr 3312743811], length 1360
net/core/dev.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
net/core/dev.c +3 -1
@@ -4057,8 +4057,10 @@ static u32 netif_receive_generic_xdp(struct sk_buff *skb,* pckt. */ off = orig_data_end - xdp.data_end; -if (off !=0 ) +if (off !=0 ) {skb_set_tail_pointer (skb, xdp.data_end - xdp.data); + skb->len -= off; + }switch (act) {case XDP_REDIRECT :
Signature · 1 line
2.15.1
Quoted 10 lines · Nikita V. Shirokov
when
bpf_adjust_tailwas introduced for generic xdp, it changed skb's tail pointer, so it was pointing to the new "end of the packet". however skb's len field wasn't properly modified, so on the wire ethernet frame had original (or even bigger, ifadjust_headwas used) size. this diff is fixing this.Fixes 198d83bb3 (" bpf: make generic xdp compatible w/
bpf_xdp_adjust_tail")Signed-off-by Nikita V. Shirokov <[email protected]>
Applied yesterday to bpf-next (and now in net-next), thanks Nikita!