gre.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  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. int tnl_hlen;
  105. bool csum;
  106. if (unlikely(skb_shinfo(skb)->gso_type &
  107. ~(SKB_GSO_TCPV4 |
  108. SKB_GSO_TCPV6 |
  109. SKB_GSO_UDP |
  110. SKB_GSO_DODGY |
  111. SKB_GSO_TCP_ECN |
  112. SKB_GSO_GRE)))
  113. goto out;
  114. if (unlikely(!pskb_may_pull(skb, sizeof(*greh))))
  115. goto out;
  116. greh = (struct gre_base_hdr *)skb_transport_header(skb);
  117. if (greh->flags & GRE_KEY)
  118. ghl += GRE_HEADER_SECTION;
  119. if (greh->flags & GRE_SEQ)
  120. ghl += GRE_HEADER_SECTION;
  121. if (greh->flags & GRE_CSUM) {
  122. ghl += GRE_HEADER_SECTION;
  123. csum = true;
  124. } else
  125. csum = false;
  126. /* setup inner skb. */
  127. if (greh->protocol == htons(ETH_P_TEB)) {
  128. struct ethhdr *eth = eth_hdr(skb);
  129. skb->protocol = eth->h_proto;
  130. } else {
  131. skb->protocol = greh->protocol;
  132. }
  133. skb->encapsulation = 0;
  134. if (unlikely(!pskb_may_pull(skb, ghl)))
  135. goto out;
  136. __skb_pull(skb, ghl);
  137. skb_reset_mac_header(skb);
  138. skb_set_network_header(skb, skb_inner_network_offset(skb));
  139. skb->mac_len = skb_inner_network_offset(skb);
  140. /* segment inner packet. */
  141. enc_features = skb->dev->hw_enc_features & netif_skb_features(skb);
  142. segs = skb_mac_gso_segment(skb, enc_features);
  143. if (!segs || IS_ERR(segs))
  144. goto out;
  145. skb = segs;
  146. tnl_hlen = skb_tnl_header_len(skb);
  147. do {
  148. __skb_push(skb, ghl);
  149. if (csum) {
  150. __be32 *pcsum;
  151. if (skb_has_shared_frag(skb)) {
  152. int err;
  153. err = __skb_linearize(skb);
  154. if (err) {
  155. kfree_skb(segs);
  156. segs = ERR_PTR(err);
  157. goto out;
  158. }
  159. }
  160. greh = (struct gre_base_hdr *)(skb->data);
  161. pcsum = (__be32 *)(greh + 1);
  162. *pcsum = 0;
  163. *(__sum16 *)pcsum = csum_fold(skb_checksum(skb, 0, skb->len, 0));
  164. }
  165. __skb_push(skb, tnl_hlen - ghl);
  166. skb_reset_mac_header(skb);
  167. skb_set_network_header(skb, mac_len);
  168. skb->mac_len = mac_len;
  169. } while ((skb = skb->next));
  170. out:
  171. return segs;
  172. }
  173. static int gre_gso_send_check(struct sk_buff *skb)
  174. {
  175. if (!skb->encapsulation)
  176. return -EINVAL;
  177. return 0;
  178. }
  179. static const struct net_protocol net_gre_protocol = {
  180. .handler = gre_rcv,
  181. .err_handler = gre_err,
  182. .netns_ok = 1,
  183. };
  184. static const struct net_offload gre_offload = {
  185. .callbacks = {
  186. .gso_send_check = gre_gso_send_check,
  187. .gso_segment = gre_gso_segment,
  188. },
  189. };
  190. static int __init gre_init(void)
  191. {
  192. pr_info("GRE over IPv4 demultiplexor driver\n");
  193. if (inet_add_protocol(&net_gre_protocol, IPPROTO_GRE) < 0) {
  194. pr_err("can't add protocol\n");
  195. return -EAGAIN;
  196. }
  197. if (inet_add_offload(&gre_offload, IPPROTO_GRE)) {
  198. pr_err("can't add protocol offload\n");
  199. inet_del_protocol(&net_gre_protocol, IPPROTO_GRE);
  200. return -EAGAIN;
  201. }
  202. return 0;
  203. }
  204. static void __exit gre_exit(void)
  205. {
  206. inet_del_offload(&gre_offload, IPPROTO_GRE);
  207. inet_del_protocol(&net_gre_protocol, IPPROTO_GRE);
  208. }
  209. module_init(gre_init);
  210. module_exit(gre_exit);
  211. MODULE_DESCRIPTION("GRE over IPv4 demultiplexer driver");
  212. MODULE_AUTHOR("D. Kozlov (xeb@mail.ru)");
  213. MODULE_LICENSE("GPL");