[libvirt] [PATCH 2/2] network: prevent duplicate entries in network device pools

Laine Stump laine at laine.org
Mon Apr 18 19:12:23 UTC 2016


Prior to this patch we didn't make any attempt to prevent two entries
in the array of interfaces/PCI devices from pointing to the same
device.

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1002423
---
 src/conf/network_conf.c                          | 33 ++++++++++++++++++++----
 tests/networkxml2xmlin/hostdev-duplicate.xml     | 11 ++++++++
 tests/networkxml2xmlin/passthrough-duplicate.xml | 10 +++++++
 tests/networkxml2xmltest.c                       |  2 ++
 4 files changed, 51 insertions(+), 5 deletions(-)
 create mode 100644 tests/networkxml2xmlin/hostdev-duplicate.xml
 create mode 100644 tests/networkxml2xmlin/passthrough-duplicate.xml

diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index 4fb2e2a..043c79b 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -1,7 +1,7 @@
 /*
  * network_conf.c: network XML handling
  *
- * Copyright (C) 2006-2015 Red Hat, Inc.
+ * Copyright (C) 2006-2016 Red Hat, Inc.
  * Copyright (C) 2006-2008 Daniel P. Berrange
  *
  * This library is free software; you can redistribute it and/or
@@ -1799,7 +1799,7 @@ virNetworkForwardDefParseXML(const char *networkName,
                              xmlXPathContextPtr ctxt,
                              virNetworkForwardDefPtr def)
 {
-    size_t i;
+    size_t i, j;
     int ret = -1;
     xmlNodePtr *forwardIfNodes = NULL;
     xmlNodePtr *forwardPfNodes = NULL;
@@ -1936,6 +1936,16 @@ virNetworkForwardDefParseXML(const char *networkName,
                 continue;
             }
 
+            for (j = 0; j < i; j++) {
+                if (STREQ_NULLABLE(def->ifs[j].device.dev, forwardDev)) {
+                    virReportError(VIR_ERR_XML_ERROR,
+                                   _("interface '%s' can only be "
+                                     "listed once in network %s"),
+                                   forwardDev, networkName);
+                    goto cleanup;
+                }
+            }
+
             def->ifs[i].device.dev = forwardDev;
             forwardDev = NULL;
             def->ifs[i].type = VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_NETDEV;
@@ -1963,12 +1973,25 @@ virNetworkForwardDefParseXML(const char *networkName,
 
             switch (def->ifs[i].type) {
             case VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_PCI:
-                if (virDevicePCIAddressParseXML(forwardAddrNodes[i],
-                                                &def->ifs[i].device.pci) < 0) {
+            {
+                virDevicePCIAddressPtr addr = &def->ifs[i].device.pci;
+
+                if (virDevicePCIAddressParseXML(forwardAddrNodes[i], addr) < 0) {
                     goto cleanup;
                 }
+                for (j = 0; j < i; j++) {
+                    if (virDevicePCIAddressEqual(addr, &def->ifs[j].device.pci)) {
+                        virReportError(VIR_ERR_XML_ERROR,
+                                       _("PCI device '%04x:%02x:%02x.%x' can "
+                                         "only be listed once in network %s"),
+                                       addr->domain, addr->bus,
+                                       addr->slot, addr->function,
+                                       networkName);
+                        goto cleanup;
+                    }
+                }
                 break;
-
+            }
             /* Add USB case here if we ever find a reason to support it */
 
             default:
diff --git a/tests/networkxml2xmlin/hostdev-duplicate.xml b/tests/networkxml2xmlin/hostdev-duplicate.xml
new file mode 100644
index 0000000..79e55aa
--- /dev/null
+++ b/tests/networkxml2xmlin/hostdev-duplicate.xml
@@ -0,0 +1,11 @@
+<network>
+  <name>hostdev</name>
+  <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
+  <forward mode='hostdev' managed='yes'>
+    <address type='pci' domain='0x0000' bus='0x03' slot='0x00' function='0x1'/>
+    <address type='pci' domain='0x0000' bus='0x03' slot='0x00' function='0x2'/>
+    <address type='pci' domain='0x0000' bus='0x03' slot='0x00' function='0x3'/>
+    <address type='pci' domain='0x0000' bus='0x03' slot='0x00' function='0x3'/>
+    <address type='pci' domain='0x0000' bus='0x03' slot='0x00' function='0x4'/>
+  </forward>
+</network>
diff --git a/tests/networkxml2xmlin/passthrough-duplicate.xml b/tests/networkxml2xmlin/passthrough-duplicate.xml
new file mode 100644
index 0000000..8f645f7
--- /dev/null
+++ b/tests/networkxml2xmlin/passthrough-duplicate.xml
@@ -0,0 +1,10 @@
+<network>
+  <name>passthrough-duplicate</name>
+  <uuid>81ff0d90-c91e-6742-64da-4a736edb9a8b</uuid>
+  <forward mode="passthrough">
+    <interface dev="eth1"/>
+    <interface dev="eth2"/>
+    <interface dev="eth3"/>
+    <interface dev="eth3"/>
+  </forward>
+</network>
diff --git a/tests/networkxml2xmltest.c b/tests/networkxml2xmltest.c
index b83396b..eafd473 100644
--- a/tests/networkxml2xmltest.c
+++ b/tests/networkxml2xmltest.c
@@ -151,6 +151,8 @@ mymain(void)
     DO_TEST("passthrough-address-crash");
     DO_TEST("nat-network-explicit-flood");
     DO_TEST("host-bridge-no-flood");
+    DO_TEST_PARSE_ERROR("hostdev-duplicate");
+    DO_TEST_PARSE_ERROR("passthrough-duplicate");
 
     return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
 }
-- 
2.5.5




More information about the libvir-list mailing list