On 04/20, Gilad Sever wrote: > Verify that socket lookup via TC with all BPF APIs is VRF aware. > > Signed-off-by: Gilad Sever <gilad9366@xxxxxxxxx> > --- > v2: Fix build by initializing vars with -1 > --- > .../bpf/prog_tests/tc_socket_lookup.c | 341 ++++++++++++++++++ > .../selftests/bpf/progs/tc_socket_lookup.c | 73 ++++ > 2 files changed, 414 insertions(+) > create mode 100644 tools/testing/selftests/bpf/prog_tests/tc_socket_lookup.c > create mode 100644 tools/testing/selftests/bpf/progs/tc_socket_lookup.c > > diff --git a/tools/testing/selftests/bpf/prog_tests/tc_socket_lookup.c b/tools/testing/selftests/bpf/prog_tests/tc_socket_lookup.c > new file mode 100644 > index 000000000000..5dcaf0ea3f8c > --- /dev/null > +++ b/tools/testing/selftests/bpf/prog_tests/tc_socket_lookup.c > @@ -0,0 +1,341 @@ > +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause > + > +/* > + * Topology: > + * --------- > + * NS1 namespace | NS2 namespace > + * | > + * +--------------+ | +--------------+ > + * | veth01 |----------| veth10 | > + * | 172.16.1.100 | | | 172.16.1.200 | > + * | bpf | | +--------------+ > + * +--------------+ | > + * server(UDP/TCP) | > + * +-------------------+ | > + * | vrf1 | | > + * | +--------------+ | | +--------------+ > + * | | veth02 |----------| veth20 | > + * | | 172.16.2.100 | | | | 172.16.2.200 | > + * | | bpf | | | +--------------+ > + * | +--------------+ | | > + * | server(UDP/TCP) | | > + * +-------------------+ | > + * > + * Test flow > + * ----------- > + * The tests verifies that socket lookup via TC is VRF aware: > + * 1) Creates two veth pairs between NS1 and NS2: > + * a) veth01 <-> veth10 outside the VRF > + * b) veth02 <-> veth20 in the VRF > + * 2) Attaches to veth01 and veth02 a program that calls: > + * a) bpf_skc_lookup_tcp() with TCP and tcp_skc is true > + * b) bpf_sk_lookup_tcp() with TCP and tcp_skc is false > + * c) bpf_sk_lookup_udp() with UDP > + * The program stores the lookup result in bss->lookup_status. > + * 3) Creates a socket TCP/UDP server in/outside the VRF. > + * 4) The test expects lookup_status to be: > + * a) 0 from device in VRF to server outside VRF > + * b) 0 from device outside VRF to server in VRF > + * c) 1 from device in VRF to server in VRF > + * d) 1 from device outside VRF to server outside VRF > + */ > + > +#include <net/if.h> > + > +#include "test_progs.h" > +#include "network_helpers.h" > +#include "tc_socket_lookup.skel.h" > + > +#define NS1 "tc_socket_lookup_1" > +#define NS2 "tc_socket_lookup_2" > + > +#define IP4_ADDR_VETH01 "172.16.1.100" > +#define IP4_ADDR_VETH10 "172.16.1.200" > +#define IP4_ADDR_VETH02 "172.16.2.100" > +#define IP4_ADDR_VETH20 "172.16.2.200" > + > +#define NON_VRF_PORT 5000 > +#define IN_VRF_PORT 5001 > + > +#define IO_TIMEOUT_SEC 3 > + > +#define SYS(fmt, ...) \ > + ({ \ > + char cmd[1024]; \ > + snprintf(cmd, sizeof(cmd), fmt, ##__VA_ARGS__); \ > + if (!ASSERT_OK(system(cmd), cmd)) \ > + goto fail; \ > + }) > + > +#define SYS_NOFAIL(fmt, ...) \ > + ({ \ > + char cmd[1024]; \ > + snprintf(cmd, sizeof(cmd), fmt, ##__VA_ARGS__); \ > + system(cmd); \ > + }) [..] > +static int make_socket(int sotype, const char *ip, int port, > + struct sockaddr_storage *addr) > +{ > + struct timeval timeo = { .tv_sec = IO_TIMEOUT_SEC }; > + int err, fd; > + > + err = make_sockaddr(AF_INET, ip, port, addr, NULL); > + if (!ASSERT_OK(err, "make_address")) > + return -1; > + > + fd = socket(AF_INET, sotype, 0); > + if (!ASSERT_OK(fd < 0, "socket")) > + return -1; > + > + err = setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeo, sizeof(timeo)); > + if (!ASSERT_OK(err, "setsockopt(SO_SNDTIMEO)")) > + goto fail; > + > + err = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeo, sizeof(timeo)); > + if (!ASSERT_OK(err, "setsockopt(SO_RCVTIMEO)")) > + goto fail; > + > + return fd; > +fail: > + close(fd); > + return -1; > +} > + > +static int make_server(int sotype, const char *ip, int port, const char *ifname) > +{ > + struct sockaddr_storage addr = {}; > + const int one = 1; > + int err, fd = -1; > + > + fd = make_socket(sotype, ip, port, &addr); > + if (fd < 0) > + return -1; > + > + if (sotype == SOCK_STREAM) { > + err = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, > + sizeof(one)); > + if (!ASSERT_OK(err, "setsockopt(SO_REUSEADDR)")) > + goto fail; > + } > + > + if (ifname) { > + err = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, > + ifname, strlen(ifname) + 1); > + if (!ASSERT_OK(err, "setsockopt(SO_BINDTODEVICE)")) > + goto fail; > + } > + > + err = bind(fd, (void *)&addr, sizeof(struct sockaddr_in)); > + if (!ASSERT_OK(err, "bind")) > + goto fail; > + > + if (sotype == SOCK_STREAM) { > + err = listen(fd, SOMAXCONN); > + if (!ASSERT_OK(err, "listen")) > + goto fail; > + } > + > + return fd; > +fail: > + close(fd); > + return -1; > +} Any reason you're not using start_server from network_helpers.h?