[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>
This commit is contained in:
committed by
David S. Miller
parent
734423cf38
commit
b020cb4885
@@ -112,7 +112,10 @@ struct vlan_dev_info {
|
|||||||
/** This will be the mapping that correlates skb->priority to
|
/** This will be the mapping that correlates skb->priority to
|
||||||
* 3 bits of VLAN QOS tags...
|
* 3 bits of VLAN QOS tags...
|
||||||
*/
|
*/
|
||||||
|
unsigned int nr_ingress_mappings;
|
||||||
u32 ingress_priority_map[8];
|
u32 ingress_priority_map[8];
|
||||||
|
|
||||||
|
unsigned int nr_egress_mappings;
|
||||||
struct vlan_priority_tci_mapping *egress_priority_map[16]; /* hash table */
|
struct vlan_priority_tci_mapping *egress_priority_map[16]; /* hash table */
|
||||||
|
|
||||||
unsigned short vlan_id; /* The VLAN Identifier for this interface. */
|
unsigned short vlan_id; /* The VLAN Identifier for this interface. */
|
||||||
|
@@ -537,35 +537,50 @@ int vlan_dev_change_mtu(struct net_device *dev, int new_mtu)
|
|||||||
void vlan_dev_set_ingress_priority(const struct net_device *dev,
|
void vlan_dev_set_ingress_priority(const struct net_device *dev,
|
||||||
u32 skb_prio, short vlan_prio)
|
u32 skb_prio, short vlan_prio)
|
||||||
{
|
{
|
||||||
VLAN_DEV_INFO(dev)->ingress_priority_map[vlan_prio & 0x7] = skb_prio;
|
struct vlan_dev_info *vlan = VLAN_DEV_INFO(dev);
|
||||||
|
|
||||||
|
if (vlan->ingress_priority_map[vlan_prio & 0x7] && !skb_prio)
|
||||||
|
vlan->nr_ingress_mappings--;
|
||||||
|
else if (!vlan->ingress_priority_map[vlan_prio & 0x7] && skb_prio)
|
||||||
|
vlan->nr_ingress_mappings++;
|
||||||
|
|
||||||
|
vlan->ingress_priority_map[vlan_prio & 0x7] = skb_prio;
|
||||||
}
|
}
|
||||||
|
|
||||||
int vlan_dev_set_egress_priority(const struct net_device *dev,
|
int vlan_dev_set_egress_priority(const struct net_device *dev,
|
||||||
u32 skb_prio, short vlan_prio)
|
u32 skb_prio, short vlan_prio)
|
||||||
{
|
{
|
||||||
|
struct vlan_dev_info *vlan = VLAN_DEV_INFO(dev);
|
||||||
struct vlan_priority_tci_mapping *mp = NULL;
|
struct vlan_priority_tci_mapping *mp = NULL;
|
||||||
struct vlan_priority_tci_mapping *np;
|
struct vlan_priority_tci_mapping *np;
|
||||||
|
u32 vlan_qos = (vlan_prio << 13) & 0xE000;
|
||||||
|
|
||||||
/* See if a priority mapping exists.. */
|
/* See if a priority mapping exists.. */
|
||||||
mp = VLAN_DEV_INFO(dev)->egress_priority_map[skb_prio & 0xF];
|
mp = vlan->egress_priority_map[skb_prio & 0xF];
|
||||||
while (mp) {
|
while (mp) {
|
||||||
if (mp->priority == skb_prio) {
|
if (mp->priority == skb_prio) {
|
||||||
mp->vlan_qos = ((vlan_prio << 13) & 0xE000);
|
if (mp->vlan_qos && !vlan_qos)
|
||||||
|
vlan->nr_egress_mappings--;
|
||||||
|
else if (!mp->vlan_qos && vlan_qos)
|
||||||
|
vlan->nr_egress_mappings++;
|
||||||
|
mp->vlan_qos = vlan_qos;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
mp = mp->next;
|
mp = mp->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create a new mapping then. */
|
/* Create a new mapping then. */
|
||||||
mp = VLAN_DEV_INFO(dev)->egress_priority_map[skb_prio & 0xF];
|
mp = vlan->egress_priority_map[skb_prio & 0xF];
|
||||||
np = kmalloc(sizeof(struct vlan_priority_tci_mapping), GFP_KERNEL);
|
np = kmalloc(sizeof(struct vlan_priority_tci_mapping), GFP_KERNEL);
|
||||||
if (!np)
|
if (!np)
|
||||||
return -ENOBUFS;
|
return -ENOBUFS;
|
||||||
|
|
||||||
np->next = mp;
|
np->next = mp;
|
||||||
np->priority = skb_prio;
|
np->priority = skb_prio;
|
||||||
np->vlan_qos = ((vlan_prio << 13) & 0xE000);
|
np->vlan_qos = vlan_qos;
|
||||||
VLAN_DEV_INFO(dev)->egress_priority_map[skb_prio & 0xF] = np;
|
vlan->egress_priority_map[skb_prio & 0xF] = np;
|
||||||
|
if (vlan_qos)
|
||||||
|
vlan->nr_egress_mappings++;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user