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