1 /* $NetBSD: if_l2tp.c,v 1.51 2026/09/19 02:15:13 riastradh 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 /* 30 * L2TPv3 kernel interface 31 */ 32 33 #include <sys/cdefs.h> 34 __KERNEL_RCSID(0, "$NetBSD: if_l2tp.c,v 1.51 2026/09/19 02:15:13 riastradh Exp $"); 35 36 #ifdef _KERNEL_OPT 37 #include "opt_inet.h" 38 #include "opt_net_mpsafe.h" 39 #endif 40 41 #include <sys/param.h> 42 #include <sys/systm.h> 43 #include <sys/kernel.h> 44 #include <sys/mbuf.h> 45 #include <sys/socket.h> 46 #include <sys/sockio.h> 47 #include <sys/errno.h> 48 #include <sys/ioctl.h> 49 #include <sys/time.h> 50 #include <sys/syslog.h> 51 #include <sys/proc.h> 52 #include <sys/conf.h> 53 #include <sys/kauth.h> 54 #include <sys/cpu.h> 55 #include <sys/cprng.h> 56 #include <sys/intr.h> 57 #include <sys/kmem.h> 58 #include <sys/mutex.h> 59 #include <sys/atomic.h> 60 #include <sys/pserialize.h> 61 #include <sys/device.h> 62 #include <sys/module.h> 63 64 #include <net/if.h> 65 #include <net/if_dl.h> 66 #include <net/if_ether.h> 67 #include <net/if_types.h> 68 #include <net/route.h> 69 #include <net/bpf.h> 70 #include <net/if_vlanvar.h> 71 72 #include <netinet/in.h> 73 #include <netinet/in_systm.h> 74 #include <netinet/ip.h> 75 #include <netinet/ip_encap.h> 76 #ifdef INET 77 #include <netinet/in_var.h> 78 #include <netinet/in_l2tp.h> 79 #endif /* INET */ 80 #ifdef INET6 81 #include <netinet6/in6_l2tp.h> 82 #endif 83 84 #include <net/if_l2tp.h> 85 86 #include <net/if_vlanvar.h> 87 88 /* TODO: IP_TCPMSS support */ 89 #undef IP_TCPMSS 90 #ifdef IP_TCPMSS 91 #include <netinet/ip_tcpmss.h> 92 #endif 93 94 /* 95 * l2tp global variable definitions 96 */ 97 static struct { 98 LIST_HEAD(l2tp_sclist, l2tp_softc) list; 99 kmutex_t lock; 100 } l2tp_softcs __cacheline_aligned; 101 102 103 #if !defined(L2TP_ID_HASH_SIZE) 104 #define L2TP_ID_HASH_SIZE 64 105 #endif 106 static struct { 107 kmutex_t lock; 108 struct pslist_head *lists; 109 u_long mask; 110 } l2tp_hash __cacheline_aligned = { 111 .lists = NULL, 112 }; 113 114 pserialize_t l2tp_psz __read_mostly; 115 struct psref_class *lv_psref_class __read_mostly; 116 117 static void l2tp_ifq_init_pc(void *, void *, struct cpu_info *); 118 static void l2tp_ifq_fini_pc(void *, void *, struct cpu_info *); 119 120 static int l2tp_clone_create(struct if_clone *, int); 121 static int l2tp_clone_destroy(struct ifnet *); 122 123 struct if_clone l2tp_cloner = 124 IF_CLONE_INITIALIZER("l2tp", l2tp_clone_create, l2tp_clone_destroy); 125 126 static int l2tp_tx_enqueue(struct l2tp_variant *, struct mbuf *); 127 static int l2tp_output(struct ifnet *, struct mbuf *, 128 const struct sockaddr *, const struct rtentry *); 129 static void l2tp_sendit(struct l2tp_variant *, struct mbuf *); 130 static void l2tpintr(struct l2tp_variant *); 131 static void l2tpintr_softint(void *); 132 133 static void l2tp_hash_init(void); 134 static int l2tp_hash_fini(void); 135 136 static void l2tp_start(struct ifnet *); 137 static int l2tp_transmit(struct ifnet *, struct mbuf *); 138 139 static int l2tp_set_tunnel(struct ifnet *, struct sockaddr *, 140 struct sockaddr *); 141 static void l2tp_delete_tunnel(struct ifnet *); 142 143 static int id_hash_func(uint32_t, u_long); 144 145 static void l2tp_variant_update(struct l2tp_softc *, struct l2tp_variant *); 146 static int l2tp_set_session(struct l2tp_softc *, uint32_t, uint32_t); 147 static int l2tp_clear_session(struct l2tp_softc *); 148 static int l2tp_set_cookie(struct l2tp_softc *, uint64_t, u_int, uint64_t, u_int); 149 static void l2tp_clear_cookie(struct l2tp_softc *); 150 static void l2tp_set_state(struct l2tp_softc *, int); 151 static int l2tp_encap_attach(struct l2tp_variant *); 152 static int l2tp_encap_detach(struct l2tp_variant *); 153 154 static inline struct ifqueue * 155 l2tp_ifq_percpu_getref(percpu_t *pc) 156 { 157 158 return *(struct ifqueue **)percpu_getref(pc); 159 } 160 161 static inline void 162 l2tp_ifq_percpu_putref(percpu_t *pc) 163 { 164 165 percpu_putref(pc); 166 } 167 168 #ifndef MAX_L2TP_NEST 169 /* 170 * This macro controls the upper limitation on nesting of l2tp tunnels. 171 * Since, setting a large value to this macro with a careless configuration 172 * may introduce system crash, we don't allow any nestings by default. 173 * If you need to configure nested l2tp tunnels, you can define this macro 174 * in your kernel configuration file. However, if you do so, please be 175 * careful to configure the tunnels so that it won't make a loop. 176 */ 177 /* 178 * XXX 179 * Currently, if in_l2tp_output recursively calls, it causes locking against 180 * myself of struct l2tp_ro->lr_lock. So, nested l2tp tunnels is prohibited. 181 */ 182 #define MAX_L2TP_NEST 0 183 #endif 184 185 static int max_l2tp_nesting = MAX_L2TP_NEST; 186 187 /* ARGSUSED */ 188 void 189 l2tpattach(int count) 190 { 191 /* 192 * Nothing to do here, initialization is handled by the 193 * module initialization code in l2tpinit() below). 194 */ 195 } 196 197 static void 198 l2tpinit(void) 199 { 200 201 mutex_init(&l2tp_softcs.lock, MUTEX_DEFAULT, IPL_NONE); 202 LIST_INIT(&l2tp_softcs.list); 203 204 mutex_init(&l2tp_hash.lock, MUTEX_DEFAULT, IPL_NONE); 205 l2tp_psz = pserialize_create(); 206 lv_psref_class = psref_class_create("l2tpvar", IPL_SOFTNET); 207 if_clone_attach(&l2tp_cloner); 208 209 l2tp_hash_init(); 210 } 211 212 static int 213 l2tpdetach(void) 214 { 215 int error; 216 217 mutex_enter(&l2tp_softcs.lock); 218 if (!LIST_EMPTY(&l2tp_softcs.list)) { 219 mutex_exit(&l2tp_softcs.lock); 220 return EBUSY; 221 } 222 mutex_exit(&l2tp_softcs.lock); 223 224 error = l2tp_hash_fini(); 225 if (error) 226 return error; 227 228 if_clone_detach(&l2tp_cloner); 229 psref_class_destroy(lv_psref_class); 230 pserialize_destroy(l2tp_psz); 231 mutex_destroy(&l2tp_hash.lock); 232 233 mutex_destroy(&l2tp_softcs.lock); 234 235 return error; 236 } 237 238 static int 239 l2tp_clone_create(struct if_clone *ifc, int unit) 240 { 241 struct l2tp_softc *sc; 242 struct l2tp_variant *var; 243 int rv; 244 u_int si_flags = SOFTINT_NET; 245 #ifdef NET_MPSAFE 246 si_flags |= SOFTINT_MPSAFE; 247 #endif 248 sc = kmem_zalloc(sizeof(struct l2tp_softc), KM_SLEEP); 249 if_initname(&sc->l2tp_ec.ec_if, ifc->ifc_name, unit); 250 rv = l2tpattach0(sc); 251 if (rv != 0) { 252 kmem_free(sc, sizeof(struct l2tp_softc)); 253 return rv; 254 } 255 256 var = kmem_zalloc(sizeof(struct l2tp_variant), KM_SLEEP); 257 var->lv_softc = sc; 258 var->lv_state = L2TP_STATE_DOWN; 259 var->lv_use_cookie = L2TP_COOKIE_OFF; 260 psref_target_init(&var->lv_psref, lv_psref_class); 261 262 sc->l2tp_var = var; 263 mutex_init(&sc->l2tp_lock, MUTEX_DEFAULT, IPL_NONE); 264 sc->l2tp_psz = pserialize_create(); 265 PSLIST_ENTRY_INIT(sc, l2tp_hash); 266 267 sc->l2tp_ro_percpu = if_tunnel_alloc_ro_percpu(); 268 269 sc->l2tp_ifq_percpu = percpu_create(sizeof(struct ifqueue *), 270 l2tp_ifq_init_pc, l2tp_ifq_fini_pc, NULL); 271 sc->l2tp_si = softint_establish(si_flags, l2tpintr_softint, sc); 272 273 mutex_enter(&l2tp_softcs.lock); 274 LIST_INSERT_HEAD(&l2tp_softcs.list, sc, l2tp_list); 275 mutex_exit(&l2tp_softcs.lock); 276 277 return (0); 278 } 279 280 int 281 l2tpattach0(struct l2tp_softc *sc) 282 { 283 284 sc->l2tp_ec.ec_capabilities = 0; 285 sc->l2tp_ec.ec_capabilities |= ETHERCAP_VLAN_MTU; 286 sc->l2tp_ec.ec_capabilities |= ETHERCAP_JUMBO_MTU; 287 288 ether_ifattach(&sc->l2tp_ec.ec_if, NULL); 289 290 sc->l2tp_ec.ec_if.if_addrlen = 0; 291 sc->l2tp_ec.ec_if.if_mtu = L2TP_MTU; 292 sc->l2tp_ec.ec_if.if_flags = IFF_POINTOPOINT|IFF_MULTICAST|IFF_SIMPLEX; 293 #ifdef NET_MPSAFE 294 sc->l2tp_ec.ec_if.if_extflags = IFEF_MPSAFE; 295 #endif 296 sc->l2tp_ec.ec_if.if_ioctl = l2tp_ioctl; 297 sc->l2tp_ec.ec_if.if_output = l2tp_output; 298 sc->l2tp_ec.ec_if.if_type = IFT_L2TP; 299 sc->l2tp_ec.ec_if.if_dlt = DLT_NULL; 300 sc->l2tp_ec.ec_if.if_start = l2tp_start; 301 sc->l2tp_ec.ec_if.if_transmit = l2tp_transmit; 302 sc->l2tp_ec.ec_if._if_input = ether_input; 303 IFQ_SET_READY(&sc->l2tp_ec.ec_if.if_snd); 304 305 /* XXX 306 * It may improve performance to use if_initialize()/if_register() 307 * so that l2tp_input() calls if_input() instead of 308 * if_percpuq_enqueue(). However, that causes recursive softnet_lock 309 * when NET_MPSAFE is not set. 310 */ 311 if_attach(&sc->l2tp_ec.ec_if); 312 if_link_state_change(&sc->l2tp_ec.ec_if, LINK_STATE_DOWN); 313 if_alloc_sadl(&sc->l2tp_ec.ec_if); 314 315 return 0; 316 } 317 318 void 319 l2tp_ifq_init_pc(void *p, void *arg __unused, struct cpu_info *ci __unused) 320 { 321 struct ifqueue **ifqp = p; 322 323 *ifqp = kmem_zalloc(sizeof(**ifqp), KM_SLEEP); 324 (*ifqp)->ifq_maxlen = IFQ_MAXLEN; 325 } 326 327 void 328 l2tp_ifq_fini_pc(void *p, void *arg __unused, struct cpu_info *ci __unused) 329 { 330 struct ifqueue **ifqp = p; 331 332 kmem_free(*ifqp, sizeof(**ifqp)); 333 } 334 335 static int 336 l2tp_clone_destroy(struct ifnet *ifp) 337 { 338 struct l2tp_variant *var; 339 struct l2tp_softc *sc = container_of(ifp, struct l2tp_softc, 340 l2tp_ec.ec_if); 341 342 ether_ifdetach(ifp); 343 344 l2tp_clear_session(sc); 345 l2tp_delete_tunnel(&sc->l2tp_ec.ec_if); 346 /* 347 * To avoid for l2tp_transmit() and l2tpintr_softint() to access 348 * sc->l2tp_var after free it. 349 */ 350 mutex_enter(&sc->l2tp_lock); 351 var = sc->l2tp_var; 352 l2tp_variant_update(sc, NULL); 353 mutex_exit(&sc->l2tp_lock); 354 355 softint_disestablish(sc->l2tp_si); 356 percpu_free(sc->l2tp_ifq_percpu, sizeof(struct ifqueue *)); 357 358 mutex_enter(&l2tp_softcs.lock); 359 LIST_REMOVE(sc, l2tp_list); 360 mutex_exit(&l2tp_softcs.lock); 361 362 if_detach(ifp); 363 364 if_tunnel_free_ro_percpu(sc->l2tp_ro_percpu); 365 366 kmem_free(var, sizeof(struct l2tp_variant)); 367 pserialize_destroy(sc->l2tp_psz); 368 mutex_destroy(&sc->l2tp_lock); 369 kmem_free(sc, sizeof(struct l2tp_softc)); 370 371 return 0; 372 } 373 374 static int 375 l2tp_tx_enqueue(struct l2tp_variant *var, struct mbuf *m) 376 { 377 struct l2tp_softc *sc; 378 struct ifnet *ifp; 379 struct ifqueue *ifq; 380 int s; 381 382 KASSERT(psref_held(&var->lv_psref, lv_psref_class)); 383 384 sc = var->lv_softc; 385 ifp = &sc->l2tp_ec.ec_if; 386 387 s = splsoftnet(); 388 ifq = l2tp_ifq_percpu_getref(sc->l2tp_ifq_percpu); 389 if (IF_QFULL(ifq)) { 390 if_statinc(ifp, if_oerrors); 391 l2tp_ifq_percpu_putref(sc->l2tp_ifq_percpu); 392 splx(s); 393 m_freem(m); 394 return ENOBUFS; 395 } 396 397 IF_ENQUEUE(ifq, m); 398 percpu_putref(sc->l2tp_ifq_percpu); 399 softint_schedule(sc->l2tp_si); 400 /* counter is incremented in l2tpintr() */ 401 splx(s); 402 return 0; 403 } 404 405 static int 406 l2tp_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, 407 const struct rtentry *rt) 408 { 409 struct l2tp_softc *sc = container_of(ifp, struct l2tp_softc, 410 l2tp_ec.ec_if); 411 struct l2tp_variant *var; 412 struct psref psref; 413 int error = 0; 414 415 var = l2tp_getref_variant(sc, &psref); 416 if (var == NULL) { 417 m_freem(m); 418 return ENETDOWN; 419 } 420 421 IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family); 422 423 m->m_flags &= ~(M_BCAST|M_MCAST); 424 425 if ((ifp->if_flags & IFF_UP) == 0) { 426 m_freem(m); 427 error = ENETDOWN; 428 goto end; 429 } 430 431 if (var->lv_psrc == NULL || var->lv_pdst == NULL) { 432 m_freem(m); 433 error = ENETDOWN; 434 goto end; 435 } 436 437 /* XXX should we check if our outer source is legal? */ 438 439 /* use DLT_NULL encapsulation here to pass inner af type */ 440 M_PREPEND(m, sizeof(int), M_DONTWAIT); 441 if (!m) { 442 error = ENOBUFS; 443 goto end; 444 } 445 *mtod(m, int *) = dst->sa_family; 446 447 error = l2tp_tx_enqueue(var, m); 448 end: 449 l2tp_putref_variant(var, &psref); 450 if (error) 451 if_statinc(ifp, if_oerrors); 452 453 return error; 454 } 455 456 static void 457 l2tp_sendit(struct l2tp_variant *var, struct mbuf *m) 458 { 459 int len; 460 int error; 461 struct l2tp_softc *sc; 462 struct ifnet *ifp; 463 464 KASSERT(psref_held(&var->lv_psref, lv_psref_class)); 465 466 sc = var->lv_softc; 467 ifp = &sc->l2tp_ec.ec_if; 468 469 len = m->m_pkthdr.len; 470 m->m_flags &= ~(M_BCAST|M_MCAST); 471 bpf_mtap(ifp, m, BPF_D_OUT); 472 473 switch (var->lv_psrc->sa_family) { 474 #ifdef INET 475 case AF_INET: 476 error = in_l2tp_output(var, m); 477 break; 478 #endif 479 #ifdef INET6 480 case AF_INET6: 481 error = in6_l2tp_output(var, m); 482 break; 483 #endif 484 default: 485 m_freem(m); 486 error = ENETDOWN; 487 break; 488 } 489 if (error) { 490 if_statinc(ifp, if_oerrors); 491 } else { 492 if_statadd2(ifp, if_opackets, 1, if_obytes, len); 493 } 494 } 495 496 static void 497 l2tpintr(struct l2tp_variant *var) 498 { 499 struct l2tp_softc *sc; 500 struct ifnet *ifp; 501 struct mbuf *m; 502 struct ifqueue *ifq; 503 u_int cpuid = cpu_index(curcpu()); 504 505 KASSERT(psref_held(&var->lv_psref, lv_psref_class)); 506 507 sc = var->lv_softc; 508 ifp = &sc->l2tp_ec.ec_if; 509 510 /* output processing */ 511 if (var->lv_my_sess_id == 0 || var->lv_peer_sess_id == 0) { 512 ifq = l2tp_ifq_percpu_getref(sc->l2tp_ifq_percpu); 513 IF_PURGE(ifq); 514 l2tp_ifq_percpu_putref(sc->l2tp_ifq_percpu); 515 if (cpuid == 0) 516 IFQ_PURGE(&ifp->if_snd); 517 return; 518 } 519 520 /* Currently, l2tpintr() is always called in softint context. */ 521 ifq = l2tp_ifq_percpu_getref(sc->l2tp_ifq_percpu); 522 for (;;) { 523 IF_DEQUEUE(ifq, m); 524 if (m != NULL) 525 l2tp_sendit(var, m); 526 else 527 break; 528 } 529 l2tp_ifq_percpu_putref(sc->l2tp_ifq_percpu); 530 531 if (cpuid == 0) { 532 for (;;) { 533 IFQ_DEQUEUE(&ifp->if_snd, m); 534 if (m != NULL) 535 l2tp_sendit(var, m); 536 else 537 break; 538 } 539 } 540 } 541 542 static void 543 l2tpintr_softint(void *arg) 544 { 545 struct l2tp_variant *var; 546 struct psref psref; 547 struct l2tp_softc *sc = arg; 548 549 var = l2tp_getref_variant(sc, &psref); 550 if (var == NULL) 551 return; 552 553 l2tpintr(var); 554 l2tp_putref_variant(var, &psref); 555 } 556 557 void 558 l2tp_input(struct mbuf *m, struct ifnet *ifp) 559 { 560 vaddr_t addr; 561 562 KASSERT(ifp != NULL); 563 564 /* 565 * Currently, l2tp(4) supports only ethernet as inner protocol. 566 */ 567 if (m->m_pkthdr.len < sizeof(struct ether_header)) { 568 m_freem(m); 569 return; 570 } 571 572 /* 573 * If the head of the payload is not aligned, align it. 574 */ 575 addr = mtod(m, vaddr_t); 576 if ((addr & 0x03) != 0x2) { 577 /* copy and align head of payload */ 578 struct mbuf *m_head; 579 int copy_length; 580 u_int pad = roundup(sizeof(struct ether_header), 4) 581 - sizeof(struct ether_header); 582 583 #define L2TP_COPY_LENGTH 60 584 585 if (m->m_pkthdr.len < L2TP_COPY_LENGTH) { 586 copy_length = m->m_pkthdr.len; 587 } else { 588 copy_length = L2TP_COPY_LENGTH; 589 } 590 591 if (m->m_len < copy_length) { 592 m = m_pullup(m, copy_length); 593 if (m == NULL) 594 return; 595 } 596 597 MGETHDR(m_head, M_DONTWAIT, MT_HEADER); 598 if (m_head == NULL) { 599 m_freem(m); 600 return; 601 } 602 m_move_pkthdr(m_head, m); 603 604 /* 605 * m_head should be: 606 * L2TP_COPY_LENGTH 607 * <- + roundup(pad, 4) - pad -> 608 * +-------+--------+-----+--------------+-------------+ 609 * | m_hdr | pkthdr | ... | ether header | payload | 610 * +-------+--------+-----+--------------+-------------+ 611 * ^ ^ 612 * m_data 4 byte aligned 613 */ 614 m_align(m_head, L2TP_COPY_LENGTH + roundup(pad, 4)); 615 m_head->m_data += pad; 616 617 memcpy(mtod(m_head, void *), mtod(m, void *), copy_length); 618 m_head->m_len = copy_length; 619 m->m_data += copy_length; 620 m->m_len -= copy_length; 621 622 /* construct chain */ 623 if (m->m_len == 0) { 624 m_head->m_next = m_free(m); 625 } else { 626 m_head->m_next = m; 627 } 628 629 /* override m */ 630 m = m_head; 631 } 632 633 m_set_rcvif(m, ifp); 634 635 /* 636 * bpf_mtap() and ifp->if_ipackets++ is done in if_input() 637 * 638 * obytes is incremented at ether_output() or bridge_enqueue(). 639 */ 640 if_percpuq_enqueue(ifp->if_percpuq, m); 641 } 642 643 void 644 l2tp_start(struct ifnet *ifp) 645 { 646 struct psref psref; 647 struct l2tp_variant *var; 648 struct l2tp_softc *sc = container_of(ifp, struct l2tp_softc, 649 l2tp_ec.ec_if); 650 651 var = l2tp_getref_variant(sc, &psref); 652 if (var == NULL) 653 return; 654 655 if (var->lv_psrc == NULL || var->lv_pdst == NULL) 656 return; 657 658 kpreempt_disable(); 659 softint_schedule(sc->l2tp_si); 660 kpreempt_enable(); 661 l2tp_putref_variant(var, &psref); 662 } 663 664 int 665 l2tp_transmit(struct ifnet *ifp, struct mbuf *m) 666 { 667 int error; 668 struct psref psref; 669 struct l2tp_variant *var; 670 struct l2tp_softc *sc = container_of(ifp, struct l2tp_softc, 671 l2tp_ec.ec_if); 672 673 var = l2tp_getref_variant(sc, &psref); 674 if (var == NULL) { 675 m_freem(m); 676 return ENETDOWN; 677 } 678 679 if (var->lv_psrc == NULL || var->lv_pdst == NULL) { 680 m_freem(m); 681 error = ENETDOWN; 682 goto out; 683 } 684 685 m->m_flags &= ~(M_BCAST|M_MCAST); 686 687 error = l2tp_tx_enqueue(var, m); 688 out: 689 l2tp_putref_variant(var, &psref); 690 return error; 691 } 692 693 /* XXX how should we handle IPv6 scope on SIOC[GS]IFPHYADDR? */ 694 int 695 l2tp_ioctl(struct ifnet *ifp, u_long cmd, void *data) 696 { 697 struct lwp *const l = curlwp; 698 struct l2tp_softc *sc = container_of(ifp, struct l2tp_softc, 699 l2tp_ec.ec_if); 700 struct l2tp_variant *var, *var_tmp; 701 struct ifreq *ifr = data; 702 int error = 0, size; 703 struct sockaddr *dst, *src; 704 struct l2tp_req l2tpr; 705 u_long mtu; 706 int bound; 707 struct psref psref; 708 709 /* 710 * Verify permission for interface-specific ioctls. 711 * Permissions for generic ioctls are checked by doifioctl. 712 */ 713 switch (cmd) { 714 case SIOCSL2TPSESSION: 715 case SIOCDL2TPSESSION: 716 case SIOCSL2TPCOOKIE: 717 case SIOCDL2TPCOOKIE: 718 case SIOCSL2TPSTATE: 719 error = kauth_authorize_network(l->l_cred, 720 KAUTH_NETWORK_INTERFACE, 721 KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, ifp, 722 KAUTH_ARG(cmd), NULL); 723 if (error) 724 return error; 725 break; 726 } 727 728 switch (cmd) { 729 case SIOCSIFADDR: 730 ifp->if_flags |= IFF_UP; 731 break; 732 733 case SIOCSIFDSTADDR: 734 break; 735 736 case SIOCADDMULTI: 737 case SIOCDELMULTI: 738 switch (ifr->ifr_addr.sa_family) { 739 #ifdef INET 740 case AF_INET: /* IP supports Multicast */ 741 break; 742 #endif /* INET */ 743 #ifdef INET6 744 case AF_INET6: /* IP6 supports Multicast */ 745 break; 746 #endif /* INET6 */ 747 default: /* Other protocols doesn't support Multicast */ 748 error = EAFNOSUPPORT; 749 break; 750 } 751 break; 752 753 case SIOCSIFMTU: 754 mtu = ifr->ifr_mtu; 755 if (mtu < L2TP_MTU_MIN || mtu > L2TP_MTU_MAX) 756 return (EINVAL); 757 ifp->if_mtu = mtu; 758 break; 759 760 #ifdef INET 761 case SIOCSIFPHYADDR: 762 src = (struct sockaddr *) 763 &(((struct in_aliasreq *)data)->ifra_addr); 764 dst = (struct sockaddr *) 765 &(((struct in_aliasreq *)data)->ifra_dstaddr); 766 if (src->sa_family != AF_INET || dst->sa_family != AF_INET) 767 return EAFNOSUPPORT; 768 else if (src->sa_len != sizeof(struct sockaddr_in) 769 || dst->sa_len != sizeof(struct sockaddr_in)) 770 return EINVAL; 771 772 error = l2tp_set_tunnel(&sc->l2tp_ec.ec_if, src, dst); 773 break; 774 775 #endif /* INET */ 776 #ifdef INET6 777 case SIOCSIFPHYADDR_IN6: 778 src = (struct sockaddr *) 779 &(((struct in6_aliasreq *)data)->ifra_addr); 780 dst = (struct sockaddr *) 781 &(((struct in6_aliasreq *)data)->ifra_dstaddr); 782 if (src->sa_family != AF_INET6 || dst->sa_family != AF_INET6) 783 return EAFNOSUPPORT; 784 else if (src->sa_len != sizeof(struct sockaddr_in6) 785 || dst->sa_len != sizeof(struct sockaddr_in6)) 786 return EINVAL; 787 788 error = l2tp_set_tunnel(&sc->l2tp_ec.ec_if, src, dst); 789 break; 790 791 #endif /* INET6 */ 792 case SIOCSLIFPHYADDR: 793 src = (struct sockaddr *) 794 &(((struct if_laddrreq *)data)->addr); 795 dst = (struct sockaddr *) 796 &(((struct if_laddrreq *)data)->dstaddr); 797 if (src->sa_family != dst->sa_family) 798 return EINVAL; 799 else if (src->sa_family == AF_INET 800 && src->sa_len != sizeof(struct sockaddr_in)) 801 return EINVAL; 802 else if (src->sa_family == AF_INET6 803 && src->sa_len != sizeof(struct sockaddr_in6)) 804 return EINVAL; 805 else if (dst->sa_family == AF_INET 806 && dst->sa_len != sizeof(struct sockaddr_in)) 807 return EINVAL; 808 else if (dst->sa_family == AF_INET6 809 && dst->sa_len != sizeof(struct sockaddr_in6)) 810 return EINVAL; 811 812 error = l2tp_set_tunnel(&sc->l2tp_ec.ec_if, src, dst); 813 break; 814 815 case SIOCDIFPHYADDR: 816 l2tp_delete_tunnel(&sc->l2tp_ec.ec_if); 817 break; 818 819 case SIOCGIFPSRCADDR: 820 #ifdef INET6 821 case SIOCGIFPSRCADDR_IN6: 822 #endif /* INET6 */ 823 bound = curlwp_bind(); 824 var = l2tp_getref_variant(sc, &psref); 825 if (var == NULL) { 826 curlwp_bindx(bound); 827 error = EADDRNOTAVAIL; 828 goto bad; 829 } 830 if (var->lv_psrc == NULL) { 831 l2tp_putref_variant(var, &psref); 832 curlwp_bindx(bound); 833 error = EADDRNOTAVAIL; 834 goto bad; 835 } 836 src = var->lv_psrc; 837 switch (cmd) { 838 #ifdef INET 839 case SIOCGIFPSRCADDR: 840 dst = &ifr->ifr_addr; 841 size = sizeof(ifr->ifr_addr); 842 break; 843 #endif /* INET */ 844 #ifdef INET6 845 case SIOCGIFPSRCADDR_IN6: 846 dst = (struct sockaddr *) 847 &(((struct in6_ifreq *)data)->ifr_addr); 848 size = sizeof(((struct in6_ifreq *)data)->ifr_addr); 849 break; 850 #endif /* INET6 */ 851 default: 852 l2tp_putref_variant(var, &psref); 853 curlwp_bindx(bound); 854 error = EADDRNOTAVAIL; 855 goto bad; 856 } 857 if (src->sa_len > size) { 858 l2tp_putref_variant(var, &psref); 859 curlwp_bindx(bound); 860 return EINVAL; 861 } 862 sockaddr_copy(dst, src->sa_len, src); 863 l2tp_putref_variant(var, &psref); 864 curlwp_bindx(bound); 865 break; 866 867 case SIOCGIFPDSTADDR: 868 #ifdef INET6 869 case SIOCGIFPDSTADDR_IN6: 870 #endif /* INET6 */ 871 bound = curlwp_bind(); 872 var = l2tp_getref_variant(sc, &psref); 873 if (var == NULL) { 874 curlwp_bindx(bound); 875 error = EADDRNOTAVAIL; 876 goto bad; 877 } 878 if (var->lv_pdst == NULL) { 879 l2tp_putref_variant(var, &psref); 880 curlwp_bindx(bound); 881 error = EADDRNOTAVAIL; 882 goto bad; 883 } 884 src = var->lv_pdst; 885 switch (cmd) { 886 #ifdef INET 887 case SIOCGIFPDSTADDR: 888 dst = &ifr->ifr_addr; 889 size = sizeof(ifr->ifr_addr); 890 break; 891 #endif /* INET */ 892 #ifdef INET6 893 case SIOCGIFPDSTADDR_IN6: 894 dst = (struct sockaddr *) 895 &(((struct in6_ifreq *)data)->ifr_addr); 896 size = sizeof(((struct in6_ifreq *)data)->ifr_addr); 897 break; 898 #endif /* INET6 */ 899 default: 900 l2tp_putref_variant(var, &psref); 901 curlwp_bindx(bound); 902 error = EADDRNOTAVAIL; 903 goto bad; 904 } 905 if (src->sa_len > size) { 906 l2tp_putref_variant(var, &psref); 907 curlwp_bindx(bound); 908 return EINVAL; 909 } 910 sockaddr_copy(dst, src->sa_len, src); 911 l2tp_putref_variant(var, &psref); 912 curlwp_bindx(bound); 913 break; 914 915 case SIOCGLIFPHYADDR: 916 bound = curlwp_bind(); 917 var = l2tp_getref_variant(sc, &psref); 918 if (var == NULL) { 919 curlwp_bindx(bound); 920 error = EADDRNOTAVAIL; 921 goto bad; 922 } 923 if (var->lv_psrc == NULL || var->lv_pdst == NULL) { 924 l2tp_putref_variant(var, &psref); 925 curlwp_bindx(bound); 926 error = EADDRNOTAVAIL; 927 goto bad; 928 } 929 930 /* copy src */ 931 src = var->lv_psrc; 932 dst = (struct sockaddr *) 933 &(((struct if_laddrreq *)data)->addr); 934 size = sizeof(((struct if_laddrreq *)data)->addr); 935 if (src->sa_len > size) { 936 l2tp_putref_variant(var, &psref); 937 curlwp_bindx(bound); 938 return EINVAL; 939 } 940 sockaddr_copy(dst, src->sa_len, src); 941 942 /* copy dst */ 943 src = var->lv_pdst; 944 dst = (struct sockaddr *) 945 &(((struct if_laddrreq *)data)->dstaddr); 946 size = sizeof(((struct if_laddrreq *)data)->dstaddr); 947 if (src->sa_len > size) { 948 l2tp_putref_variant(var, &psref); 949 curlwp_bindx(bound); 950 return EINVAL; 951 } 952 sockaddr_copy(dst, src->sa_len, src); 953 l2tp_putref_variant(var, &psref); 954 curlwp_bindx(bound); 955 break; 956 957 case SIOCSL2TPSESSION: 958 if ((error = copyin(ifr->ifr_data, &l2tpr, sizeof(l2tpr))) != 0) 959 break; 960 961 /* session id must not zero */ 962 if (l2tpr.my_sess_id == 0 || l2tpr.peer_sess_id == 0) 963 return EINVAL; 964 965 bound = curlwp_bind(); 966 var_tmp = l2tp_lookup_session_ref(l2tpr.my_sess_id, &psref); 967 if (var_tmp != NULL) { 968 /* duplicate session id */ 969 log(LOG_WARNING, "%s: duplicate session id %" PRIu32 " of %s\n", 970 sc->l2tp_ec.ec_if.if_xname, l2tpr.my_sess_id, 971 var_tmp->lv_softc->l2tp_ec.ec_if.if_xname); 972 psref_release(&psref, &var_tmp->lv_psref, 973 lv_psref_class); 974 curlwp_bindx(bound); 975 return EINVAL; 976 } 977 curlwp_bindx(bound); 978 979 error = l2tp_set_session(sc, l2tpr.my_sess_id, l2tpr.peer_sess_id); 980 break; 981 case SIOCDL2TPSESSION: 982 l2tp_clear_session(sc); 983 break; 984 case SIOCSL2TPCOOKIE: 985 if ((error = copyin(ifr->ifr_data, &l2tpr, sizeof(l2tpr))) != 0) 986 break; 987 988 error = l2tp_set_cookie(sc, l2tpr.my_cookie, l2tpr.my_cookie_len, 989 l2tpr.peer_cookie, l2tpr.peer_cookie_len); 990 break; 991 case SIOCDL2TPCOOKIE: 992 l2tp_clear_cookie(sc); 993 break; 994 case SIOCSL2TPSTATE: 995 if ((error = copyin(ifr->ifr_data, &l2tpr, sizeof(l2tpr))) != 0) 996 break; 997 998 l2tp_set_state(sc, l2tpr.state); 999 break; 1000 case SIOCGL2TP: 1001 /* get L2TPV3 session info */ 1002 memset(&l2tpr, 0, sizeof(l2tpr)); 1003 1004 bound = curlwp_bind(); 1005 var = l2tp_getref_variant(sc, &psref); 1006 if (var == NULL) { 1007 curlwp_bindx(bound); 1008 error = EADDRNOTAVAIL; 1009 goto bad; 1010 } 1011 1012 l2tpr.state = var->lv_state; 1013 l2tpr.my_sess_id = var->lv_my_sess_id; 1014 l2tpr.peer_sess_id = var->lv_peer_sess_id; 1015 l2tpr.my_cookie = var->lv_my_cookie; 1016 l2tpr.my_cookie_len = var->lv_my_cookie_len; 1017 l2tpr.peer_cookie = var->lv_peer_cookie; 1018 l2tpr.peer_cookie_len = var->lv_peer_cookie_len; 1019 l2tp_putref_variant(var, &psref); 1020 curlwp_bindx(bound); 1021 1022 error = copyout(&l2tpr, ifr->ifr_data, sizeof(l2tpr)); 1023 break; 1024 1025 default: 1026 error = ifioctl_common(ifp, cmd, data); 1027 break; 1028 } 1029 bad: 1030 return error; 1031 } 1032 1033 static int 1034 l2tp_set_tunnel(struct ifnet *ifp, struct sockaddr *src, struct sockaddr *dst) 1035 { 1036 struct l2tp_softc *sc = container_of(ifp, struct l2tp_softc, 1037 l2tp_ec.ec_if); 1038 struct sockaddr *osrc, *odst; 1039 struct sockaddr *nsrc, *ndst; 1040 struct l2tp_variant *ovar, *nvar; 1041 int error; 1042 1043 nsrc = sockaddr_dup(src, M_WAITOK); 1044 ndst = sockaddr_dup(dst, M_WAITOK); 1045 1046 nvar = kmem_alloc(sizeof(*nvar), KM_SLEEP); 1047 1048 error = encap_lock_enter(); 1049 if (error) 1050 goto error; 1051 1052 mutex_enter(&sc->l2tp_lock); 1053 1054 ovar = sc->l2tp_var; 1055 osrc = ovar->lv_psrc; 1056 odst = ovar->lv_pdst; 1057 *nvar = *ovar; 1058 psref_target_init(&nvar->lv_psref, lv_psref_class); 1059 nvar->lv_psrc = nsrc; 1060 nvar->lv_pdst = ndst; 1061 error = l2tp_encap_attach(nvar); 1062 if (error) { 1063 mutex_exit(&sc->l2tp_lock); 1064 encap_lock_exit(); 1065 goto error; 1066 } 1067 l2tp_variant_update(sc, nvar); 1068 1069 mutex_exit(&sc->l2tp_lock); 1070 1071 (void)l2tp_encap_detach(ovar); 1072 encap_lock_exit(); 1073 1074 if (osrc) 1075 sockaddr_free(osrc); 1076 if (odst) 1077 sockaddr_free(odst); 1078 kmem_free(ovar, sizeof(*ovar)); 1079 return 0; 1080 1081 error: 1082 sockaddr_free(nsrc); 1083 sockaddr_free(ndst); 1084 kmem_free(nvar, sizeof(*nvar)); 1085 1086 return error; 1087 } 1088 1089 static void 1090 l2tp_delete_tunnel(struct ifnet *ifp) 1091 { 1092 struct l2tp_softc *sc = container_of(ifp, struct l2tp_softc, 1093 l2tp_ec.ec_if); 1094 struct sockaddr *osrc, *odst; 1095 struct l2tp_variant *ovar, *nvar; 1096 int error; 1097 1098 nvar = kmem_alloc(sizeof(*nvar), KM_SLEEP); 1099 1100 error = encap_lock_enter(); 1101 if (error) { 1102 kmem_free(nvar, sizeof(*nvar)); 1103 return; 1104 } 1105 mutex_enter(&sc->l2tp_lock); 1106 1107 ovar = sc->l2tp_var; 1108 osrc = ovar->lv_psrc; 1109 odst = ovar->lv_pdst; 1110 *nvar = *ovar; 1111 psref_target_init(&nvar->lv_psref, lv_psref_class); 1112 nvar->lv_psrc = NULL; 1113 nvar->lv_pdst = NULL; 1114 l2tp_variant_update(sc, nvar); 1115 1116 mutex_exit(&sc->l2tp_lock); 1117 1118 (void)l2tp_encap_detach(ovar); 1119 encap_lock_exit(); 1120 1121 if (osrc) 1122 sockaddr_free(osrc); 1123 if (odst) 1124 sockaddr_free(odst); 1125 kmem_free(ovar, sizeof(*ovar)); 1126 } 1127 1128 static int 1129 id_hash_func(uint32_t id, u_long mask) 1130 { 1131 uint32_t hash; 1132 1133 hash = (id >> 16) ^ id; 1134 hash = (hash >> 4) ^ hash; 1135 1136 return hash & mask; 1137 } 1138 1139 static void 1140 l2tp_hash_init(void) 1141 { 1142 1143 l2tp_hash.lists = hashinit(L2TP_ID_HASH_SIZE, HASH_PSLIST, true, 1144 &l2tp_hash.mask); 1145 } 1146 1147 static int 1148 l2tp_hash_fini(void) 1149 { 1150 int i; 1151 1152 mutex_enter(&l2tp_hash.lock); 1153 1154 for (i = 0; i < l2tp_hash.mask + 1; i++) { 1155 if (PSLIST_WRITER_FIRST(&l2tp_hash.lists[i], struct l2tp_softc, 1156 l2tp_hash) != NULL) { 1157 mutex_exit(&l2tp_hash.lock); 1158 return EBUSY; 1159 } 1160 } 1161 for (i = 0; i < l2tp_hash.mask + 1; i++) 1162 PSLIST_DESTROY(&l2tp_hash.lists[i]); 1163 1164 mutex_exit(&l2tp_hash.lock); 1165 1166 hashdone(l2tp_hash.lists, HASH_PSLIST, l2tp_hash.mask); 1167 1168 return 0; 1169 } 1170 1171 static int 1172 l2tp_set_session(struct l2tp_softc *sc, uint32_t my_sess_id, 1173 uint32_t peer_sess_id) 1174 { 1175 uint32_t idx; 1176 struct l2tp_variant *nvar; 1177 struct l2tp_variant *ovar; 1178 struct ifnet *ifp = &sc->l2tp_ec.ec_if; 1179 1180 nvar = kmem_alloc(sizeof(*nvar), KM_SLEEP); 1181 1182 mutex_enter(&sc->l2tp_lock); 1183 ovar = sc->l2tp_var; 1184 *nvar = *ovar; 1185 psref_target_init(&nvar->lv_psref, lv_psref_class); 1186 nvar->lv_my_sess_id = my_sess_id; 1187 nvar->lv_peer_sess_id = peer_sess_id; 1188 1189 mutex_enter(&l2tp_hash.lock); 1190 if (ovar->lv_my_sess_id > 0 && ovar->lv_peer_sess_id > 0) { 1191 PSLIST_WRITER_REMOVE(sc, l2tp_hash); 1192 pserialize_perform(l2tp_psz); 1193 } 1194 mutex_exit(&l2tp_hash.lock); 1195 PSLIST_ENTRY_DESTROY(sc, l2tp_hash); 1196 1197 l2tp_variant_update(sc, nvar); 1198 mutex_exit(&sc->l2tp_lock); 1199 1200 idx = id_hash_func(nvar->lv_my_sess_id, l2tp_hash.mask); 1201 if ((ifp->if_flags & IFF_DEBUG) != 0) 1202 log(LOG_DEBUG, "%s: add hash entry: sess_id=%" PRIu32 ", idx=%" PRIu32 "\n", 1203 sc->l2tp_ec.ec_if.if_xname, nvar->lv_my_sess_id, idx); 1204 1205 PSLIST_ENTRY_INIT(sc, l2tp_hash); 1206 mutex_enter(&l2tp_hash.lock); 1207 PSLIST_WRITER_INSERT_HEAD(&l2tp_hash.lists[idx], sc, l2tp_hash); 1208 mutex_exit(&l2tp_hash.lock); 1209 1210 kmem_free(ovar, sizeof(*ovar)); 1211 return 0; 1212 } 1213 1214 static int 1215 l2tp_clear_session(struct l2tp_softc *sc) 1216 { 1217 struct l2tp_variant *nvar; 1218 struct l2tp_variant *ovar; 1219 1220 nvar = kmem_alloc(sizeof(*nvar), KM_SLEEP); 1221 1222 mutex_enter(&sc->l2tp_lock); 1223 ovar = sc->l2tp_var; 1224 *nvar = *ovar; 1225 psref_target_init(&nvar->lv_psref, lv_psref_class); 1226 nvar->lv_my_sess_id = 0; 1227 nvar->lv_peer_sess_id = 0; 1228 1229 mutex_enter(&l2tp_hash.lock); 1230 if (ovar->lv_my_sess_id > 0 && ovar->lv_peer_sess_id > 0) { 1231 PSLIST_WRITER_REMOVE(sc, l2tp_hash); 1232 pserialize_perform(l2tp_psz); 1233 } 1234 mutex_exit(&l2tp_hash.lock); 1235 1236 l2tp_variant_update(sc, nvar); 1237 mutex_exit(&sc->l2tp_lock); 1238 kmem_free(ovar, sizeof(*ovar)); 1239 return 0; 1240 } 1241 1242 struct l2tp_variant * 1243 l2tp_lookup_session_ref(uint32_t id, struct psref *psref) 1244 { 1245 int idx; 1246 int s; 1247 struct l2tp_softc *sc; 1248 1249 idx = id_hash_func(id, l2tp_hash.mask); 1250 1251 s = pserialize_read_enter(); 1252 PSLIST_READER_FOREACH(sc, &l2tp_hash.lists[idx], struct l2tp_softc, 1253 l2tp_hash) { 1254 struct l2tp_variant *var = atomic_load_consume(&sc->l2tp_var); 1255 if (var == NULL) 1256 continue; 1257 if (var->lv_my_sess_id != id) 1258 continue; 1259 psref_acquire(psref, &var->lv_psref, lv_psref_class); 1260 pserialize_read_exit(s); 1261 return var; 1262 } 1263 pserialize_read_exit(s); 1264 return NULL; 1265 } 1266 1267 /* 1268 * l2tp_variant update API. 1269 * 1270 * Assumption: 1271 * reader side dereferences sc->l2tp_var in reader critical section only, 1272 * that is, all of reader sides do not reader the sc->l2tp_var after 1273 * pserialize_perform(). 1274 */ 1275 static void 1276 l2tp_variant_update(struct l2tp_softc *sc, struct l2tp_variant *nvar) 1277 { 1278 struct ifnet *ifp = &sc->l2tp_ec.ec_if; 1279 struct l2tp_variant *ovar = sc->l2tp_var; 1280 1281 KASSERT(mutex_owned(&sc->l2tp_lock)); 1282 1283 atomic_store_release(&sc->l2tp_var, nvar); 1284 pserialize_perform(sc->l2tp_psz); 1285 psref_target_destroy(&ovar->lv_psref, lv_psref_class); 1286 1287 if (nvar != NULL) { 1288 if (nvar->lv_psrc != NULL && nvar->lv_pdst != NULL) 1289 ifp->if_flags |= IFF_RUNNING; 1290 else 1291 ifp->if_flags &= ~IFF_RUNNING; 1292 } 1293 } 1294 1295 static int 1296 l2tp_set_cookie(struct l2tp_softc *sc, uint64_t my_cookie, u_int my_cookie_len, 1297 uint64_t peer_cookie, u_int peer_cookie_len) 1298 { 1299 struct l2tp_variant *nvar; 1300 1301 if (my_cookie == 0 || peer_cookie == 0) 1302 return EINVAL; 1303 1304 if (my_cookie_len != 4 && my_cookie_len != 8) 1305 return EINVAL; 1306 if (peer_cookie_len != 4 && peer_cookie_len != 8) 1307 return EINVAL; 1308 1309 nvar = kmem_alloc(sizeof(*nvar), KM_SLEEP); 1310 1311 mutex_enter(&sc->l2tp_lock); 1312 1313 *nvar = *sc->l2tp_var; 1314 psref_target_init(&nvar->lv_psref, lv_psref_class); 1315 nvar->lv_my_cookie = my_cookie; 1316 nvar->lv_my_cookie_len = my_cookie_len; 1317 nvar->lv_peer_cookie = peer_cookie; 1318 nvar->lv_peer_cookie_len = peer_cookie_len; 1319 nvar->lv_use_cookie = L2TP_COOKIE_ON; 1320 l2tp_variant_update(sc, nvar); 1321 1322 mutex_exit(&sc->l2tp_lock); 1323 1324 struct ifnet *ifp = &sc->l2tp_ec.ec_if; 1325 if ((ifp->if_flags & IFF_DEBUG) != 0) { 1326 log(LOG_DEBUG, 1327 "%s: set cookie: " 1328 "local cookie_len=%u local cookie=%" PRIu64 ", " 1329 "remote cookie_len=%u remote cookie=%" PRIu64 "\n", 1330 ifp->if_xname, my_cookie_len, my_cookie, 1331 peer_cookie_len, peer_cookie); 1332 } 1333 1334 return 0; 1335 } 1336 1337 static void 1338 l2tp_clear_cookie(struct l2tp_softc *sc) 1339 { 1340 struct l2tp_variant *nvar; 1341 1342 nvar = kmem_alloc(sizeof(*nvar), KM_SLEEP); 1343 1344 mutex_enter(&sc->l2tp_lock); 1345 1346 *nvar = *sc->l2tp_var; 1347 psref_target_init(&nvar->lv_psref, lv_psref_class); 1348 nvar->lv_my_cookie = 0; 1349 nvar->lv_my_cookie_len = 0; 1350 nvar->lv_peer_cookie = 0; 1351 nvar->lv_peer_cookie_len = 0; 1352 nvar->lv_use_cookie = L2TP_COOKIE_OFF; 1353 l2tp_variant_update(sc, nvar); 1354 1355 mutex_exit(&sc->l2tp_lock); 1356 } 1357 1358 static void 1359 l2tp_set_state(struct l2tp_softc *sc, int state) 1360 { 1361 struct ifnet *ifp = &sc->l2tp_ec.ec_if; 1362 struct l2tp_variant *nvar; 1363 int ostate; 1364 1365 nvar = kmem_alloc(sizeof(*nvar), KM_SLEEP); 1366 1367 mutex_enter(&sc->l2tp_lock); 1368 1369 *nvar = *sc->l2tp_var; 1370 psref_target_init(&nvar->lv_psref, lv_psref_class); 1371 ostate = nvar->lv_state; 1372 nvar->lv_state = state; 1373 l2tp_variant_update(sc, nvar); 1374 mutex_exit(&sc->l2tp_lock); 1375 1376 if (ostate != state) { 1377 int lstate; 1378 1379 if (state == L2TP_STATE_UP) 1380 lstate = LINK_STATE_UP; 1381 else 1382 lstate = LINK_STATE_DOWN; 1383 1384 if_link_state_change(ifp, lstate); 1385 } 1386 1387 #ifdef NOTYET 1388 vlan_linkstate_notify(ifp, ifp->if_link_state); 1389 #endif 1390 } 1391 1392 static int 1393 l2tp_encap_attach(struct l2tp_variant *var) 1394 { 1395 int error; 1396 1397 if (var == NULL || var->lv_psrc == NULL) 1398 return EINVAL; 1399 1400 switch (var->lv_psrc->sa_family) { 1401 #ifdef INET 1402 case AF_INET: 1403 error = in_l2tp_attach(var); 1404 break; 1405 #endif 1406 #ifdef INET6 1407 case AF_INET6: 1408 error = in6_l2tp_attach(var); 1409 break; 1410 #endif 1411 default: 1412 error = EINVAL; 1413 break; 1414 } 1415 1416 return error; 1417 } 1418 1419 static int 1420 l2tp_encap_detach(struct l2tp_variant *var) 1421 { 1422 int error; 1423 1424 if (var == NULL || var->lv_psrc == NULL) 1425 return EINVAL; 1426 1427 switch (var->lv_psrc->sa_family) { 1428 #ifdef INET 1429 case AF_INET: 1430 error = in_l2tp_detach(var); 1431 break; 1432 #endif 1433 #ifdef INET6 1434 case AF_INET6: 1435 error = in6_l2tp_detach(var); 1436 break; 1437 #endif 1438 default: 1439 error = EINVAL; 1440 break; 1441 } 1442 1443 return error; 1444 } 1445 1446 int 1447 l2tp_check_nesting(struct ifnet *ifp, struct mbuf *m) 1448 { 1449 1450 return if_tunnel_check_nesting(ifp, m, max_l2tp_nesting); 1451 } 1452 1453 /* 1454 * Module infrastructure 1455 */ 1456 #include "if_module.h" 1457 1458 IF_MODULE(MODULE_CLASS_DRIVER, l2tp, NULL) 1459 1460 1461 /* TODO: IP_TCPMSS support */ 1462 #ifdef IP_TCPMSS 1463 static int l2tp_need_tcpmss_clamp(struct ifnet *); 1464 #ifdef INET 1465 static struct mbuf *l2tp_tcpmss4_clamp(struct ifnet *, struct mbuf *); 1466 #endif 1467 #ifdef INET6 1468 static struct mbuf *l2tp_tcpmss6_clamp(struct ifnet *, struct mbuf *); 1469 #endif 1470 1471 struct mbuf * 1472 l2tp_tcpmss_clamp(struct ifnet *ifp, struct mbuf *m) 1473 { 1474 struct ether_header *eh; 1475 struct ether_vlan_header evh; 1476 1477 if (!l2tp_need_tcpmss_clamp(ifp)) { 1478 return m; 1479 } 1480 1481 if (m->m_pkthdr.len < sizeof(evh)) { 1482 m_freem(m); 1483 return NULL; 1484 } 1485 1486 /* save ether header */ 1487 m_copydata(m, 0, sizeof(evh), (void *)&evh); 1488 eh = (struct ether_header *)&evh; 1489 1490 switch (ntohs(eh->ether_type)) { 1491 case ETHERTYPE_VLAN: /* Ether + VLAN */ 1492 if (m->m_pkthdr.len <= sizeof(struct ether_vlan_header)) 1493 break; 1494 m_adj(m, sizeof(struct ether_vlan_header)); 1495 switch (ntohs(evh.evl_proto)) { 1496 #ifdef INET 1497 case ETHERTYPE_IP: /* Ether + VLAN + IPv4 */ 1498 m = l2tp_tcpmss4_clamp(ifp, m); 1499 if (m == NULL) 1500 return NULL; 1501 break; 1502 #endif /* INET */ 1503 #ifdef INET6 1504 case ETHERTYPE_IPV6: /* Ether + VLAN + IPv6 */ 1505 m = l2tp_tcpmss6_clamp(ifp, m); 1506 if (m == NULL) 1507 return NULL; 1508 break; 1509 #endif /* INET6 */ 1510 default: 1511 break; 1512 } 1513 1514 /* restore ether header */ 1515 M_PREPEND(m, sizeof(struct ether_vlan_header), 1516 M_DONTWAIT); 1517 if (m == NULL) 1518 return NULL; 1519 *mtod(m, struct ether_vlan_header *) = evh; 1520 break; 1521 1522 #ifdef INET 1523 case ETHERTYPE_IP: /* Ether + IPv4 */ 1524 if (m->m_pkthdr.len <= sizeof(struct ether_header)) 1525 break; 1526 m_adj(m, sizeof(struct ether_header)); 1527 m = l2tp_tcpmss4_clamp(ifp, m); 1528 if (m == NULL) 1529 return NULL; 1530 /* restore ether header */ 1531 M_PREPEND(m, sizeof(struct ether_header), M_DONTWAIT); 1532 if (m == NULL) 1533 return NULL; 1534 *mtod(m, struct ether_header *) = *eh; 1535 break; 1536 #endif /* INET */ 1537 1538 #ifdef INET6 1539 case ETHERTYPE_IPV6: /* Ether + IPv6 */ 1540 if (m->m_pkthdr.len <= sizeof(struct ether_header)) 1541 break; 1542 m_adj(m, sizeof(struct ether_header)); 1543 m = l2tp_tcpmss6_clamp(ifp, m); 1544 if (m == NULL) 1545 return NULL; 1546 /* restore ether header */ 1547 M_PREPEND(m, sizeof(struct ether_header), M_DONTWAIT); 1548 if (m == NULL) 1549 return NULL; 1550 *mtod(m, struct ether_header *) = *eh; 1551 break; 1552 #endif /* INET6 */ 1553 1554 default: 1555 break; 1556 } 1557 1558 return m; 1559 } 1560 1561 static int 1562 l2tp_need_tcpmss_clamp(struct ifnet *ifp) 1563 { 1564 int ret = 0; 1565 1566 #ifdef INET 1567 if (ifp->if_tcpmss != 0) 1568 ret = 1; 1569 #endif 1570 1571 #ifdef INET6 1572 if (ifp->if_tcpmss6 != 0) 1573 ret = 1; 1574 #endif 1575 1576 return ret; 1577 } 1578 1579 #ifdef INET 1580 static struct mbuf * 1581 l2tp_tcpmss4_clamp(struct ifnet *ifp, struct mbuf *m) 1582 { 1583 1584 if (ifp->if_tcpmss != 0) { 1585 return ip_tcpmss(m, (ifp->if_tcpmss < 0) ? 1586 ifp->if_mtu - IP_TCPMSS_EXTLEN : 1587 ifp->if_tcpmss); 1588 } 1589 return m; 1590 } 1591 #endif /* INET */ 1592 1593 #ifdef INET6 1594 static struct mbuf * 1595 l2tp_tcpmss6_clamp(struct ifnet *ifp, struct mbuf *m) 1596 { 1597 int ip6hdrlen; 1598 1599 if (ifp->if_tcpmss6 != 0 && 1600 ip6_tcpmss_applicable(m, &ip6hdrlen)) { 1601 return ip6_tcpmss(m, ip6hdrlen, 1602 (ifp->if_tcpmss6 < 0) ? 1603 ifp->if_mtu - IP6_TCPMSS_EXTLEN : 1604 ifp->if_tcpmss6); 1605 } 1606 return m; 1607 } 1608 #endif /* INET6 */ 1609 1610 #endif /* IP_TCPMSS */ 1611