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