]> git.ipfire.org Git - thirdparty/iproute2.git/commitdiff
devlink: Update TC bandwidth parsing
authorCarolina Jubran <cjubran@nvidia.com>
Mon, 28 Jul 2025 15:44:38 +0000 (18:44 +0300)
committerDavid Ahern <dsahern@kernel.org>
Mon, 28 Jul 2025 16:42:40 +0000 (16:42 +0000)
Kernel commit 1bbdb81a9836 ("devlink: Fix excessive stack usage in rate TC bandwidth parsing")
introduced a dedicated attribute set (DEVLINK_RATE_TC_ATTR_*) for entries nested
under DEVLINK_ATTR_RATE_TC_BWS.

Update the parser to reflect this change by validating the nested
attributes and sync the UAPI header to include the changes.

Fixes: c83d1477f8b2 ("Add support for 'tc-bw' attribute in devlink-rate")
Signed-off-by: Carolina Jubran <cjubran@nvidia.com>
Signed-off-by: David Ahern <dsahern@kernel.org>
devlink/devlink.c
include/uapi/linux/devlink.h

index fe0c364019315bc287d9f5f76762e337d3c1449e..171b85327be34b9d90dc3c9c49cc98f8f34e61af 100644 (file)
@@ -2773,8 +2773,8 @@ static void dl_opts_put(struct nlmsghdr *nlh, struct dl *dl)
                        nla_tc_bw_entry =
                                mnl_attr_nest_start(nlh,
                                                    DEVLINK_ATTR_RATE_TC_BWS);
-                       mnl_attr_put_u8(nlh, DEVLINK_ATTR_RATE_TC_INDEX, i);
-                       mnl_attr_put_u32(nlh, DEVLINK_ATTR_RATE_TC_BW,
+                       mnl_attr_put_u8(nlh, DEVLINK_RATE_TC_ATTR_INDEX, i);
+                       mnl_attr_put_u32(nlh, DEVLINK_RATE_TC_ATTR_BW,
                                         opts->rate_tc_bw[i]);
                        mnl_attr_nest_end(nlh, nla_tc_bw_entry);
                }
@@ -5467,20 +5467,43 @@ static char *port_rate_type_name(uint16_t type)
        }
 }
 
+static const enum mnl_attr_data_type
+rate_tc_bws_policy[DEVLINK_RATE_TC_ATTR_BW + 1] = {
+       [DEVLINK_RATE_TC_ATTR_INDEX] = MNL_TYPE_U8,
+       [DEVLINK_RATE_TC_ATTR_BW] = MNL_TYPE_U32,
+};
+
+static int rate_tc_bw_attr_cb(const struct nlattr *attr, void *data)
+{
+       const struct nlattr **tb = data;
+       int type;
+
+       if (mnl_attr_type_valid(attr, DEVLINK_RATE_TC_ATTR_MAX) < 0)
+               return MNL_CB_OK;
+
+       type = mnl_attr_get_type(attr);
+
+       if (mnl_attr_validate(attr, rate_tc_bws_policy[type]) < 0)
+               return MNL_CB_ERROR;
+
+       tb[type] = attr;
+       return MNL_CB_OK;
+}
+
 static int
 parse_rate_tc_bw(struct nlattr *nla_tc_bw, uint8_t *tc_index, uint32_t *tc_bw)
 {
-       struct nlattr *tb_tc_bw[DEVLINK_ATTR_MAX + 1] = {};
+       struct nlattr *tb_tc_bw[DEVLINK_RATE_TC_ATTR_MAX + 1] = {};
 
-       if (mnl_attr_parse_nested(nla_tc_bw, attr_cb, tb_tc_bw) != MNL_CB_OK)
+       if (mnl_attr_parse_nested(nla_tc_bw, rate_tc_bw_attr_cb, tb_tc_bw) != MNL_CB_OK)
                return MNL_CB_ERROR;
 
-       if (!tb_tc_bw[DEVLINK_ATTR_RATE_TC_INDEX] ||
-           !tb_tc_bw[DEVLINK_ATTR_RATE_TC_BW])
+       if (!tb_tc_bw[DEVLINK_RATE_TC_ATTR_INDEX] ||
+           !tb_tc_bw[DEVLINK_RATE_TC_ATTR_BW])
                return MNL_CB_ERROR;
 
-       *tc_index = mnl_attr_get_u8(tb_tc_bw[DEVLINK_ATTR_RATE_TC_INDEX]);
-       *tc_bw = mnl_attr_get_u32(tb_tc_bw[DEVLINK_ATTR_RATE_TC_BW]);
+       *tc_index = mnl_attr_get_u8(tb_tc_bw[DEVLINK_RATE_TC_ATTR_INDEX]);
+       *tc_bw = mnl_attr_get_u32(tb_tc_bw[DEVLINK_RATE_TC_ATTR_BW]);
 
        return MNL_CB_OK;
 }
index 78f505c1ff9308e156121cca49e2b322adc3272e..a89df2a7db026a62bf5ace5372ef32ce8162c543 100644 (file)
@@ -635,8 +635,6 @@ enum devlink_attr {
        DEVLINK_ATTR_REGION_DIRECT,             /* flag */
 
        DEVLINK_ATTR_RATE_TC_BWS,               /* nested */
-       DEVLINK_ATTR_RATE_TC_INDEX,             /* u8 */
-       DEVLINK_ATTR_RATE_TC_BW,                /* u32 */
 
        /* Add new attributes above here, update the spec in
         * Documentation/netlink/specs/devlink.yaml and re-generate
@@ -647,6 +645,15 @@ enum devlink_attr {
        DEVLINK_ATTR_MAX = __DEVLINK_ATTR_MAX - 1
 };
 
+enum devlink_rate_tc_attr {
+       DEVLINK_RATE_TC_ATTR_UNSPEC,
+       DEVLINK_RATE_TC_ATTR_INDEX,             /* u8 */
+       DEVLINK_RATE_TC_ATTR_BW,                /* u32 */
+
+       __DEVLINK_RATE_TC_ATTR_MAX,
+       DEVLINK_RATE_TC_ATTR_MAX = __DEVLINK_RATE_TC_ATTR_MAX - 1
+};
+
 /* Mapping between internal resource described by the field and system
  * structure
  */