L2TP output netif is now selectable, making it useful to select a default route for the L2TP tunnel, in case the default interface is set to the L2TP PPP interface

This commit is contained in:
Sylvain Rochet 2012-07-12 01:11:08 +02:00
parent de6be743c6
commit 78565026ac
6 changed files with 67 additions and 30 deletions

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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 */

View File

@ -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;
}