xfrm4_mode_tunnel.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /*
  2. * xfrm4_mode_tunnel.c - Tunnel mode encapsulation for IPv4.
  3. *
  4. * Copyright (c) 2004-2006 Herbert Xu <herbert@gondor.apana.org.au>
  5. */
  6. #include <linux/gfp.h>
  7. #include <linux/init.h>
  8. #include <linux/kernel.h>
  9. #include <linux/module.h>
  10. #include <linux/skbuff.h>
  11. #include <linux/stringify.h>
  12. #include <net/dst.h>
  13. #include <net/inet_ecn.h>
  14. #include <net/ip.h>
  15. #include <net/xfrm.h>
  16. /* Informational hook. The decap is still done here. */
  17. static struct xfrm_tunnel __rcu *rcv_notify_handlers __read_mostly;
  18. static DEFINE_MUTEX(xfrm4_mode_tunnel_input_mutex);
  19. int xfrm4_mode_tunnel_input_register(struct xfrm_tunnel *handler)
  20. {
  21. struct xfrm_tunnel __rcu **pprev;
  22. struct xfrm_tunnel *t;
  23. int ret = -EEXIST;
  24. int priority = handler->priority;
  25. mutex_lock(&xfrm4_mode_tunnel_input_mutex);
  26. for (pprev = &rcv_notify_handlers;
  27. (t = rcu_dereference_protected(*pprev,
  28. lockdep_is_held(&xfrm4_mode_tunnel_input_mutex))) != NULL;
  29. pprev = &t->next) {
  30. if (t->priority > priority)
  31. break;
  32. if (t->priority == priority)
  33. goto err;
  34. }
  35. handler->next = *pprev;
  36. rcu_assign_pointer(*pprev, handler);
  37. ret = 0;
  38. err:
  39. mutex_unlock(&xfrm4_mode_tunnel_input_mutex);
  40. return ret;
  41. }
  42. EXPORT_SYMBOL_GPL(xfrm4_mode_tunnel_input_register);
  43. int xfrm4_mode_tunnel_input_deregister(struct xfrm_tunnel *handler)
  44. {
  45. struct xfrm_tunnel __rcu **pprev;
  46. struct xfrm_tunnel *t;
  47. int ret = -ENOENT;
  48. mutex_lock(&xfrm4_mode_tunnel_input_mutex);
  49. for (pprev = &rcv_notify_handlers;
  50. (t = rcu_dereference_protected(*pprev,
  51. lockdep_is_held(&xfrm4_mode_tunnel_input_mutex))) != NULL;
  52. pprev = &t->next) {
  53. if (t == handler) {
  54. *pprev = handler->next;
  55. ret = 0;
  56. break;
  57. }
  58. }
  59. mutex_unlock(&xfrm4_mode_tunnel_input_mutex);
  60. synchronize_net();
  61. return ret;
  62. }
  63. EXPORT_SYMBOL_GPL(xfrm4_mode_tunnel_input_deregister);
  64. static inline void ipip_ecn_decapsulate(struct sk_buff *skb)
  65. {
  66. struct iphdr *inner_iph = ipip_hdr(skb);
  67. if (INET_ECN_is_ce(XFRM_MODE_SKB_CB(skb)->tos))
  68. IP_ECN_set_ce(inner_iph);
  69. }
  70. /* Add encapsulation header.
  71. *
  72. * The top IP header will be constructed per RFC 2401.
  73. */
  74. static int xfrm4_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
  75. {
  76. struct dst_entry *dst = skb_dst(skb);
  77. struct iphdr *top_iph;
  78. int flags;
  79. skb_set_network_header(skb, -x->props.header_len);
  80. skb->mac_header = skb->network_header +
  81. offsetof(struct iphdr, protocol);
  82. skb->transport_header = skb->network_header + sizeof(*top_iph);
  83. top_iph = ip_hdr(skb);
  84. top_iph->ihl = 5;
  85. top_iph->version = 4;
  86. top_iph->protocol = xfrm_af2proto(skb_dst(skb)->ops->family);
  87. /* DS disclosing depends on XFRM_SA_XFLAG_DONT_ENCAP_DSCP */
  88. if (x->props.extra_flags & XFRM_SA_XFLAG_DONT_ENCAP_DSCP)
  89. top_iph->tos = 0;
  90. else
  91. top_iph->tos = XFRM_MODE_SKB_CB(skb)->tos;
  92. top_iph->tos = INET_ECN_encapsulate(top_iph->tos,
  93. XFRM_MODE_SKB_CB(skb)->tos);
  94. flags = x->props.flags;
  95. if (flags & XFRM_STATE_NOECN)
  96. IP_ECN_clear(top_iph);
  97. top_iph->frag_off = (flags & XFRM_STATE_NOPMTUDISC) ?
  98. 0 : (XFRM_MODE_SKB_CB(skb)->frag_off & htons(IP_DF));
  99. ip_select_ident(top_iph, dst->child, NULL);
  100. top_iph->ttl = ip4_dst_hoplimit(dst->child);
  101. top_iph->saddr = x->props.saddr.a4;
  102. top_iph->daddr = x->id.daddr.a4;
  103. return 0;
  104. }
  105. #define for_each_input_rcu(head, handler) \
  106. for (handler = rcu_dereference(head); \
  107. handler != NULL; \
  108. handler = rcu_dereference(handler->next))
  109. static int xfrm4_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
  110. {
  111. struct xfrm_tunnel *handler;
  112. int err = -EINVAL;
  113. if (XFRM_MODE_SKB_CB(skb)->protocol != IPPROTO_IPIP)
  114. goto out;
  115. if (!pskb_may_pull(skb, sizeof(struct iphdr)))
  116. goto out;
  117. for_each_input_rcu(rcv_notify_handlers, handler)
  118. handler->handler(skb);
  119. err = skb_unclone(skb, GFP_ATOMIC);
  120. if (err)
  121. goto out;
  122. if (x->props.flags & XFRM_STATE_DECAP_DSCP)
  123. ipv4_copy_dscp(XFRM_MODE_SKB_CB(skb)->tos, ipip_hdr(skb));
  124. if (!(x->props.flags & XFRM_STATE_NOECN))
  125. ipip_ecn_decapsulate(skb);
  126. skb_reset_network_header(skb);
  127. skb_mac_header_rebuild(skb);
  128. err = 0;
  129. out:
  130. return err;
  131. }
  132. static struct xfrm_mode xfrm4_tunnel_mode = {
  133. .input2 = xfrm4_mode_tunnel_input,
  134. .input = xfrm_prepare_input,
  135. .output2 = xfrm4_mode_tunnel_output,
  136. .output = xfrm4_prepare_output,
  137. .owner = THIS_MODULE,
  138. .encap = XFRM_MODE_TUNNEL,
  139. .flags = XFRM_MODE_FLAG_TUNNEL,
  140. };
  141. static int __init xfrm4_mode_tunnel_init(void)
  142. {
  143. return xfrm_register_mode(&xfrm4_tunnel_mode, AF_INET);
  144. }
  145. static void __exit xfrm4_mode_tunnel_exit(void)
  146. {
  147. int err;
  148. err = xfrm_unregister_mode(&xfrm4_tunnel_mode, AF_INET);
  149. BUG_ON(err);
  150. }
  151. module_init(xfrm4_mode_tunnel_init);
  152. module_exit(xfrm4_mode_tunnel_exit);
  153. MODULE_LICENSE("GPL");
  154. MODULE_ALIAS_XFRM_MODE(AF_INET, XFRM_MODE_TUNNEL);