Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ethtool: fix the check logic of at least one channel for RX/TX

The command "ethtool -L <intf> combined 0" may clean the RX/TX channel
count and skip the error path, since the attrs
tb[ETHTOOL_A_CHANNELS_RX_COUNT] and tb[ETHTOOL_A_CHANNELS_TX_COUNT]
are NULL in this case when recent ethtool is used.

Tested using ethtool v5.10.

Fixes: 7be92514b99c ("ethtool: check if there is at least one channel for TX/RX in the core")
Signed-off-by: Yinjun Zhang <yinjun.zhang@corigine.com>
Signed-off-by: Simon Horman <simon.horman@netronome.com>
Signed-off-by: Louis Peens <louis.peens@netronome.com>
Link: https://lore.kernel.org/r/20210225125102.23989-1-simon.horman@netronome.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Yinjun Zhang and committed by
Jakub Kicinski
a4fc088a eee7ede6

+13 -13
+13 -13
net/ethtool/channels.c
··· 116 116 struct ethtool_channels channels = {}; 117 117 struct ethnl_req_info req_info = {}; 118 118 struct nlattr **tb = info->attrs; 119 - const struct nlattr *err_attr; 119 + u32 err_attr, max_rx_in_use = 0; 120 120 const struct ethtool_ops *ops; 121 121 struct net_device *dev; 122 - u32 max_rx_in_use = 0; 123 122 int ret; 124 123 125 124 ret = ethnl_parse_header_dev_get(&req_info, ··· 156 157 157 158 /* ensure new channel counts are within limits */ 158 159 if (channels.rx_count > channels.max_rx) 159 - err_attr = tb[ETHTOOL_A_CHANNELS_RX_COUNT]; 160 + err_attr = ETHTOOL_A_CHANNELS_RX_COUNT; 160 161 else if (channels.tx_count > channels.max_tx) 161 - err_attr = tb[ETHTOOL_A_CHANNELS_TX_COUNT]; 162 + err_attr = ETHTOOL_A_CHANNELS_TX_COUNT; 162 163 else if (channels.other_count > channels.max_other) 163 - err_attr = tb[ETHTOOL_A_CHANNELS_OTHER_COUNT]; 164 + err_attr = ETHTOOL_A_CHANNELS_OTHER_COUNT; 164 165 else if (channels.combined_count > channels.max_combined) 165 - err_attr = tb[ETHTOOL_A_CHANNELS_COMBINED_COUNT]; 166 + err_attr = ETHTOOL_A_CHANNELS_COMBINED_COUNT; 166 167 else 167 - err_attr = NULL; 168 + err_attr = 0; 168 169 if (err_attr) { 169 170 ret = -EINVAL; 170 - NL_SET_ERR_MSG_ATTR(info->extack, err_attr, 171 + NL_SET_ERR_MSG_ATTR(info->extack, tb[err_attr], 171 172 "requested channel count exceeds maximum"); 172 173 goto out_ops; 173 174 } 174 175 175 176 /* ensure there is at least one RX and one TX channel */ 176 177 if (!channels.combined_count && !channels.rx_count) 177 - err_attr = tb[ETHTOOL_A_CHANNELS_RX_COUNT]; 178 + err_attr = ETHTOOL_A_CHANNELS_RX_COUNT; 178 179 else if (!channels.combined_count && !channels.tx_count) 179 - err_attr = tb[ETHTOOL_A_CHANNELS_TX_COUNT]; 180 + err_attr = ETHTOOL_A_CHANNELS_TX_COUNT; 180 181 else 181 - err_attr = NULL; 182 + err_attr = 0; 182 183 if (err_attr) { 183 184 if (mod_combined) 184 - err_attr = tb[ETHTOOL_A_CHANNELS_COMBINED_COUNT]; 185 + err_attr = ETHTOOL_A_CHANNELS_COMBINED_COUNT; 185 186 ret = -EINVAL; 186 - NL_SET_ERR_MSG_ATTR(info->extack, err_attr, "requested channel counts would result in no RX or TX channel being configured"); 187 + NL_SET_ERR_MSG_ATTR(info->extack, tb[err_attr], 188 + "requested channel counts would result in no RX or TX channel being configured"); 187 189 goto out_ops; 188 190 } 189 191