diff --git a/9265f8ab-apparmor-lxc-rework.patch b/9265f8ab-apparmor-lxc-rework.patch new file mode 100644 index 0000000..11c468d --- /dev/null +++ b/9265f8ab-apparmor-lxc-rework.patch @@ -0,0 +1,358 @@ +From 9265f8ab67dc14fe89a26efd5c22b156d3168fd6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?C=C3=A9dric=20Bosdonnat?= +Date: Tue, 15 Jul 2014 11:02:50 +0200 +Subject: [PATCH] Rework lxc apparmor profile + +Rework the apparmor lxc profile abstraction to mimic ubuntu's container-default. +This profile allows quite a lot, but strives to restrict access to +dangerous resources. + +Removing the explicit authorizations to bash, systemd and cron files, +forces them to keep the lxc profile for all applications inside the +container. PUx permissions where leading to running systemd (and others +tasks) unconfined. + +Put the generic files, network and capabilities restrictions directly +in the TEMPLATE.lxc: this way, users can restrict them on a per +container basis. +--- + examples/apparmor/Makefile.am | 6 +- + examples/apparmor/TEMPLATE.lxc | 15 ++++ + examples/apparmor/{TEMPLATE => TEMPLATE.qemu} | 2 +- + examples/apparmor/libvirt-lxc | 119 +++++++++++++++++++++++--- + src/security/security_apparmor.c | 21 +++-- + src/security/virt-aa-helper.c | 29 +------ + 6 files changed, 149 insertions(+), 43 deletions(-) + create mode 100644 examples/apparmor/TEMPLATE.lxc + rename examples/apparmor/{TEMPLATE => TEMPLATE.qemu} (75%) + +Index: libvirt-1.2.6/examples/apparmor/Makefile.am +=================================================================== +--- libvirt-1.2.6.orig/examples/apparmor/Makefile.am ++++ libvirt-1.2.6/examples/apparmor/Makefile.am +@@ -15,7 +15,8 @@ + ## . + + EXTRA_DIST= \ +- TEMPLATE \ ++ TEMPLATE.qemu \ ++ TEMPLATE.lxc \ + libvirt-qemu \ + libvirt-lxc \ + usr.lib.libvirt.virt-aa-helper \ +@@ -36,6 +37,7 @@ abstractions_DATA = \ + + templatesdir = $(apparmordir)/libvirt + templates_DATA = \ +- TEMPLATE \ ++ TEMPLATE.qemu \ ++ TEMPLATE.lxc \ + $(NULL) + endif WITH_APPARMOR_PROFILES +Index: libvirt-1.2.6/examples/apparmor/TEMPLATE.lxc +=================================================================== +--- /dev/null ++++ libvirt-1.2.6/examples/apparmor/TEMPLATE.lxc +@@ -0,0 +1,15 @@ ++# ++# This profile is for the domain whose UUID matches this file. ++# ++ ++#include ++ ++profile LIBVIRT_TEMPLATE { ++ #include ++ ++ # Globally allows everything to run under this profile ++ # These can be narrowed depending on the container's use. ++ file, ++ capability, ++ network, ++} +Index: libvirt-1.2.6/examples/apparmor/TEMPLATE +=================================================================== +--- libvirt-1.2.6.orig/examples/apparmor/TEMPLATE ++++ /dev/null +@@ -1,9 +0,0 @@ +-# +-# This profile is for the domain whose UUID matches this file. +-# +- +-#include +- +-profile LIBVIRT_TEMPLATE { +- #include +-} +Index: libvirt-1.2.6/examples/apparmor/TEMPLATE.qemu +=================================================================== +--- /dev/null ++++ libvirt-1.2.6/examples/apparmor/TEMPLATE.qemu +@@ -0,0 +1,9 @@ ++# ++# This profile is for the domain whose UUID matches this file. ++# ++ ++#include ++ ++profile LIBVIRT_TEMPLATE { ++ #include ++} +Index: libvirt-1.2.6/examples/apparmor/libvirt-lxc +=================================================================== +--- libvirt-1.2.6.orig/examples/apparmor/libvirt-lxc ++++ libvirt-1.2.6/examples/apparmor/libvirt-lxc +@@ -2,16 +2,115 @@ + + #include + +- # Needed for lxc-enter-namespace +- capability sys_admin, +- capability sys_chroot, +- +- # Added for lxc-enter-namespace --cmd /bin/bash +- /bin/bash PUx, +- +- /usr/sbin/cron PUx, +- /usr/lib/systemd/systemd PUx, +- +- /usr/lib/libsystemd-*.so.* mr, +- /usr/lib/libudev-*.so.* mr, +- /etc/ld.so.cache mr, ++ umount, ++ ++ # ignore DENIED message on / remount ++ deny mount options=(ro, remount) -> /, ++ ++ # allow tmpfs mounts everywhere ++ mount fstype=tmpfs, ++ ++ # allow mqueue mounts everywhere ++ mount fstype=mqueue, ++ ++ # allow fuse mounts everywhere ++ mount fstype=fuse.*, ++ ++ # deny writes in /proc/sys/fs but allow binfmt_misc to be mounted ++ mount fstype=binfmt_misc -> /proc/sys/fs/binfmt_misc/, ++ deny @{PROC}/sys/fs/** wklx, ++ ++ # allow efivars to be mounted, writing to it will be blocked though ++ mount fstype=efivarfs -> /sys/firmware/efi/efivars/, ++ ++ # block some other dangerous paths ++ deny @{PROC}/sysrq-trigger rwklx, ++ deny @{PROC}/mem rwklx, ++ deny @{PROC}/kmem rwklx, ++ ++ # deny writes in /sys except for /sys/fs/cgroup, also allow ++ # fusectl, securityfs and debugfs to be mounted there (read-only) ++ mount fstype=fusectl -> /sys/fs/fuse/connections/, ++ mount fstype=securityfs -> /sys/kernel/security/, ++ mount fstype=debugfs -> /sys/kernel/debug/, ++ mount fstype=proc -> /proc/, ++ mount fstype=sysfs -> /sys/, ++ deny /sys/firmware/efi/efivars/** rwklx, ++ deny /sys/kernel/security/** rwklx, ++ ++ # generated by: lxc-generate-aa-rules.py container-rules.base ++ deny /proc/sys/[^kn]*{,/**} wklx, ++ deny /proc/sys/k[^e]*{,/**} wklx, ++ deny /proc/sys/ke[^r]*{,/**} wklx, ++ deny /proc/sys/ker[^n]*{,/**} wklx, ++ deny /proc/sys/kern[^e]*{,/**} wklx, ++ deny /proc/sys/kerne[^l]*{,/**} wklx, ++ deny /proc/sys/kernel/[^smhd]*{,/**} wklx, ++ deny /proc/sys/kernel/d[^o]*{,/**} wklx, ++ deny /proc/sys/kernel/do[^m]*{,/**} wklx, ++ deny /proc/sys/kernel/dom[^a]*{,/**} wklx, ++ deny /proc/sys/kernel/doma[^i]*{,/**} wklx, ++ deny /proc/sys/kernel/domai[^n]*{,/**} wklx, ++ deny /proc/sys/kernel/domain[^n]*{,/**} wklx, ++ deny /proc/sys/kernel/domainn[^a]*{,/**} wklx, ++ deny /proc/sys/kernel/domainna[^m]*{,/**} wklx, ++ deny /proc/sys/kernel/domainnam[^e]*{,/**} wklx, ++ deny /proc/sys/kernel/domainname?*{,/**} wklx, ++ deny /proc/sys/kernel/h[^o]*{,/**} wklx, ++ deny /proc/sys/kernel/ho[^s]*{,/**} wklx, ++ deny /proc/sys/kernel/hos[^t]*{,/**} wklx, ++ deny /proc/sys/kernel/host[^n]*{,/**} wklx, ++ deny /proc/sys/kernel/hostn[^a]*{,/**} wklx, ++ deny /proc/sys/kernel/hostna[^m]*{,/**} wklx, ++ deny /proc/sys/kernel/hostnam[^e]*{,/**} wklx, ++ deny /proc/sys/kernel/hostname?*{,/**} wklx, ++ deny /proc/sys/kernel/m[^s]*{,/**} wklx, ++ deny /proc/sys/kernel/ms[^g]*{,/**} wklx, ++ deny /proc/sys/kernel/msg*/** wklx, ++ deny /proc/sys/kernel/s[^he]*{,/**} wklx, ++ deny /proc/sys/kernel/se[^m]*{,/**} wklx, ++ deny /proc/sys/kernel/sem*/** wklx, ++ deny /proc/sys/kernel/sh[^m]*{,/**} wklx, ++ deny /proc/sys/kernel/shm*/** wklx, ++ deny /proc/sys/kernel?*{,/**} wklx, ++ deny /proc/sys/n[^e]*{,/**} wklx, ++ deny /proc/sys/ne[^t]*{,/**} wklx, ++ deny /proc/sys/net?*{,/**} wklx, ++ deny /sys/[^fdc]*{,/**} wklx, ++ deny /sys/c[^l]*{,/**} wklx, ++ deny /sys/cl[^a]*{,/**} wklx, ++ deny /sys/cla[^s]*{,/**} wklx, ++ deny /sys/clas[^s]*{,/**} wklx, ++ deny /sys/class/[^n]*{,/**} wklx, ++ deny /sys/class/n[^e]*{,/**} wklx, ++ deny /sys/class/ne[^t]*{,/**} wklx, ++ deny /sys/class/net?*{,/**} wklx, ++ deny /sys/class?*{,/**} wklx, ++ deny /sys/d[^e]*{,/**} wklx, ++ deny /sys/de[^v]*{,/**} wklx, ++ deny /sys/dev[^i]*{,/**} wklx, ++ deny /sys/devi[^c]*{,/**} wklx, ++ deny /sys/devic[^e]*{,/**} wklx, ++ deny /sys/device[^s]*{,/**} wklx, ++ deny /sys/devices/[^v]*{,/**} wklx, ++ deny /sys/devices/v[^i]*{,/**} wklx, ++ deny /sys/devices/vi[^r]*{,/**} wklx, ++ deny /sys/devices/vir[^t]*{,/**} wklx, ++ deny /sys/devices/virt[^u]*{,/**} wklx, ++ deny /sys/devices/virtu[^a]*{,/**} wklx, ++ deny /sys/devices/virtua[^l]*{,/**} wklx, ++ deny /sys/devices/virtual/[^n]*{,/**} wklx, ++ deny /sys/devices/virtual/n[^e]*{,/**} wklx, ++ deny /sys/devices/virtual/ne[^t]*{,/**} wklx, ++ deny /sys/devices/virtual/net?*{,/**} wklx, ++ deny /sys/devices/virtual?*{,/**} wklx, ++ deny /sys/devices?*{,/**} wklx, ++ deny /sys/f[^s]*{,/**} wklx, ++ deny /sys/fs/[^c]*{,/**} wklx, ++ deny /sys/fs/c[^g]*{,/**} wklx, ++ deny /sys/fs/cg[^r]*{,/**} wklx, ++ deny /sys/fs/cgr[^o]*{,/**} wklx, ++ deny /sys/fs/cgro[^u]*{,/**} wklx, ++ deny /sys/fs/cgrou[^p]*{,/**} wklx, ++ deny /sys/fs/cgroup?*{,/**} wklx, ++ deny /sys/fs?*{,/**} wklx, +Index: libvirt-1.2.6/src/security/security_apparmor.c +=================================================================== +--- libvirt-1.2.6.orig/src/security/security_apparmor.c ++++ libvirt-1.2.6/src/security/security_apparmor.c +@@ -351,26 +351,37 @@ AppArmorSetSecuritySCSILabel(virSCSIDevi + static int + AppArmorSecurityManagerProbe(const char *virtDriver ATTRIBUTE_UNUSED) + { +- char *template = NULL; ++ char *template_qemu = NULL; ++ char *template_lxc = NULL; + int rc = SECURITY_DRIVER_DISABLE; + + if (use_apparmor() < 0) + return rc; + + /* see if template file exists */ +- if (virAsprintf(&template, "%s/TEMPLATE", ++ if (virAsprintf(&template_qemu, "%s/TEMPLATE.qemu", + APPARMOR_DIR "/libvirt") == -1) + return rc; + +- if (!virFileExists(template)) { ++ if (virAsprintf(&template_lxc, "%s/TEMPLATE.lxc", ++ APPARMOR_DIR "/libvirt") == -1) ++ goto cleanup; ++ ++ if (!virFileExists(template_qemu)) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("template \'%s\' does not exist"), template_qemu); ++ goto cleanup; ++ } ++ if (!virFileExists(template_lxc)) { + virReportError(VIR_ERR_INTERNAL_ERROR, +- _("template \'%s\' does not exist"), template); ++ _("template \'%s\' does not exist"), template_lxc); + goto cleanup; + } + rc = SECURITY_DRIVER_ENABLE; + + cleanup: +- VIR_FREE(template); ++ VIR_FREE(template_qemu); ++ VIR_FREE(template_lxc); + + return rc; + } +Index: libvirt-1.2.6/src/security/virt-aa-helper.c +=================================================================== +--- libvirt-1.2.6.orig/src/security/virt-aa-helper.c ++++ libvirt-1.2.6/src/security/virt-aa-helper.c +@@ -336,24 +336,20 @@ create_profile(const char *profile, cons + char *pcontent = NULL; + char *replace_name = NULL; + char *replace_files = NULL; +- char *replace_driver = NULL; + const char *template_name = "\nprofile LIBVIRT_TEMPLATE"; + const char *template_end = "\n}"; +- const char *template_driver = "libvirt-driver"; + int tlen, plen; + int fd; + int rc = -1; +- const char *driver_name = "qemu"; +- +- if (virtType == VIR_DOMAIN_VIRT_LXC) +- driver_name = "lxc"; + + if (virFileExists(profile)) { + vah_error(NULL, 0, _("profile exists")); + goto end; + } + +- if (virAsprintfQuiet(&template, "%s/TEMPLATE", APPARMOR_DIR "/libvirt") < 0) { ++ ++ if (virAsprintfQuiet(&template, "%s/TEMPLATE.%s", APPARMOR_DIR "/libvirt", ++ virDomainVirtTypeToString(virtType)) < 0) { + vah_error(NULL, 0, _("template name exceeds maximum length")); + goto end; + } +@@ -378,11 +374,6 @@ create_profile(const char *profile, cons + goto clean_tcontent; + } + +- if (strstr(tcontent, template_driver) == NULL) { +- vah_error(NULL, 0, _("no replacement string in template")); +- goto clean_tcontent; +- } +- + /* '\nprofile \0' */ + if (virAsprintfQuiet(&replace_name, "\nprofile %s", profile_name) == -1) { + vah_error(NULL, 0, _("could not allocate memory for profile name")); +@@ -397,15 +388,7 @@ create_profile(const char *profile, cons + goto clean_tcontent; + } + +- /* 'libvirt-\0' */ +- if (virAsprintfQuiet(&replace_driver, "libvirt-%s", driver_name) == -1) { +- vah_error(NULL, 0, _("could not allocate memory for profile driver")); +- VIR_FREE(replace_driver); +- goto clean_tcontent; +- } +- +- plen = tlen + strlen(replace_name) - strlen(template_name) + +- strlen(replace_driver) - strlen(template_driver) + 1; ++ plen = tlen + strlen(replace_name) - strlen(template_name) + 1; + + if (virtType != VIR_DOMAIN_VIRT_LXC) + plen += strlen(replace_files) - strlen(template_end); +@@ -422,9 +405,6 @@ create_profile(const char *profile, cons + pcontent[0] = '\0'; + strcpy(pcontent, tcontent); + +- if (replace_string(pcontent, plen, template_driver, replace_driver) < 0) +- goto clean_all; +- + if (replace_string(pcontent, plen, template_name, replace_name) < 0) + goto clean_all; + +@@ -455,7 +435,6 @@ create_profile(const char *profile, cons + clean_replace: + VIR_FREE(replace_name); + VIR_FREE(replace_files); +- VIR_FREE(replace_driver); + clean_tcontent: + VIR_FREE(tcontent); + end: diff --git a/9b1e4cd5-skip-useless-apparmor-files.patch b/9b1e4cd5-skip-useless-apparmor-files.patch new file mode 100644 index 0000000..4c606ee --- /dev/null +++ b/9b1e4cd5-skip-useless-apparmor-files.patch @@ -0,0 +1,29 @@ +commit 9b1e4cd5034225c7f750b38968b576c966c51d75 +Author: Cédric Bosdonnat +Date: Wed Jul 9 16:15:02 2014 +0200 + + Don't output libvirt-UUID.files for LXC apparmor profiles + +--- + src/security/virt-aa-helper.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c +index b5f66f3..c8f17f9 100644 +--- a/src/security/virt-aa-helper.c ++++ b/src/security/virt-aa-helper.c +@@ -1342,10 +1342,13 @@ main(int argc, char **argv) + vah_info(include_file); + vah_info(included_files); + rc = 0; ++ } else if (ctl->def->virtType == VIR_DOMAIN_VIRT_LXC) { ++ rc = 0; + } else if ((rc = update_include_file(include_file, + included_files, +- ctl->append)) != 0) ++ ctl->append)) != 0) { + goto cleanup; ++ } + + + /* create the profile from TEMPLATE */ diff --git a/dba3432b-virt-lxc-convert-fix.patch b/dba3432b-virt-lxc-convert-fix.patch new file mode 100644 index 0000000..5dc7ad8 --- /dev/null +++ b/dba3432b-virt-lxc-convert-fix.patch @@ -0,0 +1,22 @@ +From 236a18572216a35f742824f4056108245fac3082 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?C=C3=A9dric=20Bosdonnat?= +Date: Fri, 4 Jul 2014 15:57:17 +0200 +Subject: [PATCH] virt-lxc-convert: make free return values in bytes + +--- + examples/lxcconvert/virt-lxc-convert | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: libvirt-1.2.5/examples/lxcconvert/virt-lxc-convert +=================================================================== +--- libvirt-1.2.5.orig/examples/lxcconvert/virt-lxc-convert ++++ libvirt-1.2.5/examples/lxcconvert/virt-lxc-convert +@@ -64,7 +64,7 @@ if test -r "$fstab"; then + sed 's/^\([^#]\)/lxc.mount.entry = \1/' "$fstab" >>"${conf_new}" + fi + +-memory=$(free | sed -n '/Mem:/s/ \+/ /gp' | cut -f 2 -d ' ') ++memory=$(free -b | sed -n '/Mem:/s/ \+/ /gp' | cut -f 2 -d ' ') + default_tmpfs="size=$((memory/2))" + + # Do we have tmpfs without size param? diff --git a/install-apparmor-profiles.patch b/install-apparmor-profiles.patch index 9bb3c88..4904a53 100644 --- a/install-apparmor-profiles.patch +++ b/install-apparmor-profiles.patch @@ -2,8 +2,8 @@ Index: libvirt-1.2.6/examples/apparmor/Makefile.am =================================================================== --- libvirt-1.2.6.orig/examples/apparmor/Makefile.am +++ libvirt-1.2.6/examples/apparmor/Makefile.am -@@ -18,10 +18,22 @@ EXTRA_DIST= \ - TEMPLATE \ +@@ -19,10 +19,22 @@ EXTRA_DIST= \ + TEMPLATE.lxc \ libvirt-qemu \ libvirt-lxc \ - usr.lib.libvirt.virt-aa-helper \ diff --git a/libvirt.changes b/libvirt.changes index b2c6c77..a524ba4 100644 --- a/libvirt.changes +++ b/libvirt.changes @@ -1,3 +1,30 @@ +------------------------------------------------------------------- +Wed Jul 16 12:07:33 UTC 2014 - cbosdonnat@suse.com + +- lxc AppArmor profile now only restricting potentially dangerous + accesses. fdo#886460 +- Add virt-lxc-convert to libvirt-daemon-driver-lxc package + +- added patches: + * 9265f8ab-apparmor-lxc-rework.patch + * 9b1e4cd5-skip-useless-apparmor-files.patch +------------------------------------------------------------------- +Wed Jul 16 11:40:35 UTC 2014 - cbosdonnat@suse.com + +- virt-lxc-convert: force free to output values in bytes + +- added patches: + * dba3432b-virt-lxc-convert-fix.patch + +------------------------------------------------------------------- +Wed Jul 16 11:33:31 UTC 2014 - cbosdonnat@suse.com + +- lxc: allow setting a custom name for container NICs as LXC is + is able to do it. + lxc-net-target-name.patch, + lxc-net-target-name-conversion.patch, + lxc-net-target-name-doc.patch + ------------------------------------------------------------------- Wed Jul 2 12:49:36 MDT 2014 - jfehlig@suse.com diff --git a/libvirt.spec b/libvirt.spec index 2e8ffed..a6f4984 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -428,6 +428,9 @@ Source1: libvirtd.init Source2: libvirtd-relocation-server.fw Source99: baselibs.conf # Upstream patches +Patch0: dba3432b-virt-lxc-convert-fix.patch +Patch1: 9b1e4cd5-skip-useless-apparmor-files.patch +Patch2: 9265f8ab-apparmor-lxc-rework.patch # Need to go upstream Patch100: xen-name-for-devid.patch Patch101: xen-pv-cdrom.patch @@ -436,6 +439,9 @@ Patch102: add-nocow-to-vol-xml.patch Patch150: lxc-keep-caps-feature.patch Patch151: lxc-keep-caps-feature-conversion.patch Patch152: lxc-keep-caps-feature-doc.patch +Patch153: lxc-net-target-name.patch +Patch154: lxc-net-target-name-conversion.patch +Patch155: lxc-net-target-name-doc.patch # Our patches Patch200: libvirtd-defaults.patch Patch201: libvirtd-init-script.patch @@ -947,12 +953,18 @@ namespaces. %prep %setup -q +%patch0 -p1 +%patch1 -p1 +%patch2 -p1 %patch100 -p1 %patch101 -p1 %patch102 -p1 %patch150 -p1 %patch151 -p1 %patch152 -p1 +%patch153 -p1 +%patch154 -p1 +%patch155 -p1 %patch200 -p1 %patch201 -p1 %patch202 -p1 @@ -1183,6 +1195,7 @@ for i in object-events dominfo domsuspend hellolibvirt openauth xml/nwfilter sys do (cd examples/$i ; make clean ; rm -rf .deps .libs Makefile Makefile.in) done +cp examples/lxcconvert/virt-lxc-convert $RPM_BUILD_ROOT%{_bindir} rm -f $RPM_BUILD_ROOT%{_libdir}/*.la rm -f $RPM_BUILD_ROOT%{_libdir}/*.a rm -f $RPM_BUILD_ROOT%{_libdir}/%{name}/lock-driver/*.la @@ -1488,7 +1501,8 @@ fi %config(noreplace) %{_sysconfdir}/apparmor.d/usr.lib.libvirt.virt-aa-helper %config(noreplace) %{_sysconfdir}/apparmor.d/abstractions/libvirt-qemu %config(noreplace) %{_sysconfdir}/apparmor.d/abstractions/libvirt-lxc -%config(noreplace) %{_sysconfdir}/apparmor.d/libvirt/TEMPLATE +%config(noreplace) %{_sysconfdir}/apparmor.d/libvirt/TEMPLATE.lxc +%config(noreplace) %{_sysconfdir}/apparmor.d/libvirt/TEMPLATE.qemu %{_libdir}/%{name}/virt-aa-helper %endif %config %{_fwdefdir}/libvirtd-relocation-server @@ -1648,6 +1662,7 @@ fi %{_datadir}/augeas/lenses/tests/test_libvirtd_lxc.aug %dir %{_libdir}/%{name}/connection-driver %{_libdir}/%{name}/connection-driver/libvirt_driver_lxc.so +%attr(0755, root, root) %{_bindir}/virt-lxc-convert %endif %if %{with_uml} diff --git a/lxc-net-target-name-conversion.patch b/lxc-net-target-name-conversion.patch new file mode 100644 index 0000000..feb7805 --- /dev/null +++ b/lxc-net-target-name-conversion.patch @@ -0,0 +1,130 @@ +From 27b425b5f77029bf0d322afb930eabf6ec6899e4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?C=C3=A9dric=20Bosdonnat?= +Date: Wed, 2 Jul 2014 15:13:40 +0200 +Subject: [PATCH 1/2] lxc conf2xml: convert lxc.network.name for veth networks + +--- + src/lxc/lxc_native.c | 22 ++++++++++++++++------ + .../lxcconf2xmldata/lxcconf2xml-physnetwork.config | 1 + + tests/lxcconf2xmldata/lxcconf2xml-simple.xml | 1 + + 3 files changed, 18 insertions(+), 6 deletions(-) + +Index: libvirt-1.2.5/src/lxc/lxc_native.c +=================================================================== +--- libvirt-1.2.5.orig/src/lxc/lxc_native.c ++++ libvirt-1.2.5/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 + 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 + 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, + 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, + 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, + 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(virDomainDefPt + { + 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(virDomainDefPt + 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) +Index: libvirt-1.2.5/tests/lxcconf2xmldata/lxcconf2xml-physnetwork.config +=================================================================== +--- libvirt-1.2.5.orig/tests/lxcconf2xmldata/lxcconf2xml-physnetwork.config ++++ libvirt-1.2.5/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 +Index: libvirt-1.2.5/tests/lxcconf2xmldata/lxcconf2xml-simple.xml +=================================================================== +--- libvirt-1.2.5.orig/tests/lxcconf2xmldata/lxcconf2xml-simple.xml ++++ libvirt-1.2.5/tests/lxcconf2xmldata/lxcconf2xml-simple.xml +@@ -37,6 +37,7 @@ + + + ++ + + + diff --git a/lxc-net-target-name-doc.patch b/lxc-net-target-name-doc.patch new file mode 100644 index 0000000..9c162bd --- /dev/null +++ b/lxc-net-target-name-doc.patch @@ -0,0 +1,37 @@ +From c0b1a318442740b6c63630b61d0718598a9937d2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?C=C3=A9dric=20Bosdonnat?= +Date: Wed, 2 Jul 2014 15:24:56 +0200 +Subject: [PATCH 2/2] lxc network device names change documentation + +--- + docs/formatdomain.html.in | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +Index: libvirt-1.2.5/docs/formatdomain.html.in +=================================================================== +--- libvirt-1.2.5.orig/docs/formatdomain.html.in ++++ libvirt-1.2.5/docs/formatdomain.html.in +@@ -3757,6 +3757,23 @@ qemu-kvm -net nic,model=? /dev/null + targets using these prefixes will be ignored. +

+ ++

++ Note that for LXC containers, this defines the name of the interface ++ on the host side. Since 1.2.7, to define ++ the name of the device on the guest side, the guest ++ element should be used, as in the following snippet: ++

++ ++
++  ...
++  <devices>
++    <interface type='network'>
++      <source network='default'/>
++      <guest dev='myeth'/>
++    </interface>
++  </devices>
++  ...
++ +
Specifying boot order
+ +
diff --git a/lxc-net-target-name.patch b/lxc-net-target-name.patch
new file mode 100644
index 0000000..f5c7301
--- /dev/null
+++ b/lxc-net-target-name.patch
@@ -0,0 +1,269 @@
+From 2dd011bd1451e5e6e41c0fbe98884d7594a46dc1 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?C=C3=A9dric=20Bosdonnat?= 
+Date: Fri, 27 Jun 2014 10:41:22 +0200
+Subject: [PATCH] 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:
+
+    
+      
+      
+    
+
+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(-)
+
+Index: libvirt-1.2.5/docs/schemas/domaincommon.rng
+===================================================================
+--- libvirt-1.2.5.orig/docs/schemas/domaincommon.rng
++++ libvirt-1.2.5/docs/schemas/domaincommon.rng
+@@ -2165,6 +2165,23 @@
+         
+       
+       
++        
++          
++            
++              
++                
++              
++            
++            
++              
++                
++              
++            
++          
++          
++        
++      
++      
+         
+           
+             
+Index: libvirt-1.2.5/src/conf/domain_conf.c
+===================================================================
+--- libvirt-1.2.5.orig/src/conf/domain_conf.c
++++ libvirt-1.2.5/src/conf/domain_conf.c
+@@ -1415,6 +1415,8 @@ void virDomainNetDefFree(virDomainNetDef
+     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);
+ 
+@@ -6621,6 +6623,8 @@ virDomainNetDefParseXML(virDomainXMLOpti
+     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;
+@@ -6726,6 +6730,10 @@ virDomainNetDefParseXML(virDomainXMLOpti
+                     /* 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");
+@@ -6967,6 +6975,14 @@ virDomainNetDefParseXML(virDomainXMLOpti
+         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
+@@ -15918,6 +15934,17 @@ virDomainNetDefFormat(virBufferPtr buf,
+         /* Skip auto-generated target names for inactive config. */
+         virBufferEscapeString(buf, "\n", def->ifname);
+     }
++    if (def->ifname_guest || def->ifname_guest_actual) {
++        virBufferAddLit(buf, "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, "\n",
+                               def->model);
+Index: libvirt-1.2.5/src/conf/domain_conf.h
+===================================================================
+--- libvirt-1.2.5.orig/src/conf/domain_conf.h
++++ libvirt-1.2.5/src/conf/domain_conf.h
+@@ -916,6 +916,8 @@ struct _virDomainNetDef {
+     } tune;
+     char *script;
+     char *ifname;
++    char *ifname_guest;
++    char *ifname_guest_actual;
+     virDomainDeviceInfo info;
+     char *filter;
+     virNWFilterHashTablePtr filterparams;
+Index: libvirt-1.2.5/src/lxc/lxc_container.c
+===================================================================
+--- libvirt-1.2.5.orig/src/lxc/lxc_container.c
++++ libvirt-1.2.5/src/lxc/lxc_container.c
+@@ -464,6 +464,21 @@ static int lxcContainerSetID(virDomainDe
+ }
+ 
+ 
++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(virDomainDe
+  *
+  * 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;
+         }
+@@ -2074,8 +2096,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;
+Index: libvirt-1.2.5/src/lxc/lxc_process.c
+===================================================================
+--- libvirt-1.2.5.orig/src/lxc/lxc_process.c
++++ libvirt-1.2.5/src/lxc/lxc_process.c
+@@ -259,6 +259,8 @@ char *virLXCProcessSetupInterfaceBridged
+ 
+     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(
+ {
+     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(
+         }
+ 
+         (*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(
+     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 con
+                                     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
+Index: libvirt-1.2.5/tests/lxcxml2xmldata/lxc-idmap.xml
+===================================================================
+--- libvirt-1.2.5.orig/tests/lxcxml2xmldata/lxc-idmap.xml
++++ libvirt-1.2.5/tests/lxcxml2xmldata/lxc-idmap.xml
+@@ -29,6 +29,7 @@
+       
+       
+       
++      
+     
+     
+