aboutsummaryrefslogtreecommitdiffstats
path: root/net/8021q/vlan_dev.c
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2007-06-13 15:05:22 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-07-11 01:14:38 -0400
commitc17d8874f9959070552fddf1b4e1d73c0c144c0f (patch)
treeea5a61e37f71218f8cb69033293a55631511b470 /net/8021q/vlan_dev.c
parent9ba2cd656021e7f70038ba9d551224e04d0bfcef (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.c142
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
537int vlan_dev_set_ingress_priority(char *dev_name, __u32 skb_prio, short vlan_prio) 537void 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
554int vlan_dev_set_egress_priority(char *dev_name, __u32 skb_prio, short vlan_prio) 543int 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. */
594int vlan_dev_set_vlan_flag(char *dev_name, __u32 flag, short flag_val) 573int 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 589void vlan_dev_get_realdev_name(const struct net_device *dev, char *result)
630int 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
648int vlan_dev_get_vid(const char *dev_name, unsigned short* result) 594void 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
667int vlan_dev_set_mac_address(struct net_device *dev, void *addr_struct_p) 599int 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);