Skip to content

Commit

Permalink
router: implement RFC 7084 errata 7699
Browse files Browse the repository at this point in the history
RFC 7084 L-3 requires router advertisement daemon to send RIO for
every prefix delegation that allocates a prefix on the interface.
There is one special case though where PIO advertise the on-link
prefix route that conflicts with the RIO prefix.

Example:
 - CE-Router receives IA-PD 2001:db8:1234::/64
 - this prefix delegation gets assigned to the lan interface
 - odhcpd advertise on-link PIO with prefix 2001:db8:1234::/64

If original RFC 7084 L-3 would be followed, RA will also contain
a RIO with prefix 2001:db8:1234::/64 which will require lan hosts
to add the routes
   2001:db8:1234::/64 dev br-lan # the on-link prefix route
   2001:db8:1234::/64 dev br-lan nexthop fe80::1 # RIO route

Signed-off-by: Alin Nastac <[email protected]>
  • Loading branch information
alinnastac authored and Alin Nastac committed Dec 22, 2023
1 parent d8118f6 commit 328b390
Showing 1 changed file with 16 additions and 1 deletion.
17 changes: 16 additions & 1 deletion src/router.c
Original file line number Diff line number Diff line change
Expand Up @@ -782,7 +782,7 @@ static int send_router_advert(struct interface *iface, const struct in6_addr *fr
struct nd_opt_route_info *tmp;
uint32_t valid;

if (addr->dprefix >= 64 || addr->dprefix == 0 || addr->valid <= (uint32_t)now) {
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",
inet_ntop(AF_INET6, &addr->addr.in6, buf, sizeof(buf)),
addr->dprefix, addr->valid, iface->name);
Expand All @@ -804,6 +804,21 @@ static int send_router_advert(struct interface *iface, const struct in6_addr *fr
addr->addr.in6.s6_addr32[1] = 0;
}

if (!iface->ra_not_onlink) {
bool fully_used_in_pio = false;
for (size_t i = 0; i < pfxs_cnt; ++i) {
if (addr->dprefix == pfxs[i].nd_opt_pi_prefix_len &&
!odhcpd_bmemcmp(&pfxs[i].nd_opt_pi_prefix,
&addr->addr.in6, addr->prefix)) {
fully_used_in_pio = true;
break;
}
}

if (fully_used_in_pio)
continue; /* correspondent PIO use the entire prefix delegation (see RFC 7084 errata 7699) */
}

tmp = realloc(routes, sizeof(*routes) * (routes_cnt + 1));
if (!tmp) {
syslog(LOG_ERR, "Realloc failed for RA route option on %s", iface->name);
Expand Down

0 comments on commit 328b390

Please sign in to comment.