1243a2e63SVlad Yasevich #include <linux/kernel.h> 2243a2e63SVlad Yasevich #include <linux/netdevice.h> 3243a2e63SVlad Yasevich #include <linux/rtnetlink.h> 4243a2e63SVlad Yasevich #include <linux/slab.h> 57f109539SScott Feldman #include <net/switchdev.h> 6243a2e63SVlad Yasevich 7243a2e63SVlad Yasevich #include "br_private.h" 8243a2e63SVlad Yasevich 92594e906SNikolay Aleksandrov static inline int br_vlan_cmp(struct rhashtable_compare_arg *arg, 102594e906SNikolay Aleksandrov const void *ptr) 11552406c4SVlad Yasevich { 122594e906SNikolay Aleksandrov const struct net_bridge_vlan *vle = ptr; 132594e906SNikolay Aleksandrov u16 vid = *(u16 *)arg->key; 142594e906SNikolay Aleksandrov 152594e906SNikolay Aleksandrov return vle->vid != vid; 162594e906SNikolay Aleksandrov } 172594e906SNikolay Aleksandrov 182594e906SNikolay Aleksandrov static const struct rhashtable_params br_vlan_rht_params = { 192594e906SNikolay Aleksandrov .head_offset = offsetof(struct net_bridge_vlan, vnode), 202594e906SNikolay Aleksandrov .key_offset = offsetof(struct net_bridge_vlan, vid), 212594e906SNikolay Aleksandrov .key_len = sizeof(u16), 228af78b64SNikolay Aleksandrov .nelem_hint = 3, 238af78b64SNikolay Aleksandrov .locks_mul = 1, 242594e906SNikolay Aleksandrov .max_size = VLAN_N_VID, 252594e906SNikolay Aleksandrov .obj_cmpfn = br_vlan_cmp, 262594e906SNikolay Aleksandrov .automatic_shrinking = true, 272594e906SNikolay Aleksandrov }; 282594e906SNikolay Aleksandrov 292594e906SNikolay Aleksandrov static struct net_bridge_vlan *br_vlan_lookup(struct rhashtable *tbl, u16 vid) 302594e906SNikolay Aleksandrov { 312594e906SNikolay Aleksandrov return rhashtable_lookup_fast(tbl, &vid, br_vlan_rht_params); 322594e906SNikolay Aleksandrov } 332594e906SNikolay Aleksandrov 3477751ee8SNikolay Aleksandrov static void __vlan_add_pvid(struct net_bridge_vlan_group *vg, u16 vid) 352594e906SNikolay Aleksandrov { 3677751ee8SNikolay Aleksandrov if (vg->pvid == vid) 37552406c4SVlad Yasevich return; 38552406c4SVlad Yasevich 39552406c4SVlad Yasevich smp_wmb(); 4077751ee8SNikolay Aleksandrov vg->pvid = vid; 41552406c4SVlad Yasevich } 42552406c4SVlad Yasevich 4377751ee8SNikolay Aleksandrov static void __vlan_delete_pvid(struct net_bridge_vlan_group *vg, u16 vid) 44552406c4SVlad Yasevich { 4577751ee8SNikolay Aleksandrov if (vg->pvid != vid) 46552406c4SVlad Yasevich return; 47552406c4SVlad Yasevich 48552406c4SVlad Yasevich smp_wmb(); 4977751ee8SNikolay Aleksandrov vg->pvid = 0; 50552406c4SVlad Yasevich } 51552406c4SVlad Yasevich 522594e906SNikolay Aleksandrov static void __vlan_add_flags(struct net_bridge_vlan *v, u16 flags) 5335e03f3aSVlad Yasevich { 5477751ee8SNikolay Aleksandrov struct net_bridge_vlan_group *vg; 5577751ee8SNikolay Aleksandrov 562594e906SNikolay Aleksandrov if (br_vlan_is_master(v)) 5777751ee8SNikolay Aleksandrov vg = v->br->vlgrp; 58635126b7SVlad Yasevich else 5977751ee8SNikolay Aleksandrov vg = v->port->vlgrp; 6077751ee8SNikolay Aleksandrov 6177751ee8SNikolay Aleksandrov if (flags & BRIDGE_VLAN_INFO_PVID) 6277751ee8SNikolay Aleksandrov __vlan_add_pvid(vg, v->vid); 632594e906SNikolay Aleksandrov else 6477751ee8SNikolay Aleksandrov __vlan_delete_pvid(vg, v->vid); 6535e03f3aSVlad Yasevich 6635e03f3aSVlad Yasevich if (flags & BRIDGE_VLAN_INFO_UNTAGGED) 672594e906SNikolay Aleksandrov v->flags |= BRIDGE_VLAN_INFO_UNTAGGED; 68635126b7SVlad Yasevich else 692594e906SNikolay Aleksandrov v->flags &= ~BRIDGE_VLAN_INFO_UNTAGGED; 7035e03f3aSVlad Yasevich } 7135e03f3aSVlad Yasevich 727f109539SScott Feldman static int __vlan_vid_add(struct net_device *dev, struct net_bridge *br, 737f109539SScott Feldman u16 vid, u16 flags) 747f109539SScott Feldman { 757f109539SScott Feldman const struct net_device_ops *ops = dev->netdev_ops; 767f109539SScott Feldman int err; 777f109539SScott Feldman 787f109539SScott Feldman /* If driver uses VLAN ndo ops, use 8021q to install vid 797f109539SScott Feldman * on device, otherwise try switchdev ops to install vid. 807f109539SScott Feldman */ 817f109539SScott Feldman 827f109539SScott Feldman if (ops->ndo_vlan_rx_add_vid) { 837f109539SScott Feldman err = vlan_vid_add(dev, br->vlan_proto, vid); 847f109539SScott Feldman } else { 85ab069002SVivien Didelot struct switchdev_obj_vlan v = { 867f109539SScott Feldman .flags = flags, 873e3a78b4SScott Feldman .vid_begin = vid, 887f109539SScott Feldman .vid_end = vid, 897f109539SScott Feldman }; 907f109539SScott Feldman 91ab069002SVivien Didelot err = switchdev_port_obj_add(dev, SWITCHDEV_OBJ_PORT_VLAN, &v); 927f109539SScott Feldman if (err == -EOPNOTSUPP) 937f109539SScott Feldman err = 0; 947f109539SScott Feldman } 957f109539SScott Feldman 967f109539SScott Feldman return err; 977f109539SScott Feldman } 987f109539SScott Feldman 992594e906SNikolay Aleksandrov static void __vlan_add_list(struct net_bridge_vlan *v) 100243a2e63SVlad Yasevich { 1012594e906SNikolay Aleksandrov struct list_head *headp, *hpos; 1022594e906SNikolay Aleksandrov struct net_bridge_vlan *vent; 103243a2e63SVlad Yasevich 1042594e906SNikolay Aleksandrov headp = br_vlan_is_master(v) ? &v->br->vlgrp->vlan_list : 1052594e906SNikolay Aleksandrov &v->port->vlgrp->vlan_list; 1062594e906SNikolay Aleksandrov list_for_each_prev(hpos, headp) { 1072594e906SNikolay Aleksandrov vent = list_entry(hpos, struct net_bridge_vlan, vlist); 1082594e906SNikolay Aleksandrov if (v->vid < vent->vid) 1092594e906SNikolay Aleksandrov continue; 1102594e906SNikolay Aleksandrov else 1112594e906SNikolay Aleksandrov break; 1122594e906SNikolay Aleksandrov } 1132594e906SNikolay Aleksandrov list_add(&v->vlist, hpos); 114552406c4SVlad Yasevich } 115243a2e63SVlad Yasevich 1162594e906SNikolay Aleksandrov static void __vlan_del_list(struct net_bridge_vlan *v) 1172594e906SNikolay Aleksandrov { 1182594e906SNikolay Aleksandrov list_del(&v->vlist); 119243a2e63SVlad Yasevich } 120243a2e63SVlad Yasevich 121bf361ad3SVivien Didelot static int __vlan_vid_del(struct net_device *dev, struct net_bridge *br, 1227f109539SScott Feldman u16 vid) 1237f109539SScott Feldman { 1247f109539SScott Feldman const struct net_device_ops *ops = dev->netdev_ops; 125bf361ad3SVivien Didelot int err = 0; 1267f109539SScott Feldman 1277f109539SScott Feldman /* If driver uses VLAN ndo ops, use 8021q to delete vid 1287f109539SScott Feldman * on device, otherwise try switchdev ops to delete vid. 1297f109539SScott Feldman */ 1307f109539SScott Feldman 1317f109539SScott Feldman if (ops->ndo_vlan_rx_kill_vid) { 1327f109539SScott Feldman vlan_vid_del(dev, br->vlan_proto, vid); 1337f109539SScott Feldman } else { 134ab069002SVivien Didelot struct switchdev_obj_vlan v = { 1353e3a78b4SScott Feldman .vid_begin = vid, 1367f109539SScott Feldman .vid_end = vid, 1377f109539SScott Feldman }; 1387f109539SScott Feldman 139ab069002SVivien Didelot err = switchdev_port_obj_del(dev, SWITCHDEV_OBJ_PORT_VLAN, &v); 140bf361ad3SVivien Didelot if (err == -EOPNOTSUPP) 141bf361ad3SVivien Didelot err = 0; 1427f109539SScott Feldman } 143bf361ad3SVivien Didelot 144bf361ad3SVivien Didelot return err; 1457f109539SScott Feldman } 1467f109539SScott Feldman 1472594e906SNikolay Aleksandrov /* This is the shared VLAN add function which works for both ports and bridge 1482594e906SNikolay Aleksandrov * devices. There are four possible calls to this function in terms of the 1492594e906SNikolay Aleksandrov * vlan entry type: 1502594e906SNikolay Aleksandrov * 1. vlan is being added on a port (no master flags, global entry exists) 1512594e906SNikolay Aleksandrov * 2. vlan is being added on a bridge (both master and brvlan flags) 1522594e906SNikolay Aleksandrov * 3. vlan is being added on a port, but a global entry didn't exist which 1532594e906SNikolay Aleksandrov * is being created right now (master flag set, brvlan flag unset), the 1542594e906SNikolay Aleksandrov * global entry is used for global per-vlan features, but not for filtering 1552594e906SNikolay Aleksandrov * 4. same as 3 but with both master and brvlan flags set so the entry 1562594e906SNikolay Aleksandrov * will be used for filtering in both the port and the bridge 1572594e906SNikolay Aleksandrov */ 1582594e906SNikolay Aleksandrov static int __vlan_add(struct net_bridge_vlan *v, u16 flags) 159243a2e63SVlad Yasevich { 1602594e906SNikolay Aleksandrov struct net_bridge_vlan *masterv = NULL; 1612594e906SNikolay Aleksandrov struct net_bridge_port *p = NULL; 1622594e906SNikolay Aleksandrov struct rhashtable *tbl; 1632594e906SNikolay Aleksandrov struct net_device *dev; 1642594e906SNikolay Aleksandrov struct net_bridge *br; 165bf361ad3SVivien Didelot int err; 166bf361ad3SVivien Didelot 1672594e906SNikolay Aleksandrov if (br_vlan_is_master(v)) { 1682594e906SNikolay Aleksandrov br = v->br; 1692594e906SNikolay Aleksandrov dev = br->dev; 1702594e906SNikolay Aleksandrov tbl = &br->vlgrp->vlan_hash; 1712594e906SNikolay Aleksandrov } else { 1722594e906SNikolay Aleksandrov p = v->port; 1732594e906SNikolay Aleksandrov br = p->br; 1742594e906SNikolay Aleksandrov dev = p->dev; 1752594e906SNikolay Aleksandrov tbl = &p->vlgrp->vlan_hash; 1762594e906SNikolay Aleksandrov } 1772594e906SNikolay Aleksandrov 1782594e906SNikolay Aleksandrov if (p) { 1792594e906SNikolay Aleksandrov u16 master_flags = flags; 1802594e906SNikolay Aleksandrov 1812594e906SNikolay Aleksandrov /* Add VLAN to the device filter if it is supported. 1822594e906SNikolay Aleksandrov * This ensures tagged traffic enters the bridge when 1832594e906SNikolay Aleksandrov * promiscuous mode is disabled by br_manage_promisc(). 1842594e906SNikolay Aleksandrov */ 1852594e906SNikolay Aleksandrov err = __vlan_vid_add(dev, br, v->vid, flags); 186bf361ad3SVivien Didelot if (err) 1872594e906SNikolay Aleksandrov goto out; 1882594e906SNikolay Aleksandrov 1892594e906SNikolay Aleksandrov /* need to work on the master vlan too */ 1902594e906SNikolay Aleksandrov if (flags & BRIDGE_VLAN_INFO_MASTER) { 1912594e906SNikolay Aleksandrov master_flags |= BRIDGE_VLAN_INFO_BRENTRY; 1922594e906SNikolay Aleksandrov err = br_vlan_add(br, v->vid, master_flags); 1932594e906SNikolay Aleksandrov if (err) 1942594e906SNikolay Aleksandrov goto out_filt; 1952594e906SNikolay Aleksandrov } 1962594e906SNikolay Aleksandrov 1972594e906SNikolay Aleksandrov masterv = br_vlan_find(br->vlgrp, v->vid); 1982594e906SNikolay Aleksandrov if (!masterv) { 1992594e906SNikolay Aleksandrov /* missing global ctx, create it now */ 2002594e906SNikolay Aleksandrov err = br_vlan_add(br, v->vid, master_flags); 2012594e906SNikolay Aleksandrov if (err) 2022594e906SNikolay Aleksandrov goto out_filt; 2032594e906SNikolay Aleksandrov masterv = br_vlan_find(br->vlgrp, v->vid); 2042594e906SNikolay Aleksandrov WARN_ON(!masterv); 2052594e906SNikolay Aleksandrov } 2062594e906SNikolay Aleksandrov atomic_inc(&masterv->refcnt); 2072594e906SNikolay Aleksandrov v->brvlan = masterv; 2082594e906SNikolay Aleksandrov } 2092594e906SNikolay Aleksandrov 2102594e906SNikolay Aleksandrov /* Add the dev mac only if it's a usable vlan */ 2112594e906SNikolay Aleksandrov if (br_vlan_should_use(v)) { 2122594e906SNikolay Aleksandrov err = br_fdb_insert(br, p, dev->dev_addr, v->vid); 2132594e906SNikolay Aleksandrov if (err) { 2142594e906SNikolay Aleksandrov br_err(br, "failed insert local address into bridge forwarding table\n"); 2152594e906SNikolay Aleksandrov goto out_filt; 2162594e906SNikolay Aleksandrov } 2172594e906SNikolay Aleksandrov } 2182594e906SNikolay Aleksandrov 2192594e906SNikolay Aleksandrov err = rhashtable_lookup_insert_fast(tbl, &v->vnode, br_vlan_rht_params); 2202594e906SNikolay Aleksandrov if (err) 2212594e906SNikolay Aleksandrov goto out_fdb_insert; 2222594e906SNikolay Aleksandrov 2232594e906SNikolay Aleksandrov __vlan_add_list(v); 2242594e906SNikolay Aleksandrov __vlan_add_flags(v, flags); 2252594e906SNikolay Aleksandrov if (br_vlan_is_master(v)) { 2262594e906SNikolay Aleksandrov if (br_vlan_is_brentry(v)) 2272594e906SNikolay Aleksandrov br->vlgrp->num_vlans++; 2282594e906SNikolay Aleksandrov } else { 2292594e906SNikolay Aleksandrov p->vlgrp->num_vlans++; 2302594e906SNikolay Aleksandrov } 2312594e906SNikolay Aleksandrov out: 2322594e906SNikolay Aleksandrov return err; 2332594e906SNikolay Aleksandrov 2342594e906SNikolay Aleksandrov out_fdb_insert: 2352594e906SNikolay Aleksandrov br_fdb_find_delete_local(br, p, br->dev->dev_addr, v->vid); 2362594e906SNikolay Aleksandrov 2372594e906SNikolay Aleksandrov out_filt: 2382594e906SNikolay Aleksandrov if (p) { 2392594e906SNikolay Aleksandrov __vlan_vid_del(dev, br, v->vid); 2402594e906SNikolay Aleksandrov if (masterv) { 2412594e906SNikolay Aleksandrov atomic_dec(&masterv->refcnt); 2422594e906SNikolay Aleksandrov v->brvlan = NULL; 2432594e906SNikolay Aleksandrov } 2442594e906SNikolay Aleksandrov } 2452594e906SNikolay Aleksandrov 2462594e906SNikolay Aleksandrov goto out; 2472594e906SNikolay Aleksandrov } 2482594e906SNikolay Aleksandrov 2492594e906SNikolay Aleksandrov static int __vlan_del(struct net_bridge_vlan *v) 2502594e906SNikolay Aleksandrov { 2512594e906SNikolay Aleksandrov struct net_bridge_vlan *masterv = v; 25277751ee8SNikolay Aleksandrov struct net_bridge_vlan_group *vg; 2532594e906SNikolay Aleksandrov struct net_bridge_port *p = NULL; 2542594e906SNikolay Aleksandrov struct net_bridge *br; 2552594e906SNikolay Aleksandrov int err = 0; 2562594e906SNikolay Aleksandrov 2572594e906SNikolay Aleksandrov if (br_vlan_is_master(v)) { 2582594e906SNikolay Aleksandrov br = v->br; 25977751ee8SNikolay Aleksandrov vg = v->br->vlgrp; 2602594e906SNikolay Aleksandrov } else { 2612594e906SNikolay Aleksandrov p = v->port; 2622594e906SNikolay Aleksandrov br = p->br; 26377751ee8SNikolay Aleksandrov vg = v->port->vlgrp; 2642594e906SNikolay Aleksandrov masterv = v->brvlan; 2652594e906SNikolay Aleksandrov } 2662594e906SNikolay Aleksandrov 26777751ee8SNikolay Aleksandrov __vlan_delete_pvid(vg, v->vid); 2682594e906SNikolay Aleksandrov if (p) { 2692594e906SNikolay Aleksandrov err = __vlan_vid_del(p->dev, p->br, v->vid); 2702594e906SNikolay Aleksandrov if (err) 2712594e906SNikolay Aleksandrov goto out; 2722594e906SNikolay Aleksandrov } 2732594e906SNikolay Aleksandrov 2742594e906SNikolay Aleksandrov if (br_vlan_is_master(v)) { 2752594e906SNikolay Aleksandrov if (br_vlan_is_brentry(v)) { 2762594e906SNikolay Aleksandrov v->flags &= ~BRIDGE_VLAN_INFO_BRENTRY; 2772594e906SNikolay Aleksandrov br->vlgrp->num_vlans--; 2782594e906SNikolay Aleksandrov } 2792594e906SNikolay Aleksandrov } else { 2802594e906SNikolay Aleksandrov p->vlgrp->num_vlans--; 2812594e906SNikolay Aleksandrov } 2822594e906SNikolay Aleksandrov 2832594e906SNikolay Aleksandrov if (masterv != v) { 28477751ee8SNikolay Aleksandrov rhashtable_remove_fast(&vg->vlan_hash, &v->vnode, 28577751ee8SNikolay Aleksandrov br_vlan_rht_params); 2862594e906SNikolay Aleksandrov __vlan_del_list(v); 2872594e906SNikolay Aleksandrov kfree_rcu(v, rcu); 2882594e906SNikolay Aleksandrov } 2892594e906SNikolay Aleksandrov 2902594e906SNikolay Aleksandrov if (atomic_dec_and_test(&masterv->refcnt)) { 2912594e906SNikolay Aleksandrov rhashtable_remove_fast(&masterv->br->vlgrp->vlan_hash, 2922594e906SNikolay Aleksandrov &masterv->vnode, br_vlan_rht_params); 2932594e906SNikolay Aleksandrov __vlan_del_list(masterv); 2942594e906SNikolay Aleksandrov kfree_rcu(masterv, rcu); 2952594e906SNikolay Aleksandrov } 2962594e906SNikolay Aleksandrov out: 297bf361ad3SVivien Didelot return err; 2988580e211SToshiaki Makita } 299243a2e63SVlad Yasevich 30077751ee8SNikolay Aleksandrov static void __vlan_flush(struct net_bridge_vlan_group *vlgrp) 301243a2e63SVlad Yasevich { 3022594e906SNikolay Aleksandrov struct net_bridge_vlan *vlan, *tmp; 3032594e906SNikolay Aleksandrov 30477751ee8SNikolay Aleksandrov __vlan_delete_pvid(vlgrp, vlgrp->pvid); 3052594e906SNikolay Aleksandrov list_for_each_entry_safe(vlan, tmp, &vlgrp->vlan_list, vlist) 3062594e906SNikolay Aleksandrov __vlan_del(vlan); 3072594e906SNikolay Aleksandrov rhashtable_destroy(&vlgrp->vlan_hash); 3082594e906SNikolay Aleksandrov kfree(vlgrp); 309243a2e63SVlad Yasevich } 310243a2e63SVlad Yasevich 31178851988SVlad Yasevich struct sk_buff *br_handle_vlan(struct net_bridge *br, 3122594e906SNikolay Aleksandrov struct net_bridge_vlan_group *vg, 313a37b85c9SVlad Yasevich struct sk_buff *skb) 314a37b85c9SVlad Yasevich { 3152594e906SNikolay Aleksandrov struct net_bridge_vlan *v; 316a37b85c9SVlad Yasevich u16 vid; 317a37b85c9SVlad Yasevich 31820adfa1aSVlad Yasevich /* If this packet was not filtered at input, let it pass */ 31920adfa1aSVlad Yasevich if (!BR_INPUT_SKB_CB(skb)->vlan_filtered) 32078851988SVlad Yasevich goto out; 32178851988SVlad Yasevich 3222594e906SNikolay Aleksandrov /* At this point, we know that the frame was filtered and contains 3232594e906SNikolay Aleksandrov * a valid vlan id. If the vlan id has untagged flag set, 3242594e906SNikolay Aleksandrov * send untagged; otherwise, send tagged. 3252594e906SNikolay Aleksandrov */ 3262594e906SNikolay Aleksandrov br_vlan_get_tag(skb, &vid); 3272594e906SNikolay Aleksandrov v = br_vlan_find(vg, vid); 3282594e906SNikolay Aleksandrov /* Vlan entry must be configured at this point. The 329fc92f745SVlad Yasevich * only exception is the bridge is set in promisc mode and the 330fc92f745SVlad Yasevich * packet is destined for the bridge device. In this case 331fc92f745SVlad Yasevich * pass the packet as is. 332fc92f745SVlad Yasevich */ 3332594e906SNikolay Aleksandrov if (!v || !br_vlan_should_use(v)) { 334fc92f745SVlad Yasevich if ((br->dev->flags & IFF_PROMISC) && skb->dev == br->dev) { 335fc92f745SVlad Yasevich goto out; 336fc92f745SVlad Yasevich } else { 337fc92f745SVlad Yasevich kfree_skb(skb); 338fc92f745SVlad Yasevich return NULL; 339fc92f745SVlad Yasevich } 340fc92f745SVlad Yasevich } 3412594e906SNikolay Aleksandrov if (v->flags & BRIDGE_VLAN_INFO_UNTAGGED) 34299b192daSToshiaki Makita skb->vlan_tci = 0; 34378851988SVlad Yasevich 34478851988SVlad Yasevich out: 34578851988SVlad Yasevich return skb; 34678851988SVlad Yasevich } 34778851988SVlad Yasevich 34878851988SVlad Yasevich /* Called under RCU */ 34977751ee8SNikolay Aleksandrov static bool __allowed_ingress(struct net_bridge_vlan_group *vg, __be16 proto, 35078851988SVlad Yasevich struct sk_buff *skb, u16 *vid) 35178851988SVlad Yasevich { 3522594e906SNikolay Aleksandrov const struct net_bridge_vlan *v; 3538580e211SToshiaki Makita bool tagged; 354a37b85c9SVlad Yasevich 35520adfa1aSVlad Yasevich BR_INPUT_SKB_CB(skb)->vlan_filtered = true; 35612464bb8SToshiaki Makita /* If vlan tx offload is disabled on bridge device and frame was 35712464bb8SToshiaki Makita * sent from vlan device on the bridge device, it does not have 35812464bb8SToshiaki Makita * HW accelerated vlan tag. 35912464bb8SToshiaki Makita */ 360df8a39deSJiri Pirko if (unlikely(!skb_vlan_tag_present(skb) && 3618580e211SToshiaki Makita skb->protocol == proto)) { 3620d5501c1SVlad Yasevich skb = skb_vlan_untag(skb); 36312464bb8SToshiaki Makita if (unlikely(!skb)) 36412464bb8SToshiaki Makita return false; 36512464bb8SToshiaki Makita } 36612464bb8SToshiaki Makita 3678580e211SToshiaki Makita if (!br_vlan_get_tag(skb, vid)) { 3688580e211SToshiaki Makita /* Tagged frame */ 3698580e211SToshiaki Makita if (skb->vlan_proto != proto) { 3708580e211SToshiaki Makita /* Protocol-mismatch, empty out vlan_tci for new tag */ 3718580e211SToshiaki Makita skb_push(skb, ETH_HLEN); 37262749e2cSJiri Pirko skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto, 373df8a39deSJiri Pirko skb_vlan_tag_get(skb)); 3748580e211SToshiaki Makita if (unlikely(!skb)) 3758580e211SToshiaki Makita return false; 3768580e211SToshiaki Makita 3778580e211SToshiaki Makita skb_pull(skb, ETH_HLEN); 3788580e211SToshiaki Makita skb_reset_mac_len(skb); 3798580e211SToshiaki Makita *vid = 0; 3808580e211SToshiaki Makita tagged = false; 3818580e211SToshiaki Makita } else { 3828580e211SToshiaki Makita tagged = true; 3838580e211SToshiaki Makita } 3848580e211SToshiaki Makita } else { 3858580e211SToshiaki Makita /* Untagged frame */ 3868580e211SToshiaki Makita tagged = false; 3878580e211SToshiaki Makita } 3888580e211SToshiaki Makita 389b90356ceSToshiaki Makita if (!*vid) { 39077751ee8SNikolay Aleksandrov u16 pvid = br_get_pvid(vg); 39177751ee8SNikolay Aleksandrov 392b90356ceSToshiaki Makita /* Frame had a tag with VID 0 or did not have a tag. 393b90356ceSToshiaki Makita * See if pvid is set on this port. That tells us which 394b90356ceSToshiaki Makita * vlan untagged or priority-tagged traffic belongs to. 39578851988SVlad Yasevich */ 3963df6bf45SVlad Yasevich if (!pvid) 397eb707618SToshiaki Makita goto drop; 39878851988SVlad Yasevich 399b90356ceSToshiaki Makita /* PVID is set on this port. Any untagged or priority-tagged 400b90356ceSToshiaki Makita * ingress frame is considered to belong to this vlan. 40178851988SVlad Yasevich */ 402dfb5fa32SToshiaki Makita *vid = pvid; 4038580e211SToshiaki Makita if (likely(!tagged)) 404b90356ceSToshiaki Makita /* Untagged Frame. */ 4058580e211SToshiaki Makita __vlan_hwaccel_put_tag(skb, proto, pvid); 406b90356ceSToshiaki Makita else 407b90356ceSToshiaki Makita /* Priority-tagged Frame. 408b90356ceSToshiaki Makita * At this point, We know that skb->vlan_tci had 409b90356ceSToshiaki Makita * VLAN_TAG_PRESENT bit and its VID field was 0x000. 410b90356ceSToshiaki Makita * We update only VID field and preserve PCP field. 411b90356ceSToshiaki Makita */ 412b90356ceSToshiaki Makita skb->vlan_tci |= pvid; 413b90356ceSToshiaki Makita 41478851988SVlad Yasevich return true; 41578851988SVlad Yasevich } 41678851988SVlad Yasevich 41778851988SVlad Yasevich /* Frame had a valid vlan tag. See if vlan is allowed */ 41877751ee8SNikolay Aleksandrov v = br_vlan_find(vg, *vid); 4192594e906SNikolay Aleksandrov if (v && br_vlan_should_use(v)) 420a37b85c9SVlad Yasevich return true; 421eb707618SToshiaki Makita drop: 422eb707618SToshiaki Makita kfree_skb(skb); 423a37b85c9SVlad Yasevich return false; 424a37b85c9SVlad Yasevich } 425a37b85c9SVlad Yasevich 42677751ee8SNikolay Aleksandrov bool br_allowed_ingress(const struct net_bridge *br, 42777751ee8SNikolay Aleksandrov struct net_bridge_vlan_group *vg, struct sk_buff *skb, 4282594e906SNikolay Aleksandrov u16 *vid) 4292594e906SNikolay Aleksandrov { 4302594e906SNikolay Aleksandrov /* If VLAN filtering is disabled on the bridge, all packets are 4312594e906SNikolay Aleksandrov * permitted. 4322594e906SNikolay Aleksandrov */ 4332594e906SNikolay Aleksandrov if (!br->vlan_enabled) { 4342594e906SNikolay Aleksandrov BR_INPUT_SKB_CB(skb)->vlan_filtered = false; 4352594e906SNikolay Aleksandrov return true; 4362594e906SNikolay Aleksandrov } 4372594e906SNikolay Aleksandrov 43877751ee8SNikolay Aleksandrov return __allowed_ingress(vg, br->vlan_proto, skb, vid); 4392594e906SNikolay Aleksandrov } 4402594e906SNikolay Aleksandrov 44185f46c6bSVlad Yasevich /* Called under RCU. */ 4422594e906SNikolay Aleksandrov bool br_allowed_egress(struct net_bridge_vlan_group *vg, 44385f46c6bSVlad Yasevich const struct sk_buff *skb) 44485f46c6bSVlad Yasevich { 4452594e906SNikolay Aleksandrov const struct net_bridge_vlan *v; 44685f46c6bSVlad Yasevich u16 vid; 44785f46c6bSVlad Yasevich 44820adfa1aSVlad Yasevich /* If this packet was not filtered at input, let it pass */ 44920adfa1aSVlad Yasevich if (!BR_INPUT_SKB_CB(skb)->vlan_filtered) 45085f46c6bSVlad Yasevich return true; 45185f46c6bSVlad Yasevich 45285f46c6bSVlad Yasevich br_vlan_get_tag(skb, &vid); 4532594e906SNikolay Aleksandrov v = br_vlan_find(vg, vid); 4542594e906SNikolay Aleksandrov if (v && br_vlan_should_use(v)) 45585f46c6bSVlad Yasevich return true; 45685f46c6bSVlad Yasevich 45785f46c6bSVlad Yasevich return false; 45885f46c6bSVlad Yasevich } 45985f46c6bSVlad Yasevich 460e0d7968aSToshiaki Makita /* Called under RCU */ 461e0d7968aSToshiaki Makita bool br_should_learn(struct net_bridge_port *p, struct sk_buff *skb, u16 *vid) 462e0d7968aSToshiaki Makita { 463468e7944SNikolay Aleksandrov struct net_bridge_vlan_group *vg; 464e0d7968aSToshiaki Makita struct net_bridge *br = p->br; 465e0d7968aSToshiaki Makita 46620adfa1aSVlad Yasevich /* If filtering was disabled at input, let it pass. */ 467c095f248SVlad Yasevich if (!br->vlan_enabled) 468e0d7968aSToshiaki Makita return true; 469e0d7968aSToshiaki Makita 470468e7944SNikolay Aleksandrov vg = p->vlgrp; 471468e7944SNikolay Aleksandrov if (!vg || !vg->num_vlans) 472e0d7968aSToshiaki Makita return false; 473e0d7968aSToshiaki Makita 4748580e211SToshiaki Makita if (!br_vlan_get_tag(skb, vid) && skb->vlan_proto != br->vlan_proto) 4758580e211SToshiaki Makita *vid = 0; 4768580e211SToshiaki Makita 477e0d7968aSToshiaki Makita if (!*vid) { 47877751ee8SNikolay Aleksandrov *vid = br_get_pvid(vg); 4793df6bf45SVlad Yasevich if (!*vid) 480e0d7968aSToshiaki Makita return false; 481e0d7968aSToshiaki Makita 482e0d7968aSToshiaki Makita return true; 483e0d7968aSToshiaki Makita } 484e0d7968aSToshiaki Makita 48577751ee8SNikolay Aleksandrov if (br_vlan_find(vg, *vid)) 486e0d7968aSToshiaki Makita return true; 487e0d7968aSToshiaki Makita 488e0d7968aSToshiaki Makita return false; 489e0d7968aSToshiaki Makita } 490e0d7968aSToshiaki Makita 4918adff41cSToshiaki Makita /* Must be protected by RTNL. 4928adff41cSToshiaki Makita * Must be called with vid in range from 1 to 4094 inclusive. 4938adff41cSToshiaki Makita */ 494552406c4SVlad Yasevich int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags) 495243a2e63SVlad Yasevich { 4962594e906SNikolay Aleksandrov struct net_bridge_vlan *vlan; 4972594e906SNikolay Aleksandrov int ret; 498243a2e63SVlad Yasevich 499243a2e63SVlad Yasevich ASSERT_RTNL(); 500243a2e63SVlad Yasevich 5012594e906SNikolay Aleksandrov vlan = br_vlan_find(br->vlgrp, vid); 5022594e906SNikolay Aleksandrov if (vlan) { 5032594e906SNikolay Aleksandrov if (!br_vlan_is_brentry(vlan)) { 5042594e906SNikolay Aleksandrov /* Trying to change flags of non-existent bridge vlan */ 5052594e906SNikolay Aleksandrov if (!(flags & BRIDGE_VLAN_INFO_BRENTRY)) 5062594e906SNikolay Aleksandrov return -EINVAL; 5072594e906SNikolay Aleksandrov /* It was only kept for port vlans, now make it real */ 5082594e906SNikolay Aleksandrov ret = br_fdb_insert(br, NULL, br->dev->dev_addr, 5092594e906SNikolay Aleksandrov vlan->vid); 5102594e906SNikolay Aleksandrov if (ret) { 5112594e906SNikolay Aleksandrov br_err(br, "failed insert local address into bridge forwarding table\n"); 5122594e906SNikolay Aleksandrov return ret; 5132594e906SNikolay Aleksandrov } 5142594e906SNikolay Aleksandrov atomic_inc(&vlan->refcnt); 5152594e906SNikolay Aleksandrov vlan->flags |= BRIDGE_VLAN_INFO_BRENTRY; 5162594e906SNikolay Aleksandrov br->vlgrp->num_vlans++; 5172594e906SNikolay Aleksandrov } 5182594e906SNikolay Aleksandrov __vlan_add_flags(vlan, flags); 5192594e906SNikolay Aleksandrov return 0; 5202594e906SNikolay Aleksandrov } 521243a2e63SVlad Yasevich 5222594e906SNikolay Aleksandrov vlan = kzalloc(sizeof(*vlan), GFP_KERNEL); 5232594e906SNikolay Aleksandrov if (!vlan) 524243a2e63SVlad Yasevich return -ENOMEM; 525243a2e63SVlad Yasevich 5262594e906SNikolay Aleksandrov vlan->vid = vid; 5272594e906SNikolay Aleksandrov vlan->flags = flags | BRIDGE_VLAN_INFO_MASTER; 5282594e906SNikolay Aleksandrov vlan->flags &= ~BRIDGE_VLAN_INFO_PVID; 5292594e906SNikolay Aleksandrov vlan->br = br; 5302594e906SNikolay Aleksandrov if (flags & BRIDGE_VLAN_INFO_BRENTRY) 5312594e906SNikolay Aleksandrov atomic_set(&vlan->refcnt, 1); 5322594e906SNikolay Aleksandrov ret = __vlan_add(vlan, flags); 5332594e906SNikolay Aleksandrov if (ret) 5342594e906SNikolay Aleksandrov kfree(vlan); 535243a2e63SVlad Yasevich 5362594e906SNikolay Aleksandrov return ret; 537243a2e63SVlad Yasevich } 538243a2e63SVlad Yasevich 5398adff41cSToshiaki Makita /* Must be protected by RTNL. 5408adff41cSToshiaki Makita * Must be called with vid in range from 1 to 4094 inclusive. 5418adff41cSToshiaki Makita */ 542243a2e63SVlad Yasevich int br_vlan_delete(struct net_bridge *br, u16 vid) 543243a2e63SVlad Yasevich { 5442594e906SNikolay Aleksandrov struct net_bridge_vlan *v; 545243a2e63SVlad Yasevich 546243a2e63SVlad Yasevich ASSERT_RTNL(); 547243a2e63SVlad Yasevich 5482594e906SNikolay Aleksandrov v = br_vlan_find(br->vlgrp, vid); 5492594e906SNikolay Aleksandrov if (!v || !br_vlan_is_brentry(v)) 5502594e906SNikolay Aleksandrov return -ENOENT; 551243a2e63SVlad Yasevich 552424bb9c9SToshiaki Makita br_fdb_find_delete_local(br, NULL, br->dev->dev_addr, vid); 553bc9a25d2SVlad Yasevich 5542594e906SNikolay Aleksandrov return __vlan_del(v); 555243a2e63SVlad Yasevich } 556243a2e63SVlad Yasevich 557243a2e63SVlad Yasevich void br_vlan_flush(struct net_bridge *br) 558243a2e63SVlad Yasevich { 559243a2e63SVlad Yasevich ASSERT_RTNL(); 560243a2e63SVlad Yasevich 56177751ee8SNikolay Aleksandrov __vlan_flush(br_vlan_group(br)); 562243a2e63SVlad Yasevich } 563243a2e63SVlad Yasevich 5642594e906SNikolay Aleksandrov struct net_bridge_vlan *br_vlan_find(struct net_bridge_vlan_group *vg, u16 vid) 5652b292fb4SToshiaki Makita { 5662594e906SNikolay Aleksandrov if (!vg) 5672594e906SNikolay Aleksandrov return NULL; 5682b292fb4SToshiaki Makita 5692594e906SNikolay Aleksandrov return br_vlan_lookup(&vg->vlan_hash, vid); 5702b292fb4SToshiaki Makita } 5712b292fb4SToshiaki Makita 572204177f3SToshiaki Makita /* Must be protected by RTNL. */ 573204177f3SToshiaki Makita static void recalculate_group_addr(struct net_bridge *br) 574204177f3SToshiaki Makita { 575204177f3SToshiaki Makita if (br->group_addr_set) 576204177f3SToshiaki Makita return; 577204177f3SToshiaki Makita 578204177f3SToshiaki Makita spin_lock_bh(&br->lock); 579204177f3SToshiaki Makita if (!br->vlan_enabled || br->vlan_proto == htons(ETH_P_8021Q)) { 580204177f3SToshiaki Makita /* Bridge Group Address */ 581204177f3SToshiaki Makita br->group_addr[5] = 0x00; 582204177f3SToshiaki Makita } else { /* vlan_enabled && ETH_P_8021AD */ 583204177f3SToshiaki Makita /* Provider Bridge Group Address */ 584204177f3SToshiaki Makita br->group_addr[5] = 0x08; 585204177f3SToshiaki Makita } 586204177f3SToshiaki Makita spin_unlock_bh(&br->lock); 587204177f3SToshiaki Makita } 588204177f3SToshiaki Makita 589204177f3SToshiaki Makita /* Must be protected by RTNL. */ 590204177f3SToshiaki Makita void br_recalculate_fwd_mask(struct net_bridge *br) 591204177f3SToshiaki Makita { 592204177f3SToshiaki Makita if (!br->vlan_enabled || br->vlan_proto == htons(ETH_P_8021Q)) 593204177f3SToshiaki Makita br->group_fwd_mask_required = BR_GROUPFWD_DEFAULT; 594204177f3SToshiaki Makita else /* vlan_enabled && ETH_P_8021AD */ 595204177f3SToshiaki Makita br->group_fwd_mask_required = BR_GROUPFWD_8021AD & 596204177f3SToshiaki Makita ~(1u << br->group_addr[5]); 597204177f3SToshiaki Makita } 598204177f3SToshiaki Makita 599a7854037SNikolay Aleksandrov int __br_vlan_filter_toggle(struct net_bridge *br, unsigned long val) 600243a2e63SVlad Yasevich { 601243a2e63SVlad Yasevich if (br->vlan_enabled == val) 602a7854037SNikolay Aleksandrov return 0; 603243a2e63SVlad Yasevich 604243a2e63SVlad Yasevich br->vlan_enabled = val; 6052796d0c6SVlad Yasevich br_manage_promisc(br); 606204177f3SToshiaki Makita recalculate_group_addr(br); 607204177f3SToshiaki Makita br_recalculate_fwd_mask(br); 608243a2e63SVlad Yasevich 609a7854037SNikolay Aleksandrov return 0; 610a7854037SNikolay Aleksandrov } 611a7854037SNikolay Aleksandrov 612a7854037SNikolay Aleksandrov int br_vlan_filter_toggle(struct net_bridge *br, unsigned long val) 613a7854037SNikolay Aleksandrov { 614a7854037SNikolay Aleksandrov if (!rtnl_trylock()) 615a7854037SNikolay Aleksandrov return restart_syscall(); 616a7854037SNikolay Aleksandrov 617a7854037SNikolay Aleksandrov __br_vlan_filter_toggle(br, val); 618243a2e63SVlad Yasevich rtnl_unlock(); 619a7854037SNikolay Aleksandrov 620243a2e63SVlad Yasevich return 0; 621243a2e63SVlad Yasevich } 622243a2e63SVlad Yasevich 623d2d427b3SToshiaki Makita int __br_vlan_set_proto(struct net_bridge *br, __be16 proto) 624204177f3SToshiaki Makita { 625204177f3SToshiaki Makita int err = 0; 626204177f3SToshiaki Makita struct net_bridge_port *p; 6272594e906SNikolay Aleksandrov struct net_bridge_vlan *vlan; 628d2d427b3SToshiaki Makita __be16 oldproto; 629204177f3SToshiaki Makita 630204177f3SToshiaki Makita if (br->vlan_proto == proto) 631d2d427b3SToshiaki Makita return 0; 632204177f3SToshiaki Makita 633204177f3SToshiaki Makita /* Add VLANs for the new proto to the device filter. */ 634204177f3SToshiaki Makita list_for_each_entry(p, &br->port_list, list) { 6352594e906SNikolay Aleksandrov list_for_each_entry(vlan, &p->vlgrp->vlan_list, vlist) { 6362594e906SNikolay Aleksandrov err = vlan_vid_add(p->dev, proto, vlan->vid); 637204177f3SToshiaki Makita if (err) 638204177f3SToshiaki Makita goto err_filt; 639204177f3SToshiaki Makita } 640204177f3SToshiaki Makita } 641204177f3SToshiaki Makita 642204177f3SToshiaki Makita oldproto = br->vlan_proto; 643204177f3SToshiaki Makita br->vlan_proto = proto; 644204177f3SToshiaki Makita 645204177f3SToshiaki Makita recalculate_group_addr(br); 646204177f3SToshiaki Makita br_recalculate_fwd_mask(br); 647204177f3SToshiaki Makita 648204177f3SToshiaki Makita /* Delete VLANs for the old proto from the device filter. */ 6492594e906SNikolay Aleksandrov list_for_each_entry(p, &br->port_list, list) 6502594e906SNikolay Aleksandrov list_for_each_entry(vlan, &p->vlgrp->vlan_list, vlist) 6512594e906SNikolay Aleksandrov vlan_vid_del(p->dev, oldproto, vlan->vid); 652204177f3SToshiaki Makita 653d2d427b3SToshiaki Makita return 0; 654204177f3SToshiaki Makita 655204177f3SToshiaki Makita err_filt: 6562594e906SNikolay Aleksandrov list_for_each_entry_continue_reverse(vlan, &p->vlgrp->vlan_list, vlist) 6572594e906SNikolay Aleksandrov vlan_vid_del(p->dev, proto, vlan->vid); 658204177f3SToshiaki Makita 6592594e906SNikolay Aleksandrov list_for_each_entry_continue_reverse(p, &br->port_list, list) 6602594e906SNikolay Aleksandrov list_for_each_entry(vlan, &p->vlgrp->vlan_list, vlist) 6612594e906SNikolay Aleksandrov vlan_vid_del(p->dev, proto, vlan->vid); 662204177f3SToshiaki Makita 663d2d427b3SToshiaki Makita return err; 664d2d427b3SToshiaki Makita } 665d2d427b3SToshiaki Makita 666d2d427b3SToshiaki Makita int br_vlan_set_proto(struct net_bridge *br, unsigned long val) 667d2d427b3SToshiaki Makita { 668d2d427b3SToshiaki Makita int err; 669d2d427b3SToshiaki Makita 670d2d427b3SToshiaki Makita if (val != ETH_P_8021Q && val != ETH_P_8021AD) 671d2d427b3SToshiaki Makita return -EPROTONOSUPPORT; 672d2d427b3SToshiaki Makita 673d2d427b3SToshiaki Makita if (!rtnl_trylock()) 674d2d427b3SToshiaki Makita return restart_syscall(); 675d2d427b3SToshiaki Makita 676d2d427b3SToshiaki Makita err = __br_vlan_set_proto(br, htons(val)); 677d2d427b3SToshiaki Makita rtnl_unlock(); 678d2d427b3SToshiaki Makita 679d2d427b3SToshiaki Makita return err; 680204177f3SToshiaki Makita } 681204177f3SToshiaki Makita 68277751ee8SNikolay Aleksandrov static bool vlan_default_pvid(struct net_bridge_vlan_group *vg, u16 vid) 6835be5a2dfSVlad Yasevich { 6842594e906SNikolay Aleksandrov struct net_bridge_vlan *v; 6852594e906SNikolay Aleksandrov 68677751ee8SNikolay Aleksandrov if (vid != vg->pvid) 6872594e906SNikolay Aleksandrov return false; 6882594e906SNikolay Aleksandrov 6892594e906SNikolay Aleksandrov v = br_vlan_lookup(&vg->vlan_hash, vid); 6902594e906SNikolay Aleksandrov if (v && br_vlan_should_use(v) && 6912594e906SNikolay Aleksandrov (v->flags & BRIDGE_VLAN_INFO_UNTAGGED)) 6922594e906SNikolay Aleksandrov return true; 6932594e906SNikolay Aleksandrov 6942594e906SNikolay Aleksandrov return false; 6955be5a2dfSVlad Yasevich } 6965be5a2dfSVlad Yasevich 6975be5a2dfSVlad Yasevich static void br_vlan_disable_default_pvid(struct net_bridge *br) 6985be5a2dfSVlad Yasevich { 6995be5a2dfSVlad Yasevich struct net_bridge_port *p; 7005be5a2dfSVlad Yasevich u16 pvid = br->default_pvid; 7015be5a2dfSVlad Yasevich 7025be5a2dfSVlad Yasevich /* Disable default_pvid on all ports where it is still 7035be5a2dfSVlad Yasevich * configured. 7045be5a2dfSVlad Yasevich */ 70577751ee8SNikolay Aleksandrov if (vlan_default_pvid(br->vlgrp, pvid)) 7065be5a2dfSVlad Yasevich br_vlan_delete(br, pvid); 7075be5a2dfSVlad Yasevich 7085be5a2dfSVlad Yasevich list_for_each_entry(p, &br->port_list, list) { 70977751ee8SNikolay Aleksandrov if (vlan_default_pvid(p->vlgrp, pvid)) 7105be5a2dfSVlad Yasevich nbp_vlan_delete(p, pvid); 7115be5a2dfSVlad Yasevich } 7125be5a2dfSVlad Yasevich 7135be5a2dfSVlad Yasevich br->default_pvid = 0; 7145be5a2dfSVlad Yasevich } 7155be5a2dfSVlad Yasevich 7165be5a2dfSVlad Yasevich static int __br_vlan_set_default_pvid(struct net_bridge *br, u16 pvid) 7175be5a2dfSVlad Yasevich { 7182594e906SNikolay Aleksandrov const struct net_bridge_vlan *pvent; 7195be5a2dfSVlad Yasevich struct net_bridge_port *p; 7205be5a2dfSVlad Yasevich u16 old_pvid; 7215be5a2dfSVlad Yasevich int err = 0; 7225be5a2dfSVlad Yasevich unsigned long *changed; 7235be5a2dfSVlad Yasevich 7245be5a2dfSVlad Yasevich changed = kcalloc(BITS_TO_LONGS(BR_MAX_PORTS), sizeof(unsigned long), 7255be5a2dfSVlad Yasevich GFP_KERNEL); 7265be5a2dfSVlad Yasevich if (!changed) 7275be5a2dfSVlad Yasevich return -ENOMEM; 7285be5a2dfSVlad Yasevich 7295be5a2dfSVlad Yasevich old_pvid = br->default_pvid; 7305be5a2dfSVlad Yasevich 7315be5a2dfSVlad Yasevich /* Update default_pvid config only if we do not conflict with 7325be5a2dfSVlad Yasevich * user configuration. 7335be5a2dfSVlad Yasevich */ 7342594e906SNikolay Aleksandrov pvent = br_vlan_find(br->vlgrp, pvid); 73577751ee8SNikolay Aleksandrov if ((!old_pvid || vlan_default_pvid(br->vlgrp, old_pvid)) && 7362594e906SNikolay Aleksandrov (!pvent || !br_vlan_should_use(pvent))) { 7375be5a2dfSVlad Yasevich err = br_vlan_add(br, pvid, 7385be5a2dfSVlad Yasevich BRIDGE_VLAN_INFO_PVID | 7392594e906SNikolay Aleksandrov BRIDGE_VLAN_INFO_UNTAGGED | 7402594e906SNikolay Aleksandrov BRIDGE_VLAN_INFO_BRENTRY); 7415be5a2dfSVlad Yasevich if (err) 7425be5a2dfSVlad Yasevich goto out; 7435be5a2dfSVlad Yasevich br_vlan_delete(br, old_pvid); 7445be5a2dfSVlad Yasevich set_bit(0, changed); 7455be5a2dfSVlad Yasevich } 7465be5a2dfSVlad Yasevich 7475be5a2dfSVlad Yasevich list_for_each_entry(p, &br->port_list, list) { 7485be5a2dfSVlad Yasevich /* Update default_pvid config only if we do not conflict with 7495be5a2dfSVlad Yasevich * user configuration. 7505be5a2dfSVlad Yasevich */ 7515be5a2dfSVlad Yasevich if ((old_pvid && 75277751ee8SNikolay Aleksandrov !vlan_default_pvid(p->vlgrp, old_pvid)) || 7532594e906SNikolay Aleksandrov br_vlan_find(p->vlgrp, pvid)) 7545be5a2dfSVlad Yasevich continue; 7555be5a2dfSVlad Yasevich 7565be5a2dfSVlad Yasevich err = nbp_vlan_add(p, pvid, 7575be5a2dfSVlad Yasevich BRIDGE_VLAN_INFO_PVID | 7585be5a2dfSVlad Yasevich BRIDGE_VLAN_INFO_UNTAGGED); 7595be5a2dfSVlad Yasevich if (err) 7605be5a2dfSVlad Yasevich goto err_port; 7615be5a2dfSVlad Yasevich nbp_vlan_delete(p, old_pvid); 7625be5a2dfSVlad Yasevich set_bit(p->port_no, changed); 7635be5a2dfSVlad Yasevich } 7645be5a2dfSVlad Yasevich 7655be5a2dfSVlad Yasevich br->default_pvid = pvid; 7665be5a2dfSVlad Yasevich 7675be5a2dfSVlad Yasevich out: 7685be5a2dfSVlad Yasevich kfree(changed); 7695be5a2dfSVlad Yasevich return err; 7705be5a2dfSVlad Yasevich 7715be5a2dfSVlad Yasevich err_port: 7725be5a2dfSVlad Yasevich list_for_each_entry_continue_reverse(p, &br->port_list, list) { 7735be5a2dfSVlad Yasevich if (!test_bit(p->port_no, changed)) 7745be5a2dfSVlad Yasevich continue; 7755be5a2dfSVlad Yasevich 7765be5a2dfSVlad Yasevich if (old_pvid) 7775be5a2dfSVlad Yasevich nbp_vlan_add(p, old_pvid, 7785be5a2dfSVlad Yasevich BRIDGE_VLAN_INFO_PVID | 7795be5a2dfSVlad Yasevich BRIDGE_VLAN_INFO_UNTAGGED); 7805be5a2dfSVlad Yasevich nbp_vlan_delete(p, pvid); 7815be5a2dfSVlad Yasevich } 7825be5a2dfSVlad Yasevich 7835be5a2dfSVlad Yasevich if (test_bit(0, changed)) { 7845be5a2dfSVlad Yasevich if (old_pvid) 7855be5a2dfSVlad Yasevich br_vlan_add(br, old_pvid, 7865be5a2dfSVlad Yasevich BRIDGE_VLAN_INFO_PVID | 7872594e906SNikolay Aleksandrov BRIDGE_VLAN_INFO_UNTAGGED | 7882594e906SNikolay Aleksandrov BRIDGE_VLAN_INFO_BRENTRY); 7895be5a2dfSVlad Yasevich br_vlan_delete(br, pvid); 7905be5a2dfSVlad Yasevich } 7915be5a2dfSVlad Yasevich goto out; 7925be5a2dfSVlad Yasevich } 7935be5a2dfSVlad Yasevich 79496a20d9dSVlad Yasevich int br_vlan_set_default_pvid(struct net_bridge *br, unsigned long val) 79596a20d9dSVlad Yasevich { 79696a20d9dSVlad Yasevich u16 pvid = val; 79796a20d9dSVlad Yasevich int err = 0; 79896a20d9dSVlad Yasevich 7995be5a2dfSVlad Yasevich if (val >= VLAN_VID_MASK) 80096a20d9dSVlad Yasevich return -EINVAL; 80196a20d9dSVlad Yasevich 80296a20d9dSVlad Yasevich if (!rtnl_trylock()) 80396a20d9dSVlad Yasevich return restart_syscall(); 80496a20d9dSVlad Yasevich 80596a20d9dSVlad Yasevich if (pvid == br->default_pvid) 80696a20d9dSVlad Yasevich goto unlock; 80796a20d9dSVlad Yasevich 80896a20d9dSVlad Yasevich /* Only allow default pvid change when filtering is disabled */ 80996a20d9dSVlad Yasevich if (br->vlan_enabled) { 81096a20d9dSVlad Yasevich pr_info_once("Please disable vlan filtering to change default_pvid\n"); 81196a20d9dSVlad Yasevich err = -EPERM; 81296a20d9dSVlad Yasevich goto unlock; 81396a20d9dSVlad Yasevich } 81496a20d9dSVlad Yasevich 8155be5a2dfSVlad Yasevich if (!pvid) 8165be5a2dfSVlad Yasevich br_vlan_disable_default_pvid(br); 8175be5a2dfSVlad Yasevich else 8185be5a2dfSVlad Yasevich err = __br_vlan_set_default_pvid(br, pvid); 81996a20d9dSVlad Yasevich 82096a20d9dSVlad Yasevich unlock: 82196a20d9dSVlad Yasevich rtnl_unlock(); 82296a20d9dSVlad Yasevich return err; 82396a20d9dSVlad Yasevich } 82496a20d9dSVlad Yasevich 8255be5a2dfSVlad Yasevich int br_vlan_init(struct net_bridge *br) 8268580e211SToshiaki Makita { 8272594e906SNikolay Aleksandrov int ret = -ENOMEM; 8282594e906SNikolay Aleksandrov 8292594e906SNikolay Aleksandrov br->vlgrp = kzalloc(sizeof(struct net_bridge_vlan_group), GFP_KERNEL); 8302594e906SNikolay Aleksandrov if (!br->vlgrp) 8312594e906SNikolay Aleksandrov goto out; 8322594e906SNikolay Aleksandrov ret = rhashtable_init(&br->vlgrp->vlan_hash, &br_vlan_rht_params); 8332594e906SNikolay Aleksandrov if (ret) 8342594e906SNikolay Aleksandrov goto err_rhtbl; 8352594e906SNikolay Aleksandrov INIT_LIST_HEAD(&br->vlgrp->vlan_list); 8368580e211SToshiaki Makita br->vlan_proto = htons(ETH_P_8021Q); 83796a20d9dSVlad Yasevich br->default_pvid = 1; 8382594e906SNikolay Aleksandrov ret = br_vlan_add(br, 1, 8392594e906SNikolay Aleksandrov BRIDGE_VLAN_INFO_PVID | BRIDGE_VLAN_INFO_UNTAGGED | 8402594e906SNikolay Aleksandrov BRIDGE_VLAN_INFO_BRENTRY); 8412594e906SNikolay Aleksandrov if (ret) 8422594e906SNikolay Aleksandrov goto err_vlan_add; 8432594e906SNikolay Aleksandrov 8442594e906SNikolay Aleksandrov out: 8452594e906SNikolay Aleksandrov return ret; 8462594e906SNikolay Aleksandrov 8472594e906SNikolay Aleksandrov err_vlan_add: 8482594e906SNikolay Aleksandrov rhashtable_destroy(&br->vlgrp->vlan_hash); 8492594e906SNikolay Aleksandrov err_rhtbl: 8502594e906SNikolay Aleksandrov kfree(br->vlgrp); 8512594e906SNikolay Aleksandrov 8522594e906SNikolay Aleksandrov goto out; 8532594e906SNikolay Aleksandrov } 8542594e906SNikolay Aleksandrov 8552594e906SNikolay Aleksandrov int nbp_vlan_init(struct net_bridge_port *p) 8562594e906SNikolay Aleksandrov { 8572594e906SNikolay Aleksandrov int ret = -ENOMEM; 8582594e906SNikolay Aleksandrov 8592594e906SNikolay Aleksandrov p->vlgrp = kzalloc(sizeof(struct net_bridge_vlan_group), GFP_KERNEL); 8602594e906SNikolay Aleksandrov if (!p->vlgrp) 8612594e906SNikolay Aleksandrov goto out; 8622594e906SNikolay Aleksandrov 8632594e906SNikolay Aleksandrov ret = rhashtable_init(&p->vlgrp->vlan_hash, &br_vlan_rht_params); 8642594e906SNikolay Aleksandrov if (ret) 8652594e906SNikolay Aleksandrov goto err_rhtbl; 8662594e906SNikolay Aleksandrov INIT_LIST_HEAD(&p->vlgrp->vlan_list); 8672594e906SNikolay Aleksandrov if (p->br->default_pvid) { 8682594e906SNikolay Aleksandrov ret = nbp_vlan_add(p, p->br->default_pvid, 8692594e906SNikolay Aleksandrov BRIDGE_VLAN_INFO_PVID | 8702594e906SNikolay Aleksandrov BRIDGE_VLAN_INFO_UNTAGGED); 8712594e906SNikolay Aleksandrov if (ret) 8722594e906SNikolay Aleksandrov goto err_vlan_add; 8732594e906SNikolay Aleksandrov } 8742594e906SNikolay Aleksandrov out: 8752594e906SNikolay Aleksandrov return ret; 8762594e906SNikolay Aleksandrov 8772594e906SNikolay Aleksandrov err_vlan_add: 8782594e906SNikolay Aleksandrov rhashtable_destroy(&p->vlgrp->vlan_hash); 8792594e906SNikolay Aleksandrov err_rhtbl: 8802594e906SNikolay Aleksandrov kfree(p->vlgrp); 8812594e906SNikolay Aleksandrov 8822594e906SNikolay Aleksandrov goto out; 8838580e211SToshiaki Makita } 8848580e211SToshiaki Makita 8858adff41cSToshiaki Makita /* Must be protected by RTNL. 8868adff41cSToshiaki Makita * Must be called with vid in range from 1 to 4094 inclusive. 8878adff41cSToshiaki Makita */ 888552406c4SVlad Yasevich int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags) 889243a2e63SVlad Yasevich { 8902594e906SNikolay Aleksandrov struct net_bridge_vlan *vlan; 8912594e906SNikolay Aleksandrov int ret; 892243a2e63SVlad Yasevich 893243a2e63SVlad Yasevich ASSERT_RTNL(); 894243a2e63SVlad Yasevich 8952594e906SNikolay Aleksandrov vlan = br_vlan_find(port->vlgrp, vid); 8962594e906SNikolay Aleksandrov if (vlan) { 8972594e906SNikolay Aleksandrov __vlan_add_flags(vlan, flags); 8982594e906SNikolay Aleksandrov return 0; 899243a2e63SVlad Yasevich } 900243a2e63SVlad Yasevich 9012594e906SNikolay Aleksandrov vlan = kzalloc(sizeof(*vlan), GFP_KERNEL); 9022594e906SNikolay Aleksandrov if (!vlan) 9032594e906SNikolay Aleksandrov return -ENOMEM; 904243a2e63SVlad Yasevich 9052594e906SNikolay Aleksandrov vlan->vid = vid; 9062594e906SNikolay Aleksandrov vlan->port = port; 9072594e906SNikolay Aleksandrov ret = __vlan_add(vlan, flags); 9082594e906SNikolay Aleksandrov if (ret) 9092594e906SNikolay Aleksandrov kfree(vlan); 910243a2e63SVlad Yasevich 9112594e906SNikolay Aleksandrov return ret; 912243a2e63SVlad Yasevich } 913243a2e63SVlad Yasevich 9148adff41cSToshiaki Makita /* Must be protected by RTNL. 9158adff41cSToshiaki Makita * Must be called with vid in range from 1 to 4094 inclusive. 9168adff41cSToshiaki Makita */ 917243a2e63SVlad Yasevich int nbp_vlan_delete(struct net_bridge_port *port, u16 vid) 918243a2e63SVlad Yasevich { 9192594e906SNikolay Aleksandrov struct net_bridge_vlan *v; 920243a2e63SVlad Yasevich 921243a2e63SVlad Yasevich ASSERT_RTNL(); 922243a2e63SVlad Yasevich 9232594e906SNikolay Aleksandrov v = br_vlan_find(port->vlgrp, vid); 9242594e906SNikolay Aleksandrov if (!v) 9252594e906SNikolay Aleksandrov return -ENOENT; 926424bb9c9SToshiaki Makita br_fdb_find_delete_local(port->br, port, port->dev->dev_addr, vid); 9271ea2d020SNikolay Aleksandrov br_fdb_delete_by_port(port->br, port, vid, 0); 928bc9a25d2SVlad Yasevich 9292594e906SNikolay Aleksandrov return __vlan_del(v); 930243a2e63SVlad Yasevich } 931243a2e63SVlad Yasevich 932243a2e63SVlad Yasevich void nbp_vlan_flush(struct net_bridge_port *port) 933243a2e63SVlad Yasevich { 9342594e906SNikolay Aleksandrov struct net_bridge_vlan *vlan; 935243a2e63SVlad Yasevich 936243a2e63SVlad Yasevich ASSERT_RTNL(); 937243a2e63SVlad Yasevich 9382594e906SNikolay Aleksandrov list_for_each_entry(vlan, &port->vlgrp->vlan_list, vlist) 9392594e906SNikolay Aleksandrov vlan_vid_del(port->dev, port->br->vlan_proto, vlan->vid); 940243a2e63SVlad Yasevich 94177751ee8SNikolay Aleksandrov __vlan_flush(nbp_vlan_group(port)); 9425be5a2dfSVlad Yasevich } 943