diff --git a/src/radv.c b/src/radv.c index 87efc4e..4427564 100644 --- a/src/radv.c +++ b/src/radv.c @@ -276,7 +276,6 @@ static void send_ra(int iface, char *iface_name, struct in6_addr *dest) static int add_prefixes(struct in6_addr *local, int prefix, int scope, int if_index, int dad, void *vparam) { - struct dhcp_context *context; struct ra_param *param = vparam; (void)scope; /* warning */ @@ -290,12 +289,12 @@ static int add_prefixes(struct in6_addr *local, int prefix, !IN6_IS_ADDR_LINKLOCAL(local) && !IN6_IS_ADDR_MULTICAST(local)) { + int do_prefix = 0; int do_slaac = 0; int deprecate = 0; unsigned int time = 0xffffffff; - struct in6_addr *addr = NULL; - struct prefix_opt *opt; - + struct dhcp_context *context; + for (context = daemon->ra_contexts; context; context = context->next) if (prefix == context->prefix && is_same_net6(local, &context->start6, prefix) && @@ -331,36 +330,41 @@ static int add_prefixes(struct in6_addr *local, int prefix, param->first = 0; param->found_context = 1; - if (context->flags & CONTEXT_RA_DONE) - continue; - - context->flags |= CONTEXT_RA_DONE; - addr = &context->start6; + if (!(context->flags & CONTEXT_RA_DONE)) + { + context->flags |= CONTEXT_RA_DONE; + do_prefix = 1; + } } - - if (addr && (opt = expand(sizeof(struct prefix_opt)))) + + if (do_prefix) { - u64 addrpart = addr6part(addr); - u64 mask = (prefix == 64) ? (u64)-1LL : (1LLU << (128 - prefix)) - 1LLU; + struct prefix_opt *opt; + + if ((opt = expand(sizeof(struct prefix_opt)))) + { + u64 addrpart = addr6part(local); + u64 mask = (prefix == 64) ? (u64)-1LL : (1LLU << (128 - prefix)) - 1LLU; - /* lifetimes must be min 2 hrs, by RFC 2462 */ - if (time < 7200) - time = 7200; - - opt->type = ICMP6_OPT_PREFIX; - opt->len = 4; - opt->prefix_len = prefix; - /* autonomous only is we're not doing dhcp */ - opt->flags = do_slaac ? 0x40 : 0x00; - opt->valid_lifetime = htonl(time); - opt->preferred_lifetime = htonl(deprecate ? 0 : time); - opt->reserved = 0; - - opt->prefix = *addr; - setaddr6part(&opt->prefix, addrpart & ~mask); - - inet_ntop(AF_INET6, &opt->prefix, daemon->addrbuff, ADDRSTRLEN); - my_syslog(MS_DHCP | LOG_INFO, "RTR-ADVERT(%s) %s", param->if_name, daemon->addrbuff); + /* lifetimes must be min 2 hrs, by RFC 2462 */ + if (time < 7200) + time = 7200; + + opt->type = ICMP6_OPT_PREFIX; + opt->len = 4; + opt->prefix_len = prefix; + /* autonomous only is we're not doing dhcp */ + opt->flags = do_slaac ? 0x40 : 0x00; + opt->valid_lifetime = htonl(time); + opt->preferred_lifetime = htonl(deprecate ? 0 : time); + opt->reserved = 0; + + opt->prefix = *local; + setaddr6part(&opt->prefix, addrpart & ~mask); + + inet_ntop(AF_INET6, &opt->prefix, daemon->addrbuff, ADDRSTRLEN); + my_syslog(MS_DHCP | LOG_INFO, "RTR-ADVERT(%s) %s", param->if_name, daemon->addrbuff); + } } } }