forked from mirrors/linux
		
	Fix a typo in gue.h Signed-off-by: Aiden Leong <aiden.leong@aibsd.com> Signed-off-by: David S. Miller <davem@davemloft.net>
		
			
				
	
	
		
			117 lines
		
	
	
	
		
			3.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			117 lines
		
	
	
	
		
			3.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* 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.
 | 
						|
 */
 | 
						|
 | 
						|
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
 |