lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <5775952b-943a-f8ad-55a1-c4d0fd08475f@intel.com>
Date: Wed, 26 Jul 2023 13:09:22 +0200
From: Alexander Lobakin <aleksander.lobakin@...el.com>
To: Andy Shevchenko <andy@...nel.org>, Yury Norov <yury.norov@...il.com>,
	Marcin Szycik <marcin.szycik@...ux.intel.com>
CC: <intel-wired-lan@...ts.osuosl.org>, <netdev@...r.kernel.org>,
	<wojciech.drewek@...el.com>, <michal.swiatkowski@...ux.intel.com>,
	<davem@...emloft.net>, <kuba@...nel.org>, <jiri@...nulli.us>,
	<pabeni@...hat.com>, <jesse.brandeburg@...el.com>,
	<simon.horman@...igine.com>, <idosch@...dia.com>
Subject: Re: [PATCH iwl-next v3 2/6] ip_tunnel: convert __be16 tunnel flags to
 bitmaps

From: Andy Shevchenko <andy@...nel.org>, Yury Norov <yury.norov@...il.com>
Date: Fri, 21 Jul 2023 17:42:12 +0300

> +Cc: Yury on bitmap assignments.

I told Marcin to add you to Cc when sending, but forgot Yury, my
apologies =\

> 
> (Yury, JFYI,
>  if you need the whole series, take message ID as $MSG_ID of this email
>  and execute
> 
>    `b4 mbox $MSG_ID`
> 
>  to retrieve it)
> 
> On Fri, Jul 21, 2023 at 09:15:28AM +0200, Marcin Szycik wrote:
>> From: Alexander Lobakin <aleksander.lobakin@...el.com>
>>
>> Historically, tunnel flags like TUNNEL_CSUM or TUNNEL_ERSPAN_OPT
>> have been defined as __be16. Now all of those 16 bits are occupied
>> and there's no more free space for new flags.
>> It can't be simply switched to a bigger container with no
>> adjustments to the values, since it's an explicit Endian storage,
>> and on LE systems (__be16)0x0001 equals to
>> (__be64)0x0001000000000000.
>> We could probably define new 64-bit flags depending on the
>> Endianness, i.e. (__be64)0x0001 on BE and (__be64)0x00010000... on
>> LE, but that would introduce an Endianness dependency and spawn a
>> ton of Sparse warnings. To mitigate them, all of those places which
>> were adjusted with this change would be touched anyway, so why not
>> define stuff properly if there's no choice.
>>
>> Define IP_TUNNEL_*_BIT counterparts as a bit number instead of the
>> value already coded and a fistful of <16 <-> bitmap> converters and
>> helpers. The two flags which have a different bit position are
>> SIT_ISATAP_64 and VTI_ISVTI_64, as they were defined not as
>> __cpu_to_be16(), but as (__force __be16), i.e. had different
>> positions on LE and BE. Now they have a strongly defined place.
>> Change all __be16 fields which were used to store those flags, to
>> IP_TUNNEL_DECLARE_FLAGS() -> DECLARE_BITMAP(__IP_TUNNEL_FLAG_NUM) ->
>> unsigned long[1] for now, and replace all TUNNEL_* occurencies to
>> their 64-bit bitmap counterparts. Use the converters in the places
>> which talk to the userspace, hardware (NFP) or other hosts (GRE
>> header). The rest must explicitly use the new flags only. This must
>> be done at once, otherwise there will be too much conversions
>> throughout the code in the intermediate commits.
>> Finally, disable the old __be16 flags for use in the kernel code
>> (except for the two 'irregular' flags mentioned above), to prevent
>> any accidental (mis)use of them. For the userspace, nothing is
>> changed, only additions were made.
> 
> Any bloat-o-meter statistics, just in case?

Sure, will add. IIRC that was something like +150-200 bytes to vmlinux.

> 
> ...
> 
>> +static inline void ip_tunnel_flags_from_be16(unsigned long *dst, __be16 flags)
>> +{
>> +	bitmap_zero(dst, __IP_TUNNEL_FLAG_NUM);
> 
>> +	*dst = be16_to_cpu(flags);
> 
> Oh, This is not good. What you need is something like bitmap_set_value16() in
> analogue with bitmap_set_value8().

But I don't need `start`, those flag will always be in the first word
and I don't need to replace only some range, but to clear everything and
then set only the flags which are set in that __be16.
Why shouldn't this work?

> 
>> +	if (flags & VTI_ISVTI)
>> +		__set_bit(IP_TUNNEL_VTI_BIT, dst);
>> +}
>> +
>> +static inline __be16 ip_tunnel_flags_to_be16(const unsigned long *flags)
>> +{
>> +	__be16 ret;
> 
>> +	ret = cpu_to_be16(*flags & U16_MAX);
> 
> Same as above.
> 
> ' & U16_MAX' is redundant.

Ah, right ._.

> 
>> +	if (test_bit(IP_TUNNEL_VTI_BIT, flags))
>> +		ret |= VTI_ISVTI;
>> +
>> +	return ret;
>> +}
> 
> Side note: Make sure you know the difference between
> bitmap_zero(bitmap, nbits) and bitmap_clear(bitmap, 0, nbits).
> Similar for fill and set.

zero() and fill() rewrite the whole longs, I know :D I use them
deliberately here.

> 
> ...
> 
>> +	__set_bit(IP_TUNNEL_KEY_BIT, info->key.tun_flags);
>> +	__set_bit(IP_TUNNEL_CSUM_BIT, info->key.tun_flags);
>> +	__set_bit(IP_TUNNEL_NOCACHE_BIT, info->key.tun_flags);
>>  	if (flags & BPF_F_DONT_FRAGMENT)
>> -		info->key.tun_flags |= TUNNEL_DONT_FRAGMENT;
>> +		__set_bit(IP_TUNNEL_DONT_FRAGMENT_BIT, info->key.tun_flags);
>>  	if (flags & BPF_F_ZERO_CSUM_TX)
>> -		info->key.tun_flags &= ~TUNNEL_CSUM;
>> +		__clear_bit(IP_TUNNEL_CSUM_BIT, info->key.tun_flags);
> 
> Instead of set/clear, use assign, i.e. __asign_bit().

Just to make it clear, you mean

	__assign_bit(IP_TUNNEL_CSUM_BIT, info->key.tun_flags,
		     flags & BPF_F_ZERO_CSUM_TX);

right?

> 
>>  	if (flags & BPF_F_SEQ_NUMBER)
>> -		info->key.tun_flags |= TUNNEL_SEQ;
>> +		__set_bit(IP_TUNNEL_SEQ_BIT, info->key.tun_flags);
>>  	if (flags & BPF_F_NO_TUNNEL_KEY)
>> -		info->key.tun_flags &= ~TUNNEL_KEY;
>> +		__clear_bit(IP_TUNNEL_KEY_BIT, info->key.tun_flags);
> 
> Ditto.
> 
> Check the rest of your code for the similar.

+

> 
> ...
> 
>> +	if (test_bit(IP_TUNNEL_KEY_BIT, p->i_flags)) {
>> +		if (test_bit(IP_TUNNEL_KEY_BIT, flags))
>>  			return key == p->i_key;
> 
>>  		else
> 
> Redundant.
> 
>>  			/* key expected, none present */
>>  			return false;
> 
>> +	} else {
> 
> Ditto.

Seems like it was here before me, but I'm fine to fix it while at it,
why not.

> 
>> +		return !test_bit(IP_TUNNEL_KEY_BIT, flags);
>> +	}
> 

Thanks!
Olek

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ