net/sched: mqprio: refactor nlattr parsing to a separate function
[ 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>
This commit is contained in:
parent
7218974aba
commit
5523d2e319
@ -130,6 +130,67 @@ static int parse_attr(struct nlattr *tb[], int maxtype, struct nlattr *nla,
|
|||||||
return 0;
|
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,
|
static int mqprio_init(struct Qdisc *sch, struct nlattr *opt,
|
||||||
struct netlink_ext_ack *extack)
|
struct netlink_ext_ack *extack)
|
||||||
{
|
{
|
||||||
@ -139,9 +200,6 @@ static int mqprio_init(struct Qdisc *sch, struct nlattr *opt,
|
|||||||
struct Qdisc *qdisc;
|
struct Qdisc *qdisc;
|
||||||
int i, err = -EOPNOTSUPP;
|
int i, err = -EOPNOTSUPP;
|
||||||
struct tc_mqprio_qopt *qopt = NULL;
|
struct tc_mqprio_qopt *qopt = NULL;
|
||||||
struct nlattr *tb[TCA_MQPRIO_MAX + 1];
|
|
||||||
struct nlattr *attr;
|
|
||||||
int rem;
|
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
BUILD_BUG_ON(TC_MAX_QUEUE != TC_QOPT_MAX_QUEUE);
|
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));
|
len = nla_len(opt) - NLA_ALIGN(sizeof(*qopt));
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
err = parse_attr(tb, TCA_MQPRIO_MAX, opt, mqprio_policy,
|
err = mqprio_parse_nlattr(sch, qopt, opt);
|
||||||
sizeof(*qopt));
|
if (err)
|
||||||
if (err < 0)
|
|
||||||
return 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 */
|
/* pre-allocate qdisc, attachment can't fail */
|
||||||
|
Loading…
Reference in New Issue
Block a user