1 /* $NetBSD: if_pppoe.c,v 1.93 2008/10/15 20:08:33 scw Exp $ */
4 * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Martin Husemann <martin@NetBSD.org>.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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.
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.
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.93 2008/10/15 20:08:33 scw Exp $");
37 #include "opt_pfil_hooks.h"
38 #include "opt_pppoe.h"
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/kernel.h>
43 #include <sys/callout.h>
44 #include <sys/malloc.h>
46 #include <sys/socket.h>
48 #include <sys/ioctl.h>
49 #include <sys/kauth.h>
51 #include <sys/socketvar.h>
54 #include <net/if_types.h>
55 #include <net/if_ether.h>
56 #include <net/if_sppp.h>
57 #include <net/if_spppvar.h>
58 #include <net/if_pppoe.h>
65 #undef PPPOE_DEBUG /* XXX - remove this or make it an option */
66 /* #define PPPOE_DEBUG 1 */
80 #define PPPOE_HEADERLEN sizeof(struct pppoehdr)
81 #define PPPOE_OVERHEAD (PPPOE_HEADERLEN + 2)
82 #define PPPOE_VERTYPE 0x11 /* VER=1, TYPE = 1 */
84 #define PPPOE_TAG_EOL 0x0000 /* end of list */
85 #define PPPOE_TAG_SNAME 0x0101 /* service name */
86 #define PPPOE_TAG_ACNAME 0x0102 /* access concentrator name */
87 #define PPPOE_TAG_HUNIQUE 0x0103 /* host unique */
88 #define PPPOE_TAG_ACCOOKIE 0x0104 /* AC cookie */
89 #define PPPOE_TAG_VENDOR 0x0105 /* vendor specific */
90 #define PPPOE_TAG_RELAYSID 0x0110 /* relay session id */
91 #define PPPOE_TAG_SNAME_ERR 0x0201 /* service name error */
92 #define PPPOE_TAG_ACSYS_ERR 0x0202 /* AC system error */
93 #define PPPOE_TAG_GENERIC_ERR 0x0203 /* gerneric error */
95 #define PPPOE_CODE_PADI 0x09 /* Active Discovery Initiation */
96 #define PPPOE_CODE_PADO 0x07 /* Active Discovery Offer */
97 #define PPPOE_CODE_PADR 0x19 /* Active Discovery Request */
98 #define PPPOE_CODE_PADS 0x65 /* Active Discovery Session confirmation */
99 #define PPPOE_CODE_PADT 0xA7 /* Active Discovery Terminate */
101 /* two byte PPP protocol discriminator, then IP data */
102 #define PPPOE_MAXMTU (ETHERMTU - PPPOE_OVERHEAD)
104 /* Add a 16 bit unsigned value to a buffer pointed to by PTR */
105 #define PPPOE_ADD_16(PTR, VAL) \
106 *(PTR)++ = (VAL) / 256; \
107 *(PTR)++ = (VAL) % 256
109 /* Add a complete PPPoE header to the buffer pointed to by PTR */
110 #define PPPOE_ADD_HEADER(PTR, CODE, SESS, LEN) \
111 *(PTR)++ = PPPOE_VERTYPE; \
113 PPPOE_ADD_16(PTR, SESS); \
114 PPPOE_ADD_16(PTR, LEN)
116 #define PPPOE_DISC_TIMEOUT (hz*5) /* base for quick timeout calculation */
117 #define PPPOE_SLOW_RETRY (hz*60) /* persistent retry interval */
118 #define PPPOE_RECON_FAST (hz*15) /* first retry after auth failure */
119 #define PPPOE_RECON_IMMEDIATE (hz/10) /* "no delay" reconnect */
120 #define PPPOE_DISC_MAXPADI 4 /* retry PADI four times (quickly) */
121 #define PPPOE_DISC_MAXPADR 2 /* retry PADR twice */
124 /* from if_spppsubr.c */
125 #define IFF_PASSIVE IFF_LINK0 /* wait passively for connection */
129 struct sppp sc_sppp
; /* contains a struct ifnet as first element */
130 LIST_ENTRY(pppoe_softc
) sc_list
;
131 struct ifnet
*sc_eth_if
; /* ethernet interface we are using */
133 int sc_state
; /* discovery phase or session connected */
134 struct ether_addr sc_dest
; /* hardware address of concentrator */
135 uint16_t sc_session
; /* PPPoE session id */
137 char *sc_service_name
; /* if != NULL: requested name of service */
138 char *sc_concentrator_name
; /* if != NULL: requested concentrator id */
139 uint8_t *sc_ac_cookie
; /* content of AC cookie we must echo back */
140 size_t sc_ac_cookie_len
; /* length of cookie data */
141 uint8_t *sc_relay_sid
; /* content of relay SID we must echo back */
142 size_t sc_relay_sid_len
; /* length of relay SID data */
144 uint8_t *sc_hunique
; /* content of host unique we must echo back */
145 size_t sc_hunique_len
; /* length of host unique */
147 callout_t sc_timeout
; /* timeout while not in session state */
148 int sc_padi_retried
; /* number of PADI retries already done */
149 int sc_padr_retried
; /* number of PADR retries already done */
152 /* incoming traffic will be queued here */
153 struct ifqueue ppoediscinq
= { .ifq_maxlen
= IFQ_MAXLEN
};
154 struct ifqueue ppoeinq
= { .ifq_maxlen
= IFQ_MAXLEN
};
156 void *pppoe_softintr
= NULL
;
157 static void pppoe_softintr_handler(void *);
159 extern int sppp_ioctl(struct ifnet
*, unsigned long, void *);
162 static void pppoe_input(void);
163 static void pppoe_disc_input(struct mbuf
*);
164 static void pppoe_dispatch_disc_pkt(struct mbuf
*, int);
165 static void pppoe_data_input(struct mbuf
*);
167 /* management routines */
168 void pppoeattach(int);
169 static int pppoe_connect(struct pppoe_softc
*);
170 static int pppoe_disconnect(struct pppoe_softc
*);
171 static void pppoe_abort_connect(struct pppoe_softc
*);
172 static int pppoe_ioctl(struct ifnet
*, unsigned long, void *);
173 static void pppoe_tls(struct sppp
*);
174 static void pppoe_tlf(struct sppp
*);
175 static void pppoe_start(struct ifnet
*);
176 static void pppoe_clear_softc(struct pppoe_softc
*, const char *);
178 /* internal timeout handling */
179 static void pppoe_timeout(void *);
181 /* sending actual protocol controll packets */
182 static int pppoe_send_padi(struct pppoe_softc
*);
183 static int pppoe_send_padr(struct pppoe_softc
*);
185 static int pppoe_send_pado(struct pppoe_softc
*);
186 static int pppoe_send_pads(struct pppoe_softc
*);
188 static int pppoe_send_padt(struct ifnet
*, u_int
, const uint8_t *);
191 static int pppoe_output(struct pppoe_softc
*, struct mbuf
*);
193 /* internal helper functions */
194 static struct pppoe_softc
* pppoe_find_softc_by_session(u_int
, struct ifnet
*);
195 static struct pppoe_softc
* pppoe_find_softc_by_hunique(uint8_t *, size_t, struct ifnet
*);
196 static struct mbuf
*pppoe_get_mbuf(size_t len
);
199 static int pppoe_ifattach_hook(void *, struct mbuf
**, struct ifnet
*, int);
202 static LIST_HEAD(pppoe_softc_head
, pppoe_softc
) pppoe_softc_list
;
204 static int pppoe_clone_create(struct if_clone
*, int);
205 static int pppoe_clone_destroy(struct ifnet
*);
207 static struct if_clone pppoe_cloner
=
208 IF_CLONE_INITIALIZER("pppoe", pppoe_clone_create
, pppoe_clone_destroy
);
212 pppoeattach(int count
)
214 LIST_INIT(&pppoe_softc_list
);
215 if_clone_attach(&pppoe_cloner
);
217 pppoe_softintr
= softint_establish(SOFTINT_NET
, pppoe_softintr_handler
, NULL
);
221 pppoe_clone_create(struct if_clone
*ifc
, int unit
)
223 struct pppoe_softc
*sc
;
225 sc
= malloc(sizeof(struct pppoe_softc
), M_DEVBUF
, M_WAITOK
|M_ZERO
);
227 if_initname(&sc
->sc_sppp
.pp_if
, "pppoe", unit
);
228 sc
->sc_sppp
.pp_if
.if_softc
= sc
;
229 sc
->sc_sppp
.pp_if
.if_mtu
= PPPOE_MAXMTU
;
230 sc
->sc_sppp
.pp_if
.if_flags
= IFF_SIMPLEX
|IFF_POINTOPOINT
|IFF_MULTICAST
;
231 sc
->sc_sppp
.pp_if
.if_type
= IFT_PPP
;
232 sc
->sc_sppp
.pp_if
.if_hdrlen
= sizeof(struct ether_header
) + PPPOE_HEADERLEN
;
233 sc
->sc_sppp
.pp_if
.if_dlt
= DLT_PPP_ETHER
;
234 sc
->sc_sppp
.pp_flags
|= PP_KEEPALIVE
| /* use LCP keepalive */
235 PP_NOFRAMING
; /* no serial encapsulation */
236 sc
->sc_sppp
.pp_if
.if_ioctl
= pppoe_ioctl
;
237 IFQ_SET_MAXLEN(&sc
->sc_sppp
.pp_if
.if_snd
, IFQ_MAXLEN
);
238 IFQ_SET_READY(&sc
->sc_sppp
.pp_if
.if_snd
);
240 /* changed to real address later */
241 memcpy(&sc
->sc_dest
, etherbroadcastaddr
, sizeof(sc
->sc_dest
));
243 callout_init(&sc
->sc_timeout
, 0);
245 sc
->sc_sppp
.pp_if
.if_start
= pppoe_start
;
246 sc
->sc_sppp
.pp_tls
= pppoe_tls
;
247 sc
->sc_sppp
.pp_tlf
= pppoe_tlf
;
248 sc
->sc_sppp
.pp_framebytes
= PPPOE_HEADERLEN
; /* framing added to ppp packets */
250 if_attach(&sc
->sc_sppp
.pp_if
);
251 sppp_attach(&sc
->sc_sppp
.pp_if
);
254 bpfattach(&sc
->sc_sppp
.pp_if
, DLT_PPP_ETHER
, 0);
257 if (LIST_EMPTY(&pppoe_softc_list
))
258 pfil_add_hook(pppoe_ifattach_hook
, NULL
,
259 PFIL_IFNET
|PFIL_WAITOK
, &if_pfil
);
261 LIST_INSERT_HEAD(&pppoe_softc_list
, sc
, sc_list
);
266 pppoe_clone_destroy(struct ifnet
*ifp
)
268 struct pppoe_softc
* sc
= ifp
->if_softc
;
270 callout_stop(&sc
->sc_timeout
);
271 LIST_REMOVE(sc
, sc_list
);
273 if (LIST_EMPTY(&pppoe_softc_list
))
274 pfil_remove_hook(pppoe_ifattach_hook
, NULL
,
275 PFIL_IFNET
|PFIL_WAITOK
, &if_pfil
);
280 sppp_detach(&sc
->sc_sppp
.pp_if
);
282 if (sc
->sc_concentrator_name
)
283 free(sc
->sc_concentrator_name
, M_DEVBUF
);
284 if (sc
->sc_service_name
)
285 free(sc
->sc_service_name
, M_DEVBUF
);
286 if (sc
->sc_ac_cookie
)
287 free(sc
->sc_ac_cookie
, M_DEVBUF
);
288 if (sc
->sc_relay_sid
)
289 free(sc
->sc_relay_sid
, M_DEVBUF
);
290 callout_destroy(&sc
->sc_timeout
);
297 * Find the interface handling the specified session.
298 * Note: O(number of sessions open), this is a client-side only, mean
299 * and lean implementation, so number of open sessions typically should
302 static struct pppoe_softc
*
303 pppoe_find_softc_by_session(u_int session
, struct ifnet
*rcvif
)
305 struct pppoe_softc
*sc
;
310 LIST_FOREACH(sc
, &pppoe_softc_list
, sc_list
) {
311 if (sc
->sc_state
== PPPOE_STATE_SESSION
312 && sc
->sc_session
== session
313 && sc
->sc_eth_if
== rcvif
)
319 /* Check host unique token passed and return appropriate softc pointer,
320 * or NULL if token is bogus. */
321 static struct pppoe_softc
*
322 pppoe_find_softc_by_hunique(uint8_t *token
, size_t len
, struct ifnet
*rcvif
)
324 struct pppoe_softc
*sc
, *t
;
326 if (LIST_EMPTY(&pppoe_softc_list
))
329 if (len
!= sizeof sc
)
331 memcpy(&t
, token
, len
);
333 LIST_FOREACH(sc
, &pppoe_softc_list
, sc_list
)
338 printf("pppoe: alien host unique tag, no session found\n");
343 /* should be safe to access *sc now */
344 if (sc
->sc_state
< PPPOE_STATE_PADI_SENT
|| sc
->sc_state
>= PPPOE_STATE_SESSION
) {
345 printf("%s: host unique tag found, but it belongs to a connection in state %d\n",
346 sc
->sc_sppp
.pp_if
.if_xname
, sc
->sc_state
);
349 if (sc
->sc_eth_if
!= rcvif
) {
350 printf("%s: wrong interface, not accepting host unique\n",
351 sc
->sc_sppp
.pp_if
.if_xname
);
358 pppoe_softintr_handler(void *dummy
)
360 /* called at splsoftnet() */
361 mutex_enter(softnet_lock
);
363 mutex_exit(softnet_lock
);
366 /* called at appropriate protection level */
371 int s
, disc_done
, data_done
;
378 IF_DEQUEUE(&ppoediscinq
, m
);
380 if (m
== NULL
) break;
387 IF_DEQUEUE(&ppoeinq
, m
);
389 if (m
== NULL
) break;
393 } while (disc_done
|| data_done
);
396 /* analyze and handle a single received packet while not in session state */
398 pppoe_dispatch_disc_pkt(struct mbuf
*m
, int off
)
401 uint16_t session
, plen
;
402 struct pppoe_softc
*sc
;
403 const char *err_msg
, *devname
;
406 size_t ac_cookie_len
;
408 size_t relay_sid_len
;
416 int noff
, err
, errortag
;
417 struct ether_header
*eh
;
419 devname
= "pppoe"; /* as long as we don't know which instance */
422 if (m
->m_len
< sizeof(*eh
)) {
423 m
= m_pullup(m
, sizeof(*eh
));
427 eh
= mtod(m
, struct ether_header
*);
439 if (m
->m_pkthdr
.len
- off
<= PPPOE_HEADERLEN
) {
440 printf("pppoe: packet too short: %d\n", m
->m_pkthdr
.len
);
444 n
= m_pulldown(m
, off
, sizeof(*ph
), &noff
);
446 printf("pppoe: could not get PPPoE header\n");
450 ph
= (struct pppoehdr
*)(mtod(n
, char *) + noff
);
451 if (ph
->vertype
!= PPPOE_VERTYPE
) {
452 printf("pppoe: unknown version/type packet: 0x%x\n",
456 session
= ntohs(ph
->session
);
457 plen
= ntohs(ph
->plen
);
460 if (plen
+ off
> m
->m_pkthdr
.len
) {
461 printf("pppoe: packet content does not fit: data available = %d, packet size = %u\n",
462 m
->m_pkthdr
.len
- off
, plen
);
465 m_adj(m
, off
+ plen
- m
->m_pkthdr
.len
); /* ignore trailing garbage */
469 while (off
+ sizeof(*pt
) <= m
->m_pkthdr
.len
) {
470 n
= m_pulldown(m
, off
, sizeof(*pt
), &noff
);
472 printf("%s: parse error\n", devname
);
476 pt
= (struct pppoetag
*)(mtod(n
, char *) + noff
);
477 tag
= ntohs(pt
->tag
);
478 len
= ntohs(pt
->len
);
479 if (off
+ len
+ sizeof(*pt
) > m
->m_pkthdr
.len
) {
480 printf("pppoe: tag 0x%x len 0x%x is too long\n",
487 case PPPOE_TAG_SNAME
:
489 case PPPOE_TAG_ACNAME
:
491 if (sc
!= NULL
&& len
> 0) {
492 error
= malloc(len
+1, M_TEMP
, M_NOWAIT
);
494 n
= m_pulldown(m
, off
+ sizeof(*pt
),
498 mtod(n
, char*) + noff
,
502 printf("%s: connected to %s\n",
508 case PPPOE_TAG_HUNIQUE
:
511 n
= m_pulldown(m
, off
+ sizeof(*pt
), len
, &noff
);
514 err_msg
= "TAG HUNIQUE ERROR";
518 hunique
= mtod(n
, uint8_t *) + noff
;
521 sc
= pppoe_find_softc_by_hunique(mtod(n
, char *) + noff
,
522 len
, m
->m_pkthdr
.rcvif
);
524 devname
= sc
->sc_sppp
.pp_if
.if_xname
;
526 case PPPOE_TAG_ACCOOKIE
:
527 if (ac_cookie
== NULL
) {
528 n
= m_pulldown(m
, off
+ sizeof(*pt
), len
,
531 err_msg
= "TAG ACCOOKIE ERROR";
535 ac_cookie
= mtod(n
, char *) + noff
;
539 case PPPOE_TAG_RELAYSID
:
540 if (relay_sid
== NULL
) {
541 n
= m_pulldown(m
, off
+ sizeof(*pt
), len
,
544 err_msg
= "TAG RELAYSID ERROR";
548 relay_sid
= mtod(n
, char *) + noff
;
552 case PPPOE_TAG_SNAME_ERR
:
553 err_msg
= "SERVICE NAME ERROR";
556 case PPPOE_TAG_ACSYS_ERR
:
557 err_msg
= "AC SYSTEM ERROR";
560 case PPPOE_TAG_GENERIC_ERR
:
561 err_msg
= "GENERIC ERROR";
567 if (errortag
&& len
) {
568 error
= malloc(len
+1, M_TEMP
, M_NOWAIT
);
569 n
= m_pulldown(m
, off
+ sizeof(*pt
), len
,
573 mtod(n
, char *) + noff
, len
);
578 printf("%s: %s: %s\n", devname
,
582 printf("%s: %s\n", devname
, err_msg
);
583 if (errortag
|| m
== NULL
)
586 off
+= sizeof(*pt
) + len
;
590 case PPPOE_CODE_PADI
:
593 * got service name, concentrator name, and/or host unique.
594 * ignore if we have no interfaces with IFF_PASSIVE|IFF_UP.
596 if (LIST_EMPTY(&pppoe_softc_list
))
598 LIST_FOREACH(sc
, &pppoe_softc_list
, sc_list
) {
599 if (!(sc
->sc_sppp
.pp_if
.if_flags
& IFF_UP
))
601 if (!(sc
->sc_sppp
.pp_if
.if_flags
& IFF_PASSIVE
))
603 if (sc
->sc_state
== PPPOE_STATE_INITIAL
)
607 /* printf("pppoe: free passive interface is not found\n");*/
612 free(sc
->sc_hunique
, M_DEVBUF
);
613 sc
->sc_hunique
= malloc(hunique_len
, M_DEVBUF
,
615 if (sc
->sc_hunique
== NULL
)
617 sc
->sc_hunique_len
= hunique_len
;
618 memcpy(sc
->sc_hunique
, hunique
, hunique_len
);
620 memcpy(&sc
->sc_dest
, eh
->ether_shost
, sizeof sc
->sc_dest
);
621 sc
->sc_state
= PPPOE_STATE_PADO_SENT
;
624 #endif /* PPPOE_SERVER */
625 case PPPOE_CODE_PADR
:
628 * get sc from ac_cookie if IFF_PASSIVE
630 if (ac_cookie
== NULL
) {
631 /* be quiet if there is not a single pppoe instance */
632 printf("pppoe: received PADR but not includes ac_cookie\n");
635 sc
= pppoe_find_softc_by_hunique(ac_cookie
,
639 /* be quiet if there is not a single pppoe instance */
640 if (!LIST_EMPTY(&pppoe_softc_list
))
641 printf("pppoe: received PADR but could not find request for it\n");
644 if (sc
->sc_state
!= PPPOE_STATE_PADO_SENT
) {
645 printf("%s: received unexpected PADR\n",
646 sc
->sc_sppp
.pp_if
.if_xname
);
651 free(sc
->sc_hunique
, M_DEVBUF
);
652 sc
->sc_hunique
= malloc(hunique_len
, M_DEVBUF
,
654 if (sc
->sc_hunique
== NULL
)
656 sc
->sc_hunique_len
= hunique_len
;
657 memcpy(sc
->sc_hunique
, hunique
, hunique_len
);
660 sc
->sc_state
= PPPOE_STATE_SESSION
;
661 sc
->sc_sppp
.pp_up(&sc
->sc_sppp
);
664 /* ignore, we are no access concentrator */
666 #endif /* PPPOE_SERVER */
667 case PPPOE_CODE_PADO
:
669 /* be quiet if there is not a single pppoe instance */
670 if (!LIST_EMPTY(&pppoe_softc_list
))
671 printf("pppoe: received PADO but could not find request for it\n");
674 if (sc
->sc_state
!= PPPOE_STATE_PADI_SENT
) {
675 printf("%s: received unexpected PADO\n",
676 sc
->sc_sppp
.pp_if
.if_xname
);
680 if (sc
->sc_ac_cookie
)
681 free(sc
->sc_ac_cookie
, M_DEVBUF
);
682 sc
->sc_ac_cookie
= malloc(ac_cookie_len
, M_DEVBUF
,
684 if (sc
->sc_ac_cookie
== NULL
) {
685 printf("%s: FATAL: could not allocate memory "
687 sc
->sc_sppp
.pp_if
.if_xname
);
690 sc
->sc_ac_cookie_len
= ac_cookie_len
;
691 memcpy(sc
->sc_ac_cookie
, ac_cookie
, ac_cookie_len
);
694 if (sc
->sc_relay_sid
)
695 free(sc
->sc_relay_sid
, M_DEVBUF
);
696 sc
->sc_relay_sid
= malloc(relay_sid_len
, M_DEVBUF
,
698 if (sc
->sc_relay_sid
== NULL
) {
699 printf("%s: FATAL: could not allocate memory "
701 sc
->sc_sppp
.pp_if
.if_xname
);
704 sc
->sc_relay_sid_len
= relay_sid_len
;
705 memcpy(sc
->sc_relay_sid
, relay_sid
, relay_sid_len
);
707 memcpy(&sc
->sc_dest
, eh
->ether_shost
, sizeof sc
->sc_dest
);
708 callout_stop(&sc
->sc_timeout
);
709 sc
->sc_padr_retried
= 0;
710 sc
->sc_state
= PPPOE_STATE_PADR_SENT
;
711 if ((err
= pppoe_send_padr(sc
)) != 0) {
712 if (sc
->sc_sppp
.pp_if
.if_flags
& IFF_DEBUG
)
713 printf("%s: failed to send PADR, "
714 "error=%d\n", sc
->sc_sppp
.pp_if
.if_xname
,
717 callout_reset(&sc
->sc_timeout
,
718 PPPOE_DISC_TIMEOUT
* (1 + sc
->sc_padr_retried
),
721 case PPPOE_CODE_PADS
:
724 sc
->sc_session
= session
;
725 callout_stop(&sc
->sc_timeout
);
726 if (sc
->sc_sppp
.pp_if
.if_flags
& IFF_DEBUG
)
727 printf("%s: session 0x%x connected\n",
728 sc
->sc_sppp
.pp_if
.if_xname
, session
);
729 sc
->sc_state
= PPPOE_STATE_SESSION
;
730 sc
->sc_sppp
.pp_up(&sc
->sc_sppp
); /* notify upper layers */
732 case PPPOE_CODE_PADT
:
735 pppoe_clear_softc(sc
, "received PADT");
738 printf("%s: unknown code (0x%04x) session = 0x%04x\n",
739 sc
? sc
->sc_sppp
.pp_if
.if_xname
: "pppoe",
751 pppoe_disc_input(struct mbuf
*m
)
754 /* avoid error messages if there is not a single pppoe instance */
755 if (!LIST_EMPTY(&pppoe_softc_list
)) {
756 KASSERT(m
->m_flags
& M_PKTHDR
);
757 pppoe_dispatch_disc_pkt(m
, 0);
763 pppoe_data_input(struct mbuf
*m
)
765 uint16_t session
, plen
;
766 struct pppoe_softc
*sc
;
768 #ifdef PPPOE_TERM_UNKNOWN_SESSIONS
769 uint8_t shost
[ETHER_ADDR_LEN
];
772 KASSERT(m
->m_flags
& M_PKTHDR
);
774 #ifdef PPPOE_TERM_UNKNOWN_SESSIONS
775 memcpy(shost
, mtod(m
, struct ether_header
*)->ether_shost
, ETHER_ADDR_LEN
);
777 m_adj(m
, sizeof(struct ether_header
));
778 if (m
->m_pkthdr
.len
<= PPPOE_HEADERLEN
) {
779 printf("pppoe (data): dropping too short packet: %d bytes\n",
784 if (m
->m_len
< sizeof(*ph
)) {
785 m
= m_pullup(m
, sizeof(*ph
));
787 printf("pppoe: could not get PPPoE header\n");
791 ph
= mtod(m
, struct pppoehdr
*);
793 if (ph
->vertype
!= PPPOE_VERTYPE
) {
794 printf("pppoe (data): unknown version/type packet: 0x%x\n",
801 session
= ntohs(ph
->session
);
802 sc
= pppoe_find_softc_by_session(session
, m
->m_pkthdr
.rcvif
);
804 #ifdef PPPOE_TERM_UNKNOWN_SESSIONS
805 printf("pppoe: input for unknown session 0x%x, sending PADT\n",
807 pppoe_send_padt(m
->m_pkthdr
.rcvif
, session
, shost
);
812 plen
= ntohs(ph
->plen
);
815 if(sc
->sc_sppp
.pp_if
.if_bpf
)
816 bpf_mtap(sc
->sc_sppp
.pp_if
.if_bpf
, m
);
819 m_adj(m
, PPPOE_HEADERLEN
);
825 printf("%s: pkthdr.len=%d, pppoe.len=%d",
826 sc
->sc_sppp
.pp_if
.if_xname
,
827 m
->m_pkthdr
.len
, plen
);
830 printf(" l=%d", p
->m_len
);
837 if (m
->m_pkthdr
.len
< plen
)
840 /* fix incoming interface pointer (not the raw ethernet interface anymore) */
841 m
->m_pkthdr
.rcvif
= &sc
->sc_sppp
.pp_if
;
843 /* pass packet up and account for it */
844 sc
->sc_sppp
.pp_if
.if_ipackets
++;
845 sppp_input(&sc
->sc_sppp
.pp_if
, m
);
853 pppoe_output(struct pppoe_softc
*sc
, struct mbuf
*m
)
856 struct ether_header
*eh
;
859 if (sc
->sc_eth_if
== NULL
) {
864 memset(&dst
, 0, sizeof dst
);
865 dst
.sa_family
= AF_UNSPEC
;
866 eh
= (struct ether_header
*)&dst
.sa_data
;
867 etype
= sc
->sc_state
== PPPOE_STATE_SESSION
? ETHERTYPE_PPPOE
: ETHERTYPE_PPPOEDISC
;
868 eh
->ether_type
= htons(etype
);
869 memcpy(&eh
->ether_dhost
, &sc
->sc_dest
, sizeof sc
->sc_dest
);
872 printf("%s (%x) state=%d, session=0x%x output -> %s, len=%d\n",
873 sc
->sc_sppp
.pp_if
.if_xname
, etype
,
874 sc
->sc_state
, sc
->sc_session
,
875 ether_sprintf((const unsigned char *)&sc
->sc_dest
), m
->m_pkthdr
.len
);
878 m
->m_flags
&= ~(M_BCAST
|M_MCAST
);
879 sc
->sc_sppp
.pp_if
.if_opackets
++;
880 return sc
->sc_eth_if
->if_output(sc
->sc_eth_if
, m
, &dst
, NULL
);
884 pppoe_ioctl(struct ifnet
*ifp
, unsigned long cmd
, void *data
)
886 struct lwp
*l
= curlwp
; /* XXX */
887 struct pppoe_softc
*sc
= (struct pppoe_softc
*)ifp
;
888 struct ifreq
*ifr
= data
;
894 struct pppoediscparms
*parms
= (struct pppoediscparms
*)data
;
895 if (kauth_authorize_network(l
->l_cred
, KAUTH_NETWORK_INTERFACE
,
896 KAUTH_REQ_NETWORK_INTERFACE_SETPRIV
, ifp
, (void *)cmd
,
899 if (parms
->eth_ifname
[0] != 0) {
900 struct ifnet
*eth_if
;
902 eth_if
= ifunit(parms
->eth_ifname
);
903 if (eth_if
== NULL
|| eth_if
->if_dlt
!= DLT_EN10MB
) {
904 sc
->sc_eth_if
= NULL
;
908 if (sc
->sc_sppp
.pp_if
.if_mtu
>
909 eth_if
->if_mtu
- PPPOE_OVERHEAD
) {
910 sc
->sc_sppp
.pp_if
.if_mtu
= eth_if
->if_mtu
-
913 sc
->sc_eth_if
= eth_if
;
915 if (parms
->ac_name
!= NULL
) {
917 char *b
= malloc(parms
->ac_name_len
+ 1, M_DEVBUF
,
921 error
= copyinstr(parms
->ac_name
, b
,
922 parms
->ac_name_len
+1, &s
);
927 if (s
!= parms
->ac_name_len
+1) {
931 if (sc
->sc_concentrator_name
)
932 free(sc
->sc_concentrator_name
, M_DEVBUF
);
933 sc
->sc_concentrator_name
= b
;
935 if (parms
->service_name
!= NULL
) {
937 char *b
= malloc(parms
->service_name_len
+ 1, M_DEVBUF
,
941 error
= copyinstr(parms
->service_name
, b
,
942 parms
->service_name_len
+1, &s
);
947 if (s
!= parms
->service_name_len
+1) {
951 if (sc
->sc_service_name
)
952 free(sc
->sc_service_name
, M_DEVBUF
);
953 sc
->sc_service_name
= b
;
960 struct pppoediscparms
*parms
= (struct pppoediscparms
*)data
;
961 memset(parms
, 0, sizeof *parms
);
963 strncpy(parms
->ifname
, sc
->sc_eth_if
->if_xname
, IFNAMSIZ
);
967 case PPPOEGETSESSION
:
969 struct pppoeconnectionstate
*state
= (struct pppoeconnectionstate
*)data
;
970 state
->state
= sc
->sc_state
;
971 state
->session_id
= sc
->sc_session
;
972 state
->padi_retry_no
= sc
->sc_padi_retried
;
973 state
->padr_retry_no
= sc
->sc_padr_retried
;
979 * Prevent running re-establishment timers overriding
980 * administrators choice.
982 if ((ifr
->ifr_flags
& IFF_UP
) == 0
983 && sc
->sc_state
>= PPPOE_STATE_PADI_SENT
984 && sc
->sc_state
< PPPOE_STATE_SESSION
) {
985 callout_stop(&sc
->sc_timeout
);
986 sc
->sc_state
= PPPOE_STATE_INITIAL
;
987 sc
->sc_padi_retried
= 0;
988 sc
->sc_padr_retried
= 0;
989 memcpy(&sc
->sc_dest
, etherbroadcastaddr
,
990 sizeof(sc
->sc_dest
));
992 return sppp_ioctl(ifp
, cmd
, data
);
994 if (ifr
->ifr_mtu
> (sc
->sc_eth_if
== NULL
?
995 PPPOE_MAXMTU
: (sc
->sc_eth_if
->if_mtu
- PPPOE_OVERHEAD
))) {
1000 return sppp_ioctl(ifp
, cmd
, data
);
1006 * Allocate a mbuf/cluster with space to store the given data length
1007 * of payload, leaving space for prepending an ethernet header
1010 static struct mbuf
*
1011 pppoe_get_mbuf(size_t len
)
1015 MGETHDR(m
, M_DONTWAIT
, MT_DATA
);
1018 if (len
+ sizeof(struct ether_header
) > MHLEN
) {
1019 MCLGET(m
, M_DONTWAIT
);
1020 if ((m
->m_flags
& M_EXT
) == 0) {
1026 m
->m_data
+= sizeof(struct ether_header
);
1028 m
->m_pkthdr
.len
= len
;
1029 m
->m_pkthdr
.rcvif
= NULL
;
1035 pppoe_send_padi(struct pppoe_softc
*sc
)
1038 int len
, l1
= 0, l2
= 0; /* XXX: gcc */
1041 if (sc
->sc_state
>PPPOE_STATE_PADI_SENT
)
1042 panic("pppoe_send_padi in state %d", sc
->sc_state
);
1044 /* calculate length of frame (excluding ethernet header + pppoe header) */
1045 len
= 2 + 2 + 2 + 2 + sizeof sc
; /* service name tag is required, host unique is send too */
1046 if (sc
->sc_service_name
!= NULL
) {
1047 l1
= strlen(sc
->sc_service_name
);
1050 if (sc
->sc_concentrator_name
!= NULL
) {
1051 l2
= strlen(sc
->sc_concentrator_name
);
1055 /* allocate a buffer */
1056 m0
= pppoe_get_mbuf(len
+ PPPOE_HEADERLEN
); /* header len + payload len */
1061 p
= mtod(m0
, uint8_t *);
1062 PPPOE_ADD_HEADER(p
, PPPOE_CODE_PADI
, 0, len
);
1063 PPPOE_ADD_16(p
, PPPOE_TAG_SNAME
);
1064 if (sc
->sc_service_name
!= NULL
) {
1065 PPPOE_ADD_16(p
, l1
);
1066 memcpy(p
, sc
->sc_service_name
, l1
);
1071 if (sc
->sc_concentrator_name
!= NULL
) {
1072 PPPOE_ADD_16(p
, PPPOE_TAG_ACNAME
);
1073 PPPOE_ADD_16(p
, l2
);
1074 memcpy(p
, sc
->sc_concentrator_name
, l2
);
1077 PPPOE_ADD_16(p
, PPPOE_TAG_HUNIQUE
);
1078 PPPOE_ADD_16(p
, sizeof(sc
));
1079 memcpy(p
, &sc
, sizeof sc
);
1083 if (p
- mtod(m0
, uint8_t *) != len
+ PPPOE_HEADERLEN
)
1084 panic("pppoe_send_padi: garbled output len, should be %ld, is %ld",
1085 (long)(len
+ PPPOE_HEADERLEN
), (long)(p
- mtod(m0
, uint8_t *)));
1089 return pppoe_output(sc
, m0
);
1093 pppoe_timeout(void *arg
)
1095 int x
, retry_wait
, err
;
1096 struct pppoe_softc
*sc
= (struct pppoe_softc
*)arg
;
1099 printf("%s: timeout\n", sc
->sc_sppp
.pp_if
.if_xname
);
1102 switch (sc
->sc_state
) {
1103 case PPPOE_STATE_INITIAL
:
1104 /* delayed connect from pppoe_tls() */
1107 case PPPOE_STATE_PADI_SENT
:
1109 * We have two basic ways of retrying:
1110 * - Quick retry mode: try a few times in short sequence
1111 * - Slow retry mode: we already had a connection successfully
1112 * established and will try infinitely (without user
1114 * We only enter slow retry mode if IFF_LINK1 (aka autodial)
1118 /* initialize for quick retry mode */
1119 retry_wait
= PPPOE_DISC_TIMEOUT
* (1 + sc
->sc_padi_retried
);
1122 sc
->sc_padi_retried
++;
1123 if (sc
->sc_padi_retried
>= PPPOE_DISC_MAXPADI
) {
1124 if ((sc
->sc_sppp
.pp_if
.if_flags
& IFF_LINK1
) == 0) {
1125 /* slow retry mode */
1126 retry_wait
= PPPOE_SLOW_RETRY
;
1128 pppoe_abort_connect(sc
);
1133 if ((err
= pppoe_send_padi(sc
)) != 0) {
1134 sc
->sc_padi_retried
--;
1135 if (sc
->sc_sppp
.pp_if
.if_flags
& IFF_DEBUG
)
1136 printf("%s: failed to transmit PADI, "
1138 sc
->sc_sppp
.pp_if
.if_xname
, err
);
1140 callout_reset(&sc
->sc_timeout
, retry_wait
,
1145 case PPPOE_STATE_PADR_SENT
:
1147 sc
->sc_padr_retried
++;
1148 if (sc
->sc_padr_retried
>= PPPOE_DISC_MAXPADR
) {
1149 memcpy(&sc
->sc_dest
, etherbroadcastaddr
,
1150 sizeof(sc
->sc_dest
));
1151 sc
->sc_state
= PPPOE_STATE_PADI_SENT
;
1152 sc
->sc_padr_retried
= 0;
1153 if ((err
= pppoe_send_padi(sc
)) != 0) {
1154 if (sc
->sc_sppp
.pp_if
.if_flags
& IFF_DEBUG
)
1155 printf("%s: failed to send PADI"
1157 sc
->sc_sppp
.pp_if
.if_xname
,
1160 callout_reset(&sc
->sc_timeout
,
1161 PPPOE_DISC_TIMEOUT
* (1 + sc
->sc_padi_retried
),
1166 if ((err
= pppoe_send_padr(sc
)) != 0) {
1167 sc
->sc_padr_retried
--;
1168 if (sc
->sc_sppp
.pp_if
.if_flags
& IFF_DEBUG
)
1169 printf("%s: failed to send PADR, "
1170 "error=%d\n", sc
->sc_sppp
.pp_if
.if_xname
,
1173 callout_reset(&sc
->sc_timeout
,
1174 PPPOE_DISC_TIMEOUT
* (1 + sc
->sc_padr_retried
),
1178 case PPPOE_STATE_CLOSING
:
1179 pppoe_disconnect(sc
);
1182 return; /* all done, work in peace */
1186 /* Start a connection (i.e. initiate discovery phase) */
1188 pppoe_connect(struct pppoe_softc
*sc
)
1192 if (sc
->sc_state
!= PPPOE_STATE_INITIAL
)
1196 /* wait PADI if IFF_PASSIVE */
1197 if ((sc
->sc_sppp
.pp_if
.if_flags
& IFF_PASSIVE
))
1201 /* save state, in case we fail to send PADI */
1202 sc
->sc_state
= PPPOE_STATE_PADI_SENT
;
1203 sc
->sc_padr_retried
= 0;
1204 err
= pppoe_send_padi(sc
);
1205 if (err
!= 0 && sc
->sc_sppp
.pp_if
.if_flags
& IFF_DEBUG
)
1206 printf("%s: failed to send PADI, error=%d\n",
1207 sc
->sc_sppp
.pp_if
.if_xname
, err
);
1208 callout_reset(&sc
->sc_timeout
, PPPOE_DISC_TIMEOUT
, pppoe_timeout
, sc
);
1215 pppoe_disconnect(struct pppoe_softc
*sc
)
1221 if (sc
->sc_state
< PPPOE_STATE_SESSION
)
1224 if (sc
->sc_sppp
.pp_if
.if_flags
& IFF_DEBUG
)
1225 printf("%s: disconnecting\n",
1226 sc
->sc_sppp
.pp_if
.if_xname
);
1227 err
= pppoe_send_padt(sc
->sc_eth_if
, sc
->sc_session
, (const uint8_t *)&sc
->sc_dest
);
1231 sc
->sc_state
= PPPOE_STATE_INITIAL
;
1232 memcpy(&sc
->sc_dest
, etherbroadcastaddr
, sizeof(sc
->sc_dest
));
1233 if (sc
->sc_ac_cookie
) {
1234 free(sc
->sc_ac_cookie
, M_DEVBUF
);
1235 sc
->sc_ac_cookie
= NULL
;
1237 sc
->sc_ac_cookie_len
= 0;
1238 if (sc
->sc_relay_sid
) {
1239 free(sc
->sc_relay_sid
, M_DEVBUF
);
1240 sc
->sc_relay_sid
= NULL
;
1242 sc
->sc_relay_sid_len
= 0;
1244 if (sc
->sc_hunique
) {
1245 free(sc
->sc_hunique
, M_DEVBUF
);
1246 sc
->sc_hunique
= NULL
;
1248 sc
->sc_hunique_len
= 0;
1252 /* notify upper layer */
1253 sc
->sc_sppp
.pp_down(&sc
->sc_sppp
);
1260 /* Connection attempt aborted */
1262 pppoe_abort_connect(struct pppoe_softc
*sc
)
1264 printf("%s: could not establish connection\n",
1265 sc
->sc_sppp
.pp_if
.if_xname
);
1266 sc
->sc_state
= PPPOE_STATE_CLOSING
;
1268 /* notify upper layer */
1269 sc
->sc_sppp
.pp_down(&sc
->sc_sppp
);
1271 /* clear connection state */
1272 memcpy(&sc
->sc_dest
, etherbroadcastaddr
, sizeof(sc
->sc_dest
));
1273 sc
->sc_state
= PPPOE_STATE_INITIAL
;
1276 /* Send a PADR packet */
1278 pppoe_send_padr(struct pppoe_softc
*sc
)
1282 size_t len
, l1
= 0; /* XXX: gcc */
1284 if (sc
->sc_state
!= PPPOE_STATE_PADR_SENT
)
1287 len
= 2 + 2 + 2 + 2 + sizeof(sc
); /* service name, host unique */
1288 if (sc
->sc_service_name
!= NULL
) { /* service name tag maybe empty */
1289 l1
= strlen(sc
->sc_service_name
);
1292 if (sc
->sc_ac_cookie_len
> 0)
1293 len
+= 2 + 2 + sc
->sc_ac_cookie_len
; /* AC cookie */
1294 if (sc
->sc_relay_sid_len
> 0)
1295 len
+= 2 + 2 + sc
->sc_relay_sid_len
; /* Relay SID */
1296 m0
= pppoe_get_mbuf(len
+ PPPOE_HEADERLEN
);
1299 p
= mtod(m0
, uint8_t *);
1300 PPPOE_ADD_HEADER(p
, PPPOE_CODE_PADR
, 0, len
);
1301 PPPOE_ADD_16(p
, PPPOE_TAG_SNAME
);
1302 if (sc
->sc_service_name
!= NULL
) {
1303 PPPOE_ADD_16(p
, l1
);
1304 memcpy(p
, sc
->sc_service_name
, l1
);
1309 if (sc
->sc_ac_cookie_len
> 0) {
1310 PPPOE_ADD_16(p
, PPPOE_TAG_ACCOOKIE
);
1311 PPPOE_ADD_16(p
, sc
->sc_ac_cookie_len
);
1312 memcpy(p
, sc
->sc_ac_cookie
, sc
->sc_ac_cookie_len
);
1313 p
+= sc
->sc_ac_cookie_len
;
1315 if (sc
->sc_relay_sid_len
> 0) {
1316 PPPOE_ADD_16(p
, PPPOE_TAG_RELAYSID
);
1317 PPPOE_ADD_16(p
, sc
->sc_relay_sid_len
);
1318 memcpy(p
, sc
->sc_relay_sid
, sc
->sc_relay_sid_len
);
1319 p
+= sc
->sc_relay_sid_len
;
1321 PPPOE_ADD_16(p
, PPPOE_TAG_HUNIQUE
);
1322 PPPOE_ADD_16(p
, sizeof(sc
));
1323 memcpy(p
, &sc
, sizeof sc
);
1327 if (p
- mtod(m0
, uint8_t *) != len
+ PPPOE_HEADERLEN
)
1328 panic("pppoe_send_padr: garbled output len, should be %ld, is %ld",
1329 (long)(len
+ PPPOE_HEADERLEN
), (long)(p
- mtod(m0
, uint8_t *)));
1332 return pppoe_output(sc
, m0
);
1335 /* send a PADT packet */
1337 pppoe_send_padt(struct ifnet
*outgoing_if
, u_int session
, const uint8_t *dest
)
1339 struct ether_header
*eh
;
1340 struct sockaddr dst
;
1344 m0
= pppoe_get_mbuf(PPPOE_HEADERLEN
);
1347 p
= mtod(m0
, uint8_t *);
1348 PPPOE_ADD_HEADER(p
, PPPOE_CODE_PADT
, session
, 0);
1350 memset(&dst
, 0, sizeof dst
);
1351 dst
.sa_family
= AF_UNSPEC
;
1352 eh
= (struct ether_header
*)&dst
.sa_data
;
1353 eh
->ether_type
= htons(ETHERTYPE_PPPOEDISC
);
1354 memcpy(&eh
->ether_dhost
, dest
, ETHER_ADDR_LEN
);
1356 m0
->m_flags
&= ~(M_BCAST
|M_MCAST
);
1357 return outgoing_if
->if_output(outgoing_if
, m0
, &dst
, NULL
);
1362 pppoe_send_pado(struct pppoe_softc
*sc
)
1368 if (sc
->sc_state
!= PPPOE_STATE_PADO_SENT
)
1373 /* include ac_cookie */
1374 len
+= 2 + 2 + sizeof(sc
);
1375 /* include hunique */
1376 len
+= 2 + 2 + sc
->sc_hunique_len
;
1377 m0
= pppoe_get_mbuf(len
+ PPPOE_HEADERLEN
);
1380 p
= mtod(m0
, uint8_t *);
1381 PPPOE_ADD_HEADER(p
, PPPOE_CODE_PADO
, 0, len
);
1382 PPPOE_ADD_16(p
, PPPOE_TAG_ACCOOKIE
);
1383 PPPOE_ADD_16(p
, sizeof(sc
));
1384 memcpy(p
, &sc
, sizeof(sc
));
1386 PPPOE_ADD_16(p
, PPPOE_TAG_HUNIQUE
);
1387 PPPOE_ADD_16(p
, sc
->sc_hunique_len
);
1388 memcpy(p
, sc
->sc_hunique
, sc
->sc_hunique_len
);
1389 return pppoe_output(sc
, m0
);
1393 pppoe_send_pads(struct pppoe_softc
*sc
)
1398 size_t len
, l1
= 0; /* XXX: gcc */
1400 if (sc
->sc_state
!= PPPOE_STATE_PADO_SENT
)
1404 sc
->sc_session
= bt
.sec
% 0xff + 1;
1407 /* include hunique */
1408 len
+= 2 + 2 + 2 + 2 + sc
->sc_hunique_len
; /* service name, host unique*/
1409 if (sc
->sc_service_name
!= NULL
) { /* service name tag maybe empty */
1410 l1
= strlen(sc
->sc_service_name
);
1413 m0
= pppoe_get_mbuf(len
+ PPPOE_HEADERLEN
);
1416 p
= mtod(m0
, uint8_t *);
1417 PPPOE_ADD_HEADER(p
, PPPOE_CODE_PADS
, sc
->sc_session
, len
);
1418 PPPOE_ADD_16(p
, PPPOE_TAG_SNAME
);
1419 if (sc
->sc_service_name
!= NULL
) {
1420 PPPOE_ADD_16(p
, l1
);
1421 memcpy(p
, sc
->sc_service_name
, l1
);
1426 PPPOE_ADD_16(p
, PPPOE_TAG_HUNIQUE
);
1427 PPPOE_ADD_16(p
, sc
->sc_hunique_len
);
1428 memcpy(p
, sc
->sc_hunique
, sc
->sc_hunique_len
);
1429 return pppoe_output(sc
, m0
);
1434 pppoe_tls(struct sppp
*sp
)
1436 struct pppoe_softc
*sc
= (void *)sp
;
1439 if (sc
->sc_state
!= PPPOE_STATE_INITIAL
)
1442 if (sc
->sc_sppp
.pp_phase
== SPPP_PHASE_ESTABLISH
&&
1443 sc
->sc_sppp
.pp_auth_failures
> 0) {
1445 * Delay trying to reconnect a bit more - the peer
1446 * might have failed to contact it's radius server.
1448 wtime
= PPPOE_RECON_FAST
* sc
->sc_sppp
.pp_auth_failures
;
1449 if (wtime
> PPPOE_SLOW_RETRY
)
1450 wtime
= PPPOE_SLOW_RETRY
;
1452 wtime
= PPPOE_RECON_IMMEDIATE
;
1454 callout_reset(&sc
->sc_timeout
, wtime
, pppoe_timeout
, sc
);
1458 pppoe_tlf(struct sppp
*sp
)
1460 struct pppoe_softc
*sc
= (void *)sp
;
1461 if (sc
->sc_state
< PPPOE_STATE_SESSION
)
1464 * Do not call pppoe_disconnect here, the upper layer state
1465 * machine gets confused by this. We must return from this
1466 * function and defer disconnecting to the timeout handler.
1468 sc
->sc_state
= PPPOE_STATE_CLOSING
;
1469 callout_reset(&sc
->sc_timeout
, hz
/50, pppoe_timeout
, sc
);
1473 pppoe_start(struct ifnet
*ifp
)
1475 struct pppoe_softc
*sc
= (void *)ifp
;
1480 if (sppp_isempty(ifp
))
1483 /* are we ready to process data yet? */
1484 if (sc
->sc_state
< PPPOE_STATE_SESSION
) {
1485 sppp_flush(&sc
->sc_sppp
.pp_if
);
1489 while ((m
= sppp_dequeue(ifp
)) != NULL
) {
1490 len
= m
->m_pkthdr
.len
;
1491 M_PREPEND(m
, PPPOE_HEADERLEN
, M_DONTWAIT
);
1496 p
= mtod(m
, uint8_t *);
1497 PPPOE_ADD_HEADER(p
, 0, sc
->sc_session
, len
);
1500 if(sc
->sc_sppp
.pp_if
.if_bpf
)
1501 bpf_mtap(sc
->sc_sppp
.pp_if
.if_bpf
, m
);
1504 pppoe_output(sc
, m
);
1511 pppoe_ifattach_hook(void *arg
, struct mbuf
**mp
, struct ifnet
*ifp
,
1514 struct pppoe_softc
*sc
;
1517 if (mp
!= (struct mbuf
**)PFIL_IFNET_DETACH
)
1521 LIST_FOREACH(sc
, &pppoe_softc_list
, sc_list
) {
1522 if (sc
->sc_eth_if
!= ifp
)
1524 if (sc
->sc_sppp
.pp_if
.if_flags
& IFF_UP
) {
1525 sc
->sc_sppp
.pp_if
.if_flags
&= ~(IFF_UP
|IFF_RUNNING
);
1526 printf("%s: ethernet interface detached, going down\n",
1527 sc
->sc_sppp
.pp_if
.if_xname
);
1529 sc
->sc_eth_if
= NULL
;
1530 pppoe_clear_softc(sc
, "ethernet interface detached");
1539 pppoe_clear_softc(struct pppoe_softc
*sc
, const char *message
)
1542 callout_stop(&sc
->sc_timeout
);
1543 if (sc
->sc_sppp
.pp_if
.if_flags
& IFF_DEBUG
)
1544 printf("%s: session 0x%x terminated, %s\n",
1545 sc
->sc_sppp
.pp_if
.if_xname
, sc
->sc_session
, message
);
1548 sc
->sc_state
= PPPOE_STATE_INITIAL
;
1550 /* signal upper layer */
1551 sc
->sc_sppp
.pp_down(&sc
->sc_sppp
);
1553 /* clean up softc */
1554 memcpy(&sc
->sc_dest
, etherbroadcastaddr
, sizeof(sc
->sc_dest
));
1555 if (sc
->sc_ac_cookie
) {
1556 free(sc
->sc_ac_cookie
, M_DEVBUF
);
1557 sc
->sc_ac_cookie
= NULL
;
1559 if (sc
->sc_relay_sid
) {
1560 free(sc
->sc_relay_sid
, M_DEVBUF
);
1561 sc
->sc_relay_sid
= NULL
;
1563 sc
->sc_ac_cookie_len
= 0;