diff options
author | Craig Gallek <kraig@google.com> | 2016-01-05 15:08:07 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-01-06 01:28:04 -0500 |
commit | 1134158ba3d656b8dbc79a23d482129a531ba0ae (patch) | |
tree | 2b88e0dc8ac5cc9a85c22abe6b11ad082300cd9a /net/ipv6 | |
parent | f0138e2596f2994129451ee320ff8692cb7bc86b (diff) |
soreuseport: pass skb to secondary UDP socket lookup
This socket-lookup path did not pass along the skb in question
in my original BPF-based socket selection patch. The skb in the
udpN_lib_lookup2 path can be used for BPF-based socket selection just
like it is in the 'traditional' udpN_lib_lookup path.
udpN_lib_lookup2 kicks in when there are greater than 10 sockets in
the same hlist slot. Coincidentally, I chose 10 sockets per
reuseport group in my functional test, so the lookup2 path was not
excersised. This adds an additional set of tests with 20 sockets.
Fixes: 538950a1b752 ("soreuseport: setsockopt SO_ATTACH_REUSEPORT_[CE]BPF")
Fixes: 3ca8e4029969 ("soreuseport: BPF selection functional test")
Suggested-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Craig Gallek <kraig@google.com>
Acked-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/udp.c | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 56fcb55fda31..5d2c2afffe7b 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -251,7 +251,8 @@ static inline int compute_score2(struct sock *sk, struct net *net, | |||
251 | static struct sock *udp6_lib_lookup2(struct net *net, | 251 | static struct sock *udp6_lib_lookup2(struct net *net, |
252 | const struct in6_addr *saddr, __be16 sport, | 252 | const struct in6_addr *saddr, __be16 sport, |
253 | const struct in6_addr *daddr, unsigned int hnum, int dif, | 253 | const struct in6_addr *daddr, unsigned int hnum, int dif, |
254 | struct udp_hslot *hslot2, unsigned int slot2) | 254 | struct udp_hslot *hslot2, unsigned int slot2, |
255 | struct sk_buff *skb) | ||
255 | { | 256 | { |
256 | struct sock *sk, *result; | 257 | struct sock *sk, *result; |
257 | struct hlist_nulls_node *node; | 258 | struct hlist_nulls_node *node; |
@@ -272,7 +273,8 @@ begin: | |||
272 | struct sock *sk2; | 273 | struct sock *sk2; |
273 | hash = udp6_ehashfn(net, daddr, hnum, | 274 | hash = udp6_ehashfn(net, daddr, hnum, |
274 | saddr, sport); | 275 | saddr, sport); |
275 | sk2 = reuseport_select_sock(sk, hash, NULL, 0); | 276 | sk2 = reuseport_select_sock(sk, hash, skb, |
277 | sizeof(struct udphdr)); | ||
276 | if (sk2) { | 278 | if (sk2) { |
277 | result = sk2; | 279 | result = sk2; |
278 | goto found; | 280 | goto found; |
@@ -331,7 +333,7 @@ struct sock *__udp6_lib_lookup(struct net *net, | |||
331 | 333 | ||
332 | result = udp6_lib_lookup2(net, saddr, sport, | 334 | result = udp6_lib_lookup2(net, saddr, sport, |
333 | daddr, hnum, dif, | 335 | daddr, hnum, dif, |
334 | hslot2, slot2); | 336 | hslot2, slot2, skb); |
335 | if (!result) { | 337 | if (!result) { |
336 | hash2 = udp6_portaddr_hash(net, &in6addr_any, hnum); | 338 | hash2 = udp6_portaddr_hash(net, &in6addr_any, hnum); |
337 | slot2 = hash2 & udptable->mask; | 339 | slot2 = hash2 & udptable->mask; |
@@ -341,7 +343,7 @@ struct sock *__udp6_lib_lookup(struct net *net, | |||
341 | 343 | ||
342 | result = udp6_lib_lookup2(net, saddr, sport, | 344 | result = udp6_lib_lookup2(net, saddr, sport, |
343 | &in6addr_any, hnum, dif, | 345 | &in6addr_any, hnum, dif, |
344 | hslot2, slot2); | 346 | hslot2, slot2, skb); |
345 | } | 347 | } |
346 | rcu_read_unlock(); | 348 | rcu_read_unlock(); |
347 | return result; | 349 | return result; |