Message ID | 20220607133135.271788-1-eyal.birger@gmail.com (mailing list archive) |
---|---|
State | Changes Requested |
Delegated to: | BPF |
Headers | show |
Series | [bpf-next] selftests/bpf: add lwt ip encap tests to test_progs | expand |
Hi Eyal, On 6/7/22 3:31 PM, Eyal Birger wrote: > Port test_lwt_ip_encap.sh tests onto test_progs. > > In addition, this commit adds "egress_md" tests which test a similar > flow as egress tests only they use gre devices in collect_md mode > for encapsulation and set the tunnel key using bpf_set_tunnel_key(). > > This introduces minor changes to test_lwt_ip_encap.{sh,c} for consistency > with the new tests: > > - GRE key must exist as bpf_set_tunnel_key() explicitly sets the > TUNNEL_KEY flag > > - Source address for GRE traffic is set to IP*_5 instead of IP*_1 since > GRE traffic is sent via veth5 so its address is selected when using > bpf_set_tunnel_key() > > Note: currently these programs use the legacy section name convention > as iproute2 lwt configuration does not support providing function names. > > Signed-off-by: Eyal Birger <eyal.birger@gmail.com> > --- > .../selftests/bpf/prog_tests/lwt_ip_encap.c | 582 ++++++++++++++++++ > .../selftests/bpf/progs/test_lwt_ip_encap.c | 51 +- > .../selftests/bpf/test_lwt_ip_encap.sh | 6 +- > 3 files changed, 633 insertions(+), 6 deletions(-) > create mode 100644 tools/testing/selftests/bpf/prog_tests/lwt_ip_encap.c > > diff --git a/tools/testing/selftests/bpf/prog_tests/lwt_ip_encap.c b/tools/testing/selftests/bpf/prog_tests/lwt_ip_encap.c > new file mode 100644 > index 000000000000..e1b6f3ce6045 > --- /dev/null > +++ b/tools/testing/selftests/bpf/prog_tests/lwt_ip_encap.c > @@ -0,0 +1,582 @@ > +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause > + > +/* Setup/topology: > + * > + * NS1 NS2 NS3 > + * veth1 <---> veth2 veth3 <---> veth4 (the top route) > + * veth5 <---> veth6 veth7 <---> veth8 (the bottom route) > + * > + * each vethN gets IP[4|6]_N address > + * > + * IP*_SRC = IP*_1 > + * IP*_DST = IP*_4 > + * > + * all tests test pings from IP*_SRC to IP*_DST > + * > + * by default, routes are configured to allow packets to go > + * IP*_1 <=> IP*_2 <=> IP*_3 <=> IP*_4 (the top route) > + * > + * a GRE device is installed in NS3 with IP*_GRE, and > + * NS1/NS2 are configured to route packets to IP*_GRE via IP*_8 > + * (the bottom route) > + * > + * Tests: > + * > + * 1. routes NS2->IP*_DST are brought down, so the only way a ping > + * from IP*_SRC to IP*_DST can work is via IP*_GRE > + * > + * 2a. in an egress test, a bpf LWT_XMIT program is installed on veth1 > + * that encaps the packets with an IP/GRE header to route to IP*_GRE > + * > + * ping: SRC->[encap at veth1:egress]->GRE:decap->DST > + * ping replies go DST->SRC directly > + * > + * 2b. in an ingress test, a bpf LWT_IN program is installed on veth2 > + * that encaps the packets with an IP/GRE header to route to IP*_GRE > + * > + * ping: SRC->[encap at veth2:ingress]->GRE:decap->DST > + * ping replies go DST->SRC directly > + * > + * 2c. in an egress_md test, a bpf LWT_XMIT program is installed on a > + * route towards collect_md gre{,6} devices in NS1 and sets the tunnel > + * key such that packets are encapsulated with an IP/GRE header to route > + * to IP*_GRE > + * > + * ping: SRC->[encap at gre{,6}_md:xmit]->GRE:decap->DST > + * ping replies go DST->SRC directly > + */ > + [...] Thanks a lot for porting the test into test_progs! Looks like the BPF CI currently bails out here: https://github.com/kernel-patches/bpf/runs/6812283921?check_suite_focus=true Andrii, looks like we might be missing CONFIG_NET_VRF in vmtest config-latest.*? [...] #98/1 lwt_ip_encap/lwt_ipv4_encap_egress:OK #98/2 lwt_ip_encap/lwt_ipv6_encap_egress:OK setup_namespaces:PASS:ip netns add ns_lwt_1 0 nsec setup_namespaces:PASS:ip netns add ns_lwt_2 0 nsec setup_namespaces:PASS:ip netns add ns_lwt_3 0 nsec lwt_ip_encap_test:PASS:setup namespaces 0 nsec setup_links_and_routes:PASS:ip link add veth1 netns ns_lwt_1 type veth peer name veth2 netns ns_lwt_2 0 nsec setup_links_and_routes:PASS:ip link add veth3 netns ns_lwt_2 type veth peer name veth4 netns ns_lwt_3 0 nsec setup_links_and_routes:PASS:ip link add veth5 netns ns_lwt_1 type veth peer name veth6 netns ns_lwt_2 0 nsec setup_links_and_routes:PASS:ip link add veth7 netns ns_lwt_2 type veth peer name veth8 netns ns_lwt_3 0 nsec open_netns:PASS:malloc token 0 nsec open_netns:PASS:open /proc/self/ns/net 0 nsec open_netns:PASS:open netns fd 0 nsec setns_by_fd:PASS:setns 0 nsec setns_by_fd:PASS:unshare 0 nsec setns_by_fd:PASS:remount private /sys 0 nsec setns_by_fd:PASS:umount2 /sys 0 nsec setns_by_fd:PASS:mount /sys 0 nsec setns_by_fd:PASS:mount /sys/fs/bpf 0 nsec open_netns:PASS:setns_by_fd 0 nsec setup_ns:PASS:setns 0 nsec write_sysctl:PASS:open sysctl 0 nsec write_sysctl:PASS:write sysctl 0 nsec write_sysctl:PASS:open sysctl 0 nsec write_sysctl:PASS:write sysctl 0 nsec write_sysctl:PASS:open sysctl 0 nsec write_sysctl:PASS:write sysctl 0 nsec write_sysctl:PASS:open sysctl 0 nsec write_sysctl:PASS:write sysctl 0 nsec setup_vrf:FAIL:ip link add red type vrf table 1001 unexpected error: 512 (errno 0) setns_by_fd:PASS:setns 0 nsec setns_by_fd:PASS:unshare 0 nsec setns_by_fd:PASS:remount private /sys 0 nsec setns_by_fd:PASS:umount2 /sys 0 nsec setns_by_fd:PASS:mount /sys 0 nsec setns_by_fd:PASS:mount /sys/fs/bpf 0 nsec close_netns:PASS:setns_by_fd 0 nsec lwt_ip_encap_test:FAIL:setup links and routes unexpected error: -1 (errno 0) setup_namespaces:PASS:ip netns delete ns_lwt_1 0 nsec setup_namespaces:PASS:ip netns delete ns_lwt_2 0 nsec setup_namespaces:PASS:ip netns delete ns_lwt_3 0 nsec #98/3 lwt_ip_encap/lwt_ipv4_encap_egress_vrf:FAIL setup_namespaces:PASS:ip netns add ns_lwt_1 0 nsec setup_namespaces:PASS:ip netns add ns_lwt_2 0 nsec setup_namespaces:PASS:ip netns add ns_lwt_3 0 nsec lwt_ip_encap_test:PASS:setup namespaces 0 nsec setup_links_and_routes:PASS:ip link add veth1 netns ns_lwt_1 type veth peer name veth2 netns ns_lwt_2 0 nsec setup_links_and_routes:PASS:ip link add veth3 netns ns_lwt_2 type veth peer name veth4 netns ns_lwt_3 0 nsec setup_links_and_routes:PASS:ip link add veth5 netns ns_lwt_1 type veth peer name veth6 netns ns_lwt_2 0 nsec setup_links_and_routes:PASS:ip link add veth7 netns ns_lwt_2 type veth peer name veth8 netns ns_lwt_3 0 nsec open_netns:PASS:malloc token 0 nsec open_netns:PASS:open /proc/self/ns/net 0 nsec open_netns:PASS:open netns fd 0 nsec setns_by_fd:PASS:setns 0 nsec setns_by_fd:PASS:unshare 0 nsec setns_by_fd:PASS:remount private /sys 0 nsec setns_by_fd:PASS:umount2 /sys 0 nsec setns_by_fd:PASS:mount /sys 0 nsec setns_by_fd:PASS:mount /sys/fs/bpf 0 nsec open_netns:PASS:setns_by_fd 0 nsec setup_ns:PASS:setns 0 nsec write_sysctl:PASS:open sysctl 0 nsec write_sysctl:PASS:write sysctl 0 nsec write_sysctl:PASS:open sysctl 0 nsec write_sysctl:PASS:write sysctl 0 nsec write_sysctl:PASS:open sysctl 0 nsec write_sysctl:PASS:write sysctl 0 nsec write_sysctl:PASS:open sysctl 0 nsec write_sysctl:PASS:write sysctl 0 nsec setup_vrf:FAIL:ip link add red type vrf table 1001 unexpected error: 512 (errno 0) setns_by_fd:PASS:setns 0 nsec setns_by_fd:PASS:unshare 0 nsec setns_by_fd:PASS:remount private /sys 0 nsec setns_by_fd:PASS:umount2 /sys 0 nsec setns_by_fd:PASS:mount /sys 0 nsec setns_by_fd:PASS:mount /sys/fs/bpf 0 nsec close_netns:PASS:setns_by_fd 0 nsec lwt_ip_encap_test:FAIL:setup links and routes unexpected error: -1 (errno 0) setup_namespaces:PASS:ip netns delete ns_lwt_1 0 nsec setup_namespaces:PASS:ip netns delete ns_lwt_2 0 nsec setup_namespaces:PASS:ip netns delete ns_lwt_3 0 nsec #98/4 lwt_ip_encap/lwt_ipv6_encap_egress_vrf:FAIL #98/5 lwt_ip_encap/lwt_ipv4_encap_ingress:OK #98/6 lwt_ip_encap/lwt_ipv6_encap_ingress:OK setup_namespaces:PASS:ip netns add ns_lwt_1 0 nsec setup_namespaces:PASS:ip netns add ns_lwt_2 0 nsec setup_namespaces:PASS:ip netns add ns_lwt_3 0 nsec lwt_ip_encap_test:PASS:setup namespaces 0 nsec setup_links_and_routes:PASS:ip link add veth1 netns ns_lwt_1 type veth peer name veth2 netns ns_lwt_2 0 nsec setup_links_and_routes:PASS:ip link add veth3 netns ns_lwt_2 type veth peer name veth4 netns ns_lwt_3 0 nsec setup_links_and_routes:PASS:ip link add veth5 netns ns_lwt_1 type veth peer name veth6 netns ns_lwt_2 0 nsec setup_links_and_routes:PASS:ip link add veth7 netns ns_lwt_2 type veth peer name veth8 netns ns_lwt_3 0 nsec open_netns:PASS:malloc token 0 nsec open_netns:PASS:open /proc/self/ns/net 0 nsec open_netns:PASS:open netns fd 0 nsec setns_by_fd:PASS:setns 0 nsec setns_by_fd:PASS:unshare 0 nsec setns_by_fd:PASS:remount private /sys 0 nsec setns_by_fd:PASS:umount2 /sys 0 nsec setns_by_fd:PASS:mount /sys 0 nsec setns_by_fd:PASS:mount /sys/fs/bpf 0 nsec open_netns:PASS:setns_by_fd 0 nsec setup_ns:PASS:setns 0 nsec write_sysctl:PASS:open sysctl 0 nsec write_sysctl:PASS:write sysctl 0 nsec write_sysctl:PASS:open sysctl 0 nsec write_sysctl:PASS:write sysctl 0 nsec write_sysctl:PASS:open sysctl 0 nsec write_sysctl:PASS:write sysctl 0 nsec write_sysctl:PASS:open sysctl 0 nsec write_sysctl:PASS:write sysctl 0 nsec setup_vrf:FAIL:ip link add red type vrf table 1001 unexpected error: 512 (errno 0) setns_by_fd:PASS:setns 0 nsec setns_by_fd:PASS:unshare 0 nsec setns_by_fd:PASS:remount private /sys 0 nsec setns_by_fd:PASS:umount2 /sys 0 nsec setns_by_fd:PASS:mount /sys 0 nsec setns_by_fd:PASS:mount /sys/fs/bpf 0 nsec close_netns:PASS:setns_by_fd 0 nsec lwt_ip_encap_test:FAIL:setup links and routes unexpected error: -1 (errno 0) setup_namespaces:PASS:ip netns delete ns_lwt_1 0 nsec setup_namespaces:PASS:ip netns delete ns_lwt_2 0 nsec setup_namespaces:PASS:ip netns delete ns_lwt_3 0 nsec #98/7 lwt_ip_encap/lwt_ipv4_encap_ingress_vrf:FAIL setup_namespaces:PASS:ip netns add ns_lwt_1 0 nsec setup_namespaces:PASS:ip netns add ns_lwt_2 0 nsec setup_namespaces:PASS:ip netns add ns_lwt_3 0 nsec lwt_ip_encap_test:PASS:setup namespaces 0 nsec setup_links_and_routes:PASS:ip link add veth1 netns ns_lwt_1 type veth peer name veth2 netns ns_lwt_2 0 nsec setup_links_and_routes:PASS:ip link add veth3 netns ns_lwt_2 type veth peer name veth4 netns ns_lwt_3 0 nsec setup_links_and_routes:PASS:ip link add veth5 netns ns_lwt_1 type veth peer name veth6 netns ns_lwt_2 0 nsec setup_links_and_routes:PASS:ip link add veth7 netns ns_lwt_2 type veth peer name veth8 netns ns_lwt_3 0 nsec open_netns:PASS:malloc token 0 nsec open_netns:PASS:open /proc/self/ns/net 0 nsec open_netns:PASS:open netns fd 0 nsec setns_by_fd:PASS:setns 0 nsec setns_by_fd:PASS:unshare 0 nsec setns_by_fd:PASS:remount private /sys 0 nsec setns_by_fd:PASS:umount2 /sys 0 nsec setns_by_fd:PASS:mount /sys 0 nsec setns_by_fd:PASS:mount /sys/fs/bpf 0 nsec open_netns:PASS:setns_by_fd 0 nsec setup_ns:PASS:setns 0 nsec write_sysctl:PASS:open sysctl 0 nsec write_sysctl:PASS:write sysctl 0 nsec write_sysctl:PASS:open sysctl 0 nsec write_sysctl:PASS:write sysctl 0 nsec write_sysctl:PASS:open sysctl 0 nsec write_sysctl:PASS:write sysctl 0 nsec write_sysctl:PASS:open sysctl 0 nsec write_sysctl:PASS:write sysctl 0 nsec setup_vrf:FAIL:ip link add red type vrf table 1001 unexpected error: 512 (errno 0) setns_by_fd:PASS:setns 0 nsec setns_by_fd:PASS:unshare 0 nsec setns_by_fd:PASS:remount private /sys 0 nsec setns_by_fd:PASS:umount2 /sys 0 nsec setns_by_fd:PASS:mount /sys 0 nsec setns_by_fd:PASS:mount /sys/fs/bpf 0 nsec close_netns:PASS:setns_by_fd 0 nsec lwt_ip_encap_test:FAIL:setup links and routes unexpected error: -1 (errno 0) setup_namespaces:PASS:ip netns delete ns_lwt_1 0 nsec setup_namespaces:PASS:ip netns delete ns_lwt_2 0 nsec setup_namespaces:PASS:ip netns delete ns_lwt_3 0 nsec #98/8 lwt_ip_encap/lwt_ipv6_encap_ingress_vrf:FAIL #98/9 lwt_ip_encap/lwt_ipv4_encap_egress_md:OK #98/10 lwt_ip_encap/lwt_ipv6_encap_egress_md:OK #98 lwt_ip_encap:FAIL #99/1 map_init/pcpu_map_init:OK #99/2 map_init/pcpu_lru_map_init:OK #99 map_init:OK [...]
On Fri, Jun 10, 2022 at 12:37 AM Daniel Borkmann <daniel@iogearbox.net> wrote: > > Hi Eyal, > > On 6/7/22 3:31 PM, Eyal Birger wrote: > > Port test_lwt_ip_encap.sh tests onto test_progs. > > > > In addition, this commit adds "egress_md" tests which test a similar > > flow as egress tests only they use gre devices in collect_md mode > > for encapsulation and set the tunnel key using bpf_set_tunnel_key(). > > > > This introduces minor changes to test_lwt_ip_encap.{sh,c} for consistency > > with the new tests: > > > > - GRE key must exist as bpf_set_tunnel_key() explicitly sets the > > TUNNEL_KEY flag > > > > - Source address for GRE traffic is set to IP*_5 instead of IP*_1 since > > GRE traffic is sent via veth5 so its address is selected when using > > bpf_set_tunnel_key() > > > > Note: currently these programs use the legacy section name convention > > as iproute2 lwt configuration does not support providing function names. > > > > Signed-off-by: Eyal Birger <eyal.birger@gmail.com> > > --- > > .../selftests/bpf/prog_tests/lwt_ip_encap.c | 582 ++++++++++++++++++ > > .../selftests/bpf/progs/test_lwt_ip_encap.c | 51 +- > > .../selftests/bpf/test_lwt_ip_encap.sh | 6 +- > > 3 files changed, 633 insertions(+), 6 deletions(-) > > create mode 100644 tools/testing/selftests/bpf/prog_tests/lwt_ip_encap.c > > > > diff --git a/tools/testing/selftests/bpf/prog_tests/lwt_ip_encap.c b/tools/testing/selftests/bpf/prog_tests/lwt_ip_encap.c > > new file mode 100644 > > index 000000000000..e1b6f3ce6045 > > --- /dev/null > > +++ b/tools/testing/selftests/bpf/prog_tests/lwt_ip_encap.c > > @@ -0,0 +1,582 @@ > [...] > > Thanks a lot for porting the test into test_progs! Looks like the BPF CI currently > bails out here: > > https://github.com/kernel-patches/bpf/runs/6812283921?check_suite_focus=true > > Andrii, looks like we might be missing CONFIG_NET_VRF in vmtest config-latest.*? Hi Andrii, What's the next step - should I submit a PR to libbpf on Github for adding CONFIG_NET_VRF? Eyal.
On Tue, Jun 14, 2022 at 9:59 AM Eyal Birger <eyal.birger@gmail.com> wrote: > > On Fri, Jun 10, 2022 at 12:37 AM Daniel Borkmann <daniel@iogearbox.net> wrote: > > > > Hi Eyal, > > > > On 6/7/22 3:31 PM, Eyal Birger wrote: > > > Port test_lwt_ip_encap.sh tests onto test_progs. > > > > > > In addition, this commit adds "egress_md" tests which test a similar > > > flow as egress tests only they use gre devices in collect_md mode > > > for encapsulation and set the tunnel key using bpf_set_tunnel_key(). > > > > > > This introduces minor changes to test_lwt_ip_encap.{sh,c} for consistency > > > with the new tests: > > > > > > - GRE key must exist as bpf_set_tunnel_key() explicitly sets the > > > TUNNEL_KEY flag > > > > > > - Source address for GRE traffic is set to IP*_5 instead of IP*_1 since > > > GRE traffic is sent via veth5 so its address is selected when using > > > bpf_set_tunnel_key() > > > > > > Note: currently these programs use the legacy section name convention > > > as iproute2 lwt configuration does not support providing function names. > > > > > > Signed-off-by: Eyal Birger <eyal.birger@gmail.com> > > > --- > > > .../selftests/bpf/prog_tests/lwt_ip_encap.c | 582 ++++++++++++++++++ > > > .../selftests/bpf/progs/test_lwt_ip_encap.c | 51 +- > > > .../selftests/bpf/test_lwt_ip_encap.sh | 6 +- > > > 3 files changed, 633 insertions(+), 6 deletions(-) > > > create mode 100644 tools/testing/selftests/bpf/prog_tests/lwt_ip_encap.c > > > > > > diff --git a/tools/testing/selftests/bpf/prog_tests/lwt_ip_encap.c b/tools/testing/selftests/bpf/prog_tests/lwt_ip_encap.c > > > new file mode 100644 > > > index 000000000000..e1b6f3ce6045 > > > --- /dev/null > > > +++ b/tools/testing/selftests/bpf/prog_tests/lwt_ip_encap.c > > > @@ -0,0 +1,582 @@ > > [...] > > > > Thanks a lot for porting the test into test_progs! Looks like the BPF CI currently > > bails out here: > > > > https://github.com/kernel-patches/bpf/runs/6812283921?check_suite_focus=true > > > > Andrii, looks like we might be missing CONFIG_NET_VRF in vmtest config-latest.*? > > Hi Andrii, > > What's the next step - should I submit a PR to libbpf on Github for adding > CONFIG_NET_VRF? Yes, please, for [0] and [1]: [0] https://github.com/libbpf/libbpf [1] https://github.com/kernel-patches/vmtest > > Eyal.
Hi Eyal, On 6/16/22 1:31 AM, Andrii Nakryiko wrote: [...] >> What's the next step - should I submit a PR to libbpf on Github for adding >> CONFIG_NET_VRF? > > Yes, please, for [0] and [1]: > > [0] https://github.com/libbpf/libbpf > [1] https://github.com/kernel-patches/vmtest Thanks a lot for getting the needed configs in. The CI looks better now, but there is one small failure on s390 (big endian): https://github.com/kernel-patches/bpf/runs/6932751303?check_suite_focus=true These: 1) "Failed to cycle device vethX; route tables might be wrong!" is this expected? 2) test_gso:FAIL:recv from server unexpected recv from server: actual 7140 != expected 9000 Please take a look and fix in a v2 when you get a chance. I'm pasting the full log just in case: [...] #97 lookup_and_delete:OK IPv6: ADDRCONF(NETDEV_CHANGE): veth1: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth5: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth2: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth4: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth3: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth8: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth7: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth1: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth5: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth2: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth4: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth3: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth8: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth7: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth2: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth1: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth6: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth5: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth4: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth3: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth8: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth7: link becomes ready veth3: Failed to cycle device veth3; route tables might be wrong! veth7: Failed to cycle device veth7; route tables might be wrong! IPv6: ADDRCONF(NETDEV_CHANGE): veth1: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth6: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth5: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth4: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth3: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth8: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth7: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth2: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth1: link becomes ready veth3: Failed to cycle device veth3; route tables might be wrong! veth7: Failed to cycle device veth7; route tables might be wrong! IPv6: ADDRCONF(NETDEV_CHANGE): veth2: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth6: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth5: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth4: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth3: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth8: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth7: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth1: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth5: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth2: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth4: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth3: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth8: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth7: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth1: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth6: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth5: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth4: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth3: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth8: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth7: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth2: link becomes ready veth3: Failed to cycle device veth3; route tables might be wrong! veth7: Failed to cycle device veth7; route tables might be wrong! IPv6: ADDRCONF(NETDEV_CHANGE): veth1: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth6: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth5: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth2: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth4: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth3: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth8: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth7: link becomes ready veth3: Failed to cycle device veth3; route tables might be wrong! veth7: Failed to cycle device veth7; route tables might be wrong! IPv6: ADDRCONF(NETDEV_CHANGE): veth1: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth6: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth5: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth4: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth3: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth8: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth7: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth2: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth1: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth5: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth2: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth4: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth3: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth8: link becomes ready IPv6: ADDRCONF(NETDEV_CHANGE): veth7: link becomes ready serial_test_lwt_ip_encap:PASS:pthread_create 0 nsec setup_namespaces:PASS:ip netns add ns_lwt_1 0 nsec setup_namespaces:PASS:ip netns add ns_lwt_2 0 nsec setup_namespaces:PASS:ip netns add ns_lwt_3 0 nsec lwt_ip_encap_test:PASS:setup namespaces 0 nsec setup_links_and_routes:PASS:ip link add veth1 netns ns_lwt_1 type veth peer name veth2 netns ns_lwt_2 0 nsec setup_links_and_routes:PASS:ip link add veth3 netns ns_lwt_2 type veth peer name veth4 netns ns_lwt_3 0 nsec setup_links_and_routes:PASS:ip link add veth5 netns ns_lwt_1 type veth peer name veth6 netns ns_lwt_2 0 nsec setup_links_and_routes:PASS:ip link add veth7 netns ns_lwt_2 type veth peer name veth8 netns ns_lwt_3 0 nsec open_netns:PASS:malloc token 0 nsec open_netns:PASS:open /proc/self/ns/net 0 nsec open_netns:PASS:open netns fd 0 nsec setns_by_fd:PASS:setns 0 nsec setns_by_fd:PASS:unshare 0 nsec setns_by_fd:PASS:remount private /sys 0 nsec setns_by_fd:PASS:umount2 /sys 0 nsec setns_by_fd:PASS:mount /sys 0 nsec setns_by_fd:PASS:mount /sys/fs/bpf 0 nsec open_netns:PASS:setns_by_fd 0 nsec setup_ns:PASS:setns 0 nsec write_sysctl:PASS:open sysctl 0 nsec write_sysctl:PASS:write sysctl 0 nsec write_sysctl:PASS:open sysctl 0 nsec write_sysctl:PASS:write sysctl 0 nsec write_sysctl:PASS:open sysctl 0 nsec write_sysctl:PASS:write sysctl 0 nsec write_sysctl:PASS:open sysctl 0 nsec write_sysctl:PASS:write sysctl 0 nsec setup_ns1:PASS:ip link add gre_md type gre external 0 nsec setup_ns1:PASS:ip link add gre6_md type ip6gre external 0 nsec setup_device:PASS:ip addr add 172.16.1.100/24 dev veth1 0 nsec setup_device:PASS:ip -6 addr add fb01::1/128 nodad dev veth1 0 nsec setup_device:PASS:ip link set dev veth1 up 0 nsec setup_device:PASS:ip addr add 172.16.5.100/24 dev veth5 0 nsec setup_device:PASS:ip -6 addr add fb05::1/128 nodad dev veth5 0 nsec setup_device:PASS:ip link set dev veth5 up 0 nsec setup_device:PASS:ip addr add 172.16.1.100/24 dev gre_md 0 nsec setup_device:PASS:ip -6 addr add fb01::1/128 nodad dev gre_md 0 nsec setup_device:PASS:ip link set dev gre_md up 0 nsec setup_device:PASS:ip addr add 172.16.1.100/24 dev gre6_md 0 nsec setup_device:PASS:ip -6 addr add fb01::1/128 nodad dev gre6_md 0 nsec setup_device:PASS:ip link set dev gre6_md up 0 nsec setup_ns1:PASS:ip route add 172.16.2.100/32 dev veth1 0 nsec setup_ns1:PASS:ip -6 route add fb02::1/128 dev veth1 0 nsec setup_ns1:PASS:ip route add default dev veth1 via 172.16.2.100 0 nsec setup_ns1:PASS:ip -6 route add default dev veth1 via fb02::1 0 nsec setup_ns1:PASS:ip route add 172.16.6.100/32 dev veth5 0 nsec setup_ns1:PASS:ip route add 172.16.7.100/32 dev veth5 via 172.16.6.100 0 nsec setup_ns1:PASS:ip route add 172.16.8.100/32 dev veth5 via 172.16.6.100 0 nsec setup_ns1:PASS:ip -6 route add fb06::1/128 dev veth5 0 nsec setup_ns1:PASS:ip -6 route add fb07::1/128 dev veth5 via fb06::1 0 nsec setup_ns1:PASS:ip -6 route add fb08::1/128 dev veth5 via fb06::1 0 nsec setup_ns1:PASS:ip route add 172.16.16.100/32 dev veth5 via 172.16.6.100 0 nsec setup_ns1:PASS:ip -6 route add fb10::1/128 dev veth5 via fb06::1 0 nsec setns_by_fd:PASS:setns 0 nsec setns_by_fd:PASS:unshare 0 nsec setns_by_fd:PASS:remount private /sys 0 nsec setns_by_fd:PASS:umount2 /sys 0 nsec setns_by_fd:PASS:mount /sys 0 nsec setns_by_fd:PASS:mount /sys/fs/bpf 0 nsec close_netns:PASS:setns_by_fd 0 nsec open_netns:PASS:malloc token 0 nsec open_netns:PASS:open /proc/self/ns/net 0 nsec open_netns:PASS:open netns fd 0 nsec setns_by_fd:PASS:setns 0 nsec setns_by_fd:PASS:unshare 0 nsec setns_by_fd:PASS:remount private /sys 0 nsec setns_by_fd:PASS:umount2 /sys 0 nsec setns_by_fd:PASS:mount /sys 0 nsec setns_by_fd:PASS:mount /sys/fs/bpf 0 nsec open_netns:PASS:setns_by_fd 0 nsec setup_ns:PASS:setns 0 nsec write_sysctl:PASS:open sysctl 0 nsec write_sysctl:PASS:write sysctl 0 nsec write_sysctl:PASS:open sysctl 0 nsec write_sysctl:PASS:write sysctl 0 nsec write_sysctl:PASS:open sysctl 0 nsec write_sysctl:PASS:write sysctl 0 nsec write_sysctl:PASS:open sysctl 0 nsec write_sysctl:PASS:write sysctl 0 nsec write_sysctl:PASS:open sysctl 0 nsec write_sysctl:PASS:write sysctl 0 nsec write_sysctl:PASS:open sysctl 0 nsec write_sysctl:PASS:write sysctl 0 nsec setup_device:PASS:ip addr add 172.16.2.100/24 dev veth2 0 nsec setup_device:PASS:ip -6 addr add fb02::1/128 nodad dev veth2 0 nsec setup_device:PASS:ip link set dev veth2 up 0 nsec setup_device:PASS:ip addr add 172.16.3.100/24 dev veth3 0 nsec setup_device:PASS:ip -6 addr add fb03::1/128 nodad dev veth3 0 nsec setup_device:PASS:ip link set dev veth3 up 0 nsec setup_device:PASS:ip addr add 172.16.6.100/24 dev veth6 0 nsec setup_device:PASS:ip -6 addr add fb06::1/128 nodad dev veth6 0 nsec setup_device:PASS:ip link set dev veth6 up 0 nsec setup_device:PASS:ip addr add 172.16.7.100/24 dev veth7 0 nsec setup_device:PASS:ip -6 addr add fb07::1/128 nodad dev veth7 0 nsec setup_device:PASS:ip link set dev veth7 up 0 nsec setup_ns2:PASS:ip route add 172.16.1.100/32 dev veth2 0 nsec setup_ns2:PASS:ip route add 172.16.4.100/32 dev veth3 0 nsec setup_ns2:PASS:ip -6 route add fb01::1/128 dev veth2 0 nsec setup_ns2:PASS:ip -6 route add fb04::1/128 dev veth3 0 nsec setup_ns2:PASS:ip route add 172.16.5.100/32 dev veth6 0 nsec setup_ns2:PASS:ip route add 172.16.8.100/32 dev veth7 0 nsec setup_ns2:PASS:ip -6 route add fb05::1/128 dev veth6 0 nsec setup_ns2:PASS:ip -6 route add fb08::1/128 dev veth7 0 nsec setup_ns2:PASS:ip route add 172.16.16.100/32 dev veth7 via 172.16.8.100 0 nsec setup_ns2:PASS:ip -6 route add fb10::1/128 dev veth7 via fb08::1 0 nsec setns_by_fd:PASS:setns 0 nsec setns_by_fd:PASS:unshare 0 nsec setns_by_fd:PASS:remount private /sys 0 nsec setns_by_fd:PASS:umount2 /sys 0 nsec setns_by_fd:PASS:mount /sys 0 nsec setns_by_fd:PASS:mount /sys/fs/bpf 0 nsec close_netns:PASS:setns_by_fd 0 nsec open_netns:PASS:malloc token 0 nsec open_netns:PASS:open /proc/self/ns/net 0 nsec open_netns:PASS:open netns fd 0 nsec setns_by_fd:PASS:setns 0 nsec setns_by_fd:PASS:unshare 0 nsec setns_by_fd:PASS:remount private /sys 0 nsec setns_by_fd:PASS:umount2 /sys 0 nsec setns_by_fd:PASS:mount /sys 0 nsec setns_by_fd:PASS:mount /sys/fs/bpf 0 nsec open_netns:PASS:setns_by_fd 0 nsec setup_ns:PASS:setns 0 nsec write_sysctl:PASS:open sysctl 0 nsec write_sysctl:PASS:write sysctl 0 nsec write_sysctl:PASS:open sysctl 0 nsec write_sysctl:PASS:write sysctl 0 nsec write_sysctl:PASS:open sysctl 0 nsec write_sysctl:PASS:write sysctl 0 nsec write_sysctl:PASS:open sysctl 0 nsec write_sysctl:PASS:write sysctl 0 nsec setup_device:PASS:ip addr add 172.16.4.100/24 dev veth4 0 nsec setup_device:PASS:ip -6 addr add fb04::1/128 nodad dev veth4 0 nsec setup_device:PASS:ip link set dev veth4 up 0 nsec setup_device:PASS:ip addr add 172.16.8.100/24 dev veth8 0 nsec setup_device:PASS:ip -6 addr add fb08::1/128 nodad dev veth8 0 nsec setup_device:PASS:ip link set dev veth8 up 0 nsec setup_ns3:PASS:ip route add 172.16.3.100/32 dev veth4 0 nsec setup_ns3:PASS:ip route add 172.16.1.100/32 dev veth4 via 172.16.3.100 0 nsec setup_ns3:PASS:ip route add 172.16.2.100/32 dev veth4 via 172.16.3.100 0 nsec setup_ns3:PASS:ip -6 route add fb03::1/128 dev veth4 0 nsec setup_ns3:PASS:ip -6 route add fb01::1/128 dev veth4 via fb03::1 0 nsec setup_ns3:PASS:ip -6 route add fb02::1/128 dev veth4 via fb03::1 0 nsec setup_ns3:PASS:ip route add 172.16.7.100/32 dev veth8 0 nsec setup_ns3:PASS:ip route add 172.16.5.100/32 dev veth8 via 172.16.7.100 0 nsec setup_ns3:PASS:ip route add 172.16.6.100/32 dev veth8 via 172.16.7.100 0 nsec setup_ns3:PASS:ip -6 route add fb07::1/128 dev veth8 0 nsec setup_ns3:PASS:ip -6 route add fb05::1/128 dev veth8 via fb07::1 0 nsec setup_ns3:PASS:ip -6 route add fb06::1/128 dev veth8 via fb07::1 0 nsec setup_ns3:PASS:ip tunnel add gre_dev mode gre remote 172.16.5.100 local 172.16.16.100 ttl 255 key 0 0 nsec setup_device:PASS:ip addr add 172.16.16.100/24 dev gre_dev 0 nsec setup_device:PASS:ip link set dev gre_dev up 0 nsec setup_ns3:PASS:ip tunnel add gre6_dev mode ip6gre remote fb05::1 local fb10::1 ttl 255 key 0 0 nsec setup_device:PASS:ip -6 addr add fb10::1/128 nodad dev gre6_dev 0 nsec setup_device:PASS:ip link set dev gre6_dev up 0 nsec setns_by_fd:PASS:setns 0 nsec setns_by_fd:PASS:unshare 0 nsec setns_by_fd:PASS:remount private /sys 0 nsec setns_by_fd:PASS:umount2 /sys 0 nsec setns_by_fd:PASS:mount /sys 0 nsec setns_by_fd:PASS:mount /sys/fs/bpf 0 nsec close_netns:PASS:setns_by_fd 0 nsec lwt_ip_encap_test:PASS:setup links and routes 0 nsec test_ping:PASS:ip netns exec ns_lwt_1 ping -c 1 -W 1 -I veth1 172.16.4.100 > /dev/null 0 nsec test_ping:PASS:ip netns exec ns_lwt_1 ping6 -c 1 -W 1 -I veth1 fb04::1 > /dev/null 0 nsec lwt_ip_encap_test:PASS:ip -netns ns_lwt_2 route del 172.16.4.100/32 dev veth3 0 nsec lwt_ip_encap_test:PASS:ip -netns ns_lwt_2 -6 route del fb04::1/128 dev veth3 0 nsec test_ping:PASS:ip netns exec ns_lwt_1 ping -c 1 -W 1 -I veth1 172.16.4.100 > /dev/null 0 nsec test_ping:PASS:ip netns exec ns_lwt_1 ping6 -c 1 -W 1 -I veth1 fb04::1 > /dev/null 0 nsec lwt_ip_encap_test:PASS:ip -netns ns_lwt_1 route add 172.16.4.100/32 encap bpf xmit obj test_lwt_ip_encap.o sec encap_gre dev veth1 0 nsec lwt_ip_encap_test:PASS:ip -netns ns_lwt_1 -6 route add fb04::1/128 encap bpf xmit obj test_lwt_ip_encap.o sec encap_gre dev veth1 0 nsec test_ping:PASS:ip netns exec ns_lwt_1 ping -c 1 -W 1 -I veth1 172.16.4.100 > /dev/null 0 nsec test_ping:PASS:ip netns exec ns_lwt_1 ping6 -c 1 -W 1 -I veth1 fb04::1 > /dev/null 0 nsec open_netns:PASS:malloc token 0 nsec open_netns:PASS:open /proc/self/ns/net 0 nsec open_netns:PASS:open netns fd 0 nsec setns_by_fd:PASS:setns 0 nsec setns_by_fd:PASS:unshare 0 nsec setns_by_fd:PASS:remount private /sys 0 nsec setns_by_fd:PASS:umount2 /sys 0 nsec setns_by_fd:PASS:mount /sys 0 nsec setns_by_fd:PASS:mount /sys/fs/bpf 0 nsec open_netns:PASS:setns_by_fd 0 nsec test_gso:PASS:setns 0 nsec test_gso:PASS:listen 0 nsec setns_by_fd:PASS:setns 0 nsec setns_by_fd:PASS:unshare 0 nsec setns_by_fd:PASS:remount private /sys 0 nsec setns_by_fd:PASS:umount2 /sys 0 nsec setns_by_fd:PASS:mount /sys 0 nsec setns_by_fd:PASS:mount /sys/fs/bpf 0 nsec close_netns:PASS:setns_by_fd 0 nsec open_netns:PASS:malloc token 0 nsec open_netns:PASS:open /proc/self/ns/net 0 nsec open_netns:PASS:open netns fd 0 nsec setns_by_fd:PASS:setns 0 nsec setns_by_fd:PASS:unshare 0 nsec setns_by_fd:PASS:remount private /sys 0 nsec setns_by_fd:PASS:umount2 /sys 0 nsec setns_by_fd:PASS:mount /sys 0 nsec setns_by_fd:PASS:mount /sys/fs/bpf 0 nsec open_netns:PASS:setns_by_fd 0 nsec test_gso:PASS:setns src 0 nsec test_gso:PASS:connect_to_fd 0 nsec test_gso:PASS:accept 0 nsec test_gso:PASS:settimeo 0 nsec test_gso:PASS:send to server 0 nsec test_gso:PASS:recv from server 0 nsec setns_by_fd:PASS:setns 0 nsec setns_by_fd:PASS:unshare 0 nsec setns_by_fd:PASS:remount private /sys 0 nsec setns_by_fd:PASS:umount2 /sys 0 nsec setns_by_fd:PASS:mount /sys 0 nsec setns_by_fd:PASS:mount /sys/fs/bpf 0 nsec close_netns:PASS:setns_by_fd 0 nsec open_netns:PASS:malloc token 0 nsec open_netns:PASS:open /proc/self/ns/net 0 nsec open_netns:PASS:open netns fd 0 nsec setns_by_fd:PASS:setns 0 nsec setns_by_fd:PASS:unshare 0 nsec setns_by_fd:PASS:remount private /sys 0 nsec setns_by_fd:PASS:umount2 /sys 0 nsec setns_by_fd:PASS:mount /sys 0 nsec setns_by_fd:PASS:mount /sys/fs/bpf 0 nsec open_netns:PASS:setns_by_fd 0 nsec test_gso:PASS:setns 0 nsec test_gso:PASS:listen 0 nsec setns_by_fd:PASS:setns 0 nsec setns_by_fd:PASS:unshare 0 nsec setns_by_fd:PASS:remount private /sys 0 nsec setns_by_fd:PASS:umount2 /sys 0 nsec setns_by_fd:PASS:mount /sys 0 nsec setns_by_fd:PASS:mount /sys/fs/bpf 0 nsec close_netns:PASS:setns_by_fd 0 nsec open_netns:PASS:malloc token 0 nsec open_netns:PASS:open /proc/self/ns/net 0 nsec open_netns:PASS:open netns fd 0 nsec setns_by_fd:PASS:setns 0 nsec setns_by_fd:PASS:unshare 0 nsec setns_by_fd:PASS:remount private /sys 0 nsec setns_by_fd:PASS:umount2 /sys 0 nsec setns_by_fd:PASS:mount /sys 0 nsec setns_by_fd:PASS:mount /sys/fs/bpf 0 nsec open_netns:PASS:setns_by_fd 0 nsec test_gso:PASS:setns src 0 nsec test_gso:PASS:connect_to_fd 0 nsec test_gso:PASS:accept 0 nsec test_gso:PASS:settimeo 0 nsec test_gso:PASS:send to server 0 nsec test_gso:FAIL:recv from server unexpected recv from server: actual 7140 != expected 9000 setns_by_fd:PASS:setns 0 nsec setns_by_fd:PASS:unshare 0 nsec setns_by_fd:PASS:remount private /sys 0 nsec setns_by_fd:PASS:umount2 /sys 0 nsec setns_by_fd:PASS:mount /sys 0 nsec setns_by_fd:PASS:mount /sys/fs/bpf 0 nsec close_netns:PASS:setns_by_fd 0 nsec remove_routes_to_gredev:PASS:ip -netns ns_lwt_1 route del 172.16.16.100/32 dev veth5 0 nsec remove_routes_to_gredev:PASS:ip -netns ns_lwt_1 -6 route del fb10::1/128 dev veth5 0 nsec remove_routes_to_gredev:PASS:ip -netns ns_lwt_2 route del 172.16.16.100/32 dev veth7 0 nsec remove_routes_to_gredev:PASS:ip -netns ns_lwt_2 -6 route del fb10::1/128 dev veth7 0 nsec setup_namespaces:PASS:ip netns delete ns_lwt_1 0 nsec setup_namespaces:PASS:ip netns delete ns_lwt_2 0 nsec setup_namespaces:PASS:ip netns delete ns_lwt_3 0 nsec #98/1 lwt_ip_encap/lwt_ipv4_encap_egress:FAIL #98/2 lwt_ip_encap/lwt_ipv6_encap_egress:OK #98/3 lwt_ip_encap/lwt_ipv4_encap_egress_vrf:OK #98/4 lwt_ip_encap/lwt_ipv6_encap_egress_vrf:OK #98/5 lwt_ip_encap/lwt_ipv4_encap_ingress:OK #98/6 lwt_ip_encap/lwt_ipv6_encap_ingress:OK #98/7 lwt_ip_encap/lwt_ipv4_encap_ingress_vrf:OK #98/8 lwt_ip_encap/lwt_ipv6_encap_ingress_vrf:OK #98/9 lwt_ip_encap/lwt_ipv4_encap_egress_md:OK #98/10 lwt_ip_encap/lwt_ipv6_encap_egress_md:OK #98 lwt_ip_encap:FAIL [...] Thanks, Daniel
diff --git a/tools/testing/selftests/bpf/prog_tests/lwt_ip_encap.c b/tools/testing/selftests/bpf/prog_tests/lwt_ip_encap.c new file mode 100644 index 000000000000..e1b6f3ce6045 --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/lwt_ip_encap.c @@ -0,0 +1,582 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause + +/* Setup/topology: + * + * NS1 NS2 NS3 + * veth1 <---> veth2 veth3 <---> veth4 (the top route) + * veth5 <---> veth6 veth7 <---> veth8 (the bottom route) + * + * each vethN gets IP[4|6]_N address + * + * IP*_SRC = IP*_1 + * IP*_DST = IP*_4 + * + * all tests test pings from IP*_SRC to IP*_DST + * + * by default, routes are configured to allow packets to go + * IP*_1 <=> IP*_2 <=> IP*_3 <=> IP*_4 (the top route) + * + * a GRE device is installed in NS3 with IP*_GRE, and + * NS1/NS2 are configured to route packets to IP*_GRE via IP*_8 + * (the bottom route) + * + * Tests: + * + * 1. routes NS2->IP*_DST are brought down, so the only way a ping + * from IP*_SRC to IP*_DST can work is via IP*_GRE + * + * 2a. in an egress test, a bpf LWT_XMIT program is installed on veth1 + * that encaps the packets with an IP/GRE header to route to IP*_GRE + * + * ping: SRC->[encap at veth1:egress]->GRE:decap->DST + * ping replies go DST->SRC directly + * + * 2b. in an ingress test, a bpf LWT_IN program is installed on veth2 + * that encaps the packets with an IP/GRE header to route to IP*_GRE + * + * ping: SRC->[encap at veth2:ingress]->GRE:decap->DST + * ping replies go DST->SRC directly + * + * 2c. in an egress_md test, a bpf LWT_XMIT program is installed on a + * route towards collect_md gre{,6} devices in NS1 and sets the tunnel + * key such that packets are encapsulated with an IP/GRE header to route + * to IP*_GRE + * + * ping: SRC->[encap at gre{,6}_md:xmit]->GRE:decap->DST + * ping replies go DST->SRC directly + */ + +#include "test_progs.h" +#include "network_helpers.h" + +#define NS_1 "ns_lwt_1" +#define NS_2 "ns_lwt_2" +#define NS_3 "ns_lwt_3" + +#define IP4_1 "172.16.1.100" +#define IP4_2 "172.16.2.100" +#define IP4_3 "172.16.3.100" +#define IP4_4 "172.16.4.100" +#define IP4_5 "172.16.5.100" +#define IP4_6 "172.16.6.100" +#define IP4_7 "172.16.7.100" +#define IP4_8 "172.16.8.100" +#define IP4_GRE "172.16.16.100" +#define IP4_DST IP4_4 + +#define IP6_1 "fb01::1" +#define IP6_2 "fb02::1" +#define IP6_3 "fb03::1" +#define IP6_4 "fb04::1" +#define IP6_5 "fb05::1" +#define IP6_6 "fb06::1" +#define IP6_7 "fb07::1" +#define IP6_8 "fb08::1" +#define IP6_GRE "fb10::1" +#define IP6_DST IP6_4 + +#define TEST_VRF_NAME "red" + +static const char * const namespaces[] = {NS_1, NS_2, NS_3, NULL}; +static __u32 duration; +static bool use_vrf; + +enum encap_type { + ENCAP_EGRESS, + ENCAP_INGRESS, + ENCAP_EGRESS_MD, +}; + +#define SYS(fmt, ...) \ + ({ \ + char cmd[1024]; \ + snprintf(cmd, sizeof(cmd), fmt, ##__VA_ARGS__); \ + if (!ASSERT_OK(system(cmd), cmd)) \ + goto fail; \ + }) + +#define ADD_VETH_PAIR(v1, ns1, v2, ns2) \ + SYS("ip link add " v1 " netns " ns1 " type veth " \ + "peer name " v2 " netns " ns2) + +#define SET_NS_ROUTE(op, netns, family, fmt, ...) \ + SYS("ip %s%s %s route " op " %s " fmt, \ + netns[0] ? "-netns " : "", netns[0] ? netns : "", \ + family == AF_INET6 ? "-6" : "", \ + use_vrf ? "vrf " TEST_VRF_NAME : "", \ + ##__VA_ARGS__) + +#define SET_NS_ADDR_ROUTE(op, netns, addr, fmt, ...) \ + ({ \ + int family = strchr(addr, ':') ? AF_INET6 : AF_INET; \ + SET_NS_ROUTE(op, netns, family, addr "%s " fmt, \ + family == AF_INET6 ? "/128" : "/32", \ + ##__VA_ARGS__); \ + }) + +#define ADD_ROUTE(family, ...) SET_NS_ROUTE("add", "", family, ##__VA_ARGS__) + +#define ADD_ADDR_ROUTE(...) SET_NS_ADDR_ROUTE("add", "", ##__VA_ARGS__) + +static int write_sysctl(const char *sysctl, const char *value) +{ + int fd, err, len; + + fd = open(sysctl, O_WRONLY); + if (CHECK(fd == -1, "open sysctl", "open(%s): %s (%d)\n", + sysctl, strerror(errno), errno)) + return -1; + + len = strlen(value); + err = write(fd, value, len); + close(fd); + if (CHECK(err != len, "write sysctl", + "write(%s, %s): err:%d %s (%d)\n", + sysctl, value, err, strerror(errno), errno)) + return -1; + + return 0; +} + +static int setup_namespaces(const char *verb) +{ + const char * const *ns = namespaces; + + while (*ns) { + SYS("ip netns %s %s", verb, *ns); + ns++; + } + return 0; +fail: + return -1; +} + +static void setup_namespaces_nofail(const char *verb) +{ + const char * const *ns = namespaces; + char cmd[128]; + + while (*ns) { + snprintf(cmd, sizeof(cmd), "ip netns %s %s > /dev/null 2>&1", + verb, *ns); + system(cmd); + ns++; + } +} + +static int setup_ns(const char *ns, int (*ns_setup_fn)(void)) +{ + struct nstoken *nstoken; + int err = -1; + + nstoken = open_netns(ns); + if (!ASSERT_OK_PTR(nstoken, "setns")) + return -1; + + /* rp_filter gets confused by what these tests are doing, + * so disable it. + * also disable IPv6 DAD because it sometimes takes too long and fails + * tests. + */ + if (write_sysctl("/proc/sys/net/ipv4/conf/all/rp_filter", "0") || + write_sysctl("/proc/sys/net/ipv4/conf/default/rp_filter", "0") || + write_sysctl("/proc/sys/net/ipv6/conf/all/accept_dad", "0") || + write_sysctl("/proc/sys/net/ipv6/conf/default/accept_dad", "0")) + goto exit; + + err = ns_setup_fn(); + +exit: + close_netns(nstoken); + return err; +} + +static int setup_device(const char *devname, const char *addr4, + const char *addr6) +{ + if (use_vrf) + SYS("ip link set %s vrf %s", devname, TEST_VRF_NAME); + + if (addr4) + SYS("ip addr add %s/24 dev %s", addr4, devname); + + if (addr6) + SYS("ip -6 addr add %s/128 nodad dev %s", addr6, devname); + + SYS("ip link set dev %s up", devname); + return 0; +fail: + return -1; +} + +static int setup_vrf(void) +{ + SYS("ip link add %s type vrf table 1001", TEST_VRF_NAME); + SYS("ip link set dev %s up", TEST_VRF_NAME); + SYS("ip route add table 1001 unreachable default metric 8192"); + SYS("ip -6 route add table 1001 unreachable default metric 8192"); + return 0; +fail: + return -1; +} + +static int setup_ns1(void) +{ + if (use_vrf && setup_vrf()) + goto fail; + + SYS("ip link add gre_md type gre external"); + SYS("ip link add gre6_md type ip6gre external"); + + if (setup_device("veth1", IP4_1, IP6_1) || + setup_device("veth5", IP4_5, IP6_5) || + setup_device("gre_md", IP4_1, IP6_1) || + setup_device("gre6_md", IP4_1, IP6_1)) + goto fail; + + /* Top route */ + ADD_ADDR_ROUTE(IP4_2, "dev veth1"); + ADD_ADDR_ROUTE(IP6_2, "dev veth1"); + ADD_ROUTE(AF_INET, "default dev veth1 via " IP4_2); + ADD_ROUTE(AF_INET6, "default dev veth1 via " IP6_2); + + /* Bottom route */ + ADD_ADDR_ROUTE(IP4_6, "dev veth5"); + ADD_ADDR_ROUTE(IP4_7, "dev veth5 via " IP4_6); + ADD_ADDR_ROUTE(IP4_8, "dev veth5 via " IP4_6); + ADD_ADDR_ROUTE(IP6_6, "dev veth5"); + ADD_ADDR_ROUTE(IP6_7, "dev veth5 via " IP6_6); + ADD_ADDR_ROUTE(IP6_8, "dev veth5 via " IP6_6); + + /* GRE peer via the bottom route */ + ADD_ADDR_ROUTE(IP4_GRE, "dev veth5 via " IP4_6); + ADD_ADDR_ROUTE(IP6_GRE, "dev veth5 via " IP6_6); + return 0; +fail: + return -1; +} + +static int setup_ns2(void) +{ + if (write_sysctl("/proc/sys/net/ipv4/ip_forward", "1") || + write_sysctl("/proc/sys/net/ipv6/conf/all/forwarding", "1")) + goto fail; + + if (use_vrf && setup_vrf()) + goto fail; + + if (setup_device("veth2", IP4_2, IP6_2) || + setup_device("veth3", IP4_3, IP6_3) || + setup_device("veth6", IP4_6, IP6_6) || + setup_device("veth7", IP4_7, IP6_7)) + goto fail; + + /* Top route */ + ADD_ADDR_ROUTE(IP4_1, "dev veth2"); + ADD_ADDR_ROUTE(IP4_4, "dev veth3"); + ADD_ADDR_ROUTE(IP6_1, "dev veth2"); + ADD_ADDR_ROUTE(IP6_4, "dev veth3"); + + /* Bottom route */ + ADD_ADDR_ROUTE(IP4_5, "dev veth6"); + ADD_ADDR_ROUTE(IP4_8, "dev veth7"); + ADD_ADDR_ROUTE(IP6_5, "dev veth6"); + ADD_ADDR_ROUTE(IP6_8, "dev veth7"); + + /* GRE peer via the bottom route */ + ADD_ADDR_ROUTE(IP4_GRE, "dev veth7 via " IP4_8); + ADD_ADDR_ROUTE(IP6_GRE, "dev veth7 via " IP6_8); + return 0; +fail: + return -1; +} + +static int setup_ns3(void) +{ + if (use_vrf && setup_vrf()) + goto fail; + + if (setup_device("veth4", IP4_4, IP6_4) || + setup_device("veth8", IP4_8, IP6_8)) + goto fail; + + /* Top route */ + ADD_ADDR_ROUTE(IP4_3, "dev veth4"); + ADD_ADDR_ROUTE(IP4_1, "dev veth4 via " IP4_3); + ADD_ADDR_ROUTE(IP4_2, "dev veth4 via " IP4_3); + ADD_ADDR_ROUTE(IP6_3, "dev veth4"); + ADD_ADDR_ROUTE(IP6_1, "dev veth4 via " IP6_3); + ADD_ADDR_ROUTE(IP6_2, "dev veth4 via " IP6_3); + + /* Bottom route */ + ADD_ADDR_ROUTE(IP4_7, "dev veth8"); + ADD_ADDR_ROUTE(IP4_5, "dev veth8 via " IP4_7); + ADD_ADDR_ROUTE(IP4_6, "dev veth8 via " IP4_7); + ADD_ADDR_ROUTE(IP6_7, "dev veth8"); + ADD_ADDR_ROUTE(IP6_5, "dev veth8 via " IP6_7); + ADD_ADDR_ROUTE(IP6_6, "dev veth8 via " IP6_7); + + /* configure IPv4 GRE device in NS3, and a route to it via the + * "bottom" route + */ + SYS("ip tunnel add gre_dev mode gre remote " IP4_5 " local " IP4_GRE + " ttl 255 key 0"); + if (setup_device("gre_dev", IP4_GRE, NULL)) + goto fail; + + SYS("ip tunnel add gre6_dev mode ip6gre remote " IP6_5 " local " IP6_GRE + " ttl 255 key 0"); + if (setup_device("gre6_dev", NULL, IP6_GRE)) + goto fail; + + return 0; +fail: + return -1; +} + +static int setup_links_and_routes(void) +{ + ADD_VETH_PAIR("veth1", NS_1, "veth2", NS_2); + ADD_VETH_PAIR("veth3", NS_2, "veth4", NS_3); + ADD_VETH_PAIR("veth5", NS_1, "veth6", NS_2); + ADD_VETH_PAIR("veth7", NS_2, "veth8", NS_3); + + if (setup_ns(NS_1, setup_ns1) || + setup_ns(NS_2, setup_ns2) || + setup_ns(NS_3, setup_ns3)) + goto fail; + + return 0; +fail: + return -1; +} + +static int remove_routes_to_gredev(void) +{ + SET_NS_ADDR_ROUTE("del", NS_1, IP4_GRE, "dev veth5"); + SET_NS_ADDR_ROUTE("del", NS_1, IP6_GRE, "dev veth5"); + SET_NS_ADDR_ROUTE("del", NS_2, IP4_GRE, "dev veth7"); + SET_NS_ADDR_ROUTE("del", NS_2, IP6_GRE, "dev veth7"); +fail: + return -1; +} + +static int add_unreachable_routes_to_gredev(void) +{ + SET_NS_ROUTE("add", NS_1, AF_INET, "unreachable " IP4_GRE "/32"); + SET_NS_ROUTE("add", NS_1, AF_INET6, "unreachable " IP6_GRE "/128"); + SET_NS_ROUTE("add", NS_2, AF_INET, "unreachable " IP4_GRE "/32"); + SET_NS_ROUTE("add", NS_2, AF_INET6, "unreachable " IP6_GRE "/128"); + return 0; +fail: + return -1; +} + +static int test_ping(int family, bool must_fail, bool bindtodev) +{ + const char *addr, *ping_args; + char cmd[1024]; + int ret; + + addr = family == AF_INET ? IP4_DST : IP6_DST; + ping_args = bindtodev ? "-c 1 -W 1 -I veth1" : "-c 1 -W 1"; + snprintf(cmd, sizeof(cmd), + "ip netns exec " NS_1 " %s %s %s > /dev/null", + ping_command(family), ping_args, addr); + ret = system(cmd); + if (!ASSERT_EQ(!!ret, !!must_fail, cmd)) + return -1; + return 0; +} + +#define TIMEOUT_MILLIS 10000 + +static int test_gso(int family, const char *dst) +{ + int listen_fd = -1, accept_fd = -1, client_fd = -1; + struct nstoken *nstoken; + static char buf[9000]; + int n, ret = -1; + + nstoken = open_netns(NS_3); + if (!ASSERT_OK_PTR(nstoken, "setns")) + return -1; + + listen_fd = start_server(family, SOCK_STREAM, dst, 9000, 0); + if (!ASSERT_GE(listen_fd, 0, "listen")) + goto done; + + close_netns(nstoken); + nstoken = open_netns(NS_1); + if (!ASSERT_OK_PTR(nstoken, "setns src")) + goto done; + + client_fd = connect_to_fd(listen_fd, TIMEOUT_MILLIS); + if (!ASSERT_GE(client_fd, 0, "connect_to_fd")) + goto done; + + accept_fd = accept(listen_fd, NULL, NULL); + if (!ASSERT_GE(accept_fd, 0, "accept")) + goto done; + + if (!ASSERT_OK(settimeo(accept_fd, TIMEOUT_MILLIS), "settimeo")) + goto done; + + n = write(client_fd, buf, sizeof(buf)); + if (!ASSERT_EQ(n, sizeof(buf), "send to server")) + goto done; + + n = read(accept_fd, buf, sizeof(buf)); + ASSERT_EQ(n, sizeof(buf), "recv from server"); + + ret = 0; + +done: + if (nstoken) + close_netns(nstoken); + if (listen_fd >= 0) + close(listen_fd); + if (accept_fd >= 0) + close(accept_fd); + if (client_fd >= 0) + close(client_fd); + return ret; +} + +static void lwt_ip_encap_test(int encap_family, enum encap_type encap_type) +{ + const char *prog_sec, *encap_dev, *lwt_type, *encap_ns; + bool bindtodev = true; + + if (!ASSERT_OK(setup_namespaces("add"), "setup namespaces")) + return; + if (!ASSERT_OK(setup_links_and_routes(), + "setup links and routes")) + goto fail; + + sleep(2); /* reduce flakiness */ + + /* by default, pings work */ + test_ping(AF_INET, false, bindtodev); + test_ping(AF_INET6, false, bindtodev); + + /* remove NS2->DST routes, ping fails */ + SET_NS_ADDR_ROUTE("del", NS_2, IP4_DST, "dev veth3"); + SET_NS_ADDR_ROUTE("del", NS_2, IP6_DST, "dev veth3"); + + test_ping(AF_INET, true, bindtodev); + test_ping(AF_INET6, true, bindtodev); + + prog_sec = encap_family == AF_INET ? "encap_gre" : "encap_gre6"; + + switch (encap_type) { + case ENCAP_EGRESS: + encap_dev = "veth1"; + lwt_type = "xmit"; + encap_ns = NS_1; + break; + case ENCAP_INGRESS: + encap_dev = "veth2"; + lwt_type = "in"; + encap_ns = NS_2; + break; + case ENCAP_EGRESS_MD: + switch (encap_family) { + case AF_INET: + prog_sec = "encap_gre_md"; + encap_dev = "gre_md"; + break; + case AF_INET6: + prog_sec = "encap_gre6_md"; + encap_dev = "gre6_md"; + break; + default: + goto fail; + } + lwt_type = "xmit"; + encap_ns = NS_1; + break; + default: + goto fail; + } + + /* install replacement routes (LWT/eBPF), pings succeed */ + SET_NS_ADDR_ROUTE("add", encap_ns, IP4_DST, + "encap bpf %s obj test_lwt_ip_encap.o sec %s dev %s", + lwt_type, prog_sec, encap_dev); + SET_NS_ADDR_ROUTE("add", encap_ns, IP6_DST, + "encap bpf %s obj test_lwt_ip_encap.o sec %s dev %s", + lwt_type, prog_sec, encap_dev); + + /* binding to device doesn't work for egress_md tests as routing is + * asymmetrical + */ + bindtodev = encap_type != ENCAP_EGRESS_MD; + test_ping(AF_INET, false, bindtodev); + test_ping(AF_INET6, false, bindtodev); + + /* VRF is complex for testing GSO in this setup */ + if (!use_vrf && encap_type != ENCAP_INGRESS) { + test_gso(AF_INET, IP4_DST); + test_gso(AF_INET6, IP6_DST); + } + + /* a negative test: remove routes to GRE devices: ping fails */ + if (remove_routes_to_gredev()) + goto fail; + + test_ping(AF_INET, true, bindtodev); + test_ping(AF_INET6, true, bindtodev); + + if (add_unreachable_routes_to_gredev()) + goto fail; + + test_ping(AF_INET, true, bindtodev); + test_ping(AF_INET6, true, bindtodev); +fail: + setup_namespaces("delete"); +} + +#define RUN_TEST(name, family, encap_type, _use_vrf) \ + ({ \ + if (test__start_subtest(name)) { \ + use_vrf = _use_vrf; \ + lwt_ip_encap_test(family, encap_type); \ + } \ + }) + +static void *lwt_ip_encap_run_tests(void *arg) +{ + setup_namespaces_nofail("delete"); + + RUN_TEST("lwt_ipv4_encap_egress", AF_INET, ENCAP_EGRESS, false); + RUN_TEST("lwt_ipv6_encap_egress", AF_INET6, ENCAP_EGRESS, false); + RUN_TEST("lwt_ipv4_encap_egress_vrf", AF_INET, ENCAP_EGRESS, true); + RUN_TEST("lwt_ipv6_encap_egress_vrf", AF_INET6, ENCAP_EGRESS, true); + + RUN_TEST("lwt_ipv4_encap_ingress", AF_INET, ENCAP_INGRESS, false); + RUN_TEST("lwt_ipv6_encap_ingress", AF_INET6, ENCAP_INGRESS, false); + RUN_TEST("lwt_ipv4_encap_ingress_vrf", AF_INET, ENCAP_INGRESS, true); + RUN_TEST("lwt_ipv6_encap_ingress_vrf", AF_INET6, ENCAP_INGRESS, true); + + /* bpf_set_tunnel_key() doesn't support setting underlying VRF routing + * so egress_md tests don't run in VRF setup. + */ + RUN_TEST("lwt_ipv4_encap_egress_md", AF_INET, ENCAP_EGRESS_MD, false); + RUN_TEST("lwt_ipv6_encap_egress_md", AF_INET6, ENCAP_EGRESS_MD, false); + return NULL; +} + +void serial_test_lwt_ip_encap(void) +{ + pthread_t test_thread; + int err; + + /* Run the tests in their own thread to isolate the namespace changes + * so they do not affect the environment of other tests. + * (specifically needed because of unshare(CLONE_NEWNS) in open_netns()) + */ + err = pthread_create(&test_thread, NULL, &lwt_ip_encap_run_tests, NULL); + if (ASSERT_OK(err, "pthread_create")) + ASSERT_OK(pthread_join(test_thread, NULL), "pthread_join"); +} diff --git a/tools/testing/selftests/bpf/progs/test_lwt_ip_encap.c b/tools/testing/selftests/bpf/progs/test_lwt_ip_encap.c index d6cb986e7533..39c6bd5402ae 100644 --- a/tools/testing/selftests/bpf/progs/test_lwt_ip_encap.c +++ b/tools/testing/selftests/bpf/progs/test_lwt_ip_encap.c @@ -10,8 +10,11 @@ struct grehdr { __be16 flags; __be16 protocol; + __be32 key; }; +#define GRE_KEY 0x2000 + SEC("encap_gre") int bpf_lwt_encap_gre(struct __sk_buff *skb) { @@ -28,10 +31,10 @@ int bpf_lwt_encap_gre(struct __sk_buff *skb) hdr.iph.ttl = 0x40; hdr.iph.protocol = 47; /* IPPROTO_GRE */ #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - hdr.iph.saddr = 0x640110ac; /* 172.16.1.100 */ + hdr.iph.saddr = 0x640510ac; /* 172.16.5.100 */ hdr.iph.daddr = 0x641010ac; /* 172.16.16.100 */ #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ - hdr.iph.saddr = 0xac100164; /* 172.16.1.100 */ + hdr.iph.saddr = 0xac100564; /* 172.16.5.100 */ hdr.iph.daddr = 0xac101064; /* 172.16.16.100 */ #else #error "Fix your compiler's __BYTE_ORDER__?!" @@ -39,6 +42,7 @@ int bpf_lwt_encap_gre(struct __sk_buff *skb) hdr.iph.tot_len = bpf_htons(skb->len + sizeof(struct encap_hdr)); hdr.greh.protocol = skb->protocol; + hdr.greh.flags = bpf_htons(GRE_KEY); err = bpf_lwt_push_encap(skb, BPF_LWT_ENCAP_IP, &hdr, sizeof(struct encap_hdr)); @@ -63,9 +67,9 @@ int bpf_lwt_encap_gre6(struct __sk_buff *skb) hdr.ip6hdr.payload_len = bpf_htons(skb->len + sizeof(struct grehdr)); hdr.ip6hdr.nexthdr = 47; /* IPPROTO_GRE */ hdr.ip6hdr.hop_limit = 0x40; - /* fb01::1 */ + /* fb05::1 */ hdr.ip6hdr.saddr.s6_addr[0] = 0xfb; - hdr.ip6hdr.saddr.s6_addr[1] = 1; + hdr.ip6hdr.saddr.s6_addr[1] = 5; hdr.ip6hdr.saddr.s6_addr[15] = 1; /* fb10::1 */ hdr.ip6hdr.daddr.s6_addr[0] = 0xfb; @@ -73,6 +77,7 @@ int bpf_lwt_encap_gre6(struct __sk_buff *skb) hdr.ip6hdr.daddr.s6_addr[15] = 1; hdr.greh.protocol = skb->protocol; + hdr.greh.flags = bpf_htons(GRE_KEY); err = bpf_lwt_push_encap(skb, BPF_LWT_ENCAP_IP, &hdr, sizeof(struct encap_hdr)); @@ -82,4 +87,42 @@ int bpf_lwt_encap_gre6(struct __sk_buff *skb) return BPF_LWT_REROUTE; } +SEC("encap_gre_md") +int bpf_lwt_encap_gre_md(struct __sk_buff *skb) +{ + struct bpf_tunnel_key key; + int err; + + __builtin_memset(&key, 0x0, sizeof(key)); + key.remote_ipv4 = 0xac101064; /* 172.16.16.100 - always in host order */ + key.tunnel_ttl = 0x40; + err = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), + BPF_F_ZERO_CSUM_TX | BPF_F_SEQ_NUMBER); + if (err) + return BPF_DROP; + + return BPF_OK; +} + +SEC("encap_gre6_md") +int bpf_lwt_encap_gre6_md(struct __sk_buff *skb) +{ + struct bpf_tunnel_key key; + int err; + + __builtin_memset(&key, 0x0, sizeof(key)); + + /* fb10::1 */ + key.remote_ipv6[0] = bpf_htonl(0xfb100000); + key.remote_ipv6[3] = bpf_htonl(0x01); + key.tunnel_ttl = 0x40; + err = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), + BPF_F_ZERO_CSUM_TX | BPF_F_SEQ_NUMBER | + BPF_F_TUNINFO_IPV6); + if (err) + return BPF_DROP; + + return BPF_OK; +} + char _license[] SEC("license") = "GPL"; diff --git a/tools/testing/selftests/bpf/test_lwt_ip_encap.sh b/tools/testing/selftests/bpf/test_lwt_ip_encap.sh index 6c69c42b1d60..a79f7840ceb1 100755 --- a/tools/testing/selftests/bpf/test_lwt_ip_encap.sh +++ b/tools/testing/selftests/bpf/test_lwt_ip_encap.sh @@ -238,7 +238,8 @@ setup() ip -netns ${NS3} -6 route add ${IPv6_6}/128 dev veth8 via ${IPv6_7} # configure IPv4 GRE device in NS3, and a route to it via the "bottom" route - ip -netns ${NS3} tunnel add gre_dev mode gre remote ${IPv4_1} local ${IPv4_GRE} ttl 255 + ip -netns ${NS3} tunnel add gre_dev mode gre remote ${IPv4_5} \ + local ${IPv4_GRE} ttl 255 key 0 ip -netns ${NS3} link set gre_dev up ip -netns ${NS3} addr add ${IPv4_GRE} dev gre_dev ip -netns ${NS1} route add ${IPv4_GRE}/32 dev veth5 via ${IPv4_6} ${VRF} @@ -246,7 +247,8 @@ setup() # configure IPv6 GRE device in NS3, and a route to it via the "bottom" route - ip -netns ${NS3} -6 tunnel add name gre6_dev mode ip6gre remote ${IPv6_1} local ${IPv6_GRE} ttl 255 + ip -netns ${NS3} -6 tunnel add name gre6_dev mode ip6gre remote ${IPv6_5} \ + local ${IPv6_GRE} ttl 255 key 0 ip -netns ${NS3} link set gre6_dev up ip -netns ${NS3} -6 addr add ${IPv6_GRE} nodad dev gre6_dev ip -netns ${NS1} -6 route add ${IPv6_GRE}/128 dev veth5 via ${IPv6_6} ${VRF}
Port test_lwt_ip_encap.sh tests onto test_progs. In addition, this commit adds "egress_md" tests which test a similar flow as egress tests only they use gre devices in collect_md mode for encapsulation and set the tunnel key using bpf_set_tunnel_key(). This introduces minor changes to test_lwt_ip_encap.{sh,c} for consistency with the new tests: - GRE key must exist as bpf_set_tunnel_key() explicitly sets the TUNNEL_KEY flag - Source address for GRE traffic is set to IP*_5 instead of IP*_1 since GRE traffic is sent via veth5 so its address is selected when using bpf_set_tunnel_key() Note: currently these programs use the legacy section name convention as iproute2 lwt configuration does not support providing function names. Signed-off-by: Eyal Birger <eyal.birger@gmail.com> --- .../selftests/bpf/prog_tests/lwt_ip_encap.c | 582 ++++++++++++++++++ .../selftests/bpf/progs/test_lwt_ip_encap.c | 51 +- .../selftests/bpf/test_lwt_ip_encap.sh | 6 +- 3 files changed, 633 insertions(+), 6 deletions(-) create mode 100644 tools/testing/selftests/bpf/prog_tests/lwt_ip_encap.c