]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
nspawn: set original ifname as alternative if it is truncated
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sat, 4 Jan 2020 20:35:13 +0000 (05:35 +0900)
committerLennart Poettering <lennart@poettering.net>
Tue, 7 Jan 2020 14:15:59 +0000 (15:15 +0100)
src/libsystemd/sd-netlink/netlink-util.c
src/libsystemd/sd-netlink/netlink-util.h
src/nspawn/nspawn-network.c

index aa10d0c3a42a7eceeab94aa6e2c24500ca426d26..a91db5df5f1f0adbf8bbc406d16a79f7c9128015 100644 (file)
@@ -124,6 +124,49 @@ int rtnl_set_link_alternative_names(sd_netlink **rtnl, int ifindex, char * const
         return 0;
 }
 
+int rtnl_set_link_alternative_names_by_ifname(sd_netlink **rtnl, const char *ifname, char * const *alternative_names) {
+        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL;
+        int r;
+
+        assert(rtnl);
+        assert(ifname);
+
+        if (strv_isempty(alternative_names))
+                return 0;
+
+        if (!*rtnl) {
+                r = sd_netlink_open(rtnl);
+                if (r < 0)
+                        return r;
+        }
+
+        r = sd_rtnl_message_new_link(*rtnl, &message, RTM_NEWLINKPROP, 0);
+        if (r < 0)
+                return r;
+
+        r = sd_netlink_message_append_string(message, IFLA_IFNAME, ifname);
+        if (r < 0)
+                return r;
+
+        r = sd_netlink_message_open_container(message, IFLA_PROP_LIST);
+        if (r < 0)
+                return r;
+
+        r = sd_netlink_message_append_strv(message, IFLA_ALT_IFNAME, alternative_names);
+        if (r < 0)
+                return r;
+
+        r = sd_netlink_message_close_container(message);
+        if (r < 0)
+                return r;
+
+        r = sd_netlink_call(*rtnl, message, 0, NULL);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
 int rtnl_resolve_link_alternative_name(sd_netlink **rtnl, const char *name, int *ret) {
         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL, *reply = NULL;
         int r;
index 1782786841115dde899f58c7471fba2d81542e0e..7b007a61c23ac04ec97f201374f2a71183c4c862 100644 (file)
@@ -50,6 +50,7 @@ static inline bool rtnl_message_type_is_qdisc(uint16_t type) {
 int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name);
 int rtnl_set_link_properties(sd_netlink **rtnl, int ifindex, const char *alias, const struct ether_addr *mac, uint32_t mtu);
 int rtnl_set_link_alternative_names(sd_netlink **rtnl, int ifindex, char * const *alternative_names);
+int rtnl_set_link_alternative_names_by_ifname(sd_netlink **rtnl, const char *ifname, char * const *alternative_names);
 int rtnl_resolve_link_alternative_name(sd_netlink **rtnl, const char *name, int *ret);
 
 int rtnl_log_parse_error(int r);
index e91a9d36bf334302db28ae72d241cfea5c31c614..9c9cf4812e8f2cb8a0fea709dcefd443c89c5f7e 100644 (file)
@@ -1,5 +1,7 @@
 /* SPDX-License-Identifier: LGPL-2.1+ */
 
+#include <net/if.h>
+#include <linux/if.h>
 #include <linux/veth.h>
 #include <sys/file.h>
 
@@ -99,10 +101,34 @@ static int generate_mac(
         return 0;
 }
 
+static int set_alternative_ifname(sd_netlink *rtnl, const char *ifname, const char *altifname) {
+        int r;
+
+        assert(rtnl);
+        assert(ifname);
+
+        if (!altifname)
+                return 0;
+
+        if (strlen(altifname) >= ALTIFNAMSIZ)
+                return log_warning_errno(SYNTHETIC_ERRNO(ERANGE),
+                                         "Alternative interface name '%s' for '%s' is too long, ignoring",
+                                         altifname, ifname);
+
+        r = rtnl_set_link_alternative_names_by_ifname(&rtnl, ifname, STRV_MAKE(altifname));
+        if (r < 0)
+                return log_warning_errno(r,
+                                         "Failed to set alternative interface name '%s' to '%s', ignoring: %m",
+                                         altifname, ifname);
+
+        return 0;
+}
+
 static int add_veth(
                 sd_netlink *rtnl,
                 pid_t pid,
                 const char *ifname_host,
+                const char *altifname_host,
                 const struct ether_addr *mac_host,
                 const char *ifname_container,
                 const struct ether_addr *mac_container) {
@@ -168,6 +194,8 @@ static int add_veth(
         if (r < 0)
                 return log_error_errno(r, "Failed to add new veth interfaces (%s:%s): %m", ifname_host, ifname_container);
 
+        (void) set_alternative_ifname(rtnl, ifname_host, altifname_host);
+
         return 0;
 }
 
@@ -181,13 +209,13 @@ static char urlsafe_base64char(int x) {
         return table[x & 63];
 }
 
-static void shorten_ifname(char *ifname) {
+static int shorten_ifname(char *ifname) {
         char new_ifname[IFNAMSIZ];
 
         assert(ifname);
 
         if (strlen(ifname) < IFNAMSIZ) /* Name is short enough */
-                return;
+                return 0;
 
         if (naming_scheme_has(NAMING_NSPAWN_LONG_HASH)) {
                 uint64_t h;
@@ -211,6 +239,7 @@ static void shorten_ifname(char *ifname) {
         log_warning("Network interface name '%s' has been changed to '%s' to fit length constraints.", ifname, new_ifname);
 
         strcpy(ifname, new_ifname);
+        return 1;
 }
 
 int setup_veth(const char *machine_name,
@@ -221,7 +250,7 @@ int setup_veth(const char *machine_name,
         _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
         struct ether_addr mac_host, mac_container;
         unsigned u;
-        char *n;
+        char *n, *a = NULL;
         int r;
 
         assert(machine_name);
@@ -231,7 +260,9 @@ int setup_veth(const char *machine_name,
         /* Use two different interface name prefixes depending whether
          * we are in bridge mode or not. */
         n = strjoina(bridge ? "vb-" : "ve-", machine_name);
-        shorten_ifname(n);
+        r = shorten_ifname(n);
+        if (r > 0)
+                a = strjoina(bridge ? "vb-" : "ve-", machine_name);
 
         r = generate_mac(machine_name, &mac_container, CONTAINER_HASH_KEY, 0);
         if (r < 0)
@@ -245,7 +276,7 @@ int setup_veth(const char *machine_name,
         if (r < 0)
                 return log_error_errno(r, "Failed to connect to netlink: %m");
 
-        r = add_veth(rtnl, pid, n, &mac_host, "host0", &mac_container);
+        r = add_veth(rtnl, pid, n, a, &mac_host, "host0", &mac_container);
         if (r < 0)
                 return r;
 
@@ -288,7 +319,7 @@ int setup_veth_extra(
                 if (r < 0)
                         return log_error_errno(r, "Failed to generate predictable MAC address for container side of extra veth link: %m");
 
-                r = add_veth(rtnl, pid, *a, &mac_host, *b, &mac_container);
+                r = add_veth(rtnl, pid, *a, NULL, &mac_host, *b, &mac_container);
                 if (r < 0)
                         return r;
 
@@ -536,7 +567,7 @@ int setup_macvlan(const char *machine_name, pid_t pid, char **ifaces) {
 
         STRV_FOREACH(i, ifaces) {
                 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
-                _cleanup_free_ char *n = NULL;
+                _cleanup_free_ char *n = NULL, *a = NULL;
                 struct ether_addr mac;
                 int ifi;
 
@@ -560,7 +591,12 @@ int setup_macvlan(const char *machine_name, pid_t pid, char **ifaces) {
                 if (!n)
                         return log_oom();
 
-                shorten_ifname(n);
+                r = shorten_ifname(n);
+                if (r > 0) {
+                        a = strjoin("mv-", *i);
+                        if (!a)
+                                return log_oom();
+                }
 
                 r = sd_netlink_message_append_string(m, IFLA_IFNAME, n);
                 if (r < 0)
@@ -597,6 +633,8 @@ int setup_macvlan(const char *machine_name, pid_t pid, char **ifaces) {
                 r = sd_netlink_call(rtnl, m, 0, NULL);
                 if (r < 0)
                         return log_error_errno(r, "Failed to add new macvlan interfaces: %m");
+
+                (void) set_alternative_ifname(rtnl, n, a);
         }
 
         return 0;
@@ -616,7 +654,7 @@ int setup_ipvlan(const char *machine_name, pid_t pid, char **ifaces) {
 
         STRV_FOREACH(i, ifaces) {
                 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
-                _cleanup_free_ char *n = NULL;
+                _cleanup_free_ char *n = NULL, *a = NULL;
                 int ifi;
 
                 ifi = parse_interface(*i);
@@ -635,7 +673,12 @@ int setup_ipvlan(const char *machine_name, pid_t pid, char **ifaces) {
                 if (!n)
                         return log_oom();
 
-                shorten_ifname(n);
+                r = shorten_ifname(n);
+                if (r > 0) {
+                        a = strjoin("iv-", *i);
+                        if (!a)
+                                return log_oom();
+                }
 
                 r = sd_netlink_message_append_string(m, IFLA_IFNAME, n);
                 if (r < 0)
@@ -668,6 +711,8 @@ int setup_ipvlan(const char *machine_name, pid_t pid, char **ifaces) {
                 r = sd_netlink_call(rtnl, m, 0, NULL);
                 if (r < 0)
                         return log_error_errno(r, "Failed to add new ipvlan interfaces: %m");
+
+                (void) set_alternative_ifname(rtnl, n, a);
         }
 
         return 0;