| 
									
										
										
										
											2014-10-03 15:48:09 -07:00
										 |  |  | #ifndef __NET_GUE_H
 | 
					
						
							|  |  |  | #define __NET_GUE_H
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-04 09:06:53 -08:00
										 |  |  | /* Definitions for the GUE header, standard and private flags, lengths
 | 
					
						
							|  |  |  |  * of optional fields are below. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Diagram of GUE header: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 
					
						
							|  |  |  |  * |Ver|C|  Hlen   | Proto/ctype   |        Standard flags       |P| | 
					
						
							|  |  |  |  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 
					
						
							|  |  |  |  * |                                                               | | 
					
						
							|  |  |  |  * ~                      Fields (optional)                        ~ | 
					
						
							|  |  |  |  * |                                                               | | 
					
						
							|  |  |  |  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 
					
						
							|  |  |  |  * |            Private flags (optional, P bit is set)             | | 
					
						
							|  |  |  |  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 
					
						
							|  |  |  |  * |                                                               | | 
					
						
							|  |  |  |  * ~                   Private fields (optional)                   ~ | 
					
						
							|  |  |  |  * |                                                               | | 
					
						
							|  |  |  |  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * C bit indicates contol message when set, data message when unset. | 
					
						
							|  |  |  |  * For a control message, proto/ctype is interpreted as a type of | 
					
						
							|  |  |  |  * control message. For data messages, proto/ctype is the IP protocol | 
					
						
							|  |  |  |  * of the next header. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * P bit indicates private flags field is present. The private flags | 
					
						
							|  |  |  |  * may refer to options placed after this field. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-03 15:48:09 -07:00
										 |  |  | struct guehdr { | 
					
						
							|  |  |  | 	union { | 
					
						
							|  |  |  | 		struct { | 
					
						
							|  |  |  | #if defined(__LITTLE_ENDIAN_BITFIELD)
 | 
					
						
							| 
									
										
										
										
											2014-11-04 09:06:53 -08:00
										 |  |  | 			__u8	hlen:5, | 
					
						
							|  |  |  | 				control:1, | 
					
						
							|  |  |  | 				version:2; | 
					
						
							| 
									
										
										
										
											2014-10-03 15:48:09 -07:00
										 |  |  | #elif defined (__BIG_ENDIAN_BITFIELD)
 | 
					
						
							| 
									
										
										
										
											2014-11-04 09:06:53 -08:00
										 |  |  | 			__u8	version:2, | 
					
						
							|  |  |  | 				control:1, | 
					
						
							|  |  |  | 				hlen:5; | 
					
						
							| 
									
										
										
										
											2014-10-03 15:48:09 -07:00
										 |  |  | #else
 | 
					
						
							|  |  |  | #error  "Please fix <asm/byteorder.h>"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2014-11-04 09:06:53 -08:00
										 |  |  | 			__u8    proto_ctype; | 
					
						
							| 
									
										
										
										
											2014-10-03 15:48:09 -07:00
										 |  |  | 			__u16   flags; | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 		__u32 word; | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-04 09:06:53 -08:00
										 |  |  | /* Standard flags in GUE header */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define GUE_FLAG_PRIV	htons(1<<0)	/* Private flags are in options */
 | 
					
						
							|  |  |  | #define GUE_LEN_PRIV	4
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define GUE_FLAGS_ALL	(GUE_FLAG_PRIV)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Private flags in the private option extension */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-04 09:06:55 -08:00
										 |  |  | #define GUE_PFLAG_REMCSUM	htonl(1 << 31)
 | 
					
						
							|  |  |  | #define GUE_PLEN_REMCSUM	4
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define GUE_PFLAGS_ALL	(GUE_PFLAG_REMCSUM)
 | 
					
						
							| 
									
										
										
										
											2014-11-04 09:06:53 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* Functions to compute options length corresponding to flags.
 | 
					
						
							|  |  |  |  * If we ever have a lot of flags this can be potentially be | 
					
						
							|  |  |  |  * converted to a more optimized algorithm (table lookup | 
					
						
							|  |  |  |  * for instance). | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static inline size_t guehdr_flags_len(__be16 flags) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return ((flags & GUE_FLAG_PRIV) ? GUE_LEN_PRIV : 0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline size_t guehdr_priv_flags_len(__be32 flags) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Validate standard and private flags. Returns non-zero (meaning invalid)
 | 
					
						
							|  |  |  |  * if there is an unknown standard or private flags, or the options length for | 
					
						
							|  |  |  |  * the flags exceeds the options length specific in hlen of the GUE header. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static inline int validate_gue_flags(struct guehdr *guehdr, | 
					
						
							|  |  |  | 				     size_t optlen) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	size_t len; | 
					
						
							|  |  |  | 	__be32 flags = guehdr->flags; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (flags & ~GUE_FLAGS_ALL) | 
					
						
							|  |  |  | 		return 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	len = guehdr_flags_len(flags); | 
					
						
							|  |  |  | 	if (len > optlen) | 
					
						
							|  |  |  | 		return 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (flags & GUE_FLAG_PRIV) { | 
					
						
							|  |  |  | 		/* Private flags are last four bytes accounted in
 | 
					
						
							|  |  |  | 		 * guehdr_flags_len | 
					
						
							|  |  |  | 		 */ | 
					
						
							|  |  |  | 		flags = *(__be32 *)((void *)&guehdr[1] + len - GUE_LEN_PRIV); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (flags & ~GUE_PFLAGS_ALL) | 
					
						
							|  |  |  | 			return 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		len += guehdr_priv_flags_len(flags); | 
					
						
							|  |  |  | 		if (len > optlen) | 
					
						
							|  |  |  | 			return 1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-03 15:48:09 -07:00
										 |  |  | #endif
 |