Blame view
net/ipv6/tunnel6.c
7.05 KB
1ccea77e2 treewide: Replace... |
1 |
// SPDX-License-Identifier: GPL-2.0-or-later |
d2acc3479 [INET]: Introduce... |
2 3 4 |
/* * Copyright (C)2003,2004 USAGI/WIDE Project * |
d2acc3479 [INET]: Introduce... |
5 |
* Authors Mitsuru KANDA <mk@linux-ipv6.org> |
67ba4152e ipv6: White-space... |
6 |
* YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> |
d2acc3479 [INET]: Introduce... |
7 |
*/ |
f32138319 net: ipv6: Standa... |
8 |
#define pr_fmt(fmt) "IPv6: " fmt |
50fba2aa7 [INET]: Move no-t... |
9 |
#include <linux/icmpv6.h> |
d2acc3479 [INET]: Introduce... |
10 11 12 13 14 |
#include <linux/init.h> #include <linux/module.h> #include <linux/mutex.h> #include <linux/netdevice.h> #include <linux/skbuff.h> |
5a0e3ad6a include cleanup: ... |
15 |
#include <linux/slab.h> |
50fba2aa7 [INET]: Move no-t... |
16 |
#include <net/ipv6.h> |
d2acc3479 [INET]: Introduce... |
17 18 |
#include <net/protocol.h> #include <net/xfrm.h> |
6f0bcf152 tunnels: add _rcu... |
19 20 |
static struct xfrm6_tunnel __rcu *tunnel6_handlers __read_mostly; static struct xfrm6_tunnel __rcu *tunnel46_handlers __read_mostly; |
f234efac2 tunnel6: support ... |
21 |
static struct xfrm6_tunnel __rcu *tunnelmpls6_handlers __read_mostly; |
d2acc3479 [INET]: Introduce... |
22 |
static DEFINE_MUTEX(tunnel6_mutex); |
f234efac2 tunnel6: support ... |
23 24 25 26 |
static inline int xfrm6_tunnel_mpls_supported(void) { return IS_ENABLED(CONFIG_MPLS); } |
73d605d1a [IPSEC]: changing... |
27 |
int xfrm6_tunnel_register(struct xfrm6_tunnel *handler, unsigned short family) |
d2acc3479 [INET]: Introduce... |
28 |
{ |
6f0bcf152 tunnels: add _rcu... |
29 30 |
struct xfrm6_tunnel __rcu **pprev; struct xfrm6_tunnel *t; |
d2acc3479 [INET]: Introduce... |
31 32 33 34 |
int ret = -EEXIST; int priority = handler->priority; mutex_lock(&tunnel6_mutex); |
f234efac2 tunnel6: support ... |
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
switch (family) { case AF_INET6: pprev = &tunnel6_handlers; break; case AF_INET: pprev = &tunnel46_handlers; break; case AF_MPLS: pprev = &tunnelmpls6_handlers; break; default: goto err; } for (; (t = rcu_dereference_protected(*pprev, |
6f0bcf152 tunnels: add _rcu... |
50 51 52 |
lockdep_is_held(&tunnel6_mutex))) != NULL; pprev = &t->next) { if (t->priority > priority) |
d2acc3479 [INET]: Introduce... |
53 |
break; |
6f0bcf152 tunnels: add _rcu... |
54 |
if (t->priority == priority) |
d2acc3479 [INET]: Introduce... |
55 56 57 58 |
goto err; } handler->next = *pprev; |
49d61e239 tunnels: missing ... |
59 |
rcu_assign_pointer(*pprev, handler); |
d2acc3479 [INET]: Introduce... |
60 61 62 63 64 65 66 67 |
ret = 0; err: mutex_unlock(&tunnel6_mutex); return ret; } |
d2acc3479 [INET]: Introduce... |
68 |
EXPORT_SYMBOL(xfrm6_tunnel_register); |
73d605d1a [IPSEC]: changing... |
69 |
int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short family) |
d2acc3479 [INET]: Introduce... |
70 |
{ |
6f0bcf152 tunnels: add _rcu... |
71 72 |
struct xfrm6_tunnel __rcu **pprev; struct xfrm6_tunnel *t; |
d2acc3479 [INET]: Introduce... |
73 74 75 |
int ret = -ENOENT; mutex_lock(&tunnel6_mutex); |
f234efac2 tunnel6: support ... |
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
switch (family) { case AF_INET6: pprev = &tunnel6_handlers; break; case AF_INET: pprev = &tunnel46_handlers; break; case AF_MPLS: pprev = &tunnelmpls6_handlers; break; default: goto err; } for (; (t = rcu_dereference_protected(*pprev, |
6f0bcf152 tunnels: add _rcu... |
91 92 93 |
lockdep_is_held(&tunnel6_mutex))) != NULL; pprev = &t->next) { if (t == handler) { |
d2acc3479 [INET]: Introduce... |
94 95 96 97 98 |
*pprev = handler->next; ret = 0; break; } } |
f234efac2 tunnel6: support ... |
99 |
err: |
d2acc3479 [INET]: Introduce... |
100 101 102 103 104 105 |
mutex_unlock(&tunnel6_mutex); synchronize_net(); return ret; } |
d2acc3479 [INET]: Introduce... |
106 |
EXPORT_SYMBOL(xfrm6_tunnel_deregister); |
875168a93 net: tunnels shou... |
107 108 109 110 |
#define for_each_tunnel_rcu(head, handler) \ for (handler = rcu_dereference(head); \ handler != NULL; \ handler = rcu_dereference(handler->next)) \ |
f234efac2 tunnel6: support ... |
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
static int tunnelmpls6_rcv(struct sk_buff *skb) { struct xfrm6_tunnel *handler; if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) goto drop; for_each_tunnel_rcu(tunnelmpls6_handlers, handler) if (!handler->handler(skb)) return 0; icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0); drop: kfree_skb(skb); return 0; } |
e5bbef20e [IPV6]: Replace s... |
128 |
static int tunnel6_rcv(struct sk_buff *skb) |
d2acc3479 [INET]: Introduce... |
129 |
{ |
d2acc3479 [INET]: Introduce... |
130 |
struct xfrm6_tunnel *handler; |
50fba2aa7 [INET]: Move no-t... |
131 132 |
if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) goto drop; |
875168a93 net: tunnels shou... |
133 |
for_each_tunnel_rcu(tunnel6_handlers, handler) |
d2acc3479 [INET]: Introduce... |
134 135 |
if (!handler->handler(skb)) return 0; |
3ffe533c8 ipv6: drop unused... |
136 |
icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0); |
50fba2aa7 [INET]: Move no-t... |
137 138 |
drop: |
d2acc3479 [INET]: Introduce... |
139 140 141 |
kfree_skb(skb); return 0; } |
86afc7031 tunnel6: add tunn... |
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
#if IS_ENABLED(CONFIG_INET6_XFRM_TUNNEL) static int tunnel6_rcv_cb(struct sk_buff *skb, u8 proto, int err) { struct xfrm6_tunnel __rcu *head; struct xfrm6_tunnel *handler; int ret; head = (proto == IPPROTO_IPV6) ? tunnel6_handlers : tunnel46_handlers; for_each_tunnel_rcu(head, handler) { if (handler->cb_handler) { ret = handler->cb_handler(skb, err); if (ret <= 0) return ret; } } return 0; } static const struct xfrm_input_afinfo tunnel6_input_afinfo = { .family = AF_INET6, .is_ipip = true, .callback = tunnel6_rcv_cb, }; #endif |
e5bbef20e [IPV6]: Replace s... |
168 |
static int tunnel46_rcv(struct sk_buff *skb) |
73d605d1a [IPSEC]: changing... |
169 |
{ |
73d605d1a [IPSEC]: changing... |
170 |
struct xfrm6_tunnel *handler; |
828363723 [IPV6] TUNNEL6: F... |
171 |
if (!pskb_may_pull(skb, sizeof(struct iphdr))) |
73d605d1a [IPSEC]: changing... |
172 |
goto drop; |
875168a93 net: tunnels shou... |
173 |
for_each_tunnel_rcu(tunnel46_handlers, handler) |
73d605d1a [IPSEC]: changing... |
174 175 |
if (!handler->handler(skb)) return 0; |
3ffe533c8 ipv6: drop unused... |
176 |
icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0); |
73d605d1a [IPSEC]: changing... |
177 178 179 180 181 |
drop: kfree_skb(skb); return 0; } |
32bbd8793 net: Convert prot... |
182 |
static int tunnel6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, |
d5fdd6bab ipv6: Use correct... |
183 |
u8 type, u8 code, int offset, __be32 info) |
d2acc3479 [INET]: Introduce... |
184 185 |
{ struct xfrm6_tunnel *handler; |
875168a93 net: tunnels shou... |
186 |
for_each_tunnel_rcu(tunnel6_handlers, handler) |
d2acc3479 [INET]: Introduce... |
187 |
if (!handler->err_handler(skb, opt, type, code, offset, info)) |
32bbd8793 net: Convert prot... |
188 189 190 |
return 0; return -ENOENT; |
d2acc3479 [INET]: Introduce... |
191 |
} |
32bbd8793 net: Convert prot... |
192 |
static int tunnel46_err(struct sk_buff *skb, struct inet6_skb_parm *opt, |
ebac62fe3 ipv6: fix tunnel ... |
193 194 195 196 197 198 |
u8 type, u8 code, int offset, __be32 info) { struct xfrm6_tunnel *handler; for_each_tunnel_rcu(tunnel46_handlers, handler) if (!handler->err_handler(skb, opt, type, code, offset, info)) |
32bbd8793 net: Convert prot... |
199 200 201 |
return 0; return -ENOENT; |
ebac62fe3 ipv6: fix tunnel ... |
202 |
} |
f234efac2 tunnel6: support ... |
203 204 205 206 207 208 209 210 211 212 213 |
static int tunnelmpls6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, u8 type, u8 code, int offset, __be32 info) { struct xfrm6_tunnel *handler; for_each_tunnel_rcu(tunnelmpls6_handlers, handler) if (!handler->err_handler(skb, opt, type, code, offset, info)) return 0; return -ENOENT; } |
41135cc83 net: constify str... |
214 |
static const struct inet6_protocol tunnel6_protocol = { |
d2acc3479 [INET]: Introduce... |
215 216 217 218 |
.handler = tunnel6_rcv, .err_handler = tunnel6_err, .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, }; |
41135cc83 net: constify str... |
219 |
static const struct inet6_protocol tunnel46_protocol = { |
73d605d1a [IPSEC]: changing... |
220 |
.handler = tunnel46_rcv, |
ebac62fe3 ipv6: fix tunnel ... |
221 |
.err_handler = tunnel46_err, |
73d605d1a [IPSEC]: changing... |
222 223 |
.flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, }; |
f234efac2 tunnel6: support ... |
224 225 226 227 228 |
static const struct inet6_protocol tunnelmpls6_protocol = { .handler = tunnelmpls6_rcv, .err_handler = tunnelmpls6_err, .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, }; |
d2acc3479 [INET]: Introduce... |
229 230 231 |
static int __init tunnel6_init(void) { if (inet6_add_protocol(&tunnel6_protocol, IPPROTO_IPV6)) { |
f32138319 net: ipv6: Standa... |
232 233 |
pr_err("%s: can't add protocol ", __func__); |
d2acc3479 [INET]: Introduce... |
234 235 |
return -EAGAIN; } |
73d605d1a [IPSEC]: changing... |
236 |
if (inet6_add_protocol(&tunnel46_protocol, IPPROTO_IPIP)) { |
f32138319 net: ipv6: Standa... |
237 238 |
pr_err("%s: can't add protocol ", __func__); |
73d605d1a [IPSEC]: changing... |
239 240 241 |
inet6_del_protocol(&tunnel6_protocol, IPPROTO_IPV6); return -EAGAIN; } |
f234efac2 tunnel6: support ... |
242 243 244 245 246 247 248 249 |
if (xfrm6_tunnel_mpls_supported() && inet6_add_protocol(&tunnelmpls6_protocol, IPPROTO_MPLS)) { pr_err("%s: can't add protocol ", __func__); inet6_del_protocol(&tunnel6_protocol, IPPROTO_IPV6); inet6_del_protocol(&tunnel46_protocol, IPPROTO_IPIP); return -EAGAIN; } |
86afc7031 tunnel6: add tunn... |
250 251 252 253 254 255 256 257 258 259 260 |
#if IS_ENABLED(CONFIG_INET6_XFRM_TUNNEL) if (xfrm_input_register_afinfo(&tunnel6_input_afinfo)) { pr_err("%s: can't add input afinfo ", __func__); inet6_del_protocol(&tunnel6_protocol, IPPROTO_IPV6); inet6_del_protocol(&tunnel46_protocol, IPPROTO_IPIP); if (xfrm6_tunnel_mpls_supported()) inet6_del_protocol(&tunnelmpls6_protocol, IPPROTO_MPLS); return -EAGAIN; } #endif |
d2acc3479 [INET]: Introduce... |
261 262 263 264 265 |
return 0; } static void __exit tunnel6_fini(void) { |
86afc7031 tunnel6: add tunn... |
266 267 268 269 270 |
#if IS_ENABLED(CONFIG_INET6_XFRM_TUNNEL) if (xfrm_input_unregister_afinfo(&tunnel6_input_afinfo)) pr_err("%s: can't remove input afinfo ", __func__); #endif |
73d605d1a [IPSEC]: changing... |
271 |
if (inet6_del_protocol(&tunnel46_protocol, IPPROTO_IPIP)) |
f32138319 net: ipv6: Standa... |
272 273 |
pr_err("%s: can't remove protocol ", __func__); |
d2acc3479 [INET]: Introduce... |
274 |
if (inet6_del_protocol(&tunnel6_protocol, IPPROTO_IPV6)) |
f32138319 net: ipv6: Standa... |
275 276 |
pr_err("%s: can't remove protocol ", __func__); |
f234efac2 tunnel6: support ... |
277 278 279 280 |
if (xfrm6_tunnel_mpls_supported() && inet6_del_protocol(&tunnelmpls6_protocol, IPPROTO_MPLS)) pr_err("%s: can't remove protocol ", __func__); |
d2acc3479 [INET]: Introduce... |
281 282 283 284 285 |
} module_init(tunnel6_init); module_exit(tunnel6_fini); MODULE_LICENSE("GPL"); |