mirror of
https://git.savannah.nongnu.org/git/lwip.git
synced 2025-08-04 21:44:38 +08:00
added holdoff support for PPPoE and PPPoL2TP when persist mode is used
This commit is contained in:
parent
f534e80c71
commit
de6be743c6
@ -106,10 +106,11 @@ PACK_STRUCT_END
|
|||||||
|
|
||||||
|
|
||||||
#define PPPOE_STATE_INITIAL 0
|
#define PPPOE_STATE_INITIAL 0
|
||||||
#define PPPOE_STATE_PADI_SENT 1
|
#define PPPOE_STATE_HOLDOFF 1
|
||||||
#define PPPOE_STATE_PADR_SENT 2
|
#define PPPOE_STATE_PADI_SENT 2
|
||||||
#define PPPOE_STATE_SESSION 3
|
#define PPPOE_STATE_PADR_SENT 3
|
||||||
#define PPPOE_STATE_CLOSING 4
|
#define PPPOE_STATE_SESSION 4
|
||||||
|
#define PPPOE_STATE_CLOSING 5
|
||||||
/* passive */
|
/* passive */
|
||||||
#define PPPOE_STATE_PADO_SENT 1
|
#define PPPOE_STATE_PADO_SENT 1
|
||||||
|
|
||||||
@ -172,6 +173,7 @@ err_t pppoe_create(struct netif *ethif, ppp_pcb *pcb, void (*link_status_cb)(ppp
|
|||||||
err_t pppoe_destroy(struct netif *ifp);
|
err_t pppoe_destroy(struct netif *ifp);
|
||||||
|
|
||||||
int pppoe_connect(struct pppoe_softc *sc);
|
int pppoe_connect(struct pppoe_softc *sc);
|
||||||
|
void pppoe_reconnect(struct pppoe_softc *sc);
|
||||||
void pppoe_disconnect(struct pppoe_softc *sc);
|
void pppoe_disconnect(struct pppoe_softc *sc);
|
||||||
|
|
||||||
void pppoe_disc_input(struct netif *netif, struct pbuf *p);
|
void pppoe_disc_input(struct netif *netif, struct pbuf *p);
|
||||||
|
@ -150,11 +150,12 @@
|
|||||||
|
|
||||||
/* L2TP Session state */
|
/* L2TP Session state */
|
||||||
#define PPPOL2TP_STATE_INITIAL 0
|
#define PPPOL2TP_STATE_INITIAL 0
|
||||||
#define PPPOL2TP_STATE_SCCRQ_SENT 1
|
#define PPPOL2TP_STATE_HOLDOFF 1
|
||||||
#define PPPOL2TP_STATE_ICRQ_SENT 2
|
#define PPPOL2TP_STATE_SCCRQ_SENT 2
|
||||||
#define PPPOL2TP_STATE_ICCN_SENT 3
|
#define PPPOL2TP_STATE_ICRQ_SENT 3
|
||||||
#define PPPOL2TP_STATE_DATA 4
|
#define PPPOL2TP_STATE_ICCN_SENT 4
|
||||||
#define PPPOL2TP_STATE_CLOSING 5
|
#define PPPOL2TP_STATE_DATA 5
|
||||||
|
#define PPPOL2TP_STATE_CLOSING 6
|
||||||
|
|
||||||
#define PPPOL2TP_CB_STATE_UP 0 /* PPPoL2TP link is UP */
|
#define PPPOL2TP_CB_STATE_UP 0 /* PPPoL2TP link is UP */
|
||||||
#define PPPOL2TP_CB_STATE_DOWN 1 /* PPPo2TP link is DOWN - normal condition */
|
#define PPPOL2TP_CB_STATE_DOWN 1 /* PPPo2TP link is DOWN - normal condition */
|
||||||
@ -210,7 +211,7 @@ err_t pppol2tp_connect(pppol2tp_pcb *l2tp, ip_addr_t *ipaddr, u16_t port);
|
|||||||
void pppol2tp_disconnect(pppol2tp_pcb *l2tp);
|
void pppol2tp_disconnect(pppol2tp_pcb *l2tp);
|
||||||
|
|
||||||
/* Reconnect to a LNS, using previously set L2TP server IP address and port. */
|
/* Reconnect to a LNS, using previously set L2TP server IP address and port. */
|
||||||
err_t pppol2tp_reconnect(pppol2tp_pcb *l2tp);
|
void pppol2tp_reconnect(pppol2tp_pcb *l2tp);
|
||||||
|
|
||||||
/* Data packet from PPP to L2TP */
|
/* Data packet from PPP to L2TP */
|
||||||
err_t pppol2tp_xmit(pppol2tp_pcb *l2tp, struct pbuf *pb);
|
err_t pppol2tp_xmit(pppol2tp_pcb *l2tp, struct pbuf *pb);
|
||||||
|
@ -270,6 +270,7 @@ ppp_pcb *ppp_new(void) {
|
|||||||
/* default configuration */
|
/* default configuration */
|
||||||
pcb->settings.usepeerdns = 1;
|
pcb->settings.usepeerdns = 1;
|
||||||
pcb->settings.persist = 1;
|
pcb->settings.persist = 1;
|
||||||
|
pcb->settings.holdoff = 30;
|
||||||
#if CHAP_SUPPORT
|
#if CHAP_SUPPORT
|
||||||
pcb->settings.chap_timeout_time = 3;
|
pcb->settings.chap_timeout_time = 3;
|
||||||
pcb->settings.chap_max_transmits = 10;
|
pcb->settings.chap_max_transmits = 10;
|
||||||
@ -1808,7 +1809,7 @@ static void ppp_over_ethernet_link_status_cb(ppp_pcb *pcb, int state) {
|
|||||||
if(pcb->link_status_cb)
|
if(pcb->link_status_cb)
|
||||||
pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : pppoe_err_code, pcb->link_status_ctx);
|
pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : pppoe_err_code, pcb->link_status_ctx);
|
||||||
new_phase(pcb, PHASE_INITIALIZE);
|
new_phase(pcb, PHASE_INITIALIZE);
|
||||||
pppoe_connect(pcb->pppoe_sc);
|
pppoe_reconnect(pcb->pppoe_sc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,6 +206,8 @@ typedef struct ppp_settings_s {
|
|||||||
|
|
||||||
u16_t listen_time; /* time to listen first (ms), waiting for peer to send LCP packet */
|
u16_t listen_time; /* time to listen first (ms), waiting for peer to send LCP packet */
|
||||||
|
|
||||||
|
u16_t holdoff; /* time to wait (s) before re-initiating the link after it terminates */
|
||||||
|
|
||||||
#if PPP_IDLETIMELIMIT
|
#if PPP_IDLETIMELIMIT
|
||||||
u16_t idle_time_limit; /* Disconnect if idle for this many seconds */
|
u16_t idle_time_limit; /* Disconnect if idle for this many seconds */
|
||||||
#endif /* PPP_IDLETIMELIMIT */
|
#endif /* PPP_IDLETIMELIMIT */
|
||||||
|
@ -788,6 +788,10 @@ pppoe_timeout(void *arg)
|
|||||||
case PPPOE_STATE_CLOSING:
|
case PPPOE_STATE_CLOSING:
|
||||||
pppoe_do_disconnect(sc);
|
pppoe_do_disconnect(sc);
|
||||||
break;
|
break;
|
||||||
|
case PPPOE_STATE_HOLDOFF:
|
||||||
|
sc->sc_state = PPPOE_STATE_INITIAL;
|
||||||
|
pppoe_connect(sc);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return; /* all done, work in peace */
|
return; /* all done, work in peace */
|
||||||
}
|
}
|
||||||
@ -823,6 +827,23 @@ pppoe_connect(struct pppoe_softc *sc)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Start a reconnection */
|
||||||
|
void pppoe_reconnect(struct pppoe_softc *sc) {
|
||||||
|
|
||||||
|
if (sc->sc_state != PPPOE_STATE_INITIAL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sc->pcb->settings.holdoff == 0) {
|
||||||
|
pppoe_connect(sc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sc->sc_state = PPPOE_STATE_HOLDOFF;
|
||||||
|
sys_timeout((u32_t)sc->pcb->settings.holdoff*1000, pppoe_timeout, sc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* disconnect */
|
/* disconnect */
|
||||||
void
|
void
|
||||||
pppoe_disconnect(struct pppoe_softc *sc)
|
pppoe_disconnect(struct pppoe_softc *sc)
|
||||||
|
@ -71,6 +71,7 @@
|
|||||||
#endif /* PPPOL2TP_AUTH_SUPPORT */
|
#endif /* PPPOL2TP_AUTH_SUPPORT */
|
||||||
|
|
||||||
/* Prototypes for procedures local to this file. */
|
/* Prototypes for procedures local to this file. */
|
||||||
|
static void pppol2tp_do_reconnect(pppol2tp_pcb *l2tp);
|
||||||
static void pppol2tp_do_disconnect(pppol2tp_pcb *l2tp);
|
static void pppol2tp_do_disconnect(pppol2tp_pcb *l2tp);
|
||||||
static void pppol2tp_input(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port);
|
static void pppol2tp_input(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port);
|
||||||
static void pppol2tp_dispatch_control_packet(pppol2tp_pcb *l2tp, struct ip_addr *addr, u16_t port,
|
static void pppol2tp_dispatch_control_packet(pppol2tp_pcb *l2tp, struct ip_addr *addr, u16_t port,
|
||||||
@ -168,15 +169,27 @@ err_t pppol2tp_connect(pppol2tp_pcb *l2tp, ip_addr_t *ipaddr, u16_t port) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Reconnect to a LNS, using previously set L2TP server IP address and port. */
|
/* Reconnect to a LNS, using previously set L2TP server IP address and port. */
|
||||||
err_t pppol2tp_reconnect(pppol2tp_pcb *l2tp) {
|
void pppol2tp_reconnect(pppol2tp_pcb *l2tp) {
|
||||||
err_t err;
|
|
||||||
|
|
||||||
if (l2tp->phase != PPPOL2TP_STATE_INITIAL) {
|
if (l2tp->phase != PPPOL2TP_STATE_INITIAL) {
|
||||||
return ERR_VAL;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pppol2tp_clear(l2tp);
|
pppol2tp_clear(l2tp);
|
||||||
|
|
||||||
|
if (l2tp->ppp->settings.holdoff == 0) {
|
||||||
|
pppol2tp_do_reconnect(l2tp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
l2tp->phase = PPPOL2TP_STATE_HOLDOFF;
|
||||||
|
sys_timeout((u32_t)l2tp->ppp->settings.holdoff*1000, pppol2tp_timeout, l2tp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pppol2tp_do_reconnect(pppol2tp_pcb *l2tp) {
|
||||||
|
err_t err;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
l2tp->remote_tunnel_id = magic();
|
l2tp->remote_tunnel_id = magic();
|
||||||
} while(l2tp->remote_tunnel_id == 0);
|
} while(l2tp->remote_tunnel_id == 0);
|
||||||
@ -187,7 +200,7 @@ err_t pppol2tp_reconnect(pppol2tp_pcb *l2tp) {
|
|||||||
PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send SCCRQ, error=%d\n", err));
|
PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send SCCRQ, error=%d\n", err));
|
||||||
}
|
}
|
||||||
sys_timeout(PPPOL2TP_CONTROL_TIMEOUT, pppol2tp_timeout, l2tp);
|
sys_timeout(PPPOL2TP_CONTROL_TIMEOUT, pppol2tp_timeout, l2tp);
|
||||||
return err;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disconnect */
|
/* Disconnect */
|
||||||
@ -220,6 +233,10 @@ static void pppol2tp_input(void *arg, struct udp_pcb *pcb, struct pbuf *p, struc
|
|||||||
u16_t hflags, hlen, len=0, tunnel_id=0, session_id=0, ns=0, nr=0, offset=0;
|
u16_t hflags, hlen, len=0, tunnel_id=0, session_id=0, ns=0, nr=0, offset=0;
|
||||||
u8_t *inp;
|
u8_t *inp;
|
||||||
|
|
||||||
|
if (l2tp->phase < PPPOL2TP_STATE_SCCRQ_SENT) {
|
||||||
|
goto free_and_return;
|
||||||
|
}
|
||||||
|
|
||||||
printf("-----------\nL2TP INPUT, %d\n", p->len);
|
printf("-----------\nL2TP INPUT, %d\n", p->len);
|
||||||
p = ppp_singlebuf(p);
|
p = ppp_singlebuf(p);
|
||||||
|
|
||||||
@ -396,6 +413,7 @@ static void pppol2tp_dispatch_control_packet(pppol2tp_pcb *l2tp, struct ip_addr
|
|||||||
break;
|
break;
|
||||||
/* Stop Control Connection Notification */
|
/* Stop Control Connection Notification */
|
||||||
case PPPOL2TP_MESSAGETYPE_STOPCCN:
|
case PPPOL2TP_MESSAGETYPE_STOPCCN:
|
||||||
|
pppol2tp_send_zlb(l2tp, l2tp->our_ns); /* Ack the StopCCN before we switch to down state */
|
||||||
if (l2tp->phase < PPPOL2TP_STATE_DATA) {
|
if (l2tp->phase < PPPOL2TP_STATE_DATA) {
|
||||||
pppol2tp_abort_connect(l2tp);
|
pppol2tp_abort_connect(l2tp);
|
||||||
} else if (l2tp->phase == PPPOL2TP_STATE_DATA) {
|
} else if (l2tp->phase == PPPOL2TP_STATE_DATA) {
|
||||||
@ -601,6 +619,10 @@ static void pppol2tp_timeout(void *arg) {
|
|||||||
pppol2tp_do_disconnect(l2tp);
|
pppol2tp_do_disconnect(l2tp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PPPOL2TP_STATE_HOLDOFF:
|
||||||
|
pppol2tp_do_reconnect(l2tp);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return; /* all done, work in peace */
|
return; /* all done, work in peace */
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user