import ethtool-5.8-5.el8
This commit is contained in:
parent
328bbedcd4
commit
bf18d6f3bb
117
SOURCES/0020-uapi-linux-update-kernel-UAPI-header-files.patch
Normal file
117
SOURCES/0020-uapi-linux-update-kernel-UAPI-header-files.patch
Normal file
@ -0,0 +1,117 @@
|
||||
From 8fa6c3a1bc2536816e961a4ef865c67218683bf2 Mon Sep 17 00:00:00 2001
|
||||
From: Amit Cohen <amitc@mellanox.com>
|
||||
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 <amitc@mellanox.com>
|
||||
Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
|
||||
(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
|
||||
|
@ -0,0 +1,187 @@
|
||||
From abc33073ed6d4528d3c951cc719a155a6e1178cd Mon Sep 17 00:00:00 2001
|
||||
From: Amit Cohen <amitc@mellanox.com>
|
||||
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 <amitc@mellanox.com>
|
||||
Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
|
||||
(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
|
||||
|
126
SOURCES/0022-netlink-prepare-for-more-per-op-info.patch
Normal file
126
SOURCES/0022-netlink-prepare-for-more-per-op-info.patch
Normal file
@ -0,0 +1,126 @@
|
||||
From 15e57173470b0929fd649bc7b0376d41c786ddbe Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Kicinski <kuba@kernel.org>
|
||||
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 <kuba@kernel.org>
|
||||
Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
|
||||
(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
|
||||
|
@ -0,0 +1,53 @@
|
||||
From ef1675823905ff09cb5e551700a124d0133648b7 Mon Sep 17 00:00:00 2001
|
||||
From: Michal Kubecek <mkubecek@suse.cz>
|
||||
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 <mkubecek@suse.cz>
|
||||
(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
|
||||
|
@ -0,0 +1,64 @@
|
||||
From 5fad40a007b61092161d1e4fd0ffbbc3e7b8ba6c Mon Sep 17 00:00:00 2001
|
||||
From: Michal Kubecek <mkubecek@suse.cz>
|
||||
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 <mkubecek@suse.cz>
|
||||
(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
|
||||
|
@ -0,0 +1,301 @@
|
||||
From fc5f2a6bb2911a951bf5a1364dc5732e521d735a Mon Sep 17 00:00:00 2001
|
||||
From: Michal Kubecek <mkubecek@suse.cz>
|
||||
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 <mkubecek@suse.cz>
|
||||
(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
|
||||
|
@ -0,0 +1,191 @@
|
||||
From f16bc54fe82b9129d6852273d02e044b9cb28789 Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
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 <idosch@nvidia.com>
|
||||
Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
|
||||
(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
|
||||
|
@ -1,7 +1,7 @@
|
||||
Name: ethtool
|
||||
Epoch: 2
|
||||
Version: 5.8
|
||||
Release: 3%{?dist}
|
||||
Release: 5%{?dist}
|
||||
Summary: Settings tool for Ethernet NICs
|
||||
License: GPLv2
|
||||
Group: Applications/System
|
||||
@ -26,6 +26,13 @@ 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
|
||||
|
||||
@ -55,6 +62,13 @@ network devices, especially of Ethernet devices.
|
||||
%patch17 -p1
|
||||
%patch18 -p1
|
||||
%patch19 -p1
|
||||
%patch20 -p1
|
||||
%patch21 -p1
|
||||
%patch22 -p1
|
||||
%patch23 -p1
|
||||
%patch24 -p1
|
||||
%patch25 -p1
|
||||
%patch26 -p1
|
||||
|
||||
%build
|
||||
%configure
|
||||
@ -71,6 +85,12 @@ make DESTDIR=%{buildroot} INSTALL='install -p' install
|
||||
%{_datadir}/bash-completion/completions/ethtool
|
||||
|
||||
%changelog
|
||||
* Thu Nov 12 2020 Ivan Vecera <ivecera@redhat.com> - 2:5.8-5
|
||||
- Fixed a regression
|
||||
|
||||
* Fri Nov 06 2020 Ivan Vecera <ivecera@redhat.com> - 2:5.8-4
|
||||
- Added support for extended link state reporting
|
||||
|
||||
* Fri Sep 25 2020 Ivan Vecera <ivecera@redhat.com> - 2:5.8-3
|
||||
- Fixed memory leak
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user