Skip to contentSkip to conversation

netfilter: Add the capability to offload flowtable in XDP layer

PATCH Superseded Lorenzo Bianconi 3 participants 7 messages May 15, 2024 – May 17, 2024

Subsystems (7)

v1 of 6 Superseded Latest is v6 →

lore
Share & tools
lore
#0 lore raw

cover netfilter: Add the capability to offload flowtable in XDP layer

Introduce bpf_xdp_flow_offload_lookup kfunc in order to perform the lookup of a given flowtable entry based on the fib tuple of incoming traffic.
bpf_xdp_flow_offload_lookup can be used as building block to offload in XDP the sw flowtable processing when the hw support is not available.

This series has been tested running the xdp_flowtable_offload eBPF program on an ixgbe 10Gbps NIC (eno2) in order to XDP_REDIRECT the TCP traffic to a veth pair (veth0-veth1) based on the content of the nf_flowtable as soon as the TCP connection is in the established state:

[tcp client] (eno1) == LAN == (eno2) xdp_flowtable_offload [XDP_REDIRECT] --> veth0 == veth1 [tcp server]

table inet filter {
	flowtable ft {
		hook ingress priority filter
		devices = { eno2, veth0 }
	}
	chain forward {
		type filter hook forward priority filter
		meta l4proto { tcp, udp } flow add @ft
	}
}

- sw flowtable [1 TCP stream, T = 300s]: ~ 6.2 Gbps
- xdp flowtable [1 TCP stream, T = 300s]: ~ 7.6 Gbps

Changes since RFC:
- fix compilation error if BTF is not enabled

Florian Westphal (1):
netfilter: nf_tables: add flowtable map for xdp offload

Lorenzo Bianconi (3):
netfilter: add bpf_xdp_flow_offload_lookup kfunc samples/bpf: Add bpf sample to offload flowtable traffic to xdp selftests/bpf: Add selftest for bpf_xdp_flow_offload_lookup kfunc

 include/net/netfilter/nf_flow_table.h         |  12 +
 net/netfilter/Makefile                        |   5 +
 net/netfilter/nf_flow_table_bpf.c             |  95 +++
 net/netfilter/nf_flow_table_inet.c            |   2 +
 net/netfilter/nf_flow_table_offload.c         | 161 ++++-
 samples/bpf/Makefile                          |   7 +-
 samples/bpf/xdp_flowtable_offload.bpf.c       | 592 ++++++++++++++++++
 samples/bpf/xdp_flowtable_offload_user.c      | 128 ++++
 tools/testing/selftests/bpf/Makefile          |  10 +-
 tools/testing/selftests/bpf/config            |   4 +
 .../selftests/bpf/progs/xdp_flowtable.c       | 142 +++++
 .../selftests/bpf/test_xdp_flowtable.sh       | 112 ++++
 tools/testing/selftests/bpf/xdp_flowtable.c   | 142 +++++
 13 files changed, 1407 insertions(+), 5 deletions(-)
 create mode 100644 net/netfilter/nf_flow_table_bpf.c
 create mode 100644 samples/bpf/xdp_flowtable_offload.bpf.c
 create mode 100644 samples/bpf/xdp_flowtable_offload_user.c
 create mode 100644 tools/testing/selftests/bpf/progs/xdp_flowtable.c
 create mode 100755 tools/testing/selftests/bpf/test_xdp_flowtable.sh
 create mode 100644 tools/testing/selftests/bpf/xdp_flowtable.c
Signature · 1 line
2.45.0
#1 lore raw

PATCH 1/4 netfilter: nf_tables: add flowtable map for xdp offload

From: Florian Westphal <[email protected]>

This adds a small internal mapping table so that a new bpf (xdp) kfunc can perform lookups in a flowtable.

As-is, xdp program has access to the device pointer, but no way to do a lookup in a flowtable -- there is no way to obtain the needed struct without questionable stunts.

This allows to obtain an nf_flowtable pointer given a net_device structure.

In order to keep backward compatibility, the infrastructure allows the user to add a given device to multiple flowtables, but it will always return the first added mapping performing the lookup since it assumes the right configuration is 1:1 mapping between flowtables and net_devices.

---
 include/net/netfilter/nf_flow_table.h |   2 +
 net/netfilter/nf_flow_table_offload.c | 161 +++++++++++++++++++++++++-
 2 files changed, 161 insertions(+), 2 deletions(-)
include/net/netfilter/nf_flow_table.h +2 -0
index 9abb7ee40d72f..0bbe6ea8e0651 100644
@@ -305,6 +305,8 @@ struct flow_ports {
 	__be16 source, dest;
 };
 
+struct nf_flowtable *nf_flowtable_by_dev(const struct net_device *dev);
+
 unsigned int nf_flow_offload_ip_hook(void *priv, struct sk_buff *skb,
 				     const struct nf_hook_state *state);
 unsigned int nf_flow_offload_ipv6_hook(void *priv, struct sk_buff *skb,
net/netfilter/nf_flow_table_offload.c +159 -2

186 lines not on this page · raw message

Signature · 1 line
2.45.0
#2 lore raw

PATCH 2/4 netfilter: add bpf_xdp_flow_offload_lookup kfunc

In reply to Lorenzo Bianconi

Introduce bpf_xdp_flow_offload_lookup kfunc in order to perform the lookup of a given flowtable entry based on a fib tuple of incoming traffic.
bpf_xdp_flow_offload_lookup can be used as building block to offload in xdp the processing of sw flowtable when hw flowtable is not available.

---
 include/net/netfilter/nf_flow_table.h | 10 +++
 net/netfilter/Makefile                |  5 ++
 net/netfilter/nf_flow_table_bpf.c     | 95 +++++++++++++++++++++++++++
 net/netfilter/nf_flow_table_inet.c    |  2 +
 4 files changed, 112 insertions(+)
 create mode 100644 net/netfilter/nf_flow_table_bpf.c
include/net/netfilter/nf_flow_table.h +10 -0
index 0bbe6ea8e0651..085660cbcd3f2 100644
@@ -312,6 +312,16 @@ unsigned int nf_flow_offload_ip_hook(void *priv, struct sk_buff *skb,
 unsigned int nf_flow_offload_ipv6_hook(void *priv, struct sk_buff *skb,
 				       const struct nf_hook_state *state);
 
+#if (IS_BUILTIN(CONFIG_NF_FLOW_TABLE) && IS_ENABLED(CONFIG_DEBUG_INFO_BTF)) || \
+    (IS_MODULE(CONFIG_NF_FLOW_TABLE) && IS_ENABLED(CONFIG_DEBUG_INFO_BTF_MODULES))
+extern int nf_flow_offload_register_bpf(void);
+#else
+static inline int nf_flow_offload_register_bpf(void)
+{
+	return 0;
+}
+#endif
+
 #define MODULE_ALIAS_NF_FLOWTABLE(family)	\
 	MODULE_ALIAS("nf-flowtable-" __stringify(family))
 
net/netfilter/Makefile +5 -0
index 614815a3ed738..18b09cec92024 100644
@@ -144,6 +144,11 @@ obj-$(CONFIG_NF_FLOW_TABLE)	+= nf_flow_table.o
 nf_flow_table-objs		:= nf_flow_table_core.o nf_flow_table_ip.o \
 				   nf_flow_table_offload.o
 nf_flow_table-$(CONFIG_NF_FLOW_TABLE_PROCFS) += nf_flow_table_procfs.o
+ifeq ($(CONFIG_NF_FLOW_TABLE),m)
+nf_flow_table-$(CONFIG_DEBUG_INFO_BTF_MODULES) += nf_flow_table_bpf.o
+else ifeq ($(CONFIG_NF_FLOW_TABLE),y)
+nf_flow_table-$(CONFIG_DEBUG_INFO_BTF) += nf_flow_table_bpf.o
+endif
 
 obj-$(CONFIG_NF_FLOW_TABLE_INET) += nf_flow_table_inet.o
 
net/netfilter/nf_flow_table_bpf.c new file +95 -0

95 lines not on this page · raw message

net/netfilter/nf_flow_table_inet.c +2 -0
index 6eef15648b7b0..b13587238eceb 100644
@@ -98,6 +98,8 @@ static int __init nf_flow_inet_module_init(void)
 	nft_register_flowtable_type(&flowtable_ipv6);
 	nft_register_flowtable_type(&flowtable_inet);
 
+	nf_flow_offload_register_bpf();
+
 	return 0;
 }
 
Signature · 1 line
2.45.0
#3 lore raw

Re: [PATCH bpf-next 2/4] netfilter: add bpf_xdp_flow_offload_lookup kfunc

Quoted 87 lines · Lorenzo Bianconi

Introduce bpf_xdp_flow_offload_lookup kfunc in order to perform the lookup of a given flowtable entry based on a fib tuple of incoming traffic.
bpf_xdp_flow_offload_lookup can be used as building block to offload in xdp the processing of sw flowtable when hw flowtable is not available.

---
 include/net/netfilter/nf_flow_table.h | 10 +++
 net/netfilter/Makefile                |  5 ++
 net/netfilter/nf_flow_table_bpf.c     | 95 +++++++++++++++++++++++++++
 net/netfilter/nf_flow_table_inet.c    |  2 +
 4 files changed, 112 insertions(+)
 create mode 100644 net/netfilter/nf_flow_table_bpf.c
include/net/netfilter/nf_flow_table.h +10 -0
index 0bbe6ea8e0651..085660cbcd3f2 100644
@@ -312,6 +312,16 @@ unsigned int nf_flow_offload_ip_hook(void *priv, struct sk_buff *skb,
 unsigned int nf_flow_offload_ipv6_hook(void *priv, struct sk_buff *skb,
                                       const struct nf_hook_state *state);
 
+#if (IS_BUILTIN(CONFIG_NF_FLOW_TABLE) && IS_ENABLED(CONFIG_DEBUG_INFO_BTF)) || \
+    (IS_MODULE(CONFIG_NF_FLOW_TABLE) && IS_ENABLED(CONFIG_DEBUG_INFO_BTF_MODULES))
+extern int nf_flow_offload_register_bpf(void);
+#else
+static inline int nf_flow_offload_register_bpf(void)
+{
+       return 0;
+}
+#endif
+
 #define MODULE_ALIAS_NF_FLOWTABLE(family)      \
        MODULE_ALIAS("nf-flowtable-" __stringify(family))
 
net/netfilter/Makefile +5 -0
index 614815a3ed738..18b09cec92024 100644
@@ -144,6 +144,11 @@ obj-$(CONFIG_NF_FLOW_TABLE)        += nf_flow_table.o
 nf_flow_table-objs             := nf_flow_table_core.o nf_flow_table_ip.o \
                                   nf_flow_table_offload.o
 nf_flow_table-$(CONFIG_NF_FLOW_TABLE_PROCFS) += nf_flow_table_procfs.o
+ifeq ($(CONFIG_NF_FLOW_TABLE),m)
+nf_flow_table-$(CONFIG_DEBUG_INFO_BTF_MODULES) += nf_flow_table_bpf.o
+else ifeq ($(CONFIG_NF_FLOW_TABLE),y)
+nf_flow_table-$(CONFIG_DEBUG_INFO_BTF) += nf_flow_table_bpf.o
+endif
 
 obj-$(CONFIG_NF_FLOW_TABLE_INET) += nf_flow_table_inet.o
 
net/netfilter/nf_flow_table_bpf.c new file +27 -0
new file mode 100644
index 0000000000000..836a1127e4052
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Unstable Flow Table Helpers for XDP hook
+ *
+ * These are called from the XDP programs.
+ * Note that it is allowed to break compatibility for these functions since
+ * the interface they are exposed through to BPF programs is explicitly
+ * unstable.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <net/netfilter/nf_flow_table.h>
+#include <linux/bpf.h>
+#include <linux/btf.h>
+#include <net/xdp.h>
+
+__diag_push();
+__diag_ignore_all("-Wmissing-prototypes",
+                 "Global functions as their definitions will be in nf_flow_table BTF");
+
+static struct flow_offload_tuple_rhash *
+bpf_xdp_flow_offload_tuple_lookup(struct net_device *dev,
+                                 struct flow_offload_tuple *tuple,
+                                 __be16 proto)
+{
+       struct flow_offload_tuple_rhash *tuplehash;

net/netfilter/nf_flow_table_bpf.c line 37

Quoted 10 lines
net/netfilter/nf_flow_table_bpf.c new file +10 -0
+       struct nf_flowtable *flow_table;
+       struct flow_offload *flow;
+
+       flow_table = nf_flowtable_by_dev(dev);
+       if (!flow_table)
+               return ERR_PTR(-ENOENT);
+
+       tuplehash = flow_offload_lookup(flow_table, tuple);
+       if (!tuplehash)
+               return ERR_PTR(-ENOENT);

This is fine to do, but the caller should catch it using IS_ERR_PTR and return NULL.
BPF side cannot distinguish ERR_PTR from normal pointer, so this will cause a bad deref in the program.

net/netfilter/nf_flow_table_bpf.c line 49

Quoted 12 lines
net/netfilter/nf_flow_table_bpf.c new file +12 -0
+
+       flow = container_of(tuplehash, struct flow_offload,
+                           tuplehash[tuplehash->tuple.dir]);
+       flow_offload_refresh(flow_table, flow, false);
+
+       return tuplehash;
+}
+
+__bpf_kfunc struct flow_offload_tuple_rhash *
+bpf_xdp_flow_offload_lookup(struct xdp_md *ctx,
+                           struct bpf_fib_lookup *fib_tuple,
+                           u32 fib_tuple__sz)

Do you think the __sz has the intended effect? It only works when the preceding parameter is a void *.
If you have a type like struct bpf_fib_lookup, I think it should work fine without taking a size at all.

Quoted 14 lines
net/netfilter/nf_flow_table_bpf.c new file +14 -0
+{
+       struct xdp_buff *xdp = (struct xdp_buff *)ctx;
+       struct flow_offload_tuple tuple = {
+               .iifidx = fib_tuple->ifindex,
+               .l3proto = fib_tuple->family,
+               .l4proto = fib_tuple->l4_protocol,
+               .src_port = fib_tuple->sport,
+               .dst_port = fib_tuple->dport,
+       };
+       __be16 proto;
+
+       switch (fib_tuple->family) {
+       case AF_INET:
+               tuple.src_v4.s_addr = fib_tuple->ipv4_src;

net/netfilter/nf_flow_table_bpf.c line 73

Quoted 10 lines
net/netfilter/nf_flow_table_bpf.c new file +10 -0
+               tuple.dst_v4.s_addr = fib_tuple->ipv4_dst;
+               proto = htons(ETH_P_IP);
+               break;
+       case AF_INET6:
+               tuple.src_v6 = *(struct in6_addr *)&fib_tuple->ipv6_src;
+               tuple.dst_v6 = *(struct in6_addr *)&fib_tuple->ipv6_dst;
+               proto = htons(ETH_P_IPV6);
+               break;
+       default:
+               return ERR_PTR(-EINVAL);

Likewise. While you check IS_ERR_VALUE in selftest, direct dereference will be allowed by verifier, which would crash the kernel. It's better to do something like conntrack kfuncs, where they set opts->error when returning NULL, allowing better debugging in case lookup fails.

Quoted 11 lines
net/netfilter/nf_flow_table_bpf.c new file +11 -0
+       }
+
+       return bpf_xdp_flow_offload_tuple_lookup(xdp->rxq->dev, &tuple, proto);
+}
+
+__diag_pop()
+
+BTF_KFUNCS_START(nf_ft_kfunc_set)
+BTF_ID_FLAGS(func, bpf_xdp_flow_offload_lookup)
+BTF_KFUNCS_END(nf_ft_kfunc_set)
+

net/netfilter/nf_flow_table_bpf.c line 94

Quoted 10 lines
net/netfilter/nf_flow_table_bpf.c new file +10 -0
+static const struct btf_kfunc_id_set nf_flow_offload_kfunc_set = {
+       .owner = THIS_MODULE,
+       .set   = &nf_ft_kfunc_set,
+};
+
+int nf_flow_offload_register_bpf(void)
+{
+       return register_btf_kfunc_id_set(BPF_PROG_TYPE_XDP,
+                                        &nf_flow_offload_kfunc_set);
+}

We should probably also expose it to skb? We just need net_device, so it can work with both XDP and TC progs.
That would be similar to how we expose conntrack kfuncs to both XDP and TC progs.

net/netfilter/nf_flow_table_inet.c static int __init nf_flow_inet_module_init(void) · line 102

Quoted 11 lines
net/netfilter/nf_flow_table_bpf.c new file +1 -0
+EXPORT_SYMBOL_GPL(nf_flow_offload_register_bpf);
net/netfilter/nf_flow_table_inet.c +2 -0
index 6eef15648b7b0..b13587238eceb 100644
@@ -98,6 +98,8 @@ static int __init nf_flow_inet_module_init(void)
        nft_register_flowtable_type(&flowtable_ipv6);
        nft_register_flowtable_type(&flowtable_inet);
 
+       nf_flow_offload_register_bpf();
+

Error checking needed here? Kfunc registration can fail.

Quoted 7 lines
net/netfilter/nf_flow_table_inet.c +0 -1
        return 0;
 }
 
--

2.45.0

#4 lore raw

Re: [PATCH bpf-next 2/4] netfilter: add bpf_xdp_flow_offload_lookup kfunc

[...]

Quoted 8 lines

net/netfilter/nf_flow_table_bpf.c line 37

Quoted 3 lines
net/netfilter/nf_flow_table_bpf.c new file +3 -0
+       tuplehash = flow_offload_lookup(flow_table, tuple);
+       if (!tuplehash)
+               return ERR_PTR(-ENOENT);

This is fine to do, but the caller should catch it using IS_ERR_PTR and return NULL.
BPF side cannot distinguish ERR_PTR from normal pointer, so this will cause a bad deref in the program.

ack, I will fix it in v2.

Quoted 10 lines
Quoted 10 lines
net/netfilter/nf_flow_table_bpf.c new file +9 -0
+
+       flow = container_of(tuplehash, struct flow_offload,
+                           tuplehash[tuplehash->tuple.dir]);
+       flow_offload_refresh(flow_table, flow, false);
+
+       return tuplehash;
+}
+
+__bpf_kfunc struct flow_offload_tuple_rhash *
Quoted 8 lines

net/netfilter/nf_flow_table_bpf.c line 49

Quoted 3 lines
net/netfilter/nf_flow_table_bpf.c new file +3 -0
+bpf_xdp_flow_offload_lookup(struct xdp_md *ctx,
+                           struct bpf_fib_lookup *fib_tuple,
+                           u32 fib_tuple__sz)

Do you think the __sz has the intended effect? It only works when the preceding parameter is a void *.
If you have a type like struct bpf_fib_lookup, I think it should work fine without taking a size at all.

ack, I will fix it in v2.

Quoted 23 lines
Quoted 23 lines
net/netfilter/nf_flow_table_bpf.c new file +22 -0
+{
+       struct xdp_buff *xdp = (struct xdp_buff *)ctx;
+       struct flow_offload_tuple tuple = {
+               .iifidx = fib_tuple->ifindex,
+               .l3proto = fib_tuple->family,
+               .l4proto = fib_tuple->l4_protocol,
+               .src_port = fib_tuple->sport,
+               .dst_port = fib_tuple->dport,
+       };
+       __be16 proto;
+
+       switch (fib_tuple->family) {
+       case AF_INET:
+               tuple.src_v4.s_addr = fib_tuple->ipv4_src;
+               tuple.dst_v4.s_addr = fib_tuple->ipv4_dst;
+               proto = htons(ETH_P_IP);
+               break;
+       case AF_INET6:
+               tuple.src_v6 = *(struct in6_addr *)&fib_tuple->ipv6_src;
+               tuple.dst_v6 = *(struct in6_addr *)&fib_tuple->ipv6_dst;
+               proto = htons(ETH_P_IPV6);
+               break;
Quoted 8 lines

net/netfilter/nf_flow_table_bpf.c line 73

Quoted 2 lines
net/netfilter/nf_flow_table_bpf.c new file +2 -0
+       default:
+               return ERR_PTR(-EINVAL);

Likewise. While you check IS_ERR_VALUE in selftest, direct dereference will be allowed by verifier, which would crash the kernel. It's better to do something like conntrack kfuncs, where they set opts->error when returning NULL, allowing better debugging in case lookup fails.

ack, I will fix it in v2.

Quoted 19 lines
Quoted 19 lines
net/netfilter/nf_flow_table_bpf.c new file +18 -0
+       }
+
+       return bpf_xdp_flow_offload_tuple_lookup(xdp->rxq->dev, &tuple, proto);
+}
+
+__diag_pop()
+
+BTF_KFUNCS_START(nf_ft_kfunc_set)
+BTF_ID_FLAGS(func, bpf_xdp_flow_offload_lookup)
+BTF_KFUNCS_END(nf_ft_kfunc_set)
+
+static const struct btf_kfunc_id_set nf_flow_offload_kfunc_set = {
+       .owner = THIS_MODULE,
+       .set   = &nf_ft_kfunc_set,
+};
+
+int nf_flow_offload_register_bpf(void)
+{
Quoted 8 lines

net/netfilter/nf_flow_table_bpf.c line 94

Quoted 3 lines
net/netfilter/nf_flow_table_bpf.c new file +3 -0
+       return register_btf_kfunc_id_set(BPF_PROG_TYPE_XDP,
+                                        &nf_flow_offload_kfunc_set);
+}

We should probably also expose it to skb? We just need net_device, so it can work with both XDP and TC progs.
That would be similar to how we expose conntrack kfuncs to both XDP and TC progs.

I think we will get very similar results to sw flowtable in this case, don't you think?

Quoted 10 lines
Quoted 10 lines
net/netfilter/nf_flow_table_bpf.c new file +1 -0
+EXPORT_SYMBOL_GPL(nf_flow_offload_register_bpf);
net/netfilter/nf_flow_table_inet.c +0 -0
index 6eef15648b7b0..b13587238eceb 100644
@@ -98,6 +98,8 @@ static int __init nf_flow_inet_module_init(void)
        nft_register_flowtable_type(&flowtable_ipv6);
        nft_register_flowtable_type(&flowtable_inet);
 
Quoted 4 lines

net/netfilter/nf_flow_table_inet.c static int __init nf_flow_inet_module_init(void) · line 102

Quoted 2 lines
net/netfilter/nf_flow_table_inet.c +2 -0
+       nf_flow_offload_register_bpf();
+

Error checking needed here? Kfunc registration can fail.

ack, I will fix it.

Regards,
Lorenzo

Quoted 9 lines
Quoted 8 lines
net/netfilter/nf_flow_table_inet.c +0 -1
        return 0;
 }
 
--

2.45.0

#5 lore raw

PATCH 3/4 samples/bpf: Add bpf sample to offload flowtable traffic to xdp

In reply to Lorenzo Bianconi

Introduce xdp_flowtable_offload bpf sample to offload sw flowtable logic in xdp layer if hw flowtable is not available or does not support a specific kind of traffic.

---
 samples/bpf/Makefile                     |   7 +-
 samples/bpf/xdp_flowtable_offload.bpf.c  | 592 +++++++++++++++++++++++
 samples/bpf/xdp_flowtable_offload_user.c | 128 +++++
 3 files changed, 726 insertions(+), 1 deletion(-)
 create mode 100644 samples/bpf/xdp_flowtable_offload.bpf.c
 create mode 100644 samples/bpf/xdp_flowtable_offload_user.c
samples/bpf/Makefile +6 -1
index 9aa027b144df6..a3d089ca224d5 100644
@@ -46,6 +46,7 @@ tprogs-y += xdp_fwd
 tprogs-y += task_fd_query
 tprogs-y += ibumad
 tprogs-y += hbm
+tprogs-y += xdp_flowtable_offload
 
 # Libbpf dependencies
 LIBBPF_SRC = $(TOOLS_PATH)/lib/bpf
@@ -98,6 +99,7 @@ ibumad-objs := ibumad_user.o
 hbm-objs := hbm.o $(CGROUP_HELPERS)
 
 xdp_router_ipv4-objs := xdp_router_ipv4_user.o $(XDP_SAMPLE)
+xdp_flowtable_offload-objs := xdp_flowtable_offload_user.o $(XDP_SAMPLE)
 
 # Tell kbuild to always build the programs
 always-y := $(tprogs-y)
@@ -306,6 +308,7 @@ $(obj)/$(TRACE_HELPERS) $(obj)/$(CGROUP_HELPERS) $(obj)/$(XDP_SAMPLE): | libbpf_
 .PHONY: libbpf_hdrs
 
 $(obj)/xdp_router_ipv4_user.o: $(obj)/xdp_router_ipv4.skel.h
+$(obj)/xdp_flowtable_offload_user.o: $(obj)/xdp_flowtable_offload.skel.h
 
 $(obj)/tracex5.bpf.o: $(obj)/syscall_nrs.h
 $(obj)/hbm_out_kern.o: $(src)/hbm.h $(src)/hbm_kern.h
@@ -361,6 +364,7 @@ endef
 CLANG_SYS_INCLUDES = $(call get_sys_includes,$(CLANG))
 
 $(obj)/xdp_router_ipv4.bpf.o: $(obj)/xdp_sample.bpf.o
+$(obj)/xdp_flowtable_offload.bpf.o: $(obj)/xdp_sample.bpf.o
 
 $(obj)/%.bpf.o: $(src)/%.bpf.c $(obj)/vmlinux.h $(src)/xdp_sample.bpf.h $(src)/xdp_sample_shared.h
 	@echo "  CLANG-BPF " $@
@@ -370,10 +374,11 @@ $(obj)/%.bpf.o: $(src)/%.bpf.c $(obj)/vmlinux.h $(src)/xdp_sample.bpf.h $(src)/x
 		-I$(LIBBPF_INCLUDE) $(CLANG_SYS_INCLUDES) \
 		-c $(filter %.bpf.c,$^) -o $@
 
-LINKED_SKELS := xdp_router_ipv4.skel.h
+LINKED_SKELS := xdp_router_ipv4.skel.h xdp_flowtable_offload.skel.h
 clean-files += $(LINKED_SKELS)
 
 xdp_router_ipv4.skel.h-deps := xdp_router_ipv4.bpf.o xdp_sample.bpf.o
+xdp_flowtable_offload.skel.h-deps := xdp_flowtable_offload.bpf.o xdp_sample.bpf.o
 
 LINKED_BPF_SRCS := $(patsubst %.bpf.o,%.bpf.c,$(foreach skel,$(LINKED_SKELS),$($(skel)-deps)))
 
samples/bpf/xdp_flowtable_offload.bpf.c new file +592 -0

592 lines not on this page · raw message

samples/bpf/xdp_flowtable_offload_user.c new file +128 -0

128 lines not on this page · raw message

Signature · 1 line
2.45.0
#6 lore raw

PATCH 4/4 selftests/bpf: Add selftest for bpf_xdp_flow_offload_lookup kfunc

In reply to Lorenzo Bianconi

Introduce e2e selftest for bpf_xdp_flow_offload_lookup kfunc through xdp_flowtable utility.

---
 tools/testing/selftests/bpf/Makefile          |  10 +-
 tools/testing/selftests/bpf/config            |   4 +
 .../selftests/bpf/progs/xdp_flowtable.c       | 142 ++++++++++++++++++
 .../selftests/bpf/test_xdp_flowtable.sh       | 112 ++++++++++++++
 tools/testing/selftests/bpf/xdp_flowtable.c   | 142 ++++++++++++++++++
 5 files changed, 408 insertions(+), 2 deletions(-)
 create mode 100644 tools/testing/selftests/bpf/progs/xdp_flowtable.c
 create mode 100755 tools/testing/selftests/bpf/test_xdp_flowtable.sh
 create mode 100644 tools/testing/selftests/bpf/xdp_flowtable.c
tools/testing/selftests/bpf/Makefile +8 -2
index e0b3887b3d2df..7361c429bed62 100644
@@ -133,7 +133,8 @@ TEST_PROGS := test_kmod.sh \
 	test_bpftool_metadata.sh \
 	test_doc_build.sh \
 	test_xsk.sh \
-	test_xdp_features.sh
+	test_xdp_features.sh \
+	test_xdp_flowtable.sh
 
 TEST_PROGS_EXTENDED := with_addr.sh \
 	with_tunnels.sh ima_setup.sh verify_sig_setup.sh \
@@ -144,7 +145,7 @@ TEST_GEN_PROGS_EXTENDED = test_skb_cgroup_id_user \
 	flow_dissector_load test_flow_dissector test_tcp_check_syncookie_user \
 	test_lirc_mode2_user xdping test_cpp runqslower bench bpf_testmod.ko \
 	xskxceiver xdp_redirect_multi xdp_synproxy veristat xdp_hw_metadata \
-	xdp_features bpf_test_no_cfi.ko
+	xdp_features bpf_test_no_cfi.ko xdp_flowtable
 
 TEST_GEN_FILES += liburandom_read.so urandom_read sign-file uprobe_multi
 
@@ -476,6 +477,7 @@ test_usdt.skel.h-deps := test_usdt.bpf.o test_usdt_multispec.bpf.o
 xsk_xdp_progs.skel.h-deps := xsk_xdp_progs.bpf.o
 xdp_hw_metadata.skel.h-deps := xdp_hw_metadata.bpf.o
 xdp_features.skel.h-deps := xdp_features.bpf.o
+xdp_flowtable.skel.h-deps := xdp_flowtable.bpf.o
 
 LINKED_BPF_SRCS := $(patsubst %.bpf.o,%.c,$(foreach skel,$(LINKED_SKELS),$($(skel)-deps)))
 
@@ -710,6 +712,10 @@ $(OUTPUT)/xdp_features: xdp_features.c $(OUTPUT)/network_helpers.o $(OUTPUT)/xdp
 	$(call msg,BINARY,,$@)
 	$(Q)$(CC) $(CFLAGS) $(filter %.a %.o %.c,$^) $(LDLIBS) -o $@
 
+$(OUTPUT)/xdp_flowtable: xdp_flowtable.c $(OUTPUT)/xdp_flowtable.skel.h | $(OUTPUT)
+	$(call msg,BINARY,,$@)
+	$(Q)$(CC) $(CFLAGS) $(filter %.a %.o %.c,$^) $(LDLIBS) -o $@
+
 # Make sure we are able to include and link libbpf against c++.
 $(OUTPUT)/test_cpp: test_cpp.cpp $(OUTPUT)/test_core_extern.skel.h $(BPFOBJ)
 	$(call msg,CXX,,$@)
tools/testing/selftests/bpf/config +4 -0
index eeabd798bc3ae..1a9aea01145f7 100644
@@ -82,6 +82,10 @@ CONFIG_NF_CONNTRACK=y
 CONFIG_NF_CONNTRACK_MARK=y
 CONFIG_NF_DEFRAG_IPV4=y
 CONFIG_NF_DEFRAG_IPV6=y
+CONFIG_NF_TABLES=y
+CONFIG_NETFILTER_INGRESS=y
+CONFIG_NF_FLOW_TABLE=y
+CONFIG_NF_FLOW_TABLE_INET=y
 CONFIG_NF_NAT=y
 CONFIG_RC_CORE=y
 CONFIG_SECURITY=y
tools/testing/selftests/bpf/progs/xdp_flowtable.c new file +142 -0

142 lines not on this page · raw message

tools/testing/selftests/bpf/test_xdp_flowtable.sh new file +112 -0

112 lines not on this page · raw message

tools/testing/selftests/bpf/xdp_flowtable.c new file +142 -0

142 lines not on this page · raw message

Signature · 1 line
2.45.0