diff --git a/src/network/networkd-ipv4acd.c b/src/network/networkd-ipv4acd.c index 5c57032f2a..74a669ead4 100644 --- a/src/network/networkd-ipv4acd.c +++ b/src/network/networkd-ipv4acd.c @@ -288,3 +288,18 @@ int ipv4acd_stop(Link *link) { return r; } + +int ipv4acd_set_ifname(Link *link) { + Address *address; + int r; + + assert(link); + + SET_FOREACH(address, link->addresses_ipv4acd) { + r = sd_ipv4acd_set_ifname(address->acd, link->ifname); + if (r < 0) + return r; + } + + return 0; +} diff --git a/src/network/networkd-ipv4acd.h b/src/network/networkd-ipv4acd.h index d2b4ff775f..c3d8b0ec38 100644 --- a/src/network/networkd-ipv4acd.h +++ b/src/network/networkd-ipv4acd.h @@ -8,3 +8,4 @@ int ipv4acd_address_is_ready_to_configure(Link *link, const Address *address); int ipv4acd_update_mac(Link *link); int ipv4acd_start(Link *link); int ipv4acd_stop(Link *link); +int ipv4acd_set_ifname(Link *link); diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index caad6205ae..8ae5f35f4c 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -2280,12 +2280,9 @@ static int link_update_name(Link *link, sd_netlink_message *message) { return log_link_debug_errno(link, r, "Failed to update interface name in IPv4LL client: %m"); } - Address *a; - SET_FOREACH(a, link->addresses_ipv4acd) { - r = sd_ipv4acd_set_ifname(a->acd, link->ifname); - if (r < 0) - return log_link_debug_errno(link, r, "Failed to update interface name in IPv4ACD client: %m"); - } + r = ipv4acd_set_ifname(link); + if (r < 0) + return log_link_debug_errno(link, r, "Failed to update interface name in IPv4ACD client: %m"); return 0; } diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index a364ca45b7..c01f1ca14a 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -1187,6 +1187,24 @@ static int manager_drop_routes(Manager *manager, const Link *except) { return manager_drop_routes_internal(manager, false, except); } +static bool route_by_kernel(const Route *route) { + assert(route); + + if (route->protocol == RTPROT_KERNEL) + return true; + + /* Do not touch multicast route added by kernel. See issue #6088. + * TODO: Why the kernel adds this route with protocol RTPROT_BOOT? + * https://tools.ietf.org/html/rfc4862#section-5.4 may explain why. */ + if (route->protocol == RTPROT_BOOT && + route->family == AF_INET6 && + route->dst_prefixlen == 8 && + in6_addr_equal(&route->dst.in6, & (struct in6_addr) {{{ 0xff,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 }}})) + return true; + + return false; +} + int link_drop_foreign_routes(Link *link) { Route *route; int k, r = 0; @@ -1196,16 +1214,7 @@ int link_drop_foreign_routes(Link *link) { SET_FOREACH(route, link->routes_foreign) { /* do not touch routes managed by the kernel */ - if (route->protocol == RTPROT_KERNEL) - continue; - - /* do not touch multicast route added by kernel */ - /* FIXME: Why the kernel adds this route with protocol RTPROT_BOOT??? We need to investigate that. - * https://tools.ietf.org/html/rfc4862#section-5.4 may explain why. */ - if (route->protocol == RTPROT_BOOT && - route->family == AF_INET6 && - route->dst_prefixlen == 8 && - in_addr_equal(AF_INET6, &route->dst, &(union in_addr_union) { .in6 = {{{ 0xff,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 }}} })) + if (route_by_kernel(route)) continue; if (route->protocol == RTPROT_STATIC && link->network && diff --git a/src/network/networkd-routing-policy-rule.c b/src/network/networkd-routing-policy-rule.c index 1e56b79d84..a89c5877d9 100644 --- a/src/network/networkd-routing-policy-rule.c +++ b/src/network/networkd-routing-policy-rule.c @@ -922,10 +922,7 @@ static bool routing_policy_rule_is_created_by_kernel(const RoutingPolicyRule *ru int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, Manager *m) { _cleanup_(routing_policy_rule_freep) RoutingPolicyRule *tmp = NULL; RoutingPolicyRule *rule = NULL; - const char *iif = NULL, *oif = NULL; bool adjust_protocol = false; - uint32_t suppress_prefixlen; - unsigned flags; uint16_t type; int r; @@ -988,6 +985,7 @@ int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, Man } } + unsigned flags; r = sd_rtnl_message_routing_policy_rule_get_flags(message, &flags); if (r < 0) { log_warning_errno(r, "rtnl: received rule message without valid flag, ignoring: %m"); @@ -1034,23 +1032,17 @@ int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, Man return 0; } - r = sd_netlink_message_read_string(message, FRA_IIFNAME, &iif); + r = sd_netlink_message_read_string_strdup(message, FRA_IIFNAME, &tmp->iif); if (r < 0 && r != -ENODATA) { log_warning_errno(r, "rtnl: could not get FRA_IIFNAME attribute, ignoring: %m"); return 0; } - r = free_and_strdup(&tmp->iif, iif); - if (r < 0) - return log_oom(); - r = sd_netlink_message_read_string(message, FRA_OIFNAME, &oif); + r = sd_netlink_message_read_string_strdup(message, FRA_OIFNAME, &tmp->oif); if (r < 0 && r != -ENODATA) { log_warning_errno(r, "rtnl: could not get FRA_OIFNAME attribute, ignoring: %m"); return 0; } - r = free_and_strdup(&tmp->oif, oif); - if (r < 0) - return log_oom(); r = sd_netlink_message_read_u8(message, FRA_IP_PROTO, &tmp->ipproto); if (r < 0 && r != -ENODATA) { @@ -1093,6 +1085,7 @@ int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, Man return 0; } + uint32_t suppress_prefixlen; r = sd_netlink_message_read_u32(message, FRA_SUPPRESS_PREFIXLEN, &suppress_prefixlen); if (r < 0 && r != -ENODATA) { log_warning_errno(r, "rtnl: could not get FRA_SUPPRESS_PREFIXLEN attribute, ignoring: %m");