diff mbox series

[2/2] bpf: test table ID fib lookup BPF helper

Message ID 20230505-bpf-add-tbid-fib-lookup-v1-2-fd99f7162e76@gmail.com (mailing list archive)
State Superseded
Delegated to: BPF
Headers show
Series bpf: utilize table ID in bpf_fib_lookup helper | expand

Checks

Context Check Description
netdev/tree_selection success Not a local patch, async
bpf/vmtest-bpf-next-PR success PR summary
bpf/vmtest-bpf-next-VM_Test-1 success Logs for ShellCheck
bpf/vmtest-bpf-next-VM_Test-6 success Logs for set-matrix
bpf/vmtest-bpf-next-VM_Test-2 success Logs for build for aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-4 success Logs for build for x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-5 success Logs for build for x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-3 success Logs for build for s390x with gcc
bpf/vmtest-bpf-next-VM_Test-10 success Logs for test_maps on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-19 success Logs for test_progs_no_alu32_parallel on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-20 success Logs for test_progs_no_alu32_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-21 success Logs for test_progs_no_alu32_parallel on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-24 success Logs for test_progs_parallel on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-25 success Logs for test_verifier on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-27 success Logs for test_verifier on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-28 success Logs for test_verifier on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-29 success Logs for veristat
bpf/vmtest-bpf-next-VM_Test-7 success Logs for test_maps on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-9 success Logs for test_maps on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-11 success Logs for test_progs on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-13 success Logs for test_progs on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-14 success Logs for test_progs on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-15 success Logs for test_progs_no_alu32 on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-17 success Logs for test_progs_no_alu32 on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-18 success Logs for test_progs_no_alu32 on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-22 success Logs for test_progs_parallel on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-23 success Logs for test_progs_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-26 success Logs for test_verifier on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-16 success Logs for test_progs_no_alu32 on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-12 success Logs for test_progs on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-8 success Logs for test_maps on s390x with gcc

Commit Message

Louis DeLosSantos May 25, 2023, 2:28 p.m. UTC
Add additional test cases to `fib_lookup.c` prog_test.

These test cases add a new /24 network to the previously unused veth2
device, removes the directly connected route from the main routing table
and moves it to table 100.

The first test case then confirms a fib lookup for a remote address in this
directly connected network, using the main routing table fails.

The second test case ensures the same fib lookup using table 100
succeeds.

An additional pair of tests which function in the same manner are added
for IPv6.

Signed-off-by: Louis DeLosSantos <louis.delos.devel@gmail.com>
---
 .../testing/selftests/bpf/prog_tests/fib_lookup.c  | 58 +++++++++++++++++++---
 1 file changed, 50 insertions(+), 8 deletions(-)

Comments

Yonghong Song May 26, 2023, 6:02 a.m. UTC | #1
On 5/25/23 7:28 AM, Louis DeLosSantos wrote:
> Add additional test cases to `fib_lookup.c` prog_test.

For the subject line:
   bpf: test table ID fib lookup BPF helper
to
   selftests/bpf: test table ID fib lookup BPF helper

> 
> These test cases add a new /24 network to the previously unused veth2
> device, removes the directly connected route from the main routing table
> and moves it to table 100.
> 
> The first test case then confirms a fib lookup for a remote address in this
> directly connected network, using the main routing table fails.
> 
> The second test case ensures the same fib lookup using table 100
> succeeds.
> 
> An additional pair of tests which function in the same manner are added
> for IPv6.
> 
> Signed-off-by: Louis DeLosSantos <louis.delos.devel@gmail.com>
> ---
>   .../testing/selftests/bpf/prog_tests/fib_lookup.c  | 58 +++++++++++++++++++---
>   1 file changed, 50 insertions(+), 8 deletions(-)
> 
> diff --git a/tools/testing/selftests/bpf/prog_tests/fib_lookup.c b/tools/testing/selftests/bpf/prog_tests/fib_lookup.c
> index a1e7121058118..e8d1f35780d75 100644
> --- a/tools/testing/selftests/bpf/prog_tests/fib_lookup.c
> +++ b/tools/testing/selftests/bpf/prog_tests/fib_lookup.c
> @@ -1,6 +1,8 @@
>   // SPDX-License-Identifier: GPL-2.0
>   /* Copyright (c) 2023 Meta Platforms, Inc. and affiliates. */
>   
> +#include "linux/bpf.h"
> +#include <linux/rtnetlink.h>
>   #include <sys/types.h>
>   #include <net/if.h>
>   
> @@ -15,14 +17,23 @@
>   #define IPV4_IFACE_ADDR		"10.0.0.254"
>   #define IPV4_NUD_FAILED_ADDR	"10.0.0.1"
>   #define IPV4_NUD_STALE_ADDR	"10.0.0.2"
> +#define IPV4_TBID_ADDR		"172.0.0.254"
> +#define IPV4_TBID_NET		"172.0.0.0"
> +#define IPV4_TBID_DST		"172.0.0.2"
> +#define IPV6_TBID_ADDR		"fd00::FFFF"
> +#define IPV6_TBID_NET		"fd00::"
> +#define IPV6_TBID_DST		"fd00::2"
>   #define DMAC			"11:11:11:11:11:11"
>   #define DMAC_INIT { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, }
> +#define DMAC2			"01:01:01:01:01:01"
> +#define DMAC_INIT2 { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, }
>   
>   struct fib_lookup_test {
>   	const char *desc;
>   	const char *daddr;
>   	int expected_ret;
>   	int lookup_flags;
> +	__u32 tbid;
>   	__u8 dmac[6];
>   };
>   
> @@ -43,6 +54,18 @@ static const struct fib_lookup_test tests[] = {
>   	{ .desc = "IPv4 skip neigh",
>   	  .daddr = IPV4_NUD_FAILED_ADDR, .expected_ret = BPF_FIB_LKUP_RET_SUCCESS,
>   	  .lookup_flags = BPF_FIB_LOOKUP_SKIP_NEIGH, },
> +	{ .desc = "IPv4 TBID lookup failure",
> +	  .daddr = IPV4_TBID_DST, .expected_ret = BPF_FIB_LKUP_RET_NOT_FWDED,
> +	  .lookup_flags = BPF_FIB_LOOKUP_DIRECT },
> +	{ .desc = "IPv4 TBID lookup success",
> +	  .daddr = IPV4_TBID_DST, .expected_ret = BPF_FIB_LKUP_RET_SUCCESS,
> +	  .lookup_flags = BPF_FIB_LOOKUP_DIRECT, .tbid = 100, .dmac = DMAC_INIT2, },
> +	{ .desc = "IPv6 TBID lookup failure",
> +	  .daddr = IPV6_TBID_DST, .expected_ret = BPF_FIB_LKUP_RET_NOT_FWDED,
> +	  .lookup_flags = BPF_FIB_LOOKUP_DIRECT, },
> +	{ .desc = "IPv6 TBID lookup success",
> +	  .daddr = IPV6_TBID_DST, .expected_ret = BPF_FIB_LKUP_RET_SUCCESS,
> +	  .lookup_flags = BPF_FIB_LOOKUP_DIRECT, .tbid = 100, .dmac = DMAC_INIT2, },
>   };
>   
>   static int ifindex;
> @@ -53,6 +76,7 @@ static int setup_netns(void)
>   
>   	SYS(fail, "ip link add veth1 type veth peer name veth2");
>   	SYS(fail, "ip link set dev veth1 up");
> +	SYS(fail, "ip link set dev veth2 up");
>   
>   	err = write_sysctl("/proc/sys/net/ipv4/neigh/veth1/gc_stale_time", "900");
>   	if (!ASSERT_OK(err, "write_sysctl(net.ipv4.neigh.veth1.gc_stale_time)"))
> @@ -70,6 +94,17 @@ static int setup_netns(void)
>   	SYS(fail, "ip neigh add %s dev veth1 nud failed", IPV4_NUD_FAILED_ADDR);
>   	SYS(fail, "ip neigh add %s dev veth1 lladdr %s nud stale", IPV4_NUD_STALE_ADDR, DMAC);
>   
> +	/* Setup for tbid lookup tests */
> +	SYS(fail, "ip addr add %s/24 dev veth2", IPV4_TBID_ADDR);
> +	SYS(fail, "ip route del %s/24 dev veth2", IPV4_TBID_NET);
> +	SYS(fail, "ip route add table 100 %s/24 dev veth2", IPV4_TBID_NET);
> +	SYS(fail, "ip neigh add %s dev veth2 lladdr %s nud stale", IPV4_TBID_DST, DMAC2);
> +
> +	SYS(fail, "ip addr add %s/64 dev veth2", IPV6_TBID_ADDR);
> +	SYS(fail, "ip -6 route del %s/64 dev veth2", IPV6_TBID_NET);
> +	SYS(fail, "ip -6 route add table 100 %s/64 dev veth2", IPV6_TBID_NET);
> +	SYS(fail, "ip neigh add %s dev veth2 lladdr %s nud stale", IPV6_TBID_DST, DMAC2);
> +
>   	err = write_sysctl("/proc/sys/net/ipv4/conf/veth1/forwarding", "1");
>   	if (!ASSERT_OK(err, "write_sysctl(net.ipv4.conf.veth1.forwarding)"))
>   		goto fail;
> @@ -83,7 +118,7 @@ static int setup_netns(void)
>   	return -1;
>   }
>   
> -static int set_lookup_params(struct bpf_fib_lookup *params, const char *daddr)
> +static int set_lookup_params(struct bpf_fib_lookup *params, const struct fib_lookup_test *test)
>   {
>   	int ret;
>   
> @@ -91,8 +126,9 @@ static int set_lookup_params(struct bpf_fib_lookup *params, const char *daddr)
>   
>   	params->l4_protocol = IPPROTO_TCP;
>   	params->ifindex = ifindex;
> +	params->tbid = test->tbid;
>   
> -	if (inet_pton(AF_INET6, daddr, params->ipv6_dst) == 1) {
> +	if (inet_pton(AF_INET6, test->daddr, params->ipv6_dst) == 1) {
>   		params->family = AF_INET6;
>   		ret = inet_pton(AF_INET6, IPV6_IFACE_ADDR, params->ipv6_src);
>   		if (!ASSERT_EQ(ret, 1, "inet_pton(IPV6_IFACE_ADDR)"))
> @@ -100,7 +136,7 @@ static int set_lookup_params(struct bpf_fib_lookup *params, const char *daddr)
>   		return 0;
>   	}
>   
> -	ret = inet_pton(AF_INET, daddr, &params->ipv4_dst);
> +	ret = inet_pton(AF_INET, test->daddr, &params->ipv4_dst);
>   	if (!ASSERT_EQ(ret, 1, "convert IP[46] address"))
>   		return -1;
>   	params->family = AF_INET;
> @@ -154,13 +190,12 @@ void test_fib_lookup(void)
>   	fib_params = &skel->bss->fib_params;
>   
>   	for (i = 0; i < ARRAY_SIZE(tests); i++) {
> -		printf("Testing %s\n", tests[i].desc);
> +		printf("Testing %s ", tests[i].desc);
>   
> -		if (set_lookup_params(fib_params, tests[i].daddr))
> +		if (set_lookup_params(fib_params, &tests[i]))
>   			continue;
>   		skel->bss->fib_lookup_ret = -1;
> -		skel->bss->lookup_flags = BPF_FIB_LOOKUP_OUTPUT |
> -			tests[i].lookup_flags;
> +		skel->bss->lookup_flags = tests[i].lookup_flags;
>   
>   		err = bpf_prog_test_run_opts(prog_fd, &run_opts);
>   		if (!ASSERT_OK(err, "bpf_prog_test_run_opts"))
> @@ -175,7 +210,14 @@ void test_fib_lookup(void)
>   
>   			mac_str(expected, tests[i].dmac);
>   			mac_str(actual, fib_params->dmac);
> -			printf("dmac expected %s actual %s\n", expected, actual);
> +			printf("dmac expected %s actual %s ", expected, actual);
> +		}
> +
> +		// ensure tbid is zero'd out after fib lookup.
> +		if (tests[i].lookup_flags & BPF_FIB_LOOKUP_DIRECT) {
> +			if (!ASSERT_EQ(skel->bss->fib_params.tbid, 0,
> +					"expected fib_params.tbid to be zero"))
> +				goto fail;
>   		}
>   	}
>   
>
Louis DeLosSantos May 26, 2023, 2:23 p.m. UTC | #2
On Thu, May 25, 2023 at 11:02:54PM -0700, Yonghong Song wrote:
> 
> 
> On 5/25/23 7:28 AM, Louis DeLosSantos wrote:
> > Add additional test cases to `fib_lookup.c` prog_test.
> 
> For the subject line:
>   bpf: test table ID fib lookup BPF helper
> to
>   selftests/bpf: test table ID fib lookup BPF helper

Ack, will fix this on new rev.

> 
> > 
> > These test cases add a new /24 network to the previously unused veth2
> > device, removes the directly connected route from the main routing table
> > and moves it to table 100.
> > 
> > The first test case then confirms a fib lookup for a remote address in this
> > directly connected network, using the main routing table fails.
> > 
> > The second test case ensures the same fib lookup using table 100
> > succeeds.
> > 
> > An additional pair of tests which function in the same manner are added
> > for IPv6.
> > 
> > Signed-off-by: Louis DeLosSantos <louis.delos.devel@gmail.com>
> > ---
> >   .../testing/selftests/bpf/prog_tests/fib_lookup.c  | 58 +++++++++++++++++++---
> >   1 file changed, 50 insertions(+), 8 deletions(-)
> > 
> > diff --git a/tools/testing/selftests/bpf/prog_tests/fib_lookup.c b/tools/testing/selftests/bpf/prog_tests/fib_lookup.c
> > index a1e7121058118..e8d1f35780d75 100644
> > --- a/tools/testing/selftests/bpf/prog_tests/fib_lookup.c
> > +++ b/tools/testing/selftests/bpf/prog_tests/fib_lookup.c
> > @@ -1,6 +1,8 @@
> >   // SPDX-License-Identifier: GPL-2.0
> >   /* Copyright (c) 2023 Meta Platforms, Inc. and affiliates. */
> > +#include "linux/bpf.h"
> > +#include <linux/rtnetlink.h>
> >   #include <sys/types.h>
> >   #include <net/if.h>
> > @@ -15,14 +17,23 @@
> >   #define IPV4_IFACE_ADDR		"10.0.0.254"
> >   #define IPV4_NUD_FAILED_ADDR	"10.0.0.1"
> >   #define IPV4_NUD_STALE_ADDR	"10.0.0.2"
> > +#define IPV4_TBID_ADDR		"172.0.0.254"
> > +#define IPV4_TBID_NET		"172.0.0.0"
> > +#define IPV4_TBID_DST		"172.0.0.2"
> > +#define IPV6_TBID_ADDR		"fd00::FFFF"
> > +#define IPV6_TBID_NET		"fd00::"
> > +#define IPV6_TBID_DST		"fd00::2"
> >   #define DMAC			"11:11:11:11:11:11"
> >   #define DMAC_INIT { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, }
> > +#define DMAC2			"01:01:01:01:01:01"
> > +#define DMAC_INIT2 { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, }
> >   struct fib_lookup_test {
> >   	const char *desc;
> >   	const char *daddr;
> >   	int expected_ret;
> >   	int lookup_flags;
> > +	__u32 tbid;
> >   	__u8 dmac[6];
> >   };
> > @@ -43,6 +54,18 @@ static const struct fib_lookup_test tests[] = {
> >   	{ .desc = "IPv4 skip neigh",
> >   	  .daddr = IPV4_NUD_FAILED_ADDR, .expected_ret = BPF_FIB_LKUP_RET_SUCCESS,
> >   	  .lookup_flags = BPF_FIB_LOOKUP_SKIP_NEIGH, },
> > +	{ .desc = "IPv4 TBID lookup failure",
> > +	  .daddr = IPV4_TBID_DST, .expected_ret = BPF_FIB_LKUP_RET_NOT_FWDED,
> > +	  .lookup_flags = BPF_FIB_LOOKUP_DIRECT },
> > +	{ .desc = "IPv4 TBID lookup success",
> > +	  .daddr = IPV4_TBID_DST, .expected_ret = BPF_FIB_LKUP_RET_SUCCESS,
> > +	  .lookup_flags = BPF_FIB_LOOKUP_DIRECT, .tbid = 100, .dmac = DMAC_INIT2, },
> > +	{ .desc = "IPv6 TBID lookup failure",
> > +	  .daddr = IPV6_TBID_DST, .expected_ret = BPF_FIB_LKUP_RET_NOT_FWDED,
> > +	  .lookup_flags = BPF_FIB_LOOKUP_DIRECT, },
> > +	{ .desc = "IPv6 TBID lookup success",
> > +	  .daddr = IPV6_TBID_DST, .expected_ret = BPF_FIB_LKUP_RET_SUCCESS,
> > +	  .lookup_flags = BPF_FIB_LOOKUP_DIRECT, .tbid = 100, .dmac = DMAC_INIT2, },
> >   };
> >   static int ifindex;
> > @@ -53,6 +76,7 @@ static int setup_netns(void)
> >   	SYS(fail, "ip link add veth1 type veth peer name veth2");
> >   	SYS(fail, "ip link set dev veth1 up");
> > +	SYS(fail, "ip link set dev veth2 up");
> >   	err = write_sysctl("/proc/sys/net/ipv4/neigh/veth1/gc_stale_time", "900");
> >   	if (!ASSERT_OK(err, "write_sysctl(net.ipv4.neigh.veth1.gc_stale_time)"))
> > @@ -70,6 +94,17 @@ static int setup_netns(void)
> >   	SYS(fail, "ip neigh add %s dev veth1 nud failed", IPV4_NUD_FAILED_ADDR);
> >   	SYS(fail, "ip neigh add %s dev veth1 lladdr %s nud stale", IPV4_NUD_STALE_ADDR, DMAC);
> > +	/* Setup for tbid lookup tests */
> > +	SYS(fail, "ip addr add %s/24 dev veth2", IPV4_TBID_ADDR);
> > +	SYS(fail, "ip route del %s/24 dev veth2", IPV4_TBID_NET);
> > +	SYS(fail, "ip route add table 100 %s/24 dev veth2", IPV4_TBID_NET);
> > +	SYS(fail, "ip neigh add %s dev veth2 lladdr %s nud stale", IPV4_TBID_DST, DMAC2);
> > +
> > +	SYS(fail, "ip addr add %s/64 dev veth2", IPV6_TBID_ADDR);
> > +	SYS(fail, "ip -6 route del %s/64 dev veth2", IPV6_TBID_NET);
> > +	SYS(fail, "ip -6 route add table 100 %s/64 dev veth2", IPV6_TBID_NET);
> > +	SYS(fail, "ip neigh add %s dev veth2 lladdr %s nud stale", IPV6_TBID_DST, DMAC2);
> > +
> >   	err = write_sysctl("/proc/sys/net/ipv4/conf/veth1/forwarding", "1");
> >   	if (!ASSERT_OK(err, "write_sysctl(net.ipv4.conf.veth1.forwarding)"))
> >   		goto fail;
> > @@ -83,7 +118,7 @@ static int setup_netns(void)
> >   	return -1;
> >   }
> > -static int set_lookup_params(struct bpf_fib_lookup *params, const char *daddr)
> > +static int set_lookup_params(struct bpf_fib_lookup *params, const struct fib_lookup_test *test)
> >   {
> >   	int ret;
> > @@ -91,8 +126,9 @@ static int set_lookup_params(struct bpf_fib_lookup *params, const char *daddr)
> >   	params->l4_protocol = IPPROTO_TCP;
> >   	params->ifindex = ifindex;
> > +	params->tbid = test->tbid;
> > -	if (inet_pton(AF_INET6, daddr, params->ipv6_dst) == 1) {
> > +	if (inet_pton(AF_INET6, test->daddr, params->ipv6_dst) == 1) {
> >   		params->family = AF_INET6;
> >   		ret = inet_pton(AF_INET6, IPV6_IFACE_ADDR, params->ipv6_src);
> >   		if (!ASSERT_EQ(ret, 1, "inet_pton(IPV6_IFACE_ADDR)"))
> > @@ -100,7 +136,7 @@ static int set_lookup_params(struct bpf_fib_lookup *params, const char *daddr)
> >   		return 0;
> >   	}
> > -	ret = inet_pton(AF_INET, daddr, &params->ipv4_dst);
> > +	ret = inet_pton(AF_INET, test->daddr, &params->ipv4_dst);
> >   	if (!ASSERT_EQ(ret, 1, "convert IP[46] address"))
> >   		return -1;
> >   	params->family = AF_INET;
> > @@ -154,13 +190,12 @@ void test_fib_lookup(void)
> >   	fib_params = &skel->bss->fib_params;
> >   	for (i = 0; i < ARRAY_SIZE(tests); i++) {
> > -		printf("Testing %s\n", tests[i].desc);
> > +		printf("Testing %s ", tests[i].desc);
> > -		if (set_lookup_params(fib_params, tests[i].daddr))
> > +		if (set_lookup_params(fib_params, &tests[i]))
> >   			continue;
> >   		skel->bss->fib_lookup_ret = -1;
> > -		skel->bss->lookup_flags = BPF_FIB_LOOKUP_OUTPUT |
> > -			tests[i].lookup_flags;
> > +		skel->bss->lookup_flags = tests[i].lookup_flags;
> >   		err = bpf_prog_test_run_opts(prog_fd, &run_opts);
> >   		if (!ASSERT_OK(err, "bpf_prog_test_run_opts"))
> > @@ -175,7 +210,14 @@ void test_fib_lookup(void)
> >   			mac_str(expected, tests[i].dmac);
> >   			mac_str(actual, fib_params->dmac);
> > -			printf("dmac expected %s actual %s\n", expected, actual);
> > +			printf("dmac expected %s actual %s ", expected, actual);
> > +		}
> > +
> > +		// ensure tbid is zero'd out after fib lookup.
> > +		if (tests[i].lookup_flags & BPF_FIB_LOOKUP_DIRECT) {
> > +			if (!ASSERT_EQ(skel->bss->fib_params.tbid, 0,
> > +					"expected fib_params.tbid to be zero"))
> > +				goto fail;
> >   		}
> >   	}
> >
diff mbox series

Patch

diff --git a/tools/testing/selftests/bpf/prog_tests/fib_lookup.c b/tools/testing/selftests/bpf/prog_tests/fib_lookup.c
index a1e7121058118..e8d1f35780d75 100644
--- a/tools/testing/selftests/bpf/prog_tests/fib_lookup.c
+++ b/tools/testing/selftests/bpf/prog_tests/fib_lookup.c
@@ -1,6 +1,8 @@ 
 // SPDX-License-Identifier: GPL-2.0
 /* Copyright (c) 2023 Meta Platforms, Inc. and affiliates. */
 
+#include "linux/bpf.h"
+#include <linux/rtnetlink.h>
 #include <sys/types.h>
 #include <net/if.h>
 
@@ -15,14 +17,23 @@ 
 #define IPV4_IFACE_ADDR		"10.0.0.254"
 #define IPV4_NUD_FAILED_ADDR	"10.0.0.1"
 #define IPV4_NUD_STALE_ADDR	"10.0.0.2"
+#define IPV4_TBID_ADDR		"172.0.0.254"
+#define IPV4_TBID_NET		"172.0.0.0"
+#define IPV4_TBID_DST		"172.0.0.2"
+#define IPV6_TBID_ADDR		"fd00::FFFF"
+#define IPV6_TBID_NET		"fd00::"
+#define IPV6_TBID_DST		"fd00::2"
 #define DMAC			"11:11:11:11:11:11"
 #define DMAC_INIT { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, }
+#define DMAC2			"01:01:01:01:01:01"
+#define DMAC_INIT2 { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, }
 
 struct fib_lookup_test {
 	const char *desc;
 	const char *daddr;
 	int expected_ret;
 	int lookup_flags;
+	__u32 tbid;
 	__u8 dmac[6];
 };
 
@@ -43,6 +54,18 @@  static const struct fib_lookup_test tests[] = {
 	{ .desc = "IPv4 skip neigh",
 	  .daddr = IPV4_NUD_FAILED_ADDR, .expected_ret = BPF_FIB_LKUP_RET_SUCCESS,
 	  .lookup_flags = BPF_FIB_LOOKUP_SKIP_NEIGH, },
+	{ .desc = "IPv4 TBID lookup failure",
+	  .daddr = IPV4_TBID_DST, .expected_ret = BPF_FIB_LKUP_RET_NOT_FWDED,
+	  .lookup_flags = BPF_FIB_LOOKUP_DIRECT },
+	{ .desc = "IPv4 TBID lookup success",
+	  .daddr = IPV4_TBID_DST, .expected_ret = BPF_FIB_LKUP_RET_SUCCESS,
+	  .lookup_flags = BPF_FIB_LOOKUP_DIRECT, .tbid = 100, .dmac = DMAC_INIT2, },
+	{ .desc = "IPv6 TBID lookup failure",
+	  .daddr = IPV6_TBID_DST, .expected_ret = BPF_FIB_LKUP_RET_NOT_FWDED,
+	  .lookup_flags = BPF_FIB_LOOKUP_DIRECT, },
+	{ .desc = "IPv6 TBID lookup success",
+	  .daddr = IPV6_TBID_DST, .expected_ret = BPF_FIB_LKUP_RET_SUCCESS,
+	  .lookup_flags = BPF_FIB_LOOKUP_DIRECT, .tbid = 100, .dmac = DMAC_INIT2, },
 };
 
 static int ifindex;
@@ -53,6 +76,7 @@  static int setup_netns(void)
 
 	SYS(fail, "ip link add veth1 type veth peer name veth2");
 	SYS(fail, "ip link set dev veth1 up");
+	SYS(fail, "ip link set dev veth2 up");
 
 	err = write_sysctl("/proc/sys/net/ipv4/neigh/veth1/gc_stale_time", "900");
 	if (!ASSERT_OK(err, "write_sysctl(net.ipv4.neigh.veth1.gc_stale_time)"))
@@ -70,6 +94,17 @@  static int setup_netns(void)
 	SYS(fail, "ip neigh add %s dev veth1 nud failed", IPV4_NUD_FAILED_ADDR);
 	SYS(fail, "ip neigh add %s dev veth1 lladdr %s nud stale", IPV4_NUD_STALE_ADDR, DMAC);
 
+	/* Setup for tbid lookup tests */
+	SYS(fail, "ip addr add %s/24 dev veth2", IPV4_TBID_ADDR);
+	SYS(fail, "ip route del %s/24 dev veth2", IPV4_TBID_NET);
+	SYS(fail, "ip route add table 100 %s/24 dev veth2", IPV4_TBID_NET);
+	SYS(fail, "ip neigh add %s dev veth2 lladdr %s nud stale", IPV4_TBID_DST, DMAC2);
+
+	SYS(fail, "ip addr add %s/64 dev veth2", IPV6_TBID_ADDR);
+	SYS(fail, "ip -6 route del %s/64 dev veth2", IPV6_TBID_NET);
+	SYS(fail, "ip -6 route add table 100 %s/64 dev veth2", IPV6_TBID_NET);
+	SYS(fail, "ip neigh add %s dev veth2 lladdr %s nud stale", IPV6_TBID_DST, DMAC2);
+
 	err = write_sysctl("/proc/sys/net/ipv4/conf/veth1/forwarding", "1");
 	if (!ASSERT_OK(err, "write_sysctl(net.ipv4.conf.veth1.forwarding)"))
 		goto fail;
@@ -83,7 +118,7 @@  static int setup_netns(void)
 	return -1;
 }
 
-static int set_lookup_params(struct bpf_fib_lookup *params, const char *daddr)
+static int set_lookup_params(struct bpf_fib_lookup *params, const struct fib_lookup_test *test)
 {
 	int ret;
 
@@ -91,8 +126,9 @@  static int set_lookup_params(struct bpf_fib_lookup *params, const char *daddr)
 
 	params->l4_protocol = IPPROTO_TCP;
 	params->ifindex = ifindex;
+	params->tbid = test->tbid;
 
-	if (inet_pton(AF_INET6, daddr, params->ipv6_dst) == 1) {
+	if (inet_pton(AF_INET6, test->daddr, params->ipv6_dst) == 1) {
 		params->family = AF_INET6;
 		ret = inet_pton(AF_INET6, IPV6_IFACE_ADDR, params->ipv6_src);
 		if (!ASSERT_EQ(ret, 1, "inet_pton(IPV6_IFACE_ADDR)"))
@@ -100,7 +136,7 @@  static int set_lookup_params(struct bpf_fib_lookup *params, const char *daddr)
 		return 0;
 	}
 
-	ret = inet_pton(AF_INET, daddr, &params->ipv4_dst);
+	ret = inet_pton(AF_INET, test->daddr, &params->ipv4_dst);
 	if (!ASSERT_EQ(ret, 1, "convert IP[46] address"))
 		return -1;
 	params->family = AF_INET;
@@ -154,13 +190,12 @@  void test_fib_lookup(void)
 	fib_params = &skel->bss->fib_params;
 
 	for (i = 0; i < ARRAY_SIZE(tests); i++) {
-		printf("Testing %s\n", tests[i].desc);
+		printf("Testing %s ", tests[i].desc);
 
-		if (set_lookup_params(fib_params, tests[i].daddr))
+		if (set_lookup_params(fib_params, &tests[i]))
 			continue;
 		skel->bss->fib_lookup_ret = -1;
-		skel->bss->lookup_flags = BPF_FIB_LOOKUP_OUTPUT |
-			tests[i].lookup_flags;
+		skel->bss->lookup_flags = tests[i].lookup_flags;
 
 		err = bpf_prog_test_run_opts(prog_fd, &run_opts);
 		if (!ASSERT_OK(err, "bpf_prog_test_run_opts"))
@@ -175,7 +210,14 @@  void test_fib_lookup(void)
 
 			mac_str(expected, tests[i].dmac);
 			mac_str(actual, fib_params->dmac);
-			printf("dmac expected %s actual %s\n", expected, actual);
+			printf("dmac expected %s actual %s ", expected, actual);
+		}
+
+		// ensure tbid is zero'd out after fib lookup.
+		if (tests[i].lookup_flags & BPF_FIB_LOOKUP_DIRECT) {
+			if (!ASSERT_EQ(skel->bss->fib_params.tbid, 0,
+					"expected fib_params.tbid to be zero"))
+				goto fail;
 		}
 	}