Hi James,
Any news on this?
BTW, I don't have any news from the pppd side either, so I join to this
email my two patches for it.
Thanks.
Le mardi 07 mai 2013 à 10:58 +0100, James Chapman a écrit :
> Thanks Benjamin.
>
> I'll review your patches as soon as I can. Unfortunately I won't have
> time to do so for at least 2 weeks due to other committments.
>
> Thanks again, and sorry for the delay.
>
> James
>
>
> On 29/04/13 13:30, Benjamin Cama wrote:
> > Hi,
> >
> > I needed explicit IPv6 support for some application, and handled it with the
> > following patches.
> >
> > The first one is just a typo fix. The second one adds IPv6CP explicit
> > support.
> > The third one allows to disable IPCP altogether, when one wants an IPv6-only
> > session. And the last one allows to set the "ipparam" parameter passed to
> > pppd,
> > which will forward it to the ip-up/down script.
> >
> > BTW, it is a bit hard to add such parameters to OpenL2TP. I thought that the
> > code would be a bit more generalized. Also, one must be carefull with
> > default
> > values: it depends both on the value you define as "default", _and_ on how
> > you
> > handle it in the plugin, taking into account the flag signaling the presence
> > (or not) of the parameter. Anyway, I tested that it works well, and it does.
> >
> > Please note that IPv6-only sessions need a patch to pppd that I submitted
> > recently to the project to work well; otherwise, sessions are shut down
> > after
> > the session establishment timeout.
> >
> > Regards,
> >
> > Benjamin Cama (4):
> > l2tp_config_parse.y: Fix typo mixing LCP and IPCP parameters
> > Add explicit IPv6 support
> > IPCP deactivation support
> > Support for passing ipparam to pppd
> >
> > doc/l2tpconfig.1 | 15 +++++++
> > l2tp_api.c | 1 +
> > l2tp_common.c | 22 ++++++++--
> > l2tp_config.c | 109
> > +++++++++++++++++++++++++++++++++++++++++++++++++-
> > l2tp_config_parse.y | 51 +++++++++++++++++++++++-
> > l2tp_config_token.l | 7 +++
> > l2tp_ppp.c | 97 +++++++++++++++++++++++++++++++++++++++++++++
> > l2tp_rpc.x | 21 ++++++++++
> > plugins/ppp_unix.c | 21 ++++++++++
> > 9 files changed, 335 insertions(+), 9 deletions(-)
> >
>
>
>
--
Benjamin Cama <[email protected]>
>From 3b549d7197b02c6b78ba0bcef89f431dfa8b81f2 Mon Sep 17 00:00:00 2001
From: Benjamin Cama <[email protected]>
Date: Mon, 5 Nov 2012 20:54:55 +0100
Subject: [PATCH 1/2] Separate IPv6 handling for sifup/sifdown
The current code is buggy regarding handling of link state when using
both IPCP and IPv6CP: if IPv6CP has been set up and if during IPCP
negociation, ipcp_up() fails, it will incorrectly take the interface
down. The simple solution here is to change the platform code to do the
same as on Solaris: separate IPv6CP up/down state handling with sif6up()
and sif6down(), so that we really know when the interface is allowed to
go down.
Signed-off-by: Benjamin Cama <[email protected]>
---
pppd/ipv6cp.c | 14 +++++----
pppd/sys-linux.c | 82 ++++++++++++++++++++++++++++++++++++++++-------------
2 files changed, 70 insertions(+), 26 deletions(-)
diff --git a/pppd/ipv6cp.c b/pppd/ipv6cp.c
index caa2b26..7e76073 100644
--- a/pppd/ipv6cp.c
+++ b/pppd/ipv6cp.c
@@ -1147,13 +1147,13 @@ ipv6_demand_conf(u)
ipv6cp_options *wo = &ipv6cp_wantoptions[u];
#if defined(__linux__) || defined(SOL2) || (defined(SVR4) && (defined(SNI) || defined(__USLC__)))
-#if defined(SOL2)
+#if defined(SOL2) || defined(__linux__)
if (!sif6up(u))
return 0;
#else
if (!sifup(u))
return 0;
-#endif /* defined(SOL2) */
+#endif /* defined(SOL2) || defined(__linux__) */
#endif
if (!sif6addr(u, wo->ourid, wo->hisid))
return 0;
@@ -1260,10 +1260,10 @@ ipv6cp_up(f)
#endif
/* bring the interface up for IPv6 */
-#if defined(SOL2)
+#if defined(SOL2) || defined(__linux__)
if (!sif6up(f->unit)) {
if (debug)
- warn("sifup failed (IPV6)");
+ warn("sif6up failed (IPV6)");
ipv6cp_close(f->unit, "Interface configuration failed");
return;
}
@@ -1274,7 +1274,7 @@ ipv6cp_up(f)
ipv6cp_close(f->unit, "Interface configuration failed");
return;
}
-#endif /* defined(SOL2) */
+#endif /* defined(SOL2) || defined(__linux__) */
#if defined(__linux__) || defined(SOL2) || (defined(SVR4) && (defined(SNI) || defined(__USLC__)))
if (!sif6addr(f->unit, go->ourid, ho->hisid)) {
@@ -1349,7 +1349,9 @@ ipv6cp_down(f)
ipv6cp_clear_addrs(f->unit,
ipv6cp_gotoptions[f->unit].ourid,
ipv6cp_hisoptions[f->unit].hisid);
-#if defined(__linux__) || (defined(SVR4) && (defined(SNI) || defined(__USLC)))
+#if defined(__linux__)
+ sif6down(f->unit);
+#elif defined(SVR4) && (defined(SNI) || defined(__USLC))
sifdown(f->unit);
#endif
}
diff --git a/pppd/sys-linux.c b/pppd/sys-linux.c
index 2540c4f..20ccf31 100644
--- a/pppd/sys-linux.c
+++ b/pppd/sys-linux.c
@@ -205,6 +205,7 @@ static char loop_name[20];
static unsigned char inbuf[512]; /* buffer for chars read from loopback */
static int if_is_up; /* Interface has been marked up */
+static int if6_is_up; /* Interface has been marked up for IPv6, to help differentiate */
static int have_default_route; /* Gateway for default route added */
static u_int32_t proxy_arp_addr; /* Addr for proxy arp entry added */
static char proxy_arp_dev[16]; /* Device for proxy arp entry */
@@ -338,6 +339,9 @@ void sys_cleanup(void)
if_is_up = 0;
sifdown(0);
}
+ if (if6_is_up)
+ sif6down(0);
+
/*
* Delete any routes through the device.
*/
@@ -2251,25 +2255,12 @@ int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid)
int sifup(int u)
{
- struct ifreq ifr;
-
- memset (&ifr, '\0', sizeof (ifr));
- strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
- if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
- if (! ok_error (errno))
- error("ioctl (SIOCGIFFLAGS): %m (line %d)", __LINE__);
- return 0;
- }
+ int ret;
- ifr.ifr_flags |= (IFF_UP | IFF_POINTOPOINT);
- if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
- if (! ok_error (errno))
- error("ioctl(SIOCSIFFLAGS): %m (line %d)", __LINE__);
- return 0;
- }
- if_is_up++;
+ if ((ret = setifstate(u, 1)))
+ if_is_up++;
- return 1;
+ return ret;
}
/********************************************************************
@@ -2280,11 +2271,59 @@ int sifup(int u)
int sifdown (int u)
{
- struct ifreq ifr;
-
if (if_is_up && --if_is_up > 0)
return 1;
+#ifdef INET6
+ if (if6_is_up)
+ return 1;
+#endif /* INET6 */
+
+ return setifstate(u, 0);
+}
+
+#ifdef INET6
+/********************************************************************
+ *
+ * sif6up - Config the interface up for IPv6
+ */
+
+int sif6up(int u)
+{
+ int ret;
+
+ if ((ret = setifstate(u, 1)))
+ if6_is_up = 1;
+
+ return ret;
+}
+
+/********************************************************************
+ *
+ * sif6down - Disable the IPv6CP protocol and config the interface
+ * down if there are no remaining protocols.
+ */
+
+int sif6down (int u)
+{
+ if6_is_up = 0;
+
+ if (if_is_up)
+ return 1;
+
+ return setifstate(u, 0);
+}
+#endif /* INET6 */
+
+/********************************************************************
+ *
+ * setifstate - Config the interface up or down
+ */
+
+int setifstate (int u, int state)
+{
+ struct ifreq ifr;
+
memset (&ifr, '\0', sizeof (ifr));
strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
@@ -2293,7 +2332,10 @@ int sifdown (int u)
return 0;
}
- ifr.ifr_flags &= ~IFF_UP;
+ if (state)
+ ifr.ifr_flags |= IFF_UP;
+ else
+ ifr.ifr_flags &= ~IFF_UP;
ifr.ifr_flags |= IFF_POINTOPOINT;
if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
if (! ok_error (errno))
--
1.7.2.5
>From 4d8ee7a592dd92d76377d44508ccf4add5aeb0f3 Mon Sep 17 00:00:00 2001
From: Benjamin Cama <[email protected]>
Date: Tue, 2 Oct 2012 19:50:55 +0200
Subject: [PATCH 2/2] pppol2tp: Connect up/down events to notifiers and add IPv6 ones
Connect ip up/down events instead of using hooks, and add IPv6 up/down
events notifications too, so that we signal IPv6-only sessions
correctly; otherwise, they may get taken down because the L2TP daemon
has not received any notification.
Signed-off-by: Benjamin Cama <[email protected]>
---
pppd/plugins/pppol2tp/pppol2tp.c | 30 ++++++++++++------------------
1 files changed, 12 insertions(+), 18 deletions(-)
diff --git a/pppd/plugins/pppol2tp/pppol2tp.c b/pppd/plugins/pppol2tp/pppol2tp.c
index a7e3400..0e28606 100644
--- a/pppd/plugins/pppol2tp/pppol2tp.c
+++ b/pppd/plugins/pppol2tp/pppol2tp.c
@@ -74,8 +74,6 @@ struct channel pppol2tp_channel;
static void (*old_snoop_recv_hook)(unsigned char *p, int len) = NULL;
static void (*old_snoop_send_hook)(unsigned char *p, int len) = NULL;
-static void (*old_ip_up_hook)(void) = NULL;
-static void (*old_ip_down_hook)(void) = NULL;
/* Hook provided to allow other plugins to handle ACCM changes */
void (*pppol2tp_send_accm_hook)(int tunnel_id, int session_id,
@@ -436,22 +434,18 @@ static void pppol2tp_lcp_snoop_send(unsigned char *p, int len)
* Interface up/down events
*****************************************************************************/
-static void pppol2tp_ip_up_hook(void)
+static void pppol2tp_ip_up(void *opaque, int arg)
{
- if (old_ip_up_hook != NULL)
- (*old_ip_up_hook)();
-
+ /* may get called twice (for IPv4 and IPv6) but the hook handles that well */
if (pppol2tp_ip_updown_hook != NULL) {
(*pppol2tp_ip_updown_hook)(pppol2tp_tunnel_id,
pppol2tp_session_id, 1);
}
}
-static void pppol2tp_ip_down_hook(void)
+static void pppol2tp_ip_down(void *opaque, int arg)
{
- if (old_ip_down_hook != NULL)
- (*old_ip_down_hook)();
-
+ /* may get called twice (for IPv4 and IPv6) but the hook handles that well */
if (pppol2tp_ip_updown_hook != NULL) {
(*pppol2tp_ip_updown_hook)(pppol2tp_tunnel_id,
pppol2tp_session_id, 0);
@@ -478,14 +472,6 @@ static void pppol2tp_check_options(void)
snoop_recv_hook = pppol2tp_lcp_snoop_recv;
snoop_send_hook = pppol2tp_lcp_snoop_send;
}
-
- /* Hook up ip up/down hooks to send indicator to openl2tpd
- * that the link is up
- */
- old_ip_up_hook = ip_up_hook;
- ip_up_hook = pppol2tp_ip_up_hook;
- old_ip_down_hook = ip_down_hook;
- ip_down_hook = pppol2tp_ip_down_hook;
}
/* Called just before pppd exits.
@@ -509,6 +495,14 @@ void plugin_init(void)
fatal("No PPPoL2TP support on this OS");
#endif
add_options(pppol2tp_options);
+
+ /* Hook up ip up/down notifiers to send indicator to openl2tpd
+ * that the link is up
+ */
+ add_notifier(&ip_up_notifier, pppol2tp_ip_up, NULL);
+ add_notifier(&ip_down_notifier, pppol2tp_ip_down, NULL);
+ add_notifier(&ipv6_up_notifier, pppol2tp_ip_up, NULL);
+ add_notifier(&ipv6_down_notifier, pppol2tp_ip_down, NULL);
}
struct channel pppol2tp_channel = {
--
1.7.2.5
------------------------------------------------------------------------------
This SF.net email is sponsored by Windows:
Build for Windows Store.
http://p.sf.net/sfu/windows-dev2dev
_______________________________________________
Openl2tp-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openl2tp-users