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] = {
|
static const struct nla_policy route4_policy[TCA_ROUTE4_MAX + 1] = {
|
||||||
[TCA_ROUTE4_CLASSID] = { .type = NLA_U32 },
|
[TCA_ROUTE4_CLASSID] = { .type = NLA_U32 },
|
||||||
[TCA_ROUTE4_TO] = { .type = NLA_U32 },
|
[TCA_ROUTE4_TO] = NLA_POLICY_MAX(NLA_U32, 0xFF),
|
||||||
[TCA_ROUTE4_FROM] = { .type = NLA_U32 },
|
[TCA_ROUTE4_FROM] = NLA_POLICY_MAX(NLA_U32, 0xFF),
|
||||||
[TCA_ROUTE4_IIF] = { .type = NLA_U32 },
|
[TCA_ROUTE4_IIF] = NLA_POLICY_MAX(NLA_U32, 0x7FFF),
|
||||||
};
|
};
|
||||||
|
|
||||||
static int route4_set_parms(struct net *net, struct tcf_proto *tp,
|
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;
|
return err;
|
||||||
|
|
||||||
if (tb[TCA_ROUTE4_TO]) {
|
if (tb[TCA_ROUTE4_TO]) {
|
||||||
if (new && handle & 0x8000)
|
if (new && handle & 0x8000) {
|
||||||
|
NL_SET_ERR_MSG(extack, "Invalid handle");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
}
|
||||||
to = nla_get_u32(tb[TCA_ROUTE4_TO]);
|
to = nla_get_u32(tb[TCA_ROUTE4_TO]);
|
||||||
if (to > 0xFF)
|
|
||||||
return -EINVAL;
|
|
||||||
nhandle = to;
|
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_FROM]) {
|
||||||
if (tb[TCA_ROUTE4_IIF])
|
|
||||||
return -EINVAL;
|
|
||||||
id = nla_get_u32(tb[TCA_ROUTE4_FROM]);
|
id = nla_get_u32(tb[TCA_ROUTE4_FROM]);
|
||||||
if (id > 0xFF)
|
|
||||||
return -EINVAL;
|
|
||||||
nhandle |= id << 16;
|
nhandle |= id << 16;
|
||||||
} else if (tb[TCA_ROUTE4_IIF]) {
|
} else if (tb[TCA_ROUTE4_IIF]) {
|
||||||
id = nla_get_u32(tb[TCA_ROUTE4_IIF]);
|
id = nla_get_u32(tb[TCA_ROUTE4_IIF]);
|
||||||
if (id > 0x7FFF)
|
|
||||||
return -EINVAL;
|
|
||||||
nhandle |= (id | 0x8000) << 16;
|
nhandle |= (id | 0x8000) << 16;
|
||||||
} else
|
} else
|
||||||
nhandle |= 0xFFFF << 16;
|
nhandle |= 0xFFFF << 16;
|
||||||
|
|
||||||
if (handle && new) {
|
if (handle && new) {
|
||||||
nhandle |= handle & 0x7F00;
|
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;
|
return -EINVAL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!nhandle) {
|
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 __rcu **fp;
|
||||||
struct route4_filter *fold, *f1, *pfp, *f = NULL;
|
struct route4_filter *fold, *f1, *pfp, *f = NULL;
|
||||||
struct route4_bucket *b;
|
struct route4_bucket *b;
|
||||||
struct nlattr *opt = tca[TCA_OPTIONS];
|
|
||||||
struct nlattr *tb[TCA_ROUTE4_MAX + 1];
|
struct nlattr *tb[TCA_ROUTE4_MAX + 1];
|
||||||
unsigned int h, th;
|
unsigned int h, th;
|
||||||
int err;
|
int err;
|
||||||
@ -489,10 +492,12 @@ static int route4_change(struct net *net, struct sk_buff *in_skb,
|
|||||||
return -EINVAL;
|
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;
|
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);
|
route4_policy, NULL);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
|
Loading…
Reference in New Issue
Block a user