xfrm4_mode_tunnel.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  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 disclosed */
  88. top_iph->tos = INET_ECN_encapsulate(XFRM_MODE_SKB_CB(skb)->tos,
  89. XFRM_MODE_SKB_CB(skb)->tos);
  90. flags = x->props.flags;
  91. if (flags & XFRM_STATE_NOECN)
  92. IP_ECN_clear(top_iph);
  93. top_iph->frag_off = (flags & XFRM_STATE_NOPMTUDISC) ?
  94. 0 : (XFRM_MODE_SKB_CB(skb)->frag_off & htons(IP_DF));
  95. ip_select_ident(top_iph, dst->child, NULL);
  96. top_iph->ttl = ip4_dst_hoplimit(dst->child);
  97. top_iph->saddr = x->props.saddr.a4;
  98. top_iph->daddr = x->id.daddr.a4;
  99. return 0;
  100. }
  101. #define for_each_input_rcu(head, handler) \
  102. for (handler = rcu_dereference(head); \
  103. handler != NULL; \
  104. handler = rcu_dereference(handler->next))
  105. static int xfrm4_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
  106. {
  107. struct xfrm_tunnel *handler;
  108. int err = -EINVAL;
  109. if (XFRM_MODE_SKB_CB(skb)->protocol != IPPROTO_IPIP)
  110. goto out;
  111. if (!pskb_may_pull(skb, sizeof(struct iphdr)))
  112. goto out;
  113. for_each_input_rcu(rcv_notify_handlers, handler)
  114. handler->handler(skb);
  115. if (skb_cloned(skb) &&
  116. (err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
  117. goto out;
  118. if (x->props.flags & XFRM_STATE_DECAP_DSCP)
  119. ipv4_copy_dscp(XFRM_MODE_SKB_CB(skb)->tos, ipip_hdr(skb));
  120. if (!(x->props.flags & XFRM_STATE_NOECN))
  121. ipip_ecn_decapsulate(skb);
  122. skb_reset_network_header(skb);
  123. skb_mac_header_rebuild(skb);
  124. err = 0;
  125. out:
  126. return err;
  127. }
  128. static struct xfrm_mode xfrm4_tunnel_mode = {
  129. .input2 = xfrm4_mode_tunnel_input,
  130. .input = xfrm_prepare_input,
  131. .output2 = xfrm4_mode_tunnel_output,
  132. .output = xfrm4_prepare_output,
  133. .owner = THIS_MODULE,
  134. .encap = XFRM_MODE_TUNNEL,
  135. .flags = XFRM_MODE_FLAG_TUNNEL,
  136. };
  137. static int __init xfrm4_mode_tunnel_init(void)
  138. {
  139. return xfrm_register_mode(&xfrm4_tunnel_mode, AF_INET);
  140. }
  141. static void __exit xfrm4_mode_tunnel_exit(void)
  142. {
  143. int err;
  144. err = xfrm_unregister_mode(&xfrm4_tunnel_mode, AF_INET);
  145. BUG_ON(err);
  146. }
  147. module_init(xfrm4_mode_tunnel_init);
  148. module_exit(xfrm4_mode_tunnel_exit);
  149. MODULE_LICENSE("GPL");
  150. MODULE_ALIAS_XFRM_MODE(AF_INET, XFRM_MODE_TUNNEL);