ipsecif(4) supports multiple peers in the same NAPT. E.g. ipsec0 connects between NetBSD_A and NetBSD_B, ipsec1 connects NetBSD_A and NetBSD_C at the following figure. +----------+ +----| NetBSD_B | +----------+ +------+ | +----------+ | NetBSD_A |--- ... ---| NAPT |---+ +----------+ +------+ | +----------+ +----| NetBSD_C | +----------+ Add ATF later.diff -r1.81 -r1.82 src/sys/netipsec/ipsec_output.c
(knakahara)
--- src/sys/netipsec/ipsec_output.c 2018/11/22 04:48:34 1.81
+++ src/sys/netipsec/ipsec_output.c 2018/12/26 08:58:51 1.82
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: ipsec_output.c,v 1.81 2018/11/22 04:48:34 knakahara Exp $ */ | 1 | /* $NetBSD: ipsec_output.c,v 1.82 2018/12/26 08:58:51 knakahara Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting | 4 | * Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | 9 | * are met: | |
10 | * 1. Redistributions of source code must retain the above copyright | 10 | * 1. Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. | |
@@ -19,27 +19,27 @@ | @@ -19,27 +19,27 @@ | |||
19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |
20 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 20 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
21 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 21 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
22 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 22 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
23 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 23 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
24 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 24 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
26 | * SUCH DAMAGE. | 26 | * SUCH DAMAGE. | |
27 | * | 27 | * | |
28 | * $FreeBSD: sys/netipsec/ipsec_output.c,v 1.3.2.2 2003/03/28 20:32:53 sam Exp $ | 28 | * $FreeBSD: sys/netipsec/ipsec_output.c,v 1.3.2.2 2003/03/28 20:32:53 sam Exp $ | |
29 | */ | 29 | */ | |
30 | 30 | |||
31 | #include <sys/cdefs.h> | 31 | #include <sys/cdefs.h> | |
32 | __KERNEL_RCSID(0, "$NetBSD: ipsec_output.c,v 1.81 2018/11/22 04:48:34 knakahara Exp $"); | 32 | __KERNEL_RCSID(0, "$NetBSD: ipsec_output.c,v 1.82 2018/12/26 08:58:51 knakahara Exp $"); | |
33 | 33 | |||
34 | #if defined(_KERNEL_OPT) | 34 | #if defined(_KERNEL_OPT) | |
35 | #include "opt_inet.h" | 35 | #include "opt_inet.h" | |
36 | #include "opt_net_mpsafe.h" | 36 | #include "opt_net_mpsafe.h" | |
37 | #endif | 37 | #endif | |
38 | 38 | |||
39 | #include <sys/param.h> | 39 | #include <sys/param.h> | |
40 | #include <sys/systm.h> | 40 | #include <sys/systm.h> | |
41 | #include <sys/mbuf.h> | 41 | #include <sys/mbuf.h> | |
42 | #include <sys/domain.h> | 42 | #include <sys/domain.h> | |
43 | #include <sys/protosw.h> | 43 | #include <sys/protosw.h> | |
44 | #include <sys/socket.h> | 44 | #include <sys/socket.h> | |
45 | #include <sys/errno.h> | 45 | #include <sys/errno.h> | |
@@ -279,67 +279,85 @@ ipsec_process_done(struct mbuf *m, const | @@ -279,67 +279,85 @@ ipsec_process_done(struct mbuf *m, const | |||
279 | goto bad; | 279 | goto bad; | |
280 | 280 | |||
281 | return ipsec_reinject_ipstack(m, saidx->dst.sa.sa_family); | 281 | return ipsec_reinject_ipstack(m, saidx->dst.sa.sa_family); | |
282 | 282 | |||
283 | bad: | 283 | bad: | |
284 | m_freem(m); | 284 | m_freem(m); | |
285 | return error; | 285 | return error; | |
286 | } | 286 | } | |
287 | 287 | |||
288 | static void | 288 | static void | |
289 | ipsec_fill_saidx_bymbuf(struct secasindex *saidx, const struct mbuf *m, | 289 | ipsec_fill_saidx_bymbuf(struct secasindex *saidx, const struct mbuf *m, | |
290 | const int af) | 290 | const int af) | |
291 | { | 291 | { | |
292 | struct m_tag *mtag; | |||
293 | u_int16_t natt_src = IPSEC_PORT_ANY; | |||
294 | u_int16_t natt_dst = IPSEC_PORT_ANY; | |||
295 | ||||
296 | /* | |||
297 | * For NAT-T enabled ipsecif(4), set NAT-T port numbers | |||
298 | * even if the saidx uses transport mode. | |||
299 | * | |||
300 | * See also ipsecif[46]_output(). | |||
301 | */ | |||
302 | mtag = m_tag_find(m, PACKET_TAG_IPSEC_NAT_T_PORTS); | |||
303 | if (mtag) { | |||
304 | u_int16_t *natt_ports; | |||
305 | ||||
306 | natt_ports = (u_int16_t *)(mtag + 1); | |||
307 | natt_src = natt_ports[1]; | |||
308 | natt_dst = natt_ports[0]; | |||
309 | } | |||
292 | 310 | |||
293 | if (af == AF_INET) { | 311 | if (af == AF_INET) { | |
294 | struct sockaddr_in *sin; | 312 | struct sockaddr_in *sin; | |
295 | struct ip *ip = mtod(m, struct ip *); | 313 | struct ip *ip = mtod(m, struct ip *); | |
296 | 314 | |||
297 | if (saidx->src.sa.sa_len == 0) { | 315 | if (saidx->src.sa.sa_len == 0) { | |
298 | sin = &saidx->src.sin; | 316 | sin = &saidx->src.sin; | |
299 | sin->sin_len = sizeof(*sin); | 317 | sin->sin_len = sizeof(*sin); | |
300 | sin->sin_family = AF_INET; | 318 | sin->sin_family = AF_INET; | |
301 | sin->sin_port = IPSEC_PORT_ANY; | 319 | sin->sin_port = natt_src; | |
302 | sin->sin_addr = ip->ip_src; | 320 | sin->sin_addr = ip->ip_src; | |
303 | } | 321 | } | |
304 | if (saidx->dst.sa.sa_len == 0) { | 322 | if (saidx->dst.sa.sa_len == 0) { | |
305 | sin = &saidx->dst.sin; | 323 | sin = &saidx->dst.sin; | |
306 | sin->sin_len = sizeof(*sin); | 324 | sin->sin_len = sizeof(*sin); | |
307 | sin->sin_family = AF_INET; | 325 | sin->sin_family = AF_INET; | |
308 | sin->sin_port = IPSEC_PORT_ANY; | 326 | sin->sin_port = natt_dst; | |
309 | sin->sin_addr = ip->ip_dst; | 327 | sin->sin_addr = ip->ip_dst; | |
310 | } | 328 | } | |
311 | } else { | 329 | } else { | |
312 | struct sockaddr_in6 *sin6; | 330 | struct sockaddr_in6 *sin6; | |
313 | struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); | 331 | struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); | |
314 | 332 | |||
315 | if (saidx->src.sin6.sin6_len == 0) { | 333 | if (saidx->src.sin6.sin6_len == 0) { | |
316 | sin6 = (struct sockaddr_in6 *)&saidx->src; | 334 | sin6 = (struct sockaddr_in6 *)&saidx->src; | |
317 | sin6->sin6_len = sizeof(*sin6); | 335 | sin6->sin6_len = sizeof(*sin6); | |
318 | sin6->sin6_family = AF_INET6; | 336 | sin6->sin6_family = AF_INET6; | |
319 | sin6->sin6_port = IPSEC_PORT_ANY; | 337 | sin6->sin6_port = natt_src; | |
320 | sin6->sin6_addr = ip6->ip6_src; | 338 | sin6->sin6_addr = ip6->ip6_src; | |
321 | if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src)) { | 339 | if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src)) { | |
322 | /* fix scope id for comparing SPD */ | 340 | /* fix scope id for comparing SPD */ | |
323 | sin6->sin6_addr.s6_addr16[1] = 0; | 341 | sin6->sin6_addr.s6_addr16[1] = 0; | |
324 | sin6->sin6_scope_id = | 342 | sin6->sin6_scope_id = | |
325 | ntohs(ip6->ip6_src.s6_addr16[1]); | 343 | ntohs(ip6->ip6_src.s6_addr16[1]); | |
326 | } | 344 | } | |
327 | } | 345 | } | |
328 | if (saidx->dst.sin6.sin6_len == 0) { | 346 | if (saidx->dst.sin6.sin6_len == 0) { | |
329 | sin6 = (struct sockaddr_in6 *)&saidx->dst; | 347 | sin6 = (struct sockaddr_in6 *)&saidx->dst; | |
330 | sin6->sin6_len = sizeof(*sin6); | 348 | sin6->sin6_len = sizeof(*sin6); | |
331 | sin6->sin6_family = AF_INET6; | 349 | sin6->sin6_family = AF_INET6; | |
332 | sin6->sin6_port = IPSEC_PORT_ANY; | 350 | sin6->sin6_port = natt_dst; | |
333 | sin6->sin6_addr = ip6->ip6_dst; | 351 | sin6->sin6_addr = ip6->ip6_dst; | |
334 | if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) { | 352 | if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) { | |
335 | /* fix scope id for comparing SPD */ | 353 | /* fix scope id for comparing SPD */ | |
336 | sin6->sin6_addr.s6_addr16[1] = 0; | 354 | sin6->sin6_addr.s6_addr16[1] = 0; | |
337 | sin6->sin6_scope_id = | 355 | sin6->sin6_scope_id = | |
338 | ntohs(ip6->ip6_dst.s6_addr16[1]); | 356 | ntohs(ip6->ip6_dst.s6_addr16[1]); | |
339 | } | 357 | } | |
340 | } | 358 | } | |
341 | } | 359 | } | |
342 | } | 360 | } | |
343 | 361 | |||
344 | struct secasvar * | 362 | struct secasvar * | |
345 | ipsec_lookup_sa(const struct ipsecrequest *isr, const struct mbuf *m) | 363 | ipsec_lookup_sa(const struct ipsecrequest *isr, const struct mbuf *m) |
--- src/sys/netipsec/ipsecif.c 2018/12/07 09:11:04 1.12
+++ src/sys/netipsec/ipsecif.c 2018/12/26 08:58:51 1.13
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: ipsecif.c,v 1.12 2018/12/07 09:11:04 knakahara Exp $ */ | 1 | /* $NetBSD: ipsecif.c,v 1.13 2018/12/26 08:58:51 knakahara Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 2017 Internet Initiative Japan Inc. | 4 | * Copyright (c) 2017 Internet Initiative Japan Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | 9 | * are met: | |
10 | * 1. Redistributions of source code must retain the above copyright | 10 | * 1. Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. | |
@@ -17,27 +17,27 @@ | @@ -17,27 +17,27 @@ | |||
17 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | 17 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | 19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | |
20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
26 | * POSSIBILITY OF SUCH DAMAGE. | 26 | * POSSIBILITY OF SUCH DAMAGE. | |
27 | */ | 27 | */ | |
28 | 28 | |||
29 | #include <sys/cdefs.h> | 29 | #include <sys/cdefs.h> | |
30 | __KERNEL_RCSID(0, "$NetBSD: ipsecif.c,v 1.12 2018/12/07 09:11:04 knakahara Exp $"); | 30 | __KERNEL_RCSID(0, "$NetBSD: ipsecif.c,v 1.13 2018/12/26 08:58:51 knakahara Exp $"); | |
31 | 31 | |||
32 | #ifdef _KERNEL_OPT | 32 | #ifdef _KERNEL_OPT | |
33 | #include "opt_inet.h" | 33 | #include "opt_inet.h" | |
34 | #include "opt_ipsec.h" | 34 | #include "opt_ipsec.h" | |
35 | #endif | 35 | #endif | |
36 | 36 | |||
37 | #include <sys/param.h> | 37 | #include <sys/param.h> | |
38 | #include <sys/systm.h> | 38 | #include <sys/systm.h> | |
39 | #include <sys/socket.h> | 39 | #include <sys/socket.h> | |
40 | #include <sys/sockio.h> | 40 | #include <sys/sockio.h> | |
41 | #include <sys/mbuf.h> | 41 | #include <sys/mbuf.h> | |
42 | #include <sys/errno.h> | 42 | #include <sys/errno.h> | |
43 | #include <sys/ioctl.h> | 43 | #include <sys/ioctl.h> | |
@@ -61,26 +61,27 @@ __KERNEL_RCSID(0, "$NetBSD: ipsecif.c,v | @@ -61,26 +61,27 @@ __KERNEL_RCSID(0, "$NetBSD: ipsecif.c,v | |||
61 | #include <netinet/ip6.h> | 61 | #include <netinet/ip6.h> | |
62 | #include <netinet6/ip6_var.h> | 62 | #include <netinet6/ip6_var.h> | |
63 | #include <netinet6/ip6_private.h> | 63 | #include <netinet6/ip6_private.h> | |
64 | #include <netinet6/in6_var.h> | 64 | #include <netinet6/in6_var.h> | |
65 | #include <netinet6/ip6protosw.h> /* for struct ip6ctlparam */ | 65 | #include <netinet6/ip6protosw.h> /* for struct ip6ctlparam */ | |
66 | #include <netinet/ip_ecn.h> | 66 | #include <netinet/ip_ecn.h> | |
67 | #endif | 67 | #endif | |
68 | 68 | |||
69 | #include <netipsec/key.h> | 69 | #include <netipsec/key.h> | |
70 | #include <netipsec/ipsecif.h> | 70 | #include <netipsec/ipsecif.h> | |
71 | 71 | |||
72 | #include <net/if_ipsec.h> | 72 | #include <net/if_ipsec.h> | |
73 | 73 | |||
74 | static int ipsecif_set_natt_ports(struct ipsec_variant *, struct mbuf *); | |||
74 | static void ipsecif4_input(struct mbuf *, int, int, void *); | 75 | static void ipsecif4_input(struct mbuf *, int, int, void *); | |
75 | static int ipsecif4_output(struct ipsec_variant *, int, struct mbuf *); | 76 | static int ipsecif4_output(struct ipsec_variant *, int, struct mbuf *); | |
76 | static int ipsecif4_filter4(const struct ip *, struct ipsec_variant *, | 77 | static int ipsecif4_filter4(const struct ip *, struct ipsec_variant *, | |
77 | struct ifnet *); | 78 | struct ifnet *); | |
78 | 79 | |||
79 | #ifdef INET6 | 80 | #ifdef INET6 | |
80 | static int ipsecif6_input(struct mbuf **, int *, int, void *); | 81 | static int ipsecif6_input(struct mbuf **, int *, int, void *); | |
81 | static int ipsecif6_output(struct ipsec_variant *, int, struct mbuf *); | 82 | static int ipsecif6_output(struct ipsec_variant *, int, struct mbuf *); | |
82 | static int ipsecif6_filter6(const struct ip6_hdr *, struct ipsec_variant *, | 83 | static int ipsecif6_filter6(const struct ip6_hdr *, struct ipsec_variant *, | |
83 | struct ifnet *); | 84 | struct ifnet *); | |
84 | #endif | 85 | #endif | |
85 | 86 | |||
86 | static int ip_ipsec_ttl = IPSEC_TTL; | 87 | static int ip_ipsec_ttl = IPSEC_TTL; | |
@@ -92,26 +93,52 @@ static int ip6_ipsec_copy_tos = 0; | @@ -92,26 +93,52 @@ static int ip6_ipsec_copy_tos = 0; | |||
92 | #endif | 93 | #endif | |
93 | 94 | |||
94 | static const struct encapsw ipsecif4_encapsw = { | 95 | static const struct encapsw ipsecif4_encapsw = { | |
95 | .encapsw4 = { | 96 | .encapsw4 = { | |
96 | .pr_input = ipsecif4_input, | 97 | .pr_input = ipsecif4_input, | |
97 | .pr_ctlinput = NULL, | 98 | .pr_ctlinput = NULL, | |
98 | } | 99 | } | |
99 | }; | 100 | }; | |
100 | 101 | |||
101 | #ifdef INET6 | 102 | #ifdef INET6 | |
102 | static const struct encapsw ipsecif6_encapsw; | 103 | static const struct encapsw ipsecif6_encapsw; | |
103 | #endif | 104 | #endif | |
104 | 105 | |||
106 | static int | |||
107 | ipsecif_set_natt_ports(struct ipsec_variant *var, struct mbuf *m) | |||
108 | { | |||
109 | ||||
110 | KASSERT(if_ipsec_heldref_variant(var)); | |||
111 | ||||
112 | if (var->iv_sport || var->iv_dport) { | |||
113 | struct m_tag *mtag; | |||
114 | ||||
115 | mtag = m_tag_get(PACKET_TAG_IPSEC_NAT_T_PORTS, | |||
116 | sizeof(uint16_t) + sizeof(uint16_t), M_DONTWAIT); | |||
117 | if (mtag) { | |||
118 | uint16_t *natt_port; | |||
119 | ||||
120 | natt_port = (uint16_t *)(mtag + 1); | |||
121 | natt_port[0] = var->iv_dport; | |||
122 | natt_port[1] = var->iv_sport; | |||
123 | m_tag_prepend(m, mtag); | |||
124 | } else { | |||
125 | return ENOBUFS; | |||
126 | } | |||
127 | } | |||
128 | ||||
129 | return 0; | |||
130 | } | |||
131 | ||||
105 | static struct mbuf * | 132 | static struct mbuf * | |
106 | ipsecif4_prepend_hdr(struct ipsec_variant *var, struct mbuf *m, | 133 | ipsecif4_prepend_hdr(struct ipsec_variant *var, struct mbuf *m, | |
107 | uint8_t proto, uint8_t tos) | 134 | uint8_t proto, uint8_t tos) | |
108 | { | 135 | { | |
109 | struct ip *ip; | 136 | struct ip *ip; | |
110 | struct sockaddr_in *src, *dst; | 137 | struct sockaddr_in *src, *dst; | |
111 | 138 | |||
112 | src = satosin(var->iv_psrc); | 139 | src = satosin(var->iv_psrc); | |
113 | dst = satosin(var->iv_pdst); | 140 | dst = satosin(var->iv_pdst); | |
114 | 141 | |||
115 | if (in_nullhost(src->sin_addr) || in_nullhost(src->sin_addr) || | 142 | if (in_nullhost(src->sin_addr) || in_nullhost(src->sin_addr) || | |
116 | src->sin_addr.s_addr == INADDR_BROADCAST || | 143 | src->sin_addr.s_addr == INADDR_BROADCAST || | |
117 | dst->sin_addr.s_addr == INADDR_BROADCAST) { | 144 | dst->sin_addr.s_addr == INADDR_BROADCAST) { | |
@@ -384,26 +411,33 @@ ipsecif4_output(struct ipsec_variant *va | @@ -384,26 +411,33 @@ ipsecif4_output(struct ipsec_variant *va | |||
384 | } | 411 | } | |
385 | 412 | |||
386 | /* | 413 | /* | |
387 | * Normal netipsec's NAT-T fragmentation is done in ip_output(). | 414 | * Normal netipsec's NAT-T fragmentation is done in ip_output(). | |
388 | * See "natt_frag" processing. | 415 | * See "natt_frag" processing. | |
389 | * However, ipsec(4) interface's one is not done in the same way, | 416 | * However, ipsec(4) interface's one is not done in the same way, | |
390 | * so we must do NAT-T fragmentation by own code. | 417 | * so we must do NAT-T fragmentation by own code. | |
391 | */ | 418 | */ | |
392 | /* NAT-T ESP fragmentation */ | 419 | /* NAT-T ESP fragmentation */ | |
393 | mtu = ipsecif4_needfrag(m, sp->req); | 420 | mtu = ipsecif4_needfrag(m, sp->req); | |
394 | if (mtu > 0) | 421 | if (mtu > 0) | |
395 | return ipsecif4_fragout(var, family, m, mtu); | 422 | return ipsecif4_fragout(var, family, m, mtu); | |
396 | 423 | |||
424 | /* set NAT-T ports */ | |||
425 | error = ipsecif_set_natt_ports(var, m); | |||
426 | if (error) { | |||
427 | m_freem(m); | |||
428 | goto done; | |||
429 | } | |||
430 | ||||
397 | /* IPsec output */ | 431 | /* IPsec output */ | |
398 | IP_STATINC(IP_STAT_LOCALOUT); | 432 | IP_STATINC(IP_STAT_LOCALOUT); | |
399 | error = ipsec4_process_packet(m, sp->req, &sa_mtu); | 433 | error = ipsec4_process_packet(m, sp->req, &sa_mtu); | |
400 | if (error == ENOENT) | 434 | if (error == ENOENT) | |
401 | error = 0; | 435 | error = 0; | |
402 | /* | 436 | /* | |
403 | * frangmentation is already done in ipsecif4_fragout(), | 437 | * frangmentation is already done in ipsecif4_fragout(), | |
404 | * so ipsec4_process_packet() must not do fragmentation here. | 438 | * so ipsec4_process_packet() must not do fragmentation here. | |
405 | */ | 439 | */ | |
406 | KASSERT(sa_mtu == 0); | 440 | KASSERT(sa_mtu == 0); | |
407 | 441 | |||
408 | done: | 442 | done: | |
409 | return error; | 443 | return error; | |
@@ -576,36 +610,44 @@ ipsecif6_output(struct ipsec_variant *va | @@ -576,36 +610,44 @@ ipsecif6_output(struct ipsec_variant *va | |||
576 | return ENETUNREACH; | 610 | return ENETUNREACH; | |
577 | } | 611 | } | |
578 | 612 | |||
579 | if (rt->rt_ifp == ifp) { | 613 | if (rt->rt_ifp == ifp) { | |
580 | rtcache_unref(rt, &iro->ir_ro); | 614 | rtcache_unref(rt, &iro->ir_ro); | |
581 | rtcache_free(&iro->ir_ro); | 615 | rtcache_free(&iro->ir_ro); | |
582 | mutex_exit(iro->ir_lock); | 616 | mutex_exit(iro->ir_lock); | |
583 | percpu_putref(sc->ipsec_ro_percpu); | 617 | percpu_putref(sc->ipsec_ro_percpu); | |
584 | m_freem(m); | 618 | m_freem(m); | |
585 | return ENETUNREACH; | 619 | return ENETUNREACH; | |
586 | } | 620 | } | |
587 | rtcache_unref(rt, &iro->ir_ro); | 621 | rtcache_unref(rt, &iro->ir_ro); | |
588 | 622 | |||
623 | /* set NAT-T ports */ | |||
624 | error = ipsecif_set_natt_ports(var, m); | |||
625 | if (error) { | |||
626 | m_freem(m); | |||
627 | goto out; | |||
628 | } | |||
629 | ||||
589 | /* | 630 | /* | |
590 | * force fragmentation to minimum MTU, to avoid path MTU discovery. | 631 | * force fragmentation to minimum MTU, to avoid path MTU discovery. | |
591 | * it is too painful to ask for resend of inner packet, to achieve | 632 | * it is too painful to ask for resend of inner packet, to achieve | |
592 | * path MTU discovery for encapsulated packets. | 633 | * path MTU discovery for encapsulated packets. | |
593 | */ | 634 | */ | |
594 | error = ip6_output(m, 0, &iro->ir_ro, | 635 | error = ip6_output(m, 0, &iro->ir_ro, | |
595 | ip6_ipsec_pmtu ? 0 : IPV6_MINMTU, 0, NULL, NULL); | 636 | ip6_ipsec_pmtu ? 0 : IPV6_MINMTU, 0, NULL, NULL); | |
637 | ||||
638 | out: | |||
596 | if (error) | 639 | if (error) | |
597 | rtcache_free(&iro->ir_ro); | 640 | rtcache_free(&iro->ir_ro); | |
598 | ||||
599 | mutex_exit(iro->ir_lock); | 641 | mutex_exit(iro->ir_lock); | |
600 | percpu_putref(sc->ipsec_ro_percpu); | 642 | percpu_putref(sc->ipsec_ro_percpu); | |
601 | 643 | |||
602 | return error; | 644 | return error; | |
603 | } | 645 | } | |
604 | #endif /* INET6 */ | 646 | #endif /* INET6 */ | |
605 | 647 | |||
606 | static void | 648 | static void | |
607 | ipsecif4_input(struct mbuf *m, int off, int proto, void *eparg) | 649 | ipsecif4_input(struct mbuf *m, int off, int proto, void *eparg) | |
608 | { | 650 | { | |
609 | struct ifnet *ipsecp; | 651 | struct ifnet *ipsecp; | |
610 | struct ipsec_softc *sc = eparg; | 652 | struct ipsec_softc *sc = eparg; | |
611 | struct ipsec_variant *var; | 653 | struct ipsec_variant *var; |
--- src/sys/netipsec/key.c 2018/12/26 08:55:14 1.259
+++ src/sys/netipsec/key.c 2018/12/26 08:58:51 1.260
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: key.c,v 1.259 2018/12/26 08:55:14 knakahara Exp $ */ | 1 | /* $NetBSD: key.c,v 1.260 2018/12/26 08:58:51 knakahara Exp $ */ | |
2 | /* $FreeBSD: key.c,v 1.3.2.3 2004/02/14 22:23:23 bms Exp $ */ | 2 | /* $FreeBSD: key.c,v 1.3.2.3 2004/02/14 22:23:23 bms Exp $ */ | |
3 | /* $KAME: key.c,v 1.191 2001/06/27 10:46:49 sakane Exp $ */ | 3 | /* $KAME: key.c,v 1.191 2001/06/27 10:46:49 sakane Exp $ */ | |
4 | 4 | |||
5 | /* | 5 | /* | |
6 | * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. | 6 | * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. | |
7 | * All rights reserved. | 7 | * All rights reserved. | |
8 | * | 8 | * | |
9 | * Redistribution and use in source and binary forms, with or without | 9 | * Redistribution and use in source and binary forms, with or without | |
10 | * modification, are permitted provided that the following conditions | 10 | * modification, are permitted provided that the following conditions | |
11 | * are met: | 11 | * are met: | |
12 | * 1. Redistributions of source code must retain the above copyright | 12 | * 1. Redistributions of source code must retain the above copyright | |
13 | * notice, this list of conditions and the following disclaimer. | 13 | * notice, this list of conditions and the following disclaimer. | |
14 | * 2. Redistributions in binary form must reproduce the above copyright | 14 | * 2. Redistributions in binary form must reproduce the above copyright | |
@@ -22,27 +22,27 @@ | @@ -22,27 +22,27 @@ | |||
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE | 24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE | |
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
31 | * SUCH DAMAGE. | 31 | * SUCH DAMAGE. | |
32 | */ | 32 | */ | |
33 | 33 | |||
34 | #include <sys/cdefs.h> | 34 | #include <sys/cdefs.h> | |
35 | __KERNEL_RCSID(0, "$NetBSD: key.c,v 1.259 2018/12/26 08:55:14 knakahara Exp $"); | 35 | __KERNEL_RCSID(0, "$NetBSD: key.c,v 1.260 2018/12/26 08:58:51 knakahara Exp $"); | |
36 | 36 | |||
37 | /* | 37 | /* | |
38 | * This code is referred to RFC 2367 | 38 | * This code is referred to RFC 2367 | |
39 | */ | 39 | */ | |
40 | 40 | |||
41 | #if defined(_KERNEL_OPT) | 41 | #if defined(_KERNEL_OPT) | |
42 | #include "opt_inet.h" | 42 | #include "opt_inet.h" | |
43 | #include "opt_ipsec.h" | 43 | #include "opt_ipsec.h" | |
44 | #include "opt_gateway.h" | 44 | #include "opt_gateway.h" | |
45 | #include "opt_net_mpsafe.h" | 45 | #include "opt_net_mpsafe.h" | |
46 | #endif | 46 | #endif | |
47 | 47 | |||
48 | #include <sys/types.h> | 48 | #include <sys/types.h> | |
@@ -4557,33 +4557,33 @@ key_saidx_match( | @@ -4557,33 +4557,33 @@ key_saidx_match( | |||
4557 | if (flag == CMP_MODE_REQID) { | 4557 | if (flag == CMP_MODE_REQID) { | |
4558 | if (saidx0->mode != IPSEC_MODE_ANY && | 4558 | if (saidx0->mode != IPSEC_MODE_ANY && | |
4559 | saidx0->mode != saidx1->mode) | 4559 | saidx0->mode != saidx1->mode) | |
4560 | return 0; | 4560 | return 0; | |
4561 | } | 4561 | } | |
4562 | 4562 | |||
4563 | 4563 | |||
4564 | sa0src = &saidx0->src.sa; | 4564 | sa0src = &saidx0->src.sa; | |
4565 | sa0dst = &saidx0->dst.sa; | 4565 | sa0dst = &saidx0->dst.sa; | |
4566 | sa1src = &saidx1->src.sa; | 4566 | sa1src = &saidx1->src.sa; | |
4567 | sa1dst = &saidx1->dst.sa; | 4567 | sa1dst = &saidx1->dst.sa; | |
4568 | /* | 4568 | /* | |
4569 | * If NAT-T is enabled, check ports for tunnel mode. | 4569 | * If NAT-T is enabled, check ports for tunnel mode. | |
4570 | * Don't do it for transport mode, as there is no | 4570 | * For ipsecif(4), check ports for transport mode, too. | |
4571 | * port information available in the SP. | 4571 | * Don't check ports if they are set to zero | |
4572 | * Also don't check ports if they are set to zero | |||
4573 | * in the SPD: This means we have a non-generated | 4572 | * in the SPD: This means we have a non-generated | |
4574 | * SPD which can't know UDP ports. | 4573 | * SPD which can't know UDP ports. | |
4575 | */ | 4574 | */ | |
4576 | if (saidx1->mode == IPSEC_MODE_TUNNEL) | 4575 | if (saidx1->mode == IPSEC_MODE_TUNNEL || | |
4576 | saidx1->mode == IPSEC_MODE_TRANSPORT) | |||
4577 | chkport = PORT_LOOSE; | 4577 | chkport = PORT_LOOSE; | |
4578 | else | 4578 | else | |
4579 | chkport = PORT_NONE; | 4579 | chkport = PORT_NONE; | |
4580 | 4580 | |||
4581 | if (!key_sockaddr_match(sa0src, sa1src, chkport)) { | 4581 | if (!key_sockaddr_match(sa0src, sa1src, chkport)) { | |
4582 | return 0; | 4582 | return 0; | |
4583 | } | 4583 | } | |
4584 | if (!key_sockaddr_match(sa0dst, sa1dst, chkport)) { | 4584 | if (!key_sockaddr_match(sa0dst, sa1dst, chkport)) { | |
4585 | return 0; | 4585 | return 0; | |
4586 | } | 4586 | } | |
4587 | } | 4587 | } | |
4588 | 4588 | |||
4589 | return 1; | 4589 | return 1; |