if_ipsec.c revision 1.3.4.1 1 /* $NetBSD: if_ipsec.c,v 1.3.4.1 2018/03/15 09:12:06 pgoyette Exp $ */
2
3 /*
4 * Copyright (c) 2017 Internet Initiative Japan Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include <sys/cdefs.h>
30 __KERNEL_RCSID(0, "$NetBSD: if_ipsec.c,v 1.3.4.1 2018/03/15 09:12:06 pgoyette Exp $");
31
32 #ifdef _KERNEL_OPT
33 #include "opt_inet.h"
34 #endif
35
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/kernel.h>
39 #include <sys/mbuf.h>
40 #include <sys/socket.h>
41 #include <sys/sockio.h>
42 #include <sys/errno.h>
43 #include <sys/ioctl.h>
44 #include <sys/time.h>
45 #include <sys/syslog.h>
46 #include <sys/cpu.h>
47 #include <sys/kmem.h>
48 #include <sys/mutex.h>
49 #include <sys/pserialize.h>
50 #include <sys/psref.h>
51
52 #include <net/if.h>
53 #include <net/if_types.h>
54 #include <net/route.h>
55 #include <net/bpf.h>
56 #include <net/pfkeyv2.h>
57
58 #include <netinet/in.h>
59 #include <netinet/in_systm.h>
60 #include <netinet/ip.h>
61 #ifdef INET
62 #include <netinet/in_var.h>
63 #endif /* INET */
64
65 #ifdef INET6
66 #include <netinet6/in6_var.h>
67 #include <netinet/ip6.h>
68 #include <netinet6/ip6_var.h>
69 #endif /* INET6 */
70
71 #include <netinet/ip_encap.h>
72
73 #include <net/if_ipsec.h>
74
75 #include <net/raw_cb.h>
76 #include <net/pfkeyv2.h>
77
78 #include <netipsec/key.h>
79 #include <netipsec/ipsec.h>
80 #include <netipsec/ipsecif.h>
81
82 static void if_ipsec_ro_init_pc(void *, void *, struct cpu_info *);
83 static void if_ipsec_ro_fini_pc(void *, void *, struct cpu_info *);
84
85 static int if_ipsec_clone_create(struct if_clone *, int);
86 static int if_ipsec_clone_destroy(struct ifnet *);
87
88 static inline int if_ipsec_out_direct(struct ipsec_variant *, struct mbuf *, int);
89 static inline void if_ipsec_in_enqueue(struct mbuf *, int, struct ifnet *);
90
91 static int if_ipsec_encap_attach(struct ipsec_variant *);
92 static int if_ipsec_encap_detach(struct ipsec_variant *);
93 static int if_ipsec_set_tunnel(struct ifnet *,
94 struct sockaddr *, struct sockaddr *);
95 static void if_ipsec_delete_tunnel(struct ifnet *);
96 static int if_ipsec_ensure_flags(struct ifnet *, short);
97 static void if_ipsec_attach0(struct ipsec_softc *);
98
99 static int if_ipsec_update_variant(struct ipsec_softc *,
100 struct ipsec_variant *, struct ipsec_variant *);
101
102 /* sadb_msg */
103 static inline void if_ipsec_add_mbuf(struct mbuf *, void *, size_t);
104 static inline void if_ipsec_add_pad(struct mbuf *, size_t);
105 static inline size_t if_ipsec_set_sadb_addr(struct sadb_address *,
106 struct sockaddr *, int, uint16_t);
107 static inline size_t if_ipsec_set_sadb_src(struct sadb_address *,
108 struct sockaddr *, int);
109 static inline size_t if_ipsec_set_sadb_dst(struct sadb_address *,
110 struct sockaddr *, int);
111 static inline size_t if_ipsec_set_sadb_x_policy(struct sadb_x_policy *,
112 struct sadb_x_ipsecrequest *, uint16_t, uint8_t, uint32_t, uint8_t,
113 struct sockaddr *, struct sockaddr *);
114 static inline void if_ipsec_set_sadb_msg(struct sadb_msg *, uint16_t, uint8_t);
115 static inline void if_ipsec_set_sadb_msg_add(struct sadb_msg *, uint16_t);
116 static inline void if_ipsec_set_sadb_msg_del(struct sadb_msg *, uint16_t);
117 /* SPD */
118 static int if_ipsec_share_sp(struct ipsec_variant *);
119 static int if_ipsec_unshare_sp(struct ipsec_variant *);
120 static inline struct secpolicy *if_ipsec_add_sp0(struct sockaddr *,
121 in_port_t, struct sockaddr *, in_port_t, int, int, int, u_int);
122 static inline int if_ipsec_del_sp0(struct secpolicy *);
123 static int if_ipsec_add_sp(struct ipsec_variant *,
124 struct sockaddr *, in_port_t, struct sockaddr *, in_port_t);
125 static void if_ipsec_del_sp(struct ipsec_variant *);
126 static int if_ipsec_replace_sp(struct ipsec_softc *, struct ipsec_variant *,
127 struct ipsec_variant *);
128
129 static int if_ipsec_set_addr_port(struct sockaddr *, struct sockaddr *,
130 in_port_t);
131 #define IF_IPSEC_GATHER_PSRC_ADDR_PORT(var, target) \
132 if_ipsec_set_addr_port(target, (var)->iv_psrc, (var)->iv_sport)
133 #define IF_IPSEC_GATHER_PDST_ADDR_PORT(var, target) \
134 if_ipsec_set_addr_port(target, (var)->iv_pdst, (var)->iv_dport)
135
136 /*
137 * ipsec global variable definitions
138 */
139
140 /* This list is used in ioctl context only. */
141 LIST_HEAD(ipsec_sclist, ipsec_softc);
142 static struct {
143 struct ipsec_sclist list;
144 kmutex_t lock;
145 } ipsec_softcs __cacheline_aligned;
146
147 pserialize_t ipsec_psz __read_mostly;
148 struct psref_class *iv_psref_class __read_mostly;
149
150 struct if_clone ipsec_cloner =
151 IF_CLONE_INITIALIZER("ipsec", if_ipsec_clone_create, if_ipsec_clone_destroy);
152 static int max_ipsec_nesting = MAX_IPSEC_NEST;
153
154 /* ARGSUSED */
155 void
156 ipsecifattach(int count)
157 {
158
159 mutex_init(&ipsec_softcs.lock, MUTEX_DEFAULT, IPL_NONE);
160 LIST_INIT(&ipsec_softcs.list);
161
162 ipsec_psz = pserialize_create();
163 iv_psref_class = psref_class_create("ipsecvar", IPL_SOFTNET);
164
165 if_clone_attach(&ipsec_cloner);
166 }
167
168 static int
169 if_ipsec_clone_create(struct if_clone *ifc, int unit)
170 {
171 struct ipsec_softc *sc;
172 struct ipsec_variant *var;
173
174 sc = kmem_zalloc(sizeof(*sc), KM_SLEEP);
175
176 if_initname(&sc->ipsec_if, ifc->ifc_name, unit);
177
178 if_ipsec_attach0(sc);
179
180 var = kmem_zalloc(sizeof(*var), KM_SLEEP);
181 var->iv_softc = sc;
182 psref_target_init(&var->iv_psref, iv_psref_class);
183
184 sc->ipsec_var = var;
185 mutex_init(&sc->ipsec_lock, MUTEX_DEFAULT, IPL_NONE);
186 sc->ipsec_ro_percpu = percpu_alloc(sizeof(struct ipsec_ro));
187 percpu_foreach(sc->ipsec_ro_percpu, if_ipsec_ro_init_pc, NULL);
188
189 mutex_enter(&ipsec_softcs.lock);
190 LIST_INSERT_HEAD(&ipsec_softcs.list, sc, ipsec_list);
191 mutex_exit(&ipsec_softcs.lock);
192 return 0;
193 }
194
195 static void
196 if_ipsec_attach0(struct ipsec_softc *sc)
197 {
198
199 sc->ipsec_if.if_addrlen = 0;
200 sc->ipsec_if.if_mtu = IPSEC_MTU;
201 sc->ipsec_if.if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
202 /* set ipsec(4) specific default flags. */
203 sc->ipsec_if.if_flags |= IFF_FWD_IPV6;
204 sc->ipsec_if.if_extflags = IFEF_NO_LINK_STATE_CHANGE | IFEF_MPSAFE;
205 sc->ipsec_if.if_ioctl = if_ipsec_ioctl;
206 sc->ipsec_if.if_output = if_ipsec_output;
207 sc->ipsec_if.if_type = IFT_IPSEC;
208 sc->ipsec_if.if_dlt = DLT_NULL;
209 sc->ipsec_if.if_softc = sc;
210 IFQ_SET_READY(&sc->ipsec_if.if_snd);
211 if_initialize(&sc->ipsec_if);
212 if_alloc_sadl(&sc->ipsec_if);
213 bpf_attach(&sc->ipsec_if, DLT_NULL, sizeof(u_int));
214 if_register(&sc->ipsec_if);
215 }
216
217 static void
218 if_ipsec_ro_init_pc(void *p, void *arg __unused, struct cpu_info *ci __unused)
219 {
220 struct ipsec_ro *iro = p;
221
222 mutex_init(&iro->ir_lock, MUTEX_DEFAULT, IPL_NONE);
223 }
224
225 static void
226 if_ipsec_ro_fini_pc(void *p, void *arg __unused, struct cpu_info *ci __unused)
227 {
228 struct ipsec_ro *iro = p;
229
230 rtcache_free(&iro->ir_ro);
231
232 mutex_destroy(&iro->ir_lock);
233 }
234
235 static int
236 if_ipsec_clone_destroy(struct ifnet *ifp)
237 {
238 struct ipsec_softc *sc = ifp->if_softc;
239 struct ipsec_variant *var;
240 int bound;
241
242 mutex_enter(&ipsec_softcs.lock);
243 LIST_REMOVE(sc, ipsec_list);
244 mutex_exit(&ipsec_softcs.lock);
245
246 bound = curlwp_bind();
247 if_ipsec_delete_tunnel(&sc->ipsec_if);
248 curlwp_bindx(bound);
249
250 bpf_detach(ifp);
251 if_detach(ifp);
252
253 percpu_foreach(sc->ipsec_ro_percpu, if_ipsec_ro_fini_pc, NULL);
254 percpu_free(sc->ipsec_ro_percpu, sizeof(struct ipsec_ro));
255
256 mutex_destroy(&sc->ipsec_lock);
257
258 var = sc->ipsec_var;
259 kmem_free(var, sizeof(*var));
260 kmem_free(sc, sizeof(*sc));
261
262 return 0;
263 }
264
265 static inline bool
266 if_ipsec_nat_t(struct ipsec_softc *sc)
267 {
268
269 return (sc->ipsec_if.if_flags & IFF_NAT_T) != 0;
270 }
271
272 static inline bool
273 if_ipsec_fwd_ipv6(struct ipsec_softc *sc)
274 {
275
276 return (sc->ipsec_if.if_flags & IFF_FWD_IPV6) != 0;
277 }
278
279 int
280 if_ipsec_encap_func(struct mbuf *m, int off, int proto, void *arg)
281 {
282 struct ip ip;
283 struct ipsec_softc *sc;
284 struct ipsec_variant *var = NULL;
285 struct psref psref;
286 int ret = 0;
287
288 sc = arg;
289 KASSERT(sc != NULL);
290
291 if ((sc->ipsec_if.if_flags & IFF_UP) == 0)
292 goto out;
293
294 var = if_ipsec_getref_variant(sc, &psref);
295 if (if_ipsec_variant_is_unconfigured(var))
296 goto out;
297
298 switch (proto) {
299 case IPPROTO_IPV4:
300 case IPPROTO_IPV6:
301 break;
302 default:
303 goto out;
304 }
305
306 if (m->m_pkthdr.len < sizeof(ip))
307 goto out;
308
309 m_copydata(m, 0, sizeof(ip), &ip);
310 switch (ip.ip_v) {
311 #ifdef INET
312 case IPVERSION:
313 if (var->iv_psrc->sa_family != AF_INET ||
314 var->iv_pdst->sa_family != AF_INET)
315 goto out;
316 ret = ipsecif4_encap_func(m, &ip, var);
317 break;
318 #endif
319 default:
320 goto out;
321 }
322
323 out:
324 if (var != NULL)
325 if_ipsec_putref_variant(var, &psref);
326 return ret;
327 }
328
329 /*
330 * ipsec(4) I/F may cause infinite recursion calls when misconfigured.
331 * We'll prevent this by introducing upper limit.
332 */
333 static int
334 if_ipsec_check_nesting(struct ifnet *ifp, struct mbuf *m)
335 {
336
337 return if_tunnel_check_nesting(ifp, m, max_ipsec_nesting);
338 }
339
340 int
341 if_ipsec_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
342 const struct rtentry *rt)
343 {
344 struct ipsec_softc *sc = ifp->if_softc;
345 struct ipsec_variant *var;
346 struct psref psref;
347 int error;
348 int bound;
349
350 IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family);
351
352 error = if_ipsec_check_nesting(ifp, m);
353 if (error) {
354 m_freem(m);
355 goto noref_end;
356 }
357
358 if ((ifp->if_flags & IFF_UP) == 0) {
359 m_freem(m);
360 error = ENETDOWN;
361 goto noref_end;
362 }
363
364
365 bound = curlwp_bind();
366 var = if_ipsec_getref_variant(sc, &psref);
367 if (if_ipsec_variant_is_unconfigured(var)) {
368 m_freem(m);
369 error = ENETDOWN;
370 goto end;
371 }
372
373 m->m_flags &= ~(M_BCAST|M_MCAST);
374
375 /* use DLT_NULL encapsulation here to pass inner af type */
376 M_PREPEND(m, sizeof(int), M_DONTWAIT);
377 if (!m) {
378 error = ENOBUFS;
379 goto end;
380 }
381 *mtod(m, int *) = dst->sa_family;
382
383 #if INET6
384 /* drop IPv6 packet if IFF_FWD_IPV6 is not set */
385 if (dst->sa_family == AF_INET6 &&
386 !if_ipsec_fwd_ipv6(sc)) {
387 /*
388 * IPv6 packet is not allowed to forward,that is not error.
389 */
390 error = 0;
391 IF_DROP(&ifp->if_snd);
392 m_freem(m);
393 goto end;
394 }
395 #endif
396
397 error = if_ipsec_out_direct(var, m, dst->sa_family);
398
399 end:
400 if_ipsec_putref_variant(var, &psref);
401 curlwp_bindx(bound);
402 noref_end:
403 if (error)
404 ifp->if_oerrors++;
405
406 return error;
407 }
408
409 static inline int
410 if_ipsec_out_direct(struct ipsec_variant *var, struct mbuf *m, int family)
411 {
412 struct ifnet *ifp = &var->iv_softc->ipsec_if;
413 int error;
414 int len;
415
416 KASSERT(if_ipsec_heldref_variant(var));
417 KASSERT(var->iv_output != NULL);
418
419 len = m->m_pkthdr.len;
420
421 /* input DLT_NULL frame to BPF */
422 bpf_mtap(ifp, m);
423
424 /* grab and chop off inner af type */
425 /* XXX need pullup? */
426 m_adj(m, sizeof(int));
427
428 error = var->iv_output(var, family, m);
429 if (error)
430 return error;
431
432 ifp->if_opackets++;
433 ifp->if_obytes += len;
434
435 return 0;
436 }
437
438 void
439 if_ipsec_input(struct mbuf *m, int af, struct ifnet *ifp)
440 {
441
442 KASSERT(ifp != NULL);
443
444 m_set_rcvif(m, ifp);
445
446 bpf_mtap_af(ifp, af, m);
447
448 if_ipsec_in_enqueue(m, af, ifp);
449
450 return;
451 }
452
453 static inline void
454 if_ipsec_in_enqueue(struct mbuf *m, int af, struct ifnet *ifp)
455 {
456 pktqueue_t *pktq;
457 int pktlen;
458
459 /*
460 * Put the packet to the network layer input queue according to the
461 * specified address family.
462 */
463 switch (af) {
464 #ifdef INET
465 case AF_INET:
466 pktq = ip_pktq;
467 break;
468 #endif
469 #ifdef INET6
470 case AF_INET6:
471 pktq = ip6_pktq;
472 break;
473 #endif
474 default:
475 ifp->if_ierrors++;
476 m_freem(m);
477 return;
478 }
479
480 #if 1
481 const u_int h = curcpu()->ci_index;
482 #else
483 const uint32_t h = pktq_rps_hash(m);
484 #endif
485 pktlen = m->m_pkthdr.len;
486 if (__predict_true(pktq_enqueue(pktq, m, h))) {
487 ifp->if_ibytes += pktlen;
488 ifp->if_ipackets++;
489 } else {
490 m_freem(m);
491 }
492
493 return;
494 }
495
496 static inline int
497 if_ipsec_check_salen(struct sockaddr *addr)
498 {
499
500 switch (addr->sa_family) {
501 #ifdef INET
502 case AF_INET:
503 if (addr->sa_len != sizeof(struct sockaddr_in))
504 return EINVAL;
505 break;
506 #endif /* INET */
507 #ifdef INET6
508 case AF_INET6:
509 if (addr->sa_len != sizeof(struct sockaddr_in6))
510 return EINVAL;
511 break;
512 #endif /* INET6 */
513 default:
514 return EAFNOSUPPORT;
515 }
516
517 return 0;
518 }
519
520 /* XXX how should we handle IPv6 scope on SIOC[GS]IFPHYADDR? */
521 int
522 if_ipsec_ioctl(struct ifnet *ifp, u_long cmd, void *data)
523 {
524 struct ipsec_softc *sc = ifp->if_softc;
525 struct ipsec_variant *var = NULL;
526 struct ifreq *ifr = (struct ifreq*)data;
527 struct ifaddr *ifa = (struct ifaddr*)data;
528 int error = 0, size;
529 struct sockaddr *dst, *src;
530 u_long mtu;
531 short oflags = ifp->if_flags;
532 int bound;
533 struct psref psref;
534
535 switch (cmd) {
536 case SIOCINITIFADDR:
537 ifp->if_flags |= IFF_UP;
538 ifa->ifa_rtrequest = p2p_rtrequest;
539 break;
540
541 case SIOCSIFDSTADDR:
542 break;
543
544 case SIOCADDMULTI:
545 case SIOCDELMULTI:
546 switch (ifr->ifr_addr.sa_family) {
547 #ifdef INET
548 case AF_INET: /* IP supports Multicast */
549 break;
550 #endif /* INET */
551 #ifdef INET6
552 case AF_INET6: /* IP6 supports Multicast */
553 break;
554 #endif /* INET6 */
555 default: /* Other protocols doesn't support Multicast */
556 error = EAFNOSUPPORT;
557 break;
558 }
559 break;
560
561 case SIOCSIFMTU:
562 mtu = ifr->ifr_mtu;
563 if (mtu < IPSEC_MTU_MIN || mtu > IPSEC_MTU_MAX)
564 return EINVAL;
565 else if ((error = ifioctl_common(ifp, cmd, data)) == ENETRESET)
566 error = 0;
567 break;
568
569 #ifdef INET
570 case SIOCSIFPHYADDR:
571 #endif
572 #ifdef INET6
573 case SIOCSIFPHYADDR_IN6:
574 #endif /* INET6 */
575 case SIOCSLIFPHYADDR:
576 switch (cmd) {
577 #ifdef INET
578 case SIOCSIFPHYADDR:
579 src = (struct sockaddr *)
580 &(((struct in_aliasreq *)data)->ifra_addr);
581 dst = (struct sockaddr *)
582 &(((struct in_aliasreq *)data)->ifra_dstaddr);
583 break;
584 #endif /* INET */
585 #ifdef INET6
586 case SIOCSIFPHYADDR_IN6:
587 src = (struct sockaddr *)
588 &(((struct in6_aliasreq *)data)->ifra_addr);
589 dst = (struct sockaddr *)
590 &(((struct in6_aliasreq *)data)->ifra_dstaddr);
591 break;
592 #endif /* INET6 */
593 case SIOCSLIFPHYADDR:
594 src = (struct sockaddr *)
595 &(((struct if_laddrreq *)data)->addr);
596 dst = (struct sockaddr *)
597 &(((struct if_laddrreq *)data)->dstaddr);
598 break;
599 default:
600 return EINVAL;
601 }
602
603 /* sa_family must be equal */
604 if (src->sa_family != dst->sa_family)
605 return EINVAL;
606
607 error = if_ipsec_check_salen(src);
608 if (error)
609 return error;
610 error = if_ipsec_check_salen(dst);
611 if (error)
612 return error;
613
614 /* check sa_family looks sane for the cmd */
615 switch (cmd) {
616 #ifdef INET
617 case SIOCSIFPHYADDR:
618 if (src->sa_family == AF_INET)
619 break;
620 return EAFNOSUPPORT;
621 #endif /* INET */
622 #ifdef INET6
623 case SIOCSIFPHYADDR_IN6:
624 if (src->sa_family == AF_INET6)
625 break;
626 return EAFNOSUPPORT;
627 #endif /* INET6 */
628 case SIOCSLIFPHYADDR:
629 /* checks done in the above */
630 break;
631 }
632 /*
633 * calls if_ipsec_getref_variant() for other softcs to check
634 * address pair duplicattion
635 */
636 bound = curlwp_bind();
637 error = if_ipsec_set_tunnel(&sc->ipsec_if, src, dst);
638 if (error)
639 goto bad;
640 break;
641
642 case SIOCDIFPHYADDR:
643 bound = curlwp_bind();
644 if_ipsec_delete_tunnel(&sc->ipsec_if);
645 curlwp_bindx(bound);
646 break;
647
648 case SIOCGIFPSRCADDR:
649 #ifdef INET6
650 case SIOCGIFPSRCADDR_IN6:
651 #endif /* INET6 */
652 bound = curlwp_bind();
653 var = if_ipsec_getref_variant(sc, &psref);
654 if (var->iv_psrc == NULL) {
655 error = EADDRNOTAVAIL;
656 goto bad;
657 }
658 src = var->iv_psrc;
659 switch (cmd) {
660 #ifdef INET
661 case SIOCGIFPSRCADDR:
662 dst = &ifr->ifr_addr;
663 size = sizeof(ifr->ifr_addr);
664 break;
665 #endif /* INET */
666 #ifdef INET6
667 case SIOCGIFPSRCADDR_IN6:
668 dst = (struct sockaddr *)
669 &(((struct in6_ifreq *)data)->ifr_addr);
670 size = sizeof(((struct in6_ifreq *)data)->ifr_addr);
671 break;
672 #endif /* INET6 */
673 default:
674 error = EADDRNOTAVAIL;
675 goto bad;
676 }
677 if (src->sa_len > size) {
678 error = EINVAL;
679 goto bad;
680 }
681 error = IF_IPSEC_GATHER_PSRC_ADDR_PORT(var, dst);
682 if (error)
683 goto bad;
684 if_ipsec_putref_variant(var, &psref);
685 curlwp_bindx(bound);
686 break;
687
688 case SIOCGIFPDSTADDR:
689 #ifdef INET6
690 case SIOCGIFPDSTADDR_IN6:
691 #endif /* INET6 */
692 bound = curlwp_bind();
693 var = if_ipsec_getref_variant(sc, &psref);
694 if (var->iv_pdst == NULL) {
695 error = EADDRNOTAVAIL;
696 goto bad;
697 }
698 src = var->iv_pdst;
699 switch (cmd) {
700 #ifdef INET
701 case SIOCGIFPDSTADDR:
702 dst = &ifr->ifr_addr;
703 size = sizeof(ifr->ifr_addr);
704 break;
705 #endif /* INET */
706 #ifdef INET6
707 case SIOCGIFPDSTADDR_IN6:
708 dst = (struct sockaddr *)
709 &(((struct in6_ifreq *)data)->ifr_addr);
710 size = sizeof(((struct in6_ifreq *)data)->ifr_addr);
711 break;
712 #endif /* INET6 */
713 default:
714 error = EADDRNOTAVAIL;
715 goto bad;
716 }
717 if (src->sa_len > size) {
718 error = EINVAL;
719 goto bad;
720 }
721 error = IF_IPSEC_GATHER_PDST_ADDR_PORT(var, dst);
722 if (error)
723 goto bad;
724 if_ipsec_putref_variant(var, &psref);
725 curlwp_bindx(bound);
726 break;
727
728 case SIOCGLIFPHYADDR:
729 bound = curlwp_bind();
730 var = if_ipsec_getref_variant(sc, &psref);
731 if (if_ipsec_variant_is_unconfigured(var)) {
732 error = EADDRNOTAVAIL;
733 goto bad;
734 }
735
736 /* copy src */
737 src = var->iv_psrc;
738 dst = (struct sockaddr *)
739 &(((struct if_laddrreq *)data)->addr);
740 size = sizeof(((struct if_laddrreq *)data)->addr);
741 if (src->sa_len > size) {
742 error = EINVAL;
743 goto bad;
744 }
745 error = IF_IPSEC_GATHER_PSRC_ADDR_PORT(var, dst);
746 if (error)
747 goto bad;
748
749 /* copy dst */
750 src = var->iv_pdst;
751 dst = (struct sockaddr *)
752 &(((struct if_laddrreq *)data)->dstaddr);
753 size = sizeof(((struct if_laddrreq *)data)->dstaddr);
754 if (src->sa_len > size) {
755 error = EINVAL;
756 goto bad;
757 }
758 error = IF_IPSEC_GATHER_PDST_ADDR_PORT(var, dst);
759 if (error)
760 goto bad;
761 if_ipsec_putref_variant(var, &psref);
762 curlwp_bindx(bound);
763 break;
764
765 default:
766 error = ifioctl_common(ifp, cmd, data);
767 if (!error) {
768 bound = curlwp_bind();
769 error = if_ipsec_ensure_flags(&sc->ipsec_if, oflags);
770 if (error)
771 goto bad;
772 }
773 break;
774 }
775 return error;
776
777 bad:
778 if (var != NULL)
779 if_ipsec_putref_variant(var, &psref);
780 curlwp_bindx(bound);
781
782 return error;
783 }
784
785 struct encap_funcs {
786 #ifdef INET
787 int (*ef_inet)(struct ipsec_variant *);
788 #endif
789 #ifdef INET6
790 int (*ef_inet6)(struct ipsec_variant *);
791 #endif
792 };
793
794 static struct encap_funcs ipsec_encap_attach = {
795 #ifdef INET
796 .ef_inet = ipsecif4_attach,
797 #endif
798 #ifdef INET6
799 .ef_inet6 = &ipsecif6_attach,
800 #endif
801 };
802
803 static struct encap_funcs ipsec_encap_detach = {
804 #ifdef INET
805 .ef_inet = ipsecif4_detach,
806 #endif
807 #ifdef INET6
808 .ef_inet6 = &ipsecif6_detach,
809 #endif
810 };
811
812 static int
813 if_ipsec_encap_common(struct ipsec_variant *var, struct encap_funcs *funcs)
814 {
815 int error;
816
817 KASSERT(var != NULL);
818 KASSERT(if_ipsec_variant_is_configured(var));
819
820 switch (var->iv_psrc->sa_family) {
821 #ifdef INET
822 case AF_INET:
823 error = (funcs->ef_inet)(var);
824 break;
825 #endif /* INET */
826 #ifdef INET6
827 case AF_INET6:
828 error = (funcs->ef_inet6)(var);
829 break;
830 #endif /* INET6 */
831 default:
832 error = EINVAL;
833 break;
834 }
835
836 return error;
837 }
838
839 static int
840 if_ipsec_encap_attach(struct ipsec_variant *var)
841 {
842
843 return if_ipsec_encap_common(var, &ipsec_encap_attach);
844 }
845
846 static int
847 if_ipsec_encap_detach(struct ipsec_variant *var)
848 {
849
850 return if_ipsec_encap_common(var, &ipsec_encap_detach);
851 }
852
853 /*
854 * Validate and set ipsec(4) I/F configurations.
855 * (1) validate
856 * (1-1) Check the argument src and dst address pair will change
857 * configuration from current src and dst address pair.
858 * (1-2) Check any ipsec(4) I/F uses duplicated src and dst address pair
859 * with argument src and dst address pair, except for NAT-T shared
860 * tunnels.
861 * (2) set
862 * (2-1) Create variant for new configuration.
863 * (2-2) Create temporary "null" variant used to avoid to access
864 * dangling variant while SPs are deleted and added.
865 * (2-3) Swap variant include its SPs.
866 * (2-4) Cleanup last configurations.
867 */
868 static int
869 if_ipsec_set_tunnel(struct ifnet *ifp,
870 struct sockaddr *src, struct sockaddr *dst)
871 {
872 struct ipsec_softc *sc = ifp->if_softc;
873 struct ipsec_softc *sc2;
874 struct ipsec_variant *ovar, *nvar, *nullvar;
875 struct sockaddr *osrc, *odst;
876 struct sockaddr *nsrc, *ndst;
877 in_port_t nsport = 0, ndport = 0;
878 int error;
879
880 error = encap_lock_enter();
881 if (error)
882 return error;
883
884 nsrc = sockaddr_dup(src, M_WAITOK);
885 ndst = sockaddr_dup(dst, M_WAITOK);
886 nvar = kmem_zalloc(sizeof(*nvar), KM_SLEEP);
887 nullvar = kmem_zalloc(sizeof(*nullvar), KM_SLEEP);
888
889 mutex_enter(&sc->ipsec_lock);
890
891 ovar = sc->ipsec_var;
892
893 switch(nsrc->sa_family) {
894 #ifdef INET
895 case AF_INET:
896 nsport = satosin(src)->sin_port;
897 /*
898 * avoid confuse SP when NAT-T disabled,
899 * e.g.
900 * expected: 10.0.1.2[any] 10.0.1.1[any] 4(ipv4)
901 * confuse : 10.0.1.2[600] 10.0.1.1[600] 4(ipv4)
902 */
903 satosin(nsrc)->sin_port = 0;
904 ndport = satosin(dst)->sin_port;
905 satosin(ndst)->sin_port = 0;
906 break;
907 #endif /* INET */
908 #ifdef INET6
909 case AF_INET6:
910 nsport = satosin6(src)->sin6_port;
911 satosin6(nsrc)->sin6_port = 0;
912 ndport = satosin6(dst)->sin6_port;
913 satosin6(ndst)->sin6_port = 0;
914 break;
915 #endif /* INET6 */
916 default:
917 log(LOG_DEBUG,
918 "%s: Invalid address family: %d.\n",
919 __func__, src->sa_family);
920 error = EINVAL;
921 goto out;
922 }
923
924 /*
925 * (1-1) Check the argument src and dst address pair will change
926 * configuration from current src and dst address pair.
927 */
928 if ((ovar->iv_pdst && sockaddr_cmp(ovar->iv_pdst, dst) == 0) &&
929 (ovar->iv_psrc && sockaddr_cmp(ovar->iv_psrc, src) == 0) &&
930 (ovar->iv_sport == nsport && ovar->iv_dport == ndport)) {
931 /* address and port pair not changed. */
932 error = 0;
933 goto out;
934 }
935
936 /*
937 * (1-2) Check any ipsec(4) I/F uses duplicated src and dst address pair
938 * with argument src and dst address pair, except for NAT-T shared
939 * tunnels.
940 */
941 mutex_enter(&ipsec_softcs.lock);
942 LIST_FOREACH(sc2, &ipsec_softcs.list, ipsec_list) {
943 struct ipsec_variant *var2;
944 struct psref psref;
945
946 if (sc2 == sc)
947 continue;
948 var2 = if_ipsec_getref_variant(sc2, &psref);
949 if (if_ipsec_variant_is_unconfigured(var2)) {
950 if_ipsec_putref_variant(var2, &psref);
951 continue;
952 }
953 if (if_ipsec_nat_t(sc) || if_ipsec_nat_t(sc2)) {
954 if_ipsec_putref_variant(var2, &psref);
955 continue; /* NAT-T shared tunnel */
956 }
957 if (sockaddr_cmp(var2->iv_pdst, dst) == 0 &&
958 sockaddr_cmp(var2->iv_psrc, src) == 0) {
959 if_ipsec_putref_variant(var2, &psref);
960 mutex_exit(&ipsec_softcs.lock);
961 error = EADDRNOTAVAIL;
962 goto out;
963 }
964
965 if_ipsec_putref_variant(var2, &psref);
966 /* XXX both end must be valid? (I mean, not 0.0.0.0) */
967 }
968 mutex_exit(&ipsec_softcs.lock);
969
970
971 osrc = ovar->iv_psrc;
972 odst = ovar->iv_pdst;
973
974 /*
975 * (2-1) Create ipsec_variant for new configuration.
976 */
977 if_ipsec_copy_variant(nvar, ovar);
978 nvar->iv_psrc = nsrc;
979 nvar->iv_pdst = ndst;
980 nvar->iv_sport = nsport;
981 nvar->iv_dport = ndport;
982 nvar->iv_encap_cookie4 = NULL;
983 nvar->iv_encap_cookie6 = NULL;
984 psref_target_init(&nvar->iv_psref, iv_psref_class);
985 error = if_ipsec_encap_attach(nvar);
986 if (error)
987 goto out;
988
989 /*
990 * (2-2) Create temporary "null" variant.
991 */
992 if_ipsec_copy_variant(nullvar, ovar);
993 if_ipsec_clear_config(nullvar);
994 psref_target_init(&nullvar->iv_psref, iv_psref_class);
995 membar_producer();
996 /*
997 * (2-3) Swap variant include its SPs.
998 */
999 error = if_ipsec_update_variant(sc, nvar, nullvar);
1000 if (error) {
1001 if_ipsec_encap_detach(nvar);
1002 goto out;
1003 }
1004
1005 mutex_exit(&sc->ipsec_lock);
1006
1007 /*
1008 * (2-4) Cleanup last configurations.
1009 */
1010 if (if_ipsec_variant_is_configured(ovar))
1011 if_ipsec_encap_detach(ovar);
1012 encap_lock_exit();
1013
1014 if (osrc != NULL)
1015 sockaddr_free(osrc);
1016 if (odst != NULL)
1017 sockaddr_free(odst);
1018 kmem_free(ovar, sizeof(*ovar));
1019 kmem_free(nullvar, sizeof(*nullvar));
1020
1021 return 0;
1022
1023 out:
1024 mutex_exit(&sc->ipsec_lock);
1025 encap_lock_exit();
1026
1027 sockaddr_free(nsrc);
1028 sockaddr_free(ndst);
1029 kmem_free(nvar, sizeof(*nvar));
1030 kmem_free(nullvar, sizeof(*nullvar));
1031
1032 return error;
1033 }
1034
1035 /*
1036 * Validate and delete ipsec(4) I/F configurations.
1037 * (1) validate
1038 * (1-1) Check current src and dst address pair are null,
1039 * which means the ipsec(4) I/F is already done deletetunnel.
1040 * (2) delete
1041 * (2-1) Create variant for deleted status.
1042 * (2-2) Create temporary "null" variant used to avoid to access
1043 * dangling variant while SPs are deleted and added.
1044 * NOTE:
1045 * The contents of temporary "null" variant equal to the variant
1046 * of (2-1), however two psref_target_destroy() synchronization
1047 * points are necessary to avoid to access dangling variant
1048 * while SPs are deleted and added. To implement that simply,
1049 * we use the same manner as if_ipsec_set_tunnel(), that is,
1050 * create extra "null" variant and use it temporarily.
1051 * (2-3) Swap variant include its SPs.
1052 * (2-4) Cleanup last configurations.
1053 */
1054 static void
1055 if_ipsec_delete_tunnel(struct ifnet *ifp)
1056 {
1057 struct ipsec_softc *sc = ifp->if_softc;
1058 struct ipsec_variant *ovar, *nvar, *nullvar;
1059 struct sockaddr *osrc, *odst;
1060 int error;
1061
1062 error = encap_lock_enter();
1063 if (error)
1064 return;
1065
1066 nvar = kmem_zalloc(sizeof(*nvar), KM_SLEEP);
1067 nullvar = kmem_zalloc(sizeof(*nullvar), KM_SLEEP);
1068
1069 mutex_enter(&sc->ipsec_lock);
1070
1071 ovar = sc->ipsec_var;
1072 osrc = ovar->iv_psrc;
1073 odst = ovar->iv_pdst;
1074 /*
1075 * (1-1) Check current src and dst address pair are null,
1076 * which means the ipsec(4) I/F is already done deletetunnel.
1077 */
1078 if (osrc == NULL || odst == NULL) {
1079 /* address pair not changed. */
1080 mutex_exit(&sc->ipsec_lock);
1081 encap_lock_exit();
1082 kmem_free(nvar, sizeof(*nvar));
1083 return;
1084 }
1085
1086 /*
1087 * (2-1) Create variant for deleted status.
1088 */
1089 if_ipsec_copy_variant(nvar, ovar);
1090 if_ipsec_clear_config(nvar);
1091 psref_target_init(&nvar->iv_psref, iv_psref_class);
1092
1093 /*
1094 * (2-2) Create temporary "null" variant used to avoid to access
1095 * dangling variant while SPs are deleted and added.
1096 */
1097 if_ipsec_copy_variant(nullvar, ovar);
1098 if_ipsec_clear_config(nullvar);
1099 psref_target_init(&nullvar->iv_psref, iv_psref_class);
1100 membar_producer();
1101 /*
1102 * (2-3) Swap variant include its SPs.
1103 */
1104 /* if_ipsec_update_variant() does not fail when delete SP only. */
1105 (void)if_ipsec_update_variant(sc, nvar, nullvar);
1106
1107 mutex_exit(&sc->ipsec_lock);
1108
1109 /*
1110 * (2-4) Cleanup last configurations.
1111 */
1112 if (if_ipsec_variant_is_configured(ovar))
1113 if_ipsec_encap_detach(ovar);
1114 encap_lock_exit();
1115
1116 sockaddr_free(osrc);
1117 sockaddr_free(odst);
1118 kmem_free(ovar, sizeof(*ovar));
1119 kmem_free(nullvar, sizeof(*nullvar));
1120 }
1121
1122 /*
1123 * Check IFF_NAT_T and IFF_FWD_IPV6 flags, therefore update SPs if needed.
1124 * (1) check
1125 * (1-1) Check flags are changed.
1126 * (1-2) Check current src and dst address pair. If they are null,
1127 * that means the ipsec(4) I/F is deletetunnel'ed, so it is
1128 * not needed to update.
1129 * (2) update
1130 * (2-1) Create variant for new SPs.
1131 * (2-2) Create temporary "null" variant used to avoid to access
1132 * dangling variant while SPs are deleted and added.
1133 * NOTE:
1134 * There is the same problem as if_ipsec_delete_tunnel().
1135 * (2-3) Swap variant include its SPs.
1136 * (2-4) Cleanup unused configurations.
1137 * NOTE: use the same encap_cookies.
1138 */
1139 static int
1140 if_ipsec_ensure_flags(struct ifnet *ifp, short oflags)
1141 {
1142 struct ipsec_softc *sc = ifp->if_softc;
1143 struct ipsec_variant *ovar, *nvar, *nullvar;
1144 int error;
1145
1146 /*
1147 * (1) Check flags are changed.
1148 */
1149 if ((oflags & (IFF_NAT_T|IFF_FWD_IPV6)) ==
1150 (ifp->if_flags & (IFF_NAT_T|IFF_FWD_IPV6)))
1151 return 0; /* flags not changed. */
1152
1153 error = encap_lock_enter();
1154 if (error)
1155 return error;
1156
1157 nvar = kmem_zalloc(sizeof(*nvar), KM_SLEEP);
1158 nullvar = kmem_zalloc(sizeof(*nullvar), KM_SLEEP);
1159
1160 mutex_enter(&sc->ipsec_lock);
1161
1162 ovar = sc->ipsec_var;
1163 /*
1164 * (1-2) Check current src and dst address pair.
1165 */
1166 if (if_ipsec_variant_is_unconfigured(ovar)) {
1167 /* nothing to do */
1168 mutex_exit(&sc->ipsec_lock);
1169 return 0;
1170 }
1171
1172 /*
1173 * (2-1) Create variant for new SPs.
1174 */
1175 if_ipsec_copy_variant(nvar, ovar);
1176 psref_target_init(&nvar->iv_psref, iv_psref_class);
1177 /*
1178 * (2-2) Create temporary "null" variant used to avoid to access
1179 * dangling variant while SPs are deleted and added.
1180 */
1181 if_ipsec_copy_variant(nullvar, ovar);
1182 if_ipsec_clear_config(nullvar);
1183 psref_target_init(&nullvar->iv_psref, iv_psref_class);
1184 membar_producer();
1185 /*
1186 * (2-3) Swap variant include its SPs.
1187 */
1188 error = if_ipsec_update_variant(sc, nvar, nullvar);
1189
1190 mutex_exit(&sc->ipsec_lock);
1191 encap_lock_exit();
1192
1193 /*
1194 * (2-4) Cleanup unused configurations.
1195 */
1196 if (!error)
1197 kmem_free(ovar, sizeof(*ovar));
1198 else
1199 kmem_free(nvar, sizeof(*ovar));
1200 kmem_free(nullvar, sizeof(*nullvar));
1201
1202 return error;
1203 }
1204
1205 /*
1206 * SPD management
1207 */
1208
1209 /*
1210 * Share SP set with other NAT-T ipsec(4) I/F(s).
1211 * Return 1, when "var" shares SP set.
1212 * Return 0, when "var" cannot share SP set.
1213 *
1214 * NOTE:
1215 * if_ipsec_share_sp() and if_ipsec_unshare_sp() would require global lock
1216 * to exclude other ipsec(4) I/Fs set_tunnel/delete_tunnel. E.g. when ipsec0
1217 * and ipsec1 can share SP set, running ipsec0's set_tunnel and ipsec1's
1218 * set_tunnel causes race.
1219 * Currently, (fortunately) encap_lock works as this global lock.
1220 */
1221 static int
1222 if_ipsec_share_sp(struct ipsec_variant *var)
1223 {
1224 struct ipsec_softc *sc = var->iv_softc;
1225 struct ipsec_softc *sc2;
1226 struct ipsec_variant *var2;
1227 struct psref psref;
1228
1229 KASSERT(encap_lock_held());
1230 KASSERT(var->iv_psrc != NULL && var->iv_pdst != NULL);
1231
1232 mutex_enter(&ipsec_softcs.lock);
1233 LIST_FOREACH(sc2, &ipsec_softcs.list, ipsec_list) {
1234 if (sc2 == sc)
1235 continue;
1236 var2 = if_ipsec_getref_variant(sc2, &psref);
1237 if (if_ipsec_variant_is_unconfigured(var2)) {
1238 if_ipsec_putref_variant(var2, &psref);
1239 continue;
1240 }
1241 if (sockaddr_cmp(var2->iv_pdst, var->iv_pdst) != 0 ||
1242 sockaddr_cmp(var2->iv_psrc, var->iv_psrc) != 0) {
1243 if_ipsec_putref_variant(var2, &psref);
1244 continue;
1245 }
1246
1247 break;
1248 }
1249 mutex_exit(&ipsec_softcs.lock);
1250 if (sc2 == NULL)
1251 return 0; /* not shared */
1252
1253 IV_SP_IN(var) = IV_SP_IN(var2);
1254 IV_SP_IN6(var) = IV_SP_IN6(var2);
1255 IV_SP_OUT(var) = IV_SP_OUT(var2);
1256 IV_SP_OUT6(var) = IV_SP_OUT6(var2);
1257
1258 if_ipsec_putref_variant(var2, &psref);
1259 return 1; /* shared */
1260 }
1261
1262 /*
1263 * Unshare SP set with other NAT-T ipsec(4) I/F(s).
1264 * Return 1, when "var" shared SP set, and then unshare them.
1265 * Return 0, when "var" did not share SP set.
1266 *
1267 * NOTE:
1268 * See if_ipsec_share_sp()'s note.
1269 */
1270 static int
1271 if_ipsec_unshare_sp(struct ipsec_variant *var)
1272 {
1273 struct ipsec_softc *sc = var->iv_softc;
1274 struct ipsec_softc *sc2;
1275 struct ipsec_variant *var2;
1276 struct psref psref;
1277
1278 KASSERT(encap_lock_held());
1279
1280 if (!var->iv_pdst || !var->iv_psrc)
1281 return 0;
1282
1283 mutex_enter(&ipsec_softcs.lock);
1284 LIST_FOREACH(sc2, &ipsec_softcs.list, ipsec_list) {
1285 if (sc2 == sc)
1286 continue;
1287 var2 = if_ipsec_getref_variant(sc2, &psref);
1288 if (!var2->iv_pdst || !var2->iv_psrc) {
1289 if_ipsec_putref_variant(var2, &psref);
1290 continue;
1291 }
1292 if (sockaddr_cmp(var2->iv_pdst, var->iv_pdst) != 0 ||
1293 sockaddr_cmp(var2->iv_psrc, var->iv_psrc) != 0) {
1294 if_ipsec_putref_variant(var2, &psref);
1295 continue;
1296 }
1297
1298 break;
1299 }
1300 mutex_exit(&ipsec_softcs.lock);
1301 if (sc2 == NULL)
1302 return 0; /* not shared */
1303
1304 IV_SP_IN(var) = NULL;
1305 IV_SP_IN6(var) = NULL;
1306 IV_SP_OUT(var) = NULL;
1307 IV_SP_OUT6(var) = NULL;
1308 if_ipsec_putref_variant(var2, &psref);
1309 return 1; /* shared */
1310 }
1311
1312 static inline void
1313 if_ipsec_add_mbuf_optalign(struct mbuf *m0, void *data, size_t len, bool align)
1314 {
1315 struct mbuf *m;
1316
1317 MGET(m, M_WAITOK | M_ZERO, MT_DATA);
1318 if (align)
1319 m->m_len = PFKEY_ALIGN8(len);
1320 else
1321 m->m_len = len;
1322 m_copyback(m, 0, len, data);
1323 m_cat(m0, m);
1324 }
1325
1326 static inline void
1327 if_ipsec_add_mbuf(struct mbuf *m0, void *data, size_t len)
1328 {
1329
1330 if_ipsec_add_mbuf_optalign(m0, data, len, true);
1331 }
1332
1333 static inline void
1334 if_ipsec_add_mbuf_addr_port(struct mbuf *m0, struct sockaddr *addr, in_port_t port, bool align)
1335 {
1336
1337 if (port == 0) {
1338 if_ipsec_add_mbuf_optalign(m0, addr, addr->sa_len, align);
1339 } else {
1340 struct sockaddr addrport;
1341
1342 if_ipsec_set_addr_port(&addrport, addr, port);
1343 if_ipsec_add_mbuf_optalign(m0, &addrport, addrport.sa_len, align);
1344 }
1345 }
1346
1347 static inline void
1348 if_ipsec_add_pad(struct mbuf *m0, size_t len)
1349 {
1350 struct mbuf *m;
1351
1352 if (len == 0)
1353 return;
1354
1355 MGET(m, M_WAITOK | M_ZERO, MT_DATA);
1356 m->m_len = len;
1357 m_cat(m0, m);
1358 }
1359
1360 static inline size_t
1361 if_ipsec_set_sadb_addr(struct sadb_address *saaddr, struct sockaddr *addr,
1362 int proto, uint16_t exttype)
1363 {
1364 size_t size;
1365
1366 KASSERT(saaddr != NULL);
1367 KASSERT(addr != NULL);
1368
1369 size = sizeof(*saaddr) + PFKEY_ALIGN8(addr->sa_len);
1370 saaddr->sadb_address_len = PFKEY_UNIT64(size);
1371 saaddr->sadb_address_exttype = exttype;
1372 saaddr->sadb_address_proto = proto;
1373 switch (addr->sa_family) {
1374 #ifdef INET
1375 case AF_INET:
1376 saaddr->sadb_address_prefixlen = sizeof(struct in_addr) << 3;
1377 break;
1378 #endif /* INET */
1379 #ifdef INET6
1380 case AF_INET6:
1381 saaddr->sadb_address_prefixlen = sizeof(struct in6_addr) << 3;
1382 break;
1383 #endif /* INET6 */
1384 default:
1385 log(LOG_DEBUG,
1386 "%s: Invalid address family: %d.\n",
1387 __func__, addr->sa_family);
1388 break;
1389 }
1390 saaddr->sadb_address_reserved = 0;
1391
1392 return size;
1393 }
1394
1395 static inline size_t
1396 if_ipsec_set_sadb_src(struct sadb_address *sasrc, struct sockaddr *src,
1397 int proto)
1398 {
1399
1400 return if_ipsec_set_sadb_addr(sasrc, src, proto,
1401 SADB_EXT_ADDRESS_SRC);
1402 }
1403
1404 static inline size_t
1405 if_ipsec_set_sadb_dst(struct sadb_address *sadst, struct sockaddr *dst,
1406 int proto)
1407 {
1408
1409 return if_ipsec_set_sadb_addr(sadst, dst, proto,
1410 SADB_EXT_ADDRESS_DST);
1411 }
1412
1413 static inline size_t
1414 if_ipsec_set_sadb_x_policy(struct sadb_x_policy *xpl,
1415 struct sadb_x_ipsecrequest *xisr, uint16_t policy, uint8_t dir, uint32_t id,
1416 uint8_t level, struct sockaddr *src, struct sockaddr *dst)
1417 {
1418 size_t size;
1419
1420 KASSERT(policy != IPSEC_POLICY_IPSEC || xisr != NULL);
1421
1422 size = sizeof(*xpl);
1423 if (policy == IPSEC_POLICY_IPSEC) {
1424 size += PFKEY_ALIGN8(sizeof(*xisr));
1425 if (src != NULL && dst != NULL)
1426 size += PFKEY_ALIGN8(src->sa_len + dst->sa_len);
1427 }
1428 xpl->sadb_x_policy_len = PFKEY_UNIT64(size);
1429 xpl->sadb_x_policy_exttype = SADB_X_EXT_POLICY;
1430 xpl->sadb_x_policy_type = policy;
1431 xpl->sadb_x_policy_dir = dir;
1432 xpl->sadb_x_policy_reserved = 0;
1433 xpl->sadb_x_policy_id = id;
1434 xpl->sadb_x_policy_reserved2 = 0;
1435
1436 if (policy == IPSEC_POLICY_IPSEC) {
1437 xisr->sadb_x_ipsecrequest_len = PFKEY_ALIGN8(sizeof(*xisr));
1438 if (src != NULL && dst != NULL)
1439 xisr->sadb_x_ipsecrequest_len +=
1440 PFKEY_ALIGN8(src->sa_len + dst->sa_len);
1441 xisr->sadb_x_ipsecrequest_proto = IPPROTO_ESP;
1442 xisr->sadb_x_ipsecrequest_mode = IPSEC_MODE_TRANSPORT;
1443 xisr->sadb_x_ipsecrequest_level = level;
1444 xisr->sadb_x_ipsecrequest_reqid = key_newreqid();
1445 }
1446
1447 return size;
1448 }
1449
1450 static inline void
1451 if_ipsec_set_sadb_msg(struct sadb_msg *msg, uint16_t extlen, uint8_t msgtype)
1452 {
1453
1454 KASSERT(msg != NULL);
1455
1456 msg->sadb_msg_version = PF_KEY_V2;
1457 msg->sadb_msg_type = msgtype;
1458 msg->sadb_msg_errno = 0;
1459 msg->sadb_msg_satype = SADB_SATYPE_UNSPEC;
1460 msg->sadb_msg_len = PFKEY_UNIT64(sizeof(*msg)) + extlen;
1461 msg->sadb_msg_reserved = 0;
1462 msg->sadb_msg_seq = 0; /* XXXX */
1463 msg->sadb_msg_pid = 0; /* XXXX */
1464 }
1465
1466 static inline void
1467 if_ipsec_set_sadb_msg_add(struct sadb_msg *msg, uint16_t extlen)
1468 {
1469
1470 if_ipsec_set_sadb_msg(msg, extlen, SADB_X_SPDADD);
1471 }
1472
1473 static inline void
1474 if_ipsec_set_sadb_msg_del(struct sadb_msg *msg, uint16_t extlen)
1475 {
1476
1477 if_ipsec_set_sadb_msg(msg, extlen, SADB_X_SPDDELETE2);
1478 }
1479
1480 static int
1481 if_ipsec_set_addr_port(struct sockaddr *addrport, struct sockaddr *addr,
1482 in_port_t port)
1483 {
1484 int error = 0;
1485
1486 sockaddr_copy(addrport, addr->sa_len, addr);
1487
1488 switch (addr->sa_family) {
1489 #ifdef INET
1490 case AF_INET: {
1491 struct sockaddr_in *sin = satosin(addrport);
1492 sin->sin_port = port;
1493 break;
1494 }
1495 #endif /* INET */
1496 #ifdef INET6
1497 case AF_INET6: {
1498 struct sockaddr_in6 *sin6 = satosin6(addrport);
1499 sin6->sin6_port = port;
1500 break;
1501 }
1502 #endif /* INET6 */
1503 default:
1504 log(LOG_DEBUG,
1505 "%s: Invalid address family: %d.\n",
1506 __func__, addr->sa_family);
1507 error = EINVAL;
1508 }
1509
1510 return error;
1511 }
1512
1513 static struct secpolicy *
1514 if_ipsec_add_sp0(struct sockaddr *src, in_port_t sport,
1515 struct sockaddr *dst, in_port_t dport,
1516 int dir, int proto, int level, u_int policy)
1517 {
1518 struct sadb_msg msg;
1519 struct sadb_address xsrc, xdst;
1520 struct sadb_x_policy xpl;
1521 struct sadb_x_ipsecrequest xisr;
1522 size_t size;
1523 size_t padlen;
1524 uint16_t ext_msg_len = 0;
1525 struct mbuf *m;
1526
1527 memset(&msg, 0, sizeof(msg));
1528 memset(&xsrc, 0, sizeof(xsrc));
1529 memset(&xdst, 0, sizeof(xdst));
1530 memset(&xpl, 0, sizeof(xpl));
1531 memset(&xisr, 0, sizeof(xisr));
1532
1533 MGETHDR(m, M_WAITOK, MT_DATA);
1534
1535 size = if_ipsec_set_sadb_src(&xsrc, src, proto);
1536 ext_msg_len += PFKEY_UNIT64(size);
1537 size = if_ipsec_set_sadb_dst(&xdst, dst, proto);
1538 ext_msg_len += PFKEY_UNIT64(size);
1539 size = if_ipsec_set_sadb_x_policy(&xpl, &xisr, policy, dir, 0, level, src, dst);
1540 ext_msg_len += PFKEY_UNIT64(size);
1541 if_ipsec_set_sadb_msg_add(&msg, ext_msg_len);
1542
1543 /* build PF_KEY message */
1544
1545 m->m_len = sizeof(msg);
1546 m_copyback(m, 0, sizeof(msg), &msg);
1547
1548 if_ipsec_add_mbuf(m, &xsrc, sizeof(xsrc));
1549 if_ipsec_add_mbuf_addr_port(m, src, sport, true);
1550 padlen = PFKEY_UNUNIT64(xsrc.sadb_address_len)
1551 - (sizeof(xsrc) + PFKEY_ALIGN8(src->sa_len));
1552 if_ipsec_add_pad(m, padlen);
1553
1554 if_ipsec_add_mbuf(m, &xdst, sizeof(xdst));
1555 if_ipsec_add_mbuf_addr_port(m, dst, dport, true);
1556 padlen = PFKEY_UNUNIT64(xdst.sadb_address_len)
1557 - (sizeof(xdst) + PFKEY_ALIGN8(dst->sa_len));
1558 if_ipsec_add_pad(m, padlen);
1559
1560 if_ipsec_add_mbuf(m, &xpl, sizeof(xpl));
1561 if (policy == IPSEC_POLICY_IPSEC) {
1562 if_ipsec_add_mbuf(m, &xisr, sizeof(xisr));
1563 if_ipsec_add_mbuf_addr_port(m, src, sport, false);
1564 if_ipsec_add_mbuf_addr_port(m, dst, dport, false);
1565 }
1566 padlen = PFKEY_UNUNIT64(xpl.sadb_x_policy_len) - sizeof(xpl);
1567 if (src != NULL && dst != NULL)
1568 padlen -= PFKEY_ALIGN8(src->sa_len + dst->sa_len);
1569 if_ipsec_add_pad(m, padlen);
1570
1571 /* key_kpi_spdadd() has already done KEY_SP_REF(). */
1572 return key_kpi_spdadd(m);
1573 }
1574
1575 static int
1576 if_ipsec_add_sp(struct ipsec_variant *var,
1577 struct sockaddr *src, in_port_t sport,
1578 struct sockaddr *dst, in_port_t dport)
1579 {
1580 struct ipsec_softc *sc = var->iv_softc;
1581 int level;
1582 u_int v6policy;
1583
1584 /*
1585 * must delete sp before add it.
1586 */
1587 KASSERT(IV_SP_IN(var) == NULL);
1588 KASSERT(IV_SP_OUT(var) == NULL);
1589 KASSERT(IV_SP_IN6(var) == NULL);
1590 KASSERT(IV_SP_OUT6(var) == NULL);
1591
1592 /*
1593 * can be shared?
1594 */
1595 if (if_ipsec_share_sp(var))
1596 return 0;
1597
1598 if (if_ipsec_nat_t(sc))
1599 level = IPSEC_LEVEL_REQUIRE;
1600 else
1601 level = IPSEC_LEVEL_UNIQUE;
1602
1603 if (if_ipsec_fwd_ipv6(sc))
1604 v6policy = IPSEC_POLICY_IPSEC;
1605 else
1606 v6policy = IPSEC_POLICY_DISCARD;
1607
1608 IV_SP_IN(var) = if_ipsec_add_sp0(dst, dport, src, sport,
1609 IPSEC_DIR_INBOUND, IPPROTO_IPIP, level, IPSEC_POLICY_IPSEC);
1610 if (IV_SP_IN(var) == NULL)
1611 goto fail;
1612 IV_SP_OUT(var) = if_ipsec_add_sp0(src, sport, dst, dport,
1613 IPSEC_DIR_OUTBOUND, IPPROTO_IPIP, level, IPSEC_POLICY_IPSEC);
1614 if (IV_SP_OUT(var) == NULL)
1615 goto fail;
1616 IV_SP_IN6(var) = if_ipsec_add_sp0(dst, dport, src, sport,
1617 IPSEC_DIR_INBOUND, IPPROTO_IPV6, level, v6policy);
1618 if (IV_SP_IN6(var) == NULL)
1619 goto fail;
1620 IV_SP_OUT6(var) = if_ipsec_add_sp0(src, sport, dst, dport,
1621 IPSEC_DIR_OUTBOUND, IPPROTO_IPV6, level, v6policy);
1622 if (IV_SP_OUT6(var) == NULL)
1623 goto fail;
1624
1625 return 0;
1626
1627 fail:
1628 if (IV_SP_IN6(var) != NULL) {
1629 if_ipsec_del_sp0(IV_SP_IN6(var));
1630 IV_SP_IN6(var) = NULL;
1631 }
1632 if (IV_SP_OUT(var) != NULL) {
1633 if_ipsec_del_sp0(IV_SP_OUT(var));
1634 IV_SP_OUT(var) = NULL;
1635 }
1636 if (IV_SP_IN(var) != NULL) {
1637 if_ipsec_del_sp0(IV_SP_IN(var));
1638 IV_SP_IN(var) = NULL;
1639 }
1640
1641 return EEXIST;
1642 }
1643
1644 static int
1645 if_ipsec_del_sp0(struct secpolicy *sp)
1646 {
1647 struct sadb_msg msg;
1648 struct sadb_x_policy xpl;
1649 size_t size;
1650 uint16_t ext_msg_len = 0;
1651 int error;
1652 struct mbuf *m;
1653
1654 if (sp == NULL)
1655 return 0;
1656
1657 memset(&msg, 0, sizeof(msg));
1658 memset(&xpl, 0, sizeof(xpl));
1659
1660 MGETHDR(m, M_WAITOK, MT_DATA);
1661
1662 size = if_ipsec_set_sadb_x_policy(&xpl, NULL, 0, 0, sp->id, 0, NULL, NULL);
1663 ext_msg_len += PFKEY_UNIT64(size);
1664
1665 if_ipsec_set_sadb_msg_del(&msg, ext_msg_len);
1666
1667 m->m_len = sizeof(msg);
1668 m_copyback(m, 0, sizeof(msg), &msg);
1669
1670 if_ipsec_add_mbuf(m, &xpl, sizeof(xpl));
1671
1672 /* unreference correspond to key_kpi_spdadd(). */
1673 KEY_SP_UNREF(&sp);
1674 error = key_kpi_spddelete2(m);
1675 if (error != 0) {
1676 log(LOG_ERR, "%s: cannot delete SP(ID=%u) (error=%d).\n",
1677 __func__, sp->id, error);
1678 }
1679 return error;
1680 }
1681
1682 static void
1683 if_ipsec_del_sp(struct ipsec_variant *var)
1684 {
1685
1686 /* are the SPs shared? */
1687 if (if_ipsec_unshare_sp(var))
1688 return;
1689
1690 (void)if_ipsec_del_sp0(IV_SP_OUT(var));
1691 (void)if_ipsec_del_sp0(IV_SP_IN(var));
1692 (void)if_ipsec_del_sp0(IV_SP_OUT6(var));
1693 (void)if_ipsec_del_sp0(IV_SP_IN6(var));
1694 IV_SP_IN(var) = NULL;
1695 IV_SP_IN6(var) = NULL;
1696 IV_SP_OUT(var) = NULL;
1697 IV_SP_OUT6(var) = NULL;
1698 }
1699
1700 static int
1701 if_ipsec_replace_sp(struct ipsec_softc *sc, struct ipsec_variant *ovar,
1702 struct ipsec_variant *nvar)
1703 {
1704 in_port_t src_port = 0;
1705 in_port_t dst_port = 0;
1706 struct sockaddr *src;
1707 struct sockaddr *dst;
1708 int error = 0;
1709
1710 KASSERT(mutex_owned(&sc->ipsec_lock));
1711
1712 if_ipsec_del_sp(ovar);
1713
1714 src = nvar->iv_psrc;
1715 dst = nvar->iv_pdst;
1716 if (if_ipsec_nat_t(sc)) {
1717 /* NAT-T enabled */
1718 src_port = nvar->iv_sport;
1719 dst_port = nvar->iv_dport;
1720 }
1721 if (src && dst)
1722 error = if_ipsec_add_sp(nvar, src, src_port, dst, dst_port);
1723
1724 return error;
1725 }
1726
1727 /*
1728 * ipsec_variant and its SPs update API.
1729 *
1730 * Assumption:
1731 * reader side dereferences sc->ipsec_var in reader critical section only,
1732 * that is, all of reader sides do not reader the sc->ipsec_var after
1733 * pserialize_perform().
1734 */
1735 static int
1736 if_ipsec_update_variant(struct ipsec_softc *sc, struct ipsec_variant *nvar,
1737 struct ipsec_variant *nullvar)
1738 {
1739 struct ifnet *ifp = &sc->ipsec_if;
1740 struct ipsec_variant *ovar = sc->ipsec_var;
1741 int error;
1742
1743 KASSERT(mutex_owned(&sc->ipsec_lock));
1744
1745 /*
1746 * To keep consistency between ipsec(4) I/F settings and SPs,
1747 * we stop packet processing while replacing SPs, that is, we set
1748 * "null" config variant to sc->ipsec_var.
1749 */
1750 sc->ipsec_var = nullvar;
1751 pserialize_perform(ipsec_psz);
1752 psref_target_destroy(&ovar->iv_psref, iv_psref_class);
1753
1754 error = if_ipsec_replace_sp(sc, ovar, nvar);
1755 if (!error)
1756 sc->ipsec_var = nvar;
1757 else {
1758 sc->ipsec_var = ovar; /* rollback */
1759 psref_target_init(&ovar->iv_psref, iv_psref_class);
1760 }
1761
1762 pserialize_perform(ipsec_psz);
1763 psref_target_destroy(&nullvar->iv_psref, iv_psref_class);
1764
1765 if (if_ipsec_variant_is_configured(sc->ipsec_var))
1766 ifp->if_flags |= IFF_RUNNING;
1767 else
1768 ifp->if_flags &= ~IFF_RUNNING;
1769
1770 return error;
1771 }
1772