gre.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  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 bool netif_is_gretap(const struct net_device *dev)
  33. {
  34. return dev->rtnl_link_ops &&
  35. !strcmp(dev->rtnl_link_ops->kind, "gretap");
  36. }
  37. static inline bool netif_is_ip6gretap(const struct net_device *dev)
  38. {
  39. return dev->rtnl_link_ops &&
  40. !strcmp(dev->rtnl_link_ops->kind, "ip6gretap");
  41. }
  42. static inline int gre_calc_hlen(const unsigned long *o_flags)
  43. {
  44. int addend = 4;
  45. if (test_bit(IP_TUNNEL_CSUM_BIT, o_flags))
  46. addend += 4;
  47. if (test_bit(IP_TUNNEL_KEY_BIT, o_flags))
  48. addend += 4;
  49. if (test_bit(IP_TUNNEL_SEQ_BIT, o_flags))
  50. addend += 4;
  51. return addend;
  52. }
  53. static inline void gre_flags_to_tnl_flags(unsigned long *dst, __be16 flags)
  54. {
  55. IP_TUNNEL_DECLARE_FLAGS(res) = { };
  56. __assign_bit(IP_TUNNEL_CSUM_BIT, res, flags & GRE_CSUM);
  57. __assign_bit(IP_TUNNEL_ROUTING_BIT, res, flags & GRE_ROUTING);
  58. __assign_bit(IP_TUNNEL_KEY_BIT, res, flags & GRE_KEY);
  59. __assign_bit(IP_TUNNEL_SEQ_BIT, res, flags & GRE_SEQ);
  60. __assign_bit(IP_TUNNEL_STRICT_BIT, res, flags & GRE_STRICT);
  61. __assign_bit(IP_TUNNEL_REC_BIT, res, flags & GRE_REC);
  62. __assign_bit(IP_TUNNEL_VERSION_BIT, res, flags & GRE_VERSION);
  63. ip_tunnel_flags_copy(dst, res);
  64. }
  65. static inline __be16 gre_tnl_flags_to_gre_flags(const unsigned long *tflags)
  66. {
  67. __be16 flags = 0;
  68. if (test_bit(IP_TUNNEL_CSUM_BIT, tflags))
  69. flags |= GRE_CSUM;
  70. if (test_bit(IP_TUNNEL_ROUTING_BIT, tflags))
  71. flags |= GRE_ROUTING;
  72. if (test_bit(IP_TUNNEL_KEY_BIT, tflags))
  73. flags |= GRE_KEY;
  74. if (test_bit(IP_TUNNEL_SEQ_BIT, tflags))
  75. flags |= GRE_SEQ;
  76. if (test_bit(IP_TUNNEL_STRICT_BIT, tflags))
  77. flags |= GRE_STRICT;
  78. if (test_bit(IP_TUNNEL_REC_BIT, tflags))
  79. flags |= GRE_REC;
  80. if (test_bit(IP_TUNNEL_VERSION_BIT, tflags))
  81. flags |= GRE_VERSION;
  82. return flags;
  83. }
  84. static inline void gre_build_header(struct sk_buff *skb, int hdr_len,
  85. const unsigned long *flags, __be16 proto,
  86. __be32 key, __be32 seq)
  87. {
  88. IP_TUNNEL_DECLARE_FLAGS(cond) = { };
  89. struct gre_base_hdr *greh;
  90. skb_push(skb, hdr_len);
  91. skb_set_inner_protocol(skb, proto);
  92. skb_reset_transport_header(skb);
  93. greh = (struct gre_base_hdr *)skb->data;
  94. greh->flags = gre_tnl_flags_to_gre_flags(flags);
  95. greh->protocol = proto;
  96. __set_bit(IP_TUNNEL_KEY_BIT, cond);
  97. __set_bit(IP_TUNNEL_CSUM_BIT, cond);
  98. __set_bit(IP_TUNNEL_SEQ_BIT, cond);
  99. if (ip_tunnel_flags_intersect(flags, cond)) {
  100. __be32 *ptr = (__be32 *)(((u8 *)greh) + hdr_len - 4);
  101. if (test_bit(IP_TUNNEL_SEQ_BIT, flags)) {
  102. *ptr = seq;
  103. ptr--;
  104. }
  105. if (test_bit(IP_TUNNEL_KEY_BIT, flags)) {
  106. *ptr = key;
  107. ptr--;
  108. }
  109. if (test_bit(IP_TUNNEL_CSUM_BIT, flags) &&
  110. !(skb_shinfo(skb)->gso_type &
  111. (SKB_GSO_GRE | SKB_GSO_GRE_CSUM))) {
  112. *ptr = 0;
  113. if (skb->ip_summed == CHECKSUM_PARTIAL) {
  114. *(__sum16 *)ptr = csum_fold(lco_csum(skb));
  115. } else {
  116. skb->ip_summed = CHECKSUM_PARTIAL;
  117. skb->csum_start = skb_transport_header(skb) - skb->head;
  118. skb->csum_offset = sizeof(*greh);
  119. }
  120. }
  121. }
  122. }
  123. #endif