1 /*        $NetBSD: if_l2tp.c,v 1.49 2023/11/02 09:43:46 yamaguchi 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.49 2023/11/02 09:43:46 yamaguchi 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 *
l2tp_ifq_percpu_getref(percpu_t * pc)155 l2tp_ifq_percpu_getref(percpu_t *pc)
156 {
157 
158           return *(struct ifqueue **)percpu_getref(pc);
159 }
160 
161 static inline void
l2tp_ifq_percpu_putref(percpu_t * pc)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
l2tpattach(int count)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
l2tpinit(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
l2tpdetach(void)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
l2tp_clone_create(struct if_clone * ifc,int unit)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
l2tpattach0(struct l2tp_softc * sc)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
l2tp_ifq_init_pc(void * p,void * arg __unused,struct cpu_info * ci __unused)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
l2tp_ifq_fini_pc(void * p,void * arg __unused,struct cpu_info * ci __unused)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
l2tp_clone_destroy(struct ifnet * ifp)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
l2tp_tx_enqueue(struct l2tp_variant * var,struct mbuf * m)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
l2tp_output(struct ifnet * ifp,struct mbuf * m,const struct sockaddr * dst,const struct rtentry * rt)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
l2tp_sendit(struct l2tp_variant * var,struct mbuf * m)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
l2tpintr(struct l2tp_variant * var)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
l2tpintr_softint(void * arg)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
l2tp_input(struct mbuf * m,struct ifnet * ifp)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
l2tp_start(struct ifnet * ifp)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
l2tp_transmit(struct ifnet * ifp,struct mbuf * m)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
l2tp_ioctl(struct ifnet * ifp,u_long cmd,void * data)695 l2tp_ioctl(struct ifnet *ifp, u_long cmd, void *data)
696 {
697           struct l2tp_softc *sc = container_of(ifp, struct l2tp_softc,
698               l2tp_ec.ec_if);
699           struct l2tp_variant *var, *var_tmp;
700           struct ifreq     *ifr = data;
701           int error = 0, size;
702           struct sockaddr *dst, *src;
703           struct l2tp_req l2tpr;
704           u_long mtu;
705           int bound;
706           struct psref psref;
707 
708           switch (cmd) {
709           case SIOCSIFADDR:
710                     ifp->if_flags |= IFF_UP;
711                     break;
712 
713           case SIOCSIFDSTADDR:
714                     break;
715 
716           case SIOCADDMULTI:
717           case SIOCDELMULTI:
718                     switch (ifr->ifr_addr.sa_family) {
719 #ifdef INET
720                     case AF_INET:       /* IP supports Multicast */
721                               break;
722 #endif /* INET */
723 #ifdef INET6
724                     case AF_INET6:      /* IP6 supports Multicast */
725                               break;
726 #endif /* INET6 */
727                     default:  /* Other protocols doesn't support Multicast */
728                               error = EAFNOSUPPORT;
729                               break;
730                     }
731                     break;
732 
733           case SIOCSIFMTU:
734                     mtu = ifr->ifr_mtu;
735                     if (mtu < L2TP_MTU_MIN || mtu > L2TP_MTU_MAX)
736                               return (EINVAL);
737                     ifp->if_mtu = mtu;
738                     break;
739 
740 #ifdef INET
741           case SIOCSIFPHYADDR:
742                     src = (struct sockaddr *)
743                               &(((struct in_aliasreq *)data)->ifra_addr);
744                     dst = (struct sockaddr *)
745                               &(((struct in_aliasreq *)data)->ifra_dstaddr);
746                     if (src->sa_family != AF_INET || dst->sa_family != AF_INET)
747                               return EAFNOSUPPORT;
748                     else if (src->sa_len != sizeof(struct sockaddr_in)
749                         || dst->sa_len != sizeof(struct sockaddr_in))
750                               return EINVAL;
751 
752                     error = l2tp_set_tunnel(&sc->l2tp_ec.ec_if, src, dst);
753                     break;
754 
755 #endif /* INET */
756 #ifdef INET6
757           case SIOCSIFPHYADDR_IN6:
758                     src = (struct sockaddr *)
759                               &(((struct in6_aliasreq *)data)->ifra_addr);
760                     dst = (struct sockaddr *)
761                               &(((struct in6_aliasreq *)data)->ifra_dstaddr);
762                     if (src->sa_family != AF_INET6 || dst->sa_family != AF_INET6)
763                               return EAFNOSUPPORT;
764                     else if (src->sa_len != sizeof(struct sockaddr_in6)
765                         || dst->sa_len != sizeof(struct sockaddr_in6))
766                               return EINVAL;
767 
768                     error = l2tp_set_tunnel(&sc->l2tp_ec.ec_if, src, dst);
769                     break;
770 
771 #endif /* INET6 */
772           case SIOCSLIFPHYADDR:
773                     src = (struct sockaddr *)
774                               &(((struct if_laddrreq *)data)->addr);
775                     dst = (struct sockaddr *)
776                               &(((struct if_laddrreq *)data)->dstaddr);
777                     if (src->sa_family != dst->sa_family)
778                               return EINVAL;
779                     else if (src->sa_family == AF_INET
780                         && src->sa_len != sizeof(struct sockaddr_in))
781                               return EINVAL;
782                     else if (src->sa_family == AF_INET6
783                         && src->sa_len != sizeof(struct sockaddr_in6))
784                               return EINVAL;
785                     else if (dst->sa_family == AF_INET
786                         && dst->sa_len != sizeof(struct sockaddr_in))
787                               return EINVAL;
788                     else if (dst->sa_family == AF_INET6
789                         && dst->sa_len != sizeof(struct sockaddr_in6))
790                               return EINVAL;
791 
792                     error = l2tp_set_tunnel(&sc->l2tp_ec.ec_if, src, dst);
793                     break;
794 
795           case SIOCDIFPHYADDR:
796                     l2tp_delete_tunnel(&sc->l2tp_ec.ec_if);
797                     break;
798 
799           case SIOCGIFPSRCADDR:
800 #ifdef INET6
801           case SIOCGIFPSRCADDR_IN6:
802 #endif /* INET6 */
803                     bound = curlwp_bind();
804                     var = l2tp_getref_variant(sc, &psref);
805                     if (var == NULL) {
806                               curlwp_bindx(bound);
807                               error = EADDRNOTAVAIL;
808                               goto bad;
809                     }
810                     if (var->lv_psrc == NULL) {
811                               l2tp_putref_variant(var, &psref);
812                               curlwp_bindx(bound);
813                               error = EADDRNOTAVAIL;
814                               goto bad;
815                     }
816                     src = var->lv_psrc;
817                     switch (cmd) {
818 #ifdef INET
819                     case SIOCGIFPSRCADDR:
820                               dst = &ifr->ifr_addr;
821                               size = sizeof(ifr->ifr_addr);
822                               break;
823 #endif /* INET */
824 #ifdef INET6
825                     case SIOCGIFPSRCADDR_IN6:
826                               dst = (struct sockaddr *)
827                                         &(((struct in6_ifreq *)data)->ifr_addr);
828                               size = sizeof(((struct in6_ifreq *)data)->ifr_addr);
829                               break;
830 #endif /* INET6 */
831                     default:
832                               l2tp_putref_variant(var, &psref);
833                               curlwp_bindx(bound);
834                               error = EADDRNOTAVAIL;
835                               goto bad;
836                     }
837                     if (src->sa_len > size) {
838                               l2tp_putref_variant(var, &psref);
839                               curlwp_bindx(bound);
840                               return EINVAL;
841                     }
842                     sockaddr_copy(dst, src->sa_len, src);
843                     l2tp_putref_variant(var, &psref);
844                     curlwp_bindx(bound);
845                     break;
846 
847           case SIOCGIFPDSTADDR:
848 #ifdef INET6
849           case SIOCGIFPDSTADDR_IN6:
850 #endif /* INET6 */
851                     bound = curlwp_bind();
852                     var = l2tp_getref_variant(sc, &psref);
853                     if (var == NULL) {
854                               curlwp_bindx(bound);
855                               error = EADDRNOTAVAIL;
856                               goto bad;
857                     }
858                     if (var->lv_pdst == NULL) {
859                               l2tp_putref_variant(var, &psref);
860                               curlwp_bindx(bound);
861                               error = EADDRNOTAVAIL;
862                               goto bad;
863                     }
864                     src = var->lv_pdst;
865                     switch (cmd) {
866 #ifdef INET
867                     case SIOCGIFPDSTADDR:
868                               dst = &ifr->ifr_addr;
869                               size = sizeof(ifr->ifr_addr);
870                               break;
871 #endif /* INET */
872 #ifdef INET6
873                     case SIOCGIFPDSTADDR_IN6:
874                               dst = (struct sockaddr *)
875                                         &(((struct in6_ifreq *)data)->ifr_addr);
876                               size = sizeof(((struct in6_ifreq *)data)->ifr_addr);
877                               break;
878 #endif /* INET6 */
879                     default:
880                               l2tp_putref_variant(var, &psref);
881                               curlwp_bindx(bound);
882                               error = EADDRNOTAVAIL;
883                               goto bad;
884                     }
885                     if (src->sa_len > size) {
886                               l2tp_putref_variant(var, &psref);
887                               curlwp_bindx(bound);
888                               return EINVAL;
889                     }
890                     sockaddr_copy(dst, src->sa_len, src);
891                     l2tp_putref_variant(var, &psref);
892                     curlwp_bindx(bound);
893                     break;
894 
895           case SIOCGLIFPHYADDR:
896                     bound = curlwp_bind();
897                     var = l2tp_getref_variant(sc, &psref);
898                     if (var == NULL) {
899                               curlwp_bindx(bound);
900                               error = EADDRNOTAVAIL;
901                               goto bad;
902                     }
903                     if (var->lv_psrc == NULL || var->lv_pdst == NULL) {
904                               l2tp_putref_variant(var, &psref);
905                               curlwp_bindx(bound);
906                               error = EADDRNOTAVAIL;
907                               goto bad;
908                     }
909 
910                     /* copy src */
911                     src = var->lv_psrc;
912                     dst = (struct sockaddr *)
913                               &(((struct if_laddrreq *)data)->addr);
914                     size = sizeof(((struct if_laddrreq *)data)->addr);
915                     if (src->sa_len > size) {
916                               l2tp_putref_variant(var, &psref);
917                               curlwp_bindx(bound);
918                               return EINVAL;
919                 }
920                     sockaddr_copy(dst, src->sa_len, src);
921 
922                     /* copy dst */
923                     src = var->lv_pdst;
924                     dst = (struct sockaddr *)
925                               &(((struct if_laddrreq *)data)->dstaddr);
926                     size = sizeof(((struct if_laddrreq *)data)->dstaddr);
927                     if (src->sa_len > size) {
928                               l2tp_putref_variant(var, &psref);
929                               curlwp_bindx(bound);
930                               return EINVAL;
931                 }
932                     sockaddr_copy(dst, src->sa_len, src);
933                     l2tp_putref_variant(var, &psref);
934                     curlwp_bindx(bound);
935                     break;
936 
937           case SIOCSL2TPSESSION:
938                     if ((error = copyin(ifr->ifr_data, &l2tpr, sizeof(l2tpr))) != 0)
939                               break;
940 
941                     /* session id must not zero */
942                     if (l2tpr.my_sess_id == 0 || l2tpr.peer_sess_id == 0)
943                               return EINVAL;
944 
945                     bound = curlwp_bind();
946                     var_tmp = l2tp_lookup_session_ref(l2tpr.my_sess_id, &psref);
947                     if (var_tmp != NULL) {
948                               /* duplicate session id */
949                               log(LOG_WARNING, "%s: duplicate session id %" PRIu32 " of %s\n",
950                                         sc->l2tp_ec.ec_if.if_xname, l2tpr.my_sess_id,
951                                         var_tmp->lv_softc->l2tp_ec.ec_if.if_xname);
952                               psref_release(&psref, &var_tmp->lv_psref,
953                                   lv_psref_class);
954                               curlwp_bindx(bound);
955                               return EINVAL;
956                     }
957                     curlwp_bindx(bound);
958 
959                     error = l2tp_set_session(sc, l2tpr.my_sess_id, l2tpr.peer_sess_id);
960                     break;
961           case SIOCDL2TPSESSION:
962                     l2tp_clear_session(sc);
963                     break;
964           case SIOCSL2TPCOOKIE:
965                     if ((error = copyin(ifr->ifr_data, &l2tpr, sizeof(l2tpr))) != 0)
966                               break;
967 
968                     error = l2tp_set_cookie(sc, l2tpr.my_cookie, l2tpr.my_cookie_len,
969                         l2tpr.peer_cookie, l2tpr.peer_cookie_len);
970                     break;
971           case SIOCDL2TPCOOKIE:
972                     l2tp_clear_cookie(sc);
973                     break;
974           case SIOCSL2TPSTATE:
975                     if ((error = copyin(ifr->ifr_data, &l2tpr, sizeof(l2tpr))) != 0)
976                               break;
977 
978                     l2tp_set_state(sc, l2tpr.state);
979                     break;
980           case SIOCGL2TP:
981                     /* get L2TPV3 session info */
982                     memset(&l2tpr, 0, sizeof(l2tpr));
983 
984                     bound = curlwp_bind();
985                     var = l2tp_getref_variant(sc, &psref);
986                     if (var == NULL) {
987                               curlwp_bindx(bound);
988                               error = EADDRNOTAVAIL;
989                               goto bad;
990                     }
991 
992                     l2tpr.state = var->lv_state;
993                     l2tpr.my_sess_id = var->lv_my_sess_id;
994                     l2tpr.peer_sess_id = var->lv_peer_sess_id;
995                     l2tpr.my_cookie = var->lv_my_cookie;
996                     l2tpr.my_cookie_len = var->lv_my_cookie_len;
997                     l2tpr.peer_cookie = var->lv_peer_cookie;
998                     l2tpr.peer_cookie_len = var->lv_peer_cookie_len;
999                     l2tp_putref_variant(var, &psref);
1000                     curlwp_bindx(bound);
1001 
1002                     error = copyout(&l2tpr, ifr->ifr_data, sizeof(l2tpr));
1003                     break;
1004 
1005           default:
1006                     error =   ifioctl_common(ifp, cmd, data);
1007                     break;
1008           }
1009  bad:
1010           return error;
1011 }
1012 
1013 static int
l2tp_set_tunnel(struct ifnet * ifp,struct sockaddr * src,struct sockaddr * dst)1014 l2tp_set_tunnel(struct ifnet *ifp, struct sockaddr *src, struct sockaddr *dst)
1015 {
1016           struct l2tp_softc *sc = container_of(ifp, struct l2tp_softc,
1017               l2tp_ec.ec_if);
1018           struct sockaddr *osrc, *odst;
1019           struct sockaddr *nsrc, *ndst;
1020           struct l2tp_variant *ovar, *nvar;
1021           int error;
1022 
1023           nsrc = sockaddr_dup(src, M_WAITOK);
1024           ndst = sockaddr_dup(dst, M_WAITOK);
1025 
1026           nvar = kmem_alloc(sizeof(*nvar), KM_SLEEP);
1027 
1028           error = encap_lock_enter();
1029           if (error)
1030                     goto error;
1031 
1032           mutex_enter(&sc->l2tp_lock);
1033 
1034           ovar = sc->l2tp_var;
1035           osrc = ovar->lv_psrc;
1036           odst = ovar->lv_pdst;
1037           *nvar = *ovar;
1038           psref_target_init(&nvar->lv_psref, lv_psref_class);
1039           nvar->lv_psrc = nsrc;
1040           nvar->lv_pdst = ndst;
1041           error = l2tp_encap_attach(nvar);
1042           if (error) {
1043                     mutex_exit(&sc->l2tp_lock);
1044                     encap_lock_exit();
1045                     goto error;
1046           }
1047           l2tp_variant_update(sc, nvar);
1048 
1049           mutex_exit(&sc->l2tp_lock);
1050 
1051           (void)l2tp_encap_detach(ovar);
1052           encap_lock_exit();
1053 
1054           if (osrc)
1055                     sockaddr_free(osrc);
1056           if (odst)
1057                     sockaddr_free(odst);
1058           kmem_free(ovar, sizeof(*ovar));
1059           return 0;
1060 
1061 error:
1062           sockaddr_free(nsrc);
1063           sockaddr_free(ndst);
1064           kmem_free(nvar, sizeof(*nvar));
1065 
1066           return error;
1067 }
1068 
1069 static void
l2tp_delete_tunnel(struct ifnet * ifp)1070 l2tp_delete_tunnel(struct ifnet *ifp)
1071 {
1072           struct l2tp_softc *sc = container_of(ifp, struct l2tp_softc,
1073               l2tp_ec.ec_if);
1074           struct sockaddr *osrc, *odst;
1075           struct l2tp_variant *ovar, *nvar;
1076           int error;
1077 
1078           nvar = kmem_alloc(sizeof(*nvar), KM_SLEEP);
1079 
1080           error = encap_lock_enter();
1081           if (error) {
1082                     kmem_free(nvar, sizeof(*nvar));
1083                     return;
1084           }
1085           mutex_enter(&sc->l2tp_lock);
1086 
1087           ovar = sc->l2tp_var;
1088           osrc = ovar->lv_psrc;
1089           odst = ovar->lv_pdst;
1090           *nvar = *ovar;
1091           psref_target_init(&nvar->lv_psref, lv_psref_class);
1092           nvar->lv_psrc = NULL;
1093           nvar->lv_pdst = NULL;
1094           l2tp_variant_update(sc, nvar);
1095 
1096           mutex_exit(&sc->l2tp_lock);
1097 
1098           (void)l2tp_encap_detach(ovar);
1099           encap_lock_exit();
1100 
1101           if (osrc)
1102                     sockaddr_free(osrc);
1103           if (odst)
1104                     sockaddr_free(odst);
1105           kmem_free(ovar, sizeof(*ovar));
1106 }
1107 
1108 static int
id_hash_func(uint32_t id,u_long mask)1109 id_hash_func(uint32_t id, u_long mask)
1110 {
1111           uint32_t hash;
1112 
1113           hash = (id >> 16) ^ id;
1114           hash = (hash >> 4) ^ hash;
1115 
1116           return hash & mask;
1117 }
1118 
1119 static void
l2tp_hash_init(void)1120 l2tp_hash_init(void)
1121 {
1122 
1123           l2tp_hash.lists = hashinit(L2TP_ID_HASH_SIZE, HASH_PSLIST, true,
1124               &l2tp_hash.mask);
1125 }
1126 
1127 static int
l2tp_hash_fini(void)1128 l2tp_hash_fini(void)
1129 {
1130           int i;
1131 
1132           mutex_enter(&l2tp_hash.lock);
1133 
1134           for (i = 0; i < l2tp_hash.mask + 1; i++) {
1135                     if (PSLIST_WRITER_FIRST(&l2tp_hash.lists[i], struct l2tp_softc,
1136                               l2tp_hash) != NULL) {
1137                               mutex_exit(&l2tp_hash.lock);
1138                               return EBUSY;
1139                     }
1140           }
1141           for (i = 0; i < l2tp_hash.mask + 1; i++)
1142                     PSLIST_DESTROY(&l2tp_hash.lists[i]);
1143 
1144           mutex_exit(&l2tp_hash.lock);
1145 
1146           hashdone(l2tp_hash.lists, HASH_PSLIST, l2tp_hash.mask);
1147 
1148           return 0;
1149 }
1150 
1151 static int
l2tp_set_session(struct l2tp_softc * sc,uint32_t my_sess_id,uint32_t peer_sess_id)1152 l2tp_set_session(struct l2tp_softc *sc, uint32_t my_sess_id,
1153     uint32_t peer_sess_id)
1154 {
1155           uint32_t idx;
1156           struct l2tp_variant *nvar;
1157           struct l2tp_variant *ovar;
1158           struct ifnet *ifp = &sc->l2tp_ec.ec_if;
1159 
1160           nvar = kmem_alloc(sizeof(*nvar), KM_SLEEP);
1161 
1162           mutex_enter(&sc->l2tp_lock);
1163           ovar = sc->l2tp_var;
1164           *nvar = *ovar;
1165           psref_target_init(&nvar->lv_psref, lv_psref_class);
1166           nvar->lv_my_sess_id = my_sess_id;
1167           nvar->lv_peer_sess_id = peer_sess_id;
1168 
1169           mutex_enter(&l2tp_hash.lock);
1170           if (ovar->lv_my_sess_id > 0 && ovar->lv_peer_sess_id > 0) {
1171                     PSLIST_WRITER_REMOVE(sc, l2tp_hash);
1172                     pserialize_perform(l2tp_psz);
1173           }
1174           mutex_exit(&l2tp_hash.lock);
1175           PSLIST_ENTRY_DESTROY(sc, l2tp_hash);
1176 
1177           l2tp_variant_update(sc, nvar);
1178           mutex_exit(&sc->l2tp_lock);
1179 
1180           idx = id_hash_func(nvar->lv_my_sess_id, l2tp_hash.mask);
1181           if ((ifp->if_flags & IFF_DEBUG) != 0)
1182                     log(LOG_DEBUG, "%s: add hash entry: sess_id=%" PRIu32 ", idx=%" PRIu32 "\n",
1183                         sc->l2tp_ec.ec_if.if_xname, nvar->lv_my_sess_id, idx);
1184 
1185           PSLIST_ENTRY_INIT(sc, l2tp_hash);
1186           mutex_enter(&l2tp_hash.lock);
1187           PSLIST_WRITER_INSERT_HEAD(&l2tp_hash.lists[idx], sc, l2tp_hash);
1188           mutex_exit(&l2tp_hash.lock);
1189 
1190           kmem_free(ovar, sizeof(*ovar));
1191           return 0;
1192 }
1193 
1194 static int
l2tp_clear_session(struct l2tp_softc * sc)1195 l2tp_clear_session(struct l2tp_softc *sc)
1196 {
1197           struct l2tp_variant *nvar;
1198           struct l2tp_variant *ovar;
1199 
1200           nvar = kmem_alloc(sizeof(*nvar), KM_SLEEP);
1201 
1202           mutex_enter(&sc->l2tp_lock);
1203           ovar = sc->l2tp_var;
1204           *nvar = *ovar;
1205           psref_target_init(&nvar->lv_psref, lv_psref_class);
1206           nvar->lv_my_sess_id = 0;
1207           nvar->lv_peer_sess_id = 0;
1208 
1209           mutex_enter(&l2tp_hash.lock);
1210           if (ovar->lv_my_sess_id > 0 && ovar->lv_peer_sess_id > 0) {
1211                     PSLIST_WRITER_REMOVE(sc, l2tp_hash);
1212                     pserialize_perform(l2tp_psz);
1213           }
1214           mutex_exit(&l2tp_hash.lock);
1215 
1216           l2tp_variant_update(sc, nvar);
1217           mutex_exit(&sc->l2tp_lock);
1218           kmem_free(ovar, sizeof(*ovar));
1219           return 0;
1220 }
1221 
1222 struct l2tp_variant *
l2tp_lookup_session_ref(uint32_t id,struct psref * psref)1223 l2tp_lookup_session_ref(uint32_t id, struct psref *psref)
1224 {
1225           int idx;
1226           int s;
1227           struct l2tp_softc *sc;
1228 
1229           idx = id_hash_func(id, l2tp_hash.mask);
1230 
1231           s = pserialize_read_enter();
1232           PSLIST_READER_FOREACH(sc, &l2tp_hash.lists[idx], struct l2tp_softc,
1233               l2tp_hash) {
1234                     struct l2tp_variant *var = atomic_load_consume(&sc->l2tp_var);
1235                     if (var == NULL)
1236                               continue;
1237                     if (var->lv_my_sess_id != id)
1238                               continue;
1239                     psref_acquire(psref, &var->lv_psref, lv_psref_class);
1240                     pserialize_read_exit(s);
1241                     return var;
1242           }
1243           pserialize_read_exit(s);
1244           return NULL;
1245 }
1246 
1247 /*
1248  * l2tp_variant update API.
1249  *
1250  * Assumption:
1251  * reader side dereferences sc->l2tp_var in reader critical section only,
1252  * that is, all of reader sides do not reader the sc->l2tp_var after
1253  * pserialize_perform().
1254  */
1255 static void
l2tp_variant_update(struct l2tp_softc * sc,struct l2tp_variant * nvar)1256 l2tp_variant_update(struct l2tp_softc *sc, struct l2tp_variant *nvar)
1257 {
1258           struct ifnet *ifp = &sc->l2tp_ec.ec_if;
1259           struct l2tp_variant *ovar = sc->l2tp_var;
1260 
1261           KASSERT(mutex_owned(&sc->l2tp_lock));
1262 
1263           atomic_store_release(&sc->l2tp_var, nvar);
1264           pserialize_perform(sc->l2tp_psz);
1265           psref_target_destroy(&ovar->lv_psref, lv_psref_class);
1266 
1267           if (nvar != NULL) {
1268                     if (nvar->lv_psrc != NULL && nvar->lv_pdst != NULL)
1269                               ifp->if_flags |= IFF_RUNNING;
1270                     else
1271                               ifp->if_flags &= ~IFF_RUNNING;
1272           }
1273 }
1274 
1275 static int
l2tp_set_cookie(struct l2tp_softc * sc,uint64_t my_cookie,u_int my_cookie_len,uint64_t peer_cookie,u_int peer_cookie_len)1276 l2tp_set_cookie(struct l2tp_softc *sc, uint64_t my_cookie, u_int my_cookie_len,
1277     uint64_t peer_cookie, u_int peer_cookie_len)
1278 {
1279           struct l2tp_variant *nvar;
1280 
1281           if (my_cookie == 0 || peer_cookie == 0)
1282                     return EINVAL;
1283 
1284           if (my_cookie_len != 4 && my_cookie_len != 8
1285               && peer_cookie_len != 4 && peer_cookie_len != 8)
1286                     return EINVAL;
1287 
1288           nvar = kmem_alloc(sizeof(*nvar), KM_SLEEP);
1289 
1290           mutex_enter(&sc->l2tp_lock);
1291 
1292           *nvar = *sc->l2tp_var;
1293           psref_target_init(&nvar->lv_psref, lv_psref_class);
1294           nvar->lv_my_cookie = my_cookie;
1295           nvar->lv_my_cookie_len = my_cookie_len;
1296           nvar->lv_peer_cookie = peer_cookie;
1297           nvar->lv_peer_cookie_len = peer_cookie_len;
1298           nvar->lv_use_cookie = L2TP_COOKIE_ON;
1299           l2tp_variant_update(sc, nvar);
1300 
1301           mutex_exit(&sc->l2tp_lock);
1302 
1303           struct ifnet *ifp = &sc->l2tp_ec.ec_if;
1304           if ((ifp->if_flags & IFF_DEBUG) != 0) {
1305                     log(LOG_DEBUG,
1306                         "%s: set cookie: "
1307                         "local cookie_len=%u local cookie=%" PRIu64 ", "
1308                         "remote cookie_len=%u remote cookie=%" PRIu64 "\n",
1309                         ifp->if_xname, my_cookie_len, my_cookie,
1310                         peer_cookie_len, peer_cookie);
1311           }
1312 
1313           return 0;
1314 }
1315 
1316 static void
l2tp_clear_cookie(struct l2tp_softc * sc)1317 l2tp_clear_cookie(struct l2tp_softc *sc)
1318 {
1319           struct l2tp_variant *nvar;
1320 
1321           nvar = kmem_alloc(sizeof(*nvar), KM_SLEEP);
1322 
1323           mutex_enter(&sc->l2tp_lock);
1324 
1325           *nvar = *sc->l2tp_var;
1326           psref_target_init(&nvar->lv_psref, lv_psref_class);
1327           nvar->lv_my_cookie = 0;
1328           nvar->lv_my_cookie_len = 0;
1329           nvar->lv_peer_cookie = 0;
1330           nvar->lv_peer_cookie_len = 0;
1331           nvar->lv_use_cookie = L2TP_COOKIE_OFF;
1332           l2tp_variant_update(sc, nvar);
1333 
1334           mutex_exit(&sc->l2tp_lock);
1335 }
1336 
1337 static void
l2tp_set_state(struct l2tp_softc * sc,int state)1338 l2tp_set_state(struct l2tp_softc *sc, int state)
1339 {
1340           struct ifnet *ifp = &sc->l2tp_ec.ec_if;
1341           struct l2tp_variant *nvar;
1342           int ostate;
1343 
1344           nvar = kmem_alloc(sizeof(*nvar), KM_SLEEP);
1345 
1346           mutex_enter(&sc->l2tp_lock);
1347 
1348           *nvar = *sc->l2tp_var;
1349           psref_target_init(&nvar->lv_psref, lv_psref_class);
1350           ostate = nvar->lv_state;
1351           nvar->lv_state = state;
1352           l2tp_variant_update(sc, nvar);
1353           mutex_exit(&sc->l2tp_lock);
1354 
1355           if (ostate != state) {
1356                     int lstate;
1357 
1358                     if (state == L2TP_STATE_UP)
1359                               lstate = LINK_STATE_UP;
1360                     else
1361                               lstate = LINK_STATE_DOWN;
1362 
1363                     if_link_state_change(ifp, lstate);
1364           }
1365 
1366 #ifdef NOTYET
1367           vlan_linkstate_notify(ifp, ifp->if_link_state);
1368 #endif
1369 }
1370 
1371 static int
l2tp_encap_attach(struct l2tp_variant * var)1372 l2tp_encap_attach(struct l2tp_variant *var)
1373 {
1374           int error;
1375 
1376           if (var == NULL || var->lv_psrc == NULL)
1377                     return EINVAL;
1378 
1379           switch (var->lv_psrc->sa_family) {
1380 #ifdef INET
1381           case AF_INET:
1382                     error = in_l2tp_attach(var);
1383                     break;
1384 #endif
1385 #ifdef INET6
1386           case AF_INET6:
1387                     error = in6_l2tp_attach(var);
1388                     break;
1389 #endif
1390           default:
1391                     error = EINVAL;
1392                     break;
1393           }
1394 
1395           return error;
1396 }
1397 
1398 static int
l2tp_encap_detach(struct l2tp_variant * var)1399 l2tp_encap_detach(struct l2tp_variant *var)
1400 {
1401           int error;
1402 
1403           if (var == NULL || var->lv_psrc == NULL)
1404                     return EINVAL;
1405 
1406           switch (var->lv_psrc->sa_family) {
1407 #ifdef INET
1408           case AF_INET:
1409                     error = in_l2tp_detach(var);
1410                     break;
1411 #endif
1412 #ifdef INET6
1413           case AF_INET6:
1414                     error = in6_l2tp_detach(var);
1415                     break;
1416 #endif
1417           default:
1418                     error = EINVAL;
1419                     break;
1420           }
1421 
1422           return error;
1423 }
1424 
1425 int
l2tp_check_nesting(struct ifnet * ifp,struct mbuf * m)1426 l2tp_check_nesting(struct ifnet *ifp, struct mbuf *m)
1427 {
1428 
1429           return if_tunnel_check_nesting(ifp, m, max_l2tp_nesting);
1430 }
1431 
1432 /*
1433  * Module infrastructure
1434  */
1435 #include "if_module.h"
1436 
1437 IF_MODULE(MODULE_CLASS_DRIVER, l2tp, NULL)
1438 
1439 
1440 /* TODO: IP_TCPMSS support */
1441 #ifdef IP_TCPMSS
1442 static int l2tp_need_tcpmss_clamp(struct ifnet *);
1443 #ifdef INET
1444 static struct mbuf *l2tp_tcpmss4_clamp(struct ifnet *, struct mbuf *);
1445 #endif
1446 #ifdef INET6
1447 static struct mbuf *l2tp_tcpmss6_clamp(struct ifnet *, struct mbuf *);
1448 #endif
1449 
1450 struct mbuf *
l2tp_tcpmss_clamp(struct ifnet * ifp,struct mbuf * m)1451 l2tp_tcpmss_clamp(struct ifnet *ifp, struct mbuf *m)
1452 {
1453           struct ether_header *eh;
1454           struct ether_vlan_header evh;
1455 
1456           if (!l2tp_need_tcpmss_clamp(ifp)) {
1457                     return m;
1458           }
1459 
1460           if (m->m_pkthdr.len < sizeof(evh)) {
1461                     m_freem(m);
1462                     return NULL;
1463           }
1464 
1465           /* save ether header */
1466           m_copydata(m, 0, sizeof(evh), (void *)&evh);
1467           eh = (struct ether_header *)&evh;
1468 
1469           switch (ntohs(eh->ether_type)) {
1470           case ETHERTYPE_VLAN: /* Ether + VLAN */
1471                     if (m->m_pkthdr.len <= sizeof(struct ether_vlan_header))
1472                               break;
1473                     m_adj(m, sizeof(struct ether_vlan_header));
1474                     switch (ntohs(evh.evl_proto)) {
1475 #ifdef INET
1476                     case ETHERTYPE_IP: /* Ether + VLAN + IPv4 */
1477                               m = l2tp_tcpmss4_clamp(ifp, m);
1478                               if (m == NULL)
1479                                         return NULL;
1480                               break;
1481 #endif /* INET */
1482 #ifdef INET6
1483                     case ETHERTYPE_IPV6: /* Ether + VLAN + IPv6 */
1484                               m = l2tp_tcpmss6_clamp(ifp, m);
1485                               if (m == NULL)
1486                                         return NULL;
1487                               break;
1488 #endif /* INET6 */
1489                     default:
1490                               break;
1491                     }
1492 
1493                     /* restore ether header */
1494                     M_PREPEND(m, sizeof(struct ether_vlan_header),
1495                         M_DONTWAIT);
1496                     if (m == NULL)
1497                               return NULL;
1498                     *mtod(m, struct ether_vlan_header *) = evh;
1499                     break;
1500 
1501 #ifdef INET
1502           case ETHERTYPE_IP: /* Ether + IPv4 */
1503                     if (m->m_pkthdr.len <= sizeof(struct ether_header))
1504                               break;
1505                     m_adj(m, sizeof(struct ether_header));
1506                     m = l2tp_tcpmss4_clamp(ifp, m);
1507                     if (m == NULL)
1508                               return NULL;
1509                     /* restore ether header */
1510                     M_PREPEND(m, sizeof(struct ether_header), M_DONTWAIT);
1511                     if (m == NULL)
1512                               return NULL;
1513                     *mtod(m, struct ether_header *) = *eh;
1514                     break;
1515 #endif /* INET */
1516 
1517 #ifdef INET6
1518           case ETHERTYPE_IPV6: /* Ether + IPv6 */
1519                     if (m->m_pkthdr.len <= sizeof(struct ether_header))
1520                               break;
1521                     m_adj(m, sizeof(struct ether_header));
1522                     m = l2tp_tcpmss6_clamp(ifp, m);
1523                     if (m == NULL)
1524                               return NULL;
1525                     /* restore ether header */
1526                     M_PREPEND(m, sizeof(struct ether_header), M_DONTWAIT);
1527                     if (m == NULL)
1528                               return NULL;
1529                     *mtod(m, struct ether_header *) = *eh;
1530                     break;
1531 #endif /* INET6 */
1532 
1533           default:
1534                     break;
1535           }
1536 
1537           return m;
1538 }
1539 
1540 static int
l2tp_need_tcpmss_clamp(struct ifnet * ifp)1541 l2tp_need_tcpmss_clamp(struct ifnet *ifp)
1542 {
1543           int ret = 0;
1544 
1545 #ifdef INET
1546           if (ifp->if_tcpmss != 0)
1547                     ret = 1;
1548 #endif
1549 
1550 #ifdef INET6
1551           if (ifp->if_tcpmss6 != 0)
1552                     ret = 1;
1553 #endif
1554 
1555           return ret;
1556 }
1557 
1558 #ifdef INET
1559 static struct mbuf *
l2tp_tcpmss4_clamp(struct ifnet * ifp,struct mbuf * m)1560 l2tp_tcpmss4_clamp(struct ifnet *ifp, struct mbuf *m)
1561 {
1562 
1563           if (ifp->if_tcpmss != 0) {
1564                     return ip_tcpmss(m, (ifp->if_tcpmss < 0) ?
1565                               ifp->if_mtu - IP_TCPMSS_EXTLEN :
1566                               ifp->if_tcpmss);
1567           }
1568           return m;
1569 }
1570 #endif /* INET */
1571 
1572 #ifdef INET6
1573 static struct mbuf *
l2tp_tcpmss6_clamp(struct ifnet * ifp,struct mbuf * m)1574 l2tp_tcpmss6_clamp(struct ifnet *ifp, struct mbuf *m)
1575 {
1576           int ip6hdrlen;
1577 
1578           if (ifp->if_tcpmss6 != 0 &&
1579               ip6_tcpmss_applicable(m, &ip6hdrlen)) {
1580                     return ip6_tcpmss(m, ip6hdrlen,
1581                               (ifp->if_tcpmss6 < 0) ?
1582                               ifp->if_mtu - IP6_TCPMSS_EXTLEN :
1583                               ifp->if_tcpmss6);
1584           }
1585           return m;
1586 }
1587 #endif /* INET6 */
1588 
1589 #endif /* IP_TCPMSS */
1590