gue.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  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 control 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. #include <asm/byteorder.h>
  32. #include <linux/types.h>
  33. struct 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. /* Standard flags in GUE header */
  54. #define GUE_FLAG_PRIV htons(1<<0) /* Private flags are in options */
  55. #define GUE_LEN_PRIV 4
  56. #define GUE_FLAGS_ALL (GUE_FLAG_PRIV)
  57. /* Private flags in the private option extension */
  58. #define GUE_PFLAG_REMCSUM htonl(1U << 31)
  59. #define GUE_PLEN_REMCSUM 4
  60. #define GUE_PFLAGS_ALL (GUE_PFLAG_REMCSUM)
  61. /* Functions to compute options length corresponding to flags.
  62. * If we ever have a lot of flags this can be potentially be
  63. * converted to a more optimized algorithm (table lookup
  64. * for instance).
  65. */
  66. static inline size_t guehdr_flags_len(__be16 flags)
  67. {
  68. return ((flags & GUE_FLAG_PRIV) ? GUE_LEN_PRIV : 0);
  69. }
  70. static inline size_t guehdr_priv_flags_len(__be32 flags)
  71. {
  72. return 0;
  73. }
  74. /* Validate standard and private flags. Returns non-zero (meaning invalid)
  75. * if there is an unknown standard or private flags, or the options length for
  76. * the flags exceeds the options length specific in hlen of the GUE header.
  77. */
  78. static inline int validate_gue_flags(struct guehdr *guehdr, size_t optlen)
  79. {
  80. __be16 flags = guehdr->flags;
  81. size_t len;
  82. if (flags & ~GUE_FLAGS_ALL)
  83. return 1;
  84. len = guehdr_flags_len(flags);
  85. if (len > optlen)
  86. return 1;
  87. if (flags & GUE_FLAG_PRIV) {
  88. /* Private flags are last four bytes accounted in
  89. * guehdr_flags_len
  90. */
  91. __be32 pflags = *(__be32 *)((void *)&guehdr[1] +
  92. len - GUE_LEN_PRIV);
  93. if (pflags & ~GUE_PFLAGS_ALL)
  94. return 1;
  95. len += guehdr_priv_flags_len(pflags);
  96. if (len > optlen)
  97. return 1;
  98. }
  99. return 0;
  100. }
  101. #endif