cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

gue.h (3313B)


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