gue.h 3.2 KB

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