Skip to content

Commit e94a62f

Browse files
Paolo Abenidavem330
authored andcommitted
net/reuseport: drop legacy code
Since commit e32ea7e ("soreuseport: fast reuseport UDP socket selection") and commit c125e80 ("soreuseport: fast reuseport TCP socket selection") the relevant reuseport socket matching the current packet is selected by the reuseport_select_sock() call. The only exceptions are invalid BPF filters/filters returning out-of-range indices. In the latter case the code implicitly falls back to using the hash demultiplexing, but instead of selecting the socket inside the reuseport_select_sock() function, it relies on the hash selection logic introduced with the early soreuseport implementation. With this patch, in case of a BPF filter returning a bad socket index value, we fall back to hash-based selection inside the reuseport_select_sock() body, so that we can drop some duplicate code in the ipv4 and ipv6 stack. This also allows faster lookup in the above scenario and will allow us to avoid computing the hash value for successful, BPF based demultiplexing - in a later patch. Signed-off-by: Paolo Abeni <[email protected]> Acked-by: Craig Gallek <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 0fc66dd commit e94a62f

File tree

5 files changed

+15
-55
lines changed

5 files changed

+15
-55
lines changed

net/core/sock_reuseport.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,9 @@ struct sock *reuseport_select_sock(struct sock *sk,
235235

236236
if (prog && skb)
237237
sk2 = run_bpf(reuse, socks, prog, skb, hdr_len);
238-
else
238+
239+
/* no bpf or invalid bpf result: fall back to hash usage */
240+
if (!sk2)
239241
sk2 = reuse->socks[reciprocal_scale(hash, socks)];
240242
}
241243

net/ipv4/inet_hashtables.c

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -216,32 +216,25 @@ struct sock *__inet_lookup_listener(struct net *net,
216216
{
217217
unsigned int hash = inet_lhashfn(net, hnum);
218218
struct inet_listen_hashbucket *ilb = &hashinfo->listening_hash[hash];
219-
int score, hiscore = 0, matches = 0, reuseport = 0;
220219
bool exact_dif = inet_exact_dif_match(net, skb);
221220
struct sock *sk, *result = NULL;
221+
int score, hiscore = 0;
222222
u32 phash = 0;
223223

224224
sk_for_each_rcu(sk, &ilb->head) {
225225
score = compute_score(sk, net, hnum, daddr,
226226
dif, sdif, exact_dif);
227227
if (score > hiscore) {
228-
reuseport = sk->sk_reuseport;
229-
if (reuseport) {
228+
if (sk->sk_reuseport) {
230229
phash = inet_ehashfn(net, daddr, hnum,
231230
saddr, sport);
232231
result = reuseport_select_sock(sk, phash,
233232
skb, doff);
234233
if (result)
235234
return result;
236-
matches = 1;
237235
}
238236
result = sk;
239237
hiscore = score;
240-
} else if (score == hiscore && reuseport) {
241-
matches++;
242-
if (reciprocal_scale(phash, matches) == 0)
243-
result = sk;
244-
phash = next_pseudo_random32(phash);
245238
}
246239
}
247240
return result;

net/ipv4/udp.c

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,7 @@ static struct sock *udp4_lib_lookup2(struct net *net,
445445
struct sk_buff *skb)
446446
{
447447
struct sock *sk, *result;
448-
int score, badness, matches = 0, reuseport = 0;
448+
int score, badness;
449449
u32 hash = 0;
450450

451451
result = NULL;
@@ -454,23 +454,16 @@ static struct sock *udp4_lib_lookup2(struct net *net,
454454
score = compute_score(sk, net, saddr, sport,
455455
daddr, hnum, dif, sdif, exact_dif);
456456
if (score > badness) {
457-
reuseport = sk->sk_reuseport;
458-
if (reuseport) {
457+
if (sk->sk_reuseport) {
459458
hash = udp_ehashfn(net, daddr, hnum,
460459
saddr, sport);
461460
result = reuseport_select_sock(sk, hash, skb,
462461
sizeof(struct udphdr));
463462
if (result)
464463
return result;
465-
matches = 1;
466464
}
467465
badness = score;
468466
result = sk;
469-
} else if (score == badness && reuseport) {
470-
matches++;
471-
if (reciprocal_scale(hash, matches) == 0)
472-
result = sk;
473-
hash = next_pseudo_random32(hash);
474467
}
475468
}
476469
return result;
@@ -488,7 +481,7 @@ struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr,
488481
unsigned int hash2, slot2, slot = udp_hashfn(net, hnum, udptable->mask);
489482
struct udp_hslot *hslot2, *hslot = &udptable->hash[slot];
490483
bool exact_dif = udp_lib_exact_dif_match(net, skb);
491-
int score, badness, matches = 0, reuseport = 0;
484+
int score, badness;
492485
u32 hash = 0;
493486

494487
if (hslot->count > 10) {
@@ -526,23 +519,16 @@ struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr,
526519
score = compute_score(sk, net, saddr, sport,
527520
daddr, hnum, dif, sdif, exact_dif);
528521
if (score > badness) {
529-
reuseport = sk->sk_reuseport;
530-
if (reuseport) {
522+
if (sk->sk_reuseport) {
531523
hash = udp_ehashfn(net, daddr, hnum,
532524
saddr, sport);
533525
result = reuseport_select_sock(sk, hash, skb,
534526
sizeof(struct udphdr));
535527
if (result)
536528
return result;
537-
matches = 1;
538529
}
539530
result = sk;
540531
badness = score;
541-
} else if (score == badness && reuseport) {
542-
matches++;
543-
if (reciprocal_scale(hash, matches) == 0)
544-
result = sk;
545-
hash = next_pseudo_random32(hash);
546532
}
547533
}
548534
return result;

net/ipv6/inet6_hashtables.c

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -134,31 +134,24 @@ struct sock *inet6_lookup_listener(struct net *net,
134134
{
135135
unsigned int hash = inet_lhashfn(net, hnum);
136136
struct inet_listen_hashbucket *ilb = &hashinfo->listening_hash[hash];
137-
int score, hiscore = 0, matches = 0, reuseport = 0;
138137
bool exact_dif = inet6_exact_dif_match(net, skb);
139138
struct sock *sk, *result = NULL;
139+
int score, hiscore = 0;
140140
u32 phash = 0;
141141

142142
sk_for_each(sk, &ilb->head) {
143143
score = compute_score(sk, net, hnum, daddr, dif, sdif, exact_dif);
144144
if (score > hiscore) {
145-
reuseport = sk->sk_reuseport;
146-
if (reuseport) {
145+
if (sk->sk_reuseport) {
147146
phash = inet6_ehashfn(net, daddr, hnum,
148147
saddr, sport);
149148
result = reuseport_select_sock(sk, phash,
150149
skb, doff);
151150
if (result)
152151
return result;
153-
matches = 1;
154152
}
155153
result = sk;
156154
hiscore = score;
157-
} else if (score == hiscore && reuseport) {
158-
matches++;
159-
if (reciprocal_scale(phash, matches) == 0)
160-
result = sk;
161-
phash = next_pseudo_random32(phash);
162155
}
163156
}
164157
return result;

net/ipv6/udp.c

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ static struct sock *udp6_lib_lookup2(struct net *net,
184184
struct udp_hslot *hslot2, struct sk_buff *skb)
185185
{
186186
struct sock *sk, *result;
187-
int score, badness, matches = 0, reuseport = 0;
187+
int score, badness;
188188
u32 hash = 0;
189189

190190
result = NULL;
@@ -193,24 +193,17 @@ static struct sock *udp6_lib_lookup2(struct net *net,
193193
score = compute_score(sk, net, saddr, sport,
194194
daddr, hnum, dif, sdif, exact_dif);
195195
if (score > badness) {
196-
reuseport = sk->sk_reuseport;
197-
if (reuseport) {
196+
if (sk->sk_reuseport) {
198197
hash = udp6_ehashfn(net, daddr, hnum,
199198
saddr, sport);
200199

201200
result = reuseport_select_sock(sk, hash, skb,
202201
sizeof(struct udphdr));
203202
if (result)
204203
return result;
205-
matches = 1;
206204
}
207205
result = sk;
208206
badness = score;
209-
} else if (score == badness && reuseport) {
210-
matches++;
211-
if (reciprocal_scale(hash, matches) == 0)
212-
result = sk;
213-
hash = next_pseudo_random32(hash);
214207
}
215208
}
216209
return result;
@@ -228,7 +221,7 @@ struct sock *__udp6_lib_lookup(struct net *net,
228221
unsigned int hash2, slot2, slot = udp_hashfn(net, hnum, udptable->mask);
229222
struct udp_hslot *hslot2, *hslot = &udptable->hash[slot];
230223
bool exact_dif = udp6_lib_exact_dif_match(net, skb);
231-
int score, badness, matches = 0, reuseport = 0;
224+
int score, badness;
232225
u32 hash = 0;
233226

234227
if (hslot->count > 10) {
@@ -267,23 +260,16 @@ struct sock *__udp6_lib_lookup(struct net *net,
267260
score = compute_score(sk, net, saddr, sport, daddr, hnum, dif,
268261
sdif, exact_dif);
269262
if (score > badness) {
270-
reuseport = sk->sk_reuseport;
271-
if (reuseport) {
263+
if (sk->sk_reuseport) {
272264
hash = udp6_ehashfn(net, daddr, hnum,
273265
saddr, sport);
274266
result = reuseport_select_sock(sk, hash, skb,
275267
sizeof(struct udphdr));
276268
if (result)
277269
return result;
278-
matches = 1;
279270
}
280271
result = sk;
281272
badness = score;
282-
} else if (score == badness && reuseport) {
283-
matches++;
284-
if (reciprocal_scale(hash, matches) == 0)
285-
result = sk;
286-
hash = next_pseudo_random32(hash);
287273
}
288274
}
289275
return result;

0 commit comments

Comments
 (0)