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 --- |