[lxc-devel] [PATCH] Set high byte of mac addresses for host veth devices to 0xfe

Daniel Lezcano daniel.lezcano at free.fr
Sun Dec 4 23:18:35 UTC 2011


On 12/05/2011 12:11 AM, Serge Hallyn wrote:
> On 12/04/2011 04:28 AM, Daniel Lezcano wrote:
>> On 11/16/2011 05:49 PM, Christian Seiler wrote:
>>> Hi,
>>>
>>> I've run into the same problem as was discussed in BUG #3411497 [1]
>>> and on
>>> the users mailing list [2]. To solve this, I've decided to implement
>>> the
>>> patch that was proposed on the mailing list [3].
>>>
>>> The attached patch is against current trunk. Since trunk currently
>>> doesn't
>>> compile for me, I tested the patch against the current Debian
>>> package for
>>> LXC version 0.7.2. There, it still applies and works as expected for
>>> me,
>>> the bridge interface still keeps its mac address and the high byte
>>> of the
>>> mac address of the host veth interface is correctly set to 0xfe.
>>>
>>> It would be great if this patch or a slightly modified version could be
>>> applied to LXC.
>> Hi guys
>>
>> are ok with this patch ?
>>
>> Thanks
>>    -- Daniel
>
> Sorry, where is the patch?  I don't find it in the archives.  Can
> someone send it (inline)?
>

It was in attachment. Here it is.

>From e1b4779a89964ec43fa2bc5f76fafd965c89f73f Mon Sep 17 00:00:00 2001
From: Christian Seiler <christian at 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 is also implemented in libvirt.

Fixes SF bug #3411497
See also: <http://thread.gmane.org/gmane.linux.kernel.containers.lxc.general/2709>
---
 src/lxc/conf.c |   40 ++++++++++++++++++++++++++++++++++++++++
 1 files changed, 40 insertions(+), 0 deletions(-)

diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index 613e476..a5d067b 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -1402,6 +1402,36 @@ 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) {
+		close(sockfd);
+		return -errno;
+	}
+	
+	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 +1485,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





More information about the lxc-devel mailing list