diff options
Diffstat (limited to 'net/bridge/br_netlink.c')
| -rw-r--r-- | net/bridge/br_netlink.c | 42 |
1 files changed, 29 insertions, 13 deletions
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index 40197ff8918a..0ce26a0f7913 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c @@ -768,23 +768,16 @@ static int br_validate(struct nlattr *tb[], struct nlattr *data[]) return -EPROTONOSUPPORT; } } -#endif - return 0; -} - -static int br_dev_newlink(struct net *src_net, struct net_device *dev, - struct nlattr *tb[], struct nlattr *data[]) -{ - struct net_bridge *br = netdev_priv(dev); + if (data[IFLA_BR_VLAN_DEFAULT_PVID]) { + __u16 defpvid = nla_get_u16(data[IFLA_BR_VLAN_DEFAULT_PVID]); - if (tb[IFLA_ADDRESS]) { - spin_lock_bh(&br->lock); - br_stp_change_bridge_id(br, nla_data(tb[IFLA_ADDRESS])); - spin_unlock_bh(&br->lock); + if (defpvid >= VLAN_VID_MASK) + return -EINVAL; } +#endif - return register_netdevice(dev); + return 0; } static int br_port_slave_changelink(struct net_device *brdev, @@ -1068,6 +1061,29 @@ static int br_changelink(struct net_device *brdev, struct nlattr *tb[], return 0; } +static int br_dev_newlink(struct net *src_net, struct net_device *dev, + struct nlattr *tb[], struct nlattr *data[]) +{ + struct net_bridge *br = netdev_priv(dev); + int err; + + err = register_netdevice(dev); + if (err) + return err; + + if (tb[IFLA_ADDRESS]) { + spin_lock_bh(&br->lock); + br_stp_change_bridge_id(br, nla_data(tb[IFLA_ADDRESS])); + spin_unlock_bh(&br->lock); + } + + err = br_changelink(dev, tb, data); + if (err) + br_dev_delete(dev, NULL); + + return err; +} + static size_t br_get_size(const struct net_device *brdev) { return nla_total_size(sizeof(u32)) + /* IFLA_BR_FORWARD_DELAY */ |
