]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network-generator: ip: do not fail on ntp value
authorSebastian Gross <sgross@emlix.com>
Fri, 26 Sep 2025 09:14:30 +0000 (11:14 +0200)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 26 Sep 2025 12:11:11 +0000 (21:11 +0900)
linux https://www.kernel.org/doc/html/latest/admin-guide/nfs/nfsroot.html
states `ntp0-ip` as parameter to `ip=` command line.

Until now systemd-network-generator would fail if ntp was provided with
-EINVAL due to trailing arguments.

Stay in line with kernel doc and handle ntp value properly.

src/network/generator/network-generator.c
src/network/generator/network-generator.h
src/network/generator/test-network-generator.c

index dcb8bb3cd3bb85eb59cbbe7cceacf2bdec3715bc..0988aef93f14bc4aac0f73fb818b3b7c6d40d91f 100644 (file)
@@ -21,7 +21,7 @@
   ip={dhcp|on|any|dhcp6|auto6|either6|link6|link-local}
   ip=<interface>:{dhcp|on|any|dhcp6|auto6|link6|link-local}[:[<mtu>][:<macaddr>]]
   ip=<client-IP>:[<peer>]:<gateway-IP>:<netmask>:<client_hostname>:<interface>:{none|off|dhcp|on|any|dhcp6|auto6|link6|ibft|link-local}[:[<mtu>][:<macaddr>]]
-  ip=<client-IP>:[<peer>]:<gateway-IP>:<netmask>:<client_hostname>:<interface>:{none|off|dhcp|on|any|dhcp6|auto6|link6|ibft|link-local}[:[<dns1>][:<dns2>]]
+  ip=<client-IP>:[<peer>]:<gateway-IP>:<netmask>:<client_hostname>:<interface>:{none|off|dhcp|on|any|dhcp6|auto6|link6|ibft|link-local}[:[<dns1>][:[<dns2>][:[<ntp>]]]]
   rd.route=<net>/<netmask>:<gateway>[:<interface>]
   nameserver=<IP> [nameserver=<IP> ...]
   rd.peerdns=0
@@ -197,6 +197,7 @@ static Network* network_free(Network *network) {
         strv_free(network->vlan);
         free(network->bridge);
         free(network->bond);
+        free(network->ntp);
 
         while ((address = network->addresses))
                 address_free(address);
@@ -650,6 +651,27 @@ static int network_set_bond(Context *context, const char *ifname, const char *va
         return free_and_strdup(&network->bond, value);
 }
 
+static int network_set_ntp(Context *context, const char *ifname, const char *value) {
+        Network *network;
+        int r;
+
+        assert(context);
+        assert(ifname);
+
+        if (isempty(value))
+                return 0;
+
+        r = in_addr_from_string_auto(value, NULL, NULL);
+        if (r < 0)
+                return log_debug_errno(r, "Invalid NTP address '%s' for '%s'", value, ifname);
+
+        r = network_acquire(context, ifname, &network);
+        if (r < 0)
+                return log_debug_errno(r, "Failed to acquire network for '%s': %m", ifname);
+
+        return free_and_strdup(&network->ntp, value);
+}
+
 static int parse_cmdline_ip_mtu_mac(Context *context, const char *ifname, const char *value) {
         _cleanup_free_ char *mtu = NULL;
         int r;
@@ -865,6 +887,18 @@ static int parse_cmdline_ip_address(Context *context, int family, const char *va
         if (r < 0)
                 return r;
 
+        /* Next, try [:<ntp>] */
+        _cleanup_free_ char *ntp = NULL;
+        r = extract_ip_address_str(AF_UNSPEC, &p, &ntp);
+        if (r < 0)
+                return log_debug_errno(r, "Failed to parse NTP address in ip=%s: %m", value);
+        if (r == 0)
+                return 0;
+
+        r = network_set_ntp(context, ifname, ntp);
+        if (r < 0)
+                return r;
+
         /* refuse unexpected trailing strings */
         if (!isempty(p))
                 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Unexpected trailing string in 'ip=%s'.", value);
@@ -1373,6 +1407,9 @@ void network_dump(Network *network, FILE *f) {
         if (network->bond)
                 fprintf(f, "Bond=%s\n", network->bond);
 
+        if (network->ntp)
+                fprintf(f, "NTP=%s\n", network->ntp);
+
         fputs("\n[DHCP]\n", f);
 
         if (!isempty(network->hostname))
index f2fdd02808c3c4d3273bdcf6f2a96bd53afcf6b3..e40aa42ff7e2763f6fbf24495c60990028132991 100644 (file)
@@ -65,6 +65,7 @@ struct Network {
         char **vlan;
         char *bridge;
         char *bond;
+        char *ntp;
 
         /* [DHCP] */
         char *hostname;
index d709fa26ff7cedf40f6ebc36077f4f2e688a7721..ff2187755345b032837b28883a92eea74d32fab9 100644 (file)
@@ -213,6 +213,51 @@ int main(int argc, char *argv[]) {
                          "Gateway=192.168.0.1\n"
                          );
 
+        test_network_one("eth0", "ip", "192.168.0.10::192.168.0.1:255.255.255.0::eth0:on:10.10.10.10:10.10.10.11:10.10.10.161",
+                         "[Match]\n"
+                         "Name=eth0\n"
+                         "\n[Link]\n"
+                         "\n[Network]\n"
+                         "DHCP=yes\n"
+                         "DNS=10.10.10.10\n"
+                         "DNS=10.10.10.11\n"
+                         "NTP=10.10.10.161\n"
+                         "\n[DHCP]\n"
+                         "\n[Address]\n"
+                         "Address=192.168.0.10/24\n"
+                         "\n[Route]\n"
+                         "Gateway=192.168.0.1\n"
+                         );
+
+        test_network_one("eth0", "ip", "192.168.0.10::192.168.0.1:255.255.255.0::eth0:on:10.10.10.10::10.10.10.161",
+                         "[Match]\n"
+                         "Name=eth0\n"
+                         "\n[Link]\n"
+                         "\n[Network]\n"
+                         "DHCP=yes\n"
+                         "DNS=10.10.10.10\n"
+                         "NTP=10.10.10.161\n"
+                         "\n[DHCP]\n"
+                         "\n[Address]\n"
+                         "Address=192.168.0.10/24\n"
+                         "\n[Route]\n"
+                         "Gateway=192.168.0.1\n"
+                         );
+
+        test_network_one("eth0", "ip", "192.168.0.10::192.168.0.1:255.255.255.0::eth0:on:::10.10.10.161",
+                         "[Match]\n"
+                         "Name=eth0\n"
+                         "\n[Link]\n"
+                         "\n[Network]\n"
+                         "DHCP=yes\n"
+                         "NTP=10.10.10.161\n"
+                         "\n[DHCP]\n"
+                         "\n[Address]\n"
+                         "Address=192.168.0.10/24\n"
+                         "\n[Route]\n"
+                         "Gateway=192.168.0.1\n"
+                         );
+
         test_network_one("eth0", "ip", "[2001:1234:56:8f63::10]::[2001:1234:56:8f63::1]:64:hogehoge:eth0:on",
                          "[Match]\n"
                          "Name=eth0\n"