diff mbox series

[net,1/7] secure_seq: return the full 64-bit of the siphash

Message ID 20220427065233.2075-2-w@1wt.eu (mailing list archive)
State Superseded
Delegated to: Netdev Maintainers
Headers show
Series insufficient TCP source port randomness | expand

Checks

Context Check Description
netdev/tree_selection success Clearly marked for net
netdev/fixes_present fail Series targets non-next tree, but doesn't contain any Fixes tags
netdev/subject_prefix success Link
netdev/cover_letter success Series has a cover letter
netdev/patch_count success Link
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit fail Errors and warnings before: 1112 this patch: 1112
netdev/cc_maintainers warning 3 maintainers not CCed: yoshfuji@linux-ipv6.org dsahern@kernel.org pabeni@redhat.com
netdev/build_clang success Errors and warnings before: 139 this patch: 139
netdev/module_param success Was 0 now: 0
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 1117 this patch: 1117
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 48 lines checked
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Willy Tarreau April 27, 2022, 6:52 a.m. UTC
SipHash replaced MD5 in secure_ipv4_port_ephemeral() via commit
7cd23e5300c1 ("secure_seq: use SipHash in place of MD5"), but the
output remained truncated to 32-bit only. In order to exploit more
bits from the hash, let's make the function return the full 64-bit
of siphash_3u32().

Cc: Jason A. Donenfeld <Jason@zx2c4.com>
Cc: Moshe Kol <moshe.kol@mail.huji.ac.il>
Cc: Yossi Gilad <yossi.gilad@mail.huji.ac.il>
Cc: Amit Klein <aksecurity@gmail.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Willy Tarreau <w@1wt.eu>
---
 include/net/inet_hashtables.h | 2 +-
 include/net/secure_seq.h      | 2 +-
 net/core/secure_seq.c         | 2 +-
 net/ipv4/inet_hashtables.c    | 6 +++---
 4 files changed, 6 insertions(+), 6 deletions(-)

Comments

kernel test robot April 27, 2022, 9:56 a.m. UTC | #1
Hi Willy,

I love your patch! Yet something to improve:

[auto build test ERROR on net/master]

url:    https://github.com/intel-lab-lkp/linux/commits/Willy-Tarreau/insufficient-TCP-source-port-randomness/20220427-145651
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git 71cffebf6358a7f5031f5b208bbdc1cb4db6e539
config: i386-randconfig-r026-20220425 (https://download.01.org/0day-ci/archive/20220427/202204271705.VrWNPv7n-lkp@intel.com/config)
compiler: gcc-11 (Debian 11.2.0-20) 11.2.0
reproduce (this is a W=1 build):
        # https://github.com/intel-lab-lkp/linux/commit/01b26e522b598adf346b809075880feab3dcdc08
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Willy-Tarreau/insufficient-TCP-source-port-randomness/20220427-145651
        git checkout 01b26e522b598adf346b809075880feab3dcdc08
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        make W=1 O=build_dir ARCH=i386 SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   ld: net/ipv4/inet_hashtables.o: in function `__inet_hash_connect':
>> inet_hashtables.c:(.text+0x187d): undefined reference to `__umoddi3'
Willy Tarreau April 27, 2022, 10:07 a.m. UTC | #2
On Wed, Apr 27, 2022 at 05:56:41PM +0800, kernel test robot wrote:
> Hi Willy,
> 
> I love your patch! Yet something to improve:
> 
> [auto build test ERROR on net/master]
> 
> url:    https://github.com/intel-lab-lkp/linux/commits/Willy-Tarreau/insufficient-TCP-source-port-randomness/20220427-145651
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git 71cffebf6358a7f5031f5b208bbdc1cb4db6e539
> config: i386-randconfig-r026-20220425 (https://download.01.org/0day-ci/archive/20220427/202204271705.VrWNPv7n-lkp@intel.com/config)
> compiler: gcc-11 (Debian 11.2.0-20) 11.2.0
> reproduce (this is a W=1 build):
>         # https://github.com/intel-lab-lkp/linux/commit/01b26e522b598adf346b809075880feab3dcdc08
>         git remote add linux-review https://github.com/intel-lab-lkp/linux
>         git fetch --no-tags linux-review Willy-Tarreau/insufficient-TCP-source-port-randomness/20220427-145651
>         git checkout 01b26e522b598adf346b809075880feab3dcdc08
>         # save the config file
>         mkdir build_dir && cp config build_dir/.config
>         make W=1 O=build_dir ARCH=i386 SHELL=/bin/bash
> 
> If you fix the issue, kindly add following tag as appropriate
> Reported-by: kernel test robot <lkp@intel.com>
> 
> All errors (new ones prefixed by >>):
> 
>    ld: net/ipv4/inet_hashtables.o: in function `__inet_hash_connect':
> >> inet_hashtables.c:(.text+0x187d): undefined reference to `__umoddi3'

Argh! indeed, we spoke about using div_u64_rem() at the beginning and
that one vanished over time. Will respin it.

Thanks,
Willy
Willy Tarreau April 27, 2022, 4:35 p.m. UTC | #3
On Wed, Apr 27, 2022 at 12:07:14PM +0200, Willy Tarreau wrote:
> On Wed, Apr 27, 2022 at 05:56:41PM +0800, kernel test robot wrote:
> > Hi Willy,
> > 
> > I love your patch! Yet something to improve:
> > 
> > [auto build test ERROR on net/master]
> > 
> > url:    https://github.com/intel-lab-lkp/linux/commits/Willy-Tarreau/insufficient-TCP-source-port-randomness/20220427-145651
> > base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git 71cffebf6358a7f5031f5b208bbdc1cb4db6e539
> > config: i386-randconfig-r026-20220425 (https://download.01.org/0day-ci/archive/20220427/202204271705.VrWNPv7n-lkp@intel.com/config)
> > compiler: gcc-11 (Debian 11.2.0-20) 11.2.0
> > reproduce (this is a W=1 build):
> >         # https://github.com/intel-lab-lkp/linux/commit/01b26e522b598adf346b809075880feab3dcdc08
> >         git remote add linux-review https://github.com/intel-lab-lkp/linux
> >         git fetch --no-tags linux-review Willy-Tarreau/insufficient-TCP-source-port-randomness/20220427-145651
> >         git checkout 01b26e522b598adf346b809075880feab3dcdc08
> >         # save the config file
> >         mkdir build_dir && cp config build_dir/.config
> >         make W=1 O=build_dir ARCH=i386 SHELL=/bin/bash
> > 
> > If you fix the issue, kindly add following tag as appropriate
> > Reported-by: kernel test robot <lkp@intel.com>
> > 
> > All errors (new ones prefixed by >>):
> > 
> >    ld: net/ipv4/inet_hashtables.o: in function `__inet_hash_connect':
> > >> inet_hashtables.c:(.text+0x187d): undefined reference to `__umoddi3'
> 
> Argh! indeed, we spoke about using div_u64_rem() at the beginning and
> that one vanished over time. Will respin it.

I fixed it, built it for i386 and x86_64, tested it on x86_64 and confirmed
that it still does what I need. The change is only this:

-       offset = (READ_ONCE(table_perturb[index]) + (port_offset >> 32)) % remaining;
+       div_u64_rem(READ_ONCE(table_perturb[index]) + (port_offset >> 32), remaining, &offset);

I'll send a v2 series in a few hours if there are no more comments.

Willy
Eric Dumazet April 27, 2022, 4:50 p.m. UTC | #4
On Wed, Apr 27, 2022 at 9:35 AM Willy Tarreau <w@1wt.eu> wrote:
>
> On Wed, Apr 27, 2022 at 12:07:14PM +0200, Willy Tarreau wrote:
> > On Wed, Apr 27, 2022 at 05:56:41PM +0800, kernel test robot wrote:
> > > Hi Willy,
> > >
> > > I love your patch! Yet something to improve:
> > >
> > > [auto build test ERROR on net/master]
> > >
> > > url:    https://github.com/intel-lab-lkp/linux/commits/Willy-Tarreau/insufficient-TCP-source-port-randomness/20220427-145651
> > > base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git 71cffebf6358a7f5031f5b208bbdc1cb4db6e539
> > > config: i386-randconfig-r026-20220425 (https://download.01.org/0day-ci/archive/20220427/202204271705.VrWNPv7n-lkp@intel.com/config)
> > > compiler: gcc-11 (Debian 11.2.0-20) 11.2.0
> > > reproduce (this is a W=1 build):
> > >         # https://github.com/intel-lab-lkp/linux/commit/01b26e522b598adf346b809075880feab3dcdc08
> > >         git remote add linux-review https://github.com/intel-lab-lkp/linux
> > >         git fetch --no-tags linux-review Willy-Tarreau/insufficient-TCP-source-port-randomness/20220427-145651
> > >         git checkout 01b26e522b598adf346b809075880feab3dcdc08
> > >         # save the config file
> > >         mkdir build_dir && cp config build_dir/.config
> > >         make W=1 O=build_dir ARCH=i386 SHELL=/bin/bash
> > >
> > > If you fix the issue, kindly add following tag as appropriate
> > > Reported-by: kernel test robot <lkp@intel.com>
> > >
> > > All errors (new ones prefixed by >>):
> > >
> > >    ld: net/ipv4/inet_hashtables.o: in function `__inet_hash_connect':
> > > >> inet_hashtables.c:(.text+0x187d): undefined reference to `__umoddi3'
> >
> > Argh! indeed, we spoke about using div_u64_rem() at the beginning and
> > that one vanished over time. Will respin it.
>
> I fixed it, built it for i386 and x86_64, tested it on x86_64 and confirmed
> that it still does what I need. The change is only this:
>
> -       offset = (READ_ONCE(table_perturb[index]) + (port_offset >> 32)) % remaining;
> +       div_u64_rem(READ_ONCE(table_perturb[index]) + (port_offset >> 32), remaining, &offset);
>
> I'll send a v2 series in a few hours if there are no more comments.

We really do not need 33 bits here.

I would suggest using a 32bit divide.

offset = READ_ONCE(table_perturb[index]) + (port_offset >> 32));
offset %= remaining;
Willy Tarreau April 27, 2022, 4:56 p.m. UTC | #5
On Wed, Apr 27, 2022 at 09:50:06AM -0700, Eric Dumazet wrote:
> On Wed, Apr 27, 2022 at 9:35 AM Willy Tarreau <w@1wt.eu> wrote:
> >
> > On Wed, Apr 27, 2022 at 12:07:14PM +0200, Willy Tarreau wrote:
> > > On Wed, Apr 27, 2022 at 05:56:41PM +0800, kernel test robot wrote:
> > > > Hi Willy,
> > > >
> > > > I love your patch! Yet something to improve:
> > > >
> > > > [auto build test ERROR on net/master]
> > > >
> > > > url:    https://github.com/intel-lab-lkp/linux/commits/Willy-Tarreau/insufficient-TCP-source-port-randomness/20220427-145651
> > > > base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git 71cffebf6358a7f5031f5b208bbdc1cb4db6e539
> > > > config: i386-randconfig-r026-20220425 (https://download.01.org/0day-ci/archive/20220427/202204271705.VrWNPv7n-lkp@intel.com/config)
> > > > compiler: gcc-11 (Debian 11.2.0-20) 11.2.0
> > > > reproduce (this is a W=1 build):
> > > >         # https://github.com/intel-lab-lkp/linux/commit/01b26e522b598adf346b809075880feab3dcdc08
> > > >         git remote add linux-review https://github.com/intel-lab-lkp/linux
> > > >         git fetch --no-tags linux-review Willy-Tarreau/insufficient-TCP-source-port-randomness/20220427-145651
> > > >         git checkout 01b26e522b598adf346b809075880feab3dcdc08
> > > >         # save the config file
> > > >         mkdir build_dir && cp config build_dir/.config
> > > >         make W=1 O=build_dir ARCH=i386 SHELL=/bin/bash
> > > >
> > > > If you fix the issue, kindly add following tag as appropriate
> > > > Reported-by: kernel test robot <lkp@intel.com>
> > > >
> > > > All errors (new ones prefixed by >>):
> > > >
> > > >    ld: net/ipv4/inet_hashtables.o: in function `__inet_hash_connect':
> > > > >> inet_hashtables.c:(.text+0x187d): undefined reference to `__umoddi3'
> > >
> > > Argh! indeed, we spoke about using div_u64_rem() at the beginning and
> > > that one vanished over time. Will respin it.
> >
> > I fixed it, built it for i386 and x86_64, tested it on x86_64 and confirmed
> > that it still does what I need. The change is only this:
> >
> > -       offset = (READ_ONCE(table_perturb[index]) + (port_offset >> 32)) % remaining;
> > +       div_u64_rem(READ_ONCE(table_perturb[index]) + (port_offset >> 32), remaining, &offset);
> >
> > I'll send a v2 series in a few hours if there are no more comments.
> 
> We really do not need 33 bits here.
> 
> I would suggest using a 32bit divide.
> 
> offset = READ_ONCE(table_perturb[index]) + (port_offset >> 32));
> offset %= remaining;

Yeah much better indeed, I'll do that. Thanks Eric!

Willy
Jason A. Donenfeld April 27, 2022, 5:18 p.m. UTC | #6
Hi Willy,

On Wed, Apr 27, 2022 at 08:52:27AM +0200, Willy Tarreau wrote:
> diff --git a/include/net/secure_seq.h b/include/net/secure_seq.h
> index d7d2495f83c2..5cea9ed9c773 100644
> --- a/include/net/secure_seq.h
> +++ b/include/net/secure_seq.h
> @@ -4,7 +4,7 @@
>  
>  #include <linux/types.h>
>  
> -u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport);
> +u64 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport);
>  u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr,
>  			       __be16 dport);
>  u32 secure_tcp_seq(__be32 saddr, __be32 daddr,
> diff --git a/net/core/secure_seq.c b/net/core/secure_seq.c
> index 9b8443774449..2cdd43a63f64 100644
> --- a/net/core/secure_seq.c
> +++ b/net/core/secure_seq.c
> @@ -142,7 +142,7 @@ u32 secure_tcp_seq(__be32 saddr, __be32 daddr,
>  }
>  EXPORT_SYMBOL_GPL(secure_tcp_seq);
>  
> -u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport)
> +u64 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport)
>  {
>  	net_secret_init();
>  	return siphash_3u32((__force u32)saddr, (__force u32)daddr,

Should you be doing the same with secure_ipv6_port_ephemeral() too? Why
the asymmetry?

Jason
Willy Tarreau April 27, 2022, 8:19 p.m. UTC | #7
Hi Jason,

On Wed, Apr 27, 2022 at 07:18:48PM +0200, Jason A. Donenfeld wrote:
> Hi Willy,
> 
> On Wed, Apr 27, 2022 at 08:52:27AM +0200, Willy Tarreau wrote:
> > diff --git a/include/net/secure_seq.h b/include/net/secure_seq.h
> > index d7d2495f83c2..5cea9ed9c773 100644
> > --- a/include/net/secure_seq.h
> > +++ b/include/net/secure_seq.h
> > @@ -4,7 +4,7 @@
> >  
> >  #include <linux/types.h>
> >  
> > -u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport);
> > +u64 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport);
> >  u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr,
> >  			       __be16 dport);
> >  u32 secure_tcp_seq(__be32 saddr, __be32 daddr,
> > diff --git a/net/core/secure_seq.c b/net/core/secure_seq.c
> > index 9b8443774449..2cdd43a63f64 100644
> > --- a/net/core/secure_seq.c
> > +++ b/net/core/secure_seq.c
> > @@ -142,7 +142,7 @@ u32 secure_tcp_seq(__be32 saddr, __be32 daddr,
> >  }
> >  EXPORT_SYMBOL_GPL(secure_tcp_seq);
> >  
> > -u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport)
> > +u64 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport)
> >  {
> >  	net_secret_init();
> >  	return siphash_3u32((__force u32)saddr, (__force u32)daddr,
> 
> Should you be doing the same with secure_ipv6_port_ephemeral() too? Why
> the asymmetry?

I remember not finding it in the similar code path, but maybe I missed
something. It's used by inet6_sk_port_offset() which also returns a u32,
itself used by inet6_hash_connect() and passed to __inet_hash_connect().

Hmmm the loop is now closed, I don't know how I missed it. So yes I
agree that it would definitely be needed. I'll update the patch, many
thanks!

Willy
kernel test robot April 28, 2022, 1:59 a.m. UTC | #8
Hi Willy,

I love your patch! Yet something to improve:

[auto build test ERROR on net/master]

url:    https://github.com/intel-lab-lkp/linux/commits/Willy-Tarreau/insufficient-TCP-source-port-randomness/20220427-145651
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git 71cffebf6358a7f5031f5b208bbdc1cb4db6e539
config: i386-randconfig-a011-20220425 (https://download.01.org/0day-ci/archive/20220428/202204280348.UBtfnU6Q-lkp@intel.com/config)
compiler: gcc-11 (Debian 11.2.0-20) 11.2.0
reproduce (this is a W=1 build):
        # https://github.com/intel-lab-lkp/linux/commit/01b26e522b598adf346b809075880feab3dcdc08
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Willy-Tarreau/insufficient-TCP-source-port-randomness/20220427-145651
        git checkout 01b26e522b598adf346b809075880feab3dcdc08
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        make W=1 O=build_dir ARCH=i386 SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   ld: net/ipv4/inet_hashtables.o: in function `__inet_hash_connect':
>> net/ipv4/inet_hashtables.c:780: undefined reference to `__umoddi3'


vim +780 net/ipv4/inet_hashtables.c

190cc82489f46f Eric Dumazet             2021-02-09  735  
5ee31fc1ecdcbc Pavel Emelyanov          2008-01-31  736  int __inet_hash_connect(struct inet_timewait_death_row *death_row,
01b26e522b598a Willy Tarreau            2022-04-27  737  		struct sock *sk, u64 port_offset,
5ee31fc1ecdcbc Pavel Emelyanov          2008-01-31  738  		int (*check_established)(struct inet_timewait_death_row *,
b4d6444ea3b50b Eric Dumazet             2015-03-18  739  			struct sock *, __u16, struct inet_timewait_sock **))
a7f5e7f164788a Arnaldo Carvalho de Melo 2005-12-13  740  {
a7f5e7f164788a Arnaldo Carvalho de Melo 2005-12-13  741  	struct inet_hashinfo *hinfo = death_row->hashinfo;
1580ab63fc9a03 Eric Dumazet             2016-02-11  742  	struct inet_timewait_sock *tw = NULL;
a7f5e7f164788a Arnaldo Carvalho de Melo 2005-12-13  743  	struct inet_bind_hashbucket *head;
1580ab63fc9a03 Eric Dumazet             2016-02-11  744  	int port = inet_sk(sk)->inet_num;
3b1e0a655f8eba YOSHIFUJI Hideaki        2008-03-26  745  	struct net *net = sock_net(sk);
1580ab63fc9a03 Eric Dumazet             2016-02-11  746  	struct inet_bind_bucket *tb;
1580ab63fc9a03 Eric Dumazet             2016-02-11  747  	u32 remaining, offset;
1580ab63fc9a03 Eric Dumazet             2016-02-11  748  	int ret, i, low, high;
3c82a21f4320c8 Robert Shearman          2018-11-07  749  	int l3mdev;
190cc82489f46f Eric Dumazet             2021-02-09  750  	u32 index;
a7f5e7f164788a Arnaldo Carvalho de Melo 2005-12-13  751  
1580ab63fc9a03 Eric Dumazet             2016-02-11  752  	if (port) {
1580ab63fc9a03 Eric Dumazet             2016-02-11  753  		head = &hinfo->bhash[inet_bhashfn(net, port,
1580ab63fc9a03 Eric Dumazet             2016-02-11  754  						  hinfo->bhash_size)];
1580ab63fc9a03 Eric Dumazet             2016-02-11  755  		tb = inet_csk(sk)->icsk_bind_hash;
1580ab63fc9a03 Eric Dumazet             2016-02-11  756  		spin_lock_bh(&head->lock);
1580ab63fc9a03 Eric Dumazet             2016-02-11  757  		if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) {
01770a16616573 Ricardo Dias             2020-11-20  758  			inet_ehash_nolisten(sk, NULL, NULL);
1580ab63fc9a03 Eric Dumazet             2016-02-11  759  			spin_unlock_bh(&head->lock);
1580ab63fc9a03 Eric Dumazet             2016-02-11  760  			return 0;
1580ab63fc9a03 Eric Dumazet             2016-02-11  761  		}
1580ab63fc9a03 Eric Dumazet             2016-02-11  762  		spin_unlock(&head->lock);
1580ab63fc9a03 Eric Dumazet             2016-02-11  763  		/* No definite answer... Walk to established hash table */
1580ab63fc9a03 Eric Dumazet             2016-02-11  764  		ret = check_established(death_row, sk, port, NULL);
1580ab63fc9a03 Eric Dumazet             2016-02-11  765  		local_bh_enable();
1580ab63fc9a03 Eric Dumazet             2016-02-11  766  		return ret;
1580ab63fc9a03 Eric Dumazet             2016-02-11  767  	}
227b60f5102cda Stephen Hemminger        2007-10-10  768  
3c82a21f4320c8 Robert Shearman          2018-11-07  769  	l3mdev = inet_sk_bound_l3mdev(sk);
3c82a21f4320c8 Robert Shearman          2018-11-07  770  
1580ab63fc9a03 Eric Dumazet             2016-02-11  771  	inet_get_local_port_range(net, &low, &high);
1580ab63fc9a03 Eric Dumazet             2016-02-11  772  	high++; /* [32768, 60999] -> [32768, 61000[ */
1580ab63fc9a03 Eric Dumazet             2016-02-11  773  	remaining = high - low;
1580ab63fc9a03 Eric Dumazet             2016-02-11  774  	if (likely(remaining > 1))
1580ab63fc9a03 Eric Dumazet             2016-02-11  775  		remaining &= ~1U;
1580ab63fc9a03 Eric Dumazet             2016-02-11  776  
190cc82489f46f Eric Dumazet             2021-02-09  777  	net_get_random_once(table_perturb, sizeof(table_perturb));
190cc82489f46f Eric Dumazet             2021-02-09  778  	index = hash_32(port_offset, INET_TABLE_PERTURB_SHIFT);
190cc82489f46f Eric Dumazet             2021-02-09  779  
190cc82489f46f Eric Dumazet             2021-02-09 @780  	offset = (READ_ONCE(table_perturb[index]) + port_offset) % remaining;
1580ab63fc9a03 Eric Dumazet             2016-02-11  781  	/* In first pass we try ports of @low parity.
1580ab63fc9a03 Eric Dumazet             2016-02-11  782  	 * inet_csk_get_port() does the opposite choice.
07f4c90062f8fc Eric Dumazet             2015-05-24  783  	 */
1580ab63fc9a03 Eric Dumazet             2016-02-11  784  	offset &= ~1U;
1580ab63fc9a03 Eric Dumazet             2016-02-11  785  other_parity_scan:
1580ab63fc9a03 Eric Dumazet             2016-02-11  786  	port = low + offset;
1580ab63fc9a03 Eric Dumazet             2016-02-11  787  	for (i = 0; i < remaining; i += 2, port += 2) {
1580ab63fc9a03 Eric Dumazet             2016-02-11  788  		if (unlikely(port >= high))
1580ab63fc9a03 Eric Dumazet             2016-02-11  789  			port -= remaining;
122ff243f5f104 WANG Cong                2014-05-12  790  		if (inet_is_local_reserved_port(net, port))
e3826f1e946e7d Amerigo Wang             2010-05-05  791  			continue;
7f635ab71eef8d Pavel Emelyanov          2008-06-16  792  		head = &hinfo->bhash[inet_bhashfn(net, port,
7f635ab71eef8d Pavel Emelyanov          2008-06-16  793  						  hinfo->bhash_size)];
1580ab63fc9a03 Eric Dumazet             2016-02-11  794  		spin_lock_bh(&head->lock);
a7f5e7f164788a Arnaldo Carvalho de Melo 2005-12-13  795  
1580ab63fc9a03 Eric Dumazet             2016-02-11  796  		/* Does not bother with rcv_saddr checks, because
1580ab63fc9a03 Eric Dumazet             2016-02-11  797  		 * the established check is already unique enough.
a7f5e7f164788a Arnaldo Carvalho de Melo 2005-12-13  798  		 */
b67bfe0d42cac5 Sasha Levin              2013-02-27  799  		inet_bind_bucket_for_each(tb, &head->chain) {
3c82a21f4320c8 Robert Shearman          2018-11-07  800  			if (net_eq(ib_net(tb), net) && tb->l3mdev == l3mdev &&
3c82a21f4320c8 Robert Shearman          2018-11-07  801  			    tb->port == port) {
da5e36308d9f71 Tom Herbert              2013-01-22  802  				if (tb->fastreuse >= 0 ||
da5e36308d9f71 Tom Herbert              2013-01-22  803  				    tb->fastreuseport >= 0)
a7f5e7f164788a Arnaldo Carvalho de Melo 2005-12-13  804  					goto next_port;
a9d8f9110d7e95 Evgeniy Polyakov         2009-01-19  805  				WARN_ON(hlist_empty(&tb->owners));
5ee31fc1ecdcbc Pavel Emelyanov          2008-01-31  806  				if (!check_established(death_row, sk,
5ee31fc1ecdcbc Pavel Emelyanov          2008-01-31  807  						       port, &tw))
a7f5e7f164788a Arnaldo Carvalho de Melo 2005-12-13  808  					goto ok;
a7f5e7f164788a Arnaldo Carvalho de Melo 2005-12-13  809  				goto next_port;
a7f5e7f164788a Arnaldo Carvalho de Melo 2005-12-13  810  			}
a7f5e7f164788a Arnaldo Carvalho de Melo 2005-12-13  811  		}
a7f5e7f164788a Arnaldo Carvalho de Melo 2005-12-13  812  
941b1d22cc035a Pavel Emelyanov          2008-01-31  813  		tb = inet_bind_bucket_create(hinfo->bind_bucket_cachep,
3c82a21f4320c8 Robert Shearman          2018-11-07  814  					     net, head, port, l3mdev);
a7f5e7f164788a Arnaldo Carvalho de Melo 2005-12-13  815  		if (!tb) {
1580ab63fc9a03 Eric Dumazet             2016-02-11  816  			spin_unlock_bh(&head->lock);
1580ab63fc9a03 Eric Dumazet             2016-02-11  817  			return -ENOMEM;
a7f5e7f164788a Arnaldo Carvalho de Melo 2005-12-13  818  		}
a7f5e7f164788a Arnaldo Carvalho de Melo 2005-12-13  819  		tb->fastreuse = -1;
da5e36308d9f71 Tom Herbert              2013-01-22  820  		tb->fastreuseport = -1;
a7f5e7f164788a Arnaldo Carvalho de Melo 2005-12-13  821  		goto ok;
a7f5e7f164788a Arnaldo Carvalho de Melo 2005-12-13  822  next_port:
1580ab63fc9a03 Eric Dumazet             2016-02-11  823  		spin_unlock_bh(&head->lock);
1580ab63fc9a03 Eric Dumazet             2016-02-11  824  		cond_resched();
a7f5e7f164788a Arnaldo Carvalho de Melo 2005-12-13  825  	}
1580ab63fc9a03 Eric Dumazet             2016-02-11  826  
1580ab63fc9a03 Eric Dumazet             2016-02-11  827  	offset++;
1580ab63fc9a03 Eric Dumazet             2016-02-11  828  	if ((offset & 1) && remaining > 1)
1580ab63fc9a03 Eric Dumazet             2016-02-11  829  		goto other_parity_scan;
a7f5e7f164788a Arnaldo Carvalho de Melo 2005-12-13  830  
a7f5e7f164788a Arnaldo Carvalho de Melo 2005-12-13  831  	return -EADDRNOTAVAIL;
a7f5e7f164788a Arnaldo Carvalho de Melo 2005-12-13  832  
a7f5e7f164788a Arnaldo Carvalho de Melo 2005-12-13  833  ok:
c579bd1b4021c4 Eric Dumazet             2021-02-09  834  	/* If our first attempt found a candidate, skip next candidate
c579bd1b4021c4 Eric Dumazet             2021-02-09  835  	 * in 1/16 of cases to add some noise.
c579bd1b4021c4 Eric Dumazet             2021-02-09  836  	 */
c579bd1b4021c4 Eric Dumazet             2021-02-09  837  	if (!i && !(prandom_u32() % 16))
c579bd1b4021c4 Eric Dumazet             2021-02-09  838  		i = 2;
190cc82489f46f Eric Dumazet             2021-02-09  839  	WRITE_ONCE(table_perturb[index], READ_ONCE(table_perturb[index]) + i + 2);
a7f5e7f164788a Arnaldo Carvalho de Melo 2005-12-13  840  
a7f5e7f164788a Arnaldo Carvalho de Melo 2005-12-13  841  	/* Head lock still held and bh's disabled */
a7f5e7f164788a Arnaldo Carvalho de Melo 2005-12-13  842  	inet_bind_hash(sk, tb, port);
a7f5e7f164788a Arnaldo Carvalho de Melo 2005-12-13  843  	if (sk_unhashed(sk)) {
c720c7e8383aff Eric Dumazet             2009-10-15  844  		inet_sk(sk)->inet_sport = htons(port);
01770a16616573 Ricardo Dias             2020-11-20  845  		inet_ehash_nolisten(sk, (struct sock *)tw, NULL);
a7f5e7f164788a Arnaldo Carvalho de Melo 2005-12-13  846  	}
3cdaedae635b17 Eric Dumazet             2009-12-04  847  	if (tw)
fc01538f9fb755 Eric Dumazet             2015-07-08  848  		inet_twsk_bind_unhash(tw, hinfo);
a7f5e7f164788a Arnaldo Carvalho de Melo 2005-12-13  849  	spin_unlock(&head->lock);
dbe7faa4045ea8 Eric Dumazet             2015-07-08  850  	if (tw)
dbe7faa4045ea8 Eric Dumazet             2015-07-08  851  		inet_twsk_deschedule_put(tw);
a7f5e7f164788a Arnaldo Carvalho de Melo 2005-12-13  852  	local_bh_enable();
1580ab63fc9a03 Eric Dumazet             2016-02-11  853  	return 0;
a7f5e7f164788a Arnaldo Carvalho de Melo 2005-12-13  854  }
5ee31fc1ecdcbc Pavel Emelyanov          2008-01-31  855
diff mbox series

Patch

diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
index f72ec113ae56..98e1ec1a14f0 100644
--- a/include/net/inet_hashtables.h
+++ b/include/net/inet_hashtables.h
@@ -425,7 +425,7 @@  static inline void sk_rcv_saddr_set(struct sock *sk, __be32 addr)
 }
 
 int __inet_hash_connect(struct inet_timewait_death_row *death_row,
-			struct sock *sk, u32 port_offset,
+			struct sock *sk, u64 port_offset,
 			int (*check_established)(struct inet_timewait_death_row *,
 						 struct sock *, __u16,
 						 struct inet_timewait_sock **));
diff --git a/include/net/secure_seq.h b/include/net/secure_seq.h
index d7d2495f83c2..5cea9ed9c773 100644
--- a/include/net/secure_seq.h
+++ b/include/net/secure_seq.h
@@ -4,7 +4,7 @@ 
 
 #include <linux/types.h>
 
-u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport);
+u64 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport);
 u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr,
 			       __be16 dport);
 u32 secure_tcp_seq(__be32 saddr, __be32 daddr,
diff --git a/net/core/secure_seq.c b/net/core/secure_seq.c
index 9b8443774449..2cdd43a63f64 100644
--- a/net/core/secure_seq.c
+++ b/net/core/secure_seq.c
@@ -142,7 +142,7 @@  u32 secure_tcp_seq(__be32 saddr, __be32 daddr,
 }
 EXPORT_SYMBOL_GPL(secure_tcp_seq);
 
-u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport)
+u64 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport)
 {
 	net_secret_init();
 	return siphash_3u32((__force u32)saddr, (__force u32)daddr,
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index 17440840a791..09cbad0488ca 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -504,7 +504,7 @@  static int __inet_check_established(struct inet_timewait_death_row *death_row,
 	return -EADDRNOTAVAIL;
 }
 
-static u32 inet_sk_port_offset(const struct sock *sk)
+static u64 inet_sk_port_offset(const struct sock *sk)
 {
 	const struct inet_sock *inet = inet_sk(sk);
 
@@ -734,7 +734,7 @@  EXPORT_SYMBOL_GPL(inet_unhash);
 static u32 table_perturb[1 << INET_TABLE_PERTURB_SHIFT];
 
 int __inet_hash_connect(struct inet_timewait_death_row *death_row,
-		struct sock *sk, u32 port_offset,
+		struct sock *sk, u64 port_offset,
 		int (*check_established)(struct inet_timewait_death_row *,
 			struct sock *, __u16, struct inet_timewait_sock **))
 {
@@ -859,7 +859,7 @@  int __inet_hash_connect(struct inet_timewait_death_row *death_row,
 int inet_hash_connect(struct inet_timewait_death_row *death_row,
 		      struct sock *sk)
 {
-	u32 port_offset = 0;
+	u64 port_offset = 0;
 
 	if (!inet_sk(sk)->inet_num)
 		port_offset = inet_sk_port_offset(sk);