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 */
38typedef u8 __bitwise dscp_t;
39
40#define INET_DSCP_MASK 0xfc
41
42/* A few places in the IPv4 code need to ignore the three high order bits of
43 * DSCP because of backward compatibility (as these bits used to represent the
44 * IPv4 Precedence in RFC 791's TOS field and were ignored).
45 */
46#define INET_DSCP_LEGACY_TOS_MASK ((__force dscp_t)0x1c)
47
48static inline dscp_t inet_dsfield_to_dscp(__u8 dsfield)
49{
50 return (__force dscp_t)(dsfield & INET_DSCP_MASK);
51}
52
53static inline __u8 inet_dscp_to_dsfield(dscp_t dscp)
54{
55 return (__force __u8)dscp;
56}
57
58static inline bool inet_validate_dscp(__u8 val)
59{
60 return !(val & ~INET_DSCP_MASK);
61}
62
63#endif /* _INET_DSCP_H */
64