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