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

Configure Feed

Select the types of activity you want to include in your feed.

ethtool: plca: fix plca enable data type while parsing the value

The ETHTOOL_A_PLCA_ENABLED data type is u8. But while parsing the
value from the attribute, nla_get_u32() is used in the plca_update_sint()
function instead of nla_get_u8(). So plca_cfg.enabled variable is updated
with some garbage value instead of 0 or 1 and always enables plca even
though plca is disabled through ethtool application. This bug has been
fixed by parsing the values based on the attributes type in the policy.

Fixes: 8580e16c28f3 ("net/ethtool: add netlink interface for the PLCA RS")
Signed-off-by: Parthiban Veerasooran <Parthiban.Veerasooran@microchip.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Link: https://lore.kernel.org/r/20230908044548.5878-1-Parthiban.Veerasooran@microchip.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Parthiban Veerasooran and committed by
Jakub Kicinski
8957261c eea03d18

+29 -16
+29 -16
net/ethtool/plca.c
··· 21 21 #define PLCA_REPDATA(__reply_base) \ 22 22 container_of(__reply_base, struct plca_reply_data, base) 23 23 24 - static void plca_update_sint(int *dst, const struct nlattr *attr, 25 - bool *mod) 26 - { 27 - if (!attr) 28 - return; 29 - 30 - *dst = nla_get_u32(attr); 31 - *mod = true; 32 - } 33 - 34 24 // PLCA get configuration message ------------------------------------------- // 35 25 36 26 const struct nla_policy ethnl_plca_get_cfg_policy[] = { 37 27 [ETHTOOL_A_PLCA_HEADER] = 38 28 NLA_POLICY_NESTED(ethnl_header_policy), 39 29 }; 30 + 31 + static void plca_update_sint(int *dst, struct nlattr **tb, u32 attrid, 32 + bool *mod) 33 + { 34 + const struct nlattr *attr = tb[attrid]; 35 + 36 + if (!attr || 37 + WARN_ON_ONCE(attrid >= ARRAY_SIZE(ethnl_plca_set_cfg_policy))) 38 + return; 39 + 40 + switch (ethnl_plca_set_cfg_policy[attrid].type) { 41 + case NLA_U8: 42 + *dst = nla_get_u8(attr); 43 + break; 44 + case NLA_U32: 45 + *dst = nla_get_u32(attr); 46 + break; 47 + default: 48 + WARN_ON_ONCE(1); 49 + } 50 + 51 + *mod = true; 52 + } 40 53 41 54 static int plca_get_cfg_prepare_data(const struct ethnl_req_info *req_base, 42 55 struct ethnl_reply_data *reply_base, ··· 157 144 return -EOPNOTSUPP; 158 145 159 146 memset(&plca_cfg, 0xff, sizeof(plca_cfg)); 160 - plca_update_sint(&plca_cfg.enabled, tb[ETHTOOL_A_PLCA_ENABLED], &mod); 161 - plca_update_sint(&plca_cfg.node_id, tb[ETHTOOL_A_PLCA_NODE_ID], &mod); 162 - plca_update_sint(&plca_cfg.node_cnt, tb[ETHTOOL_A_PLCA_NODE_CNT], &mod); 163 - plca_update_sint(&plca_cfg.to_tmr, tb[ETHTOOL_A_PLCA_TO_TMR], &mod); 164 - plca_update_sint(&plca_cfg.burst_cnt, tb[ETHTOOL_A_PLCA_BURST_CNT], 147 + plca_update_sint(&plca_cfg.enabled, tb, ETHTOOL_A_PLCA_ENABLED, &mod); 148 + plca_update_sint(&plca_cfg.node_id, tb, ETHTOOL_A_PLCA_NODE_ID, &mod); 149 + plca_update_sint(&plca_cfg.node_cnt, tb, ETHTOOL_A_PLCA_NODE_CNT, &mod); 150 + plca_update_sint(&plca_cfg.to_tmr, tb, ETHTOOL_A_PLCA_TO_TMR, &mod); 151 + plca_update_sint(&plca_cfg.burst_cnt, tb, ETHTOOL_A_PLCA_BURST_CNT, 165 152 &mod); 166 - plca_update_sint(&plca_cfg.burst_tmr, tb[ETHTOOL_A_PLCA_BURST_TMR], 153 + plca_update_sint(&plca_cfg.burst_tmr, tb, ETHTOOL_A_PLCA_BURST_TMR, 167 154 &mod); 168 155 if (!mod) 169 156 return 0;