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