aboutsummaryrefslogtreecommitdiffstats
path: root/net/8021q/vlan.h
diff options
context:
space:
mode:
authorJiri Pirko <jpirko@redhat.com>2011-12-07 23:11:18 -0500
committerDavid S. Miller <davem@davemloft.net>2011-12-08 19:52:42 -0500
commit5b9ea6e022e9ba0fe39cb349ac40361f78d5da5b (patch)
tree11f0de492ee799fd4174f79ac6aae4c3533beb25 /net/8021q/vlan.h
parent87002b03baabd2b8f6281ab6411ed88d24958de1 (diff)
vlan: introduce vid list with reference counting
This allows to keep track of vids needed to be in rx vlan filters of devices even if they are used in bond/team etc. vlan_info as well as vlan_group previously was, is allocated when first vid is added and dealocated whan last vid is deleted. vlan_group definition is moved to private header. Signed-off-by: Jiri Pirko <jpirko@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/8021q/vlan.h')
-rw-r--r--net/8021q/vlan.h30
1 files changed, 27 insertions, 3 deletions
diff --git a/net/8021q/vlan.h b/net/8021q/vlan.h
index d3c4ea4a3836..28d8dc20cb6d 100644
--- a/net/8021q/vlan.h
+++ b/net/8021q/vlan.h
@@ -3,6 +3,7 @@
3 3
4#include <linux/if_vlan.h> 4#include <linux/if_vlan.h>
5#include <linux/u64_stats_sync.h> 5#include <linux/u64_stats_sync.h>
6#include <linux/list.h>
6 7
7 8
8/** 9/**
@@ -74,6 +75,29 @@ static inline struct vlan_dev_priv *vlan_dev_priv(const struct net_device *dev)
74 return netdev_priv(dev); 75 return netdev_priv(dev);
75} 76}
76 77
78/* if this changes, algorithm will have to be reworked because this
79 * depends on completely exhausting the VLAN identifier space. Thus
80 * it gives constant time look-up, but in many cases it wastes memory.
81 */
82#define VLAN_GROUP_ARRAY_SPLIT_PARTS 8
83#define VLAN_GROUP_ARRAY_PART_LEN (VLAN_N_VID/VLAN_GROUP_ARRAY_SPLIT_PARTS)
84
85struct vlan_group {
86 unsigned int nr_vlan_devs;
87 struct hlist_node hlist; /* linked list */
88 struct net_device **vlan_devices_arrays[VLAN_GROUP_ARRAY_SPLIT_PARTS];
89};
90
91struct vlan_info {
92 struct net_device *real_dev; /* The ethernet(like) device
93 * the vlan is attached to.
94 */
95 struct vlan_group grp;
96 struct list_head vid_list;
97 unsigned int nr_vids;
98 struct rcu_head rcu;
99};
100
77static inline struct net_device *vlan_group_get_device(struct vlan_group *vg, 101static inline struct net_device *vlan_group_get_device(struct vlan_group *vg,
78 u16 vlan_id) 102 u16 vlan_id)
79{ 103{
@@ -97,10 +121,10 @@ static inline void vlan_group_set_device(struct vlan_group *vg,
97static inline struct net_device *vlan_find_dev(struct net_device *real_dev, 121static inline struct net_device *vlan_find_dev(struct net_device *real_dev,
98 u16 vlan_id) 122 u16 vlan_id)
99{ 123{
100 struct vlan_group *grp = rcu_dereference_rtnl(real_dev->vlgrp); 124 struct vlan_info *vlan_info = rcu_dereference_rtnl(real_dev->vlan_info);
101 125
102 if (grp) 126 if (vlan_info)
103 return vlan_group_get_device(grp, vlan_id); 127 return vlan_group_get_device(&vlan_info->grp, vlan_id);
104 128
105 return NULL; 129 return NULL;
106} 130}