[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH v4 2/2] libxl: made vm mac address assignment deterministic



Uses MD5 on a host mac address, the vm name and vif index to generate the
last three bytes of the vm mac address (for each vm). It uses the vif
index to account for multiple vifs.

Reported-by: George Dunlap <george.dunlap@xxxxxxxxxx>
Signed-off-by: Joshua Perrett <jperrett256@xxxxxxxxx>
---
 tools/libxl/Makefile         |  2 +-
 tools/libxl/libxl_freebsd.c  |  5 +++++
 tools/libxl/libxl_internal.h |  5 +++++
 tools/libxl/libxl_linux.c    | 31 ++++++++++++++++++++++++++++++-
 tools/libxl/libxl_netbsd.c   |  5 +++++
 tools/libxl/libxl_nic.c      | 31 +++++++++++++++++++++++++------
 6 files changed, 71 insertions(+), 8 deletions(-)

diff --git a/tools/libxl/Makefile b/tools/libxl/Makefile
index 6da342ed61..21a67bc2fc 100644
--- a/tools/libxl/Makefile
+++ b/tools/libxl/Makefile
@@ -142,7 +142,7 @@ LIBXL_OBJS = flexarray.o libxl.o libxl_create.o libxl_dm.o 
libxl_pci.o \
                        libxl_9pfs.o libxl_domain.o libxl_vdispl.o \
                        libxl_pvcalls.o libxl_vsnd.o libxl_vkb.o $(LIBXL_OBJS-y)
 LIBXL_OBJS += libxl_genid.o
-LIBXL_OBJS += _libxl_types.o libxl_flask.o _libxl_types_internal.o
+LIBXL_OBJS += _libxl_types.o libxl_flask.o _libxl_types_internal.o 
$(XEN_SHARED)/md5.o
 
 LIBXL_TESTS += timedereg
 LIBXL_TESTS_PROGS = $(LIBXL_TESTS) fdderegrace
diff --git a/tools/libxl/libxl_freebsd.c b/tools/libxl/libxl_freebsd.c
index 6442ccec72..23d8155c75 100644
--- a/tools/libxl/libxl_freebsd.c
+++ b/tools/libxl/libxl_freebsd.c
@@ -245,3 +245,8 @@ int libxl__pci_topology_init(libxl__gc *gc,
 {
     return ERROR_NI;
 }
+
+int libxl__get_host_mac(libxl__gc *gc, unsigned char *buf)
+{
+    return ERROR_NI;
+}
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 802382c704..4a5154600d 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -50,6 +50,9 @@
 #include <sys/un.h>
 #include <sys/file.h>
 #include <sys/ioctl.h>
+#include <ifaddrs.h>
+#include <linux/if_packet.h>
+#include <net/ethernet.h>
 
 #include <xenevtchn.h>
 #include <xenstore.h>
@@ -1413,6 +1416,8 @@ _hidden int libxl__pci_topology_init(libxl__gc *gc,
                                      physdev_pci_device_t *devs,
                                      int num_devs);
 
+_hidden int libxl__get_host_mac(libxl__gc *gc, unsigned char *buf);
+
 /* from libxl_pci */
 
 _hidden int libxl__device_pci_add(libxl__gc *gc, uint32_t domid, 
libxl_device_pci *pcidev, int starting);
diff --git a/tools/libxl/libxl_linux.c b/tools/libxl/libxl_linux.c
index 6ef0abc693..e528f7c085 100644
--- a/tools/libxl/libxl_linux.c
+++ b/tools/libxl/libxl_linux.c
@@ -16,7 +16,7 @@
 #include "libxl_osdeps.h" /* must come before any other headers */
 
 #include "libxl_internal.h"
- 
+
 int libxl__try_phy_backend(mode_t st_mode)
 {
     if (S_ISBLK(st_mode) || S_ISREG(st_mode)) {
@@ -307,6 +307,35 @@ int libxl__pci_topology_init(libxl__gc *gc,
     return err;
 }
 
+int libxl__get_host_mac(libxl__gc *gc, unsigned char *buf)
+{
+    int rc = ERROR_FAIL;
+
+    struct ifaddrs *iface_list;
+    uint8_t largest[6] = {0};
+
+    if (getifaddrs(&iface_list) == 0) {
+        for (struct ifaddrs *iface = iface_list;
+            iface != NULL; iface = iface->ifa_next) {
+            if (iface->ifa_addr && iface->ifa_addr->sa_family == AF_PACKET) {
+                struct sockaddr_ll *s = (struct sockaddr_ll *)iface->ifa_addr;
+                if (s->sll_halen == 6) {
+                    if (memcmp(s->sll_addr, largest, s->sll_halen) > 0) {
+                        memcpy(buf, s->sll_addr, s->sll_halen);
+                        memcpy(largest, s->sll_addr, s->sll_halen);
+                        rc = 0;
+                    }
+                }
+            }
+        }
+        freeifaddrs(iface_list);
+    } else {
+        LOGE(WARN, "getifaddrs failed");
+    }
+
+    return rc;
+}
+
 /*
  * Local variables:
  * mode: C
diff --git a/tools/libxl/libxl_netbsd.c b/tools/libxl/libxl_netbsd.c
index 2edfb00641..7b001ec2b7 100644
--- a/tools/libxl/libxl_netbsd.c
+++ b/tools/libxl/libxl_netbsd.c
@@ -124,3 +124,8 @@ int libxl__pci_topology_init(libxl__gc *gc,
 {
     return ERROR_NI;
 }
+
+int libxl__get_host_mac(libxl__gc *gc, unsigned char *buf)
+{
+    return ERROR_NI;
+}
diff --git a/tools/libxl/libxl_nic.c b/tools/libxl/libxl_nic.c
index 01b711b84e..1010627f5d 100644
--- a/tools/libxl/libxl_nic.c
+++ b/tools/libxl/libxl_nic.c
@@ -17,6 +17,12 @@
 
 #include "libxl_internal.h"
 
+#include <string.h>
+
+#include <arpa/inet.h>
+
+#include "../shared/md5.h"
+
 int libxl_mac_to_device_nic(libxl_ctx *ctx, uint32_t domid,
                             const char *mac, libxl_device_nic *nic)
 {
@@ -54,7 +60,8 @@ int libxl_mac_to_device_nic(libxl_ctx *ctx, uint32_t domid,
 }
 
 static int libxl__device_nic_setdefault(libxl__gc *gc, uint32_t domid,
-                                        libxl_device_nic *nic, bool hotplug)
+                                        libxl_device_nic *nic, const char 
*name,
+                                        const int nic_index, bool hotplug)
 {
     int rc;
 
@@ -65,11 +72,23 @@ static int libxl__device_nic_setdefault(libxl__gc *gc, 
uint32_t domid,
         if (!nic->model) return ERROR_NOMEM;
     }
     if (libxl__mac_is_default(&nic->mac)) {
-        const uint8_t *r;
-        libxl_uuid uuid;
+        uint8_t r[16];
+
+        MD5_CTX ctx;
+        MD5Init(&ctx);
+
+        uint8_t hostmac[6];
+
+        if (libxl__get_host_mac(gc, hostmac) == 0) {
+            MD5Update(&ctx, hostmac, sizeof(hostmac));
+        } else {
+            LOGD(INFO, domid, "failed to get host mac address, will generate 
vm mac address without");
+        }
 
-        libxl_uuid_generate(&uuid);
-        r = libxl_uuid_bytearray(&uuid);
+        MD5Update(&ctx, (uint8_t *) name, strlen(name));
+        uint32_t index = htonl(nic_index);
+        MD5Update(&ctx, (uint8_t *) &index, sizeof(nic_index));
+        MD5Final(r, &ctx);
 
         nic->mac[0] = 0x00;
         nic->mac[1] = 0x16;
@@ -478,7 +497,7 @@ int libxl__device_nic_set_devids(libxl__gc *gc, 
libxl_domain_config *d_config,
          * but qemu needs the nic information to be complete.
          */
         ret = libxl__device_nic_setdefault(gc, domid, &d_config->nics[i],
-                                           false);
+                                           d_config->c_info.name, i, false);
         if (ret) {
             LOGD(ERROR, domid, "Unable to set nic defaults for nic %d", i);
             goto out;
-- 
2.11.0


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.