1- From 9ee21c537eea6321ed644e284a1d9c13de342fef Mon Sep 17 00:00:00 2001
2- From: skbeh <60107333+skbeh@users.noreply.github.com>
1+ From 0e41fb05fbb2896f1c6f000b0c880e837760ccce Mon Sep 17 00:00:00 2001
32Date: Sat, 16 Sep 2023 15:04:12 +0000
4- Subject: [PATCH] config: allow configuring max limit for preferred and valid
5- lifetime
3+ Subject: [PATCH] odhcpd: RFC 9096 compliance
64
5+ and allow configuring upper limit for preferred and valid lifetime.
76---
87 README | 5 +++--
98 src/config.c | 32 ++++++++++++++++++++++++++++++++
10- src/dhcpv6-ia.c | 9 + ++++++++
9+ src/dhcpv6-ia.c | 8 ++++++++
1110 src/odhcpd.h | 6 ++++++
12- src/router.c | 37 +++++++++++++++++++++++++++++---- ----
13- 5 files changed, 79 insertions(+), 10 deletions(-)
11+ src/router.c | 16 ++++++++++++----
12+ 5 files changed, 61 insertions(+), 6 deletions(-)
1413
1514diff --git a/README b/README
16- index 8f0e6a4..ddf8534 100644
15+ index 243ae24..c13d9b8 100644
1716--- a/README
1817+++ b/README
19- @@ -130 ,8 +130 ,9 @@ ra_maxinterval integer 600 Maximum time allowed between
18+ @@ -131 ,8 +131 ,9 @@ ra_maxinterval integer 600 Maximum time allowed between
2019 sending unsolicited RA
2120 ra_mininterval integer 200 Minimum time allowed between
2221 sending unsolicited RA
@@ -29,7 +28,7 @@ index 8f0e6a4..ddf8534 100644
2928 limit for the preferred and
3029 valid lifetime of a prefix
3130diff --git a/src/config.c b/src/config.c
32- index e631814..3281b5f 100644
31+ index 1cd4608..e193a94 100644
3332--- a/src/config.c
3433+++ b/src/config.c
3534@@ -92,6 +92,8 @@ enum {
@@ -50,7 +49,7 @@ index e631814..3281b5f 100644
5049 [IFACE_ATTR_NTP] = { .name = "ntp", .type = BLOBMSG_TYPE_ARRAY },
5150 };
5251
53- @@ -648 ,6 +652 ,34 @@ int config_parse_interface(void *data, size_t len, const char *name, bool overwr
52+ @@ -658 ,6 +662 ,34 @@ int config_parse_interface(void *data, size_t len, const char *name, bool overwr
5453
5554 }
5655
@@ -86,27 +85,26 @@ index e631814..3281b5f 100644
8685 iface->dhcpv4_start.s_addr = htonl(blobmsg_get_u32(c));
8786 iface->dhcpv4_end.s_addr = htonl(ntohl(iface->dhcpv4_start.s_addr) +
8887diff --git a/src/dhcpv6-ia.c b/src/dhcpv6-ia.c
89- index 41c9f30..b413ab4 100644
88+ index 1fbed44..b4d88d7 100644
9089--- a/src/dhcpv6-ia.c
9190+++ b/src/dhcpv6-ia.c
92- @@ -1027 ,6 +1027,15 @@ static size_t build_ia(uint8_t *buf, size_t buflen, uint16_t status,
91+ @@ -1141 ,6 +1141,14 @@ static size_t build_ia(uint8_t *buf, size_t buflen, uint16_t status,
9392 }
9493 }
9594
96- + if (pref) {
97- + if (iface->max_preferred_lifetime)
98- + pref = min(pref, iface->max_preferred_lifetime);
95+ + if (iface->max_preferred_lifetime) {
96+ + pref = min(pref, iface->max_preferred_lifetime);
9997+ }
100- + if (valid) {
101- + if (iface->max_valid_lifetime)
102- + valid = min(valid, iface->max_valid_lifetime);
98+ +
99+ + if (iface->max_valid_lifetime) {
100+ + valid = min(valid, iface->max_valid_lifetime);
103101+ }
104102+
105103 if (!INFINITE_VALID(a->valid_until))
106104 /* UINT32_MAX is considered as infinite leasetime */
107105 a->valid_until = (valid == UINT32_MAX) ? 0 : valid + now;
108106diff --git a/src/odhcpd.h b/src/odhcpd.h
109- index 08b4920..58ab155 100644
107+ index 02b6ac0..e409caf 100644
110108--- a/src/odhcpd.h
111109+++ b/src/odhcpd.h
112110@@ -37,6 +37,10 @@
@@ -120,7 +118,7 @@ index 08b4920..58ab155 100644
120118 #define INFINITE_VALID(x) ((x) == 0)
121119
122120 #define _unused __attribute__((unused))
123- @@ -319 ,6 +323 ,8 @@ struct interface {
121+ @@ -320 ,6 +324 ,8 @@ struct interface {
124122 uint32_t ra_hoplimit;
125123 int ra_mtu;
126124 uint32_t preferred_lifetime;
@@ -130,64 +128,34 @@ index 08b4920..58ab155 100644
130128 // DHCP
131129 uint32_t dhcp_leasetime;
132130diff --git a/src/router.c b/src/router.c
133- index d5ef7f8..55eaa6d 100644
131+ index d5ef7f8..c80358b 100644
134132--- a/src/router.c
135133+++ b/src/router.c
136- @@ -452,7 +452,8 @@ static int send_router_advert(struct interface *iface, const struct in6_addr *fr
137- size_t dns_sz = 0, search_sz = 0, pref64_sz = 0;
138- size_t pfxs_cnt = 0, routes_cnt = 0;
139- ssize_t valid_addr_cnt = 0, invalid_addr_cnt = 0;
140- - uint32_t minvalid = UINT32_MAX, maxival, lifetime;
141- + uint32_t minvalid = UINT32_MAX, maxival, lifetime, max_prefix_vlt = ND_VALID_LIMIT;
142- + uint32_t calculated_ra_lifetime;
143- int msecs, mtu = iface->ra_mtu, hlim = iface->ra_hoplimit;
144- bool default_route = false;
145- bool valid_prefix = false;
146- @@ -598,10 +599,24 @@ static int send_router_advert(struct interface *iface, const struct in6_addr *fr
147- if (addr->valid > (uint32_t)now) {
148- valid = TIME_LEFT(addr->valid, now);
134+ @@ -371,7 +371,7 @@ static int calc_adv_interval(struct interface *iface, uint32_t minvalid,
149135
150- + if (valid < max_prefix_vlt)
151- + max_prefix_vlt = valid;
152- +
153- if (iface->ra_useleasetime && valid > iface->dhcp_leasetime)
136+ static uint32_t calc_ra_lifetime(struct interface *iface, uint32_t maxival)
137+ {
138+ - uint32_t lifetime = 3*maxival;
139+ + uint32_t lifetime = maxival * 3;
140+
141+ if (iface->ra_lifetime >= 0) {
142+ lifetime = iface->ra_lifetime;
143+ @@ -602,6 +602,14 @@ static int send_router_advert(struct interface *iface, const struct in6_addr *fr
154144 valid = iface->dhcp_leasetime;
155145 }
156146
157- + if (preferred) {
158- + if (iface->max_preferred_lifetime) {
159- + preferred = min(preferred, iface->max_preferred_lifetime);
160- + }
147+ + if (iface->max_preferred_lifetime) {
148+ + preferred = min(preferred, iface->max_preferred_lifetime);
161149+ }
162- + if (valid) {
163- + if (iface->max_valid_lifetime) {
164- + valid = min(valid, iface->max_valid_lifetime);
165- + }
150+ +
151+ + if (iface->max_valid_lifetime) {
152+ + valid = min(valid, iface->max_valid_lifetime);
166153+ }
167154+
168155 if (minvalid > valid)
169156 minvalid = valid;
170157
171- @@ -629,24 +644,30 @@ static int send_router_advert(struct interface *iface, const struct in6_addr *fr
172-
173- /* Calculate periodic transmit */
174- msecs = calc_adv_interval(iface, minvalid, &maxival);
175- - lifetime = calc_ra_lifetime(iface, maxival);
176- + calculated_ra_lifetime = min(calc_ra_lifetime(iface, maxival), UINT16_MAX);
177- + lifetime = min(calculated_ra_lifetime, max_prefix_vlt);
178-
179- if (!iface->have_link_local) {
180- syslog(LOG_NOTICE, "Skip sending a RA on %s as no link local address is available", iface->name);
181- goto out;
182- }
183-
184- - if (default_route && valid_prefix) {
185- - adv.h.nd_ra_router_lifetime = htons(lifetime < UINT16_MAX ? lifetime : UINT16_MAX);
186- - } else {
187- + /* RFC9096: CE routers SHOULD set the "Router Lifetime" of Router Advertisement (RA) messages to ND_PREFERRED_LIMIT. */
188- + adv.h.nd_ra_router_lifetime = htons(ND_PREFERRED_LIMIT);
189- + if (!(default_route && valid_prefix)) {
190- adv.h.nd_ra_router_lifetime = 0;
158+ @@ -643,9 +651,9 @@ static int send_router_advert(struct interface *iface, const struct in6_addr *fr
191159
192160 if (default_route) {
193161 syslog(LOG_WARNING, "A default route is present but there is no public prefix "
@@ -197,15 +165,9 @@ index d5ef7f8..55eaa6d 100644
197165- syslog(LOG_WARNING, "No default route present, overriding ra_lifetime!");
198166+ syslog(LOG_WARNING, "No default route present, setting ra_lifetime to zero!");
199167 }
200- + } else if (iface->ra_lifetime >= 0) {
201- + adv.h.nd_ra_router_lifetime = htons(calculated_ra_lifetime);
202- + if (calculated_ra_lifetime == 0)
203- + syslog(LOG_WARNING, "A default route is present and there is public prefix "
204- + "but ra_lifetime on iface was set to zero, setting ra_lifetime to zero!");
205168 }
206169
207- syslog(LOG_DEBUG, "Using a RA lifetime of %d seconds on %s", ntohs(adv.h.nd_ra_router_lifetime), iface->name);
208- @@ -710,7 +731,7 @@ static int send_router_advert(struct interface *iface, const struct in6_addr *fr
170+ @@ -710,7 +718,7 @@ static int send_router_advert(struct interface *iface, const struct in6_addr *fr
209171
210172 if (iface->pref64_length) {
211173 /* RFC 8781 § 4.1 rounding up lifetime to multiply of 8 */
@@ -215,4 +177,4 @@ index d5ef7f8..55eaa6d 100644
215177 uint32_t mask_a1, mask_a2;
216178
217179- -
218- 2.42.0
180+ 2.42.1
0 commit comments