]> xenbits.xensource.com Git - libvirt.git/commitdiff
network: store network macTableManager setting in NetDef actual object
authorLaine Stump <laine@laine.org>
Fri, 21 Nov 2014 17:35:15 +0000 (12:35 -0500)
committerLaine Stump <laine@laine.org>
Mon, 8 Dec 2014 19:45:09 +0000 (14:45 -0500)
At the time that the network driver allocates a connection to a
network, the tap device that will be used hasn't yet been created -
that will be done later by qemu (or lxc or whoever) - but if the
network has macTableManager='libvirt', then when we do get around to
creating the tap device, we will need to add an entry for it to the
network bridge's fdb (forwarding database) *and* turn off learning and
unicast_flood for that tap device in the bridge's sysfs settings. This
means that qemu needs to know both the bridge name as well as the
setting of macTableManager, so we either need to create a new API to
retrieve that info, or just pass it back in the ActualNetDef that is
created during networkAllocateActualDevice. We choose the latter
method, since it's already done for the bridge device, and it has the
side effect of making the information available in domain status.

(NB: in the future, I think that the tap device should actually be
created by networkAllocateActualDevice(), as that will solve several
other problems, but that is a battle for another day, and this
information will still be useful outside the network driver)

src/conf/domain_conf.c
src/conf/domain_conf.h
src/libvirt_private.syms
src/network/bridge_driver.c

index f45969f6a448c854c7590b3b3de6121c75c0ed3b..843cdecf13d9741b3d5a5872af41e44351c89635 100644 (file)
@@ -51,6 +51,7 @@
 #include "netdev_bandwidth_conf.h"
 #include "netdev_vlan_conf.h"
 #include "device_conf.h"
+#include "network_conf.h"
 #include "virtpm.h"
 #include "virstring.h"
 
@@ -7003,6 +7004,7 @@ virDomainActualNetDefParseXML(xmlNodePtr node,
     char *mode = NULL;
     char *addrtype = NULL;
     char *trustGuestRxFilters = NULL;
+    char *macTableManager = NULL;
 
     if (VIR_ALLOC(actual) < 0)
         return -1;
@@ -7119,6 +7121,16 @@ virDomainActualNetDefParseXML(xmlNodePtr node,
             goto error;
         }
         actual->data.bridge.brname = brname;
+        macTableManager = virXPathString("string(./source/@macTableManager)", ctxt);
+        if (macTableManager &&
+            (actual->data.bridge.macTableManager
+             = virNetworkBridgeMACTableManagerTypeFromString(macTableManager)) <= 0) {
+            virReportError(VIR_ERR_XML_ERROR,
+                           _("Invalid macTableManager setting '%s' "
+                             "in domain interface's <actual> element"),
+                           macTableManager);
+            goto error;
+        }
     }
 
     bandwidth_node = virXPathNode("./bandwidth", ctxt);
@@ -7139,6 +7151,7 @@ virDomainActualNetDefParseXML(xmlNodePtr node,
     VIR_FREE(mode);
     VIR_FREE(addrtype);
     VIR_FREE(trustGuestRxFilters);
+    VIR_FREE(macTableManager);
     virDomainActualNetDefFree(actual);
 
     ctxt->node = save_ctxt;
@@ -17156,12 +17169,18 @@ virDomainActualNetDefContentsFormat(virBufferPtr buf,
         }
         if (actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
             actualType == VIR_DOMAIN_NET_TYPE_NETWORK) {
+            int macTableManager = virDomainNetGetActualBridgeMACTableManager(def);
+
             /* actualType == NETWORK includes the name of the bridge
              * that is used by the network, whether we are
              * "inSubElement" or not.
              */
             virBufferEscapeString(buf, " bridge='%s'",
                                   virDomainNetGetActualBridgeName(def));
+            if (macTableManager) {
+                virBufferAsprintf(buf, " macTableManager='%s'",
+                                  virNetworkBridgeMACTableManagerTypeToString(macTableManager));
+            }
         } else if (actualType == VIR_DOMAIN_NET_TYPE_DIRECT) {
             const char *mode;
 
@@ -20760,6 +20779,17 @@ virDomainNetGetActualBridgeName(virDomainNetDefPtr iface)
     return NULL;
 }
 
+int
+virDomainNetGetActualBridgeMACTableManager(virDomainNetDefPtr iface)
+{
+    if (iface->type == VIR_DOMAIN_NET_TYPE_NETWORK &&
+        iface->data.network.actual &&
+        (iface->data.network.actual->type == VIR_DOMAIN_NET_TYPE_BRIDGE ||
+         iface->data.network.actual->type == VIR_DOMAIN_NET_TYPE_NETWORK))
+        return iface->data.network.actual->data.bridge.macTableManager;
+    return 0;
+}
+
 const char *
 virDomainNetGetActualDirectDev(virDomainNetDefPtr iface)
 {
index 439f3c00b13f50ae0af0fb164ed4da5a911c98b3..e10b3c5d7fe5ef25d7b418436473fd8a2060c837 100644 (file)
@@ -888,6 +888,7 @@ struct _virDomainActualNetDef {
     union {
         struct {
             char *brname;
+            int macTableManager; /* enum virNetworkBridgeMACTableManagerType */
         } bridge;
         struct {
             char *linkdev;
@@ -2540,6 +2541,7 @@ int virDomainGraphicsListenSetNetwork(virDomainGraphicsDefPtr def,
 
 int virDomainNetGetActualType(virDomainNetDefPtr iface);
 const char *virDomainNetGetActualBridgeName(virDomainNetDefPtr iface);
+int virDomainNetGetActualBridgeMACTableManager(virDomainNetDefPtr iface);
 const char *virDomainNetGetActualDirectDev(virDomainNetDefPtr iface);
 int virDomainNetGetActualDirectMode(virDomainNetDefPtr iface);
 virDomainHostdevDefPtr virDomainNetGetActualHostdev(virDomainNetDefPtr iface);
index 645d516e1e3c7ee9e58449d4230ad927ccc41ea9..6df27848ed922eaa516b611f025bd3624f51e306 100644 (file)
@@ -328,6 +328,7 @@ virDomainNetFind;
 virDomainNetFindIdx;
 virDomainNetGenerateMAC;
 virDomainNetGetActualBandwidth;
+virDomainNetGetActualBridgeMACTableManager;
 virDomainNetGetActualBridgeName;
 virDomainNetGetActualDirectDev;
 virDomainNetGetActualDirectMode;
index a41510b87702a9ff3cb6360f97218606d63f7305..93d36ab5cd576a5a7e49054d3931ac9655172e5e 100644 (file)
@@ -3795,7 +3795,7 @@ networkAllocateActualDevice(virDomainDefPtr dom,
          */
         iface->data.network.actual->type = VIR_DOMAIN_NET_TYPE_NETWORK;
 
-        /* we also store the bridge device
+        /* we also store the bridge device and macTableManager settings
          * in iface->data.network.actual->data.bridge for later use
          * after the domain's tap device is created (to attach to the
          * bridge and set flood/learning mode on the tap device)
@@ -3803,6 +3803,8 @@ networkAllocateActualDevice(virDomainDefPtr dom,
         if (VIR_STRDUP(iface->data.network.actual->data.bridge.brname,
                        netdef->bridge) < 0)
             goto error;
+        iface->data.network.actual->data.bridge.macTableManager
+           = netdef->macTableManager;
 
         if (networkPlugBandwidth(network, iface) < 0)
             goto error;
@@ -3818,6 +3820,8 @@ networkAllocateActualDevice(virDomainDefPtr dom,
         if (VIR_STRDUP(iface->data.network.actual->data.bridge.brname,
                        netdef->bridge) < 0)
             goto error;
+        iface->data.network.actual->data.bridge.macTableManager
+           = netdef->macTableManager;
 
         /* merge virtualports from interface, network, and portgroup to
          * arrive at actual virtualport to use