OpenWrt – Rev 4

Subversion Repositories:
Rev:
pppd: Support arbitrary interface names

This patch implements a new string option "ifname" which allows to specify
fully custom PPP interface names on Linux. It does so by renaming the
allocated pppX device immediately after it has been created to the requested
interface name.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>

--- a/pppd/main.c
+++ b/pppd/main.c
@@ -745,8 +745,11 @@ void
 set_ifunit(iskey)
     int iskey;
 {
-    info("Using interface %s%d", PPP_DRV_NAME, ifunit);
-    slprintf(ifname, sizeof(ifname), "%s%d", PPP_DRV_NAME, ifunit);
+    if (use_ifname[0] == 0)
+       slprintf(ifname, sizeof(ifname), "%s%d", PPP_DRV_NAME, ifunit);
+    else
+       slprintf(ifname, sizeof(ifname), "%s", use_ifname);
+    info("Using interface %s", ifname);
     script_setenv("IFNAME", ifname, iskey);
     if (iskey) {
        create_pidfile(getpid());       /* write pid to file */
--- a/pppd/options.c
+++ b/pppd/options.c
@@ -112,6 +112,7 @@ int log_to_fd = 1;          /* send log messages
 bool   log_default = 1;        /* log_to_fd is default (stdout) */
 int    maxfail = 10;           /* max # of unsuccessful connection attempts */
 char   linkname[MAXPATHLEN];   /* logical name for link */
+char   use_ifname[IFNAMSIZ];   /* physical name for PPP link */
 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 */
@@ -277,6 +278,9 @@ option_t general_options[] = {
     { "linkname", o_string, linkname,
       "Set logical name for link",
       OPT_PRIO | OPT_PRIV | OPT_STATIC, NULL, MAXPATHLEN },
+    { "ifname", o_string, use_ifname,
+      "Set physical name for PPP interface",
+      OPT_PRIO | OPT_PRIV | OPT_STATIC, NULL, IFNAMSIZ },
 
     { "maxfail", o_int, &maxfail,
       "Maximum number of unsuccessful connection attempts to allow",
--- a/pppd/pppd.h
+++ b/pppd/pppd.h
@@ -74,6 +74,10 @@
 #include "eui64.h"
 #endif
 
+#ifndef IFNAMSIZ
+#define IFNAMSIZ       16
+#endif
+
 /*
  * Limits.
  */
@@ -317,6 +321,7 @@ extern char *record_file;   /* File to rec
 extern bool    sync_serial;    /* Device is synchronous serial device */
 extern int     maxfail;        /* Max # of unsuccessful connection attempts */
 extern char    linkname[MAXPATHLEN]; /* logical name for link */
+extern char    use_ifname[IFNAMSIZ]; /* physical name for PPP interface */
 extern bool    tune_kernel;    /* May alter kernel settings as necessary */
 extern int     connect_delay;  /* Time to delay after connect script */
 extern int     max_data_rate;  /* max bytes/sec through charshunt */
--- a/pppd/sys-linux.c
+++ b/pppd/sys-linux.c
@@ -161,6 +161,10 @@ struct in6_ifreq {
 /* We can get an EIO error on an ioctl if the modem has hung up */
 #define ok_error(num) ((num)==EIO)
 
+#if !defined(PPP_DRV_NAME)
+#define PPP_DRV_NAME   "ppp"
+#endif /* !defined(PPP_DRV_NAME) */
+
 static int tty_disc = N_TTY;   /* The TTY discipline */
 static int ppp_disc = N_PPP;   /* The PPP discpline */
 static int initfdflags = -1;   /* Initial file descriptor flags for fd */
@@ -620,7 +624,8 @@ void generic_disestablish_ppp(int dev_fd
  */
 static int make_ppp_unit()
 {
-       int x, flags;
+       struct ifreq ifr;
+       int x, flags, s;
 
        if (ppp_dev_fd >= 0) {
                dbglog("in make_ppp_unit, already had /dev/ppp open?");
@@ -643,6 +648,30 @@ static int make_ppp_unit()
        }
        if (x < 0)
                error("Couldn't create new ppp unit: %m");
+
+       if (use_ifname[0] != 0) {
+               s = socket(PF_INET, SOCK_DGRAM, 0);
+               if (s < 0)
+                       s = socket(PF_PACKET, SOCK_DGRAM, 0);
+               if (s < 0)
+                       s = socket(PF_INET6, SOCK_DGRAM, 0);
+               if (s < 0)
+                       s = socket(PF_UNIX, SOCK_DGRAM, 0);
+               if (s >= 0) {
+                       slprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s%d", PPP_DRV_NAME, ifunit);
+                       slprintf(ifr.ifr_newname, sizeof(ifr.ifr_newname), "%s", use_ifname);
+                       x = ioctl(s, SIOCSIFNAME, &ifr);
+                       close(s);
+               } else {
+                       x = s;
+               }
+               if (x < 0) {
+                       error("Couldn't rename %s to %s", ifr.ifr_name, ifr.ifr_newname);
+                       close(ppp_dev_fd);
+                       ppp_dev_fd = -1;
+               }
+       }
+
        return x;
 }
 
--- a/pppstats/pppstats.c
+++ b/pppstats/pppstats.c
@@ -506,10 +506,12 @@ main(argc, argv)
     if (argc > 0)
        interface = argv[0];
 
+#if 0
     if (sscanf(interface, PPP_DRV_NAME "%d", &unit) != 1) {
        fprintf(stderr, "%s: invalid interface '%s' specified\n",
                progname, interface);
     }
+#endif
 
 #ifndef STREAMS
     {