Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Petr Machata and committed by
David S. Miller
b67c540b 08193d1a

+99
+13
include/net/dcbnl.h
··· 34 34 int dcb_ieee_delapp(struct net_device *, struct dcb_app *); 35 35 u8 dcb_ieee_getapp_mask(struct net_device *, struct dcb_app *); 36 36 37 + struct dcb_ieee_app_prio_map { 38 + u64 map[IEEE_8021QAZ_MAX_TCS]; 39 + }; 40 + void dcb_ieee_getapp_prio_dscp_mask_map(const struct net_device *dev, 41 + struct dcb_ieee_app_prio_map *p_map); 42 + 43 + struct dcb_ieee_app_dscp_map { 44 + u8 map[64]; 45 + }; 46 + void dcb_ieee_getapp_dscp_prio_mask_map(const struct net_device *dev, 47 + struct dcb_ieee_app_dscp_map *p_map); 48 + u8 dcb_ieee_getapp_default_prio_mask(const struct net_device *dev); 49 + 37 50 int dcbnl_ieee_notify(struct net_device *dev, int event, int cmd, 38 51 u32 seq, u32 pid); 39 52 int dcbnl_cee_notify(struct net_device *dev, int event, int cmd,
+86
net/dcb/dcbnl.c
··· 1958 1958 } 1959 1959 EXPORT_SYMBOL(dcb_ieee_delapp); 1960 1960 1961 + /** 1962 + * dcb_ieee_getapp_prio_dscp_mask_map - For a given device, find mapping from 1963 + * priorities to the DSCP values assigned to that priority. Initialize p_map 1964 + * such that each map element holds a bit mask of DSCP values configured for 1965 + * that priority by APP entries. 1966 + */ 1967 + void dcb_ieee_getapp_prio_dscp_mask_map(const struct net_device *dev, 1968 + struct dcb_ieee_app_prio_map *p_map) 1969 + { 1970 + int ifindex = dev->ifindex; 1971 + struct dcb_app_type *itr; 1972 + u8 prio; 1973 + 1974 + memset(p_map->map, 0, sizeof(p_map->map)); 1975 + 1976 + spin_lock_bh(&dcb_lock); 1977 + list_for_each_entry(itr, &dcb_app_list, list) { 1978 + if (itr->ifindex == ifindex && 1979 + itr->app.selector == IEEE_8021QAZ_APP_SEL_DSCP && 1980 + itr->app.protocol < 64 && 1981 + itr->app.priority < IEEE_8021QAZ_MAX_TCS) { 1982 + prio = itr->app.priority; 1983 + p_map->map[prio] |= 1ULL << itr->app.protocol; 1984 + } 1985 + } 1986 + spin_unlock_bh(&dcb_lock); 1987 + } 1988 + EXPORT_SYMBOL(dcb_ieee_getapp_prio_dscp_mask_map); 1989 + 1990 + /** 1991 + * dcb_ieee_getapp_dscp_prio_mask_map - For a given device, find mapping from 1992 + * DSCP values to the priorities assigned to that DSCP value. Initialize p_map 1993 + * such that each map element holds a bit mask of priorities configured for a 1994 + * given DSCP value by APP entries. 1995 + */ 1996 + void 1997 + dcb_ieee_getapp_dscp_prio_mask_map(const struct net_device *dev, 1998 + struct dcb_ieee_app_dscp_map *p_map) 1999 + { 2000 + int ifindex = dev->ifindex; 2001 + struct dcb_app_type *itr; 2002 + 2003 + memset(p_map->map, 0, sizeof(p_map->map)); 2004 + 2005 + spin_lock_bh(&dcb_lock); 2006 + list_for_each_entry(itr, &dcb_app_list, list) { 2007 + if (itr->ifindex == ifindex && 2008 + itr->app.selector == IEEE_8021QAZ_APP_SEL_DSCP && 2009 + itr->app.protocol < 64 && 2010 + itr->app.priority < IEEE_8021QAZ_MAX_TCS) 2011 + p_map->map[itr->app.protocol] |= 1 << itr->app.priority; 2012 + } 2013 + spin_unlock_bh(&dcb_lock); 2014 + } 2015 + EXPORT_SYMBOL(dcb_ieee_getapp_dscp_prio_mask_map); 2016 + 2017 + /** 2018 + * Per 802.1Q-2014, the selector value of 1 is used for matching on Ethernet 2019 + * type, with valid PID values >= 1536. A special meaning is then assigned to 2020 + * protocol value of 0: "default priority. For use when priority is not 2021 + * otherwise specified". 2022 + * 2023 + * dcb_ieee_getapp_default_prio_mask - For a given device, find all APP entries 2024 + * of the form {$PRIO, ETHERTYPE, 0} and construct a bit mask of all default 2025 + * priorities set by these entries. 2026 + */ 2027 + u8 dcb_ieee_getapp_default_prio_mask(const struct net_device *dev) 2028 + { 2029 + int ifindex = dev->ifindex; 2030 + struct dcb_app_type *itr; 2031 + u8 mask = 0; 2032 + 2033 + spin_lock_bh(&dcb_lock); 2034 + list_for_each_entry(itr, &dcb_app_list, list) { 2035 + if (itr->ifindex == ifindex && 2036 + itr->app.selector == IEEE_8021QAZ_APP_SEL_ETHERTYPE && 2037 + itr->app.protocol == 0 && 2038 + itr->app.priority < IEEE_8021QAZ_MAX_TCS) 2039 + mask |= 1 << itr->app.priority; 2040 + } 2041 + spin_unlock_bh(&dcb_lock); 2042 + 2043 + return mask; 2044 + } 2045 + EXPORT_SYMBOL(dcb_ieee_getapp_default_prio_mask); 2046 + 1961 2047 static int __init dcbnl_init(void) 1962 2048 { 1963 2049 INIT_LIST_HEAD(&dcb_app_list);