diff options
author | Craig Gallek <kraig@google.com> | 2016-01-04 17:41:47 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-01-04 22:49:59 -0500 |
commit | 538950a1b7527a0a52ccd9337e3fcd304f027f13 (patch) | |
tree | 2ecd86127a55719e61ea9a37aeb1cc7be8022d0f /net/ipv6 | |
parent | e32ea7e747271a0abcd37e265005e97cc81d9df5 (diff) |
soreuseport: setsockopt SO_ATTACH_REUSEPORT_[CE]BPF
Expose socket options for setting a classic or extended BPF program
for use when selecting sockets in an SO_REUSEPORT group. These options
can be used on the first socket to belong to a group before bind or
on any socket in the group after bind.
This change includes refactoring of the existing sk_filter code to
allow reuse of the existing BPF filter validation checks.
Signed-off-by: Craig Gallek <kraig@google.com>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/udp.c | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 6204b8992de4..56fcb55fda31 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -272,7 +272,7 @@ begin: | |||
272 | struct sock *sk2; | 272 | struct sock *sk2; |
273 | hash = udp6_ehashfn(net, daddr, hnum, | 273 | hash = udp6_ehashfn(net, daddr, hnum, |
274 | saddr, sport); | 274 | saddr, sport); |
275 | sk2 = reuseport_select_sock(sk, hash); | 275 | sk2 = reuseport_select_sock(sk, hash, NULL, 0); |
276 | if (sk2) { | 276 | if (sk2) { |
277 | result = sk2; | 277 | result = sk2; |
278 | goto found; | 278 | goto found; |
@@ -310,7 +310,8 @@ found: | |||
310 | struct sock *__udp6_lib_lookup(struct net *net, | 310 | struct sock *__udp6_lib_lookup(struct net *net, |
311 | const struct in6_addr *saddr, __be16 sport, | 311 | const struct in6_addr *saddr, __be16 sport, |
312 | const struct in6_addr *daddr, __be16 dport, | 312 | const struct in6_addr *daddr, __be16 dport, |
313 | int dif, struct udp_table *udptable) | 313 | int dif, struct udp_table *udptable, |
314 | struct sk_buff *skb) | ||
314 | { | 315 | { |
315 | struct sock *sk, *result; | 316 | struct sock *sk, *result; |
316 | struct hlist_nulls_node *node; | 317 | struct hlist_nulls_node *node; |
@@ -358,7 +359,8 @@ begin: | |||
358 | struct sock *sk2; | 359 | struct sock *sk2; |
359 | hash = udp6_ehashfn(net, daddr, hnum, | 360 | hash = udp6_ehashfn(net, daddr, hnum, |
360 | saddr, sport); | 361 | saddr, sport); |
361 | sk2 = reuseport_select_sock(sk, hash); | 362 | sk2 = reuseport_select_sock(sk, hash, skb, |
363 | sizeof(struct udphdr)); | ||
362 | if (sk2) { | 364 | if (sk2) { |
363 | result = sk2; | 365 | result = sk2; |
364 | goto found; | 366 | goto found; |
@@ -407,13 +409,13 @@ static struct sock *__udp6_lib_lookup_skb(struct sk_buff *skb, | |||
407 | return sk; | 409 | return sk; |
408 | return __udp6_lib_lookup(dev_net(skb_dst(skb)->dev), &iph->saddr, sport, | 410 | return __udp6_lib_lookup(dev_net(skb_dst(skb)->dev), &iph->saddr, sport, |
409 | &iph->daddr, dport, inet6_iif(skb), | 411 | &iph->daddr, dport, inet6_iif(skb), |
410 | udptable); | 412 | udptable, skb); |
411 | } | 413 | } |
412 | 414 | ||
413 | struct sock *udp6_lib_lookup(struct net *net, const struct in6_addr *saddr, __be16 sport, | 415 | struct sock *udp6_lib_lookup(struct net *net, const struct in6_addr *saddr, __be16 sport, |
414 | const struct in6_addr *daddr, __be16 dport, int dif) | 416 | const struct in6_addr *daddr, __be16 dport, int dif) |
415 | { | 417 | { |
416 | return __udp6_lib_lookup(net, saddr, sport, daddr, dport, dif, &udp_table); | 418 | return __udp6_lib_lookup(net, saddr, sport, daddr, dport, dif, &udp_table, NULL); |
417 | } | 419 | } |
418 | EXPORT_SYMBOL_GPL(udp6_lib_lookup); | 420 | EXPORT_SYMBOL_GPL(udp6_lib_lookup); |
419 | 421 | ||
@@ -580,7 +582,7 @@ void __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
580 | struct net *net = dev_net(skb->dev); | 582 | struct net *net = dev_net(skb->dev); |
581 | 583 | ||
582 | sk = __udp6_lib_lookup(net, daddr, uh->dest, saddr, uh->source, | 584 | sk = __udp6_lib_lookup(net, daddr, uh->dest, saddr, uh->source, |
583 | inet6_iif(skb), udptable); | 585 | inet6_iif(skb), udptable, skb); |
584 | if (!sk) { | 586 | if (!sk) { |
585 | ICMP6_INC_STATS_BH(net, __in6_dev_get(skb->dev), | 587 | ICMP6_INC_STATS_BH(net, __in6_dev_get(skb->dev), |
586 | ICMP6_MIB_INERRORS); | 588 | ICMP6_MIB_INERRORS); |