@@ -51,27 +51,6 @@ const char vlan_version[] = DRV_VERSION;
5151
5252/* End of global variables definitions. */
5353
54- static void vlan_group_free (struct vlan_group * grp )
55- {
56- int i ;
57-
58- for (i = 0 ; i < VLAN_GROUP_ARRAY_SPLIT_PARTS ; i ++ )
59- kfree (grp -> vlan_devices_arrays [i ]);
60- kfree (grp );
61- }
62-
63- static struct vlan_group * vlan_group_alloc (struct net_device * real_dev )
64- {
65- struct vlan_group * grp ;
66-
67- grp = kzalloc (sizeof (struct vlan_group ), GFP_KERNEL );
68- if (!grp )
69- return NULL ;
70-
71- grp -> real_dev = real_dev ;
72- return grp ;
73- }
74-
7554static int vlan_group_prealloc_vid (struct vlan_group * vg , u16 vlan_id )
7655{
7756 struct net_device * * array ;
@@ -92,22 +71,20 @@ static int vlan_group_prealloc_vid(struct vlan_group *vg, u16 vlan_id)
9271 return 0 ;
9372}
9473
95- static void vlan_rcu_free (struct rcu_head * rcu )
96- {
97- vlan_group_free (container_of (rcu , struct vlan_group , rcu ));
98- }
99-
10074void unregister_vlan_dev (struct net_device * dev , struct list_head * head )
10175{
10276 struct vlan_dev_priv * vlan = vlan_dev_priv (dev );
10377 struct net_device * real_dev = vlan -> real_dev ;
78+ struct vlan_info * vlan_info ;
10479 struct vlan_group * grp ;
10580 u16 vlan_id = vlan -> vlan_id ;
10681
10782 ASSERT_RTNL ();
10883
109- grp = rtnl_dereference (real_dev -> vlgrp );
110- BUG_ON (!grp );
84+ vlan_info = rtnl_dereference (real_dev -> vlan_info );
85+ BUG_ON (!vlan_info );
86+
87+ grp = & vlan_info -> grp ;
11188
11289 /* Take it out of our own structures, but be sure to interlock with
11390 * HW accelerating devices or SW vlan input packet processing if
@@ -116,7 +93,7 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head)
11693 if (vlan_id )
11794 vlan_vid_del (real_dev , vlan_id );
11895
119- grp -> nr_vlans -- ;
96+ grp -> nr_vlan_devs -- ;
12097
12198 if (vlan -> flags & VLAN_FLAG_GVRP )
12299 vlan_gvrp_request_leave (dev );
@@ -128,16 +105,9 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head)
128105 */
129106 unregister_netdevice_queue (dev , head );
130107
131- /* If the group is now empty, kill off the group. */
132- if (grp -> nr_vlans == 0 ) {
108+ if (grp -> nr_vlan_devs == 0 )
133109 vlan_gvrp_uninit_applicant (real_dev );
134110
135- RCU_INIT_POINTER (real_dev -> vlgrp , NULL );
136-
137- /* Free the group, after all cpu's are done. */
138- call_rcu (& grp -> rcu , vlan_rcu_free );
139- }
140-
141111 /* Get rid of the vlan's reference to real_dev */
142112 dev_put (real_dev );
143113}
@@ -169,17 +139,23 @@ int register_vlan_dev(struct net_device *dev)
169139 struct vlan_dev_priv * vlan = vlan_dev_priv (dev );
170140 struct net_device * real_dev = vlan -> real_dev ;
171141 u16 vlan_id = vlan -> vlan_id ;
172- struct vlan_group * grp , * ngrp = NULL ;
142+ struct vlan_info * vlan_info ;
143+ struct vlan_group * grp ;
173144 int err ;
174145
175- grp = rtnl_dereference (real_dev -> vlgrp );
176- if (!grp ) {
177- ngrp = grp = vlan_group_alloc (real_dev );
178- if (!grp )
179- return - ENOBUFS ;
146+ err = vlan_vid_add (real_dev , vlan_id );
147+ if (err )
148+ return err ;
149+
150+ vlan_info = rtnl_dereference (real_dev -> vlan_info );
151+ /* vlan_info should be there now. vlan_vid_add took care of it */
152+ BUG_ON (!vlan_info );
153+
154+ grp = & vlan_info -> grp ;
155+ if (grp -> nr_vlan_devs == 0 ) {
180156 err = vlan_gvrp_init_applicant (real_dev );
181157 if (err < 0 )
182- goto out_free_group ;
158+ goto out_vid_del ;
183159 }
184160
185161 err = vlan_group_prealloc_vid (grp , vlan_id );
@@ -200,23 +176,15 @@ int register_vlan_dev(struct net_device *dev)
200176 * it into our local structure.
201177 */
202178 vlan_group_set_device (grp , vlan_id , dev );
203- grp -> nr_vlans ++ ;
204-
205- if (ngrp ) {
206- rcu_assign_pointer (real_dev -> vlgrp , ngrp );
207- }
208- vlan_vid_add (real_dev , vlan_id );
179+ grp -> nr_vlan_devs ++ ;
209180
210181 return 0 ;
211182
212183out_uninit_applicant :
213- if (ngrp )
184+ if (grp -> nr_vlan_devs == 0 )
214185 vlan_gvrp_uninit_applicant (real_dev );
215- out_free_group :
216- if (ngrp ) {
217- /* Free the group, after all cpu's are done. */
218- call_rcu (& ngrp -> rcu , vlan_rcu_free );
219- }
186+ out_vid_del :
187+ vlan_vid_del (real_dev , vlan_id );
220188 return err ;
221189}
222190
@@ -357,6 +325,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
357325{
358326 struct net_device * dev = ptr ;
359327 struct vlan_group * grp ;
328+ struct vlan_info * vlan_info ;
360329 int i , flgs ;
361330 struct net_device * vlandev ;
362331 struct vlan_dev_priv * vlan ;
@@ -372,9 +341,10 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
372341 vlan_vid_add (dev , 0 );
373342 }
374343
375- grp = rtnl_dereference (dev -> vlgrp );
376- if (!grp )
344+ vlan_info = rtnl_dereference (dev -> vlan_info );
345+ if (!vlan_info )
377346 goto out ;
347+ grp = & vlan_info -> grp ;
378348
379349 /* It is OK that we do not hold the group lock right now,
380350 * as we run under the RTNL lock.
@@ -478,9 +448,9 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
478448 if (!vlandev )
479449 continue ;
480450
481- /* unregistration of last vlan destroys group , abort
451+ /* removal of last vid destroys vlan_info , abort
482452 * afterwards */
483- if (grp -> nr_vlans == 1 )
453+ if (vlan_info -> nr_vids == 1 )
484454 i = VLAN_N_VID ;
485455
486456 unregister_vlan_dev (vlandev , & list );
0 commit comments