Skip to contentSkip to conversation

netfilter: Add the capability to offload flowtable in XDP layer

PATCH Superseded Lorenzo Bianconi 2 participants 6 messages May 23, 2024

Subsystems (7)

v3 of 6 Superseded Latest is v6 →

lore
Share & tools
lore
#0 lore raw

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

Introduce bpf_xdp_flow_lookup kfunc in order to perform the lookup of a given flowtable entry based on the fib tuple of incoming traffic. bpf_xdp_flow_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

- sw flowtable [3 TCP stream, T = 300s]: ~ 7.7 Gbps
- xdp flowtable [3 TCP stream, T = 300s]: ~ 8.8 Gbps

Changes since v2:
- introduce bpf_flowtable_opts struct in bpf_xdp_flow_lookup signature
- get rid of xdp_flowtable_offload bpf sample
- get rid of test_xdp_flowtable.sh for selftest and rely on prog_tests instead
- rename bpf_xdp_flow_offload_lookup in bpf_xdp_flow_lookup Changes since v1:
- return NULL in bpf_xdp_flow_offload_lookup kfunc in case of error
- take into account kfunc registration possible failures
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 (2):
netfilter: add bpf_xdp_flow_lookup kfunc selftests/bpf: Add selftest for bpf_xdp_flow_lookup kfunc

 include/net/netfilter/nf_flow_table.h         |  12 ++
 net/netfilter/Makefile                        |   5 +
 net/netfilter/nf_flow_table_bpf.c             | 117 ++++++++++++
 net/netfilter/nf_flow_table_inet.c            |   2 +-
 net/netfilter/nf_flow_table_offload.c         | 161 ++++++++++++++++-
 tools/testing/selftests/bpf/config            |  13 ++
 .../selftests/bpf/prog_tests/xdp_flowtable.c  | 168 ++++++++++++++++++
 .../selftests/bpf/progs/xdp_flowtable.c       | 145 +++++++++++++++
 8 files changed, 620 insertions(+), 3 deletions(-)
 create mode 100644 net/netfilter/nf_flow_table_bpf.c
 create mode 100644 tools/testing/selftests/bpf/prog_tests/xdp_flowtable.c
 create mode 100644 tools/testing/selftests/bpf/progs/xdp_flowtable.c
Signature · 1 line
2.45.1
#1 lore raw

PATCH v3 1/3 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.1
#2 lore raw

Re: [PATCH v3 bpf-next 1/3] netfilter: nf_tables: add flowtable map for xdp offload

Hi Lorenzo,

Quoted 9 lines · Lorenzo Bianconi

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.

Quoted 7 lines

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.

Would it be possible to move this new code in _offload.c to nf_flow_table_xdp.c?

The flowtable offload code is already a bit convoluted, the hardware offload API for payload matching results in chatty with many sparse warnings (unless I adds casting everywhere), but I remember I failed to provide a convincing improvements on that front without requiring changes to drivers at the time. This is of course no related to this series.

#3 lore raw

Re: [PATCH v3 bpf-next 1/3] netfilter: nf_tables: add flowtable map for xdp offload

Quoted 15 lines

Hi Lorenzo,

Quoted 12 lines · Lorenzo Bianconi

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.

Quoted 7 lines
Quoted 4 lines

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.

Would it be possible to move this new code in _offload.c to nf_flow_table_xdp.c?

ack, I will do in v4.

Regards,
Lorenzo

Quoted 7 lines

The flowtable offload code is already a bit convoluted, the hardware offload API for payload matching results in chatty with many sparse warnings (unless I adds casting everywhere), but I remember I failed to provide a convincing improvements on that front without requiring changes to drivers at the time. This is of course no related to this series.

#4 lore raw

PATCH v3 2/3 netfilter: add bpf_xdp_flow_lookup kfunc

In reply to Lorenzo Bianconi

Introduce bpf_xdp_flow_lookup kfunc in order to perform the lookup of a given flowtable entry based on a fib tuple of incoming traffic. bpf_xdp_flow_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     | 117 ++++++++++++++++++++++++++
 net/netfilter/nf_flow_table_inet.c    |   2 +-
 4 files changed, 133 insertions(+), 1 deletion(-)
 create mode 100644 net/netfilter/nf_flow_table_bpf.c
include/net/netfilter/nf_flow_table.h +10 -0
index 0bbe6ea8e0651..fb4bfeb569dee 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_register_bpf(void);
+#else
+static inline int nf_flow_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 +117 -0

117 lines not on this page · raw message

net/netfilter/nf_flow_table_inet.c +1 -1
index 6eef15648b7b0..88787b45e30d6 100644
@@ -98,7 +98,7 @@ static int __init nf_flow_inet_module_init(void)
 	nft_register_flowtable_type(&flowtable_ipv6);
 	nft_register_flowtable_type(&flowtable_inet);
 
-	return 0;
+	return nf_flow_register_bpf();
 }
 
 static void __exit nf_flow_inet_module_exit(void)
Signature · 1 line
2.45.1
#5 lore raw

PATCH v3 3/3 selftests/bpf: Add selftest for bpf_xdp_flow_lookup kfunc

In reply to Lorenzo Bianconi

Introduce e2e selftest for bpf_xdp_flow_lookup kfunc through xdp_flowtable utility.

---
 tools/testing/selftests/bpf/config            |  13 ++
 .../selftests/bpf/prog_tests/xdp_flowtable.c  | 168 ++++++++++++++++++
 .../selftests/bpf/progs/xdp_flowtable.c       | 145 +++++++++++++++
 3 files changed, 326 insertions(+)
 create mode 100644 tools/testing/selftests/bpf/prog_tests/xdp_flowtable.c
 create mode 100644 tools/testing/selftests/bpf/progs/xdp_flowtable.c
tools/testing/selftests/bpf/config +13 -0
index 2fb16da78dce8..5291e97df7494 100644
@@ -83,6 +83,19 @@ CONFIG_NF_CONNTRACK_MARK=y
 CONFIG_NF_CONNTRACK_ZONES=y
 CONFIG_NF_DEFRAG_IPV4=y
 CONFIG_NF_DEFRAG_IPV6=y
+CONFIG_NF_TABLES=y
+CONFIG_NF_TABLES_INET=y
+CONFIG_NF_TABLES_NETDEV=y
+CONFIG_NF_TABLES_IPV4=y
+CONFIG_NF_TABLES_IPV6=y
+CONFIG_NETFILTER_INGRESS=y
+CONFIG_NF_FLOW_TABLE=y
+CONFIG_NF_FLOW_TABLE_INET=y
+CONFIG_NETFILTER_NETLINK=y
+CONFIG_NFT_FLOW_OFFLOAD=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP6_NF_IPTABLES=y
+CONFIG_IP6_NF_FILTER=y
 CONFIG_NF_NAT=y
 CONFIG_RC_CORE=y
 CONFIG_SECURITY=y
tools/testing/selftests/bpf/prog_tests/xdp_flowtable.c new file +168 -0

168 lines not on this page · raw message

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

145 lines not on this page · raw message

Signature · 1 line
2.45.1