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 dev_remove_pack(&vlan_packet_type); 102 vlan_proc_cleanup(); 103 return err; 104 } 105 106 vlan_ioctl_set(vlan_ioctl_handler); 107 108 return 0; 109 } 110 111 /* Cleanup all vlan devices 112 * Note: devices that have been registered that but not 113 * brought up will exist but have no module ref count. 114 */ 115 static void __exit vlan_cleanup_devices(void) 116 { 117 struct net_device *dev, *nxt; 118 119 rtnl_lock(); 120 for_each_netdev_safe(dev, nxt) { 121 if (dev->priv_flags & IFF_802_1Q_VLAN) { 122 unregister_vlan_dev(VLAN_DEV_INFO(dev)->real_dev, 123 VLAN_DEV_INFO(dev)->vlan_id); 124 125 unregister_netdevice(dev); 126 } 127 } 128 rtnl_unlock(); 129 } 130 131 /* 132 * Module 'remove' entry point. 133 * o delete /proc/net/router directory and static entries. 134 */ 135 static void __exit vlan_cleanup_module(void) 136 { 137 int i; 138 139 vlan_ioctl_set(NULL); 140 141 /* Un-register us from receiving netdevice events */ 142 unregister_netdevice_notifier(&vlan_notifier_block); 143 144 dev_remove_pack(&vlan_packet_type); 145 vlan_cleanup_devices(); 146 147 /* This table must be empty if there are no module 148 * references left. 149 */ 150 for (i = 0; i < VLAN_GRP_HASH_SIZE; i++) { 151 BUG_ON(!hlist_empty(&vlan_group_hash[i])); 152 } 153 vlan_proc_cleanup(); 154 155 synchronize_net(); 156 } 157 158 module_init(vlan_proto_init); 159 module_exit(vlan_cleanup_module); 160 161 /* Must be invoked with RCU read lock (no preempt) */ 162 static struct vlan_group *__vlan_find_group(int real_dev_ifindex) 163 { 164 struct vlan_group *grp; 165 struct hlist_node *n; 166 int hash = vlan_grp_hashfn(real_dev_ifindex); 167 168 hlist_for_each_entry_rcu(grp, n, &vlan_group_hash[hash], hlist) { 169 if (grp->real_dev_ifindex == real_dev_ifindex) 170 return grp; 171 } 172 173 return NULL; 174 } 175 176 /* Find the protocol handler. Assumes VID < VLAN_VID_MASK. 177 * 178 * Must be invoked with RCU read lock (no preempt) 179 */ 180 struct net_device *__find_vlan_dev(struct net_device *real_dev, 181 unsigned short VID) 182 { 183 struct vlan_group *grp = __vlan_find_group(real_dev->ifindex); 184 185 if (grp) 186 return vlan_group_get_device(grp, VID); 187 188 return NULL; 189 } 190 191 static void vlan_group_free(struct vlan_group *grp) 192 { 193 int i; 194 195 for (i=0; i < VLAN_GROUP_ARRAY_SPLIT_PARTS; i++) 196 kfree(grp->vlan_devices_arrays[i]); 197 kfree(grp); 198 } 199 200 static void vlan_rcu_free(struct rcu_head *rcu) 201 { 202 vlan_group_free(container_of(rcu, struct vlan_group, rcu)); 203 } 204 205 206 /* This returns 0 if everything went fine. 207 * It will return 1 if the group was killed as a result. 208 * A negative return indicates failure. 209 * 210 * The RTNL lock must be held. 211 */ 212 static int unregister_vlan_dev(struct net_device *real_dev, 213 unsigned short vlan_id) 214 { 215 struct net_device *dev = NULL; 216 int real_dev_ifindex = real_dev->ifindex; 217 struct vlan_group *grp; 218 int i, ret; 219 220 #ifdef VLAN_DEBUG 221 printk(VLAN_DBG "%s: VID: %i\n", __FUNCTION__, vlan_id); 222 #endif 223 224 /* sanity check */ 225 if (vlan_id >= VLAN_VID_MASK) 226 return -EINVAL; 227 228 ASSERT_RTNL(); 229 grp = __vlan_find_group(real_dev_ifindex); 230 231 ret = 0; 232 233 if (grp) { 234 dev = vlan_group_get_device(grp, vlan_id); 235 if (dev) { 236 /* Remove proc entry */ 237 vlan_proc_rem_dev(dev); 238 239 /* Take it out of our own structures, but be sure to 240 * interlock with HW accelerating devices or SW vlan 241 * input packet processing. 242 */ 243 if (real_dev->features & 244 (NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER)) { 245 real_dev->vlan_rx_kill_vid(real_dev, vlan_id); 246 } 247 248 vlan_group_set_device(grp, vlan_id, NULL); 249 synchronize_net(); 250 251 252 /* Caller unregisters (and if necessary, puts) 253 * VLAN device, but we get rid of the reference to 254 * real_dev here. 255 */ 256 dev_put(real_dev); 257 258 /* If the group is now empty, kill off the 259 * group. 260 */ 261 for (i = 0; i < VLAN_VID_MASK; i++) 262 if (vlan_group_get_device(grp, i)) 263 break; 264 265 if (i == VLAN_VID_MASK) { 266 if (real_dev->features & NETIF_F_HW_VLAN_RX) 267 real_dev->vlan_rx_register(real_dev, NULL); 268 269 hlist_del_rcu(&grp->hlist); 270 271 /* Free the group, after all cpu's are done. */ 272 call_rcu(&grp->rcu, vlan_rcu_free); 273 274 grp = NULL; 275 ret = 1; 276 } 277 } 278 } 279 280 return ret; 281 } 282 283 static int unregister_vlan_device(const char *vlan_IF_name) 284 { 285 struct net_device *dev = NULL; 286 int ret; 287 288 289 dev = dev_get_by_name(vlan_IF_name); 290 ret = -EINVAL; 291 if (dev) { 292 if (dev->priv_flags & IFF_802_1Q_VLAN) { 293 rtnl_lock(); 294 295 ret = unregister_vlan_dev(VLAN_DEV_INFO(dev)->real_dev, 296 VLAN_DEV_INFO(dev)->vlan_id); 297 298 dev_put(dev); 299 unregister_netdevice(dev); 300 301 rtnl_unlock(); 302 303 if (ret == 1) 304 ret = 0; 305 } else { 306 printk(VLAN_ERR 307 "%s: ERROR: Tried to remove a non-vlan device " 308 "with VLAN code, name: %s priv_flags: %hX\n", 309 __FUNCTION__, dev->name, dev->priv_flags); 310 dev_put(dev); 311 ret = -EPERM; 312 } 313 } else { 314 #ifdef VLAN_DEBUG 315 printk(VLAN_DBG "%s: WARNING: Could not find dev.\n", __FUNCTION__); 316 #endif 317 ret = -EINVAL; 318 } 319 320 return ret; 321 } 322 323 static void vlan_setup(struct net_device *new_dev) 324 { 325 SET_MODULE_OWNER(new_dev); 326 327 /* new_dev->ifindex = 0; it will be set when added to 328 * the global list. 329 * iflink is set as well. 330 */ 331 new_dev->get_stats = vlan_dev_get_stats; 332 333 /* Make this thing known as a VLAN device */ 334 new_dev->priv_flags |= IFF_802_1Q_VLAN; 335 336 /* Set us up to have no queue, as the underlying Hardware device 337 * can do all the queueing we could want. 338 */ 339 new_dev->tx_queue_len = 0; 340 341 /* set up method calls */ 342 new_dev->change_mtu = vlan_dev_change_mtu; 343 new_dev->open = vlan_dev_open; 344 new_dev->stop = vlan_dev_stop; 345 new_dev->set_mac_address = vlan_dev_set_mac_address; 346 new_dev->set_multicast_list = vlan_dev_set_multicast_list; 347 new_dev->destructor = free_netdev; 348 new_dev->do_ioctl = vlan_dev_ioctl; 349 } 350 351 static void vlan_transfer_operstate(const struct net_device *dev, struct net_device *vlandev) 352 { 353 /* Have to respect userspace enforced dormant state 354 * of real device, also must allow supplicant running 355 * on VLAN device 356 */ 357 if (dev->operstate == IF_OPER_DORMANT) 358 netif_dormant_on(vlandev); 359 else 360 netif_dormant_off(vlandev); 361 362 if (netif_carrier_ok(dev)) { 363 if (!netif_carrier_ok(vlandev)) 364 netif_carrier_on(vlandev); 365 } else { 366 if (netif_carrier_ok(vlandev)) 367 netif_carrier_off(vlandev); 368 } 369 } 370 371 /* 372 * vlan network devices have devices nesting below it, and are a special 373 * "super class" of normal network devices; split their locks off into a 374 * separate class since they always nest. 375 */ 376 static struct lock_class_key vlan_netdev_xmit_lock_key; 377 378 379 /* Attach a VLAN device to a mac address (ie Ethernet Card). 380 * Returns the device that was created, or NULL if there was 381 * an error of some kind. 382 */ 383 static struct net_device *register_vlan_device(const char *eth_IF_name, 384 unsigned short VLAN_ID) 385 { 386 struct vlan_group *grp; 387 struct net_device *new_dev; 388 struct net_device *real_dev; /* the ethernet device */ 389 char name[IFNAMSIZ]; 390 int i; 391 392 #ifdef VLAN_DEBUG 393 printk(VLAN_DBG "%s: if_name -:%s:- vid: %i\n", 394 __FUNCTION__, eth_IF_name, VLAN_ID); 395 #endif 396 397 if (VLAN_ID >= VLAN_VID_MASK) 398 goto out_ret_null; 399 400 /* find the device relating to eth_IF_name. */ 401 real_dev = dev_get_by_name(eth_IF_name); 402 if (!real_dev) 403 goto out_ret_null; 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 goto out_put_dev; 409 } 410 411 if ((real_dev->features & NETIF_F_HW_VLAN_RX) && 412 (real_dev->vlan_rx_register == NULL || 413 real_dev->vlan_rx_kill_vid == NULL)) { 414 printk(VLAN_DBG "%s: Device %s has buggy VLAN hw accel.\n", 415 __FUNCTION__, real_dev->name); 416 goto out_put_dev; 417 } 418 419 if ((real_dev->features & NETIF_F_HW_VLAN_FILTER) && 420 (real_dev->vlan_rx_add_vid == NULL || 421 real_dev->vlan_rx_kill_vid == NULL)) { 422 printk(VLAN_DBG "%s: Device %s has buggy VLAN hw accel.\n", 423 __FUNCTION__, real_dev->name); 424 goto out_put_dev; 425 } 426 427 /* From this point on, all the data structures must remain 428 * consistent. 429 */ 430 rtnl_lock(); 431 432 /* The real device must be up and operating in order to 433 * assosciate a VLAN device with it. 434 */ 435 if (!(real_dev->flags & IFF_UP)) 436 goto out_unlock; 437 438 if (__find_vlan_dev(real_dev, VLAN_ID) != NULL) { 439 /* was already registered. */ 440 printk(VLAN_DBG "%s: ALREADY had VLAN registered\n", __FUNCTION__); 441 goto out_unlock; 442 } 443 444 /* Gotta set up the fields for the device. */ 445 #ifdef VLAN_DEBUG 446 printk(VLAN_DBG "About to allocate name, vlan_name_type: %i\n", 447 vlan_name_type); 448 #endif 449 switch (vlan_name_type) { 450 case VLAN_NAME_TYPE_RAW_PLUS_VID: 451 /* name will look like: eth1.0005 */ 452 snprintf(name, IFNAMSIZ, "%s.%.4i", real_dev->name, VLAN_ID); 453 break; 454 case VLAN_NAME_TYPE_PLUS_VID_NO_PAD: 455 /* Put our vlan.VID in the name. 456 * Name will look like: vlan5 457 */ 458 snprintf(name, IFNAMSIZ, "vlan%i", VLAN_ID); 459 break; 460 case VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD: 461 /* Put our vlan.VID in the name. 462 * Name will look like: eth0.5 463 */ 464 snprintf(name, IFNAMSIZ, "%s.%i", real_dev->name, VLAN_ID); 465 break; 466 case VLAN_NAME_TYPE_PLUS_VID: 467 /* Put our vlan.VID in the name. 468 * Name will look like: vlan0005 469 */ 470 default: 471 snprintf(name, IFNAMSIZ, "vlan%.4i", VLAN_ID); 472 } 473 474 new_dev = alloc_netdev(sizeof(struct vlan_dev_info), name, 475 vlan_setup); 476 477 if (new_dev == NULL) 478 goto out_unlock; 479 480 #ifdef VLAN_DEBUG 481 printk(VLAN_DBG "Allocated new name -:%s:-\n", new_dev->name); 482 #endif 483 /* IFF_BROADCAST|IFF_MULTICAST; ??? */ 484 new_dev->flags = real_dev->flags; 485 new_dev->flags &= ~IFF_UP; 486 487 new_dev->state = (real_dev->state & ((1<<__LINK_STATE_NOCARRIER) | 488 (1<<__LINK_STATE_DORMANT))) | 489 (1<<__LINK_STATE_PRESENT); 490 491 /* need 4 bytes for extra VLAN header info, 492 * hope the underlying device can handle it. 493 */ 494 new_dev->mtu = real_dev->mtu; 495 496 /* TODO: maybe just assign it to be ETHERNET? */ 497 new_dev->type = real_dev->type; 498 499 new_dev->hard_header_len = real_dev->hard_header_len; 500 if (!(real_dev->features & NETIF_F_HW_VLAN_TX)) { 501 /* Regular ethernet + 4 bytes (18 total). */ 502 new_dev->hard_header_len += VLAN_HLEN; 503 } 504 505 VLAN_MEM_DBG("new_dev->priv malloc, addr: %p size: %i\n", 506 new_dev->priv, 507 sizeof(struct vlan_dev_info)); 508 509 memcpy(new_dev->broadcast, real_dev->broadcast, real_dev->addr_len); 510 memcpy(new_dev->dev_addr, real_dev->dev_addr, real_dev->addr_len); 511 new_dev->addr_len = real_dev->addr_len; 512 513 if (real_dev->features & NETIF_F_HW_VLAN_TX) { 514 new_dev->hard_header = real_dev->hard_header; 515 new_dev->hard_start_xmit = vlan_dev_hwaccel_hard_start_xmit; 516 new_dev->rebuild_header = real_dev->rebuild_header; 517 } else { 518 new_dev->hard_header = vlan_dev_hard_header; 519 new_dev->hard_start_xmit = vlan_dev_hard_start_xmit; 520 new_dev->rebuild_header = vlan_dev_rebuild_header; 521 } 522 new_dev->hard_header_parse = real_dev->hard_header_parse; 523 524 VLAN_DEV_INFO(new_dev)->vlan_id = VLAN_ID; /* 1 through VLAN_VID_MASK */ 525 VLAN_DEV_INFO(new_dev)->real_dev = real_dev; 526 VLAN_DEV_INFO(new_dev)->dent = NULL; 527 VLAN_DEV_INFO(new_dev)->flags = 1; 528 529 #ifdef VLAN_DEBUG 530 printk(VLAN_DBG "About to go find the group for idx: %i\n", 531 real_dev->ifindex); 532 #endif 533 534 if (register_netdevice(new_dev)) 535 goto out_free_newdev; 536 537 lockdep_set_class(&new_dev->_xmit_lock, &vlan_netdev_xmit_lock_key); 538 539 new_dev->iflink = real_dev->ifindex; 540 vlan_transfer_operstate(real_dev, new_dev); 541 linkwatch_fire_event(new_dev); /* _MUST_ call rfc2863_policy() */ 542 543 /* So, got the sucker initialized, now lets place 544 * it into our local structure. 545 */ 546 grp = __vlan_find_group(real_dev->ifindex); 547 548 /* Note, we are running under the RTNL semaphore 549 * so it cannot "appear" on us. 550 */ 551 if (!grp) { /* need to add a new group */ 552 grp = kzalloc(sizeof(struct vlan_group), GFP_KERNEL); 553 if (!grp) 554 goto out_free_unregister; 555 556 for (i=0; i < VLAN_GROUP_ARRAY_SPLIT_PARTS; i++) { 557 grp->vlan_devices_arrays[i] = kzalloc( 558 sizeof(struct net_device *)*VLAN_GROUP_ARRAY_PART_LEN, 559 GFP_KERNEL); 560 561 if (!grp->vlan_devices_arrays[i]) 562 goto out_free_arrays; 563 } 564 565 /* printk(KERN_ALERT "VLAN REGISTER: Allocated new group.\n"); */ 566 grp->real_dev_ifindex = real_dev->ifindex; 567 568 hlist_add_head_rcu(&grp->hlist, 569 &vlan_group_hash[vlan_grp_hashfn(real_dev->ifindex)]); 570 571 if (real_dev->features & NETIF_F_HW_VLAN_RX) 572 real_dev->vlan_rx_register(real_dev, grp); 573 } 574 575 vlan_group_set_device(grp, VLAN_ID, new_dev); 576 577 if (vlan_proc_add_dev(new_dev)<0)/* create it's proc entry */ 578 printk(KERN_WARNING "VLAN: failed to add proc entry for %s\n", 579 new_dev->name); 580 581 if (real_dev->features & NETIF_F_HW_VLAN_FILTER) 582 real_dev->vlan_rx_add_vid(real_dev, VLAN_ID); 583 584 rtnl_unlock(); 585 586 587 #ifdef VLAN_DEBUG 588 printk(VLAN_DBG "Allocated new device successfully, returning.\n"); 589 #endif 590 return new_dev; 591 592 out_free_arrays: 593 vlan_group_free(grp); 594 595 out_free_unregister: 596 unregister_netdev(new_dev); 597 goto out_unlock; 598 599 out_free_newdev: 600 free_netdev(new_dev); 601 602 out_unlock: 603 rtnl_unlock(); 604 605 out_put_dev: 606 dev_put(real_dev); 607 608 out_ret_null: 609 return NULL; 610 } 611 612 static int vlan_device_event(struct notifier_block *unused, unsigned long event, void *ptr) 613 { 614 struct net_device *dev = ptr; 615 struct vlan_group *grp = __vlan_find_group(dev->ifindex); 616 int i, flgs; 617 struct net_device *vlandev; 618 619 if (!grp) 620 goto out; 621 622 /* It is OK that we do not hold the group lock right now, 623 * as we run under the RTNL lock. 624 */ 625 626 switch (event) { 627 case NETDEV_CHANGE: 628 /* Propagate real device state to vlan devices */ 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_transfer_operstate(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 = 0; 701 unsigned short vid = 0; 702 struct vlan_ioctl_args args; 703 704 if (copy_from_user(&args, arg, sizeof(struct vlan_ioctl_args))) 705 return -EFAULT; 706 707 /* Null terminate this sucker, just in case. */ 708 args.device1[23] = 0; 709 args.u.device2[23] = 0; 710 711 #ifdef VLAN_DEBUG 712 printk(VLAN_DBG "%s: args.cmd: %x\n", __FUNCTION__, args.cmd); 713 #endif 714 715 switch (args.cmd) { 716 case SET_VLAN_INGRESS_PRIORITY_CMD: 717 if (!capable(CAP_NET_ADMIN)) 718 return -EPERM; 719 err = vlan_dev_set_ingress_priority(args.device1, 720 args.u.skb_priority, 721 args.vlan_qos); 722 break; 723 724 case SET_VLAN_EGRESS_PRIORITY_CMD: 725 if (!capable(CAP_NET_ADMIN)) 726 return -EPERM; 727 err = vlan_dev_set_egress_priority(args.device1, 728 args.u.skb_priority, 729 args.vlan_qos); 730 break; 731 732 case SET_VLAN_FLAG_CMD: 733 if (!capable(CAP_NET_ADMIN)) 734 return -EPERM; 735 err = vlan_dev_set_vlan_flag(args.device1, 736 args.u.flag, 737 args.vlan_qos); 738 break; 739 740 case SET_VLAN_NAME_TYPE_CMD: 741 if (!capable(CAP_NET_ADMIN)) 742 return -EPERM; 743 if ((args.u.name_type >= 0) && 744 (args.u.name_type < VLAN_NAME_TYPE_HIGHEST)) { 745 vlan_name_type = args.u.name_type; 746 err = 0; 747 } else { 748 err = -EINVAL; 749 } 750 break; 751 752 case ADD_VLAN_CMD: 753 if (!capable(CAP_NET_ADMIN)) 754 return -EPERM; 755 /* we have been given the name of the Ethernet Device we want to 756 * talk to: args.dev1 We also have the 757 * VLAN ID: args.u.VID 758 */ 759 if (register_vlan_device(args.device1, args.u.VID)) { 760 err = 0; 761 } else { 762 err = -EINVAL; 763 } 764 break; 765 766 case DEL_VLAN_CMD: 767 if (!capable(CAP_NET_ADMIN)) 768 return -EPERM; 769 /* Here, the args.dev1 is the actual VLAN we want 770 * to get rid of. 771 */ 772 err = unregister_vlan_device(args.device1); 773 break; 774 775 case GET_VLAN_INGRESS_PRIORITY_CMD: 776 /* TODO: Implement 777 err = vlan_dev_get_ingress_priority(args); 778 if (copy_to_user((void*)arg, &args, 779 sizeof(struct vlan_ioctl_args))) { 780 err = -EFAULT; 781 } 782 */ 783 err = -EINVAL; 784 break; 785 case GET_VLAN_EGRESS_PRIORITY_CMD: 786 /* TODO: Implement 787 err = vlan_dev_get_egress_priority(args.device1, &(args.args); 788 if (copy_to_user((void*)arg, &args, 789 sizeof(struct vlan_ioctl_args))) { 790 err = -EFAULT; 791 } 792 */ 793 err = -EINVAL; 794 break; 795 case GET_VLAN_REALDEV_NAME_CMD: 796 err = vlan_dev_get_realdev_name(args.device1, args.u.device2); 797 if (err) 798 goto out; 799 if (copy_to_user(arg, &args, 800 sizeof(struct vlan_ioctl_args))) { 801 err = -EFAULT; 802 } 803 break; 804 805 case GET_VLAN_VID_CMD: 806 err = vlan_dev_get_vid(args.device1, &vid); 807 if (err) 808 goto out; 809 args.u.VID = vid; 810 if (copy_to_user(arg, &args, 811 sizeof(struct vlan_ioctl_args))) { 812 err = -EFAULT; 813 } 814 break; 815 816 default: 817 /* pass on to underlying device instead?? */ 818 printk(VLAN_DBG "%s: Unknown VLAN CMD: %x \n", 819 __FUNCTION__, args.cmd); 820 return -EINVAL; 821 } 822 out: 823 return err; 824 } 825 826 MODULE_LICENSE("GPL"); 827 MODULE_VERSION(DRV_VERSION); 828