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