Skip to content

Commit

Permalink
net/sched: cls_route: make netlink errors meaningful
Browse files Browse the repository at this point in the history
Use netlink extended ack and parsing policies to return more meaningful
errors instead of the relying solely on errnos.

Reviewed-by: Victor Nogueira <victor@mojatatu.com>
Signed-off-by: Pedro Tammela <pctammela@mojatatu.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Pedro Tammela authored and David S. Miller committed Sep 13, 2023
1 parent e2f2fb3 commit ef765c2
Showing 1 changed file with 21 additions and 16 deletions.
37 changes: 21 additions & 16 deletions net/sched/cls_route.c
Original file line number Diff line number Diff line change
Expand Up @@ -375,9 +375,9 @@ static int route4_delete(struct tcf_proto *tp, void *arg, bool *last,

static const struct nla_policy route4_policy[TCA_ROUTE4_MAX + 1] = {
[TCA_ROUTE4_CLASSID] = { .type = NLA_U32 },
[TCA_ROUTE4_TO] = { .type = NLA_U32 },
[TCA_ROUTE4_FROM] = { .type = NLA_U32 },
[TCA_ROUTE4_IIF] = { .type = NLA_U32 },
[TCA_ROUTE4_TO] = NLA_POLICY_MAX(NLA_U32, 0xFF),
[TCA_ROUTE4_FROM] = NLA_POLICY_MAX(NLA_U32, 0xFF),
[TCA_ROUTE4_IIF] = NLA_POLICY_MAX(NLA_U32, 0x7FFF),
};

static int route4_set_parms(struct net *net, struct tcf_proto *tp,
Expand All @@ -397,33 +397,37 @@ static int route4_set_parms(struct net *net, struct tcf_proto *tp,
return err;

if (tb[TCA_ROUTE4_TO]) {
if (new && handle & 0x8000)
if (new && handle & 0x8000) {
NL_SET_ERR_MSG(extack, "Invalid handle");
return -EINVAL;
}
to = nla_get_u32(tb[TCA_ROUTE4_TO]);
if (to > 0xFF)
return -EINVAL;
nhandle = to;
}

if (tb[TCA_ROUTE4_FROM] && tb[TCA_ROUTE4_IIF]) {
NL_SET_ERR_MSG_ATTR(extack, tb[TCA_ROUTE4_FROM],
"'from' and 'fromif' are mutually exclusive");
return -EINVAL;
}

if (tb[TCA_ROUTE4_FROM]) {
if (tb[TCA_ROUTE4_IIF])
return -EINVAL;
id = nla_get_u32(tb[TCA_ROUTE4_FROM]);
if (id > 0xFF)
return -EINVAL;
nhandle |= id << 16;
} else if (tb[TCA_ROUTE4_IIF]) {
id = nla_get_u32(tb[TCA_ROUTE4_IIF]);
if (id > 0x7FFF)
return -EINVAL;
nhandle |= (id | 0x8000) << 16;
} else
nhandle |= 0xFFFF << 16;

if (handle && new) {
nhandle |= handle & 0x7F00;
if (nhandle != handle)
if (nhandle != handle) {
NL_SET_ERR_MSG_FMT(extack,
"Handle mismatch constructed: %x (expected: %x)",
handle, nhandle);
return -EINVAL;
}
}

if (!nhandle) {
Expand Down Expand Up @@ -478,7 +482,6 @@ static int route4_change(struct net *net, struct sk_buff *in_skb,
struct route4_filter __rcu **fp;
struct route4_filter *fold, *f1, *pfp, *f = NULL;
struct route4_bucket *b;
struct nlattr *opt = tca[TCA_OPTIONS];
struct nlattr *tb[TCA_ROUTE4_MAX + 1];
unsigned int h, th;
int err;
Expand All @@ -489,10 +492,12 @@ static int route4_change(struct net *net, struct sk_buff *in_skb,
return -EINVAL;
}

if (opt == NULL)
if (NL_REQ_ATTR_CHECK(extack, NULL, tca, TCA_OPTIONS)) {
NL_SET_ERR_MSG_MOD(extack, "Missing options");
return -EINVAL;
}

err = nla_parse_nested_deprecated(tb, TCA_ROUTE4_MAX, opt,
err = nla_parse_nested_deprecated(tb, TCA_ROUTE4_MAX, tca[TCA_OPTIONS],
route4_policy, NULL);
if (err < 0)
return err;
Expand Down

0 comments on commit ef765c2

Please sign in to comment.