[systemd-commits] src/nspawn
Tom Gundersen
tomegun at kemper.freedesktop.org
Thu Mar 13 09:49:39 PDT 2014
src/nspawn/nspawn.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 50 insertions(+), 1 deletion(-)
New commits:
commit 01dde0611bbf08f7e27aa8442f36eea2d0cca9de
Author: Tom Gundersen <teg at jklm.no>
Date: Thu Mar 13 17:47:30 2014 +0100
nspawn: make host0's MAC address persistent
We still need to make sure that no two MAC addresses are the same, so we use
a logic similar to what is used in udev to generate MAC addresses, and base
it on a hash of the host's machine ID and thecontainer's name.
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 084929d..b637b51 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -86,6 +86,7 @@
#include "udev-util.h"
#include "blkid-util.h"
#include "gpt.h"
+#include "siphash24.h"
#ifdef HAVE_SECCOMP
#include "seccomp-util.h"
@@ -1399,9 +1400,46 @@ static int reset_audit_loginuid(void) {
return 0;
}
+#define HASH_KEY SD_ID128_MAKE(c3,c4,f9,19,b5,57,b2,1c,e6,cf,14,27,03,9c,ee,a2)
+
+static int get_mac(struct ether_addr *mac) {
+ int r;
+
+ uint8_t result[8];
+ size_t l, sz;
+ uint8_t *v;
+
+ l = strlen(arg_machine);
+ sz = sizeof(sd_id128_t) + l;
+ v = alloca(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 */
+ memcpy(v + sizeof(sd_id128_t), arg_machine, l);
+
+ /* Let's hash the host machine ID plus the container name. We
+ * use a fixed, but originally randomly created hash key here. */
+ siphash24(result, v, sz, HASH_KEY.bytes);
+
+ assert_cc(ETH_ALEN <= sizeof(result));
+ memcpy(mac->ether_addr_octet, result, ETH_ALEN);
+
+ /* see eth_random_addr in the kernel */
+ mac->ether_addr_octet[0] &= 0xfe; /* clear multicast bit */
+ mac->ether_addr_octet[0] |= 0x02; /* set local assignment bit (IEEE802) */
+
+ return 0;
+}
+
static int setup_veth(pid_t pid, char iface_name[IFNAMSIZ]) {
_cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
_cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
+ struct ether_addr mac;
int r;
if (!arg_private_network)
@@ -1416,9 +1454,14 @@ static int setup_veth(pid_t pid, char iface_name[IFNAMSIZ]) {
memcpy(iface_name, "vb-", 3);
else
memcpy(iface_name, "ve-", 3);
-
strncpy(iface_name+3, arg_machine, IFNAMSIZ - 3);
+ r = get_mac(&mac);
+ if (r < 0) {
+ log_error("Failed to generate predictable MAC address for host0");
+ return r;
+ }
+
r = sd_rtnl_open(&rtnl, 0);
if (r < 0) {
log_error("Failed to connect to netlink: %s", strerror(-r));
@@ -1467,6 +1510,12 @@ static int setup_veth(pid_t pid, char iface_name[IFNAMSIZ]) {
return r;
}
+ r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, &mac);
+ if (r < 0) {
+ log_error("Failed to add netlink MAC address: %s", strerror(-r));
+ return r;
+ }
+
r = sd_rtnl_message_append_u32(m, IFLA_NET_NS_PID, pid);
if (r < 0) {
log_error("Failed to add netlink namespace field: %s", strerror(-r));
More information about the systemd-commits
mailing list