diff options
-rw-r--r-- | net/8021q/vlan.c | 153 | ||||
-rw-r--r-- | net/8021q/vlan.h | 13 | ||||
-rw-r--r-- | net/8021q/vlan_dev.c | 142 |
3 files changed, 109 insertions, 199 deletions
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index de78c9dd713b..3678f0719934 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c | |||
@@ -278,43 +278,16 @@ static int unregister_vlan_dev(struct net_device *real_dev, | |||
278 | return ret; | 278 | return ret; |
279 | } | 279 | } |
280 | 280 | ||
281 | static int unregister_vlan_device(const char *vlan_IF_name) | 281 | static int unregister_vlan_device(struct net_device *dev) |
282 | { | 282 | { |
283 | struct net_device *dev = NULL; | ||
284 | int ret; | 283 | int ret; |
285 | 284 | ||
285 | ret = unregister_vlan_dev(VLAN_DEV_INFO(dev)->real_dev, | ||
286 | VLAN_DEV_INFO(dev)->vlan_id); | ||
287 | unregister_netdevice(dev); | ||
286 | 288 | ||
287 | dev = dev_get_by_name(vlan_IF_name); | 289 | if (ret == 1) |
288 | ret = -EINVAL; | 290 | ret = 0; |
289 | if (dev) { | ||
290 | if (dev->priv_flags & IFF_802_1Q_VLAN) { | ||
291 | rtnl_lock(); | ||
292 | |||
293 | ret = unregister_vlan_dev(VLAN_DEV_INFO(dev)->real_dev, | ||
294 | VLAN_DEV_INFO(dev)->vlan_id); | ||
295 | |||
296 | dev_put(dev); | ||
297 | unregister_netdevice(dev); | ||
298 | |||
299 | rtnl_unlock(); | ||
300 | |||
301 | if (ret == 1) | ||
302 | ret = 0; | ||
303 | } else { | ||
304 | printk(VLAN_ERR | ||
305 | "%s: ERROR: Tried to remove a non-vlan device " | ||
306 | "with VLAN code, name: %s priv_flags: %hX\n", | ||
307 | __FUNCTION__, dev->name, dev->priv_flags); | ||
308 | dev_put(dev); | ||
309 | ret = -EPERM; | ||
310 | } | ||
311 | } else { | ||
312 | #ifdef VLAN_DEBUG | ||
313 | printk(VLAN_DBG "%s: WARNING: Could not find dev.\n", __FUNCTION__); | ||
314 | #endif | ||
315 | ret = -EINVAL; | ||
316 | } | ||
317 | |||
318 | return ret; | 291 | return ret; |
319 | } | 292 | } |
320 | 293 | ||
@@ -378,12 +351,11 @@ static struct lock_class_key vlan_netdev_xmit_lock_key; | |||
378 | * Returns the device that was created, or NULL if there was | 351 | * Returns the device that was created, or NULL if there was |
379 | * an error of some kind. | 352 | * an error of some kind. |
380 | */ | 353 | */ |
381 | static struct net_device *register_vlan_device(const char *eth_IF_name, | 354 | static struct net_device *register_vlan_device(struct net_device *real_dev, |
382 | unsigned short VLAN_ID) | 355 | unsigned short VLAN_ID) |
383 | { | 356 | { |
384 | struct vlan_group *grp; | 357 | struct vlan_group *grp; |
385 | struct net_device *new_dev; | 358 | struct net_device *new_dev; |
386 | struct net_device *real_dev; /* the ethernet device */ | ||
387 | char name[IFNAMSIZ]; | 359 | char name[IFNAMSIZ]; |
388 | int i; | 360 | int i; |
389 | 361 | ||
@@ -395,46 +367,36 @@ static struct net_device *register_vlan_device(const char *eth_IF_name, | |||
395 | if (VLAN_ID >= VLAN_VID_MASK) | 367 | if (VLAN_ID >= VLAN_VID_MASK) |
396 | goto out_ret_null; | 368 | goto out_ret_null; |
397 | 369 | ||
398 | /* find the device relating to eth_IF_name. */ | ||
399 | real_dev = dev_get_by_name(eth_IF_name); | ||
400 | if (!real_dev) | ||
401 | goto out_ret_null; | ||
402 | |||
403 | if (real_dev->features & NETIF_F_VLAN_CHALLENGED) { | 370 | if (real_dev->features & NETIF_F_VLAN_CHALLENGED) { |
404 | printk(VLAN_DBG "%s: VLANs not supported on %s.\n", | 371 | printk(VLAN_DBG "%s: VLANs not supported on %s.\n", |
405 | __FUNCTION__, real_dev->name); | 372 | __FUNCTION__, real_dev->name); |
406 | goto out_put_dev; | 373 | goto out_ret_null; |
407 | } | 374 | } |
408 | 375 | ||
409 | if ((real_dev->features & NETIF_F_HW_VLAN_RX) && | 376 | if ((real_dev->features & NETIF_F_HW_VLAN_RX) && |
410 | !real_dev->vlan_rx_register) { | 377 | !real_dev->vlan_rx_register) { |
411 | printk(VLAN_DBG "%s: Device %s has buggy VLAN hw accel.\n", | 378 | printk(VLAN_DBG "%s: Device %s has buggy VLAN hw accel.\n", |
412 | __FUNCTION__, real_dev->name); | 379 | __FUNCTION__, real_dev->name); |
413 | goto out_put_dev; | 380 | goto out_ret_null; |
414 | } | 381 | } |
415 | 382 | ||
416 | if ((real_dev->features & NETIF_F_HW_VLAN_FILTER) && | 383 | if ((real_dev->features & NETIF_F_HW_VLAN_FILTER) && |
417 | (!real_dev->vlan_rx_add_vid || !real_dev->vlan_rx_kill_vid)) { | 384 | (!real_dev->vlan_rx_add_vid || !real_dev->vlan_rx_kill_vid)) { |
418 | printk(VLAN_DBG "%s: Device %s has buggy VLAN hw accel.\n", | 385 | printk(VLAN_DBG "%s: Device %s has buggy VLAN hw accel.\n", |
419 | __FUNCTION__, real_dev->name); | 386 | __FUNCTION__, real_dev->name); |
420 | goto out_put_dev; | 387 | goto out_ret_null; |
421 | } | 388 | } |
422 | 389 | ||
423 | /* From this point on, all the data structures must remain | ||
424 | * consistent. | ||
425 | */ | ||
426 | rtnl_lock(); | ||
427 | |||
428 | /* The real device must be up and operating in order to | 390 | /* The real device must be up and operating in order to |
429 | * assosciate a VLAN device with it. | 391 | * assosciate a VLAN device with it. |
430 | */ | 392 | */ |
431 | if (!(real_dev->flags & IFF_UP)) | 393 | if (!(real_dev->flags & IFF_UP)) |
432 | goto out_unlock; | 394 | goto out_ret_null; |
433 | 395 | ||
434 | if (__find_vlan_dev(real_dev, VLAN_ID) != NULL) { | 396 | if (__find_vlan_dev(real_dev, VLAN_ID) != NULL) { |
435 | /* was already registered. */ | 397 | /* was already registered. */ |
436 | printk(VLAN_DBG "%s: ALREADY had VLAN registered\n", __FUNCTION__); | 398 | printk(VLAN_DBG "%s: ALREADY had VLAN registered\n", __FUNCTION__); |
437 | goto out_unlock; | 399 | goto out_ret_null; |
438 | } | 400 | } |
439 | 401 | ||
440 | /* Gotta set up the fields for the device. */ | 402 | /* Gotta set up the fields for the device. */ |
@@ -471,7 +433,7 @@ static struct net_device *register_vlan_device(const char *eth_IF_name, | |||
471 | vlan_setup); | 433 | vlan_setup); |
472 | 434 | ||
473 | if (new_dev == NULL) | 435 | if (new_dev == NULL) |
474 | goto out_unlock; | 436 | goto out_ret_null; |
475 | 437 | ||
476 | #ifdef VLAN_DEBUG | 438 | #ifdef VLAN_DEBUG |
477 | printk(VLAN_DBG "Allocated new name -:%s:-\n", new_dev->name); | 439 | printk(VLAN_DBG "Allocated new name -:%s:-\n", new_dev->name); |
@@ -577,9 +539,8 @@ static struct net_device *register_vlan_device(const char *eth_IF_name, | |||
577 | if (real_dev->features & NETIF_F_HW_VLAN_FILTER) | 539 | if (real_dev->features & NETIF_F_HW_VLAN_FILTER) |
578 | real_dev->vlan_rx_add_vid(real_dev, VLAN_ID); | 540 | real_dev->vlan_rx_add_vid(real_dev, VLAN_ID); |
579 | 541 | ||
580 | rtnl_unlock(); | 542 | /* Account for reference in struct vlan_dev_info */ |
581 | 543 | dev_hold(real_dev); | |
582 | |||
583 | #ifdef VLAN_DEBUG | 544 | #ifdef VLAN_DEBUG |
584 | printk(VLAN_DBG "Allocated new device successfully, returning.\n"); | 545 | printk(VLAN_DBG "Allocated new device successfully, returning.\n"); |
585 | #endif | 546 | #endif |
@@ -590,17 +551,11 @@ out_free_arrays: | |||
590 | 551 | ||
591 | out_free_unregister: | 552 | out_free_unregister: |
592 | unregister_netdev(new_dev); | 553 | unregister_netdev(new_dev); |
593 | goto out_unlock; | 554 | goto out_ret_null; |
594 | 555 | ||
595 | out_free_newdev: | 556 | out_free_newdev: |
596 | free_netdev(new_dev); | 557 | free_netdev(new_dev); |
597 | 558 | ||
598 | out_unlock: | ||
599 | rtnl_unlock(); | ||
600 | |||
601 | out_put_dev: | ||
602 | dev_put(real_dev); | ||
603 | |||
604 | out_ret_null: | 559 | out_ret_null: |
605 | return NULL; | 560 | return NULL; |
606 | } | 561 | } |
@@ -693,9 +648,10 @@ out: | |||
693 | */ | 648 | */ |
694 | static int vlan_ioctl_handler(void __user *arg) | 649 | static int vlan_ioctl_handler(void __user *arg) |
695 | { | 650 | { |
696 | int err = 0; | 651 | int err; |
697 | unsigned short vid = 0; | 652 | unsigned short vid = 0; |
698 | struct vlan_ioctl_args args; | 653 | struct vlan_ioctl_args args; |
654 | struct net_device *dev = NULL; | ||
699 | 655 | ||
700 | if (copy_from_user(&args, arg, sizeof(struct vlan_ioctl_args))) | 656 | if (copy_from_user(&args, arg, sizeof(struct vlan_ioctl_args))) |
701 | return -EFAULT; | 657 | return -EFAULT; |
@@ -708,35 +664,61 @@ static int vlan_ioctl_handler(void __user *arg) | |||
708 | printk(VLAN_DBG "%s: args.cmd: %x\n", __FUNCTION__, args.cmd); | 664 | printk(VLAN_DBG "%s: args.cmd: %x\n", __FUNCTION__, args.cmd); |
709 | #endif | 665 | #endif |
710 | 666 | ||
667 | rtnl_lock(); | ||
668 | |||
711 | switch (args.cmd) { | 669 | switch (args.cmd) { |
712 | case SET_VLAN_INGRESS_PRIORITY_CMD: | 670 | case SET_VLAN_INGRESS_PRIORITY_CMD: |
671 | case SET_VLAN_EGRESS_PRIORITY_CMD: | ||
672 | case SET_VLAN_FLAG_CMD: | ||
673 | case ADD_VLAN_CMD: | ||
674 | case DEL_VLAN_CMD: | ||
675 | case GET_VLAN_REALDEV_NAME_CMD: | ||
676 | case GET_VLAN_VID_CMD: | ||
677 | err = -ENODEV; | ||
678 | dev = __dev_get_by_name(args.device1); | ||
679 | if (!dev) | ||
680 | goto out; | ||
681 | |||
682 | err = -EINVAL; | ||
683 | if (args.cmd != ADD_VLAN_CMD && | ||
684 | !(dev->priv_flags & IFF_802_1Q_VLAN)) | ||
685 | goto out; | ||
686 | } | ||
687 | |||
688 | switch (args.cmd) { | ||
689 | case SET_VLAN_INGRESS_PRIORITY_CMD: | ||
690 | err = -EPERM; | ||
713 | if (!capable(CAP_NET_ADMIN)) | 691 | if (!capable(CAP_NET_ADMIN)) |
714 | return -EPERM; | 692 | break; |
715 | err = vlan_dev_set_ingress_priority(args.device1, | 693 | vlan_dev_set_ingress_priority(dev, |
716 | args.u.skb_priority, | 694 | args.u.skb_priority, |
717 | args.vlan_qos); | 695 | args.vlan_qos); |
718 | break; | 696 | break; |
719 | 697 | ||
720 | case SET_VLAN_EGRESS_PRIORITY_CMD: | 698 | case SET_VLAN_EGRESS_PRIORITY_CMD: |
699 | err = -EPERM; | ||
721 | if (!capable(CAP_NET_ADMIN)) | 700 | if (!capable(CAP_NET_ADMIN)) |
722 | return -EPERM; | 701 | break; |
723 | err = vlan_dev_set_egress_priority(args.device1, | 702 | err = vlan_dev_set_egress_priority(dev, |
724 | args.u.skb_priority, | 703 | args.u.skb_priority, |
725 | args.vlan_qos); | 704 | args.vlan_qos); |
726 | break; | 705 | break; |
727 | 706 | ||
728 | case SET_VLAN_FLAG_CMD: | 707 | case SET_VLAN_FLAG_CMD: |
708 | err = -EPERM; | ||
729 | if (!capable(CAP_NET_ADMIN)) | 709 | if (!capable(CAP_NET_ADMIN)) |
730 | return -EPERM; | 710 | break; |
731 | err = vlan_dev_set_vlan_flag(args.device1, | 711 | err = vlan_dev_set_vlan_flag(dev, |
732 | args.u.flag, | 712 | args.u.flag, |
733 | args.vlan_qos); | 713 | args.vlan_qos); |
734 | break; | 714 | break; |
735 | 715 | ||
736 | case SET_VLAN_NAME_TYPE_CMD: | 716 | case SET_VLAN_NAME_TYPE_CMD: |
717 | err = -EPERM; | ||
737 | if (!capable(CAP_NET_ADMIN)) | 718 | if (!capable(CAP_NET_ADMIN)) |
738 | return -EPERM; | 719 | return -EPERM; |
739 | if (args.u.name_type < VLAN_NAME_TYPE_HIGHEST) { | 720 | if ((args.u.name_type >= 0) && |
721 | (args.u.name_type < VLAN_NAME_TYPE_HIGHEST)) { | ||
740 | vlan_name_type = args.u.name_type; | 722 | vlan_name_type = args.u.name_type; |
741 | err = 0; | 723 | err = 0; |
742 | } else { | 724 | } else { |
@@ -745,13 +727,10 @@ static int vlan_ioctl_handler(void __user *arg) | |||
745 | break; | 727 | break; |
746 | 728 | ||
747 | case ADD_VLAN_CMD: | 729 | case ADD_VLAN_CMD: |
730 | err = -EPERM; | ||
748 | if (!capable(CAP_NET_ADMIN)) | 731 | if (!capable(CAP_NET_ADMIN)) |
749 | return -EPERM; | 732 | break; |
750 | /* we have been given the name of the Ethernet Device we want to | 733 | if (register_vlan_device(dev, args.u.VID)) { |
751 | * talk to: args.dev1 We also have the | ||
752 | * VLAN ID: args.u.VID | ||
753 | */ | ||
754 | if (register_vlan_device(args.device1, args.u.VID)) { | ||
755 | err = 0; | 734 | err = 0; |
756 | } else { | 735 | } else { |
757 | err = -EINVAL; | 736 | err = -EINVAL; |
@@ -759,12 +738,10 @@ static int vlan_ioctl_handler(void __user *arg) | |||
759 | break; | 738 | break; |
760 | 739 | ||
761 | case DEL_VLAN_CMD: | 740 | case DEL_VLAN_CMD: |
741 | err = -EPERM; | ||
762 | if (!capable(CAP_NET_ADMIN)) | 742 | if (!capable(CAP_NET_ADMIN)) |
763 | return -EPERM; | 743 | break; |
764 | /* Here, the args.dev1 is the actual VLAN we want | 744 | err = unregister_vlan_device(dev); |
765 | * to get rid of. | ||
766 | */ | ||
767 | err = unregister_vlan_device(args.device1); | ||
768 | break; | 745 | break; |
769 | 746 | ||
770 | case GET_VLAN_INGRESS_PRIORITY_CMD: | 747 | case GET_VLAN_INGRESS_PRIORITY_CMD: |
@@ -788,9 +765,7 @@ static int vlan_ioctl_handler(void __user *arg) | |||
788 | err = -EINVAL; | 765 | err = -EINVAL; |
789 | break; | 766 | break; |
790 | case GET_VLAN_REALDEV_NAME_CMD: | 767 | case GET_VLAN_REALDEV_NAME_CMD: |
791 | err = vlan_dev_get_realdev_name(args.device1, args.u.device2); | 768 | vlan_dev_get_realdev_name(dev, args.u.device2); |
792 | if (err) | ||
793 | goto out; | ||
794 | if (copy_to_user(arg, &args, | 769 | if (copy_to_user(arg, &args, |
795 | sizeof(struct vlan_ioctl_args))) { | 770 | sizeof(struct vlan_ioctl_args))) { |
796 | err = -EFAULT; | 771 | err = -EFAULT; |
@@ -798,9 +773,7 @@ static int vlan_ioctl_handler(void __user *arg) | |||
798 | break; | 773 | break; |
799 | 774 | ||
800 | case GET_VLAN_VID_CMD: | 775 | case GET_VLAN_VID_CMD: |
801 | err = vlan_dev_get_vid(args.device1, &vid); | 776 | vlan_dev_get_vid(dev, &vid); |
802 | if (err) | ||
803 | goto out; | ||
804 | args.u.VID = vid; | 777 | args.u.VID = vid; |
805 | if (copy_to_user(arg, &args, | 778 | if (copy_to_user(arg, &args, |
806 | sizeof(struct vlan_ioctl_args))) { | 779 | sizeof(struct vlan_ioctl_args))) { |
@@ -812,9 +785,11 @@ static int vlan_ioctl_handler(void __user *arg) | |||
812 | /* pass on to underlying device instead?? */ | 785 | /* pass on to underlying device instead?? */ |
813 | printk(VLAN_DBG "%s: Unknown VLAN CMD: %x \n", | 786 | printk(VLAN_DBG "%s: Unknown VLAN CMD: %x \n", |
814 | __FUNCTION__, args.cmd); | 787 | __FUNCTION__, args.cmd); |
815 | return -EINVAL; | 788 | err = -EINVAL; |
789 | break; | ||
816 | } | 790 | } |
817 | out: | 791 | out: |
792 | rtnl_unlock(); | ||
818 | return err; | 793 | return err; |
819 | } | 794 | } |
820 | 795 | ||
diff --git a/net/8021q/vlan.h b/net/8021q/vlan.h index 1976cdba8f72..b83739017e9d 100644 --- a/net/8021q/vlan.h +++ b/net/8021q/vlan.h | |||
@@ -62,11 +62,14 @@ int vlan_dev_set_mac_address(struct net_device *dev, void* addr); | |||
62 | int vlan_dev_open(struct net_device* dev); | 62 | int vlan_dev_open(struct net_device* dev); |
63 | int vlan_dev_stop(struct net_device* dev); | 63 | int vlan_dev_stop(struct net_device* dev); |
64 | int vlan_dev_ioctl(struct net_device* dev, struct ifreq *ifr, int cmd); | 64 | int vlan_dev_ioctl(struct net_device* dev, struct ifreq *ifr, int cmd); |
65 | int vlan_dev_set_ingress_priority(char* dev_name, __u32 skb_prio, short vlan_prio); | 65 | void vlan_dev_set_ingress_priority(const struct net_device *dev, |
66 | int vlan_dev_set_egress_priority(char* dev_name, __u32 skb_prio, short vlan_prio); | 66 | u32 skb_prio, short vlan_prio); |
67 | int vlan_dev_set_vlan_flag(char* dev_name, __u32 flag, short flag_val); | 67 | int vlan_dev_set_egress_priority(const struct net_device *dev, |
68 | int vlan_dev_get_realdev_name(const char* dev_name, char* result); | 68 | u32 skb_prio, short vlan_prio); |
69 | int vlan_dev_get_vid(const char* dev_name, unsigned short* result); | 69 | int vlan_dev_set_vlan_flag(const struct net_device *dev, |
70 | u32 flag, short flag_val); | ||
71 | void vlan_dev_get_realdev_name(const struct net_device *dev, char *result); | ||
72 | void vlan_dev_get_vid(const struct net_device *dev, unsigned short *result); | ||
70 | void vlan_dev_set_multicast_list(struct net_device *vlan_dev); | 73 | void vlan_dev_set_multicast_list(struct net_device *vlan_dev); |
71 | 74 | ||
72 | #endif /* !(__BEN_VLAN_802_1Q_INC__) */ | 75 | #endif /* !(__BEN_VLAN_802_1Q_INC__) */ |
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index ec46084f44b4..05a23601f670 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c | |||
@@ -534,136 +534,68 @@ int vlan_dev_change_mtu(struct net_device *dev, int new_mtu) | |||
534 | return 0; | 534 | return 0; |
535 | } | 535 | } |
536 | 536 | ||
537 | int vlan_dev_set_ingress_priority(char *dev_name, __u32 skb_prio, short vlan_prio) | 537 | void vlan_dev_set_ingress_priority(const struct net_device *dev, |
538 | u32 skb_prio, short vlan_prio) | ||
538 | { | 539 | { |
539 | struct net_device *dev = dev_get_by_name(dev_name); | 540 | VLAN_DEV_INFO(dev)->ingress_priority_map[vlan_prio & 0x7] = skb_prio; |
540 | |||
541 | if (dev) { | ||
542 | if (dev->priv_flags & IFF_802_1Q_VLAN) { | ||
543 | /* see if a priority mapping exists.. */ | ||
544 | VLAN_DEV_INFO(dev)->ingress_priority_map[vlan_prio & 0x7] = skb_prio; | ||
545 | dev_put(dev); | ||
546 | return 0; | ||
547 | } | ||
548 | |||
549 | dev_put(dev); | ||
550 | } | ||
551 | return -EINVAL; | ||
552 | } | 541 | } |
553 | 542 | ||
554 | int vlan_dev_set_egress_priority(char *dev_name, __u32 skb_prio, short vlan_prio) | 543 | int vlan_dev_set_egress_priority(const struct net_device *dev, |
544 | u32 skb_prio, short vlan_prio) | ||
555 | { | 545 | { |
556 | struct net_device *dev = dev_get_by_name(dev_name); | ||
557 | struct vlan_priority_tci_mapping *mp = NULL; | 546 | struct vlan_priority_tci_mapping *mp = NULL; |
558 | struct vlan_priority_tci_mapping *np; | 547 | struct vlan_priority_tci_mapping *np; |
559 | 548 | ||
560 | if (dev) { | 549 | /* See if a priority mapping exists.. */ |
561 | if (dev->priv_flags & IFF_802_1Q_VLAN) { | 550 | mp = VLAN_DEV_INFO(dev)->egress_priority_map[skb_prio & 0xF]; |
562 | /* See if a priority mapping exists.. */ | 551 | while (mp) { |
563 | mp = VLAN_DEV_INFO(dev)->egress_priority_map[skb_prio & 0xF]; | 552 | if (mp->priority == skb_prio) { |
564 | while (mp) { | 553 | mp->vlan_qos = ((vlan_prio << 13) & 0xE000); |
565 | if (mp->priority == skb_prio) { | 554 | return 0; |
566 | mp->vlan_qos = ((vlan_prio << 13) & 0xE000); | ||
567 | dev_put(dev); | ||
568 | return 0; | ||
569 | } | ||
570 | mp = mp->next; | ||
571 | } | ||
572 | |||
573 | /* Create a new mapping then. */ | ||
574 | mp = VLAN_DEV_INFO(dev)->egress_priority_map[skb_prio & 0xF]; | ||
575 | np = kmalloc(sizeof(struct vlan_priority_tci_mapping), GFP_KERNEL); | ||
576 | if (np) { | ||
577 | np->next = mp; | ||
578 | np->priority = skb_prio; | ||
579 | np->vlan_qos = ((vlan_prio << 13) & 0xE000); | ||
580 | VLAN_DEV_INFO(dev)->egress_priority_map[skb_prio & 0xF] = np; | ||
581 | dev_put(dev); | ||
582 | return 0; | ||
583 | } else { | ||
584 | dev_put(dev); | ||
585 | return -ENOBUFS; | ||
586 | } | ||
587 | } | 555 | } |
588 | dev_put(dev); | 556 | mp = mp->next; |
589 | } | 557 | } |
590 | return -EINVAL; | 558 | |
559 | /* Create a new mapping then. */ | ||
560 | mp = VLAN_DEV_INFO(dev)->egress_priority_map[skb_prio & 0xF]; | ||
561 | np = kmalloc(sizeof(struct vlan_priority_tci_mapping), GFP_KERNEL); | ||
562 | if (!np) | ||
563 | return -ENOBUFS; | ||
564 | |||
565 | np->next = mp; | ||
566 | np->priority = skb_prio; | ||
567 | np->vlan_qos = ((vlan_prio << 13) & 0xE000); | ||
568 | VLAN_DEV_INFO(dev)->egress_priority_map[skb_prio & 0xF] = np; | ||
569 | return 0; | ||
591 | } | 570 | } |
592 | 571 | ||
593 | /* Flags are defined in the vlan_dev_info class in include/linux/if_vlan.h file. */ | 572 | /* Flags are defined in the vlan_dev_info class in include/linux/if_vlan.h file. */ |
594 | int vlan_dev_set_vlan_flag(char *dev_name, __u32 flag, short flag_val) | 573 | int vlan_dev_set_vlan_flag(const struct net_device *dev, |
574 | u32 flag, short flag_val) | ||
595 | { | 575 | { |
596 | struct net_device *dev = dev_get_by_name(dev_name); | 576 | /* verify flag is supported */ |
597 | 577 | if (flag == 1) { | |
598 | if (dev) { | 578 | if (flag_val) { |
599 | if (dev->priv_flags & IFF_802_1Q_VLAN) { | 579 | VLAN_DEV_INFO(dev)->flags |= 1; |
600 | /* verify flag is supported */ | ||
601 | if (flag == 1) { | ||
602 | if (flag_val) { | ||
603 | VLAN_DEV_INFO(dev)->flags |= 1; | ||
604 | } else { | ||
605 | VLAN_DEV_INFO(dev)->flags &= ~1; | ||
606 | } | ||
607 | dev_put(dev); | ||
608 | return 0; | ||
609 | } else { | ||
610 | printk(KERN_ERR "%s: flag %i is not valid.\n", | ||
611 | __FUNCTION__, (int)(flag)); | ||
612 | dev_put(dev); | ||
613 | return -EINVAL; | ||
614 | } | ||
615 | } else { | 580 | } else { |
616 | printk(KERN_ERR | 581 | VLAN_DEV_INFO(dev)->flags &= ~1; |
617 | "%s: %s is not a vlan device, priv_flags: %hX.\n", | ||
618 | __FUNCTION__, dev->name, dev->priv_flags); | ||
619 | dev_put(dev); | ||
620 | } | 582 | } |
621 | } else { | 583 | return 0; |
622 | printk(KERN_ERR "%s: Could not find device: %s\n", | ||
623 | __FUNCTION__, dev_name); | ||
624 | } | 584 | } |
625 | 585 | printk(KERN_ERR "%s: flag %i is not valid.\n", __FUNCTION__, flag); | |
626 | return -EINVAL; | 586 | return -EINVAL; |
627 | } | 587 | } |
628 | 588 | ||
629 | 589 | void vlan_dev_get_realdev_name(const struct net_device *dev, char *result) | |
630 | int vlan_dev_get_realdev_name(const char *dev_name, char* result) | ||
631 | { | 590 | { |
632 | struct net_device *dev = dev_get_by_name(dev_name); | 591 | strncpy(result, VLAN_DEV_INFO(dev)->real_dev->name, 23); |
633 | int rv = 0; | ||
634 | if (dev) { | ||
635 | if (dev->priv_flags & IFF_802_1Q_VLAN) { | ||
636 | strncpy(result, VLAN_DEV_INFO(dev)->real_dev->name, 23); | ||
637 | rv = 0; | ||
638 | } else { | ||
639 | rv = -EINVAL; | ||
640 | } | ||
641 | dev_put(dev); | ||
642 | } else { | ||
643 | rv = -ENODEV; | ||
644 | } | ||
645 | return rv; | ||
646 | } | 592 | } |
647 | 593 | ||
648 | int vlan_dev_get_vid(const char *dev_name, unsigned short* result) | 594 | void vlan_dev_get_vid(const struct net_device *dev, unsigned short *result) |
649 | { | 595 | { |
650 | struct net_device *dev = dev_get_by_name(dev_name); | 596 | *result = VLAN_DEV_INFO(dev)->vlan_id; |
651 | int rv = 0; | ||
652 | if (dev) { | ||
653 | if (dev->priv_flags & IFF_802_1Q_VLAN) { | ||
654 | *result = VLAN_DEV_INFO(dev)->vlan_id; | ||
655 | rv = 0; | ||
656 | } else { | ||
657 | rv = -EINVAL; | ||
658 | } | ||
659 | dev_put(dev); | ||
660 | } else { | ||
661 | rv = -ENODEV; | ||
662 | } | ||
663 | return rv; | ||
664 | } | 597 | } |
665 | 598 | ||
666 | |||
667 | int vlan_dev_set_mac_address(struct net_device *dev, void *addr_struct_p) | 599 | int vlan_dev_set_mac_address(struct net_device *dev, void *addr_struct_p) |
668 | { | 600 | { |
669 | struct sockaddr *addr = (struct sockaddr *)(addr_struct_p); | 601 | struct sockaddr *addr = (struct sockaddr *)(addr_struct_p); |