gre.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  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. bool is_gretap_dev(const struct net_device *dev);
  33. bool is_ip6gretap_dev(const struct net_device *dev);
  34. static inline int gre_calc_hlen(__be16 o_flags)
  35. {
  36. int addend = 4;
  37. if (o_flags & TUNNEL_CSUM)
  38. addend += 4;
  39. if (o_flags & TUNNEL_KEY)
  40. addend += 4;
  41. if (o_flags & TUNNEL_SEQ)
  42. addend += 4;
  43. return addend;
  44. }
  45. static inline __be16 gre_flags_to_tnl_flags(__be16 flags)
  46. {
  47. __be16 tflags = 0;
  48. if (flags & GRE_CSUM)
  49. tflags |= TUNNEL_CSUM;
  50. if (flags & GRE_ROUTING)
  51. tflags |= TUNNEL_ROUTING;
  52. if (flags & GRE_KEY)
  53. tflags |= TUNNEL_KEY;
  54. if (flags & GRE_SEQ)
  55. tflags |= TUNNEL_SEQ;
  56. if (flags & GRE_STRICT)
  57. tflags |= TUNNEL_STRICT;
  58. if (flags & GRE_REC)
  59. tflags |= TUNNEL_REC;
  60. if (flags & GRE_VERSION)
  61. tflags |= TUNNEL_VERSION;
  62. return tflags;
  63. }
  64. static inline __be16 gre_tnl_flags_to_gre_flags(__be16 tflags)
  65. {
  66. __be16 flags = 0;
  67. if (tflags & TUNNEL_CSUM)
  68. flags |= GRE_CSUM;
  69. if (tflags & TUNNEL_ROUTING)
  70. flags |= GRE_ROUTING;
  71. if (tflags & TUNNEL_KEY)
  72. flags |= GRE_KEY;
  73. if (tflags & TUNNEL_SEQ)
  74. flags |= GRE_SEQ;
  75. if (tflags & TUNNEL_STRICT)
  76. flags |= GRE_STRICT;
  77. if (tflags & TUNNEL_REC)
  78. flags |= GRE_REC;
  79. if (tflags & TUNNEL_VERSION)
  80. flags |= GRE_VERSION;
  81. return flags;
  82. }
  83. static inline __sum16 gre_checksum(struct sk_buff *skb)
  84. {
  85. __wsum csum;
  86. if (skb->ip_summed == CHECKSUM_PARTIAL)
  87. csum = lco_csum(skb);
  88. else
  89. csum = skb_checksum(skb, 0, skb->len, 0);
  90. return csum_fold(csum);
  91. }
  92. static inline void gre_build_header(struct sk_buff *skb, int hdr_len,
  93. __be16 flags, __be16 proto,
  94. __be32 key, __be32 seq)
  95. {
  96. struct gre_base_hdr *greh;
  97. skb_push(skb, hdr_len);
  98. skb_set_inner_protocol(skb, proto);
  99. skb_reset_transport_header(skb);
  100. greh = (struct gre_base_hdr *)skb->data;
  101. greh->flags = gre_tnl_flags_to_gre_flags(flags);
  102. greh->protocol = proto;
  103. if (flags & (TUNNEL_KEY | TUNNEL_CSUM | TUNNEL_SEQ)) {
  104. __be32 *ptr = (__be32 *)(((u8 *)greh) + hdr_len - 4);
  105. if (flags & TUNNEL_SEQ) {
  106. *ptr = seq;
  107. ptr--;
  108. }
  109. if (flags & TUNNEL_KEY) {
  110. *ptr = key;
  111. ptr--;
  112. }
  113. if (flags & TUNNEL_CSUM &&
  114. !(skb_shinfo(skb)->gso_type &
  115. (SKB_GSO_GRE | SKB_GSO_GRE_CSUM))) {
  116. *ptr = 0;
  117. *(__sum16 *)ptr = gre_checksum(skb);
  118. }
  119. }
  120. }
  121. #endif