xfrm6_protocol.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /* xfrm6_protocol.c - Generic xfrm protocol multiplexer for ipv6.
  3. *
  4. * Copyright (C) 2013 secunet Security Networks AG
  5. *
  6. * Author:
  7. * Steffen Klassert <[email protected]>
  8. *
  9. * Based on:
  10. * net/ipv4/xfrm4_protocol.c
  11. */
  12. #include <linux/init.h>
  13. #include <linux/mutex.h>
  14. #include <linux/skbuff.h>
  15. #include <linux/icmpv6.h>
  16. #include <net/ip6_route.h>
  17. #include <net/ipv6.h>
  18. #include <net/protocol.h>
  19. #include <net/xfrm.h>
  20. static struct xfrm6_protocol __rcu *esp6_handlers __read_mostly;
  21. static struct xfrm6_protocol __rcu *ah6_handlers __read_mostly;
  22. static struct xfrm6_protocol __rcu *ipcomp6_handlers __read_mostly;
  23. static DEFINE_MUTEX(xfrm6_protocol_mutex);
  24. static inline struct xfrm6_protocol __rcu **proto_handlers(u8 protocol)
  25. {
  26. switch (protocol) {
  27. case IPPROTO_ESP:
  28. return &esp6_handlers;
  29. case IPPROTO_AH:
  30. return &ah6_handlers;
  31. case IPPROTO_COMP:
  32. return &ipcomp6_handlers;
  33. }
  34. return NULL;
  35. }
  36. #define for_each_protocol_rcu(head, handler) \
  37. for (handler = rcu_dereference(head); \
  38. handler != NULL; \
  39. handler = rcu_dereference(handler->next)) \
  40. static int xfrm6_rcv_cb(struct sk_buff *skb, u8 protocol, int err)
  41. {
  42. int ret;
  43. struct xfrm6_protocol *handler;
  44. struct xfrm6_protocol __rcu **head = proto_handlers(protocol);
  45. if (!head)
  46. return 0;
  47. for_each_protocol_rcu(*proto_handlers(protocol), handler)
  48. if ((ret = handler->cb_handler(skb, err)) <= 0)
  49. return ret;
  50. return 0;
  51. }
  52. int xfrm6_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
  53. int encap_type)
  54. {
  55. int ret;
  56. struct xfrm6_protocol *handler;
  57. struct xfrm6_protocol __rcu **head = proto_handlers(nexthdr);
  58. XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6 = NULL;
  59. XFRM_SPI_SKB_CB(skb)->family = AF_INET6;
  60. XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct ipv6hdr, daddr);
  61. if (!head)
  62. goto out;
  63. if (!skb_dst(skb)) {
  64. const struct ipv6hdr *ip6h = ipv6_hdr(skb);
  65. int flags = RT6_LOOKUP_F_HAS_SADDR;
  66. struct dst_entry *dst;
  67. struct flowi6 fl6 = {
  68. .flowi6_iif = skb->dev->ifindex,
  69. .daddr = ip6h->daddr,
  70. .saddr = ip6h->saddr,
  71. .flowlabel = ip6_flowinfo(ip6h),
  72. .flowi6_mark = skb->mark,
  73. .flowi6_proto = ip6h->nexthdr,
  74. };
  75. dst = ip6_route_input_lookup(dev_net(skb->dev), skb->dev, &fl6,
  76. skb, flags);
  77. if (dst->error)
  78. goto drop;
  79. skb_dst_set(skb, dst);
  80. }
  81. for_each_protocol_rcu(*head, handler)
  82. if ((ret = handler->input_handler(skb, nexthdr, spi, encap_type)) != -EINVAL)
  83. return ret;
  84. out:
  85. icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0);
  86. drop:
  87. kfree_skb(skb);
  88. return 0;
  89. }
  90. EXPORT_SYMBOL(xfrm6_rcv_encap);
  91. static int xfrm6_esp_rcv(struct sk_buff *skb)
  92. {
  93. int ret;
  94. struct xfrm6_protocol *handler;
  95. XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6 = NULL;
  96. for_each_protocol_rcu(esp6_handlers, handler)
  97. if ((ret = handler->handler(skb)) != -EINVAL)
  98. return ret;
  99. icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0);
  100. kfree_skb(skb);
  101. return 0;
  102. }
  103. static int xfrm6_esp_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
  104. u8 type, u8 code, int offset, __be32 info)
  105. {
  106. struct xfrm6_protocol *handler;
  107. for_each_protocol_rcu(esp6_handlers, handler)
  108. if (!handler->err_handler(skb, opt, type, code, offset, info))
  109. return 0;
  110. return -ENOENT;
  111. }
  112. static int xfrm6_ah_rcv(struct sk_buff *skb)
  113. {
  114. int ret;
  115. struct xfrm6_protocol *handler;
  116. XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6 = NULL;
  117. for_each_protocol_rcu(ah6_handlers, handler)
  118. if ((ret = handler->handler(skb)) != -EINVAL)
  119. return ret;
  120. icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0);
  121. kfree_skb(skb);
  122. return 0;
  123. }
  124. static int xfrm6_ah_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
  125. u8 type, u8 code, int offset, __be32 info)
  126. {
  127. struct xfrm6_protocol *handler;
  128. for_each_protocol_rcu(ah6_handlers, handler)
  129. if (!handler->err_handler(skb, opt, type, code, offset, info))
  130. return 0;
  131. return -ENOENT;
  132. }
  133. static int xfrm6_ipcomp_rcv(struct sk_buff *skb)
  134. {
  135. int ret;
  136. struct xfrm6_protocol *handler;
  137. XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6 = NULL;
  138. for_each_protocol_rcu(ipcomp6_handlers, handler)
  139. if ((ret = handler->handler(skb)) != -EINVAL)
  140. return ret;
  141. icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0);
  142. kfree_skb(skb);
  143. return 0;
  144. }
  145. static int xfrm6_ipcomp_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
  146. u8 type, u8 code, int offset, __be32 info)
  147. {
  148. struct xfrm6_protocol *handler;
  149. for_each_protocol_rcu(ipcomp6_handlers, handler)
  150. if (!handler->err_handler(skb, opt, type, code, offset, info))
  151. return 0;
  152. return -ENOENT;
  153. }
  154. static const struct inet6_protocol esp6_protocol = {
  155. .handler = xfrm6_esp_rcv,
  156. .err_handler = xfrm6_esp_err,
  157. .flags = INET6_PROTO_NOPOLICY,
  158. };
  159. static const struct inet6_protocol ah6_protocol = {
  160. .handler = xfrm6_ah_rcv,
  161. .err_handler = xfrm6_ah_err,
  162. .flags = INET6_PROTO_NOPOLICY,
  163. };
  164. static const struct inet6_protocol ipcomp6_protocol = {
  165. .handler = xfrm6_ipcomp_rcv,
  166. .err_handler = xfrm6_ipcomp_err,
  167. .flags = INET6_PROTO_NOPOLICY,
  168. };
  169. static const struct xfrm_input_afinfo xfrm6_input_afinfo = {
  170. .family = AF_INET6,
  171. .callback = xfrm6_rcv_cb,
  172. };
  173. static inline const struct inet6_protocol *netproto(unsigned char protocol)
  174. {
  175. switch (protocol) {
  176. case IPPROTO_ESP:
  177. return &esp6_protocol;
  178. case IPPROTO_AH:
  179. return &ah6_protocol;
  180. case IPPROTO_COMP:
  181. return &ipcomp6_protocol;
  182. }
  183. return NULL;
  184. }
  185. int xfrm6_protocol_register(struct xfrm6_protocol *handler,
  186. unsigned char protocol)
  187. {
  188. struct xfrm6_protocol __rcu **pprev;
  189. struct xfrm6_protocol *t;
  190. bool add_netproto = false;
  191. int ret = -EEXIST;
  192. int priority = handler->priority;
  193. if (!proto_handlers(protocol) || !netproto(protocol))
  194. return -EINVAL;
  195. mutex_lock(&xfrm6_protocol_mutex);
  196. if (!rcu_dereference_protected(*proto_handlers(protocol),
  197. lockdep_is_held(&xfrm6_protocol_mutex)))
  198. add_netproto = true;
  199. for (pprev = proto_handlers(protocol);
  200. (t = rcu_dereference_protected(*pprev,
  201. lockdep_is_held(&xfrm6_protocol_mutex))) != NULL;
  202. pprev = &t->next) {
  203. if (t->priority < priority)
  204. break;
  205. if (t->priority == priority)
  206. goto err;
  207. }
  208. handler->next = *pprev;
  209. rcu_assign_pointer(*pprev, handler);
  210. ret = 0;
  211. err:
  212. mutex_unlock(&xfrm6_protocol_mutex);
  213. if (add_netproto) {
  214. if (inet6_add_protocol(netproto(protocol), protocol)) {
  215. pr_err("%s: can't add protocol\n", __func__);
  216. ret = -EAGAIN;
  217. }
  218. }
  219. return ret;
  220. }
  221. EXPORT_SYMBOL(xfrm6_protocol_register);
  222. int xfrm6_protocol_deregister(struct xfrm6_protocol *handler,
  223. unsigned char protocol)
  224. {
  225. struct xfrm6_protocol __rcu **pprev;
  226. struct xfrm6_protocol *t;
  227. int ret = -ENOENT;
  228. if (!proto_handlers(protocol) || !netproto(protocol))
  229. return -EINVAL;
  230. mutex_lock(&xfrm6_protocol_mutex);
  231. for (pprev = proto_handlers(protocol);
  232. (t = rcu_dereference_protected(*pprev,
  233. lockdep_is_held(&xfrm6_protocol_mutex))) != NULL;
  234. pprev = &t->next) {
  235. if (t == handler) {
  236. *pprev = handler->next;
  237. ret = 0;
  238. break;
  239. }
  240. }
  241. if (!rcu_dereference_protected(*proto_handlers(protocol),
  242. lockdep_is_held(&xfrm6_protocol_mutex))) {
  243. if (inet6_del_protocol(netproto(protocol), protocol) < 0) {
  244. pr_err("%s: can't remove protocol\n", __func__);
  245. ret = -EAGAIN;
  246. }
  247. }
  248. mutex_unlock(&xfrm6_protocol_mutex);
  249. synchronize_net();
  250. return ret;
  251. }
  252. EXPORT_SYMBOL(xfrm6_protocol_deregister);
  253. int __init xfrm6_protocol_init(void)
  254. {
  255. return xfrm_input_register_afinfo(&xfrm6_input_afinfo);
  256. }
  257. void xfrm6_protocol_fini(void)
  258. {
  259. xfrm_input_unregister_afinfo(&xfrm6_input_afinfo);
  260. }