diff --git a/src/api/pppapi.c b/src/api/pppapi.c index 40905362..07fc0130 100644 --- a/src/api/pppapi.c +++ b/src/api/pppapi.c @@ -148,8 +148,8 @@ int pppapi_over_ethernet_open(ppp_pcb *pcb, struct netif *ethif, const char *ser */ static void pppapi_do_ppp_over_l2tp_open(struct pppapi_msg_msg *msg) { - msg->err = ppp_over_l2tp_open(msg->ppp, msg->msg.l2tpopen.ipaddr, - msg->msg.l2tpopen.port, + msg->err = ppp_over_l2tp_open(msg->ppp, + msg->msg.l2tpopen.netif, msg->msg.l2tpopen.ipaddr, msg->msg.l2tpopen.port, #if PPPOL2TP_AUTH_SUPPORT msg->msg.l2tpopen.secret, msg->msg.l2tpopen.secret_len, @@ -164,11 +164,13 @@ static void pppapi_do_ppp_over_l2tp_open(struct pppapi_msg_msg *msg) { * Call ppp_over_l2tp_open() in a thread-safe way by running that function inside the * tcpip_thread context. */ -int pppapi_over_l2tp_open(ppp_pcb *pcb, ip_addr_t *ipaddr, u16_t port, u8_t *secret, u8_t secret_len, +int pppapi_over_l2tp_open(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, u16_t port, + u8_t *secret, u8_t secret_len, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx) { struct pppapi_msg msg; msg.function = pppapi_do_ppp_over_l2tp_open; msg.msg.ppp = pcb; + msg.msg.msg.l2tpopen.netif = netif; msg.msg.msg.l2tpopen.ipaddr = ipaddr; msg.msg.msg.l2tpopen.port = port; #if PPPOL2TP_AUTH_SUPPORT diff --git a/src/include/lwip/pppapi.h b/src/include/lwip/pppapi.h index 4b139ab8..6b2897a7 100644 --- a/src/include/lwip/pppapi.h +++ b/src/include/lwip/pppapi.h @@ -69,6 +69,7 @@ struct pppapi_msg_msg { #endif /* PPPOE_SUPPORT */ #if PPPOL2TP_SUPPORT struct { + struct netif *netif; ip_addr_t *ipaddr; u16_t port; #if PPPOL2TP_AUTH_SUPPORT @@ -119,7 +120,8 @@ int pppapi_over_ethernet_open(ppp_pcb *pcb, struct netif *ethif, const char *ser void *link_status_ctx); #endif /* PPPOE_SUPPORT */ #if PPPOL2TP_SUPPORT -int pppapi_over_l2tp_open(ppp_pcb *pcb, ip_addr_t *ipaddr, u16_t port, u8_t *secret, u8_t secret_len, +int pppapi_over_l2tp_open(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, u16_t port, + u8_t *secret, u8_t secret_len, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx); #endif /* PPPOL2TP_SUPPORT */ int pppapi_close(ppp_pcb *pcb); diff --git a/src/include/netif/pppol2tp.h b/src/include/netif/pppol2tp.h index 3dded088..c7741431 100644 --- a/src/include/netif/pppol2tp.h +++ b/src/include/netif/pppol2tp.h @@ -172,6 +172,7 @@ struct pppol2tp_pcb_s { u8_t phase; /* L2TP phase */ void (*link_status_cb)(ppp_pcb *pcb, int status); struct udp_pcb *udp; /* UDP L2TP Socket */ + struct netif *netif; /* Output interface, used as a default route */ ip_addr_t remote_ip; /* LNS IP Address */ u16_t remote_port; /* LNS port */ #if PPPOL2TP_AUTH_SUPPORT @@ -205,7 +206,7 @@ err_t pppol2tp_create(ppp_pcb *ppp, void (*link_status_cb)(ppp_pcb *pcb, int sta err_t pppol2tp_destroy(pppol2tp_pcb *l2tp); /* Be a LAC, connect to a LNS. */ -err_t pppol2tp_connect(pppol2tp_pcb *l2tp, ip_addr_t *ipaddr, u16_t port); +err_t pppol2tp_connect(pppol2tp_pcb *l2tp, struct netif *netif, ip_addr_t *ipaddr, u16_t port); /* Disconnect */ void pppol2tp_disconnect(pppol2tp_pcb *l2tp); diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index af2cadd2..66cccbe7 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -284,6 +284,13 @@ ppp_pcb *ppp_new(void) { for (i = 0; (protp = protocols[i]) != NULL; ++i) (*protp->init)(pcb); + if (!netif_add(&pcb->netif, &pcb->addrs.our_ipaddr, &pcb->addrs.netmask, + &pcb->addrs.his_ipaddr, (void *)pcb, ppp_netif_init_cb, NULL)) { + memp_free(MEMP_PPP_PCB, pcb); + PPPDEBUG(LOG_ERR, ("ppp_new[%d]: netif_add failed\n", pcb->num)); + return NULL; + } + return pcb; } @@ -428,7 +435,8 @@ int ppp_over_ethernet_open(ppp_pcb *pcb, struct netif *ethif, const char *servic #if PPPOL2TP_SUPPORT static void ppp_over_l2tp_link_status_cb(ppp_pcb *pcb, int state); -int ppp_over_l2tp_open(ppp_pcb *pcb, ip_addr_t *ipaddr, u16_t port, u8_t *secret, u8_t secret_len, +int ppp_over_l2tp_open(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, u16_t port, + u8_t *secret, u8_t secret_len, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx) { lcp_options *wo = &pcb->lcp_wantoptions; @@ -457,7 +465,7 @@ int ppp_over_l2tp_open(ppp_pcb *pcb, ip_addr_t *ipaddr, u16_t port, u8_t *secret } new_phase(pcb, PHASE_INITIALIZE); - if(!pppol2tp_connect(pcb->l2tp_pcb, ipaddr, port) != ERR_OK) { + if(!pppol2tp_connect(pcb->l2tp_pcb, netif, ipaddr, port) != ERR_OK) { return PPPERR_OPEN; } return PPPERR_NONE; @@ -874,7 +882,6 @@ static err_t ppp_netif_init_cb(struct netif *netif) { #if PPP_IPV6_SUPPORT netif->output_ip6 = ppp_netif_output_ip6; #endif /* PPP_IPV6_SUPPORT */ - netif->mtu = netif_get_mtu((ppp_pcb*)netif->state); netif->flags = NETIF_FLAG_POINTTOPOINT | NETIF_FLAG_LINK_UP; #if LWIP_NETIF_HOSTNAME /* @todo: Initialize interface hostname */ @@ -1017,7 +1024,7 @@ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, u_short prot } /* Check that the link is up. */ - if (pcb->phase == PHASE_DEAD) { + if (!pcb->if_up) { PPPDEBUG(LOG_ERR, ("ppp_netif_output[%d]: link not up\n", pcb->num)); LINK_STATS_INC(link.rterr); LINK_STATS_INC(link.drop); @@ -1905,6 +1912,7 @@ void ppp_link_terminated(ppp_pcb *pcb) { static void ppp_destroy(ppp_pcb *pcb) { PPPDEBUG(LOG_DEBUG, ("ppp_destroy: unit %d\n", pcb->num)); + netif_remove(&pcb->netif); memp_free(MEMP_PPP_PCB, pcb); } @@ -2117,22 +2125,14 @@ int cdns(ppp_pcb *pcb, u32_t ns1, u32_t ns2) { */ int sifup(ppp_pcb *pcb) { - if(!pcb->if_up) { - if(!netif_add(&pcb->netif, &pcb->addrs.our_ipaddr, &pcb->addrs.netmask, - &pcb->addrs.his_ipaddr, (void *)pcb, ppp_netif_init_cb, NULL)) { - PPPDEBUG(LOG_ERR, ("sifup[%d]: netif_add failed\n", pcb->num)); - return 0; - } - } else { - netif_set_addr(&pcb->netif, &pcb->addrs.our_ipaddr, &pcb->addrs.netmask, - &pcb->addrs.his_ipaddr); - } - + netif_set_addr(&pcb->netif, &pcb->addrs.our_ipaddr, &pcb->addrs.netmask, + &pcb->addrs.his_ipaddr); #if PPP_IPV6_SUPPORT ip6_addr_copy(pcb->netif.ip6_addr[0], pcb->addrs.our6_ipaddr); netif_ip6_addr_set_state(&pcb->netif, 0, IP6_ADDR_PREFERRED); #endif /* PPP_IPV6_SUPPORT */ + pcb->netif.mtu = netif_get_mtu(pcb); netif_set_up(&pcb->netif); pcb->if_up = 1; pcb->err_code = PPPERR_NONE; @@ -2157,7 +2157,6 @@ int sifdown(ppp_pcb *pcb) { pcb->if_up = 0; /* make sure the netif status callback is called */ netif_set_down(&pcb->netif); - netif_remove(&pcb->netif); PPPDEBUG(LOG_DEBUG, ("sifdown: unit %d: err_code=%d\n", pcb->num, pcb->err_code)); if (pcb->link_status_cb) pcb->link_status_cb(pcb, PPPERR_CONNECT, pcb->link_status_ctx); diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index bc7422df..71e2bca6 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -481,7 +481,8 @@ int ppp_over_ethernet_open(ppp_pcb *pcb, struct netif *ethif, const char *servic /* * Open a new PPP Over L2TP (PPPoL2TP) connection. */ -int ppp_over_l2tp_open(ppp_pcb *pcb, ip_addr_t *ipaddr, u16_t port, u8_t *secret, u8_t secret_len, +int ppp_over_l2tp_open(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, u16_t port, + u8_t *secret, u8_t secret_len, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx); #endif /* PPPOL2TP_SUPPORT */ @@ -512,6 +513,8 @@ int ppp_ioctl(ppp_pcb *pcb, int cmd, void *arg); void pppos_input(ppp_pcb *pcb, u_char* data, int len); #endif /* PPPOS_SUPPORT && !PPP_INPROC_OWNTHREAD */ +/* Get the PPP netif interface */ +#define ppp_netif(ppp) (&(ppp)->netif) #if LWIP_NETIF_STATUS_CALLBACK /* Set an lwIP-style status-callback for the selected PPP device */ diff --git a/src/netif/ppp/pppol2tp.c b/src/netif/ppp/pppol2tp.c index f6940875..a911ba2f 100644 --- a/src/netif/ppp/pppol2tp.c +++ b/src/netif/ppp/pppol2tp.c @@ -55,6 +55,7 @@ #include "lwip/err.h" #include "lwip/memp.h" +#include "lwip/netif.h" #include "lwip/udp.h" #include "ppp_impl.h" @@ -132,13 +133,14 @@ err_t pppol2tp_destroy(pppol2tp_pcb *l2tp) { } /* Be a LAC, connect to a LNS. */ -err_t pppol2tp_connect(pppol2tp_pcb *l2tp, ip_addr_t *ipaddr, u16_t port) { +err_t pppol2tp_connect(pppol2tp_pcb *l2tp, struct netif *netif, ip_addr_t *ipaddr, u16_t port) { err_t err; if (l2tp->phase != PPPOL2TP_STATE_INITIAL) { return ERR_VAL; } + l2tp->netif = netif; ip_addr_set(&l2tp->remote_ip, ipaddr); l2tp->remote_port = l2tp->tunnel_port = port; @@ -743,7 +745,11 @@ static err_t pppol2tp_send_sccrq(pppol2tp_pcb *l2tp) { } #endif /* PPPOL2TP_AUTH_SUPPORT */ - udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->remote_port); + if(l2tp->netif) { + udp_sendto_if(l2tp->udp, pb, &l2tp->remote_ip, l2tp->remote_port, l2tp->netif); + } else { + udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->remote_port); + } pbuf_free(pb); return ERR_OK; } @@ -796,7 +802,11 @@ static err_t pppol2tp_send_scccn(pppol2tp_pcb *l2tp, u16_t ns) { } #endif /* PPPOL2TP_AUTH_SUPPORT */ - udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->tunnel_port); + if(l2tp->netif) { + udp_sendto_if(l2tp->udp, pb, &l2tp->remote_ip, l2tp->remote_port, l2tp->netif); + } else { + udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->remote_port); + } pbuf_free(pb); return ERR_OK; } @@ -847,7 +857,11 @@ static err_t pppol2tp_send_icrq(pppol2tp_pcb *l2tp, u16_t ns) { serialnumber = magic(); PUTLONG(serialnumber, p); /* Attribute value: Serial number */ - udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->tunnel_port); + if(l2tp->netif) { + udp_sendto_if(l2tp->udp, pb, &l2tp->remote_ip, l2tp->remote_port, l2tp->netif); + } else { + udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->remote_port); + } pbuf_free(pb); return ERR_OK; } @@ -896,7 +910,11 @@ static err_t pppol2tp_send_iccn(pppol2tp_pcb *l2tp, u16_t ns) { PUTSHORT(PPPOL2TP_AVPTYPE_TXCONNECTSPEED, p); /* Attribute type: TX Connect speed */ PUTLONG(PPPOL2TP_TXCONNECTSPEED, p); /* Attribute value: TX Connect speed */ - udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->tunnel_port); + if(l2tp->netif) { + udp_sendto_if(l2tp->udp, pb, &l2tp->remote_ip, l2tp->remote_port, l2tp->netif); + } else { + udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->remote_port); + } pbuf_free(pb); return ERR_OK; } @@ -927,7 +945,11 @@ static err_t pppol2tp_send_zlb(pppol2tp_pcb *l2tp, u16_t ns) { PUTSHORT(ns, p); /* NS Sequence number - to peer */ PUTSHORT(l2tp->peer_ns+1, p); /* NR Sequence number - expected for peer */ - udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->tunnel_port); + if(l2tp->netif) { + udp_sendto_if(l2tp->udp, pb, &l2tp->remote_ip, l2tp->remote_port, l2tp->netif); + } else { + udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->remote_port); + } pbuf_free(pb); return ERR_OK; } @@ -976,7 +998,11 @@ static err_t pppol2tp_send_stopccn(pppol2tp_pcb *l2tp, u16_t ns) { PUTSHORT(PPPOL2TP_AVPTYPE_RESULTCODE, p); /* Attribute type: Result code */ PUTSHORT(PPPOL2TP_RESULTCODE, p); /* Attribute value: Result code */ - udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->tunnel_port); + if(l2tp->netif) { + udp_sendto_if(l2tp->udp, pb, &l2tp->remote_ip, l2tp->remote_port, l2tp->netif); + } else { + udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->remote_port); + } pbuf_free(pb); return ERR_OK; } @@ -1004,7 +1030,11 @@ err_t pppol2tp_xmit(pppol2tp_pcb *l2tp, struct pbuf *pb) { PUTSHORT(l2tp->source_tunnel_id, p); /* Tunnel Id */ PUTSHORT(l2tp->source_session_id, p); /* Session Id */ - udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->tunnel_port); + if(l2tp->netif) { + udp_sendto_if(l2tp->udp, pb, &l2tp->remote_ip, l2tp->remote_port, l2tp->netif); + } else { + udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->remote_port); + } pbuf_free(pb); return ERR_OK; }