Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests/bpf: Fix BPF_FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL for empty flow label

Kernel's flow dissector continues to parse the packet when
the (optional) IPv6 flow label is empty even when instructed
to stop (via BPF_FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL). Do
the same in our reference BPF reimplementation.

Signed-off-by: Stanislav Fomichev <sdf@google.com>
Acked-by: Willem de Bruijn <willemb@google.com>
Link: https://lore.kernel.org/r/20230221180518.2139026-1-sdf@google.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Stanislav Fomichev and committed by
Alexei Starovoitov
9fa02892 d40c3847

+25 -1
+24
tools/testing/selftests/bpf/prog_tests/flow_dissector.c
··· 346 346 .retval = BPF_OK, 347 347 }, 348 348 { 349 + .name = "ipv6-empty-flow-label", 350 + .pkt.ipv6 = { 351 + .eth.h_proto = __bpf_constant_htons(ETH_P_IPV6), 352 + .iph.nexthdr = IPPROTO_TCP, 353 + .iph.payload_len = __bpf_constant_htons(MAGIC_BYTES), 354 + .iph.flow_lbl = { 0x00, 0x00, 0x00 }, 355 + .tcp.doff = 5, 356 + .tcp.source = 80, 357 + .tcp.dest = 8080, 358 + }, 359 + .keys = { 360 + .flags = BPF_FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL, 361 + .nhoff = ETH_HLEN, 362 + .thoff = ETH_HLEN + sizeof(struct ipv6hdr), 363 + .addr_proto = ETH_P_IPV6, 364 + .ip_proto = IPPROTO_TCP, 365 + .n_proto = __bpf_constant_htons(ETH_P_IPV6), 366 + .sport = 80, 367 + .dport = 8080, 368 + }, 369 + .flags = BPF_FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL, 370 + .retval = BPF_OK, 371 + }, 372 + { 349 373 .name = "ipip-encap", 350 374 .pkt.ipip = { 351 375 .eth.h_proto = __bpf_constant_htons(ETH_P_IP),
+1 -1
tools/testing/selftests/bpf/progs/bpf_flow.c
··· 337 337 keys->ip_proto = ip6h->nexthdr; 338 338 keys->flow_label = ip6_flowlabel(ip6h); 339 339 340 - if (keys->flags & BPF_FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL) 340 + if (keys->flow_label && keys->flags & BPF_FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL) 341 341 return export_flow_keys(keys, BPF_OK); 342 342 343 343 return parse_ipv6_proto(skb, ip6h->nexthdr);