@@ -51,27 +51,6 @@ const char vlan_version[] = DRV_VERSION;
51
51
52
52
/* End of global variables definitions. */
53
53
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
-
75
54
static int vlan_group_prealloc_vid (struct vlan_group * vg , u16 vlan_id )
76
55
{
77
56
struct net_device * * array ;
@@ -92,22 +71,20 @@ static int vlan_group_prealloc_vid(struct vlan_group *vg, u16 vlan_id)
92
71
return 0 ;
93
72
}
94
73
95
- static void vlan_rcu_free (struct rcu_head * rcu )
96
- {
97
- vlan_group_free (container_of (rcu , struct vlan_group , rcu ));
98
- }
99
-
100
74
void unregister_vlan_dev (struct net_device * dev , struct list_head * head )
101
75
{
102
76
struct vlan_dev_priv * vlan = vlan_dev_priv (dev );
103
77
struct net_device * real_dev = vlan -> real_dev ;
78
+ struct vlan_info * vlan_info ;
104
79
struct vlan_group * grp ;
105
80
u16 vlan_id = vlan -> vlan_id ;
106
81
107
82
ASSERT_RTNL ();
108
83
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 ;
111
88
112
89
/* Take it out of our own structures, but be sure to interlock with
113
90
* 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)
116
93
if (vlan_id )
117
94
vlan_vid_del (real_dev , vlan_id );
118
95
119
- grp -> nr_vlans -- ;
96
+ grp -> nr_vlan_devs -- ;
120
97
121
98
if (vlan -> flags & VLAN_FLAG_GVRP )
122
99
vlan_gvrp_request_leave (dev );
@@ -128,16 +105,9 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head)
128
105
*/
129
106
unregister_netdevice_queue (dev , head );
130
107
131
- /* If the group is now empty, kill off the group. */
132
- if (grp -> nr_vlans == 0 ) {
108
+ if (grp -> nr_vlan_devs == 0 )
133
109
vlan_gvrp_uninit_applicant (real_dev );
134
110
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
-
141
111
/* Get rid of the vlan's reference to real_dev */
142
112
dev_put (real_dev );
143
113
}
@@ -169,17 +139,23 @@ int register_vlan_dev(struct net_device *dev)
169
139
struct vlan_dev_priv * vlan = vlan_dev_priv (dev );
170
140
struct net_device * real_dev = vlan -> real_dev ;
171
141
u16 vlan_id = vlan -> vlan_id ;
172
- struct vlan_group * grp , * ngrp = NULL ;
142
+ struct vlan_info * vlan_info ;
143
+ struct vlan_group * grp ;
173
144
int err ;
174
145
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 ) {
180
156
err = vlan_gvrp_init_applicant (real_dev );
181
157
if (err < 0 )
182
- goto out_free_group ;
158
+ goto out_vid_del ;
183
159
}
184
160
185
161
err = vlan_group_prealloc_vid (grp , vlan_id );
@@ -200,23 +176,15 @@ int register_vlan_dev(struct net_device *dev)
200
176
* it into our local structure.
201
177
*/
202
178
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 ++ ;
209
180
210
181
return 0 ;
211
182
212
183
out_uninit_applicant :
213
- if (ngrp )
184
+ if (grp -> nr_vlan_devs == 0 )
214
185
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 );
220
188
return err ;
221
189
}
222
190
@@ -357,6 +325,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
357
325
{
358
326
struct net_device * dev = ptr ;
359
327
struct vlan_group * grp ;
328
+ struct vlan_info * vlan_info ;
360
329
int i , flgs ;
361
330
struct net_device * vlandev ;
362
331
struct vlan_dev_priv * vlan ;
@@ -372,9 +341,10 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
372
341
vlan_vid_add (dev , 0 );
373
342
}
374
343
375
- grp = rtnl_dereference (dev -> vlgrp );
376
- if (!grp )
344
+ vlan_info = rtnl_dereference (dev -> vlan_info );
345
+ if (!vlan_info )
377
346
goto out ;
347
+ grp = & vlan_info -> grp ;
378
348
379
349
/* It is OK that we do not hold the group lock right now,
380
350
* as we run under the RTNL lock.
@@ -478,9 +448,9 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
478
448
if (!vlandev )
479
449
continue ;
480
450
481
- /* unregistration of last vlan destroys group , abort
451
+ /* removal of last vid destroys vlan_info , abort
482
452
* afterwards */
483
- if (grp -> nr_vlans == 1 )
453
+ if (vlan_info -> nr_vids == 1 )
484
454
i = VLAN_N_VID ;
485
455
486
456
unregister_vlan_dev (vlandev , & list );
0 commit comments