diff options
author | Patrick McHardy <kaber@trash.net> | 2007-06-13 15:05:22 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-07-11 01:14:38 -0400 |
commit | c17d8874f9959070552fddf1b4e1d73c0c144c0f (patch) | |
tree | ea5a61e37f71218f8cb69033293a55631511b470 /net/8021q/vlan_dev.c | |
parent | 9ba2cd656021e7f70038ba9d551224e04d0bfcef (diff) |
[VLAN]: Convert name-based configuration functions to struct netdevice *
Move the device lookup and checks to the ioctl handler under the RTNL and
change all name-based interfaces to take a struct net_device * instead.
This allows to use them from a netlink interface, which identifies devices
based on ifindex not name. It also avoids races between the ioctl interface
and the (upcoming) netlink interface since now all changes happen under the
RTNL.
As a nice side effect this greatly simplifies error handling in the helper
functions and fixes a number of incorrect error codes like -EINVAL for
device not found.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/8021q/vlan_dev.c')
-rw-r--r-- | net/8021q/vlan_dev.c | 142 |
1 files changed, 37 insertions, 105 deletions
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); |