r = sd_ndisc_router_solicit_get_sender_address(rs, &src);
if (r < 0 && r != -ENODATA) /* null address is allowed */
return log_radv_errno(ra, r, "Failed to get sender address of RS, ignoring: %m");
+ if (r >= 0 && in6_addr_equal(&src, &ra->ipv6ll))
+ /* This should be definitely caused by a misconfiguration. If we send RA to ourself, the
+ * kernel complains about that. Let's ignore the packet. */
+ return log_radv_errno(ra, SYNTHETIC_ERRNO(EADDRINUSE), "Received RS from the same interface, ignoring.");
r = radv_send_router(ra, &src, ra->lifetime_usec);
if (r < 0)
return 0;
}
+int sd_radv_set_link_local_address(sd_radv *ra, const struct in6_addr *addr) {
+ assert_return(ra, -EINVAL);
+ assert_return(!addr || in6_addr_is_link_local(addr), -EINVAL);
+
+ if (addr)
+ ra->ipv6ll = *addr;
+ else
+ zero(ra->ipv6ll);
+
+ return 0;
+}
+
int sd_radv_set_mac(sd_radv *ra, const struct ether_addr *mac_addr) {
assert_return(ra, -EINVAL);
return log_link_debug_errno(link, r, "Failed to request DHCP delegated subnet prefix: %m");
}
+ r = sd_radv_set_link_local_address(link->radv, &link->ipv6ll_address);
+ if (r < 0)
+ return r;
+
log_link_debug(link, "Starting IPv6 Router Advertisements");
return sd_radv_start(link->radv);
}
int sd_radv_set_ifindex(sd_radv *ra, int interface_index);
int sd_radv_set_ifname(sd_radv *ra, const char *interface_name);
int sd_radv_get_ifname(sd_radv *ra, const char **ret);
+int sd_radv_set_link_local_address(sd_radv *ra, const struct in6_addr *addr);
int sd_radv_set_mac(sd_radv *ra, const struct ether_addr *mac_addr);
int sd_radv_set_mtu(sd_radv *ra, uint32_t mtu);
int sd_radv_set_hop_limit(sd_radv *ra, uint8_t hop_limit);