Hi, Nathan.

> I'm looking at supporting Multilink PPP (using PPPoE) in OpenWrt and
> LuCI.
> 
> I've experimented by adding a "MLPPP" protocol
> to /usr/lib/lua/luci/model/network/proto_ppp.lua (and adding a copy of
> proto_pppoe.lua to model/cbi/admin_network/proto_mlppp.lua).
> 
> Unfortunately the 320-custom_iface_names.patch PPP patch doesn't work
> for Multilink PPP because mp_join_bundle() fails to find an IFNAME=pppX
> when bringing up the second link.
> 
> So my MLPPP protocol as a virtual interface doesn't work because
> virtual
> interfaces have to be named $proto-$config (e.g. mlppp-wan).
> 
> Now I've tried setting MLPPP up so it's not virtual and specified ppp0
> as the Custom Interface.  But now I'm having trouble because my
> proto_mlppp_setup() function in /lib/netifd/proto/ppp.sh doesn't seem
> to
> be getting called.
> 
> I suppose the best solution is to fix pppd so custom interface names
> work with Multilink PPP, but for now where can I find the code that's
> preventing my proto_mlppp_setup() from getting called?  I'm guessing
> it's because ppp0 doesn't exist (yet)?
Some time ago I've been building mlpppoe channel (its 4xpppoe over 18Mbps
adsl atm working for several months without noticeable problems). Attached
are patches I've used to get things working, network config from my ASUS
RT-N16 and /var/run/pppd2.tdb dump.

To get single pppoe-pppX bundled interface add config interface pppX to
your /etc/config/network for each link with option pppd_options multilink.
Then ifup your pppX interfaces and watch log - you should see first one
creating bundle and subsequent ones joining it.

Bear in mind patches provided won't make mlppp working for tty attached
links - only client-side mlppp with rp-pppoe or alike plugin.

Have nice day,
George
--- openwrt.orig/package/network/services/ppp/patches/404-multilink-fix-non-pppX-interface-naming.patch	1970-01-01 03:00:00.000000000 +0300
+++ openwrt/package/network/services/ppp/patches/404-multilink-fix-non-pppX-interface-naming.patch	2012-11-09 16:43:55.000000000 +0200
@@ -0,0 +1,146 @@
+From: George Kashperko <geo...@znau.edu.ua>
+
+Make mlppp support more generic interface naming other than pppX
+Signed-off-by: George Kashperko <geo...@znau.edu.ua>
+---
+ pppd/multilink.c |   55 +++++++++++++++++++++++++++++++++------------
+ pppd/sys-linux.c |   12 +++++++++
+ 2 files changed, 53 insertions(+), 14 deletions(-)
+--- ppp-2.4.5.orig/pppd/multilink.c	2009-11-17 00:26:07.000000000 +0200
++++ ppp-2.4.5/pppd/multilink.c	2012-10-22 01:35:25.291630529 +0300
+@@ -56,7 +56,8 @@ static void iterate_bundle_links __P((vo
+ 
+ static int get_default_epdisc __P((struct epdisc *));
+ static int parse_num __P((char *str, const char *key, int *valp));
+-static int owns_unit __P((TDB_DATA pid, int unit));
++static int parse_str __P((char *str, const char *key, char *buf, int buflen));
++static int owns_link __P((TDB_DATA pid, char *ifname));
+ 
+ #define set_ip_epdisc(ep, addr) do {	\
+ 	ep->length = 4;			\
+@@ -197,35 +198,38 @@ mp_join_bundle()
+ 	key.dptr = bundle_id;
+ 	key.dsize = p - bundle_id;
+ 	pid = tdb_fetch(pppdb, key);
++
+ 	if (pid.dptr != NULL) {
++		char tmp[IFNAMSIZ];
++
+ 		/* bundle ID exists, see if the pppd record exists */
+ 		rec = tdb_fetch(pppdb, pid);
++
+ 		if (rec.dptr != NULL && rec.dsize > 0) {
+ 			/* make sure the string is null-terminated */
+ 			rec.dptr[rec.dsize-1] = 0;
+-			/* parse the interface number */
+-			parse_num(rec.dptr, "IFNAME=ppp", &unit);
++
+ 			/* check the pid value */
+ 			if (!parse_num(rec.dptr, "PPPD_PID=", &pppd_pid)
++			    || !parse_str(rec.dptr, "IFNAME=", tmp, sizeof(tmp))
++			    || !parse_num(rec.dptr, "IFUNIT=", &unit)
+ 			    || !process_exists(pppd_pid)
+-			    || !owns_unit(pid, unit))
++			    || !owns_link(pid, tmp))
+ 				unit = -1;
+ 			free(rec.dptr);
+ 		}
+ 		free(pid.dptr);
+-	}
+ 
+-	if (unit >= 0) {
+ 		/* attach to existing unit */
+-		if (bundle_attach(unit)) {
++		if (unit >= 0 && bundle_attach(unit)) {
+ 			set_ifunit(0);
+ 			script_setenv("BUNDLE", bundle_id + 7, 0);
+ 			make_bundle_links(1);
+ 			unlock_db();
+-			info("Link attached to %s", ifname);
++			info("Link attached to %s", tmp);
+ 			return 1;
++			/* attach failed because bundle doesn't exist */
+ 		}
+-		/* attach failed because bundle doesn't exist */
+ 	}
+ 
+ 	/* we have to make a new bundle */
+@@ -408,22 +412,45 @@ parse_num(str, key, valp)
+ 	return 0;
+ }
+ 
++static int
++parse_str(str, key, buf, buflen)
++     char *str;
++     const char *key;
++     char *buf;
++     int buflen;
++{
++	char *p, *endp;
++	int i;
++
++	p = strstr(str, key);
++	if (p) {
++		p += strlen(key);
++		while (--buflen && *p != 0 && *p != ';')
++			*(buf++) = *(p++);
++		*buf = 0;
++		return 1;
++	}
++	return 0;
++}
++
+ /*
+- * Check whether the pppd identified by `key' still owns ppp unit `unit'.
++ * Check whether the pppd identified by `key' still owns ppp link `ifname'.
+  */
+ static int
+-owns_unit(key, unit)
++owns_link(key, ifname)
+      TDB_DATA key;
+-     int unit;
++     char *ifname;
+ {
+-	char ifkey[32];
++	char ifkey[7 + IFNAMSIZ];
+ 	TDB_DATA kd, vd;
+ 	int ret = 0;
+ 
+-	slprintf(ifkey, sizeof(ifkey), "IFNAME=ppp%d", unit);
++	slprintf(ifkey, sizeof(ifkey), "IFNAME=%s", ifname);
++
+ 	kd.dptr = ifkey;
+ 	kd.dsize = strlen(ifkey);
+ 	vd = tdb_fetch(pppdb, kd);
++
+ 	if (vd.dptr != NULL) {
+ 		ret = vd.dsize == key.dsize
+ 			&& memcmp(vd.dptr, key.dptr, vd.dsize) == 0;
+--- ppp-2.4.5.orig/pppd/sys-linux.c	2012-10-22 01:34:10.741635627 +0300
++++ ppp-2.4.5/pppd/sys-linux.c	2012-10-22 01:39:41.153613033 +0300
+@@ -700,6 +700,16 @@ void cfg_bundle(int mrru, int mtru, int 
+ 	add_fd(ppp_dev_fd);
+ }
+ 
++static void
++setenv_ifunit(void)
++{
++#ifdef USE_TDB
++	char tmp[11];
++	slprintf(tmp, sizeof(tmp), "%d", ifunit);
++	script_setenv("IFUNIT", tmp, 0);
++#endif
++}
++
+ /*
+  * make_new_bundle - create a new PPP unit (i.e. a bundle)
+  * and connect our channel to it.  This should only get called
+@@ -718,6 +728,8 @@ void make_new_bundle(int mrru, int mtru,
+ 
+ 	/* set the mrru and flags */
+ 	cfg_bundle(mrru, mtru, rssn, tssn);
++
++	setenv_ifunit();
+ }
+ 
+ /*
--- openwrt.orig/package/network/services/ppp/patches/405-multilink-fix-master-never-reconnect.patch	1970-01-01 03:00:00.000000000 +0300
+++ openwrt/package/network/services/ppp/patches/405-multilink-fix-master-never-reconnect.patch	2012-11-09 16:45:49.000000000 +0200
@@ -0,0 +1,256 @@
+From: George Kashperko <geo...@znau.edu.ua>
+
+Fix mlppp master never reconnecting after connection lost for plugin-
+based connections (like rp-pppoe).
+WARNING: This breaks tty-attached mlppp.
+Signed-off-by: George Kashperko <geo...@znau.edu.ua>
+---
+ pppd/auth.c      |   14 +++++-------
+ pppd/lcp.c       |    2 -
+ pppd/main.c      |   22 +++++++++++++------
+ pppd/multilink.c |   52 ++++++++++++++++++++++++++++++++++-----------
+ pppd/pppd.h      |    1 
+ 5 files changed, 63 insertions(+), 28 deletions(-)
+--- ppp-2.4.5.orig/pppd/auth.c	2009-11-17 00:26:07.000000000 +0200
++++ ppp-2.4.5/pppd/auth.c	2012-10-22 04:04:15.731019865 +0300
+@@ -616,7 +616,7 @@ void
+ link_terminated(unit)
+     int unit;
+ {
+-    if (phase == PHASE_DEAD || phase == PHASE_MASTER)
++    if (phase == PHASE_DEAD)
+ 	return;
+     new_phase(PHASE_DISCONNECT);
+ 
+@@ -654,7 +654,7 @@ link_terminated(unit)
+     }
+     if (!hungup)
+ 	lcp_lowerdown(0);
+-    if (!doing_multilink && !demand)
++    if (!doing_multilink && !demand && !multilink_master)
+ 	script_unsetenv("IFNAME");
+ 
+     /*
+@@ -669,12 +669,10 @@ link_terminated(unit)
+ 	(*the_channel->cleanup)();
+ 
+     if (doing_multilink && multilink_master) {
+-	if (!bundle_terminating)
+-	    new_phase(PHASE_MASTER);
+-	else
++	if (bundle_terminating)
+ 	    mp_bundle_terminated();
+-    } else
+-	new_phase(PHASE_DEAD);
++    }
++    new_phase(PHASE_DEAD);
+ }
+ 
+ /*
+@@ -695,7 +693,7 @@ link_down(unit)
+     }
+     if (!doing_multilink) {
+ 	upper_layers_down(unit);
+-	if (phase != PHASE_DEAD && phase != PHASE_MASTER)
++	if (phase != PHASE_DEAD)
+ 	    new_phase(PHASE_ESTABLISH);
+     }
+     /* XXX if doing_multilink, should do something to stop
+--- ppp-2.4.5.orig/pppd/lcp.c	2012-10-22 01:34:10.000000000 +0300
++++ ppp-2.4.5/pppd/lcp.c	2012-10-22 01:57:13.393541081 +0300
+@@ -398,7 +398,7 @@ lcp_close(unit, reason)
+ {
+     fsm *f = &lcp_fsm[unit];
+ 
+-    if (phase != PHASE_DEAD && phase != PHASE_MASTER)
++    if (phase != PHASE_DEAD)
+ 	new_phase(PHASE_TERMINATE);
+     if (f->state == STOPPED && f->flags & (OPT_PASSIVE|OPT_SILENT)) {
+ 	/*
+--- ppp-2.4.5.orig/pppd/main.c	2012-10-22 01:34:10.000000000 +0300
++++ ppp-2.4.5/pppd/main.c	2012-10-22 04:48:00.457840387 +0300
+@@ -552,7 +552,7 @@ main(argc, argv)
+ 		lcp_close(0, "User request");
+ 	    if (asked_to_quit) {
+ 		bundle_terminating = 1;
+-		if (phase == PHASE_MASTER)
++		if (multilink_master)
+ 		    mp_bundle_terminated();
+ 	    }
+ 	    if (open_ccp_flag) {
+@@ -565,7 +565,7 @@ main(argc, argv)
+ 	/* restore FSMs to original state */
+ 	lcp_close(0, "");
+ 
+-	if (!persist || asked_to_quit || (maxfail > 0 && unsuccess >= maxfail))
++	if (!persist || asked_to_quit || (maxfail > 0 && unsuccess >= maxfail && !multilink_master))
+ 	    break;
+ 
+ 	if (demand)
+@@ -578,8 +578,11 @@ main(argc, argv)
+ 	    TIMEOUT(holdoff_end, NULL, t);
+ 	    do {
+ 		handle_events();
+-		if (kill_link)
++		if (kill_link) {
++		    if (multilink_master)
++			mp_bundle_terminated();
+ 		    new_phase(PHASE_DORMANT); /* allow signal to end holdoff */
++		}
+ 	    } while (phase == PHASE_HOLDOFF);
+ 	    if (!persist)
+ 		break;
+@@ -599,8 +602,12 @@ main(argc, argv)
+ 	}
+ 	while (n_children > 0 && !childwait_done) {
+ 	    handle_events();
+-	    if (kill_link && !childwait_done)
+-		childwait_end(NULL);
++	    if (kill_link) {
++		if (multilink_master)
++		    mp_bundle_terminated();
++		if (!childwait_done)
++		    childwait_end(NULL);
++	    }
+ 	}
+     }
+ 
+@@ -1223,8 +1230,11 @@ cleanup()
+ {
+     sys_cleanup();
+ 
+-    if (fd_ppp >= 0)
++    if (fd_ppp >= 0) {
+ 	the_channel->disestablish_ppp(devfd);
++	if (doing_multilink)
++	    mp_exit_bundle();
++    }
+     if (the_channel->cleanup)
+ 	(*the_channel->cleanup)();
+     remove_pidfiles();
+--- ppp-2.4.5.orig/pppd/multilink.c	2012-10-22 02:20:13.368446716 +0300
++++ ppp-2.4.5/pppd/multilink.c	2012-10-22 04:05:34.880014452 +0300
+@@ -46,6 +46,7 @@ char *bundle_id;		/* identifier for our 
+ char *blinks_id;		/* key for the list of links */
+ bool doing_multilink;		/* multilink was enabled and agreed to */
+ bool multilink_master;		/* we own the multilink bundle */
++int pppd_pid;			/* bundle master pppd pid */
+ 
+ extern TDB_CONTEXT *pppdb;
+ extern char db_key[];
+@@ -108,12 +109,12 @@ mp_join_bundle()
+ 	lcp_options *go = &lcp_gotoptions[0];
+ 	lcp_options *ho = &lcp_hisoptions[0];
+ 	lcp_options *ao = &lcp_allowoptions[0];
+-	int unit, pppd_pid;
++	int unit;
+ 	int l, mtu;
+ 	char *p;
+ 	TDB_DATA key, pid, rec;
+ 
+-	if (doing_multilink) {
++	if (doing_multilink && !multilink_master) {
+ 		/* have previously joined a bundle */
+ 		if (!go->neg_mrru || !ho->neg_mrru) {
+ 			notice("oops, didn't get multilink on renegotiation");
+@@ -157,7 +158,7 @@ mp_join_bundle()
+ 		l += 3 * ho->endpoint.length + 8;
+ 	if (bundle_name)
+ 		l += 3 * strlen(bundle_name) + 2;
+-	bundle_id = malloc(l);
++	bundle_id = realloc(bundle_id, l);
+ 	if (bundle_id == 0)
+ 		novm("bundle identifier");
+ 
+@@ -173,7 +174,7 @@ mp_join_bundle()
+ 
+ 	/* Make the key for the list of links belonging to the bundle */
+ 	l = p - bundle_id;
+-	blinks_id = malloc(l + 7);
++	blinks_id = realloc(blinks_id, l + 7);
+ 	if (blinks_id == NULL)
+ 		novm("bundle links key");
+ 	slprintf(blinks_id, l + 7, "BUNDLE_LINKS=%s", bundle_id + 7);
+@@ -221,14 +222,20 @@ mp_join_bundle()
+ 		free(pid.dptr);
+ 
+ 		/* attach to existing unit */
++
+ 		if (unit >= 0 && bundle_attach(unit)) {
+-			set_ifunit(0);
+-			script_setenv("BUNDLE", bundle_id + 7, 0);
++			set_ifunit(multilink_master);
++			script_setenv("BUNDLE", bundle_id + 7, multilink_master);
+ 			make_bundle_links(1);
+ 			unlock_db();
+ 			info("Link attached to %s", tmp);
+ 			return 1;
+-			/* attach failed because bundle doesn't exist */
++		}
++
++		/* attach failed because bundle doesn't exist */
++		if (multilink_master) {
++			unlock_db();
++			return 0;
+ 		}
+ 	}
+ 
+@@ -244,22 +251,43 @@ mp_join_bundle()
+ 	return 0;
+ }
+ 
++static void __sendhup(pid_t pid)
++{
++	if (debug)
++		dbglog("sending SIGHUP to process %d", pid);
++	kill(pid, SIGHUP);
++}
++
+ void mp_exit_bundle()
+ {
++	int nr_links = 0;
++
++	auto void count(char *str)
++	{
++		nr_links++;
++	}
++
+ 	lock_db();
+ 	remove_bundle_link();
++	iterate_bundle_links(count);
++	doing_multilink = 0;
+ 	unlock_db();
++
++	if (nr_links)
++		return;
++
++	if (multilink_master)
++		mp_bundle_terminated();
++	else
++		__sendhup(pppd_pid);
+ }
+ 
+ static void sendhup(char *str)
+ {
+ 	int pid;
+ 
+-	if (parse_num(str, "PPPD_PID=", &pid) && pid != getpid()) {
+-		if (debug)
+-			dbglog("sending SIGHUP to process %d", pid);
+-		kill(pid, SIGHUP);
+-	}
++	if (parse_num(str, "PPPD_PID=", &pid) && pid != getpid())
++		__sendhup(pid);
+ }
+ 
+ void mp_bundle_terminated()
+--- ppp-2.4.5.orig/pppd/pppd.h	2012-10-22 01:34:10.000000000 +0300
++++ ppp-2.4.5/pppd/pppd.h	2012-10-22 02:13:02.525476177 +0300
+@@ -391,7 +391,6 @@ extern int  option_priority;	/* priority
+ #define PHASE_TERMINATE		9
+ #define PHASE_DISCONNECT	10
+ #define PHASE_HOLDOFF		11
+-#define PHASE_MASTER		12
+ 
+ /*
+  * The following struct gives the addresses of procedures to call

Attachment: etc.config.network
Description: Binary data

{
key = "pppd1222"
data = 
"ORIG_UID=0;PPPLOGNAME=root;DEVICE=eth0.1;PPPD_PID=1222;MACREMOTE=1C:AF:F7:0E:89:EB;IFNAME=pppoe-ppp0;BUNDLE=\22\22/MAC:00:e0:81:24:f5:04\00"
}
{
key = "PPPD_PID=1222"
data = "pppd1222"
}
{
key = "BUNDLE=\22\22/MAC:00:e0:81:24:f5:04"
data = "pppd938"
}
{
key = "pppd938"
data = 
"ORIG_UID=0;PPPLOGNAME=root;DEVICE=eth0.2;PPPD_PID=938;MACREMOTE=1C:AF:F7:0E:89:EB;IFUNIT=0;IFNAME=pppoe-ppp1;BUNDLE=\22\22/MAC:00:e0:81:24:f5:04;IPLOCAL=192.168.255.142;IPREMOTE=192.168.255.2;DNS1=10.0.2.10;DNS2=10.0.2.10;USEPEERDNS=1\00"
}
{
key = "DEVICE=eth0.4"
data = "pppd1157"
}
{
key = "IFNAME=pppoe-ppp1"
data = "pppd938"
}
{
key = "DEVICE=eth0.1"
data = "pppd1222"
}
{
key = "pppd1157"
data = 
"ORIG_UID=0;PPPLOGNAME=root;DEVICE=eth0.4;PPPD_PID=1157;MACREMOTE=1C:AF:F7:0E:89:E8;IFNAME=pppoe-ppp3;BUNDLE=\22\22/MAC:00:e0:81:24:f5:04\00"
}
{
key = "pppd1211"
data = 
"ORIG_UID=0;PPPLOGNAME=root;DEVICE=eth0.3;PPPD_PID=1211;MACREMOTE=1C:AF:F7:0E:89:E8;IFNAME=pppoe-ppp2;BUNDLE=\22\22/MAC:00:e0:81:24:f5:04\00"
}
{
key = "PPPD_PID=938"
data = "pppd938"
}
{
key = "DEVICE=eth0.2"
data = "pppd938"
}
{
key = "IPREMOTE=192.168.255.2"
data = "pppd938"
}
{
key = "PPPD_PID=1211"
data = "pppd1211"
}
{
key = "BUNDLE_LINKS=\22\22/MAC:00:e0:81:24:f5:04"
data = "pppd938;pppd1157;pppd1222;pppd1211;\00"
}
{
key = "PPPD_PID=1157"
data = "pppd1157"
}
{
key = "DEVICE=eth0.3"
data = "pppd1211"
}
_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel

Reply via email to