if (info->rt.dst_len)
break;
- list_for_each_entry(iface, &interfaces, head) {
+ avl_for_each_element(&interfaces, iface, avl) {
if (iface->ra == MODE_SERVER && !iface->master)
uloop_timeout_set(&iface->timer_rs, 1000);
}
break;
}
}
-
}
}
}
if (odhcpd_bmemcmp(&addr->addr, &iface->pio_filter_addr,
- iface->pio_filter_length) != 0 ||
- addr->prefix < iface->pio_filter_length)
- continue; // PIO filtered out of this RA
+ iface->pio_filter_length) != 0 ||
+ addr->prefix < iface->pio_filter_length) {
+ syslog(LOG_INFO, "Address %s filtered out as RA prefix on %s",
+ inet_ntop(AF_INET6, &addr->addr.in6, buf, sizeof(buf)),
+ iface->name);
+ continue; /* PIO filtered out of this RA */
+ }
struct nd_opt_prefix_info *p = NULL;
for (size_t i = 0; i < pfxs_cnt; ++i) {
if (odhcpd_bmemcmp(&addr->addr, &iface->pio_filter_addr,
iface->pio_filter_length) != 0 ||
- addr->prefix < iface->pio_filter_length)
- continue; /* RIO filtered out of this RA */
+ addr->prefix < iface->pio_filter_length) {
+ syslog(LOG_INFO, "Address %s filtered out as RA route on %s",
+ inet_ntop(AF_INET6, &addr->addr.in6, buf, sizeof(buf)),
+ iface->name);
+ continue; /* PIO filtered out of this RA */
+ }
if (addr->dprefix > 32) {
addr->addr.in6.s6_addr32[1] &= htonl(~((1U << (64 - addr->dprefix)) - 1));
else
inet_pton(AF_INET6, ALL_IPV6_NODES, &dest.sin6_addr);
+ syslog(LOG_INFO, "Sending a RA on %s", iface->name);
+
odhcpd_send(router_event.uloop.fd,
&dest, iov, ARRAY_SIZE(iov), iface);
if (hdr->icmp6_type == ND_ROUTER_SOLICIT)
send_router_advert(iface, &from->sin6_addr);
} else if (iface->ra == MODE_RELAY) { /* Relay mode */
- if (hdr->icmp6_type == ND_ROUTER_ADVERT && iface->master)
+ if (hdr->icmp6_type == ND_ROUTER_SOLICIT && !iface->master) {
+ struct interface *c;
+
+ avl_for_each_element(&interfaces, c, avl) {
+ if (!c->master || c->ra != MODE_RELAY)
+ continue;
+
+ forward_router_solicitation(c);
+ }
+ } else if (hdr->icmp6_type == ND_ROUTER_ADVERT && iface->master)
forward_router_advertisement(iface, data, len);
- else if (hdr->icmp6_type == ND_ROUTER_SOLICIT && !iface->master)
- forward_router_solicitation(odhcpd_get_master_interface());
}
}
{
struct nd_router_advert *adv = (struct nd_router_advert *)data;
struct sockaddr_in6 all_nodes;
-
+ struct icmpv6_opt *opt;
+ struct interface *c;
+ struct iovec iov = { .iov_base = data, .iov_len = len };
/* Rewrite options */
uint8_t *end = data + len;
uint8_t *mac_ptr = NULL;
struct in6_addr *dns_ptr = NULL;
size_t dns_count = 0;
- struct icmpv6_opt *opt;
icmpv6_for_each_option(opt, &adv[1], end) {
if (opt->type == ND_OPT_SOURCE_LINKADDR) {
/* Store address of source MAC-address */
all_nodes.sin6_family = AF_INET6;
inet_pton(AF_INET6, ALL_IPV6_NODES, &all_nodes.sin6_addr);
- struct iovec iov = {data, len};
-
- struct interface *c;
- list_for_each_entry(c, &interfaces, head) {
+ avl_for_each_element(&interfaces, c, avl) {
if (c->ra != MODE_RELAY || c->master)
continue;
}
}
+ syslog(LOG_NOTICE, "Forward a RA on %s", c->name);
+
odhcpd_send(router_event.uloop.fd, &all_nodes, &iov, 1, c);
}
}