[libvirt] [PATCH] lxc: support <interface type='ethernet'>

This is identical to type='bridge', but without the "connect to a bridge" part, so it can be handled by using the same functions (and often even the same cases in switch statements), after renaming virLXCProcessSetupInterfaceBridged() to virLXCProcessInterfaceTap() and enhancing it to skip bridge-related items when brname == NULL. To be truly useful, we need to support setting the ip address on the host side veth as well as guest side veth (already supported for type='bridge'), as well as setting the peer address for both. The <script> element isn't supported in this patch because I have no need for it. I'd rather add it after determining it's needed rather than adding it for no reason and than being required to support it forever. --- I wrote this mostly so that I could experiment with setting the peer addresses of both sides of the veth pair to see what was usable and what we needed to support in terms of setting IP addresses. I had intended to post this patch along with patches to re-enable the peer address setting patches that I reverted just before 1.3.4 was released, but decided that having lxc <interface type='ethernet'> already in might help in any discussion we had about that (since it gives everyone a working example where libvirt has control of both the host-side and guest-side interface config. This will of course be much more useful once the IP addresses can be set from within libvirt, but all code that is here will remain and, as I said above, it provides a useful platform for experimentation. src/lxc/lxc_controller.c | 4 +- src/lxc/lxc_driver.c | 16 ++++--- src/lxc/lxc_native.c | 15 +++---- src/lxc/lxc_process.c | 36 +++++++-------- src/lxc/lxc_process.h | 6 +-- tests/lxcconf2xmldata/lxcconf2xml-ethernet.config | 44 ++++++++++++++++++ tests/lxcconf2xmldata/lxcconf2xml-ethernet.xml | 54 +++++++++++++++++++++++ tests/lxcconf2xmltest.c | 1 + tests/lxcxml2xmldata/lxc-ethernet.xml | 42 ++++++++++++++++++ tests/lxcxml2xmltest.c | 1 + 10 files changed, 181 insertions(+), 38 deletions(-) create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-ethernet.config create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-ethernet.xml create mode 100644 tests/lxcxml2xmldata/lxc-ethernet.xml diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c index 0304354..25f28ea 100644 --- a/src/lxc/lxc_controller.c +++ b/src/lxc/lxc_controller.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2015 Red Hat, Inc. + * Copyright (C) 2010-2016 Red Hat, Inc. * Copyright IBM Corp. 2008 * * lxc_controller.c: linux container process controller @@ -371,6 +371,7 @@ static int virLXCControllerGetNICIndexes(virLXCControllerPtr ctrl) switch (ctrl->def->nets[i]->type) { case VIR_DOMAIN_NET_TYPE_BRIDGE: case VIR_DOMAIN_NET_TYPE_NETWORK: + case VIR_DOMAIN_NET_TYPE_ETHERNET: if (ctrl->def->nets[i]->ifname == NULL) continue; if (virNetDevGetIndex(ctrl->def->nets[i]->ifname, @@ -386,7 +387,6 @@ static int virLXCControllerGetNICIndexes(virLXCControllerPtr ctrl) break; case VIR_DOMAIN_NET_TYPE_USER: - case VIR_DOMAIN_NET_TYPE_ETHERNET: case VIR_DOMAIN_NET_TYPE_VHOSTUSER: case VIR_DOMAIN_NET_TYPE_SERVER: case VIR_DOMAIN_NET_TYPE_CLIENT: diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index a226850..f811053 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2015 Red Hat, Inc. + * Copyright (C) 2010-2016 Red Hat, Inc. * Copyright IBM Corp. 2008 * * lxc_driver.c: linux container driver functions @@ -4225,15 +4225,15 @@ lxcDomainAttachDeviceNetLive(virConnectPtr conn, _("No bridge name specified")); goto cleanup; } - if (!(veth = virLXCProcessSetupInterfaceBridged(vm->def, - net, - brname))) + if (!(veth = virLXCProcessSetupInterfaceTap(vm->def, net, brname))) goto cleanup; } break; + case VIR_DOMAIN_NET_TYPE_ETHERNET: + if (!(veth = virLXCProcessSetupInterfaceTap(vm->def, net, NULL))) + goto cleanup; + break; case VIR_DOMAIN_NET_TYPE_DIRECT: { - if (!(veth = virLXCProcessSetupInterfaceDirect(conn, - vm->def, - net))) + if (!(veth = virLXCProcessSetupInterfaceDirect(conn, vm->def, net))) goto cleanup; } break; default: @@ -4270,6 +4270,7 @@ lxcDomainAttachDeviceNetLive(virConnectPtr conn, switch (actualType) { case VIR_DOMAIN_NET_TYPE_BRIDGE: case VIR_DOMAIN_NET_TYPE_NETWORK: + case VIR_DOMAIN_NET_TYPE_ETHERNET: ignore_value(virNetDevVethDelete(veth)); break; @@ -4695,6 +4696,7 @@ lxcDomainDetachDeviceNetLive(virDomainObjPtr vm, switch (actualType) { case VIR_DOMAIN_NET_TYPE_BRIDGE: case VIR_DOMAIN_NET_TYPE_NETWORK: + case VIR_DOMAIN_NET_TYPE_ETHERNET: if (virNetDevVethDelete(detach->ifname) < 0) { virDomainAuditNet(vm, detach, NULL, "detach", false); goto cleanup; diff --git a/src/lxc/lxc_native.c b/src/lxc/lxc_native.c index 31ffce7..0bea32e 100644 --- a/src/lxc/lxc_native.c +++ b/src/lxc/lxc_native.c @@ -360,14 +360,13 @@ lxcCreateNetDef(const char *type, net->mac = macAddr; if (STREQ(type, "veth")) { - if (!linkdev) - goto error; - - net->type = VIR_DOMAIN_NET_TYPE_BRIDGE; - - if (VIR_STRDUP(net->data.bridge.brname, linkdev) < 0) - goto error; - + if (linkdev) { + net->type = VIR_DOMAIN_NET_TYPE_BRIDGE; + if (VIR_STRDUP(net->data.bridge.brname, linkdev) < 0) + goto error; + } else { + net->type = VIR_DOMAIN_NET_TYPE_ETHERNET; + } } else if (STREQ(type, "macvlan")) { net->type = VIR_DOMAIN_NET_TYPE_DIRECT; diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c index 8981d9a..f8a0c32 100644 --- a/src/lxc/lxc_process.c +++ b/src/lxc/lxc_process.c @@ -256,9 +256,9 @@ static void virLXCProcessCleanup(virLXCDriverPtr driver, } -char *virLXCProcessSetupInterfaceBridged(virDomainDefPtr vm, - virDomainNetDefPtr net, - const char *brname) +char *virLXCProcessSetupInterfaceTap(virDomainDefPtr vm, + virDomainNetDefPtr net, + const char *brname) { char *ret = NULL; char *parentVeth; @@ -277,13 +277,15 @@ char *virLXCProcessSetupInterfaceBridged(virDomainDefPtr vm, if (virNetDevSetMAC(containerVeth, &net->mac) < 0) goto cleanup; - if (vport && vport->virtPortType == VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH) { - if (virNetDevOpenvswitchAddPort(brname, parentVeth, &net->mac, - vm->uuid, vport, virDomainNetGetActualVlan(net)) < 0) - goto cleanup; - } else { - if (virNetDevBridgeAddPort(brname, parentVeth) < 0) - goto cleanup; + if (brname) { + if (vport && vport->virtPortType == VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH) { + if (virNetDevOpenvswitchAddPort(brname, parentVeth, &net->mac, vm->uuid, + vport, virDomainNetGetActualVlan(net)) < 0) + goto cleanup; + } else { + if (virNetDevBridgeAddPort(brname, parentVeth) < 0) + goto cleanup; + } } if (virNetDevSetOnline(parentVeth, true) < 0) @@ -546,20 +548,18 @@ static int virLXCProcessSetupInterfaces(virConnectPtr conn, _("No bridge name specified")); goto cleanup; } - if (!(veth = virLXCProcessSetupInterfaceBridged(def, - net, - brname))) + if (!(veth = virLXCProcessSetupInterfaceTap(def, net, brname))) goto cleanup; } break; - + case VIR_DOMAIN_NET_TYPE_ETHERNET: + if (!(veth = virLXCProcessSetupInterfaceTap(def, net, NULL))) + goto cleanup; + break; case VIR_DOMAIN_NET_TYPE_DIRECT: - if (!(veth = virLXCProcessSetupInterfaceDirect(conn, - def, - net))) + if (!(veth = virLXCProcessSetupInterfaceDirect(conn, def, net))) goto cleanup; break; - case VIR_DOMAIN_NET_TYPE_ETHERNET: case VIR_DOMAIN_NET_TYPE_USER: case VIR_DOMAIN_NET_TYPE_VHOSTUSER: case VIR_DOMAIN_NET_TYPE_SERVER: diff --git a/src/lxc/lxc_process.h b/src/lxc/lxc_process.h index b6c8083..fcb50a8 100644 --- a/src/lxc/lxc_process.h +++ b/src/lxc/lxc_process.h @@ -47,9 +47,9 @@ void virLXCProcessAutostartAll(virLXCDriverPtr driver); int virLXCProcessReconnectAll(virLXCDriverPtr driver, virDomainObjListPtr doms); -char *virLXCProcessSetupInterfaceBridged(virDomainDefPtr vm, - virDomainNetDefPtr net, - const char *brname); +char *virLXCProcessSetupInterfaceTap(virDomainDefPtr vm, + virDomainNetDefPtr net, + const char *brname); char *virLXCProcessSetupInterfaceDirect(virConnectPtr conn, virDomainDefPtr def, virDomainNetDefPtr net); diff --git a/tests/lxcconf2xmldata/lxcconf2xml-ethernet.config b/tests/lxcconf2xmldata/lxcconf2xml-ethernet.config new file mode 100644 index 0000000..d39917d --- /dev/null +++ b/tests/lxcconf2xmldata/lxcconf2xml-ethernet.config @@ -0,0 +1,44 @@ +# Template used to create this container: opensuse +# Template script checksum (SHA-1): 27307e0a95bd81b2c0bd82d6f87fdbe83be075ef + +lxc.network.type = veth +lxc.network.flags = up +lxc.network.hwaddr = 02:00:15:8f:05:c1 +lxc.network.name = eth0 +lxc.network.ipv4 = 192.168.122.2/24 +lxc.network.ipv4.gateway = 192.168.122.1 +lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3596/64 +lxc.network.ipv6.gateway = 2003:db8:1:0:214:1234:fe0b:3595 + +#remove next line if host DNS configuration should not be available to container +lxc.mount.entry = proc proc proc nodev,noexec,nosuid 0 0 +lxc.mount.entry = sysfs sys sysfs defaults 0 0 +lxc.mount.entry = tmpfs run tmpfs size=8m,mode=0755,nodev,nosuid 0 0 +lxc.mount.entry = /etc/resolv.conf etc/resolv.conf none bind,ro 0 0 +lxc.rootfs = /var/lib/lxc/migrate_test/rootfs +lxc.utsname = migrate_test +lxc.arch = x86 +lxc.autodev=1 +lxc.tty = 2 +lxc.pts = 1024 +lxc.cap.drop = sys_module mac_admin mac_override mknod + +# When using LXC with apparmor, uncomment the next line to run unconfined: +#lxc.aa_profile = unconfined + +lxc.cgroup.devices.deny = a +# /dev/null and zero +lxc.cgroup.devices.allow = c 1:3 rwm +lxc.cgroup.devices.allow = c 1:5 rwm +# consoles +lxc.cgroup.devices.allow = c 5:1 rwm +lxc.cgroup.devices.allow = c 5:0 rwm +lxc.cgroup.devices.allow = c 4:0 rwm +lxc.cgroup.devices.allow = c 4:1 rwm +# /dev/{,u}random +lxc.cgroup.devices.allow = c 1:9 rwm +lxc.cgroup.devices.allow = c 1:8 rwm +lxc.cgroup.devices.allow = c 136:* rwm +lxc.cgroup.devices.allow = c 5:2 rwm +# rtc +lxc.cgroup.devices.allow = c 254:0 rwm diff --git a/tests/lxcconf2xmldata/lxcconf2xml-ethernet.xml b/tests/lxcconf2xmldata/lxcconf2xml-ethernet.xml new file mode 100644 index 0000000..24b017a --- /dev/null +++ b/tests/lxcconf2xmldata/lxcconf2xml-ethernet.xml @@ -0,0 +1,54 @@ +<domain type='lxc'> + <name>migrate_test</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>65536</memory> + <currentMemory unit='KiB'>65536</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='i686'>exe</type> + <init>/sbin/init</init> + </os> + <features> + <capabilities policy='allow'> + <mac_admin state='off'/> + <mac_override state='off'/> + <mknod state='off'/> + <sys_module state='off'/> + </capabilities> + </features> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/libexec/libvirt_lxc</emulator> + <filesystem type='mount' accessmode='passthrough'> + <source dir='/var/lib/lxc/migrate_test/rootfs'/> + <target dir='/'/> + </filesystem> + <filesystem type='ram' accessmode='passthrough'> + <source usage='8192' units='KiB'/> + <target dir='/run'/> + </filesystem> + <filesystem type='mount' accessmode='passthrough'> + <source dir='/etc/resolv.conf'/> + <target dir='/etc/resolv.conf'/> + <readonly/> + </filesystem> + <interface type='ethernet'> + <mac address='02:00:15:8f:05:c1'/> + <ip address='192.168.122.2' family='ipv4' prefix='24'/> + <ip address='2003:db8:1:0:214:1234:fe0b:3596' family='ipv6' prefix='64'/> + <route family='ipv4' address='0.0.0.0' gateway='192.168.122.1'/> + <route family='ipv6' address='::' gateway='2003:db8:1:0:214:1234:fe0b:3595'/> + <guest dev='eth0'/> + <link state='up'/> + </interface> + <console type='pty'> + <target type='lxc' port='0'/> + </console> + <console type='pty'> + <target type='lxc' port='1'/> + </console> + </devices> +</domain> diff --git a/tests/lxcconf2xmltest.c b/tests/lxcconf2xmltest.c index 83895cd..7a0893e 100644 --- a/tests/lxcconf2xmltest.c +++ b/tests/lxcconf2xmltest.c @@ -119,6 +119,7 @@ mymain(void) DO_TEST("cputune", false); DO_TEST("cpusettune", false); DO_TEST("blkiotune", false); + DO_TEST("ethernet", false); virObjectUnref(xmlopt); virObjectUnref(caps); diff --git a/tests/lxcxml2xmldata/lxc-ethernet.xml b/tests/lxcxml2xmldata/lxc-ethernet.xml new file mode 100644 index 0000000..6c4a739 --- /dev/null +++ b/tests/lxcxml2xmldata/lxc-ethernet.xml @@ -0,0 +1,42 @@ +<domain type='lxc'> + <name>8675309</name> + <uuid>e21987a5-e98e-9c99-0e35-803e4d9ad1fe</uuid> + <memory unit='KiB'>1048576</memory> + <currentMemory unit='KiB'>1048576</currentMemory> + <vcpu placement='static'>1</vcpu> + <resource> + <partition>/machine</partition> + </resource> + <os> + <type arch='x86_64'>exe</type> + <init>/sbin/init</init> + </os> + <idmap> + <uid start='0' target='100000' count='100000'/> + <gid start='0' target='100000' count='100000'/> + </idmap> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>restart</on_crash> + <devices> + <emulator>/usr/libexec/libvirt_lxc</emulator> + <filesystem type='mount' accessmode='passthrough'> + <source dir='/mach/8675309'/> + <target dir='/'/> + </filesystem> + <interface type='ethernet'> + <mac address='00:16:3e:0f:ef:8a'/> + <ip address='192.168.122.12' family='ipv4' prefix='24'/> + <ip address='192.168.122.13' family='ipv4' prefix='24'/> + <route family='ipv4' address='0.0.0.0' gateway='192.168.122.1'/> + <route family='ipv4' address='192.168.124.0' prefix='24' gateway='192.168.124.1'/> + <target dev='veth0'/> + <guest dev='eth2'/> + </interface> + <console type='pty'> + <target type='lxc' port='0'/> + </console> + </devices> + <seclabel type='none'/> +</domain> diff --git a/tests/lxcxml2xmltest.c b/tests/lxcxml2xmltest.c index fec0142..001aa8d 100644 --- a/tests/lxcxml2xmltest.c +++ b/tests/lxcxml2xmltest.c @@ -94,6 +94,7 @@ mymain(void) DO_TEST("idmap"); DO_TEST("capabilities"); DO_TEST("sharenet"); + DO_TEST("ethernet"); DO_TEST_FULL("filesystem-root", 0, false, VIR_DOMAIN_DEF_PARSE_SKIP_OSTYPE_CHECKS); -- 2.5.5

On 05/16/2016 12:21 PM, Laine Stump wrote:
This is identical to type='bridge', but without the "connect to a bridge" part, so it can be handled by using the same functions (and often even the same cases in switch statements), after renaming virLXCProcessSetupInterfaceBridged() to virLXCProcessInterfaceTap() and enhancing it to skip bridge-related items when brname == NULL.
To be truly useful, we need to support setting the ip address on the host side veth as well as guest side veth (already supported for type='bridge'), as well as setting the peer address for both.
The <script> element isn't supported in this patch because I have no need for it. I'd rather add it after determining it's needed rather than adding it for no reason and than being required to support it forever.
I suggest explicitly rejecting the <script> option then, since at least the formatdomain docs make it sound like it's the only valid type=ethernet config. virLXCProcessSetupInterfaceTap seems like the only shared place for it though Also, this is https://bugzilla.redhat.com/show_bug.cgi?id=1325687 Patch looks fine otherwise, ACK if it's simple to reject the script bit, up to you - Cole

2016-05-17 1:53 GMT+03:00 Cole Robinson <crobinso@redhat.com>:
I suggest explicitly rejecting the <script> option then, since at least the formatdomain docs make it sound like it's the only valid type=ethernet config. virLXCProcessSetupInterfaceTap seems like the only shared place for it though
Also, this is https://bugzilla.redhat.com/show_bug.cgi?id=1325687
Patch looks fine otherwise, ACK if it's simple to reject the script bit, up to you
I think that script may be useful.... May be simple utilize logic to run script like in qemu? -- Vasiliy Tolstov, e-mail: v.tolstov@yoctocloud.net

On 05/17/2016 07:48 AM, Vasiliy Tolstov wrote:
2016-05-17 1:53 GMT+03:00 Cole Robinson <crobinso@redhat.com>:
I suggest explicitly rejecting the <script> option then, since at least the formatdomain docs make it sound like it's the only valid type=ethernet config. virLXCProcessSetupInterfaceTap seems like the only shared place for it though
Also, this is https://bugzilla.redhat.com/show_bug.cgi?id=1325687
Patch looks fine otherwise, ACK if it's simple to reject the script bit, up to you
I think that script may be useful.... May be simple utilize logic to run script like in qemu?
I think Laine was saying 'I personally don't care about ->script so I'm not planning on implementing it', so if it isn't implemented we should error explicitly rather than silently ignore it. That said it's probably not hard to get ->script to work since we already have the plumbing as you mention, so 'patches welcome' :) - Cole

2016-05-17 15:33 GMT+03:00 Cole Robinson <crobinso@redhat.com>:
I think Laine was saying 'I personally don't care about ->script so I'm not planning on implementing it', so if it isn't implemented we should error explicitly rather than silently ignore it.
That said it's probably not hard to get ->script to work since we already have the plumbing as you mention, so 'patches welcome' :)
Ok, after Laine patch merged i send script patch. -- Vasiliy Tolstov, e-mail: v.tolstov@yoctocloud.net

On 05/17/2016 08:40 AM, Vasiliy Tolstov wrote:
2016-05-17 15:33 GMT+03:00 Cole Robinson <crobinso@redhat.com>:
I think Laine was saying 'I personally don't care about ->script so I'm not planning on implementing it',
My position is a bit stronger than that. It's not that I don't want to spend the effort. It's that everything added is just that much more to support. A capability to call an arbitrary external script is especially problematic, because nearly anything could happen during execution of the script, making support of other parts of the system much more difficult (at least with any level of certainty. It also gives at least a feeling of greater vulnerability to potential security exploits (although libvirtd is running as root already). Also, keep in mind that the script capability was originally there just to allow overriding the default script that qemu in order to create a tap device and make it functional at all. Much (in most cases all?) of the required setup is now done within libvirt, making me wonder if it's necessary to do anything outside. If not, then we shouldn't put in something that just invites Rube Goldberg-type contraptions. (I'm not saying that's definitely what it would be; just saying "let's talk about what this would be used for first to be sure we *really* want it) Another thing - there was no design thought put into the script feature for the qemu driver - it is just an approximate replacement for what qemu itself does with a script; for example, the only input the script gets is the name of the tap interface (as a command line arg), and is only called once (just after the tap is created and MAC address is set) which may be inadequate. If we're going to do this at all, perhaps we should do it right, and send (in stdin) the full domain XML + an extra copy of the interface XML for the interface being started (similar to the libvirt network hook, but can be specified differently for each interface). For that matter, we should also be calling the script both before the tap/veth devices are created/configed, then again after they are fully setup from libvirt's PoV - some things can only be done once the interface exists (and some other things must be done before it's created).
so if it isn't implemented we should error explicitly rather than silently ignore it.
I agree with this.
That said it's probably not hard to get ->script to work since we already have the plumbing as you mention,
I also agree with this :-). It's trivial to all *all kinds of things* to libvirt (but remember "just because you can do it, doesn't mean you *should*"). I actually almost added support for script before posting, then changed my mind and started to add an error condition when script was specified. But since I was undecided I did neither. I don't intend to push the patches without one or the other. If there really is a good case for enabling script (maybe combined with officially tainting the domain so that we can refuse to support anyone who has a script) then I'll do that.
so 'patches welcome' :) Ok, after Laine patch merged i send script patch.
Rather than me spending time adding something to my patches that will just be superceded by another patch immediately, I would rather just do it the way everyone wants to begin with. What type of things are usually done in the upscript? (and is a "down script" needed?) (Speaking of that - I had asked in my discussion of re-doing the peer-address patches if you could supply some example address/route configs (for both host and guest side) of what you're doing with the peer address, to see just how generalized those need to be. Any chance you can send me that?)

2016-05-17 17:39 GMT+03:00 Laine Stump <laine@laine.org>:
Rather than me spending time adding something to my patches that will just be superceded by another patch immediately, I would rather just do it the way everyone wants to begin with.
What type of things are usually done in the upscript? (and is a "down script" needed?)
(Speaking of that - I had asked in my discussion of re-doing the peer-address patches if you could supply some example address/route configs (for both host and guest side) of what you're doing with the peer address, to see just how generalized those need to be. Any chance you can send me that?)
I think script needed to manually ping some sort of agent on node for example to add network info about newly created domain. May be this is expensive (because agent can listen libvirt events...) So may be i'm wrong. Please forget about script... I think that I was mistaken.. For qemu i'm use this lines: <ip address='HOST_IP' family='ipv4' peer='VM_IP' prefix='32'/> -- this address used bi bird routing daemon and via ospf propagated to other nodes. <ip address='VM_GW' family='ipv4' prefix='32'/> -- this address used for gateway <ip address='169.254.169.254' family='ipv4' prefix='32'/> -- this address used by cloud-init (inside vm cloud-init talk to 169.254.169.254, so on host node i have some web server). <ip family="ipv6" address="HOST_IP6" peer='VP_IP6' prefix="64"/> -- this is ipv6 address <ip family="ipv6" address="VM_GW6" prefix="64"/> -- this is ipv6 gateway Now i don't used route elements because i'm use bird routing daemon and ospf. -- Vasiliy Tolstov, e-mail: v.tolstov@yoctocloud.net

On 05/18/2016 07:37 AM, Vasiliy Tolstov wrote:
2016-05-17 17:39 GMT+03:00 Laine Stump <laine@laine.org>:
Rather than me spending time adding something to my patches that will just be superceded by another patch immediately, I would rather just do it the way everyone wants to begin with.
Since this has been sitting in my queue for a week and I'm no closer to making a decision on exactly what to do, I think I *will* just put in an UNSUPPORTED error and punt on it for now. When somebody does add support for the script, I think we really should consider if we want to just mimic the qemu script (which only gets the tap device name as input, and is only called once just after creating the tap and setting its MAC address), or if we should do something more like the network hook script - it is called multiple times during a network's lifetime. Each time the script gets commandline arguments telling the name of the network, operation, and "subop", as well as the script's stdin getting XML with (hopefully) as much information as you could ever need: <hookData> <interface> [the XML of the interface being operated on] </interface> <network> [the XML of the network being operated on] </network> <domain> [the XML of the domain being operated on] </domain> </hookData> We could do something similar (and it could be made to work for *all* types of interfaces (or at least type='ethernet') on both LXC and qemu). Something like this: 1) in the interface xml, look for "<script hook='/Bob/Lob/Law/Law/Blog'/>" (note this doesn't use "path" as the existing simple qemu script does). 2) when found pepper calls to it in strategic places during the interface setup, sending "$domainname $mac start $subopname" on the commandline, as well as: <hookData> <interface> [the XML of the interface being operated on] </interface> <domain> [the XML of the domain being operated on] </domain> </hookData> to stdin, just in case there's something else in the config that is needed. This one script could contain bits to create a tap device in lieu of libvirt creating it, starting up a VPN attaching the tap to some strange unknown network technology, adding rules to a firewall, or whatever - putting in calls at multiple points in the device setup would make it possible to intervene at just the right time. Similarly, the same script would be called several times as the interface was being shutdown. I'm just throwing that out for discussion. For right now, I'm going to flag script as UNSUPPORTED and move on.
What type of things are usually done in the upscript? (and is a "down script" needed?)
(Speaking of that - I had asked in my discussion of re-doing the peer-address patches if you could supply some example address/route configs (for both host and guest side) of what you're doing with the peer address, to see just how generalized those need to be. Any chance you can send me that?)
I think script needed to manually ping some sort of agent on node for example to add network info about newly created domain. May be this is expensive (because agent can listen libvirt events...) So may be i'm wrong. Please forget about script... I think that I was mistaken..
For qemu i'm use this lines:
<ip address='HOST_IP' family='ipv4' peer='VM_IP' prefix='32'/> -- this address used bi bird routing daemon and via ospf propagated to other nodes. <ip address='VM_GW' family='ipv4' prefix='32'/> -- this address used for gateway <ip address='169.254.169.254' family='ipv4' prefix='32'/> -- this address used by cloud-init (inside vm cloud-init talk to 169.254.169.254, so on host node i have some web server).
So ignoring the IPv6 addresses for now. You now have a tap device on the *host* that has the following IP addresses: $HOST_IP peer $VM_IP/32 $VM_GW 169.254.169.254 I'm guessing that in the guest you configure its ethernet to have $VM_IP peer $HOST_IP/24 (or some other prefix < 32) route add default $VM_GW ($VM_GW on same subnet as $HOST_IP/24) (I'm not sure what the guest does with 169.254.169.254) What if you instead set the host to: $HOST_IP peer $VM_IP/32 and set the guest to: $VM_IP peer $HOST_IP/32 route add default $HOST_IP ?? Anyway, it's important to know if you set the IP config on host and guest to exact mirrors of each other. It seems like the answer is "no", though, so i'm going to make a patch that allows what I was talking about last week: <interface type='ethernet'> <source> <ip address='HOST_IP' family='ipv4' peer='VM_IP' prefix='32'/> <ip address='VM_GW' family='ipv4' prefix='32'/> </source> <ip address='VM_IP' family='ipv4' peer='HOST_IP' prefix='24'/> <route family='ipv4' address='0.0.0.0' gateway='HOST_IP'/> ... </interface> On qemu only the address info inside <source> would be used, since we don't have control over the guest's network config. On LXC, we can set both. Does that sound usable?
<ip family="ipv6" address="HOST_IP6" peer='VP_IP6' prefix="64"/> -- this is ipv6 address <ip family="ipv6" address="VM_GW6" prefix="64"/> -- this is ipv6 gateway
Now i don't used route elements because i'm use bird routing daemon and ospf.

On 05/24/2016 12:33 PM, Laine Stump wrote:
On 05/18/2016 07:37 AM, Vasiliy Tolstov wrote:
2016-05-17 17:39 GMT+03:00 Laine Stump <laine@laine.org>:
Rather than me spending time adding something to my patches that will just be superceded by another patch immediately, I would rather just do it the way everyone wants to begin with.
Since this has been sitting in my queue for a week and I'm no closer to making a decision on exactly what to do, I think I *will* just put in an UNSUPPORTED error and punt on it for now.
I just pushed this patch with the addition of a simple check for script.

2016-05-24 19:33 GMT+03:00 Laine Stump <laine@laine.org>:
So ignoring the IPv6 addresses for now. You now have a tap device on the *host* that has the following IP addresses:
$HOST_IP peer $VM_IP/32 $VM_GW 169.254.169.254
I'm guessing that in the guest you configure its ethernet to have
$VM_IP peer $HOST_IP/24 (or some other prefix < 32) route add default $VM_GW ($VM_GW on same subnet as $HOST_IP/24)
No, inside guest i'm assign address via dhcp to $VM_IP/24 (not using peer) and route add default $VM_GW peer only used on host machine to determine on which interface kernel needs to send traffic
(I'm not sure what the guest does with 169.254.169.254)
What if you instead set the host to:
$HOST_IP peer $VM_IP/32
and set the guest to:
$VM_IP peer $HOST_IP/32 route add default $HOST_IP
??
I don't use this scheme... If i set $VM_IP peer $HOST_IP/32 on host machine i think kernel recieves packet and drop it =)
Anyway, it's important to know if you set the IP config on host and guest to exact mirrors of each other. It seems like the answer is "no", though, so i'm going to make a patch that allows what I was talking about last week:
<interface type='ethernet'> <source> <ip address='HOST_IP' family='ipv4' peer='VM_IP' prefix='32'/> <ip address='VM_GW' family='ipv4' prefix='32'/> </source> <ip address='VM_IP' family='ipv4' peer='HOST_IP' prefix='24'/> <route family='ipv4' address='0.0.0.0' gateway='HOST_IP'/> ... </interface>
On qemu only the address info inside <source> would be used, since we don't have control over the guest's network config. On LXC, we can set both.
Does that sound usable?
Yes, but don't cleanup please <ip address='VM_IP' family='ipv4' peer='HOST_IP' prefix='24'/> in qemu case, because on somedays we can launch dnsmasq or orhet software that can provide dhcp and use this element.. -- Vasiliy Tolstov, e-mail: v.tolstov@yoctocloud.net

On 05/25/2016 08:58 AM, Vasiliy Tolstov wrote:
2016-05-24 19:33 GMT+03:00 Laine Stump <laine@laine.org>:
So ignoring the IPv6 addresses for now. You now have a tap device on the *host* that has the following IP addresses:
$HOST_IP peer $VM_IP/32 $VM_GW 169.254.169.254
I'm guessing that in the guest you configure its ethernet to have
$VM_IP peer $HOST_IP/24 (or some other prefix < 32) route add default $VM_GW ($VM_GW on same subnet as $HOST_IP/24) No, inside guest i'm assign address via dhcp to $VM_IP/24 (not using peer) and route add default $VM_GW
So $VM_GW is on the same subnet as $VM_IP/24 ? Is that also the same subnet as $HOST_IP? Or is that on a completely different network? (This is all very useful, because it's pointing out that the config of the two ends definitely aren't mirror images, so we really do need independent settings for both).
peer only used on host machine to determine on which interface kernel needs to send traffic
Well, you *could* do the same thing with a /30 subnet for each tap (so that your routing daemon would get a bunch of /30 routes pointing to your host for all of them), but that would use up a lot more address space.
(I'm not sure what the guest does with 169.254.169.254)
What if you instead set the host to:
$HOST_IP peer $VM_IP/32
and set the guest to:
$VM_IP peer $HOST_IP/32 route add default $HOST_IP
??
I don't use this scheme... If i set $VM_IP peer $HOST_IP/32 on host machine i think kernel recieves packet and drop it =)
No - you would set that on the *guest*, not the host. I setup an LXC container in this manner and everything seemed to work properly.
Anyway, it's important to know if you set the IP config on host and guest to exact mirrors of each other. It seems like the answer is "no", though, so i'm going to make a patch that allows what I was talking about last week:
<interface type='ethernet'> <source> <ip address='HOST_IP' family='ipv4' peer='VM_IP' prefix='32'/> <ip address='VM_GW' family='ipv4' prefix='32'/> </source> <ip address='VM_IP' family='ipv4' peer='HOST_IP' prefix='24'/> <route family='ipv4' address='0.0.0.0' gateway='HOST_IP'/> ... </interface>
On qemu only the address info inside <source> would be used, since we don't have control over the guest's network config. On LXC, we can set both.
Does that sound usable? Yes, but don't cleanup please <ip address='VM_IP' family='ipv4' peer='HOST_IP' prefix='24'/> in qemu case, because on somedays we can launch dnsmasq or orhet software that can provide dhcp and use this element..
An interesting point - even if libvirt itself doesn't launch the dnsmasq, it could be done by a more intelligent script (one that received the full interface XML on stdin, as I discussed in my last mail), so we should probably just ignore it rather than complaining that it's unsupported... Thanks for the info!

2016-05-25 18:00 GMT+03:00 Laine Stump <laine@laine.org>:
So $VM_GW is on the same subnet as $VM_IP/24 ? Is that also the same subnet as $HOST_IP? Or is that on a completely different network?
(This is all very useful, because it's pointing out that the config of the two ends definitely aren't mirror images, so we really do need independent settings for both).
VM_GW on the same subnet as PEER , but on host side i apply /32 address, but inside vm /24.
peer only used on host machine to determine on which interface kernel needs to send traffic
Well, you *could* do the same thing with a /30 subnet for each tap (so that your routing daemon would get a bunch of /30 routes pointing to your host for all of them), but that would use up a lot more address space.
(I'm not sure what the guest does with 169.254.169.254)
What if you instead set the host to:
$HOST_IP peer $VM_IP/32
and set the guest to:
$VM_IP peer $HOST_IP/32 route add default $HOST_IP
??
I don't use this scheme... If i set $VM_IP peer $HOST_IP/32 on host machine i think kernel recieves packet and drop it =)
No - you would set that on the *guest*, not the host. I setup an LXC container in this manner and everything seemed to work properly.
May be, but in case of qemu i use simple dhcp server and on vm simple dhcp client. It can't assign peer addresses, may be this is works. I don't try. In my setup guest vm does not know host side of network, so it does not need know about peer... Also i can live migrate guest without changing.... (Changes only host side of network)
Anyway, it's important to know if you set the IP config on host and guest to exact mirrors of each other. It seems like the answer is "no", though, so i'm going to make a patch that allows what I was talking about last week:
<interface type='ethernet'> <source> <ip address='HOST_IP' family='ipv4' peer='VM_IP' prefix='32'/> <ip address='VM_GW' family='ipv4' prefix='32'/> </source> <ip address='VM_IP' family='ipv4' peer='HOST_IP' prefix='24'/> <route family='ipv4' address='0.0.0.0' gateway='HOST_IP'/> ... </interface>
On qemu only the address info inside <source> would be used, since we don't have control over the guest's network config. On LXC, we can set both.
Does that sound usable?
Yes, but don't cleanup please <ip address='VM_IP' family='ipv4' peer='HOST_IP' prefix='24'/> in qemu case, because on somedays we can launch dnsmasq or orhet software that can provide dhcp and use this element..
An interesting point - even if libvirt itself doesn't launch the dnsmasq, it could be done by a more intelligent script (one that received the full interface XML on stdin, as I discussed in my last mail), so we should probably just ignore it rather than complaining that it's unsupported...
Thanks for the info!
Yes, i handmade my own dhcp server on golang what listens libvirt hooks and serves needed addresses for needed tap devices. So i have only one daemon that have stateless config (it get it via libvirt xml). So i don't need database or something else. -- Vasiliy Tolstov, e-mail: v.tolstov@yoctocloud.net

On 05/25/2016 11:13 AM, Vasiliy Tolstov wrote:
2016-05-25 18:00 GMT+03:00 Laine Stump <laine@laine.org>:
So $VM_GW is on the same subnet as $VM_IP/24 ? Is that also the same subnet as $HOST_IP? Or is that on a completely different network?
(This is all very useful, because it's pointing out that the config of the two ends definitely aren't mirror images, so we really do need independent settings for both).
VM_GW on the same subnet as PEER , but on host side i apply /32 address, but inside vm /24.
peer only used on host machine to determine on which interface kernel needs to send traffic
Well, you *could* do the same thing with a /30 subnet for each tap (so that your routing daemon would get a bunch of /30 routes pointing to your host for all of them), but that would use up a lot more address space.
(I'm not sure what the guest does with 169.254.169.254)
What if you instead set the host to:
$HOST_IP peer $VM_IP/32
and set the guest to:
$VM_IP peer $HOST_IP/32 route add default $HOST_IP
??
I don't use this scheme... If i set $VM_IP peer $HOST_IP/32 on host machine i think kernel recieves packet and drop it =)
No - you would set that on the *guest*, not the host. I setup an LXC container in this manner and everything seemed to work properly.
May be, but in case of qemu i use simple dhcp server and on vm simple dhcp client. It can't assign peer addresses
Ah, right. I haven't looked, but doubt there is a dhcp option to specify a peer address.
may be this is works. I don't try. In my setup guest vm does not know host side of network, so it does not need know about peer... Also i can live migrate guest without changing.... (Changes only host side of network)
Anyway, it's important to know if you set the IP config on host and guest to exact mirrors of each other. It seems like the answer is "no", though, so i'm going to make a patch that allows what I was talking about last week:
<interface type='ethernet'> <source> <ip address='HOST_IP' family='ipv4' peer='VM_IP' prefix='32'/> <ip address='VM_GW' family='ipv4' prefix='32'/> </source> <ip address='VM_IP' family='ipv4' peer='HOST_IP' prefix='24'/> <route family='ipv4' address='0.0.0.0' gateway='HOST_IP'/> ... </interface>
On qemu only the address info inside <source> would be used, since we don't have control over the guest's network config. On LXC, we can set both.
Does that sound usable? Yes, but don't cleanup please <ip address='VM_IP' family='ipv4' peer='HOST_IP' prefix='24'/> in qemu case, because on somedays we can launch dnsmasq or orhet software that can provide dhcp and use this element..
An interesting point - even if libvirt itself doesn't launch the dnsmasq, it could be done by a more intelligent script (one that received the full interface XML on stdin, as I discussed in my last mail), so we should probably just ignore it rather than complaining that it's unsupported...
Thanks for the info! Yes, i handmade my own dhcp server on golang what listens libvirt hooks and serves needed addresses for needed tap devices.
Yeah, I had considered that if we were to support such a thing in libvirt, it would be best to do it by having a single dnsmasq instance for all tap-only guest interfaces.
So i have only one daemon that have stateless config (it get it via libvirt xml). So i don't need database or something else.
How does it gather than config? With a qemu hook script?

2016-05-25 21:51 GMT+03:00 Laine Stump <laine@laine.org>:
How does it gather than config? With a qemu hook script?
No, libvirit send event when domain starts, i catch it and get domain xml from libvirt via binding. Parse xml element with address and answer to dhcp queries from vm. Also i use this method because libvirt now does not have ability to use netfilter with ethernet devices (i have hand-made patch to remove physdev from default iptables rules, but this is ugly hack). -- Vasiliy Tolstov, e-mail: v.tolstov@yoctocloud.net

Hi Laine The above patch of interface type="ethernet" is for which libvirt version? On Mon, May 16, 2016 at 9:51 PM, Laine Stump <laine@laine.org> wrote:
This is identical to type='bridge', but without the "connect to a bridge" part, so it can be handled by using the same functions (and often even the same cases in switch statements), after renaming virLXCProcessSetupInterfaceBridged() to virLXCProcessInterfaceTap() and enhancing it to skip bridge-related items when brname == NULL.
To be truly useful, we need to support setting the ip address on the host side veth as well as guest side veth (already supported for type='bridge'), as well as setting the peer address for both.
The <script> element isn't supported in this patch because I have no need for it. I'd rather add it after determining it's needed rather than adding it for no reason and than being required to support it forever. ---
I wrote this mostly so that I could experiment with setting the peer addresses of both sides of the veth pair to see what was usable and what we needed to support in terms of setting IP addresses. I had intended to post this patch along with patches to re-enable the peer address setting patches that I reverted just before 1.3.4 was released, but decided that having lxc <interface type='ethernet'> already in might help in any discussion we had about that (since it gives everyone a working example where libvirt has control of both the host-side and guest-side interface config.
This will of course be much more useful once the IP addresses can be set from within libvirt, but all code that is here will remain and, as I said above, it provides a useful platform for experimentation.
src/lxc/lxc_controller.c | 4 +- src/lxc/lxc_driver.c | 16 ++++--- src/lxc/lxc_native.c | 15 +++---- src/lxc/lxc_process.c | 36 +++++++-------- src/lxc/lxc_process.h | 6 +-- tests/lxcconf2xmldata/lxcconf2xml-ethernet.config | 44 ++++++++++++++++++ tests/lxcconf2xmldata/lxcconf2xml-ethernet.xml | 54 +++++++++++++++++++++++ tests/lxcconf2xmltest.c | 1 + tests/lxcxml2xmldata/lxc-ethernet.xml | 42 ++++++++++++++++++ tests/lxcxml2xmltest.c | 1 + 10 files changed, 181 insertions(+), 38 deletions(-) create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-ethernet.config create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-ethernet.xml create mode 100644 tests/lxcxml2xmldata/lxc-ethernet.xml
diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c index 0304354..25f28ea 100644 --- a/src/lxc/lxc_controller.c +++ b/src/lxc/lxc_controller.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2015 Red Hat, Inc. + * Copyright (C) 2010-2016 Red Hat, Inc. * Copyright IBM Corp. 2008 * * lxc_controller.c: linux container process controller @@ -371,6 +371,7 @@ static int virLXCControllerGetNICIndexes(virLXCControllerPtr ctrl) switch (ctrl->def->nets[i]->type) { case VIR_DOMAIN_NET_TYPE_BRIDGE: case VIR_DOMAIN_NET_TYPE_NETWORK: + case VIR_DOMAIN_NET_TYPE_ETHERNET: if (ctrl->def->nets[i]->ifname == NULL) continue; if (virNetDevGetIndex(ctrl->def->nets[i]->ifname, @@ -386,7 +387,6 @@ static int virLXCControllerGetNICIndexes(virLXCControllerPtr ctrl) break;
case VIR_DOMAIN_NET_TYPE_USER: - case VIR_DOMAIN_NET_TYPE_ETHERNET: case VIR_DOMAIN_NET_TYPE_VHOSTUSER: case VIR_DOMAIN_NET_TYPE_SERVER: case VIR_DOMAIN_NET_TYPE_CLIENT: diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index a226850..f811053 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2015 Red Hat, Inc. + * Copyright (C) 2010-2016 Red Hat, Inc. * Copyright IBM Corp. 2008 * * lxc_driver.c: linux container driver functions @@ -4225,15 +4225,15 @@ lxcDomainAttachDeviceNetLive(virConnectPtr conn, _("No bridge name specified")); goto cleanup; } - if (!(veth = virLXCProcessSetupInterfaceBridged(vm->def, - net, - brname))) + if (!(veth = virLXCProcessSetupInterfaceTap(vm->def, net, brname))) goto cleanup; } break; + case VIR_DOMAIN_NET_TYPE_ETHERNET: + if (!(veth = virLXCProcessSetupInterfaceTap(vm->def, net, NULL))) + goto cleanup; + break; case VIR_DOMAIN_NET_TYPE_DIRECT: { - if (!(veth = virLXCProcessSetupInterfaceDirect(conn, - vm->def, - net))) + if (!(veth = virLXCProcessSetupInterfaceDirect(conn, vm->def, net))) goto cleanup; } break; default: @@ -4270,6 +4270,7 @@ lxcDomainAttachDeviceNetLive(virConnectPtr conn, switch (actualType) { case VIR_DOMAIN_NET_TYPE_BRIDGE: case VIR_DOMAIN_NET_TYPE_NETWORK: + case VIR_DOMAIN_NET_TYPE_ETHERNET: ignore_value(virNetDevVethDelete(veth)); break;
@@ -4695,6 +4696,7 @@ lxcDomainDetachDeviceNetLive(virDomainObjPtr vm, switch (actualType) { case VIR_DOMAIN_NET_TYPE_BRIDGE: case VIR_DOMAIN_NET_TYPE_NETWORK: + case VIR_DOMAIN_NET_TYPE_ETHERNET: if (virNetDevVethDelete(detach->ifname) < 0) { virDomainAuditNet(vm, detach, NULL, "detach", false); goto cleanup; diff --git a/src/lxc/lxc_native.c b/src/lxc/lxc_native.c index 31ffce7..0bea32e 100644 --- a/src/lxc/lxc_native.c +++ b/src/lxc/lxc_native.c @@ -360,14 +360,13 @@ lxcCreateNetDef(const char *type, net->mac = macAddr;
if (STREQ(type, "veth")) { - if (!linkdev) - goto error; - - net->type = VIR_DOMAIN_NET_TYPE_BRIDGE; - - if (VIR_STRDUP(net->data.bridge.brname, linkdev) < 0) - goto error; - + if (linkdev) { + net->type = VIR_DOMAIN_NET_TYPE_BRIDGE; + if (VIR_STRDUP(net->data.bridge.brname, linkdev) < 0) + goto error; + } else { + net->type = VIR_DOMAIN_NET_TYPE_ETHERNET; + } } else if (STREQ(type, "macvlan")) { net->type = VIR_DOMAIN_NET_TYPE_DIRECT;
diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c index 8981d9a..f8a0c32 100644 --- a/src/lxc/lxc_process.c +++ b/src/lxc/lxc_process.c @@ -256,9 +256,9 @@ static void virLXCProcessCleanup(virLXCDriverPtr driver, }
-char *virLXCProcessSetupInterfaceBridged(virDomainDefPtr vm, - virDomainNetDefPtr net, - const char *brname) +char *virLXCProcessSetupInterfaceTap(virDomainDefPtr vm, + virDomainNetDefPtr net, + const char *brname) { char *ret = NULL; char *parentVeth; @@ -277,13 +277,15 @@ char *virLXCProcessSetupInterfaceBridged(virDomainDefPtr vm, if (virNetDevSetMAC(containerVeth, &net->mac) < 0) goto cleanup;
- if (vport && vport->virtPortType == VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH) { - if (virNetDevOpenvswitchAddPort(brname, parentVeth, &net->mac, - vm->uuid, vport, virDomainNetGetActualVlan(net)) < 0) - goto cleanup; - } else { - if (virNetDevBridgeAddPort(brname, parentVeth) < 0) - goto cleanup; + if (brname) { + if (vport && vport->virtPortType == VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH) { + if (virNetDevOpenvswitchAddPort(brname, parentVeth, &net->mac, vm->uuid, + vport, virDomainNetGetActualVlan(net)) < 0) + goto cleanup; + } else { + if (virNetDevBridgeAddPort(brname, parentVeth) < 0) + goto cleanup; + } }
if (virNetDevSetOnline(parentVeth, true) < 0) @@ -546,20 +548,18 @@ static int virLXCProcessSetupInterfaces(virConnectPtr conn, _("No bridge name specified")); goto cleanup; } - if (!(veth = virLXCProcessSetupInterfaceBridged(def, - net, - brname))) + if (!(veth = virLXCProcessSetupInterfaceTap(def, net, brname))) goto cleanup; } break; - + case VIR_DOMAIN_NET_TYPE_ETHERNET: + if (!(veth = virLXCProcessSetupInterfaceTap(def, net, NULL))) + goto cleanup; + break; case VIR_DOMAIN_NET_TYPE_DIRECT: - if (!(veth = virLXCProcessSetupInterfaceDirect(conn, - def, - net))) + if (!(veth = virLXCProcessSetupInterfaceDirect(conn, def, net))) goto cleanup; break;
- case VIR_DOMAIN_NET_TYPE_ETHERNET: case VIR_DOMAIN_NET_TYPE_USER: case VIR_DOMAIN_NET_TYPE_VHOSTUSER: case VIR_DOMAIN_NET_TYPE_SERVER: diff --git a/src/lxc/lxc_process.h b/src/lxc/lxc_process.h index b6c8083..fcb50a8 100644 --- a/src/lxc/lxc_process.h +++ b/src/lxc/lxc_process.h @@ -47,9 +47,9 @@ void virLXCProcessAutostartAll(virLXCDriverPtr driver); int virLXCProcessReconnectAll(virLXCDriverPtr driver, virDomainObjListPtr doms);
-char *virLXCProcessSetupInterfaceBridged(virDomainDefPtr vm, - virDomainNetDefPtr net, - const char *brname); +char *virLXCProcessSetupInterfaceTap(virDomainDefPtr vm, + virDomainNetDefPtr net, + const char *brname); char *virLXCProcessSetupInterfaceDirect(virConnectPtr conn, virDomainDefPtr def, virDomainNetDefPtr net); diff --git a/tests/lxcconf2xmldata/lxcconf2xml-ethernet.config b/tests/lxcconf2xmldata/lxcconf2xml-ethernet.config new file mode 100644 index 0000000..d39917d --- /dev/null +++ b/tests/lxcconf2xmldata/lxcconf2xml-ethernet.config @@ -0,0 +1,44 @@ +# Template used to create this container: opensuse +# Template script checksum (SHA-1): 27307e0a95bd81b2c0bd82d6f87fdbe83be075ef + +lxc.network.type = veth +lxc.network.flags = up +lxc.network.hwaddr = 02:00:15:8f:05:c1 +lxc.network.name = eth0 +lxc.network.ipv4 = 192.168.122.2/24 +lxc.network.ipv4.gateway = 192.168.122.1 +lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3596/64 +lxc.network.ipv6.gateway = 2003:db8:1:0:214:1234:fe0b:3595 + +#remove next line if host DNS configuration should not be available to container +lxc.mount.entry = proc proc proc nodev,noexec,nosuid 0 0 +lxc.mount.entry = sysfs sys sysfs defaults 0 0 +lxc.mount.entry = tmpfs run tmpfs size=8m,mode=0755,nodev,nosuid 0 0 +lxc.mount.entry = /etc/resolv.conf etc/resolv.conf none bind,ro 0 0 +lxc.rootfs = /var/lib/lxc/migrate_test/rootfs +lxc.utsname = migrate_test +lxc.arch = x86 +lxc.autodev=1 +lxc.tty = 2 +lxc.pts = 1024 +lxc.cap.drop = sys_module mac_admin mac_override mknod + +# When using LXC with apparmor, uncomment the next line to run unconfined: +#lxc.aa_profile = unconfined + +lxc.cgroup.devices.deny = a +# /dev/null and zero +lxc.cgroup.devices.allow = c 1:3 rwm +lxc.cgroup.devices.allow = c 1:5 rwm +# consoles +lxc.cgroup.devices.allow = c 5:1 rwm +lxc.cgroup.devices.allow = c 5:0 rwm +lxc.cgroup.devices.allow = c 4:0 rwm +lxc.cgroup.devices.allow = c 4:1 rwm +# /dev/{,u}random +lxc.cgroup.devices.allow = c 1:9 rwm +lxc.cgroup.devices.allow = c 1:8 rwm +lxc.cgroup.devices.allow = c 136:* rwm +lxc.cgroup.devices.allow = c 5:2 rwm +# rtc +lxc.cgroup.devices.allow = c 254:0 rwm diff --git a/tests/lxcconf2xmldata/lxcconf2xml-ethernet.xml b/tests/lxcconf2xmldata/lxcconf2xml-ethernet.xml new file mode 100644 index 0000000..24b017a --- /dev/null +++ b/tests/lxcconf2xmldata/lxcconf2xml-ethernet.xml @@ -0,0 +1,54 @@ +<domain type='lxc'> + <name>migrate_test</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>65536</memory> + <currentMemory unit='KiB'>65536</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='i686'>exe</type> + <init>/sbin/init</init> + </os> + <features> + <capabilities policy='allow'> + <mac_admin state='off'/> + <mac_override state='off'/> + <mknod state='off'/> + <sys_module state='off'/> + </capabilities> + </features> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/libexec/libvirt_lxc</emulator> + <filesystem type='mount' accessmode='passthrough'> + <source dir='/var/lib/lxc/migrate_test/rootfs'/> + <target dir='/'/> + </filesystem> + <filesystem type='ram' accessmode='passthrough'> + <source usage='8192' units='KiB'/> + <target dir='/run'/> + </filesystem> + <filesystem type='mount' accessmode='passthrough'> + <source dir='/etc/resolv.conf'/> + <target dir='/etc/resolv.conf'/> + <readonly/> + </filesystem> + <interface type='ethernet'> + <mac address='02:00:15:8f:05:c1'/> + <ip address='192.168.122.2' family='ipv4' prefix='24'/> + <ip address='2003:db8:1:0:214:1234:fe0b:3596' family='ipv6' prefix='64'/> + <route family='ipv4' address='0.0.0.0' gateway='192.168.122.1'/> + <route family='ipv6' address='::' gateway='2003:db8:1:0:214:1234:fe0b:3595'/> + <guest dev='eth0'/> + <link state='up'/> + </interface> + <console type='pty'> + <target type='lxc' port='0'/> + </console> + <console type='pty'> + <target type='lxc' port='1'/> + </console> + </devices> +</domain> diff --git a/tests/lxcconf2xmltest.c b/tests/lxcconf2xmltest.c index 83895cd..7a0893e 100644 --- a/tests/lxcconf2xmltest.c +++ b/tests/lxcconf2xmltest.c @@ -119,6 +119,7 @@ mymain(void) DO_TEST("cputune", false); DO_TEST("cpusettune", false); DO_TEST("blkiotune", false); + DO_TEST("ethernet", false);
virObjectUnref(xmlopt); virObjectUnref(caps); diff --git a/tests/lxcxml2xmldata/lxc-ethernet.xml b/tests/lxcxml2xmldata/lxc-ethernet.xml new file mode 100644 index 0000000..6c4a739 --- /dev/null +++ b/tests/lxcxml2xmldata/lxc-ethernet.xml @@ -0,0 +1,42 @@ +<domain type='lxc'> + <name>8675309</name> + <uuid>e21987a5-e98e-9c99-0e35-803e4d9ad1fe</uuid> + <memory unit='KiB'>1048576</memory> + <currentMemory unit='KiB'>1048576</currentMemory> + <vcpu placement='static'>1</vcpu> + <resource> + <partition>/machine</partition> + </resource> + <os> + <type arch='x86_64'>exe</type> + <init>/sbin/init</init> + </os> + <idmap> + <uid start='0' target='100000' count='100000'/> + <gid start='0' target='100000' count='100000'/> + </idmap> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>restart</on_crash> + <devices> + <emulator>/usr/libexec/libvirt_lxc</emulator> + <filesystem type='mount' accessmode='passthrough'> + <source dir='/mach/8675309'/> + <target dir='/'/> + </filesystem> + <interface type='ethernet'> + <mac address='00:16:3e:0f:ef:8a'/> + <ip address='192.168.122.12' family='ipv4' prefix='24'/> + <ip address='192.168.122.13' family='ipv4' prefix='24'/> + <route family='ipv4' address='0.0.0.0' gateway='192.168.122.1'/> + <route family='ipv4' address='192.168.124.0' prefix='24' gateway='192.168.124.1'/> + <target dev='veth0'/> + <guest dev='eth2'/> + </interface> + <console type='pty'> + <target type='lxc' port='0'/> + </console> + </devices> + <seclabel type='none'/> +</domain> diff --git a/tests/lxcxml2xmltest.c b/tests/lxcxml2xmltest.c index fec0142..001aa8d 100644 --- a/tests/lxcxml2xmltest.c +++ b/tests/lxcxml2xmltest.c @@ -94,6 +94,7 @@ mymain(void) DO_TEST("idmap"); DO_TEST("capabilities"); DO_TEST("sharenet"); + DO_TEST("ethernet"); DO_TEST_FULL("filesystem-root", 0, false, VIR_DOMAIN_DEF_PARSE_SKIP_OSTYPE_CHECKS);
-- 2.5.5
-- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
participants (4)
-
Cole Robinson
-
Laine Stump
-
sonia verma
-
Vasiliy Tolstov