bridge: vlan: move pvid inside net_bridge_vlan_group

One obvious way to converge more code (which was also used by the
previous vlan code) is to move pvid inside net_bridge_vlan_group. This
allows us to simplify some and remove other port-specific functions.
Also gives us the ability to simply pass the vlan group and use all of the
contained information.

Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c
index 678d5c4..90ac4b0 100644
--- a/net/bridge/br_vlan.c
+++ b/net/bridge/br_vlan.c
@@ -31,37 +31,37 @@
 	return rhashtable_lookup_fast(tbl, &vid, br_vlan_rht_params);
 }
 
-static void __vlan_add_pvid(u16 *pvid, u16 vid)
+static void __vlan_add_pvid(struct net_bridge_vlan_group *vg, u16 vid)
 {
-	if (*pvid == vid)
+	if (vg->pvid == vid)
 		return;
 
 	smp_wmb();
-	*pvid = vid;
+	vg->pvid = vid;
 }
 
-static void __vlan_delete_pvid(u16 *pvid, u16 vid)
+static void __vlan_delete_pvid(struct net_bridge_vlan_group *vg, u16 vid)
 {
-	if (*pvid != vid)
+	if (vg->pvid != vid)
 		return;
 
 	smp_wmb();
-	*pvid = 0;
+	vg->pvid = 0;
 }
 
 static void __vlan_add_flags(struct net_bridge_vlan *v, u16 flags)
 {
-	if (flags & BRIDGE_VLAN_INFO_PVID) {
-		if (br_vlan_is_master(v))
-			__vlan_add_pvid(&v->br->pvid, v->vid);
-		else
-			__vlan_add_pvid(&v->port->pvid, v->vid);
-	} else {
-		if (br_vlan_is_master(v))
-			__vlan_delete_pvid(&v->br->pvid, v->vid);
-		else
-			__vlan_delete_pvid(&v->port->pvid, v->vid);
-	}
+	struct net_bridge_vlan_group *vg;
+
+	if (br_vlan_is_master(v))
+		vg = v->br->vlgrp;
+	else
+		vg = v->port->vlgrp;
+
+	if (flags & BRIDGE_VLAN_INFO_PVID)
+		__vlan_add_pvid(vg, v->vid);
+	else
+		__vlan_delete_pvid(vg, v->vid);
 
 	if (flags & BRIDGE_VLAN_INFO_UNTAGGED)
 		v->flags |= BRIDGE_VLAN_INFO_UNTAGGED;
@@ -249,25 +249,22 @@
 static int __vlan_del(struct net_bridge_vlan *v)
 {
 	struct net_bridge_vlan *masterv = v;
+	struct net_bridge_vlan_group *vg;
 	struct net_bridge_port *p = NULL;
 	struct net_bridge *br;
 	int err = 0;
-	struct rhashtable *tbl;
-	u16 *pvid;
 
 	if (br_vlan_is_master(v)) {
 		br = v->br;
-		tbl = &v->br->vlgrp->vlan_hash;
-		pvid = &v->br->pvid;
+		vg = v->br->vlgrp;
 	} else {
 		p = v->port;
 		br = p->br;
-		tbl = &p->vlgrp->vlan_hash;
+		vg = v->port->vlgrp;
 		masterv = v->brvlan;
-		pvid = &p->pvid;
 	}
 
-	__vlan_delete_pvid(pvid, v->vid);
+	__vlan_delete_pvid(vg, v->vid);
 	if (p) {
 		err = __vlan_vid_del(p->dev, p->br, v->vid);
 		if (err)
@@ -284,7 +281,8 @@
 	}
 
 	if (masterv != v) {
-		rhashtable_remove_fast(tbl, &v->vnode, br_vlan_rht_params);
+		rhashtable_remove_fast(&vg->vlan_hash, &v->vnode,
+				       br_vlan_rht_params);
 		__vlan_del_list(v);
 		kfree_rcu(v, rcu);
 	}
@@ -299,11 +297,11 @@
 	return err;
 }
 
-static void __vlan_flush(struct net_bridge_vlan_group *vlgrp, u16 *pvid)
+static void __vlan_flush(struct net_bridge_vlan_group *vlgrp)
 {
 	struct net_bridge_vlan *vlan, *tmp;
 
-	__vlan_delete_pvid(pvid, *pvid);
+	__vlan_delete_pvid(vlgrp, vlgrp->pvid);
 	list_for_each_entry_safe(vlan, tmp, &vlgrp->vlan_list, vlist)
 		__vlan_del(vlan);
 	rhashtable_destroy(&vlgrp->vlan_hash);
@@ -348,7 +346,7 @@
 }
 
 /* Called under RCU */
-static bool __allowed_ingress(struct rhashtable *tbl, u16 pvid, __be16 proto,
+static bool __allowed_ingress(struct net_bridge_vlan_group *vg, __be16 proto,
 			      struct sk_buff *skb, u16 *vid)
 {
 	const struct net_bridge_vlan *v;
@@ -389,6 +387,8 @@
 	}
 
 	if (!*vid) {
+		u16 pvid = br_get_pvid(vg);
+
 		/* Frame had a tag with VID 0 or did not have a tag.
 		 * See if pvid is set on this port.  That tells us which
 		 * vlan untagged or priority-tagged traffic belongs to.
@@ -415,7 +415,7 @@
 	}
 
 	/* Frame had a valid vlan tag.  See if vlan is allowed */
-	v = br_vlan_lookup(tbl, *vid);
+	v = br_vlan_find(vg, *vid);
 	if (v && br_vlan_should_use(v))
 		return true;
 drop:
@@ -423,7 +423,9 @@
 	return false;
 }
 
-bool br_allowed_ingress(struct net_bridge *br, struct sk_buff *skb, u16 *vid)
+bool br_allowed_ingress(const struct net_bridge *br,
+			struct net_bridge_vlan_group *vg, struct sk_buff *skb,
+			u16 *vid)
 {
 	/* If VLAN filtering is disabled on the bridge, all packets are
 	 * permitted.
@@ -433,25 +435,7 @@
 		return true;
 	}
 
-	return __allowed_ingress(&br->vlgrp->vlan_hash, br->pvid,
-				 br->vlan_proto, skb, vid);
-}
-
-bool nbp_allowed_ingress(struct net_bridge_port *p, struct sk_buff *skb,
-			 u16 *vid)
-{
-	struct net_bridge *br = p->br;
-
-	/* If VLAN filtering is disabled on the bridge, all packets are
-	 * permitted.
-	 */
-	if (!br->vlan_enabled) {
-		BR_INPUT_SKB_CB(skb)->vlan_filtered = false;
-		return true;
-	}
-
-	return __allowed_ingress(&p->vlgrp->vlan_hash, p->pvid, br->vlan_proto,
-				 skb, vid);
+	return __allowed_ingress(vg, br->vlan_proto, skb, vid);
 }
 
 /* Called under RCU. */
@@ -491,14 +475,14 @@
 		*vid = 0;
 
 	if (!*vid) {
-		*vid = nbp_get_pvid(p);
+		*vid = br_get_pvid(vg);
 		if (!*vid)
 			return false;
 
 		return true;
 	}
 
-	if (br_vlan_find(p->vlgrp, *vid))
+	if (br_vlan_find(vg, *vid))
 		return true;
 
 	return false;
@@ -574,7 +558,7 @@
 {
 	ASSERT_RTNL();
 
-	__vlan_flush(br_vlan_group(br), &br->pvid);
+	__vlan_flush(br_vlan_group(br));
 }
 
 struct net_bridge_vlan *br_vlan_find(struct net_bridge_vlan_group *vg, u16 vid)
@@ -695,12 +679,11 @@
 	return err;
 }
 
-static bool vlan_default_pvid(struct net_bridge_vlan_group *vg, u16 pvid,
-			      u16 vid)
+static bool vlan_default_pvid(struct net_bridge_vlan_group *vg, u16 vid)
 {
 	struct net_bridge_vlan *v;
 
-	if (vid != pvid)
+	if (vid != vg->pvid)
 		return false;
 
 	v = br_vlan_lookup(&vg->vlan_hash, vid);
@@ -719,11 +702,11 @@
 	/* Disable default_pvid on all ports where it is still
 	 * configured.
 	 */
-	if (vlan_default_pvid(br->vlgrp, br->pvid, pvid))
+	if (vlan_default_pvid(br->vlgrp, pvid))
 		br_vlan_delete(br, pvid);
 
 	list_for_each_entry(p, &br->port_list, list) {
-		if (vlan_default_pvid(p->vlgrp, p->pvid, pvid))
+		if (vlan_default_pvid(p->vlgrp, pvid))
 			nbp_vlan_delete(p, pvid);
 	}
 
@@ -749,7 +732,7 @@
 	 * user configuration.
 	 */
 	pvent = br_vlan_find(br->vlgrp, pvid);
-	if ((!old_pvid || vlan_default_pvid(br->vlgrp, br->pvid, old_pvid)) &&
+	if ((!old_pvid || vlan_default_pvid(br->vlgrp, old_pvid)) &&
 	    (!pvent || !br_vlan_should_use(pvent))) {
 		err = br_vlan_add(br, pvid,
 				  BRIDGE_VLAN_INFO_PVID |
@@ -766,7 +749,7 @@
 		 * user configuration.
 		 */
 		if ((old_pvid &&
-		     !vlan_default_pvid(p->vlgrp, p->pvid, old_pvid)) ||
+		     !vlan_default_pvid(p->vlgrp, old_pvid)) ||
 		    br_vlan_find(p->vlgrp, pvid))
 			continue;
 
@@ -955,5 +938,5 @@
 	list_for_each_entry(vlan, &port->vlgrp->vlan_list, vlist)
 		vlan_vid_del(port->dev, port->br->vlan_proto, vlan->vid);
 
-	__vlan_flush(nbp_vlan_group(port), &port->pvid);
+	__vlan_flush(nbp_vlan_group(port));
 }