aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/if_vlan.h3
-rw-r--r--net/8021q/vlan_dev.c27
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)
537void vlan_dev_set_ingress_priority(const struct net_device *dev, 537void 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
543int vlan_dev_set_egress_priority(const struct net_device *dev, 550int 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