added a persist option (enabled by default for now until we add a way for users to pass a ppp_settings structure)

improved PPPoE state machine and added persist mode support
This commit is contained in:
Sylvain Rochet 2012-06-07 00:46:19 +02:00
parent e44aada634
commit 7ef99ee6f3
4 changed files with 52 additions and 33 deletions

View File

@ -145,7 +145,7 @@ struct pppoe_softc {
struct pppoe_softc *next;
struct netif *sc_ethif; /* ethernet interface we are using */
int sc_pd; /* ppp unit number */
void (*sc_linkStatusCB)(int pd, int up);
void (*sc_link_status_cb)(int pd, int up);
int sc_state; /* discovery phase or session connected */
struct eth_addr sc_dest; /* hardware address of concentrator */
@ -168,7 +168,7 @@ struct pppoe_softc {
#define pppoe_init() /* compatibility define, no initialization needed */
err_t pppoe_create(struct netif *ethif, int pd, void (*linkStatusCB)(int pd, int up), struct pppoe_softc **scptr);
err_t pppoe_create(struct netif *ethif, int pd, void (*link_status_cb)(int pd, int up), struct pppoe_softc **scptr);
err_t pppoe_destroy(struct netif *ifp);
int pppoe_connect(struct pppoe_softc *sc);

View File

@ -380,6 +380,7 @@ int ppp_init(void) {
memset(&ppp_settings, 0, sizeof(ppp_settings));
ppp_settings.usepeerdns = 1;
ppp_settings.persist = 1;
ppp_set_auth(PPPAUTHTYPE_NONE, NULL, NULL);
/*
@ -1835,39 +1836,46 @@ struct pbuf * ppp_singlebuf(struct pbuf *p) {
#if PPPOE_SUPPORT
static void ppp_over_ethernet_link_status_cb(int pd, int state) {
ppp_control *pc = &ppp_control_list[pd];
int pppoe_err_code = PPPERR_NONE;
ppp_control *pc;
switch(state) {
/* PPPoE link is established, starting PPP negotiation */
case PPPOE_CB_STATE_UP:
PPPDEBUG(LOG_INFO, ("ppp_over_ethernet_link_status_cb: unit %d: UP, connecting\n", pd));
ppp_start(pd);
break;
return;
/* FIXME: here we can handle the PPPoE persist, in case of DOWN or FAILED, we just have to
* call pppoe_connect(sc); without setting pc->open_flag to 0.
*/
/* PPPoE link normally down (i.e. asked to do so) */
case PPPOE_CB_STATE_DOWN:
PPPDEBUG(LOG_INFO, ("ppp_over_ethernet_link_status_cb: unit %d: DOWN, disconnected\n", pd));
ppp_hup(pd);
ppp_stop(pd);
pppoe_destroy(&pc->netif);
pc->open_flag = 0;
if(pc->link_status_cb) {
pc->link_status_cb(pc->link_status_ctx, pc->err_code ? pc->err_code : PPPERR_CONNECT, NULL);
}
pppoe_err_code = PPPERR_CONNECT;
break;
/* PPPoE link failed to setup (i.e. PADI/PADO timeout */
case PPPOE_CB_STATE_FAILED:
PPPDEBUG(LOG_INFO, ("ppp_over_ethernet_link_status_cb: unit %d: FAILED, aborting\n", pd));
ppp_hup(pd);
ppp_stop(pd);
pppoe_destroy(&pc->netif);
pc->open_flag = 0;
if(pc->link_status_cb) {
pc->link_status_cb(pc->link_status_ctx, pc->err_code ? pc->err_code : PPPERR_PROTOCOL, NULL);
}
pppoe_err_code = PPPERR_OPEN;
break;
}
pc = &ppp_control_list[pd];
/* Reconnect if persist mode is enabled */
if(ppp_settings.persist) {
if(pc->link_status_cb)
pc->link_status_cb(pc->link_status_ctx, pc->err_code ? pc->err_code : pppoe_err_code, NULL);
pppoe_connect(pc->pppoe_sc);
return;
}
ppp_hup(pd);
ppp_stop(pd);
pppoe_destroy(&pc->netif);
pc->open_flag = 0;
if(pc->link_status_cb)
pc->link_status_cb(pc->link_status_ctx, pc->err_code ? pc->err_code : pppoe_err_code, NULL);
}
#endif /* PPPOE_SUPPORT */

View File

@ -437,6 +437,7 @@ struct ppp_settings {
#endif /* EAP_SUPPORT */
u_int usehostname : 1; /* Use hostname for our_name */
u_int usepeerdns : 1; /* Ask peer for DNS adds */
u_int persist : 1; /* Persist mode, always try to reopen the connection */
u_short idle_time_limit; /* Shut down link if idle for this long */
int maxconnect; /* Maximum connect time (seconds) */

View File

@ -141,7 +141,7 @@ static struct pppoe_softc * pppoe_find_softc_by_hunique(u8_t *, size_t, struct n
static struct pppoe_softc *pppoe_softc_list;
err_t
pppoe_create(struct netif *ethif, int pd, void (*linkStatusCB)(int pd, int up), struct pppoe_softc **scptr)
pppoe_create(struct netif *ethif, int pd, void (*link_status_cb)(int pd, int up), struct pppoe_softc **scptr)
{
struct pppoe_softc *sc;
@ -156,7 +156,7 @@ pppoe_create(struct netif *ethif, int pd, void (*linkStatusCB)(int pd, int up),
MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest));
sc->sc_pd = pd;
sc->sc_linkStatusCB = linkStatusCB;
sc->sc_link_status_cb = link_status_cb;
sc->sc_ethif = ethif;
/* put the new interface at the head of the list */
@ -277,7 +277,7 @@ pppoe_find_softc_by_hunique(u8_t *token, size_t len, struct netif *rcvif)
static void
pppoe_linkstatus_up(struct pppoe_softc *sc)
{
sc->sc_linkStatusCB(sc->sc_pd, PPPOE_CB_STATE_UP);
sc->sc_link_status_cb(sc->sc_pd, PPPOE_CB_STATE_UP);
}
/* analyze and handle a single received packet while not in session state */
@ -806,6 +806,12 @@ pppoe_connect(struct pppoe_softc *sc)
return EBUSY;
}
/* stop any timer */
sys_untimeout(pppoe_timeout, sc);
sc->sc_session = 0;
sc->sc_padi_retried = 0;
sc->sc_padr_retried = 0;
#ifdef PPPOE_SERVER
/* wait PADI if IFF_PASSIVE */
if ((sc->sc_sppp.pp_if.if_flags & IFF_PASSIVE)) {
@ -814,7 +820,6 @@ pppoe_connect(struct pppoe_softc *sc)
#endif
/* save state, in case we fail to send PADI */
sc->sc_state = PPPOE_STATE_PADI_SENT;
sc->sc_padr_retried = 0;
if ((err = pppoe_send_padi(sc)) != 0) {
PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to send PADI, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err));
}
@ -862,8 +867,10 @@ pppoe_do_disconnect(struct pppoe_softc *sc)
sc->sc_hunique_len = 0;
#endif
sc->sc_session = 0;
sc->sc_padi_retried = 0;
sc->sc_padr_retried = 0;
sc->sc_linkStatusCB(sc->sc_pd, PPPOE_CB_STATE_DOWN); /* notify upper layers */
sc->sc_link_status_cb(sc->sc_pd, PPPOE_CB_STATE_DOWN); /* notify upper layers */
return err;
}
@ -872,13 +879,16 @@ static void
pppoe_abort_connect(struct pppoe_softc *sc)
{
PPPDEBUG(LOG_DEBUG, ("%c%c%"U16_F": could not establish connection\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num));
sc->sc_state = PPPOE_STATE_CLOSING;
sc->sc_linkStatusCB(sc->sc_pd, PPPOE_CB_STATE_FAILED); /* notify upper layers */
/* clear connection state */
MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest));
sc->sc_state = PPPOE_STATE_INITIAL;
MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest));
sc->sc_ac_cookie_len = 0;
sc->sc_session = 0;
sc->sc_padi_retried = 0;
sc->sc_padr_retried = 0;
sc->sc_link_status_cb(sc->sc_pd, PPPOE_CB_STATE_FAILED); /* notify upper layers */
}
/* Send a PADR packet */
@ -1112,17 +1122,17 @@ pppoe_clear_softc(struct pppoe_softc *sc, const char *message)
/* stop timer */
sys_untimeout(pppoe_timeout, sc);
PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": session 0x%x terminated, %s\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, sc->sc_session, message));
/* fix our state */
sc->sc_state = PPPOE_STATE_INITIAL;
/* notify upper layers */
sc->sc_linkStatusCB(sc->sc_pd, PPPOE_CB_STATE_DOWN);
sc->sc_link_status_cb(sc->sc_pd, PPPOE_CB_STATE_DOWN);
/* clean up softc */
MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest));
sc->sc_ac_cookie_len = 0;
sc->sc_session = 0;
sc->sc_padi_retried = 0;
sc->sc_padr_retried = 0;
}
#endif /* PPP_SUPPORT && PPPOE_SUPPORT */