dhcpv6/router: add support for mutiple master interfaces
[project/odhcpd.git] / src / router.c
index a3456a8e1f18406afc291bb87554e4d8e4acf397..976e28aaa949dcc09c89a4e716e3689ea637c68f 100644 (file)
@@ -292,7 +292,6 @@ static bool parse_routes(struct odhcpd_ipaddr *n, ssize_t len)
                                        break;
                                }
                        }
-
                }
        }
 
@@ -456,9 +455,13 @@ static uint64_t send_router_advert(struct interface *iface, const struct in6_add
                }
 
                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) {
@@ -605,8 +608,12 @@ static uint64_t send_router_advert(struct interface *iface, const struct in6_add
 
                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));
@@ -668,6 +675,8 @@ static uint64_t send_router_advert(struct interface *iface, const struct in6_add
        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);
 
@@ -703,10 +712,17 @@ static void handle_icmpv6(void *addr, void *data, size_t len,
                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());
        }
 }
 
@@ -795,6 +811,8 @@ static void forward_router_advertisement(const struct interface *iface, uint8_t
                        }
                }
 
+               syslog(LOG_NOTICE, "Forward a RA on %s", c->name);
+
                odhcpd_send(router_event.uloop.fd, &all_nodes, &iov, 1, c);
        }
 }