Hi,
Sorry I didn't reply earlier.
> Thanks, sorry for the trouble. Looks good, with one exception - if
> ioctl failed, then you may end up returning the wrong errno (from the
> close syscall). With that fixed, please do apply.
Oh, yes, nice catch. I've attached a fixed patch.
Thanks!
Christian
>From 0dce40ea882c560e0847a78058f962cd20fb4813 Mon Sep 17 00:00:00 2001
From: Christian Seiler <christ...@iwakd.de>
Date: Tue, 15 Nov 2011 18:53:53 +0100
Subject: [PATCH] Set high byte of mac addresses for host veth devices to 0xfe
When used in conjunction with a bridge, veth devices with random addresses
may change the mac address of the bridge itself if the mac address of the
interface newly added is numerically lower than the previous mac address
of the bridge. This is documented kernel behavior. To avoid changing the
host's mac address back and forth when starting and/or stopping containers,
this patch ensures that the high byte of the mac address of the veth
interface visible from the host side is set to 0xfe.
A similar logic has previously also been implemented by the libvirt
developers for libvirt.
Fixes SF bug #3411497
See also: <http://thread.gmane.org/gmane.linux.kernel.containers.lxc.general/2709>
---
src/lxc/conf.c | 41 +++++++++++++++++++++++++++++++++++++++++
1 files changed, 41 insertions(+), 0 deletions(-)
diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index 613e476..b9b25f9 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -1402,6 +1402,37 @@ static int setup_network(struct lxc_list *network)
return 0;
}
+static int setup_private_host_hw_addr(char *veth1)
+{
+ struct ifreq ifr;
+ int err;
+ int sockfd;
+
+ sockfd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (sockfd < 0)
+ return -errno;
+
+ snprintf((char *)ifr.ifr_name, IFNAMSIZ, "%s", veth1);
+ err = ioctl(sockfd, SIOCGIFHWADDR, &ifr);
+ if (err < 0) {
+ err = -errno;
+ close(sockfd);
+ return err;
+ }
+
+ ifr.ifr_hwaddr.sa_data[0] = 0xfe;
+ err = ioctl(sockfd, SIOCSIFHWADDR, &ifr);
+ close(sockfd);
+ if (err < 0)
+ return -errno;
+
+ DEBUG("mac address of host interface '%s' changed to private %02x:%02x:%02x:%02x:%02x:%02x",
+ veth1, ifr.ifr_hwaddr.sa_data[0] & 0xff, ifr.ifr_hwaddr.sa_data[1] & 0xff, ifr.ifr_hwaddr.sa_data[2] & 0xff,
+ ifr.ifr_hwaddr.sa_data[3] & 0xff, ifr.ifr_hwaddr.sa_data[4] & 0xff, ifr.ifr_hwaddr.sa_data[5] & 0xff);
+
+ return 0;
+}
+
struct lxc_conf *lxc_conf_init(void)
{
struct lxc_conf *new;
@@ -1455,6 +1486,16 @@ static int instanciate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
strerror(-err));
return -1;
}
+
+ /* changing the high byte of the mac address to 0xfe, the bridge interface
+ * will always keep the host's mac address and not take the mac address
+ * of a container */
+ err = setup_private_host_hw_addr(veth1);
+ if (err) {
+ ERROR("failed to change mac address of host interface '%s' : %s",
+ veth1, strerror(-err));
+ goto out_delete;
+ }
if (netdev->mtu) {
err = lxc_netdev_set_mtu(veth1, atoi(netdev->mtu));
--
1.7.2.5
------------------------------------------------------------------------------
Write once. Port to many.
Get the SDK and tools to simplify cross-platform app development. Create
new or port existing apps to sell to consumers worldwide. Explore the
Intel AppUpSM program developer opportunity. appdeveloper.intel.com/join
http://p.sf.net/sfu/intel-appdev
_______________________________________________
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel