gre.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. /*
  2. * GRE over IPv4 demultiplexer driver
  3. *
  4. * Authors: Dmitry Kozlov (xeb@mail.ru)
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version
  9. * 2 of the License, or (at your option) any later version.
  10. *
  11. */
  12. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  13. #include <linux/module.h>
  14. #include <linux/kernel.h>
  15. #include <linux/kmod.h>
  16. #include <linux/skbuff.h>
  17. #include <linux/in.h>
  18. #include <linux/ip.h>
  19. #include <linux/netdevice.h>
  20. #include <linux/if_tunnel.h>
  21. #include <linux/spinlock.h>
  22. #include <net/protocol.h>
  23. #include <net/gre.h>
  24. static const struct gre_protocol __rcu *gre_proto[GREPROTO_MAX] __read_mostly;
  25. static DEFINE_SPINLOCK(gre_proto_lock);
  26. int gre_add_protocol(const struct gre_protocol *proto, u8 version)
  27. {
  28. if (version >= GREPROTO_MAX)
  29. goto err_out;
  30. spin_lock(&gre_proto_lock);
  31. if (gre_proto[version])
  32. goto err_out_unlock;
  33. RCU_INIT_POINTER(gre_proto[version], proto);
  34. spin_unlock(&gre_proto_lock);
  35. return 0;
  36. err_out_unlock:
  37. spin_unlock(&gre_proto_lock);
  38. err_out:
  39. return -1;
  40. }
  41. EXPORT_SYMBOL_GPL(gre_add_protocol);
  42. int gre_del_protocol(const struct gre_protocol *proto, u8 version)
  43. {
  44. if (version >= GREPROTO_MAX)
  45. goto err_out;
  46. spin_lock(&gre_proto_lock);
  47. if (rcu_dereference_protected(gre_proto[version],
  48. lockdep_is_held(&gre_proto_lock)) != proto)
  49. goto err_out_unlock;
  50. RCU_INIT_POINTER(gre_proto[version], NULL);
  51. spin_unlock(&gre_proto_lock);
  52. synchronize_rcu();
  53. return 0;
  54. err_out_unlock:
  55. spin_unlock(&gre_proto_lock);
  56. err_out:
  57. return -1;
  58. }
  59. EXPORT_SYMBOL_GPL(gre_del_protocol);
  60. static int gre_rcv(struct sk_buff *skb)
  61. {
  62. const struct gre_protocol *proto;
  63. u8 ver;
  64. int ret;
  65. if (!pskb_may_pull(skb, 12))
  66. goto drop;
  67. ver = skb->data[1]&0x7f;
  68. if (ver >= GREPROTO_MAX)
  69. goto drop;
  70. rcu_read_lock();
  71. proto = rcu_dereference(gre_proto[ver]);
  72. if (!proto || !proto->handler)
  73. goto drop_unlock;
  74. ret = proto->handler(skb);
  75. rcu_read_unlock();
  76. return ret;
  77. drop_unlock:
  78. rcu_read_unlock();
  79. drop:
  80. kfree_skb(skb);
  81. return NET_RX_DROP;
  82. }
  83. static void gre_err(struct sk_buff *skb, u32 info)
  84. {
  85. const struct gre_protocol *proto;
  86. const struct iphdr *iph = (const struct iphdr *)skb->data;
  87. u8 ver = skb->data[(iph->ihl<<2) + 1]&0x7f;
  88. if (ver >= GREPROTO_MAX)
  89. return;
  90. rcu_read_lock();
  91. proto = rcu_dereference(gre_proto[ver]);
  92. if (proto && proto->err_handler)
  93. proto->err_handler(skb, info);
  94. rcu_read_unlock();
  95. }
  96. static struct sk_buff *gre_gso_segment(struct sk_buff *skb,
  97. netdev_features_t features)
  98. {
  99. struct sk_buff *segs = ERR_PTR(-EINVAL);
  100. netdev_features_t enc_features;
  101. int ghl = GRE_HEADER_SECTION;
  102. struct gre_base_hdr *greh;
  103. int mac_len = skb->mac_len;
  104. __be16 protocol = skb->protocol;
  105. int tnl_hlen;
  106. bool csum;
  107. if (unlikely(skb_shinfo(skb)->gso_type &
  108. ~(SKB_GSO_TCPV4 |
  109. SKB_GSO_TCPV6 |
  110. SKB_GSO_UDP |
  111. SKB_GSO_DODGY |
  112. SKB_GSO_TCP_ECN |
  113. SKB_GSO_GRE)))
  114. goto out;
  115. if (unlikely(!pskb_may_pull(skb, sizeof(*greh))))
  116. goto out;
  117. greh = (struct gre_base_hdr *)skb_transport_header(skb);
  118. if (greh->flags & GRE_KEY)
  119. ghl += GRE_HEADER_SECTION;
  120. if (greh->flags & GRE_SEQ)
  121. ghl += GRE_HEADER_SECTION;
  122. if (greh->flags & GRE_CSUM) {
  123. ghl += GRE_HEADER_SECTION;
  124. csum = true;
  125. } else
  126. csum = false;
  127. /* setup inner skb. */
  128. skb->protocol = greh->protocol;
  129. skb->encapsulation = 0;
  130. if (unlikely(!pskb_may_pull(skb, ghl)))
  131. goto out;
  132. __skb_pull(skb, ghl);
  133. skb_reset_mac_header(skb);
  134. skb_set_network_header(skb, skb_inner_network_offset(skb));
  135. skb->mac_len = skb_inner_network_offset(skb);
  136. /* segment inner packet. */
  137. enc_features = skb->dev->hw_enc_features & netif_skb_features(skb);
  138. segs = skb_mac_gso_segment(skb, enc_features);
  139. if (!segs || IS_ERR(segs))
  140. goto out;
  141. skb = segs;
  142. tnl_hlen = skb_tnl_header_len(skb);
  143. do {
  144. __skb_push(skb, ghl);
  145. if (csum) {
  146. __be32 *pcsum;
  147. if (skb_has_shared_frag(skb)) {
  148. int err;
  149. err = __skb_linearize(skb);
  150. if (err) {
  151. kfree_skb(segs);
  152. segs = ERR_PTR(err);
  153. goto out;
  154. }
  155. }
  156. greh = (struct gre_base_hdr *)(skb->data);
  157. pcsum = (__be32 *)(greh + 1);
  158. *pcsum = 0;
  159. *(__sum16 *)pcsum = csum_fold(skb_checksum(skb, 0, skb->len, 0));
  160. }
  161. __skb_push(skb, tnl_hlen - ghl);
  162. skb_reset_mac_header(skb);
  163. skb_set_network_header(skb, mac_len);
  164. skb->mac_len = mac_len;
  165. skb->protocol = protocol;
  166. } while ((skb = skb->next));
  167. out:
  168. return segs;
  169. }
  170. static int gre_gso_send_check(struct sk_buff *skb)
  171. {
  172. if (!skb->encapsulation)
  173. return -EINVAL;
  174. return 0;
  175. }
  176. static const struct net_protocol net_gre_protocol = {
  177. .handler = gre_rcv,
  178. .err_handler = gre_err,
  179. .netns_ok = 1,
  180. };
  181. static const struct net_offload gre_offload = {
  182. .callbacks = {
  183. .gso_send_check = gre_gso_send_check,
  184. .gso_segment = gre_gso_segment,
  185. },
  186. };
  187. static int __init gre_init(void)
  188. {
  189. pr_info("GRE over IPv4 demultiplexor driver\n");
  190. if (inet_add_protocol(&net_gre_protocol, IPPROTO_GRE) < 0) {
  191. pr_err("can't add protocol\n");
  192. return -EAGAIN;
  193. }
  194. if (inet_add_offload(&gre_offload, IPPROTO_GRE)) {
  195. pr_err("can't add protocol offload\n");
  196. inet_del_protocol(&net_gre_protocol, IPPROTO_GRE);
  197. return -EAGAIN;
  198. }
  199. return 0;
  200. }
  201. static void __exit gre_exit(void)
  202. {
  203. inet_del_offload(&gre_offload, IPPROTO_GRE);
  204. inet_del_protocol(&net_gre_protocol, IPPROTO_GRE);
  205. }
  206. module_init(gre_init);
  207. module_exit(gre_exit);
  208. MODULE_DESCRIPTION("GRE over IPv4 demultiplexer driver");
  209. MODULE_AUTHOR("D. Kozlov (xeb@mail.ru)");
  210. MODULE_LICENSE("GPL");