gre.h 2.8 KB

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