[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1596170660-5582-2-git-send-email-komachi.yoshiki@gmail.com>
Date: Fri, 31 Jul 2020 13:44:18 +0900
From: Yoshiki Komachi <komachi.yoshiki@...il.com>
To: "David S. Miller" <davem@...emloft.net>,
Alexei Starovoitov <ast@...nel.org>,
Daniel Borkmann <daniel@...earbox.net>,
Jesper Dangaard Brouer <hawk@...nel.org>,
John Fastabend <john.fastabend@...il.com>,
Jakub Kicinski <kuba@...nel.org>,
Martin KaFai Lau <kafai@...com>,
Song Liu <songliubraving@...com>, Yonghong Song <yhs@...com>,
Andrii Nakryiko <andriin@...com>,
KP Singh <kpsingh@...omium.org>,
Roopa Prabhu <roopa@...ulusnetworks.com>,
Nikolay Aleksandrov <nikolay@...ulusnetworks.com>,
David Ahern <dsahern@...nel.org>
Cc: Yoshiki Komachi <komachi.yoshiki@...il.com>,
netdev@...r.kernel.org, bridge@...ts.linux-foundation.org,
bpf@...r.kernel.org
Subject: [RFC PATCH bpf-next 1/3] net/bridge: Add new function to access FDB from XDP programs
This patch adds a function to find the destination port from the
FDB in the kernel tables, which mainly helps XDP programs to access
FDB in the kernel via bpf helper. Note that, unlike the existing
br_fdb_find_port(), this function takes an ingress device as an
argument.
The br_fdb_find_port() also enables us to access FDB in the kernel,
and rcu_read_lock()/rcu_read_unlock() must be called in the function.
But, these are unnecessary in that cases because XDP programs have
to call APIs with rcu_read_lock()/rcu_read_unlock(). Thus, proposed
function could be used without these locks in the function.
Signed-off-by: Yoshiki Komachi <komachi.yoshiki@...il.com>
---
include/linux/if_bridge.h | 11 +++++++++++
net/bridge/br_fdb.c | 25 +++++++++++++++++++++++++
2 files changed, 36 insertions(+)
diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h
index 6479a38e52fa..24d72d115d0b 100644
--- a/include/linux/if_bridge.h
+++ b/include/linux/if_bridge.h
@@ -127,6 +127,9 @@ static inline int br_vlan_get_info(const struct net_device *dev, u16 vid,
struct net_device *br_fdb_find_port(const struct net_device *br_dev,
const unsigned char *addr,
__u16 vid);
+struct net_device *br_fdb_find_port_xdp(const struct net_device *dev,
+ const unsigned char *addr,
+ __u16 vid);
void br_fdb_clear_offload(const struct net_device *dev, u16 vid);
bool br_port_flag_is_set(const struct net_device *dev, unsigned long flag);
#else
@@ -138,6 +141,14 @@ br_fdb_find_port(const struct net_device *br_dev,
return NULL;
}
+static inline struct net_device *
+br_fdb_find_port_xdp(const struct net_device *dev,
+ const unsigned char *addr,
+ __u16 vid);
+{
+ return NULL;
+}
+
static inline void br_fdb_clear_offload(const struct net_device *dev, u16 vid)
{
}
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c
index 9db504baa094..79bc3c2da668 100644
--- a/net/bridge/br_fdb.c
+++ b/net/bridge/br_fdb.c
@@ -141,6 +141,31 @@ struct net_device *br_fdb_find_port(const struct net_device *br_dev,
}
EXPORT_SYMBOL_GPL(br_fdb_find_port);
+struct net_device *br_fdb_find_port_xdp(const struct net_device *dev,
+ const unsigned char *addr,
+ __u16 vid)
+{
+ struct net_bridge_fdb_entry *f;
+ struct net_device *dst = NULL;
+ struct net_bridge *br = NULL;
+ struct net_bridge_port *p;
+
+ p = br_port_get_check_rcu(dev);
+ if (!p)
+ return NULL;
+
+ br = p->br;
+ if (!br)
+ return NULL;
+
+ f = br_fdb_find_rcu(br, addr, vid);
+ if (f && f->dst)
+ dst = f->dst->dev;
+
+ return dst;
+}
+EXPORT_SYMBOL_GPL(br_fdb_find_port_xdp);
+
struct net_bridge_fdb_entry *br_fdb_find_rcu(struct net_bridge *br,
const unsigned char *addr,
__u16 vid)
--
2.20.1 (Apple Git-117)
Powered by blists - more mailing lists