]> xenbits.xensource.com Git - libvirt.git/commitdiff
lxc: support <interface type='ethernet'>
authorLaine Stump <laine@laine.org>
Fri, 13 May 2016 17:20:54 +0000 (13:20 -0400)
committerLaine Stump <laine@laine.org>
Tue, 24 May 2016 19:21:05 +0000 (15:21 -0400)
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 (supported by type='ethernet' in qemu) isn't
supported in this patch. An error is logged at domain start time if it
is encountered. This may be changed in a later patch.

src/lxc/lxc_controller.c
src/lxc/lxc_driver.c
src/lxc/lxc_native.c
src/lxc/lxc_process.c
src/lxc/lxc_process.h
tests/lxcconf2xmldata/lxcconf2xml-ethernet.config [new file with mode: 0644]
tests/lxcconf2xmldata/lxcconf2xml-ethernet.xml [new file with mode: 0644]
tests/lxcconf2xmltest.c
tests/lxcxml2xmldata/lxc-ethernet.xml [new file with mode: 0644]
tests/lxcxml2xmltest.c

index dc3921b70e8d5f26165e201f3e1aeefaf6ae29c8..8b428036cadcca5f7afac822d952c635498bb5d6 100644 (file)
@@ -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:
index 4aef78d73e7081c204e53cd0e7ddd16cf93cc719..d6908864be075bf7f8719fed22fba2616bdf2290 100644 (file)
@@ -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
@@ -4278,6 +4278,9 @@ lxcDomainAttachDeviceNetLive(virConnectPtr conn,
         goto cleanup;
     }
 
+    if (virLXCProcessValidateInterface(net) < 0)
+       return -1;
+
     /* preallocate new slot for device */
     if (VIR_REALLOC_N(vm->def->nets, vm->def->nnets+1) < 0)
         return -1;
@@ -4300,15 +4303,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:
@@ -4345,6 +4348,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;
 
@@ -4770,6 +4774,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;
index 31ffce7d9be269f9d02ab3f043fc6d32445a7a1a..0bea32e48392e8f9979cebc83e384de08c244464 100644 (file)
@@ -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;
 
index 9f607d8a9d3ece04d922cc5e3740257122fcd4cc..17fbc5f6e637c5104b5d5fc1d9bdd3d1a41b884f 100644 (file)
@@ -256,9 +256,22 @@ static void virLXCProcessCleanup(virLXCDriverPtr driver,
 }
 
 
-char *virLXCProcessSetupInterfaceBridged(virDomainDefPtr vm,
-                                         virDomainNetDefPtr net,
-                                         const char *brname)
+int
+virLXCProcessValidateInterface(virDomainNetDefPtr net)
+{
+    if (net->script) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                       _("scripts are not supported on LXC network interfaces"));
+        return -1;
+    }
+    return 0;
+}
+
+
+char *
+virLXCProcessSetupInterfaceTap(virDomainDefPtr vm,
+                               virDomainNetDefPtr net,
+                               const char *brname)
 {
     char *ret = NULL;
     char *parentVeth;
@@ -277,13 +290,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)
@@ -530,6 +545,10 @@ static int virLXCProcessSetupInterfaces(virConnectPtr conn,
          * to the one defined in the network definition.
          */
         net = def->nets[i];
+
+        if (virLXCProcessValidateInterface(net) < 0)
+            return -1;
+
         if (networkAllocateActualDevice(def, net) < 0)
             goto cleanup;
 
@@ -546,20 +565,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:
index b6c8083e29dacc9a7b3b7917a72fa1c258e456f3..d78cddef4b18840986a8518a8186edc2540531b9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010-2012 Red Hat, Inc.
+ * Copyright (C) 2010-2012, 2016 Red Hat, Inc.
  * Copyright IBM Corp. 2008
  *
  * lxc_process.h: LXC process lifecycle management
@@ -47,9 +47,10 @@ void virLXCProcessAutostartAll(virLXCDriverPtr driver);
 int virLXCProcessReconnectAll(virLXCDriverPtr driver,
                               virDomainObjListPtr doms);
 
-char *virLXCProcessSetupInterfaceBridged(virDomainDefPtr vm,
-                                         virDomainNetDefPtr net,
-                                         const char *brname);
+int virLXCProcessValidateInterface(virDomainNetDefPtr net);
+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 (file)
index 0000000..d39917d
--- /dev/null
@@ -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 (file)
index 0000000..24b017a
--- /dev/null
@@ -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>
index 83895cd4ad1c61dc564603395a31785d32e1ca1b..7a0893eb31a5d0604c654e061210d0eb7c77002b 100644 (file)
@@ -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 (file)
index 0000000..6c4a739
--- /dev/null
@@ -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>
index fec0142b16f87a661d6a4fcd95ac39f055085adc..001aa8d123b71e5f3fc09a996068a65216620a7d 100644 (file)
@@ -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);