The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/net/if_pppoe.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* $NetBSD: if_pppoe.c,v 1.183 2022/08/15 08:28:41 knakahara Exp $ */
    2 
    3 /*
    4  * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Martin Husemann <martin@NetBSD.org>.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   29  * POSSIBILITY OF SUCH DAMAGE.
   30  */
   31 
   32 #include <sys/cdefs.h>
   33 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.183 2022/08/15 08:28:41 knakahara Exp $");
   34 
   35 #ifdef _KERNEL_OPT
   36 #include "pppoe.h"
   37 #include "opt_pppoe.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/atomic.h>
   45 #include <sys/callout.h>
   46 #include <sys/malloc.h>
   47 #include <sys/mbuf.h>
   48 #include <sys/socket.h>
   49 #include <sys/proc.h>
   50 #include <sys/ioctl.h>
   51 #include <sys/kauth.h>
   52 #include <sys/intr.h>
   53 #include <sys/socketvar.h>
   54 #include <sys/device.h>
   55 #include <sys/module.h>
   56 #include <sys/sysctl.h>
   57 #include <sys/rwlock.h>
   58 #include <sys/mutex.h>
   59 #include <sys/psref.h>
   60 #include <sys/cprng.h>
   61 #include <sys/workqueue.h>
   62 
   63 #include <net/if.h>
   64 #include <net/if_types.h>
   65 #include <net/if_ether.h>
   66 #include <net/if_sppp.h>
   67 #include <net/if_spppvar.h>
   68 #include <net/if_pppoe.h>
   69 #include <net/if_dl.h>
   70 
   71 #include <net/bpf.h>
   72 
   73 #include "ioconf.h"
   74 
   75 #ifdef NET_MPSAFE
   76 #define PPPOE_MPSAFE    1
   77 #endif
   78 
   79 #ifndef PPPOE_DEQUEUE_MAXLEN
   80 #define PPPOE_DEQUEUE_MAXLEN    IFQ_MAXLEN
   81 #endif
   82 
   83 struct pppoehdr {
   84         uint8_t vertype;
   85         uint8_t code;
   86         uint16_t session;
   87         uint16_t plen;
   88 } __packed;
   89 
   90 struct pppoetag {
   91         uint16_t tag;
   92         uint16_t len;
   93 } __packed;
   94 
   95 #define PPPOE_HEADERLEN sizeof(struct pppoehdr)
   96 #define PPPOE_OVERHEAD  (PPPOE_HEADERLEN + 2)
   97 #define PPPOE_VERTYPE   0x11    /* VER=1, TYPE = 1 */
   98 
   99 #define PPPOE_TAG_EOL           0x0000          /* end of list */
  100 #define PPPOE_TAG_SNAME         0x0101          /* service name */
  101 #define PPPOE_TAG_ACNAME        0x0102          /* access concentrator name */
  102 #define PPPOE_TAG_HUNIQUE       0x0103          /* host unique */
  103 #define PPPOE_TAG_ACCOOKIE      0x0104          /* AC cookie */
  104 #define PPPOE_TAG_VENDOR        0x0105          /* vendor specific */
  105 #define PPPOE_TAG_RELAYSID      0x0110          /* relay session id */
  106 #define PPPOE_TAG_MAX_PAYLOAD   0x0120          /* max payload */
  107 #define PPPOE_TAG_SNAME_ERR     0x0201          /* service name error */
  108 #define PPPOE_TAG_ACSYS_ERR     0x0202          /* AC system error */
  109 #define PPPOE_TAG_GENERIC_ERR   0x0203          /* generic error */
  110 
  111 #define PPPOE_CODE_PADI         0x09            /* Active Discovery Initiation */
  112 #define PPPOE_CODE_PADO         0x07            /* Active Discovery Offer */
  113 #define PPPOE_CODE_PADR         0x19            /* Active Discovery Request */
  114 #define PPPOE_CODE_PADS         0x65            /* Active Discovery Session confirmation */
  115 #define PPPOE_CODE_PADT         0xA7            /* Active Discovery Terminate */
  116 
  117 /* two byte PPP protocol discriminator, then IP data */
  118 #define PPPOE_MAXMTU    (ETHERMTU - PPPOE_OVERHEAD)
  119 
  120 /* Add a 16 bit unsigned value to a buffer pointed to by PTR */
  121 #define PPPOE_ADD_16(PTR, VAL)                  \
  122                 *(PTR)++ = (VAL) / 256;         \
  123                 *(PTR)++ = (VAL) % 256
  124 
  125 /* Add a complete PPPoE header to the buffer pointed to by PTR */
  126 #define PPPOE_ADD_HEADER(PTR, CODE, SESS, LEN)  \
  127                 *(PTR)++ = PPPOE_VERTYPE;       \
  128                 *(PTR)++ = (CODE);              \
  129                 PPPOE_ADD_16(PTR, SESS);        \
  130                 PPPOE_ADD_16(PTR, LEN)
  131 
  132 #define PPPOE_DISC_TIMEOUT      (hz*5)  /* base for quick timeout calculation */
  133 #define PPPOE_SLOW_RETRY        (hz*60) /* persistent retry interval */
  134 #define PPPOE_RECON_FAST        (hz*15) /* first retry after auth failure */
  135 #define PPPOE_RECON_IMMEDIATE   (hz/10) /* "no delay" reconnect */
  136 #define PPPOE_RECON_PADTRCVD    (hz*5)  /* reconnect delay after PADT received */
  137 #define PPPOE_DISC_MAXPADI      4       /* retry PADI four times (quickly) */
  138 #define PPPOE_DISC_MAXPADR      2       /* retry PADR twice */
  139 
  140 #ifdef PPPOE_SERVER
  141 /* from if_spppsubr.c */
  142 #define IFF_PASSIVE     IFF_LINK0       /* wait passively for connection */
  143 #endif
  144 
  145 #define PPPOE_LOCK(_sc, _op)    rw_enter(&(_sc)->sc_lock, (_op))
  146 #define PPPOE_UNLOCK(_sc)       rw_exit(&(_sc)->sc_lock)
  147 #define PPPOE_WLOCKED(_sc)      rw_write_held(&(_sc)->sc_lock)
  148 
  149 #ifdef PPPOE_MPSAFE
  150 #define DECLARE_SPLNET_VARIABLE
  151 #define ACQUIRE_SPLNET()        do { } while (0)
  152 #define RELEASE_SPLNET()        do { } while (0)
  153 #else
  154 #define DECLARE_SPLNET_VARIABLE int __s
  155 #define ACQUIRE_SPLNET()        do {                                    \
  156                                         __s = splnet();                 \
  157                                 } while (0)
  158 #define RELEASE_SPLNET()        do {                                    \
  159                                         splx(__s);                      \
  160                                 } while (0)
  161 #endif
  162 
  163 #ifdef PPPOE_DEBUG
  164 #define DPRINTF(_sc, _fmt, _arg...)     pppoe_printf((_sc), (_fmt), ##_arg)
  165 #else
  166 #define DPRINTF(_sc, _fmt, _arg...)     __nothing
  167 #endif
  168 
  169 struct pppoe_softc {
  170         struct sppp sc_sppp;            /* contains a struct ifnet as first element */
  171         LIST_ENTRY(pppoe_softc) sc_list;
  172         struct ifnet *sc_eth_if;        /* ethernet interface we are using */
  173 
  174         uint64_t sc_id;                 /* id of this softc, our hunique */
  175         int sc_state;                   /* discovery phase or session connected */
  176         struct ether_addr sc_dest;      /* hardware address of concentrator */
  177         uint16_t sc_session;            /* PPPoE session id */
  178 
  179         char *sc_service_name;          /* if != NULL: requested name of service */
  180         char *sc_concentrator_name;     /* if != NULL: requested concentrator id */
  181         uint8_t *sc_ac_cookie;          /* content of AC cookie we must echo back */
  182         size_t sc_ac_cookie_len;        /* length of cookie data */
  183         uint8_t *sc_relay_sid;          /* content of relay SID we must echo back */
  184         size_t sc_relay_sid_len;        /* length of relay SID data */
  185 #ifdef PPPOE_SERVER
  186         uint8_t *sc_hunique;            /* content of host unique we must echo back */
  187         size_t sc_hunique_len;          /* length of host unique */
  188 #endif
  189         callout_t sc_timeout;           /* timeout while not in session state */
  190         struct workqueue *sc_timeout_wq;        /* workqueue for timeout */
  191         struct work sc_timeout_wk;
  192         u_int sc_timeout_scheduled;
  193         int sc_padi_retried;            /* number of PADI retries already done */
  194         int sc_padr_retried;            /* number of PADR retries already done */
  195         krwlock_t sc_lock;      /* lock of sc_state, sc_session, and sc_eth_if */
  196         bool sc_detaching;
  197 };
  198 
  199 /* incoming traffic will be queued here */
  200 struct ifqueue ppoediscinq = { .ifq_maxlen = IFQ_MAXLEN };
  201 struct ifqueue ppoeinq = { .ifq_maxlen = IFQ_MAXLEN };
  202 
  203 void *pppoe_softintr = NULL;
  204 static void pppoe_softintr_handler(void *);
  205 
  206 extern int sppp_ioctl(struct ifnet *, unsigned long, void *);
  207 
  208 /* input routines */
  209 static void pppoeintr(void);
  210 static void pppoe_disc_input(struct mbuf *);
  211 static void pppoe_dispatch_disc_pkt(struct mbuf *, int);
  212 static void pppoe_data_input(struct mbuf *);
  213 static void pppoe_enqueue(struct ifqueue *, struct mbuf *);
  214 
  215 /* management routines */
  216 static int pppoe_connect(struct pppoe_softc *);
  217 static int pppoe_disconnect(struct pppoe_softc *);
  218 static void pppoe_abort_connect(struct pppoe_softc *);
  219 static int pppoe_ioctl(struct ifnet *, unsigned long, void *);
  220 static void pppoe_tls(struct sppp *);
  221 static void pppoe_tlf(struct sppp *);
  222 static void pppoe_start(struct ifnet *);
  223 #ifdef PPPOE_MPSAFE
  224 static int pppoe_transmit(struct ifnet *, struct mbuf *);
  225 #endif
  226 static void pppoe_clear_softc(struct pppoe_softc *, const char *);
  227 static void pppoe_printf(struct pppoe_softc *, const char *, ...);
  228 
  229 /* internal timeout handling */
  230 static void pppoe_timeout_co(void *);
  231 static void pppoe_timeout_co_halt(void *);
  232 static void pppoe_timeout_wk(struct work *, void *);
  233 static void pppoe_timeout(struct pppoe_softc *);
  234 
  235 /* sending actual protocol control packets */
  236 static int pppoe_send_padi(struct pppoe_softc *);
  237 static int pppoe_send_padr(struct pppoe_softc *);
  238 #ifdef PPPOE_SERVER
  239 static int pppoe_send_pado(struct pppoe_softc *);
  240 static int pppoe_send_pads(struct pppoe_softc *);
  241 #endif
  242 static int pppoe_send_padt(struct ifnet *, u_int, const uint8_t *);
  243 
  244 /* raw output */
  245 static int pppoe_output(struct pppoe_softc *, struct mbuf *);
  246 
  247 /* internal helper functions */
  248 static struct pppoe_softc * pppoe_find_softc_by_session(u_int, struct ifnet *,
  249     krw_t);
  250 static struct pppoe_softc * pppoe_find_softc_by_hunique(uint8_t *, size_t,
  251     struct ifnet *, krw_t);
  252 static struct mbuf *pppoe_get_mbuf(size_t len);
  253 
  254 static void pppoe_ifattach_hook(void *, unsigned long, void *);
  255 
  256 static LIST_HEAD(pppoe_softc_head, pppoe_softc) pppoe_softc_list;
  257 static krwlock_t pppoe_softc_list_lock;
  258 
  259 static int      pppoe_clone_create(struct if_clone *, int);
  260 static int      pppoe_clone_destroy(struct ifnet *);
  261 
  262 static bool     pppoe_term_unknown = false;
  263 static int      pppoe_term_unknown_pps = 1;
  264 
  265 static struct sysctllog *pppoe_sysctl_clog;
  266 static void sysctl_net_pppoe_setup(struct sysctllog **);
  267 
  268 static struct if_clone pppoe_cloner =
  269     IF_CLONE_INITIALIZER("pppoe", pppoe_clone_create, pppoe_clone_destroy);
  270 
  271 /* ARGSUSED */
  272 void
  273 pppoeattach(int count)
  274 {
  275 
  276         /*
  277          * Nothing to do here, initialization is handled by the
  278          * module initialization code in pppoeinit() below).
  279          */
  280 }
  281 
  282 static void
  283 pppoeinit(void)
  284 {
  285 
  286         LIST_INIT(&pppoe_softc_list);
  287         rw_init(&pppoe_softc_list_lock);
  288         if_clone_attach(&pppoe_cloner);
  289 
  290         pppoe_softintr = softint_establish(SOFTINT_MPSAFE|SOFTINT_NET,
  291             pppoe_softintr_handler, NULL);
  292         sysctl_net_pppoe_setup(&pppoe_sysctl_clog);
  293 
  294         IFQ_LOCK_INIT(&ppoediscinq);
  295         IFQ_LOCK_INIT(&ppoeinq);
  296 }
  297 
  298 static int
  299 pppoedetach(void)
  300 {
  301         int error = 0;
  302 
  303         rw_enter(&pppoe_softc_list_lock, RW_READER);
  304         if (!LIST_EMPTY(&pppoe_softc_list)) {
  305                 rw_exit(&pppoe_softc_list_lock);
  306                 error = EBUSY;
  307         }
  308 
  309         if (error == 0) {
  310                 if_clone_detach(&pppoe_cloner);
  311                 softint_disestablish(pppoe_softintr);
  312                 /* Remove our sysctl sub-tree */
  313                 sysctl_teardown(&pppoe_sysctl_clog);
  314         }
  315 
  316         return error;
  317 }
  318 
  319 static void
  320 pppoe_softc_genid(uint64_t *id)
  321 {
  322         struct pppoe_softc *sc;
  323         uint64_t rndid;
  324 
  325         rw_enter(&pppoe_softc_list_lock, RW_READER);
  326 
  327         while (1) {
  328                 rndid = cprng_strong64();
  329 
  330                 sc = NULL;
  331                 LIST_FOREACH(sc, &pppoe_softc_list, sc_list) {
  332                         if (sc->sc_id == rndid)
  333                                 break;
  334                 }
  335                 if (sc == NULL) {
  336                         break;
  337                 }
  338         }
  339 
  340         rw_exit(&pppoe_softc_list_lock);
  341         *id = rndid;
  342 }
  343 
  344 static int
  345 pppoe_clone_create(struct if_clone *ifc, int unit)
  346 {
  347         struct pppoe_softc *sc;
  348         struct ifnet *ifp;
  349         int rv;
  350 
  351         sc = kmem_zalloc(sizeof(*sc), KM_SLEEP);
  352         ifp = &sc->sc_sppp.pp_if;
  353 
  354         rw_init(&sc->sc_lock);
  355         pppoe_softc_genid(&sc->sc_id);
  356         /* changed to real address later */
  357         memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest));
  358 
  359         if_initname(ifp, "pppoe", unit);
  360         ifp->if_softc = sc;
  361         ifp->if_mtu = PPPOE_MAXMTU;
  362         ifp->if_flags = IFF_SIMPLEX|IFF_POINTOPOINT|IFF_MULTICAST;
  363 #ifdef PPPOE_MPSAFE
  364         ifp->if_extflags = IFEF_MPSAFE;
  365 #endif
  366         ifp->if_type = IFT_PPP;
  367         ifp->if_hdrlen = sizeof(struct ether_header) + PPPOE_HEADERLEN;
  368         ifp->if_dlt = DLT_PPP_ETHER;
  369         ifp->if_ioctl = pppoe_ioctl;
  370         ifp->if_start = pppoe_start;
  371 #ifdef PPPOE_MPSAFE
  372         ifp->if_transmit = pppoe_transmit;
  373 #endif
  374         IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
  375         IFQ_SET_READY(&ifp->if_snd);
  376 
  377         sc->sc_sppp.pp_tls = pppoe_tls;
  378         sc->sc_sppp.pp_tlf = pppoe_tlf;
  379         sc->sc_sppp.pp_flags |= PP_KEEPALIVE |  /* use LCP keepalive */
  380                                 PP_NOFRAMING;   /* no serial encapsulation */
  381         sc->sc_sppp.pp_framebytes = PPPOE_HEADERLEN;    /* framing added to ppp packets */
  382 
  383         rv = workqueue_create(&sc->sc_timeout_wq,
  384             ifp->if_xname, pppoe_timeout_wk, sc,
  385             PRI_SOFTNET, IPL_SOFTNET, 0);
  386         if (rv != 0)
  387                 goto destroy_sclock;
  388 
  389         callout_init(&sc->sc_timeout, CALLOUT_MPSAFE);
  390         callout_setfunc(&sc->sc_timeout, pppoe_timeout_co, sc);
  391 
  392         if_initialize(ifp);
  393 
  394         ifp->if_percpuq = if_percpuq_create(ifp);
  395 
  396         rw_enter(&pppoe_softc_list_lock, RW_READER);
  397         if (LIST_EMPTY(&pppoe_softc_list)) {
  398                 pfil_add_ihook(pppoe_ifattach_hook, NULL, PFIL_IFNET, if_pfil);
  399         }
  400         LIST_INSERT_HEAD(&pppoe_softc_list, sc, sc_list);
  401         rw_exit(&pppoe_softc_list_lock);
  402 
  403         sppp_attach(ifp);
  404         bpf_attach(ifp, DLT_PPP_ETHER, 0);
  405         if_register(ifp);
  406 
  407         return 0;
  408 
  409 destroy_sclock:
  410         rw_destroy(&sc->sc_lock);
  411         kmem_free(sc, sizeof(*sc));
  412 
  413         return rv;
  414 }
  415 
  416 static int
  417 pppoe_clone_destroy(struct ifnet *ifp)
  418 {
  419         struct pppoe_softc * sc = ifp->if_softc;
  420 
  421         PPPOE_LOCK(sc, RW_WRITER);
  422         /* stop ioctls */
  423         sc->sc_detaching = true;
  424 
  425         if (ifp->if_flags & IFF_RUNNING) {
  426                 pppoe_clear_softc(sc, "destroy interface");
  427                 sc->sc_eth_if = NULL;
  428         }
  429         PPPOE_UNLOCK(sc);
  430 
  431         rw_enter(&pppoe_softc_list_lock, RW_WRITER);
  432         LIST_REMOVE(sc, sc_list);
  433 
  434         if (LIST_EMPTY(&pppoe_softc_list)) {
  435                 pfil_remove_ihook(pppoe_ifattach_hook, NULL, PFIL_IFNET, if_pfil);
  436         }
  437         rw_exit(&pppoe_softc_list_lock);
  438 
  439         bpf_detach(ifp);
  440         sppp_detach(&sc->sc_sppp.pp_if);
  441         if_detach(ifp);
  442 
  443         callout_setfunc(&sc->sc_timeout, pppoe_timeout_co_halt, sc);
  444 
  445         workqueue_wait(sc->sc_timeout_wq, &sc->sc_timeout_wk);
  446         workqueue_destroy(sc->sc_timeout_wq);
  447 
  448         callout_halt(&sc->sc_timeout, NULL);
  449         callout_destroy(&sc->sc_timeout);
  450 
  451 #ifdef PPPOE_SERVER
  452         if (sc->sc_hunique) {
  453                 free(sc->sc_hunique, M_DEVBUF);
  454                 sc->sc_hunique = NULL;
  455                 sc->sc_hunique_len = 0;
  456         }
  457 #endif
  458         if (sc->sc_concentrator_name)
  459                 free(sc->sc_concentrator_name, M_DEVBUF);
  460         if (sc->sc_service_name)
  461                 free(sc->sc_service_name, M_DEVBUF);
  462         if (sc->sc_ac_cookie)
  463                 free(sc->sc_ac_cookie, M_DEVBUF);
  464         if (sc->sc_relay_sid)
  465                 free(sc->sc_relay_sid, M_DEVBUF);
  466 
  467         rw_destroy(&sc->sc_lock);
  468 
  469         kmem_free(sc, sizeof(*sc));
  470 
  471         return 0;
  472 }
  473 
  474 static void
  475 pppoe_printf(struct pppoe_softc *sc, const char *fmt, ...)
  476 {
  477         va_list ap;
  478         bool pppoe_debug;
  479 
  480 #ifdef PPPOE_DEBUG
  481         pppoe_debug = true;
  482 #else
  483         pppoe_debug = false;
  484 #endif
  485 
  486         if (sc == NULL) {
  487                 if (!pppoe_debug)
  488                         return;
  489 
  490                 printf("pppoe: ");
  491         } else {
  492                 if (!ISSET(sc->sc_sppp.pp_if.if_flags, IFF_DEBUG))
  493                         return;
  494 
  495                 printf("%s: ", sc->sc_sppp.pp_if.if_xname);
  496         }
  497 
  498         va_start(ap, fmt);
  499         vprintf(fmt, ap);
  500         va_end(ap);
  501 }
  502 
  503 /*
  504  * Find the interface handling the specified session.
  505  * Note: O(number of sessions open), this is a client-side only, mean
  506  * and lean implementation, so number of open sessions typically should
  507  * be 1.
  508  */
  509 static struct pppoe_softc *
  510 pppoe_find_softc_by_session(u_int session, struct ifnet *rcvif, krw_t lock)
  511 {
  512         struct pppoe_softc *sc = NULL;
  513 
  514         if (session == 0)
  515                 return NULL;
  516         rw_enter(&pppoe_softc_list_lock, RW_READER);
  517         LIST_FOREACH(sc, &pppoe_softc_list, sc_list) {
  518                 PPPOE_LOCK(sc, lock);
  519                 if ( sc->sc_state == PPPOE_STATE_SESSION
  520                     && sc->sc_session == session
  521                     && sc->sc_eth_if == rcvif)
  522                         break;
  523 
  524                 PPPOE_UNLOCK(sc);
  525         }
  526         rw_exit(&pppoe_softc_list_lock);
  527         return sc;
  528 }
  529 
  530 /* Check host unique token passed and return appropriate softc pointer,
  531  * or NULL if token is bogus. */
  532 static struct pppoe_softc *
  533 pppoe_find_softc_by_hunique(uint8_t *token, size_t len,
  534     struct ifnet *rcvif, krw_t lock)
  535 {
  536         struct pppoe_softc *sc;
  537         uint64_t t;
  538 
  539         CTASSERT(sizeof(t) == sizeof(sc->sc_id));
  540 
  541         rw_enter(&pppoe_softc_list_lock, RW_READER);
  542         if (LIST_EMPTY(&pppoe_softc_list)) {
  543                 rw_exit(&pppoe_softc_list_lock);
  544                 return NULL;
  545         }
  546 
  547         if (len != sizeof(sc->sc_id)) {
  548                 rw_exit(&pppoe_softc_list_lock);
  549                 return NULL;
  550         }
  551         memcpy(&t, token, len);
  552 
  553         LIST_FOREACH(sc, &pppoe_softc_list, sc_list) {
  554                 PPPOE_LOCK(sc, lock);
  555                 if (sc->sc_id == t && sc->sc_eth_if != NULL) {
  556                         break;
  557                 }
  558                 PPPOE_UNLOCK(sc);
  559         }
  560         rw_exit(&pppoe_softc_list_lock);
  561 
  562         if (sc == NULL) {
  563                 pppoe_printf(NULL, "alien host unique tag"
  564                     ", no session found\n");
  565                 return NULL;
  566         }
  567 
  568         /* should be safe to access *sc now */
  569         if (sc->sc_state < PPPOE_STATE_PADI_SENT || sc->sc_state >= PPPOE_STATE_SESSION) {
  570                 pppoe_printf(sc, "host unique tag found"
  571                     ", but it belongs to a connection in state %d\n",
  572                     sc->sc_state);
  573                 PPPOE_UNLOCK(sc);
  574                 return NULL;
  575         }
  576         if (sc->sc_eth_if != rcvif) {
  577                 pppoe_printf(sc, "wrong interface, not accepting host unique\n");
  578                 PPPOE_UNLOCK(sc);
  579                 return NULL;
  580         }
  581         return sc;
  582 }
  583 
  584 static void
  585 pppoe_softintr_handler(void *dummy)
  586 {
  587         /* called at splsoftnet() */
  588         pppoeintr();
  589 }
  590 
  591 /* called at appropriate protection level */
  592 static void
  593 pppoeintr(void)
  594 {
  595         struct mbuf *m;
  596         int i;
  597 
  598         SOFTNET_LOCK_UNLESS_NET_MPSAFE();
  599 
  600         for (i = 0; i < PPPOE_DEQUEUE_MAXLEN; i++) {
  601                 IFQ_LOCK(&ppoediscinq);
  602                 IF_DEQUEUE(&ppoediscinq, m);
  603                 IFQ_UNLOCK(&ppoediscinq);
  604                 if (m == NULL)
  605                         break;
  606                 pppoe_disc_input(m);
  607         }
  608 
  609         for (i = 0; i < PPPOE_DEQUEUE_MAXLEN; i++) {
  610                 IFQ_LOCK(&ppoeinq);
  611                 IF_DEQUEUE(&ppoeinq, m);
  612                 IFQ_UNLOCK(&ppoeinq);
  613                 if (m == NULL)
  614                         break;
  615                 pppoe_data_input(m);
  616         }
  617 
  618 #if PPPOE_DEQUEUE_MAXLEN < IFQ_MAXLEN
  619         if (!IF_IS_EMPTY(&ppoediscinq) || !IF_IS_EMPTY(&ppoeinq))
  620                 softint_schedule(pppoe_softintr);
  621 #endif
  622 
  623         SOFTNET_UNLOCK_UNLESS_NET_MPSAFE();
  624 }
  625 
  626 /* analyze and handle a single received packet while not in session state */
  627 static void
  628 pppoe_dispatch_disc_pkt(struct mbuf *m, int off)
  629 {
  630         uint16_t tag, len;
  631         uint16_t session, plen;
  632         struct pppoe_softc *sc;
  633         const char *err_msg;
  634         char *error;
  635         size_t dlen;
  636         uint8_t *ac_cookie;
  637         size_t ac_cookie_len;
  638         uint8_t *relay_sid;
  639         size_t relay_sid_len;
  640         uint8_t *hunique;
  641         size_t hunique_len;
  642         struct pppoehdr *ph;
  643         struct pppoetag *pt;
  644         struct mbuf *n;
  645         int noff, err, errortag;
  646         struct ether_header *eh;
  647         struct ifnet *rcvif;
  648         struct psref psref;
  649 
  650         if (m->m_len < sizeof(*eh)) {
  651                 m = m_pullup(m, sizeof(*eh));
  652                 if (m == NULL)
  653                         goto done;
  654         }
  655         eh = mtod(m, struct ether_header *);
  656         off += sizeof(*eh);
  657 
  658         if (m->m_pkthdr.len - off < PPPOE_HEADERLEN) {
  659                 goto done;
  660         }
  661 
  662         M_REGION_GET(ph, struct pppoehdr *, m, off, sizeof(*ph));
  663         if (ph == NULL) {
  664                 goto done;
  665         }
  666         if (ph->vertype != PPPOE_VERTYPE) {
  667                 goto done;
  668         }
  669 
  670         ac_cookie = NULL;
  671         ac_cookie_len = 0;
  672         relay_sid = NULL;
  673         relay_sid_len = 0;
  674         hunique = NULL;
  675         hunique_len = 0;
  676 
  677         session = ntohs(ph->session);
  678         plen = ntohs(ph->plen);
  679         off += sizeof(*ph);
  680 
  681         if (plen + off > m->m_pkthdr.len) {
  682                 goto done;
  683         }
  684         m_adj(m, off + plen - m->m_pkthdr.len); /* ignore trailing garbage */
  685 
  686         tag = 0;
  687         len = 0;
  688         sc = NULL;
  689         err_msg = NULL;
  690         errortag = 0;
  691         while (off + sizeof(*pt) <= m->m_pkthdr.len) {
  692                 M_REGION_GET(pt, struct pppoetag *, m, off, sizeof(*pt));
  693                 if (pt == NULL) {
  694                         goto done;
  695                 }
  696 
  697                 tag = ntohs(pt->tag);
  698                 len = ntohs(pt->len);
  699                 if (off + len + sizeof(*pt) > m->m_pkthdr.len) {
  700                         goto done;
  701                 }
  702                 switch (tag) {
  703                 case PPPOE_TAG_EOL:
  704                         goto breakbreak;
  705                 case PPPOE_TAG_SNAME:
  706                         break;  /* ignored */
  707                 case PPPOE_TAG_ACNAME:
  708                         if (len > 0) {
  709                                 dlen = 4 * len + 1;
  710                                 error = malloc(dlen, M_TEMP, M_NOWAIT);
  711                                 if (error == NULL)
  712                                         break;
  713 
  714                                 n = m_pulldown(m, off + sizeof(*pt), len,
  715                                     &noff);
  716                                 if (!n) {
  717                                         m = NULL;
  718                                         free(error, M_TEMP);
  719                                         goto done;
  720                                 }
  721 
  722                                 strnvisx(error, dlen,
  723                                     mtod(n, char*) + noff, len,
  724                                     VIS_SAFE | VIS_OCTAL);
  725                                 pppoe_printf(NULL, "connected to %s\n", error);
  726                                 free(error, M_TEMP);
  727                         }
  728                         break;  /* ignored */
  729                 case PPPOE_TAG_HUNIQUE:
  730                         if (hunique == NULL) {
  731                                 n = m_pulldown(m, off + sizeof(*pt), len,
  732                                     &noff);
  733                                 if (!n) {
  734                                         m = NULL;
  735                                         err_msg = "TAG HUNIQUE ERROR";
  736                                         break;
  737                                 }
  738 
  739                                 hunique = mtod(n, uint8_t *) + noff;
  740                                 hunique_len = len;
  741                         }
  742                         break;
  743                 case PPPOE_TAG_ACCOOKIE:
  744                         if (ac_cookie == NULL) {
  745                                 n = m_pulldown(m, off + sizeof(*pt), len,
  746                                     &noff);
  747                                 if (!n) {
  748                                         err_msg = "TAG ACCOOKIE ERROR";
  749                                         m = NULL;
  750                                         break;
  751                                 }
  752                                 ac_cookie = mtod(n, char *) + noff;
  753                                 ac_cookie_len = len;
  754                         }
  755                         break;
  756                 case PPPOE_TAG_RELAYSID:
  757                         if (relay_sid == NULL) {
  758                                 n = m_pulldown(m, off + sizeof(*pt), len,
  759                                     &noff);
  760                                 if (!n) {
  761                                         err_msg = "TAG RELAYSID ERROR";
  762                                         m = NULL;
  763                                         break;
  764                                 }
  765                                 relay_sid = mtod(n, char *) + noff;
  766                                 relay_sid_len = len;
  767                         }
  768                         break;
  769                 case PPPOE_TAG_SNAME_ERR:
  770                         err_msg = "SERVICE NAME ERROR";
  771                         errortag = 1;
  772                         break;
  773                 case PPPOE_TAG_ACSYS_ERR:
  774                         err_msg = "AC SYSTEM ERROR";
  775                         errortag = 1;
  776                         break;
  777                 case PPPOE_TAG_GENERIC_ERR:
  778                         err_msg = "GENERIC ERROR";
  779                         errortag = 1;
  780                         break;
  781                 }
  782                 if (err_msg) {
  783                         error = NULL;
  784                         if (errortag && len) {
  785                                 dlen = 4 * len + 1;
  786                                 error = malloc(dlen, M_TEMP,
  787                                     M_NOWAIT|M_ZERO);
  788                                 n = m_pulldown(m, off + sizeof(*pt), len,
  789                                     &noff);
  790                                 if (!n) {
  791                                         m = NULL;
  792                                 } else if (error) {
  793                                         strnvisx(error, dlen,
  794                                             mtod(n, char*) + noff, len,
  795                                             VIS_SAFE | VIS_OCTAL);
  796                                 }
  797                         }
  798                         if (error) {
  799                                 pppoe_printf(NULL, "%s: %s\n", err_msg, error);
  800                                 free(error, M_TEMP);
  801                         } else
  802                                 pppoe_printf(NULL, "%s\n", err_msg);
  803                         if (errortag || m == NULL)
  804                                 goto done;
  805                 }
  806                 off += sizeof(*pt) + len;
  807         }
  808 breakbreak:;
  809 
  810         switch (ph->code) {
  811         case PPPOE_CODE_PADI:
  812 #ifdef PPPOE_SERVER
  813                 /*
  814                  * got service name, concentrator name, and/or host unique.
  815                  * ignore if we have no interfaces with IFF_PASSIVE|IFF_UP.
  816                  */
  817                 rw_enter(&pppoe_softc_list_lock, RW_READER);
  818                 if (LIST_EMPTY(&pppoe_softc_list)) {
  819                         rw_exit(&pppoe_softc_list_lock);
  820                         goto done;
  821                 }
  822 
  823                 LIST_FOREACH(sc, &pppoe_softc_list, sc_list) {
  824                         PPPOE_LOCK(sc, RW_WRITER);
  825                         if (!(sc->sc_sppp.pp_if.if_flags & IFF_UP)) {
  826                                 PPPOE_UNLOCK(sc);
  827                                 continue;
  828                         }
  829                         if (!(sc->sc_sppp.pp_if.if_flags & IFF_PASSIVE)) {
  830                                 PPPOE_UNLOCK(sc);
  831                                 continue;
  832                         }
  833 
  834                         if (sc->sc_state == PPPOE_STATE_INITIAL)
  835                                 break;
  836 
  837                         PPPOE_UNLOCK(sc);
  838                 }
  839                 rw_exit(&pppoe_softc_list_lock);
  840 
  841                 if (sc == NULL) {
  842                         goto done;
  843                 }
  844 
  845                 if (hunique) {
  846                         if (sc->sc_hunique)
  847                                 free(sc->sc_hunique, M_DEVBUF);
  848                         sc->sc_hunique = malloc(hunique_len, M_DEVBUF,
  849                             M_DONTWAIT);
  850                         if (sc->sc_hunique == NULL) {
  851                                 PPPOE_UNLOCK(sc);
  852                                 goto done;
  853                         }
  854                         sc->sc_hunique_len = hunique_len;
  855                         memcpy(sc->sc_hunique, hunique, hunique_len);
  856                 }
  857                 memcpy(&sc->sc_dest, eh->ether_shost, sizeof sc->sc_dest);
  858                 sc->sc_state = PPPOE_STATE_PADO_SENT;
  859                 pppoe_send_pado(sc);
  860                 PPPOE_UNLOCK(sc);
  861                 break;
  862 #endif /* PPPOE_SERVER */
  863 
  864         case PPPOE_CODE_PADR:
  865 #ifdef PPPOE_SERVER
  866                 /*
  867                  * get sc from ac_cookie if IFF_PASSIVE
  868                  */
  869                 if (ac_cookie == NULL) {
  870                         goto done;
  871                 }
  872 
  873                 rcvif = m_get_rcvif_psref(m, &psref);
  874                 if (__predict_true(rcvif != NULL)) {
  875                         sc = pppoe_find_softc_by_hunique(ac_cookie,
  876                             ac_cookie_len, rcvif, RW_WRITER);
  877                 }
  878                 m_put_rcvif_psref(rcvif, &psref);
  879                 if (sc == NULL) {
  880                         /* be quiet if there is not a single pppoe instance */
  881                         rw_enter(&pppoe_softc_list_lock, RW_READER);
  882                         if (!LIST_EMPTY(&pppoe_softc_list)) {
  883                                 pppoe_printf(NULL, "received PADR"
  884                                     " but could not find request for it\n");
  885                         }
  886                         rw_exit(&pppoe_softc_list_lock);
  887                         goto done;
  888                 }
  889 
  890                 if (sc->sc_state != PPPOE_STATE_PADO_SENT) {
  891                         pppoe_printf(sc, "received unexpected PADR\n");
  892                         PPPOE_UNLOCK(sc);
  893                         goto done;
  894                 }
  895 
  896                 if (hunique) {
  897                         if (sc->sc_hunique)
  898                                 free(sc->sc_hunique, M_DEVBUF);
  899                         sc->sc_hunique = malloc(hunique_len, M_DEVBUF,
  900                             M_DONTWAIT);
  901                         if (sc->sc_hunique == NULL) {
  902                                 PPPOE_UNLOCK(sc);
  903                                 goto done;
  904                         }
  905                         sc->sc_hunique_len = hunique_len;
  906                         memcpy(sc->sc_hunique, hunique, hunique_len);
  907                 }
  908                 pppoe_send_pads(sc);
  909                 sc->sc_state = PPPOE_STATE_SESSION;
  910                 PPPOE_UNLOCK(sc);
  911 
  912                 sc->sc_sppp.pp_up(&sc->sc_sppp);
  913                 break;
  914 #else
  915                 /* ignore, we are no access concentrator */
  916                 goto done;
  917 #endif /* PPPOE_SERVER */
  918 
  919         case PPPOE_CODE_PADO:
  920                 rcvif = m_get_rcvif_psref(m, &psref);
  921                 if (__predict_false(rcvif == NULL))
  922                         goto done;
  923 
  924                 if (hunique != NULL) {
  925                         sc = pppoe_find_softc_by_hunique(hunique,
  926                             hunique_len, rcvif, RW_WRITER);
  927                 }
  928 
  929                 m_put_rcvif_psref(rcvif, &psref);
  930 
  931                 if (sc == NULL) {
  932                         /* be quiet if there is not a single pppoe instance */
  933                         rw_enter(&pppoe_softc_list_lock, RW_READER);
  934                         if (!LIST_EMPTY(&pppoe_softc_list)) {
  935                                 pppoe_printf(NULL, "received PADO"
  936                                     " but could not find request for it\n");
  937                         }
  938                         rw_exit(&pppoe_softc_list_lock);
  939                         goto done;
  940                 }
  941 
  942                 if (sc->sc_state != PPPOE_STATE_PADI_SENT) {
  943                         pppoe_printf(sc, "received unexpected PADO\n");
  944                         PPPOE_UNLOCK(sc);
  945                         goto done;
  946                 }
  947 
  948                 if (ac_cookie) {
  949                         if (sc->sc_ac_cookie)
  950                                 free(sc->sc_ac_cookie, M_DEVBUF);
  951                         sc->sc_ac_cookie = malloc(ac_cookie_len, M_DEVBUF,
  952                             M_DONTWAIT);
  953                         if (sc->sc_ac_cookie == NULL) {
  954                                 pppoe_printf(sc, "FATAL: could not allocate memory "
  955                                     "for AC cookie\n");
  956                                 sc->sc_ac_cookie_len = 0;
  957                                 PPPOE_UNLOCK(sc);
  958                                 goto done;
  959                         }
  960                         sc->sc_ac_cookie_len = ac_cookie_len;
  961                         memcpy(sc->sc_ac_cookie, ac_cookie, ac_cookie_len);
  962                 } else if (sc->sc_ac_cookie) {
  963                         free(sc->sc_ac_cookie, M_DEVBUF);
  964                         sc->sc_ac_cookie = NULL;
  965                         sc->sc_ac_cookie_len = 0;
  966                 }
  967                 if (relay_sid) {
  968                         if (sc->sc_relay_sid)
  969                                 free(sc->sc_relay_sid, M_DEVBUF);
  970                         sc->sc_relay_sid = malloc(relay_sid_len, M_DEVBUF,
  971                             M_DONTWAIT);
  972                         if (sc->sc_relay_sid == NULL) {
  973                                 pppoe_printf(sc, "FATAL: could not allocate memory "
  974                                     "for relay SID\n");
  975                                 sc->sc_relay_sid_len = 0;
  976                                 PPPOE_UNLOCK(sc);
  977                                 goto done;
  978                         }
  979                         sc->sc_relay_sid_len = relay_sid_len;
  980                         memcpy(sc->sc_relay_sid, relay_sid, relay_sid_len);
  981                 } else if (sc->sc_relay_sid) {
  982                         free(sc->sc_relay_sid, M_DEVBUF);
  983                         sc->sc_relay_sid = NULL;
  984                         sc->sc_relay_sid_len = 0;
  985                 }
  986                 memcpy(&sc->sc_dest, eh->ether_shost, sizeof sc->sc_dest);
  987                 callout_stop(&sc->sc_timeout);
  988                 sc->sc_padr_retried = 0;
  989                 sc->sc_state = PPPOE_STATE_PADR_SENT;
  990                 if ((err = pppoe_send_padr(sc)) != 0) {
  991                         if (err == ENOBUFS) {
  992                                 pppoe_printf(sc, "PADO is too large, drop it\n");
  993                                 /*
  994                                  * Cannot send PADR generated by received PADO,
  995                                  * so restart from sending PAD*I*.
  996                                  */
  997                                 sc->sc_state = PPPOE_STATE_PADI_SENT;
  998                                 callout_schedule(&sc->sc_timeout,
  999                                     PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried));
 1000                                 PPPOE_UNLOCK(sc);
 1001                                 goto done;
 1002                         }
 1003 
 1004                         pppoe_printf(sc,
 1005                             "failed to send PADR, error=%d\n", err);
 1006                 }
 1007                 callout_schedule(&sc->sc_timeout,
 1008                     PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried));
 1009 
 1010                 PPPOE_UNLOCK(sc);
 1011                 break;
 1012 
 1013         case PPPOE_CODE_PADS:
 1014                 rcvif = m_get_rcvif_psref(m, &psref);
 1015                 if (__predict_false(rcvif == NULL))
 1016                         goto done;
 1017 
 1018                 if (hunique != NULL) {
 1019                         sc = pppoe_find_softc_by_hunique(hunique,
 1020                             hunique_len, rcvif, RW_WRITER);
 1021                 }
 1022 
 1023                 m_put_rcvif_psref(rcvif, &psref);
 1024 
 1025                 if (sc == NULL)
 1026                         goto done;
 1027 
 1028                 if (memcmp(&sc->sc_dest, eh->ether_shost,
 1029                     sizeof sc->sc_dest) != 0) {
 1030                         PPPOE_UNLOCK(sc);
 1031                         goto done;
 1032                 }
 1033 
 1034                 sc->sc_session = session;
 1035                 callout_stop(&sc->sc_timeout);
 1036                 pppoe_printf(sc, "session 0x%x connected\n", session);
 1037                 sc->sc_state = PPPOE_STATE_SESSION;
 1038                 PPPOE_UNLOCK(sc);
 1039 
 1040                 sc->sc_sppp.pp_up(&sc->sc_sppp);        /* notify upper layers */
 1041                 break;
 1042 
 1043         case PPPOE_CODE_PADT:
 1044                 rcvif = m_get_rcvif_psref(m, &psref);
 1045                 if (__predict_false(rcvif == NULL))
 1046                         goto done;
 1047 
 1048                 sc = pppoe_find_softc_by_session(session, rcvif,
 1049                     RW_WRITER);
 1050 
 1051                 m_put_rcvif_psref(rcvif, &psref);
 1052 
 1053                 if (sc == NULL)
 1054                         goto done;
 1055 
 1056                 if (memcmp(&sc->sc_dest, eh->ether_shost,
 1057                     sizeof sc->sc_dest) != 0) {
 1058                         PPPOE_UNLOCK(sc);
 1059                         goto done;
 1060                 }
 1061 
 1062                 pppoe_clear_softc(sc, "received PADT");
 1063                 if (sc->sc_sppp.pp_if.if_flags & IFF_RUNNING) {
 1064                         pppoe_printf(sc, "wait for reconnect\n");
 1065                         callout_schedule(&sc->sc_timeout,
 1066                             PPPOE_RECON_PADTRCVD);
 1067                 }
 1068                 PPPOE_UNLOCK(sc);
 1069                 break;
 1070 
 1071         default:
 1072                 rcvif = m_get_rcvif_psref(m, &psref);
 1073                 if (__predict_false(rcvif == NULL))
 1074                         goto done;
 1075 
 1076                 if (hunique != NULL) {
 1077                         sc = pppoe_find_softc_by_hunique(hunique,
 1078                             hunique_len, rcvif, RW_READER);
 1079                 }
 1080 
 1081                 m_put_rcvif_psref(rcvif, &psref);
 1082 
 1083                 pppoe_printf(sc, "unknown code (0x%04x) session = 0x%04x\n",
 1084                     ph->code, session);
 1085                 if (sc == NULL)
 1086                         goto done;
 1087                 PPPOE_UNLOCK(sc);
 1088                 break;
 1089         }
 1090 
 1091 done:
 1092         if (m)
 1093                 m_freem(m);
 1094         return;
 1095 }
 1096 
 1097 static void
 1098 pppoe_disc_input(struct mbuf *m)
 1099 {
 1100         KASSERT(m->m_flags & M_PKTHDR);
 1101 
 1102         /*
 1103          * Avoid error messages if there is not a single PPPoE instance.
 1104          */
 1105         rw_enter(&pppoe_softc_list_lock, RW_READER);
 1106         if (!LIST_EMPTY(&pppoe_softc_list)) {
 1107                 rw_exit(&pppoe_softc_list_lock);
 1108                 pppoe_dispatch_disc_pkt(m, 0);
 1109         } else {
 1110                 rw_exit(&pppoe_softc_list_lock);
 1111                 m_freem(m);
 1112         }
 1113 }
 1114 
 1115 static bool
 1116 pppoe_is_my_frame(uint8_t *dhost, struct ifnet *rcvif)
 1117 {
 1118 
 1119         if (memcmp(CLLADDR(rcvif->if_sadl), dhost, ETHER_ADDR_LEN) == 0)
 1120                 return true;
 1121 
 1122         return false;
 1123 }
 1124 
 1125 static void
 1126 pppoe_data_input(struct mbuf *m)
 1127 {
 1128         uint16_t session, plen;
 1129         struct pppoe_softc *sc;
 1130         struct pppoehdr *ph;
 1131         struct ifnet *rcvif;
 1132         struct psref psref;
 1133         uint8_t shost[ETHER_ADDR_LEN];
 1134         uint8_t dhost[ETHER_ADDR_LEN];
 1135         bool term_unknown = pppoe_term_unknown;
 1136 
 1137         KASSERT(m->m_flags & M_PKTHDR);
 1138 
 1139         /*
 1140          * Avoid error messages if there is not a single PPPoE instance.
 1141          */
 1142         rw_enter(&pppoe_softc_list_lock, RW_READER);
 1143         if (LIST_EMPTY(&pppoe_softc_list)) {
 1144                 rw_exit(&pppoe_softc_list_lock);
 1145                 goto drop;
 1146         }
 1147         rw_exit(&pppoe_softc_list_lock);
 1148 
 1149         if (term_unknown) {
 1150                 memcpy(shost, mtod(m, struct ether_header*)->ether_shost,
 1151                     ETHER_ADDR_LEN);
 1152                 memcpy(dhost, mtod(m, struct ether_header*)->ether_dhost,
 1153                     ETHER_ADDR_LEN);
 1154         }
 1155         m_adj(m, sizeof(struct ether_header));
 1156         if (m->m_pkthdr.len <= PPPOE_HEADERLEN) {
 1157                 goto drop;
 1158         }
 1159 
 1160         if (m->m_len < sizeof(*ph)) {
 1161                 m = m_pullup(m, sizeof(*ph));
 1162                 if (m == NULL) {
 1163                         return;
 1164                 }
 1165         }
 1166         ph = mtod(m, struct pppoehdr *);
 1167 
 1168         if (ph->vertype != PPPOE_VERTYPE) {
 1169                 goto drop;
 1170         }
 1171         if (ph->code != 0) {
 1172                 goto drop;
 1173         }
 1174 
 1175         session = ntohs(ph->session);
 1176         rcvif = m_get_rcvif_psref(m, &psref);
 1177         if (__predict_false(rcvif == NULL))
 1178                 goto drop;
 1179         sc = pppoe_find_softc_by_session(session, rcvif, RW_READER);
 1180         if (sc == NULL) {
 1181                 if (term_unknown) {
 1182                         static struct timeval lasttime = {0, 0};
 1183                         static int curpps = 0;
 1184                         /*
 1185                          * avoid to send wrong PADT which is response from
 1186                          * session stage packets for other hosts when parent
 1187                          * ethernet is promiscuous mode.
 1188                          */
 1189                         if (pppoe_is_my_frame(dhost, rcvif) &&
 1190                             ppsratecheck(&lasttime, &curpps,
 1191                                 pppoe_term_unknown_pps)) {
 1192                                 pppoe_printf(NULL, "input for unknown session %#x, "
 1193                                     "sending PADT\n", session);
 1194                                 pppoe_send_padt(rcvif, session, shost);
 1195                         }
 1196                 }
 1197                 m_put_rcvif_psref(rcvif, &psref);
 1198                 goto drop;
 1199         }
 1200 
 1201         m_put_rcvif_psref(rcvif, &psref);
 1202 
 1203         plen = ntohs(ph->plen);
 1204 
 1205         bpf_mtap(&sc->sc_sppp.pp_if, m, BPF_D_IN);
 1206 
 1207         m_adj(m, PPPOE_HEADERLEN);
 1208 
 1209 #ifdef PPPOE_DEBUG
 1210         {
 1211                 struct mbuf *p;
 1212 
 1213                 printf("%s: pkthdr.len=%d, pppoe.len=%d",
 1214                     sc->sc_sppp.pp_if.if_xname, m->m_pkthdr.len, plen);
 1215                 p = m;
 1216                 while (p) {
 1217                         printf(" l=%d", p->m_len);
 1218                         p = p->m_next;
 1219                 }
 1220                 printf("\n");
 1221         }
 1222 #endif
 1223         PPPOE_UNLOCK(sc);
 1224 
 1225         if (m->m_pkthdr.len < plen)
 1226                 goto drop;
 1227 
 1228         /* ignore trailing garbage */
 1229         m_adj(m, plen - m->m_pkthdr.len);
 1230         /*
 1231          * Fix incoming interface pointer (not the raw ethernet interface
 1232          * anymore)
 1233          */
 1234         m_set_rcvif(m, &sc->sc_sppp.pp_if);
 1235 
 1236         /* pass packet up and account for it */
 1237         if_statinc(&sc->sc_sppp.pp_if, if_ipackets);
 1238         sppp_input(&sc->sc_sppp.pp_if, m);
 1239         return;
 1240 
 1241 drop:
 1242         m_freem(m);
 1243 }
 1244 
 1245 static int
 1246 pppoe_output(struct pppoe_softc *sc, struct mbuf *m)
 1247 {
 1248         struct sockaddr dst;
 1249         struct ether_header *eh;
 1250         uint16_t etype;
 1251 
 1252         if (sc->sc_eth_if == NULL) {
 1253                 m_freem(m);
 1254                 return EIO;
 1255         }
 1256 
 1257         memset(&dst, 0, sizeof dst);
 1258         dst.sa_family = AF_UNSPEC;
 1259         eh = (struct ether_header*)&dst.sa_data;
 1260         etype = sc->sc_state == PPPOE_STATE_SESSION
 1261             ? ETHERTYPE_PPPOE : ETHERTYPE_PPPOEDISC;
 1262         eh->ether_type = htons(etype);
 1263         memcpy(&eh->ether_dhost, &sc->sc_dest, sizeof sc->sc_dest);
 1264 
 1265         DPRINTF(sc, "(%x) state=%d, session=0x%x output -> %s, len=%d\n",
 1266             etype, sc->sc_state, sc->sc_session,
 1267             ether_sprintf((const unsigned char *)&sc->sc_dest), m->m_pkthdr.len);
 1268 
 1269         m->m_flags &= ~(M_BCAST|M_MCAST);
 1270         if_statinc(&sc->sc_sppp.pp_if, if_opackets);
 1271         return if_output_lock(sc->sc_eth_if, sc->sc_eth_if, m, &dst, NULL);
 1272 }
 1273 
 1274 static int
 1275 pppoe_parm_cpyinstr(struct pppoe_softc *sc,
 1276     char **dst, const void *src, size_t len)
 1277 {
 1278         int error = 0;
 1279         char *next = NULL;
 1280         size_t bufsiz, cpysiz, strsiz;
 1281 
 1282         bufsiz = len + 1;
 1283 
 1284         if (src == NULL)
 1285                 goto out;
 1286 
 1287         bufsiz = len + 1;
 1288         next = malloc(bufsiz, M_DEVBUF, M_WAITOK);
 1289         if (next == NULL)
 1290                 return ENOMEM;
 1291 
 1292         error = copyinstr(src, next, bufsiz, &cpysiz);
 1293         if (error != 0)
 1294                 goto fail;
 1295         if (cpysiz != bufsiz) {
 1296                 error = EINVAL;
 1297                 goto fail;
 1298         }
 1299 
 1300         strsiz = strnlen(next, bufsiz);
 1301         if (strsiz == bufsiz) {
 1302                 error = EINVAL;
 1303                 goto fail;
 1304         }
 1305 
 1306 out:
 1307         PPPOE_LOCK(sc, RW_WRITER);
 1308         if (*dst != NULL)
 1309                 free(*dst, M_DEVBUF);
 1310         *dst = next;
 1311         next = NULL;
 1312         PPPOE_UNLOCK(sc);
 1313 fail:
 1314         if (next != NULL)
 1315                 free(next, M_DEVBUF);
 1316 
 1317         return error;
 1318 }
 1319 
 1320 static int
 1321 pppoe_ioctl(struct ifnet *ifp, unsigned long cmd, void *data)
 1322 {
 1323         struct lwp *l = curlwp; /* XXX */
 1324         struct pppoe_softc *sc = (struct pppoe_softc*)ifp;
 1325         struct ifreq *ifr = data;
 1326         int error = 0;
 1327 
 1328         switch (cmd) {
 1329         case PPPOESETPARMS:
 1330         {
 1331                 struct pppoediscparms *parms = (struct pppoediscparms*)data;
 1332                 if (kauth_authorize_network(l->l_cred, KAUTH_NETWORK_INTERFACE,
 1333                     KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, ifp, (void *)cmd,
 1334                     NULL) != 0)
 1335                         return EPERM;
 1336                 if (parms->eth_ifname[0] != 0) {
 1337                         struct ifnet *eth_if;
 1338 
 1339                         PPPOE_LOCK(sc, RW_WRITER);
 1340                         if (sc->sc_detaching) {
 1341                                 PPPOE_UNLOCK(sc);
 1342                                 return ENXIO;
 1343                         }
 1344                         eth_if = ifunit(parms->eth_ifname);
 1345                         if (eth_if == NULL || eth_if->if_dlt != DLT_EN10MB) {
 1346                                 sc->sc_eth_if = NULL;
 1347                                 PPPOE_UNLOCK(sc);
 1348                                 return ENXIO;
 1349                         }
 1350 
 1351                         if (sc->sc_sppp.pp_if.if_mtu !=
 1352                             eth_if->if_mtu - PPPOE_OVERHEAD) {
 1353                                 sc->sc_sppp.pp_if.if_mtu = eth_if->if_mtu -
 1354                                     PPPOE_OVERHEAD;
 1355                         }
 1356                         sc->sc_eth_if = eth_if;
 1357                         PPPOE_UNLOCK(sc);
 1358                 }
 1359 
 1360                 error = pppoe_parm_cpyinstr(sc, &sc->sc_concentrator_name,
 1361                     parms->ac_name, parms->ac_name_len);
 1362                 if (error != 0)
 1363                         return error;
 1364 
 1365                 error = pppoe_parm_cpyinstr(sc, &sc->sc_service_name,
 1366                     parms->service_name, parms->service_name_len);
 1367                 if (error != 0)
 1368                         return error;
 1369                 return 0;
 1370         }
 1371         break;
 1372         case PPPOEGETPARMS:
 1373         {
 1374                 struct pppoediscparms *parms = (struct pppoediscparms*)data;
 1375                 memset(parms, 0, sizeof *parms);
 1376                 PPPOE_LOCK(sc, RW_READER);
 1377                 if (sc->sc_eth_if)
 1378                         strlcpy(parms->ifname, sc->sc_eth_if->if_xname,
 1379                             sizeof(parms->ifname));
 1380                 PPPOE_UNLOCK(sc);
 1381                 return 0;
 1382         }
 1383         break;
 1384         case PPPOEGETSESSION:
 1385         {
 1386                 struct pppoeconnectionstate *state = (struct pppoeconnectionstate*)data;
 1387                 PPPOE_LOCK(sc, RW_READER);
 1388                 state->state = sc->sc_state;
 1389                 state->session_id = sc->sc_session;
 1390                 state->padi_retry_no = sc->sc_padi_retried;
 1391                 state->padr_retry_no = sc->sc_padr_retried;
 1392                 PPPOE_UNLOCK(sc);
 1393                 return 0;
 1394         }
 1395         break;
 1396         case SIOCSIFFLAGS:
 1397                 /*
 1398                  * Prevent running re-establishment timers overriding
 1399                  * administrators choice.
 1400                  */
 1401                 PPPOE_LOCK(sc, RW_WRITER);
 1402                 if (sc->sc_detaching) {
 1403                         PPPOE_UNLOCK(sc);
 1404                         return ENXIO;
 1405                 }
 1406 
 1407                 if ((ifr->ifr_flags & IFF_UP) == 0
 1408                      && sc->sc_state < PPPOE_STATE_SESSION) {
 1409                         callout_stop(&sc->sc_timeout);
 1410                         sc->sc_state = PPPOE_STATE_INITIAL;
 1411                         sc->sc_padi_retried = 0;
 1412                         sc->sc_padr_retried = 0;
 1413                         memcpy(&sc->sc_dest, etherbroadcastaddr,
 1414                             sizeof(sc->sc_dest));
 1415                 }
 1416 
 1417                 PPPOE_UNLOCK(sc);
 1418 
 1419                 error = sppp_ioctl(ifp, cmd, data);
 1420 
 1421                 return error;
 1422         case SIOCSIFMTU:
 1423                 if (ifr->ifr_mtu > (sc->sc_eth_if == NULL ?
 1424                     PPPOE_MAXMTU : (sc->sc_eth_if->if_mtu - PPPOE_OVERHEAD))) {
 1425                         return EINVAL;
 1426                 }
 1427                 /*FALLTHROUGH*/
 1428         default:
 1429                 return sppp_ioctl(ifp, cmd, data);
 1430         }
 1431         return 0;
 1432 }
 1433 
 1434 /*
 1435  * Allocate a mbuf/cluster with space to store the given data length
 1436  * of payload, leaving space for prepending an ethernet header
 1437  * in front.
 1438  */
 1439 static struct mbuf *
 1440 pppoe_get_mbuf(size_t len)
 1441 {
 1442         struct mbuf *m;
 1443 
 1444         if (len + sizeof(struct ether_header) > MCLBYTES)
 1445                 return NULL;
 1446 
 1447         MGETHDR(m, M_DONTWAIT, MT_DATA);
 1448         if (m == NULL)
 1449                 return NULL;
 1450         if (len + sizeof(struct ether_header) > MHLEN) {
 1451                 MCLGET(m, M_DONTWAIT);
 1452                 if ((m->m_flags & M_EXT) == 0) {
 1453                         m_free(m);
 1454                         return NULL;
 1455                 }
 1456         }
 1457         m->m_data += sizeof(struct ether_header);
 1458         m->m_len = len;
 1459         m->m_pkthdr.len = len;
 1460         m_reset_rcvif(m);
 1461 
 1462         return m;
 1463 }
 1464 
 1465 static int
 1466 pppoe_send_padi(struct pppoe_softc *sc)
 1467 {
 1468         struct mbuf *m0;
 1469         int len, l1 = 0, l2 = 0;
 1470         uint8_t *p;
 1471 
 1472         if (sc->sc_state > PPPOE_STATE_PADI_SENT)
 1473                 panic("pppoe_send_padi in state %d", sc->sc_state);
 1474 
 1475         /* Compute packet length. */
 1476         len = sizeof(struct pppoetag);
 1477         if (sc->sc_service_name != NULL) {
 1478                 l1 = strlen(sc->sc_service_name);
 1479                 len += l1;
 1480         }
 1481         if (sc->sc_concentrator_name != NULL) {
 1482                 l2 = strlen(sc->sc_concentrator_name);
 1483                 len += sizeof(struct pppoetag) + l2;
 1484         }
 1485         len += sizeof(struct pppoetag) + sizeof(sc->sc_id);
 1486         if (sc->sc_sppp.pp_if.if_mtu > PPPOE_MAXMTU) {
 1487                 len += sizeof(struct pppoetag) + 2;
 1488         }
 1489 
 1490         /* Allocate packet. */
 1491         m0 = pppoe_get_mbuf(len + PPPOE_HEADERLEN);
 1492         if (m0 == NULL)
 1493                 return ENOBUFS;
 1494 
 1495         /* Fill in packet. */
 1496         p = mtod(m0, uint8_t *);
 1497         PPPOE_ADD_HEADER(p, PPPOE_CODE_PADI, 0, len);
 1498         PPPOE_ADD_16(p, PPPOE_TAG_SNAME);
 1499         if (sc->sc_service_name != NULL) {
 1500                 PPPOE_ADD_16(p, l1);
 1501                 memcpy(p, sc->sc_service_name, l1);
 1502                 p += l1;
 1503         } else {
 1504                 PPPOE_ADD_16(p, 0);
 1505         }
 1506         if (sc->sc_concentrator_name != NULL) {
 1507                 PPPOE_ADD_16(p, PPPOE_TAG_ACNAME);
 1508                 PPPOE_ADD_16(p, l2);
 1509                 memcpy(p, sc->sc_concentrator_name, l2);
 1510                 p += l2;
 1511         }
 1512         PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE);
 1513         PPPOE_ADD_16(p, sizeof(sc->sc_id));
 1514         memcpy(p, &sc->sc_id, sizeof(sc->sc_id));
 1515         p += sizeof(sc->sc_id);
 1516 
 1517         if (sc->sc_sppp.pp_if.if_mtu > PPPOE_MAXMTU) {
 1518                 PPPOE_ADD_16(p, PPPOE_TAG_MAX_PAYLOAD);
 1519                 PPPOE_ADD_16(p, 2);
 1520                 PPPOE_ADD_16(p, (uint16_t)sc->sc_sppp.pp_if.if_mtu);
 1521         }
 1522 
 1523 #ifdef PPPOE_DEBUG
 1524         if (p - mtod(m0, uint8_t *) != len + PPPOE_HEADERLEN)
 1525                 panic("pppoe_send_padi: garbled output len, should be %ld, is %ld",
 1526                     (long)(len + PPPOE_HEADERLEN), (long)(p - mtod(m0, uint8_t *)));
 1527 #endif
 1528 
 1529         /* Send packet. */
 1530         return pppoe_output(sc, m0);
 1531 }
 1532 
 1533 static void
 1534 pppoe_timeout_co(void *arg)
 1535 {
 1536         struct pppoe_softc *sc = (struct pppoe_softc *)arg;
 1537 
 1538         if (atomic_swap_uint(&sc->sc_timeout_scheduled, 1) != 0)
 1539                 return;
 1540 
 1541         workqueue_enqueue(sc->sc_timeout_wq, &sc->sc_timeout_wk, NULL);
 1542 }
 1543 
 1544 static void
 1545 pppoe_timeout_co_halt(void *unused __unused)
 1546 {
 1547 
 1548         /* do nothing to halt callout safely */
 1549 }
 1550 
 1551 static void
 1552 pppoe_timeout_wk(struct work *wk __unused, void *arg)
 1553 {
 1554         struct pppoe_softc *sc = (struct pppoe_softc *)arg;
 1555 
 1556         atomic_swap_uint(&sc->sc_timeout_scheduled, 0);
 1557         pppoe_timeout(sc);
 1558 }
 1559 
 1560 static void
 1561 pppoe_timeout(struct pppoe_softc *sc)
 1562 {
 1563         int retry_wait, err;
 1564         DECLARE_SPLNET_VARIABLE;
 1565 
 1566         pppoe_printf(sc, "timeout\n");
 1567 
 1568         PPPOE_LOCK(sc, RW_WRITER);
 1569         switch (sc->sc_state) {
 1570         case PPPOE_STATE_INITIAL:
 1571                 /* delayed connect from pppoe_tls() */
 1572                 if (!sc->sc_detaching)
 1573                         pppoe_connect(sc);
 1574                 break;
 1575         case PPPOE_STATE_PADI_SENT:
 1576                 /*
 1577                  * We have two basic ways of retrying:
 1578                  *  - Quick retry mode: try a few times in short sequence
 1579                  *  - Slow retry mode: we already had a connection successfully
 1580                  *    established and will try infinitely (without user
 1581                  *    intervention)
 1582                  * We only enter slow retry mode if IFF_LINK1 (aka autodial)
 1583                  * is not set.
 1584                  */
 1585 
 1586                 /* initialize for quick retry mode */
 1587                 retry_wait = PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried);
 1588 
 1589                 ACQUIRE_SPLNET();
 1590                 sc->sc_padi_retried++;
 1591                 if (sc->sc_padi_retried >= PPPOE_DISC_MAXPADI) {
 1592                         if ((sc->sc_sppp.pp_if.if_flags & IFF_LINK1) == 0) {
 1593                                 /* slow retry mode */
 1594                                 retry_wait = PPPOE_SLOW_RETRY;
 1595                         } else {
 1596                                 pppoe_abort_connect(sc);
 1597                                 RELEASE_SPLNET();
 1598                                 PPPOE_UNLOCK(sc);
 1599                                 return;
 1600                         }
 1601                 }
 1602                 if ((err = pppoe_send_padi(sc)) != 0) {
 1603                         sc->sc_padi_retried--;
 1604                         pppoe_printf(sc,
 1605                             "failed to transmit PADI, error=%d\n", err);
 1606                 }
 1607                 callout_schedule(&sc->sc_timeout,retry_wait);
 1608                 RELEASE_SPLNET();
 1609                 break;
 1610 
 1611         case PPPOE_STATE_PADR_SENT:
 1612                 ACQUIRE_SPLNET();
 1613                 sc->sc_padr_retried++;
 1614                 if (sc->sc_padr_retried >= PPPOE_DISC_MAXPADR) {
 1615                         memcpy(&sc->sc_dest, etherbroadcastaddr,
 1616                             sizeof(sc->sc_dest));
 1617                         sc->sc_state = PPPOE_STATE_PADI_SENT;
 1618                         sc->sc_padi_retried = 0;
 1619                         sc->sc_padr_retried = 0;
 1620                         if ((err = pppoe_send_padi(sc)) != 0) {
 1621                                 pppoe_printf(sc,
 1622                                     "failed to send PADI, error=%d\n", err);
 1623                         }
 1624                         callout_schedule(&sc->sc_timeout,
 1625                             PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried));
 1626                         RELEASE_SPLNET();
 1627                         PPPOE_UNLOCK(sc);
 1628                         return;
 1629                 }
 1630                 if ((err = pppoe_send_padr(sc)) != 0) {
 1631                         pppoe_printf(sc,"failed to send PADR, error=%d", err);
 1632                 }
 1633                 callout_schedule(&sc->sc_timeout,
 1634                     PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried));
 1635                 RELEASE_SPLNET();
 1636                 break;
 1637         case PPPOE_STATE_CLOSING:
 1638                 pppoe_disconnect(sc);
 1639                 break;
 1640         default:
 1641                 PPPOE_UNLOCK(sc);
 1642                 return; /* all done, work in peace */
 1643         }
 1644         PPPOE_UNLOCK(sc);
 1645 }
 1646 
 1647 /* Start a connection (i.e. initiate discovery phase) */
 1648 static int
 1649 pppoe_connect(struct pppoe_softc *sc)
 1650 {
 1651         int err;
 1652         DECLARE_SPLNET_VARIABLE;
 1653 
 1654         KASSERT(PPPOE_WLOCKED(sc));
 1655 
 1656         if (sc->sc_state != PPPOE_STATE_INITIAL)
 1657                 return EBUSY;
 1658 
 1659 #ifdef PPPOE_SERVER
 1660         /* wait PADI if IFF_PASSIVE */
 1661         if ((sc->sc_sppp.pp_if.if_flags & IFF_PASSIVE))
 1662                 return 0;
 1663 #endif
 1664         ACQUIRE_SPLNET();
 1665         /* save state, in case we fail to send PADI */
 1666         sc->sc_state = PPPOE_STATE_PADI_SENT;
 1667         sc->sc_padi_retried = 0;
 1668         sc->sc_padr_retried = 0;
 1669         err = pppoe_send_padi(sc);
 1670         if (err != 0)
 1671                 pppoe_printf(sc, "failed to send PADI, error=%d\n", err);
 1672         callout_schedule(&sc->sc_timeout, PPPOE_DISC_TIMEOUT);
 1673         RELEASE_SPLNET();
 1674         return err;
 1675 }
 1676 
 1677 /* disconnect */
 1678 static int
 1679 pppoe_disconnect(struct pppoe_softc *sc)
 1680 {
 1681         int err;
 1682         DECLARE_SPLNET_VARIABLE;
 1683 
 1684         KASSERT(PPPOE_WLOCKED(sc));
 1685 
 1686         ACQUIRE_SPLNET();
 1687 
 1688         if (sc->sc_state < PPPOE_STATE_SESSION)
 1689                 err = EBUSY;
 1690         else {
 1691                 pppoe_printf(sc, "disconnecting\n");
 1692                 err = pppoe_send_padt(sc->sc_eth_if, sc->sc_session,
 1693                     (const uint8_t *)&sc->sc_dest);
 1694         }
 1695 
 1696         /* cleanup softc */
 1697         sc->sc_state = PPPOE_STATE_INITIAL;
 1698 
 1699         memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest));
 1700         if (sc->sc_ac_cookie) {
 1701                 free(sc->sc_ac_cookie, M_DEVBUF);
 1702                 sc->sc_ac_cookie = NULL;
 1703         }
 1704         sc->sc_ac_cookie_len = 0;
 1705         if (sc->sc_relay_sid) {
 1706                 free(sc->sc_relay_sid, M_DEVBUF);
 1707                 sc->sc_relay_sid = NULL;
 1708         }
 1709         sc->sc_relay_sid_len = 0;
 1710 #ifdef PPPOE_SERVER
 1711         if (sc->sc_hunique) {
 1712                 free(sc->sc_hunique, M_DEVBUF);
 1713                 sc->sc_hunique = NULL;
 1714         }
 1715         sc->sc_hunique_len = 0;
 1716 #endif
 1717         sc->sc_session = 0;
 1718 
 1719         PPPOE_UNLOCK(sc);
 1720 
 1721         /* notify upper layer */
 1722         sc->sc_sppp.pp_down(&sc->sc_sppp);
 1723 
 1724         PPPOE_LOCK(sc, RW_WRITER);
 1725 
 1726         RELEASE_SPLNET();
 1727         return err;
 1728 }
 1729 
 1730 /* Connection attempt aborted */
 1731 static void
 1732 pppoe_abort_connect(struct pppoe_softc *sc)
 1733 {
 1734         KASSERT(PPPOE_WLOCKED(sc));
 1735 
 1736         pppoe_printf(sc, "could not establish connection\n");
 1737         sc->sc_state = PPPOE_STATE_CLOSING;
 1738 
 1739         PPPOE_UNLOCK(sc);
 1740 
 1741         /* notify upper layer */
 1742         sc->sc_sppp.pp_down(&sc->sc_sppp);
 1743 
 1744         PPPOE_LOCK(sc, RW_WRITER);
 1745 
 1746         /* clear connection state */
 1747         memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest));
 1748         sc->sc_state = PPPOE_STATE_INITIAL;
 1749 }
 1750 
 1751 static int
 1752 pppoe_send_padr(struct pppoe_softc *sc)
 1753 {
 1754         struct mbuf *m0;
 1755         uint8_t *p;
 1756         size_t len, l1 = 0;
 1757 
 1758         if (sc->sc_state != PPPOE_STATE_PADR_SENT)
 1759                 return EIO;
 1760 
 1761         /* Compute packet length. */
 1762         len = sizeof(struct pppoetag);
 1763         if (sc->sc_service_name != NULL) {
 1764                 l1 = strlen(sc->sc_service_name);
 1765                 len += l1;
 1766         }
 1767         if (sc->sc_ac_cookie_len > 0) {
 1768                 len += sizeof(struct pppoetag) + sc->sc_ac_cookie_len;
 1769         }
 1770         if (sc->sc_relay_sid_len > 0) {
 1771                 len += sizeof(struct pppoetag) + sc->sc_relay_sid_len;
 1772         }
 1773         len += sizeof(struct pppoetag) + sizeof(sc->sc_id);
 1774         if (sc->sc_sppp.pp_if.if_mtu > PPPOE_MAXMTU) {
 1775                 len += sizeof(struct pppoetag) + 2;
 1776         }
 1777 
 1778         /* Allocate packet. */
 1779         m0 = pppoe_get_mbuf(len + PPPOE_HEADERLEN);
 1780         if (m0 == NULL)
 1781                 return ENOBUFS;
 1782 
 1783         /* Fill in packet. */
 1784         p = mtod(m0, uint8_t *);
 1785         PPPOE_ADD_HEADER(p, PPPOE_CODE_PADR, 0, len);
 1786         PPPOE_ADD_16(p, PPPOE_TAG_SNAME);
 1787         if (sc->sc_service_name != NULL) {
 1788                 PPPOE_ADD_16(p, l1);
 1789                 memcpy(p, sc->sc_service_name, l1);
 1790                 p += l1;
 1791         } else {
 1792                 PPPOE_ADD_16(p, 0);
 1793         }
 1794         if (sc->sc_ac_cookie_len > 0) {
 1795                 PPPOE_ADD_16(p, PPPOE_TAG_ACCOOKIE);
 1796                 PPPOE_ADD_16(p, sc->sc_ac_cookie_len);
 1797                 memcpy(p, sc->sc_ac_cookie, sc->sc_ac_cookie_len);
 1798                 p += sc->sc_ac_cookie_len;
 1799         }
 1800         if (sc->sc_relay_sid_len > 0) {
 1801                 PPPOE_ADD_16(p, PPPOE_TAG_RELAYSID);
 1802                 PPPOE_ADD_16(p, sc->sc_relay_sid_len);
 1803                 memcpy(p, sc->sc_relay_sid, sc->sc_relay_sid_len);
 1804                 p += sc->sc_relay_sid_len;
 1805         }
 1806         PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE);
 1807         PPPOE_ADD_16(p, sizeof(sc->sc_id));
 1808         memcpy(p, &sc->sc_id, sizeof(sc->sc_id));
 1809         p += sizeof(sc->sc_id);
 1810 
 1811         if (sc->sc_sppp.pp_if.if_mtu > PPPOE_MAXMTU) {
 1812                 PPPOE_ADD_16(p, PPPOE_TAG_MAX_PAYLOAD);
 1813                 PPPOE_ADD_16(p, 2);
 1814                 PPPOE_ADD_16(p, (uint16_t)sc->sc_sppp.pp_if.if_mtu);
 1815         }
 1816 
 1817 #ifdef PPPOE_DEBUG
 1818         if (p - mtod(m0, uint8_t *) != len + PPPOE_HEADERLEN)
 1819                 panic("pppoe_send_padr: garbled output len, should be %ld, is %ld",
 1820                         (long)(len + PPPOE_HEADERLEN), (long)(p - mtod(m0, uint8_t *)));
 1821 #endif
 1822 
 1823         /* Send packet. */
 1824         return pppoe_output(sc, m0);
 1825 }
 1826 
 1827 /* send a PADT packet */
 1828 static int
 1829 pppoe_send_padt(struct ifnet *outgoing_if, u_int session, const uint8_t *dest)
 1830 {
 1831         struct ether_header *eh;
 1832         struct sockaddr dst;
 1833         struct mbuf *m0;
 1834         uint8_t *p;
 1835 
 1836         m0 = pppoe_get_mbuf(PPPOE_HEADERLEN);
 1837         if (!m0)
 1838                 return EIO;
 1839         p = mtod(m0, uint8_t *);
 1840         PPPOE_ADD_HEADER(p, PPPOE_CODE_PADT, session, 0);
 1841 
 1842         memset(&dst, 0, sizeof dst);
 1843         dst.sa_family = AF_UNSPEC;
 1844         eh = (struct ether_header*)&dst.sa_data;
 1845         eh->ether_type = htons(ETHERTYPE_PPPOEDISC);
 1846         memcpy(&eh->ether_dhost, dest, ETHER_ADDR_LEN);
 1847 
 1848         m0->m_flags &= ~(M_BCAST|M_MCAST);
 1849         return if_output_lock(outgoing_if, outgoing_if, m0, &dst, NULL);
 1850 }
 1851 
 1852 #ifdef PPPOE_SERVER
 1853 static int
 1854 pppoe_send_pado(struct pppoe_softc *sc)
 1855 {
 1856         struct mbuf *m0;
 1857         uint8_t *p;
 1858         size_t len;
 1859 
 1860         if (sc->sc_state != PPPOE_STATE_PADO_SENT)
 1861                 return EIO;
 1862 
 1863         /* Include AC cookie. */
 1864         len = sizeof(struct pppoetag) + sizeof(sc->sc_id);
 1865         /* Include hunique. */
 1866         len += sizeof(struct pppoetag) + sc->sc_hunique_len;
 1867 
 1868         m0 = pppoe_get_mbuf(len + PPPOE_HEADERLEN);
 1869         if (!m0)
 1870                 return EIO;
 1871         p = mtod(m0, uint8_t *);
 1872 
 1873         PPPOE_ADD_HEADER(p, PPPOE_CODE_PADO, 0, len);
 1874         PPPOE_ADD_16(p, PPPOE_TAG_ACCOOKIE);
 1875         PPPOE_ADD_16(p, sizeof(sc->sc_id));
 1876         memcpy(p, &sc->sc_id, sizeof(sc->sc_id));
 1877         p += sizeof(sc->sc_id);
 1878         PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE);
 1879         PPPOE_ADD_16(p, sc->sc_hunique_len);
 1880         memcpy(p, sc->sc_hunique, sc->sc_hunique_len);
 1881         return pppoe_output(sc, m0);
 1882 }
 1883 
 1884 static int
 1885 pppoe_send_pads(struct pppoe_softc *sc)
 1886 {
 1887         struct bintime bt;
 1888         struct mbuf *m0;
 1889         uint8_t *p;
 1890         size_t len, l1 = 0;     /* XXX: gcc */
 1891 
 1892         KASSERT(PPPOE_WLOCKED(sc));
 1893 
 1894         if (sc->sc_state != PPPOE_STATE_PADO_SENT)
 1895                 return EIO;
 1896 
 1897         getbinuptime(&bt);
 1898         sc->sc_session = bt.sec % 0xff + 1;
 1899 
 1900         /* Include service name. */
 1901         len = sizeof(struct pppoetag);
 1902         if (sc->sc_service_name != NULL) {
 1903                 l1 = strlen(sc->sc_service_name);
 1904                 len += l1;
 1905         }
 1906         /* Include hunique. */
 1907         len += sizeof(struct pppoetag) + sc->sc_hunique_len;
 1908 
 1909         m0 = pppoe_get_mbuf(len + PPPOE_HEADERLEN);
 1910         if (!m0)
 1911                 return ENOBUFS;
 1912         p = mtod(m0, uint8_t *);
 1913 
 1914         PPPOE_ADD_HEADER(p, PPPOE_CODE_PADS, sc->sc_session, len);
 1915         PPPOE_ADD_16(p, PPPOE_TAG_SNAME);
 1916         if (sc->sc_service_name != NULL) {
 1917                 PPPOE_ADD_16(p, l1);
 1918                 memcpy(p, sc->sc_service_name, l1);
 1919                 p += l1;
 1920         } else {
 1921                 PPPOE_ADD_16(p, 0);
 1922         }
 1923         PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE);
 1924         PPPOE_ADD_16(p, sc->sc_hunique_len);
 1925         memcpy(p, sc->sc_hunique, sc->sc_hunique_len);
 1926         return pppoe_output(sc, m0);
 1927 }
 1928 #endif
 1929 
 1930 static void
 1931 pppoe_tls(struct sppp *sp)
 1932 {
 1933         struct pppoe_softc *sc = (void *)sp;
 1934         int wtime;
 1935 
 1936         PPPOE_LOCK(sc, RW_READER);
 1937 
 1938         if (sc->sc_state != PPPOE_STATE_INITIAL) {
 1939                 PPPOE_UNLOCK(sc);
 1940                 return;
 1941         }
 1942 
 1943         if (sc->sc_sppp.pp_phase == SPPP_PHASE_ESTABLISH &&
 1944             sc->sc_sppp.pp_auth_failures > 0) {
 1945                 /*
 1946                  * Delay trying to reconnect a bit more - the peer
 1947                  * might have failed to contact its radius server.
 1948                  */
 1949                 wtime = PPPOE_RECON_FAST * sc->sc_sppp.pp_auth_failures;
 1950                 if (wtime > PPPOE_SLOW_RETRY)
 1951                         wtime = PPPOE_SLOW_RETRY;
 1952         } else {
 1953                 wtime = PPPOE_RECON_IMMEDIATE;
 1954         }
 1955         callout_schedule(&sc->sc_timeout, wtime);
 1956 
 1957         PPPOE_UNLOCK(sc);
 1958 }
 1959 
 1960 static void
 1961 pppoe_tlf(struct sppp *sp)
 1962 {
 1963         struct pppoe_softc *sc = (void *)sp;
 1964 
 1965         PPPOE_LOCK(sc, RW_WRITER);
 1966 
 1967         if (sc->sc_state < PPPOE_STATE_SESSION) {
 1968                 callout_stop(&sc->sc_timeout);
 1969                 sc->sc_state = PPPOE_STATE_INITIAL;
 1970                 sc->sc_padi_retried = 0;
 1971                 sc->sc_padr_retried = 0;
 1972                 memcpy(&sc->sc_dest, etherbroadcastaddr,
 1973                     sizeof(sc->sc_dest));
 1974                 PPPOE_UNLOCK(sc);
 1975                 return;
 1976         }
 1977 
 1978         /*
 1979          * Do not call pppoe_disconnect here, the upper layer state
 1980          * machine gets confused by this. We must return from this
 1981          * function and defer disconnecting to the timeout handler.
 1982          */
 1983         sc->sc_state = PPPOE_STATE_CLOSING;
 1984 
 1985         callout_schedule(&sc->sc_timeout, hz/50);
 1986 
 1987         PPPOE_UNLOCK(sc);
 1988 }
 1989 
 1990 static void
 1991 pppoe_start(struct ifnet *ifp)
 1992 {
 1993         struct pppoe_softc *sc = (void *)ifp;
 1994         struct mbuf *m;
 1995         uint8_t *p;
 1996         size_t len;
 1997 
 1998         if (sppp_isempty(ifp))
 1999                 return;
 2000 
 2001         /* are we ready to process data yet? */
 2002         PPPOE_LOCK(sc, RW_READER);
 2003         if (sc->sc_state < PPPOE_STATE_SESSION) {
 2004                 sppp_flush(&sc->sc_sppp.pp_if);
 2005                 PPPOE_UNLOCK(sc);
 2006                 return;
 2007         }
 2008 
 2009         while ((m = sppp_dequeue(ifp)) != NULL) {
 2010                 len = m->m_pkthdr.len;
 2011                 M_PREPEND(m, PPPOE_HEADERLEN, M_DONTWAIT);
 2012                 if (m == NULL) {
 2013                         if_statinc(ifp, if_oerrors);
 2014                         continue;
 2015                 }
 2016                 p = mtod(m, uint8_t *);
 2017                 PPPOE_ADD_HEADER(p, 0, sc->sc_session, len);
 2018 
 2019                 bpf_mtap(&sc->sc_sppp.pp_if, m, BPF_D_OUT);
 2020 
 2021                 pppoe_output(sc, m);
 2022         }
 2023         PPPOE_UNLOCK(sc);
 2024 }
 2025 
 2026 #ifdef PPPOE_MPSAFE
 2027 static int
 2028 pppoe_transmit(struct ifnet *ifp, struct mbuf *m)
 2029 {
 2030         struct pppoe_softc *sc = (void *)ifp;
 2031         uint8_t *p;
 2032         size_t len;
 2033 
 2034         if (m == NULL)
 2035                 return EINVAL;
 2036 
 2037         /* are we ready to process data yet? */
 2038         PPPOE_LOCK(sc, RW_READER);
 2039         if (sc->sc_state < PPPOE_STATE_SESSION) {
 2040                 PPPOE_UNLOCK(sc);
 2041                 m_freem(m);
 2042                 return ENOBUFS;
 2043         }
 2044 
 2045         len = m->m_pkthdr.len;
 2046         M_PREPEND(m, PPPOE_HEADERLEN, M_DONTWAIT);
 2047         if (m == NULL) {
 2048                 PPPOE_UNLOCK(sc);
 2049                 if_statinc(ifp, if_oerrors);
 2050                 return ENETDOWN;
 2051         }
 2052         p = mtod(m, uint8_t *);
 2053         PPPOE_ADD_HEADER(p, 0, sc->sc_session, len);
 2054 
 2055         bpf_mtap(&sc->sc_sppp.pp_if, m, BPF_D_OUT);
 2056 
 2057         pppoe_output(sc, m);
 2058         PPPOE_UNLOCK(sc);
 2059         return 0;
 2060 }
 2061 #endif /* PPPOE_MPSAFE */
 2062 
 2063 static void
 2064 pppoe_ifattach_hook(void *arg, unsigned long cmd, void *arg2)
 2065 {
 2066         struct ifnet *ifp = arg2;
 2067         struct pppoe_softc *sc;
 2068         DECLARE_SPLNET_VARIABLE;
 2069 
 2070         if (cmd != PFIL_IFNET_DETACH)
 2071                 return;
 2072 
 2073         ACQUIRE_SPLNET();
 2074         rw_enter(&pppoe_softc_list_lock, RW_READER);
 2075         LIST_FOREACH(sc, &pppoe_softc_list, sc_list) {
 2076                 PPPOE_LOCK(sc, RW_WRITER);
 2077                 if (sc->sc_eth_if != ifp) {
 2078                         PPPOE_UNLOCK(sc);
 2079                         continue;
 2080                 }
 2081                 if (sc->sc_sppp.pp_if.if_flags & IFF_UP) {
 2082                         sc->sc_sppp.pp_if.if_flags &= ~(IFF_UP|IFF_RUNNING);
 2083                         pppoe_printf(sc,
 2084                             "ethernet interface detached, going down\n");
 2085                 }
 2086                 sc->sc_eth_if = NULL;
 2087                 pppoe_clear_softc(sc, "ethernet interface detached");
 2088                 PPPOE_UNLOCK(sc);
 2089         }
 2090         rw_exit(&pppoe_softc_list_lock);
 2091         RELEASE_SPLNET();
 2092 }
 2093 
 2094 static void
 2095 pppoe_clear_softc(struct pppoe_softc *sc, const char *message)
 2096 {
 2097         KASSERT(PPPOE_WLOCKED(sc));
 2098 
 2099         /* stop timer */
 2100         callout_stop(&sc->sc_timeout);
 2101         pppoe_printf(sc, "session 0x%x terminated, %s\n",
 2102             sc->sc_session, message);
 2103 
 2104         /* fix our state */
 2105         sc->sc_state = PPPOE_STATE_INITIAL;
 2106 
 2107         PPPOE_UNLOCK(sc);
 2108 
 2109         /* signal upper layer */
 2110         sc->sc_sppp.pp_down(&sc->sc_sppp);
 2111 
 2112         PPPOE_LOCK(sc, RW_WRITER);
 2113 
 2114         /* clean up softc */
 2115         memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest));
 2116         if (sc->sc_ac_cookie) {
 2117                 free(sc->sc_ac_cookie, M_DEVBUF);
 2118                 sc->sc_ac_cookie = NULL;
 2119         }
 2120         if (sc->sc_relay_sid) {
 2121                 free(sc->sc_relay_sid, M_DEVBUF);
 2122                 sc->sc_relay_sid = NULL;
 2123         }
 2124         sc->sc_ac_cookie_len = 0;
 2125         sc->sc_session = 0;
 2126 }
 2127 
 2128 static void
 2129 pppoe_enqueue(struct ifqueue *inq, struct mbuf *m)
 2130 {
 2131         if (m->m_flags & M_PROMISC) {
 2132                 m_freem(m);
 2133                 return;
 2134         }
 2135 
 2136 #ifndef PPPOE_SERVER
 2137         if (m->m_flags & (M_MCAST | M_BCAST)) {
 2138                 m_freem(m);
 2139                 return;
 2140         }
 2141 #endif
 2142 
 2143         IFQ_LOCK(inq);
 2144         if (IF_QFULL(inq)) {
 2145                 IF_DROP(inq);
 2146                 IFQ_UNLOCK(inq);
 2147                 m_freem(m);
 2148         } else {
 2149                 IF_ENQUEUE(inq, m);
 2150                 IFQ_UNLOCK(inq);
 2151                 softint_schedule(pppoe_softintr);
 2152         }
 2153         return;
 2154 }
 2155 
 2156 void
 2157 pppoe_input(struct ifnet *ifp, struct mbuf *m)
 2158 {
 2159         pppoe_enqueue(&ppoeinq, m);
 2160         return;
 2161 }
 2162 
 2163 void
 2164 pppoedisc_input(struct ifnet *ifp, struct mbuf *m)
 2165 {
 2166         pppoe_enqueue(&ppoediscinq, m);
 2167         return;
 2168 }
 2169 
 2170 static void
 2171 sysctl_net_pppoe_setup(struct sysctllog **clog)
 2172 {
 2173         const struct sysctlnode *node = NULL;
 2174         extern pktq_rps_hash_func_t sppp_pktq_rps_hash_p;
 2175 
 2176         sppp_pktq_rps_hash_p = pktq_rps_hash_default;
 2177 
 2178         sysctl_createv(clog, 0, NULL, &node,
 2179             CTLFLAG_PERMANENT,
 2180             CTLTYPE_NODE, "pppoe",
 2181             SYSCTL_DESCR("PPPOE protocol"),
 2182             NULL, 0, NULL, 0,
 2183             CTL_NET, CTL_CREATE, CTL_EOL);
 2184 
 2185         if (node == NULL)
 2186                 return;
 2187 
 2188         sysctl_createv(clog, 0, &node, NULL,
 2189             CTLFLAG_PERMANENT | CTLFLAG_READWRITE,
 2190             CTLTYPE_BOOL, "term_unknown",
 2191             SYSCTL_DESCR("Terminate unknown sessions"),
 2192             NULL, 0, &pppoe_term_unknown, sizeof(pppoe_term_unknown),
 2193             CTL_CREATE, CTL_EOL);
 2194 
 2195         sysctl_createv(clog, 0, &node, NULL,
 2196             CTLFLAG_PERMANENT | CTLFLAG_READWRITE,
 2197             CTLTYPE_STRING, "rps_hash",
 2198             SYSCTL_DESCR("Interface rps hash function control"),
 2199             sysctl_pktq_rps_hash_handler, 0, (void *)&sppp_pktq_rps_hash_p,
 2200             PKTQ_RPS_HASH_NAME_LEN,
 2201             CTL_CREATE, CTL_EOL);
 2202 }
 2203 
 2204 /*
 2205  * Module infrastructure
 2206  */
 2207 #include "if_module.h"
 2208 
 2209 IF_MODULE(MODULE_CLASS_DRIVER, pppoe, "sppp_subr")

Cache object: 249070156533e6980ba4c693981b1fdf


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.