@@ -296,6 +296,57 @@ static inline int sk_reuseport_match(struct inet_bind_bucket *tb,
296
296
ipv6_only_sock (sk ), true, false);
297
297
}
298
298
299
+ void inet_csk_update_fastreuse (struct inet_bind_bucket * tb ,
300
+ struct sock * sk )
301
+ {
302
+ kuid_t uid = sock_i_uid (sk );
303
+ bool reuse = sk -> sk_reuse && sk -> sk_state != TCP_LISTEN ;
304
+
305
+ if (hlist_empty (& tb -> owners )) {
306
+ tb -> fastreuse = reuse ;
307
+ if (sk -> sk_reuseport ) {
308
+ tb -> fastreuseport = FASTREUSEPORT_ANY ;
309
+ tb -> fastuid = uid ;
310
+ tb -> fast_rcv_saddr = sk -> sk_rcv_saddr ;
311
+ tb -> fast_ipv6_only = ipv6_only_sock (sk );
312
+ tb -> fast_sk_family = sk -> sk_family ;
313
+ #if IS_ENABLED (CONFIG_IPV6 )
314
+ tb -> fast_v6_rcv_saddr = sk -> sk_v6_rcv_saddr ;
315
+ #endif
316
+ } else {
317
+ tb -> fastreuseport = 0 ;
318
+ }
319
+ } else {
320
+ if (!reuse )
321
+ tb -> fastreuse = 0 ;
322
+ if (sk -> sk_reuseport ) {
323
+ /* We didn't match or we don't have fastreuseport set on
324
+ * the tb, but we have sk_reuseport set on this socket
325
+ * and we know that there are no bind conflicts with
326
+ * this socket in this tb, so reset our tb's reuseport
327
+ * settings so that any subsequent sockets that match
328
+ * our current socket will be put on the fast path.
329
+ *
330
+ * If we reset we need to set FASTREUSEPORT_STRICT so we
331
+ * do extra checking for all subsequent sk_reuseport
332
+ * socks.
333
+ */
334
+ if (!sk_reuseport_match (tb , sk )) {
335
+ tb -> fastreuseport = FASTREUSEPORT_STRICT ;
336
+ tb -> fastuid = uid ;
337
+ tb -> fast_rcv_saddr = sk -> sk_rcv_saddr ;
338
+ tb -> fast_ipv6_only = ipv6_only_sock (sk );
339
+ tb -> fast_sk_family = sk -> sk_family ;
340
+ #if IS_ENABLED (CONFIG_IPV6 )
341
+ tb -> fast_v6_rcv_saddr = sk -> sk_v6_rcv_saddr ;
342
+ #endif
343
+ }
344
+ } else {
345
+ tb -> fastreuseport = 0 ;
346
+ }
347
+ }
348
+ }
349
+
299
350
/* Obtain a reference to a local port for the given sock,
300
351
* if snum is zero it means select any available local port.
301
352
* We try to allocate an odd port (and leave even ports for connect())
@@ -308,7 +359,6 @@ int inet_csk_get_port(struct sock *sk, unsigned short snum)
308
359
struct inet_bind_hashbucket * head ;
309
360
struct net * net = sock_net (sk );
310
361
struct inet_bind_bucket * tb = NULL ;
311
- kuid_t uid = sock_i_uid (sk );
312
362
int l3mdev ;
313
363
314
364
l3mdev = inet_sk_bound_l3mdev (sk );
@@ -345,49 +395,8 @@ int inet_csk_get_port(struct sock *sk, unsigned short snum)
345
395
goto fail_unlock ;
346
396
}
347
397
success :
348
- if (hlist_empty (& tb -> owners )) {
349
- tb -> fastreuse = reuse ;
350
- if (sk -> sk_reuseport ) {
351
- tb -> fastreuseport = FASTREUSEPORT_ANY ;
352
- tb -> fastuid = uid ;
353
- tb -> fast_rcv_saddr = sk -> sk_rcv_saddr ;
354
- tb -> fast_ipv6_only = ipv6_only_sock (sk );
355
- tb -> fast_sk_family = sk -> sk_family ;
356
- #if IS_ENABLED (CONFIG_IPV6 )
357
- tb -> fast_v6_rcv_saddr = sk -> sk_v6_rcv_saddr ;
358
- #endif
359
- } else {
360
- tb -> fastreuseport = 0 ;
361
- }
362
- } else {
363
- if (!reuse )
364
- tb -> fastreuse = 0 ;
365
- if (sk -> sk_reuseport ) {
366
- /* We didn't match or we don't have fastreuseport set on
367
- * the tb, but we have sk_reuseport set on this socket
368
- * and we know that there are no bind conflicts with
369
- * this socket in this tb, so reset our tb's reuseport
370
- * settings so that any subsequent sockets that match
371
- * our current socket will be put on the fast path.
372
- *
373
- * If we reset we need to set FASTREUSEPORT_STRICT so we
374
- * do extra checking for all subsequent sk_reuseport
375
- * socks.
376
- */
377
- if (!sk_reuseport_match (tb , sk )) {
378
- tb -> fastreuseport = FASTREUSEPORT_STRICT ;
379
- tb -> fastuid = uid ;
380
- tb -> fast_rcv_saddr = sk -> sk_rcv_saddr ;
381
- tb -> fast_ipv6_only = ipv6_only_sock (sk );
382
- tb -> fast_sk_family = sk -> sk_family ;
383
- #if IS_ENABLED (CONFIG_IPV6 )
384
- tb -> fast_v6_rcv_saddr = sk -> sk_v6_rcv_saddr ;
385
- #endif
386
- }
387
- } else {
388
- tb -> fastreuseport = 0 ;
389
- }
390
- }
398
+ inet_csk_update_fastreuse (tb , sk );
399
+
391
400
if (!inet_csk (sk )-> icsk_bind_hash )
392
401
inet_bind_hash (sk , tb , port );
393
402
WARN_ON (inet_csk (sk )-> icsk_bind_hash != tb );
0 commit comments