From 582a1e187701b02ab3ed948dc452f1387848c788 Mon Sep 17 00:00:00 2001 From: Sebastian Gross Date: Fri, 26 Sep 2025 11:14:30 +0200 Subject: [PATCH] network-generator: ip: do not fail on ntp value 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 | 39 +++++++++++++++- src/network/generator/network-generator.h | 1 + .../generator/test-network-generator.c | 45 +++++++++++++++++++ 3 files changed, 84 insertions(+), 1 deletion(-) diff --git a/src/network/generator/network-generator.c b/src/network/generator/network-generator.c index dcb8bb3cd3b..0988aef93f1 100644 --- a/src/network/generator/network-generator.c +++ b/src/network/generator/network-generator.c @@ -21,7 +21,7 @@ ip={dhcp|on|any|dhcp6|auto6|either6|link6|link-local} ip=:{dhcp|on|any|dhcp6|auto6|link6|link-local}[:[][:]] ip=:[]:::::{none|off|dhcp|on|any|dhcp6|auto6|link6|ibft|link-local}[:[][:]] - ip=:[]:::::{none|off|dhcp|on|any|dhcp6|auto6|link6|ibft|link-local}[:[][:]] + ip=:[]:::::{none|off|dhcp|on|any|dhcp6|auto6|link6|ibft|link-local}[:[][:[][:[]]]] rd.route=/:[:] nameserver= [nameserver= ...] 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 [:] */ + _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)) diff --git a/src/network/generator/network-generator.h b/src/network/generator/network-generator.h index f2fdd02808c..e40aa42ff7e 100644 --- a/src/network/generator/network-generator.h +++ b/src/network/generator/network-generator.h @@ -65,6 +65,7 @@ struct Network { char **vlan; char *bridge; char *bond; + char *ntp; /* [DHCP] */ char *hostname; diff --git a/src/network/generator/test-network-generator.c b/src/network/generator/test-network-generator.c index d709fa26ff7..ff218775534 100644 --- a/src/network/generator/test-network-generator.c +++ b/src/network/generator/test-network-generator.c @@ -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" -- 2.47.3