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