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