^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #ifndef __NET_GUE_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #define __NET_GUE_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) /* Definitions for the GUE header, standard and private flags, lengths
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * of optional fields are below.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Diagram of GUE header:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * |Ver|C| Hlen | Proto/ctype | Standard flags |P|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * ~ Fields (optional) ~
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * | Private flags (optional, P bit is set) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * ~ Private fields (optional) ~
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * C bit indicates control message when set, data message when unset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * For a control message, proto/ctype is interpreted as a type of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * control message. For data messages, proto/ctype is the IP protocol
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * of the next header.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * P bit indicates private flags field is present. The private flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * may refer to options placed after this field.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) struct guehdr {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #if defined(__LITTLE_ENDIAN_BITFIELD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) __u8 hlen:5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) control:1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) version:2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #elif defined (__BIG_ENDIAN_BITFIELD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) __u8 version:2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) control:1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) hlen:5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #error "Please fix <asm/byteorder.h>"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) __u8 proto_ctype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) __be16 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) __be32 word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) /* Standard flags in GUE header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define GUE_FLAG_PRIV htons(1<<0) /* Private flags are in options */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define GUE_LEN_PRIV 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define GUE_FLAGS_ALL (GUE_FLAG_PRIV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) /* Private flags in the private option extension */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define GUE_PFLAG_REMCSUM htonl(1U << 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define GUE_PLEN_REMCSUM 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define GUE_PFLAGS_ALL (GUE_PFLAG_REMCSUM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) /* Functions to compute options length corresponding to flags.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * If we ever have a lot of flags this can be potentially be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * converted to a more optimized algorithm (table lookup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * for instance).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) static inline size_t guehdr_flags_len(__be16 flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) return ((flags & GUE_FLAG_PRIV) ? GUE_LEN_PRIV : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) static inline size_t guehdr_priv_flags_len(__be32 flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) /* Validate standard and private flags. Returns non-zero (meaning invalid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * if there is an unknown standard or private flags, or the options length for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * the flags exceeds the options length specific in hlen of the GUE header.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) static inline int validate_gue_flags(struct guehdr *guehdr, size_t optlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) __be16 flags = guehdr->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if (flags & ~GUE_FLAGS_ALL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) len = guehdr_flags_len(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) if (len > optlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) if (flags & GUE_FLAG_PRIV) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) /* Private flags are last four bytes accounted in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * guehdr_flags_len
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) __be32 pflags = *(__be32 *)((void *)&guehdr[1] +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) len - GUE_LEN_PRIV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) if (pflags & ~GUE_PFLAGS_ALL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) len += guehdr_priv_flags_len(pflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) if (len > optlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #endif