From c89b8b3f2ff31084d1bebbb414f396eb3c993e6a Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20H=C3=A4rdeman?= Date: Sat, 28 Dec 2024 17:54:49 +0100 Subject: [PATCH] odhcpd: make the IPv6 RA DNR lifetime configurable MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Add a fake SVC parameter "_lifetime=" which allows explicit configuration of the maximum time in seconds over which a given ADN announcement is valid. In particular, this allows announcing ADNs which should no longer be used (zero lifetime, see rfc9463, §6.1). In the absence of an explicit lifetime, the previous logic is kept (i.e. the lifetime is set to 3 * MaxRtrAdvInterval, as per §6.1 of RFC9463). Signed-off-by: David Härdeman --- src/config.c | 13 +++++++++++++ src/odhcpd.h | 3 +++ src/router.c | 5 ++++- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/config.c b/src/config.c index 2eba544..42fc2fe 100644 --- a/src/config.c +++ b/src/config.c @@ -661,6 +661,19 @@ static int parse_dnr_str(char *str, struct interface *iface) svc_key = strtok_r(svc_tok, "=", &saveptr2); svc_val = strtok_r(NULL, "=", &saveptr2); + if (!strcmp(svc_key, "_lifetime")) { + uint32_t lifetime; + + if (!svc_val || sscanf(svc_val, "%" SCNu32, &lifetime) != 1) { + syslog(LOG_ERR, "Invalid value '%s' for _lifetime", svc_val ? svc_val : ""); + goto err; + } + + dnr.lifetime = lifetime; + dnr.lifetime_set = true; + continue; + } + for (svc_id = 0; svc_id < DNR_SVC_MAX; svc_id++) if (!strcmp(svc_key, svc_param_key_names[svc_id])) break; diff --git a/src/odhcpd.h b/src/odhcpd.h index 473c95b..4d589f8 100644 --- a/src/odhcpd.h +++ b/src/odhcpd.h @@ -249,6 +249,9 @@ struct dhcp_assignment { struct dnr_options { uint16_t priority; + uint32_t lifetime; + bool lifetime_set; + uint8_t *adn; uint16_t adn_len; diff --git a/src/router.c b/src/router.c index 722f2e3..b630953 100644 --- a/src/router.c +++ b/src/router.c @@ -824,7 +824,10 @@ pref64_out: dnr->type = ND_OPT_DNR; dnr->len = dnr_sz[i] / 8; dnr->priority = htons(iface->dnr[i].priority); - dnr->lifetime = htonl(lifetime); + if (iface->dnr[i].lifetime_set) + dnr->lifetime = htonl(iface->dnr[i].lifetime); + else + dnr->lifetime = htonl(lifetime); dnr->adn_len = htons(iface->dnr[i].adn_len); memcpy(tmp, iface->dnr[i].adn, iface->dnr[i].adn_len); -- 2.30.2