xref: /openbsd-src/sys/netinet/ip_spd.c (revision f1dd7b858388b4a23f4f67a4957ec5ff656ebbe8)
1 /* $OpenBSD: ip_spd.c,v 1.103 2021/05/04 09:28:04 mvs Exp $ */
2 /*
3  * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
4  *
5  * Copyright (c) 2000-2001 Angelos D. Keromytis.
6  *
7  * Permission to use, copy, and modify this software with or without fee
8  * is hereby granted, provided that this entire notice is included in
9  * all copies of any software which is or includes a copy or
10  * modification of this software.
11  * You may use this code under the GNU public license if you so wish. Please
12  * contribute changes back to the authors under this freer than GPL license
13  * so that we may further the use of strong encryption without limitations to
14  * all.
15  *
16  * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
17  * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
18  * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
19  * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
20  * PURPOSE.
21  */
22 
23 #include <sys/param.h>
24 #include <sys/systm.h>
25 #include <sys/mbuf.h>
26 #include <sys/socket.h>
27 #include <sys/kernel.h>
28 #include <sys/socketvar.h>
29 #include <sys/domain.h>
30 #include <sys/protosw.h>
31 #include <sys/pool.h>
32 #include <sys/timeout.h>
33 
34 #include <net/route.h>
35 #include <net/netisr.h>
36 
37 #include <netinet/in.h>
38 #include <netinet/ip.h>
39 #include <netinet/ip_var.h>
40 #include <netinet/in_pcb.h>
41 #include <netinet/ip_ipsp.h>
42 #include <net/pfkeyv2.h>
43 
44 int	ipsp_acquire_sa(struct ipsec_policy *, union sockaddr_union *,
45 	    union sockaddr_union *, struct sockaddr_encap *, struct mbuf *);
46 struct	ipsec_acquire *ipsp_pending_acquire(struct ipsec_policy *,
47 	    union sockaddr_union *);
48 void	ipsp_delete_acquire_timo(void *);
49 void	ipsp_delete_acquire(struct ipsec_acquire *);
50 
51 struct pool ipsec_policy_pool;
52 struct pool ipsec_acquire_pool;
53 
54 /* Protected by the NET_LOCK(). */
55 int ipsec_acquire_pool_initialized = 0;
56 struct radix_node_head **spd_tables;
57 unsigned int spd_table_max;
58 TAILQ_HEAD(ipsec_acquire_head, ipsec_acquire) ipsec_acquire_head =
59     TAILQ_HEAD_INITIALIZER(ipsec_acquire_head);
60 
61 struct radix_node_head *
62 spd_table_get(unsigned int rtableid)
63 {
64 	unsigned int rdomain;
65 
66 	NET_ASSERT_LOCKED();
67 
68 	if (spd_tables == NULL)
69 		return (NULL);
70 
71 	rdomain = rtable_l2(rtableid);
72 	if (rdomain > spd_table_max)
73 		return (NULL);
74 
75 	return (spd_tables[rdomain]);
76 }
77 
78 struct radix_node_head *
79 spd_table_add(unsigned int rtableid)
80 {
81 	struct radix_node_head *rnh = NULL;
82 	unsigned int rdomain;
83 	void *p;
84 
85 	NET_ASSERT_LOCKED();
86 
87 	rdomain = rtable_l2(rtableid);
88 	if (spd_tables == NULL || rdomain > spd_table_max) {
89 		if ((p = mallocarray(rdomain + 1, sizeof(*rnh),
90 		    M_RTABLE, M_NOWAIT|M_ZERO)) == NULL)
91 			return (NULL);
92 
93 		if (spd_tables != NULL) {
94 			memcpy(p, spd_tables, sizeof(*rnh) * (spd_table_max+1));
95 			free(spd_tables, M_RTABLE,
96 			    sizeof(*rnh) * (spd_table_max+1));
97 		}
98 		spd_tables = p;
99 		spd_table_max = rdomain;
100 	}
101 
102 	if (spd_tables[rdomain] == NULL) {
103 		if (rn_inithead((void **)&rnh,
104 		    offsetof(struct sockaddr_encap, sen_type)) == 0)
105 			rnh = NULL;
106 		spd_tables[rdomain] = rnh;
107 	}
108 
109 	return (spd_tables[rdomain]);
110 }
111 
112 int
113 spd_table_walk(unsigned int rtableid,
114     int (*func)(struct ipsec_policy *, void *, unsigned int), void *arg)
115 {
116 	struct radix_node_head *rnh;
117 	int (*walker)(struct radix_node *, void *, u_int) = (void *)func;
118 	int error;
119 
120 	rnh = spd_table_get(rtableid);
121 	if (rnh == NULL)
122 		return (0);
123 
124 	/* EGAIN means the tree changed. */
125 	while ((error = rn_walktree(rnh, walker, arg)) == EAGAIN)
126 		continue;
127 
128 	return (error);
129 }
130 
131 /*
132  * Lookup at the SPD based on the headers contained on the mbuf. The second
133  * argument indicates what protocol family the header at the beginning of
134  * the mbuf is. hlen is the offset of the transport protocol header
135  * in the mbuf.
136  *
137  * Return combinations (of return value and in *error):
138  * - NULL/0 -> no IPsec required on packet
139  * - NULL/-EINVAL -> silently drop the packet
140  * - NULL/errno -> drop packet and return error
141  * or a pointer to a TDB (and 0 in *error).
142  *
143  * In the case of incoming flows, only the first three combinations are
144  * returned.
145  */
146 struct tdb *
147 ipsp_spd_lookup(struct mbuf *m, int af, int hlen, int *error, int direction,
148     struct tdb *tdbp, struct inpcb *inp, u_int32_t ipsecflowinfo)
149 {
150 	struct radix_node_head *rnh;
151 	struct radix_node *rn;
152 	union sockaddr_union sdst, ssrc;
153 	struct sockaddr_encap *ddst, dst;
154 	struct ipsec_policy *ipo;
155 	struct ipsec_ids *ids = NULL;
156 	int signore = 0, dignore = 0;
157 	u_int rdomain = rtable_l2(m->m_pkthdr.ph_rtableid);
158 
159 	NET_ASSERT_LOCKED();
160 
161 	/*
162 	 * If there are no flows in place, there's no point
163 	 * continuing with the SPD lookup.
164 	 */
165 	if (!ipsec_in_use && inp == NULL) {
166 		*error = 0;
167 		return NULL;
168 	}
169 
170 	/*
171 	 * If an input packet is destined to a BYPASS socket, just accept it.
172 	 */
173 	if ((inp != NULL) && (direction == IPSP_DIRECTION_IN) &&
174 	    (inp->inp_seclevel[SL_ESP_TRANS] == IPSEC_LEVEL_BYPASS) &&
175 	    (inp->inp_seclevel[SL_ESP_NETWORK] == IPSEC_LEVEL_BYPASS) &&
176 	    (inp->inp_seclevel[SL_AUTH] == IPSEC_LEVEL_BYPASS)) {
177 		*error = 0;
178 		return NULL;
179 	}
180 
181 	memset(&dst, 0, sizeof(dst));
182 	memset(&sdst, 0, sizeof(union sockaddr_union));
183 	memset(&ssrc, 0, sizeof(union sockaddr_union));
184 	ddst = (struct sockaddr_encap *)&dst;
185 	ddst->sen_family = PF_KEY;
186 	ddst->sen_len = SENT_LEN;
187 
188 	switch (af) {
189 	case AF_INET:
190 		if (hlen < sizeof (struct ip) || m->m_pkthdr.len < hlen) {
191 			*error = EINVAL;
192 			return NULL;
193 		}
194 		ddst->sen_direction = direction;
195 		ddst->sen_type = SENT_IP4;
196 
197 		m_copydata(m, offsetof(struct ip, ip_src),
198 		    sizeof(struct in_addr), (caddr_t) &(ddst->sen_ip_src));
199 		m_copydata(m, offsetof(struct ip, ip_dst),
200 		    sizeof(struct in_addr), (caddr_t) &(ddst->sen_ip_dst));
201 		m_copydata(m, offsetof(struct ip, ip_p), sizeof(u_int8_t),
202 		    (caddr_t) &(ddst->sen_proto));
203 
204 		sdst.sin.sin_family = ssrc.sin.sin_family = AF_INET;
205 		sdst.sin.sin_len = ssrc.sin.sin_len =
206 		    sizeof(struct sockaddr_in);
207 		ssrc.sin.sin_addr = ddst->sen_ip_src;
208 		sdst.sin.sin_addr = ddst->sen_ip_dst;
209 
210 		/*
211 		 * If TCP/UDP, extract the port numbers to use in the lookup.
212 		 */
213 		switch (ddst->sen_proto) {
214 		case IPPROTO_UDP:
215 		case IPPROTO_TCP:
216 			/* Make sure there's enough data in the packet. */
217 			if (m->m_pkthdr.len < hlen + 2 * sizeof(u_int16_t)) {
218 				*error = EINVAL;
219 				return NULL;
220 			}
221 
222 			/*
223 			 * Luckily, the offset of the src/dst ports in
224 			 * both the UDP and TCP headers is the same (first
225 			 * two 16-bit values in the respective headers),
226 			 * so we can just copy them.
227 			 */
228 			m_copydata(m, hlen, sizeof(u_int16_t),
229 			    (caddr_t) &(ddst->sen_sport));
230 			m_copydata(m, hlen + sizeof(u_int16_t), sizeof(u_int16_t),
231 			    (caddr_t) &(ddst->sen_dport));
232 			break;
233 
234 		default:
235 			ddst->sen_sport = 0;
236 			ddst->sen_dport = 0;
237 		}
238 
239 		break;
240 
241 #ifdef INET6
242 	case AF_INET6:
243 		if (hlen < sizeof (struct ip6_hdr) || m->m_pkthdr.len < hlen) {
244 			*error = EINVAL;
245 			return NULL;
246 		}
247 		ddst->sen_type = SENT_IP6;
248 		ddst->sen_ip6_direction = direction;
249 
250 		m_copydata(m, offsetof(struct ip6_hdr, ip6_src),
251 		    sizeof(struct in6_addr),
252 		    (caddr_t) &(ddst->sen_ip6_src));
253 		m_copydata(m, offsetof(struct ip6_hdr, ip6_dst),
254 		    sizeof(struct in6_addr),
255 		    (caddr_t) &(ddst->sen_ip6_dst));
256 		m_copydata(m, offsetof(struct ip6_hdr, ip6_nxt),
257 		    sizeof(u_int8_t),
258 		    (caddr_t) &(ddst->sen_ip6_proto));
259 
260 		sdst.sin6.sin6_family = ssrc.sin6.sin6_family = AF_INET6;
261 		sdst.sin6.sin6_len = ssrc.sin6.sin6_len =
262 		    sizeof(struct sockaddr_in6);
263 		in6_recoverscope(&ssrc.sin6, &ddst->sen_ip6_src);
264 		in6_recoverscope(&sdst.sin6, &ddst->sen_ip6_dst);
265 
266 		/*
267 		 * If TCP/UDP, extract the port numbers to use in the lookup.
268 		 */
269 		switch (ddst->sen_ip6_proto) {
270 		case IPPROTO_UDP:
271 		case IPPROTO_TCP:
272 			/* Make sure there's enough data in the packet. */
273 			if (m->m_pkthdr.len < hlen + 2 * sizeof(u_int16_t)) {
274 				*error = EINVAL;
275 				return NULL;
276 			}
277 
278 			/*
279 			 * Luckily, the offset of the src/dst ports in
280 			 * both the UDP and TCP headers is the same
281 			 * (first two 16-bit values in the respective
282 			 * headers), so we can just copy them.
283 			 */
284 			m_copydata(m, hlen, sizeof(u_int16_t),
285 			    (caddr_t) &(ddst->sen_ip6_sport));
286 			m_copydata(m, hlen + sizeof(u_int16_t), sizeof(u_int16_t),
287 			    (caddr_t) &(ddst->sen_ip6_dport));
288 			break;
289 
290 		default:
291 			ddst->sen_ip6_sport = 0;
292 			ddst->sen_ip6_dport = 0;
293 		}
294 
295 		break;
296 #endif /* INET6 */
297 
298 	default:
299 		*error = EAFNOSUPPORT;
300 		return NULL;
301 	}
302 
303 	/* Actual SPD lookup. */
304 	if ((rnh = spd_table_get(rdomain)) == NULL ||
305 	    (rn = rn_match((caddr_t)&dst, rnh)) == NULL) {
306 		/*
307 		 * Return whatever the socket requirements are, there are no
308 		 * system-wide policies.
309 		 */
310 		*error = 0;
311 		return ipsp_spd_inp(m, af, hlen, error, direction,
312 		    tdbp, inp, NULL);
313 	}
314 	ipo = (struct ipsec_policy *)rn;
315 
316 	switch (ipo->ipo_type) {
317 	case IPSP_PERMIT:
318 		*error = 0;
319 		return ipsp_spd_inp(m, af, hlen, error, direction, tdbp,
320 		    inp, ipo);
321 
322 	case IPSP_DENY:
323 		*error = EHOSTUNREACH;
324 		return NULL;
325 
326 	case IPSP_IPSEC_USE:
327 	case IPSP_IPSEC_ACQUIRE:
328 	case IPSP_IPSEC_REQUIRE:
329 	case IPSP_IPSEC_DONTACQ:
330 		/* Nothing more needed here. */
331 		break;
332 
333 	default:
334 		*error = EINVAL;
335 		return NULL;
336 	}
337 
338 	/* Check for non-specific destination in the policy. */
339 	switch (ipo->ipo_dst.sa.sa_family) {
340 	case AF_INET:
341 		if ((ipo->ipo_dst.sin.sin_addr.s_addr == INADDR_ANY) ||
342 		    (ipo->ipo_dst.sin.sin_addr.s_addr == INADDR_BROADCAST))
343 			dignore = 1;
344 		break;
345 
346 #ifdef INET6
347 	case AF_INET6:
348 		if ((IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_dst.sin6.sin6_addr)) ||
349 		    (memcmp(&ipo->ipo_dst.sin6.sin6_addr, &in6mask128,
350 		    sizeof(in6mask128)) == 0))
351 			dignore = 1;
352 		break;
353 #endif /* INET6 */
354 	}
355 
356 	/* Likewise for source. */
357 	switch (ipo->ipo_src.sa.sa_family) {
358 	case AF_INET:
359 		if (ipo->ipo_src.sin.sin_addr.s_addr == INADDR_ANY)
360 			signore = 1;
361 		break;
362 
363 #ifdef INET6
364 	case AF_INET6:
365 		if (IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_src.sin6.sin6_addr))
366 			signore = 1;
367 		break;
368 #endif /* INET6 */
369 	}
370 
371 	/* Do we have a cached entry ? If so, check if it's still valid. */
372 	if ((ipo->ipo_tdb) && (ipo->ipo_tdb->tdb_flags & TDBF_INVALID)) {
373 		TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head, ipo,
374 		    ipo_tdb_next);
375 		ipo->ipo_tdb = NULL;
376 	}
377 
378 	/* Outgoing packet policy check. */
379 	if (direction == IPSP_DIRECTION_OUT) {
380 		/*
381 		 * If the packet is destined for the policy-specified
382 		 * gateway/endhost, and the socket has the BYPASS
383 		 * option set, skip IPsec processing.
384 		 */
385 		if ((inp != NULL) &&
386 		    (inp->inp_seclevel[SL_ESP_TRANS] == IPSEC_LEVEL_BYPASS) &&
387 		    (inp->inp_seclevel[SL_ESP_NETWORK] ==
388 			IPSEC_LEVEL_BYPASS) &&
389 		    (inp->inp_seclevel[SL_AUTH] == IPSEC_LEVEL_BYPASS)) {
390 			/* Direct match. */
391 			if (dignore ||
392 			    !memcmp(&sdst, &ipo->ipo_dst, sdst.sa.sa_len)) {
393 				*error = 0;
394 				return NULL;
395 			}
396 		}
397 
398 		if (ipsecflowinfo)
399 			ids = ipsp_ids_lookup(ipsecflowinfo);
400 
401 		/* Check that the cached TDB (if present), is appropriate. */
402 		if (ipo->ipo_tdb) {
403 			if ((ipo->ipo_last_searched <= ipsec_last_added) ||
404 			    (ipo->ipo_sproto != ipo->ipo_tdb->tdb_sproto) ||
405 			    memcmp(dignore ? &sdst : &ipo->ipo_dst,
406 			    &ipo->ipo_tdb->tdb_dst,
407 			    ipo->ipo_tdb->tdb_dst.sa.sa_len))
408 				goto nomatchout;
409 
410 			if (!ipsp_aux_match(ipo->ipo_tdb,
411 			    ids ? ids : ipo->ipo_ids,
412 			    &ipo->ipo_addr, &ipo->ipo_mask))
413 				goto nomatchout;
414 
415 			/* Cached entry is good. */
416 			*error = 0;
417 			return ipsp_spd_inp(m, af, hlen, error, direction,
418 			    tdbp, inp, ipo);
419 
420   nomatchout:
421 			/* Cached TDB was not good. */
422 			TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head, ipo,
423 			    ipo_tdb_next);
424 			ipo->ipo_tdb = NULL;
425 			ipo->ipo_last_searched = 0;
426 		}
427 
428 		/*
429 		 * If no SA has been added since the last time we did a
430 		 * lookup, there's no point searching for one. However, if the
431 		 * destination gateway is left unspecified (or is all-1's),
432 		 * always lookup since this is a generic-match rule
433 		 * (otherwise, we can have situations where SAs to some
434 		 * destinations exist but are not used, possibly leading to an
435 		 * explosion in the number of acquired SAs).
436 		 */
437 		if (ipo->ipo_last_searched <= ipsec_last_added)	{
438 			/* "Touch" the entry. */
439 			if (dignore == 0)
440 				ipo->ipo_last_searched = getuptime();
441 
442 			/* Find an appropriate SA from the existing ones. */
443 			ipo->ipo_tdb =
444 			    gettdbbydst(rdomain,
445 				dignore ? &sdst : &ipo->ipo_dst,
446 				ipo->ipo_sproto,
447 				ids ? ids: ipo->ipo_ids,
448 				&ipo->ipo_addr, &ipo->ipo_mask);
449 			if (ipo->ipo_tdb) {
450 				TAILQ_INSERT_TAIL(&ipo->ipo_tdb->tdb_policy_head,
451 				    ipo, ipo_tdb_next);
452 				*error = 0;
453 				return ipsp_spd_inp(m, af, hlen, error,
454 				    direction, tdbp, inp, ipo);
455 			}
456 		}
457 
458 		/* So, we don't have an SA -- just a policy. */
459 		switch (ipo->ipo_type) {
460 		case IPSP_IPSEC_REQUIRE:
461 			/* Acquire SA through key management. */
462 			if (ipsp_acquire_sa(ipo,
463 			    dignore ? &sdst : &ipo->ipo_dst,
464 			    signore ? NULL : &ipo->ipo_src, ddst, m) != 0) {
465 				*error = EACCES;
466 				return NULL;
467 			}
468 
469 			/* FALLTHROUGH */
470 		case IPSP_IPSEC_DONTACQ:
471 			*error = -EINVAL; /* Silently drop packet. */
472 			return NULL;
473 
474 		case IPSP_IPSEC_ACQUIRE:
475 			/* Acquire SA through key management. */
476 			ipsp_acquire_sa(ipo, dignore ? &sdst : &ipo->ipo_dst,
477 			    signore ? NULL : &ipo->ipo_src, ddst, NULL);
478 
479 			/* FALLTHROUGH */
480 		case IPSP_IPSEC_USE:
481 			*error = 0;
482 			return ipsp_spd_inp(m, af, hlen, error, direction,
483 			    tdbp, inp, ipo);
484 		}
485 	} else { /* IPSP_DIRECTION_IN */
486 		if (tdbp != NULL) {
487 			/*
488 			 * Special case for bundled IPcomp/ESP SAs:
489 			 * 1) only IPcomp flows are loaded into kernel
490 			 * 2) input processing processes ESP SA first
491 			 * 3) then optional IPcomp processing happens
492 			 * 4) we only update m_tag for ESP
493 			 * => 'tdbp' is always set to ESP SA
494 			 * => flow has ipo_proto for IPcomp
495 			 * So if 'tdbp' points to an ESP SA and this 'tdbp' is
496 			 * bundled with an IPcomp SA, then we replace 'tdbp'
497 			 * with the IPcomp SA at tdbp->tdb_inext.
498 			 */
499 			if (ipo->ipo_sproto == IPPROTO_IPCOMP &&
500 			    tdbp->tdb_sproto == IPPROTO_ESP &&
501 			    tdbp->tdb_inext != NULL &&
502 			    tdbp->tdb_inext->tdb_sproto == IPPROTO_IPCOMP)
503 				tdbp = tdbp->tdb_inext;
504 
505 			/* Direct match in the cache. */
506 			if (ipo->ipo_tdb == tdbp) {
507 				*error = 0;
508 				return ipsp_spd_inp(m, af, hlen, error,
509 				    direction, tdbp, inp, ipo);
510 			}
511 
512 			if (memcmp(dignore ? &ssrc : &ipo->ipo_dst,
513 			    &tdbp->tdb_src, tdbp->tdb_src.sa.sa_len) ||
514 			    (ipo->ipo_sproto != tdbp->tdb_sproto))
515 				goto nomatchin;
516 
517 			/* Match source/dest IDs. */
518 			if (ipo->ipo_ids)
519 				if (tdbp->tdb_ids == NULL ||
520 				    !ipsp_ids_match(ipo->ipo_ids, tdbp->tdb_ids))
521 					goto nomatchin;
522 
523 			/* Add it to the cache. */
524 			if (ipo->ipo_tdb)
525 				TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head,
526 				    ipo, ipo_tdb_next);
527 			ipo->ipo_tdb = tdbp;
528 			TAILQ_INSERT_TAIL(&tdbp->tdb_policy_head, ipo,
529 			    ipo_tdb_next);
530 			*error = 0;
531 			return ipsp_spd_inp(m, af, hlen, error, direction,
532 			    tdbp, inp, ipo);
533 
534   nomatchin: /* Nothing needed here, falling through */
535 	;
536 		}
537 
538 		/* Check whether cached entry applies. */
539 		if (ipo->ipo_tdb) {
540 			/*
541 			 * We only need to check that the correct
542 			 * security protocol and security gateway are
543 			 * set; IDs will be the same since the cached
544 			 * entry is linked on this policy.
545 			 */
546 			if (ipo->ipo_sproto == ipo->ipo_tdb->tdb_sproto &&
547 			    !memcmp(&ipo->ipo_tdb->tdb_src,
548 			    dignore ? &ssrc : &ipo->ipo_dst,
549 			    ipo->ipo_tdb->tdb_src.sa.sa_len))
550 				goto skipinputsearch;
551 
552 			/* Not applicable, unlink. */
553 			TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head, ipo,
554 			    ipo_tdb_next);
555 			ipo->ipo_last_searched = 0;
556 			ipo->ipo_tdb = NULL;
557 		}
558 
559 		/* Find whether there exists an appropriate SA. */
560 		if (ipo->ipo_last_searched <= ipsec_last_added)	{
561 			if (dignore == 0)
562 				ipo->ipo_last_searched = getuptime();
563 
564 			ipo->ipo_tdb =
565 			    gettdbbysrc(rdomain,
566 				dignore ? &ssrc : &ipo->ipo_dst,
567 				ipo->ipo_sproto, ipo->ipo_ids,
568 				&ipo->ipo_addr, &ipo->ipo_mask);
569 			if (ipo->ipo_tdb)
570 				TAILQ_INSERT_TAIL(&ipo->ipo_tdb->tdb_policy_head,
571 				    ipo, ipo_tdb_next);
572 		}
573   skipinputsearch:
574 
575 		switch (ipo->ipo_type) {
576 		case IPSP_IPSEC_REQUIRE:
577 			/* If appropriate SA exists, don't acquire another. */
578 			if (ipo->ipo_tdb) {
579 				*error = -EINVAL;
580 				return NULL;
581 			}
582 
583 			/* Acquire SA through key management. */
584 			if ((*error = ipsp_acquire_sa(ipo,
585 			    dignore ? &ssrc : &ipo->ipo_dst,
586 			    signore ? NULL : &ipo->ipo_src, ddst, m)) != 0)
587 				return NULL;
588 
589 			/* FALLTHROUGH */
590 		case IPSP_IPSEC_DONTACQ:
591 			/* Drop packet. */
592 			*error = -EINVAL;
593 			return NULL;
594 
595 		case IPSP_IPSEC_ACQUIRE:
596 			/* If appropriate SA exists, don't acquire another. */
597 			if (ipo->ipo_tdb) {
598 				*error = 0;
599 				return ipsp_spd_inp(m, af, hlen, error,
600 				    direction, tdbp, inp, ipo);
601 			}
602 
603 			/* Acquire SA through key management. */
604 			ipsp_acquire_sa(ipo, dignore ? &ssrc : &ipo->ipo_dst,
605 			    signore ? NULL : &ipo->ipo_src, ddst, NULL);
606 
607 			/* FALLTHROUGH */
608 		case IPSP_IPSEC_USE:
609 			*error = 0;
610 			return ipsp_spd_inp(m, af, hlen, error, direction,
611 			    tdbp, inp, ipo);
612 		}
613 	}
614 
615 	/* Shouldn't ever get this far. */
616 	*error = EINVAL;
617 	return NULL;
618 }
619 
620 /*
621  * Delete a policy from the SPD.
622  */
623 int
624 ipsec_delete_policy(struct ipsec_policy *ipo)
625 {
626 	struct ipsec_acquire *ipa;
627 	struct radix_node_head *rnh;
628 	struct radix_node *rn = (struct radix_node *)ipo;
629 	int err = 0;
630 
631 	NET_ASSERT_LOCKED();
632 
633 	if (--ipo->ipo_ref_count > 0)
634 		return 0;
635 
636 	/* Delete from SPD. */
637 	if ((rnh = spd_table_get(ipo->ipo_rdomain)) == NULL ||
638 	    rn_delete(&ipo->ipo_addr, &ipo->ipo_mask, rnh, rn) == NULL)
639 		return (ESRCH);
640 
641 	if (ipo->ipo_tdb != NULL)
642 		TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head, ipo,
643 		    ipo_tdb_next);
644 
645 	while ((ipa = TAILQ_FIRST(&ipo->ipo_acquires)) != NULL)
646 		ipsp_delete_acquire(ipa);
647 
648 	TAILQ_REMOVE(&ipsec_policy_head, ipo, ipo_list);
649 
650 	if (ipo->ipo_ids)
651 		ipsp_ids_free(ipo->ipo_ids);
652 
653 	ipsec_in_use--;
654 
655 	pool_put(&ipsec_policy_pool, ipo);
656 
657 	return err;
658 }
659 
660 void
661 ipsp_delete_acquire_timo(void *v)
662 {
663 	struct ipsec_acquire *ipa = v;
664 
665 	NET_LOCK();
666 	ipsp_delete_acquire(ipa);
667 	NET_UNLOCK();
668 }
669 
670 /*
671  * Delete a pending IPsec acquire record.
672  */
673 void
674 ipsp_delete_acquire(struct ipsec_acquire *ipa)
675 {
676 	NET_ASSERT_LOCKED();
677 
678 	timeout_del(&ipa->ipa_timeout);
679 	TAILQ_REMOVE(&ipsec_acquire_head, ipa, ipa_next);
680 	if (ipa->ipa_policy != NULL)
681 		TAILQ_REMOVE(&ipa->ipa_policy->ipo_acquires, ipa,
682 		    ipa_ipo_next);
683 	pool_put(&ipsec_acquire_pool, ipa);
684 }
685 
686 /*
687  * Find out if there's an ACQUIRE pending.
688  * XXX Need a better structure.
689  */
690 struct ipsec_acquire *
691 ipsp_pending_acquire(struct ipsec_policy *ipo, union sockaddr_union *gw)
692 {
693 	struct ipsec_acquire *ipa;
694 
695 	NET_ASSERT_LOCKED();
696 
697 	TAILQ_FOREACH (ipa, &ipo->ipo_acquires, ipa_ipo_next) {
698 		if (!memcmp(gw, &ipa->ipa_addr, gw->sa.sa_len))
699 			return ipa;
700 	}
701 
702 	return NULL;
703 }
704 
705 /*
706  * Signal key management that we need an SA.
707  * XXX For outgoing policies, we could try to hold on to the mbuf.
708  */
709 int
710 ipsp_acquire_sa(struct ipsec_policy *ipo, union sockaddr_union *gw,
711     union sockaddr_union *laddr, struct sockaddr_encap *ddst, struct mbuf *m)
712 {
713 	struct ipsec_acquire *ipa;
714 
715 	NET_ASSERT_LOCKED();
716 
717 	/* Check whether request has been made already. */
718 	if ((ipa = ipsp_pending_acquire(ipo, gw)) != NULL)
719 		return 0;
720 
721 	/* Add request in cache and proceed. */
722 	if (ipsec_acquire_pool_initialized == 0) {
723 		ipsec_acquire_pool_initialized = 1;
724 		pool_init(&ipsec_acquire_pool, sizeof(struct ipsec_acquire),
725 		    0, IPL_SOFTNET, 0, "ipsec acquire", NULL);
726 	}
727 
728 	ipa = pool_get(&ipsec_acquire_pool, PR_NOWAIT|PR_ZERO);
729 	if (ipa == NULL)
730 		return ENOMEM;
731 
732 	ipa->ipa_addr = *gw;
733 
734 	timeout_set_proc(&ipa->ipa_timeout, ipsp_delete_acquire_timo, ipa);
735 
736 	ipa->ipa_info.sen_len = ipa->ipa_mask.sen_len = SENT_LEN;
737 	ipa->ipa_info.sen_family = ipa->ipa_mask.sen_family = PF_KEY;
738 
739 	/* Just copy the right information. */
740 	switch (ipo->ipo_addr.sen_type) {
741 	case SENT_IP4:
742 		ipa->ipa_info.sen_type = ipa->ipa_mask.sen_type = SENT_IP4;
743 		ipa->ipa_info.sen_direction = ipo->ipo_addr.sen_direction;
744 		ipa->ipa_mask.sen_direction = ipo->ipo_mask.sen_direction;
745 
746 		if (ipsp_is_unspecified(ipo->ipo_dst)) {
747 			ipa->ipa_info.sen_ip_src = ddst->sen_ip_src;
748 			ipa->ipa_mask.sen_ip_src.s_addr = INADDR_BROADCAST;
749 
750 			ipa->ipa_info.sen_ip_dst = ddst->sen_ip_dst;
751 			ipa->ipa_mask.sen_ip_dst.s_addr = INADDR_BROADCAST;
752 		} else {
753 			ipa->ipa_info.sen_ip_src = ipo->ipo_addr.sen_ip_src;
754 			ipa->ipa_mask.sen_ip_src = ipo->ipo_mask.sen_ip_src;
755 
756 			ipa->ipa_info.sen_ip_dst = ipo->ipo_addr.sen_ip_dst;
757 			ipa->ipa_mask.sen_ip_dst = ipo->ipo_mask.sen_ip_dst;
758 		}
759 
760 		ipa->ipa_info.sen_proto = ipo->ipo_addr.sen_proto;
761 		ipa->ipa_mask.sen_proto = ipo->ipo_mask.sen_proto;
762 
763 		if (ipo->ipo_addr.sen_proto) {
764 			ipa->ipa_info.sen_sport = ipo->ipo_addr.sen_sport;
765 			ipa->ipa_mask.sen_sport = ipo->ipo_mask.sen_sport;
766 
767 			ipa->ipa_info.sen_dport = ipo->ipo_addr.sen_dport;
768 			ipa->ipa_mask.sen_dport = ipo->ipo_mask.sen_dport;
769 		}
770 		break;
771 
772 #ifdef INET6
773 	case SENT_IP6:
774 		ipa->ipa_info.sen_type = ipa->ipa_mask.sen_type = SENT_IP6;
775 		ipa->ipa_info.sen_ip6_direction =
776 		    ipo->ipo_addr.sen_ip6_direction;
777 		ipa->ipa_mask.sen_ip6_direction =
778 		    ipo->ipo_mask.sen_ip6_direction;
779 
780 		if (ipsp_is_unspecified(ipo->ipo_dst)) {
781 			ipa->ipa_info.sen_ip6_src = ddst->sen_ip6_src;
782 			ipa->ipa_mask.sen_ip6_src = in6mask128;
783 
784 			ipa->ipa_info.sen_ip6_dst = ddst->sen_ip6_dst;
785 			ipa->ipa_mask.sen_ip6_dst = in6mask128;
786 		} else {
787 			ipa->ipa_info.sen_ip6_src = ipo->ipo_addr.sen_ip6_src;
788 			ipa->ipa_mask.sen_ip6_src = ipo->ipo_mask.sen_ip6_src;
789 
790 			ipa->ipa_info.sen_ip6_dst = ipo->ipo_addr.sen_ip6_dst;
791 			ipa->ipa_mask.sen_ip6_dst = ipo->ipo_mask.sen_ip6_dst;
792 		}
793 
794 		ipa->ipa_info.sen_ip6_proto = ipo->ipo_addr.sen_ip6_proto;
795 		ipa->ipa_mask.sen_ip6_proto = ipo->ipo_mask.sen_ip6_proto;
796 
797 		if (ipo->ipo_mask.sen_ip6_proto) {
798 			ipa->ipa_info.sen_ip6_sport =
799 			    ipo->ipo_addr.sen_ip6_sport;
800 			ipa->ipa_mask.sen_ip6_sport =
801 			    ipo->ipo_mask.sen_ip6_sport;
802 			ipa->ipa_info.sen_ip6_dport =
803 			    ipo->ipo_addr.sen_ip6_dport;
804 			ipa->ipa_mask.sen_ip6_dport =
805 			    ipo->ipo_mask.sen_ip6_dport;
806 		}
807 		break;
808 #endif /* INET6 */
809 
810 	default:
811 		pool_put(&ipsec_acquire_pool, ipa);
812 		return 0;
813 	}
814 
815 #ifdef IPSEC
816 	timeout_add_sec(&ipa->ipa_timeout, ipsec_expire_acquire);
817 #endif
818 
819 	TAILQ_INSERT_TAIL(&ipsec_acquire_head, ipa, ipa_next);
820 	TAILQ_INSERT_TAIL(&ipo->ipo_acquires, ipa, ipa_ipo_next);
821 	ipa->ipa_policy = ipo;
822 
823 	/* PF_KEYv2 notification message. */
824 	return pfkeyv2_acquire(ipo, gw, laddr, &ipa->ipa_seq, ddst);
825 }
826 
827 /*
828  * Deal with PCB security requirements.
829  */
830 struct tdb *
831 ipsp_spd_inp(struct mbuf *m, int af, int hlen, int *error, int direction,
832     struct tdb *tdbp, struct inpcb *inp, struct ipsec_policy *ipo)
833 {
834 	/* Sanity check. */
835 	if (inp == NULL)
836 		goto justreturn;
837 
838 	/* We only support IPSEC_LEVEL_BYPASS or IPSEC_LEVEL_AVAIL */
839 
840 	if (inp->inp_seclevel[SL_ESP_TRANS] == IPSEC_LEVEL_BYPASS &&
841 	    inp->inp_seclevel[SL_ESP_NETWORK] == IPSEC_LEVEL_BYPASS &&
842 	    inp->inp_seclevel[SL_AUTH] == IPSEC_LEVEL_BYPASS)
843 		goto justreturn;
844 
845 	if (inp->inp_seclevel[SL_ESP_TRANS] == IPSEC_LEVEL_AVAIL &&
846 	    inp->inp_seclevel[SL_ESP_NETWORK] == IPSEC_LEVEL_AVAIL &&
847 	    inp->inp_seclevel[SL_AUTH] == IPSEC_LEVEL_AVAIL)
848 		goto justreturn;
849 
850 	*error = -EINVAL;
851 	return NULL;
852 
853  justreturn:
854 	if (ipo != NULL)
855 		return ipo->ipo_tdb;
856 	else
857 		return NULL;
858 }
859 
860 /*
861  * Find a pending ACQUIRE record based on its sequence number.
862  * XXX Need to use a better data structure.
863  */
864 struct ipsec_acquire *
865 ipsec_get_acquire(u_int32_t seq)
866 {
867 	struct ipsec_acquire *ipa;
868 
869 	NET_ASSERT_LOCKED();
870 
871 	TAILQ_FOREACH (ipa, &ipsec_acquire_head, ipa_next)
872 		if (ipa->ipa_seq == seq)
873 			return ipa;
874 
875 	return NULL;
876 }
877