gre.h 3.0 KB

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