Skip to content

Commit 054f579

Browse files
committed
router: remove duplicated PIOs
There can be duplicated PIOs if the user changed the assigned prefix length in the configuration. Signed-off-by: Álvaro Fernández Rojas <[email protected]>
1 parent d9a9ddc commit 054f579

File tree

1 file changed

+41
-2
lines changed

1 file changed

+41
-2
lines changed

src/router.c

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,44 @@ static void router_add_ra_pio(struct interface *iface,
520520
pio->length);
521521
}
522522

523-
static void router_clear_ra_pio(time_t now,
523+
static void router_clear_duplicated_ra_pio(struct interface *iface)
524+
{
525+
size_t pio_cnt = iface->pio_cnt;
526+
char ipv6_str[INET6_ADDRSTRLEN];
527+
528+
for (size_t i = 0; i < iface->pio_cnt; i++) {
529+
struct ra_pio *pio_a = &iface->pios[i];
530+
size_t j = i + 1;
531+
532+
while (j < iface->pio_cnt) {
533+
struct ra_pio *pio_b = &iface->pios[j];
534+
535+
if (pio_a->length == pio_b->length &&
536+
!memcmp(&pio_a->prefix, &pio_b->prefix, sizeof(struct in6_addr))) {
537+
warn("rfc9096: %s: duplicated %s/%u",
538+
iface->ifname,
539+
inet_ntop(AF_INET6, &pio_a->prefix, ipv6_str, sizeof(ipv6_str)),
540+
pio_a->length);
541+
542+
if (j + 1 < iface->pio_cnt)
543+
iface->pios[j] = iface->pios[iface->pio_cnt - 1];
544+
545+
iface->pio_cnt--;
546+
} else {
547+
j++;
548+
}
549+
}
550+
}
551+
552+
if (iface->pio_cnt != pio_cnt) {
553+
struct ra_pio *new_pios = realloc(iface->pios, sizeof(struct ra_pio) * iface->pio_cnt);
554+
555+
if (new_pios)
556+
iface->pios = new_pios;
557+
}
558+
}
559+
560+
static void router_clear_expired_ra_pio(time_t now,
524561
struct interface *iface)
525562
{
526563
size_t i = 0, pio_cnt = iface->pio_cnt;
@@ -605,7 +642,7 @@ static int send_router_advert(struct interface *iface, const struct in6_addr *fr
605642
bool valid_prefix = false;
606643
char buf[INET6_ADDRSTRLEN];
607644

608-
router_clear_ra_pio(now, iface);
645+
router_clear_expired_ra_pio(now, iface);
609646

610647
memset(&adv, 0, sizeof(adv));
611648
adv.h.nd_ra_type = ND_ROUTER_ADVERT;
@@ -819,6 +856,8 @@ static int send_router_advert(struct interface *iface, const struct in6_addr *fr
819856
}
820857
}
821858

859+
router_clear_duplicated_ra_pio(iface);
860+
822861
iov[IOV_RA_PFXS].iov_base = (char *)pfxs;
823862
iov[IOV_RA_PFXS].iov_len = pfxs_cnt * sizeof(*pfxs);
824863

0 commit comments

Comments
 (0)