net/sched: mqprio: refactor nlattr parsing to a separate function
authorVladimir Oltean <vladimir.oltean@nxp.com>
Sat, 4 Feb 2023 13:52:55 +0000 (15:52 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 3 Aug 2023 08:24:02 +0000 (10:24 +0200)
[ Upstream commit feb2cf3dcfb930aec2ca65c66d1365543d5ba943 ]

mqprio_init() is quite large and unwieldy to add more code to.
Split the netlink attribute parsing to a dedicated function.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
Reviewed-by: Simon Horman <simon.horman@corigine.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Stable-dep-of: 6c58c8816abb ("net/sched: mqprio: Add length check for TCA_MQPRIO_{MAX/MIN}_RATE64")
Signed-off-by: Sasha Levin <sashal@kernel.org>
net/sched/sch_mqprio.c

index 9f26fb7..166b226 100644 (file)
@@ -130,6 +130,67 @@ static int parse_attr(struct nlattr *tb[], int maxtype, struct nlattr *nla,
        return 0;
 }
 
+static int mqprio_parse_nlattr(struct Qdisc *sch, struct tc_mqprio_qopt *qopt,
+                              struct nlattr *opt)
+{
+       struct mqprio_sched *priv = qdisc_priv(sch);
+       struct nlattr *tb[TCA_MQPRIO_MAX + 1];
+       struct nlattr *attr;
+       int i, rem, err;
+
+       err = parse_attr(tb, TCA_MQPRIO_MAX, opt, mqprio_policy,
+                        sizeof(*qopt));
+       if (err < 0)
+               return err;
+
+       if (!qopt->hw)
+               return -EINVAL;
+
+       if (tb[TCA_MQPRIO_MODE]) {
+               priv->flags |= TC_MQPRIO_F_MODE;
+               priv->mode = *(u16 *)nla_data(tb[TCA_MQPRIO_MODE]);
+       }
+
+       if (tb[TCA_MQPRIO_SHAPER]) {
+               priv->flags |= TC_MQPRIO_F_SHAPER;
+               priv->shaper = *(u16 *)nla_data(tb[TCA_MQPRIO_SHAPER]);
+       }
+
+       if (tb[TCA_MQPRIO_MIN_RATE64]) {
+               if (priv->shaper != TC_MQPRIO_SHAPER_BW_RATE)
+                       return -EINVAL;
+               i = 0;
+               nla_for_each_nested(attr, tb[TCA_MQPRIO_MIN_RATE64],
+                                   rem) {
+                       if (nla_type(attr) != TCA_MQPRIO_MIN_RATE64)
+                               return -EINVAL;
+                       if (i >= qopt->num_tc)
+                               break;
+                       priv->min_rate[i] = *(u64 *)nla_data(attr);
+                       i++;
+               }
+               priv->flags |= TC_MQPRIO_F_MIN_RATE;
+       }
+
+       if (tb[TCA_MQPRIO_MAX_RATE64]) {
+               if (priv->shaper != TC_MQPRIO_SHAPER_BW_RATE)
+                       return -EINVAL;
+               i = 0;
+               nla_for_each_nested(attr, tb[TCA_MQPRIO_MAX_RATE64],
+                                   rem) {
+                       if (nla_type(attr) != TCA_MQPRIO_MAX_RATE64)
+                               return -EINVAL;
+                       if (i >= qopt->num_tc)
+                               break;
+                       priv->max_rate[i] = *(u64 *)nla_data(attr);
+                       i++;
+               }
+               priv->flags |= TC_MQPRIO_F_MAX_RATE;
+       }
+
+       return 0;
+}
+
 static int mqprio_init(struct Qdisc *sch, struct nlattr *opt,
                       struct netlink_ext_ack *extack)
 {
@@ -139,9 +200,6 @@ static int mqprio_init(struct Qdisc *sch, struct nlattr *opt,
        struct Qdisc *qdisc;
        int i, err = -EOPNOTSUPP;
        struct tc_mqprio_qopt *qopt = NULL;
-       struct nlattr *tb[TCA_MQPRIO_MAX + 1];
-       struct nlattr *attr;
-       int rem;
        int len;
 
        BUILD_BUG_ON(TC_MAX_QUEUE != TC_QOPT_MAX_QUEUE);
@@ -166,55 +224,9 @@ static int mqprio_init(struct Qdisc *sch, struct nlattr *opt,
 
        len = nla_len(opt) - NLA_ALIGN(sizeof(*qopt));
        if (len > 0) {
-               err = parse_attr(tb, TCA_MQPRIO_MAX, opt, mqprio_policy,
-                                sizeof(*qopt));
-               if (err < 0)
+               err = mqprio_parse_nlattr(sch, qopt, opt);
+               if (err)
                        return err;
-
-               if (!qopt->hw)
-                       return -EINVAL;
-
-               if (tb[TCA_MQPRIO_MODE]) {
-                       priv->flags |= TC_MQPRIO_F_MODE;
-                       priv->mode = *(u16 *)nla_data(tb[TCA_MQPRIO_MODE]);
-               }
-
-               if (tb[TCA_MQPRIO_SHAPER]) {
-                       priv->flags |= TC_MQPRIO_F_SHAPER;
-                       priv->shaper = *(u16 *)nla_data(tb[TCA_MQPRIO_SHAPER]);
-               }
-
-               if (tb[TCA_MQPRIO_MIN_RATE64]) {
-                       if (priv->shaper != TC_MQPRIO_SHAPER_BW_RATE)
-                               return -EINVAL;
-                       i = 0;
-                       nla_for_each_nested(attr, tb[TCA_MQPRIO_MIN_RATE64],
-                                           rem) {
-                               if (nla_type(attr) != TCA_MQPRIO_MIN_RATE64)
-                                       return -EINVAL;
-                               if (i >= qopt->num_tc)
-                                       break;
-                               priv->min_rate[i] = *(u64 *)nla_data(attr);
-                               i++;
-                       }
-                       priv->flags |= TC_MQPRIO_F_MIN_RATE;
-               }
-
-               if (tb[TCA_MQPRIO_MAX_RATE64]) {
-                       if (priv->shaper != TC_MQPRIO_SHAPER_BW_RATE)
-                               return -EINVAL;
-                       i = 0;
-                       nla_for_each_nested(attr, tb[TCA_MQPRIO_MAX_RATE64],
-                                           rem) {
-                               if (nla_type(attr) != TCA_MQPRIO_MAX_RATE64)
-                                       return -EINVAL;
-                               if (i >= qopt->num_tc)
-                                       break;
-                               priv->max_rate[i] = *(u64 *)nla_data(attr);
-                               i++;
-                       }
-                       priv->flags |= TC_MQPRIO_F_MAX_RATE;
-               }
        }
 
        /* pre-allocate qdisc, attachment can't fail */