diff options
author | Patrick McHardy <kaber@trash.net> | 2007-06-13 15:07:22 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-07-11 01:15:01 -0400 |
commit | b020cb488586f982f40eb257a32e92a4de710d65 (patch) | |
tree | a6476a48f969688256079c53b02d8ab20e1d7719 | |
parent | 734423cf38021966a5d3bd5f5c6aaecaf32fb4ac (diff) |
[VLAN]: Keep track of number of QoS mappings
Keep track of the number of configured ingress/egress QoS mappings to
avoid iteration while calculating the netlink attribute size.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/linux/if_vlan.h | 3 | ||||
-rw-r--r-- | net/8021q/vlan_dev.c | 27 |
2 files changed, 24 insertions, 6 deletions
diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index aeddb49193f9..b46d4225f74e 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h | |||
@@ -112,7 +112,10 @@ struct vlan_dev_info { | |||
112 | /** This will be the mapping that correlates skb->priority to | 112 | /** This will be the mapping that correlates skb->priority to |
113 | * 3 bits of VLAN QOS tags... | 113 | * 3 bits of VLAN QOS tags... |
114 | */ | 114 | */ |
115 | unsigned int nr_ingress_mappings; | ||
115 | u32 ingress_priority_map[8]; | 116 | u32 ingress_priority_map[8]; |
117 | |||
118 | unsigned int nr_egress_mappings; | ||
116 | struct vlan_priority_tci_mapping *egress_priority_map[16]; /* hash table */ | 119 | struct vlan_priority_tci_mapping *egress_priority_map[16]; /* hash table */ |
117 | 120 | ||
118 | unsigned short vlan_id; /* The VLAN Identifier for this interface. */ | 121 | unsigned short vlan_id; /* The VLAN Identifier for this interface. */ |
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 05a23601f670..4f6ede752a37 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c | |||
@@ -537,35 +537,50 @@ int vlan_dev_change_mtu(struct net_device *dev, int new_mtu) | |||
537 | void vlan_dev_set_ingress_priority(const struct net_device *dev, | 537 | void vlan_dev_set_ingress_priority(const struct net_device *dev, |
538 | u32 skb_prio, short vlan_prio) | 538 | u32 skb_prio, short vlan_prio) |
539 | { | 539 | { |
540 | VLAN_DEV_INFO(dev)->ingress_priority_map[vlan_prio & 0x7] = skb_prio; | 540 | struct vlan_dev_info *vlan = VLAN_DEV_INFO(dev); |
541 | |||
542 | if (vlan->ingress_priority_map[vlan_prio & 0x7] && !skb_prio) | ||
543 | vlan->nr_ingress_mappings--; | ||
544 | else if (!vlan->ingress_priority_map[vlan_prio & 0x7] && skb_prio) | ||
545 | vlan->nr_ingress_mappings++; | ||
546 | |||
547 | vlan->ingress_priority_map[vlan_prio & 0x7] = skb_prio; | ||
541 | } | 548 | } |
542 | 549 | ||
543 | int vlan_dev_set_egress_priority(const struct net_device *dev, | 550 | int vlan_dev_set_egress_priority(const struct net_device *dev, |
544 | u32 skb_prio, short vlan_prio) | 551 | u32 skb_prio, short vlan_prio) |
545 | { | 552 | { |
553 | struct vlan_dev_info *vlan = VLAN_DEV_INFO(dev); | ||
546 | struct vlan_priority_tci_mapping *mp = NULL; | 554 | struct vlan_priority_tci_mapping *mp = NULL; |
547 | struct vlan_priority_tci_mapping *np; | 555 | struct vlan_priority_tci_mapping *np; |
556 | u32 vlan_qos = (vlan_prio << 13) & 0xE000; | ||
548 | 557 | ||
549 | /* See if a priority mapping exists.. */ | 558 | /* See if a priority mapping exists.. */ |
550 | mp = VLAN_DEV_INFO(dev)->egress_priority_map[skb_prio & 0xF]; | 559 | mp = vlan->egress_priority_map[skb_prio & 0xF]; |
551 | while (mp) { | 560 | while (mp) { |
552 | if (mp->priority == skb_prio) { | 561 | if (mp->priority == skb_prio) { |
553 | mp->vlan_qos = ((vlan_prio << 13) & 0xE000); | 562 | if (mp->vlan_qos && !vlan_qos) |
563 | vlan->nr_egress_mappings--; | ||
564 | else if (!mp->vlan_qos && vlan_qos) | ||
565 | vlan->nr_egress_mappings++; | ||
566 | mp->vlan_qos = vlan_qos; | ||
554 | return 0; | 567 | return 0; |
555 | } | 568 | } |
556 | mp = mp->next; | 569 | mp = mp->next; |
557 | } | 570 | } |
558 | 571 | ||
559 | /* Create a new mapping then. */ | 572 | /* Create a new mapping then. */ |
560 | mp = VLAN_DEV_INFO(dev)->egress_priority_map[skb_prio & 0xF]; | 573 | mp = vlan->egress_priority_map[skb_prio & 0xF]; |
561 | np = kmalloc(sizeof(struct vlan_priority_tci_mapping), GFP_KERNEL); | 574 | np = kmalloc(sizeof(struct vlan_priority_tci_mapping), GFP_KERNEL); |
562 | if (!np) | 575 | if (!np) |
563 | return -ENOBUFS; | 576 | return -ENOBUFS; |
564 | 577 | ||
565 | np->next = mp; | 578 | np->next = mp; |
566 | np->priority = skb_prio; | 579 | np->priority = skb_prio; |
567 | np->vlan_qos = ((vlan_prio << 13) & 0xE000); | 580 | np->vlan_qos = vlan_qos; |
568 | VLAN_DEV_INFO(dev)->egress_priority_map[skb_prio & 0xF] = np; | 581 | vlan->egress_priority_map[skb_prio & 0xF] = np; |
582 | if (vlan_qos) | ||
583 | vlan->nr_egress_mappings++; | ||
569 | return 0; | 584 | return 0; |
570 | } | 585 | } |
571 | 586 | ||