Commit dbd6dc75 authored by Petr Machata's avatar Petr Machata Committed by David S. Miller

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: default avatarPetr Machata <petrm@mellanox.com>
Reviewed-by: default avatarNikolay Aleksandrov <nikolay@cumulusnetworks.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d66e4348
...@@ -551,43 +551,54 @@ bool br_should_learn(struct net_bridge_port *p, struct sk_buff *skb, u16 *vid) ...@@ -551,43 +551,54 @@ bool br_should_learn(struct net_bridge_port *p, struct sk_buff *skb, u16 *vid)
return false; return false;
} }
/* Must be protected by RTNL. static int br_vlan_add_existing(struct net_bridge *br,
* Must be called with vid in range from 1 to 4094 inclusive. struct net_bridge_vlan_group *vg,
* changed must be true only if the vlan was created or updated struct net_bridge_vlan *vlan,
*/ u16 flags, bool *changed)
int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags, bool *changed)
{ {
struct net_bridge_vlan_group *vg; int err;
struct net_bridge_vlan *vlan;
int ret;
ASSERT_RTNL();
*changed = false;
vg = br_vlan_group(br);
vlan = br_vlan_find(vg, vid);
if (vlan) {
if (!br_vlan_is_brentry(vlan)) { if (!br_vlan_is_brentry(vlan)) {
/* Trying to change flags of non-existent bridge vlan */ /* Trying to change flags of non-existent bridge vlan */
if (!(flags & BRIDGE_VLAN_INFO_BRENTRY)) if (!(flags & BRIDGE_VLAN_INFO_BRENTRY))
return -EINVAL; return -EINVAL;
/* It was only kept for port vlans, now make it real */ /* It was only kept for port vlans, now make it real */
ret = br_fdb_insert(br, NULL, br->dev->dev_addr, err = br_fdb_insert(br, NULL, br->dev->dev_addr,
vlan->vid); vlan->vid);
if (ret) { if (err) {
br_err(br, "failed insert local address into bridge forwarding table\n"); br_err(br, "failed to insert local address into bridge forwarding table\n");
return ret; return err;
} }
refcount_inc(&vlan->refcnt); refcount_inc(&vlan->refcnt);
vlan->flags |= BRIDGE_VLAN_INFO_BRENTRY; vlan->flags |= BRIDGE_VLAN_INFO_BRENTRY;
vg->num_vlans++; vg->num_vlans++;
*changed = true; *changed = true;
} }
if (__vlan_add_flags(vlan, flags)) if (__vlan_add_flags(vlan, flags))
*changed = true; *changed = true;
return 0; 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
*/
int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags, bool *changed)
{
struct net_bridge_vlan_group *vg;
struct net_bridge_vlan *vlan;
int ret;
ASSERT_RTNL();
*changed = false;
vg = br_vlan_group(br);
vlan = br_vlan_find(vg, vid);
if (vlan)
return br_vlan_add_existing(br, vg, vlan, flags, changed);
vlan = kzalloc(sizeof(*vlan), GFP_KERNEL); vlan = kzalloc(sizeof(*vlan), GFP_KERNEL);
if (!vlan) if (!vlan)
......
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