gue.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #ifndef __NET_GUE_H
  3. #define __NET_GUE_H
  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. struct guehdr {
  32. union {
  33. struct {
  34. #if defined(__LITTLE_ENDIAN_BITFIELD)
  35. __u8 hlen:5,
  36. control:1,
  37. version:2;
  38. #elif defined (__BIG_ENDIAN_BITFIELD)
  39. __u8 version:2,
  40. control:1,
  41. hlen:5;
  42. #else
  43. #error "Please fix <asm/byteorder.h>"
  44. #endif
  45. __u8 proto_ctype;
  46. __u16 flags;
  47. };
  48. __u32 word;
  49. };
  50. };
  51. /* Standard flags in GUE header */
  52. #define GUE_FLAG_PRIV htons(1<<0) /* Private flags are in options */
  53. #define GUE_LEN_PRIV 4
  54. #define GUE_FLAGS_ALL (GUE_FLAG_PRIV)
  55. /* Private flags in the private option extension */
  56. #define GUE_PFLAG_REMCSUM htonl(1 << 31)
  57. #define GUE_PLEN_REMCSUM 4
  58. #define GUE_PFLAGS_ALL (GUE_PFLAG_REMCSUM)
  59. /* Functions to compute options length corresponding to flags.
  60. * If we ever have a lot of flags this can be potentially be
  61. * converted to a more optimized algorithm (table lookup
  62. * for instance).
  63. */
  64. static inline size_t guehdr_flags_len(__be16 flags)
  65. {
  66. return ((flags & GUE_FLAG_PRIV) ? GUE_LEN_PRIV : 0);
  67. }
  68. static inline size_t guehdr_priv_flags_len(__be32 flags)
  69. {
  70. return 0;
  71. }
  72. /* Validate standard and private flags. Returns non-zero (meaning invalid)
  73. * if there is an unknown standard or private flags, or the options length for
  74. * the flags exceeds the options length specific in hlen of the GUE header.
  75. */
  76. static inline int validate_gue_flags(struct guehdr *guehdr,
  77. size_t optlen)
  78. {
  79. size_t len;
  80. __be32 flags = guehdr->flags;
  81. if (flags & ~GUE_FLAGS_ALL)
  82. return 1;
  83. len = guehdr_flags_len(flags);
  84. if (len > optlen)
  85. return 1;
  86. if (flags & GUE_FLAG_PRIV) {
  87. /* Private flags are last four bytes accounted in
  88. * guehdr_flags_len
  89. */
  90. flags = *(__be32 *)((void *)&guehdr[1] + len - GUE_LEN_PRIV);
  91. if (flags & ~GUE_PFLAGS_ALL)
  92. return 1;
  93. len += guehdr_priv_flags_len(flags);
  94. if (len > optlen)
  95. return 1;
  96. }
  97. return 0;
  98. }
  99. #endif