Skip to content

Commit 1134158

Browse files
kraigatgoogdavem330
authored andcommitted
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: 538950a ("soreuseport: setsockopt SO_ATTACH_REUSEPORT_[CE]BPF") Fixes: 3ca8e40 ("soreuseport: BPF selection functional test") Suggested-by: Eric Dumazet <[email protected]> Signed-off-by: Craig Gallek <[email protected]> Acked-by: Eric Dumazet <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent f0138e2 commit 1134158

File tree

3 files changed

+59
-8
lines changed

3 files changed

+59
-8
lines changed

net/ipv4/udp.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -493,7 +493,8 @@ static u32 udp_ehashfn(const struct net *net, const __be32 laddr,
493493
static struct sock *udp4_lib_lookup2(struct net *net,
494494
__be32 saddr, __be16 sport,
495495
__be32 daddr, unsigned int hnum, int dif,
496-
struct udp_hslot *hslot2, unsigned int slot2)
496+
struct udp_hslot *hslot2, unsigned int slot2,
497+
struct sk_buff *skb)
497498
{
498499
struct sock *sk, *result;
499500
struct hlist_nulls_node *node;
@@ -514,7 +515,8 @@ static struct sock *udp4_lib_lookup2(struct net *net,
514515
struct sock *sk2;
515516
hash = udp_ehashfn(net, daddr, hnum,
516517
saddr, sport);
517-
sk2 = reuseport_select_sock(sk, hash, NULL, 0);
518+
sk2 = reuseport_select_sock(sk, hash, skb,
519+
sizeof(struct udphdr));
518520
if (sk2) {
519521
result = sk2;
520522
goto found;
@@ -573,7 +575,7 @@ struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr,
573575

574576
result = udp4_lib_lookup2(net, saddr, sport,
575577
daddr, hnum, dif,
576-
hslot2, slot2);
578+
hslot2, slot2, skb);
577579
if (!result) {
578580
hash2 = udp4_portaddr_hash(net, htonl(INADDR_ANY), hnum);
579581
slot2 = hash2 & udptable->mask;
@@ -583,7 +585,7 @@ struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr,
583585

584586
result = udp4_lib_lookup2(net, saddr, sport,
585587
htonl(INADDR_ANY), hnum, dif,
586-
hslot2, slot2);
588+
hslot2, slot2, skb);
587589
}
588590
rcu_read_unlock();
589591
return result;

net/ipv6/udp.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,8 @@ static inline int compute_score2(struct sock *sk, struct net *net,
251251
static struct sock *udp6_lib_lookup2(struct net *net,
252252
const struct in6_addr *saddr, __be16 sport,
253253
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)
255256
{
256257
struct sock *sk, *result;
257258
struct hlist_nulls_node *node;
@@ -272,7 +273,8 @@ static struct sock *udp6_lib_lookup2(struct net *net,
272273
struct sock *sk2;
273274
hash = udp6_ehashfn(net, daddr, hnum,
274275
saddr, sport);
275-
sk2 = reuseport_select_sock(sk, hash, NULL, 0);
276+
sk2 = reuseport_select_sock(sk, hash, skb,
277+
sizeof(struct udphdr));
276278
if (sk2) {
277279
result = sk2;
278280
goto found;
@@ -331,7 +333,7 @@ struct sock *__udp6_lib_lookup(struct net *net,
331333

332334
result = udp6_lib_lookup2(net, saddr, sport,
333335
daddr, hnum, dif,
334-
hslot2, slot2);
336+
hslot2, slot2, skb);
335337
if (!result) {
336338
hash2 = udp6_portaddr_hash(net, &in6addr_any, hnum);
337339
slot2 = hash2 & udptable->mask;
@@ -341,7 +343,7 @@ struct sock *__udp6_lib_lookup(struct net *net,
341343

342344
result = udp6_lib_lookup2(net, saddr, sport,
343345
&in6addr_any, hnum, dif,
344-
hslot2, slot2);
346+
hslot2, slot2, skb);
345347
}
346348
rcu_read_unlock();
347349
return result;

tools/testing/selftests/net/reuseport_bpf.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@ static void attach_ebpf(int fd, uint16_t mod)
123123
if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_REUSEPORT_EBPF, &bpf_fd,
124124
sizeof(bpf_fd)))
125125
error(1, errno, "failed to set SO_ATTACH_REUSEPORT_EBPF");
126+
127+
close(bpf_fd);
126128
}
127129

128130
static void attach_cbpf(int fd, uint16_t mod)
@@ -396,20 +398,37 @@ static void test_filter_without_bind(void)
396398
int main(void)
397399
{
398400
fprintf(stderr, "---- IPv4 UDP ----\n");
401+
/* NOTE: UDP socket lookups traverse a different code path when there
402+
* are > 10 sockets in a group. Run the bpf test through both paths.
403+
*/
399404
test_reuseport_ebpf((struct test_params) {
400405
.recv_family = AF_INET,
401406
.send_family = AF_INET,
402407
.protocol = SOCK_DGRAM,
403408
.recv_socks = 10,
404409
.recv_port = 8000,
405410
.send_port_min = 9000});
411+
test_reuseport_ebpf((struct test_params) {
412+
.recv_family = AF_INET,
413+
.send_family = AF_INET,
414+
.protocol = SOCK_DGRAM,
415+
.recv_socks = 20,
416+
.recv_port = 8000,
417+
.send_port_min = 9000});
406418
test_reuseport_cbpf((struct test_params) {
407419
.recv_family = AF_INET,
408420
.send_family = AF_INET,
409421
.protocol = SOCK_DGRAM,
410422
.recv_socks = 10,
411423
.recv_port = 8001,
412424
.send_port_min = 9020});
425+
test_reuseport_cbpf((struct test_params) {
426+
.recv_family = AF_INET,
427+
.send_family = AF_INET,
428+
.protocol = SOCK_DGRAM,
429+
.recv_socks = 20,
430+
.recv_port = 8001,
431+
.send_port_min = 9020});
413432
test_extra_filter((struct test_params) {
414433
.recv_family = AF_INET,
415434
.protocol = SOCK_DGRAM,
@@ -427,13 +446,27 @@ int main(void)
427446
.recv_socks = 10,
428447
.recv_port = 8003,
429448
.send_port_min = 9040});
449+
test_reuseport_ebpf((struct test_params) {
450+
.recv_family = AF_INET6,
451+
.send_family = AF_INET6,
452+
.protocol = SOCK_DGRAM,
453+
.recv_socks = 20,
454+
.recv_port = 8003,
455+
.send_port_min = 9040});
430456
test_reuseport_cbpf((struct test_params) {
431457
.recv_family = AF_INET6,
432458
.send_family = AF_INET6,
433459
.protocol = SOCK_DGRAM,
434460
.recv_socks = 10,
435461
.recv_port = 8004,
436462
.send_port_min = 9060});
463+
test_reuseport_cbpf((struct test_params) {
464+
.recv_family = AF_INET6,
465+
.send_family = AF_INET6,
466+
.protocol = SOCK_DGRAM,
467+
.recv_socks = 20,
468+
.recv_port = 8004,
469+
.send_port_min = 9060});
437470
test_extra_filter((struct test_params) {
438471
.recv_family = AF_INET6,
439472
.protocol = SOCK_DGRAM,
@@ -444,6 +477,13 @@ int main(void)
444477
.recv_port = 8009});
445478

446479
fprintf(stderr, "---- IPv6 UDP w/ mapped IPv4 ----\n");
480+
test_reuseport_ebpf((struct test_params) {
481+
.recv_family = AF_INET6,
482+
.send_family = AF_INET,
483+
.protocol = SOCK_DGRAM,
484+
.recv_socks = 20,
485+
.recv_port = 8006,
486+
.send_port_min = 9080});
447487
test_reuseport_ebpf((struct test_params) {
448488
.recv_family = AF_INET6,
449489
.send_family = AF_INET,
@@ -458,6 +498,13 @@ int main(void)
458498
.recv_socks = 10,
459499
.recv_port = 8007,
460500
.send_port_min = 9100});
501+
test_reuseport_cbpf((struct test_params) {
502+
.recv_family = AF_INET6,
503+
.send_family = AF_INET,
504+
.protocol = SOCK_DGRAM,
505+
.recv_socks = 20,
506+
.recv_port = 8007,
507+
.send_port_min = 9100});
461508

462509

463510
test_filter_without_bind();

0 commit comments

Comments
 (0)