net/sched: cls_route: make netlink errors meaningful
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>
This commit is contained in:
parent
e2f2fb3c35
commit
ef765c2587
@ -375,9 +375,9 @@ out:
|
||||
|
||||
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,
|
||||
@ -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) {
|
||||
@ -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;
|
||||
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user