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.
Originally written by Suse. Used by openwrt, debian, ubuntu.
Reference:
https://dev.openwrt.org/browser/trunk/package/network/services/ppp/patches/320-custom_iface_names.patch
diff -purN ppp-2.4.7.orig/pppd/main.c ppp-2.4.7/pppd/main.c
--- ppp-2.4.7.orig/pppd/main.c 2016-08-25 15:52:52.032202044 +0200
+++ ppp-2.4.7/pppd/main.c 2016-08-25 16:22:25.740299940 +0200
@@ -729,8 +729,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 */
diff -purN ppp-2.4.7.orig/pppd/options.c ppp-2.4.7/pppd/options.c
--- ppp-2.4.7.orig/pppd/options.c 2016-08-25 15:52:52.191194523 +0200
+++ ppp-2.4.7/pppd/options.c 2016-08-25 16:04:23.335501924 +0200
@@ -115,6 +115,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 */
@@ -274,6 +275,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",
diff -purN ppp-2.4.7.orig/pppd/pppd.h ppp-2.4.7/pppd/pppd.h
--- ppp-2.4.7.orig/pppd/pppd.h 2016-08-25 15:52:52.829164346 +0200
+++ ppp-2.4.7/pppd/pppd.h 2016-08-25 16:07:12.024522417 +0200
@@ -71,6 +71,10 @@
#include "eui64.h"
#endif
+#ifndef IFNAMSIZ
+#define IFNAMSIZ 16
+#endif
+
/*
* Limits.
*/
@@ -319,6 +323,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 */
diff -purN ppp-2.4.7.orig/pppd/sys-linux.c ppp-2.4.7/pppd/sys-linux.c
--- ppp-2.4.7.orig/pppd/sys-linux.c 2016-08-25 15:52:52.268190881 +0200
+++ ppp-2.4.7/pppd/sys-linux.c 2016-08-25 16:12:13.905242396 +0200
@@ -172,6 +172,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 */
@@ -644,7 +648,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?");
@@ -667,6 +672,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;
}
diff -purN ppp-2.4.7.orig/pppstats/pppstats.c ppp-2.4.7/pppstats/pppstats.c
--- ppp-2.4.7.orig/pppstats/pppstats.c 2014-08-09 14:31:39.000000000 +0200
+++ ppp-2.4.7/pppstats/pppstats.c 2016-08-25 16:13:52.623572634 +0200
@@ -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
{