vlan.c (acc5efbcd2a023c8801f2bba39971cf93812ce7c) vlan.c (af30151709bcace1ca844d4bb8b7e2e392ff81eb)
1/*
2 * INET 802.1Q VLAN
3 * Ethernet-type device handling.
4 *
5 * Authors: Ben Greear <greearb@candelatech.com>
6 * Please send support related email to: vlan@scry.wanfear.com
7 * VLAN Home Page: http://www.candelatech.com/~greear/vlan.html
8 *

--- 118 unchanged lines hidden (view full) ---

127 return NULL;
128}
129
130static void vlan_rcu_free(struct rcu_head *rcu)
131{
132 vlan_group_free(container_of(rcu, struct vlan_group, rcu));
133}
134
1/*
2 * INET 802.1Q VLAN
3 * Ethernet-type device handling.
4 *
5 * Authors: Ben Greear <greearb@candelatech.com>
6 * Please send support related email to: vlan@scry.wanfear.com
7 * VLAN Home Page: http://www.candelatech.com/~greear/vlan.html
8 *

--- 118 unchanged lines hidden (view full) ---

127 return NULL;
128}
129
130static void vlan_rcu_free(struct rcu_head *rcu)
131{
132 vlan_group_free(container_of(rcu, struct vlan_group, rcu));
133}
134
135
136/* This returns 0 if everything went fine.
137 * It will return 1 if the group was killed as a result.
138 * A negative return indicates failure.
139 *
140 * The RTNL lock must be held.
141 */
142static int unregister_vlan_dev(struct net_device *real_dev,
143 unsigned short vlan_id)
135void unregister_vlan_dev(struct net_device *dev)
144{
136{
145 struct net_device *dev;
146 int real_dev_ifindex = real_dev->ifindex;
137 struct vlan_dev_info *vlan = VLAN_DEV_INFO(dev);
138 struct net_device *real_dev = vlan->real_dev;
147 struct vlan_group *grp;
139 struct vlan_group *grp;
148 unsigned int i;
149 int ret;
140 unsigned short vlan_id = vlan->vlan_id;
150
141
151 if (vlan_id >= VLAN_VID_MASK)
152 return -EINVAL;
153
154 ASSERT_RTNL();
142 ASSERT_RTNL();
155 grp = __vlan_find_group(real_dev_ifindex);
156 if (!grp)
157 return -ENOENT;
158
143
159 dev = vlan_group_get_device(grp, vlan_id);
160 if (!dev)
161 return -ENOENT;
144 grp = __vlan_find_group(real_dev->ifindex);
145 BUG_ON(!grp);
162
163 vlan_proc_rem_dev(dev);
164
165 /* Take it out of our own structures, but be sure to interlock with
166 * HW accelerating devices or SW vlan input packet processing.
167 */
168 if (real_dev->features & NETIF_F_HW_VLAN_FILTER)
169 real_dev->vlan_rx_kill_vid(real_dev, vlan_id);
170
171 vlan_group_set_device(grp, vlan_id, NULL);
146
147 vlan_proc_rem_dev(dev);
148
149 /* Take it out of our own structures, but be sure to interlock with
150 * HW accelerating devices or SW vlan input packet processing.
151 */
152 if (real_dev->features & NETIF_F_HW_VLAN_FILTER)
153 real_dev->vlan_rx_kill_vid(real_dev, vlan_id);
154
155 vlan_group_set_device(grp, vlan_id, NULL);
156 grp->nr_vlans--;
157
172 synchronize_net();
173
158 synchronize_net();
159
174 /* Caller unregisters (and if necessary, puts) VLAN device, but we
175 * get rid of the reference to real_dev here.
176 */
177 dev_put(real_dev);
178
179 /* If the group is now empty, kill off the group. */
160 /* If the group is now empty, kill off the group. */
180 ret = 0;
181 for (i = 0; i < VLAN_VID_MASK; i++)
182 if (vlan_group_get_device(grp, i))
183 break;
184
185 if (i == VLAN_VID_MASK) {
161 if (grp->nr_vlans == 0) {
186 if (real_dev->features & NETIF_F_HW_VLAN_RX)
187 real_dev->vlan_rx_register(real_dev, NULL);
188
189 hlist_del_rcu(&grp->hlist);
190
191 /* Free the group, after all cpu's are done. */
192 call_rcu(&grp->rcu, vlan_rcu_free);
162 if (real_dev->features & NETIF_F_HW_VLAN_RX)
163 real_dev->vlan_rx_register(real_dev, NULL);
164
165 hlist_del_rcu(&grp->hlist);
166
167 /* Free the group, after all cpu's are done. */
168 call_rcu(&grp->rcu, vlan_rcu_free);
193 ret = 1;
194 }
195
169 }
170
196 return ret;
197}
171 /* Get rid of the vlan's reference to real_dev */
172 dev_put(real_dev);
198
173
199int unregister_vlan_device(struct net_device *dev)
200{
201 int ret;
202
203 ret = unregister_vlan_dev(VLAN_DEV_INFO(dev)->real_dev,
204 VLAN_DEV_INFO(dev)->vlan_id);
205 unregister_netdevice(dev);
174 unregister_netdevice(dev);
206
207 if (ret == 1)
208 ret = 0;
209 return ret;
210}
211
212static void vlan_transfer_operstate(const struct net_device *dev, struct net_device *vlandev)
213{
214 /* Have to respect userspace enforced dormant state
215 * of real device, also must allow supplicant running
216 * on VLAN device
217 */

--- 68 unchanged lines hidden (view full) ---

286
287 vlan_transfer_operstate(real_dev, dev);
288 linkwatch_fire_event(dev); /* _MUST_ call rfc2863_policy() */
289
290 /* So, got the sucker initialized, now lets place
291 * it into our local structure.
292 */
293 vlan_group_set_device(grp, vlan_id, dev);
175}
176
177static void vlan_transfer_operstate(const struct net_device *dev, struct net_device *vlandev)
178{
179 /* Have to respect userspace enforced dormant state
180 * of real device, also must allow supplicant running
181 * on VLAN device
182 */

--- 68 unchanged lines hidden (view full) ---

251
252 vlan_transfer_operstate(real_dev, dev);
253 linkwatch_fire_event(dev); /* _MUST_ call rfc2863_policy() */
254
255 /* So, got the sucker initialized, now lets place
256 * it into our local structure.
257 */
258 vlan_group_set_device(grp, vlan_id, dev);
259 grp->nr_vlans++;
260
294 if (ngrp && real_dev->features & NETIF_F_HW_VLAN_RX)
295 real_dev->vlan_rx_register(real_dev, ngrp);
296 if (real_dev->features & NETIF_F_HW_VLAN_FILTER)
297 real_dev->vlan_rx_add_vid(real_dev, vlan_id);
298
299 if (vlan_proc_add_dev(dev) < 0)
300 pr_warning("8021q: failed to add proc entry for %s\n",
301 dev->name);

--- 172 unchanged lines hidden (view full) ---

474
475 dev_change_flags(vlandev, flgs | IFF_UP);
476 }
477 break;
478
479 case NETDEV_UNREGISTER:
480 /* Delete all VLANs for this dev. */
481 for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
261 if (ngrp && real_dev->features & NETIF_F_HW_VLAN_RX)
262 real_dev->vlan_rx_register(real_dev, ngrp);
263 if (real_dev->features & NETIF_F_HW_VLAN_FILTER)
264 real_dev->vlan_rx_add_vid(real_dev, vlan_id);
265
266 if (vlan_proc_add_dev(dev) < 0)
267 pr_warning("8021q: failed to add proc entry for %s\n",
268 dev->name);

--- 172 unchanged lines hidden (view full) ---

441
442 dev_change_flags(vlandev, flgs | IFF_UP);
443 }
444 break;
445
446 case NETDEV_UNREGISTER:
447 /* Delete all VLANs for this dev. */
448 for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
482 int ret;
483
484 vlandev = vlan_group_get_device(grp, i);
485 if (!vlandev)
486 continue;
487
449 vlandev = vlan_group_get_device(grp, i);
450 if (!vlandev)
451 continue;
452
488 ret = unregister_vlan_dev(dev,
489 VLAN_DEV_INFO(vlandev)->vlan_id);
453 /* unregistration of last vlan destroys group, abort
454 * afterwards */
455 if (grp->nr_vlans == 1)
456 i = VLAN_GROUP_ARRAY_LEN;
490
457
491 unregister_netdevice(vlandev);
492
493 /* Group was destroyed? */
494 if (ret == 1)
495 break;
458 unregister_vlan_dev(vlandev);
496 }
497 break;
498 }
499
500out:
501 return NOTIFY_DONE;
502}
503

--- 89 unchanged lines hidden (view full) ---

593 break;
594 err = register_vlan_device(dev, args.u.VID);
595 break;
596
597 case DEL_VLAN_CMD:
598 err = -EPERM;
599 if (!capable(CAP_NET_ADMIN))
600 break;
459 }
460 break;
461 }
462
463out:
464 return NOTIFY_DONE;
465}
466

--- 89 unchanged lines hidden (view full) ---

556 break;
557 err = register_vlan_device(dev, args.u.VID);
558 break;
559
560 case DEL_VLAN_CMD:
561 err = -EPERM;
562 if (!capable(CAP_NET_ADMIN))
563 break;
601 err = unregister_vlan_device(dev);
564 unregister_vlan_dev(dev);
565 err = 0;
602 break;
603
604 case GET_VLAN_REALDEV_NAME_CMD:
605 err = 0;
606 vlan_dev_get_realdev_name(dev, args.u.device2);
607 if (copy_to_user(arg, &args,
608 sizeof(struct vlan_ioctl_args))) {
609 err = -EFAULT;

--- 78 unchanged lines hidden ---
566 break;
567
568 case GET_VLAN_REALDEV_NAME_CMD:
569 err = 0;
570 vlan_dev_get_realdev_name(dev, args.u.device2);
571 if (copy_to_user(arg, &args,
572 sizeof(struct vlan_ioctl_args))) {
573 err = -EFAULT;

--- 78 unchanged lines hidden ---