]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
nspawn: correctly parse a list of interfaces
authorFrantisek Sumsal <frantisek@sumsal.cz>
Thu, 18 May 2023 10:54:15 +0000 (12:54 +0200)
committerFrantisek Sumsal <frantisek@sumsal.cz>
Thu, 18 May 2023 14:50:24 +0000 (16:50 +0200)
Interface=/MACVLAN=/IPVLAN= nspawn options take a _list_ of interface
names - this was recently enhanced by 2f091b1b49 to support interface
pairs. Unfortunately, this also introduced a regression where we don't
parse the list as a list, but just as a single value. For example,
having `Interface=sd-shared1 sd-shared2` in an nspawn config file would
throw:

systemd-nspawn[898]: Network interface, interface name not valid: sd-shared1 sd-shared2
systemd-nspawn[898]: /run/systemd/nspawn/testsuite-13.nspawn-settings.1po.nspawn:41: Failed to parse file: Invalid argument

Follow-up to 2f091b1b49.

src/nspawn/nspawn-network.c

index d898f0d4c911803a122cd50c471444fd1f1e00cb..b1c4f1cad8e4dba8563e7abcf8f0838395ff120d 100644 (file)
@@ -752,38 +752,48 @@ int remove_veth_links(const char *primary, char **pairs) {
 }
 
 static int network_iface_pair_parse(const char* iftype, char ***l, const char *p, const char* ifprefix) {
-        _cleanup_free_ char *a = NULL, *b = NULL;
         int r;
 
-        r = extract_first_word(&p, &a, ":", EXTRACT_DONT_COALESCE_SEPARATORS);
-        if (r < 0)
-                return log_error_errno(r, "Failed to extract first word in %s parameter: %m", iftype);
-        if (r == 0)
-                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
-                                       "Short read while reading %s parameter: %m", iftype);
-        if (!ifname_valid(a))
-                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
-                                       "%s, interface name not valid: %s", iftype, a);
-
-        if (isempty(p)) {
-                if (ifprefix)
-                        b = strjoin(ifprefix, a);
-                else
-                        b = strdup(a);
-        } else
-                b = strdup(p);
-        if (!b)
-                return log_oom();
+        for (;;) {
+                _cleanup_free_ char *word = NULL, *a = NULL, *b = NULL;
+                const char *interface;
 
-        if (!ifname_valid(b))
-                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
-                        "%s, interface name not valid: %s", iftype, b);
+                r = extract_first_word(&p, &word, NULL, 0);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to parse interface name: %m");
+                if (r == 0)
+                        break;
 
-        r = strv_push_pair(l, a, b);
-        if (r < 0)
-                return log_oom();
+                interface = word;
+                r = extract_first_word(&interface, &a, ":", EXTRACT_DONT_COALESCE_SEPARATORS);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to extract first word in %s parameter: %m", iftype);
+                if (r == 0)
+                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+                                               "Short read while reading %s parameter: %m", iftype);
+                if (!ifname_valid(a))
+                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+                                               "%s, interface name not valid: %s", iftype, a);
+
+                if (isempty(interface)) {
+                        if (ifprefix)
+                                b = strjoin(ifprefix, a);
+                        else
+                                b = strdup(a);
+                } else
+                        b = strdup(interface);
+                if (!b)
+                        return log_oom();
+
+                if (!ifname_valid(b))
+                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+                                               "%s, interface name not valid: %s", iftype, b);
+
+                r = strv_consume_pair(l, TAKE_PTR(a), TAKE_PTR(b));
+                if (r < 0)
+                        return log_oom();
+        }
 
-        a = b = NULL;
         return 0;
 }