Use the RA lifetime as lifetime for the recursive DNS and DNS search options
For the route options use as lifetime the smallest value of either the valid
lifetime of the address associated with the route or the RA lifetime.
This avoids routes having infinite lifetime being installed in downstream
clients which can results into routes pointing to a removed router.
Signed-off-by: Hans Dedecker <dedeckeh@gmail.com>
}
static int calc_adv_interval(struct interface *iface, uint32_t minvalid,
}
static int calc_adv_interval(struct interface *iface, uint32_t minvalid,
{
uint32_t minival = iface->ra_mininterval;
int msecs;
{
uint32_t minival = iface->ra_mininterval;
int msecs;
-static uint16_t calc_ra_lifetime(struct interface *iface, uint32_t maxival)
+static uint32_t calc_ra_lifetime(struct interface *iface, uint32_t maxival)
- uint16_t lifetime = 3*maxival;
+ uint32_t lifetime = 3*maxival;
if (iface->ra_lifetime >= 0) {
lifetime = iface->ra_lifetime;
if (iface->ra_lifetime >= 0) {
lifetime = iface->ra_lifetime;
struct sockaddr_in6 dest;
size_t dns_sz = 0, search_sz = 0, pfxs_cnt = 0, routes_cnt = 0;
ssize_t addr_cnt = 0;
struct sockaddr_in6 dest;
size_t dns_sz = 0, search_sz = 0, pfxs_cnt = 0, routes_cnt = 0;
ssize_t addr_cnt = 0;
- uint32_t minvalid = UINT32_MAX, maxival;
+ uint32_t minvalid = UINT32_MAX, maxival, lifetime;
int msecs, mtu = iface->ra_mtu, hlim = iface->ra_hoplimit;
bool default_route = false;
bool valid_prefix = false;
int msecs, mtu = iface->ra_mtu, hlim = iface->ra_hoplimit;
bool default_route = false;
bool valid_prefix = false;
/* Calculate periodic transmit */
msecs = calc_adv_interval(iface, minvalid, &maxival);
/* Calculate periodic transmit */
msecs = calc_adv_interval(iface, minvalid, &maxival);
+ lifetime = calc_ra_lifetime(iface, maxival);
if (default_route) {
if (!valid_prefix) {
if (default_route) {
if (!valid_prefix) {
"on %s thus we don't announce a default route!", iface->name);
adv.h.nd_ra_router_lifetime = 0;
} else
"on %s thus we don't announce a default route!", iface->name);
adv.h.nd_ra_router_lifetime = 0;
} else
- adv.h.nd_ra_router_lifetime = htons(calc_ra_lifetime(iface, maxival));
+ adv.h.nd_ra_router_lifetime = htons(lifetime < UINT16_MAX ? lifetime : UINT16_MAX);
} else
adv.h.nd_ra_router_lifetime = 0;
} else
adv.h.nd_ra_router_lifetime = 0;
memset(dns, 0, dns_sz);
dns->type = ND_OPT_RECURSIVE_DNS;
dns->len = 1 + (2 * dns_cnt);
memset(dns, 0, dns_sz);
dns->type = ND_OPT_RECURSIVE_DNS;
dns->len = 1 + (2 * dns_cnt);
- dns->lifetime = htonl(maxival*10);
+ dns->lifetime = htonl(lifetime);
memcpy(dns->addr, dns_addr, sizeof(struct in6_addr)*dns_cnt);
}
memcpy(dns->addr, dns_addr, sizeof(struct in6_addr)*dns_cnt);
}
memset(search, 0, search_sz);
search->type = ND_OPT_DNS_SEARCH;
search->len = search_len ? ((sizeof(*search) + search_padded) / 8) : 0;
memset(search, 0, search_sz);
search->type = ND_OPT_DNS_SEARCH;
search->len = search_len ? ((sizeof(*search) + search_padded) / 8) : 0;
- search->lifetime = htonl(maxival*10);
+ search->lifetime = htonl(lifetime);
if (search_len > 0) {
memcpy(search->name, search_domain, search_len);
if (search_len > 0) {
memcpy(search->name, search_domain, search_len);
for (ssize_t i = 0; i < addr_cnt; ++i) {
struct odhcpd_ipaddr *addr = &addrs[i];
struct nd_opt_route_info *tmp;
for (ssize_t i = 0; i < addr_cnt; ++i) {
struct odhcpd_ipaddr *addr = &addrs[i];
struct nd_opt_route_info *tmp;
if (addr->dprefix > 64 || addr->dprefix == 0 || addr->valid <= (uint32_t)now) {
syslog(LOG_INFO, "Address %s (dprefix %d, valid %u) not suitable as RA route on %s",
if (addr->dprefix > 64 || addr->dprefix == 0 || addr->valid <= (uint32_t)now) {
syslog(LOG_INFO, "Address %s (dprefix %d, valid %u) not suitable as RA route on %s",
else if (iface->route_preference > 0)
routes[routes_cnt].flags |= ND_RA_PREF_HIGH;
else if (iface->route_preference > 0)
routes[routes_cnt].flags |= ND_RA_PREF_HIGH;
- routes[routes_cnt].lifetime = htonl(TIME_LEFT(addr->valid, now));
+ valid = TIME_LEFT(addr->valid, now);
+ routes[routes_cnt].lifetime = htonl(valid < lifetime ? valid : lifetime);
routes[routes_cnt].addr[0] = addr->addr.in6.s6_addr32[0];
routes[routes_cnt].addr[1] = addr->addr.in6.s6_addr32[1];
routes[routes_cnt].addr[2] = 0;
routes[routes_cnt].addr[0] = addr->addr.in6.s6_addr32[0];
routes[routes_cnt].addr[1] = addr->addr.in6.s6_addr32[1];
routes[routes_cnt].addr[2] = 0;