提交 2ac95dfe 编写于 作者: N Nikolay Aleksandrov 提交者: David S. Miller

net: bridge: mdb: use extack in br_mdb_parse()

We can drop the pr_info() calls and just use extack to return a
meaningful error to user-space when br_mdb_parse() fails.
Signed-off-by: NNikolay Aleksandrov <nikolay@nvidia.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 35c52c5c
...@@ -629,33 +629,50 @@ void br_rtr_notify(struct net_device *dev, struct net_bridge_port *port, ...@@ -629,33 +629,50 @@ void br_rtr_notify(struct net_device *dev, struct net_bridge_port *port,
rtnl_set_sk_err(net, RTNLGRP_MDB, err); rtnl_set_sk_err(net, RTNLGRP_MDB, err);
} }
static bool is_valid_mdb_entry(struct br_mdb_entry *entry) static bool is_valid_mdb_entry(struct br_mdb_entry *entry,
struct netlink_ext_ack *extack)
{ {
if (entry->ifindex == 0) if (entry->ifindex == 0) {
NL_SET_ERR_MSG_MOD(extack, "Zero entry ifindex is not allowed");
return false; return false;
}
if (entry->addr.proto == htons(ETH_P_IP)) { if (entry->addr.proto == htons(ETH_P_IP)) {
if (!ipv4_is_multicast(entry->addr.u.ip4)) if (!ipv4_is_multicast(entry->addr.u.ip4)) {
NL_SET_ERR_MSG_MOD(extack, "IPv4 entry group address is not multicast");
return false; return false;
if (ipv4_is_local_multicast(entry->addr.u.ip4)) }
if (ipv4_is_local_multicast(entry->addr.u.ip4)) {
NL_SET_ERR_MSG_MOD(extack, "IPv4 entry group address is local multicast");
return false; return false;
}
#if IS_ENABLED(CONFIG_IPV6) #if IS_ENABLED(CONFIG_IPV6)
} else if (entry->addr.proto == htons(ETH_P_IPV6)) { } else if (entry->addr.proto == htons(ETH_P_IPV6)) {
if (ipv6_addr_is_ll_all_nodes(&entry->addr.u.ip6)) if (ipv6_addr_is_ll_all_nodes(&entry->addr.u.ip6)) {
NL_SET_ERR_MSG_MOD(extack, "IPv6 entry group address is link-local all nodes");
return false; return false;
}
#endif #endif
} else } else {
NL_SET_ERR_MSG_MOD(extack, "Unknown entry protocol");
return false; return false;
if (entry->state != MDB_PERMANENT && entry->state != MDB_TEMPORARY) }
if (entry->state != MDB_PERMANENT && entry->state != MDB_TEMPORARY) {
NL_SET_ERR_MSG_MOD(extack, "Unknown entry state");
return false; return false;
if (entry->vid >= VLAN_VID_MASK) }
if (entry->vid >= VLAN_VID_MASK) {
NL_SET_ERR_MSG_MOD(extack, "Invalid entry VLAN id");
return false; return false;
}
return true; return true;
} }
static int br_mdb_parse(struct sk_buff *skb, struct nlmsghdr *nlh, static int br_mdb_parse(struct sk_buff *skb, struct nlmsghdr *nlh,
struct net_device **pdev, struct br_mdb_entry **pentry) struct net_device **pdev, struct br_mdb_entry **pentry,
struct netlink_ext_ack *extack)
{ {
struct net *net = sock_net(skb->sk); struct net *net = sock_net(skb->sk);
struct br_mdb_entry *entry; struct br_mdb_entry *entry;
...@@ -671,36 +688,37 @@ static int br_mdb_parse(struct sk_buff *skb, struct nlmsghdr *nlh, ...@@ -671,36 +688,37 @@ static int br_mdb_parse(struct sk_buff *skb, struct nlmsghdr *nlh,
bpm = nlmsg_data(nlh); bpm = nlmsg_data(nlh);
if (bpm->ifindex == 0) { if (bpm->ifindex == 0) {
pr_info("PF_BRIDGE: br_mdb_parse() with invalid ifindex\n"); NL_SET_ERR_MSG_MOD(extack, "Invalid bridge ifindex");
return -EINVAL; return -EINVAL;
} }
dev = __dev_get_by_index(net, bpm->ifindex); dev = __dev_get_by_index(net, bpm->ifindex);
if (dev == NULL) { if (dev == NULL) {
pr_info("PF_BRIDGE: br_mdb_parse() with unknown ifindex\n"); NL_SET_ERR_MSG_MOD(extack, "Bridge device doesn't exist");
return -ENODEV; return -ENODEV;
} }
if (!(dev->priv_flags & IFF_EBRIDGE)) { if (!(dev->priv_flags & IFF_EBRIDGE)) {
pr_info("PF_BRIDGE: br_mdb_parse() with non-bridge\n"); NL_SET_ERR_MSG_MOD(extack, "Device is not a bridge");
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
*pdev = dev; *pdev = dev;
if (!tb[MDBA_SET_ENTRY] || if (!tb[MDBA_SET_ENTRY]) {
nla_len(tb[MDBA_SET_ENTRY]) != sizeof(struct br_mdb_entry)) { NL_SET_ERR_MSG_MOD(extack, "Missing MDBA_SET_ENTRY attribute");
pr_info("PF_BRIDGE: br_mdb_parse() with invalid attr\n");
return -EINVAL; return -EINVAL;
} }
if (nla_len(tb[MDBA_SET_ENTRY]) != sizeof(struct br_mdb_entry)) {
entry = nla_data(tb[MDBA_SET_ENTRY]); NL_SET_ERR_MSG_MOD(extack, "Invalid MDBA_SET_ENTRY attribute length");
if (!is_valid_mdb_entry(entry)) {
pr_info("PF_BRIDGE: br_mdb_parse() with invalid entry\n");
return -EINVAL; return -EINVAL;
} }
entry = nla_data(tb[MDBA_SET_ENTRY]);
if (!is_valid_mdb_entry(entry, extack))
return -EINVAL;
*pentry = entry; *pentry = entry;
return 0; return 0;
} }
...@@ -797,7 +815,7 @@ static int br_mdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, ...@@ -797,7 +815,7 @@ static int br_mdb_add(struct sk_buff *skb, struct nlmsghdr *nlh,
struct net_bridge *br; struct net_bridge *br;
int err; int err;
err = br_mdb_parse(skb, nlh, &dev, &entry); err = br_mdb_parse(skb, nlh, &dev, &entry, extack);
if (err < 0) if (err < 0)
return err; return err;
...@@ -892,7 +910,7 @@ static int br_mdb_del(struct sk_buff *skb, struct nlmsghdr *nlh, ...@@ -892,7 +910,7 @@ static int br_mdb_del(struct sk_buff *skb, struct nlmsghdr *nlh,
struct net_bridge *br; struct net_bridge *br;
int err; int err;
err = br_mdb_parse(skb, nlh, &dev, &entry); err = br_mdb_parse(skb, nlh, &dev, &entry, extack);
if (err < 0) if (err < 0)
return err; return err;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册