* Re: [ethtool] ethtool: fix netlink bitmasks when sent as NOMASK
2020-07-27 21:47 [ethtool] ethtool: fix netlink bitmasks when sent as NOMASK Jacob Keller
@ 2020-07-27 21:51 ` Jacob Keller
2020-07-27 22:02 ` Jamie Gloudon
2020-07-27 22:11 ` Andrew Lunn
2020-07-27 22:21 ` Michal Kubecek
2 siblings, 1 reply; 12+ messages in thread
From: Jacob Keller @ 2020-07-27 21:51 UTC (permalink / raw)
To: Andrew Lunn, Michal Kubecek, netdev; +Cc: Jamie Gloudon
On 7/27/2020 2:47 PM, Jacob Keller wrote:
> The ethtool netlink API can send bitsets without an associated bitmask.
> These do not get displayed properly, because the dump_link_modes, and
> bitset_get_bit to not check whether the provided bitset is a NOMASK
> bitset. This results in the inability to display peer advertised link
> modes.
>
> The dump_link_modes and bitset_get_bit functions are designed so they
> can print either the values or the mask. For a nomask bitmap, this
> doesn't make sense. There is no mask.
>
> Modify dump_link_modes to check ETHTOOL_A_BITSET_NOMASK. For compact
> bitmaps, always check and print the ETHTOOL_A_BITSET_VALUE bits,
> regardless of the request to display the mask or the value. For full
> size bitmaps, the set of provided bits indicates the valid values,
> without using ETHTOOL_A_BITSET_VALUE fields. Thus, do not skip printing
> bits without this attribute if nomask is set. This essentially means
> that dump_link_modes will treat a NOMASK bitset as having a mask
> equivalent to all of its set bits.
>
> For bitset_get_bit, also check for ETHTOOL_A_BITSET_NOMASK. For compact
> bitmaps, always use ETHTOOL_A_BITSET_BIT_VALUE as in dump_link_modes.
> For full bitmaps, if nomask is set, then always return true of the bit
> is in the set, rather than only if it provides an
> ETHTOOL_A_BITSET_BIT_VALUE. This will then correctly report the set
> bits.
>
> This fixes display of link partner advertised fields when using the
> netlink API.
>
> Reported-by: Jamie Gloudon <jamie.gloudon@gmx.fr>
> Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Andrew, could you kindly test this in your setup? I believe it will
fully resolve the issue.
Michal, I think this is complete based on the docs in
ethtool-netlink.rst and some tests. Any further insight?
Thanks,
Jake
> ---
> netlink/bitset.c | 9 ++++++---
> netlink/settings.c | 8 +++++---
> 2 files changed, 11 insertions(+), 6 deletions(-)
>
> diff --git a/netlink/bitset.c b/netlink/bitset.c
> index 130bcdb5b52c..ba5d3ea77ff7 100644
> --- a/netlink/bitset.c
> +++ b/netlink/bitset.c
> @@ -50,6 +50,7 @@ bool bitset_get_bit(const struct nlattr *bitset, bool mask, unsigned int idx,
> DECLARE_ATTR_TB_INFO(bitset_tb);
> const struct nlattr *bits;
> const struct nlattr *bit;
> + bool nomask;
> int ret;
>
> *retptr = 0;
> @@ -57,8 +58,10 @@ bool bitset_get_bit(const struct nlattr *bitset, bool mask, unsigned int idx,
> if (ret < 0)
> goto err;
>
> - bits = mask ? bitset_tb[ETHTOOL_A_BITSET_MASK] :
> - bitset_tb[ETHTOOL_A_BITSET_VALUE];
> + nomask = bitset_tb[ETHTOOL_A_BITSET_NOMASK];
> +
> + bits = mask && !nomask ? bitset_tb[ETHTOOL_A_BITSET_MASK] :
> + bitset_tb[ETHTOOL_A_BITSET_VALUE];
> if (bits) {
> const uint32_t *bitmap =
> (const uint32_t *)mnl_attr_get_payload(bits);
> @@ -87,7 +90,7 @@ bool bitset_get_bit(const struct nlattr *bitset, bool mask, unsigned int idx,
>
> my_idx = mnl_attr_get_u32(tb[ETHTOOL_A_BITSET_BIT_INDEX]);
> if (my_idx == idx)
> - return mask || tb[ETHTOOL_A_BITSET_BIT_VALUE];
> + return mask || nomask || tb[ETHTOOL_A_BITSET_BIT_VALUE];
> }
>
> return false;
> diff --git a/netlink/settings.c b/netlink/settings.c
> index 35ba2f5dd6d5..29557653336e 100644
> --- a/netlink/settings.c
> +++ b/netlink/settings.c
> @@ -280,9 +280,11 @@ int dump_link_modes(struct nl_context *nlctx, const struct nlattr *bitset,
> const struct nlattr *bit;
> bool first = true;
> int prev = -2;
> + bool nomask;
> int ret;
>
> ret = mnl_attr_parse_nested(bitset, attr_cb, &bitset_tb_info);
> + nomask = bitset_tb[ETHTOOL_A_BITSET_NOMASK];
> bits = bitset_tb[ETHTOOL_A_BITSET_BITS];
> if (ret < 0)
> goto err_nonl;
> @@ -297,8 +299,8 @@ int dump_link_modes(struct nl_context *nlctx, const struct nlattr *bitset,
> goto err_nonl;
> lm_strings = global_stringset(ETH_SS_LINK_MODES,
> nlctx->ethnl2_socket);
> - bits = mask ? bitset_tb[ETHTOOL_A_BITSET_MASK] :
> - bitset_tb[ETHTOOL_A_BITSET_VALUE];
> + bits = mask && !nomask ? bitset_tb[ETHTOOL_A_BITSET_MASK] :
> + bitset_tb[ETHTOOL_A_BITSET_VALUE];
> ret = -EFAULT;
> if (!bits || !bitset_tb[ETHTOOL_A_BITSET_SIZE])
> goto err_nonl;
> @@ -354,7 +356,7 @@ int dump_link_modes(struct nl_context *nlctx, const struct nlattr *bitset,
> if (!tb[ETHTOOL_A_BITSET_BIT_INDEX] ||
> !tb[ETHTOOL_A_BITSET_BIT_NAME])
> goto err;
> - if (!mask && !tb[ETHTOOL_A_BITSET_BIT_VALUE])
> + if (!mask && !nomask && !tb[ETHTOOL_A_BITSET_BIT_VALUE])
> continue;
>
> idx = mnl_attr_get_u32(tb[ETHTOOL_A_BITSET_BIT_INDEX]);
>
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [ethtool] ethtool: fix netlink bitmasks when sent as NOMASK
2020-07-27 21:51 ` Jacob Keller
@ 2020-07-27 22:02 ` Jamie Gloudon
0 siblings, 0 replies; 12+ messages in thread
From: Jamie Gloudon @ 2020-07-27 22:02 UTC (permalink / raw)
To: Jacob Keller; +Cc: Andrew Lunn, Michal Kubecek, netdev
On Mon, Jul 27, 2020 at 02:51:28PM -0700, Jacob Keller wrote:
>
>
> On 7/27/2020 2:47 PM, Jacob Keller wrote:
> > The ethtool netlink API can send bitsets without an associated bitmask.
> > These do not get displayed properly, because the dump_link_modes, and
> > bitset_get_bit to not check whether the provided bitset is a NOMASK
> > bitset. This results in the inability to display peer advertised link
> > modes.
> >
> > The dump_link_modes and bitset_get_bit functions are designed so they
> > can print either the values or the mask. For a nomask bitmap, this
> > doesn't make sense. There is no mask.
> >
> > Modify dump_link_modes to check ETHTOOL_A_BITSET_NOMASK. For compact
> > bitmaps, always check and print the ETHTOOL_A_BITSET_VALUE bits,
> > regardless of the request to display the mask or the value. For full
> > size bitmaps, the set of provided bits indicates the valid values,
> > without using ETHTOOL_A_BITSET_VALUE fields. Thus, do not skip printing
> > bits without this attribute if nomask is set. This essentially means
> > that dump_link_modes will treat a NOMASK bitset as having a mask
> > equivalent to all of its set bits.
> >
> > For bitset_get_bit, also check for ETHTOOL_A_BITSET_NOMASK. For compact
> > bitmaps, always use ETHTOOL_A_BITSET_BIT_VALUE as in dump_link_modes.
> > For full bitmaps, if nomask is set, then always return true of the bit
> > is in the set, rather than only if it provides an
> > ETHTOOL_A_BITSET_BIT_VALUE. This will then correctly report the set
> > bits.
> >
> > This fixes display of link partner advertised fields when using the
> > netlink API.
> >
> > Reported-by: Jamie Gloudon <jamie.gloudon@gmx.fr>
> > Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
>
> Andrew, could you kindly test this in your setup? I believe it will
> fully resolve the issue.
>
> Michal, I think this is complete based on the docs in
> ethtool-netlink.rst and some tests. Any further insight?
>
> Thanks,
> Jake
>
> > ---
> > netlink/bitset.c | 9 ++++++---
> > netlink/settings.c | 8 +++++---
> > 2 files changed, 11 insertions(+), 6 deletions(-)
> >
> > diff --git a/netlink/bitset.c b/netlink/bitset.c
> > index 130bcdb5b52c..ba5d3ea77ff7 100644
> > --- a/netlink/bitset.c
> > +++ b/netlink/bitset.c
> > @@ -50,6 +50,7 @@ bool bitset_get_bit(const struct nlattr *bitset, bool mask, unsigned int idx,
> > DECLARE_ATTR_TB_INFO(bitset_tb);
> > const struct nlattr *bits;
> > const struct nlattr *bit;
> > + bool nomask;
> > int ret;
> >
> > *retptr = 0;
> > @@ -57,8 +58,10 @@ bool bitset_get_bit(const struct nlattr *bitset, bool mask, unsigned int idx,
> > if (ret < 0)
> > goto err;
> >
> > - bits = mask ? bitset_tb[ETHTOOL_A_BITSET_MASK] :
> > - bitset_tb[ETHTOOL_A_BITSET_VALUE];
> > + nomask = bitset_tb[ETHTOOL_A_BITSET_NOMASK];
> > +
> > + bits = mask && !nomask ? bitset_tb[ETHTOOL_A_BITSET_MASK] :
> > + bitset_tb[ETHTOOL_A_BITSET_VALUE];
> > if (bits) {
> > const uint32_t *bitmap =
> > (const uint32_t *)mnl_attr_get_payload(bits);
> > @@ -87,7 +90,7 @@ bool bitset_get_bit(const struct nlattr *bitset, bool mask, unsigned int idx,
> >
> > my_idx = mnl_attr_get_u32(tb[ETHTOOL_A_BITSET_BIT_INDEX]);
> > if (my_idx == idx)
> > - return mask || tb[ETHTOOL_A_BITSET_BIT_VALUE];
> > + return mask || nomask || tb[ETHTOOL_A_BITSET_BIT_VALUE];
> > }
> >
> > return false;
> > diff --git a/netlink/settings.c b/netlink/settings.c
> > index 35ba2f5dd6d5..29557653336e 100644
> > --- a/netlink/settings.c
> > +++ b/netlink/settings.c
> > @@ -280,9 +280,11 @@ int dump_link_modes(struct nl_context *nlctx, const struct nlattr *bitset,
> > const struct nlattr *bit;
> > bool first = true;
> > int prev = -2;
> > + bool nomask;
> > int ret;
> >
> > ret = mnl_attr_parse_nested(bitset, attr_cb, &bitset_tb_info);
> > + nomask = bitset_tb[ETHTOOL_A_BITSET_NOMASK];
> > bits = bitset_tb[ETHTOOL_A_BITSET_BITS];
> > if (ret < 0)
> > goto err_nonl;
> > @@ -297,8 +299,8 @@ int dump_link_modes(struct nl_context *nlctx, const struct nlattr *bitset,
> > goto err_nonl;
> > lm_strings = global_stringset(ETH_SS_LINK_MODES,
> > nlctx->ethnl2_socket);
> > - bits = mask ? bitset_tb[ETHTOOL_A_BITSET_MASK] :
> > - bitset_tb[ETHTOOL_A_BITSET_VALUE];
> > + bits = mask && !nomask ? bitset_tb[ETHTOOL_A_BITSET_MASK] :
> > + bitset_tb[ETHTOOL_A_BITSET_VALUE];
> > ret = -EFAULT;
> > if (!bits || !bitset_tb[ETHTOOL_A_BITSET_SIZE])
> > goto err_nonl;
> > @@ -354,7 +356,7 @@ int dump_link_modes(struct nl_context *nlctx, const struct nlattr *bitset,
> > if (!tb[ETHTOOL_A_BITSET_BIT_INDEX] ||
> > !tb[ETHTOOL_A_BITSET_BIT_NAME])
> > goto err;
> > - if (!mask && !tb[ETHTOOL_A_BITSET_BIT_VALUE])
> > + if (!mask && !nomask && !tb[ETHTOOL_A_BITSET_BIT_VALUE])
> > continue;
> >
> > idx = mnl_attr_get_u32(tb[ETHTOOL_A_BITSET_BIT_INDEX]);
> >
I can confirm that your patch works. As you can see below:
Link partner advertised pause frame use: Symmetric Receive-only
Link partner advertised auto-negotiation: Yes
Link partner advertised FEC modes: No
You can tag this patch Tested-by me. Thanks!
Regards,
Jamie Gloudon
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [ethtool] ethtool: fix netlink bitmasks when sent as NOMASK
2020-07-27 21:47 [ethtool] ethtool: fix netlink bitmasks when sent as NOMASK Jacob Keller
2020-07-27 21:51 ` Jacob Keller
@ 2020-07-27 22:11 ` Andrew Lunn
2020-07-27 22:22 ` Jacob Keller
2020-07-27 22:26 ` Michal Kubecek
2020-07-27 22:21 ` Michal Kubecek
2 siblings, 2 replies; 12+ messages in thread
From: Andrew Lunn @ 2020-07-27 22:11 UTC (permalink / raw)
To: Jacob Keller; +Cc: Michal Kubecek, netdev, Jamie Gloudon
On Mon, Jul 27, 2020 at 02:47:00PM -0700, Jacob Keller wrote:
> The ethtool netlink API can send bitsets without an associated bitmask.
> These do not get displayed properly, because the dump_link_modes, and
> bitset_get_bit to not check whether the provided bitset is a NOMASK
> bitset. This results in the inability to display peer advertised link
> modes.
>
> The dump_link_modes and bitset_get_bit functions are designed so they
> can print either the values or the mask. For a nomask bitmap, this
> doesn't make sense. There is no mask.
>
> Modify dump_link_modes to check ETHTOOL_A_BITSET_NOMASK. For compact
> bitmaps, always check and print the ETHTOOL_A_BITSET_VALUE bits,
> regardless of the request to display the mask or the value. For full
> size bitmaps, the set of provided bits indicates the valid values,
> without using ETHTOOL_A_BITSET_VALUE fields. Thus, do not skip printing
> bits without this attribute if nomask is set. This essentially means
> that dump_link_modes will treat a NOMASK bitset as having a mask
> equivalent to all of its set bits.
>
> For bitset_get_bit, also check for ETHTOOL_A_BITSET_NOMASK. For compact
> bitmaps, always use ETHTOOL_A_BITSET_BIT_VALUE as in dump_link_modes.
> For full bitmaps, if nomask is set, then always return true of the bit
> is in the set, rather than only if it provides an
> ETHTOOL_A_BITSET_BIT_VALUE. This will then correctly report the set
> bits.
>
> This fixes display of link partner advertised fields when using the
> netlink API.
Hi Jacob
This is close
Netlink
Link partner advertised link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
1000baseT/Full
Link partner advertised pause frame use: No
Link partner advertised auto-negotiation: Yes
Link partner advertised FEC modes: No
IOCTL
Link partner advertised link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
1000baseT/Full
Link partner advertised pause frame use: No
Link partner advertised auto-negotiation: Yes
Link partner advertised FEC modes: Not reported
So just the FEC modes differ.
However, i don't think this was part of the original issue, so:
Tested-by: Andrew Lunn <andrew@lunn.ch>
It would be nice to get the FEC modes fixed.
Andrew
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [ethtool] ethtool: fix netlink bitmasks when sent as NOMASK
2020-07-27 22:11 ` Andrew Lunn
@ 2020-07-27 22:22 ` Jacob Keller
2020-07-27 22:26 ` Michal Kubecek
1 sibling, 0 replies; 12+ messages in thread
From: Jacob Keller @ 2020-07-27 22:22 UTC (permalink / raw)
To: Andrew Lunn; +Cc: Michal Kubecek, netdev, Jamie Gloudon
On 7/27/2020 3:11 PM, Andrew Lunn wrote:
> On Mon, Jul 27, 2020 at 02:47:00PM -0700, Jacob Keller wrote:
>> The ethtool netlink API can send bitsets without an associated bitmask.
>> These do not get displayed properly, because the dump_link_modes, and
>> bitset_get_bit to not check whether the provided bitset is a NOMASK
>> bitset. This results in the inability to display peer advertised link
>> modes.
>>
>> The dump_link_modes and bitset_get_bit functions are designed so they
>> can print either the values or the mask. For a nomask bitmap, this
>> doesn't make sense. There is no mask.
>>
>> Modify dump_link_modes to check ETHTOOL_A_BITSET_NOMASK. For compact
>> bitmaps, always check and print the ETHTOOL_A_BITSET_VALUE bits,
>> regardless of the request to display the mask or the value. For full
>> size bitmaps, the set of provided bits indicates the valid values,
>> without using ETHTOOL_A_BITSET_VALUE fields. Thus, do not skip printing
>> bits without this attribute if nomask is set. This essentially means
>> that dump_link_modes will treat a NOMASK bitset as having a mask
>> equivalent to all of its set bits.
>>
>> For bitset_get_bit, also check for ETHTOOL_A_BITSET_NOMASK. For compact
>> bitmaps, always use ETHTOOL_A_BITSET_BIT_VALUE as in dump_link_modes.
>> For full bitmaps, if nomask is set, then always return true of the bit
>> is in the set, rather than only if it provides an
>> ETHTOOL_A_BITSET_BIT_VALUE. This will then correctly report the set
>> bits.
>>
>> This fixes display of link partner advertised fields when using the
>> netlink API.
>
> Hi Jacob
>
> This is close
>
> Netlink
> Link partner advertised link modes: 10baseT/Half 10baseT/Full
> 100baseT/Half 100baseT/Full
> 1000baseT/Full
> Link partner advertised pause frame use: No
> Link partner advertised auto-negotiation: Yes
> Link partner advertised FEC modes: No
>
> IOCTL
> Link partner advertised link modes: 10baseT/Half 10baseT/Full
> 100baseT/Half 100baseT/Full
> 1000baseT/Full
> Link partner advertised pause frame use: No
> Link partner advertised auto-negotiation: Yes
> Link partner advertised FEC modes: Not reported
>
> So just the FEC modes differ.
>
> However, i don't think this was part of the original issue, so:
>
> Tested-by: Andrew Lunn <andrew@lunn.ch>
>
> It would be nice to get the FEC modes fixed.
>
> Andrew
>
Yea, it looks like FEC modes is because FEC actually send a "None" flag,
as opposed to using an empty set as "none". I can follow-up this fix
with a change I think will resolve this as well.
Thanks,
Jake
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [ethtool] ethtool: fix netlink bitmasks when sent as NOMASK
2020-07-27 22:11 ` Andrew Lunn
2020-07-27 22:22 ` Jacob Keller
@ 2020-07-27 22:26 ` Michal Kubecek
2020-07-27 22:32 ` Keller, Jacob E
1 sibling, 1 reply; 12+ messages in thread
From: Michal Kubecek @ 2020-07-27 22:26 UTC (permalink / raw)
To: Andrew Lunn; +Cc: Jacob Keller, netdev, Jamie Gloudon
On Tue, Jul 28, 2020 at 12:11:04AM +0200, Andrew Lunn wrote:
> On Mon, Jul 27, 2020 at 02:47:00PM -0700, Jacob Keller wrote:
> > The ethtool netlink API can send bitsets without an associated bitmask.
> > These do not get displayed properly, because the dump_link_modes, and
> > bitset_get_bit to not check whether the provided bitset is a NOMASK
> > bitset. This results in the inability to display peer advertised link
> > modes.
> >
> > The dump_link_modes and bitset_get_bit functions are designed so they
> > can print either the values or the mask. For a nomask bitmap, this
> > doesn't make sense. There is no mask.
> >
> > Modify dump_link_modes to check ETHTOOL_A_BITSET_NOMASK. For compact
> > bitmaps, always check and print the ETHTOOL_A_BITSET_VALUE bits,
> > regardless of the request to display the mask or the value. For full
> > size bitmaps, the set of provided bits indicates the valid values,
> > without using ETHTOOL_A_BITSET_VALUE fields. Thus, do not skip printing
> > bits without this attribute if nomask is set. This essentially means
> > that dump_link_modes will treat a NOMASK bitset as having a mask
> > equivalent to all of its set bits.
> >
> > For bitset_get_bit, also check for ETHTOOL_A_BITSET_NOMASK. For compact
> > bitmaps, always use ETHTOOL_A_BITSET_BIT_VALUE as in dump_link_modes.
> > For full bitmaps, if nomask is set, then always return true of the bit
> > is in the set, rather than only if it provides an
> > ETHTOOL_A_BITSET_BIT_VALUE. This will then correctly report the set
> > bits.
> >
> > This fixes display of link partner advertised fields when using the
> > netlink API.
>
> Hi Jacob
>
> This is close
>
> Netlink
> Link partner advertised link modes: 10baseT/Half 10baseT/Full
> 100baseT/Half 100baseT/Full
> 1000baseT/Full
> Link partner advertised pause frame use: No
> Link partner advertised auto-negotiation: Yes
> Link partner advertised FEC modes: No
>
> IOCTL
> Link partner advertised link modes: 10baseT/Half 10baseT/Full
> 100baseT/Half 100baseT/Full
> 1000baseT/Full
> Link partner advertised pause frame use: No
> Link partner advertised auto-negotiation: Yes
> Link partner advertised FEC modes: Not reported
>
> So just the FEC modes differ.
This is a different issue, the last call to dump_link_modes() in
dump_peer_modes() should be
ret = dump_link_modes(nlctx, attr, false, LM_CLASS_FEC,
(third parameter needs to be false, not true).
Michal
>
> However, i don't think this was part of the original issue, so:
>
> Tested-by: Andrew Lunn <andrew@lunn.ch>
>
> It would be nice to get the FEC modes fixed.
>
> Andrew
^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: [ethtool] ethtool: fix netlink bitmasks when sent as NOMASK
2020-07-27 22:26 ` Michal Kubecek
@ 2020-07-27 22:32 ` Keller, Jacob E
2020-07-27 22:40 ` Michal Kubecek
0 siblings, 1 reply; 12+ messages in thread
From: Keller, Jacob E @ 2020-07-27 22:32 UTC (permalink / raw)
To: Michal Kubecek, Andrew Lunn; +Cc: netdev@vger.kernel.org, Jamie Gloudon
> -----Original Message-----
> From: Michal Kubecek <mkubecek@suse.cz>
> Sent: Monday, July 27, 2020 3:27 PM
> To: Andrew Lunn <andrew@lunn.ch>
> Cc: Keller, Jacob E <jacob.e.keller@intel.com>; netdev@vger.kernel.org; Jamie
> Gloudon <jamie.gloudon@gmx.fr>
> Subject: Re: [ethtool] ethtool: fix netlink bitmasks when sent as NOMASK
>
> On Tue, Jul 28, 2020 at 12:11:04AM +0200, Andrew Lunn wrote:
> > On Mon, Jul 27, 2020 at 02:47:00PM -0700, Jacob Keller wrote:
> > > The ethtool netlink API can send bitsets without an associated bitmask.
> > > These do not get displayed properly, because the dump_link_modes, and
> > > bitset_get_bit to not check whether the provided bitset is a NOMASK
> > > bitset. This results in the inability to display peer advertised link
> > > modes.
> > >
> > > The dump_link_modes and bitset_get_bit functions are designed so they
> > > can print either the values or the mask. For a nomask bitmap, this
> > > doesn't make sense. There is no mask.
> > >
> > > Modify dump_link_modes to check ETHTOOL_A_BITSET_NOMASK. For
> compact
> > > bitmaps, always check and print the ETHTOOL_A_BITSET_VALUE bits,
> > > regardless of the request to display the mask or the value. For full
> > > size bitmaps, the set of provided bits indicates the valid values,
> > > without using ETHTOOL_A_BITSET_VALUE fields. Thus, do not skip printing
> > > bits without this attribute if nomask is set. This essentially means
> > > that dump_link_modes will treat a NOMASK bitset as having a mask
> > > equivalent to all of its set bits.
> > >
> > > For bitset_get_bit, also check for ETHTOOL_A_BITSET_NOMASK. For compact
> > > bitmaps, always use ETHTOOL_A_BITSET_BIT_VALUE as in dump_link_modes.
> > > For full bitmaps, if nomask is set, then always return true of the bit
> > > is in the set, rather than only if it provides an
> > > ETHTOOL_A_BITSET_BIT_VALUE. This will then correctly report the set
> > > bits.
> > >
> > > This fixes display of link partner advertised fields when using the
> > > netlink API.
> >
> > Hi Jacob
> >
> > This is close
> >
> > Netlink
> > Link partner advertised link modes: 10baseT/Half 10baseT/Full
> > 100baseT/Half 100baseT/Full
> > 1000baseT/Full
> > Link partner advertised pause frame use: No
> > Link partner advertised auto-negotiation: Yes
> > Link partner advertised FEC modes: No
> >
> > IOCTL
> > Link partner advertised link modes: 10baseT/Half 10baseT/Full
> > 100baseT/Half 100baseT/Full
> > 1000baseT/Full
> > Link partner advertised pause frame use: No
> > Link partner advertised auto-negotiation: Yes
> > Link partner advertised FEC modes: Not reported
> >
> > So just the FEC modes differ.
>
> This is a different issue, the last call to dump_link_modes() in
> dump_peer_modes() should be
>
> ret = dump_link_modes(nlctx, attr, false, LM_CLASS_FEC,
>
> (third parameter needs to be false, not true).
>
> Michal
>
That's part of it, yea, but also it should use the string "Not Reported" instead of "No" I think?
> >
> > However, i don't think this was part of the original issue, so:
> >
> > Tested-by: Andrew Lunn <andrew@lunn.ch>
> >
> > It would be nice to get the FEC modes fixed.
> >
> > Andrew
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [ethtool] ethtool: fix netlink bitmasks when sent as NOMASK
2020-07-27 22:32 ` Keller, Jacob E
@ 2020-07-27 22:40 ` Michal Kubecek
0 siblings, 0 replies; 12+ messages in thread
From: Michal Kubecek @ 2020-07-27 22:40 UTC (permalink / raw)
To: Keller, Jacob E; +Cc: Andrew Lunn, netdev@vger.kernel.org, Jamie Gloudon
On Mon, Jul 27, 2020 at 10:32:03PM +0000, Keller, Jacob E wrote:
> > -----Original Message-----
> > From: Michal Kubecek <mkubecek@suse.cz>
> > Sent: Monday, July 27, 2020 3:27 PM
> > To: Andrew Lunn <andrew@lunn.ch>
> > Cc: Keller, Jacob E <jacob.e.keller@intel.com>; netdev@vger.kernel.org; Jamie
> > Gloudon <jamie.gloudon@gmx.fr>
> > Subject: Re: [ethtool] ethtool: fix netlink bitmasks when sent as NOMASK
> >
> > On Tue, Jul 28, 2020 at 12:11:04AM +0200, Andrew Lunn wrote:
> > > Hi Jacob
> > >
> > > This is close
> > >
> > > Netlink
> > > Link partner advertised link modes: 10baseT/Half 10baseT/Full
> > > 100baseT/Half 100baseT/Full
> > > 1000baseT/Full
> > > Link partner advertised pause frame use: No
> > > Link partner advertised auto-negotiation: Yes
> > > Link partner advertised FEC modes: No
> > >
> > > IOCTL
> > > Link partner advertised link modes: 10baseT/Half 10baseT/Full
> > > 100baseT/Half 100baseT/Full
> > > 1000baseT/Full
> > > Link partner advertised pause frame use: No
> > > Link partner advertised auto-negotiation: Yes
> > > Link partner advertised FEC modes: Not reported
> > >
> > > So just the FEC modes differ.
> >
> > This is a different issue, the last call to dump_link_modes() in
> > dump_peer_modes() should be
> >
> > ret = dump_link_modes(nlctx, attr, false, LM_CLASS_FEC,
> >
> > (third parameter needs to be false, not true).
> >
> > Michal
> >
>
> That's part of it, yea, but also it should use the string "Not
> Reported" instead of "No" I think?
Right, both should be fixed.
Michal
>
> > >
> > > However, i don't think this was part of the original issue, so:
> > >
> > > Tested-by: Andrew Lunn <andrew@lunn.ch>
> > >
> > > It would be nice to get the FEC modes fixed.
> > >
> > > Andrew
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [ethtool] ethtool: fix netlink bitmasks when sent as NOMASK
2020-07-27 21:47 [ethtool] ethtool: fix netlink bitmasks when sent as NOMASK Jacob Keller
2020-07-27 21:51 ` Jacob Keller
2020-07-27 22:11 ` Andrew Lunn
@ 2020-07-27 22:21 ` Michal Kubecek
2020-07-27 22:32 ` Jacob Keller
2 siblings, 1 reply; 12+ messages in thread
From: Michal Kubecek @ 2020-07-27 22:21 UTC (permalink / raw)
To: Jacob Keller; +Cc: Andrew Lunn, netdev, Jamie Gloudon
On Mon, Jul 27, 2020 at 02:47:00PM -0700, Jacob Keller wrote:
> The ethtool netlink API can send bitsets without an associated bitmask.
> These do not get displayed properly, because the dump_link_modes, and
> bitset_get_bit to not check whether the provided bitset is a NOMASK
> bitset. This results in the inability to display peer advertised link
> modes.
>
> The dump_link_modes and bitset_get_bit functions are designed so they
> can print either the values or the mask. For a nomask bitmap, this
> doesn't make sense. There is no mask.
>
> Modify dump_link_modes to check ETHTOOL_A_BITSET_NOMASK. For compact
> bitmaps, always check and print the ETHTOOL_A_BITSET_VALUE bits,
> regardless of the request to display the mask or the value. For full
> size bitmaps, the set of provided bits indicates the valid values,
> without using ETHTOOL_A_BITSET_VALUE fields. Thus, do not skip printing
> bits without this attribute if nomask is set. This essentially means
> that dump_link_modes will treat a NOMASK bitset as having a mask
> equivalent to all of its set bits.
>
> For bitset_get_bit, also check for ETHTOOL_A_BITSET_NOMASK. For compact
> bitmaps, always use ETHTOOL_A_BITSET_BIT_VALUE as in dump_link_modes.
> For full bitmaps, if nomask is set, then always return true of the bit
> is in the set, rather than only if it provides an
> ETHTOOL_A_BITSET_BIT_VALUE. This will then correctly report the set
> bits.
>
> This fixes display of link partner advertised fields when using the
> netlink API.
>
> Reported-by: Jamie Gloudon <jamie.gloudon@gmx.fr>
> Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
> ---
> netlink/bitset.c | 9 ++++++---
> netlink/settings.c | 8 +++++---
> 2 files changed, 11 insertions(+), 6 deletions(-)
>
> diff --git a/netlink/bitset.c b/netlink/bitset.c
> index 130bcdb5b52c..ba5d3ea77ff7 100644
> --- a/netlink/bitset.c
> +++ b/netlink/bitset.c
> @@ -50,6 +50,7 @@ bool bitset_get_bit(const struct nlattr *bitset, bool mask, unsigned int idx,
> DECLARE_ATTR_TB_INFO(bitset_tb);
> const struct nlattr *bits;
> const struct nlattr *bit;
> + bool nomask;
> int ret;
>
> *retptr = 0;
> @@ -57,8 +58,10 @@ bool bitset_get_bit(const struct nlattr *bitset, bool mask, unsigned int idx,
> if (ret < 0)
> goto err;
>
> - bits = mask ? bitset_tb[ETHTOOL_A_BITSET_MASK] :
> - bitset_tb[ETHTOOL_A_BITSET_VALUE];
> + nomask = bitset_tb[ETHTOOL_A_BITSET_NOMASK];
> +
> + bits = mask && !nomask ? bitset_tb[ETHTOOL_A_BITSET_MASK] :
> + bitset_tb[ETHTOOL_A_BITSET_VALUE];
> if (bits) {
> const uint32_t *bitmap =
> (const uint32_t *)mnl_attr_get_payload(bits);
I don't like this part: (mask && nomask) is a situation which should
never happen as it would mean we are trying to get mask value from
a bitmap which does not any. In other words, if we ever see such
combination, it is a result of a bug either on ethtool side or on kernel
side.
Rather than silently returning something else than asked, we should
IMHO report an error. Which is easy in dump_link_modes() but it would
require rewriting bitset_get_bit().
Michal
> @@ -87,7 +90,7 @@ bool bitset_get_bit(const struct nlattr *bitset, bool mask, unsigned int idx,
>
> my_idx = mnl_attr_get_u32(tb[ETHTOOL_A_BITSET_BIT_INDEX]);
> if (my_idx == idx)
> - return mask || tb[ETHTOOL_A_BITSET_BIT_VALUE];
> + return mask || nomask || tb[ETHTOOL_A_BITSET_BIT_VALUE];
> }
>
> return false;
> diff --git a/netlink/settings.c b/netlink/settings.c
> index 35ba2f5dd6d5..29557653336e 100644
> --- a/netlink/settings.c
> +++ b/netlink/settings.c
> @@ -280,9 +280,11 @@ int dump_link_modes(struct nl_context *nlctx, const struct nlattr *bitset,
> const struct nlattr *bit;
> bool first = true;
> int prev = -2;
> + bool nomask;
> int ret;
>
> ret = mnl_attr_parse_nested(bitset, attr_cb, &bitset_tb_info);
> + nomask = bitset_tb[ETHTOOL_A_BITSET_NOMASK];
> bits = bitset_tb[ETHTOOL_A_BITSET_BITS];
> if (ret < 0)
> goto err_nonl;
> @@ -297,8 +299,8 @@ int dump_link_modes(struct nl_context *nlctx, const struct nlattr *bitset,
> goto err_nonl;
> lm_strings = global_stringset(ETH_SS_LINK_MODES,
> nlctx->ethnl2_socket);
> - bits = mask ? bitset_tb[ETHTOOL_A_BITSET_MASK] :
> - bitset_tb[ETHTOOL_A_BITSET_VALUE];
> + bits = mask && !nomask ? bitset_tb[ETHTOOL_A_BITSET_MASK] :
> + bitset_tb[ETHTOOL_A_BITSET_VALUE];
> ret = -EFAULT;
> if (!bits || !bitset_tb[ETHTOOL_A_BITSET_SIZE])
> goto err_nonl;
> @@ -354,7 +356,7 @@ int dump_link_modes(struct nl_context *nlctx, const struct nlattr *bitset,
> if (!tb[ETHTOOL_A_BITSET_BIT_INDEX] ||
> !tb[ETHTOOL_A_BITSET_BIT_NAME])
> goto err;
> - if (!mask && !tb[ETHTOOL_A_BITSET_BIT_VALUE])
> + if (!mask && !nomask && !tb[ETHTOOL_A_BITSET_BIT_VALUE])
> continue;
>
> idx = mnl_attr_get_u32(tb[ETHTOOL_A_BITSET_BIT_INDEX]);
> --
> 2.26.2
>
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [ethtool] ethtool: fix netlink bitmasks when sent as NOMASK
2020-07-27 22:21 ` Michal Kubecek
@ 2020-07-27 22:32 ` Jacob Keller
2020-07-27 22:53 ` Michal Kubecek
0 siblings, 1 reply; 12+ messages in thread
From: Jacob Keller @ 2020-07-27 22:32 UTC (permalink / raw)
To: Michal Kubecek; +Cc: Andrew Lunn, netdev, Jamie Gloudon
On 7/27/2020 3:21 PM, Michal Kubecek wrote:
> On Mon, Jul 27, 2020 at 02:47:00PM -0700, Jacob Keller wrote:
>> The ethtool netlink API can send bitsets without an associated bitmask.
>> These do not get displayed properly, because the dump_link_modes, and
>> bitset_get_bit to not check whether the provided bitset is a NOMASK
>> bitset. This results in the inability to display peer advertised link
>> modes.
>>
>> The dump_link_modes and bitset_get_bit functions are designed so they
>> can print either the values or the mask. For a nomask bitmap, this
>> doesn't make sense. There is no mask.
>>
>> Modify dump_link_modes to check ETHTOOL_A_BITSET_NOMASK. For compact
>> bitmaps, always check and print the ETHTOOL_A_BITSET_VALUE bits,
>> regardless of the request to display the mask or the value. For full
>> size bitmaps, the set of provided bits indicates the valid values,
>> without using ETHTOOL_A_BITSET_VALUE fields. Thus, do not skip printing
>> bits without this attribute if nomask is set. This essentially means
>> that dump_link_modes will treat a NOMASK bitset as having a mask
>> equivalent to all of its set bits.
>>
>> For bitset_get_bit, also check for ETHTOOL_A_BITSET_NOMASK. For compact
>> bitmaps, always use ETHTOOL_A_BITSET_BIT_VALUE as in dump_link_modes.
>> For full bitmaps, if nomask is set, then always return true of the bit
>> is in the set, rather than only if it provides an
>> ETHTOOL_A_BITSET_BIT_VALUE. This will then correctly report the set
>> bits.
>>
>> This fixes display of link partner advertised fields when using the
>> netlink API.
>>
>> Reported-by: Jamie Gloudon <jamie.gloudon@gmx.fr>
>> Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
>> ---
>> netlink/bitset.c | 9 ++++++---
>> netlink/settings.c | 8 +++++---
>> 2 files changed, 11 insertions(+), 6 deletions(-)
>>
>> diff --git a/netlink/bitset.c b/netlink/bitset.c
>> index 130bcdb5b52c..ba5d3ea77ff7 100644
>> --- a/netlink/bitset.c
>> +++ b/netlink/bitset.c
>> @@ -50,6 +50,7 @@ bool bitset_get_bit(const struct nlattr *bitset, bool mask, unsigned int idx,
>> DECLARE_ATTR_TB_INFO(bitset_tb);
>> const struct nlattr *bits;
>> const struct nlattr *bit;
>> + bool nomask;
>> int ret;
>>
>> *retptr = 0;
>> @@ -57,8 +58,10 @@ bool bitset_get_bit(const struct nlattr *bitset, bool mask, unsigned int idx,
>> if (ret < 0)
>> goto err;
>>
>> - bits = mask ? bitset_tb[ETHTOOL_A_BITSET_MASK] :
>> - bitset_tb[ETHTOOL_A_BITSET_VALUE];
>> + nomask = bitset_tb[ETHTOOL_A_BITSET_NOMASK];
>> +
>> + bits = mask && !nomask ? bitset_tb[ETHTOOL_A_BITSET_MASK] :
>> + bitset_tb[ETHTOOL_A_BITSET_VALUE];
>> if (bits) {
>> const uint32_t *bitmap =
>> (const uint32_t *)mnl_attr_get_payload(bits);
>
> I don't like this part: (mask && nomask) is a situation which should
> never happen as it would mean we are trying to get mask value from
> a bitmap which does not any. In other words, if we ever see such
> combination, it is a result of a bug either on ethtool side or on kernel
> side.
>
> Rather than silently returning something else than asked, we should
> IMHO report an error. Which is easy in dump_link_modes() but it would
> require rewriting bitset_get_bit().
>
> Michal
The "mask" boolean is an indication that you want to print the mask for
a bitmap, rather than its value. I think treating a bitmap without a
predefined mask to have its mask be equivalent to its values is
reasonable. However, I could see the argument for not wanting this since
it is effectively a bug somewhere.
For dump_link_modes, it is trivial. If nomask is set, and mask is
requested, bail out of the function. It looks like we can also report an
error for the bitset_get_bit too. I'll take a look closer.
Thanks,
Jake
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [ethtool] ethtool: fix netlink bitmasks when sent as NOMASK
2020-07-27 22:32 ` Jacob Keller
@ 2020-07-27 22:53 ` Michal Kubecek
2020-07-27 23:18 ` Jacob Keller
0 siblings, 1 reply; 12+ messages in thread
From: Michal Kubecek @ 2020-07-27 22:53 UTC (permalink / raw)
To: Jacob Keller; +Cc: Andrew Lunn, netdev, Jamie Gloudon
On Mon, Jul 27, 2020 at 03:32:34PM -0700, Jacob Keller wrote:
> On 7/27/2020 3:21 PM, Michal Kubecek wrote:
> > On Mon, Jul 27, 2020 at 02:47:00PM -0700, Jacob Keller wrote:
> >> The ethtool netlink API can send bitsets without an associated bitmask.
> >> These do not get displayed properly, because the dump_link_modes, and
> >> bitset_get_bit to not check whether the provided bitset is a NOMASK
> >> bitset. This results in the inability to display peer advertised link
> >> modes.
> >>
> >> The dump_link_modes and bitset_get_bit functions are designed so they
> >> can print either the values or the mask. For a nomask bitmap, this
> >> doesn't make sense. There is no mask.
> >>
> >> Modify dump_link_modes to check ETHTOOL_A_BITSET_NOMASK. For compact
> >> bitmaps, always check and print the ETHTOOL_A_BITSET_VALUE bits,
> >> regardless of the request to display the mask or the value. For full
> >> size bitmaps, the set of provided bits indicates the valid values,
> >> without using ETHTOOL_A_BITSET_VALUE fields. Thus, do not skip printing
> >> bits without this attribute if nomask is set. This essentially means
> >> that dump_link_modes will treat a NOMASK bitset as having a mask
> >> equivalent to all of its set bits.
> >>
> >> For bitset_get_bit, also check for ETHTOOL_A_BITSET_NOMASK. For compact
> >> bitmaps, always use ETHTOOL_A_BITSET_BIT_VALUE as in dump_link_modes.
> >> For full bitmaps, if nomask is set, then always return true of the bit
> >> is in the set, rather than only if it provides an
> >> ETHTOOL_A_BITSET_BIT_VALUE. This will then correctly report the set
> >> bits.
> >>
> >> This fixes display of link partner advertised fields when using the
> >> netlink API.
> >>
> >> Reported-by: Jamie Gloudon <jamie.gloudon@gmx.fr>
> >> Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
> >> ---
> >> netlink/bitset.c | 9 ++++++---
> >> netlink/settings.c | 8 +++++---
> >> 2 files changed, 11 insertions(+), 6 deletions(-)
> >>
> >> diff --git a/netlink/bitset.c b/netlink/bitset.c
> >> index 130bcdb5b52c..ba5d3ea77ff7 100644
> >> --- a/netlink/bitset.c
> >> +++ b/netlink/bitset.c
> >> @@ -50,6 +50,7 @@ bool bitset_get_bit(const struct nlattr *bitset, bool mask, unsigned int idx,
> >> DECLARE_ATTR_TB_INFO(bitset_tb);
> >> const struct nlattr *bits;
> >> const struct nlattr *bit;
> >> + bool nomask;
> >> int ret;
> >>
> >> *retptr = 0;
> >> @@ -57,8 +58,10 @@ bool bitset_get_bit(const struct nlattr *bitset, bool mask, unsigned int idx,
> >> if (ret < 0)
> >> goto err;
> >>
> >> - bits = mask ? bitset_tb[ETHTOOL_A_BITSET_MASK] :
> >> - bitset_tb[ETHTOOL_A_BITSET_VALUE];
> >> + nomask = bitset_tb[ETHTOOL_A_BITSET_NOMASK];
> >> +
> >> + bits = mask && !nomask ? bitset_tb[ETHTOOL_A_BITSET_MASK] :
> >> + bitset_tb[ETHTOOL_A_BITSET_VALUE];
> >> if (bits) {
> >> const uint32_t *bitmap =
> >> (const uint32_t *)mnl_attr_get_payload(bits);
> >
> > I don't like this part: (mask && nomask) is a situation which should
> > never happen as it would mean we are trying to get mask value from
> > a bitmap which does not any. In other words, if we ever see such
> > combination, it is a result of a bug either on ethtool side or on kernel
> > side.
> >
> > Rather than silently returning something else than asked, we should
> > IMHO report an error. Which is easy in dump_link_modes() but it would
> > require rewriting bitset_get_bit().
> >
> > Michal
>
> The "mask" boolean is an indication that you want to print the mask for
> a bitmap, rather than its value. I think treating a bitmap without a
> predefined mask to have its mask be equivalent to its values is
> reasonable.
It depends on the context. In requests, value=0x1,mask=0x1 means "set
bit 0 and leave the rest untouched" while nomask bitmap with value=0x1
would mean "set bit 0 and clear the rest".
For kernel replies, it should be documented which variant is expected.
> However, I could see the argument for not wanting this since
> it is effectively a bug somewhere.
We actually had this kind of bug in FEC modes handling as we just found.
Michal
> For dump_link_modes, it is trivial. If nomask is set, and mask is
> requested, bail out of the function. It looks like we can also report an
> error for the bitset_get_bit too. I'll take a look closer.
>
> Thanks,
> Jake
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [ethtool] ethtool: fix netlink bitmasks when sent as NOMASK
2020-07-27 22:53 ` Michal Kubecek
@ 2020-07-27 23:18 ` Jacob Keller
0 siblings, 0 replies; 12+ messages in thread
From: Jacob Keller @ 2020-07-27 23:18 UTC (permalink / raw)
To: Michal Kubecek; +Cc: Andrew Lunn, netdev, Jamie Gloudon
On 7/27/2020 3:53 PM, Michal Kubecek wrote:
> On Mon, Jul 27, 2020 at 03:32:34PM -0700, Jacob Keller wrote:
>> On 7/27/2020 3:21 PM, Michal Kubecek wrote:
>>> On Mon, Jul 27, 2020 at 02:47:00PM -0700, Jacob Keller wrote:
>>>> The ethtool netlink API can send bitsets without an associated bitmask.
>>>> These do not get displayed properly, because the dump_link_modes, and
>>>> bitset_get_bit to not check whether the provided bitset is a NOMASK
>>>> bitset. This results in the inability to display peer advertised link
>>>> modes.
>>>>
>>>> The dump_link_modes and bitset_get_bit functions are designed so they
>>>> can print either the values or the mask. For a nomask bitmap, this
>>>> doesn't make sense. There is no mask.
>>>>
>>>> Modify dump_link_modes to check ETHTOOL_A_BITSET_NOMASK. For compact
>>>> bitmaps, always check and print the ETHTOOL_A_BITSET_VALUE bits,
>>>> regardless of the request to display the mask or the value. For full
>>>> size bitmaps, the set of provided bits indicates the valid values,
>>>> without using ETHTOOL_A_BITSET_VALUE fields. Thus, do not skip printing
>>>> bits without this attribute if nomask is set. This essentially means
>>>> that dump_link_modes will treat a NOMASK bitset as having a mask
>>>> equivalent to all of its set bits.
>>>>
>>>> For bitset_get_bit, also check for ETHTOOL_A_BITSET_NOMASK. For compact
>>>> bitmaps, always use ETHTOOL_A_BITSET_BIT_VALUE as in dump_link_modes.
>>>> For full bitmaps, if nomask is set, then always return true of the bit
>>>> is in the set, rather than only if it provides an
>>>> ETHTOOL_A_BITSET_BIT_VALUE. This will then correctly report the set
>>>> bits.
>>>>
>>>> This fixes display of link partner advertised fields when using the
>>>> netlink API.
>>>>
>>>> Reported-by: Jamie Gloudon <jamie.gloudon@gmx.fr>
>>>> Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
>>>> ---
>>>> netlink/bitset.c | 9 ++++++---
>>>> netlink/settings.c | 8 +++++---
>>>> 2 files changed, 11 insertions(+), 6 deletions(-)
>>>>
>>>> diff --git a/netlink/bitset.c b/netlink/bitset.c
>>>> index 130bcdb5b52c..ba5d3ea77ff7 100644
>>>> --- a/netlink/bitset.c
>>>> +++ b/netlink/bitset.c
>>>> @@ -50,6 +50,7 @@ bool bitset_get_bit(const struct nlattr *bitset, bool mask, unsigned int idx,
>>>> DECLARE_ATTR_TB_INFO(bitset_tb);
>>>> const struct nlattr *bits;
>>>> const struct nlattr *bit;
>>>> + bool nomask;
>>>> int ret;
>>>>
>>>> *retptr = 0;
>>>> @@ -57,8 +58,10 @@ bool bitset_get_bit(const struct nlattr *bitset, bool mask, unsigned int idx,
>>>> if (ret < 0)
>>>> goto err;
>>>>
>>>> - bits = mask ? bitset_tb[ETHTOOL_A_BITSET_MASK] :
>>>> - bitset_tb[ETHTOOL_A_BITSET_VALUE];
>>>> + nomask = bitset_tb[ETHTOOL_A_BITSET_NOMASK];
>>>> +
>>>> + bits = mask && !nomask ? bitset_tb[ETHTOOL_A_BITSET_MASK] :
>>>> + bitset_tb[ETHTOOL_A_BITSET_VALUE];
>>>> if (bits) {
>>>> const uint32_t *bitmap =
>>>> (const uint32_t *)mnl_attr_get_payload(bits);
>>>
>>> I don't like this part: (mask && nomask) is a situation which should
>>> never happen as it would mean we are trying to get mask value from
>>> a bitmap which does not any. In other words, if we ever see such
>>> combination, it is a result of a bug either on ethtool side or on kernel
>>> side.
>>>
>>> Rather than silently returning something else than asked, we should
>>> IMHO report an error. Which is easy in dump_link_modes() but it would
>>> require rewriting bitset_get_bit().
>>>
>>> Michal
>>
>> The "mask" boolean is an indication that you want to print the mask for
>> a bitmap, rather than its value. I think treating a bitmap without a
>> predefined mask to have its mask be equivalent to its values is
>> reasonable.
>
> It depends on the context. In requests, value=0x1,mask=0x1 means "set
> bit 0 and leave the rest untouched" while nomask bitmap with value=0x1
> would mean "set bit 0 and clear the rest".
>
> For kernel replies, it should be documented which variant is expected.
>
Right, I was mostly referring to the reply side of things. I've updated
the patch in v2 to explicitly reject trying to print the mask of a NO
MASK bitset.
Thanks,
Jake
^ permalink raw reply [flat|nested] 12+ messages in thread