Commit 5bb7357f authored by David S. Miller's avatar David S. Miller

Merge branch 'cls_flower-Use-extack-in-fl_set_key'

Guillaume Nault says:

====================
cls_flower: Use extack in fl_set_key()

Add missing extack messages in fl_set_key(), so that users can get more
meaningfull error messages when netlink attributes are rejected.

Patch 1 also extends extack in tcf_change_indev() (in pkt_cls.h) since
this function is used by fl_set_key().
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 6a864730 e304e21a
...@@ -502,12 +502,16 @@ tcf_change_indev(struct net *net, struct nlattr *indev_tlv, ...@@ -502,12 +502,16 @@ tcf_change_indev(struct net *net, struct nlattr *indev_tlv,
struct net_device *dev; struct net_device *dev;
if (nla_strlcpy(indev, indev_tlv, IFNAMSIZ) >= IFNAMSIZ) { if (nla_strlcpy(indev, indev_tlv, IFNAMSIZ) >= IFNAMSIZ) {
NL_SET_ERR_MSG(extack, "Interface name too long"); NL_SET_ERR_MSG_ATTR(extack, indev_tlv,
"Interface name too long");
return -EINVAL; return -EINVAL;
} }
dev = __dev_get_by_name(net, indev); dev = __dev_get_by_name(net, indev);
if (!dev) if (!dev) {
NL_SET_ERR_MSG_ATTR(extack, indev_tlv,
"Network device not found");
return -ENODEV; return -ENODEV;
}
return dev->ifindex; return dev->ifindex;
} }
......
...@@ -738,7 +738,8 @@ static void fl_set_key_val(struct nlattr **tb, ...@@ -738,7 +738,8 @@ static void fl_set_key_val(struct nlattr **tb,
} }
static int fl_set_key_port_range(struct nlattr **tb, struct fl_flow_key *key, static int fl_set_key_port_range(struct nlattr **tb, struct fl_flow_key *key,
struct fl_flow_key *mask) struct fl_flow_key *mask,
struct netlink_ext_ack *extack)
{ {
fl_set_key_val(tb, &key->tp_range.tp_min.dst, fl_set_key_val(tb, &key->tp_range.tp_min.dst,
TCA_FLOWER_KEY_PORT_DST_MIN, &mask->tp_range.tp_min.dst, TCA_FLOWER_KEY_PORT_DST_MIN, &mask->tp_range.tp_min.dst,
...@@ -753,20 +754,30 @@ static int fl_set_key_port_range(struct nlattr **tb, struct fl_flow_key *key, ...@@ -753,20 +754,30 @@ static int fl_set_key_port_range(struct nlattr **tb, struct fl_flow_key *key,
TCA_FLOWER_KEY_PORT_SRC_MAX, &mask->tp_range.tp_max.src, TCA_FLOWER_KEY_PORT_SRC_MAX, &mask->tp_range.tp_max.src,
TCA_FLOWER_UNSPEC, sizeof(key->tp_range.tp_max.src)); TCA_FLOWER_UNSPEC, sizeof(key->tp_range.tp_max.src));
if ((mask->tp_range.tp_min.dst && mask->tp_range.tp_max.dst && if (mask->tp_range.tp_min.dst && mask->tp_range.tp_max.dst &&
htons(key->tp_range.tp_max.dst) <= htons(key->tp_range.tp_max.dst) <=
htons(key->tp_range.tp_min.dst)) || htons(key->tp_range.tp_min.dst)) {
(mask->tp_range.tp_min.src && mask->tp_range.tp_max.src && NL_SET_ERR_MSG_ATTR(extack,
htons(key->tp_range.tp_max.src) <= tb[TCA_FLOWER_KEY_PORT_DST_MIN],
htons(key->tp_range.tp_min.src))) "Invalid destination port range (min must be strictly smaller than max)");
return -EINVAL; return -EINVAL;
}
if (mask->tp_range.tp_min.src && mask->tp_range.tp_max.src &&
htons(key->tp_range.tp_max.src) <=
htons(key->tp_range.tp_min.src)) {
NL_SET_ERR_MSG_ATTR(extack,
tb[TCA_FLOWER_KEY_PORT_SRC_MIN],
"Invalid source port range (min must be strictly smaller than max)");
return -EINVAL;
}
return 0; return 0;
} }
static int fl_set_key_mpls(struct nlattr **tb, static int fl_set_key_mpls(struct nlattr **tb,
struct flow_dissector_key_mpls *key_val, struct flow_dissector_key_mpls *key_val,
struct flow_dissector_key_mpls *key_mask) struct flow_dissector_key_mpls *key_mask,
struct netlink_ext_ack *extack)
{ {
if (tb[TCA_FLOWER_KEY_MPLS_TTL]) { if (tb[TCA_FLOWER_KEY_MPLS_TTL]) {
key_val->mpls_ttl = nla_get_u8(tb[TCA_FLOWER_KEY_MPLS_TTL]); key_val->mpls_ttl = nla_get_u8(tb[TCA_FLOWER_KEY_MPLS_TTL]);
...@@ -775,24 +786,36 @@ static int fl_set_key_mpls(struct nlattr **tb, ...@@ -775,24 +786,36 @@ static int fl_set_key_mpls(struct nlattr **tb,
if (tb[TCA_FLOWER_KEY_MPLS_BOS]) { if (tb[TCA_FLOWER_KEY_MPLS_BOS]) {
u8 bos = nla_get_u8(tb[TCA_FLOWER_KEY_MPLS_BOS]); u8 bos = nla_get_u8(tb[TCA_FLOWER_KEY_MPLS_BOS]);
if (bos & ~MPLS_BOS_MASK) if (bos & ~MPLS_BOS_MASK) {
NL_SET_ERR_MSG_ATTR(extack,
tb[TCA_FLOWER_KEY_MPLS_BOS],
"Bottom Of Stack (BOS) must be 0 or 1");
return -EINVAL; return -EINVAL;
}
key_val->mpls_bos = bos; key_val->mpls_bos = bos;
key_mask->mpls_bos = MPLS_BOS_MASK; key_mask->mpls_bos = MPLS_BOS_MASK;
} }
if (tb[TCA_FLOWER_KEY_MPLS_TC]) { if (tb[TCA_FLOWER_KEY_MPLS_TC]) {
u8 tc = nla_get_u8(tb[TCA_FLOWER_KEY_MPLS_TC]); u8 tc = nla_get_u8(tb[TCA_FLOWER_KEY_MPLS_TC]);
if (tc & ~MPLS_TC_MASK) if (tc & ~MPLS_TC_MASK) {
NL_SET_ERR_MSG_ATTR(extack,
tb[TCA_FLOWER_KEY_MPLS_TC],
"Traffic Class (TC) must be between 0 and 7");
return -EINVAL; return -EINVAL;
}
key_val->mpls_tc = tc; key_val->mpls_tc = tc;
key_mask->mpls_tc = MPLS_TC_MASK; key_mask->mpls_tc = MPLS_TC_MASK;
} }
if (tb[TCA_FLOWER_KEY_MPLS_LABEL]) { if (tb[TCA_FLOWER_KEY_MPLS_LABEL]) {
u32 label = nla_get_u32(tb[TCA_FLOWER_KEY_MPLS_LABEL]); u32 label = nla_get_u32(tb[TCA_FLOWER_KEY_MPLS_LABEL]);
if (label & ~MPLS_LABEL_MASK) if (label & ~MPLS_LABEL_MASK) {
NL_SET_ERR_MSG_ATTR(extack,
tb[TCA_FLOWER_KEY_MPLS_LABEL],
"Label must be between 0 and 1048575");
return -EINVAL; return -EINVAL;
}
key_val->mpls_label = label; key_val->mpls_label = label;
key_mask->mpls_label = MPLS_LABEL_MASK; key_mask->mpls_label = MPLS_LABEL_MASK;
} }
...@@ -833,14 +856,16 @@ static void fl_set_key_flag(u32 flower_key, u32 flower_mask, ...@@ -833,14 +856,16 @@ static void fl_set_key_flag(u32 flower_key, u32 flower_mask,
} }
} }
static int fl_set_key_flags(struct nlattr **tb, static int fl_set_key_flags(struct nlattr **tb, u32 *flags_key,
u32 *flags_key, u32 *flags_mask) u32 *flags_mask, struct netlink_ext_ack *extack)
{ {
u32 key, mask; u32 key, mask;
/* mask is mandatory for flags */ /* mask is mandatory for flags */
if (!tb[TCA_FLOWER_KEY_FLAGS_MASK]) if (!tb[TCA_FLOWER_KEY_FLAGS_MASK]) {
NL_SET_ERR_MSG(extack, "Missing flags mask");
return -EINVAL; return -EINVAL;
}
key = be32_to_cpu(nla_get_u32(tb[TCA_FLOWER_KEY_FLAGS])); key = be32_to_cpu(nla_get_u32(tb[TCA_FLOWER_KEY_FLAGS]));
mask = be32_to_cpu(nla_get_u32(tb[TCA_FLOWER_KEY_FLAGS_MASK])); mask = be32_to_cpu(nla_get_u32(tb[TCA_FLOWER_KEY_FLAGS_MASK]));
...@@ -1364,7 +1389,7 @@ static int fl_set_key(struct net *net, struct nlattr **tb, ...@@ -1364,7 +1389,7 @@ static int fl_set_key(struct net *net, struct nlattr **tb,
sizeof(key->icmp.code)); sizeof(key->icmp.code));
} else if (key->basic.n_proto == htons(ETH_P_MPLS_UC) || } else if (key->basic.n_proto == htons(ETH_P_MPLS_UC) ||
key->basic.n_proto == htons(ETH_P_MPLS_MC)) { key->basic.n_proto == htons(ETH_P_MPLS_MC)) {
ret = fl_set_key_mpls(tb, &key->mpls, &mask->mpls); ret = fl_set_key_mpls(tb, &key->mpls, &mask->mpls, extack);
if (ret) if (ret)
return ret; return ret;
} else if (key->basic.n_proto == htons(ETH_P_ARP) || } else if (key->basic.n_proto == htons(ETH_P_ARP) ||
...@@ -1389,7 +1414,7 @@ static int fl_set_key(struct net *net, struct nlattr **tb, ...@@ -1389,7 +1414,7 @@ static int fl_set_key(struct net *net, struct nlattr **tb,
if (key->basic.ip_proto == IPPROTO_TCP || if (key->basic.ip_proto == IPPROTO_TCP ||
key->basic.ip_proto == IPPROTO_UDP || key->basic.ip_proto == IPPROTO_UDP ||
key->basic.ip_proto == IPPROTO_SCTP) { key->basic.ip_proto == IPPROTO_SCTP) {
ret = fl_set_key_port_range(tb, key, mask); ret = fl_set_key_port_range(tb, key, mask, extack);
if (ret) if (ret)
return ret; return ret;
} }
...@@ -1451,7 +1476,8 @@ static int fl_set_key(struct net *net, struct nlattr **tb, ...@@ -1451,7 +1476,8 @@ static int fl_set_key(struct net *net, struct nlattr **tb,
return ret; return ret;
if (tb[TCA_FLOWER_KEY_FLAGS]) if (tb[TCA_FLOWER_KEY_FLAGS])
ret = fl_set_key_flags(tb, &key->control.flags, &mask->control.flags); ret = fl_set_key_flags(tb, &key->control.flags,
&mask->control.flags, extack);
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment