@@ -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