1243a2e63SVlad Yasevich #include <linux/kernel.h> 2243a2e63SVlad Yasevich #include <linux/netdevice.h> 3243a2e63SVlad Yasevich #include <linux/rtnetlink.h> 4243a2e63SVlad Yasevich #include <linux/slab.h> 5243a2e63SVlad Yasevich 6243a2e63SVlad Yasevich #include "br_private.h" 7243a2e63SVlad Yasevich 8243a2e63SVlad Yasevich static int __vlan_add(struct net_port_vlans *v, u16 vid) 9243a2e63SVlad Yasevich { 10243a2e63SVlad Yasevich int err; 11243a2e63SVlad Yasevich 12243a2e63SVlad Yasevich if (test_bit(vid, v->vlan_bitmap)) 13243a2e63SVlad Yasevich return -EEXIST; 14243a2e63SVlad Yasevich 15243a2e63SVlad Yasevich if (v->port_idx && vid) { 16243a2e63SVlad Yasevich struct net_device *dev = v->parent.port->dev; 17243a2e63SVlad Yasevich 18243a2e63SVlad Yasevich /* Add VLAN to the device filter if it is supported. 19243a2e63SVlad Yasevich * Stricly speaking, this is not necessary now, since devices 20243a2e63SVlad Yasevich * are made promiscuous by the bridge, but if that ever changes 21243a2e63SVlad Yasevich * this code will allow tagged traffic to enter the bridge. 22243a2e63SVlad Yasevich */ 23243a2e63SVlad Yasevich if (dev->features & NETIF_F_HW_VLAN_FILTER) { 24243a2e63SVlad Yasevich err = dev->netdev_ops->ndo_vlan_rx_add_vid(dev, vid); 25243a2e63SVlad Yasevich if (err) 26243a2e63SVlad Yasevich return err; 27243a2e63SVlad Yasevich } 28243a2e63SVlad Yasevich } 29243a2e63SVlad Yasevich 30243a2e63SVlad Yasevich set_bit(vid, v->vlan_bitmap); 31243a2e63SVlad Yasevich return 0; 32243a2e63SVlad Yasevich } 33243a2e63SVlad Yasevich 34243a2e63SVlad Yasevich static int __vlan_del(struct net_port_vlans *v, u16 vid) 35243a2e63SVlad Yasevich { 36243a2e63SVlad Yasevich if (!test_bit(vid, v->vlan_bitmap)) 37243a2e63SVlad Yasevich return -EINVAL; 38243a2e63SVlad Yasevich 39243a2e63SVlad Yasevich if (v->port_idx && vid) { 40243a2e63SVlad Yasevich struct net_device *dev = v->parent.port->dev; 41243a2e63SVlad Yasevich 42243a2e63SVlad Yasevich if (dev->features & NETIF_F_HW_VLAN_FILTER) 43243a2e63SVlad Yasevich dev->netdev_ops->ndo_vlan_rx_kill_vid(dev, vid); 44243a2e63SVlad Yasevich } 45243a2e63SVlad Yasevich 46243a2e63SVlad Yasevich clear_bit(vid, v->vlan_bitmap); 47243a2e63SVlad Yasevich if (bitmap_empty(v->vlan_bitmap, BR_VLAN_BITMAP_LEN)) { 48243a2e63SVlad Yasevich if (v->port_idx) 49243a2e63SVlad Yasevich rcu_assign_pointer(v->parent.port->vlan_info, NULL); 50243a2e63SVlad Yasevich else 51243a2e63SVlad Yasevich rcu_assign_pointer(v->parent.br->vlan_info, NULL); 52243a2e63SVlad Yasevich kfree_rcu(v, rcu); 53243a2e63SVlad Yasevich } 54243a2e63SVlad Yasevich return 0; 55243a2e63SVlad Yasevich } 56243a2e63SVlad Yasevich 57243a2e63SVlad Yasevich static void __vlan_flush(struct net_port_vlans *v) 58243a2e63SVlad Yasevich { 59243a2e63SVlad Yasevich bitmap_zero(v->vlan_bitmap, BR_VLAN_BITMAP_LEN); 60243a2e63SVlad Yasevich if (v->port_idx) 61243a2e63SVlad Yasevich rcu_assign_pointer(v->parent.port->vlan_info, NULL); 62243a2e63SVlad Yasevich else 63243a2e63SVlad Yasevich rcu_assign_pointer(v->parent.br->vlan_info, NULL); 64243a2e63SVlad Yasevich kfree_rcu(v, rcu); 65243a2e63SVlad Yasevich } 66243a2e63SVlad Yasevich 67a37b85c9SVlad Yasevich /* Called under RCU */ 68a37b85c9SVlad Yasevich bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v, 69a37b85c9SVlad Yasevich struct sk_buff *skb) 70a37b85c9SVlad Yasevich { 71a37b85c9SVlad Yasevich u16 vid; 72a37b85c9SVlad Yasevich 73a37b85c9SVlad Yasevich /* If VLAN filtering is disabled on the bridge, all packets are 74a37b85c9SVlad Yasevich * permitted. 75a37b85c9SVlad Yasevich */ 76a37b85c9SVlad Yasevich if (!br->vlan_enabled) 77a37b85c9SVlad Yasevich return true; 78a37b85c9SVlad Yasevich 79a37b85c9SVlad Yasevich /* If there are no vlan in the permitted list, all packets are 80a37b85c9SVlad Yasevich * rejected. 81a37b85c9SVlad Yasevich */ 82a37b85c9SVlad Yasevich if (!v) 83a37b85c9SVlad Yasevich return false; 84a37b85c9SVlad Yasevich 85a37b85c9SVlad Yasevich br_vlan_get_tag(skb, &vid); 86a37b85c9SVlad Yasevich if (test_bit(vid, v->vlan_bitmap)) 87a37b85c9SVlad Yasevich return true; 88a37b85c9SVlad Yasevich 89a37b85c9SVlad Yasevich return false; 90a37b85c9SVlad Yasevich } 91a37b85c9SVlad Yasevich 92243a2e63SVlad Yasevich /* Must be protected by RTNL */ 93243a2e63SVlad Yasevich int br_vlan_add(struct net_bridge *br, u16 vid) 94243a2e63SVlad Yasevich { 95243a2e63SVlad Yasevich struct net_port_vlans *pv = NULL; 96243a2e63SVlad Yasevich int err; 97243a2e63SVlad Yasevich 98243a2e63SVlad Yasevich ASSERT_RTNL(); 99243a2e63SVlad Yasevich 100243a2e63SVlad Yasevich pv = rtnl_dereference(br->vlan_info); 101243a2e63SVlad Yasevich if (pv) 102243a2e63SVlad Yasevich return __vlan_add(pv, vid); 103243a2e63SVlad Yasevich 104243a2e63SVlad Yasevich /* Create port vlan infomration 105243a2e63SVlad Yasevich */ 106243a2e63SVlad Yasevich pv = kzalloc(sizeof(*pv), GFP_KERNEL); 107243a2e63SVlad Yasevich if (!pv) 108243a2e63SVlad Yasevich return -ENOMEM; 109243a2e63SVlad Yasevich 110243a2e63SVlad Yasevich pv->parent.br = br; 111243a2e63SVlad Yasevich err = __vlan_add(pv, vid); 112243a2e63SVlad Yasevich if (err) 113243a2e63SVlad Yasevich goto out; 114243a2e63SVlad Yasevich 115243a2e63SVlad Yasevich rcu_assign_pointer(br->vlan_info, pv); 116243a2e63SVlad Yasevich return 0; 117243a2e63SVlad Yasevich out: 118243a2e63SVlad Yasevich kfree(pv); 119243a2e63SVlad Yasevich return err; 120243a2e63SVlad Yasevich } 121243a2e63SVlad Yasevich 122243a2e63SVlad Yasevich /* Must be protected by RTNL */ 123243a2e63SVlad Yasevich int br_vlan_delete(struct net_bridge *br, u16 vid) 124243a2e63SVlad Yasevich { 125243a2e63SVlad Yasevich struct net_port_vlans *pv; 126243a2e63SVlad Yasevich 127243a2e63SVlad Yasevich ASSERT_RTNL(); 128243a2e63SVlad Yasevich 129243a2e63SVlad Yasevich pv = rtnl_dereference(br->vlan_info); 130243a2e63SVlad Yasevich if (!pv) 131243a2e63SVlad Yasevich return -EINVAL; 132243a2e63SVlad Yasevich 133243a2e63SVlad Yasevich __vlan_del(pv, vid); 134243a2e63SVlad Yasevich return 0; 135243a2e63SVlad Yasevich } 136243a2e63SVlad Yasevich 137243a2e63SVlad Yasevich void br_vlan_flush(struct net_bridge *br) 138243a2e63SVlad Yasevich { 139243a2e63SVlad Yasevich struct net_port_vlans *pv; 140243a2e63SVlad Yasevich 141243a2e63SVlad Yasevich ASSERT_RTNL(); 142243a2e63SVlad Yasevich 143243a2e63SVlad Yasevich pv = rtnl_dereference(br->vlan_info); 144243a2e63SVlad Yasevich if (!pv) 145243a2e63SVlad Yasevich return; 146243a2e63SVlad Yasevich 147243a2e63SVlad Yasevich __vlan_flush(pv); 148243a2e63SVlad Yasevich } 149243a2e63SVlad Yasevich 150243a2e63SVlad Yasevich int br_vlan_filter_toggle(struct net_bridge *br, unsigned long val) 151243a2e63SVlad Yasevich { 152243a2e63SVlad Yasevich if (!rtnl_trylock()) 153243a2e63SVlad Yasevich return restart_syscall(); 154243a2e63SVlad Yasevich 155243a2e63SVlad Yasevich if (br->vlan_enabled == val) 156243a2e63SVlad Yasevich goto unlock; 157243a2e63SVlad Yasevich 158243a2e63SVlad Yasevich br->vlan_enabled = val; 159243a2e63SVlad Yasevich 160243a2e63SVlad Yasevich unlock: 161243a2e63SVlad Yasevich rtnl_unlock(); 162243a2e63SVlad Yasevich return 0; 163243a2e63SVlad Yasevich } 164243a2e63SVlad Yasevich 165243a2e63SVlad Yasevich /* Must be protected by RTNL */ 166243a2e63SVlad Yasevich int nbp_vlan_add(struct net_bridge_port *port, u16 vid) 167243a2e63SVlad Yasevich { 168243a2e63SVlad Yasevich struct net_port_vlans *pv = NULL; 169243a2e63SVlad Yasevich int err; 170243a2e63SVlad Yasevich 171243a2e63SVlad Yasevich ASSERT_RTNL(); 172243a2e63SVlad Yasevich 173243a2e63SVlad Yasevich pv = rtnl_dereference(port->vlan_info); 174243a2e63SVlad Yasevich if (pv) 175243a2e63SVlad Yasevich return __vlan_add(pv, vid); 176243a2e63SVlad Yasevich 177243a2e63SVlad Yasevich /* Create port vlan infomration 178243a2e63SVlad Yasevich */ 179243a2e63SVlad Yasevich pv = kzalloc(sizeof(*pv), GFP_KERNEL); 180243a2e63SVlad Yasevich if (!pv) { 181243a2e63SVlad Yasevich err = -ENOMEM; 182243a2e63SVlad Yasevich goto clean_up; 183243a2e63SVlad Yasevich } 184243a2e63SVlad Yasevich 185243a2e63SVlad Yasevich pv->port_idx = port->port_no; 186243a2e63SVlad Yasevich pv->parent.port = port; 187243a2e63SVlad Yasevich err = __vlan_add(pv, vid); 188243a2e63SVlad Yasevich if (err) 189243a2e63SVlad Yasevich goto clean_up; 190243a2e63SVlad Yasevich 191243a2e63SVlad Yasevich rcu_assign_pointer(port->vlan_info, pv); 192243a2e63SVlad Yasevich return 0; 193243a2e63SVlad Yasevich 194243a2e63SVlad Yasevich clean_up: 195243a2e63SVlad Yasevich kfree(pv); 196243a2e63SVlad Yasevich return err; 197243a2e63SVlad Yasevich } 198243a2e63SVlad Yasevich 199243a2e63SVlad Yasevich /* Must be protected by RTNL */ 200243a2e63SVlad Yasevich int nbp_vlan_delete(struct net_bridge_port *port, u16 vid) 201243a2e63SVlad Yasevich { 202243a2e63SVlad Yasevich struct net_port_vlans *pv; 203243a2e63SVlad Yasevich 204243a2e63SVlad Yasevich ASSERT_RTNL(); 205243a2e63SVlad Yasevich 206243a2e63SVlad Yasevich pv = rtnl_dereference(port->vlan_info); 207243a2e63SVlad Yasevich if (!pv) 208243a2e63SVlad Yasevich return -EINVAL; 209243a2e63SVlad Yasevich 210243a2e63SVlad Yasevich return __vlan_del(pv, vid); 211243a2e63SVlad Yasevich } 212243a2e63SVlad Yasevich 213243a2e63SVlad Yasevich void nbp_vlan_flush(struct net_bridge_port *port) 214243a2e63SVlad Yasevich { 215243a2e63SVlad Yasevich struct net_port_vlans *pv; 216243a2e63SVlad Yasevich 217243a2e63SVlad Yasevich ASSERT_RTNL(); 218243a2e63SVlad Yasevich 219243a2e63SVlad Yasevich pv = rtnl_dereference(port->vlan_info); 220243a2e63SVlad Yasevich if (!pv) 221243a2e63SVlad Yasevich return; 222243a2e63SVlad Yasevich 223243a2e63SVlad Yasevich __vlan_flush(pv); 224243a2e63SVlad Yasevich } 225