[libvirt] [PATCH 0/3] LXC guest network device name changes

This patch series allows users to configure the network device name in the LXC container. I intentionaly didn't allow this for hostdev net interfaces as the NIC would be returned with a different name to the host and we have no way to guess under what name it was returned to the host namespace. This will help filling the feature gap with LXC WRT network configuration. Cédric Bosdonnat (3): lxc network configuration allows setting target container NIC name lxc conf2xml: convert lxc.network.name for veth networks lxc network device names change documentation docs/formatdomain.html.in | 17 +++++++++++++ docs/schemas/domaincommon.rng | 17 +++++++++++++ src/conf/domain_conf.c | 27 ++++++++++++++++++++ src/conf/domain_conf.h | 2 ++ src/lxc/lxc_container.c | 29 +++++++++++++++++++--- src/lxc/lxc_native.c | 22 +++++++++++----- src/lxc/lxc_process.c | 25 +++++++++++++++++++ .../lxcconf2xmldata/lxcconf2xml-physnetwork.config | 1 + tests/lxcconf2xmldata/lxcconf2xml-simple.xml | 1 + tests/lxcxml2xmldata/lxc-idmap.xml | 1 + 10 files changed, 132 insertions(+), 10 deletions(-) -- 1.8.4.5

LXC network devices can now be assigned a custom NIC device name on the container side. For example, this is configured with: <interface type='network'> <source network='default'/> <guest dev="eth1"/> </interface> In this example the network card will appear as eth1 in the guest. --- docs/schemas/domaincommon.rng | 17 +++++++++++++++++ src/conf/domain_conf.c | 27 +++++++++++++++++++++++++++ src/conf/domain_conf.h | 2 ++ src/lxc/lxc_container.c | 29 +++++++++++++++++++++++++---- src/lxc/lxc_process.c | 25 +++++++++++++++++++++++++ tests/lxcxml2xmldata/lxc-idmap.xml | 1 + 6 files changed, 97 insertions(+), 4 deletions(-) diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 33d0308..e7ca992 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -2165,6 +2165,23 @@ </element> </optional> <optional> + <element name="guest"> + <interleave> + <optional> + <attribute name="dev"> + <ref name="deviceName"/> + </attribute> + </optional> + <optional> + <attribute name="actual"> + <ref name="deviceName"/> + </attribute> + </optional> + </interleave> + <empty/> + </element> + </optional> + <optional> <element name="mac"> <attribute name="address"> <ref name="uniMacAddr"/> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index b7aa4f5..5cd6ae6 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1383,6 +1383,8 @@ void virDomainNetDefFree(virDomainNetDefPtr def) VIR_FREE(def->virtPortProfile); VIR_FREE(def->script); VIR_FREE(def->ifname); + VIR_FREE(def->ifname_guest); + VIR_FREE(def->ifname_guest_actual); virDomainDeviceInfoClear(&def->info); @@ -6618,6 +6620,8 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt, char *bridge = NULL; char *dev = NULL; char *ifname = NULL; + char *ifname_guest = NULL; + char *ifname_guest_actual = NULL; char *script = NULL; char *address = NULL; char *port = NULL; @@ -6723,6 +6727,10 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt, /* An auto-generated target name, blank it out */ VIR_FREE(ifname); } + } else if ((!ifname_guest || !ifname_guest_actual) && + xmlStrEqual(cur->name, BAD_CAST "guest")) { + ifname_guest = virXMLPropString(cur, "dev"); + ifname_guest_actual = virXMLPropString(cur, "actual"); } else if (!linkstate && xmlStrEqual(cur->name, BAD_CAST "link")) { linkstate = virXMLPropString(cur, "state"); @@ -6964,6 +6972,14 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt, def->ifname = ifname; ifname = NULL; } + if (ifname_guest != NULL) { + def->ifname_guest = ifname_guest; + ifname_guest = NULL; + } + if (ifname_guest_actual != NULL) { + def->ifname_guest_actual = ifname_guest_actual; + ifname_guest_actual = NULL; + } /* NIC model (see -net nic,model=?). We only check that it looks * reasonable, not that it is a supported NIC type. FWIW kvm @@ -15883,6 +15899,17 @@ virDomainNetDefFormat(virBufferPtr buf, /* Skip auto-generated target names for inactive config. */ virBufferEscapeString(buf, "<target dev='%s'/>\n", def->ifname); } + if (def->ifname_guest || def->ifname_guest_actual) { + virBufferAddLit(buf, "<guest"); + /* Skip auto-generated target names for inactive config. */ + if (def->ifname_guest) + virBufferEscapeString(buf, " dev='%s'", def->ifname_guest); + + /* Only set if the host is running, so shouldn't pollute output */ + if (def->ifname_guest_actual) + virBufferEscapeString(buf, " actual='%s'", def->ifname_guest_actual); + virBufferAddLit(buf, "/>\n"); + } if (def->model) { virBufferEscapeString(buf, "<model type='%s'/>\n", def->model); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 1122eb2..60aa491 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -915,6 +915,8 @@ struct _virDomainNetDef { } tune; char *script; char *ifname; + char *ifname_guest; + char *ifname_guest_actual; virDomainDeviceInfo info; char *filter; virNWFilterHashTablePtr filterparams; diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c index fd8ab16..c7423db 100644 --- a/src/lxc/lxc_container.c +++ b/src/lxc/lxc_container.c @@ -464,6 +464,21 @@ static int lxcContainerSetID(virDomainDefPtr def) } +static virDomainNetDefPtr +lxcContainerGetNetDef(virDomainDefPtr vmDef, const char *devName) +{ + size_t i; + virDomainNetDefPtr netDef; + + for (i = 0; i < vmDef->nnets; i++) { + netDef = vmDef->nets[i]; + if (STREQ(netDef->ifname_guest_actual, devName)) + return netDef; + } + + return NULL; +} + /** * lxcContainerRenameAndEnableInterfaces: * @nveths: number of interfaces @@ -475,16 +490,23 @@ static int lxcContainerSetID(virDomainDefPtr def) * * Returns 0 on success or nonzero in case of error */ -static int lxcContainerRenameAndEnableInterfaces(bool privNet, +static int lxcContainerRenameAndEnableInterfaces(virDomainDefPtr vmDef, size_t nveths, char **veths) { int rc = 0; size_t i; char *newname = NULL; + virDomainNetDefPtr netDef; + bool privNet = vmDef->features[VIR_DOMAIN_FEATURE_PRIVNET] == + VIR_DOMAIN_FEATURE_STATE_ON; for (i = 0; i < nveths; i++) { - if (virAsprintf(&newname, "eth%zu", i) < 0) { + if (!(netDef = lxcContainerGetNetDef(vmDef, veths[i]))) + return -1; + + newname = netDef->ifname_guest; + if (!newname) { rc = -1; goto error_out; } @@ -1866,8 +1888,7 @@ static int lxcContainerChild(void *data) } /* rename and enable interfaces */ - if (lxcContainerRenameAndEnableInterfaces(vmDef->features[VIR_DOMAIN_FEATURE_PRIVNET] == - VIR_DOMAIN_FEATURE_STATE_ON, + if (lxcContainerRenameAndEnableInterfaces(vmDef, argv->nveths, argv->veths) < 0) { goto cleanup; diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c index 0aef13a..d532e20 100644 --- a/src/lxc/lxc_process.c +++ b/src/lxc/lxc_process.c @@ -259,6 +259,8 @@ char *virLXCProcessSetupInterfaceBridged(virConnectPtr conn, if (virNetDevSetMAC(containerVeth, &net->mac) < 0) goto cleanup; + if (VIR_STRDUP(net->ifname_guest_actual, containerVeth) < 0) + goto cleanup; if (vport && vport->virtPortType == VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH) { if (virNetDevOpenvswitchAddPort(brname, parentVeth, &net->mac, @@ -369,6 +371,7 @@ static int virLXCProcessSetupInterfaces(virConnectPtr conn, { int ret = -1; size_t i; + size_t niface = 0; for (i = 0; i < def->nnets; i++) { char *veth = NULL; @@ -451,6 +454,13 @@ static int virLXCProcessSetupInterfaces(virConnectPtr conn, } (*veths)[(*nveths)-1] = veth; + + /* Make sure all net definitions will have a name in the container */ + if (!def->nets[i]->ifname_guest) { + if (virAsprintf(&def->nets[i]->ifname_guest, "eth%zu", niface) < 0) + return -1; + niface++; + } } ret = 0; @@ -470,6 +480,18 @@ static int virLXCProcessSetupInterfaces(virConnectPtr conn, return ret; } +static void +virLXCProcessCleanInterfaces(virDomainDefPtr def) +{ + size_t i; + + for (i = 0; i < def->nnets; i++) { + VIR_FREE(def->nets[i]->ifname_guest_actual); + def->nets[i]->ifname_guest_actual = NULL; + VIR_DEBUG("Cleared net names: %s", def->nets[i]->ifname_guest); + } +} + extern virLXCDriverPtr lxc_driver; static void virLXCProcessMonitorEOFNotify(virLXCMonitorPtr mon, @@ -1306,6 +1328,9 @@ int virLXCProcessStart(virConnectPtr conn, vm, false) < 0) goto error; + /* We don't need the temporary NIC names anymore, clear them */ + virLXCProcessCleanInterfaces(vm->def); + /* Write domain status to disk. * * XXX: Earlier we wrote the plain "live" domain XML to this diff --git a/tests/lxcxml2xmldata/lxc-idmap.xml b/tests/lxcxml2xmldata/lxc-idmap.xml index 3cced21..946d363 100644 --- a/tests/lxcxml2xmldata/lxc-idmap.xml +++ b/tests/lxcxml2xmldata/lxc-idmap.xml @@ -29,6 +29,7 @@ <mac address='00:16:3e:0f:ef:8a'/> <source bridge='bri0'/> <target dev='veth0'/> + <guest dev='eth2'/> </interface> <console type='pty'> <target type='lxc' port='0'/> -- 1.8.4.5

On 02.07.2014 15:57, Cédric Bosdonnat wrote:
LXC network devices can now be assigned a custom NIC device name on the container side. For example, this is configured with:
<interface type='network'> <source network='default'/> <guest dev="eth1"/> </interface>
In this example the network card will appear as eth1 in the guest. --- docs/schemas/domaincommon.rng | 17 +++++++++++++++++ src/conf/domain_conf.c | 27 +++++++++++++++++++++++++++ src/conf/domain_conf.h | 2 ++ src/lxc/lxc_container.c | 29 +++++++++++++++++++++++++---- src/lxc/lxc_process.c | 25 +++++++++++++++++++++++++ tests/lxcxml2xmldata/lxc-idmap.xml | 1 + 6 files changed, 97 insertions(+), 4 deletions(-)
The 3/3 should be merged with this so any element addition goes with RNG schema adjustment and is documented.
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 33d0308..e7ca992 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -2165,6 +2165,23 @@ </element> </optional> <optional> + <element name="guest"> + <interleave> + <optional> + <attribute name="dev"> + <ref name="deviceName"/> + </attribute> + </optional> + <optional> + <attribute name="actual"> + <ref name="deviceName"/> + </attribute> + </optional> + </interleave> + <empty/> + </element> + </optional> + <optional> <element name="mac"> <attribute name="address"> <ref name="uniMacAddr"/> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index b7aa4f5..5cd6ae6 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1383,6 +1383,8 @@ void virDomainNetDefFree(virDomainNetDefPtr def) VIR_FREE(def->virtPortProfile); VIR_FREE(def->script); VIR_FREE(def->ifname); + VIR_FREE(def->ifname_guest); + VIR_FREE(def->ifname_guest_actual);
virDomainDeviceInfoClear(&def->info);
@@ -6618,6 +6620,8 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt, char *bridge = NULL; char *dev = NULL; char *ifname = NULL; + char *ifname_guest = NULL; + char *ifname_guest_actual = NULL; char *script = NULL; char *address = NULL; char *port = NULL; @@ -6723,6 +6727,10 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt, /* An auto-generated target name, blank it out */ VIR_FREE(ifname); } + } else if ((!ifname_guest || !ifname_guest_actual) && + xmlStrEqual(cur->name, BAD_CAST "guest")) { + ifname_guest = virXMLPropString(cur, "dev"); + ifname_guest_actual = virXMLPropString(cur, "actual"); } else if (!linkstate && xmlStrEqual(cur->name, BAD_CAST "link")) { linkstate = virXMLPropString(cur, "state"); @@ -6964,6 +6972,14 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt, def->ifname = ifname; ifname = NULL; } + if (ifname_guest != NULL) { + def->ifname_guest = ifname_guest; + ifname_guest = NULL; + } + if (ifname_guest_actual != NULL) { + def->ifname_guest_actual = ifname_guest_actual; + ifname_guest_actual = NULL; + }
/* NIC model (see -net nic,model=?). We only check that it looks * reasonable, not that it is a supported NIC type. FWIW kvm @@ -15883,6 +15899,17 @@ virDomainNetDefFormat(virBufferPtr buf, /* Skip auto-generated target names for inactive config. */ virBufferEscapeString(buf, "<target dev='%s'/>\n", def->ifname); } + if (def->ifname_guest || def->ifname_guest_actual) { + virBufferAddLit(buf, "<guest"); + /* Skip auto-generated target names for inactive config. */ + if (def->ifname_guest) + virBufferEscapeString(buf, " dev='%s'", def->ifname_guest); + + /* Only set if the host is running, so shouldn't pollute output */ + if (def->ifname_guest_actual) + virBufferEscapeString(buf, " actual='%s'", def->ifname_guest_actual); + virBufferAddLit(buf, "/>\n"); + } if (def->model) { virBufferEscapeString(buf, "<model type='%s'/>\n", def->model); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 1122eb2..60aa491 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -915,6 +915,8 @@ struct _virDomainNetDef { } tune; char *script; char *ifname; + char *ifname_guest; + char *ifname_guest_actual; virDomainDeviceInfo info; char *filter; virNWFilterHashTablePtr filterparams; diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c index fd8ab16..c7423db 100644 --- a/src/lxc/lxc_container.c +++ b/src/lxc/lxc_container.c @@ -464,6 +464,21 @@ static int lxcContainerSetID(virDomainDefPtr def) }
+static virDomainNetDefPtr +lxcContainerGetNetDef(virDomainDefPtr vmDef, const char *devName) +{ + size_t i; + virDomainNetDefPtr netDef; + + for (i = 0; i < vmDef->nnets; i++) { + netDef = vmDef->nets[i]; + if (STREQ(netDef->ifname_guest_actual, devName)) + return netDef; + } + + return NULL; +} + /** * lxcContainerRenameAndEnableInterfaces: * @nveths: number of interfaces @@ -475,16 +490,23 @@ static int lxcContainerSetID(virDomainDefPtr def) * * Returns 0 on success or nonzero in case of error */ -static int lxcContainerRenameAndEnableInterfaces(bool privNet, +static int lxcContainerRenameAndEnableInterfaces(virDomainDefPtr vmDef, size_t nveths, char **veths) { int rc = 0; size_t i; char *newname = NULL; + virDomainNetDefPtr netDef; + bool privNet = vmDef->features[VIR_DOMAIN_FEATURE_PRIVNET] == + VIR_DOMAIN_FEATURE_STATE_ON;
for (i = 0; i < nveths; i++) { - if (virAsprintf(&newname, "eth%zu", i) < 0) { + if (!(netDef = lxcContainerGetNetDef(vmDef, veths[i]))) + return -1; + + newname = netDef->ifname_guest; + if (!newname) { rc = -1; goto error_out; } @@ -1866,8 +1888,7 @@ static int lxcContainerChild(void *data) }
/* rename and enable interfaces */ - if (lxcContainerRenameAndEnableInterfaces(vmDef->features[VIR_DOMAIN_FEATURE_PRIVNET] == - VIR_DOMAIN_FEATURE_STATE_ON, + if (lxcContainerRenameAndEnableInterfaces(vmDef, argv->nveths, argv->veths) < 0) { goto cleanup; diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c index 0aef13a..d532e20 100644 --- a/src/lxc/lxc_process.c +++ b/src/lxc/lxc_process.c @@ -259,6 +259,8 @@ char *virLXCProcessSetupInterfaceBridged(virConnectPtr conn,
if (virNetDevSetMAC(containerVeth, &net->mac) < 0) goto cleanup; + if (VIR_STRDUP(net->ifname_guest_actual, containerVeth) < 0) + goto cleanup;
if (vport && vport->virtPortType == VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH) { if (virNetDevOpenvswitchAddPort(brname, parentVeth, &net->mac, @@ -369,6 +371,7 @@ static int virLXCProcessSetupInterfaces(virConnectPtr conn, { int ret = -1; size_t i; + size_t niface = 0;
for (i = 0; i < def->nnets; i++) { char *veth = NULL; @@ -451,6 +454,13 @@ static int virLXCProcessSetupInterfaces(virConnectPtr conn, }
(*veths)[(*nveths)-1] = veth; + + /* Make sure all net definitions will have a name in the container */ + if (!def->nets[i]->ifname_guest) { + if (virAsprintf(&def->nets[i]->ifname_guest, "eth%zu", niface) < 0) + return -1; + niface++; + } }
ret = 0; @@ -470,6 +480,18 @@ static int virLXCProcessSetupInterfaces(virConnectPtr conn, return ret; }
+static void +virLXCProcessCleanInterfaces(virDomainDefPtr def) +{ + size_t i; + + for (i = 0; i < def->nnets; i++) { + VIR_FREE(def->nets[i]->ifname_guest_actual); + def->nets[i]->ifname_guest_actual = NULL;
There's no need to set the @ifname_guest_actual to NULL, VIR_FREE() has already done that. ACK with 3/3 squashed in. Michal

--- src/lxc/lxc_native.c | 22 ++++++++++++++++------ .../lxcconf2xmldata/lxcconf2xml-physnetwork.config | 1 + tests/lxcconf2xmldata/lxcconf2xml-simple.xml | 1 + 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/lxc/lxc_native.c b/src/lxc/lxc_native.c index f4c4556..e14face 100644 --- a/src/lxc/lxc_native.c +++ b/src/lxc/lxc_native.c @@ -338,7 +338,8 @@ lxcCreateNetDef(const char *type, const char *linkdev, const char *mac, const char *flag, - const char *macvlanmode) + const char *macvlanmode, + const char *name) { virDomainNetDefPtr net = NULL; virMacAddr macAddr; @@ -353,6 +354,8 @@ lxcCreateNetDef(const char *type, net->linkstate = VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN; } + if (name && VIR_STRDUP(net->ifname_guest, name) < 0) + goto error; if (mac && virMacAddrParse(mac, &macAddr) == 0) net->mac = macAddr; @@ -416,7 +419,8 @@ lxcAddNetworkDefinition(virDomainDefPtr def, const char *mac, const char *flag, const char *macvlanmode, - const char *vlanid) + const char *vlanid, + const char *name) { virDomainNetDefPtr net = NULL; virDomainHostdevDefPtr hostdev = NULL; @@ -452,7 +456,7 @@ lxcAddNetworkDefinition(virDomainDefPtr def, goto error; def->hostdevs[def->nhostdevs - 1] = hostdev; } else { - if (!(net = lxcCreateNetDef(type, linkdev, mac, flag, macvlanmode))) + if (!(net = lxcCreateNetDef(type, linkdev, mac, flag, macvlanmode, name))) goto error; if (VIR_EXPAND_N(def->nets, def->nnets, 1) < 0) @@ -476,6 +480,7 @@ typedef struct { char *flag; char *macvlanmode; char *vlanid; + char *name; bool privnet; size_t networks; } lxcNetworkParseData; @@ -492,7 +497,8 @@ lxcNetworkWalkCallback(const char *name, virConfValuePtr value, void *data) parseData->link, parseData->mac, parseData->flag, parseData->macvlanmode, - parseData->vlanid); + parseData->vlanid, + parseData->name); if (status < 0) return -1; @@ -508,6 +514,7 @@ lxcNetworkWalkCallback(const char *name, virConfValuePtr value, void *data) parseData->flag = NULL; parseData->macvlanmode = NULL; parseData->vlanid = NULL; + parseData->name = NULL; /* Keep the new value */ parseData->type = value->str; @@ -522,6 +529,8 @@ lxcNetworkWalkCallback(const char *name, virConfValuePtr value, void *data) parseData->macvlanmode = value->str; else if (STREQ(name, "lxc.network.vlan.id")) parseData->vlanid = value->str; + else if (STREQ(name, "lxc.network.name")) + parseData->name = value->str; else if (STRPREFIX(name, "lxc.network")) VIR_WARN("Unhandled network property: %s = %s", name, @@ -535,7 +544,7 @@ lxcConvertNetworkSettings(virDomainDefPtr def, virConfPtr properties) { int status; lxcNetworkParseData data = {def, NULL, NULL, NULL, NULL, - NULL, NULL, true, 0}; + NULL, NULL, NULL, true, 0}; virConfWalk(properties, lxcNetworkWalkCallback, &data); @@ -543,7 +552,8 @@ lxcConvertNetworkSettings(virDomainDefPtr def, virConfPtr properties) status = lxcAddNetworkDefinition(def, data.type, data.link, data.mac, data.flag, data.macvlanmode, - data.vlanid); + data.vlanid, + data.name); if (status < 0) return -1; else if (status > 0) diff --git a/tests/lxcconf2xmldata/lxcconf2xml-physnetwork.config b/tests/lxcconf2xmldata/lxcconf2xml-physnetwork.config index 63a4aa1..ed196e1 100644 --- a/tests/lxcconf2xmldata/lxcconf2xml-physnetwork.config +++ b/tests/lxcconf2xmldata/lxcconf2xml-physnetwork.config @@ -1,5 +1,6 @@ lxc.network.type = phys lxc.network.link = eth0 +lxc.network.name = eth1 lxc.rootfs = /var/lib/lxc/migrate_test/rootfs lxc.utsname = migrate_test diff --git a/tests/lxcconf2xmldata/lxcconf2xml-simple.xml b/tests/lxcconf2xmldata/lxcconf2xml-simple.xml index b3c3659..dabb76e 100644 --- a/tests/lxcconf2xmldata/lxcconf2xml-simple.xml +++ b/tests/lxcconf2xmldata/lxcconf2xml-simple.xml @@ -29,6 +29,7 @@ <interface type='bridge'> <mac address='02:00:15:8f:05:c1'/> <source bridge='virbr0'/> + <guest dev='eth0'/> <link state='up'/> </interface> <console type='pty'> -- 1.8.4.5

On 02.07.2014 15:57, Cédric Bosdonnat wrote:
--- src/lxc/lxc_native.c | 22 ++++++++++++++++------ .../lxcconf2xmldata/lxcconf2xml-physnetwork.config | 1 + tests/lxcconf2xmldata/lxcconf2xml-simple.xml | 1 + 3 files changed, 18 insertions(+), 6 deletions(-)
diff --git a/src/lxc/lxc_native.c b/src/lxc/lxc_native.c index f4c4556..e14face 100644 --- a/src/lxc/lxc_native.c +++ b/src/lxc/lxc_native.c @@ -338,7 +338,8 @@ lxcCreateNetDef(const char *type, const char *linkdev, const char *mac, const char *flag, - const char *macvlanmode) + const char *macvlanmode, + const char *name) { virDomainNetDefPtr net = NULL; virMacAddr macAddr; @@ -353,6 +354,8 @@ lxcCreateNetDef(const char *type, net->linkstate = VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN; }
+ if (name && VIR_STRDUP(net->ifname_guest, name) < 0) + goto error;
One of the requirements when I introduced VIR_STRDUP was, that it's NULL safe so we don't have to do this. s/name && // ACK Michal

--- docs/formatdomain.html.in | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 3075e16..b23736e 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -3767,6 +3767,23 @@ qemu-kvm -net nic,model=? /dev/null targets using these prefixes will be ignored. </p> + <p> + Note that for LXC containers, this defines the name of the interface + on the host side. <span class="since">Since 1.2.7</span>, to define + the name of the device on the guest side, the <code>guest</code> + element should be used, as in the following snippet: + </p> + +<pre> + ... + <devices> + <interface type='network'> + <source network='default'/> + <b><guest dev='myeth'/></b> + </interface> + </devices> + ...</pre> + <h5><a name="elementsNICSBoot">Specifying boot order</a></h5> <pre> -- 1.8.4.5

On Wed, Jul 2, 2014 at 3:57 PM, Cédric Bosdonnat <cbosdonnat@suse.com> wrote:
This patch series allows users to configure the network device name in the LXC container. I intentionaly didn't allow this for hostdev net interfaces as the NIC would be returned with a different name to the host and we have no way to guess under what name it was returned to the host namespace.
This will help filling the feature gap with LXC WRT network configuration.
We need this feature because you want to change the interface name and drop CAP_NET_ADMIN?
Cédric Bosdonnat (3): lxc network configuration allows setting target container NIC name lxc conf2xml: convert lxc.network.name for veth networks lxc network device names change documentation
docs/formatdomain.html.in | 17 +++++++++++++ docs/schemas/domaincommon.rng | 17 +++++++++++++ src/conf/domain_conf.c | 27 ++++++++++++++++++++ src/conf/domain_conf.h | 2 ++ src/lxc/lxc_container.c | 29 +++++++++++++++++++--- src/lxc/lxc_native.c | 22 +++++++++++----- src/lxc/lxc_process.c | 25 +++++++++++++++++++ .../lxcconf2xmldata/lxcconf2xml-physnetwork.config | 1 + tests/lxcconf2xmldata/lxcconf2xml-simple.xml | 1 + tests/lxcxml2xmldata/lxc-idmap.xml | 1 + 10 files changed, 132 insertions(+), 10 deletions(-)
-- 1.8.4.5
-- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
-- Thanks, //richard

On Wed, 2014-07-02 at 23:00 +0200, Richard Weinberger wrote:
On Wed, Jul 2, 2014 at 3:57 PM, Cédric Bosdonnat <cbosdonnat@suse.com> wrote:
This patch series allows users to configure the network device name in the LXC container. I intentionaly didn't allow this for hostdev net interfaces as the NIC would be returned with a different name to the host and we have no way to guess under what name it was returned to the host namespace.
This will help filling the feature gap with LXC WRT network configuration.
We need this feature because you want to change the interface name and drop CAP_NET_ADMIN?
Well that is mostly the beginning of another patch series to help converting lxc.network.ipv[46] properties too. I have no feedback on how LXC users are using lxc.network.name in their containers. -- Cedric

Am 03.07.2014 09:15, schrieb Cedric Bosdonnat:
On Wed, 2014-07-02 at 23:00 +0200, Richard Weinberger wrote:
On Wed, Jul 2, 2014 at 3:57 PM, Cédric Bosdonnat <cbosdonnat@suse.com> wrote:
This patch series allows users to configure the network device name in the LXC container. I intentionaly didn't allow this for hostdev net interfaces as the NIC would be returned with a different name to the host and we have no way to guess under what name it was returned to the host namespace.
This will help filling the feature gap with LXC WRT network configuration.
We need this feature because you want to change the interface name and drop CAP_NET_ADMIN?
Well that is mostly the beginning of another patch series to help converting lxc.network.ipv[46] properties too. I have no feedback on how LXC users are using lxc.network.name in their containers.
Okay. I'd assume that ifrename does the job. :) Thanks, //richard
participants (5)
-
Cedric Bosdonnat
-
Cédric Bosdonnat
-
Michal Privoznik
-
Richard Weinberger
-
Richard Weinberger