Wed Jun 14 02:00:44 2017 UTC ()
KNF


(ozaki-r)
diff -r1.99 -r1.100 src/sys/netipsec/ipsec.c

cvs diff -r1.99 -r1.100 src/sys/netipsec/ipsec.c (expand / switch to unified diff)

--- src/sys/netipsec/ipsec.c 2017/06/02 03:41:20 1.99
+++ src/sys/netipsec/ipsec.c 2017/06/14 02:00:43 1.100
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: ipsec.c,v 1.99 2017/06/02 03:41:20 ozaki-r Exp $ */ 1/* $NetBSD: ipsec.c,v 1.100 2017/06/14 02:00:43 ozaki-r Exp $ */
2/* $FreeBSD: /usr/local/www/cvsroot/FreeBSD/src/sys/netipsec/ipsec.c,v 1.2.2.2 2003/07/01 01:38:13 sam Exp $ */ 2/* $FreeBSD: /usr/local/www/cvsroot/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.99 2017/06/02 03:41:20 ozaki-r Exp $"); 35__KERNEL_RCSID(0, "$NetBSD: ipsec.c,v 1.100 2017/06/14 02:00:43 ozaki-r 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>
@@ -227,30 +227,28 @@ ipsec_checkpcbcache(struct mbuf *m, stru @@ -227,30 +227,28 @@ ipsec_checkpcbcache(struct mbuf *m, stru
227 if (pcbsp->sp_cache[dir].cachesp->state != IPSEC_SPSTATE_ALIVE) { 227 if (pcbsp->sp_cache[dir].cachesp->state != IPSEC_SPSTATE_ALIVE) {
228 ipsec_invalpcbcache(pcbsp, dir); 228 ipsec_invalpcbcache(pcbsp, dir);
229 return NULL; 229 return NULL;
230 } 230 }
231 if ((pcbsp->sp_cacheflags & IPSEC_PCBSP_CONNECTED) == 0) { 231 if ((pcbsp->sp_cacheflags & IPSEC_PCBSP_CONNECTED) == 0) {
232 if (ipsec_setspidx(m, &spidx, 1) != 0) 232 if (ipsec_setspidx(m, &spidx, 1) != 0)
233 return NULL; 233 return NULL;
234 234
235 /* 235 /*
236 * We have to make an exact match here since the cached rule 236 * We have to make an exact match here since the cached rule
237 * might have lower priority than a rule that would otherwise 237 * might have lower priority than a rule that would otherwise
238 * have matched the packet.  238 * have matched the packet.
239 */ 239 */
240 
241 if (memcmp(&pcbsp->sp_cache[dir].cacheidx, &spidx, sizeof(spidx)))  240 if (memcmp(&pcbsp->sp_cache[dir].cacheidx, &spidx, sizeof(spidx)))
242 return NULL; 241 return NULL;
243  
244 } else { 242 } else {
245 /* 243 /*
246 * The pcb is connected, and the L4 code is sure that: 244 * The pcb is connected, and the L4 code is sure that:
247 * - outgoing side uses inp_[lf]addr 245 * - outgoing side uses inp_[lf]addr
248 * - incoming side looks up policy after inpcb lookup 246 * - incoming side looks up policy after inpcb lookup
249 * and address pair is know to be stable. We do not need 247 * and address pair is know to be stable. We do not need
250 * to generate spidx again, nor check the address match again. 248 * to generate spidx again, nor check the address match again.
251 * 249 *
252 * For IPv4/v6 SOCK_STREAM sockets, this assumptions holds 250 * For IPv4/v6 SOCK_STREAM sockets, this assumptions holds
253 * and there are calls to ipsec_pcbconn() from in_pcbconnect(). 251 * and there are calls to ipsec_pcbconn() from in_pcbconnect().
254 */ 252 */
255 } 253 }
256 254
@@ -286,56 +284,56 @@ ipsec_fillpcbcache(struct inpcbpolicy *p @@ -286,56 +284,56 @@ ipsec_fillpcbcache(struct inpcbpolicy *p
286 "DP cause refcnt++:%d SP:%p\n", 284 "DP cause refcnt++:%d SP:%p\n",
287 pcbsp->sp_cache[dir].cachesp->refcnt, 285 pcbsp->sp_cache[dir].cachesp->refcnt,
288 pcbsp->sp_cache[dir].cachesp); 286 pcbsp->sp_cache[dir].cachesp);
289 287
290 /* 288 /*
291 * If the PCB is connected, we can remember a hint to 289 * If the PCB is connected, we can remember a hint to
292 * possibly short-circuit IPsec processing in other places. 290 * possibly short-circuit IPsec processing in other places.
293 */ 291 */
294 if (pcbsp->sp_cacheflags & IPSEC_PCBSP_CONNECTED) { 292 if (pcbsp->sp_cacheflags & IPSEC_PCBSP_CONNECTED) {
295 switch (pcbsp->sp_cache[dir].cachesp->policy) { 293 switch (pcbsp->sp_cache[dir].cachesp->policy) {
296 case IPSEC_POLICY_NONE: 294 case IPSEC_POLICY_NONE:
297 case IPSEC_POLICY_BYPASS: 295 case IPSEC_POLICY_BYPASS:
298 pcbsp->sp_cache[dir].cachehint = 296 pcbsp->sp_cache[dir].cachehint =
299 IPSEC_PCBHINT_NO; 297 IPSEC_PCBHINT_NO;
300 break; 298 break;
301 default: 299 default:
302 pcbsp->sp_cache[dir].cachehint = 300 pcbsp->sp_cache[dir].cachehint =
303 IPSEC_PCBHINT_YES; 301 IPSEC_PCBHINT_YES;
304 } 302 }
305 } 303 }
306 } 304 }
307 pcbsp->sp_cache[dir].cachegen = ipsec_spdgen; 305 pcbsp->sp_cache[dir].cachegen = ipsec_spdgen;
308 306
309 return 0; 307 return 0;
310} 308}
311 309
312static int 310static int
313ipsec_invalpcbcache(struct inpcbpolicy *pcbsp, int dir) 311ipsec_invalpcbcache(struct inpcbpolicy *pcbsp, int dir)
314{ 312{
315 int i; 313 int i;
316 314
317 KASSERT(inph_locked(pcbsp->sp_inph)); 315 KASSERT(inph_locked(pcbsp->sp_inph));
318 316
319 for (i = IPSEC_DIR_INBOUND; i <= IPSEC_DIR_OUTBOUND; i++) { 317 for (i = IPSEC_DIR_INBOUND; i <= IPSEC_DIR_OUTBOUND; i++) {
320 if (dir != IPSEC_DIR_ANY && i != dir) 318 if (dir != IPSEC_DIR_ANY && i != dir)
321 continue; 319 continue;
322 if (pcbsp->sp_cache[i].cachesp) 320 if (pcbsp->sp_cache[i].cachesp)
323 KEY_FREESP(&pcbsp->sp_cache[i].cachesp); 321 KEY_FREESP(&pcbsp->sp_cache[i].cachesp);
324 pcbsp->sp_cache[i].cachesp = NULL; 322 pcbsp->sp_cache[i].cachesp = NULL;
325 pcbsp->sp_cache[i].cachehint = IPSEC_PCBHINT_UNKNOWN; 323 pcbsp->sp_cache[i].cachehint = IPSEC_PCBHINT_UNKNOWN;
326 pcbsp->sp_cache[i].cachegen = 0; 324 pcbsp->sp_cache[i].cachegen = 0;
327 memset(&pcbsp->sp_cache[i].cacheidx, 0, 325 memset(&pcbsp->sp_cache[i].cacheidx, 0,
328 sizeof(pcbsp->sp_cache[i].cacheidx)); 326 sizeof(pcbsp->sp_cache[i].cacheidx));
329 } 327 }
330 return 0; 328 return 0;
331} 329}
332 330
333void 331void
334ipsec_pcbconn(struct inpcbpolicy *pcbsp) 332ipsec_pcbconn(struct inpcbpolicy *pcbsp)
335{ 333{
336 334
337 KASSERT(inph_locked(pcbsp->sp_inph)); 335 KASSERT(inph_locked(pcbsp->sp_inph));
338 336
339 pcbsp->sp_cacheflags |= IPSEC_PCBSP_CONNECTED; 337 pcbsp->sp_cacheflags |= IPSEC_PCBSP_CONNECTED;
340 ipsec_invalpcbcache(pcbsp, IPSEC_DIR_ANY); 338 ipsec_invalpcbcache(pcbsp, IPSEC_DIR_ANY);
341} 339}
@@ -906,29 +904,29 @@ ipsec4_setspidx_inpcb(struct mbuf *m, st @@ -906,29 +904,29 @@ ipsec4_setspidx_inpcb(struct mbuf *m, st
906 904
907 KASSERT(pcb != NULL); 905 KASSERT(pcb != NULL);
908 KASSERT(pcb->inp_sp != NULL); 906 KASSERT(pcb->inp_sp != NULL);
909 KASSERT(pcb->inp_sp->sp_out != NULL); 907 KASSERT(pcb->inp_sp->sp_out != NULL);
910 KASSERT(pcb->inp_sp->sp_in != NULL); 908 KASSERT(pcb->inp_sp->sp_in != NULL);
911 909
912 error = ipsec_setspidx(m, &pcb->inp_sp->sp_in->spidx, 1); 910 error = ipsec_setspidx(m, &pcb->inp_sp->sp_in->spidx, 1);
913 if (error == 0) { 911 if (error == 0) {
914 pcb->inp_sp->sp_in->spidx.dir = IPSEC_DIR_INBOUND; 912 pcb->inp_sp->sp_in->spidx.dir = IPSEC_DIR_INBOUND;
915 pcb->inp_sp->sp_out->spidx = pcb->inp_sp->sp_in->spidx; 913 pcb->inp_sp->sp_out->spidx = pcb->inp_sp->sp_in->spidx;
916 pcb->inp_sp->sp_out->spidx.dir = IPSEC_DIR_OUTBOUND; 914 pcb->inp_sp->sp_out->spidx.dir = IPSEC_DIR_OUTBOUND;
917 } else { 915 } else {
918 memset(&pcb->inp_sp->sp_in->spidx, 0, 916 memset(&pcb->inp_sp->sp_in->spidx, 0,
919 sizeof (pcb->inp_sp->sp_in->spidx)); 917 sizeof(pcb->inp_sp->sp_in->spidx));
920 memset(&pcb->inp_sp->sp_out->spidx, 0, 918 memset(&pcb->inp_sp->sp_out->spidx, 0,
921 sizeof (pcb->inp_sp->sp_in->spidx)); 919 sizeof(pcb->inp_sp->sp_in->spidx));
922 } 920 }
923 return error; 921 return error;
924} 922}
925 923
926#ifdef INET6 924#ifdef INET6
927static int 925static int
928ipsec6_setspidx_in6pcb(struct mbuf *m, struct in6pcb *pcb) 926ipsec6_setspidx_in6pcb(struct mbuf *m, struct in6pcb *pcb)
929{ 927{
930 struct secpolicyindex *spidx; 928 struct secpolicyindex *spidx;
931 int error; 929 int error;
932 930
933 KASSERT(pcb != NULL); 931 KASSERT(pcb != NULL);
934 KASSERT(pcb->in6p_sp != NULL); 932 KASSERT(pcb->in6p_sp != NULL);
@@ -1123,31 +1121,29 @@ static int @@ -1123,31 +1121,29 @@ static int
1123ipsec4_setspidx_ipaddr(struct mbuf *m, struct secpolicyindex *spidx) 1121ipsec4_setspidx_ipaddr(struct mbuf *m, struct secpolicyindex *spidx)
1124{ 1122{
1125 static const struct sockaddr_in template = { 1123 static const struct sockaddr_in template = {
1126 sizeof (struct sockaddr_in), 1124 sizeof (struct sockaddr_in),
1127 AF_INET, 1125 AF_INET,
1128 0, { 0 }, { 0, 0, 0, 0, 0, 0, 0, 0 } 1126 0, { 0 }, { 0, 0, 0, 0, 0, 0, 0, 0 }
1129 }; 1127 };
1130 1128
1131 spidx->src.sin = template; 1129 spidx->src.sin = template;
1132 spidx->dst.sin = template; 1130 spidx->dst.sin = template;
1133 1131
1134 if (m->m_len < sizeof (struct ip)) { 1132 if (m->m_len < sizeof (struct ip)) {
1135 m_copydata(m, offsetof(struct ip, ip_src), 1133 m_copydata(m, offsetof(struct ip, ip_src),
1136 sizeof (struct in_addr), 1134 sizeof(struct in_addr), &spidx->src.sin.sin_addr);
1137 &spidx->src.sin.sin_addr); 
1138 m_copydata(m, offsetof(struct ip, ip_dst), 1135 m_copydata(m, offsetof(struct ip, ip_dst),
1139 sizeof (struct in_addr), 1136 sizeof(struct in_addr), &spidx->dst.sin.sin_addr);
1140 &spidx->dst.sin.sin_addr); 
1141 } else { 1137 } else {
1142 struct ip *ip = mtod(m, struct ip *); 1138 struct ip *ip = mtod(m, struct ip *);
1143 spidx->src.sin.sin_addr = ip->ip_src; 1139 spidx->src.sin.sin_addr = ip->ip_src;
1144 spidx->dst.sin.sin_addr = ip->ip_dst; 1140 spidx->dst.sin.sin_addr = ip->ip_dst;
1145 } 1141 }
1146 1142
1147 spidx->prefs = sizeof(struct in_addr) << 3; 1143 spidx->prefs = sizeof(struct in_addr) << 3;
1148 spidx->prefd = sizeof(struct in_addr) << 3; 1144 spidx->prefd = sizeof(struct in_addr) << 3;
1149 1145
1150 return 0; 1146 return 0;
1151} 1147}
1152 1148
1153#ifdef INET6 1149#ifdef INET6