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

net: rss: fix reporting RXH_XFRM_NO_CHANGE as input_xfrm for contexts

Initializing input_xfrm to RXH_XFRM_NO_CHANGE in RSS contexts is
problematic. I think I did this to make it clear that the context
does not have its own settings applied. But unlike ETH_RSS_HASH_NO_CHANGE
which is zero, RXH_XFRM_NO_CHANGE is 0xff. We need to be careful
when reading the value back, and remember to treat 0xff as 0.

Remove the initialization and switch to storing 0. This lets us
also remove the workaround in ethnl_rss_set(). Get side does not
need any adjustments and context get no longer reports:

RSS input transformation:
symmetric-xor: on
symmetric-or-xor: on
Unknown bits in RSS input transformation: 0xfc

for NICs which don't support input_xfrm.

Remove the init of hfunc to ETH_RSS_HASH_NO_CHANGE while at it.
As already mentioned this is a noop since ETH_RSS_HASH_NO_CHANGE
is 0 and struct is zalloc'd. But as this fix exemplifies storing
NO_CHANGE as state is fragile.

This issue is implicitly caught by running our selftests because
YNL in selftests errors out on unknown bits.

Fixes: d3e2c7bab124 ("ethtool: rss: support setting input-xfrm via Netlink")
Link: https://patch.msgid.link/20260130190311.811129-1-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+2 -10
-3
net/ethtool/common.c
··· 862 862 ctx->key_off = key_off; 863 863 ctx->priv_size = ops->rxfh_priv_size; 864 864 865 - ctx->hfunc = ETH_RSS_HASH_NO_CHANGE; 866 - ctx->input_xfrm = RXH_XFRM_NO_CHANGE; 867 - 868 865 return ctx; 869 866 } 870 867
+2 -7
net/ethtool/rss.c
··· 824 824 static int 825 825 ethnl_rss_set(struct ethnl_req_info *req_info, struct genl_info *info) 826 826 { 827 - bool indir_reset = false, indir_mod, xfrm_sym = false; 828 827 struct rss_req_info *request = RSS_REQINFO(req_info); 828 + bool indir_reset = false, indir_mod, xfrm_sym; 829 829 struct ethtool_rxfh_context *ctx = NULL; 830 830 struct net_device *dev = req_info->dev; 831 831 bool mod = false, fields_mod = false; ··· 860 860 861 861 rxfh.input_xfrm = data.input_xfrm; 862 862 ethnl_update_u8(&rxfh.input_xfrm, tb[ETHTOOL_A_RSS_INPUT_XFRM], &mod); 863 - /* For drivers which don't support input_xfrm it will be set to 0xff 864 - * in the RSS context info. In all other case input_xfrm != 0 means 865 - * symmetric hashing is requested. 866 - */ 867 - if (!request->rss_context || ops->rxfh_per_ctx_key) 868 - xfrm_sym = rxfh.input_xfrm || data.input_xfrm; 863 + xfrm_sym = rxfh.input_xfrm || data.input_xfrm; 869 864 if (rxfh.input_xfrm == data.input_xfrm) 870 865 rxfh.input_xfrm = RXH_XFRM_NO_CHANGE; 871 866