diff --git a/ethtool-5.6.tar.sign b/ethtool-5.6.tar.sign deleted file mode 100644 index 71ff61e..0000000 --- a/ethtool-5.6.tar.sign +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN PGP SIGNATURE----- - -iQIzBAABCAAdFiEEzkpNCA8NME8juevdly1b9NxhOAYFAl66uwEACgkQly1b9Nxh -OAawuxAAiwkGrEX++L/hoNYXYRpz1+h2DQsO0tBDQuqCrCkuL+tIH9M3D5aVzesL -a3TopQTutuWcvTQ49wye6k0jF4rncE8s24WcCQYxi2Y9HNtEWjqigXkwP/GoLSCF -oO73p7gM3IGKpK9Cz5RAh3xbgtPrvBq7fmP93+f0mTiXiaUiw9WEq90XV8buLbP4 -JXcClnitFh5D8Cbv5s+vfvWEHWSjFUISaQBMdl5SKbZQT3nfzZR0AKiZPtt9QI4G -LqSIP18Ou/hBdstET2M0mdBEiM2oICnQ0cmjZIupBtYEAk3XwnebP3a5d4eNl0mL -Nlscw0gwDefAr7X9rrtQurFWaTjMHDDZ2LDEtFm6pYE9kxO6GGGGd5W2KziDHvLC -/2JfrQI+f6Z7ackPb3nfAYNvhaIQatBMK27371PwQYZ8e3ii0Sgi/t1jxvS+xejZ -TSXptwQoF2x2urfnwuowsHWWwzJEmqDYm1u662LfuJVYh4+3G587XRRte4bK+xaI -LClwO7zGh0al1RDxD4LaE7LZ6L5XqS2brFvWeoTKMhL2u6HhmZQgAlnIjPzImlz3 -egdAd+9mj3Vx/4KYYa4VUVMSUqm5C/99a7AUbSSJKRs6u1uqpjXUTodx0fhzqA7G -8Ub1Lh8yTXOI3PbUPspnmJTzc9p21inktLAU6oKsobFN9iV+aPI= -=cWjJ ------END PGP SIGNATURE----- diff --git a/ethtool-5.6.tar.xz b/ethtool-5.6.tar.xz deleted file mode 100644 index 7cdf7c4..0000000 --- a/ethtool-5.6.tar.xz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ca0f1b526dad5153f0aa0f1eb3c17c31770c75a74f70af622b1a83ae38043995 -size 281084 diff --git a/ethtool-5.7.tar.sign b/ethtool-5.7.tar.sign new file mode 100644 index 0000000..2be1f64 --- /dev/null +++ b/ethtool-5.7.tar.sign @@ -0,0 +1,16 @@ +-----BEGIN PGP SIGNATURE----- + +iQIzBAABCAAdFiEEzkpNCA8NME8juevdly1b9NxhOAYFAl7ZOvwACgkQly1b9Nxh +OAaFyQ//cSW86pi2Ii06dK83dA+dsvHCApoUcxOS1UNuXfdUoOxQQzxgR7uU0i98 +SbZJvSTSGxR3h1wsqNFrTxtYw9xbFLC3u+8otUJbbqatbVaT8DlB84v4UklcBsCE +if1CuYzCJEBUjCKneXL/WAET03uxV0RkKEgjcrXRma0JTYB0+5JW//7W2cKLFn2B +iCEWU65G9hR73nafUQJ1vypgTz5e1eMHl9FfXJNjqScHeAwJq9aGUePal8Mkfr80 +ttb0yV48uw13j46Zj+w/QrurQPLNHAhUme2mHIwIly510rX6UZlylMBaTy0WDvGR +zg394CmyR9XvddIkTS+lQHBrAUdhA4xtEpUasTq4dWp6I/Q8xIg1S04TDLNeoznr +PTYLuGJAx+fuB6SaGSIAeClG++OEQzLeJQxrI9v3H3iLzqJpPZzchWWVC8QoTt8m +vQraqxXtUkqrosIinAL1kIjj508N706+7bTZA+ke8oRoQC5/KeRIjwhLk6+kthzo +vYOe/PKHU7o8RWoCERcj6LRWea6m6XaeNQEoMv2e7xEz6tKrRUdmlRSUbsIXWX7b +XhVgrBM4EHmW1oPkNhLLdG0i0eyXYF0cyBi13yfO0+suPdY7B9oXWdT/uZv48Lfj +YRUSpHqqb7aQxAZd4FysivXc+F7LEJKe4gPfV/4z8BaMgd6wZdI= +=yuDM +-----END PGP SIGNATURE----- diff --git a/ethtool-5.7.tar.xz b/ethtool-5.7.tar.xz new file mode 100644 index 0000000..4180cc5 --- /dev/null +++ b/ethtool-5.7.tar.xz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:724eb8bd3c3a389fe285735959a1902fbd9310624656ad3220c5f23df1053c39 +size 283048 diff --git a/ethtool.changes b/ethtool.changes index 1b2bd3c..ec7d2bd 100644 --- a/ethtool.changes +++ b/ethtool.changes @@ -1,3 +1,22 @@ +------------------------------------------------------------------- +Sun Jun 7 19:55:27 UTC 2020 - Michal Kubecek + +- update to new upstream release 5.7 + * support LLRS (Low Latency Reed Solomon) FEC mode + * accept long legacy flag names (-K) + * support for newer SFF-8024 compliance codes + * report transceiver when reported by kernel + * improve fallback from netlink to ioctl and error messages +- drop patches present in 5.7 release: + netlink-show-netlink-error-even-without-extack.patch + features-accept-long-legacy-flag-names-when-setting-.patch + refactor-interface-between-ioctl-and-netlink-code.patch + netlink-use-genetlink-ops-information-to-decide-abou.patch +- refresh + netlink-fix-build-warnings.patch +- fix cherry picked from upstream git: + netlink-fix-unwanted-switch-fall-through-in-family_i.patch + ------------------------------------------------------------------- Fri May 15 20:12:57 UTC 2020 - Michal Kubecek diff --git a/ethtool.spec b/ethtool.spec index c23514e..8154220 100644 --- a/ethtool.spec +++ b/ethtool.spec @@ -17,7 +17,7 @@ Name: ethtool -Version: 5.6 +Version: 5.7 Release: 0 Summary: Utility for examining and tuning Ethernet-based network interfaces License: GPL-2.0-only @@ -34,10 +34,7 @@ BuildRequires: xz BuildRequires: pkgconfig(libmnl) Patch1: netlink-fix-build-warnings.patch -Patch2: netlink-show-netlink-error-even-without-extack.patch -Patch3: features-accept-long-legacy-flag-names-when-setting-.patch -Patch4: refactor-interface-between-ioctl-and-netlink-code.patch -Patch5: netlink-use-genetlink-ops-information-to-decide-abou.patch +Patch2: netlink-fix-unwanted-switch-fall-through-in-family_i.patch %description Ethtool is a small utility for examining and tuning ethernet-based @@ -47,9 +44,6 @@ network interfaces. See the man page for more details. %setup -q %patch1 -p1 %patch2 -p1 -%patch3 -p1 -%patch4 -p1 -%patch5 -p1 %build export CFLAGS="%optflags -W -Wall -Wstrict-prototypes -Wformat-security -Wpointer-arith -Wno-missing-field-initializers" diff --git a/features-accept-long-legacy-flag-names-when-setting-.patch b/features-accept-long-legacy-flag-names-when-setting-.patch deleted file mode 100644 index 290de45..0000000 --- a/features-accept-long-legacy-flag-names-when-setting-.patch +++ /dev/null @@ -1,63 +0,0 @@ -From: Michal Kubecek -Date: Mon, 13 Apr 2020 11:46:42 +0200 -Subject: features: accept long legacy flag names when setting features -Patch-mainline: v5.7 -Git-commit: 4b1fa2c2d250441f83b90f9410cd6ce7d879c2fe - -The legacy feature flags have long names (e.g. "generic-receive-offload") -and short names (e.g. "gro"). While "ethtool -k" shows only long names, -"ethtool -K" accepts only short names. This is a bit confusing as users -have to resort to documentation to see what flag name to use; in -particular, if a legacy flag corresponds to only one actual kernel feature, -"ethtool -k" shows the output in the same form as if long flag name were -a kernel feature name but this name cannot be used to set the flag/feature. - -Accept both short and long legacy flag names in "ethool -K". - -Reported-by: Konstantin Kharlamov -Signed-off-by: Michal Kubecek ---- - ethtool.c | 17 ++++++++++++----- - 1 file changed, 12 insertions(+), 5 deletions(-) - ---- a/ethtool.c -+++ b/ethtool.c -@@ -2297,26 +2297,33 @@ static int do_sfeatures(struct cmd_context *ctx) - /* Generate cmdline_info for legacy flags and kernel-named - * features, and parse our arguments. - */ -- cmdline_features = calloc(ARRAY_SIZE(off_flag_def) + defs->n_features, -+ cmdline_features = calloc(2 * ARRAY_SIZE(off_flag_def) + -+ defs->n_features, - sizeof(cmdline_features[0])); - if (!cmdline_features) { - perror("Cannot parse arguments"); - rc = 1; - goto err; - } -- for (i = 0; i < ARRAY_SIZE(off_flag_def); i++) -+ j = 0; -+ for (i = 0; i < ARRAY_SIZE(off_flag_def); i++) { - flag_to_cmdline_info(off_flag_def[i].short_name, - off_flag_def[i].value, - &off_flags_wanted, &off_flags_mask, -- &cmdline_features[i]); -+ &cmdline_features[j++]); -+ flag_to_cmdline_info(off_flag_def[i].long_name, -+ off_flag_def[i].value, -+ &off_flags_wanted, &off_flags_mask, -+ &cmdline_features[j++]); -+ } - for (i = 0; i < defs->n_features; i++) - flag_to_cmdline_info( - defs->def[i].name, FEATURE_FIELD_FLAG(i), - &FEATURE_WORD(efeatures->features, i, requested), - &FEATURE_WORD(efeatures->features, i, valid), -- &cmdline_features[ARRAY_SIZE(off_flag_def) + i]); -+ &cmdline_features[j++]); - parse_generic_cmdline(ctx, &any_changed, cmdline_features, -- ARRAY_SIZE(off_flag_def) + defs->n_features); -+ 2 * ARRAY_SIZE(off_flag_def) + defs->n_features); - free(cmdline_features); - - if (!any_changed) { diff --git a/netlink-fix-build-warnings.patch b/netlink-fix-build-warnings.patch index e20dadd..cd1c379 100644 --- a/netlink-fix-build-warnings.patch +++ b/netlink-fix-build-warnings.patch @@ -1,21 +1,21 @@ From: Michal Kubecek -Date: Tue, 12 May 2020 22:10:19 +0200 +Date: Fri, 29 May 2020 01:21:12 +0200 Subject: netlink: fix build warnings -Patch-mainline: Not yet, going to submit for 5.7 cycle +Patch-mainline: v5.8 +Git-commit: a9b8685859075771887aad0328246e0afa089caf Depending on compiler version and options, some of these warnings may result in build failure. - gcc 4.8 wants __KERNEL_DIV_ROUND_UP defined before including ethtool.h - avoid pointer arithmetic on void * -- do not use printf(s) if string is not a string literal Signed-off-by: Michal Kubecek +Tested-by: Heiko Thiery --- netlink/desc-ethtool.c | 2 +- netlink/parser.c | 2 +- - netlink/settings.c | 2 +- - 3 files changed, 3 insertions(+), 3 deletions(-) + 2 files changed, 2 insertions(+), 2 deletions(-) --- a/netlink/desc-ethtool.c +++ b/netlink/desc-ethtool.c @@ -41,14 +41,3 @@ Signed-off-by: Michal Kubecek ret = parser->handler(nlctx, parser->type, parser->handler_data, msgbuff, param_dest); if (ret < 0) ---- a/netlink/settings.c -+++ b/netlink/settings.c -@@ -375,7 +375,7 @@ static int dump_link_modes(struct nl_context *nlctx, - after: - if (first && if_none) - printf("%s", if_none); -- printf(after); -+ fputs(after, stdout); - - return 0; - err: diff --git a/netlink-fix-unwanted-switch-fall-through-in-family_i.patch b/netlink-fix-unwanted-switch-fall-through-in-family_i.patch new file mode 100644 index 0000000..57cd23b --- /dev/null +++ b/netlink-fix-unwanted-switch-fall-through-in-family_i.patch @@ -0,0 +1,26 @@ +From: Michal Kubecek +Date: Sun, 7 Jun 2020 21:32:50 +0200 +Subject: netlink: fix unwanted switch fall through in family_info_cb() +Patch-mainline: v5.8 +Git-commit: c07ea9e10498a09a08cc9b507704471d4d7f505b + +Recently added switch branch for CTRL_ATTR_OPS in family_info_cb() is +missing final break statement so that it will fall through into +CTRL_ATTR_MCAST_GROUPS. + +Fixes: 6c19c0d559c8 ("netlink: use genetlink ops information to decide about fallback") +Signed-off-by: Michal Kubecek +--- + netlink/netlink.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/netlink/netlink.c ++++ b/netlink/netlink.c +@@ -211,6 +211,7 @@ static int family_info_cb(const struct nlmsghdr *nlhdr, void *data) + ret = genl_read_ops(nlctx, attr); + if (ret < 0) + return MNL_CB_ERROR; ++ break; + case CTRL_ATTR_MCAST_GROUPS: + find_mc_group(nlctx, attr); + break; diff --git a/netlink-show-netlink-error-even-without-extack.patch b/netlink-show-netlink-error-even-without-extack.patch deleted file mode 100644 index 515ceac..0000000 --- a/netlink-show-netlink-error-even-without-extack.patch +++ /dev/null @@ -1,87 +0,0 @@ -From: Michal Kubecek -Date: Tue, 10 Mar 2020 13:24:55 +0100 -Subject: netlink: show netlink error even without extack -Patch-mainline: v5.7 -Git-commit: 684f3e6c31bd096ef50725267957e0423b7932c6 - -Even if the NLMSG_ERROR message has no extack (NLM_F_ACK_TLVS not set, i.e. -no error/warning message and bad attribute offset), we still want to -display the error code (unless suppressed) and, if pretty printing is -enabled, the embedded client message (if present). - -Fixes: 50efb3cdd2bb ("netlink: netlink socket wrapper and helpers") -Signed-off-by: Michal Kubecek ---- - netlink/nlsock.c | 37 +++++++++++++++++-------------------- - 1 file changed, 17 insertions(+), 20 deletions(-) - ---- a/netlink/nlsock.c -+++ b/netlink/nlsock.c -@@ -173,25 +173,25 @@ static int nlsock_process_ack(struct nlmsghdr *nlhdr, ssize_t len, - { - const struct nlattr *tb[NLMSGERR_ATTR_MAX + 1] = {}; - DECLARE_ATTR_TB_INFO(tb); -+ unsigned int err_offset = 0; - unsigned int tlv_offset; - struct nlmsgerr *nlerr; - bool silent; - -- if (len < NLMSG_HDRLEN + sizeof(*nlerr)) -+ if ((len < NLMSG_HDRLEN + sizeof(*nlerr)) || (len < nlhdr->nlmsg_len)) - return -EFAULT; - nlerr = mnl_nlmsg_get_payload(nlhdr); -- silent = (!(nlhdr->nlmsg_flags & NLM_F_ACK_TLVS) || -- suppress_nlerr >= 2 || -- (suppress_nlerr && nlerr->error == -EOPNOTSUPP)); -- if (silent) -- goto out; -+ silent = suppress_nlerr >= 2 || -+ (suppress_nlerr && nlerr->error == -EOPNOTSUPP); -+ if (silent || !(nlhdr->nlmsg_flags & NLM_F_ACK_TLVS)) -+ goto tlv_done; - - tlv_offset = sizeof(*nlerr); - if (!(nlhdr->nlmsg_flags & NLM_F_CAPPED)) - tlv_offset += MNL_ALIGN(mnl_nlmsg_get_payload_len(&nlerr->msg)); -- - if (mnl_attr_parse(nlhdr, tlv_offset, attr_cb, &tb_info) < 0) -- goto out; -+ goto tlv_done; -+ - if (tb[NLMSGERR_ATTR_MSG]) { - const char *msg = mnl_attr_get_str(tb[NLMSGERR_ATTR_MSG]); - -@@ -202,24 +202,21 @@ static int nlsock_process_ack(struct nlmsghdr *nlhdr, ssize_t len, - mnl_attr_get_u32(tb[NLMSGERR_ATTR_OFFS])); - fputc('\n', stderr); - } -+ if (tb[NLMSGERR_ATTR_OFFS]) -+ err_offset = mnl_attr_get_u32(tb[NLMSGERR_ATTR_OFFS]); - -- if (nlerr->error && pretty) { -- unsigned int err_offset = 0; -- -- if (tb[NLMSGERR_ATTR_OFFS]) -- err_offset = mnl_attr_get_u32(tb[NLMSGERR_ATTR_OFFS]); -+tlv_done: -+ if (nlerr->error && !silent) { -+ errno = -nlerr->error; -+ perror("netlink error"); -+ } -+ if (pretty && !(nlhdr->nlmsg_flags & NLM_F_CAPPED) && -+ nlhdr->nlmsg_len >= NLMSG_HDRLEN + nlerr->msg.nlmsg_len) { - fprintf(stderr, "offending message%s:\n", - err_offset ? " and attribute" : ""); - pretty_print_genlmsg(&nlerr->msg, ethnl_umsg_desc, - ethnl_umsg_n_desc, err_offset); - } -- --out: -- if (nlerr->error) { -- errno = -nlerr->error; -- if (!silent) -- perror("netlink error"); -- } - return nlerr->error; - } - diff --git a/netlink-use-genetlink-ops-information-to-decide-abou.patch b/netlink-use-genetlink-ops-information-to-decide-abou.patch deleted file mode 100644 index baa3ff9..0000000 --- a/netlink-use-genetlink-ops-information-to-decide-abou.patch +++ /dev/null @@ -1,335 +0,0 @@ -From: Michal Kubecek -Date: Mon, 13 Apr 2020 17:39:32 +0200 -Subject: netlink: use genetlink ops information to decide about fallback -Patch-mainline: v5.7 -Git-commit: 6c19c0d559c80824383c5f0e2dc229878d9b19f5 - -Currently ethtool falls back to ioctl when netlink socket initialization -fails or if netlink request fails with -EOPNOTSUPP (and we do not know that -request cannot possibly work via ioctl, e.g. because of wildcard device -name or device name longer than IFNAMSIZ). This logic has one problem: we -cannot distinguish if -EOPNOTSUPP error code means that subcommand as such -is not implemented in kernel or that it failed for some other reason (e.g. -specific combination of parameters is not supported by driver). If the -latter is the case, fallback to ioctl is pointless as the same request -would fail via ioctl as well. In some cases we can even get a duplicate -error message. - -Fortunately, genetlink provides information about supported family commands -in the form of CTRL_ATTR_OPS nested attribute. Parse this information when -available and use it to only fall back to ioctl only if kernel support for -netlink request as such is missing so that there is a chance that ioctl -request will work. In such case, do not send netlink request at all. - -Signed-off-by: Michal Kubecek ---- - netlink/netlink.c | 138 ++++++++++++++++++++++++++++++++++++--------- - netlink/netlink.h | 5 ++ - netlink/parser.c | 7 +++ - netlink/settings.c | 7 +++ - 4 files changed, 129 insertions(+), 28 deletions(-) - ---- a/netlink/netlink.c -+++ b/netlink/netlink.c -@@ -92,16 +92,88 @@ int get_dev_info(const struct nlattr *nest, int *ifindex, char *ifname) - return 0; - } - -+/** -+ * netlink_cmd_check() - check support for netlink command -+ * @ctx: ethtool command context -+ * @cmd: netlink command id -+ * @devname: device name from user -+ * @allow_wildcard: wildcard dumps supported -+ * -+ * Check if command @cmd is known to be unsupported based on ops information -+ * from genetlink family id request. Set nlctx->ioctl_fallback if ethtool -+ * should fall back to ioctl, i.e. when we do not know in advance that -+ * netlink request is supported. Set nlctx->wildcard_unsupported if "*" was -+ * used as device name but the request does not support wildcards (on either -+ * side). -+ * -+ * Return: true if we know the netlink request is not supported and should -+ * fail (and possibly fall back) without actually sending it to kernel. -+ */ -+bool netlink_cmd_check(struct cmd_context *ctx, unsigned int cmd, -+ bool allow_wildcard) -+{ -+ bool is_dump = !strcmp(ctx->devname, WILDCARD_DEVNAME); -+ uint32_t cap = is_dump ? GENL_CMD_CAP_DUMP : GENL_CMD_CAP_DO; -+ struct nl_context *nlctx = ctx->nlctx; -+ -+ if (is_dump && !allow_wildcard) { -+ nlctx->wildcard_unsupported = true; -+ return true; -+ } -+ if (!nlctx->ops_flags) { -+ nlctx->ioctl_fallback = true; -+ return false; -+ } -+ if (cmd > ETHTOOL_MSG_USER_MAX || !nlctx->ops_flags[cmd]) { -+ nlctx->ioctl_fallback = true; -+ return true; -+ } -+ -+ if (is_dump && !(nlctx->ops_flags[cmd] & GENL_CMD_CAP_DUMP)) -+ nlctx->wildcard_unsupported = true; -+ -+ return !(nlctx->ops_flags[cmd] & cap); -+} -+ - /* initialization */ - --struct fam_info { -- const char *fam_name; -- const char *grp_name; -- uint16_t fam_id; -- uint32_t grp_id; --}; -+static int genl_read_ops(struct nl_context *nlctx, -+ const struct nlattr *ops_attr) -+{ -+ struct nlattr *op_attr; -+ uint32_t *ops_flags; -+ int ret; -+ -+ ops_flags = calloc(__ETHTOOL_MSG_USER_CNT, sizeof(ops_flags[0])); -+ if (!ops_flags) -+ return -ENOMEM; -+ -+ mnl_attr_for_each_nested(op_attr, ops_attr) { -+ const struct nlattr *tb[CTRL_ATTR_OP_MAX + 1] = {}; -+ DECLARE_ATTR_TB_INFO(tb); -+ uint32_t op_id; -+ -+ ret = mnl_attr_parse_nested(op_attr, attr_cb, &tb_info); -+ if (ret < 0) -+ goto err; -+ -+ if (!tb[CTRL_ATTR_OP_ID] || !tb[CTRL_ATTR_OP_FLAGS]) -+ continue; -+ op_id = mnl_attr_get_u32(tb[CTRL_ATTR_OP_ID]); -+ if (op_id >= __ETHTOOL_MSG_USER_CNT) -+ continue; -+ -+ ops_flags[op_id] = mnl_attr_get_u32(tb[CTRL_ATTR_OP_FLAGS]); -+ } -+ -+ nlctx->ops_flags = ops_flags; -+ return 0; -+err: -+ free(ops_flags); -+ return ret; -+} - --static void find_mc_group(struct nlattr *nest, struct fam_info *info) -+static void find_mc_group(struct nl_context *nlctx, struct nlattr *nest) - { - const struct nlattr *grp_tb[CTRL_ATTR_MCAST_GRP_MAX + 1] = {}; - DECLARE_ATTR_TB_INFO(grp_tb); -@@ -116,9 +188,9 @@ static void find_mc_group(struct nlattr *nest, struct fam_info *info) - !grp_tb[CTRL_ATTR_MCAST_GRP_ID]) - continue; - if (strcmp(mnl_attr_get_str(grp_tb[CTRL_ATTR_MCAST_GRP_NAME]), -- info->grp_name)) -+ ETHTOOL_MCGRP_MONITOR_NAME)) - continue; -- info->grp_id = -+ nlctx->ethnl_mongrp = - mnl_attr_get_u32(grp_tb[CTRL_ATTR_MCAST_GRP_ID]); - return; - } -@@ -126,16 +198,21 @@ static void find_mc_group(struct nlattr *nest, struct fam_info *info) - - static int family_info_cb(const struct nlmsghdr *nlhdr, void *data) - { -- struct fam_info *info = data; -+ struct nl_context *nlctx = data; - struct nlattr *attr; -+ int ret; - - mnl_attr_for_each(attr, nlhdr, GENL_HDRLEN) { - switch (mnl_attr_get_type(attr)) { - case CTRL_ATTR_FAMILY_ID: -- info->fam_id = mnl_attr_get_u16(attr); -+ nlctx->ethnl_fam = mnl_attr_get_u16(attr); - break; -+ case CTRL_ATTR_OPS: -+ ret = genl_read_ops(nlctx, attr); -+ if (ret < 0) -+ return MNL_CB_ERROR; - case CTRL_ATTR_MCAST_GROUPS: -- find_mc_group(attr, info); -+ find_mc_group(nlctx, attr); - break; - } - } -@@ -144,41 +221,37 @@ static int family_info_cb(const struct nlmsghdr *nlhdr, void *data) - } - - #ifdef TEST_ETHTOOL --static int get_genl_family(struct nl_socket *nlsk, struct fam_info *info) -+static int get_genl_family(struct nl_context *nlctx, struct nl_socket *nlsk) - { - return 0; - } - #else --static int get_genl_family(struct nl_socket *nlsk, struct fam_info *info) -+static int get_genl_family(struct nl_context *nlctx, struct nl_socket *nlsk) - { - struct nl_msg_buff *msgbuff = &nlsk->msgbuff; - int ret; - -- nlsk->nlctx->suppress_nlerr = 2; -+ nlctx->suppress_nlerr = 2; - ret = __msg_init(msgbuff, GENL_ID_CTRL, CTRL_CMD_GETFAMILY, - NLM_F_REQUEST | NLM_F_ACK, 1); - if (ret < 0) - goto out; - ret = -EMSGSIZE; -- if (ethnla_put_strz(msgbuff, CTRL_ATTR_FAMILY_NAME, info->fam_name)) -+ if (ethnla_put_strz(msgbuff, CTRL_ATTR_FAMILY_NAME, ETHTOOL_GENL_NAME)) - goto out; - - nlsock_sendmsg(nlsk, NULL); -- nlsock_process_reply(nlsk, family_info_cb, info); -- ret = info->fam_id ? 0 : -EADDRNOTAVAIL; -+ nlsock_process_reply(nlsk, family_info_cb, nlctx); -+ ret = nlctx->ethnl_fam ? 0 : -EADDRNOTAVAIL; - - out: -- nlsk->nlctx->suppress_nlerr = 0; -+ nlctx->suppress_nlerr = 0; - return ret; - } - #endif - - int netlink_init(struct cmd_context *ctx) - { -- struct fam_info info = { -- .fam_name = ETHTOOL_GENL_NAME, -- .grp_name = ETHTOOL_MCGRP_MONITOR_NAME, -- }; - struct nl_context *nlctx; - int ret; - -@@ -189,11 +262,9 @@ int netlink_init(struct cmd_context *ctx) - ret = nlsock_init(nlctx, &nlctx->ethnl_socket, NETLINK_GENERIC); - if (ret < 0) - goto out_free; -- ret = get_genl_family(nlctx->ethnl_socket, &info); -+ ret = get_genl_family(nlctx, nlctx->ethnl_socket); - if (ret < 0) - goto out_nlsk; -- nlctx->ethnl_fam = info.fam_id; -- nlctx->ethnl_mongrp = info.grp_id; - - ctx->nlctx = nlctx; - return 0; -@@ -201,6 +272,7 @@ int netlink_init(struct cmd_context *ctx) - out_nlsk: - nlsock_done(nlctx->ethnl_socket); - out_free: -+ free(nlctx->ops_flags); - free(nlctx); - return ret; - } -@@ -210,6 +282,7 @@ static void netlink_done(struct cmd_context *ctx) - if (!ctx->nlctx) - return; - -+ free(ctx->nlctx->ops_flags); - free(ctx->nlctx); - ctx->nlctx = NULL; - cleanup_all_strings(); -@@ -228,6 +301,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); -+ struct nl_context *nlctx; - const char *reason; - int ret; - -@@ -245,12 +319,20 @@ void netlink_run_handler(struct cmd_context *ctx, nl_func_t nlfunc, - reason = "netlink interface initialization failed"; - goto no_support; - } -+ nlctx = ctx->nlctx; - - ret = nlfunc(ctx); - netlink_done(ctx); -- if (ret != -EOPNOTSUPP || no_fallback) -+ if (no_fallback || ret != -EOPNOTSUPP || !nlctx->ioctl_fallback) { -+ if (nlctx->wildcard_unsupported) -+ fprintf(stderr, "%s\n", -+ "subcommand does not support wildcard dump"); - exit(ret >= 0 ? ret : 1); -- reason = "kernel netlink support for subcommand missing"; -+ } -+ if (nlctx->wildcard_unsupported) -+ reason = "subcommand does not support wildcard dump"; -+ else -+ reason = "kernel netlink support for subcommand missing"; - - no_support: - if (no_fallback) { ---- a/netlink/netlink.h -+++ b/netlink/netlink.h -@@ -25,6 +25,7 @@ struct nl_context { - unsigned int suppress_nlerr; - uint16_t ethnl_fam; - uint32_t ethnl_mongrp; -+ uint32_t *ops_flags; - struct nl_socket *ethnl_socket; - struct nl_socket *ethnl2_socket; - struct nl_socket *rtnl_socket; -@@ -36,6 +37,8 @@ struct nl_context { - const char *param; - char **argp; - int argc; -+ bool ioctl_fallback; -+ bool wildcard_unsupported; - }; - - struct attr_tb_info { -@@ -50,6 +53,8 @@ int nomsg_reply_cb(const struct nlmsghdr *nlhdr, void *data); - int attr_cb(const struct nlattr *attr, void *data); - - int netlink_init(struct cmd_context *ctx); -+bool netlink_cmd_check(struct cmd_context *ctx, unsigned int cmd, -+ bool allow_wildcard); - const char *get_dev_name(const struct nlattr *nest); - int get_dev_info(const struct nlattr *nest, int *ifindex, char *ifname); - ---- a/netlink/parser.c -+++ b/netlink/parser.c -@@ -1023,6 +1023,13 @@ int nl_parser(struct nl_context *nlctx, const struct param_parser *params, - goto out_free; - } - -+ if (group_style == PARSER_GROUP_MSG) { -+ ret = -EOPNOTSUPP; -+ for (buff = buffs; buff; buff = buff->next) -+ 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; - ---- a/netlink/settings.c -+++ b/netlink/settings.c -@@ -726,6 +726,13 @@ int nl_gset(struct cmd_context *ctx) - struct nl_socket *nlsk = nlctx->ethnl_socket; - int ret; - -+ if (netlink_cmd_check(ctx, ETHTOOL_MSG_LINKMODES_GET, true) || -+ netlink_cmd_check(ctx, ETHTOOL_MSG_LINKINFO_GET, true) || -+ netlink_cmd_check(ctx, ETHTOOL_MSG_WOL_GET, true) || -+ netlink_cmd_check(ctx, ETHTOOL_MSG_DEBUG_GET, true) || -+ netlink_cmd_check(ctx, ETHTOOL_MSG_LINKSTATE_GET, true)) -+ return -EOPNOTSUPP; -+ - nlctx->suppress_nlerr = 1; - - ret = gset_request(nlsk, ETHTOOL_MSG_LINKMODES_GET, diff --git a/refactor-interface-between-ioctl-and-netlink-code.patch b/refactor-interface-between-ioctl-and-netlink-code.patch deleted file mode 100644 index 010d32c..0000000 --- a/refactor-interface-between-ioctl-and-netlink-code.patch +++ /dev/null @@ -1,271 +0,0 @@ -From: Michal Kubecek -Date: Mon, 13 Apr 2020 13:04:42 +0200 -Subject: refactor interface between ioctl and netlink code -Patch-mainline: v5.7 -Git-commit: ab88f37fa432eea925306b442ac283daf71d8791 - -Move netlink related code from main() to separate handlers in netlink code. -Improve the logic of fallback to ioctl and improve error messages when -fallback is not possible (e.g. wildcard device name or name longer than -IFNAMSIZ). Also handle the (theoretical for now) case when ioctl handler is -not available. - -Signed-off-by: Michal Kubecek ---- - ethtool.c | 51 +++++++++++----------------------------- - netlink/extapi.h | 14 +++++++---- - netlink/monitor.c | 15 +++++++++--- - netlink/netlink.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++- - netlink/netlink.h | 1 + - 5 files changed, 93 insertions(+), 47 deletions(-) - ---- a/ethtool.c -+++ b/ethtool.c -@@ -5164,7 +5164,7 @@ struct option { - const char *opts; - bool no_dev; - int (*func)(struct cmd_context *); -- int (*nlfunc)(struct cmd_context *); -+ nl_func_t nlfunc; - const char *help; - const char *xhelp; - }; -@@ -5738,6 +5738,11 @@ static int ioctl_init(struct cmd_context *ctx, bool no_dev) - ctx->fd = -1; - return 0; - } -+ if (strlen(ctx->devname) >= IFNAMSIZ) { -+ fprintf(stderr, "Device name longer than %u characters\n", -+ IFNAMSIZ - 1); -+ exit_bad_args(); -+ } - - /* Setup our control structures. */ - memset(&ctx->ifr, 0, sizeof(ctx->ifr)); -@@ -5757,9 +5762,9 @@ static int ioctl_init(struct cmd_context *ctx, bool no_dev) - - int main(int argc, char **argp) - { -- int (*nlfunc)(struct cmd_context *) = NULL; - int (*func)(struct cmd_context *); - struct cmd_context ctx = {}; -+ nl_func_t nlfunc = NULL; - bool no_dev; - int ret; - int k; -@@ -5782,19 +5787,12 @@ int main(int argc, char **argp) - argp += 2; - argc -= 2; - } --#ifdef ETHTOOL_ENABLE_NETLINK - if (*argp && !strcmp(*argp, "--monitor")) { -- if (netlink_init(&ctx)) { -- fprintf(stderr, -- "Option --monitor is only available with netlink.\n"); -- return 1; -- } else { -- ctx.argp = ++argp; -- ctx.argc = --argc; -- return nl_monitor(&ctx); -- } -+ ctx.argp = ++argp; -+ ctx.argc = --argc; -+ ret = nl_monitor(&ctx); -+ return ret ? 1 : 0; - } --#endif - - /* First argument must be either a valid option or a device - * name to get settings for (which we don't expect to begin -@@ -5819,40 +5817,17 @@ int main(int argc, char **argp) - no_dev = false; - - opt_found: -- if (nlfunc) { -- if (netlink_init(&ctx)) -- nlfunc = NULL; /* fallback to ioctl() */ -- } -- - if (!no_dev) { - ctx.devname = *argp++; - argc--; - -- /* netlink supports altnames, we will have to recheck against -- * IFNAMSIZ later in case of fallback to ioctl -- */ -- if (!ctx.devname || strlen(ctx.devname) >= ALTIFNAMSIZ) { -- netlink_done(&ctx); -+ if (!ctx.devname) - exit_bad_args(); -- } - } -- - ctx.argc = argc; - ctx.argp = argp; -+ netlink_run_handler(&ctx, nlfunc, !func); - -- if (nlfunc) { -- ret = nlfunc(&ctx); -- netlink_done(&ctx); -- if ((ret != -EOPNOTSUPP) || !func) -- return (ret >= 0) ? ret : 1; -- } -- -- if (ctx.devname && strlen(ctx.devname) >= IFNAMSIZ) { -- fprintf(stderr, -- "ethtool: device names longer than %u characters are only allowed with netlink\n", -- IFNAMSIZ - 1); -- exit_bad_args(); -- } - ret = ioctl_init(&ctx, no_dev); - if (ret) - return ret; ---- a/netlink/extapi.h -+++ b/netlink/extapi.h -@@ -10,10 +10,12 @@ - struct cmd_context; - struct nl_context; - -+typedef int (*nl_func_t)(struct cmd_context *); -+ - #ifdef ETHTOOL_ENABLE_NETLINK - --int netlink_init(struct cmd_context *ctx); --void netlink_done(struct cmd_context *ctx); -+void netlink_run_handler(struct cmd_context *ctx, nl_func_t nlfunc, -+ bool no_fallback); - - int nl_gset(struct cmd_context *ctx); - int nl_sset(struct cmd_context *ctx); -@@ -24,13 +26,15 @@ void nl_monitor_usage(void); - - #else /* ETHTOOL_ENABLE_NETLINK */ - --static inline int netlink_init(struct cmd_context *ctx maybe_unused) -+static inline void netlink_run_handler(struct cmd_context *ctx, -+ nl_func_t nlfunc, bool no_fallback) - { -- return -EOPNOTSUPP; - } - --static inline void netlink_done(struct cmd_context *ctx maybe_unused) -+static inline int nl_monitor(struct cmd_context *ctx) - { -+ fprintf(stderr, "Netlink not supported by ethtool, option --monitor unsupported.\n"); -+ return -EOPNOTSUPP; - } - - static inline void nl_monitor_usage(void) ---- a/netlink/monitor.c -+++ b/netlink/monitor.c -@@ -167,16 +167,25 @@ static int parse_monitor(struct cmd_context *ctx) - - int nl_monitor(struct cmd_context *ctx) - { -- struct nl_context *nlctx = ctx->nlctx; -- struct nl_socket *nlsk = nlctx->ethnl_socket; -- uint32_t grpid = nlctx->ethnl_mongrp; -+ struct nl_context *nlctx; -+ struct nl_socket *nlsk; -+ uint32_t grpid; - bool is_dev; - int ret; - -+ ret = netlink_init(ctx); -+ if (ret < 0) { -+ fprintf(stderr, "Netlink interface initialization failed, option --monitor not supported.\n"); -+ return ret; -+ } -+ nlctx = ctx->nlctx; -+ nlsk = nlctx->ethnl_socket; -+ grpid = nlctx->ethnl_mongrp; - if (!grpid) { - fprintf(stderr, "multicast group 'monitor' not found\n"); - return -EOPNOTSUPP; - } -+ - if (parse_monitor(ctx) < 0) - return 1; - is_dev = ctx->devname && strcmp(ctx->devname, WILDCARD_DEVNAME); ---- a/netlink/netlink.c -+++ b/netlink/netlink.c -@@ -205,7 +205,7 @@ out_free: - return ret; - } - --void netlink_done(struct cmd_context *ctx) -+static void netlink_done(struct cmd_context *ctx) - { - if (!ctx->nlctx) - return; -@@ -214,3 +214,60 @@ void netlink_done(struct cmd_context *ctx) - ctx->nlctx = NULL; - cleanup_all_strings(); - } -+ -+/** -+ * netlink_run_handler() - run netlink handler for subcommand -+ * @ctx: command context -+ * @nlfunc: subcommand netlink handler to call -+ * @no_fallback: there is no ioctl fallback handler -+ * -+ * This function returns only if ioctl() handler should be run as fallback. -+ * Otherwise it exits with appropriate return code. -+ */ -+void netlink_run_handler(struct cmd_context *ctx, nl_func_t nlfunc, -+ bool no_fallback) -+{ -+ bool wildcard = ctx->devname && !strcmp(ctx->devname, WILDCARD_DEVNAME); -+ const char *reason; -+ int ret; -+ -+ if (ctx->devname && strlen(ctx->devname) >= ALTIFNAMSIZ) { -+ fprintf(stderr, "device name '%s' longer than %u characters\n", -+ ctx->devname, ALTIFNAMSIZ - 1); -+ exit(1); -+ } -+ -+ if (!nlfunc) { -+ reason = "ethtool netlink support for subcommand missing"; -+ goto no_support; -+ } -+ if (netlink_init(ctx)) { -+ reason = "netlink interface initialization failed"; -+ goto no_support; -+ } -+ -+ ret = nlfunc(ctx); -+ netlink_done(ctx); -+ if (ret != -EOPNOTSUPP || no_fallback) -+ exit(ret >= 0 ? ret : 1); -+ reason = "kernel netlink support for subcommand missing"; -+ -+no_support: -+ if (no_fallback) { -+ fprintf(stderr, "%s, subcommand not supported by ioctl\n", -+ reason); -+ exit(1); -+ } -+ if (wildcard) { -+ fprintf(stderr, "%s, wildcard dump not supported\n", reason); -+ exit(1); -+ } -+ if (ctx->devname && strlen(ctx->devname) >= IFNAMSIZ) { -+ fprintf(stderr, -+ "%s, device name longer than %u not supported\n", -+ reason, IFNAMSIZ - 1); -+ exit(1); -+ } -+ -+ /* fallback to ioctl() */ -+} ---- a/netlink/netlink.h -+++ b/netlink/netlink.h -@@ -49,6 +49,7 @@ struct attr_tb_info { - int nomsg_reply_cb(const struct nlmsghdr *nlhdr, void *data); - int attr_cb(const struct nlattr *attr, void *data); - -+int netlink_init(struct cmd_context *ctx); - const char *get_dev_name(const struct nlattr *nest); - int get_dev_info(const struct nlattr *nest, int *ifindex, char *ifname); -