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