Merge pull request #28496 from ssahani/ndisc-28426
network: ndisc - Also fill router preference
This commit is contained in:
@@ -448,10 +448,10 @@ static int ndisc_router_process_autonomous_prefix(Link *link, sd_ndisc_router *r
|
||||
|
||||
static int ndisc_router_process_onlink_prefix(Link *link, sd_ndisc_router *rt) {
|
||||
_cleanup_(route_freep) Route *route = NULL;
|
||||
unsigned prefixlen, preference;
|
||||
usec_t timestamp_usec;
|
||||
uint32_t lifetime_sec;
|
||||
struct in6_addr prefix;
|
||||
unsigned prefixlen;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
@@ -477,6 +477,11 @@ static int ndisc_router_process_onlink_prefix(Link *link, sd_ndisc_router *rt) {
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to get prefix length: %m");
|
||||
|
||||
/* Prefix Information option does not have preference, hence we use the 'main' preference here */
|
||||
r = sd_ndisc_router_get_preference(rt, &preference);
|
||||
if (r < 0)
|
||||
log_link_warning_errno(link, r, "Failed to get default router preference from RA: %m");
|
||||
|
||||
r = route_new(&route);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
@@ -484,6 +489,7 @@ static int ndisc_router_process_onlink_prefix(Link *link, sd_ndisc_router *rt) {
|
||||
route->family = AF_INET6;
|
||||
route->dst.in6 = prefix;
|
||||
route->dst_prefixlen = prefixlen;
|
||||
route->pref = preference;
|
||||
route->lifetime_usec = sec_to_usec(lifetime_sec, timestamp_usec);
|
||||
|
||||
r = ndisc_request_route(TAKE_PTR(route), link, rt);
|
||||
@@ -972,7 +978,7 @@ static int ndisc_router_process_options(Link *link, sd_ndisc_router *rt) {
|
||||
}
|
||||
}
|
||||
|
||||
static int ndisc_drop_outdated(Link *link, usec_t timestamp_usec) {
|
||||
static int ndisc_drop_outdated(Link *link, usec_t timestamp_usec, const struct in6_addr *router) {
|
||||
bool updated = false;
|
||||
NDiscDNSSL *dnssl;
|
||||
NDiscRDNSS *rdnss;
|
||||
@@ -996,6 +1002,9 @@ static int ndisc_drop_outdated(Link *link, usec_t timestamp_usec) {
|
||||
if (route->lifetime_usec >= timestamp_usec)
|
||||
continue; /* the route is still valid */
|
||||
|
||||
if (router && !in6_addr_equal(&route->provider.in6, router))
|
||||
continue;
|
||||
|
||||
k = route_remove_and_drop(route);
|
||||
if (k < 0)
|
||||
r = log_link_warning_errno(link, k, "Failed to remove outdated SLAAC route, ignoring: %m");
|
||||
@@ -1008,6 +1017,9 @@ static int ndisc_drop_outdated(Link *link, usec_t timestamp_usec) {
|
||||
if (address->lifetime_valid_usec >= timestamp_usec)
|
||||
continue; /* the address is still valid */
|
||||
|
||||
if (router && !in6_addr_equal(&address->provider.in6, router))
|
||||
continue;
|
||||
|
||||
k = address_remove_and_drop(address);
|
||||
if (k < 0)
|
||||
r = log_link_warning_errno(link, k, "Failed to remove outdated SLAAC address, ignoring: %m");
|
||||
@@ -1017,6 +1029,9 @@ static int ndisc_drop_outdated(Link *link, usec_t timestamp_usec) {
|
||||
if (rdnss->lifetime_usec >= timestamp_usec)
|
||||
continue; /* the DNS server is still valid */
|
||||
|
||||
if (router && !in6_addr_equal(&rdnss->router, router))
|
||||
continue;
|
||||
|
||||
free(set_remove(link->ndisc_rdnss, rdnss));
|
||||
updated = true;
|
||||
}
|
||||
@@ -1025,6 +1040,9 @@ static int ndisc_drop_outdated(Link *link, usec_t timestamp_usec) {
|
||||
if (dnssl->lifetime_usec >= timestamp_usec)
|
||||
continue; /* the DNS domain is still valid */
|
||||
|
||||
if (router && !in6_addr_equal(&dnssl->router, router))
|
||||
continue;
|
||||
|
||||
free(set_remove(link->ndisc_dnssl, dnssl));
|
||||
updated = true;
|
||||
}
|
||||
@@ -1033,6 +1051,9 @@ static int ndisc_drop_outdated(Link *link, usec_t timestamp_usec) {
|
||||
if (cp->lifetime_usec >= timestamp_usec)
|
||||
continue; /* the captive portal is still valid */
|
||||
|
||||
if (router && !in6_addr_equal(&cp->router, router))
|
||||
continue;
|
||||
|
||||
ndisc_captive_portal_free(set_remove(link->ndisc_captive_portals, cp));
|
||||
updated = true;
|
||||
}
|
||||
@@ -1053,7 +1074,7 @@ static int ndisc_expire_handler(sd_event_source *s, uint64_t usec, void *userdat
|
||||
|
||||
assert_se(sd_event_now(link->manager->event, CLOCK_BOOTTIME, &now_usec) >= 0);
|
||||
|
||||
(void) ndisc_drop_outdated(link, now_usec);
|
||||
(void) ndisc_drop_outdated(link, now_usec, NULL);
|
||||
(void) ndisc_setup_expire(link);
|
||||
return 0;
|
||||
}
|
||||
@@ -1154,6 +1175,7 @@ static int ndisc_start_dhcp6_client(Link *link, sd_ndisc_router *rt) {
|
||||
}
|
||||
|
||||
static int ndisc_router_handler(Link *link, sd_ndisc_router *rt) {
|
||||
uint16_t router_lifetime_sec;
|
||||
struct in6_addr router;
|
||||
usec_t timestamp_usec;
|
||||
int r;
|
||||
@@ -1186,12 +1208,28 @@ static int ndisc_router_handler(Link *link, sd_ndisc_router *rt) {
|
||||
log_link_debug(link, "Received RA without timestamp, ignoring.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = ndisc_drop_outdated(link, timestamp_usec, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = ndisc_drop_outdated(link, timestamp_usec);
|
||||
r = sd_ndisc_router_get_lifetime(rt, &router_lifetime_sec);
|
||||
if (r < 0)
|
||||
return r;
|
||||
return log_link_warning_errno(link, r, "Failed to get lifetime of RA message: %m");
|
||||
|
||||
/* https://datatracker.ietf.org/doc/html/rfc4861
|
||||
* Router Lifetime: A Lifetime of 0 indicates that the router is not a default router
|
||||
* and SHOULD NOT appear on the default router list.
|
||||
*/
|
||||
if (router_lifetime_sec == 0) {
|
||||
log_link_debug(link, "Received RA with lifetime = 0, dropping configurations.");
|
||||
|
||||
r = ndisc_drop_outdated(link, USEC_INFINITY, &router);
|
||||
if (r < 0)
|
||||
log_link_warning_errno(link, r, "Failed to process RA with zero lifetime, ignoring: %m");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = ndisc_start_dhcp6_client(link, rt);
|
||||
if (r < 0)
|
||||
|
||||
Reference in New Issue
Block a user