]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/net/if_ipsec.c
Add ELF flag to disable ASLR stack gap.
[FreeBSD/FreeBSD.git] / sys / net / if_ipsec.c
1 /*-
2  * Copyright (c) 2016-2018 Yandex LLC
3  * Copyright (c) 2016-2018 Andrey V. Elsukov <ae@FreeBSD.org>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
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 AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
30
31 #include "opt_inet.h"
32 #include "opt_inet6.h"
33 #include "opt_ipsec.h"
34
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/kernel.h>
38 #include <sys/fnv_hash.h>
39 #include <sys/jail.h>
40 #include <sys/lock.h>
41 #include <sys/malloc.h>
42 #include <sys/mbuf.h>
43 #include <sys/module.h>
44 #include <sys/socket.h>
45 #include <sys/sockio.h>
46 #include <sys/sx.h>
47 #include <sys/errno.h>
48 #include <sys/sysctl.h>
49 #include <sys/priv.h>
50 #include <sys/proc.h>
51 #include <sys/conf.h>
52
53 #include <net/if.h>
54 #include <net/if_var.h>
55 #include <net/if_clone.h>
56 #include <net/if_types.h>
57 #include <net/bpf.h>
58 #include <net/route.h>
59 #include <net/vnet.h>
60
61 #include <netinet/in.h>
62 #include <netinet/in_var.h>
63 #include <netinet/ip.h>
64 #include <netinet/ip_encap.h>
65
66 #include <netinet/ip6.h>
67 #include <netinet6/in6_var.h>
68 #include <netinet6/scope6_var.h>
69
70 #include <netipsec/ipsec.h>
71 #ifdef INET6
72 #include <netipsec/ipsec6.h>
73 #endif
74
75 #include <net/if_ipsec.h>
76 #include <netipsec/key.h>
77
78 #include <security/mac/mac_framework.h>
79
80 static MALLOC_DEFINE(M_IPSEC, "ipsec", "IPsec Virtual Tunnel Interface");
81 static const char ipsecname[] = "ipsec";
82
83 #if defined(INET) && defined(INET6)
84 #define IPSEC_SPCOUNT           4
85 #else
86 #define IPSEC_SPCOUNT           2
87 #endif
88
89 struct ipsec_softc {
90         struct ifnet            *ifp;
91         struct secpolicy        *sp[IPSEC_SPCOUNT];
92         uint32_t                reqid;
93         u_int                   family;
94         u_int                   fibnum;
95
96         CK_LIST_ENTRY(ipsec_softc) idhash;
97         CK_LIST_ENTRY(ipsec_softc) srchash;
98 };
99
100 #define IPSEC_RLOCK_TRACKER     struct epoch_tracker ipsec_et
101 #define IPSEC_RLOCK()   epoch_enter_preempt(net_epoch_preempt, &ipsec_et)
102 #define IPSEC_RUNLOCK() epoch_exit_preempt(net_epoch_preempt, &ipsec_et)
103 #define IPSEC_WAIT()    epoch_wait_preempt(net_epoch_preempt)
104
105 #ifndef IPSEC_HASH_SIZE
106 #define IPSEC_HASH_SIZE (1 << 5)
107 #endif
108
109 CK_LIST_HEAD(ipsec_iflist, ipsec_softc);
110 VNET_DEFINE_STATIC(struct ipsec_iflist *, ipsec_idhtbl) = NULL;
111 #define V_ipsec_idhtbl          VNET(ipsec_idhtbl)
112
113 #ifdef INET
114 VNET_DEFINE_STATIC(struct ipsec_iflist *, ipsec4_srchtbl) = NULL;
115 #define V_ipsec4_srchtbl        VNET(ipsec4_srchtbl)
116 static const struct srcaddrtab *ipsec4_srctab = NULL;
117 #endif
118
119 #ifdef INET6
120 VNET_DEFINE_STATIC(struct ipsec_iflist *, ipsec6_srchtbl) = NULL;
121 #define V_ipsec6_srchtbl        VNET(ipsec6_srchtbl)
122 static const struct srcaddrtab *ipsec6_srctab = NULL;
123 #endif
124
125 static struct ipsec_iflist *
126 ipsec_idhash(uint32_t id)
127 {
128
129         return (&V_ipsec_idhtbl[fnv_32_buf(&id, sizeof(id),
130             FNV1_32_INIT) & (IPSEC_HASH_SIZE - 1)]);
131 }
132
133 static struct ipsec_iflist *
134 ipsec_srchash(const struct sockaddr *sa)
135 {
136         uint32_t hval;
137
138         switch (sa->sa_family) {
139 #ifdef INET
140         case AF_INET:
141                 hval = fnv_32_buf(
142                     &((const struct sockaddr_in *)sa)->sin_addr.s_addr,
143                     sizeof(in_addr_t), FNV1_32_INIT);
144                 return (&V_ipsec4_srchtbl[hval & (IPSEC_HASH_SIZE - 1)]);
145 #endif
146 #ifdef INET6
147         case AF_INET6:
148                 hval = fnv_32_buf(
149                     &((const struct sockaddr_in6 *)sa)->sin6_addr,
150                     sizeof(struct in6_addr), FNV1_32_INIT);
151                 return (&V_ipsec6_srchtbl[hval & (IPSEC_HASH_SIZE - 1)]);
152 #endif
153         }
154         return (NULL);
155 }
156
157 /*
158  * ipsec_ioctl_sx protects from concurrent ioctls.
159  */
160 static struct sx ipsec_ioctl_sx;
161 SX_SYSINIT(ipsec_ioctl_sx, &ipsec_ioctl_sx, "ipsec_ioctl");
162
163 static int      ipsec_init_reqid(struct ipsec_softc *);
164 static int      ipsec_set_tunnel(struct ipsec_softc *, struct sockaddr *,
165     struct sockaddr *, uint32_t);
166 static void     ipsec_delete_tunnel(struct ipsec_softc *);
167
168 static int      ipsec_set_addresses(struct ifnet *, struct sockaddr *,
169     struct sockaddr *);
170 static int      ipsec_set_reqid(struct ipsec_softc *, uint32_t);
171 static void     ipsec_set_running(struct ipsec_softc *);
172
173 #ifdef VIMAGE
174 static void     ipsec_reassign(struct ifnet *, struct vnet *, char *);
175 #endif
176 static void     ipsec_srcaddr(void *, const struct sockaddr *, int);
177 static int      ipsec_ioctl(struct ifnet *, u_long, caddr_t);
178 static int      ipsec_transmit(struct ifnet *, struct mbuf *);
179 static int      ipsec_output(struct ifnet *, struct mbuf *,
180     const struct sockaddr *, struct route *);
181 static void     ipsec_qflush(struct ifnet *);
182 static int      ipsec_clone_create(struct if_clone *, int, caddr_t);
183 static void     ipsec_clone_destroy(struct ifnet *);
184
185 VNET_DEFINE_STATIC(struct if_clone *, ipsec_cloner);
186 #define V_ipsec_cloner          VNET(ipsec_cloner)
187
188 static int
189 ipsec_clone_create(struct if_clone *ifc, int unit, caddr_t params)
190 {
191         struct ipsec_softc *sc;
192         struct ifnet *ifp;
193
194         sc = malloc(sizeof(*sc), M_IPSEC, M_WAITOK | M_ZERO);
195         sc->fibnum = curthread->td_proc->p_fibnum;
196         sc->ifp = ifp = if_alloc(IFT_TUNNEL);
197         ifp->if_softc = sc;
198         if_initname(ifp, ipsecname, unit);
199
200         ifp->if_addrlen = 0;
201         ifp->if_mtu = IPSEC_MTU;
202         ifp->if_flags  = IFF_POINTOPOINT | IFF_MULTICAST;
203         ifp->if_ioctl  = ipsec_ioctl;
204         ifp->if_transmit  = ipsec_transmit;
205         ifp->if_qflush  = ipsec_qflush;
206         ifp->if_output = ipsec_output;
207 #ifdef VIMAGE
208         ifp->if_reassign = ipsec_reassign;
209 #endif
210         if_attach(ifp);
211         bpfattach(ifp, DLT_NULL, sizeof(uint32_t));
212
213         return (0);
214 }
215
216 #ifdef VIMAGE
217 static void
218 ipsec_reassign(struct ifnet *ifp, struct vnet *new_vnet __unused,
219     char *unused __unused)
220 {
221         struct ipsec_softc *sc;
222
223         sx_xlock(&ipsec_ioctl_sx);
224         sc = ifp->if_softc;
225         if (sc != NULL)
226                 ipsec_delete_tunnel(sc);
227         sx_xunlock(&ipsec_ioctl_sx);
228 }
229 #endif /* VIMAGE */
230
231 static void
232 ipsec_clone_destroy(struct ifnet *ifp)
233 {
234         struct ipsec_softc *sc;
235
236         sx_xlock(&ipsec_ioctl_sx);
237         sc = ifp->if_softc;
238         ipsec_delete_tunnel(sc);
239         /*
240          * Delete softc from idhash on interface destroy, since
241          * ipsec_delete_tunnel() keeps reqid unchanged.
242          */
243         if (sc->reqid != 0)
244                 CK_LIST_REMOVE(sc, idhash);
245         bpfdetach(ifp);
246         if_detach(ifp);
247         ifp->if_softc = NULL;
248         sx_xunlock(&ipsec_ioctl_sx);
249
250         IPSEC_WAIT();
251         if_free(ifp);
252         free(sc, M_IPSEC);
253 }
254
255 static struct ipsec_iflist *
256 ipsec_hashinit(void)
257 {
258         struct ipsec_iflist *hash;
259         int i;
260
261         hash = malloc(sizeof(struct ipsec_iflist) * IPSEC_HASH_SIZE,
262             M_IPSEC, M_WAITOK);
263         for (i = 0; i < IPSEC_HASH_SIZE; i++)
264                 CK_LIST_INIT(&hash[i]);
265
266         return (hash);
267 }
268
269 static void
270 vnet_ipsec_init(const void *unused __unused)
271 {
272
273         V_ipsec_idhtbl = ipsec_hashinit();
274 #ifdef INET
275         V_ipsec4_srchtbl = ipsec_hashinit();
276         if (IS_DEFAULT_VNET(curvnet))
277                 ipsec4_srctab = ip_encap_register_srcaddr(ipsec_srcaddr,
278                     NULL, M_WAITOK);
279 #endif
280 #ifdef INET6
281         V_ipsec6_srchtbl = ipsec_hashinit();
282         if (IS_DEFAULT_VNET(curvnet))
283                 ipsec6_srctab = ip6_encap_register_srcaddr(ipsec_srcaddr,
284                     NULL, M_WAITOK);
285 #endif
286         V_ipsec_cloner = if_clone_simple(ipsecname, ipsec_clone_create,
287             ipsec_clone_destroy, 0);
288 }
289 VNET_SYSINIT(vnet_ipsec_init, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY,
290     vnet_ipsec_init, NULL);
291
292 static void
293 vnet_ipsec_uninit(const void *unused __unused)
294 {
295
296         if_clone_detach(V_ipsec_cloner);
297         free(V_ipsec_idhtbl, M_IPSEC);
298         /*
299          * Use V_ipsec_idhtbl pointer as indicator that VNET is going to be
300          * destroyed, it is used by ipsec_srcaddr() callback.
301          */
302         V_ipsec_idhtbl = NULL;
303         IPSEC_WAIT();
304
305 #ifdef INET
306         if (IS_DEFAULT_VNET(curvnet))
307                 ip_encap_unregister_srcaddr(ipsec4_srctab);
308         free(V_ipsec4_srchtbl, M_IPSEC);
309 #endif
310 #ifdef INET6
311         if (IS_DEFAULT_VNET(curvnet))
312                 ip6_encap_unregister_srcaddr(ipsec6_srctab);
313         free(V_ipsec6_srchtbl, M_IPSEC);
314 #endif
315 }
316 VNET_SYSUNINIT(vnet_ipsec_uninit, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY,
317     vnet_ipsec_uninit, NULL);
318
319 static struct secpolicy *
320 ipsec_getpolicy(struct ipsec_softc *sc, int dir, sa_family_t af)
321 {
322
323         switch (af) {
324 #ifdef INET
325         case AF_INET:
326                 return (sc->sp[(dir == IPSEC_DIR_INBOUND ? 0: 1)]);
327 #endif
328 #ifdef INET6
329         case AF_INET6:
330                 return (sc->sp[(dir == IPSEC_DIR_INBOUND ? 0: 1)
331 #ifdef INET
332                         + 2
333 #endif
334                 ]);
335 #endif
336         }
337         return (NULL);
338 }
339
340 static struct secasindex *
341 ipsec_getsaidx(struct ipsec_softc *sc, int dir, sa_family_t af)
342 {
343         struct secpolicy *sp;
344
345         sp = ipsec_getpolicy(sc, dir, af);
346         if (sp == NULL)
347                 return (NULL);
348         return (&sp->req[0]->saidx);
349 }
350
351 static int
352 ipsec_transmit(struct ifnet *ifp, struct mbuf *m)
353 {
354         IPSEC_RLOCK_TRACKER;
355         struct ipsec_softc *sc;
356         struct secpolicy *sp;
357         struct ip *ip;
358         uint32_t af;
359         int error;
360
361         IPSEC_RLOCK();
362 #ifdef MAC
363         error = mac_ifnet_check_transmit(ifp, m);
364         if (error) {
365                 m_freem(m);
366                 goto err;
367         }
368 #endif
369         error = ENETDOWN;
370         sc = ifp->if_softc;
371         if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 ||
372             (ifp->if_flags & IFF_MONITOR) != 0 ||
373             (ifp->if_flags & IFF_UP) == 0 || sc->family == 0) {
374                 m_freem(m);
375                 goto err;
376         }
377
378         /* Determine address family to correctly handle packet in BPF */
379         ip = mtod(m, struct ip *);
380         switch (ip->ip_v) {
381 #ifdef INET
382         case IPVERSION:
383                 af = AF_INET;
384                 break;
385 #endif
386 #ifdef INET6
387         case (IPV6_VERSION >> 4):
388                 af = AF_INET6;
389                 break;
390 #endif
391         default:
392                 error = EAFNOSUPPORT;
393                 m_freem(m);
394                 goto err;
395         }
396
397         /*
398          * Loop prevention.
399          * XXX: for now just check presence of IPSEC_OUT_DONE mbuf tag.
400          *      We can read full chain and compare destination address,
401          *      proto and mode from xform_history with values from softc.
402          */
403         if (m_tag_find(m, PACKET_TAG_IPSEC_OUT_DONE, NULL) != NULL) {
404                 m_freem(m);
405                 goto err;
406         }
407
408         sp = ipsec_getpolicy(sc, IPSEC_DIR_OUTBOUND, af);
409         key_addref(sp);
410         M_SETFIB(m, sc->fibnum);
411
412         BPF_MTAP2(ifp, &af, sizeof(af), m);
413         if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
414         if_inc_counter(ifp, IFCOUNTER_OBYTES, m->m_pkthdr.len);
415
416         switch (af) {
417 #ifdef INET
418         case AF_INET:
419                 error = ipsec4_process_packet(m, sp, NULL);
420                 break;
421 #endif
422 #ifdef INET6
423         case AF_INET6:
424                 error = ipsec6_process_packet(m, sp, NULL);
425                 break;
426 #endif
427         default:
428                 panic("%s: unknown address family\n", __func__);
429         }
430 err:
431         if (error != 0)
432                 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
433         IPSEC_RUNLOCK();
434         return (error);
435 }
436
437 static void
438 ipsec_qflush(struct ifnet *ifp __unused)
439 {
440
441 }
442
443 static int
444 ipsec_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
445         struct route *ro)
446 {
447
448         return (ifp->if_transmit(ifp, m));
449 }
450
451 int
452 ipsec_if_input(struct mbuf *m, struct secasvar *sav, uint32_t af)
453 {
454         IPSEC_RLOCK_TRACKER;
455         struct secasindex *saidx;
456         struct ipsec_softc *sc;
457         struct ifnet *ifp;
458
459         if (sav->state != SADB_SASTATE_MATURE &&
460             sav->state != SADB_SASTATE_DYING) {
461                 m_freem(m);
462                 return (ENETDOWN);
463         }
464
465         if (sav->sah->saidx.mode != IPSEC_MODE_TUNNEL ||
466             sav->sah->saidx.proto != IPPROTO_ESP)
467                 return (0);
468
469         IPSEC_RLOCK();
470         CK_LIST_FOREACH(sc, ipsec_idhash(sav->sah->saidx.reqid), idhash) {
471                 if (sc->family == 0)
472                         continue;
473                 saidx = ipsec_getsaidx(sc, IPSEC_DIR_INBOUND,
474                     sav->sah->saidx.src.sa.sa_family);
475                 /* SA's reqid should match reqid in SP */
476                 if (saidx == NULL ||
477                     sav->sah->saidx.reqid != saidx->reqid)
478                         continue;
479                 /* SAH's addresses should match tunnel endpoints. */
480                 if (key_sockaddrcmp(&sav->sah->saidx.dst.sa,
481                     &saidx->dst.sa, 0) != 0)
482                         continue;
483                 if (key_sockaddrcmp(&sav->sah->saidx.src.sa,
484                     &saidx->src.sa, 0) == 0)
485                         break;
486         }
487         if (sc == NULL) {
488                 IPSEC_RUNLOCK();
489                 /* Tunnel was not found. Nothing to do. */
490                 return (0);
491         }
492         ifp = sc->ifp;
493         if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 ||
494             (ifp->if_flags & IFF_UP) == 0) {
495                 IPSEC_RUNLOCK();
496                 m_freem(m);
497                 return (ENETDOWN);
498         }
499         /*
500          * We found matching and working tunnel.
501          * Set its ifnet as receiving interface.
502          */
503         m->m_pkthdr.rcvif = ifp;
504
505         m_clrprotoflags(m);
506         M_SETFIB(m, ifp->if_fib);
507         BPF_MTAP2(ifp, &af, sizeof(af), m);
508         if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
509         if_inc_counter(ifp, IFCOUNTER_IBYTES, m->m_pkthdr.len);
510         if ((ifp->if_flags & IFF_MONITOR) != 0) {
511                 IPSEC_RUNLOCK();
512                 m_freem(m);
513                 return (ENETDOWN);
514         }
515         IPSEC_RUNLOCK();
516         return (0);
517 }
518
519 static int
520 ipsec_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
521 {
522         struct ifreq *ifr = (struct ifreq*)data;
523         struct sockaddr *dst, *src;
524         struct ipsec_softc *sc;
525         struct secasindex *saidx;
526 #ifdef INET
527         struct sockaddr_in *sin = NULL;
528 #endif
529 #ifdef INET6
530         struct sockaddr_in6 *sin6 = NULL;
531 #endif
532         uint32_t reqid;
533         int error;
534
535         switch (cmd) {
536         case SIOCSIFADDR:
537                 ifp->if_flags |= IFF_UP;
538         case SIOCADDMULTI:
539         case SIOCDELMULTI:
540         case SIOCGIFMTU:
541         case SIOCSIFFLAGS:
542                 return (0);
543         case SIOCSIFMTU:
544                 if (ifr->ifr_mtu < IPSEC_MTU_MIN ||
545                     ifr->ifr_mtu > IPSEC_MTU_MAX)
546                         return (EINVAL);
547                 else
548                         ifp->if_mtu = ifr->ifr_mtu;
549                 return (0);
550         }
551         sx_xlock(&ipsec_ioctl_sx);
552         sc = ifp->if_softc;
553         /* Check that softc is still here */
554         if (sc == NULL) {
555                 error = ENXIO;
556                 goto bad;
557         }
558         error = 0;
559         switch (cmd) {
560         case SIOCSIFPHYADDR:
561 #ifdef INET6
562         case SIOCSIFPHYADDR_IN6:
563 #endif
564                 error = EINVAL;
565                 switch (cmd) {
566 #ifdef INET
567                 case SIOCSIFPHYADDR:
568                         src = (struct sockaddr *)
569                                 &(((struct in_aliasreq *)data)->ifra_addr);
570                         dst = (struct sockaddr *)
571                                 &(((struct in_aliasreq *)data)->ifra_dstaddr);
572                         break;
573 #endif
574 #ifdef INET6
575                 case SIOCSIFPHYADDR_IN6:
576                         src = (struct sockaddr *)
577                                 &(((struct in6_aliasreq *)data)->ifra_addr);
578                         dst = (struct sockaddr *)
579                                 &(((struct in6_aliasreq *)data)->ifra_dstaddr);
580                         break;
581 #endif
582                 default:
583                         goto bad;
584                 }
585                 /* sa_family must be equal */
586                 if (src->sa_family != dst->sa_family ||
587                     src->sa_len != dst->sa_len)
588                         goto bad;
589
590                 /* validate sa_len */
591                 switch (src->sa_family) {
592 #ifdef INET
593                 case AF_INET:
594                         if (src->sa_len != sizeof(struct sockaddr_in))
595                                 goto bad;
596                         break;
597 #endif
598 #ifdef INET6
599                 case AF_INET6:
600                         if (src->sa_len != sizeof(struct sockaddr_in6))
601                                 goto bad;
602                         break;
603 #endif
604                 default:
605                         error = EAFNOSUPPORT;
606                         goto bad;
607                 }
608                 /* check sa_family looks sane for the cmd */
609                 error = EAFNOSUPPORT;
610                 switch (cmd) {
611 #ifdef INET
612                 case SIOCSIFPHYADDR:
613                         if (src->sa_family == AF_INET)
614                                 break;
615                         goto bad;
616 #endif
617 #ifdef INET6
618                 case SIOCSIFPHYADDR_IN6:
619                         if (src->sa_family == AF_INET6)
620                                 break;
621                         goto bad;
622 #endif
623                 }
624                 error = EADDRNOTAVAIL;
625                 switch (src->sa_family) {
626 #ifdef INET
627                 case AF_INET:
628                         if (satosin(src)->sin_addr.s_addr == INADDR_ANY ||
629                             satosin(dst)->sin_addr.s_addr == INADDR_ANY)
630                                 goto bad;
631                         break;
632 #endif
633 #ifdef INET6
634                 case AF_INET6:
635                         if (IN6_IS_ADDR_UNSPECIFIED(
636                             &satosin6(src)->sin6_addr) ||
637                             IN6_IS_ADDR_UNSPECIFIED(
638                             &satosin6(dst)->sin6_addr))
639                                 goto bad;
640                         /*
641                          * Check validity of the scope zone ID of the
642                          * addresses, and convert it into the kernel
643                          * internal form if necessary.
644                          */
645                         error = sa6_embedscope(satosin6(src), 0);
646                         if (error != 0)
647                                 goto bad;
648                         error = sa6_embedscope(satosin6(dst), 0);
649                         if (error != 0)
650                                 goto bad;
651 #endif
652                 };
653                 error = ipsec_set_addresses(ifp, src, dst);
654                 break;
655         case SIOCDIFPHYADDR:
656                 ipsec_delete_tunnel(sc);
657                 break;
658         case SIOCGIFPSRCADDR:
659         case SIOCGIFPDSTADDR:
660 #ifdef INET6
661         case SIOCGIFPSRCADDR_IN6:
662         case SIOCGIFPDSTADDR_IN6:
663 #endif
664                 if (sc->family == 0) {
665                         error = EADDRNOTAVAIL;
666                         break;
667                 }
668                 saidx = ipsec_getsaidx(sc, IPSEC_DIR_OUTBOUND, sc->family);
669                 switch (cmd) {
670 #ifdef INET
671                 case SIOCGIFPSRCADDR:
672                 case SIOCGIFPDSTADDR:
673                         if (saidx->src.sa.sa_family != AF_INET) {
674                                 error = EADDRNOTAVAIL;
675                                 break;
676                         }
677                         sin = (struct sockaddr_in *)&ifr->ifr_addr;
678                         memset(sin, 0, sizeof(*sin));
679                         sin->sin_family = AF_INET;
680                         sin->sin_len = sizeof(*sin);
681                         break;
682 #endif
683 #ifdef INET6
684                 case SIOCGIFPSRCADDR_IN6:
685                 case SIOCGIFPDSTADDR_IN6:
686                         if (saidx->src.sa.sa_family != AF_INET6) {
687                                 error = EADDRNOTAVAIL;
688                                 break;
689                         }
690                         sin6 = (struct sockaddr_in6 *)
691                                 &(((struct in6_ifreq *)data)->ifr_addr);
692                         memset(sin6, 0, sizeof(*sin6));
693                         sin6->sin6_family = AF_INET6;
694                         sin6->sin6_len = sizeof(*sin6);
695                         break;
696 #endif
697                 default:
698                         error = EAFNOSUPPORT;
699                 }
700                 if (error == 0) {
701                         switch (cmd) {
702 #ifdef INET
703                         case SIOCGIFPSRCADDR:
704                                 sin->sin_addr = saidx->src.sin.sin_addr;
705                                 break;
706                         case SIOCGIFPDSTADDR:
707                                 sin->sin_addr = saidx->dst.sin.sin_addr;
708                                 break;
709 #endif
710 #ifdef INET6
711                         case SIOCGIFPSRCADDR_IN6:
712                                 sin6->sin6_addr = saidx->src.sin6.sin6_addr;
713                                 break;
714                         case SIOCGIFPDSTADDR_IN6:
715                                 sin6->sin6_addr = saidx->dst.sin6.sin6_addr;
716                                 break;
717 #endif
718                         }
719                 }
720                 if (error != 0)
721                         break;
722                 switch (cmd) {
723 #ifdef INET
724                 case SIOCGIFPSRCADDR:
725                 case SIOCGIFPDSTADDR:
726                         error = prison_if(curthread->td_ucred,
727                             (struct sockaddr *)sin);
728                         if (error != 0)
729                                 memset(sin, 0, sizeof(*sin));
730                         break;
731 #endif
732 #ifdef INET6
733                 case SIOCGIFPSRCADDR_IN6:
734                 case SIOCGIFPDSTADDR_IN6:
735                         error = prison_if(curthread->td_ucred,
736                             (struct sockaddr *)sin6);
737                         if (error == 0)
738                                 error = sa6_recoverscope(sin6);
739                         if (error != 0)
740                                 memset(sin6, 0, sizeof(*sin6));
741 #endif
742                 }
743                 break;
744         case SIOCGTUNFIB:
745                 ifr->ifr_fib = sc->fibnum;
746                 break;
747         case SIOCSTUNFIB:
748                 if ((error = priv_check(curthread, PRIV_NET_SETIFFIB)) != 0)
749                         break;
750                 if (ifr->ifr_fib >= rt_numfibs)
751                         error = EINVAL;
752                 else
753                         sc->fibnum = ifr->ifr_fib;
754                 break;
755         case IPSECGREQID:
756                 reqid = sc->reqid;
757                 error = copyout(&reqid, ifr_data_get_ptr(ifr), sizeof(reqid));
758                 break;
759         case IPSECSREQID:
760                 if ((error = priv_check(curthread, PRIV_NET_SETIFCAP)) != 0)
761                         break;
762                 error = copyin(ifr_data_get_ptr(ifr), &reqid, sizeof(reqid));
763                 if (error != 0)
764                         break;
765                 error = ipsec_set_reqid(sc, reqid);
766                 break;
767         default:
768                 error = EINVAL;
769                 break;
770         }
771 bad:
772         sx_xunlock(&ipsec_ioctl_sx);
773         return (error);
774 }
775
776 /*
777  * Check that ingress address belongs to local host.
778  */
779 static void
780 ipsec_set_running(struct ipsec_softc *sc)
781 {
782         struct secasindex *saidx;
783         int localip;
784
785         saidx = ipsec_getsaidx(sc, IPSEC_DIR_OUTBOUND, sc->family);
786         localip = 0;
787         switch (sc->family) {
788 #ifdef INET
789         case AF_INET:
790                 localip = in_localip(saidx->src.sin.sin_addr);
791                 break;
792 #endif
793 #ifdef INET6
794         case AF_INET6:
795                 localip = in6_localip(&saidx->src.sin6.sin6_addr);
796                 break;
797 #endif
798         }
799         if (localip != 0)
800                 sc->ifp->if_drv_flags |= IFF_DRV_RUNNING;
801         else
802                 sc->ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
803 }
804
805 /*
806  * ifaddr_event handler.
807  * Clear IFF_DRV_RUNNING flag when ingress address disappears to prevent
808  * source address spoofing.
809  */
810 static void
811 ipsec_srcaddr(void *arg __unused, const struct sockaddr *sa,
812     int event __unused)
813 {
814         struct ipsec_softc *sc;
815         struct secasindex *saidx;
816
817         /* Check that VNET is ready */
818         if (V_ipsec_idhtbl == NULL)
819                 return;
820
821         NET_EPOCH_ASSERT();
822         CK_LIST_FOREACH(sc, ipsec_srchash(sa), srchash) {
823                 if (sc->family == 0)
824                         continue;
825                 saidx = ipsec_getsaidx(sc, IPSEC_DIR_OUTBOUND, sa->sa_family);
826                 if (saidx == NULL ||
827                     key_sockaddrcmp(&saidx->src.sa, sa, 0) != 0)
828                         continue;
829                 ipsec_set_running(sc);
830         }
831 }
832
833 /*
834  * Allocate new private security policies for tunneling interface.
835  * Each tunneling interface has following security policies for
836  * both AF:
837  *   0.0.0.0/0[any] 0.0.0.0/0[any] -P in \
838  *      ipsec esp/tunnel/RemoteIP-LocalIP/unique:reqid
839  *   0.0.0.0/0[any] 0.0.0.0/0[any] -P out \
840  *      ipsec esp/tunnel/LocalIP-RemoteIP/unique:reqid
841  */
842 static int
843 ipsec_newpolicies(struct ipsec_softc *sc, struct secpolicy *sp[IPSEC_SPCOUNT],
844     const struct sockaddr *src, const struct sockaddr *dst, uint32_t reqid)
845 {
846         struct ipsecrequest *isr;
847         int i;
848
849         memset(sp, 0, sizeof(struct secpolicy *) * IPSEC_SPCOUNT);
850         for (i = 0; i < IPSEC_SPCOUNT; i++) {
851                 if ((sp[i] = key_newsp()) == NULL)
852                         goto fail;
853                 if ((isr = ipsec_newisr()) == NULL)
854                         goto fail;
855
856                 sp[i]->policy = IPSEC_POLICY_IPSEC;
857                 sp[i]->state = IPSEC_SPSTATE_DEAD;
858                 sp[i]->req[sp[i]->tcount++] = isr;
859                 sp[i]->created = time_second;
860                 /* Use priority field to store if_index */
861                 sp[i]->priority = sc->ifp->if_index;
862                 isr->level = IPSEC_LEVEL_UNIQUE;
863                 isr->saidx.proto = IPPROTO_ESP;
864                 isr->saidx.mode = IPSEC_MODE_TUNNEL;
865                 isr->saidx.reqid = reqid;
866                 if (i % 2 == 0) {
867                         sp[i]->spidx.dir = IPSEC_DIR_INBOUND;
868                         bcopy(src, &isr->saidx.dst, src->sa_len);
869                         bcopy(dst, &isr->saidx.src, dst->sa_len);
870                 } else {
871                         sp[i]->spidx.dir = IPSEC_DIR_OUTBOUND;
872                         bcopy(src, &isr->saidx.src, src->sa_len);
873                         bcopy(dst, &isr->saidx.dst, dst->sa_len);
874                 }
875                 sp[i]->spidx.ul_proto = IPSEC_ULPROTO_ANY;
876 #ifdef INET
877                 if (i < 2) {
878                         sp[i]->spidx.src.sa.sa_family =
879                             sp[i]->spidx.dst.sa.sa_family = AF_INET;
880                         sp[i]->spidx.src.sa.sa_len =
881                             sp[i]->spidx.dst.sa.sa_len =
882                             sizeof(struct sockaddr_in);
883                         continue;
884                 }
885 #endif
886 #ifdef INET6
887                 sp[i]->spidx.src.sa.sa_family =
888                     sp[i]->spidx.dst.sa.sa_family = AF_INET6;
889                 sp[i]->spidx.src.sa.sa_len =
890                     sp[i]->spidx.dst.sa.sa_len = sizeof(struct sockaddr_in6);
891 #endif
892         }
893         return (0);
894 fail:
895         for (i = 0; i < IPSEC_SPCOUNT; i++)
896                 key_freesp(&sp[i]);
897         return (ENOMEM);
898 }
899
900 static int
901 ipsec_check_reqid(uint32_t reqid)
902 {
903         struct ipsec_softc *sc;
904
905         sx_assert(&ipsec_ioctl_sx, SA_XLOCKED);
906         CK_LIST_FOREACH(sc, ipsec_idhash(reqid), idhash) {
907                 if (sc->reqid == reqid)
908                         return (EEXIST);
909         }
910         return (0);
911 }
912
913 /*
914  * We use key_newreqid() to automatically obtain unique reqid.
915  * Then we check that given id is unique, i.e. it is not used by
916  * another if_ipsec(4) interface. This macro limits the number of
917  * tries to get unique id.
918  */
919 #define IPSEC_REQID_TRYCNT      64
920 static int
921 ipsec_init_reqid(struct ipsec_softc *sc)
922 {
923         uint32_t reqid;
924         int trycount;
925
926         sx_assert(&ipsec_ioctl_sx, SA_XLOCKED);
927         if (sc->reqid != 0) /* already initialized */
928                 return (0);
929
930         trycount = IPSEC_REQID_TRYCNT;
931         while (--trycount > 0) {
932                 reqid = key_newreqid();
933                 if (ipsec_check_reqid(reqid) == 0)
934                         break;
935         }
936         if (trycount == 0)
937                 return (EEXIST);
938         sc->reqid = reqid;
939         CK_LIST_INSERT_HEAD(ipsec_idhash(reqid), sc, idhash);
940         return (0);
941 }
942
943 /*
944  * Set or update reqid for given tunneling interface.
945  * When specified reqid is zero, generate new one.
946  * We are protected by ioctl_sx lock from concurrent id generation.
947  * Also softc would not disappear while we hold ioctl_sx lock.
948  */
949 static int
950 ipsec_set_reqid(struct ipsec_softc *sc, uint32_t reqid)
951 {
952         struct secasindex *saidx;
953
954         sx_assert(&ipsec_ioctl_sx, SA_XLOCKED);
955
956         if (sc->reqid == reqid && reqid != 0)
957                 return (0);
958
959         if (reqid != 0) {
960                 /* Check that specified reqid doesn't exist */
961                 if (ipsec_check_reqid(reqid) != 0)
962                         return (EEXIST);
963                 if (sc->reqid != 0) {
964                         CK_LIST_REMOVE(sc, idhash);
965                         IPSEC_WAIT();
966                 }
967                 sc->reqid = reqid;
968                 CK_LIST_INSERT_HEAD(ipsec_idhash(reqid), sc, idhash);
969         } else {
970                 /* Generate new reqid */
971                 if (ipsec_init_reqid(sc) != 0)
972                         return (EEXIST);
973         }
974
975         /* Tunnel isn't fully configured, just return. */
976         if (sc->family == 0)
977                 return (0);
978
979         saidx = ipsec_getsaidx(sc, IPSEC_DIR_OUTBOUND, sc->family);
980         KASSERT(saidx != NULL,
981             ("saidx is NULL, but family is %d", sc->family));
982         return (ipsec_set_tunnel(sc, &saidx->src.sa, &saidx->dst.sa,
983             sc->reqid));
984 }
985
986 /*
987  * Set tunnel endpoints addresses.
988  */
989 static int
990 ipsec_set_addresses(struct ifnet *ifp, struct sockaddr *src,
991     struct sockaddr *dst)
992 {
993         struct ipsec_softc *sc;
994         struct secasindex *saidx;
995
996         sx_assert(&ipsec_ioctl_sx, SA_XLOCKED);
997
998         sc = ifp->if_softc;
999         if (sc->family != 0) {
1000                 saidx = ipsec_getsaidx(sc, IPSEC_DIR_OUTBOUND,
1001                     src->sa_family);
1002                 if (saidx != NULL && saidx->reqid == sc->reqid &&
1003                     key_sockaddrcmp(&saidx->src.sa, src, 0) == 0 &&
1004                     key_sockaddrcmp(&saidx->dst.sa, dst, 0) == 0)
1005                         return (0); /* Nothing has been changed. */
1006         }
1007         /* If reqid is not set, generate new one. */
1008         if (ipsec_init_reqid(sc) != 0)
1009                 return (EEXIST);
1010         return (ipsec_set_tunnel(sc, src, dst, sc->reqid));
1011 }
1012
1013 static int
1014 ipsec_set_tunnel(struct ipsec_softc *sc, struct sockaddr *src,
1015     struct sockaddr *dst, uint32_t reqid)
1016 {
1017         struct secpolicy *sp[IPSEC_SPCOUNT];
1018         int i;
1019
1020         sx_assert(&ipsec_ioctl_sx, SA_XLOCKED);
1021
1022         /* Allocate SP with new addresses. */
1023         if (ipsec_newpolicies(sc, sp, src, dst, reqid) == 0) {
1024                 /* Add new policies to SPDB */
1025                 if (key_register_ifnet(sp, IPSEC_SPCOUNT) != 0) {
1026                         for (i = 0; i < IPSEC_SPCOUNT; i++)
1027                                 key_freesp(&sp[i]);
1028                         return (EAGAIN);
1029                 }
1030                 if (sc->family != 0)
1031                         ipsec_delete_tunnel(sc);
1032                 for (i = 0; i < IPSEC_SPCOUNT; i++)
1033                         sc->sp[i] = sp[i];
1034                 sc->family = src->sa_family;
1035                 CK_LIST_INSERT_HEAD(ipsec_srchash(src), sc, srchash);
1036         } else {
1037                 sc->ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
1038                 return (ENOMEM);
1039         }
1040         ipsec_set_running(sc);
1041         return (0);
1042 }
1043
1044 static void
1045 ipsec_delete_tunnel(struct ipsec_softc *sc)
1046 {
1047         int i;
1048
1049         sx_assert(&ipsec_ioctl_sx, SA_XLOCKED);
1050
1051         sc->ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
1052         if (sc->family != 0) {
1053                 CK_LIST_REMOVE(sc, srchash);
1054                 sc->family = 0;
1055                 /*
1056                  * Make sure that ipsec_if_input() will not do access
1057                  * to softc's policies.
1058                  */
1059                 IPSEC_WAIT();
1060
1061                 key_unregister_ifnet(sc->sp, IPSEC_SPCOUNT);
1062                 for (i = 0; i < IPSEC_SPCOUNT; i++)
1063                         key_freesp(&sc->sp[i]);
1064         }
1065 }