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 9552406c4SVlad Yasevich static void __vlan_add_pvid(struct net_port_vlans *v, u16 vid) 10552406c4SVlad Yasevich { 11552406c4SVlad Yasevich if (v->pvid == vid) 12552406c4SVlad Yasevich return; 13552406c4SVlad Yasevich 14552406c4SVlad Yasevich smp_wmb(); 15552406c4SVlad Yasevich v->pvid = vid; 16552406c4SVlad Yasevich } 17552406c4SVlad Yasevich 18552406c4SVlad Yasevich static void __vlan_delete_pvid(struct net_port_vlans *v, u16 vid) 19552406c4SVlad Yasevich { 20552406c4SVlad Yasevich if (v->pvid != vid) 21552406c4SVlad Yasevich return; 22552406c4SVlad Yasevich 23552406c4SVlad Yasevich smp_wmb(); 24552406c4SVlad Yasevich v->pvid = 0; 25552406c4SVlad Yasevich } 26552406c4SVlad Yasevich 2735e03f3aSVlad Yasevich static void __vlan_add_flags(struct net_port_vlans *v, u16 vid, u16 flags) 2835e03f3aSVlad Yasevich { 2935e03f3aSVlad Yasevich if (flags & BRIDGE_VLAN_INFO_PVID) 3035e03f3aSVlad Yasevich __vlan_add_pvid(v, vid); 31635126b7SVlad Yasevich else 32635126b7SVlad Yasevich __vlan_delete_pvid(v, vid); 3335e03f3aSVlad Yasevich 3435e03f3aSVlad Yasevich if (flags & BRIDGE_VLAN_INFO_UNTAGGED) 3535e03f3aSVlad Yasevich set_bit(vid, v->untagged_bitmap); 36635126b7SVlad Yasevich else 37635126b7SVlad Yasevich clear_bit(vid, v->untagged_bitmap); 3835e03f3aSVlad Yasevich } 3935e03f3aSVlad Yasevich 407f109539SScott Feldman static int __vlan_vid_add(struct net_device *dev, struct net_bridge *br, 417f109539SScott Feldman u16 vid, u16 flags) 427f109539SScott Feldman { 437f109539SScott Feldman const struct net_device_ops *ops = dev->netdev_ops; 447f109539SScott Feldman int err; 457f109539SScott Feldman 467f109539SScott Feldman /* If driver uses VLAN ndo ops, use 8021q to install vid 477f109539SScott Feldman * on device, otherwise try switchdev ops to install vid. 487f109539SScott Feldman */ 497f109539SScott Feldman 507f109539SScott Feldman if (ops->ndo_vlan_rx_add_vid) { 517f109539SScott Feldman err = vlan_vid_add(dev, br->vlan_proto, vid); 527f109539SScott Feldman } else { 537f109539SScott Feldman struct switchdev_obj vlan_obj = { 547f109539SScott Feldman .id = SWITCHDEV_OBJ_PORT_VLAN, 557f109539SScott Feldman .u.vlan = { 567f109539SScott Feldman .flags = flags, 573e3a78b4SScott Feldman .vid_begin = vid, 587f109539SScott Feldman .vid_end = vid, 597f109539SScott Feldman }, 607f109539SScott Feldman }; 617f109539SScott Feldman 627f109539SScott Feldman err = switchdev_port_obj_add(dev, &vlan_obj); 637f109539SScott Feldman if (err == -EOPNOTSUPP) 647f109539SScott Feldman err = 0; 657f109539SScott Feldman } 667f109539SScott Feldman 677f109539SScott Feldman return err; 687f109539SScott Feldman } 697f109539SScott Feldman 70552406c4SVlad Yasevich static int __vlan_add(struct net_port_vlans *v, u16 vid, u16 flags) 71243a2e63SVlad Yasevich { 72bc9a25d2SVlad Yasevich struct net_bridge_port *p = NULL; 73bc9a25d2SVlad Yasevich struct net_bridge *br; 74bc9a25d2SVlad Yasevich struct net_device *dev; 75243a2e63SVlad Yasevich int err; 76243a2e63SVlad Yasevich 77552406c4SVlad Yasevich if (test_bit(vid, v->vlan_bitmap)) { 7835e03f3aSVlad Yasevich __vlan_add_flags(v, vid, flags); 79552406c4SVlad Yasevich return 0; 80552406c4SVlad Yasevich } 81243a2e63SVlad Yasevich 82bc9a25d2SVlad Yasevich if (v->port_idx) { 83bc9a25d2SVlad Yasevich p = v->parent.port; 84bc9a25d2SVlad Yasevich br = p->br; 85bc9a25d2SVlad Yasevich dev = p->dev; 86bc9a25d2SVlad Yasevich } else { 87bc9a25d2SVlad Yasevich br = v->parent.br; 88bc9a25d2SVlad Yasevich dev = br->dev; 89bc9a25d2SVlad Yasevich } 90243a2e63SVlad Yasevich 9119236837SToshiaki Makita if (p) { 92243a2e63SVlad Yasevich /* Add VLAN to the device filter if it is supported. 93fdb0a662SToshiaki Makita * This ensures tagged traffic enters the bridge when 94fdb0a662SToshiaki Makita * promiscuous mode is disabled by br_manage_promisc(). 95243a2e63SVlad Yasevich */ 967f109539SScott Feldman err = __vlan_vid_add(dev, br, vid, flags); 97243a2e63SVlad Yasevich if (err) 98243a2e63SVlad Yasevich return err; 99243a2e63SVlad Yasevich } 100bc9a25d2SVlad Yasevich 101bc9a25d2SVlad Yasevich err = br_fdb_insert(br, p, dev->dev_addr, vid); 102bc9a25d2SVlad Yasevich if (err) { 103bc9a25d2SVlad Yasevich br_err(br, "failed insert local address into bridge " 104bc9a25d2SVlad Yasevich "forwarding table\n"); 105bc9a25d2SVlad Yasevich goto out_filt; 106bc9a25d2SVlad Yasevich } 107bc9a25d2SVlad Yasevich 108243a2e63SVlad Yasevich set_bit(vid, v->vlan_bitmap); 1096cbdceebSVlad Yasevich v->num_vlans++; 11035e03f3aSVlad Yasevich __vlan_add_flags(v, vid, flags); 111552406c4SVlad Yasevich 112243a2e63SVlad Yasevich return 0; 113bc9a25d2SVlad Yasevich 114bc9a25d2SVlad Yasevich out_filt: 11519236837SToshiaki Makita if (p) 1168580e211SToshiaki Makita vlan_vid_del(dev, br->vlan_proto, vid); 117bc9a25d2SVlad Yasevich return err; 118243a2e63SVlad Yasevich } 119243a2e63SVlad Yasevich 1207f109539SScott Feldman static void __vlan_vid_del(struct net_device *dev, struct net_bridge *br, 1217f109539SScott Feldman u16 vid) 1227f109539SScott Feldman { 1237f109539SScott Feldman const struct net_device_ops *ops = dev->netdev_ops; 1247f109539SScott Feldman 1257f109539SScott Feldman /* If driver uses VLAN ndo ops, use 8021q to delete vid 1267f109539SScott Feldman * on device, otherwise try switchdev ops to delete vid. 1277f109539SScott Feldman */ 1287f109539SScott Feldman 1297f109539SScott Feldman if (ops->ndo_vlan_rx_kill_vid) { 1307f109539SScott Feldman vlan_vid_del(dev, br->vlan_proto, vid); 1317f109539SScott Feldman } else { 1327f109539SScott Feldman struct switchdev_obj vlan_obj = { 1337f109539SScott Feldman .id = SWITCHDEV_OBJ_PORT_VLAN, 1347f109539SScott Feldman .u.vlan = { 1353e3a78b4SScott Feldman .vid_begin = vid, 1367f109539SScott Feldman .vid_end = vid, 1377f109539SScott Feldman }, 1387f109539SScott Feldman }; 1397f109539SScott Feldman 1407f109539SScott Feldman switchdev_port_obj_del(dev, &vlan_obj); 1417f109539SScott Feldman } 1427f109539SScott Feldman } 1437f109539SScott Feldman 144243a2e63SVlad Yasevich static int __vlan_del(struct net_port_vlans *v, u16 vid) 145243a2e63SVlad Yasevich { 146243a2e63SVlad Yasevich if (!test_bit(vid, v->vlan_bitmap)) 147243a2e63SVlad Yasevich return -EINVAL; 148243a2e63SVlad Yasevich 149552406c4SVlad Yasevich __vlan_delete_pvid(v, vid); 15035e03f3aSVlad Yasevich clear_bit(vid, v->untagged_bitmap); 151552406c4SVlad Yasevich 1528580e211SToshiaki Makita if (v->port_idx) { 1538580e211SToshiaki Makita struct net_bridge_port *p = v->parent.port; 1547f109539SScott Feldman __vlan_vid_del(p->dev, p->br, vid); 1558580e211SToshiaki Makita } 156243a2e63SVlad Yasevich 157243a2e63SVlad Yasevich clear_bit(vid, v->vlan_bitmap); 1586cbdceebSVlad Yasevich v->num_vlans--; 159ef40b7efSToshiaki Makita if (bitmap_empty(v->vlan_bitmap, VLAN_N_VID)) { 160243a2e63SVlad Yasevich if (v->port_idx) 161cd18721eSMonam Agarwal RCU_INIT_POINTER(v->parent.port->vlan_info, NULL); 162243a2e63SVlad Yasevich else 163cd18721eSMonam Agarwal RCU_INIT_POINTER(v->parent.br->vlan_info, NULL); 164243a2e63SVlad Yasevich kfree_rcu(v, rcu); 165243a2e63SVlad Yasevich } 166243a2e63SVlad Yasevich return 0; 167243a2e63SVlad Yasevich } 168243a2e63SVlad Yasevich 169243a2e63SVlad Yasevich static void __vlan_flush(struct net_port_vlans *v) 170243a2e63SVlad Yasevich { 171552406c4SVlad Yasevich smp_wmb(); 172552406c4SVlad Yasevich v->pvid = 0; 173ef40b7efSToshiaki Makita bitmap_zero(v->vlan_bitmap, VLAN_N_VID); 174243a2e63SVlad Yasevich if (v->port_idx) 175cd18721eSMonam Agarwal RCU_INIT_POINTER(v->parent.port->vlan_info, NULL); 176243a2e63SVlad Yasevich else 177cd18721eSMonam Agarwal RCU_INIT_POINTER(v->parent.br->vlan_info, NULL); 178243a2e63SVlad Yasevich kfree_rcu(v, rcu); 179243a2e63SVlad Yasevich } 180243a2e63SVlad Yasevich 18178851988SVlad Yasevich struct sk_buff *br_handle_vlan(struct net_bridge *br, 18278851988SVlad Yasevich const struct net_port_vlans *pv, 183a37b85c9SVlad Yasevich struct sk_buff *skb) 184a37b85c9SVlad Yasevich { 185a37b85c9SVlad Yasevich u16 vid; 186a37b85c9SVlad Yasevich 18720adfa1aSVlad Yasevich /* If this packet was not filtered at input, let it pass */ 18820adfa1aSVlad Yasevich if (!BR_INPUT_SKB_CB(skb)->vlan_filtered) 18978851988SVlad Yasevich goto out; 19078851988SVlad Yasevich 191fc92f745SVlad Yasevich /* Vlan filter table must be configured at this point. The 192fc92f745SVlad Yasevich * only exception is the bridge is set in promisc mode and the 193fc92f745SVlad Yasevich * packet is destined for the bridge device. In this case 194fc92f745SVlad Yasevich * pass the packet as is. 195fc92f745SVlad Yasevich */ 196fc92f745SVlad Yasevich if (!pv) { 197fc92f745SVlad Yasevich if ((br->dev->flags & IFF_PROMISC) && skb->dev == br->dev) { 198fc92f745SVlad Yasevich goto out; 199fc92f745SVlad Yasevich } else { 200fc92f745SVlad Yasevich kfree_skb(skb); 201fc92f745SVlad Yasevich return NULL; 202fc92f745SVlad Yasevich } 203fc92f745SVlad Yasevich } 204fc92f745SVlad Yasevich 20578851988SVlad Yasevich /* At this point, we know that the frame was filtered and contains 20635e03f3aSVlad Yasevich * a valid vlan id. If the vlan id is set in the untagged bitmap, 2071a81a2e0Stanxiaojun * send untagged; otherwise, send tagged. 20878851988SVlad Yasevich */ 20978851988SVlad Yasevich br_vlan_get_tag(skb, &vid); 21035e03f3aSVlad Yasevich if (test_bit(vid, pv->untagged_bitmap)) 21199b192daSToshiaki Makita skb->vlan_tci = 0; 21278851988SVlad Yasevich 21378851988SVlad Yasevich out: 21478851988SVlad Yasevich return skb; 21578851988SVlad Yasevich } 21678851988SVlad Yasevich 21778851988SVlad Yasevich /* Called under RCU */ 21878851988SVlad Yasevich bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v, 21978851988SVlad Yasevich struct sk_buff *skb, u16 *vid) 22078851988SVlad Yasevich { 2218580e211SToshiaki Makita bool tagged; 2228580e211SToshiaki Makita __be16 proto; 223b90356ceSToshiaki Makita 224a37b85c9SVlad Yasevich /* If VLAN filtering is disabled on the bridge, all packets are 225a37b85c9SVlad Yasevich * permitted. 226a37b85c9SVlad Yasevich */ 22720adfa1aSVlad Yasevich if (!br->vlan_enabled) { 22820adfa1aSVlad Yasevich BR_INPUT_SKB_CB(skb)->vlan_filtered = false; 229a37b85c9SVlad Yasevich return true; 23020adfa1aSVlad Yasevich } 231a37b85c9SVlad Yasevich 232a37b85c9SVlad Yasevich /* If there are no vlan in the permitted list, all packets are 233a37b85c9SVlad Yasevich * rejected. 234a37b85c9SVlad Yasevich */ 235a37b85c9SVlad Yasevich if (!v) 236eb707618SToshiaki Makita goto drop; 237a37b85c9SVlad Yasevich 23820adfa1aSVlad Yasevich BR_INPUT_SKB_CB(skb)->vlan_filtered = true; 2398580e211SToshiaki Makita proto = br->vlan_proto; 2408580e211SToshiaki Makita 24112464bb8SToshiaki Makita /* If vlan tx offload is disabled on bridge device and frame was 24212464bb8SToshiaki Makita * sent from vlan device on the bridge device, it does not have 24312464bb8SToshiaki Makita * HW accelerated vlan tag. 24412464bb8SToshiaki Makita */ 245df8a39deSJiri Pirko if (unlikely(!skb_vlan_tag_present(skb) && 2468580e211SToshiaki Makita skb->protocol == proto)) { 2470d5501c1SVlad Yasevich skb = skb_vlan_untag(skb); 24812464bb8SToshiaki Makita if (unlikely(!skb)) 24912464bb8SToshiaki Makita return false; 25012464bb8SToshiaki Makita } 25112464bb8SToshiaki Makita 2528580e211SToshiaki Makita if (!br_vlan_get_tag(skb, vid)) { 2538580e211SToshiaki Makita /* Tagged frame */ 2548580e211SToshiaki Makita if (skb->vlan_proto != proto) { 2558580e211SToshiaki Makita /* Protocol-mismatch, empty out vlan_tci for new tag */ 2568580e211SToshiaki Makita skb_push(skb, ETH_HLEN); 25762749e2cSJiri Pirko skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto, 258df8a39deSJiri Pirko skb_vlan_tag_get(skb)); 2598580e211SToshiaki Makita if (unlikely(!skb)) 2608580e211SToshiaki Makita return false; 2618580e211SToshiaki Makita 2628580e211SToshiaki Makita skb_pull(skb, ETH_HLEN); 2638580e211SToshiaki Makita skb_reset_mac_len(skb); 2648580e211SToshiaki Makita *vid = 0; 2658580e211SToshiaki Makita tagged = false; 2668580e211SToshiaki Makita } else { 2678580e211SToshiaki Makita tagged = true; 2688580e211SToshiaki Makita } 2698580e211SToshiaki Makita } else { 2708580e211SToshiaki Makita /* Untagged frame */ 2718580e211SToshiaki Makita tagged = false; 2728580e211SToshiaki Makita } 2738580e211SToshiaki Makita 274b90356ceSToshiaki Makita if (!*vid) { 27578851988SVlad Yasevich u16 pvid = br_get_pvid(v); 27678851988SVlad Yasevich 277b90356ceSToshiaki Makita /* Frame had a tag with VID 0 or did not have a tag. 278b90356ceSToshiaki Makita * See if pvid is set on this port. That tells us which 279b90356ceSToshiaki Makita * vlan untagged or priority-tagged traffic belongs to. 28078851988SVlad Yasevich */ 2813df6bf45SVlad Yasevich if (!pvid) 282eb707618SToshiaki Makita goto drop; 28378851988SVlad Yasevich 284b90356ceSToshiaki Makita /* PVID is set on this port. Any untagged or priority-tagged 285b90356ceSToshiaki Makita * ingress frame is considered to belong to this vlan. 28678851988SVlad Yasevich */ 287dfb5fa32SToshiaki Makita *vid = pvid; 2888580e211SToshiaki Makita if (likely(!tagged)) 289b90356ceSToshiaki Makita /* Untagged Frame. */ 2908580e211SToshiaki Makita __vlan_hwaccel_put_tag(skb, proto, pvid); 291b90356ceSToshiaki Makita else 292b90356ceSToshiaki Makita /* Priority-tagged Frame. 293b90356ceSToshiaki Makita * At this point, We know that skb->vlan_tci had 294b90356ceSToshiaki Makita * VLAN_TAG_PRESENT bit and its VID field was 0x000. 295b90356ceSToshiaki Makita * We update only VID field and preserve PCP field. 296b90356ceSToshiaki Makita */ 297b90356ceSToshiaki Makita skb->vlan_tci |= pvid; 298b90356ceSToshiaki Makita 29978851988SVlad Yasevich return true; 30078851988SVlad Yasevich } 30178851988SVlad Yasevich 30278851988SVlad Yasevich /* Frame had a valid vlan tag. See if vlan is allowed */ 30378851988SVlad Yasevich if (test_bit(*vid, v->vlan_bitmap)) 304a37b85c9SVlad Yasevich return true; 305eb707618SToshiaki Makita drop: 306eb707618SToshiaki Makita kfree_skb(skb); 307a37b85c9SVlad Yasevich return false; 308a37b85c9SVlad Yasevich } 309a37b85c9SVlad Yasevich 31085f46c6bSVlad Yasevich /* Called under RCU. */ 31185f46c6bSVlad Yasevich bool br_allowed_egress(struct net_bridge *br, 31285f46c6bSVlad Yasevich const struct net_port_vlans *v, 31385f46c6bSVlad Yasevich const struct sk_buff *skb) 31485f46c6bSVlad Yasevich { 31585f46c6bSVlad Yasevich u16 vid; 31685f46c6bSVlad Yasevich 31720adfa1aSVlad Yasevich /* If this packet was not filtered at input, let it pass */ 31820adfa1aSVlad Yasevich if (!BR_INPUT_SKB_CB(skb)->vlan_filtered) 31985f46c6bSVlad Yasevich return true; 32085f46c6bSVlad Yasevich 32185f46c6bSVlad Yasevich if (!v) 32285f46c6bSVlad Yasevich return false; 32385f46c6bSVlad Yasevich 32485f46c6bSVlad Yasevich br_vlan_get_tag(skb, &vid); 32585f46c6bSVlad Yasevich if (test_bit(vid, v->vlan_bitmap)) 32685f46c6bSVlad Yasevich return true; 32785f46c6bSVlad Yasevich 32885f46c6bSVlad Yasevich return false; 32985f46c6bSVlad Yasevich } 33085f46c6bSVlad Yasevich 331e0d7968aSToshiaki Makita /* Called under RCU */ 332e0d7968aSToshiaki Makita bool br_should_learn(struct net_bridge_port *p, struct sk_buff *skb, u16 *vid) 333e0d7968aSToshiaki Makita { 334e0d7968aSToshiaki Makita struct net_bridge *br = p->br; 335e0d7968aSToshiaki Makita struct net_port_vlans *v; 336e0d7968aSToshiaki Makita 33720adfa1aSVlad Yasevich /* If filtering was disabled at input, let it pass. */ 338c095f248SVlad Yasevich if (!br->vlan_enabled) 339e0d7968aSToshiaki Makita return true; 340e0d7968aSToshiaki Makita 341e0d7968aSToshiaki Makita v = rcu_dereference(p->vlan_info); 342e0d7968aSToshiaki Makita if (!v) 343e0d7968aSToshiaki Makita return false; 344e0d7968aSToshiaki Makita 3458580e211SToshiaki Makita if (!br_vlan_get_tag(skb, vid) && skb->vlan_proto != br->vlan_proto) 3468580e211SToshiaki Makita *vid = 0; 3478580e211SToshiaki Makita 348e0d7968aSToshiaki Makita if (!*vid) { 349e0d7968aSToshiaki Makita *vid = br_get_pvid(v); 3503df6bf45SVlad Yasevich if (!*vid) 351e0d7968aSToshiaki Makita return false; 352e0d7968aSToshiaki Makita 353e0d7968aSToshiaki Makita return true; 354e0d7968aSToshiaki Makita } 355e0d7968aSToshiaki Makita 356e0d7968aSToshiaki Makita if (test_bit(*vid, v->vlan_bitmap)) 357e0d7968aSToshiaki Makita return true; 358e0d7968aSToshiaki Makita 359e0d7968aSToshiaki Makita return false; 360e0d7968aSToshiaki Makita } 361e0d7968aSToshiaki Makita 3628adff41cSToshiaki Makita /* Must be protected by RTNL. 3638adff41cSToshiaki Makita * Must be called with vid in range from 1 to 4094 inclusive. 3648adff41cSToshiaki Makita */ 365552406c4SVlad Yasevich int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags) 366243a2e63SVlad Yasevich { 367243a2e63SVlad Yasevich struct net_port_vlans *pv = NULL; 368243a2e63SVlad Yasevich int err; 369243a2e63SVlad Yasevich 370243a2e63SVlad Yasevich ASSERT_RTNL(); 371243a2e63SVlad Yasevich 372243a2e63SVlad Yasevich pv = rtnl_dereference(br->vlan_info); 373243a2e63SVlad Yasevich if (pv) 374552406c4SVlad Yasevich return __vlan_add(pv, vid, flags); 375243a2e63SVlad Yasevich 376243a2e63SVlad Yasevich /* Create port vlan infomration 377243a2e63SVlad Yasevich */ 378243a2e63SVlad Yasevich pv = kzalloc(sizeof(*pv), GFP_KERNEL); 379243a2e63SVlad Yasevich if (!pv) 380243a2e63SVlad Yasevich return -ENOMEM; 381243a2e63SVlad Yasevich 382243a2e63SVlad Yasevich pv->parent.br = br; 383552406c4SVlad Yasevich err = __vlan_add(pv, vid, flags); 384243a2e63SVlad Yasevich if (err) 385243a2e63SVlad Yasevich goto out; 386243a2e63SVlad Yasevich 387243a2e63SVlad Yasevich rcu_assign_pointer(br->vlan_info, pv); 388243a2e63SVlad Yasevich return 0; 389243a2e63SVlad Yasevich out: 390243a2e63SVlad Yasevich kfree(pv); 391243a2e63SVlad Yasevich return err; 392243a2e63SVlad Yasevich } 393243a2e63SVlad Yasevich 3948adff41cSToshiaki Makita /* Must be protected by RTNL. 3958adff41cSToshiaki Makita * Must be called with vid in range from 1 to 4094 inclusive. 3968adff41cSToshiaki Makita */ 397243a2e63SVlad Yasevich int br_vlan_delete(struct net_bridge *br, u16 vid) 398243a2e63SVlad Yasevich { 399243a2e63SVlad Yasevich struct net_port_vlans *pv; 400243a2e63SVlad Yasevich 401243a2e63SVlad Yasevich ASSERT_RTNL(); 402243a2e63SVlad Yasevich 403243a2e63SVlad Yasevich pv = rtnl_dereference(br->vlan_info); 404243a2e63SVlad Yasevich if (!pv) 405243a2e63SVlad Yasevich return -EINVAL; 406243a2e63SVlad Yasevich 407424bb9c9SToshiaki Makita br_fdb_find_delete_local(br, NULL, br->dev->dev_addr, vid); 408bc9a25d2SVlad Yasevich 409243a2e63SVlad Yasevich __vlan_del(pv, vid); 410243a2e63SVlad Yasevich return 0; 411243a2e63SVlad Yasevich } 412243a2e63SVlad Yasevich 413243a2e63SVlad Yasevich void br_vlan_flush(struct net_bridge *br) 414243a2e63SVlad Yasevich { 415243a2e63SVlad Yasevich struct net_port_vlans *pv; 416243a2e63SVlad Yasevich 417243a2e63SVlad Yasevich ASSERT_RTNL(); 418243a2e63SVlad Yasevich pv = rtnl_dereference(br->vlan_info); 419243a2e63SVlad Yasevich if (!pv) 420243a2e63SVlad Yasevich return; 421243a2e63SVlad Yasevich 422243a2e63SVlad Yasevich __vlan_flush(pv); 423243a2e63SVlad Yasevich } 424243a2e63SVlad Yasevich 4252b292fb4SToshiaki Makita bool br_vlan_find(struct net_bridge *br, u16 vid) 4262b292fb4SToshiaki Makita { 4272b292fb4SToshiaki Makita struct net_port_vlans *pv; 4282b292fb4SToshiaki Makita bool found = false; 4292b292fb4SToshiaki Makita 4302b292fb4SToshiaki Makita rcu_read_lock(); 4312b292fb4SToshiaki Makita pv = rcu_dereference(br->vlan_info); 4322b292fb4SToshiaki Makita 4332b292fb4SToshiaki Makita if (!pv) 4342b292fb4SToshiaki Makita goto out; 4352b292fb4SToshiaki Makita 4362b292fb4SToshiaki Makita if (test_bit(vid, pv->vlan_bitmap)) 4372b292fb4SToshiaki Makita found = true; 4382b292fb4SToshiaki Makita 4392b292fb4SToshiaki Makita out: 4402b292fb4SToshiaki Makita rcu_read_unlock(); 4412b292fb4SToshiaki Makita return found; 4422b292fb4SToshiaki Makita } 4432b292fb4SToshiaki Makita 444204177f3SToshiaki Makita /* Must be protected by RTNL. */ 445204177f3SToshiaki Makita static void recalculate_group_addr(struct net_bridge *br) 446204177f3SToshiaki Makita { 447204177f3SToshiaki Makita if (br->group_addr_set) 448204177f3SToshiaki Makita return; 449204177f3SToshiaki Makita 450204177f3SToshiaki Makita spin_lock_bh(&br->lock); 451204177f3SToshiaki Makita if (!br->vlan_enabled || br->vlan_proto == htons(ETH_P_8021Q)) { 452204177f3SToshiaki Makita /* Bridge Group Address */ 453204177f3SToshiaki Makita br->group_addr[5] = 0x00; 454204177f3SToshiaki Makita } else { /* vlan_enabled && ETH_P_8021AD */ 455204177f3SToshiaki Makita /* Provider Bridge Group Address */ 456204177f3SToshiaki Makita br->group_addr[5] = 0x08; 457204177f3SToshiaki Makita } 458204177f3SToshiaki Makita spin_unlock_bh(&br->lock); 459204177f3SToshiaki Makita } 460204177f3SToshiaki Makita 461204177f3SToshiaki Makita /* Must be protected by RTNL. */ 462204177f3SToshiaki Makita void br_recalculate_fwd_mask(struct net_bridge *br) 463204177f3SToshiaki Makita { 464204177f3SToshiaki Makita if (!br->vlan_enabled || br->vlan_proto == htons(ETH_P_8021Q)) 465204177f3SToshiaki Makita br->group_fwd_mask_required = BR_GROUPFWD_DEFAULT; 466204177f3SToshiaki Makita else /* vlan_enabled && ETH_P_8021AD */ 467204177f3SToshiaki Makita br->group_fwd_mask_required = BR_GROUPFWD_8021AD & 468204177f3SToshiaki Makita ~(1u << br->group_addr[5]); 469204177f3SToshiaki Makita } 470204177f3SToshiaki Makita 471a7854037SNikolay Aleksandrov int __br_vlan_filter_toggle(struct net_bridge *br, unsigned long val) 472243a2e63SVlad Yasevich { 473243a2e63SVlad Yasevich if (br->vlan_enabled == val) 474a7854037SNikolay Aleksandrov return 0; 475243a2e63SVlad Yasevich 476243a2e63SVlad Yasevich br->vlan_enabled = val; 4772796d0c6SVlad Yasevich br_manage_promisc(br); 478204177f3SToshiaki Makita recalculate_group_addr(br); 479204177f3SToshiaki Makita br_recalculate_fwd_mask(br); 480243a2e63SVlad Yasevich 481a7854037SNikolay Aleksandrov return 0; 482a7854037SNikolay Aleksandrov } 483a7854037SNikolay Aleksandrov 484a7854037SNikolay Aleksandrov int br_vlan_filter_toggle(struct net_bridge *br, unsigned long val) 485a7854037SNikolay Aleksandrov { 486a7854037SNikolay Aleksandrov if (!rtnl_trylock()) 487a7854037SNikolay Aleksandrov return restart_syscall(); 488a7854037SNikolay Aleksandrov 489a7854037SNikolay Aleksandrov __br_vlan_filter_toggle(br, val); 490243a2e63SVlad Yasevich rtnl_unlock(); 491a7854037SNikolay Aleksandrov 492243a2e63SVlad Yasevich return 0; 493243a2e63SVlad Yasevich } 494243a2e63SVlad Yasevich 495204177f3SToshiaki Makita int br_vlan_set_proto(struct net_bridge *br, unsigned long val) 496204177f3SToshiaki Makita { 497204177f3SToshiaki Makita int err = 0; 498204177f3SToshiaki Makita struct net_bridge_port *p; 499204177f3SToshiaki Makita struct net_port_vlans *pv; 500204177f3SToshiaki Makita __be16 proto, oldproto; 501204177f3SToshiaki Makita u16 vid, errvid; 502204177f3SToshiaki Makita 503204177f3SToshiaki Makita if (val != ETH_P_8021Q && val != ETH_P_8021AD) 504204177f3SToshiaki Makita return -EPROTONOSUPPORT; 505204177f3SToshiaki Makita 506204177f3SToshiaki Makita if (!rtnl_trylock()) 507204177f3SToshiaki Makita return restart_syscall(); 508204177f3SToshiaki Makita 509204177f3SToshiaki Makita proto = htons(val); 510204177f3SToshiaki Makita if (br->vlan_proto == proto) 511204177f3SToshiaki Makita goto unlock; 512204177f3SToshiaki Makita 513204177f3SToshiaki Makita /* Add VLANs for the new proto to the device filter. */ 514204177f3SToshiaki Makita list_for_each_entry(p, &br->port_list, list) { 515204177f3SToshiaki Makita pv = rtnl_dereference(p->vlan_info); 516204177f3SToshiaki Makita if (!pv) 517204177f3SToshiaki Makita continue; 518204177f3SToshiaki Makita 519204177f3SToshiaki Makita for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID) { 520204177f3SToshiaki Makita err = vlan_vid_add(p->dev, proto, vid); 521204177f3SToshiaki Makita if (err) 522204177f3SToshiaki Makita goto err_filt; 523204177f3SToshiaki Makita } 524204177f3SToshiaki Makita } 525204177f3SToshiaki Makita 526204177f3SToshiaki Makita oldproto = br->vlan_proto; 527204177f3SToshiaki Makita br->vlan_proto = proto; 528204177f3SToshiaki Makita 529204177f3SToshiaki Makita recalculate_group_addr(br); 530204177f3SToshiaki Makita br_recalculate_fwd_mask(br); 531204177f3SToshiaki Makita 532204177f3SToshiaki Makita /* Delete VLANs for the old proto from the device filter. */ 533204177f3SToshiaki Makita list_for_each_entry(p, &br->port_list, list) { 534204177f3SToshiaki Makita pv = rtnl_dereference(p->vlan_info); 535204177f3SToshiaki Makita if (!pv) 536204177f3SToshiaki Makita continue; 537204177f3SToshiaki Makita 538204177f3SToshiaki Makita for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID) 539204177f3SToshiaki Makita vlan_vid_del(p->dev, oldproto, vid); 540204177f3SToshiaki Makita } 541204177f3SToshiaki Makita 542204177f3SToshiaki Makita unlock: 543204177f3SToshiaki Makita rtnl_unlock(); 544204177f3SToshiaki Makita return err; 545204177f3SToshiaki Makita 546204177f3SToshiaki Makita err_filt: 547204177f3SToshiaki Makita errvid = vid; 548204177f3SToshiaki Makita for_each_set_bit(vid, pv->vlan_bitmap, errvid) 549204177f3SToshiaki Makita vlan_vid_del(p->dev, proto, vid); 550204177f3SToshiaki Makita 551204177f3SToshiaki Makita list_for_each_entry_continue_reverse(p, &br->port_list, list) { 552204177f3SToshiaki Makita pv = rtnl_dereference(p->vlan_info); 553204177f3SToshiaki Makita if (!pv) 554204177f3SToshiaki Makita continue; 555204177f3SToshiaki Makita 556204177f3SToshiaki Makita for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID) 557204177f3SToshiaki Makita vlan_vid_del(p->dev, proto, vid); 558204177f3SToshiaki Makita } 559204177f3SToshiaki Makita 560204177f3SToshiaki Makita goto unlock; 561204177f3SToshiaki Makita } 562204177f3SToshiaki Makita 5635be5a2dfSVlad Yasevich static bool vlan_default_pvid(struct net_port_vlans *pv, u16 vid) 5645be5a2dfSVlad Yasevich { 5655be5a2dfSVlad Yasevich return pv && vid == pv->pvid && test_bit(vid, pv->untagged_bitmap); 5665be5a2dfSVlad Yasevich } 5675be5a2dfSVlad Yasevich 5685be5a2dfSVlad Yasevich static void br_vlan_disable_default_pvid(struct net_bridge *br) 5695be5a2dfSVlad Yasevich { 5705be5a2dfSVlad Yasevich struct net_bridge_port *p; 5715be5a2dfSVlad Yasevich u16 pvid = br->default_pvid; 5725be5a2dfSVlad Yasevich 5735be5a2dfSVlad Yasevich /* Disable default_pvid on all ports where it is still 5745be5a2dfSVlad Yasevich * configured. 5755be5a2dfSVlad Yasevich */ 5765be5a2dfSVlad Yasevich if (vlan_default_pvid(br_get_vlan_info(br), pvid)) 5775be5a2dfSVlad Yasevich br_vlan_delete(br, pvid); 5785be5a2dfSVlad Yasevich 5795be5a2dfSVlad Yasevich list_for_each_entry(p, &br->port_list, list) { 5805be5a2dfSVlad Yasevich if (vlan_default_pvid(nbp_get_vlan_info(p), pvid)) 5815be5a2dfSVlad Yasevich nbp_vlan_delete(p, pvid); 5825be5a2dfSVlad Yasevich } 5835be5a2dfSVlad Yasevich 5845be5a2dfSVlad Yasevich br->default_pvid = 0; 5855be5a2dfSVlad Yasevich } 5865be5a2dfSVlad Yasevich 5875be5a2dfSVlad Yasevich static int __br_vlan_set_default_pvid(struct net_bridge *br, u16 pvid) 5885be5a2dfSVlad Yasevich { 5895be5a2dfSVlad Yasevich struct net_bridge_port *p; 5905be5a2dfSVlad Yasevich u16 old_pvid; 5915be5a2dfSVlad Yasevich int err = 0; 5925be5a2dfSVlad Yasevich unsigned long *changed; 5935be5a2dfSVlad Yasevich 5945be5a2dfSVlad Yasevich changed = kcalloc(BITS_TO_LONGS(BR_MAX_PORTS), sizeof(unsigned long), 5955be5a2dfSVlad Yasevich GFP_KERNEL); 5965be5a2dfSVlad Yasevich if (!changed) 5975be5a2dfSVlad Yasevich return -ENOMEM; 5985be5a2dfSVlad Yasevich 5995be5a2dfSVlad Yasevich old_pvid = br->default_pvid; 6005be5a2dfSVlad Yasevich 6015be5a2dfSVlad Yasevich /* Update default_pvid config only if we do not conflict with 6025be5a2dfSVlad Yasevich * user configuration. 6035be5a2dfSVlad Yasevich */ 6045be5a2dfSVlad Yasevich if ((!old_pvid || vlan_default_pvid(br_get_vlan_info(br), old_pvid)) && 6055be5a2dfSVlad Yasevich !br_vlan_find(br, pvid)) { 6065be5a2dfSVlad Yasevich err = br_vlan_add(br, pvid, 6075be5a2dfSVlad Yasevich BRIDGE_VLAN_INFO_PVID | 6085be5a2dfSVlad Yasevich BRIDGE_VLAN_INFO_UNTAGGED); 6095be5a2dfSVlad Yasevich if (err) 6105be5a2dfSVlad Yasevich goto out; 6115be5a2dfSVlad Yasevich br_vlan_delete(br, old_pvid); 6125be5a2dfSVlad Yasevich set_bit(0, changed); 6135be5a2dfSVlad Yasevich } 6145be5a2dfSVlad Yasevich 6155be5a2dfSVlad Yasevich list_for_each_entry(p, &br->port_list, list) { 6165be5a2dfSVlad Yasevich /* Update default_pvid config only if we do not conflict with 6175be5a2dfSVlad Yasevich * user configuration. 6185be5a2dfSVlad Yasevich */ 6195be5a2dfSVlad Yasevich if ((old_pvid && 6205be5a2dfSVlad Yasevich !vlan_default_pvid(nbp_get_vlan_info(p), old_pvid)) || 6215be5a2dfSVlad Yasevich nbp_vlan_find(p, pvid)) 6225be5a2dfSVlad Yasevich continue; 6235be5a2dfSVlad Yasevich 6245be5a2dfSVlad Yasevich err = nbp_vlan_add(p, pvid, 6255be5a2dfSVlad Yasevich BRIDGE_VLAN_INFO_PVID | 6265be5a2dfSVlad Yasevich BRIDGE_VLAN_INFO_UNTAGGED); 6275be5a2dfSVlad Yasevich if (err) 6285be5a2dfSVlad Yasevich goto err_port; 6295be5a2dfSVlad Yasevich nbp_vlan_delete(p, old_pvid); 6305be5a2dfSVlad Yasevich set_bit(p->port_no, changed); 6315be5a2dfSVlad Yasevich } 6325be5a2dfSVlad Yasevich 6335be5a2dfSVlad Yasevich br->default_pvid = pvid; 6345be5a2dfSVlad Yasevich 6355be5a2dfSVlad Yasevich out: 6365be5a2dfSVlad Yasevich kfree(changed); 6375be5a2dfSVlad Yasevich return err; 6385be5a2dfSVlad Yasevich 6395be5a2dfSVlad Yasevich err_port: 6405be5a2dfSVlad Yasevich list_for_each_entry_continue_reverse(p, &br->port_list, list) { 6415be5a2dfSVlad Yasevich if (!test_bit(p->port_no, changed)) 6425be5a2dfSVlad Yasevich continue; 6435be5a2dfSVlad Yasevich 6445be5a2dfSVlad Yasevich if (old_pvid) 6455be5a2dfSVlad Yasevich nbp_vlan_add(p, old_pvid, 6465be5a2dfSVlad Yasevich BRIDGE_VLAN_INFO_PVID | 6475be5a2dfSVlad Yasevich BRIDGE_VLAN_INFO_UNTAGGED); 6485be5a2dfSVlad Yasevich nbp_vlan_delete(p, pvid); 6495be5a2dfSVlad Yasevich } 6505be5a2dfSVlad Yasevich 6515be5a2dfSVlad Yasevich if (test_bit(0, changed)) { 6525be5a2dfSVlad Yasevich if (old_pvid) 6535be5a2dfSVlad Yasevich br_vlan_add(br, old_pvid, 6545be5a2dfSVlad Yasevich BRIDGE_VLAN_INFO_PVID | 6555be5a2dfSVlad Yasevich BRIDGE_VLAN_INFO_UNTAGGED); 6565be5a2dfSVlad Yasevich br_vlan_delete(br, pvid); 6575be5a2dfSVlad Yasevich } 6585be5a2dfSVlad Yasevich goto out; 6595be5a2dfSVlad Yasevich } 6605be5a2dfSVlad Yasevich 66196a20d9dSVlad Yasevich int br_vlan_set_default_pvid(struct net_bridge *br, unsigned long val) 66296a20d9dSVlad Yasevich { 66396a20d9dSVlad Yasevich u16 pvid = val; 66496a20d9dSVlad Yasevich int err = 0; 66596a20d9dSVlad Yasevich 6665be5a2dfSVlad Yasevich if (val >= VLAN_VID_MASK) 66796a20d9dSVlad Yasevich return -EINVAL; 66896a20d9dSVlad Yasevich 66996a20d9dSVlad Yasevich if (!rtnl_trylock()) 67096a20d9dSVlad Yasevich return restart_syscall(); 67196a20d9dSVlad Yasevich 67296a20d9dSVlad Yasevich if (pvid == br->default_pvid) 67396a20d9dSVlad Yasevich goto unlock; 67496a20d9dSVlad Yasevich 67596a20d9dSVlad Yasevich /* Only allow default pvid change when filtering is disabled */ 67696a20d9dSVlad Yasevich if (br->vlan_enabled) { 67796a20d9dSVlad Yasevich pr_info_once("Please disable vlan filtering to change default_pvid\n"); 67896a20d9dSVlad Yasevich err = -EPERM; 67996a20d9dSVlad Yasevich goto unlock; 68096a20d9dSVlad Yasevich } 68196a20d9dSVlad Yasevich 6825be5a2dfSVlad Yasevich if (!pvid) 6835be5a2dfSVlad Yasevich br_vlan_disable_default_pvid(br); 6845be5a2dfSVlad Yasevich else 6855be5a2dfSVlad Yasevich err = __br_vlan_set_default_pvid(br, pvid); 68696a20d9dSVlad Yasevich 68796a20d9dSVlad Yasevich unlock: 68896a20d9dSVlad Yasevich rtnl_unlock(); 68996a20d9dSVlad Yasevich return err; 69096a20d9dSVlad Yasevich } 69196a20d9dSVlad Yasevich 6925be5a2dfSVlad Yasevich int br_vlan_init(struct net_bridge *br) 6938580e211SToshiaki Makita { 6948580e211SToshiaki Makita br->vlan_proto = htons(ETH_P_8021Q); 69596a20d9dSVlad Yasevich br->default_pvid = 1; 6965be5a2dfSVlad Yasevich return br_vlan_add(br, 1, 6975be5a2dfSVlad Yasevich BRIDGE_VLAN_INFO_PVID | BRIDGE_VLAN_INFO_UNTAGGED); 6988580e211SToshiaki Makita } 6998580e211SToshiaki Makita 7008adff41cSToshiaki Makita /* Must be protected by RTNL. 7018adff41cSToshiaki Makita * Must be called with vid in range from 1 to 4094 inclusive. 7028adff41cSToshiaki Makita */ 703552406c4SVlad Yasevich int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags) 704243a2e63SVlad Yasevich { 705243a2e63SVlad Yasevich struct net_port_vlans *pv = NULL; 706243a2e63SVlad Yasevich int err; 707243a2e63SVlad Yasevich 708243a2e63SVlad Yasevich ASSERT_RTNL(); 709243a2e63SVlad Yasevich 710243a2e63SVlad Yasevich pv = rtnl_dereference(port->vlan_info); 711243a2e63SVlad Yasevich if (pv) 712552406c4SVlad Yasevich return __vlan_add(pv, vid, flags); 713243a2e63SVlad Yasevich 714243a2e63SVlad Yasevich /* Create port vlan infomration 715243a2e63SVlad Yasevich */ 716243a2e63SVlad Yasevich pv = kzalloc(sizeof(*pv), GFP_KERNEL); 717243a2e63SVlad Yasevich if (!pv) { 718243a2e63SVlad Yasevich err = -ENOMEM; 719243a2e63SVlad Yasevich goto clean_up; 720243a2e63SVlad Yasevich } 721243a2e63SVlad Yasevich 722243a2e63SVlad Yasevich pv->port_idx = port->port_no; 723243a2e63SVlad Yasevich pv->parent.port = port; 724552406c4SVlad Yasevich err = __vlan_add(pv, vid, flags); 725243a2e63SVlad Yasevich if (err) 726243a2e63SVlad Yasevich goto clean_up; 727243a2e63SVlad Yasevich 728243a2e63SVlad Yasevich rcu_assign_pointer(port->vlan_info, pv); 729243a2e63SVlad Yasevich return 0; 730243a2e63SVlad Yasevich 731243a2e63SVlad Yasevich clean_up: 732243a2e63SVlad Yasevich kfree(pv); 733243a2e63SVlad Yasevich return err; 734243a2e63SVlad Yasevich } 735243a2e63SVlad Yasevich 7368adff41cSToshiaki Makita /* Must be protected by RTNL. 7378adff41cSToshiaki Makita * Must be called with vid in range from 1 to 4094 inclusive. 7388adff41cSToshiaki Makita */ 739243a2e63SVlad Yasevich int nbp_vlan_delete(struct net_bridge_port *port, u16 vid) 740243a2e63SVlad Yasevich { 741243a2e63SVlad Yasevich struct net_port_vlans *pv; 742243a2e63SVlad Yasevich 743243a2e63SVlad Yasevich ASSERT_RTNL(); 744243a2e63SVlad Yasevich 745243a2e63SVlad Yasevich pv = rtnl_dereference(port->vlan_info); 746243a2e63SVlad Yasevich if (!pv) 747243a2e63SVlad Yasevich return -EINVAL; 748243a2e63SVlad Yasevich 749424bb9c9SToshiaki Makita br_fdb_find_delete_local(port->br, port, port->dev->dev_addr, vid); 7501ea2d020SNikolay Aleksandrov br_fdb_delete_by_port(port->br, port, vid, 0); 751bc9a25d2SVlad Yasevich 752243a2e63SVlad Yasevich return __vlan_del(pv, vid); 753243a2e63SVlad Yasevich } 754243a2e63SVlad Yasevich 755243a2e63SVlad Yasevich void nbp_vlan_flush(struct net_bridge_port *port) 756243a2e63SVlad Yasevich { 757243a2e63SVlad Yasevich struct net_port_vlans *pv; 758dbbaf949SToshiaki Makita u16 vid; 759243a2e63SVlad Yasevich 760243a2e63SVlad Yasevich ASSERT_RTNL(); 761243a2e63SVlad Yasevich 762243a2e63SVlad Yasevich pv = rtnl_dereference(port->vlan_info); 763243a2e63SVlad Yasevich if (!pv) 764243a2e63SVlad Yasevich return; 765243a2e63SVlad Yasevich 766dbbaf949SToshiaki Makita for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID) 7678580e211SToshiaki Makita vlan_vid_del(port->dev, port->br->vlan_proto, vid); 768dbbaf949SToshiaki Makita 769243a2e63SVlad Yasevich __vlan_flush(pv); 770243a2e63SVlad Yasevich } 771bc9a25d2SVlad Yasevich 772bc9a25d2SVlad Yasevich bool nbp_vlan_find(struct net_bridge_port *port, u16 vid) 773bc9a25d2SVlad Yasevich { 774bc9a25d2SVlad Yasevich struct net_port_vlans *pv; 775bc9a25d2SVlad Yasevich bool found = false; 776bc9a25d2SVlad Yasevich 777bc9a25d2SVlad Yasevich rcu_read_lock(); 778bc9a25d2SVlad Yasevich pv = rcu_dereference(port->vlan_info); 779bc9a25d2SVlad Yasevich 780bc9a25d2SVlad Yasevich if (!pv) 781bc9a25d2SVlad Yasevich goto out; 782bc9a25d2SVlad Yasevich 783bc9a25d2SVlad Yasevich if (test_bit(vid, pv->vlan_bitmap)) 784bc9a25d2SVlad Yasevich found = true; 785bc9a25d2SVlad Yasevich 786bc9a25d2SVlad Yasevich out: 787bc9a25d2SVlad Yasevich rcu_read_unlock(); 788bc9a25d2SVlad Yasevich return found; 789bc9a25d2SVlad Yasevich } 7905be5a2dfSVlad Yasevich 7915be5a2dfSVlad Yasevich int nbp_vlan_init(struct net_bridge_port *p) 7925be5a2dfSVlad Yasevich { 7935be5a2dfSVlad Yasevich return p->br->default_pvid ? 7945be5a2dfSVlad Yasevich nbp_vlan_add(p, p->br->default_pvid, 7955be5a2dfSVlad Yasevich BRIDGE_VLAN_INFO_PVID | 7965be5a2dfSVlad Yasevich BRIDGE_VLAN_INFO_UNTAGGED) : 7975be5a2dfSVlad Yasevich 0; 7985be5a2dfSVlad Yasevich } 799