Skip to content

Commit b020cb4

Browse files
kaberDavid S. Miller
authored andcommitted
[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>
1 parent 734423c commit b020cb4

File tree

2 files changed

+24
-6
lines changed

2 files changed

+24
-6
lines changed

include/linux/if_vlan.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,10 @@ struct vlan_dev_info {
112112
/** This will be the mapping that correlates skb->priority to
113113
* 3 bits of VLAN QOS tags...
114114
*/
115+
unsigned int nr_ingress_mappings;
115116
u32 ingress_priority_map[8];
117+
118+
unsigned int nr_egress_mappings;
116119
struct vlan_priority_tci_mapping *egress_priority_map[16]; /* hash table */
117120

118121
unsigned short vlan_id; /* The VLAN Identifier for this interface. */

net/8021q/vlan_dev.c

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -537,35 +537,50 @@ int vlan_dev_change_mtu(struct net_device *dev, int new_mtu)
537537
void vlan_dev_set_ingress_priority(const struct net_device *dev,
538538
u32 skb_prio, short vlan_prio)
539539
{
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;
541548
}
542549

543550
int vlan_dev_set_egress_priority(const struct net_device *dev,
544551
u32 skb_prio, short vlan_prio)
545552
{
553+
struct vlan_dev_info *vlan = VLAN_DEV_INFO(dev);
546554
struct vlan_priority_tci_mapping *mp = NULL;
547555
struct vlan_priority_tci_mapping *np;
556+
u32 vlan_qos = (vlan_prio << 13) & 0xE000;
548557

549558
/* 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];
551560
while (mp) {
552561
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;
554567
return 0;
555568
}
556569
mp = mp->next;
557570
}
558571

559572
/* 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];
561574
np = kmalloc(sizeof(struct vlan_priority_tci_mapping), GFP_KERNEL);
562575
if (!np)
563576
return -ENOBUFS;
564577

565578
np->next = mp;
566579
np->priority = skb_prio;
567-
np->vlan_qos = ((vlan_prio << 13) & 0xE000);
568-
VLAN_DEV_INFO(dev)->egress_priority_map[skb_prio & 0xF] = np;
580+
np->vlan_qos = vlan_qos;
581+
vlan->egress_priority_map[skb_prio & 0xF] = np;
582+
if (vlan_qos)
583+
vlan->nr_egress_mappings++;
569584
return 0;
570585
}
571586

0 commit comments

Comments
 (0)