This source file includes following definitions.
- ipsp_spd_lookup
- ipsec_delete_policy
- ipsec_add_policy
- ipsec_update_policy
- ipsp_delete_acquire
- ipsp_pending_acquire
- ipsp_acquire_sa
- ipsp_spd_inp
- ipsec_get_acquire
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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
31 #include <net/if.h>
32 #include <net/route.h>
33 #include <net/netisr.h>
34
35 #ifdef INET
36 #include <netinet/in.h>
37 #include <netinet/in_systm.h>
38 #include <netinet/ip.h>
39 #include <netinet/in_pcb.h>
40 #include <netinet/in_var.h>
41 #endif
42
43 #ifdef INET6
44 #ifndef INET
45 #include <netinet/in.h>
46 #endif
47 #include <netinet6/in6_var.h>
48 #endif
49
50 #include <netinet/ip_ipsp.h>
51 #include <net/pfkeyv2.h>
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
66
67
68
69
70
71
72
73
74
75
76
77
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)
82 {
83 struct route_enc re0, *re = &re0;
84 union sockaddr_union sdst, ssrc;
85 struct sockaddr_encap *ddst;
86 struct ipsec_policy *ipo;
87 int signore = 0, dignore = 0;
88
89
90
91
92
93 if (!ipsec_in_use && inp == NULL) {
94 *error = 0;
95 return NULL;
96 }
97
98
99
100
101 if ((inp != NULL) && (direction == IPSP_DIRECTION_IN) &&
102 (inp->inp_seclevel[SL_ESP_TRANS] == IPSEC_LEVEL_BYPASS) &&
103 (inp->inp_seclevel[SL_ESP_NETWORK] == IPSEC_LEVEL_BYPASS) &&
104 (inp->inp_seclevel[SL_AUTH] == IPSEC_LEVEL_BYPASS)) {
105 *error = 0;
106 return NULL;
107 }
108
109 bzero((caddr_t) re, sizeof(struct route_enc));
110 bzero((caddr_t) &sdst, sizeof(union sockaddr_union));
111 bzero((caddr_t) &ssrc, sizeof(union sockaddr_union));
112 ddst = (struct sockaddr_encap *) &re->re_dst;
113 ddst->sen_family = PF_KEY;
114 ddst->sen_len = SENT_LEN;
115
116 switch (af) {
117 #ifdef INET
118 case AF_INET:
119 if (hlen < sizeof (struct ip) || m->m_pkthdr.len < hlen) {
120 *error = EINVAL;
121 return NULL;
122 }
123 ddst->sen_direction = direction;
124 ddst->sen_type = SENT_IP4;
125
126 m_copydata(m, offsetof(struct ip, ip_src),
127 sizeof(struct in_addr), (caddr_t) &(ddst->sen_ip_src));
128 m_copydata(m, offsetof(struct ip, ip_dst),
129 sizeof(struct in_addr), (caddr_t) &(ddst->sen_ip_dst));
130 m_copydata(m, offsetof(struct ip, ip_p), sizeof(u_int8_t),
131 (caddr_t) &(ddst->sen_proto));
132
133 sdst.sin.sin_family = ssrc.sin.sin_family = AF_INET;
134 sdst.sin.sin_len = ssrc.sin.sin_len =
135 sizeof(struct sockaddr_in);
136 ssrc.sin.sin_addr = ddst->sen_ip_src;
137 sdst.sin.sin_addr = ddst->sen_ip_dst;
138
139
140
141
142 switch (ddst->sen_proto) {
143 case IPPROTO_UDP:
144 case IPPROTO_TCP:
145
146 if (m->m_pkthdr.len < hlen + 2 * sizeof(u_int16_t)) {
147 *error = EINVAL;
148 return NULL;
149 }
150
151
152
153
154
155
156
157 m_copydata(m, hlen, sizeof(u_int16_t),
158 (caddr_t) &(ddst->sen_sport));
159 m_copydata(m, hlen + sizeof(u_int16_t), sizeof(u_int16_t),
160 (caddr_t) &(ddst->sen_dport));
161 break;
162
163 default:
164 ddst->sen_sport = 0;
165 ddst->sen_dport = 0;
166 }
167
168 break;
169 #endif
170
171 #ifdef INET6
172 case AF_INET6:
173 if (hlen < sizeof (struct ip6_hdr) || m->m_pkthdr.len < hlen) {
174 *error = EINVAL;
175 return NULL;
176 }
177 ddst->sen_type = SENT_IP6;
178 ddst->sen_ip6_direction = direction;
179
180 m_copydata(m, offsetof(struct ip6_hdr, ip6_src),
181 sizeof(struct in6_addr),
182 (caddr_t) &(ddst->sen_ip6_src));
183 m_copydata(m, offsetof(struct ip6_hdr, ip6_dst),
184 sizeof(struct in6_addr),
185 (caddr_t) &(ddst->sen_ip6_dst));
186 m_copydata(m, offsetof(struct ip6_hdr, ip6_nxt),
187 sizeof(u_int8_t),
188 (caddr_t) &(ddst->sen_ip6_proto));
189
190 sdst.sin6.sin6_family = ssrc.sin6.sin6_family = AF_INET6;
191 sdst.sin6.sin6_len = ssrc.sin6.sin6_family =
192 sizeof(struct sockaddr_in6);
193 in6_recoverscope(&ssrc.sin6, &ddst->sen_ip6_src, NULL);
194 in6_recoverscope(&sdst.sin6, &ddst->sen_ip6_dst, NULL);
195
196
197
198
199 switch (ddst->sen_ip6_proto) {
200 case IPPROTO_UDP:
201 case IPPROTO_TCP:
202
203 if (m->m_pkthdr.len < hlen + 2 * sizeof(u_int16_t)) {
204 *error = EINVAL;
205 return NULL;
206 }
207
208
209
210
211
212
213
214 m_copydata(m, hlen, sizeof(u_int16_t),
215 (caddr_t) &(ddst->sen_ip6_sport));
216 m_copydata(m, hlen + sizeof(u_int16_t), sizeof(u_int16_t),
217 (caddr_t) &(ddst->sen_ip6_dport));
218 break;
219
220 default:
221 ddst->sen_ip6_sport = 0;
222 ddst->sen_ip6_dport = 0;
223 }
224
225 break;
226 #endif
227
228 default:
229 *error = EAFNOSUPPORT;
230 return NULL;
231 }
232
233
234 rtalloc((struct route *) re);
235 if (re->re_rt == NULL) {
236
237
238
239
240 *error = 0;
241 return ipsp_spd_inp(m, af, hlen, error, direction,
242 tdbp, inp, NULL);
243 }
244
245
246 if ((re->re_rt->rt_gateway == NULL) ||
247 (((struct sockaddr_encap *) re->re_rt->rt_gateway)->sen_type !=
248 SENT_IPSP)) {
249 RTFREE(re->re_rt);
250 *error = EHOSTUNREACH;
251 DPRINTF(("ip_spd_lookup: no gateway in SPD entry!"));
252 return NULL;
253 }
254
255 ipo = ((struct sockaddr_encap *) (re->re_rt->rt_gateway))->sen_ipsp;
256 RTFREE(re->re_rt);
257 if (ipo == NULL) {
258 *error = EHOSTUNREACH;
259 DPRINTF(("ip_spd_lookup: no policy attached to SPD entry!"));
260 return NULL;
261 }
262
263 switch (ipo->ipo_type) {
264 case IPSP_PERMIT:
265 *error = 0;
266 return ipsp_spd_inp(m, af, hlen, error, direction, tdbp,
267 inp, ipo);
268
269 case IPSP_DENY:
270 *error = EHOSTUNREACH;
271 return NULL;
272
273 case IPSP_IPSEC_USE:
274 case IPSP_IPSEC_ACQUIRE:
275 case IPSP_IPSEC_REQUIRE:
276 case IPSP_IPSEC_DONTACQ:
277
278 break;
279
280 default:
281 *error = EINVAL;
282 return NULL;
283 }
284
285
286 switch (ipo->ipo_dst.sa.sa_family) {
287 #ifdef INET
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 #endif
294
295 #ifdef INET6
296 case AF_INET6:
297 if ((IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_dst.sin6.sin6_addr)) ||
298 (bcmp(&ipo->ipo_dst.sin6.sin6_addr, &in6mask128,
299 sizeof(in6mask128)) == 0))
300 dignore = 1;
301 break;
302 #endif
303 }
304
305
306 switch (ipo->ipo_src.sa.sa_family) {
307 #ifdef INET
308 case AF_INET:
309 if (ipo->ipo_src.sin.sin_addr.s_addr == INADDR_ANY)
310 signore = 1;
311 break;
312 #endif
313
314 #ifdef INET6
315 case AF_INET6:
316 if (IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_src.sin6.sin6_addr))
317 signore = 1;
318 break;
319 #endif
320 }
321
322
323 if ((ipo->ipo_tdb) && (ipo->ipo_tdb->tdb_flags & TDBF_INVALID)) {
324 TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head, ipo,
325 ipo_tdb_next);
326 ipo->ipo_tdb = NULL;
327 }
328
329
330 if (direction == IPSP_DIRECTION_OUT) {
331
332
333
334
335
336 if ((inp != NULL) &&
337 (inp->inp_seclevel[SL_ESP_TRANS] == IPSEC_LEVEL_BYPASS) &&
338 (inp->inp_seclevel[SL_ESP_NETWORK] ==
339 IPSEC_LEVEL_BYPASS) &&
340 (inp->inp_seclevel[SL_AUTH] == IPSEC_LEVEL_BYPASS)) {
341
342 if (dignore ||
343 !bcmp(&sdst, &ipo->ipo_dst, sdst.sa.sa_len)) {
344 *error = 0;
345 return NULL;
346 }
347 }
348
349
350 if (ipo->ipo_tdb) {
351 if ((ipo->ipo_last_searched <= ipsec_last_added) ||
352 (ipo->ipo_sproto != ipo->ipo_tdb->tdb_sproto) ||
353 bcmp(dignore ? &sdst : &ipo->ipo_dst,
354 &ipo->ipo_tdb->tdb_dst,
355 ipo->ipo_tdb->tdb_dst.sa.sa_len))
356 goto nomatchout;
357
358 if (!ipsp_aux_match(ipo->ipo_tdb,
359 ipo->ipo_srcid, ipo->ipo_dstid,
360 ipo->ipo_local_cred, NULL,
361 &ipo->ipo_addr, &ipo->ipo_mask))
362 goto nomatchout;
363
364
365 *error = 0;
366 return ipsp_spd_inp(m, af, hlen, error, direction,
367 tdbp, inp, ipo);
368
369 nomatchout:
370
371 TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head, ipo,
372 ipo_tdb_next);
373 ipo->ipo_tdb = NULL;
374 ipo->ipo_last_searched = 0;
375 }
376
377
378
379
380
381
382
383
384
385
386 if (ipo->ipo_last_searched <= ipsec_last_added) {
387
388 if (dignore == 0)
389 ipo->ipo_last_searched = time_second;
390
391
392 ipo->ipo_tdb =
393 gettdbbyaddr(dignore ? &sdst : &ipo->ipo_dst,
394 ipo->ipo_sproto, ipo->ipo_srcid,
395 ipo->ipo_dstid, ipo->ipo_local_cred, m, af,
396 &ipo->ipo_addr, &ipo->ipo_mask);
397 if (ipo->ipo_tdb) {
398 TAILQ_INSERT_TAIL(&ipo->ipo_tdb->tdb_policy_head,
399 ipo, ipo_tdb_next);
400 *error = 0;
401 return ipsp_spd_inp(m, af, hlen, error,
402 direction, tdbp, inp, ipo);
403 }
404 }
405
406
407 switch (ipo->ipo_type) {
408 case IPSP_IPSEC_REQUIRE:
409
410 if (ipsp_acquire_sa(ipo,
411 dignore ? &sdst : &ipo->ipo_dst,
412 signore ? NULL : &ipo->ipo_src, ddst, m) != 0) {
413 *error = EACCES;
414 return NULL;
415 }
416
417
418 case IPSP_IPSEC_DONTACQ:
419 *error = -EINVAL;
420 return NULL;
421
422 case IPSP_IPSEC_ACQUIRE:
423
424 ipsp_acquire_sa(ipo, dignore ? &sdst : &ipo->ipo_dst,
425 signore ? NULL : &ipo->ipo_src, ddst, NULL);
426
427
428 case IPSP_IPSEC_USE:
429 *error = 0;
430 return ipsp_spd_inp(m, af, hlen, error, direction,
431 tdbp, inp, ipo);
432 }
433 } else {
434 if (tdbp != NULL) {
435
436 if (ipo->ipo_tdb == tdbp) {
437 *error = 0;
438 return ipsp_spd_inp(m, af, hlen, error,
439 direction, tdbp, inp, ipo);
440 }
441
442 if (bcmp(dignore ? &ssrc : &ipo->ipo_dst,
443 &tdbp->tdb_src, tdbp->tdb_src.sa.sa_len) ||
444 (ipo->ipo_sproto != tdbp->tdb_sproto))
445 goto nomatchin;
446
447
448 if (ipo->ipo_srcid) {
449 if (tdbp->tdb_dstid == NULL ||
450 !ipsp_ref_match(ipo->ipo_srcid,
451 tdbp->tdb_dstid))
452 goto nomatchin;
453 }
454
455
456 if (ipo->ipo_dstid) {
457 if (tdbp->tdb_srcid == NULL ||
458 !ipsp_ref_match(ipo->ipo_dstid,
459 tdbp->tdb_srcid))
460 goto nomatchin;
461 }
462
463
464 if (ipo->ipo_tdb)
465 TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head,
466 ipo, ipo_tdb_next);
467 ipo->ipo_tdb = tdbp;
468 TAILQ_INSERT_TAIL(&tdbp->tdb_policy_head, ipo,
469 ipo_tdb_next);
470 *error = 0;
471 return ipsp_spd_inp(m, af, hlen, error, direction,
472 tdbp, inp, ipo);
473
474 nomatchin:
475 ;
476 }
477
478
479 if (ipo->ipo_tdb) {
480
481
482
483
484
485
486
487 if (ipo->ipo_sproto == ipo->ipo_tdb->tdb_sproto &&
488 !bcmp(&ipo->ipo_tdb->tdb_src,
489 dignore ? &ssrc : &ipo->ipo_dst,
490 ipo->ipo_tdb->tdb_src.sa.sa_len))
491 goto skipinputsearch;
492
493
494 TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head, ipo,
495 ipo_tdb_next);
496 ipo->ipo_last_searched = 0;
497 ipo->ipo_tdb = NULL;
498 }
499
500
501 if (ipo->ipo_last_searched <= ipsec_last_added) {
502 if (dignore == 0)
503 ipo->ipo_last_searched = time_second;
504
505 ipo->ipo_tdb =
506 gettdbbysrc(dignore ? &ssrc : &ipo->ipo_dst,
507 ipo->ipo_sproto, ipo->ipo_srcid,
508 ipo->ipo_dstid, m, af, &ipo->ipo_addr,
509 &ipo->ipo_mask);
510 if (ipo->ipo_tdb)
511 TAILQ_INSERT_TAIL(&ipo->ipo_tdb->tdb_policy_head,
512 ipo, ipo_tdb_next);
513 }
514 skipinputsearch:
515
516 switch (ipo->ipo_type) {
517 case IPSP_IPSEC_REQUIRE:
518
519 if (ipo->ipo_tdb) {
520 *error = -EINVAL;
521 return NULL;
522 }
523
524
525 if ((*error = ipsp_acquire_sa(ipo,
526 dignore ? &ssrc : &ipo->ipo_dst,
527 signore ? NULL : &ipo->ipo_src, ddst, m)) != 0)
528 return NULL;
529
530
531 case IPSP_IPSEC_DONTACQ:
532
533 *error = -EINVAL;
534 return NULL;
535
536 case IPSP_IPSEC_ACQUIRE:
537
538 if (ipo->ipo_tdb) {
539 *error = 0;
540 return ipsp_spd_inp(m, af, hlen, error,
541 direction, tdbp, inp, ipo);
542 }
543
544
545 ipsp_acquire_sa(ipo, dignore ? &ssrc : &ipo->ipo_dst,
546 signore ? NULL : &ipo->ipo_src, ddst, NULL);
547
548
549 case IPSP_IPSEC_USE:
550 *error = 0;
551 return ipsp_spd_inp(m, af, hlen, error, direction,
552 tdbp, inp, ipo);
553 }
554 }
555
556
557 *error = EINVAL;
558 return NULL;
559 }
560
561
562
563
564 int
565 ipsec_delete_policy(struct ipsec_policy *ipo)
566 {
567 struct ipsec_acquire *ipa;
568 int err = 0;
569
570 if (--ipo->ipo_ref_count > 0)
571 return 0;
572
573
574 if (!(ipo->ipo_flags & IPSP_POLICY_SOCKET))
575 err = rtrequest(RTM_DELETE, (struct sockaddr *) &ipo->ipo_addr,
576 (struct sockaddr *) 0,
577 (struct sockaddr *) &ipo->ipo_mask,
578 0, (struct rtentry **) 0, 0);
579
580 if (ipo->ipo_tdb != NULL)
581 TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head, ipo,
582 ipo_tdb_next);
583
584 while ((ipa = TAILQ_FIRST(&ipo->ipo_acquires)) != NULL)
585 ipsp_delete_acquire(ipa);
586
587 TAILQ_REMOVE(&ipsec_policy_head, ipo, ipo_list);
588
589 if (ipo->ipo_srcid)
590 ipsp_reffree(ipo->ipo_srcid);
591 if (ipo->ipo_dstid)
592 ipsp_reffree(ipo->ipo_dstid);
593 if (ipo->ipo_local_cred)
594 ipsp_reffree(ipo->ipo_local_cred);
595 if (ipo->ipo_local_auth)
596 ipsp_reffree(ipo->ipo_local_auth);
597
598 pool_put(&ipsec_policy_pool, ipo);
599
600 if (!(ipo->ipo_flags & IPSP_POLICY_SOCKET))
601 ipsec_in_use--;
602
603 return err;
604 }
605
606
607
608
609 struct ipsec_policy *
610 ipsec_add_policy(struct inpcb *inp, int af, int direction)
611 {
612 struct ipsec_policy *ipon;
613
614 if (ipsec_policy_pool_initialized == 0) {
615 ipsec_policy_pool_initialized = 1;
616 pool_init(&ipsec_policy_pool, sizeof(struct ipsec_policy),
617 0, 0, 0, "ipsec policy", NULL);
618 }
619
620 ipon = pool_get(&ipsec_policy_pool, 0);
621 if (ipon == NULL)
622 return NULL;
623
624 bzero(ipon, sizeof(struct ipsec_policy));
625
626 ipon->ipo_ref_count = 1;
627 ipon->ipo_flags |= IPSP_POLICY_SOCKET;
628
629 ipon->ipo_type = IPSP_IPSEC_REQUIRE;
630
631
632
633
634
635 ipon->ipo_sproto = IPPROTO_ESP;
636
637 TAILQ_INIT(&ipon->ipo_acquires);
638 TAILQ_INSERT_HEAD(&ipsec_policy_head, ipon, ipo_list);
639
640 ipsec_update_policy(inp, ipon, af, direction);
641
642 return ipon;
643 }
644
645
646
647
648 void
649 ipsec_update_policy(struct inpcb *inp, struct ipsec_policy *ipon, int af,
650 int direction)
651 {
652 ipon->ipo_addr.sen_len = ipon->ipo_mask.sen_len = SENT_LEN;
653 ipon->ipo_addr.sen_family = ipon->ipo_mask.sen_family = PF_KEY;
654 ipon->ipo_src.sa.sa_family = ipon->ipo_dst.sa.sa_family = af;
655
656 switch (af) {
657 case AF_INET:
658 #ifdef INET
659 ipon->ipo_addr.sen_type = ipon->ipo_mask.sen_type = SENT_IP4;
660 ipon->ipo_addr.sen_ip_src = inp->inp_laddr;
661 ipon->ipo_addr.sen_ip_dst = inp->inp_faddr;
662 ipon->ipo_addr.sen_sport = inp->inp_lport;
663 ipon->ipo_addr.sen_dport = inp->inp_fport;
664 ipon->ipo_addr.sen_proto =
665 inp->inp_socket->so_proto->pr_protocol;
666 ipon->ipo_addr.sen_direction = direction;
667
668 ipon->ipo_mask.sen_ip_src.s_addr = 0xffffffff;
669 ipon->ipo_mask.sen_ip_dst.s_addr = 0xffffffff;
670 ipon->ipo_mask.sen_sport = ipon->ipo_mask.sen_dport = 0xffff;
671 ipon->ipo_mask.sen_proto = 0xff;
672 ipon->ipo_mask.sen_direction = direction;
673
674 ipon->ipo_src.sa.sa_len = sizeof(struct sockaddr_in);
675 ipon->ipo_dst.sa.sa_len = sizeof(struct sockaddr_in);
676 ipon->ipo_src.sin.sin_addr = inp->inp_laddr;
677 ipon->ipo_dst.sin.sin_addr = inp->inp_faddr;
678 #endif
679 break;
680
681 case AF_INET6:
682 #ifdef INET6
683 ipon->ipo_addr.sen_type = ipon->ipo_mask.sen_type = SENT_IP6;
684 ipon->ipo_addr.sen_ip6_src = inp->inp_laddr6;
685 ipon->ipo_addr.sen_ip6_dst = inp->inp_faddr6;
686 ipon->ipo_addr.sen_ip6_sport = inp->inp_lport;
687 ipon->ipo_addr.sen_ip6_dport = inp->inp_fport;
688 ipon->ipo_addr.sen_ip6_proto =
689 inp->inp_socket->so_proto->pr_protocol;
690 ipon->ipo_addr.sen_ip6_direction = direction;
691
692 ipon->ipo_mask.sen_ip6_src = in6mask128;
693 ipon->ipo_mask.sen_ip6_dst = in6mask128;
694 ipon->ipo_mask.sen_ip6_sport = 0xffff;
695 ipon->ipo_mask.sen_ip6_dport = 0xffff;
696 ipon->ipo_mask.sen_ip6_proto = 0xff;
697 ipon->ipo_mask.sen_ip6_direction = direction;
698
699 ipon->ipo_src.sa.sa_len = sizeof(struct sockaddr_in6);
700 ipon->ipo_dst.sa.sa_len = sizeof(struct sockaddr_in6);
701 ipon->ipo_src.sin6.sin6_addr = inp->inp_laddr6;
702 ipon->ipo_dst.sin6.sin6_addr = inp->inp_faddr6;
703 #endif
704 break;
705 }
706 }
707
708
709
710
711 void
712 ipsp_delete_acquire(void *v)
713 {
714 struct ipsec_acquire *ipa = v;
715
716 timeout_del(&ipa->ipa_timeout);
717 TAILQ_REMOVE(&ipsec_acquire_head, ipa, ipa_next);
718 if (ipa->ipa_policy != NULL)
719 TAILQ_REMOVE(&ipa->ipa_policy->ipo_acquires, ipa,
720 ipa_ipo_next);
721 pool_put(&ipsec_acquire_pool, ipa);
722 }
723
724
725
726
727
728 struct ipsec_acquire *
729 ipsp_pending_acquire(struct ipsec_policy *ipo, union sockaddr_union *gw)
730 {
731 struct ipsec_acquire *ipa;
732
733 TAILQ_FOREACH (ipa, &ipo->ipo_acquires, ipa_ipo_next) {
734 if (!bcmp(gw, &ipa->ipa_addr, gw->sa.sa_len))
735 return ipa;
736 }
737
738 return NULL;
739 }
740
741
742
743
744
745 int
746 ipsp_acquire_sa(struct ipsec_policy *ipo, union sockaddr_union *gw,
747 union sockaddr_union *laddr, struct sockaddr_encap *ddst, struct mbuf *m)
748 {
749 struct ipsec_acquire *ipa;
750
751
752
753
754
755
756
757
758
759 if (ipo->ipo_flags & IPSP_POLICY_SOCKET &&
760 ipo->ipo_local_auth == NULL)
761 return EINVAL;
762
763
764 if ((ipa = ipsp_pending_acquire(ipo, gw)) != NULL)
765 return 0;
766
767
768 if (ipsec_acquire_pool_initialized == 0) {
769 ipsec_acquire_pool_initialized = 1;
770 pool_init(&ipsec_acquire_pool, sizeof(struct ipsec_acquire),
771 0, 0, 0, "ipsec acquire", NULL);
772 }
773
774 ipa = pool_get(&ipsec_acquire_pool, 0);
775 if (ipa == NULL)
776 return ENOMEM;
777
778 bzero(ipa, sizeof(struct ipsec_acquire));
779 bcopy(gw, &ipa->ipa_addr, sizeof(union sockaddr_union));
780
781 timeout_set(&ipa->ipa_timeout, ipsp_delete_acquire, ipa);
782
783 ipa->ipa_info.sen_len = ipa->ipa_mask.sen_len = SENT_LEN;
784 ipa->ipa_info.sen_family = ipa->ipa_mask.sen_family = PF_KEY;
785
786
787 switch (ipo->ipo_addr.sen_type) {
788 #ifdef INET
789 case SENT_IP4:
790 ipa->ipa_info.sen_type = ipa->ipa_mask.sen_type = SENT_IP4;
791 ipa->ipa_info.sen_direction = ipo->ipo_addr.sen_direction;
792 ipa->ipa_mask.sen_direction = ipo->ipo_mask.sen_direction;
793
794 if (ipo->ipo_mask.sen_ip_src.s_addr == INADDR_ANY ||
795 ipo->ipo_addr.sen_ip_src.s_addr == INADDR_ANY ||
796 ipsp_is_unspecified(ipo->ipo_dst)) {
797 ipa->ipa_info.sen_ip_src = ddst->sen_ip_src;
798 ipa->ipa_mask.sen_ip_src.s_addr = INADDR_BROADCAST;
799 } else {
800 ipa->ipa_info.sen_ip_src = ipo->ipo_addr.sen_ip_src;
801 ipa->ipa_mask.sen_ip_src = ipo->ipo_mask.sen_ip_src;
802 }
803
804 if (ipo->ipo_mask.sen_ip_dst.s_addr == INADDR_ANY ||
805 ipo->ipo_addr.sen_ip_dst.s_addr == INADDR_ANY ||
806 ipsp_is_unspecified(ipo->ipo_dst)) {
807 ipa->ipa_info.sen_ip_dst = ddst->sen_ip_dst;
808 ipa->ipa_mask.sen_ip_dst.s_addr = INADDR_BROADCAST;
809 } else {
810 ipa->ipa_info.sen_ip_dst = ipo->ipo_addr.sen_ip_dst;
811 ipa->ipa_mask.sen_ip_dst = ipo->ipo_mask.sen_ip_dst;
812 }
813
814 ipa->ipa_info.sen_proto = ipo->ipo_addr.sen_proto;
815 ipa->ipa_mask.sen_proto = ipo->ipo_mask.sen_proto;
816
817 if (ipo->ipo_addr.sen_proto) {
818 ipa->ipa_info.sen_sport = ipo->ipo_addr.sen_sport;
819 ipa->ipa_mask.sen_sport = ipo->ipo_mask.sen_sport;
820
821 ipa->ipa_info.sen_dport = ipo->ipo_addr.sen_dport;
822 ipa->ipa_mask.sen_dport = ipo->ipo_mask.sen_dport;
823 }
824 break;
825 #endif
826
827 #ifdef INET6
828 case SENT_IP6:
829 ipa->ipa_info.sen_type = ipa->ipa_mask.sen_type = SENT_IP6;
830 ipa->ipa_info.sen_ip6_direction =
831 ipo->ipo_addr.sen_ip6_direction;
832 ipa->ipa_mask.sen_ip6_direction =
833 ipo->ipo_mask.sen_ip6_direction;
834
835 if (IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_mask.sen_ip6_src) ||
836 IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_addr.sen_ip6_src) ||
837 ipsp_is_unspecified(ipo->ipo_dst)) {
838 ipa->ipa_info.sen_ip6_src = ddst->sen_ip6_src;
839 ipa->ipa_mask.sen_ip6_src = in6mask128;
840 } else {
841 ipa->ipa_info.sen_ip6_src = ipo->ipo_addr.sen_ip6_src;
842 ipa->ipa_mask.sen_ip6_src = ipo->ipo_mask.sen_ip6_src;
843 }
844
845 if (IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_mask.sen_ip6_dst) ||
846 IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_addr.sen_ip6_dst) ||
847 ipsp_is_unspecified(ipo->ipo_dst)) {
848 ipa->ipa_info.sen_ip6_dst = ddst->sen_ip6_dst;
849 ipa->ipa_mask.sen_ip6_dst = in6mask128;
850 } else {
851 ipa->ipa_info.sen_ip6_dst = ipo->ipo_addr.sen_ip6_dst;
852 ipa->ipa_mask.sen_ip6_dst = ipo->ipo_mask.sen_ip6_dst;
853 }
854
855 ipa->ipa_info.sen_ip6_proto = ipo->ipo_addr.sen_ip6_proto;
856 ipa->ipa_mask.sen_ip6_proto = ipo->ipo_mask.sen_ip6_proto;
857
858 if (ipo->ipo_mask.sen_ip6_proto) {
859 ipa->ipa_info.sen_ip6_sport =
860 ipo->ipo_addr.sen_ip6_sport;
861 ipa->ipa_mask.sen_ip6_sport =
862 ipo->ipo_mask.sen_ip6_sport;
863 ipa->ipa_info.sen_ip6_dport =
864 ipo->ipo_addr.sen_ip6_dport;
865 ipa->ipa_mask.sen_ip6_dport =
866 ipo->ipo_mask.sen_ip6_dport;
867 }
868 break;
869 #endif
870
871 default:
872 pool_put(&ipsec_acquire_pool, ipa);
873 return 0;
874 }
875
876 timeout_add(&ipa->ipa_timeout, ipsec_expire_acquire * hz);
877
878 TAILQ_INSERT_TAIL(&ipsec_acquire_head, ipa, ipa_next);
879 TAILQ_INSERT_TAIL(&ipo->ipo_acquires, ipa, ipa_ipo_next);
880 ipa->ipa_policy = ipo;
881
882
883 return pfkeyv2_acquire(ipo, gw, laddr, &ipa->ipa_seq, ddst);
884 }
885
886
887
888
889 struct tdb *
890 ipsp_spd_inp(struct mbuf *m, int af, int hlen, int *error, int direction,
891 struct tdb *tdbp, struct inpcb *inp, struct ipsec_policy *ipo)
892 {
893 struct ipsec_policy sipon;
894 struct tdb_ident *tdbi;
895 struct m_tag *mtag;
896 struct tdb *tdb = NULL;
897
898
899 if (inp == NULL)
900 goto justreturn;
901
902
903 if ((inp->inp_seclevel[SL_ESP_TRANS] == IPSEC_LEVEL_BYPASS ||
904 inp->inp_seclevel[SL_ESP_TRANS] == IPSEC_LEVEL_NONE) &&
905 (inp->inp_seclevel[SL_ESP_NETWORK] == IPSEC_LEVEL_BYPASS ||
906 inp->inp_seclevel[SL_ESP_NETWORK] == IPSEC_LEVEL_NONE) &&
907 (inp->inp_seclevel[SL_AUTH] == IPSEC_LEVEL_BYPASS ||
908 inp->inp_seclevel[SL_AUTH] == IPSEC_LEVEL_NONE))
909 goto justreturn;
910
911 switch (direction) {
912 case IPSP_DIRECTION_IN:
913
914
915
916
917
918 if ((inp->inp_seclevel[SL_ESP_TRANS] == IPSEC_LEVEL_AVAIL ||
919 inp->inp_seclevel[SL_ESP_TRANS] == IPSEC_LEVEL_USE) &&
920 (inp->inp_seclevel[SL_ESP_NETWORK] == IPSEC_LEVEL_AVAIL ||
921 inp->inp_seclevel[SL_ESP_NETWORK] == IPSEC_LEVEL_USE) &&
922 (inp->inp_seclevel[SL_AUTH] == IPSEC_LEVEL_AVAIL ||
923 inp->inp_seclevel[SL_AUTH] == IPSEC_LEVEL_USE))
924 goto justreturn;
925
926
927 if (inp->inp_ipo == NULL) {
928 inp->inp_ipo = ipsec_add_policy(inp, af,
929 IPSP_DIRECTION_OUT);
930 if (inp->inp_ipo == NULL) {
931 *error = ENOBUFS;
932 return NULL;
933 }
934 }
935
936
937
938
939
940 if (inp->inp_tdb_in != NULL) {
941 if (inp->inp_tdb_in == tdbp)
942 goto justreturn;
943
944
945
946
947
948
949
950 if (tdbp == NULL) {
951 *error = -EINVAL;
952 return NULL;
953 }
954
955
956 ipsec_update_policy(inp, inp->inp_ipo, af,
957 IPSP_DIRECTION_OUT);
958
959
960
961
962
963
964 if (tdbp->tdb_sproto == inp->inp_ipo->ipo_sproto &&
965 !bcmp(&tdbp->tdb_src, &inp->inp_ipo->ipo_dst,
966 SA_LEN(&tdbp->tdb_src.sa)) &&
967 ipsp_aux_match(tdbp,
968 inp->inp_ipo->ipo_srcid,
969 inp->inp_ipo->ipo_dstid,
970 NULL, NULL,
971 &inp->inp_ipo->ipo_addr,
972 &inp->inp_ipo->ipo_mask))
973 goto justreturn;
974 else {
975 *error = -EINVAL;
976 return NULL;
977 }
978 } else {
979
980 ipsec_update_policy(inp, inp->inp_ipo, af,
981 IPSP_DIRECTION_OUT);
982
983
984
985
986
987
988 if (tdbp != NULL &&
989 tdbp->tdb_sproto == inp->inp_ipo->ipo_sproto &&
990 !bcmp(&tdbp->tdb_src, &inp->inp_ipo->ipo_dst,
991 SA_LEN(&tdbp->tdb_src.sa)) &&
992 ipsp_aux_match(tdbp,
993 inp->inp_ipo->ipo_srcid,
994 inp->inp_ipo->ipo_dstid,
995 NULL, NULL,
996 &inp->inp_ipo->ipo_addr,
997 &inp->inp_ipo->ipo_mask))
998 goto justreturn;
999
1000
1001
1002
1003
1004
1005
1006 if (inp->inp_ipo->ipo_last_searched <=
1007 ipsec_last_added) {
1008 inp->inp_ipo->ipo_last_searched = time_second;
1009
1010
1011 if (gettdbbysrc(&inp->inp_ipo->ipo_dst,
1012 inp->inp_ipo->ipo_sproto,
1013 inp->inp_ipo->ipo_srcid,
1014 inp->inp_ipo->ipo_dstid, m, af,
1015 &inp->inp_ipo->ipo_addr,
1016 &inp->inp_ipo->ipo_mask) != NULL) {
1017 *error = -EINVAL;
1018 return NULL;
1019 }
1020
1021 }
1022
1023
1024
1025
1026
1027 ipsp_acquire_sa(inp->inp_ipo, &inp->inp_ipo->ipo_dst,
1028 &inp->inp_ipo->ipo_src, &inp->inp_ipo->ipo_addr, m);
1029 *error = -EINVAL;
1030 return NULL;
1031 }
1032
1033 break;
1034
1035 case IPSP_DIRECTION_OUT:
1036
1037 if (inp->inp_tdb_out != NULL) {
1038
1039
1040
1041
1042
1043 if (ipo != NULL && m != NULL &&
1044 ipo->ipo_tdb != NULL &&
1045 ipo->ipo_tdb != inp->inp_tdb_out) {
1046 tdb = inp->inp_tdb_out;
1047 goto tagandreturn;
1048 } else
1049 return inp->inp_tdb_out;
1050 }
1051
1052
1053
1054
1055
1056
1057
1058 if (inp->inp_ipo != NULL) {
1059 if (inp->inp_ipo->ipo_last_searched <=
1060 ipsec_last_added) {
1061 inp->inp_ipo->ipo_last_searched = time_second;
1062
1063
1064 ipsec_update_policy(inp, inp->inp_ipo, af,
1065 IPSP_DIRECTION_OUT);
1066
1067 tdb = gettdbbyaddr(&inp->inp_ipo->ipo_dst,
1068 inp->inp_ipo->ipo_sproto,
1069 inp->inp_ipo->ipo_srcid,
1070 inp->inp_ipo->ipo_dstid,
1071 inp->inp_ipo->ipo_local_cred, m, af,
1072 &inp->inp_ipo->ipo_addr,
1073 &inp->inp_ipo->ipo_mask);
1074 }
1075 } else {
1076
1077
1078
1079
1080 ipsec_update_policy(inp, &sipon, af,
1081 IPSP_DIRECTION_OUT);
1082
1083 tdb = gettdbbyaddr(&sipon.ipo_dst, IPPROTO_ESP, NULL,
1084 NULL, NULL, m, af, &sipon.ipo_addr,
1085 &sipon.ipo_mask);
1086 }
1087
1088
1089 if (tdb != NULL) {
1090 tdb_add_inp(tdb, inp, 0);
1091
1092 if (ipo != NULL && ipo->ipo_tdb != NULL &&
1093 ipo->ipo_tdb != inp->inp_tdb_out && m != NULL)
1094 goto tagandreturn;
1095 else
1096 return tdb;
1097 } else {
1098
1099 switch (inp->inp_seclevel[SL_ESP_TRANS]) {
1100 case IPSEC_LEVEL_BYPASS:
1101 case IPSEC_LEVEL_AVAIL:
1102
1103 goto justreturn;
1104 case IPSEC_LEVEL_USE:
1105 case IPSEC_LEVEL_REQUIRE:
1106 case IPSEC_LEVEL_UNIQUE:
1107
1108 if (inp->inp_ipo == NULL) {
1109 inp->inp_ipo = ipsec_add_policy(inp, af, IPSP_DIRECTION_OUT);
1110 if (inp->inp_ipo == NULL) {
1111 *error = ENOBUFS;
1112 return NULL;
1113 }
1114 }
1115
1116
1117 if ((*error = ipsp_acquire_sa(inp->inp_ipo,
1118 &inp->inp_ipo->ipo_dst,
1119 &inp->inp_ipo->ipo_src,
1120 &inp->inp_ipo->ipo_addr, m)) == 0)
1121 *error = -EINVAL;
1122
1123 return NULL;
1124 default:
1125 DPRINTF(("ipsp_spd_inp: unknown sock security"
1126 " level %d",
1127 inp->inp_seclevel[SL_ESP_TRANS]));
1128 *error = -EINVAL;
1129 return NULL;
1130 }
1131 }
1132 break;
1133
1134 default:
1135 *error = -EINVAL;
1136 return NULL;
1137 }
1138
1139 tagandreturn:
1140 if (tdb == NULL)
1141 goto justreturn;
1142
1143 mtag = m_tag_get(PACKET_TAG_IPSEC_PENDING_TDB,
1144 sizeof (struct tdb_ident), M_NOWAIT);
1145 if (mtag == NULL) {
1146 *error = ENOMEM;
1147 return NULL;
1148 }
1149
1150 tdbi = (struct tdb_ident *)(mtag + 1);
1151 tdbi->spi = ipo->ipo_tdb->tdb_spi;
1152 tdbi->proto = ipo->ipo_tdb->tdb_sproto;
1153 bcopy(&ipo->ipo_tdb->tdb_dst, &tdbi->dst,
1154 ipo->ipo_tdb->tdb_dst.sa.sa_len);
1155 m_tag_prepend(m, mtag);
1156 return tdb;
1157
1158 justreturn:
1159 if (ipo != NULL)
1160 return ipo->ipo_tdb;
1161 else
1162 return NULL;
1163 }
1164
1165
1166
1167
1168
1169 struct ipsec_acquire *
1170 ipsec_get_acquire(u_int32_t seq)
1171 {
1172 struct ipsec_acquire *ipa;
1173
1174 TAILQ_FOREACH (ipa, &ipsec_acquire_head, ipa_next)
1175 if (ipa->ipa_seq == seq)
1176 return ipa;
1177
1178 return NULL;
1179 }