]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network/dhcp4: Gateway=_dhcp4 also assign DHCP address as preferred source
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 26 Jan 2025 22:07:55 +0000 (07:07 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 26 Jan 2025 23:38:24 +0000 (08:38 +0900)
With the following, now preferred source address is set to the DHCP
address.
====
[Route]
Gatewa=_dhcp4
Table=100
====

Before:
====
$ ip route show table 100 default
default via 192.168.0.1 dev eth0 proto dhcp metric 1024
====

After:
====
$ ip route show table 100 default
default via 192.168.0.1 dev eth0 proto dhcp src 192.168.0.100 metric 1024
====

To avoid the assignment, this also introduces PreferredSource=no.

man/systemd.network.xml
src/network/networkd-dhcp4.c
src/network/networkd-route.c
src/network/networkd-route.h

index 126accaca9ba822e18e7dad22c2338b01a3885e5..186c0250b288885fe5ae3a563bddaf763a53c658 100644 (file)
@@ -2010,8 +2010,10 @@ NFTSet=prefix:netdev:filter:eth_ipv4_prefix</programlisting>
         <term><varname>Gateway=</varname></term>
         <listitem>
           <para>Takes the gateway address or the special values <literal>_dhcp4</literal> and
-          <literal>_ipv6ra</literal>. If <literal>_dhcp4</literal> or <literal>_ipv6ra</literal> is
-          set, then the gateway address provided by DHCPv4 or IPv6 RA is used.</para>
+          <literal>_ipv6ra</literal>. If <literal>_dhcp4</literal> or <literal>_ipv6ra</literal> is set, then
+          the gateway address provided by DHCPv4 or IPv6 RA is used. When<literal>_dhcp4</literal>, the
+          acquired DHCPv4 address will be used as the preferred source address of the route, unless it is
+          explicitly configured in <varname>PreferredSource=</varname>.</para>
 
         <xi:include href="version-info.xml" xpointer="v211"/>
         </listitem>
@@ -2117,10 +2119,12 @@ NFTSet=prefix:netdev:filter:eth_ipv4_prefix</programlisting>
       <varlistentry>
         <term><varname>PreferredSource=</varname></term>
         <listitem>
-          <para>The preferred source address of the route. The address must be in the format described
-          in
+          <para>The preferred source address of the route. Takes <literal>no</literal> or an address
+          in the format described in
           <citerefentry project='man-pages'><refentrytitle>inet_pton</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
-          </para>
+          If <varname>Gateway=_dhcp4</varname> is specified, defaults to the acquired DHCPv4 address.
+          Otherwise, defaults to unset. The value <literal>no</literal> may be useful to configure a route
+          with <varname>Gateway=_dhcp4</varname> without setting preferred source route address.</para>
 
           <xi:include href="version-info.xml" xpointer="v227"/>
         </listitem>
index 949f08cf53f36a5bad050d2fea12a3d39be27041..926e769258b30c2e767a7a6dc7dd9986dd4e54a7 100644 (file)
@@ -681,6 +681,12 @@ static int dhcp4_request_semi_static_routes(Link *link) {
 
                 route->nexthop.gw.in = gw;
 
+                if (!route->prefsrc_set) {
+                        r = sd_dhcp_lease_get_address(link->dhcp_lease, &route->prefsrc.in);
+                        if (r < 0)
+                                return r;
+                }
+
                 r = dhcp4_request_prefix_route(link, route);
                 if (r < 0)
                         return r;
index ff93c1d27de08403298133bc7ae58d8eff9f568c..e41b4c31be1095295f1758499e6de0a83f79c0f4 100644 (file)
@@ -1663,7 +1663,19 @@ static int config_parse_preferred_src(
         Route *route = ASSERT_PTR(userdata);
         int r;
 
-        assert(rvalue);
+        if (isempty(rvalue)) {
+                route->prefsrc_set = false;
+                route->prefsrc = IN_ADDR_NULL;
+                return 1;
+        }
+
+        r = parse_boolean(rvalue);
+        if (r == 0) {
+                /* Accepts only no. That prohibits prefsrc set by DHCP lease. */
+                route->prefsrc_set = true;
+                route->prefsrc = IN_ADDR_NULL;
+                return 1;
+        }
 
         if (route->family == AF_UNSPEC)
                 r = in_addr_from_string_auto(rvalue, &route->family, &route->prefsrc);
@@ -1672,6 +1684,7 @@ static int config_parse_preferred_src(
         if (r < 0)
                 return log_syntax_parse_error(unit, filename, line, r, lvalue, rvalue);
 
+        route->prefsrc_set = true;
         return 1;
 }
 
index b9d2dbf9a6f91adb0812dd8fad335aa7695c8931..46bbe2899e025d98ec4a2f710ced882897065aa2 100644 (file)
@@ -71,6 +71,7 @@ struct Route {
         bool expiration_managed_by_kernel:1; /* RTA_CACHEINFO has nonzero rta_expires */
 
         /* Only used by conf persers and route_section_verify(). */
+        bool prefsrc_set:1;
         bool scope_set:1;
         bool table_set:1;
         bool priority_set:1;