1 /* SPDX-License-Identifier: GPL-2.0 */
5 /* Definitions for the GUE header, standard and private flags, lengths
6 * of optional fields are below.
8 * Diagram of GUE header:
10 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
11 * |Ver|C| Hlen | Proto/ctype | Standard flags |P|
12 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
14 * ~ Fields (optional) ~
16 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
17 * | Private flags (optional, P bit is set) |
18 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
20 * ~ Private fields (optional) ~
22 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24 * C bit indicates contol message when set, data message when unset.
25 * For a control message, proto/ctype is interpreted as a type of
26 * control message. For data messages, proto/ctype is the IP protocol
29 * P bit indicates private flags field is present. The private flags
30 * may refer to options placed after this field.
36 #if defined(__LITTLE_ENDIAN_BITFIELD)
40 #elif defined (__BIG_ENDIAN_BITFIELD)
45 #error "Please fix <asm/byteorder.h>"
54 /* Standard flags in GUE header */
56 #define GUE_FLAG_PRIV htons(1<<0) /* Private flags are in options */
57 #define GUE_LEN_PRIV 4
59 #define GUE_FLAGS_ALL (GUE_FLAG_PRIV)
61 /* Private flags in the private option extension */
63 #define GUE_PFLAG_REMCSUM htonl(1 << 31)
64 #define GUE_PLEN_REMCSUM 4
66 #define GUE_PFLAGS_ALL (GUE_PFLAG_REMCSUM)
68 /* Functions to compute options length corresponding to flags.
69 * If we ever have a lot of flags this can be potentially be
70 * converted to a more optimized algorithm (table lookup
73 static inline size_t guehdr_flags_len(__be16 flags
)
75 return ((flags
& GUE_FLAG_PRIV
) ? GUE_LEN_PRIV
: 0);
78 static inline size_t guehdr_priv_flags_len(__be32 flags
)
83 /* Validate standard and private flags. Returns non-zero (meaning invalid)
84 * if there is an unknown standard or private flags, or the options length for
85 * the flags exceeds the options length specific in hlen of the GUE header.
87 static inline int validate_gue_flags(struct guehdr
*guehdr
, size_t optlen
)
89 __be16 flags
= guehdr
->flags
;
92 if (flags
& ~GUE_FLAGS_ALL
)
95 len
= guehdr_flags_len(flags
);
99 if (flags
& GUE_FLAG_PRIV
) {
100 /* Private flags are last four bytes accounted in
103 __be32 pflags
= *(__be32
*)((void *)&guehdr
[1] +
106 if (pflags
& ~GUE_PFLAGS_ALL
)
109 len
+= guehdr_priv_flags_len(pflags
);