]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
ethtool: rss: support setting hfunc via Netlink
authorJakub Kicinski <kuba@kernel.org>
Wed, 16 Jul 2025 00:03:25 +0000 (17:03 -0700)
committerJakub Kicinski <kuba@kernel.org>
Thu, 17 Jul 2025 23:13:58 +0000 (16:13 -0700)
Support setting RSS hash function / algo via ethtool Netlink.
Like IOCTL we don't validate that the function is within the
range known to the kernel. The drivers do a pretty good job
validating the inputs, and the IDs are technically "dynamically
queried" rather than part of uAPI.

Only change should be that in Netlink we don't support user
explicitly passing ETH_RSS_HASH_NO_CHANGE (0), if no change
is requested the attribute should be absent.

The ETH_RSS_HASH_NO_CHANGE is retained in driver-facing
API for consistency (not that I see a strong reason for it).

Reviewed-by: Gal Pressman <gal@nvidia.com>
Link: https://patch.msgid.link/20250716000331.1378807-6-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Documentation/netlink/specs/ethtool.yaml
Documentation/networking/ethtool-netlink.rst
net/ethtool/rss.c

index 1eca88a508a01093ec86851bf31cb88784406430..0d02d8342e4c5193359b95a8c208f8dd439ee7c3 100644 (file)
@@ -2654,6 +2654,7 @@ operations:
           attributes:
             - header
             - context
+            - hfunc
             - indir
     -
       name: rss-ntf
index 27db7540e60e9af74b546d3b802039847e33c717..f6e4439caa9474c66b432284701a3ef5ea1578ce 100644 (file)
@@ -1999,6 +1999,7 @@ Request contents:
 =====================================  ======  ==============================
   ``ETHTOOL_A_RSS_HEADER``             nested  request header
   ``ETHTOOL_A_RSS_CONTEXT``            u32     context number
+  ``ETHTOOL_A_RSS_HFUNC``              u32     RSS hash func
   ``ETHTOOL_A_RSS_INDIR``              binary  Indir table bytes
 =====================================  ======  ==============================
 
index c8db523671de1eeb96826b69c89ad05782fd017e..bc9025cfcf1c2c60f6363fdd50a714dffef679d6 100644 (file)
@@ -475,6 +475,7 @@ void ethtool_rss_notify(struct net_device *dev, u32 rss_context)
 const struct nla_policy ethnl_rss_set_policy[ETHTOOL_A_RSS_START_CONTEXT + 1] = {
        [ETHTOOL_A_RSS_HEADER] = NLA_POLICY_NESTED(ethnl_header_policy),
        [ETHTOOL_A_RSS_CONTEXT] = { .type = NLA_U32, },
+       [ETHTOOL_A_RSS_HFUNC] = NLA_POLICY_MIN(NLA_U32, 1),
        [ETHTOOL_A_RSS_INDIR] = { .type = NLA_BINARY, },
 };
 
@@ -489,6 +490,9 @@ ethnl_rss_set_validate(struct ethnl_req_info *req_info, struct genl_info *info)
        if (request->rss_context && !ops->create_rxfh_context)
                bad_attr = bad_attr ?: tb[ETHTOOL_A_RSS_CONTEXT];
 
+       if (request->rss_context && !ops->rxfh_per_ctx_key)
+               bad_attr = bad_attr ?: tb[ETHTOOL_A_RSS_HFUNC];
+
        if (bad_attr) {
                NL_SET_BAD_ATTR(info->extack, bad_attr);
                return -EOPNOTSUPP;
@@ -588,6 +592,8 @@ rss_set_ctx_update(struct ethtool_rxfh_context *ctx, struct nlattr **tb,
                        ethtool_rxfh_context_indir(ctx)[i] = rxfh->indir[i];
                ctx->indir_configured = !!nla_len(tb[ETHTOOL_A_RSS_INDIR]);
        }
+       if (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE)
+               ctx->hfunc = rxfh->hfunc;
 }
 
 static int
@@ -618,7 +624,11 @@ ethnl_rss_set(struct ethnl_req_info *req_info, struct genl_info *info)
                goto exit_clean_data;
        indir_mod = !!tb[ETHTOOL_A_RSS_INDIR];
 
-       rxfh.hfunc = ETH_RSS_HASH_NO_CHANGE;
+       rxfh.hfunc = data.hfunc;
+       ethnl_update_u8(&rxfh.hfunc, tb[ETHTOOL_A_RSS_HFUNC], &mod);
+       if (rxfh.hfunc == data.hfunc)
+               rxfh.hfunc = ETH_RSS_HASH_NO_CHANGE;
+
        rxfh.input_xfrm = RXH_XFRM_NO_CHANGE;
 
        mutex_lock(&dev->ethtool->rss_lock);