]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/network/networkd-dhcp4.c
network: rename DHCPUseDomains -> UseDomains
[thirdparty/systemd.git] / src / network / networkd-dhcp4.c
index efbae6d8686d437667bd253ca622f998bc3f8fca..4a0e26d1720ded7b411ca06ecf7248fe78001ab2 100644 (file)
@@ -243,21 +243,20 @@ static int dhcp4_find_gateway_for_destination(
 static int dhcp4_remove_address_and_routes(Link *link, bool only_marked) {
         Address *address;
         Route *route;
-        int k, r = 0;
+        int ret = 0;
 
         assert(link);
+        assert(link->manager);
 
-        SET_FOREACH(route, link->routes) {
+        SET_FOREACH(route, link->manager->routes) {
                 if (route->source != NETWORK_CONFIG_SOURCE_DHCP4)
                         continue;
+                if (route->nexthop.ifindex != 0 && route->nexthop.ifindex != link->ifindex)
+                        continue;
                 if (only_marked && !route_is_marked(route))
                         continue;
 
-                k = route_remove(route);
-                if (k < 0)
-                        r = k;
-
-                route_cancel_request(route, link);
+                RET_GATHER(ret, route_remove_and_cancel(route, link->manager));
         }
 
         SET_FOREACH(address, link->addresses) {
@@ -266,12 +265,10 @@ static int dhcp4_remove_address_and_routes(Link *link, bool only_marked) {
                 if (only_marked && !address_is_marked(address))
                         continue;
 
-                k = address_remove_and_drop(address);
-                if (k < 0)
-                        r = k;
+                RET_GATHER(ret, address_remove_and_cancel(address, link));
         }
 
-        return r;
+        return ret;
 }
 
 static int dhcp4_address_get(Link *link, Address **ret) {
@@ -347,12 +344,9 @@ static int dhcp4_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Request
         assert(m);
         assert(link);
 
-        r = sd_netlink_message_get_errno(m);
-        if (r < 0 && r != -EEXIST) {
-                log_link_message_warning_errno(link, m, r, "Could not set DHCPv4 route");
-                link_enter_failed(link);
-                return 1;
-        }
+        r = route_configure_handler_internal(rtnl, m, link, route, "Could not set DHCPv4 route");
+        if (r <= 0)
+                return r;
 
         r = dhcp4_check_ready(link);
         if (r < 0)
@@ -361,14 +355,14 @@ static int dhcp4_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Request
         return 1;
 }
 
-static int dhcp4_request_route(Route *in, Link *link) {
-        _cleanup_(route_freep) Route *route = in;
+static int dhcp4_request_route(Route *route, Link *link) {
         struct in_addr server;
         Route *existing;
         int r;
 
         assert(route);
         assert(link);
+        assert(link->manager);
         assert(link->network);
         assert(link->dhcp_lease);
 
@@ -385,22 +379,29 @@ static int dhcp4_request_route(Route *in, Link *link) {
                 route->priority = link->network->dhcp_route_metric;
         if (!route->table_set)
                 route->table = link_get_dhcp4_route_table(link);
-        if (route->mtu == 0)
-                route->mtu = link->network->dhcp_route_mtu;
-        if (route->quickack < 0)
-                route->quickack = link->network->dhcp_quickack;
-        if (route->initcwnd == 0)
-                route->initcwnd = link->network->dhcp_initial_congestion_window;
-        if (route->initrwnd == 0)
-                route->initrwnd = link->network->dhcp_advertised_receive_window;
-
-        if (route_get(NULL, link, route, &existing) < 0) /* This is a new route. */
+        r = route_metric_set(&route->metric, RTAX_MTU, link->network->dhcp_route_mtu);
+        if (r < 0)
+                return r;
+        r = route_metric_set(&route->metric, RTAX_INITCWND, link->network->dhcp_initial_congestion_window);
+        if (r < 0)
+                return r;
+        r = route_metric_set(&route->metric, RTAX_INITRWND, link->network->dhcp_advertised_receive_window);
+        if (r < 0)
+                return r;
+        r = route_metric_set(&route->metric, RTAX_QUICKACK, link->network->dhcp_quickack);
+        if (r < 0)
+                return r;
+
+        r = route_adjust_nexthops(route, link);
+        if (r < 0)
+                return r;
+
+        if (route_get(link->manager, route, &existing) < 0) /* This is a new route. */
                 link->dhcp4_configured = false;
         else
                 route_unmark(existing);
 
-        return link_request_route(link, TAKE_PTR(route), true, &link->dhcp4_messages,
-                                  dhcp4_route_handler, NULL);
+        return link_request_route(link, route, &link->dhcp4_messages, dhcp4_route_handler);
 }
 
 static bool link_prefixroute(Link *link) {
@@ -409,7 +410,7 @@ static bool link_prefixroute(Link *link) {
 }
 
 static int dhcp4_request_prefix_route(Link *link) {
-        _cleanup_(route_freep) Route *route = NULL;
+        _cleanup_(route_unrefp) Route *route = NULL;
         int r;
 
         assert(link);
@@ -433,11 +434,11 @@ static int dhcp4_request_prefix_route(Link *link) {
         if (r < 0)
                 return r;
 
-        return dhcp4_request_route(TAKE_PTR(route), link);
+        return dhcp4_request_route(route, link);
 }
 
 static int dhcp4_request_route_to_gateway(Link *link, const struct in_addr *gw) {
-        _cleanup_(route_freep) Route *route = NULL;
+        _cleanup_(route_unrefp) Route *route = NULL;
         struct in_addr address;
         int r;
 
@@ -458,15 +459,14 @@ static int dhcp4_request_route_to_gateway(Link *link, const struct in_addr *gw)
         route->prefsrc.in = address;
         route->scope = RT_SCOPE_LINK;
 
-        return dhcp4_request_route(TAKE_PTR(route), link);
+        return dhcp4_request_route(route, link);
 }
 
 static int dhcp4_request_route_auto(
-                Route *in,
+                Route *route,
                 Link *link,
                 const struct in_addr *gw) {
 
-        _cleanup_(route_freep) Route *route = in;
         struct in_addr address;
         int r;
 
@@ -486,8 +486,8 @@ static int dhcp4_request_route_auto(
                                        IPV4_ADDRESS_FMT_VAL(route->dst.in), route->dst_prefixlen, IPV4_ADDRESS_FMT_VAL(*gw));
 
                 route->scope = RT_SCOPE_HOST;
-                route->gw_family = AF_UNSPEC;
-                route->gw = IN_ADDR_NULL;
+                route->nexthop.family = AF_UNSPEC;
+                route->nexthop.gw = IN_ADDR_NULL;
                 route->prefsrc = IN_ADDR_NULL;
 
         } else if (in4_addr_equal(&route->dst.in, &address)) {
@@ -497,8 +497,8 @@ static int dhcp4_request_route_auto(
                                        IPV4_ADDRESS_FMT_VAL(route->dst.in), route->dst_prefixlen, IPV4_ADDRESS_FMT_VAL(*gw));
 
                 route->scope = RT_SCOPE_HOST;
-                route->gw_family = AF_UNSPEC;
-                route->gw = IN_ADDR_NULL;
+                route->nexthop.family = AF_UNSPEC;
+                route->nexthop.gw = IN_ADDR_NULL;
                 route->prefsrc.in = address;
 
         } else if (in4_addr_is_null(gw)) {
@@ -520,8 +520,8 @@ static int dhcp4_request_route_auto(
                 }
 
                 route->scope = RT_SCOPE_LINK;
-                route->gw_family = AF_UNSPEC;
-                route->gw = IN_ADDR_NULL;
+                route->nexthop.family = AF_UNSPEC;
+                route->nexthop.gw = IN_ADDR_NULL;
                 route->prefsrc.in = address;
 
         } else {
@@ -530,12 +530,12 @@ static int dhcp4_request_route_auto(
                         return r;
 
                 route->scope = RT_SCOPE_UNIVERSE;
-                route->gw_family = AF_INET;
-                route->gw.in = *gw;
+                route->nexthop.family = AF_INET;
+                route->nexthop.gw.in = *gw;
                 route->prefsrc.in = address;
         }
 
-        return dhcp4_request_route(TAKE_PTR(route), link);
+        return dhcp4_request_route(route, link);
 }
 
 static int dhcp4_request_classless_static_or_static_routes(Link *link) {
@@ -556,7 +556,7 @@ static int dhcp4_request_classless_static_or_static_routes(Link *link) {
                 return r;
 
         FOREACH_ARRAY(e, routes, n_routes) {
-                _cleanup_(route_freep) Route *route = NULL;
+                _cleanup_(route_unrefp) Route *route = NULL;
                 struct in_addr gw;
 
                 r = route_new(&route);
@@ -575,7 +575,7 @@ static int dhcp4_request_classless_static_or_static_routes(Link *link) {
                 if (r < 0)
                         return r;
 
-                r = dhcp4_request_route_auto(TAKE_PTR(route), link, &gw);
+                r = dhcp4_request_route_auto(route, link, &gw);
                 if (r < 0)
                         return r;
         }
@@ -584,7 +584,7 @@ static int dhcp4_request_classless_static_or_static_routes(Link *link) {
 }
 
 static int dhcp4_request_default_gateway(Link *link) {
-        _cleanup_(route_freep) Route *route = NULL;
+        _cleanup_(route_unrefp) Route *route = NULL;
         struct in_addr address, router;
         int r;
 
@@ -623,11 +623,11 @@ static int dhcp4_request_default_gateway(Link *link) {
                 return r;
 
         /* Next, add a default gateway. */
-        route->gw_family = AF_INET;
-        route->gw.in = router;
+        route->nexthop.family = AF_INET;
+        route->nexthop.gw.in = router;
         route->prefsrc.in = address;
 
-        return dhcp4_request_route(TAKE_PTR(route), link);
+        return dhcp4_request_route(route, link);
 }
 
 static int dhcp4_request_semi_static_routes(Link *link) {
@@ -639,13 +639,13 @@ static int dhcp4_request_semi_static_routes(Link *link) {
         assert(link->network);
 
         HASHMAP_FOREACH(rt, link->network->routes_by_section) {
-                _cleanup_(route_freep) Route *route = NULL;
+                _cleanup_(route_unrefp) Route *route = NULL;
                 struct in_addr gw;
 
                 if (!rt->gateway_from_dhcp_or_ra)
                         continue;
 
-                if (rt->gw_family != AF_INET)
+                if (rt->nexthop.family != AF_INET)
                         continue;
 
                 assert(rt->family == AF_INET);
@@ -663,13 +663,13 @@ static int dhcp4_request_semi_static_routes(Link *link) {
                 if (r < 0)
                         return r;
 
-                r = route_dup(rt, &route);
+                r = route_dup(rt, NULL, &route);
                 if (r < 0)
                         return r;
 
-                route->gw.in = gw;
+                route->nexthop.gw.in = gw;
 
-                r = dhcp4_request_route(TAKE_PTR(route), link);
+                r = dhcp4_request_route(route, link);
                 if (r < 0)
                         return r;
         }
@@ -690,7 +690,7 @@ static int dhcp4_request_routes_to_servers(
         assert(servers || n_servers == 0);
 
         FOREACH_ARRAY(dst, servers, n_servers) {
-                _cleanup_(route_freep) Route *route = NULL;
+                _cleanup_(route_unrefp) Route *route = NULL;
                 struct in_addr gw;
 
                 if (in4_addr_is_null(dst))
@@ -712,7 +712,7 @@ static int dhcp4_request_routes_to_servers(
                 route->dst.in = *dst;
                 route->dst_prefixlen = 32;
 
-                r = dhcp4_request_route_auto(TAKE_PTR(route), link, &gw);
+                r = dhcp4_request_route_auto(route, link, &gw);
                 if (r < 0)
                         return r;
         }
@@ -835,7 +835,7 @@ static int dhcp_reset_hostname(Link *link) {
 }
 
 int dhcp4_lease_lost(Link *link) {
-        int k, r = 0;
+        int r = 0;
 
         assert(link);
         assert(link->dhcp_lease);
@@ -849,17 +849,9 @@ int dhcp4_lease_lost(Link *link) {
             sd_dhcp_lease_has_6rd(link->dhcp_lease))
                 dhcp4_pd_prefix_lost(link);
 
-        k = dhcp4_remove_address_and_routes(link, /* only_marked = */ false);
-        if (k < 0)
-                r = k;
-
-        k = dhcp_reset_mtu(link);
-        if (k < 0)
-                r = k;
-
-        k = dhcp_reset_hostname(link);
-        if (k < 0)
-                r = k;
+        RET_GATHER(r, dhcp4_remove_address_and_routes(link, /* only_marked = */ false));
+        RET_GATHER(r, dhcp_reset_mtu(link));
+        RET_GATHER(r, dhcp_reset_hostname(link));
 
         link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease);
         link_dirty(link);
@@ -892,7 +884,7 @@ static int dhcp4_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Reques
 }
 
 static int dhcp4_request_address(Link *link, bool announce) {
-        _cleanup_(address_freep) Address *addr = NULL;
+        _cleanup_(address_unrefp) Address *addr = NULL;
         struct in_addr address, server;
         uint8_t prefixlen;
         Address *existing;
@@ -997,7 +989,7 @@ static int dhcp4_request_address_and_routes(Link *link, bool announce) {
         assert(link);
 
         link_mark_addresses(link, NETWORK_CONFIG_SOURCE_DHCP4);
-        link_mark_routes(link, NETWORK_CONFIG_SOURCE_DHCP4);
+        manager_mark_routes(link->manager, link, NETWORK_CONFIG_SOURCE_DHCP4);
 
         r = dhcp4_request_address(link, announce);
         if (r < 0)
@@ -1181,7 +1173,7 @@ static int dhcp4_handler(sd_dhcp_client *client, int event, void *userdata) {
                                 }
 
                                 r = sd_ipv4ll_start(link->ipv4ll);
-                                if (r < 0)
+                                if (r < 0 && r != -ESTALE) /* On exit, we cannot and should not start sd-ipv4ll. */
                                         return log_link_warning_errno(link, r, "Could not acquire IPv4 link-local address: %m");
                         }
 
@@ -1463,10 +1455,12 @@ static bool link_dhcp4_ipv6_only_mode(Link *link) {
         assert(link);
         assert(link->network);
 
+        /* If it is explicitly specified, then honor the setting. */
         if (link->network->dhcp_ipv6_only_mode >= 0)
                 return link->network->dhcp_ipv6_only_mode;
 
-        return link_dhcp6_enabled(link) || link_ipv6_accept_ra_enabled(link);
+        /* Defaults to false, until we support 464XLAT. See issue #30891. */
+        return false;
 }
 
 static int dhcp4_configure(Link *link) {
@@ -1546,7 +1540,7 @@ static int dhcp4_configure(Link *link) {
                                 return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set request flag for classless static route: %m");
                 }
 
-                if (link->network->dhcp_use_domains != DHCP_USE_DOMAINS_NO) {
+                if (link->network->dhcp_use_domains > 0) {
                         r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_DOMAIN_SEARCH);
                         if (r < 0)
                                 return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set request flag for domain search list: %m");
@@ -1640,6 +1634,11 @@ static int dhcp4_configure(Link *link) {
                 if (r < 0)
                         return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set listen port: %m");
         }
+        if (link->network->dhcp_port > 0) {
+                r = sd_dhcp_client_set_port(link->dhcp_client, link->network->dhcp_port);
+                if (r < 0)
+                        return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set server port: %m");
+        }
 
         if (link->network->dhcp_max_attempts > 0) {
                 r = sd_dhcp_client_set_max_attempts(link->dhcp_client, link->network->dhcp_max_attempts);