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