From c96cf60217eab5a876adbe0a93b1cb3f925b0d45 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Mar 30 2021 15:11:31 +0000 Subject: import ethtool-5.8-5.el8 --- diff --git a/.ethtool.metadata b/.ethtool.metadata index 9ac880d..3d8d79d 100644 --- a/.ethtool.metadata +++ b/.ethtool.metadata @@ -1 +1 @@ -a7149633abb2556ba48e87a2989a5e1a394256b4 SOURCES/ethtool-5.0.tar.xz +b16ecf0ede1635f8a8abac9b8db58b831f408f7b SOURCES/ethtool-5.8.tar.xz diff --git a/.gitignore b/.gitignore index adeaeb9..f648a3c 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/ethtool-5.0.tar.xz +SOURCES/ethtool-5.8.tar.xz diff --git a/SOURCES/0001-ethtool-Add-support-for-200Gbps-50Gbps-per-lane-link.patch b/SOURCES/0001-ethtool-Add-support-for-200Gbps-50Gbps-per-lane-link.patch deleted file mode 100644 index 4479bd2..0000000 --- a/SOURCES/0001-ethtool-Add-support-for-200Gbps-50Gbps-per-lane-link.patch +++ /dev/null @@ -1,162 +0,0 @@ -From b13bc90142533a7cfe79d1f136a24ed20a75c1fb Mon Sep 17 00:00:00 2001 -From: Aya Levin -Date: Mon, 25 Feb 2019 17:44:34 +0200 -Subject: [PATCH] ethtool: Add support for 200Gbps (50Gbps per lane) link mode - -Introduce 50Gbps per lane link modes and 200Gbps speed, update print -functions and initialization functions accordingly. -In addition, update related man page accordingly. - -Signed-off-by: Aya Levin -Signed-off-by: Tariq Toukan -Reviewed-by: Michal Kubecek -Signed-off-by: John W. Linville -(cherry picked from commit caa4bbef6ff920a0ff1d94c5bff7f2c7c875fca3) ---- - ethtool-copy.h | 18 +++++++++++++++++- - ethtool.8.in | 15 +++++++++++++++ - ethtool.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 77 insertions(+), 1 deletion(-) - -diff --git a/ethtool-copy.h b/ethtool-copy.h -index 6bfbb85..1204076 100644 ---- a/ethtool-copy.h -+++ b/ethtool-copy.h -@@ -1455,6 +1455,21 @@ enum ethtool_link_mode_bit_indices { - ETHTOOL_LINK_MODE_FEC_NONE_BIT = 49, - ETHTOOL_LINK_MODE_FEC_RS_BIT = 50, - ETHTOOL_LINK_MODE_FEC_BASER_BIT = 51, -+ ETHTOOL_LINK_MODE_50000baseKR_Full_BIT = 52, -+ ETHTOOL_LINK_MODE_50000baseSR_Full_BIT = 53, -+ ETHTOOL_LINK_MODE_50000baseCR_Full_BIT = 54, -+ ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT = 55, -+ ETHTOOL_LINK_MODE_50000baseDR_Full_BIT = 56, -+ ETHTOOL_LINK_MODE_100000baseKR2_Full_BIT = 57, -+ ETHTOOL_LINK_MODE_100000baseSR2_Full_BIT = 58, -+ ETHTOOL_LINK_MODE_100000baseCR2_Full_BIT = 59, -+ ETHTOOL_LINK_MODE_100000baseLR2_ER2_FR2_Full_BIT = 60, -+ ETHTOOL_LINK_MODE_100000baseDR2_Full_BIT = 61, -+ ETHTOOL_LINK_MODE_200000baseKR4_Full_BIT = 62, -+ ETHTOOL_LINK_MODE_200000baseSR4_Full_BIT = 63, -+ ETHTOOL_LINK_MODE_200000baseLR4_ER4_FR4_Full_BIT = 64, -+ ETHTOOL_LINK_MODE_200000baseDR4_Full_BIT = 65, -+ ETHTOOL_LINK_MODE_200000baseCR4_Full_BIT = 66, - - /* Last allowed bit for __ETHTOOL_LINK_MODE_LEGACY_MASK is bit - * 31. Please do NOT define any SUPPORTED_* or ADVERTISED_* -@@ -1463,7 +1478,7 @@ enum ethtool_link_mode_bit_indices { - */ - - __ETHTOOL_LINK_MODE_LAST -- = ETHTOOL_LINK_MODE_FEC_BASER_BIT, -+ = ETHTOOL_LINK_MODE_200000baseCR4_Full_BIT, - }; - - #define __ETHTOOL_LINK_MODE_LEGACY_MASK(base_name) \ -@@ -1571,6 +1586,7 @@ enum ethtool_link_mode_bit_indices { - #define SPEED_50000 50000 - #define SPEED_56000 56000 - #define SPEED_100000 100000 -+#define SPEED_200000 200000 - - #define SPEED_UNKNOWN -1 - -diff --git a/ethtool.8.in b/ethtool.8.in -index 4053a56..4df6f38 100644 ---- a/ethtool.8.in -+++ b/ethtool.8.in -@@ -650,6 +650,11 @@ lB l lB. - 0x400000000 50000baseCR2 Full - 0x800000000 50000baseKR2 Full - 0x10000000000 50000baseSR2 Full -+0x10000000000000 50000baseKR Full -+0x20000000000000 50000baseSR Full -+0x40000000000000 50000baseCR Full -+0x80000000000000 50000baseLR_ER_FR Full -+0x100000000000000 50000baseDR Full - 0x8000000 56000baseKR4 Full - 0x10000000 56000baseCR4 Full - 0x20000000 56000baseSR4 Full -@@ -658,6 +663,16 @@ lB l lB. - 0x2000000000 100000baseSR4 Full - 0x4000000000 100000baseCR4 Full - 0x8000000000 100000baseLR4_ER4 Full -+0x200000000000000 100000baseKR2 Full -+0x400000000000000 100000baseSR2 Full -+0x800000000000000 100000baseCR2 Full -+0x1000000000000000 100000baseLR2_ER2_FR2 Full -+0x2000000000000000 100000baseDR2 Full -+0x4000000000000000 200000baseKR4 Full -+0x8000000000000000 200000baseSR4 Full -+0x10000000000000000 200000baseLR4_ER4_FR4 Full -+0x20000000000000000 200000baseDR4 Full -+0x40000000000000000 200000baseCR4 Full - .TE - .TP - .BI phyad \ N -diff --git a/ethtool.c b/ethtool.c -index fb4c088..c36aafd 100644 ---- a/ethtool.c -+++ b/ethtool.c -@@ -530,6 +530,21 @@ static void init_global_link_mode_masks(void) - ETHTOOL_LINK_MODE_10000baseER_Full_BIT, - ETHTOOL_LINK_MODE_2500baseT_Full_BIT, - ETHTOOL_LINK_MODE_5000baseT_Full_BIT, -+ ETHTOOL_LINK_MODE_50000baseKR_Full_BIT, -+ ETHTOOL_LINK_MODE_50000baseSR_Full_BIT, -+ ETHTOOL_LINK_MODE_50000baseCR_Full_BIT, -+ ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT, -+ ETHTOOL_LINK_MODE_50000baseDR_Full_BIT, -+ ETHTOOL_LINK_MODE_100000baseKR2_Full_BIT, -+ ETHTOOL_LINK_MODE_100000baseSR2_Full_BIT, -+ ETHTOOL_LINK_MODE_100000baseCR2_Full_BIT, -+ ETHTOOL_LINK_MODE_100000baseLR2_ER2_FR2_Full_BIT, -+ ETHTOOL_LINK_MODE_100000baseDR2_Full_BIT, -+ ETHTOOL_LINK_MODE_200000baseKR4_Full_BIT, -+ ETHTOOL_LINK_MODE_200000baseSR4_Full_BIT, -+ ETHTOOL_LINK_MODE_200000baseLR4_ER4_FR4_Full_BIT, -+ ETHTOOL_LINK_MODE_200000baseDR4_Full_BIT, -+ ETHTOOL_LINK_MODE_200000baseCR4_Full_BIT, - }; - static const enum ethtool_link_mode_bit_indices - additional_advertised_flags_bits[] = { -@@ -689,6 +704,36 @@ static void dump_link_caps(const char *prefix, const char *an_prefix, - "2500baseT/Full" }, - { 0, ETHTOOL_LINK_MODE_5000baseT_Full_BIT, - "5000baseT/Full" }, -+ { 0, ETHTOOL_LINK_MODE_50000baseKR_Full_BIT, -+ "50000baseKR/Full" }, -+ { 0, ETHTOOL_LINK_MODE_50000baseSR_Full_BIT, -+ "50000baseSR/Full" }, -+ { 0, ETHTOOL_LINK_MODE_50000baseCR_Full_BIT, -+ "50000baseCR/Full" }, -+ { 0, ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT, -+ "50000baseLR_ER_FR/Full" }, -+ { 0, ETHTOOL_LINK_MODE_50000baseDR_Full_BIT, -+ "50000baseDR/Full" }, -+ { 0, ETHTOOL_LINK_MODE_100000baseKR2_Full_BIT, -+ "100000baseKR2/Full" }, -+ { 0, ETHTOOL_LINK_MODE_100000baseSR2_Full_BIT, -+ "100000baseSR2/Full" }, -+ { 0, ETHTOOL_LINK_MODE_100000baseCR2_Full_BIT, -+ "100000baseCR2/Full" }, -+ { 0, ETHTOOL_LINK_MODE_100000baseLR2_ER2_FR2_Full_BIT, -+ "100000baseLR2_ER2_FR2/Full" }, -+ { 0, ETHTOOL_LINK_MODE_100000baseDR2_Full_BIT, -+ "100000baseDR2/Full" }, -+ { 0, ETHTOOL_LINK_MODE_200000baseKR4_Full_BIT, -+ "200000baseKR4/Full" }, -+ { 0, ETHTOOL_LINK_MODE_200000baseSR4_Full_BIT, -+ "200000baseSR4/Full" }, -+ { 0, ETHTOOL_LINK_MODE_200000baseLR4_ER4_FR4_Full_BIT, -+ "200000baseLR4_ER4_FR4/Full" }, -+ { 0, ETHTOOL_LINK_MODE_200000baseDR4_Full_BIT, -+ "200000baseDR4/Full" }, -+ { 0, ETHTOOL_LINK_MODE_200000baseCR4_Full_BIT, -+ "200000baseCR4/Full" }, - }; - int indent; - int did1, new_line_pend, i; --- -1.8.3.1 - diff --git a/SOURCES/0001-netlink-Fix-the-condition-for-displaying-actual-chan.patch b/SOURCES/0001-netlink-Fix-the-condition-for-displaying-actual-chan.patch new file mode 100644 index 0000000..f0fc6af --- /dev/null +++ b/SOURCES/0001-netlink-Fix-the-condition-for-displaying-actual-chan.patch @@ -0,0 +1,46 @@ +From 89b49b2a88392c510c6a171940701ba4cf580116 Mon Sep 17 00:00:00 2001 +From: Maxim Mikityanskiy +Date: Fri, 14 Aug 2020 16:17:44 +0300 +Subject: [PATCH 01/17] netlink: Fix the condition for displaying actual + changes + +This comment in the code: + + /* result is not exactly as requested, show differences */ + +implies that the "Actual changes" output should be displayed only if the +result is not as requested, which matches the legacy ethtool behavior. +However, in fact, ethtool-netlink displays "actual changes" even when +the changes are expected (e.g., one bit was requested, and it was +changed as requested). + +This commit fixes the condition above to make the behavior match the +description in the comment and the behavior of the legacy ethtool. The +new condition excludes the req_mask bits from active_mask to avoid +reacting on bit changes that we asked for. The new condition now +matches the ifs in the loop above that print "[requested on/off]" and +"[not requested]". + +Signed-off-by: Maxim Mikityanskiy +Signed-off-by: Michal Kubecek +(cherry picked from commit 83d2b635de121a16a27663cc4e3045243e56063b) +--- + netlink/features.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/netlink/features.c b/netlink/features.c +index 8b5b8588ca23..133529da2b9f 100644 +--- a/netlink/features.c ++++ b/netlink/features.c +@@ -413,7 +413,7 @@ static void show_feature_changes(struct nl_context *nlctx, + + diff = false; + for (i = 0; i < words; i++) +- if (wanted_mask[i] || active_mask[i]) ++ if (wanted_mask[i] || (active_mask[i] & ~sfctx->req_mask[i])) + diff = true; + if (!diff) + return; +-- +2.26.2 + diff --git a/SOURCES/0002-netlink-Print-and-return-an-error-when-features-were.patch b/SOURCES/0002-netlink-Print-and-return-an-error-when-features-were.patch new file mode 100644 index 0000000..8e9dd10 --- /dev/null +++ b/SOURCES/0002-netlink-Print-and-return-an-error-when-features-were.patch @@ -0,0 +1,61 @@ +From ad9e296622adf2cd775c93a94c4ba2756d07e0d5 Mon Sep 17 00:00:00 2001 +From: Maxim Mikityanskiy +Date: Tue, 25 Aug 2020 11:11:38 +0300 +Subject: [PATCH 02/17] netlink: Print and return an error when features + weren't changed + +The legacy ethtool prints an error message and returns 1 if no features +were changed as requested. Port this behavior to ethtool-netlink. +req_mask is compared to wanted_mask to detect if any feature was +changed. If these masks are equal, it means that the kernel hasn't +changed anything, and all bits got to wanted. + +Signed-off-by: Maxim Mikityanskiy +Signed-off-by: Michal Kubecek +(cherry picked from commit e06cf83352d5161399da49eae7296126cd5e4ea1) +--- + netlink/features.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/netlink/features.c b/netlink/features.c +index 133529da2b9f..762259405acc 100644 +--- a/netlink/features.c ++++ b/netlink/features.c +@@ -243,6 +243,7 @@ int nl_gfeatures(struct cmd_context *ctx) + /* FEATURES_SET */ + + struct sfeatures_context { ++ bool nothing_changed; + uint32_t req_mask[0]; + }; + +@@ -411,10 +412,14 @@ static void show_feature_changes(struct nl_context *nlctx, + if (!wanted_val || !wanted_mask || !active_val || !active_mask) + goto err; + ++ sfctx->nothing_changed = true; + diff = false; +- for (i = 0; i < words; i++) ++ for (i = 0; i < words; i++) { ++ if (wanted_mask[i] != sfctx->req_mask[i]) ++ sfctx->nothing_changed = false; + if (wanted_mask[i] || (active_mask[i] & ~sfctx->req_mask[i])) + diff = true; ++ } + if (!diff) + return; + +@@ -520,6 +525,10 @@ int nl_sfeatures(struct cmd_context *ctx) + if (ret < 0) + return 92; + ret = nlsock_process_reply(nlsk, sfeatures_reply_cb, nlctx); ++ if (sfctx->nothing_changed) { ++ fprintf(stderr, "Could not change any device features\n"); ++ return nlctx->exit_code ?: 1; ++ } + if (ret == 0) + return 0; + return nlctx->exit_code ?: 92; +-- +2.26.2 + diff --git a/SOURCES/0003-netlink-get-rid-of-signed-unsigned-comparison-warnin.patch b/SOURCES/0003-netlink-get-rid-of-signed-unsigned-comparison-warnin.patch new file mode 100644 index 0000000..cae78ed --- /dev/null +++ b/SOURCES/0003-netlink-get-rid-of-signed-unsigned-comparison-warnin.patch @@ -0,0 +1,147 @@ +From aef2a21a2221c03e4e00fd06ea74002317fbfd5e Mon Sep 17 00:00:00 2001 +From: Michal Kubecek +Date: Sun, 23 Aug 2020 21:40:18 +0200 +Subject: [PATCH 03/17] netlink: get rid of signed/unsigned comparison warnings + +Use unsigned types where appropriate to get rid of compiler warnings about +comparison between signed and unsigned integer values in netlink code. + +v2: avoid casts in dump_features() + +Signed-off-by: Michal Kubecek +Reviewed-by: Andrew Lunn +(cherry picked from commit b038eef080221b1f9df944c3d2307bad172cf318) +--- + netlink/features.c | 6 +++--- + netlink/netlink.c | 4 ++-- + netlink/netlink.h | 2 +- + netlink/nlsock.c | 2 +- + netlink/parser.c | 2 +- + netlink/settings.c | 6 +++--- + 6 files changed, 11 insertions(+), 11 deletions(-) + +diff --git a/netlink/features.c b/netlink/features.c +index 762259405acc..3f1240437350 100644 +--- a/netlink/features.c ++++ b/netlink/features.c +@@ -109,9 +109,9 @@ static bool flag_pattern_match(const char *name, const char *pattern) + int dump_features(const struct nlattr *const *tb, + const struct stringset *feature_names) + { ++ unsigned int *feature_flags = NULL; + struct feature_results results; + unsigned int i, j; +- int *feature_flags = NULL; + int ret; + + ret = prepare_feature_results(tb, &results); +@@ -126,7 +126,7 @@ int dump_features(const struct nlattr *const *tb, + /* map netdev features to legacy flags */ + for (i = 0; i < results.count; i++) { + const char *name = get_string(feature_names, i); +- feature_flags[i] = -1; ++ feature_flags[i] = UINT_MAX; + + if (!name || !*name) + continue; +@@ -177,7 +177,7 @@ int dump_features(const struct nlattr *const *tb, + for (i = 0; i < results.count; i++) { + const char *name = get_string(feature_names, i); + +- if (!name || !*name || feature_flags[i] >= 0) ++ if (!name || !*name || feature_flags[i] != UINT_MAX) + continue; + dump_feature(&results, NULL, NULL, i, name, ""); + } +diff --git a/netlink/netlink.c b/netlink/netlink.c +index 76b6e825b1d0..e42d57076a4b 100644 +--- a/netlink/netlink.c ++++ b/netlink/netlink.c +@@ -33,9 +33,9 @@ int nomsg_reply_cb(const struct nlmsghdr *nlhdr, void *data __maybe_unused) + int attr_cb(const struct nlattr *attr, void *data) + { + const struct attr_tb_info *tb_info = data; +- int type = mnl_attr_get_type(attr); ++ uint16_t type = mnl_attr_get_type(attr); + +- if (type >= 0 && type <= tb_info->max_type) ++ if (type <= tb_info->max_type) + tb_info->tb[type] = attr; + + return MNL_CB_OK; +diff --git a/netlink/netlink.h b/netlink/netlink.h +index a4984c82ae76..dd4a02bcc916 100644 +--- a/netlink/netlink.h ++++ b/netlink/netlink.h +@@ -45,7 +45,7 @@ struct nl_context { + const char *cmd; + const char *param; + char **argp; +- int argc; ++ unsigned int argc; + bool ioctl_fallback; + bool wildcard_unsupported; + }; +diff --git a/netlink/nlsock.c b/netlink/nlsock.c +index c3f09b6ee9ab..ef31d8c33b29 100644 +--- a/netlink/nlsock.c ++++ b/netlink/nlsock.c +@@ -168,7 +168,7 @@ static void debug_msg(struct nl_socket *nlsk, const void *msg, unsigned int len, + * + * Return: error code extracted from the message + */ +-static int nlsock_process_ack(struct nlmsghdr *nlhdr, ssize_t len, ++static int nlsock_process_ack(struct nlmsghdr *nlhdr, unsigned long len, + unsigned int suppress_nlerr, bool pretty) + { + const struct nlattr *tb[NLMSGERR_ATTR_MAX + 1] = {}; +diff --git a/netlink/parser.c b/netlink/parser.c +index 395bd5743af9..c5a368a65a7a 100644 +--- a/netlink/parser.c ++++ b/netlink/parser.c +@@ -604,7 +604,7 @@ static int parse_numeric_bitset(struct nl_context *nlctx, uint16_t type, + parser_err_invalid_value(nlctx, arg); + return -EINVAL; + } +- len1 = maskptr ? (maskptr - arg) : strlen(arg); ++ len1 = maskptr ? (unsigned int)(maskptr - arg) : strlen(arg); + nwords = DIV_ROUND_UP(len1, 8); + nbits = 0; + +diff --git a/netlink/settings.c b/netlink/settings.c +index 17ef000ed812..2b9c6e7a782c 100644 +--- a/netlink/settings.c ++++ b/netlink/settings.c +@@ -276,10 +276,10 @@ int dump_link_modes(struct nl_context *nlctx, const struct nlattr *bitset, + const struct nlattr *bitset_tb[ETHTOOL_A_BITSET_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(bitset_tb); + const unsigned int before_len = strlen(before); ++ unsigned int prev = UINT_MAX - 1; + const struct nlattr *bits; + const struct nlattr *bit; + bool first = true; +- int prev = -2; + bool nomask; + int ret; + +@@ -333,7 +333,7 @@ int dump_link_modes(struct nl_context *nlctx, const struct nlattr *bitset, + if (first) + first = false; + /* ugly hack to preserve old output format */ +- if (class == LM_CLASS_REAL && (prev == idx - 1) && ++ if (class == LM_CLASS_REAL && (idx == prev + 1) && + prev < link_modes_count && + link_modes[prev].class == LM_CLASS_REAL && + link_modes[prev].duplex == DUPLEX_HALF) +@@ -375,7 +375,7 @@ int dump_link_modes(struct nl_context *nlctx, const struct nlattr *bitset, + first = false; + } else { + /* ugly hack to preserve old output format */ +- if ((class == LM_CLASS_REAL) && (prev == idx - 1) && ++ if ((class == LM_CLASS_REAL) && (idx == prev + 1) && + (prev < link_modes_count) && + (link_modes[prev].class == LM_CLASS_REAL) && + (link_modes[prev].duplex == DUPLEX_HALF)) +-- +2.26.2 + diff --git a/SOURCES/0004-ioctl-check-presence-of-eeprom-length-argument-prope.patch b/SOURCES/0004-ioctl-check-presence-of-eeprom-length-argument-prope.patch new file mode 100644 index 0000000..f83e89c --- /dev/null +++ b/SOURCES/0004-ioctl-check-presence-of-eeprom-length-argument-prope.patch @@ -0,0 +1,108 @@ +From ce297bec23dd0054600678b4297f6e73ecdc540d Mon Sep 17 00:00:00 2001 +From: Michal Kubecek +Date: Sun, 23 Aug 2020 21:40:21 +0200 +Subject: [PATCH 04/17] ioctl: check presence of eeprom length argument + properly + +In do_geeprom(), do_seprom() and do_getmodule(), check if user used +"length" command line argument is done by setting the value to -1 before +parsing and checking if it changed. This is quite ugly and also causes +compiler warnings as the variable is u32. + +Use proper "seen" flag to let parser tell us if the argument was used. + +Signed-off-by: Michal Kubecek +Reviewed-by: Andrew Lunn +(cherry picked from commit 923c3f51c4442a5f25afb529bd49ec2ef4f185a3) +--- + ethtool.c | 24 +++++++++++++++--------- + 1 file changed, 15 insertions(+), 9 deletions(-) + +diff --git a/ethtool.c b/ethtool.c +index c4ad186cd390..4fa7a2c1716f 100644 +--- a/ethtool.c ++++ b/ethtool.c +@@ -3184,10 +3184,12 @@ static int do_geeprom(struct cmd_context *ctx) + int geeprom_changed = 0; + int geeprom_dump_raw = 0; + u32 geeprom_offset = 0; +- u32 geeprom_length = -1; ++ u32 geeprom_length = 0; ++ int geeprom_length_seen = 0; + struct cmdline_info cmdline_geeprom[] = { + { "offset", CMDL_U32, &geeprom_offset, NULL }, +- { "length", CMDL_U32, &geeprom_length, NULL }, ++ { "length", CMDL_U32, &geeprom_length, NULL, ++ 0, &geeprom_length_seen }, + { "raw", CMDL_BOOL, &geeprom_dump_raw, NULL }, + }; + int err; +@@ -3204,7 +3206,7 @@ static int do_geeprom(struct cmd_context *ctx) + return 74; + } + +- if (geeprom_length == -1) ++ if (!geeprom_length_seen) + geeprom_length = drvinfo.eedump_len; + + if (drvinfo.eedump_len < geeprom_offset + geeprom_length) +@@ -3234,14 +3236,16 @@ static int do_seeprom(struct cmd_context *ctx) + { + int seeprom_changed = 0; + u32 seeprom_magic = 0; +- u32 seeprom_length = -1; ++ u32 seeprom_length = 0; + u32 seeprom_offset = 0; + u8 seeprom_value = 0; ++ int seeprom_length_seen = 0; + int seeprom_value_seen = 0; + struct cmdline_info cmdline_seeprom[] = { + { "magic", CMDL_U32, &seeprom_magic, NULL }, + { "offset", CMDL_U32, &seeprom_offset, NULL }, +- { "length", CMDL_U32, &seeprom_length, NULL }, ++ { "length", CMDL_U32, &seeprom_length, NULL, ++ 0, &seeprom_length_seen }, + { "value", CMDL_U8, &seeprom_value, NULL, + 0, &seeprom_value_seen }, + }; +@@ -3262,7 +3266,7 @@ static int do_seeprom(struct cmd_context *ctx) + if (seeprom_value_seen) + seeprom_length = 1; + +- if (seeprom_length == -1) ++ if (!seeprom_length_seen) + seeprom_length = drvinfo.eedump_len; + + if (drvinfo.eedump_len < seeprom_offset + seeprom_length) { +@@ -4538,15 +4542,17 @@ static int do_getmodule(struct cmd_context *ctx) + struct ethtool_modinfo modinfo; + struct ethtool_eeprom *eeprom; + u32 geeprom_offset = 0; +- u32 geeprom_length = -1; ++ u32 geeprom_length = 0; + int geeprom_changed = 0; + int geeprom_dump_raw = 0; + int geeprom_dump_hex = 0; ++ int geeprom_length_seen = 0; + int err; + + struct cmdline_info cmdline_geeprom[] = { + { "offset", CMDL_U32, &geeprom_offset, NULL }, +- { "length", CMDL_U32, &geeprom_length, NULL }, ++ { "length", CMDL_U32, &geeprom_length, NULL, ++ 0, &geeprom_length_seen }, + { "raw", CMDL_BOOL, &geeprom_dump_raw, NULL }, + { "hex", CMDL_BOOL, &geeprom_dump_hex, NULL }, + }; +@@ -4566,7 +4572,7 @@ static int do_getmodule(struct cmd_context *ctx) + return 1; + } + +- if (geeprom_length == -1) ++ if (!geeprom_length_seen) + geeprom_length = modinfo.eeprom_len; + + if (modinfo.eeprom_len < geeprom_offset + geeprom_length) +-- +2.26.2 + diff --git a/SOURCES/0005-ioctl-prevent-argc-underflow-in-do_perqueue.patch b/SOURCES/0005-ioctl-prevent-argc-underflow-in-do_perqueue.patch new file mode 100644 index 0000000..422f028 --- /dev/null +++ b/SOURCES/0005-ioctl-prevent-argc-underflow-in-do_perqueue.patch @@ -0,0 +1,33 @@ +From 04315b072d623ba9200612a4c5f5330f1eb28a27 Mon Sep 17 00:00:00 2001 +From: Michal Kubecek +Date: Sun, 23 Aug 2020 21:40:24 +0200 +Subject: [PATCH 05/17] ioctl: prevent argc underflow in do_perqueue() + +When first command line argument after "-Q" is "queue_mask", we parse +the queue mask and following subcommand without checking if these +arguments do actually exist. Add check if we have at least two arguments +left after "queue_mask" in the corresponding branch. + +Fixes: 9ecd54248b1a ("ethtool: introduce new ioctl for per-queue settings") +Signed-off-by: Michal Kubecek +(cherry picked from commit 39c354e591b66cc29edaab89f90ed03a513ad88f) +--- + ethtool.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/ethtool.c b/ethtool.c +index 4fa7a2c1716f..6c12452be7b4 100644 +--- a/ethtool.c ++++ b/ethtool.c +@@ -5880,6 +5880,8 @@ static int do_perqueue(struct cmd_context *ctx) + "The sub commands will be applied to all %d queues\n", + n_queues); + } else { ++ if (ctx->argc <= 2) ++ exit_bad_args(); + ctx->argc--; + ctx->argp++; + if (parse_hex_u32_bitmap(*ctx->argp, MAX_NUM_QUEUE, +-- +2.26.2 + diff --git a/SOURCES/0006-ioctl-make-argc-counters-unsigned.patch b/SOURCES/0006-ioctl-make-argc-counters-unsigned.patch new file mode 100644 index 0000000..229f05e --- /dev/null +++ b/SOURCES/0006-ioctl-make-argc-counters-unsigned.patch @@ -0,0 +1,113 @@ +From 7e3888aeb31d2920c3c282b135563a06c3bcf6e1 Mon Sep 17 00:00:00 2001 +From: Michal Kubecek +Date: Sun, 23 Aug 2020 21:40:27 +0200 +Subject: [PATCH 06/17] ioctl: make argc counters unsigned + +Use unsigned int for cmd_context::argc and local variables used for +command line argument count. These counters may never get negative and are +often compared to unsigned expressions. + +Signed-off-by: Michal Kubecek +Reviewed-by: Andrew Lunn +(cherry picked from commit 519f95bd59034e672cfbac70ca8d7badc4f26cc7) +--- + ethtool.c | 24 ++++++++++++------------ + internal.h | 2 +- + 2 files changed, 13 insertions(+), 13 deletions(-) + +diff --git a/ethtool.c b/ethtool.c +index 6c12452be7b4..7c7e98957c80 100644 +--- a/ethtool.c ++++ b/ethtool.c +@@ -223,9 +223,9 @@ static void parse_generic_cmdline(struct cmd_context *ctx, + struct cmdline_info *info, + unsigned int n_info) + { +- int argc = ctx->argc; ++ unsigned int argc = ctx->argc; + char **argp = ctx->argp; +- int i, idx; ++ unsigned int i, idx; + int found; + + for (i = 0; i < argc; i++) { +@@ -2724,9 +2724,9 @@ static int do_sset(struct cmd_context *ctx) + u32 msglvl_wanted = 0; + u32 msglvl_mask = 0; + struct cmdline_info cmdline_msglvl[n_flags_msglvl]; +- int argc = ctx->argc; ++ unsigned int argc = ctx->argc; + char **argp = ctx->argp; +- int i; ++ unsigned int i; + int err = 0; + + for (i = 0; i < n_flags_msglvl; i++) +@@ -3671,7 +3671,7 @@ static int do_grxfh(struct cmd_context *ctx) + struct ethtool_rxfh *rss; + u32 rss_context = 0; + u32 i, indir_bytes; +- int arg_num = 0; ++ unsigned int arg_num = 0; + char *hkey; + int err; + +@@ -4832,9 +4832,8 @@ static int do_gtunable(struct cmd_context *ctx) + { + struct ethtool_tunable_info *tinfo = tunables_info; + char **argp = ctx->argp; +- int argc = ctx->argc; +- int i; +- int j; ++ unsigned int argc = ctx->argc; ++ unsigned int i, j; + + if (argc < 1) + exit_bad_args(); +@@ -4876,7 +4875,7 @@ static int do_gtunable(struct cmd_context *ctx) + + static int do_get_phy_tunable(struct cmd_context *ctx) + { +- int argc = ctx->argc; ++ unsigned int argc = ctx->argc; + char **argp = ctx->argp; + + if (argc < 1) +@@ -4980,9 +4979,9 @@ static int do_reset(struct cmd_context *ctx) + { + struct ethtool_value resetinfo; + __u32 data; +- int argc = ctx->argc; ++ unsigned int argc = ctx->argc; + char **argp = ctx->argp; +- int i; ++ unsigned int i; + + if (argc == 0) + exit_bad_args(); +@@ -5270,7 +5269,8 @@ static int do_sfec(struct cmd_context *ctx) + enum { ARG_NONE, ARG_ENCODING } state = ARG_NONE; + struct ethtool_fecparam feccmd; + int fecmode = 0, newmode; +- int rv, i; ++ unsigned int i; ++ int rv; + + for (i = 0; i < ctx->argc; i++) { + if (!strcmp(ctx->argp[i], "encoding")) { +diff --git a/internal.h b/internal.h +index 8ae1efab5b5c..d096a28abfa2 100644 +--- a/internal.h ++++ b/internal.h +@@ -221,7 +221,7 @@ struct cmd_context { + const char *devname; /* net device name */ + int fd; /* socket suitable for ethtool ioctl */ + struct ifreq ifr; /* ifreq suitable for ethtool ioctl */ +- int argc; /* number of arguments to the sub-command */ ++ unsigned int argc; /* number of arguments to the sub-command */ + char **argp; /* arguments to the sub-command */ + unsigned long debug; /* debugging mask */ + bool json; /* Output JSON, if supported */ +-- +2.26.2 + diff --git a/SOURCES/0007-ioctl-get-rid-of-signed-unsigned-comparison-warnings.patch b/SOURCES/0007-ioctl-get-rid-of-signed-unsigned-comparison-warnings.patch new file mode 100644 index 0000000..2d94966 --- /dev/null +++ b/SOURCES/0007-ioctl-get-rid-of-signed-unsigned-comparison-warnings.patch @@ -0,0 +1,144 @@ +From 4be3e49856ef6c4f09f2230bbcf40cb7492313ca Mon Sep 17 00:00:00 2001 +From: Michal Kubecek +Date: Sun, 23 Aug 2020 21:40:30 +0200 +Subject: [PATCH 07/17] ioctl: get rid of signed/unsigned comparison warnings + +Comparison between signed and unsigned values is fragile and causes +compiler warnings with recent compilers and stricter CFLAGS. Prevent such +comparisons either by properly declaring variables (mostly loop iterators) +as unsigned or by explicitly casting one side of the comparison. + +v2: rework argc related changes and split them into a separate patch + +Signed-off-by: Michal Kubecek +(cherry picked from commit f2f0fca943ffa25458865e4187690c9c7d6a89bc) +--- + ethtool.c | 31 +++++++++++++++++-------------- + 1 file changed, 17 insertions(+), 14 deletions(-) + +diff --git a/ethtool.c b/ethtool.c +index 7c7e98957c80..3c30824016d5 100644 +--- a/ethtool.c ++++ b/ethtool.c +@@ -641,8 +641,9 @@ static void dump_link_caps(const char *prefix, const char *an_prefix, + "200000baseCR4/Full" }, + }; + int indent; +- int did1, new_line_pend, i; ++ int did1, new_line_pend; + int fecreported = 0; ++ unsigned int i; + + /* Indent just like the separate functions used to */ + indent = strlen(prefix) + 14; +@@ -1071,7 +1072,7 @@ void dump_hex(FILE *file, const u8 *data, int len, int offset) + static int dump_regs(int gregs_dump_raw, int gregs_dump_hex, + struct ethtool_drvinfo *info, struct ethtool_regs *regs) + { +- int i; ++ unsigned int i; + + if (gregs_dump_raw) { + fwrite(regs->data, regs->len, 1, stdout); +@@ -1128,7 +1129,8 @@ static int dump_eeprom(int geeprom_dump_raw, + static int dump_test(struct ethtool_test *test, + struct ethtool_gstrings *strings) + { +- int i, rc; ++ unsigned int i; ++ int rc; + + rc = test->flags & ETH_TEST_FL_FAILED; + fprintf(stdout, "The test result is %s\n", rc ? "FAIL" : "PASS"); +@@ -1359,7 +1361,7 @@ static void dump_one_feature(const char *indent, const char *name, + : ""); + } + +-static int linux_version_code(void) ++static unsigned int linux_version_code(void) + { + struct utsname utsname; + unsigned version, patchlevel, sublevel = 0; +@@ -1375,10 +1377,10 @@ static void dump_features(const struct feature_defs *defs, + const struct feature_state *state, + const struct feature_state *ref_state) + { +- int kernel_ver = linux_version_code(); +- u32 value; ++ unsigned int kernel_ver = linux_version_code(); ++ unsigned int i, j; + int indent; +- int i, j; ++ u32 value; + + for (i = 0; i < OFF_FLAG_DEF_SIZE; i++) { + /* Don't show features whose state is unknown on this +@@ -1411,7 +1413,7 @@ static void dump_features(const struct feature_defs *defs, + + /* Show matching features */ + for (j = 0; j < defs->n_features; j++) { +- if (defs->def[j].off_flag_index != i) ++ if (defs->def[j].off_flag_index != (int)i) + continue; + if (defs->off_flag_matched[i] != 1) + /* Show all matching feature states */ +@@ -1668,8 +1670,8 @@ static struct feature_defs *get_feature_defs(struct cmd_context *ctx) + { + struct ethtool_gstrings *names; + struct feature_defs *defs; ++ unsigned int i, j; + u32 n_features; +- int i, j; + + names = get_stringset(ctx, ETH_SS_FEATURES, 0, 1); + if (names) { +@@ -2236,8 +2238,8 @@ static int do_sfeatures(struct cmd_context *ctx) + struct cmdline_info *cmdline_features; + struct feature_state *old_state, *new_state; + struct ethtool_value eval; ++ unsigned int i, j; + int err, rc; +- int i, j; + + defs = get_feature_defs(ctx); + if (!defs) { +@@ -2317,7 +2319,7 @@ static int do_sfeatures(struct cmd_context *ctx) + continue; + + for (j = 0; j < defs->n_features; j++) { +- if (defs->def[j].off_flag_index != i || ++ if (defs->def[j].off_flag_index != (int)i || + !FEATURE_BIT_IS_SET( + old_state->features.features, + j, available) || +@@ -3869,7 +3871,7 @@ static int do_srxfh(struct cmd_context *ctx) + char *hfunc_name = NULL; + char *hkey = NULL; + int err = 0; +- int i; ++ unsigned int i; + u32 arg_num = 0, indir_bytes = 0; + u32 req_hfunc = 0; + u32 entry_size = sizeof(rss_head.rss_config[0]); +@@ -4135,7 +4137,8 @@ static int do_flash(struct cmd_context *ctx) + + static int do_permaddr(struct cmd_context *ctx) + { +- int i, err; ++ unsigned int i; ++ int err; + struct ethtool_perm_addr *epaddr; + + epaddr = malloc(sizeof(struct ethtool_perm_addr) + MAX_ADDR_LEN); +@@ -4750,7 +4753,7 @@ static int do_stunable(struct cmd_context *ctx) + struct cmdline_info cmdline_tunable[TUNABLES_INFO_SIZE]; + struct ethtool_tunable_info *tinfo = tunables_info; + int changed = 0; +- int i; ++ unsigned int i; + + for (i = 0; i < TUNABLES_INFO_SIZE; i++) { + cmdline_tunable[i].name = tunable_strings[tinfo[i].t_id]; +-- +2.26.2 + diff --git a/SOURCES/0008-get-rid-of-signed-unsigned-comparison-warnings-in-re.patch b/SOURCES/0008-get-rid-of-signed-unsigned-comparison-warnings-in-re.patch new file mode 100644 index 0000000..218240f --- /dev/null +++ b/SOURCES/0008-get-rid-of-signed-unsigned-comparison-warnings-in-re.patch @@ -0,0 +1,164 @@ +From a76ac50c3049b7fa77f71828c4e0a3569eea626d Mon Sep 17 00:00:00 2001 +From: Michal Kubecek +Date: Sun, 23 Aug 2020 21:40:33 +0200 +Subject: [PATCH 08/17] get rid of signed/unsigned comparison warnings in + register dump parsers + +All of these are avoided by declaring a variable (mostly loop iterators) +holding only unsigned values as unsigned. + +Signed-off-by: Michal Kubecek +Reviewed-by: Andrew Lunn +(cherry picked from commit 16c87d0a03757958d857d7054bd296bfc74c6d39) +--- + dsa.c | 2 +- + fec.c | 2 +- + ibm_emac.c | 2 +- + marvell.c | 2 +- + natsemi.c | 2 +- + rxclass.c | 8 +++++--- + sfpdiag.c | 2 +- + tg3.c | 4 ++-- + 8 files changed, 13 insertions(+), 11 deletions(-) + +diff --git a/dsa.c b/dsa.c +index 65502a899194..33c1d39d6605 100644 +--- a/dsa.c ++++ b/dsa.c +@@ -824,8 +824,8 @@ static int dsa_mv88e6xxx_dump_regs(struct ethtool_regs *regs) + { + const struct dsa_mv88e6xxx_switch *sw = NULL; + const u16 *data = (u16 *)regs->data; ++ unsigned int i; + u16 id; +- int i; + + /* Marvell chips have 32 per-port 16-bit registers */ + if (regs->len < 32 * sizeof(u16)) +diff --git a/fec.c b/fec.c +index 9cb4f8b1d4e1..d2373d6124c0 100644 +--- a/fec.c ++++ b/fec.c +@@ -198,7 +198,7 @@ int fec_dump_regs(struct ethtool_drvinfo *info __maybe_unused, + struct ethtool_regs *regs) + { + const u32 *data = (u32 *)regs->data; +- int offset; ++ unsigned int offset; + u32 val; + + for (offset = 0; offset < regs->len; offset += 4) { +diff --git a/ibm_emac.c b/ibm_emac.c +index ea01d56f609c..9f7cae605482 100644 +--- a/ibm_emac.c ++++ b/ibm_emac.c +@@ -238,7 +238,7 @@ static void *print_mal_regs(void *buf) + { + struct emac_ethtool_regs_subhdr *hdr = buf; + struct mal_regs *p = (struct mal_regs *)(hdr + 1); +- int i; ++ unsigned int i; + + printf("MAL%d Registers\n", hdr->index); + printf("-----------------\n"); +diff --git a/marvell.c b/marvell.c +index 8afb150327a3..d3d570e4d4ad 100644 +--- a/marvell.c ++++ b/marvell.c +@@ -130,7 +130,7 @@ static void dump_fifo(const char *name, const void *p) + static void dump_gmac_fifo(const char *name, const void *p) + { + const u32 *r = p; +- int i; ++ unsigned int i; + static const char *regs[] = { + "End Address", + "Almost Full Thresh", +diff --git a/natsemi.c b/natsemi.c +index 0af465959cbc..4d9fc092b623 100644 +--- a/natsemi.c ++++ b/natsemi.c +@@ -967,8 +967,8 @@ int + natsemi_dump_eeprom(struct ethtool_drvinfo *info __maybe_unused, + struct ethtool_eeprom *ee) + { +- int i; + u16 *eebuf = (u16 *)ee->data; ++ unsigned int i; + + if (ee->magic != NATSEMI_MAGIC) { + fprintf(stderr, "Magic number 0x%08x does not match 0x%08x\n", +diff --git a/rxclass.c b/rxclass.c +index 79972651e706..6cf81fdafc85 100644 +--- a/rxclass.c ++++ b/rxclass.c +@@ -348,8 +348,9 @@ int rxclass_rule_getall(struct cmd_context *ctx) + { + struct ethtool_rxnfc *nfccmd; + __u32 *rule_locs; +- int err, i; ++ unsigned int i; + __u32 count; ++ int err; + + /* determine rule count */ + err = rxclass_get_dev_info(ctx, &count, NULL); +@@ -481,8 +482,9 @@ static int rmgr_find_empty_slot(struct rmgr_ctrl *rmgr, + static int rmgr_init(struct cmd_context *ctx, struct rmgr_ctrl *rmgr) + { + struct ethtool_rxnfc *nfccmd; +- int err, i; + __u32 *rule_locs; ++ unsigned int i; ++ int err; + + /* clear rule manager settings */ + memset(rmgr, 0, sizeof(*rmgr)); +@@ -941,7 +943,7 @@ static int rxclass_get_long(char *str, long long *val, int size) + + static int rxclass_get_ulong(char *str, unsigned long long *val, int size) + { +- long long max = ~0ULL >> (64 - size); ++ unsigned long long max = ~0ULL >> (64 - size); + char *endp; + + errno = 0; +diff --git a/sfpdiag.c b/sfpdiag.c +index fa41651422ea..1fa8b7ba8fec 100644 +--- a/sfpdiag.c ++++ b/sfpdiag.c +@@ -190,8 +190,8 @@ static float befloattoh(const __u32 *source) + + static void sff8472_calibration(const __u8 *id, struct sff_diags *sd) + { +- int i; + __u16 rx_reading; ++ unsigned int i; + + /* Calibration should occur for all values (threshold and current) */ + for (i = 0; i < ARRAY_SIZE(sd->bias_cur); ++i) { +diff --git a/tg3.c b/tg3.c +index ac73b33ae4e3..ebdef2d60e6b 100644 +--- a/tg3.c ++++ b/tg3.c +@@ -7,7 +7,7 @@ + int tg3_dump_eeprom(struct ethtool_drvinfo *info __maybe_unused, + struct ethtool_eeprom *ee) + { +- int i; ++ unsigned int i; + + if (ee->magic != TG3_MAGIC) { + fprintf(stderr, "Magic number 0x%08x does not match 0x%08x\n", +@@ -26,7 +26,7 @@ int tg3_dump_eeprom(struct ethtool_drvinfo *info __maybe_unused, + int tg3_dump_regs(struct ethtool_drvinfo *info __maybe_unused, + struct ethtool_regs *regs) + { +- int i; ++ unsigned int i; + u32 reg; + + fprintf(stdout, "Offset\tValue\n"); +-- +2.26.2 + diff --git a/SOURCES/0009-settings-simplify-link_mode_info-initializers.patch b/SOURCES/0009-settings-simplify-link_mode_info-initializers.patch new file mode 100644 index 0000000..1e3d9b2 --- /dev/null +++ b/SOURCES/0009-settings-simplify-link_mode_info-initializers.patch @@ -0,0 +1,273 @@ +From f99224132fba926ac0fb736748586ecdd51bb9d4 Mon Sep 17 00:00:00 2001 +From: Michal Kubecek +Date: Sun, 23 Aug 2020 21:40:36 +0200 +Subject: [PATCH 09/17] settings: simplify link_mode_info[] initializers + +Use macro helpers to make link_mode_info[] initializers easier to read and +less prone to mistakes. As a bonus, this gets rid of "missing field +initializer" warnings in netlink/settings.c + +This commit should have no effect on resulting code (checked with gcc-11 +and -O2). + +Signed-off-by: Michal Kubecek +Reviewed-by: Andrew Lunn +(cherry picked from commit 5319fae14254df9cb38cb2db0a4e39973c3fc1d8) +--- + netlink/settings.c | 236 +++++++++++++++++---------------------------- + 1 file changed, 86 insertions(+), 150 deletions(-) + +diff --git a/netlink/settings.c b/netlink/settings.c +index 2b9c6e7a782c..d1da995b434c 100644 +--- a/netlink/settings.c ++++ b/netlink/settings.c +@@ -64,160 +64,96 @@ static const char *const names_transceiver[] = { + * there is little chance of getting them separated any time soon so let's + * sort them out ourselves + */ ++#define __REAL(_speed) \ ++ { .class = LM_CLASS_REAL, .speed = _speed, .duplex = DUPLEX_FULL } ++#define __HALF_DUPLEX(_speed) \ ++ { .class = LM_CLASS_REAL, .speed = _speed, .duplex = DUPLEX_HALF } ++#define __SPECIAL(_class) \ ++ { .class = LM_CLASS_ ## _class } ++ + static const struct link_mode_info link_modes[] = { +- [ETHTOOL_LINK_MODE_10baseT_Half_BIT] = +- { LM_CLASS_REAL, 10, DUPLEX_HALF }, +- [ETHTOOL_LINK_MODE_10baseT_Full_BIT] = +- { LM_CLASS_REAL, 10, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_100baseT_Half_BIT] = +- { LM_CLASS_REAL, 100, DUPLEX_HALF }, +- [ETHTOOL_LINK_MODE_100baseT_Full_BIT] = +- { LM_CLASS_REAL, 100, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_1000baseT_Half_BIT] = +- { LM_CLASS_REAL, 1000, DUPLEX_HALF }, +- [ETHTOOL_LINK_MODE_1000baseT_Full_BIT] = +- { LM_CLASS_REAL, 1000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_Autoneg_BIT] = +- { LM_CLASS_AUTONEG }, +- [ETHTOOL_LINK_MODE_TP_BIT] = +- { LM_CLASS_PORT }, +- [ETHTOOL_LINK_MODE_AUI_BIT] = +- { LM_CLASS_PORT }, +- [ETHTOOL_LINK_MODE_MII_BIT] = +- { LM_CLASS_PORT }, +- [ETHTOOL_LINK_MODE_FIBRE_BIT] = +- { LM_CLASS_PORT }, +- [ETHTOOL_LINK_MODE_BNC_BIT] = +- { LM_CLASS_PORT }, +- [ETHTOOL_LINK_MODE_10000baseT_Full_BIT] = +- { LM_CLASS_REAL, 10000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_Pause_BIT] = +- { LM_CLASS_PAUSE }, +- [ETHTOOL_LINK_MODE_Asym_Pause_BIT] = +- { LM_CLASS_PAUSE }, +- [ETHTOOL_LINK_MODE_2500baseX_Full_BIT] = +- { LM_CLASS_REAL, 2500, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_Backplane_BIT] = +- { LM_CLASS_PORT }, +- [ETHTOOL_LINK_MODE_1000baseKX_Full_BIT] = +- { LM_CLASS_REAL, 1000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT] = +- { LM_CLASS_REAL, 10000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_10000baseKR_Full_BIT] = +- { LM_CLASS_REAL, 10000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_10000baseR_FEC_BIT] = +- { LM_CLASS_REAL, 10000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_20000baseMLD2_Full_BIT] = +- { LM_CLASS_REAL, 20000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT] = +- { LM_CLASS_REAL, 20000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT] = +- { LM_CLASS_REAL, 40000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT] = +- { LM_CLASS_REAL, 40000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT] = +- { LM_CLASS_REAL, 40000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT] = +- { LM_CLASS_REAL, 40000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_56000baseKR4_Full_BIT] = +- { LM_CLASS_REAL, 56000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_56000baseCR4_Full_BIT] = +- { LM_CLASS_REAL, 56000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_56000baseSR4_Full_BIT] = +- { LM_CLASS_REAL, 56000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT] = +- { LM_CLASS_REAL, 56000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_25000baseCR_Full_BIT] = +- { LM_CLASS_REAL, 25000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_25000baseKR_Full_BIT] = +- { LM_CLASS_REAL, 25000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_25000baseSR_Full_BIT] = +- { LM_CLASS_REAL, 25000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT] = +- { LM_CLASS_REAL, 50000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT] = +- { LM_CLASS_REAL, 50000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT] = +- { LM_CLASS_REAL, 100000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT] = +- { LM_CLASS_REAL, 100000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT] = +- { LM_CLASS_REAL, 100000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT] = +- { LM_CLASS_REAL, 100000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT] = +- { LM_CLASS_REAL, 50000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_1000baseX_Full_BIT] = +- { LM_CLASS_REAL, 1000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_10000baseCR_Full_BIT] = +- { LM_CLASS_REAL, 10000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_10000baseSR_Full_BIT] = +- { LM_CLASS_REAL, 10000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_10000baseLR_Full_BIT] = +- { LM_CLASS_REAL, 10000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT] = +- { LM_CLASS_REAL, 10000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_10000baseER_Full_BIT] = +- { LM_CLASS_REAL, 10000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_2500baseT_Full_BIT] = +- { LM_CLASS_REAL, 2500, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_5000baseT_Full_BIT] = +- { LM_CLASS_REAL, 5000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_FEC_NONE_BIT] = +- { LM_CLASS_FEC }, +- [ETHTOOL_LINK_MODE_FEC_RS_BIT] = +- { LM_CLASS_FEC }, +- [ETHTOOL_LINK_MODE_FEC_BASER_BIT] = +- { LM_CLASS_FEC }, +- [ETHTOOL_LINK_MODE_50000baseKR_Full_BIT] = +- { LM_CLASS_REAL, 50000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_50000baseSR_Full_BIT] = +- { LM_CLASS_REAL, 50000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_50000baseCR_Full_BIT] = +- { LM_CLASS_REAL, 50000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT] = +- { LM_CLASS_REAL, 50000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_50000baseDR_Full_BIT] = +- { LM_CLASS_REAL, 50000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_100000baseKR2_Full_BIT] = +- { LM_CLASS_REAL, 100000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_100000baseSR2_Full_BIT] = +- { LM_CLASS_REAL, 100000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_100000baseCR2_Full_BIT] = +- { LM_CLASS_REAL, 100000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_100000baseLR2_ER2_FR2_Full_BIT] = +- { LM_CLASS_REAL, 100000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_100000baseDR2_Full_BIT] = +- { LM_CLASS_REAL, 100000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_200000baseKR4_Full_BIT] = +- { LM_CLASS_REAL, 200000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_200000baseSR4_Full_BIT] = +- { LM_CLASS_REAL, 200000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_200000baseLR4_ER4_FR4_Full_BIT] = +- { LM_CLASS_REAL, 200000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_200000baseDR4_Full_BIT] = +- { LM_CLASS_REAL, 200000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_200000baseCR4_Full_BIT] = +- { LM_CLASS_REAL, 200000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_100baseT1_Full_BIT] = +- { LM_CLASS_REAL, 100, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_1000baseT1_Full_BIT] = +- { LM_CLASS_REAL, 1000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_400000baseKR8_Full_BIT] = +- { LM_CLASS_REAL, 400000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_400000baseSR8_Full_BIT] = +- { LM_CLASS_REAL, 400000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_400000baseLR8_ER8_FR8_Full_BIT] = +- { LM_CLASS_REAL, 400000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_400000baseDR8_Full_BIT] = +- { LM_CLASS_REAL, 400000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_400000baseCR8_Full_BIT] = +- { LM_CLASS_REAL, 400000, DUPLEX_FULL }, +- [ETHTOOL_LINK_MODE_FEC_LLRS_BIT] = +- { LM_CLASS_FEC }, ++ [ETHTOOL_LINK_MODE_10baseT_Half_BIT] = __HALF_DUPLEX(10), ++ [ETHTOOL_LINK_MODE_10baseT_Full_BIT] = __REAL(10), ++ [ETHTOOL_LINK_MODE_100baseT_Half_BIT] = __HALF_DUPLEX(100), ++ [ETHTOOL_LINK_MODE_100baseT_Full_BIT] = __REAL(100), ++ [ETHTOOL_LINK_MODE_1000baseT_Half_BIT] = __HALF_DUPLEX(1000), ++ [ETHTOOL_LINK_MODE_1000baseT_Full_BIT] = __REAL(1000), ++ [ETHTOOL_LINK_MODE_Autoneg_BIT] = __SPECIAL(AUTONEG), ++ [ETHTOOL_LINK_MODE_TP_BIT] = __SPECIAL(PORT), ++ [ETHTOOL_LINK_MODE_AUI_BIT] = __SPECIAL(PORT), ++ [ETHTOOL_LINK_MODE_MII_BIT] = __SPECIAL(PORT), ++ [ETHTOOL_LINK_MODE_FIBRE_BIT] = __SPECIAL(PORT), ++ [ETHTOOL_LINK_MODE_BNC_BIT] = __SPECIAL(PORT), ++ [ETHTOOL_LINK_MODE_10000baseT_Full_BIT] = __REAL(10000), ++ [ETHTOOL_LINK_MODE_Pause_BIT] = __SPECIAL(PAUSE), ++ [ETHTOOL_LINK_MODE_Asym_Pause_BIT] = __SPECIAL(PAUSE), ++ [ETHTOOL_LINK_MODE_2500baseX_Full_BIT] = __REAL(2500), ++ [ETHTOOL_LINK_MODE_Backplane_BIT] = __SPECIAL(PORT), ++ [ETHTOOL_LINK_MODE_1000baseKX_Full_BIT] = __REAL(1000), ++ [ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT] = __REAL(10000), ++ [ETHTOOL_LINK_MODE_10000baseKR_Full_BIT] = __REAL(10000), ++ [ETHTOOL_LINK_MODE_10000baseR_FEC_BIT] = __REAL(10000), ++ [ETHTOOL_LINK_MODE_20000baseMLD2_Full_BIT] = __REAL(20000), ++ [ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT] = __REAL(20000), ++ [ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT] = __REAL(40000), ++ [ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT] = __REAL(40000), ++ [ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT] = __REAL(40000), ++ [ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT] = __REAL(40000), ++ [ETHTOOL_LINK_MODE_56000baseKR4_Full_BIT] = __REAL(56000), ++ [ETHTOOL_LINK_MODE_56000baseCR4_Full_BIT] = __REAL(56000), ++ [ETHTOOL_LINK_MODE_56000baseSR4_Full_BIT] = __REAL(56000), ++ [ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT] = __REAL(56000), ++ [ETHTOOL_LINK_MODE_25000baseCR_Full_BIT] = __REAL(25000), ++ [ETHTOOL_LINK_MODE_25000baseKR_Full_BIT] = __REAL(25000), ++ [ETHTOOL_LINK_MODE_25000baseSR_Full_BIT] = __REAL(25000), ++ [ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT] = __REAL(50000), ++ [ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT] = __REAL(50000), ++ [ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT] = __REAL(100000), ++ [ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT] = __REAL(100000), ++ [ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT] = __REAL(100000), ++ [ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT] = __REAL(100000), ++ [ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT] = __REAL(50000), ++ [ETHTOOL_LINK_MODE_1000baseX_Full_BIT] = __REAL(1000), ++ [ETHTOOL_LINK_MODE_10000baseCR_Full_BIT] = __REAL(10000), ++ [ETHTOOL_LINK_MODE_10000baseSR_Full_BIT] = __REAL(10000), ++ [ETHTOOL_LINK_MODE_10000baseLR_Full_BIT] = __REAL(10000), ++ [ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT] = __REAL(10000), ++ [ETHTOOL_LINK_MODE_10000baseER_Full_BIT] = __REAL(10000), ++ [ETHTOOL_LINK_MODE_2500baseT_Full_BIT] = __REAL(2500), ++ [ETHTOOL_LINK_MODE_5000baseT_Full_BIT] = __REAL(5000), ++ [ETHTOOL_LINK_MODE_FEC_NONE_BIT] = __SPECIAL(FEC), ++ [ETHTOOL_LINK_MODE_FEC_RS_BIT] = __SPECIAL(FEC), ++ [ETHTOOL_LINK_MODE_FEC_BASER_BIT] = __SPECIAL(FEC), ++ [ETHTOOL_LINK_MODE_50000baseKR_Full_BIT] = __REAL(50000), ++ [ETHTOOL_LINK_MODE_50000baseSR_Full_BIT] = __REAL(50000), ++ [ETHTOOL_LINK_MODE_50000baseCR_Full_BIT] = __REAL(50000), ++ [ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT] = __REAL(50000), ++ [ETHTOOL_LINK_MODE_50000baseDR_Full_BIT] = __REAL(50000), ++ [ETHTOOL_LINK_MODE_100000baseKR2_Full_BIT] = __REAL(100000), ++ [ETHTOOL_LINK_MODE_100000baseSR2_Full_BIT] = __REAL(100000), ++ [ETHTOOL_LINK_MODE_100000baseCR2_Full_BIT] = __REAL(100000), ++ [ETHTOOL_LINK_MODE_100000baseLR2_ER2_FR2_Full_BIT] = __REAL(100000), ++ [ETHTOOL_LINK_MODE_100000baseDR2_Full_BIT] = __REAL(100000), ++ [ETHTOOL_LINK_MODE_200000baseKR4_Full_BIT] = __REAL(200000), ++ [ETHTOOL_LINK_MODE_200000baseSR4_Full_BIT] = __REAL(200000), ++ [ETHTOOL_LINK_MODE_200000baseLR4_ER4_FR4_Full_BIT] = __REAL(200000), ++ [ETHTOOL_LINK_MODE_200000baseDR4_Full_BIT] = __REAL(200000), ++ [ETHTOOL_LINK_MODE_200000baseCR4_Full_BIT] = __REAL(200000), ++ [ETHTOOL_LINK_MODE_100baseT1_Full_BIT] = __REAL(100), ++ [ETHTOOL_LINK_MODE_1000baseT1_Full_BIT] = __REAL(1000), ++ [ETHTOOL_LINK_MODE_400000baseKR8_Full_BIT] = __REAL(400000), ++ [ETHTOOL_LINK_MODE_400000baseSR8_Full_BIT] = __REAL(400000), ++ [ETHTOOL_LINK_MODE_400000baseLR8_ER8_FR8_Full_BIT] = __REAL(400000), ++ [ETHTOOL_LINK_MODE_400000baseDR8_Full_BIT] = __REAL(400000), ++ [ETHTOOL_LINK_MODE_400000baseCR8_Full_BIT] = __REAL(400000), ++ [ETHTOOL_LINK_MODE_FEC_LLRS_BIT] = __SPECIAL(FEC), + }; + const unsigned int link_modes_count = ARRAY_SIZE(link_modes); + ++#undef __REAL ++#undef __HALF_DUPLEX ++#undef __SPECIAL ++ + static bool lm_class_match(unsigned int mode, enum link_mode_class class) + { + unsigned int mode_class = (mode < link_modes_count) ? +-- +2.26.2 + diff --git a/SOURCES/0010-ioctl-convert-cmdline_info-arrays-to-named-initializ.patch b/SOURCES/0010-ioctl-convert-cmdline_info-arrays-to-named-initializ.patch new file mode 100644 index 0000000..dc7309e --- /dev/null +++ b/SOURCES/0010-ioctl-convert-cmdline_info-arrays-to-named-initializ.patch @@ -0,0 +1,468 @@ +From 35fb9ff49c579d6e6819d71ab4c614cb3d2c0dae Mon Sep 17 00:00:00 2001 +From: Michal Kubecek +Date: Sun, 23 Aug 2020 21:40:39 +0200 +Subject: [PATCH 10/17] ioctl: convert cmdline_info arrays to named + initializers + +To get rid of remaining "missing field initializer" compiler warnings, +convert arrays of struct cmdline_info used for command line parser to +named initializers. This also makes the initializers easier to read. + +This commit should have no effect on resulting code (checked with gcc-11 +and -O2). + +Signed-off-by: Michal Kubecek +Reviewed-by: Andrew Lunn +(cherry picked from commit 0c43dec5cf64aee41bbd4195c96671032ea6556d) +--- + ethtool.c | 378 ++++++++++++++++++++++++++++++++++++++++++------------ + 1 file changed, 296 insertions(+), 82 deletions(-) + +diff --git a/ethtool.c b/ethtool.c +index 3c30824016d5..e32a93b41088 100644 +--- a/ethtool.c ++++ b/ethtool.c +@@ -1825,10 +1825,24 @@ static int do_spause(struct cmd_context *ctx) + int pause_rx_wanted = -1; + int pause_tx_wanted = -1; + struct cmdline_info cmdline_pause[] = { +- { "autoneg", CMDL_BOOL, &pause_autoneg_wanted, +- &epause.autoneg }, +- { "rx", CMDL_BOOL, &pause_rx_wanted, &epause.rx_pause }, +- { "tx", CMDL_BOOL, &pause_tx_wanted, &epause.tx_pause }, ++ { ++ .name = "autoneg", ++ .type = CMDL_BOOL, ++ .wanted_val = &pause_autoneg_wanted, ++ .ioctl_val = &epause.autoneg, ++ }, ++ { ++ .name = "rx", ++ .type = CMDL_BOOL, ++ .wanted_val = &pause_rx_wanted, ++ .ioctl_val = &epause.rx_pause, ++ }, ++ { ++ .name = "tx", ++ .type = CMDL_BOOL, ++ .wanted_val = &pause_tx_wanted, ++ .ioctl_val = &epause.tx_pause, ++ }, + }; + int err, changed = 0; + +@@ -1868,12 +1882,30 @@ static int do_sring(struct cmd_context *ctx) + s32 ring_rx_jumbo_wanted = -1; + s32 ring_tx_wanted = -1; + struct cmdline_info cmdline_ring[] = { +- { "rx", CMDL_S32, &ring_rx_wanted, &ering.rx_pending }, +- { "rx-mini", CMDL_S32, &ring_rx_mini_wanted, +- &ering.rx_mini_pending }, +- { "rx-jumbo", CMDL_S32, &ring_rx_jumbo_wanted, +- &ering.rx_jumbo_pending }, +- { "tx", CMDL_S32, &ring_tx_wanted, &ering.tx_pending }, ++ { ++ .name = "rx", ++ .type = CMDL_S32, ++ .wanted_val = &ring_rx_wanted, ++ .ioctl_val = &ering.rx_pending, ++ }, ++ { ++ .name = "rx-mini", ++ .type = CMDL_S32, ++ .wanted_val = &ring_rx_mini_wanted, ++ .ioctl_val = &ering.rx_mini_pending, ++ }, ++ { ++ .name = "rx-jumbo", ++ .type = CMDL_S32, ++ .wanted_val = &ring_rx_jumbo_wanted, ++ .ioctl_val = &ering.rx_jumbo_pending, ++ }, ++ { ++ .name = "tx", ++ .type = CMDL_S32, ++ .wanted_val = &ring_tx_wanted, ++ .ioctl_val = &ering.tx_pending, ++ }, + }; + int err, changed = 0; + +@@ -1937,12 +1969,30 @@ static int do_schannels(struct cmd_context *ctx) + s32 channels_other_wanted = -1; + s32 channels_combined_wanted = -1; + struct cmdline_info cmdline_channels[] = { +- { "rx", CMDL_S32, &channels_rx_wanted, &echannels.rx_count }, +- { "tx", CMDL_S32, &channels_tx_wanted, &echannels.tx_count }, +- { "other", CMDL_S32, &channels_other_wanted, +- &echannels.other_count }, +- { "combined", CMDL_S32, &channels_combined_wanted, +- &echannels.combined_count }, ++ { ++ .name = "rx", ++ .type = CMDL_S32, ++ .wanted_val = &channels_rx_wanted, ++ .ioctl_val = &echannels.rx_count, ++ }, ++ { ++ .name = "tx", ++ .type = CMDL_S32, ++ .wanted_val = &channels_tx_wanted, ++ .ioctl_val = &echannels.tx_count, ++ }, ++ { ++ .name = "other", ++ .type = CMDL_S32, ++ .wanted_val = &channels_other_wanted, ++ .ioctl_val = &echannels.other_count, ++ }, ++ { ++ .name = "combined", ++ .type = CMDL_S32, ++ .wanted_val = &channels_combined_wanted, ++ .ioctl_val = &echannels.combined_count, ++ }, + }; + int err, changed = 0; + +@@ -2052,50 +2102,138 @@ static int do_gcoalesce(struct cmd_context *ctx) + + #define COALESCE_CMDLINE_INFO(__ecoal) \ + { \ +- { "adaptive-rx", CMDL_BOOL, &coal_adaptive_rx_wanted, \ +- &__ecoal.use_adaptive_rx_coalesce }, \ +- { "adaptive-tx", CMDL_BOOL, &coal_adaptive_tx_wanted, \ +- &__ecoal.use_adaptive_tx_coalesce }, \ +- { "sample-interval", CMDL_S32, &coal_sample_rate_wanted, \ +- &__ecoal.rate_sample_interval }, \ +- { "stats-block-usecs", CMDL_S32, &coal_stats_wanted, \ +- &__ecoal.stats_block_coalesce_usecs }, \ +- { "pkt-rate-low", CMDL_S32, &coal_pkt_rate_low_wanted, \ +- &__ecoal.pkt_rate_low }, \ +- { "pkt-rate-high", CMDL_S32, &coal_pkt_rate_high_wanted, \ +- &__ecoal.pkt_rate_high }, \ +- { "rx-usecs", CMDL_S32, &coal_rx_usec_wanted, \ +- &__ecoal.rx_coalesce_usecs }, \ +- { "rx-frames", CMDL_S32, &coal_rx_frames_wanted, \ +- &__ecoal.rx_max_coalesced_frames }, \ +- { "rx-usecs-irq", CMDL_S32, &coal_rx_usec_irq_wanted, \ +- &__ecoal.rx_coalesce_usecs_irq }, \ +- { "rx-frames-irq", CMDL_S32, &coal_rx_frames_irq_wanted, \ +- &__ecoal.rx_max_coalesced_frames_irq }, \ +- { "tx-usecs", CMDL_S32, &coal_tx_usec_wanted, \ +- &__ecoal.tx_coalesce_usecs }, \ +- { "tx-frames", CMDL_S32, &coal_tx_frames_wanted, \ +- &__ecoal.tx_max_coalesced_frames }, \ +- { "tx-usecs-irq", CMDL_S32, &coal_tx_usec_irq_wanted, \ +- &__ecoal.tx_coalesce_usecs_irq }, \ +- { "tx-frames-irq", CMDL_S32, &coal_tx_frames_irq_wanted, \ +- &__ecoal.tx_max_coalesced_frames_irq }, \ +- { "rx-usecs-low", CMDL_S32, &coal_rx_usec_low_wanted, \ +- &__ecoal.rx_coalesce_usecs_low }, \ +- { "rx-frames-low", CMDL_S32, &coal_rx_frames_low_wanted, \ +- &__ecoal.rx_max_coalesced_frames_low }, \ +- { "tx-usecs-low", CMDL_S32, &coal_tx_usec_low_wanted, \ +- &__ecoal.tx_coalesce_usecs_low }, \ +- { "tx-frames-low", CMDL_S32, &coal_tx_frames_low_wanted, \ +- &__ecoal.tx_max_coalesced_frames_low }, \ +- { "rx-usecs-high", CMDL_S32, &coal_rx_usec_high_wanted, \ +- &__ecoal.rx_coalesce_usecs_high }, \ +- { "rx-frames-high", CMDL_S32, &coal_rx_frames_high_wanted, \ +- &__ecoal.rx_max_coalesced_frames_high }, \ +- { "tx-usecs-high", CMDL_S32, &coal_tx_usec_high_wanted, \ +- &__ecoal.tx_coalesce_usecs_high }, \ +- { "tx-frames-high", CMDL_S32, &coal_tx_frames_high_wanted, \ +- &__ecoal.tx_max_coalesced_frames_high }, \ ++ { \ ++ .name = "adaptive-rx", \ ++ .type = CMDL_BOOL, \ ++ .wanted_val = &coal_adaptive_rx_wanted, \ ++ .ioctl_val = &__ecoal.use_adaptive_rx_coalesce, \ ++ }, \ ++ { \ ++ .name = "adaptive-tx", \ ++ .type = CMDL_BOOL, \ ++ .wanted_val = &coal_adaptive_tx_wanted, \ ++ .ioctl_val = &__ecoal.use_adaptive_tx_coalesce, \ ++ }, \ ++ { \ ++ .name = "sample-interval", \ ++ .type = CMDL_S32, \ ++ .wanted_val = &coal_sample_rate_wanted, \ ++ .ioctl_val = &__ecoal.rate_sample_interval, \ ++ }, \ ++ { \ ++ .name = "stats-block-usecs", \ ++ .type = CMDL_S32, \ ++ .wanted_val = &coal_stats_wanted, \ ++ .ioctl_val = &__ecoal.stats_block_coalesce_usecs, \ ++ }, \ ++ { \ ++ .name = "pkt-rate-low", \ ++ .type = CMDL_S32, \ ++ .wanted_val = &coal_pkt_rate_low_wanted, \ ++ .ioctl_val = &__ecoal.pkt_rate_low, \ ++ }, \ ++ { \ ++ .name = "pkt-rate-high", \ ++ .type = CMDL_S32, \ ++ .wanted_val = &coal_pkt_rate_high_wanted, \ ++ .ioctl_val = &__ecoal.pkt_rate_high, \ ++ }, \ ++ { \ ++ .name = "rx-usecs", \ ++ .type = CMDL_S32, \ ++ .wanted_val = &coal_rx_usec_wanted, \ ++ .ioctl_val = &__ecoal.rx_coalesce_usecs, \ ++ }, \ ++ { \ ++ .name = "rx-frames", \ ++ .type = CMDL_S32, \ ++ .wanted_val = &coal_rx_frames_wanted, \ ++ .ioctl_val = &__ecoal.rx_max_coalesced_frames, \ ++ }, \ ++ { \ ++ .name = "rx-usecs-irq", \ ++ .type = CMDL_S32, \ ++ .wanted_val = &coal_rx_usec_irq_wanted, \ ++ .ioctl_val = &__ecoal.rx_coalesce_usecs_irq, \ ++ }, \ ++ { \ ++ .name = "rx-frames-irq", \ ++ .type = CMDL_S32, \ ++ .wanted_val = &coal_rx_frames_irq_wanted, \ ++ .ioctl_val = &__ecoal.rx_max_coalesced_frames_irq, \ ++ }, \ ++ { \ ++ .name = "tx-usecs", \ ++ .type = CMDL_S32, \ ++ .wanted_val = &coal_tx_usec_wanted, \ ++ .ioctl_val = &__ecoal.tx_coalesce_usecs, \ ++ }, \ ++ { \ ++ .name = "tx-frames", \ ++ .type = CMDL_S32, \ ++ .wanted_val = &coal_tx_frames_wanted, \ ++ .ioctl_val = &__ecoal.tx_max_coalesced_frames, \ ++ }, \ ++ { \ ++ .name = "tx-usecs-irq", \ ++ .type = CMDL_S32, \ ++ .wanted_val = &coal_tx_usec_irq_wanted, \ ++ .ioctl_val = &__ecoal.tx_coalesce_usecs_irq, \ ++ }, \ ++ { \ ++ .name = "tx-frames-irq", \ ++ .type = CMDL_S32, \ ++ .wanted_val = &coal_tx_frames_irq_wanted, \ ++ .ioctl_val = &__ecoal.tx_max_coalesced_frames_irq, \ ++ }, \ ++ { \ ++ .name = "rx-usecs-low", \ ++ .type = CMDL_S32, \ ++ .wanted_val = &coal_rx_usec_low_wanted, \ ++ .ioctl_val = &__ecoal.rx_coalesce_usecs_low, \ ++ }, \ ++ { \ ++ .name = "rx-frames-low", \ ++ .type = CMDL_S32, \ ++ .wanted_val = &coal_rx_frames_low_wanted, \ ++ .ioctl_val = &__ecoal.rx_max_coalesced_frames_low, \ ++ }, \ ++ { \ ++ .name = "tx-usecs-low", \ ++ .type = CMDL_S32, \ ++ .wanted_val = &coal_tx_usec_low_wanted, \ ++ .ioctl_val = &__ecoal.tx_coalesce_usecs_low, \ ++ }, \ ++ { \ ++ .name = "tx-frames-low", \ ++ .type = CMDL_S32, \ ++ .wanted_val = &coal_tx_frames_low_wanted, \ ++ .ioctl_val = &__ecoal.tx_max_coalesced_frames_low, \ ++ }, \ ++ { \ ++ .name = "rx-usecs-high", \ ++ .type = CMDL_S32, \ ++ .wanted_val = &coal_rx_usec_high_wanted, \ ++ .ioctl_val = &__ecoal.rx_coalesce_usecs_high, \ ++ }, \ ++ { \ ++ .name = "rx-frames-high", \ ++ .type = CMDL_S32, \ ++ .wanted_val = &coal_rx_frames_high_wanted, \ ++ .ioctl_val = &__ecoal.rx_max_coalesced_frames_high,\ ++ }, \ ++ { \ ++ .name = "tx-usecs-high", \ ++ .type = CMDL_S32, \ ++ .wanted_val = &coal_tx_usec_high_wanted, \ ++ .ioctl_val = &__ecoal.tx_coalesce_usecs_high, \ ++ }, \ ++ { \ ++ .name = "tx-frames-high", \ ++ .type = CMDL_S32, \ ++ .wanted_val = &coal_tx_frames_high_wanted, \ ++ .ioctl_val = &__ecoal.tx_max_coalesced_frames_high,\ ++ }, \ + } + + static int do_scoalesce(struct cmd_context *ctx) +@@ -3090,9 +3228,21 @@ static int do_gregs(struct cmd_context *ctx) + int gregs_dump_hex = 0; + char *gregs_dump_file = NULL; + struct cmdline_info cmdline_gregs[] = { +- { "raw", CMDL_BOOL, &gregs_dump_raw, NULL }, +- { "hex", CMDL_BOOL, &gregs_dump_hex, NULL }, +- { "file", CMDL_STR, &gregs_dump_file, NULL }, ++ { ++ .name = "raw", ++ .type = CMDL_BOOL, ++ .wanted_val = &gregs_dump_raw, ++ }, ++ { ++ .name = "hex", ++ .type = CMDL_BOOL, ++ .wanted_val = &gregs_dump_hex, ++ }, ++ { ++ .name = "file", ++ .type = CMDL_STR, ++ .wanted_val = &gregs_dump_file, ++ }, + }; + int err; + struct ethtool_drvinfo drvinfo; +@@ -3189,10 +3339,22 @@ static int do_geeprom(struct cmd_context *ctx) + u32 geeprom_length = 0; + int geeprom_length_seen = 0; + struct cmdline_info cmdline_geeprom[] = { +- { "offset", CMDL_U32, &geeprom_offset, NULL }, +- { "length", CMDL_U32, &geeprom_length, NULL, +- 0, &geeprom_length_seen }, +- { "raw", CMDL_BOOL, &geeprom_dump_raw, NULL }, ++ { ++ .name = "offset", ++ .type = CMDL_U32, ++ .wanted_val = &geeprom_offset, ++ }, ++ { ++ .name = "length", ++ .type = CMDL_U32, ++ .wanted_val = &geeprom_length, ++ .seen_val = &geeprom_length_seen, ++ }, ++ { ++ .name = "raw", ++ .type = CMDL_BOOL, ++ .wanted_val = &geeprom_dump_raw, ++ }, + }; + int err; + struct ethtool_drvinfo drvinfo; +@@ -3244,12 +3406,28 @@ static int do_seeprom(struct cmd_context *ctx) + int seeprom_length_seen = 0; + int seeprom_value_seen = 0; + struct cmdline_info cmdline_seeprom[] = { +- { "magic", CMDL_U32, &seeprom_magic, NULL }, +- { "offset", CMDL_U32, &seeprom_offset, NULL }, +- { "length", CMDL_U32, &seeprom_length, NULL, +- 0, &seeprom_length_seen }, +- { "value", CMDL_U8, &seeprom_value, NULL, +- 0, &seeprom_value_seen }, ++ { ++ .name = "magic", ++ .type = CMDL_U32, ++ .wanted_val = &seeprom_magic, ++ }, ++ { ++ .name = "offset", ++ .type = CMDL_U32, ++ .wanted_val = &seeprom_offset, ++ }, ++ { ++ .name = "length", ++ .type = CMDL_U32, ++ .wanted_val = &seeprom_length, ++ .seen_val = &seeprom_length_seen, ++ }, ++ { ++ .name = "value", ++ .type = CMDL_U8, ++ .wanted_val = &seeprom_value, ++ .seen_val = &seeprom_value_seen, ++ }, + }; + int err; + struct ethtool_drvinfo drvinfo; +@@ -4553,11 +4731,27 @@ static int do_getmodule(struct cmd_context *ctx) + int err; + + struct cmdline_info cmdline_geeprom[] = { +- { "offset", CMDL_U32, &geeprom_offset, NULL }, +- { "length", CMDL_U32, &geeprom_length, NULL, +- 0, &geeprom_length_seen }, +- { "raw", CMDL_BOOL, &geeprom_dump_raw, NULL }, +- { "hex", CMDL_BOOL, &geeprom_dump_hex, NULL }, ++ { ++ .name = "offset", ++ .type = CMDL_U32, ++ .wanted_val = &geeprom_offset, ++ }, ++ { ++ .name = "length", ++ .type = CMDL_U32, ++ .wanted_val = &geeprom_length, ++ .seen_val = &geeprom_length_seen, ++ }, ++ { ++ .name = "raw", ++ .type = CMDL_BOOL, ++ .wanted_val = &geeprom_dump_raw, ++ }, ++ { ++ .name = "hex", ++ .type = CMDL_BOOL, ++ .wanted_val = &geeprom_dump_hex, ++ }, + }; + + parse_generic_cmdline(ctx, &geeprom_changed, +@@ -4669,10 +4863,30 @@ static int do_seee(struct cmd_context *ctx) + int change = -1, change2 = 0; + struct ethtool_eee eeecmd; + struct cmdline_info cmdline_eee[] = { +- { "advertise", CMDL_U32, &adv_c, &eeecmd.advertised }, +- { "tx-lpi", CMDL_BOOL, &lpi_c, &eeecmd.tx_lpi_enabled }, +- { "tx-timer", CMDL_U32, &lpi_time_c, &eeecmd.tx_lpi_timer}, +- { "eee", CMDL_BOOL, &eee_c, &eeecmd.eee_enabled}, ++ { ++ .name = "advertise", ++ .type = CMDL_U32, ++ .wanted_val = &adv_c, ++ .ioctl_val = &eeecmd.advertised, ++ }, ++ { ++ .name = "tx-lpi", ++ .type = CMDL_BOOL, ++ .wanted_val = &lpi_c, ++ .ioctl_val = &eeecmd.tx_lpi_enabled, ++ }, ++ { ++ .name = "tx-timer", ++ .type = CMDL_U32, ++ .wanted_val = &lpi_time_c, ++ .ioctl_val = &eeecmd.tx_lpi_timer, ++ }, ++ { ++ .name = "eee", ++ .type = CMDL_BOOL, ++ .wanted_val = &eee_c, ++ .ioctl_val = &eeecmd.eee_enabled, ++ }, + }; + + if (ctx->argc == 0) +-- +2.26.2 + diff --git a/SOURCES/0011-build-add-Wextra-to-default-CFLAGS.patch b/SOURCES/0011-build-add-Wextra-to-default-CFLAGS.patch new file mode 100644 index 0000000..dc6330b --- /dev/null +++ b/SOURCES/0011-build-add-Wextra-to-default-CFLAGS.patch @@ -0,0 +1,31 @@ +From 0d042007945d6fadb9b59ce8d01502575689067d Mon Sep 17 00:00:00 2001 +From: Michal Kubecek +Date: Sun, 23 Aug 2020 21:40:42 +0200 +Subject: [PATCH 11/17] build: add -Wextra to default CFLAGS + +As a result of previous commits, ethtool source now builds with gcc +versions 7-11 without any compiler warning with "-Wall -Wextra". Add +"-Wextra" to default cflags to make sure that any new warnings are +caught as early as possible. + +Suggested-by: Andrew Lunn +Signed-off-by: Michal Kubecek +Reviewed-by: Andrew Lunn +(cherry picked from commit 257d90cd946699c0951b670576d2d63a12b92541) +--- + Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile.am b/Makefile.am +index 2abb2742c335..099182e8d6ad 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -1,4 +1,4 @@ +-AM_CFLAGS = -Wall ++AM_CFLAGS = -Wall -Wextra + AM_CPPFLAGS = -I$(top_srcdir)/uapi + LDADD = -lm + +-- +2.26.2 + diff --git a/SOURCES/0012-ioctl-only-memset-non-NULL-link-settings.patch b/SOURCES/0012-ioctl-only-memset-non-NULL-link-settings.patch new file mode 100644 index 0000000..0dcf3a6 --- /dev/null +++ b/SOURCES/0012-ioctl-only-memset-non-NULL-link-settings.patch @@ -0,0 +1,42 @@ +From a4186edd5bcb44d3236852816c21752eb82e5039 Mon Sep 17 00:00:00 2001 +From: Hans-Christian Noren Egtvedt +Date: Thu, 27 Aug 2020 11:50:33 +0200 +Subject: [PATCH 12/17] ioctl: only memset non-NULL link settings + +In commit bef780467fa ("ioctl: do not pass transceiver value back to +kernel") a regression slipped in. If we have a kernel that does not +support the ETHTOOL_xLINKSETTINGS API, then the do_ioctl_glinksettings() +function will return a NULL pointer. + +Hence before memset'ing the pointer to zero we must first check it is +valid, as NULL return is perfectly fine when running on old kernels. + +Fixes: bef780467fa7 ("ioctl: do not pass transceiver value back to kernel") +Signed-off-by: Hans-Christian Noren Egtvedt +Signed-off-by: Michal Kubecek +(cherry picked from commit cf12872ebe7d8fac2088e7d2cd5e2a0a5f03499d) +--- + ethtool.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/ethtool.c b/ethtool.c +index e32a93b41088..606af3e6b48f 100644 +--- a/ethtool.c ++++ b/ethtool.c +@@ -3048,10 +3048,11 @@ static int do_sset(struct cmd_context *ctx) + struct ethtool_link_usettings *link_usettings; + + link_usettings = do_ioctl_glinksettings(ctx); +- memset(&link_usettings->deprecated, 0, +- sizeof(link_usettings->deprecated)); + if (link_usettings == NULL) + link_usettings = do_ioctl_gset(ctx); ++ else ++ memset(&link_usettings->deprecated, 0, ++ sizeof(link_usettings->deprecated)); + if (link_usettings == NULL) { + perror("Cannot get current device settings"); + err = -1; +-- +2.26.2 + diff --git a/SOURCES/0013-netlink-mark-unused-function-parameters-of-non-netli.patch b/SOURCES/0013-netlink-mark-unused-function-parameters-of-non-netli.patch new file mode 100644 index 0000000..8acc678 --- /dev/null +++ b/SOURCES/0013-netlink-mark-unused-function-parameters-of-non-netli.patch @@ -0,0 +1,44 @@ +From fd001f7b3e530afefe470db246e8fc299077329e Mon Sep 17 00:00:00 2001 +From: Michal Kubecek +Date: Wed, 16 Sep 2020 18:48:20 +0200 +Subject: [PATCH 13/17] netlink: mark unused function parameters of non-netlink + stubs + +Recent compiler warning cleanup missed three unused parameters in versions +of netlink_run_handler() and nl_monitor() used when netlink support is +disabled (configure --disable-netlink). + +Signed-off-by: Michal Kubecek +(cherry picked from commit eb5bd877ec5bd2a2d2b5e09fc90033be1a64c95a) +--- + netlink/extapi.h | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/netlink/extapi.h b/netlink/extapi.h +index a35d5f2c0b26..4fee6a9c3a99 100644 +--- a/netlink/extapi.h ++++ b/netlink/extapi.h +@@ -43,8 +43,9 @@ void nl_monitor_usage(void); + + #else /* ETHTOOL_ENABLE_NETLINK */ + +-static inline void netlink_run_handler(struct cmd_context *ctx, +- nl_func_t nlfunc, bool no_fallback) ++static inline void netlink_run_handler(struct cmd_context *ctx __maybe_unused, ++ nl_func_t nlfunc __maybe_unused, ++ bool no_fallback) + { + if (no_fallback) { + fprintf(stderr, +@@ -54,7 +55,7 @@ static inline void netlink_run_handler(struct cmd_context *ctx, + } + } + +-static inline int nl_monitor(struct cmd_context *ctx) ++static inline int nl_monitor(struct cmd_context *ctx __maybe_unused) + { + fprintf(stderr, "Netlink not supported by ethtool, option --monitor unsupported.\n"); + return -EOPNOTSUPP; +-- +2.26.2 + diff --git a/SOURCES/0014-update-UAPI-header-copies.patch b/SOURCES/0014-update-UAPI-header-copies.patch new file mode 100644 index 0000000..43c781d --- /dev/null +++ b/SOURCES/0014-update-UAPI-header-copies.patch @@ -0,0 +1,490 @@ +From 708dee5555dc4849bc03038048b9b9d08404f18e Mon Sep 17 00:00:00 2001 +From: Jakub Kicinski +Date: Thu, 10 Sep 2020 12:09:14 -0700 +Subject: [PATCH 14/17] update UAPI header copies + +Update to kernel commit 4f6a5caf187f. + +Signed-off-by: Jakub Kicinski +Signed-off-by: Michal Kubecek +(cherry picked from commit 1be081a983c94ab2eaa81686fbb9bcd707a2bac6) +--- + uapi/linux/ethtool.h | 17 +++ + uapi/linux/ethtool_netlink.h | 55 +++++++++ + uapi/linux/if_link.h | 227 ++++++++++++++++++++++++++++++++--- + uapi/linux/rtnetlink.h | 46 +++---- + 4 files changed, 305 insertions(+), 40 deletions(-) + +diff --git a/uapi/linux/ethtool.h b/uapi/linux/ethtool.h +index 6074caa2f220..355e718a99fd 100644 +--- a/uapi/linux/ethtool.h ++++ b/uapi/linux/ethtool.h +@@ -597,6 +597,7 @@ struct ethtool_pauseparam { + * @ETH_SS_SOF_TIMESTAMPING: SOF_TIMESTAMPING_* flags + * @ETH_SS_TS_TX_TYPES: timestamping Tx types + * @ETH_SS_TS_RX_FILTERS: timestamping Rx filters ++ * @ETH_SS_UDP_TUNNEL_TYPES: UDP tunnel types + */ + enum ethtool_stringset { + ETH_SS_TEST = 0, +@@ -614,6 +615,7 @@ enum ethtool_stringset { + ETH_SS_SOF_TIMESTAMPING, + ETH_SS_TS_TX_TYPES, + ETH_SS_TS_RX_FILTERS, ++ ETH_SS_UDP_TUNNEL_TYPES, + + /* add new constants above here */ + ETH_SS_COUNT +@@ -1528,6 +1530,21 @@ enum ethtool_link_mode_bit_indices { + ETHTOOL_LINK_MODE_400000baseDR8_Full_BIT = 72, + ETHTOOL_LINK_MODE_400000baseCR8_Full_BIT = 73, + ETHTOOL_LINK_MODE_FEC_LLRS_BIT = 74, ++ ETHTOOL_LINK_MODE_100000baseKR_Full_BIT = 75, ++ ETHTOOL_LINK_MODE_100000baseSR_Full_BIT = 76, ++ ETHTOOL_LINK_MODE_100000baseLR_ER_FR_Full_BIT = 77, ++ ETHTOOL_LINK_MODE_100000baseCR_Full_BIT = 78, ++ ETHTOOL_LINK_MODE_100000baseDR_Full_BIT = 79, ++ ETHTOOL_LINK_MODE_200000baseKR2_Full_BIT = 80, ++ ETHTOOL_LINK_MODE_200000baseSR2_Full_BIT = 81, ++ ETHTOOL_LINK_MODE_200000baseLR2_ER2_FR2_Full_BIT = 82, ++ ETHTOOL_LINK_MODE_200000baseDR2_Full_BIT = 83, ++ ETHTOOL_LINK_MODE_200000baseCR2_Full_BIT = 84, ++ ETHTOOL_LINK_MODE_400000baseKR4_Full_BIT = 85, ++ ETHTOOL_LINK_MODE_400000baseSR4_Full_BIT = 86, ++ ETHTOOL_LINK_MODE_400000baseLR4_ER4_FR4_Full_BIT = 87, ++ ETHTOOL_LINK_MODE_400000baseDR4_Full_BIT = 88, ++ ETHTOOL_LINK_MODE_400000baseCR4_Full_BIT = 89, + /* must be last entry */ + __ETHTOOL_LINK_MODE_MASK_NBITS + }; +diff --git a/uapi/linux/ethtool_netlink.h b/uapi/linux/ethtool_netlink.h +index b18e7bc539f2..c1b4d67d35d1 100644 +--- a/uapi/linux/ethtool_netlink.h ++++ b/uapi/linux/ethtool_netlink.h +@@ -41,6 +41,7 @@ enum { + ETHTOOL_MSG_TSINFO_GET, + ETHTOOL_MSG_CABLE_TEST_ACT, + ETHTOOL_MSG_CABLE_TEST_TDR_ACT, ++ ETHTOOL_MSG_TUNNEL_INFO_GET, + + /* add new constants above here */ + __ETHTOOL_MSG_USER_CNT, +@@ -554,6 +555,60 @@ enum { + ETHTOOL_A_CABLE_TEST_TDR_NTF_MAX = __ETHTOOL_A_CABLE_TEST_TDR_NTF_CNT - 1 + }; + ++/* TUNNEL INFO */ ++ ++enum { ++ ETHTOOL_UDP_TUNNEL_TYPE_VXLAN, ++ ETHTOOL_UDP_TUNNEL_TYPE_GENEVE, ++ ETHTOOL_UDP_TUNNEL_TYPE_VXLAN_GPE, ++ ++ __ETHTOOL_UDP_TUNNEL_TYPE_CNT ++}; ++ ++enum { ++ ETHTOOL_A_TUNNEL_UDP_ENTRY_UNSPEC, ++ ++ ETHTOOL_A_TUNNEL_UDP_ENTRY_PORT, /* be16 */ ++ ETHTOOL_A_TUNNEL_UDP_ENTRY_TYPE, /* u32 */ ++ ++ /* add new constants above here */ ++ __ETHTOOL_A_TUNNEL_UDP_ENTRY_CNT, ++ ETHTOOL_A_TUNNEL_UDP_ENTRY_MAX = (__ETHTOOL_A_TUNNEL_UDP_ENTRY_CNT - 1) ++}; ++ ++enum { ++ ETHTOOL_A_TUNNEL_UDP_TABLE_UNSPEC, ++ ++ ETHTOOL_A_TUNNEL_UDP_TABLE_SIZE, /* u32 */ ++ ETHTOOL_A_TUNNEL_UDP_TABLE_TYPES, /* bitset */ ++ ETHTOOL_A_TUNNEL_UDP_TABLE_ENTRY, /* nest - _UDP_ENTRY_* */ ++ ++ /* add new constants above here */ ++ __ETHTOOL_A_TUNNEL_UDP_TABLE_CNT, ++ ETHTOOL_A_TUNNEL_UDP_TABLE_MAX = (__ETHTOOL_A_TUNNEL_UDP_TABLE_CNT - 1) ++}; ++ ++enum { ++ ETHTOOL_A_TUNNEL_UDP_UNSPEC, ++ ++ ETHTOOL_A_TUNNEL_UDP_TABLE, /* nest - _UDP_TABLE_* */ ++ ++ /* add new constants above here */ ++ __ETHTOOL_A_TUNNEL_UDP_CNT, ++ ETHTOOL_A_TUNNEL_UDP_MAX = (__ETHTOOL_A_TUNNEL_UDP_CNT - 1) ++}; ++ ++enum { ++ ETHTOOL_A_TUNNEL_INFO_UNSPEC, ++ ETHTOOL_A_TUNNEL_INFO_HEADER, /* nest - _A_HEADER_* */ ++ ++ ETHTOOL_A_TUNNEL_INFO_UDP_PORTS, /* nest - _UDP_TABLE */ ++ ++ /* add new constants above here */ ++ __ETHTOOL_A_TUNNEL_INFO_CNT, ++ ETHTOOL_A_TUNNEL_INFO_MAX = (__ETHTOOL_A_TUNNEL_INFO_CNT - 1) ++}; ++ + /* generic netlink info */ + #define ETHTOOL_GENL_NAME "ethtool" + #define ETHTOOL_GENL_VERSION 1 +diff --git a/uapi/linux/if_link.h b/uapi/linux/if_link.h +index a8901a39a345..9d96890f9742 100644 +--- a/uapi/linux/if_link.h ++++ b/uapi/linux/if_link.h +@@ -40,26 +40,197 @@ struct rtnl_link_stats { + __u32 rx_nohandler; /* dropped, no handler found */ + }; + +-/* The main device statistics structure */ ++/** ++ * struct rtnl_link_stats64 - The main device statistics structure. ++ * ++ * @rx_packets: Number of good packets received by the interface. ++ * For hardware interfaces counts all good packets received from the device ++ * by the host, including packets which host had to drop at various stages ++ * of processing (even in the driver). ++ * ++ * @tx_packets: Number of packets successfully transmitted. ++ * For hardware interfaces counts packets which host was able to successfully ++ * hand over to the device, which does not necessarily mean that packets ++ * had been successfully transmitted out of the device, only that device ++ * acknowledged it copied them out of host memory. ++ * ++ * @rx_bytes: Number of good received bytes, corresponding to @rx_packets. ++ * ++ * For IEEE 802.3 devices should count the length of Ethernet Frames ++ * excluding the FCS. ++ * ++ * @tx_bytes: Number of good transmitted bytes, corresponding to @tx_packets. ++ * ++ * For IEEE 802.3 devices should count the length of Ethernet Frames ++ * excluding the FCS. ++ * ++ * @rx_errors: Total number of bad packets received on this network device. ++ * This counter must include events counted by @rx_length_errors, ++ * @rx_crc_errors, @rx_frame_errors and other errors not otherwise ++ * counted. ++ * ++ * @tx_errors: Total number of transmit problems. ++ * This counter must include events counter by @tx_aborted_errors, ++ * @tx_carrier_errors, @tx_fifo_errors, @tx_heartbeat_errors, ++ * @tx_window_errors and other errors not otherwise counted. ++ * ++ * @rx_dropped: Number of packets received but not processed, ++ * e.g. due to lack of resources or unsupported protocol. ++ * For hardware interfaces this counter should not include packets ++ * dropped by the device which are counted separately in ++ * @rx_missed_errors (since procfs folds those two counters together). ++ * ++ * @tx_dropped: Number of packets dropped on their way to transmission, ++ * e.g. due to lack of resources. ++ * ++ * @multicast: Multicast packets received. ++ * For hardware interfaces this statistic is commonly calculated ++ * at the device level (unlike @rx_packets) and therefore may include ++ * packets which did not reach the host. ++ * ++ * For IEEE 802.3 devices this counter may be equivalent to: ++ * ++ * - 30.3.1.1.21 aMulticastFramesReceivedOK ++ * ++ * @collisions: Number of collisions during packet transmissions. ++ * ++ * @rx_length_errors: Number of packets dropped due to invalid length. ++ * Part of aggregate "frame" errors in `/proc/net/dev`. ++ * ++ * For IEEE 802.3 devices this counter should be equivalent to a sum ++ * of the following attributes: ++ * ++ * - 30.3.1.1.23 aInRangeLengthErrors ++ * - 30.3.1.1.24 aOutOfRangeLengthField ++ * - 30.3.1.1.25 aFrameTooLongErrors ++ * ++ * @rx_over_errors: Receiver FIFO overflow event counter. ++ * ++ * Historically the count of overflow events. Such events may be ++ * reported in the receive descriptors or via interrupts, and may ++ * not correspond one-to-one with dropped packets. ++ * ++ * The recommended interpretation for high speed interfaces is - ++ * number of packets dropped because they did not fit into buffers ++ * provided by the host, e.g. packets larger than MTU or next buffer ++ * in the ring was not available for a scatter transfer. ++ * ++ * Part of aggregate "frame" errors in `/proc/net/dev`. ++ * ++ * This statistics was historically used interchangeably with ++ * @rx_fifo_errors. ++ * ++ * This statistic corresponds to hardware events and is not commonly used ++ * on software devices. ++ * ++ * @rx_crc_errors: Number of packets received with a CRC error. ++ * Part of aggregate "frame" errors in `/proc/net/dev`. ++ * ++ * For IEEE 802.3 devices this counter must be equivalent to: ++ * ++ * - 30.3.1.1.6 aFrameCheckSequenceErrors ++ * ++ * @rx_frame_errors: Receiver frame alignment errors. ++ * Part of aggregate "frame" errors in `/proc/net/dev`. ++ * ++ * For IEEE 802.3 devices this counter should be equivalent to: ++ * ++ * - 30.3.1.1.7 aAlignmentErrors ++ * ++ * @rx_fifo_errors: Receiver FIFO error counter. ++ * ++ * Historically the count of overflow events. Those events may be ++ * reported in the receive descriptors or via interrupts, and may ++ * not correspond one-to-one with dropped packets. ++ * ++ * This statistics was used interchangeably with @rx_over_errors. ++ * Not recommended for use in drivers for high speed interfaces. ++ * ++ * This statistic is used on software devices, e.g. to count software ++ * packet queue overflow (can) or sequencing errors (GRE). ++ * ++ * @rx_missed_errors: Count of packets missed by the host. ++ * Folded into the "drop" counter in `/proc/net/dev`. ++ * ++ * Counts number of packets dropped by the device due to lack ++ * of buffer space. This usually indicates that the host interface ++ * is slower than the network interface, or host is not keeping up ++ * with the receive packet rate. ++ * ++ * This statistic corresponds to hardware events and is not used ++ * on software devices. ++ * ++ * @tx_aborted_errors: ++ * Part of aggregate "carrier" errors in `/proc/net/dev`. ++ * For IEEE 802.3 devices capable of half-duplex operation this counter ++ * must be equivalent to: ++ * ++ * - 30.3.1.1.11 aFramesAbortedDueToXSColls ++ * ++ * High speed interfaces may use this counter as a general device ++ * discard counter. ++ * ++ * @tx_carrier_errors: Number of frame transmission errors due to loss ++ * of carrier during transmission. ++ * Part of aggregate "carrier" errors in `/proc/net/dev`. ++ * ++ * For IEEE 802.3 devices this counter must be equivalent to: ++ * ++ * - 30.3.1.1.13 aCarrierSenseErrors ++ * ++ * @tx_fifo_errors: Number of frame transmission errors due to device ++ * FIFO underrun / underflow. This condition occurs when the device ++ * begins transmission of a frame but is unable to deliver the ++ * entire frame to the transmitter in time for transmission. ++ * Part of aggregate "carrier" errors in `/proc/net/dev`. ++ * ++ * @tx_heartbeat_errors: Number of Heartbeat / SQE Test errors for ++ * old half-duplex Ethernet. ++ * Part of aggregate "carrier" errors in `/proc/net/dev`. ++ * ++ * For IEEE 802.3 devices possibly equivalent to: ++ * ++ * - 30.3.2.1.4 aSQETestErrors ++ * ++ * @tx_window_errors: Number of frame transmission errors due ++ * to late collisions (for Ethernet - after the first 64B of transmission). ++ * Part of aggregate "carrier" errors in `/proc/net/dev`. ++ * ++ * For IEEE 802.3 devices this counter must be equivalent to: ++ * ++ * - 30.3.1.1.10 aLateCollisions ++ * ++ * @rx_compressed: Number of correctly received compressed packets. ++ * This counters is only meaningful for interfaces which support ++ * packet compression (e.g. CSLIP, PPP). ++ * ++ * @tx_compressed: Number of transmitted compressed packets. ++ * This counters is only meaningful for interfaces which support ++ * packet compression (e.g. CSLIP, PPP). ++ * ++ * @rx_nohandler: Number of packets received on the interface ++ * but dropped by the networking stack because the device is ++ * not designated to receive packets (e.g. backup link in a bond). ++ */ + struct rtnl_link_stats64 { +- __u64 rx_packets; /* total packets received */ +- __u64 tx_packets; /* total packets transmitted */ +- __u64 rx_bytes; /* total bytes received */ +- __u64 tx_bytes; /* total bytes transmitted */ +- __u64 rx_errors; /* bad packets received */ +- __u64 tx_errors; /* packet transmit problems */ +- __u64 rx_dropped; /* no space in linux buffers */ +- __u64 tx_dropped; /* no space available in linux */ +- __u64 multicast; /* multicast packets received */ ++ __u64 rx_packets; ++ __u64 tx_packets; ++ __u64 rx_bytes; ++ __u64 tx_bytes; ++ __u64 rx_errors; ++ __u64 tx_errors; ++ __u64 rx_dropped; ++ __u64 tx_dropped; ++ __u64 multicast; + __u64 collisions; + + /* detailed rx_errors: */ + __u64 rx_length_errors; +- __u64 rx_over_errors; /* receiver ring buff overflow */ +- __u64 rx_crc_errors; /* recved pkt with crc error */ +- __u64 rx_frame_errors; /* recv'd frame alignment error */ +- __u64 rx_fifo_errors; /* recv'r fifo overrun */ +- __u64 rx_missed_errors; /* receiver missed packet */ ++ __u64 rx_over_errors; ++ __u64 rx_crc_errors; ++ __u64 rx_frame_errors; ++ __u64 rx_fifo_errors; ++ __u64 rx_missed_errors; + + /* detailed tx_errors */ + __u64 tx_aborted_errors; +@@ -71,8 +242,7 @@ struct rtnl_link_stats64 { + /* for cslip etc */ + __u64 rx_compressed; + __u64 tx_compressed; +- +- __u64 rx_nohandler; /* dropped, no handler found */ ++ __u64 rx_nohandler; + }; + + /* The struct should be in sync with struct ifmap */ +@@ -170,12 +340,22 @@ enum { + IFLA_PROP_LIST, + IFLA_ALT_IFNAME, /* Alternative ifname */ + IFLA_PERM_ADDRESS, ++ IFLA_PROTO_DOWN_REASON, + __IFLA_MAX + }; + + + #define IFLA_MAX (__IFLA_MAX - 1) + ++enum { ++ IFLA_PROTO_DOWN_REASON_UNSPEC, ++ IFLA_PROTO_DOWN_REASON_MASK, /* u32, mask for reason bits */ ++ IFLA_PROTO_DOWN_REASON_VALUE, /* u32, reason bit value */ ++ ++ __IFLA_PROTO_DOWN_REASON_CNT, ++ IFLA_PROTO_DOWN_REASON_MAX = __IFLA_PROTO_DOWN_REASON_CNT - 1 ++}; ++ + /* backwards compatibility for userspace */ + #define IFLA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg)))) + #define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifinfomsg)) +@@ -342,6 +522,7 @@ enum { + IFLA_BRPORT_ISOLATED, + IFLA_BRPORT_BACKUP_PORT, + IFLA_BRPORT_MRP_RING_OPEN, ++ IFLA_BRPORT_MRP_IN_OPEN, + __IFLA_BRPORT_MAX + }; + #define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1) +@@ -904,7 +1085,14 @@ enum { + #define IFLA_IPOIB_MAX (__IFLA_IPOIB_MAX - 1) + + +-/* HSR section */ ++/* HSR/PRP section, both uses same interface */ ++ ++/* Different redundancy protocols for hsr device */ ++enum { ++ HSR_PROTOCOL_HSR, ++ HSR_PROTOCOL_PRP, ++ HSR_PROTOCOL_MAX, ++}; + + enum { + IFLA_HSR_UNSPEC, +@@ -914,6 +1102,9 @@ enum { + IFLA_HSR_SUPERVISION_ADDR, /* Supervision frame multicast addr */ + IFLA_HSR_SEQ_NR, + IFLA_HSR_VERSION, /* HSR version */ ++ IFLA_HSR_PROTOCOL, /* Indicate different protocol than ++ * HSR. For example PRP. ++ */ + __IFLA_HSR_MAX, + }; + +diff --git a/uapi/linux/rtnetlink.h b/uapi/linux/rtnetlink.h +index bcb1ba4d0146..5ad84e663d01 100644 +--- a/uapi/linux/rtnetlink.h ++++ b/uapi/linux/rtnetlink.h +@@ -257,12 +257,12 @@ enum { + + /* rtm_protocol */ + +-#define RTPROT_UNSPEC 0 +-#define RTPROT_REDIRECT 1 /* Route installed by ICMP redirects; +- not used by current IPv4 */ +-#define RTPROT_KERNEL 2 /* Route installed by kernel */ +-#define RTPROT_BOOT 3 /* Route installed during boot */ +-#define RTPROT_STATIC 4 /* Route installed by administrator */ ++#define RTPROT_UNSPEC 0 ++#define RTPROT_REDIRECT 1 /* Route installed by ICMP redirects; ++ not used by current IPv4 */ ++#define RTPROT_KERNEL 2 /* Route installed by kernel */ ++#define RTPROT_BOOT 3 /* Route installed during boot */ ++#define RTPROT_STATIC 4 /* Route installed by administrator */ + + /* Values of protocol >= RTPROT_STATIC are not interpreted by kernel; + they are just passed from user and back as is. +@@ -271,22 +271,23 @@ enum { + avoid conflicts. + */ + +-#define RTPROT_GATED 8 /* Apparently, GateD */ +-#define RTPROT_RA 9 /* RDISC/ND router advertisements */ +-#define RTPROT_MRT 10 /* Merit MRT */ +-#define RTPROT_ZEBRA 11 /* Zebra */ +-#define RTPROT_BIRD 12 /* BIRD */ +-#define RTPROT_DNROUTED 13 /* DECnet routing daemon */ +-#define RTPROT_XORP 14 /* XORP */ +-#define RTPROT_NTK 15 /* Netsukuku */ +-#define RTPROT_DHCP 16 /* DHCP client */ +-#define RTPROT_MROUTED 17 /* Multicast daemon */ +-#define RTPROT_BABEL 42 /* Babel daemon */ +-#define RTPROT_BGP 186 /* BGP Routes */ +-#define RTPROT_ISIS 187 /* ISIS Routes */ +-#define RTPROT_OSPF 188 /* OSPF Routes */ +-#define RTPROT_RIP 189 /* RIP Routes */ +-#define RTPROT_EIGRP 192 /* EIGRP Routes */ ++#define RTPROT_GATED 8 /* Apparently, GateD */ ++#define RTPROT_RA 9 /* RDISC/ND router advertisements */ ++#define RTPROT_MRT 10 /* Merit MRT */ ++#define RTPROT_ZEBRA 11 /* Zebra */ ++#define RTPROT_BIRD 12 /* BIRD */ ++#define RTPROT_DNROUTED 13 /* DECnet routing daemon */ ++#define RTPROT_XORP 14 /* XORP */ ++#define RTPROT_NTK 15 /* Netsukuku */ ++#define RTPROT_DHCP 16 /* DHCP client */ ++#define RTPROT_MROUTED 17 /* Multicast daemon */ ++#define RTPROT_KEEPALIVED 18 /* Keepalived daemon */ ++#define RTPROT_BABEL 42 /* Babel daemon */ ++#define RTPROT_BGP 186 /* BGP Routes */ ++#define RTPROT_ISIS 187 /* ISIS Routes */ ++#define RTPROT_OSPF 188 /* OSPF Routes */ ++#define RTPROT_RIP 189 /* RIP Routes */ ++#define RTPROT_EIGRP 192 /* EIGRP Routes */ + + /* rtm_scope + +@@ -775,6 +776,7 @@ enum { + #define RTEXT_FILTER_BRVLAN (1 << 1) + #define RTEXT_FILTER_BRVLAN_COMPRESSED (1 << 2) + #define RTEXT_FILTER_SKIP_STATS (1 << 3) ++#define RTEXT_FILTER_MRP (1 << 4) + + /* End of information exported to user level */ + +-- +2.26.2 + diff --git a/SOURCES/0015-update-link-mode-tables.patch b/SOURCES/0015-update-link-mode-tables.patch new file mode 100644 index 0000000..d5e1c5d --- /dev/null +++ b/SOURCES/0015-update-link-mode-tables.patch @@ -0,0 +1,158 @@ +From aefd1fcb99c1d64198f315a20e087888d7715632 Mon Sep 17 00:00:00 2001 +From: Michal Kubecek +Date: Wed, 16 Sep 2020 23:12:18 +0200 +Subject: [PATCH 15/17] update link mode tables + +Update tables of link modes to cover all modes currently defined in uapi +header: + + - link_modes[] array in netlink/settings.c + - all_advertised_modes_bits[] array in ethtool.c + - table of modes and corresponding bit values in manual page + +In the manual page table, fix also whitespace and order inconsistencies. + +Signed-off-by: Michal Kubecek +(cherry picked from commit 63130d0b00040136629988a1170da93ae742ca51) +--- + ethtool.8.in | 32 ++++++++++++++++++++++++++------ + ethtool.c | 24 ++++++++++++++++++++++-- + netlink/settings.c | 15 +++++++++++++++ + 3 files changed, 63 insertions(+), 8 deletions(-) + +diff --git a/ethtool.8.in b/ethtool.8.in +index a50a4769895c..12866dc456cf 100644 +--- a/ethtool.8.in ++++ b/ethtool.8.in +@@ -721,21 +721,21 @@ lB l lB. + 0x80000000000000000 100baseT1 Full + 0x010 1000baseT Half (not supported by IEEE standards) + 0x020 1000baseT Full +-0x100000000000000000 1000baseT1 Full + 0x20000 1000baseKX Full + 0x20000000000 1000baseX Full +-0x800000000000 2500baseT Full ++0x100000000000000000 1000baseT1 Full + 0x8000 2500baseX Full (not supported by IEEE standards) ++0x800000000000 2500baseT Full + 0x1000000000000 5000baseT Full + 0x1000 10000baseT Full + 0x40000 10000baseKX4 Full + 0x80000 10000baseKR Full + 0x100000 10000baseR_FEC +-0x40000000000 10000baseCR Full +-0x80000000000 10000baseSR Full +-0x100000000000 10000baseLR Full ++0x40000000000 10000baseCR Full ++0x80000000000 10000baseSR Full ++0x100000000000 10000baseLR Full + 0x200000000000 10000baseLRM Full +-0x400000000000 10000baseER Full ++0x400000000000 10000baseER Full + 0x200000 20000baseMLD2 Full (not supported by IEEE standards) + 0x400000 20000baseKR2 Full (not supported by IEEE standards) + 0x80000000 25000baseCR Full +@@ -766,11 +766,31 @@ lB l lB. + 0x800000000000000 100000baseCR2 Full + 0x1000000000000000 100000baseLR2_ER2_FR2 Full + 0x2000000000000000 100000baseDR2 Full ++0x8000000000000000000 100000baseKR Full ++0x10000000000000000000 100000baseSR Full ++0x20000000000000000000 100000baseLR_ER_FR Full ++0x40000000000000000000 100000baseCR Full ++0x80000000000000000000 100000baseDR Full + 0x4000000000000000 200000baseKR4 Full + 0x8000000000000000 200000baseSR4 Full + 0x10000000000000000 200000baseLR4_ER4_FR4 Full + 0x20000000000000000 200000baseDR4 Full + 0x40000000000000000 200000baseCR4 Full ++0x100000000000000000000 200000baseKR2 Full ++0x200000000000000000000 200000baseSR2 Full ++0x400000000000000000000 200000baseLR2_ER2_FR2 Full ++0x800000000000000000000 200000baseDR2 Full ++0x1000000000000000000000 200000baseCR2 Full ++0x200000000000000000 400000baseKR8 Full ++0x400000000000000000 400000baseSR8 Full ++0x800000000000000000 400000baseLR8_ER8_FR8 Full ++0x1000000000000000000 400000baseDR8 Full ++0x2000000000000000000 400000baseCR8 Full ++0x2000000000000000000000 400000baseKR4 Full ++0x4000000000000000000000 400000baseSR4 Full ++0x8000000000000000000000 400000baseLR4_ER4_FR4 Full ++0x10000000000000000000000 400000baseDR4 Full ++0x20000000000000000000000 400000baseCR4 Full + .TE + .TP + .BI phyad \ N +diff --git a/ethtool.c b/ethtool.c +index 606af3e6b48f..2e24e98187d2 100644 +--- a/ethtool.c ++++ b/ethtool.c +@@ -392,9 +392,9 @@ static void init_global_link_mode_masks(void) + ETHTOOL_LINK_MODE_100baseT_Full_BIT, + ETHTOOL_LINK_MODE_1000baseT_Half_BIT, + ETHTOOL_LINK_MODE_1000baseT_Full_BIT, +- ETHTOOL_LINK_MODE_1000baseKX_Full_BIT, +- ETHTOOL_LINK_MODE_2500baseX_Full_BIT, + ETHTOOL_LINK_MODE_10000baseT_Full_BIT, ++ ETHTOOL_LINK_MODE_2500baseX_Full_BIT, ++ ETHTOOL_LINK_MODE_1000baseKX_Full_BIT, + ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT, + ETHTOOL_LINK_MODE_10000baseKR_Full_BIT, + ETHTOOL_LINK_MODE_10000baseR_FEC_BIT, +@@ -443,6 +443,26 @@ static void init_global_link_mode_masks(void) + ETHTOOL_LINK_MODE_200000baseCR4_Full_BIT, + ETHTOOL_LINK_MODE_100baseT1_Full_BIT, + ETHTOOL_LINK_MODE_1000baseT1_Full_BIT, ++ ETHTOOL_LINK_MODE_400000baseKR8_Full_BIT, ++ ETHTOOL_LINK_MODE_400000baseSR8_Full_BIT, ++ ETHTOOL_LINK_MODE_400000baseLR8_ER8_FR8_Full_BIT, ++ ETHTOOL_LINK_MODE_400000baseDR8_Full_BIT, ++ ETHTOOL_LINK_MODE_400000baseCR8_Full_BIT, ++ ETHTOOL_LINK_MODE_100000baseKR_Full_BIT, ++ ETHTOOL_LINK_MODE_100000baseSR_Full_BIT, ++ ETHTOOL_LINK_MODE_100000baseLR_ER_FR_Full_BIT, ++ ETHTOOL_LINK_MODE_100000baseCR_Full_BIT, ++ ETHTOOL_LINK_MODE_100000baseDR_Full_BIT, ++ ETHTOOL_LINK_MODE_200000baseKR2_Full_BIT, ++ ETHTOOL_LINK_MODE_200000baseSR2_Full_BIT, ++ ETHTOOL_LINK_MODE_200000baseLR2_ER2_FR2_Full_BIT, ++ ETHTOOL_LINK_MODE_200000baseDR2_Full_BIT, ++ ETHTOOL_LINK_MODE_200000baseCR2_Full_BIT, ++ ETHTOOL_LINK_MODE_400000baseKR4_Full_BIT, ++ ETHTOOL_LINK_MODE_400000baseSR4_Full_BIT, ++ ETHTOOL_LINK_MODE_400000baseLR4_ER4_FR4_Full_BIT, ++ ETHTOOL_LINK_MODE_400000baseDR4_Full_BIT, ++ ETHTOOL_LINK_MODE_400000baseCR4_Full_BIT, + }; + static const enum ethtool_link_mode_bit_indices + additional_advertised_flags_bits[] = { +diff --git a/netlink/settings.c b/netlink/settings.c +index d1da995b434c..3a9518a7e12b 100644 +--- a/netlink/settings.c ++++ b/netlink/settings.c +@@ -147,6 +147,21 @@ static const struct link_mode_info link_modes[] = { + [ETHTOOL_LINK_MODE_400000baseDR8_Full_BIT] = __REAL(400000), + [ETHTOOL_LINK_MODE_400000baseCR8_Full_BIT] = __REAL(400000), + [ETHTOOL_LINK_MODE_FEC_LLRS_BIT] = __SPECIAL(FEC), ++ [ETHTOOL_LINK_MODE_100000baseKR_Full_BIT] = __REAL(100000), ++ [ETHTOOL_LINK_MODE_100000baseSR_Full_BIT] = __REAL(100000), ++ [ETHTOOL_LINK_MODE_100000baseLR_ER_FR_Full_BIT] = __REAL(100000), ++ [ETHTOOL_LINK_MODE_100000baseCR_Full_BIT] = __REAL(100000), ++ [ETHTOOL_LINK_MODE_100000baseDR_Full_BIT] = __REAL(100000), ++ [ETHTOOL_LINK_MODE_200000baseKR2_Full_BIT] = __REAL(200000), ++ [ETHTOOL_LINK_MODE_200000baseSR2_Full_BIT] = __REAL(200000), ++ [ETHTOOL_LINK_MODE_200000baseLR2_ER2_FR2_Full_BIT] = __REAL(200000), ++ [ETHTOOL_LINK_MODE_200000baseDR2_Full_BIT] = __REAL(200000), ++ [ETHTOOL_LINK_MODE_200000baseCR2_Full_BIT] = __REAL(200000), ++ [ETHTOOL_LINK_MODE_400000baseKR4_Full_BIT] = __REAL(400000), ++ [ETHTOOL_LINK_MODE_400000baseSR4_Full_BIT] = __REAL(400000), ++ [ETHTOOL_LINK_MODE_400000baseLR4_ER4_FR4_Full_BIT] = __REAL(400000), ++ [ETHTOOL_LINK_MODE_400000baseDR4_Full_BIT] = __REAL(400000), ++ [ETHTOOL_LINK_MODE_400000baseCR4_Full_BIT] = __REAL(400000), + }; + const unsigned int link_modes_count = ARRAY_SIZE(link_modes); + +-- +2.26.2 + diff --git a/SOURCES/0016-netlink-return-ENOMEM-when-calloc-fails.patch b/SOURCES/0016-netlink-return-ENOMEM-when-calloc-fails.patch new file mode 100644 index 0000000..6140036 --- /dev/null +++ b/SOURCES/0016-netlink-return-ENOMEM-when-calloc-fails.patch @@ -0,0 +1,50 @@ +From d0362097e60d227bac4f66a06891ee1d807d2c48 Mon Sep 17 00:00:00 2001 +From: Ivan Vecera +Date: Thu, 24 Sep 2020 19:51:47 +0200 +Subject: [PATCH 16/17] netlink: return -ENOMEM when calloc fails + +Fixes: f2c17e107900 ("netlink: add netlink handler for gfeatures (-k)") + +Cc: Michal Kubecek +Signed-off-by: Ivan Vecera +--- + netlink/features.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/netlink/features.c b/netlink/features.c +index 3f1240437350..b2cf57eea660 100644 +--- a/netlink/features.c ++++ b/netlink/features.c +@@ -112,16 +112,17 @@ int dump_features(const struct nlattr *const *tb, + unsigned int *feature_flags = NULL; + struct feature_results results; + unsigned int i, j; +- int ret; ++ int ret = 0; + + ret = prepare_feature_results(tb, &results); + if (ret < 0) + return -EFAULT; + +- ret = -ENOMEM; + feature_flags = calloc(results.count, sizeof(feature_flags[0])); +- if (!feature_flags) ++ if (!feature_flags) { ++ ret = -ENOMEM; + goto out_free; ++ } + + /* map netdev features to legacy flags */ + for (i = 0; i < results.count; i++) { +@@ -184,7 +185,7 @@ int dump_features(const struct nlattr *const *tb, + + out_free: + free(feature_flags); +- return 0; ++ return ret; + } + + int features_reply_cb(const struct nlmsghdr *nlhdr, void *data) +-- +2.26.2 + diff --git a/SOURCES/0017-netlink-fix-memory-leak.patch b/SOURCES/0017-netlink-fix-memory-leak.patch new file mode 100644 index 0000000..306bd38 --- /dev/null +++ b/SOURCES/0017-netlink-fix-memory-leak.patch @@ -0,0 +1,35 @@ +From f1bb0c6263ca11bedea9e18bc9753c6b1d4c924d Mon Sep 17 00:00:00 2001 +From: Ivan Vecera +Date: Thu, 24 Sep 2020 20:10:31 +0200 +Subject: [PATCH 17/17] netlink: fix memory leak + +Potentially allocated memory allocated for mask is not freed when +the allocation for value fails. + +Fixes: 81a30f416ec7 ("netlink: add bitset command line parser handlers") + +Cc: Michal Kubecek +Signed-off-by: Ivan Vecera +--- + netlink/parser.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/netlink/parser.c b/netlink/parser.c +index c5a368a65a7a..3b25f5d5a88e 100644 +--- a/netlink/parser.c ++++ b/netlink/parser.c +@@ -630,8 +630,10 @@ static int parse_numeric_bitset(struct nl_context *nlctx, uint16_t type, + } + + value = calloc(nwords, sizeof(uint32_t)); +- if (!value) ++ if (!value) { ++ free(mask); + return -ENOMEM; ++ } + ret = __parse_num_string(arg, len1, value, force_hex1); + if (ret < 0) { + parser_err_invalid_value(nlctx, arg); +-- +2.26.2 + diff --git a/SOURCES/0018-fix-memory-leaks-in-do_sfeatures.patch b/SOURCES/0018-fix-memory-leaks-in-do_sfeatures.patch new file mode 100644 index 0000000..6fa5fcc --- /dev/null +++ b/SOURCES/0018-fix-memory-leaks-in-do_sfeatures.patch @@ -0,0 +1,60 @@ +From 78b5b29e6cf286ce687e7b4d42745fb06cfb2353 Mon Sep 17 00:00:00 2001 +From: Ivan Vecera +Date: Fri, 25 Sep 2020 08:39:16 +0200 +Subject: [PATCH 18/19] fix memory leaks in do_sfeatures() + +Memory blocks referenced by new_state and old_state are never freed. +For efeatures there is no need to check pointer as free() can be called +with NULL parameter. + +Fixes: 6042804cf6ec ("Change -k/-K options to use ETHTOOL_{G,S}FEATURES") + +Cc: Michal Kubecek +Signed-off-by: Ivan Vecera +--- + ethtool.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +diff --git a/ethtool.c b/ethtool.c +index 2e24e98187d2..32ef80add923 100644 +--- a/ethtool.c ++++ b/ethtool.c +@@ -2392,9 +2392,10 @@ static int do_sfeatures(struct cmd_context *ctx) + int any_changed = 0, any_mismatch = 0; + u32 off_flags_wanted = 0; + u32 off_flags_mask = 0; +- struct ethtool_sfeatures *efeatures; ++ struct ethtool_sfeatures *efeatures = NULL; ++ struct feature_state *old_state = NULL; ++ struct feature_state *new_state = NULL; + struct cmdline_info *cmdline_features; +- struct feature_state *old_state, *new_state; + struct ethtool_value eval; + unsigned int i, j; + int err, rc; +@@ -2418,8 +2419,6 @@ static int do_sfeatures(struct cmd_context *ctx) + memset(efeatures->features, 0, + FEATURE_BITS_TO_BLOCKS(defs->n_features) * + sizeof(efeatures->features[0])); +- } else { +- efeatures = NULL; + } + + /* Generate cmdline_info for legacy flags and kernel-named +@@ -2578,9 +2577,11 @@ static int do_sfeatures(struct cmd_context *ctx) + rc = 0; + + err: ++ free(new_state); ++ free(old_state); + free(defs); +- if (efeatures) +- free(efeatures); ++ free(efeatures); ++ + return rc; + } + +-- +2.26.2 + diff --git a/SOURCES/0019-netlink-fix-copy-paste-error-in-rtm_link_summary.patch b/SOURCES/0019-netlink-fix-copy-paste-error-in-rtm_link_summary.patch new file mode 100644 index 0000000..7542e7f --- /dev/null +++ b/SOURCES/0019-netlink-fix-copy-paste-error-in-rtm_link_summary.patch @@ -0,0 +1,29 @@ +From d76260a0c91c0590f9c82a2771fd10f40b8c81fd Mon Sep 17 00:00:00 2001 +From: Ivan Vecera +Date: Fri, 25 Sep 2020 09:03:57 +0200 +Subject: [PATCH 19/19] netlink: fix copy-paste error in rtm_link_summary() + +Fixes: bdfffab54933 ("netlink: message format descriptions for rtnetlink") + +Cc: Michal Kubecek +Signed-off-by: Ivan Vecera +--- + netlink/prettymsg.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/netlink/prettymsg.c b/netlink/prettymsg.c +index 9e62bebe615e..f992dcaf071f 100644 +--- a/netlink/prettymsg.c ++++ b/netlink/prettymsg.c +@@ -202,7 +202,7 @@ static void rtm_link_summary(const struct ifinfomsg *ifinfo) + printf(" ifindex=%d", ifinfo->ifi_index); + if (ifinfo->ifi_flags) + printf(" flags=0x%x", ifinfo->ifi_flags); +- if (ifinfo->ifi_flags) ++ if (ifinfo->ifi_change) + printf(" change=0x%x", ifinfo->ifi_change); + } + +-- +2.26.2 + diff --git a/SOURCES/0020-uapi-linux-update-kernel-UAPI-header-files.patch b/SOURCES/0020-uapi-linux-update-kernel-UAPI-header-files.patch new file mode 100644 index 0000000..f36f8b9 --- /dev/null +++ b/SOURCES/0020-uapi-linux-update-kernel-UAPI-header-files.patch @@ -0,0 +1,117 @@ +From 8fa6c3a1bc2536816e961a4ef865c67218683bf2 Mon Sep 17 00:00:00 2001 +From: Amit Cohen +Date: Thu, 2 Jul 2020 16:11:09 +0300 +Subject: [PATCH 20/26] uapi: linux: update kernel UAPI header files + +Add copies of kernel UAPI header files needed for link extended state: + uapi/linux/ethtool.h + uapi/linux/ethtool_netlink.h + +The copies are taken from net-next tree, +commit ecc31c60240b ("ethtool: Add link extended state") + +Signed-off-by: Amit Cohen +Signed-off-by: Michal Kubecek +(cherry picked from commit dc46dd315071190b880dba9b48dd4521cf7c133e) +--- + uapi/linux/ethtool.h | 70 ++++++++++++++++++++++++++++++++++++ + uapi/linux/ethtool_netlink.h | 2 ++ + 2 files changed, 72 insertions(+) + +diff --git a/uapi/linux/ethtool.h b/uapi/linux/ethtool.h +index 355e718a99fd..847ccd0b1fce 100644 +--- a/uapi/linux/ethtool.h ++++ b/uapi/linux/ethtool.h +@@ -577,6 +577,76 @@ struct ethtool_pauseparam { + __u32 tx_pause; + }; + ++/** ++ * enum ethtool_link_ext_state - link extended state ++ */ ++enum ethtool_link_ext_state { ++ ETHTOOL_LINK_EXT_STATE_AUTONEG, ++ ETHTOOL_LINK_EXT_STATE_LINK_TRAINING_FAILURE, ++ ETHTOOL_LINK_EXT_STATE_LINK_LOGICAL_MISMATCH, ++ ETHTOOL_LINK_EXT_STATE_BAD_SIGNAL_INTEGRITY, ++ ETHTOOL_LINK_EXT_STATE_NO_CABLE, ++ ETHTOOL_LINK_EXT_STATE_CABLE_ISSUE, ++ ETHTOOL_LINK_EXT_STATE_EEPROM_ISSUE, ++ ETHTOOL_LINK_EXT_STATE_CALIBRATION_FAILURE, ++ ETHTOOL_LINK_EXT_STATE_POWER_BUDGET_EXCEEDED, ++ ETHTOOL_LINK_EXT_STATE_OVERHEAT, ++}; ++ ++/** ++ * enum ethtool_link_ext_substate_autoneg - more information in addition to ++ * ETHTOOL_LINK_EXT_STATE_AUTONEG. ++ */ ++enum ethtool_link_ext_substate_autoneg { ++ ETHTOOL_LINK_EXT_SUBSTATE_AN_NO_PARTNER_DETECTED = 1, ++ ETHTOOL_LINK_EXT_SUBSTATE_AN_ACK_NOT_RECEIVED, ++ ETHTOOL_LINK_EXT_SUBSTATE_AN_NEXT_PAGE_EXCHANGE_FAILED, ++ ETHTOOL_LINK_EXT_SUBSTATE_AN_NO_PARTNER_DETECTED_FORCE_MODE, ++ ETHTOOL_LINK_EXT_SUBSTATE_AN_FEC_MISMATCH_DURING_OVERRIDE, ++ ETHTOOL_LINK_EXT_SUBSTATE_AN_NO_HCD, ++}; ++ ++/** ++ * enum ethtool_link_ext_substate_link_training - more information in addition to ++ * ETHTOOL_LINK_EXT_STATE_LINK_TRAINING_FAILURE. ++ */ ++enum ethtool_link_ext_substate_link_training { ++ ETHTOOL_LINK_EXT_SUBSTATE_LT_KR_FRAME_LOCK_NOT_ACQUIRED = 1, ++ ETHTOOL_LINK_EXT_SUBSTATE_LT_KR_LINK_INHIBIT_TIMEOUT, ++ ETHTOOL_LINK_EXT_SUBSTATE_LT_KR_LINK_PARTNER_DID_NOT_SET_RECEIVER_READY, ++ ETHTOOL_LINK_EXT_SUBSTATE_LT_REMOTE_FAULT, ++}; ++ ++/** ++ * enum ethtool_link_ext_substate_logical_mismatch - more information in addition ++ * to ETHTOOL_LINK_EXT_STATE_LINK_LOGICAL_MISMATCH. ++ */ ++enum ethtool_link_ext_substate_link_logical_mismatch { ++ ETHTOOL_LINK_EXT_SUBSTATE_LLM_PCS_DID_NOT_ACQUIRE_BLOCK_LOCK = 1, ++ ETHTOOL_LINK_EXT_SUBSTATE_LLM_PCS_DID_NOT_ACQUIRE_AM_LOCK, ++ ETHTOOL_LINK_EXT_SUBSTATE_LLM_PCS_DID_NOT_GET_ALIGN_STATUS, ++ ETHTOOL_LINK_EXT_SUBSTATE_LLM_FC_FEC_IS_NOT_LOCKED, ++ ETHTOOL_LINK_EXT_SUBSTATE_LLM_RS_FEC_IS_NOT_LOCKED, ++}; ++ ++/** ++ * enum ethtool_link_ext_substate_bad_signal_integrity - more information in ++ * addition to ETHTOOL_LINK_EXT_STATE_BAD_SIGNAL_INTEGRITY. ++ */ ++enum ethtool_link_ext_substate_bad_signal_integrity { ++ ETHTOOL_LINK_EXT_SUBSTATE_BSI_LARGE_NUMBER_OF_PHYSICAL_ERRORS = 1, ++ ETHTOOL_LINK_EXT_SUBSTATE_BSI_UNSUPPORTED_RATE, ++}; ++ ++/** ++ * enum ethtool_link_ext_substate_cable_issue - more information in ++ * addition to ETHTOOL_LINK_EXT_STATE_CABLE_ISSUE. ++ */ ++enum ethtool_link_ext_substate_cable_issue { ++ ETHTOOL_LINK_EXT_SUBSTATE_CI_UNSUPPORTED_CABLE = 1, ++ ETHTOOL_LINK_EXT_SUBSTATE_CI_CABLE_TEST_FAILURE, ++}; ++ + #define ETH_GSTRING_LEN 32 + + /** +diff --git a/uapi/linux/ethtool_netlink.h b/uapi/linux/ethtool_netlink.h +index c1b4d67d35d1..cebdb52e6a05 100644 +--- a/uapi/linux/ethtool_netlink.h ++++ b/uapi/linux/ethtool_netlink.h +@@ -237,6 +237,8 @@ enum { + ETHTOOL_A_LINKSTATE_LINK, /* u8 */ + ETHTOOL_A_LINKSTATE_SQI, /* u32 */ + ETHTOOL_A_LINKSTATE_SQI_MAX, /* u32 */ ++ ETHTOOL_A_LINKSTATE_EXT_STATE, /* u8 */ ++ ETHTOOL_A_LINKSTATE_EXT_SUBSTATE, /* u8 */ + + /* add new constants above here */ + __ETHTOOL_A_LINKSTATE_CNT, +-- +2.26.2 + diff --git a/SOURCES/0021-netlink-settings-expand-linkstate_reply_cb-to-suppor.patch b/SOURCES/0021-netlink-settings-expand-linkstate_reply_cb-to-suppor.patch new file mode 100644 index 0000000..1b5bcf3 --- /dev/null +++ b/SOURCES/0021-netlink-settings-expand-linkstate_reply_cb-to-suppor.patch @@ -0,0 +1,187 @@ +From abc33073ed6d4528d3c951cc719a155a6e1178cd Mon Sep 17 00:00:00 2001 +From: Amit Cohen +Date: Thu, 2 Jul 2020 16:11:11 +0300 +Subject: [PATCH 21/26] netlink: settings: expand linkstate_reply_cb() to + support link extended state + +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 +Signed-off-by: Michal Kubecek +(cherry picked from commit ba6367d2bb32173166b91fbcc053865c99ca7c57) +--- + netlink/settings.c | 147 ++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 146 insertions(+), 1 deletion(-) + +diff --git a/netlink/settings.c b/netlink/settings.c +index 3a9518a7e12b..75db15e5069c 100644 +--- a/netlink/settings.c ++++ b/netlink/settings.c +@@ -565,6 +565,149 @@ int linkinfo_reply_cb(const struct nlmsghdr *nlhdr, void *data) + return MNL_CB_OK; + } + ++static const char *get_enum_string(const char *const *string_table, unsigned int n_string_table, ++ unsigned int val) ++{ ++ if (val >= n_string_table || !string_table[val]) ++ return NULL; ++ else ++ return string_table[val]; ++} ++ ++static const char *const names_link_ext_state[] = { ++ [ETHTOOL_LINK_EXT_STATE_AUTONEG] = "Autoneg", ++ [ETHTOOL_LINK_EXT_STATE_LINK_TRAINING_FAILURE] = "Link training failure", ++ [ETHTOOL_LINK_EXT_STATE_LINK_LOGICAL_MISMATCH] = "Logical mismatch", ++ [ETHTOOL_LINK_EXT_STATE_BAD_SIGNAL_INTEGRITY] = "Bad signal integrity", ++ [ETHTOOL_LINK_EXT_STATE_NO_CABLE] = "No cable", ++ [ETHTOOL_LINK_EXT_STATE_CABLE_ISSUE] = "Cable issue", ++ [ETHTOOL_LINK_EXT_STATE_EEPROM_ISSUE] = "EEPROM issue", ++ [ETHTOOL_LINK_EXT_STATE_CALIBRATION_FAILURE] = "Calibration failure", ++ [ETHTOOL_LINK_EXT_STATE_POWER_BUDGET_EXCEEDED] = "Power budget exceeded", ++ [ETHTOOL_LINK_EXT_STATE_OVERHEAT] = "Overheat", ++}; ++ ++static const char *const names_autoneg_link_ext_substate[] = { ++ [ETHTOOL_LINK_EXT_SUBSTATE_AN_NO_PARTNER_DETECTED] = ++ "No partner detected", ++ [ETHTOOL_LINK_EXT_SUBSTATE_AN_ACK_NOT_RECEIVED] = ++ "Ack not received", ++ [ETHTOOL_LINK_EXT_SUBSTATE_AN_NEXT_PAGE_EXCHANGE_FAILED] = ++ "Next page exchange failed", ++ [ETHTOOL_LINK_EXT_SUBSTATE_AN_NO_PARTNER_DETECTED_FORCE_MODE] = ++ "No partner detected during force mode", ++ [ETHTOOL_LINK_EXT_SUBSTATE_AN_FEC_MISMATCH_DURING_OVERRIDE] = ++ "FEC mismatch during override", ++ [ETHTOOL_LINK_EXT_SUBSTATE_AN_NO_HCD] = ++ "No HCD", ++}; ++ ++static const char *const names_link_training_link_ext_substate[] = { ++ [ETHTOOL_LINK_EXT_SUBSTATE_LT_KR_FRAME_LOCK_NOT_ACQUIRED] = ++ "KR frame lock not acquired", ++ [ETHTOOL_LINK_EXT_SUBSTATE_LT_KR_LINK_INHIBIT_TIMEOUT] = ++ "KR link inhibit timeout", ++ [ETHTOOL_LINK_EXT_SUBSTATE_LT_KR_LINK_PARTNER_DID_NOT_SET_RECEIVER_READY] = ++ "KR Link partner did not set receiver ready", ++ [ETHTOOL_LINK_EXT_SUBSTATE_LT_REMOTE_FAULT] = ++ "Remote side is not ready yet", ++}; ++ ++static const char *const names_link_logical_mismatch_link_ext_substate[] = { ++ [ETHTOOL_LINK_EXT_SUBSTATE_LLM_PCS_DID_NOT_ACQUIRE_BLOCK_LOCK] = ++ "PCS did not acquire block lock", ++ [ETHTOOL_LINK_EXT_SUBSTATE_LLM_PCS_DID_NOT_ACQUIRE_AM_LOCK] = ++ "PCS did not acquire AM lock", ++ [ETHTOOL_LINK_EXT_SUBSTATE_LLM_PCS_DID_NOT_GET_ALIGN_STATUS] = ++ "PCS did not get align_status", ++ [ETHTOOL_LINK_EXT_SUBSTATE_LLM_FC_FEC_IS_NOT_LOCKED] = ++ "FC FEC is not locked", ++ [ETHTOOL_LINK_EXT_SUBSTATE_LLM_RS_FEC_IS_NOT_LOCKED] = ++ "RS FEC is not locked", ++}; ++ ++static const char *const names_bad_signal_integrity_link_ext_substate[] = { ++ [ETHTOOL_LINK_EXT_SUBSTATE_BSI_LARGE_NUMBER_OF_PHYSICAL_ERRORS] = ++ "Large number of physical errors", ++ [ETHTOOL_LINK_EXT_SUBSTATE_BSI_UNSUPPORTED_RATE] = ++ "Unsupported rate", ++}; ++ ++static const char *const names_cable_issue_link_ext_substate[] = { ++ [ETHTOOL_LINK_EXT_SUBSTATE_CI_UNSUPPORTED_CABLE] = ++ "Unsupported cable", ++ [ETHTOOL_LINK_EXT_SUBSTATE_CI_CABLE_TEST_FAILURE] = ++ "Cable test failure", ++}; ++ ++static const char *link_ext_substate_get(uint8_t link_ext_state_val, uint8_t link_ext_substate_val) ++{ ++ switch (link_ext_state_val) { ++ case ETHTOOL_LINK_EXT_STATE_AUTONEG: ++ return get_enum_string(names_autoneg_link_ext_substate, ++ ARRAY_SIZE(names_autoneg_link_ext_substate), ++ link_ext_substate_val); ++ case ETHTOOL_LINK_EXT_STATE_LINK_TRAINING_FAILURE: ++ return get_enum_string(names_link_training_link_ext_substate, ++ ARRAY_SIZE(names_link_training_link_ext_substate), ++ link_ext_substate_val); ++ case ETHTOOL_LINK_EXT_STATE_LINK_LOGICAL_MISMATCH: ++ return get_enum_string(names_link_logical_mismatch_link_ext_substate, ++ ARRAY_SIZE(names_link_logical_mismatch_link_ext_substate), ++ link_ext_substate_val); ++ case ETHTOOL_LINK_EXT_STATE_BAD_SIGNAL_INTEGRITY: ++ return get_enum_string(names_bad_signal_integrity_link_ext_substate, ++ ARRAY_SIZE(names_bad_signal_integrity_link_ext_substate), ++ link_ext_substate_val); ++ case ETHTOOL_LINK_EXT_STATE_CABLE_ISSUE: ++ return get_enum_string(names_cable_issue_link_ext_substate, ++ ARRAY_SIZE(names_cable_issue_link_ext_substate), ++ link_ext_substate_val); ++ default: ++ return NULL; ++ } ++} ++ ++static void linkstate_link_ext_substate_print(const struct nlattr *tb[], struct nl_context *nlctx, ++ uint8_t link_ext_state_val) ++{ ++ uint8_t link_ext_substate_val; ++ const char *link_ext_substate_str; ++ ++ if (!tb[ETHTOOL_A_LINKSTATE_EXT_SUBSTATE]) ++ return; ++ ++ 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) ++ printf(", %u", link_ext_substate_val); ++ else ++ printf(", %s", link_ext_substate_str); ++} ++ ++static void linkstate_link_ext_state_print(const struct nlattr *tb[], struct nl_context *nlctx) ++{ ++ uint8_t link_ext_state_val; ++ const char *link_ext_state_str; ++ ++ if (!tb[ETHTOOL_A_LINKSTATE_EXT_STATE]) ++ return; ++ ++ link_ext_state_val = mnl_attr_get_u8(tb[ETHTOOL_A_LINKSTATE_EXT_STATE]); ++ ++ link_ext_state_str = get_enum_string(names_link_ext_state, ++ ARRAY_SIZE(names_link_ext_state), ++ link_ext_state_val); ++ if (!link_ext_state_str) ++ printf(" (%u", link_ext_state_val); ++ else ++ printf(" (%s", link_ext_state_str); ++ ++ linkstate_link_ext_substate_print(tb, nlctx, link_ext_state_val); ++ printf(")"); ++} ++ + int linkstate_reply_cb(const struct nlmsghdr *nlhdr, void *data) + { + const struct nlattr *tb[ETHTOOL_A_LINKSTATE_MAX + 1] = {}; +@@ -585,7 +728,9 @@ int linkstate_reply_cb(const struct nlmsghdr *nlhdr, void *data) + uint8_t val = mnl_attr_get_u8(tb[ETHTOOL_A_LINKSTATE_LINK]); + + print_banner(nlctx); +- printf("\tLink detected: %s\n", val ? "yes" : "no"); ++ printf("\tLink detected: %s", val ? "yes" : "no"); ++ linkstate_link_ext_state_print(tb, nlctx); ++ printf("\n"); + } + + if (tb[ETHTOOL_A_LINKSTATE_SQI]) { +-- +2.26.2 + diff --git a/SOURCES/0022-netlink-prepare-for-more-per-op-info.patch b/SOURCES/0022-netlink-prepare-for-more-per-op-info.patch new file mode 100644 index 0000000..4b3a008 --- /dev/null +++ b/SOURCES/0022-netlink-prepare-for-more-per-op-info.patch @@ -0,0 +1,126 @@ +From 15e57173470b0929fd649bc7b0376d41c786ddbe Mon Sep 17 00:00:00 2001 +From: Jakub Kicinski +Date: Sun, 18 Oct 2020 14:31:49 -0700 +Subject: [PATCH 22/26] netlink: prepare for more per-op info + +We stored an array of op flags, to check if operations are +supported. Make that array a structure rather than plain +uint32_t in preparation for storing more state. + +v3: new patch + +Signed-off-by: Jakub Kicinski +Signed-off-by: Michal Kubecek +(cherry picked from commit 8d36270be3c06b99eba281ccf341ebfab555c6b6) +--- + netlink/netlink.c | 25 +++++++++++++------------ + netlink/netlink.h | 6 +++++- + 2 files changed, 18 insertions(+), 13 deletions(-) + +diff --git a/netlink/netlink.c b/netlink/netlink.c +index e42d57076a4b..86dc1efdf5ce 100644 +--- a/netlink/netlink.c ++++ b/netlink/netlink.c +@@ -120,19 +120,19 @@ bool netlink_cmd_check(struct cmd_context *ctx, unsigned int cmd, + nlctx->wildcard_unsupported = true; + return true; + } +- if (!nlctx->ops_flags) { ++ if (!nlctx->ops_info) { + nlctx->ioctl_fallback = true; + return false; + } +- if (cmd > ETHTOOL_MSG_USER_MAX || !nlctx->ops_flags[cmd]) { ++ if (cmd > ETHTOOL_MSG_USER_MAX || !nlctx->ops_info[cmd].op_flags) { + nlctx->ioctl_fallback = true; + return true; + } + +- if (is_dump && !(nlctx->ops_flags[cmd] & GENL_CMD_CAP_DUMP)) ++ if (is_dump && !(nlctx->ops_info[cmd].op_flags & GENL_CMD_CAP_DUMP)) + nlctx->wildcard_unsupported = true; + +- return !(nlctx->ops_flags[cmd] & cap); ++ return !(nlctx->ops_info[cmd].op_flags & cap); + } + + /* initialization */ +@@ -140,12 +140,12 @@ bool netlink_cmd_check(struct cmd_context *ctx, unsigned int cmd, + static int genl_read_ops(struct nl_context *nlctx, + const struct nlattr *ops_attr) + { ++ struct nl_op_info *ops_info; + struct nlattr *op_attr; +- uint32_t *ops_flags; + int ret; + +- ops_flags = calloc(__ETHTOOL_MSG_USER_CNT, sizeof(ops_flags[0])); +- if (!ops_flags) ++ ops_info = calloc(__ETHTOOL_MSG_USER_CNT, sizeof(ops_info[0])); ++ if (!ops_info) + return -ENOMEM; + + mnl_attr_for_each_nested(op_attr, ops_attr) { +@@ -163,13 +163,14 @@ static int genl_read_ops(struct nl_context *nlctx, + if (op_id >= __ETHTOOL_MSG_USER_CNT) + continue; + +- ops_flags[op_id] = mnl_attr_get_u32(tb[CTRL_ATTR_OP_FLAGS]); ++ ops_info[op_id].op_flags = ++ mnl_attr_get_u32(tb[CTRL_ATTR_OP_FLAGS]); + } + +- nlctx->ops_flags = ops_flags; ++ nlctx->ops_info = ops_info; + return 0; + err: +- free(ops_flags); ++ free(ops_info); + return ret; + } + +@@ -273,7 +274,7 @@ int netlink_init(struct cmd_context *ctx) + out_nlsk: + nlsock_done(nlctx->ethnl_socket); + out_free: +- free(nlctx->ops_flags); ++ free(nlctx->ops_info); + free(nlctx); + return ret; + } +@@ -283,7 +284,7 @@ static void netlink_done(struct cmd_context *ctx) + if (!ctx->nlctx) + return; + +- free(ctx->nlctx->ops_flags); ++ free(ctx->nlctx->ops_info); + free(ctx->nlctx); + ctx->nlctx = NULL; + cleanup_all_strings(); +diff --git a/netlink/netlink.h b/netlink/netlink.h +index dd4a02bcc916..61a072db8ed9 100644 +--- a/netlink/netlink.h ++++ b/netlink/netlink.h +@@ -25,6 +25,10 @@ enum link_mode_class { + LM_CLASS_FEC, + }; + ++struct nl_op_info { ++ uint32_t op_flags; ++}; ++ + struct nl_context { + struct cmd_context *ctx; + void *cmd_private; +@@ -34,7 +38,7 @@ struct nl_context { + unsigned int suppress_nlerr; + uint16_t ethnl_fam; + uint32_t ethnl_mongrp; +- uint32_t *ops_flags; ++ struct nl_op_info *ops_info; + struct nl_socket *ethnl_socket; + struct nl_socket *ethnl2_socket; + struct nl_socket *rtnl_socket; +-- +2.26.2 + diff --git a/SOURCES/0023-netlink-fix-use-after-free-in-netlink_run_handler.patch b/SOURCES/0023-netlink-fix-use-after-free-in-netlink_run_handler.patch new file mode 100644 index 0000000..45cfd61 --- /dev/null +++ b/SOURCES/0023-netlink-fix-use-after-free-in-netlink_run_handler.patch @@ -0,0 +1,53 @@ +From ef1675823905ff09cb5e551700a124d0133648b7 Mon Sep 17 00:00:00 2001 +From: Michal Kubecek +Date: Mon, 9 Nov 2020 13:30:54 +0100 +Subject: [PATCH 23/26] netlink: fix use after free in netlink_run_handler() + +Valgrind detected use after free in netlink_run_handler(): some members of +struct nl_context are accessed after the netlink context is freed by +netlink_done(). Use local variables to store the two flags and check them +instead. + +Fixes: 6c19c0d559c8 ("netlink: use genetlink ops information to decide about fallback") +Signed-off-by: Michal Kubecek +(cherry picked from commit 29b38ea218bd978d1950e12cc24da98215a1eeef) +--- + netlink/netlink.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/netlink/netlink.c b/netlink/netlink.c +index 86dc1efdf5ce..2a12bb8b1759 100644 +--- a/netlink/netlink.c ++++ b/netlink/netlink.c +@@ -303,6 +303,7 @@ void netlink_run_handler(struct cmd_context *ctx, nl_func_t nlfunc, + bool no_fallback) + { + bool wildcard = ctx->devname && !strcmp(ctx->devname, WILDCARD_DEVNAME); ++ bool wildcard_unsupported, ioctl_fallback; + struct nl_context *nlctx; + const char *reason; + int ret; +@@ -324,14 +325,17 @@ void netlink_run_handler(struct cmd_context *ctx, nl_func_t nlfunc, + nlctx = ctx->nlctx; + + ret = nlfunc(ctx); ++ wildcard_unsupported = nlctx->wildcard_unsupported; ++ ioctl_fallback = nlctx->ioctl_fallback; + netlink_done(ctx); +- if (no_fallback || ret != -EOPNOTSUPP || !nlctx->ioctl_fallback) { +- if (nlctx->wildcard_unsupported) ++ ++ if (no_fallback || ret != -EOPNOTSUPP || !ioctl_fallback) { ++ if (wildcard_unsupported) + fprintf(stderr, "%s\n", + "subcommand does not support wildcard dump"); + exit(ret >= 0 ? ret : 1); + } +- if (nlctx->wildcard_unsupported) ++ if (wildcard_unsupported) + reason = "subcommand does not support wildcard dump"; + else + reason = "kernel netlink support for subcommand missing"; +-- +2.26.2 + diff --git a/SOURCES/0024-netlink-fix-leaked-instances-of-struct-nl_socket.patch b/SOURCES/0024-netlink-fix-leaked-instances-of-struct-nl_socket.patch new file mode 100644 index 0000000..8d6b809 --- /dev/null +++ b/SOURCES/0024-netlink-fix-leaked-instances-of-struct-nl_socket.patch @@ -0,0 +1,64 @@ +From 5fad40a007b61092161d1e4fd0ffbbc3e7b8ba6c Mon Sep 17 00:00:00 2001 +From: Michal Kubecek +Date: Mon, 9 Nov 2020 13:30:57 +0100 +Subject: [PATCH 24/26] netlink: fix leaked instances of struct nl_socket + +Valgrind detected memory leaks caused by missing cleanup of netlink +context's ethnl_socket, ethnl2_socket and rtnl_socket. Also, contrary to +its description, nlsock_done() does not free struct nl_socket itself. +Fix nlsock_done() to free the structure and use it to dispose of sockets +pointed to by struct nl_context members. + +Fixes: 50efb3cdd2bb ("netlink: netlink socket wrapper and helpers") +Fixes: 87307c30724d ("netlink: initialize ethtool netlink socket") +Fixes: 7f3585b22a4b ("netlink: add handler for permaddr (-P)") +Signed-off-by: Michal Kubecek +(cherry picked from commit d85f57499d75da5c98b73652488f3f62c6f6d8ea) +--- + netlink/netlink.c | 11 ++++++++--- + netlink/nlsock.c | 3 +++ + 2 files changed, 11 insertions(+), 3 deletions(-) + +diff --git a/netlink/netlink.c b/netlink/netlink.c +index 2a12bb8b1759..5677274c2fce 100644 +--- a/netlink/netlink.c ++++ b/netlink/netlink.c +@@ -281,11 +281,16 @@ out_free: + + static void netlink_done(struct cmd_context *ctx) + { +- if (!ctx->nlctx) ++ struct nl_context *nlctx = ctx->nlctx; ++ ++ if (!nlctx) + return; + +- free(ctx->nlctx->ops_info); +- free(ctx->nlctx); ++ nlsock_done(nlctx->ethnl_socket); ++ nlsock_done(nlctx->ethnl2_socket); ++ nlsock_done(nlctx->rtnl_socket); ++ free(nlctx->ops_info); ++ free(nlctx); + ctx->nlctx = NULL; + cleanup_all_strings(); + } +diff --git a/netlink/nlsock.c b/netlink/nlsock.c +index ef31d8c33b29..0ec2738d81d2 100644 +--- a/netlink/nlsock.c ++++ b/netlink/nlsock.c +@@ -395,8 +395,11 @@ out_msgbuff: + */ + void nlsock_done(struct nl_socket *nlsk) + { ++ if (!nlsk) ++ return; + if (nlsk->sk) + mnl_socket_close(nlsk->sk); + msgbuff_done(&nlsk->msgbuff); + memset(nlsk, '\0', sizeof(*nlsk)); ++ free(nlsk); + } +-- +2.26.2 + diff --git a/SOURCES/0025-netlink-do-not-send-messages-and-process-replies-in-.patch b/SOURCES/0025-netlink-do-not-send-messages-and-process-replies-in-.patch new file mode 100644 index 0000000..e5866c2 --- /dev/null +++ b/SOURCES/0025-netlink-do-not-send-messages-and-process-replies-in-.patch @@ -0,0 +1,301 @@ +From fc5f2a6bb2911a951bf5a1364dc5732e521d735a Mon Sep 17 00:00:00 2001 +From: Michal Kubecek +Date: Mon, 9 Nov 2020 14:29:56 +0100 +Subject: [PATCH 25/26] netlink: do not send messages and process replies in + nl_parser() + +When called with group_style = PARSER_GROUP_MSG, nl_parser() not only +parses the command line and composes the messages but also sends them to +kernel and processes the replies. This is inconsistent with other modes and +also impractical as it takes the control over the process from caller where +it belongs. + +Modify nl_parser() to pass composed messages back to caller (which is only +nl_sset() at the moment) and let it send requests and process replies. This +will be needed for an upcoming backward compatibility patch which will need +to inspect and possibly modify one of the composed messages. + +Signed-off-by: Michal Kubecek +(cherry picked from commit acd9730d1e794f85caf1192fe8788876e6f96305) +--- + netlink/cable_test.c | 2 +- + netlink/channels.c | 2 +- + netlink/coalesce.c | 2 +- + netlink/eee.c | 2 +- + netlink/parser.c | 43 ++++++++++++++++++++++++++++--------------- + netlink/parser.h | 3 ++- + netlink/pause.c | 2 +- + netlink/rings.c | 2 +- + netlink/settings.c | 35 ++++++++++++++++++++++++++++++----- + 9 files changed, 66 insertions(+), 27 deletions(-) + +diff --git a/netlink/cable_test.c b/netlink/cable_test.c +index d39b7d82efb0..e05b67c4e231 100644 +--- a/netlink/cable_test.c ++++ b/netlink/cable_test.c +@@ -574,7 +574,7 @@ int nl_cable_test_tdr(struct cmd_context *ctx) + ctx->devname, 0)) + return -EMSGSIZE; + +- ret = nl_parser(nlctx, tdr_params, NULL, PARSER_GROUP_NEST); ++ ret = nl_parser(nlctx, tdr_params, NULL, PARSER_GROUP_NEST, NULL); + if (ret < 0) + return ret; + +diff --git a/netlink/channels.c b/netlink/channels.c +index c6002ceeb121..894c74bcc11a 100644 +--- a/netlink/channels.c ++++ b/netlink/channels.c +@@ -126,7 +126,7 @@ int nl_schannels(struct cmd_context *ctx) + ctx->devname, 0)) + return -EMSGSIZE; + +- ret = nl_parser(nlctx, schannels_params, NULL, PARSER_GROUP_NONE); ++ ret = nl_parser(nlctx, schannels_params, NULL, PARSER_GROUP_NONE, NULL); + if (ret < 0) + return 1; + +diff --git a/netlink/coalesce.c b/netlink/coalesce.c +index 65f75cf9a8dd..0223f8e3484e 100644 +--- a/netlink/coalesce.c ++++ b/netlink/coalesce.c +@@ -254,7 +254,7 @@ int nl_scoalesce(struct cmd_context *ctx) + ctx->devname, 0)) + return -EMSGSIZE; + +- ret = nl_parser(nlctx, scoalesce_params, NULL, PARSER_GROUP_NONE); ++ ret = nl_parser(nlctx, scoalesce_params, NULL, PARSER_GROUP_NONE, NULL); + if (ret < 0) + return 1; + +diff --git a/netlink/eee.c b/netlink/eee.c +index d3135b2094a4..04d8f0bbe3fc 100644 +--- a/netlink/eee.c ++++ b/netlink/eee.c +@@ -174,7 +174,7 @@ int nl_seee(struct cmd_context *ctx) + ctx->devname, 0)) + return -EMSGSIZE; + +- ret = nl_parser(nlctx, seee_params, NULL, PARSER_GROUP_NONE); ++ ret = nl_parser(nlctx, seee_params, NULL, PARSER_GROUP_NONE, NULL); + if (ret < 0) + return 1; + +diff --git a/netlink/parser.c b/netlink/parser.c +index 3b25f5d5a88e..c2eae93efb69 100644 +--- a/netlink/parser.c ++++ b/netlink/parser.c +@@ -920,7 +920,7 @@ static void __parser_set(uint64_t *map, unsigned int idx) + } + + struct tmp_buff { +- struct nl_msg_buff msgbuff; ++ struct nl_msg_buff *msgbuff; + unsigned int id; + unsigned int orig_len; + struct tmp_buff *next; +@@ -951,7 +951,12 @@ static struct tmp_buff *tmp_buff_find_or_create(struct tmp_buff **phead, + if (!new_buff) + return NULL; + new_buff->id = id; +- msgbuff_init(&new_buff->msgbuff); ++ new_buff->msgbuff = malloc(sizeof(*new_buff->msgbuff)); ++ if (!new_buff->msgbuff) { ++ free(new_buff); ++ return NULL; ++ } ++ msgbuff_init(new_buff->msgbuff); + new_buff->next = NULL; + *pbuff = new_buff; + +@@ -965,7 +970,10 @@ static void tmp_buff_destroy(struct tmp_buff *head) + + while (buff) { + next = buff->next; +- msgbuff_done(&buff->msgbuff); ++ if (buff->msgbuff) { ++ msgbuff_done(buff->msgbuff); ++ free(buff->msgbuff); ++ } + free(buff); + buff = next; + } +@@ -980,13 +988,22 @@ static void tmp_buff_destroy(struct tmp_buff *head) + * param_parser::offset) + * @group_style: defines if identifiers in .group represent separate messages, + * nested attributes or are not allowed ++ * @msgbuffs: (only used for @group_style = PARSER_GROUP_MSG) array to store ++ * pointers to composed messages; caller must make sure this ++ * array is sufficient, i.e. that it has at least as many entries ++ * as the number of different .group values in params array; ++ * entries are filled from the start, remaining entries are not ++ * modified; caller should zero initialize the array before ++ * calling nl_parser() + */ + int nl_parser(struct nl_context *nlctx, const struct param_parser *params, +- void *dest, enum parser_group_style group_style) ++ void *dest, enum parser_group_style group_style, ++ struct nl_msg_buff **msgbuffs) + { + struct nl_socket *nlsk = nlctx->ethnl_socket; + const struct param_parser *parser; + struct tmp_buff *buffs = NULL; ++ unsigned int n_msgbuffs = 0; + struct tmp_buff *buff; + unsigned int n_params; + uint64_t *params_seen; +@@ -1004,7 +1021,7 @@ int nl_parser(struct nl_context *nlctx, const struct param_parser *params, + buff = tmp_buff_find_or_create(&buffs, parser->group); + if (!buff) + goto out_free_buffs; +- msgbuff = &buff->msgbuff; ++ msgbuff = buff->msgbuff; + ret = msg_init(nlctx, msgbuff, parser->group, + NLM_F_REQUEST | NLM_F_ACK); + if (ret < 0) +@@ -1013,7 +1030,7 @@ int nl_parser(struct nl_context *nlctx, const struct param_parser *params, + switch (group_style) { + case PARSER_GROUP_NEST: + ret = -EMSGSIZE; +- nest = ethnla_nest_start(&buff->msgbuff, parser->group); ++ nest = ethnla_nest_start(buff->msgbuff, parser->group); + if (!nest) + goto out_free_buffs; + break; +@@ -1062,7 +1079,7 @@ int nl_parser(struct nl_context *nlctx, const struct param_parser *params, + buff = NULL; + if (parser->group) + buff = tmp_buff_find(buffs, parser->group); +- msgbuff = buff ? &buff->msgbuff : &nlsk->msgbuff; ++ msgbuff = buff ? buff->msgbuff : &nlsk->msgbuff; + + param_dest = dest ? ((char *)dest + parser->dest_offset) : NULL; + ret = parser->handler(nlctx, parser->type, parser->handler_data, +@@ -1074,12 +1091,12 @@ int nl_parser(struct nl_context *nlctx, const struct param_parser *params, + if (group_style == PARSER_GROUP_MSG) { + ret = -EOPNOTSUPP; + for (buff = buffs; buff; buff = buff->next) +- if (msgbuff_len(&buff->msgbuff) > buff->orig_len && ++ if (msgbuff_len(buff->msgbuff) > buff->orig_len && + netlink_cmd_check(nlctx->ctx, buff->id, false)) + goto out_free; + } + for (buff = buffs; buff; buff = buff->next) { +- struct nl_msg_buff *msgbuff = &buff->msgbuff; ++ struct nl_msg_buff *msgbuff = buff->msgbuff; + + if (group_style == PARSER_GROUP_NONE || + msgbuff_len(msgbuff) == buff->orig_len) +@@ -1092,12 +1109,8 @@ int nl_parser(struct nl_context *nlctx, const struct param_parser *params, + goto out_free; + break; + case PARSER_GROUP_MSG: +- ret = nlsock_sendmsg(nlsk, msgbuff); +- if (ret < 0) +- goto out_free; +- ret = nlsock_process_reply(nlsk, nomsg_reply_cb, NULL); +- if (ret < 0) +- goto out_free; ++ msgbuffs[n_msgbuffs++] = msgbuff; ++ buff->msgbuff = NULL; + break; + default: + break; +diff --git a/netlink/parser.h b/netlink/parser.h +index fd55bc768d42..28f26ccc2a1c 100644 +--- a/netlink/parser.h ++++ b/netlink/parser.h +@@ -143,6 +143,7 @@ int nl_parse_char_bitset(struct nl_context *nlctx, uint16_t type, + + /* main entry point called to parse the command line */ + int nl_parser(struct nl_context *nlctx, const struct param_parser *params, +- void *dest, enum parser_group_style group_style); ++ void *dest, enum parser_group_style group_style, ++ struct nl_msg_buff **msgbuffs); + + #endif /* ETHTOOL_NETLINK_PARSER_H__ */ +diff --git a/netlink/pause.c b/netlink/pause.c +index 7b6b3a1d2c10..048320b123d2 100644 +--- a/netlink/pause.c ++++ b/netlink/pause.c +@@ -208,7 +208,7 @@ int nl_spause(struct cmd_context *ctx) + ctx->devname, 0)) + return -EMSGSIZE; + +- ret = nl_parser(nlctx, spause_params, NULL, PARSER_GROUP_NONE); ++ ret = nl_parser(nlctx, spause_params, NULL, PARSER_GROUP_NONE, NULL); + if (ret < 0) + return 1; + +diff --git a/netlink/rings.c b/netlink/rings.c +index 4061520212d5..b8c458fce25f 100644 +--- a/netlink/rings.c ++++ b/netlink/rings.c +@@ -126,7 +126,7 @@ int nl_sring(struct cmd_context *ctx) + ctx->devname, 0)) + return -EMSGSIZE; + +- ret = nl_parser(nlctx, sring_params, NULL, PARSER_GROUP_NONE); ++ ret = nl_parser(nlctx, sring_params, NULL, PARSER_GROUP_NONE, NULL); + if (ret < 0) + return 1; + +diff --git a/netlink/settings.c b/netlink/settings.c +index 75db15e5069c..fac192e2fbb7 100644 +--- a/netlink/settings.c ++++ b/netlink/settings.c +@@ -1108,9 +1108,16 @@ static const struct param_parser sset_params[] = { + {} + }; + ++/* Maximum number of request messages sent to kernel; must be equal to the ++ * number of different .group values in sset_params[] array. ++ */ ++#define SSET_MAX_MSGS 4 ++ + int nl_sset(struct cmd_context *ctx) + { ++ struct nl_msg_buff *msgbuffs[SSET_MAX_MSGS] = {}; + struct nl_context *nlctx = ctx->nlctx; ++ unsigned int i; + int ret; + + nlctx->cmd = "-s"; +@@ -1118,11 +1125,29 @@ int nl_sset(struct cmd_context *ctx) + nlctx->argc = ctx->argc; + nlctx->devname = ctx->devname; + +- ret = nl_parser(nlctx, sset_params, NULL, PARSER_GROUP_MSG); +- if (ret < 0) +- return 1; ++ ret = nl_parser(nlctx, sset_params, NULL, PARSER_GROUP_MSG, msgbuffs); ++ if (ret < 0) { ++ ret = 1; ++ goto out_free; ++ } ++ ++ for (i = 0; i < SSET_MAX_MSGS && msgbuffs[i]; i++) { ++ struct nl_socket *nlsk = nlctx->ethnl_socket; + +- if (ret == 0) +- return 0; ++ ret = nlsock_sendmsg(nlsk, msgbuffs[i]); ++ if (ret < 0) ++ goto out_free; ++ ret = nlsock_process_reply(nlsk, nomsg_reply_cb, NULL); ++ if (ret < 0) ++ goto out_free; ++ } ++ ++out_free: ++ for (i = 0; i < SSET_MAX_MSGS && msgbuffs[i]; i++) { ++ msgbuff_done(msgbuffs[i]); ++ free(msgbuffs[i]); ++ } ++ if (ret >= 0) ++ return ret; + return nlctx->exit_code ?: 75; + } +-- +2.26.2 + diff --git a/SOURCES/0026-ethtool-Improve-compatibility-between-netlink-and-io.patch b/SOURCES/0026-ethtool-Improve-compatibility-between-netlink-and-io.patch new file mode 100644 index 0000000..bb2e9da --- /dev/null +++ b/SOURCES/0026-ethtool-Improve-compatibility-between-netlink-and-io.patch @@ -0,0 +1,191 @@ +From f16bc54fe82b9129d6852273d02e044b9cb28789 Mon Sep 17 00:00:00 2001 +From: Ido Schimmel +Date: Mon, 9 Nov 2020 14:29:59 +0100 +Subject: [PATCH 26/26] ethtool: Improve compatibility between netlink and + ioctl interfaces + +With the ioctl interface, when autoneg is enabled, but without +specifying speed, duplex or link modes, the advertised link modes are +set to the supported link modes by the ethtool user space utility. + +This does not happen when using the netlink interface. Fix this +incompatibility problem by having ethtool query the supported link modes +from the kernel and advertise all the "real" ones when only "autoneg on" +is specified. + +Before: + +Settings for eth0: + Supported ports: [ TP ] + Supported link modes: 10baseT/Half 10baseT/Full + 100baseT/Half 100baseT/Full + 1000baseT/Full + Supported pause frame use: No + Supports auto-negotiation: Yes + Supported FEC modes: Not reported + Advertised link modes: 100baseT/Half 100baseT/Full + Advertised pause frame use: No + Advertised auto-negotiation: Yes + Advertised FEC modes: Not reported + Speed: 1000Mb/s + Duplex: Full + Auto-negotiation: on + Port: Twisted Pair + PHYAD: 0 + Transceiver: internal + MDI-X: off (auto) + Supports Wake-on: umbg + Wake-on: d + Current message level: 0x00000007 (7) + drv probe link + Link detected: yes + +After: + +Settings for eth0: + Supported ports: [ TP ] + Supported link modes: 10baseT/Half 10baseT/Full + 100baseT/Half 100baseT/Full + 1000baseT/Full + Supported pause frame use: No + Supports auto-negotiation: Yes + Supported FEC modes: Not reported + Advertised link modes: 10baseT/Half 10baseT/Full + 100baseT/Half 100baseT/Full + 1000baseT/Full + Advertised pause frame use: No + Advertised auto-negotiation: Yes + Advertised FEC modes: Not reported + Speed: 1000Mb/s + Duplex: Full + Auto-negotiation: on + Port: Twisted Pair + PHYAD: 0 + Transceiver: internal + MDI-X: on (auto) + Supports Wake-on: umbg + Wake-on: d + Current message level: 0x00000007 (7) + drv probe link + Link detected: yes + +Signed-off-by: Ido Schimmel +Signed-off-by: Michal Kubecek +(cherry picked from commit 124a3c06d1c34b125d84a9eb312fddd365bb7bf6) +--- + netlink/settings.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 92 insertions(+) + +diff --git a/netlink/settings.c b/netlink/settings.c +index fac192e2fbb7..01c1d38d323f 100644 +--- a/netlink/settings.c ++++ b/netlink/settings.c +@@ -1113,6 +1113,93 @@ static const struct param_parser sset_params[] = { + */ + #define SSET_MAX_MSGS 4 + ++static int linkmodes_reply_advert_all_cb(const struct nlmsghdr *nlhdr, ++ void *data) ++{ ++ const struct nlattr *tb[ETHTOOL_A_LINKMODES_MAX + 1] = {}; ++ DECLARE_ATTR_TB_INFO(tb); ++ struct nl_msg_buff *req_msgbuff = data; ++ const struct nlattr *ours_attr; ++ struct nlattr *req_bitset; ++ uint32_t *supported_modes; ++ unsigned int modes_count; ++ unsigned int i; ++ int ret; ++ ++ ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info); ++ if (ret < 0) ++ return MNL_CB_ERROR; ++ ours_attr = tb[ETHTOOL_A_LINKMODES_OURS]; ++ if (!ours_attr) ++ return MNL_CB_ERROR; ++ modes_count = bitset_get_count(tb[ETHTOOL_A_LINKMODES_OURS], &ret); ++ if (ret < 0) ++ return MNL_CB_ERROR; ++ supported_modes = get_compact_bitset_mask(tb[ETHTOOL_A_LINKMODES_OURS]); ++ if (!supported_modes) ++ return MNL_CB_ERROR; ++ ++ /* keep only "real" link modes */ ++ for (i = 0; i < modes_count; i++) ++ if (!lm_class_match(i, LM_CLASS_REAL)) ++ supported_modes[i / 32] &= ~((uint32_t)1 << (i % 32)); ++ ++ req_bitset = ethnla_nest_start(req_msgbuff, ETHTOOL_A_LINKMODES_OURS); ++ if (!req_bitset) ++ return MNL_CB_ERROR; ++ ++ if (ethnla_put_u32(req_msgbuff, ETHTOOL_A_BITSET_SIZE, modes_count) || ++ ethnla_put(req_msgbuff, ETHTOOL_A_BITSET_VALUE, ++ DIV_ROUND_UP(modes_count, 32) * sizeof(uint32_t), ++ supported_modes) || ++ ethnla_put(req_msgbuff, ETHTOOL_A_BITSET_MASK, ++ DIV_ROUND_UP(modes_count, 32) * sizeof(uint32_t), ++ supported_modes)) { ++ ethnla_nest_cancel(req_msgbuff, req_bitset); ++ return MNL_CB_ERROR; ++ } ++ ++ ethnla_nest_end(req_msgbuff, req_bitset); ++ return MNL_CB_OK; ++} ++ ++/* For compatibility reasons with ioctl-based ethtool, when "autoneg on" is ++ * specified without "advertise", "speed" and "duplex", we need to query the ++ * supported link modes from the kernel and advertise all the "real" ones. ++ */ ++static int nl_sset_compat_linkmodes(struct nl_context *nlctx, ++ struct nl_msg_buff *msgbuff) ++{ ++ const struct nlattr *tb[ETHTOOL_A_LINKMODES_MAX + 1] = {}; ++ DECLARE_ATTR_TB_INFO(tb); ++ struct nl_socket *nlsk = nlctx->ethnl_socket; ++ int ret; ++ ++ ret = mnl_attr_parse(msgbuff->nlhdr, GENL_HDRLEN, attr_cb, &tb_info); ++ if (ret < 0) ++ return ret; ++ if (!tb[ETHTOOL_A_LINKMODES_AUTONEG] || tb[ETHTOOL_A_LINKMODES_OURS] || ++ tb[ETHTOOL_A_LINKMODES_SPEED] || tb[ETHTOOL_A_LINKMODES_DUPLEX]) ++ return 0; ++ if (!mnl_attr_get_u8(tb[ETHTOOL_A_LINKMODES_AUTONEG])) ++ return 0; ++ ++ /* all conditions satisfied, create ETHTOOL_A_LINKMODES_OURS */ ++ if (netlink_cmd_check(nlctx->ctx, ETHTOOL_MSG_LINKMODES_GET, false) || ++ netlink_cmd_check(nlctx->ctx, ETHTOOL_MSG_LINKMODES_SET, false)) ++ return -EOPNOTSUPP; ++ ret = nlsock_prep_get_request(nlsk, ETHTOOL_MSG_LINKMODES_GET, ++ ETHTOOL_A_LINKMODES_HEADER, ++ ETHTOOL_FLAG_COMPACT_BITSETS); ++ if (ret < 0) ++ return ret; ++ ret = nlsock_sendmsg(nlsk, NULL); ++ if (ret < 0) ++ return ret; ++ return nlsock_process_reply(nlsk, linkmodes_reply_advert_all_cb, ++ msgbuff); ++} ++ + int nl_sset(struct cmd_context *ctx) + { + struct nl_msg_buff *msgbuffs[SSET_MAX_MSGS] = {}; +@@ -1134,6 +1221,11 @@ int nl_sset(struct cmd_context *ctx) + for (i = 0; i < SSET_MAX_MSGS && msgbuffs[i]; i++) { + struct nl_socket *nlsk = nlctx->ethnl_socket; + ++ if (msgbuffs[i]->genlhdr->cmd == ETHTOOL_MSG_LINKMODES_SET) { ++ ret = nl_sset_compat_linkmodes(nlctx, msgbuffs[i]); ++ if (ret < 0) ++ goto out_free; ++ } + ret = nlsock_sendmsg(nlsk, msgbuffs[i]); + if (ret < 0) + goto out_free; +-- +2.26.2 + diff --git a/SPECS/ethtool.spec b/SPECS/ethtool.spec index 6720646..874fba0 100644 --- a/SPECS/ethtool.spec +++ b/SPECS/ethtool.spec @@ -1,14 +1,40 @@ Name: ethtool Epoch: 2 -Version: 5.0 -Release: 2%{?dist} +Version: 5.8 +Release: 5%{?dist} Summary: Settings tool for Ethernet NICs License: GPLv2 Group: Applications/System URL: https://www.kernel.org/pub/software/network/%{name}/ Source0: https://www.kernel.org/pub/software/network/%{name}/%{name}-%{version}.tar.xz +Patch1: 0001-netlink-Fix-the-condition-for-displaying-actual-chan.patch +Patch2: 0002-netlink-Print-and-return-an-error-when-features-were.patch +Patch3: 0003-netlink-get-rid-of-signed-unsigned-comparison-warnin.patch +Patch4: 0004-ioctl-check-presence-of-eeprom-length-argument-prope.patch +Patch5: 0005-ioctl-prevent-argc-underflow-in-do_perqueue.patch +Patch6: 0006-ioctl-make-argc-counters-unsigned.patch +Patch7: 0007-ioctl-get-rid-of-signed-unsigned-comparison-warnings.patch +Patch8: 0008-get-rid-of-signed-unsigned-comparison-warnings-in-re.patch +Patch9: 0009-settings-simplify-link_mode_info-initializers.patch +Patch10: 0010-ioctl-convert-cmdline_info-arrays-to-named-initializ.patch +Patch11: 0011-build-add-Wextra-to-default-CFLAGS.patch +Patch12: 0012-ioctl-only-memset-non-NULL-link-settings.patch +Patch13: 0013-netlink-mark-unused-function-parameters-of-non-netli.patch +Patch14: 0014-update-UAPI-header-copies.patch +Patch15: 0015-update-link-mode-tables.patch +Patch16: 0016-netlink-return-ENOMEM-when-calloc-fails.patch +Patch17: 0017-netlink-fix-memory-leak.patch +Patch18: 0018-fix-memory-leaks-in-do_sfeatures.patch +Patch19: 0019-netlink-fix-copy-paste-error-in-rtm_link_summary.patch +Patch20: 0020-uapi-linux-update-kernel-UAPI-header-files.patch +Patch21: 0021-netlink-settings-expand-linkstate_reply_cb-to-suppor.patch +Patch22: 0022-netlink-prepare-for-more-per-op-info.patch +Patch23: 0023-netlink-fix-use-after-free-in-netlink_run_handler.patch +Patch24: 0024-netlink-fix-leaked-instances-of-struct-nl_socket.patch +Patch25: 0025-netlink-do-not-send-messages-and-process-replies-in-.patch +Patch26: 0026-ethtool-Improve-compatibility-between-netlink-and-io.patch +BuildRequires: libmnl-devel Conflicts: filesystem < 3 -Patch0: 0001-ethtool-Add-support-for-200Gbps-50Gbps-per-lane-link.patch %description This utility allows querying and changing settings such as speed, @@ -17,7 +43,32 @@ network devices, especially of Ethernet devices. %prep %setup -q -%patch0 -p1 +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 +%patch6 -p1 +%patch7 -p1 +%patch8 -p1 +%patch9 -p1 +%patch10 -p1 +%patch11 -p1 +%patch12 -p1 +%patch13 -p1 +%patch14 -p1 +%patch15 -p1 +%patch16 -p1 +%patch17 -p1 +%patch18 -p1 +%patch19 -p1 +%patch20 -p1 +%patch21 -p1 +%patch22 -p1 +%patch23 -p1 +%patch24 -p1 +%patch25 -p1 +%patch26 -p1 %build %configure @@ -31,8 +82,24 @@ make DESTDIR=%{buildroot} INSTALL='install -p' install %doc AUTHORS ChangeLog* NEWS README %{_sbindir}/%{name} %{_mandir}/man8/%{name}.8* +%{_datadir}/bash-completion/completions/ethtool %changelog +* Thu Nov 12 2020 Ivan Vecera - 2:5.8-5 +- Fixed a regression + +* Fri Nov 06 2020 Ivan Vecera - 2:5.8-4 +- Added support for extended link state reporting + +* Fri Sep 25 2020 Ivan Vecera - 2:5.8-3 +- Fixed memory leak + +* Thu Sep 24 2020 Ivan Vecera - 2:5.8-2 +- Add post-5.8 bugfixes + +* Tue Sep 15 2020 Ivan Vecera - 2:5.8-1 +- Update to 5.8 (#1878826) + * Thu May 16 2019 Ivan Vecera - 2:5.0-2 - Added support for 200Gbps (50Gbps/lane) link mode