vlan.c (1e43bee9c70654b4d52472c19e5f0a0cc18b6b36) vlan.c (5e7565930524410f097f5b04f8aba663089a6ffc)
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: netdev@vger.kernel.org
7 * VLAN Home Page: http://www.candelatech.com/~greear/vlan.html
8 *

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

36#include <linux/if_vlan.h>
37#include "vlan.h"
38#include "vlanproc.h"
39
40#define DRV_VERSION "1.8"
41
42/* Global VLAN variables */
43
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: netdev@vger.kernel.org
7 * VLAN Home Page: http://www.candelatech.com/~greear/vlan.html
8 *

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

36#include <linux/if_vlan.h>
37#include "vlan.h"
38#include "vlanproc.h"
39
40#define DRV_VERSION "1.8"
41
42/* Global VLAN variables */
43
44int vlan_net_id;
44int vlan_net_id __read_mostly;
45
46/* Our listing of VLAN group(s) */
47static struct hlist_head vlan_group_hash[VLAN_GRP_HASH_SIZE];
48
49const char vlan_fullname[] = "802.1Q VLAN Support";
50const char vlan_version[] = DRV_VERSION;
51static const char vlan_copyright[] = "Ben Greear <greearb@candelatech.com>";
52static const char vlan_buggyright[] = "David S. Miller <davem@redhat.com>";

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

135 return 0;
136}
137
138static void vlan_rcu_free(struct rcu_head *rcu)
139{
140 vlan_group_free(container_of(rcu, struct vlan_group, rcu));
141}
142
45
46/* Our listing of VLAN group(s) */
47static struct hlist_head vlan_group_hash[VLAN_GRP_HASH_SIZE];
48
49const char vlan_fullname[] = "802.1Q VLAN Support";
50const char vlan_version[] = DRV_VERSION;
51static const char vlan_copyright[] = "Ben Greear <greearb@candelatech.com>";
52static const char vlan_buggyright[] = "David S. Miller <davem@redhat.com>";

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

135 return 0;
136}
137
138static void vlan_rcu_free(struct rcu_head *rcu)
139{
140 vlan_group_free(container_of(rcu, struct vlan_group, rcu));
141}
142
143void unregister_vlan_dev(struct net_device *dev)
143void unregister_vlan_dev(struct net_device *dev, struct list_head *head)
144{
145 struct vlan_dev_info *vlan = vlan_dev_info(dev);
146 struct net_device *real_dev = vlan->real_dev;
147 const struct net_device_ops *ops = real_dev->netdev_ops;
148 struct vlan_group *grp;
149 u16 vlan_id = vlan->vlan_id;
150
151 ASSERT_RTNL();
152
153 grp = __vlan_find_group(real_dev);
154 BUG_ON(!grp);
155
156 /* Take it out of our own structures, but be sure to interlock with
157 * HW accelerating devices or SW vlan input packet processing.
158 */
159 if (real_dev->features & NETIF_F_HW_VLAN_FILTER)
160 ops->ndo_vlan_rx_kill_vid(real_dev, vlan_id);
161
144{
145 struct vlan_dev_info *vlan = vlan_dev_info(dev);
146 struct net_device *real_dev = vlan->real_dev;
147 const struct net_device_ops *ops = real_dev->netdev_ops;
148 struct vlan_group *grp;
149 u16 vlan_id = vlan->vlan_id;
150
151 ASSERT_RTNL();
152
153 grp = __vlan_find_group(real_dev);
154 BUG_ON(!grp);
155
156 /* Take it out of our own structures, but be sure to interlock with
157 * HW accelerating devices or SW vlan input packet processing.
158 */
159 if (real_dev->features & NETIF_F_HW_VLAN_FILTER)
160 ops->ndo_vlan_rx_kill_vid(real_dev, vlan_id);
161
162 vlan_group_set_device(grp, vlan_id, NULL);
163 grp->nr_vlans--;
164
162 grp->nr_vlans--;
163
165 synchronize_net();
164 vlan_group_set_device(grp, vlan_id, NULL);
165 if (!grp->killall)
166 synchronize_net();
166
167
167 unregister_netdevice(dev);
168 unregister_netdevice_queue(dev, head);
168
169 /* If the group is now empty, kill off the group. */
170 if (grp->nr_vlans == 0) {
171 vlan_gvrp_uninit_applicant(real_dev);
172
173 if (real_dev->features & NETIF_F_HW_VLAN_RX)
174 ops->ndo_vlan_rx_register(real_dev, NULL);
175

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

425
426static int vlan_device_event(struct notifier_block *unused, unsigned long event,
427 void *ptr)
428{
429 struct net_device *dev = ptr;
430 struct vlan_group *grp;
431 int i, flgs;
432 struct net_device *vlandev;
169
170 /* If the group is now empty, kill off the group. */
171 if (grp->nr_vlans == 0) {
172 vlan_gvrp_uninit_applicant(real_dev);
173
174 if (real_dev->features & NETIF_F_HW_VLAN_RX)
175 ops->ndo_vlan_rx_register(real_dev, NULL);
176

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

426
427static int vlan_device_event(struct notifier_block *unused, unsigned long event,
428 void *ptr)
429{
430 struct net_device *dev = ptr;
431 struct vlan_group *grp;
432 int i, flgs;
433 struct net_device *vlandev;
434 struct vlan_dev_info *vlan;
435 LIST_HEAD(list);
433
434 if (is_vlan_dev(dev))
435 __vlan_device_event(dev, event);
436
437 grp = __vlan_find_group(dev);
438 if (!grp)
439 goto out;
440

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

500 vlandev = vlan_group_get_device(grp, i);
501 if (!vlandev)
502 continue;
503
504 flgs = vlandev->flags;
505 if (!(flgs & IFF_UP))
506 continue;
507
436
437 if (is_vlan_dev(dev))
438 __vlan_device_event(dev, event);
439
440 grp = __vlan_find_group(dev);
441 if (!grp)
442 goto out;
443

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

503 vlandev = vlan_group_get_device(grp, i);
504 if (!vlandev)
505 continue;
506
507 flgs = vlandev->flags;
508 if (!(flgs & IFF_UP))
509 continue;
510
508 dev_change_flags(vlandev, flgs & ~IFF_UP);
511 vlan = vlan_dev_info(vlandev);
512 if (!(vlan->flags & VLAN_FLAG_LOOSE_BINDING))
513 dev_change_flags(vlandev, flgs & ~IFF_UP);
509 vlan_transfer_operstate(dev, vlandev);
510 }
511 break;
512
513 case NETDEV_UP:
514 /* Put all VLANs for this dev in the up state too. */
515 for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
516 vlandev = vlan_group_get_device(grp, i);
517 if (!vlandev)
518 continue;
519
520 flgs = vlandev->flags;
521 if (flgs & IFF_UP)
522 continue;
523
514 vlan_transfer_operstate(dev, vlandev);
515 }
516 break;
517
518 case NETDEV_UP:
519 /* Put all VLANs for this dev in the up state too. */
520 for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
521 vlandev = vlan_group_get_device(grp, i);
522 if (!vlandev)
523 continue;
524
525 flgs = vlandev->flags;
526 if (flgs & IFF_UP)
527 continue;
528
524 dev_change_flags(vlandev, flgs | IFF_UP);
529 vlan = vlan_dev_info(vlandev);
530 if (!(vlan->flags & VLAN_FLAG_LOOSE_BINDING))
531 dev_change_flags(vlandev, flgs | IFF_UP);
525 vlan_transfer_operstate(dev, vlandev);
526 }
527 break;
528
529 case NETDEV_UNREGISTER:
530 /* Delete all VLANs for this dev. */
532 vlan_transfer_operstate(dev, vlandev);
533 }
534 break;
535
536 case NETDEV_UNREGISTER:
537 /* Delete all VLANs for this dev. */
538 grp->killall = 1;
539
531 for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
532 vlandev = vlan_group_get_device(grp, i);
533 if (!vlandev)
534 continue;
535
536 /* unregistration of last vlan destroys group, abort
537 * afterwards */
538 if (grp->nr_vlans == 1)
539 i = VLAN_GROUP_ARRAY_LEN;
540
540 for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
541 vlandev = vlan_group_get_device(grp, i);
542 if (!vlandev)
543 continue;
544
545 /* unregistration of last vlan destroys group, abort
546 * afterwards */
547 if (grp->nr_vlans == 1)
548 i = VLAN_GROUP_ARRAY_LEN;
549
541 unregister_vlan_dev(vlandev);
550 unregister_vlan_dev(vlandev, &list);
542 }
551 }
552 unregister_netdevice_many(&list);
543 break;
544 }
545
546out:
547 return NOTIFY_DONE;
548}
549
550static struct notifier_block vlan_notifier_block __read_mostly = {

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

640 break;
641 err = register_vlan_device(dev, args.u.VID);
642 break;
643
644 case DEL_VLAN_CMD:
645 err = -EPERM;
646 if (!capable(CAP_NET_ADMIN))
647 break;
553 break;
554 }
555
556out:
557 return NOTIFY_DONE;
558}
559
560static struct notifier_block vlan_notifier_block __read_mostly = {

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

650 break;
651 err = register_vlan_device(dev, args.u.VID);
652 break;
653
654 case DEL_VLAN_CMD:
655 err = -EPERM;
656 if (!capable(CAP_NET_ADMIN))
657 break;
648 unregister_vlan_dev(dev);
658 unregister_vlan_dev(dev, NULL);
649 err = 0;
650 break;
651
652 case GET_VLAN_REALDEV_NAME_CMD:
653 err = 0;
654 vlan_dev_get_realdev_name(dev, args.u.device2);
655 if (copy_to_user(arg, &args,
656 sizeof(struct vlan_ioctl_args)))

--- 128 unchanged lines hidden ---
659 err = 0;
660 break;
661
662 case GET_VLAN_REALDEV_NAME_CMD:
663 err = 0;
664 vlan_dev_get_realdev_name(dev, args.u.device2);
665 if (copy_to_user(arg, &args,
666 sizeof(struct vlan_ioctl_args)))

--- 128 unchanged lines hidden ---