gre.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #ifndef __LINUX_GRE_H
  3. #define __LINUX_GRE_H
  4. #include <linux/skbuff.h>
  5. #include <net/ip_tunnels.h>
  6. struct gre_base_hdr {
  7. __be16 flags;
  8. __be16 protocol;
  9. } __packed;
  10. struct gre_full_hdr {
  11. struct gre_base_hdr fixed_header;
  12. __be16 csum;
  13. __be16 reserved1;
  14. __be32 key;
  15. __be32 seq;
  16. } __packed;
  17. #define GRE_HEADER_SECTION 4
  18. #define GREPROTO_CISCO 0
  19. #define GREPROTO_PPTP 1
  20. #define GREPROTO_MAX 2
  21. #define GRE_IP_PROTO_MAX 2
  22. struct gre_protocol {
  23. int (*handler)(struct sk_buff *skb);
  24. void (*err_handler)(struct sk_buff *skb, u32 info);
  25. };
  26. int gre_add_protocol(const struct gre_protocol *proto, u8 version);
  27. int gre_del_protocol(const struct gre_protocol *proto, u8 version);
  28. struct net_device *gretap_fb_dev_create(struct net *net, const char *name,
  29. u8 name_assign_type);
  30. int gre_parse_header(struct sk_buff *skb, struct tnl_ptk_info *tpi,
  31. bool *csum_err, __be16 proto, int nhs);
  32. static inline int gre_calc_hlen(__be16 o_flags)
  33. {
  34. int addend = 4;
  35. if (o_flags & TUNNEL_CSUM)
  36. addend += 4;
  37. if (o_flags & TUNNEL_KEY)
  38. addend += 4;
  39. if (o_flags & TUNNEL_SEQ)
  40. addend += 4;
  41. return addend;
  42. }
  43. static inline __be16 gre_flags_to_tnl_flags(__be16 flags)
  44. {
  45. __be16 tflags = 0;
  46. if (flags & GRE_CSUM)
  47. tflags |= TUNNEL_CSUM;
  48. if (flags & GRE_ROUTING)
  49. tflags |= TUNNEL_ROUTING;
  50. if (flags & GRE_KEY)
  51. tflags |= TUNNEL_KEY;
  52. if (flags & GRE_SEQ)
  53. tflags |= TUNNEL_SEQ;
  54. if (flags & GRE_STRICT)
  55. tflags |= TUNNEL_STRICT;
  56. if (flags & GRE_REC)
  57. tflags |= TUNNEL_REC;
  58. if (flags & GRE_VERSION)
  59. tflags |= TUNNEL_VERSION;
  60. return tflags;
  61. }
  62. static inline __be16 gre_tnl_flags_to_gre_flags(__be16 tflags)
  63. {
  64. __be16 flags = 0;
  65. if (tflags & TUNNEL_CSUM)
  66. flags |= GRE_CSUM;
  67. if (tflags & TUNNEL_ROUTING)
  68. flags |= GRE_ROUTING;
  69. if (tflags & TUNNEL_KEY)
  70. flags |= GRE_KEY;
  71. if (tflags & TUNNEL_SEQ)
  72. flags |= GRE_SEQ;
  73. if (tflags & TUNNEL_STRICT)
  74. flags |= GRE_STRICT;
  75. if (tflags & TUNNEL_REC)
  76. flags |= GRE_REC;
  77. if (tflags & TUNNEL_VERSION)
  78. flags |= GRE_VERSION;
  79. return flags;
  80. }
  81. static inline __sum16 gre_checksum(struct sk_buff *skb)
  82. {
  83. __wsum csum;
  84. if (skb->ip_summed == CHECKSUM_PARTIAL)
  85. csum = lco_csum(skb);
  86. else
  87. csum = skb_checksum(skb, 0, skb->len, 0);
  88. return csum_fold(csum);
  89. }
  90. static inline void gre_build_header(struct sk_buff *skb, int hdr_len,
  91. __be16 flags, __be16 proto,
  92. __be32 key, __be32 seq)
  93. {
  94. struct gre_base_hdr *greh;
  95. skb_push(skb, hdr_len);
  96. skb_set_inner_protocol(skb, proto);
  97. skb_reset_transport_header(skb);
  98. greh = (struct gre_base_hdr *)skb->data;
  99. greh->flags = gre_tnl_flags_to_gre_flags(flags);
  100. greh->protocol = proto;
  101. if (flags & (TUNNEL_KEY | TUNNEL_CSUM | TUNNEL_SEQ)) {
  102. __be32 *ptr = (__be32 *)(((u8 *)greh) + hdr_len - 4);
  103. if (flags & TUNNEL_SEQ) {
  104. *ptr = seq;
  105. ptr--;
  106. }
  107. if (flags & TUNNEL_KEY) {
  108. *ptr = key;
  109. ptr--;
  110. }
  111. if (flags & TUNNEL_CSUM &&
  112. !(skb_shinfo(skb)->gso_type &
  113. (SKB_GSO_GRE | SKB_GSO_GRE_CSUM))) {
  114. *ptr = 0;
  115. *(__sum16 *)ptr = gre_checksum(skb);
  116. }
  117. }
  118. }
  119. #endif