120 lines · 3.3 KB · C
RawDownload
/* SPDX-License-Identifier: GPL-2.0 */#ifndef __NET_GUE_H#define __NET_GUE_H /* 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 control 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. */ #include <asm/byteorder.h>#include <linux/types.h> struct guehdr {	union {		struct {#if defined(__LITTLE_ENDIAN_BITFIELD)			__u8	hlen:5,				control:1,				version:2;#elif defined (__BIG_ENDIAN_BITFIELD)			__u8	version:2,				control:1,				hlen:5;#else#error  "Please fix <asm/byteorder.h>"#endif			__u8	proto_ctype;			__be16	flags;		};		__be32	word;	};}; /* 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 */ #define GUE_PFLAG_REMCSUM	htonl(1U << 31)#define GUE_PLEN_REMCSUM	4 #define GUE_PFLAGS_ALL	(GUE_PFLAG_REMCSUM) /* 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){	__be16 flags = guehdr->flags;	size_t len; 	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		 */		__be32 pflags = *(__be32 *)((void *)&guehdr[1] +					    len - GUE_LEN_PRIV); 		if (pflags & ~GUE_PFLAGS_ALL)			return 1; 		len += guehdr_priv_flags_len(pflags);		if (len > optlen)			return 1;	} 	return 0;} #endif