diff options
-rw-r--r-- | src/libsystemd-network/sd-ndisc.c | 3 | ||||
-rw-r--r-- | src/network/networkd-link.c | 26 | ||||
-rw-r--r-- | src/network/networkd-ndisc.c | 13 |
3 files changed, 20 insertions, 22 deletions
diff --git a/src/libsystemd-network/sd-ndisc.c b/src/libsystemd-network/sd-ndisc.c index 6703d87bc4..3bb06f6892 100644 --- a/src/libsystemd-network/sd-ndisc.c +++ b/src/libsystemd-network/sd-ndisc.c @@ -508,6 +508,9 @@ static int ndisc_router_advertisment_recv(sd_event_source *s, int fd, uint32_t r return 0; } + if (!in_addr_is_link_local(AF_INET6, (const union in_addr_union*) &router.in6.sin6_addr)) + return 0; + if (ra->nd_ra_type != ND_ROUTER_ADVERT) return 0; diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 0d3c141312..4af895a6fb 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -626,6 +626,9 @@ void link_check_ready(Link *link) { !link->dhcp4_configured && !link->dhcp6_configured)) return; + if (link_ipv6_accept_ra_enabled(link) && !link->ndisc_configured) + return; + SET_FOREACH(a, link->addresses, i) if (!address_is_ready(a)) return; @@ -1923,7 +1926,6 @@ static int link_set_ipv6_privacy_extensions(Link *link) { static int link_set_ipv6_accept_ra(Link *link) { const char *p = NULL; - const char *v; int r; /* Make this a NOP if IPv6 is not available */ @@ -1936,16 +1938,12 @@ static int link_set_ipv6_accept_ra(Link *link) { if (!link->network) return 0; - if (link_ipv6_accept_ra_enabled(link)) - v = "1"; - else - v = "0"; - p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/accept_ra"); - r = write_string_file(p, v, WRITE_STRING_FILE_VERIFY_ON_FAILURE); + /* We handle router advertisments ourselves, tell the kernel to GTFO */ + r = write_string_file(p, "0", WRITE_STRING_FILE_VERIFY_ON_FAILURE); if (r < 0) - log_link_warning_errno(link, r, "Cannot configure kernel IPv6 accept_ra for interface: %m"); + log_link_warning_errno(link, r, "Cannot disable kernel IPv6 accept_ra for interface: %m"); return 0; } @@ -2006,7 +2004,6 @@ static int link_set_ipv6_hop_limit(Link *link) { return 0; } -/* static int link_drop_foreign_config(Link *link) { Address *address; Route *route; @@ -2014,6 +2011,7 @@ static int link_drop_foreign_config(Link *link) { int r; SET_FOREACH(address, link->addresses_foreign, i) { + /* we consider IPv6LL addresses to be managed by the kernel */ if (address->family == AF_INET6 && in_addr_is_link_local(AF_INET6, &address->in_addr) == 1) continue; @@ -2023,6 +2021,7 @@ static int link_drop_foreign_config(Link *link) { } SET_FOREACH(route, link->routes_foreign, i) { + /* do not touch routes managed by the kernel */ if (route->protocol == RTPROT_KERNEL) continue; @@ -2033,7 +2032,6 @@ static int link_drop_foreign_config(Link *link) { return 0; } -*/ static int link_configure(Link *link) { int r; @@ -2042,11 +2040,9 @@ static int link_configure(Link *link) { assert(link->network); assert(link->state == LINK_STATE_PENDING); -/* r = link_drop_foreign_config(link); if (r < 0) return r; -*/ r = link_set_bridge_fdb(link); if (r < 0) @@ -2300,7 +2296,8 @@ network_file_fail: if (r < 0) { log_link_debug_errno(link, r, "Failed to extract next address string: %m"); continue; - } if (r == 0) + } + if (r == 0) break; prefixlen_str = strchr(address_str, '/'); @@ -2344,7 +2341,8 @@ network_file_fail: if (r < 0) { log_link_debug_errno(link, r, "Failed to extract next route string: %m"); continue; - } if (r == 0) + } + if (r == 0) break; prefixlen_str = strchr(route_str, '/'); diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c index 966d729d85..ce9e513ceb 100644 --- a/src/network/networkd-ndisc.c +++ b/src/network/networkd-ndisc.c @@ -26,7 +26,7 @@ #include "sd-ndisc.h" #include "networkd-link.h" -/* + static int ndisc_netlink_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { _cleanup_link_unref_ Link *link = userdata; int r; @@ -77,6 +77,7 @@ static void ndisc_prefix_autonomous_handler(sd_ndisc *nd, const struct in6_addr if (in_addr_is_null(AF_INET6, (const union in_addr_union *) &link->network->ipv6_token) == 0) memcpy(((char *)&address->in_addr.in6) + 8, ((char *)&link->network->ipv6_token) + 8, 8); else { + /* see RFC4291 section 2.5.1 */ address->in_addr.in6.__in6_u.__u6_addr8[8] = link->mac.ether_addr_octet[0]; address->in_addr.in6.__in6_u.__u6_addr8[8] ^= 1 << 1; address->in_addr.in6.__in6_u.__u6_addr8[9] = link->mac.ether_addr_octet[1]; @@ -139,12 +140,11 @@ static void ndisc_prefix_onlink_handler(sd_ndisc *nd, const struct in6_addr *pre link->ndisc_messages ++; } -*/ static void ndisc_router_handler(sd_ndisc *nd, uint8_t flags, const struct in6_addr *gateway, unsigned lifetime, int pref, void *userdata) { _cleanup_route_free_ Route *route = NULL; Link *link = userdata; - /* usec_t time_now; */ + usec_t time_now; int r; assert(link); @@ -163,8 +163,6 @@ static void ndisc_router_handler(sd_ndisc *nd, uint8_t flags, const struct in6_a log_link_warning_errno(link, r, "Starting DHCPv6 client on NDisc request failed: %m"); } - return; -/* if (!gateway) return; @@ -191,7 +189,6 @@ static void ndisc_router_handler(sd_ndisc *nd, uint8_t flags, const struct in6_a } link->ndisc_messages ++; -*/ } static void ndisc_handler(sd_ndisc *nd, int event, void *userdata) { @@ -245,8 +242,8 @@ int ndisc_configure(Link *link) { r = sd_ndisc_set_callback(link->ndisc_router_discovery, ndisc_router_handler, - NULL, - NULL, + ndisc_prefix_onlink_handler, + ndisc_prefix_autonomous_handler, ndisc_handler, link); |