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

Reply via email to