Subject: ppp: Please support arbitrary interface names
Package: ppp
Version: 2.4.4rel-9
Severity: normal
Justification (for not being wishlist): because selectable interface names are 
becoming necessary on today's increasingly complex ADSL, UMTS; etc. 
configrations
Tags: patch, upstream

*** Please type your report below this line ***

Use of arbitrary and freely selectable network interface names both improves
manageability of systems with multiple interfaces (e.g. two "outgoing" ADSL
lines for upstream connection and multiple "incoming" L2TP/IPSec tunnels with
obviously very different settings/requirements) and makes firewalling much
easier. Although pppX interface names can be changed with 
"ip link set pppX name YYYY", e.g. in ip-up.d/ scripts, this solution is far 
from optimal because ppp itself gets confused when the current interface name
does not correspond to its internal "unit name". The most obvious breakage is
that statistics no longer get printed (e.g. to syslog) when terminating a
connection and that the CONNECT_TIME, BYTES_RCVD, and BYTES_SENT variables 
are not set for ip-down scripts. This makes accurate accounting and keeping
track of quota a lot harder.

I found the attached patch on the ppp mailing list archives from quite a while
ago and forward-ported it to ppp 2.4.4 with Debian specific patches taken into
consideration. It should apply cleanly when dropping the attached file into
debian/patches. When applied, the new option "ifname" can be used e.g. in
/etc/ppp/peers/YYY to set which interface name should be used for the specific
connection. This is complementary to the existing "linkname" option, which is 
not sufficient for clean interaction with firewalling, NAT, policy routing, 
IPSec, etc.
I have tested it on multiple systems with and without this option being used 
and found no issues at all (elthough I have not tried multilink, which the 
patch also seems to take care of). It will be used for all ppp versions in 
future Gibraltar releases.

Please consider applying it to future ppp packages.

best regards,
Rene

-- System Information:
Debian Release: lenny/sid
  APT prefers testing
  APT policy: (800, 'testing'), (300, 'unstable'), (100, 'experimental')
Architecture: i386 (i686)

Kernel: Linux 2.6.22-3-686 (SMP w/1 CPU core)
Locale: LANG=de_AT.UTF-8, LC_CTYPE=de_AT.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash

Versions of packages ppp depends on:
ii  libc6                         2.7-5      GNU C Library: Shared libraries
ii  libpam-modules                0.99.7.1-5 Pluggable Authentication Modules 
f
ii  libpam-runtime                0.99.7.1-5 Runtime support for the PAM 
librar
ii  libpam0g                      0.99.7.1-5 Pluggable Authentication Modules 
l
ii  libpcap0.8                    0.9.8-2    System interface for user-level 
pa
ii  netbase                       4.30       Basic TCP/IP networking system
ii  procps                        1:3.2.7-5  /proc file system utilities

ppp recommends no packages.

-- no debconf information
diff -urN ppp-2.4.4.orig/pppd/auth.c ppp-2.4.4/pppd/auth.c
--- ppp-2.4.4.orig/pppd/auth.c	Tue Jan  1 14:44:37 2008
+++ ppp-2.4.4/pppd/auth.c	Tue Jan  1 14:45:12 2008
@@ -647,8 +647,10 @@
     }
     if (!hungup)
 	lcp_lowerdown(0);
-    if (!doing_multilink && !demand)
+    if (!doing_multilink && !demand) {
 	script_unsetenv("IFNAME");
+        script_unsetenv("IFUNIT");
+    }
 
     /*
      * Run disconnector script, if requested.
diff -urN ppp-2.4.4.orig/pppd/main.c ppp-2.4.4/pppd/main.c
--- ppp-2.4.4.orig/pppd/main.c	Tue Jan  1 14:44:37 2008
+++ ppp-2.4.4/pppd/main.c	Tue Jan  1 14:45:12 2008
@@ -739,9 +739,14 @@
 set_ifunit(iskey)
     int iskey;
 {
-    info("Using interface %s%d", PPP_DRV_NAME, ifunit);
     slprintf(ifname, sizeof(ifname), "%s%d", PPP_DRV_NAME, ifunit);
-    script_setenv("IFNAME", ifname, iskey);
+    info("Using interface %s", ifname);
+    script_setenv("IFUNIT", ifname, iskey);
+    if (req_ifname[0] && sys_change_ifname(ifname, req_ifname)) {
+       slprintf(ifname, sizeof(ifname), "%s", req_ifname);
+        info("Changing interface to %s", ifname);
+    }
+    script_setenv("IFNAME", ifname, 0);
     if (iskey) {
 	create_pidfile(getpid());	/* write pid to file */
 	create_linkpidfile(getpid());
diff -urN ppp-2.4.4.orig/pppd/multilink.c ppp-2.4.4/pppd/multilink.c
--- ppp-2.4.4.orig/pppd/multilink.c	Tue Jan  1 14:44:37 2008
+++ ppp-2.4.4/pppd/multilink.c	Tue Jan  1 14:45:12 2008
@@ -204,7 +204,7 @@
 			/* make sure the string is null-terminated */
 			rec.dptr[rec.dsize-1] = 0;
 			/* parse the interface number */
-			parse_num(rec.dptr, "IFNAME=ppp", &unit);
+			parse_num(rec.dptr, "IFUNIT=ppp", &unit);
 			/* check the pid value */
 			if (!parse_num(rec.dptr, "PPPD_PID=", &pppd_pid)
 			    || !process_exists(pppd_pid)
@@ -417,7 +417,7 @@
 	TDB_DATA kd, vd;
 	int ret = 0;
 
-	slprintf(ifkey, sizeof(ifkey), "IFNAME=ppp%d", unit);
+	slprintf(ifkey, sizeof(ifkey), "IFUNIT=ppp%d", unit);
 	kd.dptr = ifkey;
 	kd.dsize = strlen(ifkey);
 	vd = tdb_fetch(pppdb, kd);
diff -urN ppp-2.4.4.orig/pppd/options.c ppp-2.4.4/pppd/options.c
--- ppp-2.4.4.orig/pppd/options.c	Tue Jan  1 14:44:37 2008
+++ ppp-2.4.4/pppd/options.c	Tue Jan  1 14:46:03 2008
@@ -113,6 +113,7 @@
 bool	tune_kernel;		/* may alter kernel settings */
 int	connect_delay = 1000;	/* wait this many ms after connect script */
 int	req_unit = -1;		/* requested interface unit */
+char    req_ifname[16];         /* requested interface name */
 char	path_ipup[MAXPATHLEN];	/* pathname of ip-up script */
 char	path_ipdown[MAXPATHLEN];/* pathname of ip-down script */
 bool	multilink = 0;		/* Enable multilink operation */
@@ -273,6 +274,10 @@
     { "unit", o_int, &req_unit,
       "PPP interface unit number to use if possible",
       OPT_PRIO | OPT_LLIMIT, 0, 0 },
+
+    { "ifname", o_string, req_ifname,
+      "PPP interface name to use if possible",
+      OPT_PRIO | OPT_PRIV | OPT_STATIC, NULL, sizeof(req_ifname) },
 
     { "dump", o_bool, &dump_options,
       "Print out option values after parsing all options", 1 },
diff -urN ppp-2.4.4.orig/pppd/pppd.h ppp-2.4.4/pppd/pppd.h
--- ppp-2.4.4.orig/pppd/pppd.h	Tue Jan  1 14:44:37 2008
+++ ppp-2.4.4/pppd/pppd.h	Tue Jan  1 14:46:39 2008
@@ -312,6 +312,7 @@
 extern int	connect_delay;	/* Time to delay after connect script */
 extern int	max_data_rate;	/* max bytes/sec through charshunt */
 extern int	req_unit;	/* interface unit number to use */
+extern char     req_ifname[16]; /* interface name to use */
 extern char	path_ipup[MAXPATHLEN]; /* pathname of ip-up script */
 extern char	path_ipdown[MAXPATHLEN]; /* pathname of ip-down script */
 extern bool	multilink;	/* enable multilink operation */
@@ -670,6 +671,7 @@
 #endif
 int  get_if_hwaddr __P((u_char *addr, char *name));
 char *get_first_ethernet __P((void));
+int sys_change_ifname __P((const char *, const char *));
 
 /* Procedures exported from options.c */
 int setipaddr __P((char *, char **, int)); /* Set local/remote ip addresses */
diff -urN ppp-2.4.4.orig/pppd/sys-linux.c ppp-2.4.4/pppd/sys-linux.c
--- ppp-2.4.4.orig/pppd/sys-linux.c	Tue Jan  1 14:44:37 2008
+++ ppp-2.4.4/pppd/sys-linux.c	Tue Jan  1 14:45:12 2008
@@ -2931,4 +2931,29 @@
 
     return 1;
 }
 #endif
+
+int
+sys_change_ifname(const char *old, const char *new)
+{
+    struct ifreq ifr;
+
+    SYSDEBUG ((LOG_DEBUG, "sys_change_ifname: %s -> %s\n", old, new));
+
+    memset (&ifr, '\0', sizeof (ifr));
+    strlcpy(ifr.ifr_name, old, sizeof (ifr.ifr_name));
+    strlcpy(ifr.ifr_newname, new, sizeof (ifr.ifr_newname));
+
+#ifndef SIOCSIFNAME
+#define SIOCSIFNAME 0x8923
+#endif
+    if (ioctl(sock_fd, SIOCSIFNAME, (caddr_t) &ifr) < 0) {
+       if (errno == EEXIST)
+           warn("Couldn't change name to %s as it is already in use", new);
+       else
+           error("Couldn't change name from %s to %s: %m", old, new);
+       return 0;
+    }
+    return 1;
+}
+

Attachment: signature.asc
Description: This is a digitally signed message part.

Reply via email to