Thread (20 messages) 20 messages, 7 authors, 2020-08-07

Re: [RFC PATCH bpf-next 2/3] bpf: Add helper to do forwarding lookups in kernel FDB table

From: Yoshiki Komachi <hidden>
Date: 2020-08-04 08:44:24
Also in: bpf, bridge

2020/07/31 20:52、Maciej Fijalkowski [off-list ref]のメール:

On Fri, Jul 31, 2020 at 01:44:19PM +0900, Yoshiki Komachi wrote:
quoted
This patch adds a new bpf helper to access FDB in the kernel tables
from XDP programs. The helper enables us to find the destination port
of master bridge in XDP layer with high speed. If an entry in the
tables is successfully found, egress device index will be returned.

In cases of failure, packets will be dropped or forwarded to upper
networking stack in the kernel by XDP programs. Multicast and broadcast
packets are currently not supported. Thus, these will need to be
passed to upper layer on the basis of XDP_PASS action.

The API uses destination MAC and VLAN ID as keys, so XDP programs
need to extract these from forwarded packets.

Signed-off-by: Yoshiki Komachi <redacted>
---
include/uapi/linux/bpf.h       | 28 +++++++++++++++++++++
net/core/filter.c              | 45 ++++++++++++++++++++++++++++++++++
scripts/bpf_helpers_doc.py     |  1 +
tools/include/uapi/linux/bpf.h | 28 +++++++++++++++++++++
4 files changed, 102 insertions(+)
[...]
quoted
diff --git a/net/core/filter.c b/net/core/filter.c
index 654c346b7d91..68800d1b8cd5 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -45,6 +45,7 @@
#include <linux/filter.h>
#include <linux/ratelimit.h>
#include <linux/seccomp.h>
+#include <linux/if_bridge.h>
#include <linux/if_vlan.h>
#include <linux/bpf.h>
#include <linux/btf.h>
@@ -5084,6 +5085,46 @@ static const struct bpf_func_proto bpf_skb_fib_lookup_proto = {
	.arg4_type	= ARG_ANYTHING,
};

+#if IS_ENABLED(CONFIG_BRIDGE)
+BPF_CALL_4(bpf_xdp_fdb_lookup, struct xdp_buff *, ctx,
+	   struct bpf_fdb_lookup *, params, int, plen, u32, flags)
+{
+	struct net_device *src, *dst;
+	struct net *net;
+
+	if (plen < sizeof(*params))
+		return -EINVAL;
+
+	net = dev_net(ctx->rxq->dev);
+
+	if (is_multicast_ether_addr(params->addr) ||
+	    is_broadcast_ether_addr(params->addr))
+		return BPF_FDB_LKUP_RET_NOENT;
small nit: you could move that validation before dev_net() call.
Thanks for your quick response.
I will try to fix it in the next version.

Best regards,
quoted
+
+	src = dev_get_by_index_rcu(net, params->ifindex);
+	if (unlikely(!src))
+		return -ENODEV;
+
+	dst = br_fdb_find_port_xdp(src, params->addr, params->vlan_id);
+	if (dst) {
+		params->ifindex = dst->ifindex;
+		return BPF_FDB_LKUP_RET_SUCCESS;
+	}
+
+	return BPF_FDB_LKUP_RET_NOENT;
+}
—
Yoshiki Komachi
komachi.yoshiki@gmail.com
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help