Add support for Qemu to have firewall rules applied and removed on VM
startup and shutdown respectively. This  patch also provides support for
the updating of a filter that causes all VMs that reference the filter
to have their ebtables/iptables rules updated.

Signed-off-by: Stefan Berger <stef...@us.ibm.com>

---
 src/qemu/qemu_conf.c   |   29 +++++++++++++++++++++++++++++
 src/qemu/qemu_driver.c |   40 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 69 insertions(+)

Index: libvirt-acl/src/qemu/qemu_conf.c
===================================================================
--- libvirt-acl.orig/src/qemu/qemu_conf.c
+++ libvirt-acl/src/qemu/qemu_conf.c
@@ -54,6 +54,7 @@
 #include "network.h"
 #include "macvtap.h"
 #include "cpu/cpu.h"
+#include "nwfilter/nwfilter_gentech_driver.h"
 
 #define VIR_FROM_THIS VIR_FROM_QEMU
 
@@ -1472,6 +1473,17 @@ qemudPhysIfaceConnect(virConnectPtr conn
                                  net->ifname);
         }
     }
+
+    if (rc >= 0) {
+        if ((net->filter) && (net->ifname)) {
+            err = virNWFilterInstantiateFilter(conn, net);
+            if (err) {
+                close(rc);
+                rc = -1;
+                delMacvtap(net->ifname);
+            }
+        }
+    }
 #else
     (void)conn;
     (void)net;
@@ -1594,6 +1606,16 @@ qemudNetworkIfaceConnect(virConnectPtr c
         }
     }
 
+    if (tapfd >= 0) {
+        if ((net->filter) && (net->ifname)) {
+            err = virNWFilterInstantiateFilter(conn, net);
+            if (err) {
+                close(tapfd);
+                tapfd = -1;
+            }
+        }
+    }
+
 cleanup:
     VIR_FREE(brname);
 
@@ -3301,6 +3323,7 @@ int qemudBuildCommandLine(virConnectPtr 
     char domid[50];
     char *cpu;
     char *smp;
+    int last_good_net = -1;
 
     uname_normalize(&ut);
 
@@ -3955,6 +3978,7 @@ int qemudBuildCommandLine(virConnectPtr 
                     goto error;
                 ADD_ARG(host);
             }
+            last_good_net = i;
         }
     }
 
@@ -4415,6 +4439,11 @@ int qemudBuildCommandLine(virConnectPtr 
             VIR_FREE((qenv)[i]);
         VIR_FREE(qenv);
     }
+    for (i = 0; i <= last_good_net; i++) {
+        virDomainNetDefPtr net = def->nets[i];
+        if ((net->filter) && (net->ifname))
+            virNWFilterTeardownFilter(net);
+    }
     return -1;
 
 #undef ADD_ARG
Index: libvirt-acl/src/qemu/qemu_driver.c
===================================================================
--- libvirt-acl.orig/src/qemu/qemu_driver.c
+++ libvirt-acl/src/qemu/qemu_driver.c
@@ -83,6 +83,7 @@
 #include "xml.h"
 #include "cpu/cpu.h"
 #include "macvtap.h"
+#include "nwfilter/nwfilter_gentech_driver.h"
 
 
 #define VIR_FROM_THIS VIR_FROM_QEMU
@@ -2644,6 +2645,21 @@ cleanup:
 }
 
 
+static void
+qemuTearNWFilter(virDomainNetDefPtr net) {
+    if ((net->filter) && (net->ifname))
+        virNWFilterTeardownFilter(net);
+}
+
+
+static void
+qemuTearVMNWFilters(virDomainObjPtr vm) {
+    int i;
+    for (i = 0; i < vm->def->nnets; i++)
+        qemuTearNWFilter(vm->def->nets[i]);
+}
+
+
 struct qemudHookData {
     virConnectPtr conn;
     virDomainObjPtr vm;
@@ -2993,6 +3009,8 @@ cleanup:
     /* We jump here if we failed to start the VM for any reason
      * XXX investigate if we can kill this block and safely call
      * qemudShutdownVMDaemon even though no PID is running */
+    qemuTearVMNWFilters(vm);
+
     qemuDomainReAttachHostDevices(driver, vm->def);
 
     if (driver->securityDriver &&
@@ -3041,6 +3059,8 @@ static void qemudShutdownVMDaemon(struct
      * reporting so we don't squash a legit error. */
     orig_err = virSaveLastError();
 
+    qemuTearVMNWFilters(vm);
+
     if (driver->macFilter) {
         def = vm->def;
         for (i = 0 ; i < def->nnets ; i++) {
@@ -6433,6 +6453,8 @@ cleanup:
         qemuDomainPCIAddressReleaseAddr(priv->pciaddrs, &net->info) < 0)
         VIR_WARN0("Unable to release PCI address on NIC");
 
+    qemuTearNWFilter(net);
+
     VIR_FREE(nicstr);
     VIR_FREE(netstr);
     VIR_FREE(tapfd_name);
@@ -7052,6 +7074,8 @@ qemudDomainDetachNetDevice(struct qemud_
         }
     }
 
+    qemuTearNWFilter(detach);
+
     if (vm->def->nnets > 1) {
         memmove(vm->def->nets + i,
                 vm->def->nets + i + 1,
@@ -9687,8 +9711,24 @@ static virStateDriver qemuStateDriver = 
     .active = qemudActive,
 };
 
+static int
+qemudVMFilterRebuild(virConnectPtr conn,
+                     virHashIterator iter, void *data)
+{
+    (void)conn;
+    virHashForEach(qemu_driver->domains.objs, iter, data);
+    return 0;
+}
+
+
+static virNWFilterCallbackDriver qemuCallbackDriver = {
+    .name = "QEMU",
+    .vmFilterRebuild = qemudVMFilterRebuild,
+};
+
 int qemuRegister(void) {
     virRegisterDriver(&qemuDriver);
     virRegisterStateDriver(&qemuStateDriver);
+    virNWFilterRegisterCallbackDriver(&qemuCallbackDriver);
     return 0;
 }

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to