[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20200511185218.1422406-8-jakub@cloudflare.com>
Date: Mon, 11 May 2020 20:52:08 +0200
From: Jakub Sitnicki <jakub@...udflare.com>
To: netdev@...r.kernel.org, bpf@...r.kernel.org
Cc: dccp@...r.kernel.org, kernel-team@...udflare.com,
Alexei Starovoitov <ast@...nel.org>,
Daniel Borkmann <daniel@...earbox.net>,
"David S. Miller" <davem@...emloft.net>,
Eric Dumazet <edumazet@...gle.com>,
Gerrit Renker <gerrit@....abdn.ac.uk>,
Jakub Kicinski <kuba@...nel.org>,
Andrii Nakryiko <andrii.nakryiko@...il.com>,
Martin KaFai Lau <kafai@...com>,
Marek Majkowski <marek@...udflare.com>,
Lorenz Bauer <lmb@...udflare.com>
Subject: [PATCH bpf-next v2 07/17] inet6: Run SK_LOOKUP BPF program on socket lookup
Following ipv4 stack changes, run a BPF program attached to netns before
looking up a listening socket. Program can return a listening socket to use
as result of socket lookup, fail the lookup, or take no action.
Suggested-by: Marek Majkowski <marek@...udflare.com>
Reviewed-by: Lorenz Bauer <lmb@...udflare.com>
Signed-off-by: Jakub Sitnicki <jakub@...udflare.com>
---
include/net/inet6_hashtables.h | 20 ++++++++++++++++++++
net/ipv6/inet6_hashtables.c | 15 ++++++++++++++-
2 files changed, 34 insertions(+), 1 deletion(-)
diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h
index 81b965953036..8b8c0cb92ea8 100644
--- a/include/net/inet6_hashtables.h
+++ b/include/net/inet6_hashtables.h
@@ -21,6 +21,7 @@
#include <net/ipv6.h>
#include <net/netns/hash.h>
+#include <net/inet_hashtables.h>
struct inet_hashinfo;
@@ -103,6 +104,25 @@ struct sock *inet6_lookup(struct net *net, struct inet_hashinfo *hashinfo,
const int dif);
int inet6_hash(struct sock *sk);
+
+static inline struct sock *inet6_lookup_run_bpf(struct net *net, u8 protocol,
+ const struct in6_addr *saddr,
+ __be16 sport,
+ const struct in6_addr *daddr,
+ u16 dport)
+{
+ struct bpf_sk_lookup_kern ctx = {
+ .family = AF_INET6,
+ .protocol = protocol,
+ .v6.saddr = *saddr,
+ .v6.daddr = *daddr,
+ .sport = sport,
+ .dport = dport,
+ };
+
+ return bpf_sk_lookup_run(net, &ctx);
+}
+
#endif /* IS_ENABLED(CONFIG_IPV6) */
#define INET6_MATCH(__sk, __net, __saddr, __daddr, __ports, __dif, __sdif) \
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
index 03942eef8ab6..6d91de89fd2b 100644
--- a/net/ipv6/inet6_hashtables.c
+++ b/net/ipv6/inet6_hashtables.c
@@ -167,9 +167,22 @@ struct sock *inet6_lookup_listener(struct net *net,
const unsigned short hnum, const int dif, const int sdif)
{
struct inet_listen_hashbucket *ilb2;
- struct sock *result = NULL;
+ struct sock *result, *reuse_sk;
unsigned int hash2;
+ /* Lookup redirect from BPF */
+ result = inet6_lookup_run_bpf(net, hashinfo->protocol,
+ saddr, sport, daddr, hnum);
+ if (IS_ERR(result))
+ return NULL;
+ if (result) {
+ reuse_sk = lookup_reuseport(net, result, skb, doff,
+ saddr, sport, daddr, hnum);
+ if (reuse_sk)
+ result = reuse_sk;
+ goto done;
+ }
+
hash2 = ipv6_portaddr_hash(net, daddr, hnum);
ilb2 = inet_lhash2_bucket(hashinfo, hash2);
--
2.25.3
Powered by blists - more mailing lists