xref: /openbmc/linux/include/net/inet_dscp.h (revision a410a0cf)
1*a410a0cfSGuillaume Nault /* SPDX-License-Identifier: GPL-2.0-or-later */
2*a410a0cfSGuillaume Nault /*
3*a410a0cfSGuillaume Nault  * inet_dscp.h: helpers for handling differentiated services codepoints (DSCP)
4*a410a0cfSGuillaume Nault  *
5*a410a0cfSGuillaume Nault  * DSCP is defined in RFC 2474:
6*a410a0cfSGuillaume Nault  *
7*a410a0cfSGuillaume Nault  *        0   1   2   3   4   5   6   7
8*a410a0cfSGuillaume Nault  *      +---+---+---+---+---+---+---+---+
9*a410a0cfSGuillaume Nault  *      |         DSCP          |  CU   |
10*a410a0cfSGuillaume Nault  *      +---+---+---+---+---+---+---+---+
11*a410a0cfSGuillaume Nault  *
12*a410a0cfSGuillaume Nault  *        DSCP: differentiated services codepoint
13*a410a0cfSGuillaume Nault  *        CU:   currently unused
14*a410a0cfSGuillaume Nault  *
15*a410a0cfSGuillaume Nault  * The whole DSCP + CU bits form the DS field.
16*a410a0cfSGuillaume Nault  * The DS field is also commonly called TOS or Traffic Class (for IPv6).
17*a410a0cfSGuillaume Nault  *
18*a410a0cfSGuillaume Nault  * Note: the CU bits are now used for Explicit Congestion Notification
19*a410a0cfSGuillaume Nault  *       (RFC 3168).
20*a410a0cfSGuillaume Nault  */
21*a410a0cfSGuillaume Nault 
22*a410a0cfSGuillaume Nault #ifndef _INET_DSCP_H
23*a410a0cfSGuillaume Nault #define _INET_DSCP_H
24*a410a0cfSGuillaume Nault 
25*a410a0cfSGuillaume Nault #include <linux/types.h>
26*a410a0cfSGuillaume Nault 
27*a410a0cfSGuillaume Nault /* Special type for storing DSCP values.
28*a410a0cfSGuillaume Nault  *
29*a410a0cfSGuillaume Nault  * A dscp_t variable stores a DS field with the CU (ECN) bits cleared.
30*a410a0cfSGuillaume Nault  * Using dscp_t allows to strictly separate DSCP and ECN bits, thus avoiding
31*a410a0cfSGuillaume Nault  * bugs where ECN bits are erroneously taken into account during FIB lookups
32*a410a0cfSGuillaume Nault  * or policy routing.
33*a410a0cfSGuillaume Nault  *
34*a410a0cfSGuillaume Nault  * Note: to get the real DSCP value contained in a dscp_t variable one would
35*a410a0cfSGuillaume Nault  * have to do a bit shift after calling inet_dscp_to_dsfield(). We could have
36*a410a0cfSGuillaume Nault  * a helper for that, but there's currently no users.
37*a410a0cfSGuillaume Nault  */
38*a410a0cfSGuillaume Nault typedef u8 __bitwise dscp_t;
39*a410a0cfSGuillaume Nault 
40*a410a0cfSGuillaume Nault #define INET_DSCP_MASK 0xfc
41*a410a0cfSGuillaume Nault 
inet_dsfield_to_dscp(__u8 dsfield)42*a410a0cfSGuillaume Nault static inline dscp_t inet_dsfield_to_dscp(__u8 dsfield)
43*a410a0cfSGuillaume Nault {
44*a410a0cfSGuillaume Nault 	return (__force dscp_t)(dsfield & INET_DSCP_MASK);
45*a410a0cfSGuillaume Nault }
46*a410a0cfSGuillaume Nault 
inet_dscp_to_dsfield(dscp_t dscp)47*a410a0cfSGuillaume Nault static inline __u8 inet_dscp_to_dsfield(dscp_t dscp)
48*a410a0cfSGuillaume Nault {
49*a410a0cfSGuillaume Nault 	return (__force __u8)dscp;
50*a410a0cfSGuillaume Nault }
51*a410a0cfSGuillaume Nault 
inet_validate_dscp(__u8 val)52*a410a0cfSGuillaume Nault static inline bool inet_validate_dscp(__u8 val)
53*a410a0cfSGuillaume Nault {
54*a410a0cfSGuillaume Nault 	return !(val & ~INET_DSCP_MASK);
55*a410a0cfSGuillaume Nault }
56*a410a0cfSGuillaume Nault 
57*a410a0cfSGuillaume Nault #endif /* _INET_DSCP_H */
58