On Tue, Jun 30, 2020 at 12:24:12PM +0300, Amit Cohen wrote:
> Print extended state in addition to link state.
> 
> In case that extended state is not provided, print state only.
> If extended substate is provided in addition to the extended state,
> print it also.
> 
> Signed-off-by: Amit Cohen <am...@mellanox.com>
> ---
>  netlink/settings.c | 59 +++++++++++++++++++++++++++++++++++++++++++---
>  1 file changed, 56 insertions(+), 3 deletions(-)
> 
> diff --git a/netlink/settings.c b/netlink/settings.c
> index 35ba2f5..a4d1908 100644
> --- a/netlink/settings.c
> +++ b/netlink/settings.c
> @@ -604,6 +604,57 @@ int linkinfo_reply_cb(const struct nlmsghdr *nlhdr, void 
> *data)
>       return MNL_CB_OK;
>  }
>  
> +int linkstate_link_ext_substate_print(const struct nlattr *tb[],
> +                                   struct nl_context *nlctx, uint8_t 
> link_val,
> +                                   uint8_t link_ext_state_val,
> +                                   const char *link_ext_state_str)
> +{
> +     uint8_t link_ext_substate_val;
> +     const char *link_ext_substate_str;
> +
> +     if (!tb[ETHTOOL_A_LINKSTATE_EXT_SUBSTATE])
> +             return -ENODATA;
> +
> +     link_ext_substate_val = 
> mnl_attr_get_u8(tb[ETHTOOL_A_LINKSTATE_EXT_SUBSTATE]);
> +
> +     link_ext_substate_str = link_ext_substate_get(link_ext_state_val, 
> link_ext_substate_val);
> +     if (!link_ext_substate_str)
> +             return -ENODATA;

This does not distinguish between missing attribute (substate not
provided by kernel) and unknown value which can happen when older
ethtool version is used on a newer kernel which returns a new substate
not known by ethtool. IMHO we should fall back to reporting the numeric
value in such case rather than behaving as if the information were not
provided.

> +
> +     print_banner(nlctx);
> +     printf("\tLink detected: %s (%s, %s)\n", link_val ? "yes" : "no",
> +            link_ext_state_str, link_ext_substate_str);
> +
> +     return 0;
> +}
> +
> +int linkstate_link_ext_state_print(const struct nlattr *tb[],
> +                                struct nl_context *nlctx, uint8_t link_val)
> +{
> +     uint8_t link_ext_state_val;
> +     const char *link_ext_state_str;
> +     int ret;
> +
> +     if (!tb[ETHTOOL_A_LINKSTATE_EXT_STATE])
> +             return -ENODATA;
> +
> +     link_ext_state_val = mnl_attr_get_u8(tb[ETHTOOL_A_LINKSTATE_EXT_STATE]);
> +
> +     link_ext_state_str = link_ext_state_get(link_ext_state_val);
> +     if (!link_ext_state_str)
> +             return -ENODATA;

The same problem as above.

> +
> +     ret = linkstate_link_ext_substate_print(tb, nlctx, link_val, 
> link_ext_state_val,
> +                                             link_ext_state_str);
> +     if (ret < 0) {
> +             print_banner(nlctx);
> +             printf("\tLink detected: %s (%s)\n", link_val ? "yes" : "no",
> +                    link_ext_state_str);
> +     }
> +
> +     return 0;
> +}
> +
>  int linkstate_reply_cb(const struct nlmsghdr *nlhdr, void *data)
>  {
>       const struct nlattr *tb[ETHTOOL_A_LINKSTATE_MAX + 1] = {};
> @@ -622,9 +673,11 @@ int linkstate_reply_cb(const struct nlmsghdr *nlhdr, 
> void *data)
>  
>       if (tb[ETHTOOL_A_LINKSTATE_LINK]) {
>               uint8_t val = mnl_attr_get_u8(tb[ETHTOOL_A_LINKSTATE_LINK]);
> -
> -             print_banner(nlctx);
> -             printf("\tLink detected: %s\n", val ? "yes" : "no");
> +             ret = linkstate_link_ext_state_print(tb, nlctx, val);
> +             if (ret < 0) {
> +                     print_banner(nlctx);
> +                     printf("\tLink detected: %s\n", val ? "yes" : "no");
> +             }
>       }
>  
>       if (tb[ETHTOOL_A_LINKSTATE_SQI]) {

It's a bit impractical to have the banner and first part of the line
printed in three differente places. How about this:

  - linkstate_reply_cb() calls print_banner() and prints what it does
    now, only without the newline
  - linkstate_link_ext_state_print() prints " (%s" or " (%u" with
    extended state if it is provided or bails out if not
  - linkstate_link_ext_substate_print() prints ", %s" or ", %u" with
    extended substate if it is provided
  - linkstate_link_ext_state_print() prints ")"
  - linkstate_reply_cb() prints the newline

Michal

Reply via email to