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

selftests/bpf: Add BPF_FIB_LOOKUP_MARK tests

This patch extends the fib_lookup test suite by adding a few test
cases for each IP family to test the new BPF_FIB_LOOKUP_MARK flag
to the bpf_fib_lookup:

* Test destination IP address selection with and without a mark
and/or the BPF_FIB_LOOKUP_MARK flag set

Signed-off-by: Anton Protopopov <aspsk@isovalent.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Link: https://lore.kernel.org/bpf/20240326101742.17421-3-aspsk@isovalent.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Anton Protopopov and committed by
Alexei Starovoitov
6efec2cb 5311591f

+103 -29
+103 -29
tools/testing/selftests/bpf/prog_tests/fib_lookup.c
··· 26 26 #define IPV6_TBID_ADDR "fd00::FFFF" 27 27 #define IPV6_TBID_NET "fd00::" 28 28 #define IPV6_TBID_DST "fd00::2" 29 + #define MARK_NO_POLICY 33 30 + #define MARK 42 31 + #define MARK_TABLE "200" 32 + #define IPV4_REMOTE_DST "1.2.3.4" 33 + #define IPV4_LOCAL "10.4.0.3" 34 + #define IPV4_GW1 "10.4.0.1" 35 + #define IPV4_GW2 "10.4.0.2" 36 + #define IPV6_REMOTE_DST "be:ef::b0:10" 37 + #define IPV6_LOCAL "fd01::3" 38 + #define IPV6_GW1 "fd01::1" 39 + #define IPV6_GW2 "fd01::2" 29 40 #define DMAC "11:11:11:11:11:11" 30 41 #define DMAC_INIT { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, } 31 42 #define DMAC2 "01:01:01:01:01:01" ··· 47 36 const char *daddr; 48 37 int expected_ret; 49 38 const char *expected_src; 39 + const char *expected_dst; 50 40 int lookup_flags; 51 41 __u32 tbid; 52 42 __u8 dmac[6]; 43 + __u32 mark; 53 44 }; 54 45 55 46 static const struct fib_lookup_test tests[] = { ··· 103 90 .daddr = IPV6_ADDR_DST, .expected_ret = BPF_FIB_LKUP_RET_SUCCESS, 104 91 .expected_src = IPV6_IFACE_ADDR_SEC, 105 92 .lookup_flags = BPF_FIB_LOOKUP_SRC | BPF_FIB_LOOKUP_SKIP_NEIGH, }, 93 + /* policy routing */ 94 + { .desc = "IPv4 policy routing, default", 95 + .daddr = IPV4_REMOTE_DST, .expected_ret = BPF_FIB_LKUP_RET_SUCCESS, 96 + .expected_dst = IPV4_GW1, 97 + .lookup_flags = BPF_FIB_LOOKUP_MARK | BPF_FIB_LOOKUP_SKIP_NEIGH, }, 98 + { .desc = "IPv4 policy routing, mark doesn't point to a policy", 99 + .daddr = IPV4_REMOTE_DST, .expected_ret = BPF_FIB_LKUP_RET_SUCCESS, 100 + .expected_dst = IPV4_GW1, 101 + .lookup_flags = BPF_FIB_LOOKUP_MARK | BPF_FIB_LOOKUP_SKIP_NEIGH, 102 + .mark = MARK_NO_POLICY, }, 103 + { .desc = "IPv4 policy routing, mark points to a policy", 104 + .daddr = IPV4_REMOTE_DST, .expected_ret = BPF_FIB_LKUP_RET_SUCCESS, 105 + .expected_dst = IPV4_GW2, 106 + .lookup_flags = BPF_FIB_LOOKUP_MARK | BPF_FIB_LOOKUP_SKIP_NEIGH, 107 + .mark = MARK, }, 108 + { .desc = "IPv4 policy routing, mark points to a policy, but no flag", 109 + .daddr = IPV4_REMOTE_DST, .expected_ret = BPF_FIB_LKUP_RET_SUCCESS, 110 + .expected_dst = IPV4_GW1, 111 + .lookup_flags = BPF_FIB_LOOKUP_SKIP_NEIGH, 112 + .mark = MARK, }, 113 + { .desc = "IPv6 policy routing, default", 114 + .daddr = IPV6_REMOTE_DST, .expected_ret = BPF_FIB_LKUP_RET_SUCCESS, 115 + .expected_dst = IPV6_GW1, 116 + .lookup_flags = BPF_FIB_LOOKUP_MARK | BPF_FIB_LOOKUP_SKIP_NEIGH, }, 117 + { .desc = "IPv6 policy routing, mark doesn't point to a policy", 118 + .daddr = IPV6_REMOTE_DST, .expected_ret = BPF_FIB_LKUP_RET_SUCCESS, 119 + .expected_dst = IPV6_GW1, 120 + .lookup_flags = BPF_FIB_LOOKUP_MARK | BPF_FIB_LOOKUP_SKIP_NEIGH, 121 + .mark = MARK_NO_POLICY, }, 122 + { .desc = "IPv6 policy routing, mark points to a policy", 123 + .daddr = IPV6_REMOTE_DST, .expected_ret = BPF_FIB_LKUP_RET_SUCCESS, 124 + .expected_dst = IPV6_GW2, 125 + .lookup_flags = BPF_FIB_LOOKUP_MARK | BPF_FIB_LOOKUP_SKIP_NEIGH, 126 + .mark = MARK, }, 127 + { .desc = "IPv6 policy routing, mark points to a policy, but no flag", 128 + .daddr = IPV6_REMOTE_DST, .expected_ret = BPF_FIB_LKUP_RET_SUCCESS, 129 + .expected_dst = IPV6_GW1, 130 + .lookup_flags = BPF_FIB_LOOKUP_SKIP_NEIGH, 131 + .mark = MARK, }, 106 132 }; 107 - 108 - static int ifindex; 109 133 110 134 static int setup_netns(void) 111 135 { ··· 194 144 if (!ASSERT_OK(err, "write_sysctl(net.ipv6.conf.veth1.forwarding)")) 195 145 goto fail; 196 146 147 + /* Setup for policy routing tests */ 148 + SYS(fail, "ip addr add %s/24 dev veth1", IPV4_LOCAL); 149 + SYS(fail, "ip addr add %s/64 dev veth1 nodad", IPV6_LOCAL); 150 + SYS(fail, "ip route add %s/32 via %s", IPV4_REMOTE_DST, IPV4_GW1); 151 + SYS(fail, "ip route add %s/32 via %s table %s", IPV4_REMOTE_DST, IPV4_GW2, MARK_TABLE); 152 + SYS(fail, "ip -6 route add %s/128 via %s", IPV6_REMOTE_DST, IPV6_GW1); 153 + SYS(fail, "ip -6 route add %s/128 via %s table %s", IPV6_REMOTE_DST, IPV6_GW2, MARK_TABLE); 154 + SYS(fail, "ip rule add prio 2 fwmark %d lookup %s", MARK, MARK_TABLE); 155 + SYS(fail, "ip -6 rule add prio 2 fwmark %d lookup %s", MARK, MARK_TABLE); 156 + 197 157 return 0; 198 158 fail: 199 159 return -1; 200 160 } 201 161 202 - static int set_lookup_params(struct bpf_fib_lookup *params, const struct fib_lookup_test *test) 162 + static int set_lookup_params(struct bpf_fib_lookup *params, 163 + const struct fib_lookup_test *test, 164 + int ifindex) 203 165 { 204 166 int ret; 205 167 ··· 220 158 params->l4_protocol = IPPROTO_TCP; 221 159 params->ifindex = ifindex; 222 160 params->tbid = test->tbid; 161 + params->mark = test->mark; 223 162 224 163 if (inet_pton(AF_INET6, test->daddr, params->ipv6_dst) == 1) { 225 164 params->family = AF_INET6; ··· 253 190 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); 254 191 } 255 192 256 - static void assert_src_ip(struct bpf_fib_lookup *fib_params, const char *expected_src) 193 + static void assert_ip_address(int family, void *addr, const char *expected_str) 257 194 { 195 + char str[INET6_ADDRSTRLEN]; 196 + u8 expected_addr[16]; 197 + int addr_len = 0; 258 198 int ret; 259 - __u32 src6[4]; 260 - __be32 src4; 261 199 262 - switch (fib_params->family) { 200 + switch (family) { 263 201 case AF_INET6: 264 - ret = inet_pton(AF_INET6, expected_src, src6); 265 - ASSERT_EQ(ret, 1, "inet_pton(expected_src)"); 266 - 267 - ret = memcmp(src6, fib_params->ipv6_src, sizeof(fib_params->ipv6_src)); 268 - if (!ASSERT_EQ(ret, 0, "fib_lookup ipv6 src")) { 269 - char str_src6[64]; 270 - 271 - inet_ntop(AF_INET6, fib_params->ipv6_src, str_src6, 272 - sizeof(str_src6)); 273 - printf("ipv6 expected %s actual %s ", expected_src, 274 - str_src6); 275 - } 276 - 202 + ret = inet_pton(AF_INET6, expected_str, expected_addr); 203 + ASSERT_EQ(ret, 1, "inet_pton(AF_INET6, expected_str)"); 204 + addr_len = 16; 277 205 break; 278 206 case AF_INET: 279 - ret = inet_pton(AF_INET, expected_src, &src4); 280 - ASSERT_EQ(ret, 1, "inet_pton(expected_src)"); 281 - 282 - ASSERT_EQ(fib_params->ipv4_src, src4, "fib_lookup ipv4 src"); 283 - 207 + ret = inet_pton(AF_INET, expected_str, expected_addr); 208 + ASSERT_EQ(ret, 1, "inet_pton(AF_INET, expected_str)"); 209 + addr_len = 4; 284 210 break; 285 211 default: 286 - PRINT_FAIL("invalid addr family: %d", fib_params->family); 212 + PRINT_FAIL("invalid address family: %d", family); 213 + break; 287 214 } 215 + 216 + if (memcmp(addr, expected_addr, addr_len)) { 217 + inet_ntop(family, addr, str, sizeof(str)); 218 + PRINT_FAIL("expected %s actual %s ", expected_str, str); 219 + } 220 + } 221 + 222 + static void assert_src_ip(struct bpf_fib_lookup *params, const char *expected) 223 + { 224 + assert_ip_address(params->family, params->ipv6_src, expected); 225 + } 226 + 227 + static void assert_dst_ip(struct bpf_fib_lookup *params, const char *expected) 228 + { 229 + assert_ip_address(params->family, params->ipv6_dst, expected); 288 230 } 289 231 290 232 void test_fib_lookup(void) ··· 324 256 if (setup_netns()) 325 257 goto fail; 326 258 327 - ifindex = if_nametoindex("veth1"); 328 - skb.ifindex = ifindex; 259 + skb.ifindex = if_nametoindex("veth1"); 260 + if (!ASSERT_NEQ(skb.ifindex, 0, "if_nametoindex(veth1)")) 261 + goto fail; 262 + 329 263 fib_params = &skel->bss->fib_params; 330 264 331 265 for (i = 0; i < ARRAY_SIZE(tests); i++) { 332 266 printf("Testing %s ", tests[i].desc); 333 267 334 - if (set_lookup_params(fib_params, &tests[i])) 268 + if (set_lookup_params(fib_params, &tests[i], skb.ifindex)) 335 269 continue; 270 + 336 271 skel->bss->fib_lookup_ret = -1; 337 272 skel->bss->lookup_flags = tests[i].lookup_flags; 338 273 ··· 348 277 349 278 if (tests[i].expected_src) 350 279 assert_src_ip(fib_params, tests[i].expected_src); 280 + 281 + if (tests[i].expected_dst) 282 + assert_dst_ip(fib_params, tests[i].expected_dst); 351 283 352 284 ret = memcmp(tests[i].dmac, fib_params->dmac, sizeof(tests[i].dmac)); 353 285 if (!ASSERT_EQ(ret, 0, "dmac not match")) {