changeset 5456:9203603adc76 draft

duid: Allow optional argument to specify ll or llt alongside uuid
author Roy Marples <roy@marples.name>
date Wed, 16 Sep 2020 15:55:11 +0100
parents d106ecc43837
children 7fb0274b9127
files src/dhcpcd.conf.5.in src/dhcpcd.h src/duid.c src/duid.h src/if-options.c
diffstat 5 files changed, 33 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/src/dhcpcd.conf.5.in	Tue Sep 15 11:45:21 2020 +0100
+++ b/src/dhcpcd.conf.5.in	Wed Sep 16 15:55:11 2020 +0100
@@ -24,7 +24,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd September 2, 2020
+.Dd September 15, 2020
 .Dt DHCPCD.CONF 5
 .Os
 .Sh NAME
@@ -211,12 +211,15 @@
 sends a default
 .Ar clientid
 of the hardware family and the hardware address.
-.It Ic duid
+.It Ic duid Op ll | lt | uuid
 Use a DHCP Unique Identifier.
 If a system UUID is available, that will be used to create a DUID-UUID,
 otheriwse if persistent storage is available then a DUID-LLT
 (link local address + time) is generated,
 otherwise DUID-LL is generated (link local address).
+The DUID type can be hinted as an optional parameter if the file
+.Pa @DBDIR@/duid
+does not exist.
 This, plus the IAID will be used as the
 .Ic clientid .
 The DUID generated will be held in
--- a/src/dhcpcd.h	Tue Sep 15 11:45:21 2020 +0100
+++ b/src/dhcpcd.h	Wed Sep 16 15:55:11 2020 +0100
@@ -135,6 +135,7 @@
 	char **ifv;	/* listed interfaces */
 	int ifcc;	/* configured interfaces */
 	char **ifcv;	/* configured interfaces */
+	uint8_t duid_type;
 	unsigned char *duid;
 	size_t duid_len;
 	struct if_head *ifaces;
--- a/src/duid.c	Tue Sep 15 11:45:21 2020 +0100
+++ b/src/duid.c	Wed Sep 16 15:55:11 2020 +0100
@@ -176,6 +176,9 @@
 
 	/* No file? OK, lets make one based the machines UUID */
 	if (ifp == NULL) {
+		if (ctx->duid_type != DUID_DEFAULT &&
+		    ctx->duid_type != DUID_UUID)
+			return 0;
 		len = duid_make_uuid(data);
 		if (len == 0)
 			free(data);
@@ -199,13 +202,15 @@
 			logwarnx("picked interface %s to generate a DUID",
 			    ifp->name);
 		} else {
-			logwarnx("no interfaces have a fixed hardware "
-			    "address");
+			if (ctx->duid_type != DUID_LL)
+				logwarnx("no interfaces have a fixed hardware "
+				    "address");
 			return duid_make(data, ifp, DUID_LL);
 		}
 	}
 
-	len = duid_make(data, ifp, DUID_LLT);
+	len = duid_make(data, ifp,
+	    ctx->duid_type == DUID_LL ? DUID_LL : DUID_LLT);
 	hwaddr_ntoa(data, len, line, sizeof(line));
 	slen = strlen(line);
 	if (slen < sizeof(line) - 2) {
@@ -214,7 +219,8 @@
 	}
 	if (dhcp_writefile(ctx, DUID, 0640, line, slen) == -1) {
 		logerr("%s: cannot write duid", __func__);
-		return duid_make(data, ifp, DUID_LL);
+		if (ctx->duid_type != DUID_LL)
+			return duid_make(data, ifp, DUID_LL);
 	}
 	return len;
 }
--- a/src/duid.h	Tue Sep 15 11:45:21 2020 +0100
+++ b/src/duid.h	Wed Sep 16 15:55:11 2020 +0100
@@ -30,6 +30,7 @@
 #define DUID_H
 
 #define DUID_LEN	128 + 2
+#define	DUID_DEFAULT	0
 #define	DUID_LLT	1
 #define	DUID_LL		3
 #define	DUID_UUID	4
--- a/src/if-options.c	Tue Sep 15 11:45:21 2020 +0100
+++ b/src/if-options.c	Wed Sep 16 15:55:11 2020 +0100
@@ -49,6 +49,7 @@
 #include "dhcp.h"
 #include "dhcp6.h"
 #include "dhcpcd-embedded.h"
+#include "duid.h"
 #include "if.h"
 #include "if-options.h"
 #include "ipv4.h"
@@ -94,7 +95,7 @@
 	{"noarp",           no_argument,       NULL, 'A'},
 	{"nobackground",    no_argument,       NULL, 'B'},
 	{"nohook",          required_argument, NULL, 'C'},
-	{"duid",            no_argument,       NULL, 'D'},
+	{"duid",            optional_argument, NULL, 'D'},
 	{"lastlease",       no_argument,       NULL, 'E'},
 	{"fqdn",            optional_argument, NULL, 'F'},
 	{"nogateway",       no_argument,       NULL, 'G'},
@@ -985,6 +986,20 @@
 		break;
 	case 'D':
 		ifo->options |= DHCPCD_CLIENTID | DHCPCD_DUID;
+		if (ifname != NULL) /* duid type only a global option */
+			break;
+		if (arg == NULL)
+			ctx->duid_type = DUID_DEFAULT;
+		else if (strcmp(arg, "ll") == 0)
+			ctx->duid_type = DUID_LL;
+		else if (strcmp(arg, "llt") == 0)
+			ctx->duid_type = DUID_LLT;
+		else if (strcmp(arg, "uuid") == 0)
+			ctx->duid_type = DUID_UUID;
+		else {
+			logwarnx("%s: invalid duid type", arg);
+			ctx->duid_type = DUID_DEFAULT;
+		}
 		break;
 	case 'E':
 		ifo->options |= DHCPCD_LASTLEASE;