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