net: dcb: Add priority-to-DSCP map getters
On ingress, a network device such as a switch assigns to packets priority based on various criteria. Common options include interpreting PCP and DSCP fields according to user configuration. When a packet egresses the switch, a reverse process may rewrite PCP and/or DSCP values according to packet priority. The following three functions support a) obtaining a DSCP-to-priority map or vice versa, and b) finding default-priority entries in APP database. The DCB subsystem supports for APP entries a very generous M:N mapping between priorities and protocol identifiers. Understandably, several (say) DSCP values can map to the same priority. But this asymmetry holds the other way around as well--one priority can map to several DSCP values. For this reason, the following functions operate in terms of bitmaps, with ones in positions that match some APP entry. - dcb_ieee_getapp_dscp_prio_mask_map() to compute for a given netdevice a map of DSCP-to-priority-mask, which gives for each DSCP value a bitmap of priorities related to that DSCP value by APP, along the lines of dcb_ieee_getapp_mask(). - dcb_ieee_getapp_prio_dscp_mask_map() similarly to compute for a given netdevice a map from priorities to a bitmap of DSCPs. - dcb_ieee_getapp_default_prio_mask() which finds all default-priority rules for a given port in APP database, and returns a mask of priorities allowed by these default-priority rules. Signed-off-by: Petr Machata <petrm@mellanox.com> Signed-off-by: Ido Schimmel <idosch@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
08193d1a89
commit
b67c540b8a
|
@ -34,6 +34,19 @@ int dcb_ieee_setapp(struct net_device *, struct dcb_app *);
|
|||
int dcb_ieee_delapp(struct net_device *, struct dcb_app *);
|
||||
u8 dcb_ieee_getapp_mask(struct net_device *, struct dcb_app *);
|
||||
|
||||
struct dcb_ieee_app_prio_map {
|
||||
u64 map[IEEE_8021QAZ_MAX_TCS];
|
||||
};
|
||||
void dcb_ieee_getapp_prio_dscp_mask_map(const struct net_device *dev,
|
||||
struct dcb_ieee_app_prio_map *p_map);
|
||||
|
||||
struct dcb_ieee_app_dscp_map {
|
||||
u8 map[64];
|
||||
};
|
||||
void dcb_ieee_getapp_dscp_prio_mask_map(const struct net_device *dev,
|
||||
struct dcb_ieee_app_dscp_map *p_map);
|
||||
u8 dcb_ieee_getapp_default_prio_mask(const struct net_device *dev);
|
||||
|
||||
int dcbnl_ieee_notify(struct net_device *dev, int event, int cmd,
|
||||
u32 seq, u32 pid);
|
||||
int dcbnl_cee_notify(struct net_device *dev, int event, int cmd,
|
||||
|
|
|
@ -1958,6 +1958,92 @@ int dcb_ieee_delapp(struct net_device *dev, struct dcb_app *del)
|
|||
}
|
||||
EXPORT_SYMBOL(dcb_ieee_delapp);
|
||||
|
||||
/**
|
||||
* dcb_ieee_getapp_prio_dscp_mask_map - For a given device, find mapping from
|
||||
* priorities to the DSCP values assigned to that priority. Initialize p_map
|
||||
* such that each map element holds a bit mask of DSCP values configured for
|
||||
* that priority by APP entries.
|
||||
*/
|
||||
void dcb_ieee_getapp_prio_dscp_mask_map(const struct net_device *dev,
|
||||
struct dcb_ieee_app_prio_map *p_map)
|
||||
{
|
||||
int ifindex = dev->ifindex;
|
||||
struct dcb_app_type *itr;
|
||||
u8 prio;
|
||||
|
||||
memset(p_map->map, 0, sizeof(p_map->map));
|
||||
|
||||
spin_lock_bh(&dcb_lock);
|
||||
list_for_each_entry(itr, &dcb_app_list, list) {
|
||||
if (itr->ifindex == ifindex &&
|
||||
itr->app.selector == IEEE_8021QAZ_APP_SEL_DSCP &&
|
||||
itr->app.protocol < 64 &&
|
||||
itr->app.priority < IEEE_8021QAZ_MAX_TCS) {
|
||||
prio = itr->app.priority;
|
||||
p_map->map[prio] |= 1ULL << itr->app.protocol;
|
||||
}
|
||||
}
|
||||
spin_unlock_bh(&dcb_lock);
|
||||
}
|
||||
EXPORT_SYMBOL(dcb_ieee_getapp_prio_dscp_mask_map);
|
||||
|
||||
/**
|
||||
* dcb_ieee_getapp_dscp_prio_mask_map - For a given device, find mapping from
|
||||
* DSCP values to the priorities assigned to that DSCP value. Initialize p_map
|
||||
* such that each map element holds a bit mask of priorities configured for a
|
||||
* given DSCP value by APP entries.
|
||||
*/
|
||||
void
|
||||
dcb_ieee_getapp_dscp_prio_mask_map(const struct net_device *dev,
|
||||
struct dcb_ieee_app_dscp_map *p_map)
|
||||
{
|
||||
int ifindex = dev->ifindex;
|
||||
struct dcb_app_type *itr;
|
||||
|
||||
memset(p_map->map, 0, sizeof(p_map->map));
|
||||
|
||||
spin_lock_bh(&dcb_lock);
|
||||
list_for_each_entry(itr, &dcb_app_list, list) {
|
||||
if (itr->ifindex == ifindex &&
|
||||
itr->app.selector == IEEE_8021QAZ_APP_SEL_DSCP &&
|
||||
itr->app.protocol < 64 &&
|
||||
itr->app.priority < IEEE_8021QAZ_MAX_TCS)
|
||||
p_map->map[itr->app.protocol] |= 1 << itr->app.priority;
|
||||
}
|
||||
spin_unlock_bh(&dcb_lock);
|
||||
}
|
||||
EXPORT_SYMBOL(dcb_ieee_getapp_dscp_prio_mask_map);
|
||||
|
||||
/**
|
||||
* Per 802.1Q-2014, the selector value of 1 is used for matching on Ethernet
|
||||
* type, with valid PID values >= 1536. A special meaning is then assigned to
|
||||
* protocol value of 0: "default priority. For use when priority is not
|
||||
* otherwise specified".
|
||||
*
|
||||
* dcb_ieee_getapp_default_prio_mask - For a given device, find all APP entries
|
||||
* of the form {$PRIO, ETHERTYPE, 0} and construct a bit mask of all default
|
||||
* priorities set by these entries.
|
||||
*/
|
||||
u8 dcb_ieee_getapp_default_prio_mask(const struct net_device *dev)
|
||||
{
|
||||
int ifindex = dev->ifindex;
|
||||
struct dcb_app_type *itr;
|
||||
u8 mask = 0;
|
||||
|
||||
spin_lock_bh(&dcb_lock);
|
||||
list_for_each_entry(itr, &dcb_app_list, list) {
|
||||
if (itr->ifindex == ifindex &&
|
||||
itr->app.selector == IEEE_8021QAZ_APP_SEL_ETHERTYPE &&
|
||||
itr->app.protocol == 0 &&
|
||||
itr->app.priority < IEEE_8021QAZ_MAX_TCS)
|
||||
mask |= 1 << itr->app.priority;
|
||||
}
|
||||
spin_unlock_bh(&dcb_lock);
|
||||
|
||||
return mask;
|
||||
}
|
||||
EXPORT_SYMBOL(dcb_ieee_getapp_default_prio_mask);
|
||||
|
||||
static int __init dcbnl_init(void)
|
||||
{
|
||||
INIT_LIST_HEAD(&dcb_app_list);
|
||||
|
|
Loading…
Reference in New Issue