Skip to content

Commit 2769622

Browse files
Fixed IPv6 RA router lifetime misbehavours
Signed-off-by: Nicholas Sun <nicholas-sun@outlook.com>
1 parent 94fa28c commit 2769622

1 file changed

Lines changed: 44 additions & 15 deletions

File tree

PATCH/odhcpd/001-config-allow-configuring-limit-of-min-and-max-value.patch

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,35 @@
1-
From 8a8150f045ed73e15c77c38be4b90999024f6d17 Mon Sep 17 00:00:00 2001
1+
From 9ee21c537eea6321ed644e284a1d9c13de342fef Mon Sep 17 00:00:00 2001
22
From: skbeh <60107333+skbeh@users.noreply.github.com>
33
Date: Sat, 16 Sep 2023 15:04:12 +0000
44
Subject: [PATCH] config: allow configuring max limit for preferred and valid
55
lifetime
66

77
---
8+
README | 5 +++--
89
src/config.c | 32 ++++++++++++++++++++++++++++++++
910
src/dhcpv6-ia.c | 9 +++++++++
1011
src/odhcpd.h | 6 ++++++
11-
src/router.c | 35 +++++++++++++++++++++++++++--------
12-
4 files changed, 74 insertions(+), 8 deletions(-)
12+
src/router.c | 37 +++++++++++++++++++++++++++++--------
13+
5 files changed, 79 insertions(+), 10 deletions(-)
1314

15+
diff --git a/README b/README
16+
index 8f0e6a4..ddf8534 100644
17+
--- a/README
18+
+++ b/README
19+
@@ -130,8 +130,9 @@ ra_maxinterval integer 600 Maximum time allowed between
20+
sending unsolicited RA
21+
ra_mininterval integer 200 Minimum time allowed between
22+
sending unsolicited RA
23+
-ra_lifetime integer 1800 Value to be placed in Router
24+
- Lifetime field of RA
25+
+ra_lifetime integer 2700 Value to be placed in Router
26+
+ Lifetime field of RA. Not recommended to be
27+
+ more than 2700 (RFC9096).
28+
ra_useleasetime bool 0 Use configured leasetime as
29+
limit for the preferred and
30+
valid lifetime of a prefix
31+
diff --git a/src/config.c b/src/config.c
32+
index e631814..3281b5f 100644
1433
--- a/src/config.c
1534
+++ b/src/config.c
1635
@@ -92,6 +92,8 @@ enum {
@@ -22,7 +41,7 @@ Subject: [PATCH] config: allow configuring max limit for preferred and valid
2241
IFACE_ATTR_NTP,
2342
IFACE_ATTR_MAX
2443
};
25-
@@ -145,6 +147,8 @@ static const struct blobmsg_policy iface
44+
@@ -145,6 +147,8 @@ static const struct blobmsg_policy iface_attrs[IFACE_ATTR_MAX] = {
2645
[IFACE_ATTR_NDPROXY_SLAVE] = { .name = "ndproxy_slave", .type = BLOBMSG_TYPE_BOOL },
2746
[IFACE_ATTR_PREFIX_FILTER] = { .name = "prefix_filter", .type = BLOBMSG_TYPE_STRING },
2847
[IFACE_ATTR_PREFERRED_LIFETIME] = { .name = "preferred_lifetime", .type = BLOBMSG_TYPE_STRING },
@@ -31,7 +50,7 @@ Subject: [PATCH] config: allow configuring max limit for preferred and valid
3150
[IFACE_ATTR_NTP] = { .name = "ntp", .type = BLOBMSG_TYPE_ARRAY },
3251
};
3352

34-
@@ -648,6 +652,34 @@ int config_parse_interface(void *data, s
53+
@@ -648,6 +652,34 @@ int config_parse_interface(void *data, size_t len, const char *name, bool overwr
3554

3655
}
3756

@@ -66,9 +85,11 @@ Subject: [PATCH] config: allow configuring max limit for preferred and valid
6685
if ((c = tb[IFACE_ATTR_START])) {
6786
iface->dhcpv4_start.s_addr = htonl(blobmsg_get_u32(c));
6887
iface->dhcpv4_end.s_addr = htonl(ntohl(iface->dhcpv4_start.s_addr) +
88+
diff --git a/src/dhcpv6-ia.c b/src/dhcpv6-ia.c
89+
index 41c9f30..b413ab4 100644
6990
--- a/src/dhcpv6-ia.c
7091
+++ b/src/dhcpv6-ia.c
71-
@@ -1027,6 +1027,15 @@ static size_t build_ia(uint8_t *buf, siz
92+
@@ -1027,6 +1027,15 @@ static size_t build_ia(uint8_t *buf, size_t buflen, uint16_t status,
7293
}
7394
}
7495

@@ -84,6 +105,8 @@ Subject: [PATCH] config: allow configuring max limit for preferred and valid
84105
if (!INFINITE_VALID(a->valid_until))
85106
/* UINT32_MAX is considered as infinite leasetime */
86107
a->valid_until = (valid == UINT32_MAX) ? 0 : valid + now;
108+
diff --git a/src/odhcpd.h b/src/odhcpd.h
109+
index 08b4920..58ab155 100644
87110
--- a/src/odhcpd.h
88111
+++ b/src/odhcpd.h
89112
@@ -37,6 +37,10 @@
@@ -106,9 +129,11 @@ Subject: [PATCH] config: allow configuring max limit for preferred and valid
106129

107130
// DHCP
108131
uint32_t dhcp_leasetime;
132+
diff --git a/src/router.c b/src/router.c
133+
index d5ef7f8..55eaa6d 100644
109134
--- a/src/router.c
110135
+++ b/src/router.c
111-
@@ -452,7 +452,8 @@ static int send_router_advert(struct int
136+
@@ -452,7 +452,8 @@ static int send_router_advert(struct interface *iface, const struct in6_addr *fr
112137
size_t dns_sz = 0, search_sz = 0, pref64_sz = 0;
113138
size_t pfxs_cnt = 0, routes_cnt = 0;
114139
ssize_t valid_addr_cnt = 0, invalid_addr_cnt = 0;
@@ -118,7 +143,7 @@ Subject: [PATCH] config: allow configuring max limit for preferred and valid
118143
int msecs, mtu = iface->ra_mtu, hlim = iface->ra_hoplimit;
119144
bool default_route = false;
120145
bool valid_prefix = false;
121-
@@ -598,10 +599,22 @@ static int send_router_advert(struct int
146+
@@ -598,10 +599,24 @@ static int send_router_advert(struct interface *iface, const struct in6_addr *fr
122147
if (addr->valid > (uint32_t)now) {
123148
valid = TIME_LEFT(addr->valid, now);
124149

@@ -130,23 +155,25 @@ Subject: [PATCH] config: allow configuring max limit for preferred and valid
130155
}
131156

132157
+ if (preferred) {
133-
+ if (iface->max_preferred_lifetime)
158+
+ if (iface->max_preferred_lifetime) {
134159
+ preferred = min(preferred, iface->max_preferred_lifetime);
160+
+ }
135161
+ }
136162
+ if (valid) {
137-
+ if (iface->max_valid_lifetime)
163+
+ if (iface->max_valid_lifetime) {
138164
+ valid = min(valid, iface->max_valid_lifetime);
165+
+ }
139166
+ }
140167
+
141168
if (minvalid > valid)
142169
minvalid = valid;
143170

144-
@@ -629,24 +642,30 @@ static int send_router_advert(struct int
171+
@@ -629,24 +644,30 @@ static int send_router_advert(struct interface *iface, const struct in6_addr *fr
145172

146173
/* Calculate periodic transmit */
147174
msecs = calc_adv_interval(iface, minvalid, &maxival);
148175
- lifetime = calc_ra_lifetime(iface, maxival);
149-
+ calculated_ra_lifetime = calc_ra_lifetime(iface, maxival);
176+
+ calculated_ra_lifetime = min(calc_ra_lifetime(iface, maxival), UINT16_MAX);
150177
+ lifetime = min(calculated_ra_lifetime, max_prefix_vlt);
151178

152179
if (!iface->have_link_local) {
@@ -158,7 +185,7 @@ Subject: [PATCH] config: allow configuring max limit for preferred and valid
158185
- adv.h.nd_ra_router_lifetime = htons(lifetime < UINT16_MAX ? lifetime : UINT16_MAX);
159186
- } else {
160187
+ /* RFC9096: CE routers SHOULD set the "Router Lifetime" of Router Advertisement (RA) messages to ND_PREFERRED_LIMIT. */
161-
+ adv.h.nd_ra_router_lifetime = ND_PREFERRED_LIMIT;
188+
+ adv.h.nd_ra_router_lifetime = htons(ND_PREFERRED_LIMIT);
162189
+ if (!(default_route && valid_prefix)) {
163190
adv.h.nd_ra_router_lifetime = 0;
164191

@@ -171,14 +198,14 @@ Subject: [PATCH] config: allow configuring max limit for preferred and valid
171198
+ syslog(LOG_WARNING, "No default route present, setting ra_lifetime to zero!");
172199
}
173200
+ } else if (iface->ra_lifetime >= 0) {
174-
+ adv.h.nd_ra_router_lifetime = calculated_ra_lifetime;
201+
+ adv.h.nd_ra_router_lifetime = htons(calculated_ra_lifetime);
175202
+ if (calculated_ra_lifetime == 0)
176203
+ syslog(LOG_WARNING, "A default route is present and there is public prefix "
177204
+ "but ra_lifetime on iface was set to zero, setting ra_lifetime to zero!");
178205
}
179206

180207
syslog(LOG_DEBUG, "Using a RA lifetime of %d seconds on %s", ntohs(adv.h.nd_ra_router_lifetime), iface->name);
181-
@@ -710,7 +729,7 @@ static int send_router_advert(struct int
208+
@@ -710,7 +731,7 @@ static int send_router_advert(struct interface *iface, const struct in6_addr *fr
182209

183210
if (iface->pref64_length) {
184211
/* RFC 8781 § 4.1 rounding up lifetime to multiply of 8 */
@@ -187,3 +214,5 @@ Subject: [PATCH] config: allow configuring max limit for preferred and valid
187214
uint8_t prefix_length_code;
188215
uint32_t mask_a1, mask_a2;
189216

217+
--
218+
2.42.0

0 commit comments

Comments
 (0)