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 * 9 * Fixes: 10 * Fix for packet capture - Nick Eggleston <nick@dccinc.com>; 11 * Add HW acceleration hooks - David S. Miller <davem@redhat.com>; 12 * Correct all the locking - David S. Miller <davem@redhat.com>; 13 * Use hash table for VLAN groups - David S. Miller <davem@redhat.com> 14 * 15 * This program is free software; you can redistribute it and/or 16 * modify it under the terms of the GNU General Public License 17 * as published by the Free Software Foundation; either version 18 * 2 of the License, or (at your option) any later version. 19 */ 20 21 #include <asm/uaccess.h> /* for copy_from_user */ 22 #include <linux/capability.h> 23 #include <linux/module.h> 24 #include <linux/netdevice.h> 25 #include <linux/skbuff.h> 26 #include <net/datalink.h> 27 #include <linux/mm.h> 28 #include <linux/in.h> 29 #include <linux/init.h> 30 #include <net/p8022.h> 31 #include <net/arp.h> 32 #include <linux/rtnetlink.h> 33 #include <linux/notifier.h> 34 35 #include <linux/if_vlan.h> 36 #include "vlan.h" 37 #include "vlanproc.h" 38 39 #define DRV_VERSION "1.8" 40 41 /* Global VLAN variables */ 42 43 /* Our listing of VLAN group(s) */ 44 static struct hlist_head vlan_group_hash[VLAN_GRP_HASH_SIZE]; 45 #define vlan_grp_hashfn(IDX) ((((IDX) >> VLAN_GRP_HASH_SHIFT) ^ (IDX)) & VLAN_GRP_HASH_MASK) 46 47 static char vlan_fullname[] = "802.1Q VLAN Support"; 48 static char vlan_version[] = DRV_VERSION; 49 static char vlan_copyright[] = "Ben Greear <greearb@candelatech.com>"; 50 static char vlan_buggyright[] = "David S. Miller <davem@redhat.com>"; 51 52 static int vlan_device_event(struct notifier_block *, unsigned long, void *); 53 static int vlan_ioctl_handler(void __user *); 54 static int unregister_vlan_dev(struct net_device *, unsigned short ); 55 56 static struct notifier_block vlan_notifier_block = { 57 .notifier_call = vlan_device_event, 58 }; 59 60 /* These may be changed at run-time through IOCTLs */ 61 62 /* Determines interface naming scheme. */ 63 unsigned short vlan_name_type = VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD; 64 65 static struct packet_type vlan_packet_type = { 66 .type = __constant_htons(ETH_P_8021Q), 67 .func = vlan_skb_recv, /* VLAN receive method */ 68 }; 69 70 /* End of global variables definitions. */ 71 72 /* 73 * Function vlan_proto_init (pro) 74 * 75 * Initialize VLAN protocol layer, 76 * 77 */ 78 static int __init vlan_proto_init(void) 79 { 80 int err; 81 82 printk(VLAN_INF "%s v%s %s\n", 83 vlan_fullname, vlan_version, vlan_copyright); 84 printk(VLAN_INF "All bugs added by %s\n", 85 vlan_buggyright); 86 87 /* proc file system initialization */ 88 err = vlan_proc_init(); 89 if (err < 0) { 90 printk(KERN_ERR 91 "%s %s: can't create entry in proc filesystem!\n", 92 __FUNCTION__, VLAN_NAME); 93 return err; 94 } 95 96 dev_add_pack(&vlan_packet_type); 97 98 /* Register us to receive netdevice events */ 99 err = register_netdevice_notifier(&vlan_notifier_block); 100 if (err < 0) 101 goto err1; 102 103 err = vlan_netlink_init(); 104 if (err < 0) 105 goto err2; 106 107 vlan_ioctl_set(vlan_ioctl_handler); 108 return 0; 109 110 err2: 111 unregister_netdevice_notifier(&vlan_notifier_block); 112 err1: 113 vlan_proc_cleanup(); 114 dev_remove_pack(&vlan_packet_type); 115 return err; 116 } 117 118 /* 119 * Module 'remove' entry point. 120 * o delete /proc/net/router directory and static entries. 121 */ 122 static void __exit vlan_cleanup_module(void) 123 { 124 int i; 125 126 vlan_netlink_fini(); 127 vlan_ioctl_set(NULL); 128 129 /* Un-register us from receiving netdevice events */ 130 unregister_netdevice_notifier(&vlan_notifier_block); 131 132 dev_remove_pack(&vlan_packet_type); 133 134 /* This table must be empty if there are no module 135 * references left. 136 */ 137 for (i = 0; i < VLAN_GRP_HASH_SIZE; i++) { 138 BUG_ON(!hlist_empty(&vlan_group_hash[i])); 139 } 140 vlan_proc_cleanup(); 141 142 synchronize_net(); 143 } 144 145 module_init(vlan_proto_init); 146 module_exit(vlan_cleanup_module); 147 148 /* Must be invoked with RCU read lock (no preempt) */ 149 static struct vlan_group *__vlan_find_group(int real_dev_ifindex) 150 { 151 struct vlan_group *grp; 152 struct hlist_node *n; 153 int hash = vlan_grp_hashfn(real_dev_ifindex); 154 155 hlist_for_each_entry_rcu(grp, n, &vlan_group_hash[hash], hlist) { 156 if (grp->real_dev_ifindex == real_dev_ifindex) 157 return grp; 158 } 159 160 return NULL; 161 } 162 163 /* Find the protocol handler. Assumes VID < VLAN_VID_MASK. 164 * 165 * Must be invoked with RCU read lock (no preempt) 166 */ 167 struct net_device *__find_vlan_dev(struct net_device *real_dev, 168 unsigned short VID) 169 { 170 struct vlan_group *grp = __vlan_find_group(real_dev->ifindex); 171 172 if (grp) 173 return vlan_group_get_device(grp, VID); 174 175 return NULL; 176 } 177 178 static void vlan_group_free(struct vlan_group *grp) 179 { 180 int i; 181 182 for (i=0; i < VLAN_GROUP_ARRAY_SPLIT_PARTS; i++) 183 kfree(grp->vlan_devices_arrays[i]); 184 kfree(grp); 185 } 186 187 static struct vlan_group *vlan_group_alloc(int ifindex) 188 { 189 struct vlan_group *grp; 190 unsigned int size; 191 unsigned int i; 192 193 grp = kzalloc(sizeof(struct vlan_group), GFP_KERNEL); 194 if (!grp) 195 return NULL; 196 197 size = sizeof(struct net_device *) * VLAN_GROUP_ARRAY_PART_LEN; 198 199 for (i = 0; i < VLAN_GROUP_ARRAY_SPLIT_PARTS; i++) { 200 grp->vlan_devices_arrays[i] = kzalloc(size, GFP_KERNEL); 201 if (!grp->vlan_devices_arrays[i]) 202 goto err; 203 } 204 205 grp->real_dev_ifindex = ifindex; 206 hlist_add_head_rcu(&grp->hlist, 207 &vlan_group_hash[vlan_grp_hashfn(ifindex)]); 208 return grp; 209 210 err: 211 vlan_group_free(grp); 212 return NULL; 213 } 214 215 static void vlan_rcu_free(struct rcu_head *rcu) 216 { 217 vlan_group_free(container_of(rcu, struct vlan_group, rcu)); 218 } 219 220 221 /* This returns 0 if everything went fine. 222 * It will return 1 if the group was killed as a result. 223 * A negative return indicates failure. 224 * 225 * The RTNL lock must be held. 226 */ 227 static int unregister_vlan_dev(struct net_device *real_dev, 228 unsigned short vlan_id) 229 { 230 struct net_device *dev = NULL; 231 int real_dev_ifindex = real_dev->ifindex; 232 struct vlan_group *grp; 233 int i, ret; 234 235 #ifdef VLAN_DEBUG 236 printk(VLAN_DBG "%s: VID: %i\n", __FUNCTION__, vlan_id); 237 #endif 238 239 /* sanity check */ 240 if (vlan_id >= VLAN_VID_MASK) 241 return -EINVAL; 242 243 ASSERT_RTNL(); 244 grp = __vlan_find_group(real_dev_ifindex); 245 246 ret = 0; 247 248 if (grp) { 249 dev = vlan_group_get_device(grp, vlan_id); 250 if (dev) { 251 /* Remove proc entry */ 252 vlan_proc_rem_dev(dev); 253 254 /* Take it out of our own structures, but be sure to 255 * interlock with HW accelerating devices or SW vlan 256 * input packet processing. 257 */ 258 if (real_dev->features & NETIF_F_HW_VLAN_FILTER) 259 real_dev->vlan_rx_kill_vid(real_dev, vlan_id); 260 261 vlan_group_set_device(grp, vlan_id, NULL); 262 synchronize_net(); 263 264 265 /* Caller unregisters (and if necessary, puts) 266 * VLAN device, but we get rid of the reference to 267 * real_dev here. 268 */ 269 dev_put(real_dev); 270 271 /* If the group is now empty, kill off the 272 * group. 273 */ 274 for (i = 0; i < VLAN_VID_MASK; i++) 275 if (vlan_group_get_device(grp, i)) 276 break; 277 278 if (i == VLAN_VID_MASK) { 279 if (real_dev->features & NETIF_F_HW_VLAN_RX) 280 real_dev->vlan_rx_register(real_dev, NULL); 281 282 hlist_del_rcu(&grp->hlist); 283 284 /* Free the group, after all cpu's are done. */ 285 call_rcu(&grp->rcu, vlan_rcu_free); 286 287 grp = NULL; 288 ret = 1; 289 } 290 } 291 } 292 293 return ret; 294 } 295 296 int unregister_vlan_device(struct net_device *dev) 297 { 298 int ret; 299 300 ret = unregister_vlan_dev(VLAN_DEV_INFO(dev)->real_dev, 301 VLAN_DEV_INFO(dev)->vlan_id); 302 unregister_netdevice(dev); 303 304 if (ret == 1) 305 ret = 0; 306 return ret; 307 } 308 309 /* 310 * vlan network devices have devices nesting below it, and are a special 311 * "super class" of normal network devices; split their locks off into a 312 * separate class since they always nest. 313 */ 314 static struct lock_class_key vlan_netdev_xmit_lock_key; 315 316 static int vlan_dev_init(struct net_device *dev) 317 { 318 struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev; 319 320 /* IFF_BROADCAST|IFF_MULTICAST; ??? */ 321 dev->flags = real_dev->flags & ~IFF_UP; 322 dev->iflink = real_dev->ifindex; 323 dev->state = (real_dev->state & ((1<<__LINK_STATE_NOCARRIER) | 324 (1<<__LINK_STATE_DORMANT))) | 325 (1<<__LINK_STATE_PRESENT); 326 327 if (is_zero_ether_addr(dev->dev_addr)) 328 memcpy(dev->dev_addr, real_dev->dev_addr, dev->addr_len); 329 if (is_zero_ether_addr(dev->broadcast)) 330 memcpy(dev->broadcast, real_dev->broadcast, dev->addr_len); 331 332 if (real_dev->features & NETIF_F_HW_VLAN_TX) { 333 dev->hard_header = real_dev->hard_header; 334 dev->hard_header_len = real_dev->hard_header_len; 335 dev->hard_start_xmit = vlan_dev_hwaccel_hard_start_xmit; 336 dev->rebuild_header = real_dev->rebuild_header; 337 } else { 338 dev->hard_header = vlan_dev_hard_header; 339 dev->hard_header_len = real_dev->hard_header_len + VLAN_HLEN; 340 dev->hard_start_xmit = vlan_dev_hard_start_xmit; 341 dev->rebuild_header = vlan_dev_rebuild_header; 342 } 343 dev->hard_header_parse = real_dev->hard_header_parse; 344 dev->hard_header_cache = NULL; 345 346 lockdep_set_class(&dev->_xmit_lock, &vlan_netdev_xmit_lock_key); 347 return 0; 348 } 349 350 void vlan_setup(struct net_device *new_dev) 351 { 352 SET_MODULE_OWNER(new_dev); 353 354 ether_setup(new_dev); 355 356 /* new_dev->ifindex = 0; it will be set when added to 357 * the global list. 358 * iflink is set as well. 359 */ 360 new_dev->get_stats = vlan_dev_get_stats; 361 362 /* Make this thing known as a VLAN device */ 363 new_dev->priv_flags |= IFF_802_1Q_VLAN; 364 365 /* Set us up to have no queue, as the underlying Hardware device 366 * can do all the queueing we could want. 367 */ 368 new_dev->tx_queue_len = 0; 369 370 /* set up method calls */ 371 new_dev->change_mtu = vlan_dev_change_mtu; 372 new_dev->init = vlan_dev_init; 373 new_dev->open = vlan_dev_open; 374 new_dev->stop = vlan_dev_stop; 375 new_dev->set_multicast_list = vlan_dev_set_multicast_list; 376 new_dev->change_rx_flags = vlan_change_rx_flags; 377 new_dev->destructor = free_netdev; 378 new_dev->do_ioctl = vlan_dev_ioctl; 379 380 memset(new_dev->broadcast, 0, ETH_ALEN); 381 } 382 383 static void vlan_transfer_operstate(const struct net_device *dev, struct net_device *vlandev) 384 { 385 /* Have to respect userspace enforced dormant state 386 * of real device, also must allow supplicant running 387 * on VLAN device 388 */ 389 if (dev->operstate == IF_OPER_DORMANT) 390 netif_dormant_on(vlandev); 391 else 392 netif_dormant_off(vlandev); 393 394 if (netif_carrier_ok(dev)) { 395 if (!netif_carrier_ok(vlandev)) 396 netif_carrier_on(vlandev); 397 } else { 398 if (netif_carrier_ok(vlandev)) 399 netif_carrier_off(vlandev); 400 } 401 } 402 403 int vlan_check_real_dev(struct net_device *real_dev, unsigned short vlan_id) 404 { 405 if (real_dev->features & NETIF_F_VLAN_CHALLENGED) { 406 printk(VLAN_DBG "%s: VLANs not supported on %s.\n", 407 __FUNCTION__, real_dev->name); 408 return -EOPNOTSUPP; 409 } 410 411 if ((real_dev->features & NETIF_F_HW_VLAN_RX) && 412 !real_dev->vlan_rx_register) { 413 printk(VLAN_DBG "%s: Device %s has buggy VLAN hw accel.\n", 414 __FUNCTION__, real_dev->name); 415 return -EOPNOTSUPP; 416 } 417 418 if ((real_dev->features & NETIF_F_HW_VLAN_FILTER) && 419 (!real_dev->vlan_rx_add_vid || !real_dev->vlan_rx_kill_vid)) { 420 printk(VLAN_DBG "%s: Device %s has buggy VLAN hw accel.\n", 421 __FUNCTION__, real_dev->name); 422 return -EOPNOTSUPP; 423 } 424 425 /* The real device must be up and operating in order to 426 * assosciate a VLAN device with it. 427 */ 428 if (!(real_dev->flags & IFF_UP)) 429 return -ENETDOWN; 430 431 if (__find_vlan_dev(real_dev, vlan_id) != NULL) { 432 /* was already registered. */ 433 printk(VLAN_DBG "%s: ALREADY had VLAN registered\n", __FUNCTION__); 434 return -EEXIST; 435 } 436 437 return 0; 438 } 439 440 int register_vlan_dev(struct net_device *dev) 441 { 442 struct vlan_dev_info *vlan = VLAN_DEV_INFO(dev); 443 struct net_device *real_dev = vlan->real_dev; 444 unsigned short vlan_id = vlan->vlan_id; 445 struct vlan_group *grp, *ngrp = NULL; 446 int err; 447 448 grp = __vlan_find_group(real_dev->ifindex); 449 if (!grp) { 450 ngrp = grp = vlan_group_alloc(real_dev->ifindex); 451 if (!grp) 452 return -ENOBUFS; 453 } 454 455 err = register_netdevice(dev); 456 if (err < 0) 457 goto out_free_group; 458 459 /* Account for reference in struct vlan_dev_info */ 460 dev_hold(real_dev); 461 462 vlan_transfer_operstate(real_dev, dev); 463 linkwatch_fire_event(dev); /* _MUST_ call rfc2863_policy() */ 464 465 /* So, got the sucker initialized, now lets place 466 * it into our local structure. 467 */ 468 vlan_group_set_device(grp, vlan_id, dev); 469 if (ngrp && real_dev->features & NETIF_F_HW_VLAN_RX) 470 real_dev->vlan_rx_register(real_dev, ngrp); 471 if (real_dev->features & NETIF_F_HW_VLAN_FILTER) 472 real_dev->vlan_rx_add_vid(real_dev, vlan_id); 473 474 if (vlan_proc_add_dev(dev) < 0) 475 printk(KERN_WARNING "VLAN: failed to add proc entry for %s\n", 476 dev->name); 477 return 0; 478 479 out_free_group: 480 if (ngrp) 481 vlan_group_free(ngrp); 482 return err; 483 } 484 485 /* Attach a VLAN device to a mac address (ie Ethernet Card). 486 * Returns 0 if the device was created or a negative error code otherwise. 487 */ 488 static int register_vlan_device(struct net_device *real_dev, 489 unsigned short VLAN_ID) 490 { 491 struct net_device *new_dev; 492 char name[IFNAMSIZ]; 493 int err; 494 495 #ifdef VLAN_DEBUG 496 printk(VLAN_DBG "%s: if_name -:%s:- vid: %i\n", 497 __FUNCTION__, eth_IF_name, VLAN_ID); 498 #endif 499 500 if (VLAN_ID >= VLAN_VID_MASK) 501 return -ERANGE; 502 503 err = vlan_check_real_dev(real_dev, VLAN_ID); 504 if (err < 0) 505 return err; 506 507 /* Gotta set up the fields for the device. */ 508 #ifdef VLAN_DEBUG 509 printk(VLAN_DBG "About to allocate name, vlan_name_type: %i\n", 510 vlan_name_type); 511 #endif 512 switch (vlan_name_type) { 513 case VLAN_NAME_TYPE_RAW_PLUS_VID: 514 /* name will look like: eth1.0005 */ 515 snprintf(name, IFNAMSIZ, "%s.%.4i", real_dev->name, VLAN_ID); 516 break; 517 case VLAN_NAME_TYPE_PLUS_VID_NO_PAD: 518 /* Put our vlan.VID in the name. 519 * Name will look like: vlan5 520 */ 521 snprintf(name, IFNAMSIZ, "vlan%i", VLAN_ID); 522 break; 523 case VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD: 524 /* Put our vlan.VID in the name. 525 * Name will look like: eth0.5 526 */ 527 snprintf(name, IFNAMSIZ, "%s.%i", real_dev->name, VLAN_ID); 528 break; 529 case VLAN_NAME_TYPE_PLUS_VID: 530 /* Put our vlan.VID in the name. 531 * Name will look like: vlan0005 532 */ 533 default: 534 snprintf(name, IFNAMSIZ, "vlan%.4i", VLAN_ID); 535 } 536 537 new_dev = alloc_netdev(sizeof(struct vlan_dev_info), name, 538 vlan_setup); 539 540 if (new_dev == NULL) 541 return -ENOBUFS; 542 543 /* need 4 bytes for extra VLAN header info, 544 * hope the underlying device can handle it. 545 */ 546 new_dev->mtu = real_dev->mtu; 547 548 #ifdef VLAN_DEBUG 549 printk(VLAN_DBG "Allocated new name -:%s:-\n", new_dev->name); 550 VLAN_MEM_DBG("new_dev->priv malloc, addr: %p size: %i\n", 551 new_dev->priv, 552 sizeof(struct vlan_dev_info)); 553 #endif 554 555 VLAN_DEV_INFO(new_dev)->vlan_id = VLAN_ID; /* 1 through VLAN_VID_MASK */ 556 VLAN_DEV_INFO(new_dev)->real_dev = real_dev; 557 VLAN_DEV_INFO(new_dev)->dent = NULL; 558 VLAN_DEV_INFO(new_dev)->flags = VLAN_FLAG_REORDER_HDR; 559 560 new_dev->rtnl_link_ops = &vlan_link_ops; 561 err = register_vlan_dev(new_dev); 562 if (err < 0) 563 goto out_free_newdev; 564 565 /* Account for reference in struct vlan_dev_info */ 566 dev_hold(real_dev); 567 #ifdef VLAN_DEBUG 568 printk(VLAN_DBG "Allocated new device successfully, returning.\n"); 569 #endif 570 return 0; 571 572 out_free_newdev: 573 free_netdev(new_dev); 574 return err; 575 } 576 577 static void vlan_sync_address(struct net_device *dev, 578 struct net_device *vlandev) 579 { 580 struct vlan_dev_info *vlan = VLAN_DEV_INFO(vlandev); 581 582 /* May be called without an actual change */ 583 if (!compare_ether_addr(vlan->real_dev_addr, dev->dev_addr)) 584 return; 585 586 /* vlan address was different from the old address and is equal to 587 * the new address */ 588 if (compare_ether_addr(vlandev->dev_addr, vlan->real_dev_addr) && 589 !compare_ether_addr(vlandev->dev_addr, dev->dev_addr)) 590 dev_unicast_delete(dev, vlandev->dev_addr, ETH_ALEN); 591 592 /* vlan address was equal to the old address and is different from 593 * the new address */ 594 if (!compare_ether_addr(vlandev->dev_addr, vlan->real_dev_addr) && 595 compare_ether_addr(vlandev->dev_addr, dev->dev_addr)) 596 dev_unicast_add(dev, vlandev->dev_addr, ETH_ALEN); 597 598 memcpy(vlan->real_dev_addr, dev->dev_addr, ETH_ALEN); 599 } 600 601 static int vlan_device_event(struct notifier_block *unused, unsigned long event, void *ptr) 602 { 603 struct net_device *dev = ptr; 604 struct vlan_group *grp = __vlan_find_group(dev->ifindex); 605 int i, flgs; 606 struct net_device *vlandev; 607 608 if (!grp) 609 goto out; 610 611 /* It is OK that we do not hold the group lock right now, 612 * as we run under the RTNL lock. 613 */ 614 615 switch (event) { 616 case NETDEV_CHANGE: 617 /* Propagate real device state to vlan devices */ 618 for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { 619 vlandev = vlan_group_get_device(grp, i); 620 if (!vlandev) 621 continue; 622 623 vlan_transfer_operstate(dev, vlandev); 624 } 625 break; 626 627 case NETDEV_CHANGEADDR: 628 /* Adjust unicast filters on underlying device */ 629 for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { 630 vlandev = vlan_group_get_device(grp, i); 631 if (!vlandev) 632 continue; 633 634 vlan_sync_address(dev, vlandev); 635 } 636 break; 637 638 case NETDEV_DOWN: 639 /* Put all VLANs for this dev in the down state too. */ 640 for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { 641 vlandev = vlan_group_get_device(grp, i); 642 if (!vlandev) 643 continue; 644 645 flgs = vlandev->flags; 646 if (!(flgs & IFF_UP)) 647 continue; 648 649 dev_change_flags(vlandev, flgs & ~IFF_UP); 650 } 651 break; 652 653 case NETDEV_UP: 654 /* Put all VLANs for this dev in the up state too. */ 655 for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { 656 vlandev = vlan_group_get_device(grp, i); 657 if (!vlandev) 658 continue; 659 660 flgs = vlandev->flags; 661 if (flgs & IFF_UP) 662 continue; 663 664 dev_change_flags(vlandev, flgs | IFF_UP); 665 } 666 break; 667 668 case NETDEV_UNREGISTER: 669 /* Delete all VLANs for this dev. */ 670 for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { 671 int ret; 672 673 vlandev = vlan_group_get_device(grp, i); 674 if (!vlandev) 675 continue; 676 677 ret = unregister_vlan_dev(dev, 678 VLAN_DEV_INFO(vlandev)->vlan_id); 679 680 unregister_netdevice(vlandev); 681 682 /* Group was destroyed? */ 683 if (ret == 1) 684 break; 685 } 686 break; 687 } 688 689 out: 690 return NOTIFY_DONE; 691 } 692 693 /* 694 * VLAN IOCTL handler. 695 * o execute requested action or pass command to the device driver 696 * arg is really a struct vlan_ioctl_args __user *. 697 */ 698 static int vlan_ioctl_handler(void __user *arg) 699 { 700 int err; 701 unsigned short vid = 0; 702 struct vlan_ioctl_args args; 703 struct net_device *dev = NULL; 704 705 if (copy_from_user(&args, arg, sizeof(struct vlan_ioctl_args))) 706 return -EFAULT; 707 708 /* Null terminate this sucker, just in case. */ 709 args.device1[23] = 0; 710 args.u.device2[23] = 0; 711 712 #ifdef VLAN_DEBUG 713 printk(VLAN_DBG "%s: args.cmd: %x\n", __FUNCTION__, args.cmd); 714 #endif 715 716 rtnl_lock(); 717 718 switch (args.cmd) { 719 case SET_VLAN_INGRESS_PRIORITY_CMD: 720 case SET_VLAN_EGRESS_PRIORITY_CMD: 721 case SET_VLAN_FLAG_CMD: 722 case ADD_VLAN_CMD: 723 case DEL_VLAN_CMD: 724 case GET_VLAN_REALDEV_NAME_CMD: 725 case GET_VLAN_VID_CMD: 726 err = -ENODEV; 727 dev = __dev_get_by_name(args.device1); 728 if (!dev) 729 goto out; 730 731 err = -EINVAL; 732 if (args.cmd != ADD_VLAN_CMD && 733 !(dev->priv_flags & IFF_802_1Q_VLAN)) 734 goto out; 735 } 736 737 switch (args.cmd) { 738 case SET_VLAN_INGRESS_PRIORITY_CMD: 739 err = -EPERM; 740 if (!capable(CAP_NET_ADMIN)) 741 break; 742 vlan_dev_set_ingress_priority(dev, 743 args.u.skb_priority, 744 args.vlan_qos); 745 break; 746 747 case SET_VLAN_EGRESS_PRIORITY_CMD: 748 err = -EPERM; 749 if (!capable(CAP_NET_ADMIN)) 750 break; 751 err = vlan_dev_set_egress_priority(dev, 752 args.u.skb_priority, 753 args.vlan_qos); 754 break; 755 756 case SET_VLAN_FLAG_CMD: 757 err = -EPERM; 758 if (!capable(CAP_NET_ADMIN)) 759 break; 760 err = vlan_dev_set_vlan_flag(dev, 761 args.u.flag, 762 args.vlan_qos); 763 break; 764 765 case SET_VLAN_NAME_TYPE_CMD: 766 err = -EPERM; 767 if (!capable(CAP_NET_ADMIN)) 768 return -EPERM; 769 if ((args.u.name_type >= 0) && 770 (args.u.name_type < VLAN_NAME_TYPE_HIGHEST)) { 771 vlan_name_type = args.u.name_type; 772 err = 0; 773 } else { 774 err = -EINVAL; 775 } 776 break; 777 778 case ADD_VLAN_CMD: 779 err = -EPERM; 780 if (!capable(CAP_NET_ADMIN)) 781 break; 782 err = register_vlan_device(dev, args.u.VID); 783 break; 784 785 case DEL_VLAN_CMD: 786 err = -EPERM; 787 if (!capable(CAP_NET_ADMIN)) 788 break; 789 err = unregister_vlan_device(dev); 790 break; 791 792 case GET_VLAN_INGRESS_PRIORITY_CMD: 793 /* TODO: Implement 794 err = vlan_dev_get_ingress_priority(args); 795 if (copy_to_user((void*)arg, &args, 796 sizeof(struct vlan_ioctl_args))) { 797 err = -EFAULT; 798 } 799 */ 800 err = -EINVAL; 801 break; 802 case GET_VLAN_EGRESS_PRIORITY_CMD: 803 /* TODO: Implement 804 err = vlan_dev_get_egress_priority(args.device1, &(args.args); 805 if (copy_to_user((void*)arg, &args, 806 sizeof(struct vlan_ioctl_args))) { 807 err = -EFAULT; 808 } 809 */ 810 err = -EINVAL; 811 break; 812 case GET_VLAN_REALDEV_NAME_CMD: 813 err = 0; 814 vlan_dev_get_realdev_name(dev, args.u.device2); 815 if (copy_to_user(arg, &args, 816 sizeof(struct vlan_ioctl_args))) { 817 err = -EFAULT; 818 } 819 break; 820 821 case GET_VLAN_VID_CMD: 822 err = 0; 823 vlan_dev_get_vid(dev, &vid); 824 args.u.VID = vid; 825 if (copy_to_user(arg, &args, 826 sizeof(struct vlan_ioctl_args))) { 827 err = -EFAULT; 828 } 829 break; 830 831 default: 832 /* pass on to underlying device instead?? */ 833 printk(VLAN_DBG "%s: Unknown VLAN CMD: %x \n", 834 __FUNCTION__, args.cmd); 835 err = -EINVAL; 836 break; 837 } 838 out: 839 rtnl_unlock(); 840 return err; 841 } 842 843 MODULE_LICENSE("GPL"); 844 MODULE_VERSION(DRV_VERSION); 845