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