mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 04:02:20 +00:00
cf3ab8d4a7
When clatd starts with ebpf offloaing, and NETIF_F_GRO_FRAGLIST is enable, several skbs are gathered in skb_shinfo(skb)->frag_list. The first skb's ipv6 header will be changed to ipv4 after bpf_skb_proto_6_to_4, network_header\transport_header\mac_header have been updated as ipv4 acts, but other skbs in frag_list didnot update anything, just ipv6 packets. udp_queue_rcv_skb will call skb_segment_list to traverse other skbs in frag_list and make sure right udp payload is delivered to user space. Unfortunately, other skbs in frag_list who are still ipv6 packets are updated like the first skb and will have wrong transport header length. e.g.before bpf_skb_proto_6_to_4,the first skb and other skbs in frag_list has the same network_header(24)& transport_header(64), after bpf_skb_proto_6_to_4, ipv6 protocol has been changed to ipv4, the first skb's network_header is 44,transport_header is 64, other skbs in frag_list didnot change.After skb_segment_list, the other skbs in frag_list has different network_header(24) and transport_header(44), so there will be 20 bytes different from original,that is difference between ipv6 header and ipv4 header. Just change transport_header to be the same with original. Actually, there are two solutions to fix it, one is traversing all skbs and changing every skb header in bpf_skb_proto_6_to_4, the other is modifying frag_list skb's header in skb_segment_list. Considering efficiency, adopt the second one--- when the first skb and other skbs in frag_list has different network_header length, restore them to make sure right udp payload is delivered to user space. Signed-off-by: Lina Wang <lina.wang@mediatek.com> Signed-off-by: David S. Miller <davem@davemloft.net> |
||
---|---|---|
.. | ||
bpf_sk_storage.c | ||
datagram.c | ||
datagram.h | ||
dev_addr_lists_test.c | ||
dev_addr_lists.c | ||
dev_ioctl.c | ||
dev.c | ||
devlink.c | ||
drop_monitor.c | ||
dst_cache.c | ||
dst.c | ||
failover.c | ||
fib_notifier.c | ||
fib_rules.c | ||
filter.c | ||
flow_dissector.c | ||
flow_offload.c | ||
gen_estimator.c | ||
gen_stats.c | ||
gro_cells.c | ||
gro.c | ||
hwbm.c | ||
link_watch.c | ||
lwt_bpf.c | ||
lwtunnel.c | ||
Makefile | ||
neighbour.c | ||
net_namespace.c | ||
net-procfs.c | ||
net-sysfs.c | ||
net-sysfs.h | ||
net-traces.c | ||
netclassid_cgroup.c | ||
netevent.c | ||
netpoll.c | ||
netprio_cgroup.c | ||
of_net.c | ||
page_pool.c | ||
pktgen.c | ||
ptp_classifier.c | ||
request_sock.c | ||
rtnetlink.c | ||
scm.c | ||
secure_seq.c | ||
selftests.c | ||
skbuff.c | ||
skmsg.c | ||
sock_destructor.h | ||
sock_diag.c | ||
sock_map.c | ||
sock_reuseport.c | ||
sock.c | ||
stream.c | ||
sysctl_net_core.c | ||
timestamping.c | ||
tso.c | ||
utils.c | ||
xdp.c |