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