mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-03 03:25:20 +00:00
lxc network configuration allows setting target container NIC name
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.
This commit is contained in:
parent
d659b412a8
commit
3ba0469ce6
@ -3810,6 +3810,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>
|
||||
|
@ -2218,6 +2218,23 @@
|
||||
<empty/>
|
||||
</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">
|
||||
|
@ -1388,6 +1388,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);
|
||||
|
||||
@ -6608,6 +6610,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;
|
||||
@ -6722,6 +6726,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");
|
||||
@ -7022,6 +7030,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
|
||||
@ -15849,6 +15865,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);
|
||||
|
@ -923,6 +923,8 @@ struct _virDomainNetDef {
|
||||
} tune;
|
||||
char *script;
|
||||
char *ifname;
|
||||
char *ifname_guest;
|
||||
char *ifname_guest_actual;
|
||||
virDomainDeviceInfo info;
|
||||
char *filter;
|
||||
virNWFilterHashTablePtr filterparams;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
@ -452,6 +455,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;
|
||||
@ -471,6 +481,17 @@ 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);
|
||||
VIR_DEBUG("Cleared net names: %s", def->nets[i]->ifname_guest);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extern virLXCDriverPtr lxc_driver;
|
||||
static void virLXCProcessMonitorEOFNotify(virLXCMonitorPtr mon,
|
||||
@ -1307,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
|
||||
|
@ -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'/>
|
||||
|
Loading…
Reference in New Issue
Block a user