From c14b4e41526e08f921243aad0906550d7cd2cbc5 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Fri, 8 Dec 2023 08:29:33 +0100 Subject: [PATCH] confd: initial enhancements to DHCP client - Add support for option 12, provide current hostname to server for registering the lease with -- this allows registering in local DNS for some DHCP servers. - Add support for option 50, request any previously cached IP address - Override option 60, vendor class identifier, with Infix vYY.MM - Adjust timers and retry options to be more persistant - Include initial metric as environment variable to client - Disable all default options, set a hard-coded subset, which will be replaced in a later commit by a generated list. - Ensure udhcpc creates a pid file, in case we may need to start any other service/task in sync with the DHCP client Signed-off-by: Joachim Wiberg --- src/confd/src/infix-dhcp.c | 74 +++++++++++++++++++++++++++++++++++--- 1 file changed, 70 insertions(+), 4 deletions(-) diff --git a/src/confd/src/infix-dhcp.c b/src/confd/src/infix-dhcp.c index cdc76b6e..58591703 100644 --- a/src/confd/src/infix-dhcp.c +++ b/src/confd/src/infix-dhcp.c @@ -21,8 +21,10 @@ static const struct srx_module_requirement infix_dhcp_reqs[] = { static void add(const char *ifname, const char *client_id) { - char *args = NULL; - FILE *fp; + const char *opts = "-O subnet -O router -O dns -O domain -O ntpsrv -O 121"; + char *args = NULL, *ipcache = NULL; + char buf[256], vendor[128] = { 0 }; + FILE *fp, *xp; fp = fopenf("w", "/etc/finit.d/available/dhcp-%s.conf", ifname); if (!fp) { @@ -31,13 +33,77 @@ static void add(const char *ifname, const char *client_id) return; } + if (fexistf("/var/lib/misc/%s.cache", ifname)) { + struct in_addr ina; + + xp = fopenf("r", "/var/lib/misc/%s.cache", ifname); + if (!xp) + goto nocache; + + if (!fgets(buf, sizeof(buf), xp)) { + fclose(xp); + goto nocache; + } + fclose(xp); + chomp(buf); + + if (!inet_aton(buf, &ina)) { + erasef("/var/lib/misc/%s.cache", ifname); + goto nocache; + } + + ipcache = alloca(20); + if (ipcache) + snprintf(ipcache, 20, "-r %.15s", buf); + nocache: + } + + xp = fopen("/etc/os-relase", "r"); + if (xp) { + while (fgets(buf, sizeof(buf), xp)) { + if (!strncmp(buf, "NAME=", 5)) + snprintf(vendor, sizeof(vendor), "-V '%.32s ", &buf[5]); + if (!strncmp(buf, "VERSION=", 8)) { + strlcat(vendor, &buf[8], sizeof(vendor)); + strlcat(vendor, "'", sizeof(vendor)); + break; + } + } + fclose(xp); + } + + xp = fopen("/etc/hostname", "r"); + if (xp) { + int pos; + + pos = snprintf(buf, sizeof(buf), "-x hostname:"); + if (!fgets(&buf[pos], sizeof(buf) - pos, xp)) + buf[0] = 0; + fclose(xp); + chomp(buf); + } + if (client_id && client_id[0]) { args = alloca(strlen(client_id) + 12); if (args) sprintf(args, "-C -x 61:'\"%s\"'", client_id); } - fprintf(fp, "service name:dhcp :%s udhcpc -f -S -R -i %s %s -- DHCP client @%s\n", - ifname, ifname, args ?: "", ifname); + + /* + * XXX: hard-coded metric for now. Should be 100 + ifmetric, + * which in turn should be based on the iftype. E.g., a WiFi + * interface should have a base metric of 500 while a plain + * Ethernet interface has a base metric of 0. These are the + * defaults, a user should be able to override this all by a + * dhcp routing metric. + */ + fprintf(fp, "# Generated by Infix confd\n"); + fprintf(fp, "metric=100\n"); + fprintf(fp, "service name:dhcp :%s\\\n" + " [2345] udhcpc -f -p /run/dhcp-%s.pid -t 10 -T 3 -A 10\\\n" + " -S -R %s -o %s -i %s %s %s %s\\\n" + " -- DHCP client @%s\n", ifname, ifname, + buf, opts, ifname, args ?: "", ipcache ?: "", vendor, ifname); fclose(fp); if (systemf("initctl -bfq enable dhcp-%s", ifname))