[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20200506125514.1020829-13-jakub@cloudflare.com>
Date: Wed, 6 May 2020 14:55: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>,
Marek Majkowski <marek@...udflare.com>,
Lorenz Bauer <lmb@...udflare.com>
Subject: [PATCH bpf-next 12/17] udp6: Run SK_LOOKUP BPF program on socket lookup
Same as for udp4, let BPF program override the socket lookup result, by
selecting a receiving socket of its choice or failing the lookup, if no
connected UDP socket matched packet 4-tuple.
Suggested-by: Marek Majkowski <marek@...udflare.com>
Reviewed-by: Lorenz Bauer <lmb@...udflare.com>
Signed-off-by: Jakub Sitnicki <jakub@...udflare.com>
---
net/ipv6/udp.c | 37 ++++++++++++++++++++++++++++---------
1 file changed, 28 insertions(+), 9 deletions(-)
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index ee2073329d25..934f41a5e6ca 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -197,28 +197,47 @@ struct sock *__udp6_lib_lookup(struct net *net,
int dif, int sdif, struct udp_table *udptable,
struct sk_buff *skb)
{
+ struct sock *result, *sk, *reuse_sk;
unsigned short hnum = ntohs(dport);
unsigned int hash2, slot2;
struct udp_hslot *hslot2;
- struct sock *result;
hash2 = ipv6_portaddr_hash(net, daddr, hnum);
slot2 = hash2 & udptable->mask;
hslot2 = &udptable->hash2[slot2];
+ /* Lookup connected or non-wildcard sockets */
result = udp6_lib_lookup2(net, saddr, sport,
daddr, hnum, dif, sdif,
hslot2, skb);
- if (!result) {
- hash2 = ipv6_portaddr_hash(net, &in6addr_any, hnum);
- slot2 = hash2 & udptable->mask;
+ if (!IS_ERR_OR_NULL(result) && result->sk_state == TCP_ESTABLISHED)
+ goto done;
- hslot2 = &udptable->hash2[slot2];
-
- result = udp6_lib_lookup2(net, saddr, sport,
- &in6addr_any, hnum, dif, sdif,
- hslot2, skb);
+ /* Lookup redirect from BPF */
+ sk = inet6_lookup_run_bpf(net, udptable->protocol,
+ saddr, sport, daddr, hnum);
+ if (IS_ERR(sk))
+ return NULL;
+ if (sk) {
+ reuse_sk = lookup_reuseport(net, sk, skb,
+ saddr, sport, daddr, hnum);
+ result = reuse_sk ? : sk;
+ goto done;
}
+
+ /* Got non-wildcard socket or error on first lookup */
+ if (result)
+ goto done;
+
+ /* Lookup wildcard sockets */
+ hash2 = ipv6_portaddr_hash(net, &in6addr_any, hnum);
+ slot2 = hash2 & udptable->mask;
+ hslot2 = &udptable->hash2[slot2];
+
+ result = udp6_lib_lookup2(net, saddr, sport,
+ &in6addr_any, hnum, dif, sdif,
+ hslot2, skb);
+done:
if (IS_ERR(result))
return NULL;
return result;
--
2.25.3
Powered by blists - more mailing lists