odhcpd: make the IPv6 RA DNR lifetime configurable
authorDavid Härdeman <david@hardeman.nu>
Sat, 28 Dec 2024 16:54:49 +0000 (17:54 +0100)
committerdedeckeh <dedeckeh@gmail.com>
Sun, 29 Dec 2024 11:50:42 +0000 (12:50 +0100)
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 <david@hardeman.nu>
src/config.c
src/odhcpd.h
src/router.c

index 2eba544ed7f76f92103c4bf8e40d1d33a490ad1f..42fc2fe0caeb16b164834292ae3a331253b023b9 100644 (file)
@@ -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;
index 473c95bc233db24179ec285bb9cf628302f52024..4d589f8e2e177001fa1f7826957f480d2794e971 100644 (file)
@@ -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;
 
index 722f2e3f23cbbf51050ed808f9b148ae00f86cdc..b6309531a5920ab1692c05ffb79bd848c502d612 100644 (file)
@@ -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);