aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Tan <samueltan@google.com>2015-08-13 16:41:21 -0700
committerSamuel Tan <samueltan@google.com>2015-08-18 13:46:52 -0700
commita3595821594453ea89ef8e6790927694b0a1adf1 (patch)
tree5592cd518978b8199fa080709e7a50bfb5f1d5ca
parentdd90b01b5502dc66e00ea6a4d00ebdf77ea1eddc (diff)
downloaddhcpcd-6.8.2-a3595821594453ea89ef8e6790927694b0a1adf1.tar.gz
[PATCH] dhcpcd: Allow lease file to be set on command line
Cherry-picked from https://chromium.googlesource.com/chromiumos/overlays/chromiumos-overlay/+/ master/net-misc/dhcpcd/files/patches/dhcpcd-6.8.2-Allow-lease-file-to-be- set-on-command-line.patch. Currently, dhcpcd names its lease files using the interface name as the unique part of the name. There are a couple reasons why this may not work well: firstly if "eth0" can have different MAC addresses (multiple USB-Ethernet dongles for example) leases for one interface aren't valid for the other. Secondly, when using a wireless interface, it would be convenient to hold multiple leases in parallel for each SSID one is connected to. This change adds a suffix to each interface argument (dhcpcd can accept multiple interface arguments) that specifies the identifier to use to save lease files with. By default, the behavior is identical. The second CL (https://gerrit.chromium.org/gerrit/22170) for fixing pid file formating bug originally introduced by this CL is not needed anymore since this bug doesn't exist/apply in the updated implementation. BUG: 22956197 Change-Id: Id04168daa965065ca50e60f55c4cdc80f751c9c3 Reviewed-on: https://gerrit.chromium.org/gerrit/21991 Reviewed-on: https://gerrit.chromium.org/gerrit/22170
-rw-r--r--dhcp-common.c8
-rw-r--r--dhcp.h2
-rw-r--r--dhcpcd.8.in6
-rw-r--r--dhcpcd.c22
-rw-r--r--dhcpcd.h2
-rw-r--r--if.c65
-rw-r--r--if.h2
7 files changed, 88 insertions, 19 deletions
diff --git a/dhcp-common.c b/dhcp-common.c
index 2936b55..39d9787 100644
--- a/dhcp-common.c
+++ b/dhcp-common.c
@@ -741,6 +741,14 @@ dhcp_set_leasefile(char *leasefile, size_t len, int family,
return 0;
}
+ if (strlen(ifp->lease_identifier) > 0) {
+ /* Only supports lease identifier for IPv4 for now. */
+ if (family == AF_INET) {
+ return snprintf(leasefile, len, LEASEFILE,
+ ifp->lease_identifier, "", "");
+ }
+ }
+
switch (family) {
case AF_INET:
case AF_INET6:
diff --git a/dhcp.h b/dhcp.h
index acef896..ed94395 100644
--- a/dhcp.h
+++ b/dhcp.h
@@ -228,7 +228,7 @@ struct dhcp_state {
struct in_addr dst;
uint8_t added;
- char leasefile[sizeof(LEASEFILE) + IF_NAMESIZE + (IF_SSIDSIZE * 4)];
+ char leasefile[PATH_MAX];
time_t start_uptime;
unsigned char *clientid;
diff --git a/dhcpcd.8.in b/dhcpcd.8.in
index a67626a..e815620 100644
--- a/dhcpcd.8.in
+++ b/dhcpcd.8.in
@@ -191,6 +191,12 @@ changes the routes to use the interface with the same route and the lowest
metric.
See options below for controlling which interfaces we allow and deny through
the use of patterns.
+.Pp
+If an interface name is suffixed by an equal-sign, the text following the
+equal sign will be used instead of the interface name as the unique identifier
+for the DHCP lease file. Doing so allows the caller to specify different
+lease files for the same interface (e.g, when switching the same wireless
+interface between different 802.11 networks).
.Ss Hooking into events
.Nm
runs
diff --git a/dhcpcd.c b/dhcpcd.c
index 9528dc8..763e06f 100644
--- a/dhcpcd.c
+++ b/dhcpcd.c
@@ -1362,6 +1362,7 @@ main(int argc, char **argv)
int sig;
const char *siga;
#endif
+ char ifn[IF_NAMESIZE];
/* Test for --help and --version */
if (argc > 1) {
@@ -1523,13 +1524,15 @@ main(int argc, char **argv)
* instance for that interface. */
if (optind == argc - 1 && !(ctx.options & DHCPCD_MASTER)) {
const char *per;
-
- if (strlen(argv[optind]) > IF_NAMESIZE) {
+ int intf_len = strlen(argv[optind]);
+ split_interface_lease(argv[optind], &intf_len, NULL);
+ if (intf_len > IF_NAMESIZE) {
logger(&ctx, LOG_ERR,
"%s: interface name too long",
argv[optind]);
goto exit_failure;
}
+ strlcpy(ifn, argv[optind], intf_len + 1);
/* Allow a dhcpcd interface per address family */
switch(family) {
case AF_INET:
@@ -1542,7 +1545,7 @@ main(int argc, char **argv)
per = "";
}
snprintf(ctx.pidfile, sizeof(ctx.pidfile),
- PIDFILE, "-", argv[optind], per);
+ PIDFILE, "-", ifn, per);
} else {
snprintf(ctx.pidfile, sizeof(ctx.pidfile),
PIDFILE, "", "", "");
@@ -1780,10 +1783,19 @@ main(int argc, char **argv)
goto exit_failure;
}
for (i = 0; i < ctx.ifc; i++) {
- if (if_find(ctx.ifaces, ctx.ifv[i]) == NULL)
+ int intf_len = strlen(ctx.ifv[i]);
+ split_interface_lease(ctx.ifv[i], &intf_len, NULL);
+ if (intf_len > IF_NAMESIZE) {
logger(&ctx, LOG_ERR,
- "%s: interface not found or invalid",
+ "%s: interface name too long",
ctx.ifv[i]);
+ continue;
+ }
+ strlcpy(ifn, ctx.ifv[i], intf_len + 1);
+ if (if_find(ctx.ifaces, ifn) == NULL)
+ logger(&ctx, LOG_ERR,
+ "%s: interface not found or invalid",
+ ifn);
}
if (TAILQ_FIRST(ctx.ifaces) == NULL) {
if (ctx.ifc == 0)
diff --git a/dhcpcd.h b/dhcpcd.h
index 8b34997..ae2b0ce 100644
--- a/dhcpcd.h
+++ b/dhcpcd.h
@@ -40,6 +40,7 @@
#define IF_SSIDSIZE 33
#define PROFILE_LEN 64
#define SECRET_LEN 64
+#define LEASE_IDENTIFIER_LEN (PATH_MAX - sizeof(LEASEFILE))
#define LINK_UP 1
#define LINK_UNKNOWN 0
@@ -73,6 +74,7 @@ struct interface {
int wireless;
uint8_t ssid[IF_SSIDSIZE];
unsigned int ssid_len;
+ char lease_identifier[LEASE_IDENTIFIER_LEN];
char profile[PROFILE_LEN];
struct if_options *options;
diff --git a/if.c b/if.c
index 2f1a7e5..683021f 100644
--- a/if.c
+++ b/if.c
@@ -74,6 +74,34 @@
#undef IFLR_ACTIVE
#endif
+int
+split_interface_lease(const char *ifname, int *interface_name_len,
+ const char **lease_identifier)
+{
+ int ret = 0;
+ int len;
+ const char *lease_ptr = ifname;
+ const char *p = strchr(ifname, '=');
+
+ if (interface_name_len)
+ len = *interface_name_len;
+ else
+ len = strlen(ifname);
+
+ if (p) {
+ lease_ptr = p + 1;
+ if (len > p - ifname)
+ len = p - ifname;
+ ret = 1;
+ }
+
+ if (interface_name_len)
+ *interface_name_len = len;
+ if (lease_identifier)
+ *lease_identifier = lease_ptr;
+ return ret;
+}
+
void
if_free(struct interface *ifp)
{
@@ -229,9 +257,13 @@ if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv)
int i;
struct if_head *ifs;
struct interface *ifp;
-#ifdef __linux__
+ const char *lease_identifier;
char ifn[IF_NAMESIZE];
+
+#ifdef __linux__
+ char alias[IF_NAMESIZE];
#endif
+
#ifdef AF_LINK
const struct sockaddr_dl *sdl;
#ifdef SIOCGIFPRIORITY
@@ -287,28 +319,31 @@ if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv)
if (ifp)
continue;
+ lease_identifier = NULL;
if (argc > 0) {
for (i = 0; i < argc; i++) {
+ int intf_len = strlen(argv[i]);
+ split_interface_lease(argv[i], &intf_len,
+ &lease_identifier);
+ if (intf_len > IF_NAMESIZE)
+ continue;
+ strlcpy(ifn, argv[i], intf_len + 1);
#ifdef __linux__
+ strlcpy(alias, argv[i], intf_len + 1);
/* Check the real interface name */
- strlcpy(ifn, argv[i], sizeof(ifn));
p = strchr(ifn, ':');
if (p)
*p = '\0';
+#endif
if (strcmp(ifn, ifa->ifa_name) == 0)
break;
-#else
- if (strcmp(argv[i], ifa->ifa_name) == 0)
- break;
-#endif
}
if (i == argc)
continue;
- p = argv[i];
} else {
- p = ifa->ifa_name;
-#ifdef __linux__
strlcpy(ifn, ifa->ifa_name, sizeof(ifn));
+#ifdef __linux
+ strlcpy(alias, ifa->ifa_name, sizeof(alias));
#endif
/* -1 means we're discovering against a specific
* interface, but we still need the below rules
@@ -316,6 +351,8 @@ if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv)
if (argc == -1 && strcmp(argv[0], ifa->ifa_name) != 0)
continue;
}
+ p = ifn;
+
for (i = 0; i < ctx->ifdc; i++)
if (!fnmatch(ctx->ifdv[i], p, 0))
break;
@@ -351,11 +388,13 @@ if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv)
}
ifp->ctx = ctx;
#ifdef __linux__
- strlcpy(ifp->name, ifn, sizeof(ifp->name));
- strlcpy(ifp->alias, p, sizeof(ifp->alias));
-#else
- strlcpy(ifp->name, p, sizeof(ifp->name));
+ strlcpy(ifp->alias, alias, sizeof(ifp->alias));
#endif
+ strlcpy(ifp->name, p, sizeof(ifp->name));
+ if (lease_identifier) {
+ strlcpy(ifp->lease_identifier, lease_identifier,
+ sizeof(ifp->lease_identifier));
+ }
ifp->flags = ifa->ifa_flags;
ifp->carrier = if_carrier(ifp);
diff --git a/if.h b/if.h
index cda4c01..a4c67a6 100644
--- a/if.h
+++ b/if.h
@@ -105,6 +105,8 @@ int if_domtu(const char *, short int);
#define if_getmtu(iface) if_domtu(iface, 0)
#define if_setmtu(iface, mtu) if_domtu(iface, mtu)
int if_carrier(struct interface *);
+int split_interface_lease(const char *ifname, int *ifname_len,
+ const char **lease_identifier);
/* The below functions are provided by if-KERNEL.c */
int if_conf(struct interface *);