diff options
author | 2018-05-30 02:56:55 +0200 | |
---|---|---|
committer | 2018-05-31 14:13:43 -0400 | |
commit | dbd6dc752c8a6de428eacad47d4fd37e52f98183 (patch) | |
tree | 569ae047d67febb61d0a10735313512863a00412 /net/bridge/br_vlan.c | |
parent | net: bridge: Extract boilerplate around switchdev_port_obj_*() (diff) | |
download | linux-dbd6dc752c8a6de428eacad47d4fd37e52f98183.tar.gz linux-dbd6dc752c8a6de428eacad47d4fd37e52f98183.tar.bz2 linux-dbd6dc752c8a6de428eacad47d4fd37e52f98183.zip |
net: bridge: Extract br_vlan_add_existing()
Extract the code that deals with adding a preexisting VLAN to bridge CPU
port to a separate function. A follow-up patch introduces a need to roll
back operations in this block due to an error, and this split will make
the error-handling code clearer.
Signed-off-by: Petr Machata <petrm@mellanox.com>
Reviewed-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bridge/br_vlan.c')
-rw-r--r-- | net/bridge/br_vlan.c | 55 |
1 files changed, 33 insertions, 22 deletions
diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c index e3b14c0b2060..602c869c9821 100644 --- a/net/bridge/br_vlan.c +++ b/net/bridge/br_vlan.c @@ -551,6 +551,37 @@ bool br_should_learn(struct net_bridge_port *p, struct sk_buff *skb, u16 *vid) return false; } +static int br_vlan_add_existing(struct net_bridge *br, + struct net_bridge_vlan_group *vg, + struct net_bridge_vlan *vlan, + u16 flags, bool *changed) +{ + int err; + + if (!br_vlan_is_brentry(vlan)) { + /* Trying to change flags of non-existent bridge vlan */ + if (!(flags & BRIDGE_VLAN_INFO_BRENTRY)) + return -EINVAL; + /* It was only kept for port vlans, now make it real */ + err = br_fdb_insert(br, NULL, br->dev->dev_addr, + vlan->vid); + if (err) { + br_err(br, "failed to insert local address into bridge forwarding table\n"); + return err; + } + + refcount_inc(&vlan->refcnt); + vlan->flags |= BRIDGE_VLAN_INFO_BRENTRY; + vg->num_vlans++; + *changed = true; + } + + if (__vlan_add_flags(vlan, flags)) + *changed = true; + + return 0; +} + /* Must be protected by RTNL. * Must be called with vid in range from 1 to 4094 inclusive. * changed must be true only if the vlan was created or updated @@ -566,28 +597,8 @@ int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags, bool *changed) *changed = false; vg = br_vlan_group(br); vlan = br_vlan_find(vg, vid); - if (vlan) { - if (!br_vlan_is_brentry(vlan)) { - /* Trying to change flags of non-existent bridge vlan */ - if (!(flags & BRIDGE_VLAN_INFO_BRENTRY)) - return -EINVAL; - /* It was only kept for port vlans, now make it real */ - ret = br_fdb_insert(br, NULL, br->dev->dev_addr, - vlan->vid); - if (ret) { - br_err(br, "failed insert local address into bridge forwarding table\n"); - return ret; - } - refcount_inc(&vlan->refcnt); - vlan->flags |= BRIDGE_VLAN_INFO_BRENTRY; - vg->num_vlans++; - *changed = true; - } - if (__vlan_add_flags(vlan, flags)) - *changed = true; - - return 0; - } + if (vlan) + return br_vlan_add_existing(br, vg, vlan, flags, changed); vlan = kzalloc(sizeof(*vlan), GFP_KERNEL); if (!vlan) |