br_vlan.c (30b0594a3e6c2bcbe5bd59753d0319d6f9925e40) | br_vlan.c (9163a0fc1f0c0980f117cc25f4fa6ba9b0750a36) |
---|---|
1#include <linux/kernel.h> 2#include <linux/netdevice.h> 3#include <linux/rtnetlink.h> 4#include <linux/slab.h> 5#include <net/switchdev.h> 6 7#include "br_private.h" 8#include "br_private_tunnel.h" --- 176 unchanged lines hidden (view full) --- 185 if (refcount_dec_and_test(&masterv->refcnt)) { 186 rhashtable_remove_fast(&vg->vlan_hash, 187 &masterv->vnode, br_vlan_rht_params); 188 __vlan_del_list(masterv); 189 call_rcu(&masterv->rcu, br_master_vlan_rcu_free); 190 } 191} 192 | 1#include <linux/kernel.h> 2#include <linux/netdevice.h> 3#include <linux/rtnetlink.h> 4#include <linux/slab.h> 5#include <net/switchdev.h> 6 7#include "br_private.h" 8#include "br_private_tunnel.h" --- 176 unchanged lines hidden (view full) --- 185 if (refcount_dec_and_test(&masterv->refcnt)) { 186 rhashtable_remove_fast(&vg->vlan_hash, 187 &masterv->vnode, br_vlan_rht_params); 188 __vlan_del_list(masterv); 189 call_rcu(&masterv->rcu, br_master_vlan_rcu_free); 190 } 191} 192 |
193static void nbp_vlan_rcu_free(struct rcu_head *rcu) 194{ 195 struct net_bridge_vlan *v; 196 197 v = container_of(rcu, struct net_bridge_vlan, rcu); 198 WARN_ON(br_vlan_is_master(v)); 199 /* if we had per-port stats configured then free them here */ 200 if (v->brvlan->stats != v->stats) 201 free_percpu(v->stats); 202 v->stats = NULL; 203 kfree(v); 204} 205 |
|
193/* This is the shared VLAN add function which works for both ports and bridge 194 * devices. There are four possible calls to this function in terms of the 195 * vlan entry type: 196 * 1. vlan is being added on a port (no master flags, global entry exists) 197 * 2. vlan is being added on a bridge (both master and brentry flags) 198 * 3. vlan is being added on a port, but a global entry didn't exist which 199 * is being created right now (master flag set, brentry flag unset), the 200 * global entry is used for global per-vlan features, but not for filtering --- 39 unchanged lines hidden (view full) --- 240 if (err) 241 goto out_filt; 242 } 243 244 masterv = br_vlan_get_master(br, v->vid); 245 if (!masterv) 246 goto out_filt; 247 v->brvlan = masterv; | 206/* This is the shared VLAN add function which works for both ports and bridge 207 * devices. There are four possible calls to this function in terms of the 208 * vlan entry type: 209 * 1. vlan is being added on a port (no master flags, global entry exists) 210 * 2. vlan is being added on a bridge (both master and brentry flags) 211 * 3. vlan is being added on a port, but a global entry didn't exist which 212 * is being created right now (master flag set, brentry flag unset), the 213 * global entry is used for global per-vlan features, but not for filtering --- 39 unchanged lines hidden (view full) --- 253 if (err) 254 goto out_filt; 255 } 256 257 masterv = br_vlan_get_master(br, v->vid); 258 if (!masterv) 259 goto out_filt; 260 v->brvlan = masterv; |
248 v->stats = masterv->stats; | 261 if (br_opt_get(br, BROPT_VLAN_STATS_PER_PORT)) { 262 v->stats = netdev_alloc_pcpu_stats(struct br_vlan_stats); 263 if (!v->stats) { 264 err = -ENOMEM; 265 goto out_filt; 266 } 267 } else { 268 v->stats = masterv->stats; 269 } |
249 } else { 250 err = br_switchdev_port_vlan_add(dev, v->vid, flags); 251 if (err && err != -EOPNOTSUPP) 252 goto out; 253 } 254 255 /* Add the dev mac and count the vlan only if it's usable */ 256 if (br_vlan_should_use(v)) { --- 67 unchanged lines hidden (view full) --- 324 vg->num_vlans--; 325 } 326 327 if (masterv != v) { 328 vlan_tunnel_info_del(vg, v); 329 rhashtable_remove_fast(&vg->vlan_hash, &v->vnode, 330 br_vlan_rht_params); 331 __vlan_del_list(v); | 270 } else { 271 err = br_switchdev_port_vlan_add(dev, v->vid, flags); 272 if (err && err != -EOPNOTSUPP) 273 goto out; 274 } 275 276 /* Add the dev mac and count the vlan only if it's usable */ 277 if (br_vlan_should_use(v)) { --- 67 unchanged lines hidden (view full) --- 345 vg->num_vlans--; 346 } 347 348 if (masterv != v) { 349 vlan_tunnel_info_del(vg, v); 350 rhashtable_remove_fast(&vg->vlan_hash, &v->vnode, 351 br_vlan_rht_params); 352 __vlan_del_list(v); |
332 kfree_rcu(v, rcu); | 353 call_rcu(&v->rcu, nbp_vlan_rcu_free); |
333 } 334 335 br_vlan_put_master(masterv); 336out: 337 return err; 338} 339 340static void __vlan_group_free(struct net_bridge_vlan_group *vg) --- 484 unchanged lines hidden (view full) --- 825 break; 826 default: 827 return -EINVAL; 828 } 829 830 return 0; 831} 832 | 354 } 355 356 br_vlan_put_master(masterv); 357out: 358 return err; 359} 360 361static void __vlan_group_free(struct net_bridge_vlan_group *vg) --- 484 unchanged lines hidden (view full) --- 846 break; 847 default: 848 return -EINVAL; 849 } 850 851 return 0; 852} 853 |
854int br_vlan_set_stats_per_port(struct net_bridge *br, unsigned long val) 855{ 856 struct net_bridge_port *p; 857 858 /* allow to change the option if there are no port vlans configured */ 859 list_for_each_entry(p, &br->port_list, list) { 860 struct net_bridge_vlan_group *vg = nbp_vlan_group(p); 861 862 if (vg->num_vlans) 863 return -EBUSY; 864 } 865 866 switch (val) { 867 case 0: 868 case 1: 869 br_opt_toggle(br, BROPT_VLAN_STATS_PER_PORT, !!val); 870 break; 871 default: 872 return -EINVAL; 873 } 874 875 return 0; 876} 877 |
|
833static bool vlan_default_pvid(struct net_bridge_vlan_group *vg, u16 vid) 834{ 835 struct net_bridge_vlan *v; 836 837 if (vid != vg->pvid) 838 return false; 839 840 v = br_vlan_lookup(&vg->vlan_hash, vid); --- 366 unchanged lines hidden --- | 878static bool vlan_default_pvid(struct net_bridge_vlan_group *vg, u16 vid) 879{ 880 struct net_bridge_vlan *v; 881 882 if (vid != vg->pvid) 883 return false; 884 885 v = br_vlan_lookup(&vg->vlan_hash, vid); --- 366 unchanged lines hidden --- |