| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: ipsec.c,v 1.147 2018/02/28 10:09:17 maxv Exp $ */ | | 1 | /* $NetBSD: ipsec.c,v 1.148 2018/02/28 10:16:19 maxv Exp $ */ |
2 | /* $FreeBSD: src/sys/netipsec/ipsec.c,v 1.2.2.2 2003/07/01 01:38:13 sam Exp $ */ | | 2 | /* $FreeBSD: src/sys/netipsec/ipsec.c,v 1.2.2.2 2003/07/01 01:38:13 sam Exp $ */ |
3 | /* $KAME: ipsec.c,v 1.103 2001/05/24 07:14:18 sakane Exp $ */ | | 3 | /* $KAME: ipsec.c,v 1.103 2001/05/24 07:14:18 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: ipsec.c,v 1.147 2018/02/28 10:09:17 maxv Exp $"); | | 35 | __KERNEL_RCSID(0, "$NetBSD: ipsec.c,v 1.148 2018/02/28 10:16:19 maxv Exp $"); |
36 | | | 36 | |
37 | /* | | 37 | /* |
38 | * IPsec controller part. | | 38 | * IPsec controller part. |
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 | #endif | | 44 | #endif |
45 | | | 45 | |
46 | #include <sys/param.h> | | 46 | #include <sys/param.h> |
47 | #include <sys/systm.h> | | 47 | #include <sys/systm.h> |
48 | #include <sys/mbuf.h> | | 48 | #include <sys/mbuf.h> |
| @@ -160,30 +160,27 @@ int crypto_support = 0; | | | @@ -160,30 +160,27 @@ int crypto_support = 0; |
160 | | | 160 | |
161 | static struct secpolicy *ipsec_getpolicybysock(struct mbuf *, u_int, | | 161 | static struct secpolicy *ipsec_getpolicybysock(struct mbuf *, u_int, |
162 | struct inpcb_hdr *, int *); | | 162 | struct inpcb_hdr *, int *); |
163 | | | 163 | |
164 | #ifdef INET6 | | 164 | #ifdef INET6 |
165 | int ip6_esp_trans_deflev = IPSEC_LEVEL_USE; | | 165 | int ip6_esp_trans_deflev = IPSEC_LEVEL_USE; |
166 | int ip6_esp_net_deflev = IPSEC_LEVEL_USE; | | 166 | int ip6_esp_net_deflev = IPSEC_LEVEL_USE; |
167 | int ip6_ah_trans_deflev = IPSEC_LEVEL_USE; | | 167 | int ip6_ah_trans_deflev = IPSEC_LEVEL_USE; |
168 | int ip6_ah_net_deflev = IPSEC_LEVEL_USE; | | 168 | int ip6_ah_net_deflev = IPSEC_LEVEL_USE; |
169 | struct secpolicy ip6_def_policy; | | 169 | struct secpolicy ip6_def_policy; |
170 | int ip6_ipsec_ecn = 0; /* ECN ignore(-1)/forbidden(0)/allowed(1) */ | | 170 | int ip6_ipsec_ecn = 0; /* ECN ignore(-1)/forbidden(0)/allowed(1) */ |
171 | #endif | | 171 | #endif |
172 | | | 172 | |
173 | static int ipsec4_setspidx_inpcb(struct mbuf *, struct inpcb *); | | 173 | static int ipsec_setspidx_inpcb(struct mbuf *, void *); |
174 | #ifdef INET6 | | | |
175 | static int ipsec6_setspidx_in6pcb(struct mbuf *, struct in6pcb *); | | | |
176 | #endif | | | |
177 | static int ipsec_setspidx(struct mbuf *, struct secpolicyindex *, int); | | 174 | static int ipsec_setspidx(struct mbuf *, struct secpolicyindex *, int); |
178 | static void ipsec4_get_ulp(struct mbuf *m, struct secpolicyindex *, int); | | 175 | static void ipsec4_get_ulp(struct mbuf *m, struct secpolicyindex *, int); |
179 | static int ipsec4_setspidx_ipaddr(struct mbuf *, struct secpolicyindex *); | | 176 | static int ipsec4_setspidx_ipaddr(struct mbuf *, struct secpolicyindex *); |
180 | #ifdef INET6 | | 177 | #ifdef INET6 |
181 | static void ipsec6_get_ulp(struct mbuf *m, struct secpolicyindex *, int); | | 178 | static void ipsec6_get_ulp(struct mbuf *m, struct secpolicyindex *, int); |
182 | static int ipsec6_setspidx_ipaddr(struct mbuf *, struct secpolicyindex *); | | 179 | static int ipsec6_setspidx_ipaddr(struct mbuf *, struct secpolicyindex *); |
183 | #endif | | 180 | #endif |
184 | static void ipsec_delpcbpolicy(struct inpcbpolicy *); | | 181 | static void ipsec_delpcbpolicy(struct inpcbpolicy *); |
185 | #if 0 /* unused */ | | 182 | #if 0 /* unused */ |
186 | static struct secpolicy *ipsec_deepcopy_policy(const struct secpolicy *); | | 183 | static struct secpolicy *ipsec_deepcopy_policy(const struct secpolicy *); |
187 | #endif | | 184 | #endif |
188 | static void ipsec_destroy_policy(struct secpolicy *); | | 185 | static void ipsec_destroy_policy(struct secpolicy *); |
189 | static int ipsec_sp_reject(const struct secpolicy *, const struct mbuf *); | | 186 | static int ipsec_sp_reject(const struct secpolicy *, const struct mbuf *); |
| @@ -429,35 +426,35 @@ ipsec_getpolicybysock(struct mbuf *m, u_ | | | @@ -429,35 +426,35 @@ ipsec_getpolicybysock(struct mbuf *m, u_ |
429 | /* If we have a cached entry, and if it is still valid, use it. */ | | 426 | /* If we have a cached entry, and if it is still valid, use it. */ |
430 | IPSEC_STATINC(IPSEC_STAT_SPDCACHELOOKUP); | | 427 | IPSEC_STATINC(IPSEC_STAT_SPDCACHELOOKUP); |
431 | currsp = ipsec_checkpcbcache(m, inph->inph_sp, dir); | | 428 | currsp = ipsec_checkpcbcache(m, inph->inph_sp, dir); |
432 | if (currsp) { | | 429 | if (currsp) { |
433 | *error = 0; | | 430 | *error = 0; |
434 | return currsp; | | 431 | return currsp; |
435 | } | | 432 | } |
436 | IPSEC_STATINC(IPSEC_STAT_SPDCACHEMISS); | | 433 | IPSEC_STATINC(IPSEC_STAT_SPDCACHEMISS); |
437 | | | 434 | |
438 | switch (af) { | | 435 | switch (af) { |
439 | case AF_INET: { | | 436 | case AF_INET: { |
440 | struct inpcb *in4p = (struct inpcb *)inph; | | 437 | struct inpcb *in4p = (struct inpcb *)inph; |
441 | /* set spidx in pcb */ | | 438 | /* set spidx in pcb */ |
442 | *error = ipsec4_setspidx_inpcb(m, in4p); | | 439 | *error = ipsec_setspidx_inpcb(m, in4p); |
443 | pcbsp = in4p->inp_sp; | | 440 | pcbsp = in4p->inp_sp; |
444 | break; | | 441 | break; |
445 | } | | 442 | } |
446 | #if defined(INET6) | | 443 | #if defined(INET6) |
447 | case AF_INET6: { | | 444 | case AF_INET6: { |
448 | struct in6pcb *in6p = (struct in6pcb *)inph; | | 445 | struct in6pcb *in6p = (struct in6pcb *)inph; |
449 | /* set spidx in pcb */ | | 446 | /* set spidx in pcb */ |
450 | *error = ipsec6_setspidx_in6pcb(m, in6p); | | 447 | *error = ipsec_setspidx_inpcb(m, in6p); |
451 | pcbsp = in6p->in6p_sp; | | 448 | pcbsp = in6p->in6p_sp; |
452 | break; | | 449 | break; |
453 | } | | 450 | } |
454 | #endif | | 451 | #endif |
455 | default: | | 452 | default: |
456 | *error = EPFNOSUPPORT; | | 453 | *error = EPFNOSUPPORT; |
457 | break; | | 454 | break; |
458 | } | | 455 | } |
459 | if (*error) | | 456 | if (*error) |
460 | return NULL; | | 457 | return NULL; |
461 | | | 458 | |
462 | KASSERT(pcbsp != NULL); | | 459 | KASSERT(pcbsp != NULL); |
463 | switch (dir) { | | 460 | switch (dir) { |
| @@ -784,74 +781,49 @@ ipsec4_forward(struct mbuf *m, int *dest | | | @@ -784,74 +781,49 @@ ipsec4_forward(struct mbuf *m, int *dest |
784 | *destmtu = rt->rt_rmx.rmx_mtu ? | | 781 | *destmtu = rt->rt_rmx.rmx_mtu ? |
785 | rt->rt_rmx.rmx_mtu : rt->rt_ifp->if_mtu; | | 782 | rt->rt_rmx.rmx_mtu : rt->rt_ifp->if_mtu; |
786 | *destmtu -= ipsechdr; | | 783 | *destmtu -= ipsechdr; |
787 | } | | 784 | } |
788 | rtcache_unref(rt, ro); | | 785 | rtcache_unref(rt, ro); |
789 | KEY_SA_UNREF(&sav); | | 786 | KEY_SA_UNREF(&sav); |
790 | } | | 787 | } |
791 | } | | 788 | } |
792 | KEY_SP_UNREF(&sp); | | 789 | KEY_SP_UNREF(&sp); |
793 | return 0; | | 790 | return 0; |
794 | } | | 791 | } |
795 | | | 792 | |
796 | static int | | 793 | static int |
797 | ipsec4_setspidx_inpcb(struct mbuf *m, struct inpcb *pcb) | | 794 | ipsec_setspidx_inpcb(struct mbuf *m, void *pcb) |
798 | { | | 795 | { |
| | | 796 | struct inpcb_hdr *inph = (struct inpcb_hdr *)pcb; |
799 | int error; | | 797 | int error; |
800 | | | 798 | |
801 | KASSERT(pcb != NULL); | | 799 | KASSERT(inph != NULL); |
802 | KASSERT(pcb->inp_sp != NULL); | | 800 | KASSERT(inph->inph_sp != NULL); |
803 | KASSERT(pcb->inp_sp->sp_out != NULL); | | 801 | KASSERT(inph->inph_sp->sp_out != NULL); |
804 | KASSERT(pcb->inp_sp->sp_in != NULL); | | 802 | KASSERT(inph->inph_sp->sp_in != NULL); |
805 | | | | |
806 | error = ipsec_setspidx(m, &pcb->inp_sp->sp_in->spidx, 1); | | | |
807 | if (error == 0) { | | | |
808 | pcb->inp_sp->sp_in->spidx.dir = IPSEC_DIR_INBOUND; | | | |
809 | pcb->inp_sp->sp_out->spidx = pcb->inp_sp->sp_in->spidx; | | | |
810 | pcb->inp_sp->sp_out->spidx.dir = IPSEC_DIR_OUTBOUND; | | | |
811 | } else { | | | |
812 | memset(&pcb->inp_sp->sp_in->spidx, 0, | | | |
813 | sizeof(pcb->inp_sp->sp_in->spidx)); | | | |
814 | memset(&pcb->inp_sp->sp_out->spidx, 0, | | | |
815 | sizeof(pcb->inp_sp->sp_out->spidx)); | | | |
816 | } | | | |
817 | return error; | | | |
818 | } | | | |
819 | | | | |
820 | #ifdef INET6 | | | |
821 | static int | | | |
822 | ipsec6_setspidx_in6pcb(struct mbuf *m, struct in6pcb *pcb) | | | |
823 | { | | | |
824 | int error; | | | |
825 | | | | |
826 | KASSERT(pcb != NULL); | | | |
827 | KASSERT(pcb->in6p_sp != NULL); | | | |
828 | KASSERT(pcb->in6p_sp->sp_out != NULL); | | | |
829 | KASSERT(pcb->in6p_sp->sp_in != NULL); | | | |
830 | | | 803 | |
831 | error = ipsec_setspidx(m, &pcb->in6p_sp->sp_in->spidx, 1); | | 804 | error = ipsec_setspidx(m, &inph->inph_sp->sp_in->spidx, 1); |
832 | if (error == 0) { | | 805 | if (error == 0) { |
833 | pcb->in6p_sp->sp_in->spidx.dir = IPSEC_DIR_INBOUND; | | 806 | inph->inph_sp->sp_in->spidx.dir = IPSEC_DIR_INBOUND; |
834 | pcb->in6p_sp->sp_out->spidx = pcb->in6p_sp->sp_in->spidx; | | 807 | inph->inph_sp->sp_out->spidx = inph->inph_sp->sp_in->spidx; |
835 | pcb->in6p_sp->sp_out->spidx.dir = IPSEC_DIR_OUTBOUND; | | 808 | inph->inph_sp->sp_out->spidx.dir = IPSEC_DIR_OUTBOUND; |
836 | } else { | | 809 | } else { |
837 | memset(&pcb->in6p_sp->sp_in->spidx, 0, | | 810 | memset(&inph->inph_sp->sp_in->spidx, 0, |
838 | sizeof(pcb->in6p_sp->sp_in->spidx)); | | 811 | sizeof(inph->inph_sp->sp_in->spidx)); |
839 | memset(&pcb->in6p_sp->sp_out->spidx, 0, | | 812 | memset(&inph->inph_sp->sp_out->spidx, 0, |
840 | sizeof(pcb->in6p_sp->sp_out->spidx)); | | 813 | sizeof(inph->inph_sp->sp_out->spidx)); |
841 | } | | 814 | } |
842 | return error; | | 815 | return error; |
843 | } | | 816 | } |
844 | #endif | | | |
845 | | | 817 | |
846 | /* | | 818 | /* |
847 | * configure security policy index (src/dst/proto/sport/dport) | | 819 | * configure security policy index (src/dst/proto/sport/dport) |
848 | * by looking at the content of mbuf. | | 820 | * by looking at the content of mbuf. |
849 | * the caller is responsible for error recovery (like clearing up spidx). | | 821 | * the caller is responsible for error recovery (like clearing up spidx). |
850 | */ | | 822 | */ |
851 | static int | | 823 | static int |
852 | ipsec_setspidx(struct mbuf *m, struct secpolicyindex *spidx, int needport) | | 824 | ipsec_setspidx(struct mbuf *m, struct secpolicyindex *spidx, int needport) |
853 | { | | 825 | { |
854 | struct ip *ip = NULL; | | 826 | struct ip *ip = NULL; |
855 | struct ip ipbuf; | | 827 | struct ip ipbuf; |
856 | u_int v; | | 828 | u_int v; |
857 | struct mbuf *n; | | 829 | struct mbuf *n; |