]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
nspawn,shared/netif-util: move generate_mac and shorten_ifname to shared/netif-util
authorSam Leonard <sam.leonard@codethink.co.uk>
Mon, 15 Apr 2024 08:33:10 +0000 (09:33 +0100)
committerSam Leonard <sam.leonard@codethink.co.uk>
Mon, 15 Apr 2024 10:42:05 +0000 (11:42 +0100)
src/nspawn/nspawn-network.c
src/shared/netif-util.c
src/shared/netif-util.h

index 1e804a2be3c8f63d40e6d84e568932aedcdc1a32..ec5d39690e484b9df0e49c999bbbe2fba0658852 100644 (file)
@@ -24,6 +24,7 @@
 #include "mount-util.h"
 #include "namespace-util.h"
 #include "netif-naming-scheme.h"
+#include "netif-util.h"
 #include "netlink-util.h"
 #include "nspawn-network.h"
 #include "parse-util.h"
@@ -41,7 +42,6 @@
 #define VETH_EXTRA_HOST_HASH_KEY SD_ID128_MAKE(48,c7,f6,b7,ea,9d,4c,9e,b7,28,d4,de,91,d5,bf,66)
 #define VETH_EXTRA_CONTAINER_HASH_KEY SD_ID128_MAKE(af,50,17,61,ce,f9,4d,35,84,0d,2b,20,54,be,ce,59)
 #define MACVLAN_HASH_KEY SD_ID128_MAKE(00,13,6d,bc,66,83,44,81,bb,0c,f9,51,1f,24,a6,6f)
-#define SHORTEN_IFNAME_HASH_KEY SD_ID128_MAKE(e1,90,a4,04,a8,ef,4b,51,8c,cc,c3,3a,9f,11,fc,a2)
 
 static int remove_one_link(sd_netlink *rtnl, const char *name) {
         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
@@ -67,49 +67,6 @@ static int remove_one_link(sd_netlink *rtnl, const char *name) {
         return 1;
 }
 
-static int generate_mac(
-                const char *machine_name,
-                struct ether_addr *mac,
-                sd_id128_t hash_key,
-                uint64_t idx) {
-
-        uint64_t result;
-        size_t l, sz;
-        uint8_t *v, *i;
-        int r;
-
-        l = strlen(machine_name);
-        sz = sizeof(sd_id128_t) + l;
-        if (idx > 0)
-                sz += sizeof(idx);
-
-        v = newa(uint8_t, sz);
-
-        /* fetch some persistent data unique to the host */
-        r = sd_id128_get_machine((sd_id128_t*) v);
-        if (r < 0)
-                return r;
-
-        /* combine with some data unique (on this host) to this
-         * container instance */
-        i = mempcpy(v + sizeof(sd_id128_t), machine_name, l);
-        if (idx > 0) {
-                idx = htole64(idx);
-                memcpy(i, &idx, sizeof(idx));
-        }
-
-        /* Let's hash the host machine ID plus the container name. We
-         * use a fixed, but originally randomly created hash key here. */
-        result = htole64(siphash24(v, sz, hash_key.bytes));
-
-        assert_cc(ETH_ALEN <= sizeof(result));
-        memcpy(mac->ether_addr_octet, &result, ETH_ALEN);
-
-        ether_addr_mark_random(mac);
-
-        return 0;
-}
-
 static int set_alternative_ifname(sd_netlink *rtnl, const char *ifname, const char *altifname) {
         int r;
 
@@ -208,39 +165,6 @@ static int add_veth(
         return 0;
 }
 
-static int shorten_ifname(char *ifname) {
-        char new_ifname[IFNAMSIZ];
-
-        assert(ifname);
-
-        if (strlen(ifname) < IFNAMSIZ) /* Name is short enough */
-                return 0;
-
-        if (naming_scheme_has(NAMING_NSPAWN_LONG_HASH)) {
-                uint64_t h;
-
-                /* Calculate 64-bit hash value */
-                h = siphash24(ifname, strlen(ifname), SHORTEN_IFNAME_HASH_KEY.bytes);
-
-                /* Set the final four bytes (i.e. 32-bit) to the lower 24bit of the hash, encoded in url-safe base64 */
-                memcpy(new_ifname, ifname, IFNAMSIZ - 5);
-                new_ifname[IFNAMSIZ - 5] = urlsafe_base64char(h >> 18);
-                new_ifname[IFNAMSIZ - 4] = urlsafe_base64char(h >> 12);
-                new_ifname[IFNAMSIZ - 3] = urlsafe_base64char(h >> 6);
-                new_ifname[IFNAMSIZ - 2] = urlsafe_base64char(h);
-        } else
-                /* On old nspawn versions we just truncated the name, provide compatibility */
-                memcpy(new_ifname, ifname, IFNAMSIZ-1);
-
-        new_ifname[IFNAMSIZ - 1] = 0;
-
-        /* Log the incident to make it more discoverable */
-        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,
                pid_t pid,
                char iface_name[IFNAMSIZ],
@@ -260,18 +184,18 @@ 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);
-        r = shorten_ifname(n);
+        r = net_shorten_ifname(n, /* check_naming_scheme= */ true);
         if (r > 0)
                 a = strjoina(bridge ? "vb-" : "ve-", machine_name);
 
         if (ether_addr_is_null(provided_mac)){
-                r = generate_mac(machine_name, &mac_container, CONTAINER_HASH_KEY, 0);
+                r = net_generate_mac(machine_name, &mac_container, CONTAINER_HASH_KEY, 0);
                 if (r < 0)
                         return log_error_errno(r, "Failed to generate predictable MAC address for container side: %m");
         } else
                 mac_container = *provided_mac;
 
-        r = generate_mac(machine_name, &mac_host, HOST_HASH_KEY, 0);
+        r = net_generate_mac(machine_name, &mac_host, HOST_HASH_KEY, 0);
         if (r < 0)
                 return log_error_errno(r, "Failed to generate predictable MAC address for host side: %m");
 
@@ -314,11 +238,11 @@ int setup_veth_extra(
         STRV_FOREACH_PAIR(a, b, pairs) {
                 struct ether_addr mac_host, mac_container;
 
-                r = generate_mac(machine_name, &mac_container, VETH_EXTRA_CONTAINER_HASH_KEY, idx);
+                r = net_generate_mac(machine_name, &mac_container, VETH_EXTRA_CONTAINER_HASH_KEY, idx);
                 if (r < 0)
                         return log_error_errno(r, "Failed to generate predictable MAC address for container side of extra veth link: %m");
 
-                r = generate_mac(machine_name, &mac_host, VETH_EXTRA_HOST_HASH_KEY, idx);
+                r = net_generate_mac(machine_name, &mac_host, VETH_EXTRA_HOST_HASH_KEY, idx);
                 if (r < 0)
                         return log_error_errno(r, "Failed to generate predictable MAC address for host side of extra veth link: %m");
 
@@ -836,7 +760,7 @@ int setup_macvlan(const char *machine_name, pid_t pid, char **iface_pairs) {
                 if (ifi < 0)
                         return ifi;
 
-                r = generate_mac(machine_name, &mac, MACVLAN_HASH_KEY, idx++);
+                r = net_generate_mac(machine_name, &mac, MACVLAN_HASH_KEY, idx++);
                 if (r < 0)
                         return log_error_errno(r, "Failed to create MACVLAN MAC address: %m");
 
@@ -852,7 +776,7 @@ int setup_macvlan(const char *machine_name, pid_t pid, char **iface_pairs) {
                 if (!n)
                         return log_oom();
 
-                shortened = shorten_ifname(n);
+                shortened = net_shorten_ifname(n, /* check_naming_scheme= */ true);
 
                 r = sd_netlink_message_append_string(m, IFLA_IFNAME, n);
                 if (r < 0)
@@ -929,7 +853,7 @@ int setup_ipvlan(const char *machine_name, pid_t pid, char **iface_pairs) {
                 if (!n)
                         return log_oom();
 
-                shortened = shorten_ifname(n);
+                shortened = net_shorten_ifname(n, /* check_naming_scheme= */ true);
 
                 r = sd_netlink_message_append_string(m, IFLA_IFNAME, n);
                 if (r < 0)
index c9a14b4739bef8101a408403d06cd54c27c93af4..8adc2c89c8141281b89890e42bc32affbc2bcfaa 100644 (file)
@@ -5,13 +5,17 @@
 
 #include "arphrd-util.h"
 #include "device-util.h"
+#include "hexdecoct.h"
 #include "log-link.h"
 #include "memory-util.h"
+#include "netif-naming-scheme.h"
 #include "netif-util.h"
 #include "siphash24.h"
 #include "sparse-endian.h"
 #include "strv.h"
 
+#define SHORTEN_IFNAME_HASH_KEY SD_ID128_MAKE(e1,90,a4,04,a8,ef,4b,51,8c,cc,c3,3a,9f,11,fc,a2)
+
 bool netif_has_carrier(uint8_t operstate, unsigned flags) {
         /* see Documentation/networking/operstates.txt in the kernel sources */
 
@@ -198,3 +202,79 @@ int net_verify_hardware_address(
 
         return 0;
 }
+
+int net_generate_mac(
+                const char *machine_name,
+                struct ether_addr *mac,
+                sd_id128_t hash_key,
+                uint64_t idx) {
+
+        uint64_t result;
+        size_t l, sz;
+        uint8_t *v, *i;
+        int r;
+
+        l = strlen(machine_name);
+        sz = sizeof(sd_id128_t) + l;
+        if (idx > 0)
+                sz += sizeof(idx);
+
+        v = newa(uint8_t, sz);
+
+        /* fetch some persistent data unique to the host */
+        r = sd_id128_get_machine((sd_id128_t*) v);
+        if (r < 0)
+                return r;
+
+        /* combine with some data unique (on this host) to this
+         * container instance */
+        i = mempcpy(v + sizeof(sd_id128_t), machine_name, l);
+        if (idx > 0) {
+                idx = htole64(idx);
+                memcpy(i, &idx, sizeof(idx));
+        }
+
+        /* Let's hash the host machine ID plus the container name. We
+         * use a fixed, but originally randomly created hash key here. */
+        result = htole64(siphash24(v, sz, hash_key.bytes));
+
+        assert_cc(ETH_ALEN <= sizeof(result));
+        memcpy(mac->ether_addr_octet, &result, ETH_ALEN);
+
+        ether_addr_mark_random(mac);
+
+        return 0;
+}
+
+int net_shorten_ifname(char *ifname, bool check_naming_scheme) {
+        char new_ifname[IFNAMSIZ];
+
+        assert(ifname);
+
+        if (strlen(ifname) < IFNAMSIZ) /* Name is short enough */
+                return 0;
+
+        if (!check_naming_scheme || naming_scheme_has(NAMING_NSPAWN_LONG_HASH)) {
+                uint64_t h;
+
+                /* Calculate 64-bit hash value */
+                h = siphash24(ifname, strlen(ifname), SHORTEN_IFNAME_HASH_KEY.bytes);
+
+                /* Set the final four bytes (i.e. 32-bit) to the lower 24bit of the hash, encoded in url-safe base64 */
+                memcpy(new_ifname, ifname, IFNAMSIZ - 5);
+                new_ifname[IFNAMSIZ - 5] = urlsafe_base64char(h >> 18);
+                new_ifname[IFNAMSIZ - 4] = urlsafe_base64char(h >> 12);
+                new_ifname[IFNAMSIZ - 3] = urlsafe_base64char(h >> 6);
+                new_ifname[IFNAMSIZ - 2] = urlsafe_base64char(h);
+        } else
+                /* On old nspawn versions we just truncated the name, provide compatibility */
+                memcpy(new_ifname, ifname, IFNAMSIZ-1);
+
+        new_ifname[IFNAMSIZ - 1] = 0;
+
+        /* Log the incident to make it more discoverable */
+        log_warning("Network interface name '%s' has been changed to '%s' to fit length constraints.", ifname, new_ifname);
+
+        strcpy(ifname, new_ifname);
+        return 1;
+}
index fb6a27cce151783f0244dc276a67294fbd56ae34..02c531e2712493fda44a3ff8d97cc273aba234c8 100644 (file)
@@ -20,3 +20,9 @@ int net_verify_hardware_address(
                 uint16_t iftype,
                 const struct hw_addr_data *ib_hw_addr,
                 struct hw_addr_data *new_hw_addr);
+int net_generate_mac(
+                const char *machine_name,
+                struct ether_addr *mac,
+                sd_id128_t hash_key,
+                uint64_t idx);
+int net_shorten_ifname(char *ifname, bool check_naming_scheme);