]> xenbits.xensource.com Git - libvirt.git/commitdiff
network: Track MAC address map
authorMichal Privoznik <mprivozn@redhat.com>
Mon, 28 Nov 2016 16:56:14 +0000 (17:56 +0100)
committerMichal Privoznik <mprivozn@redhat.com>
Tue, 6 Dec 2016 12:33:18 +0000 (13:33 +0100)
Now that we have a module that's able to track
<domain, mac addres list> pairs, hook it up into
our network driver.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
src/conf/network_conf.h
src/network/bridge_driver.c

index 3b227db6f3ffd9c0f30f92129cb4edcc8285a333..09e091616250040d818e3bccf3cd179217ca82cb 100644 (file)
@@ -41,6 +41,7 @@
 # include "virbitmap.h"
 # include "networkcommon_conf.h"
 # include "virobject.h"
+# include "virmacmap.h"
 
 typedef enum {
     VIR_NETWORK_FORWARD_NONE   = 0,
@@ -284,6 +285,9 @@ struct _virNetworkObj {
     unsigned long long floor_sum; /* sum of all 'floor'-s of attached NICs */
 
     unsigned int taint;
+
+    /* Immutable pointer, self locking APIs */
+    virMacMapPtr macmap;
 };
 
 virNetworkObjPtr virNetworkObjNew(void);
index 073f5019a7029d6bb345f05d7d2ce1e1e5ee3232..ae1589d8c962109aa27d7c6af9d705b32b68ac99 100644 (file)
@@ -289,6 +289,17 @@ networkRadvdConfigFileName(virNetworkDriverStatePtr driver,
     return configfile;
 }
 
+static char *
+networkMacMgrFileName(virNetworkDriverStatePtr driver,
+                      const char *bridge)
+{
+    char *filename;
+
+    ignore_value(virAsprintf(&filename, "%s/%s.macs",
+                             driver->dnsmasqStateDir, bridge));
+    return filename;
+}
+
 /* do needed cleanup steps and remove the network from the list */
 static int
 networkRemoveInactive(virNetworkDriverStatePtr driver,
@@ -300,6 +311,7 @@ networkRemoveInactive(virNetworkDriverStatePtr driver,
     char *configfile = NULL;
     char *radvdpidbase = NULL;
     char *statusfile = NULL;
+    char *macMapFile = NULL;
     dnsmasqContext *dctx = NULL;
     virNetworkDefPtr def = virNetworkObjGetPersistentDef(net);
 
@@ -329,12 +341,18 @@ networkRemoveInactive(virNetworkDriverStatePtr driver,
     if (!(statusfile = virNetworkConfigFile(driver->stateDir, def->name)))
         goto cleanup;
 
+    if (!(macMapFile = networkMacMgrFileName(driver, def->bridge)))
+        goto cleanup;
+
     /* dnsmasq */
     dnsmasqDelete(dctx);
     unlink(leasefile);
     unlink(customleasefile);
     unlink(configfile);
 
+    /* MAC map manager */
+    unlink(macMapFile);
+
     /* radvd */
     unlink(radvdconfigfile);
     virPidFileDelete(driver->pidDir, radvdpidbase);
@@ -354,10 +372,71 @@ networkRemoveInactive(virNetworkDriverStatePtr driver,
     VIR_FREE(radvdconfigfile);
     VIR_FREE(radvdpidbase);
     VIR_FREE(statusfile);
+    VIR_FREE(macMapFile);
     dnsmasqContextFree(dctx);
     return ret;
 }
 
+static int
+networkMacMgrAdd(virNetworkDriverStatePtr driver,
+                 virNetworkObjPtr network,
+                 const char *domain,
+                 const virMacAddr *mac)
+{
+    char macStr[VIR_MAC_STRING_BUFLEN];
+    char *file = NULL;
+    int ret = -1;
+
+    if (!network->macmap)
+        return 0;
+
+    virMacAddrFormat(mac, macStr);
+
+    if (!(file = networkMacMgrFileName(driver, network->def->bridge)))
+        goto cleanup;
+
+    if (virMacMapAdd(network->macmap, domain, macStr) < 0)
+        goto cleanup;
+
+    if (virMacMapWriteFile(network->macmap, file) < 0)
+        goto cleanup;
+
+    ret = 0;
+ cleanup:
+    VIR_FREE(file);
+    return ret;
+}
+
+static int
+networkMacMgrDel(virNetworkDriverStatePtr driver,
+                 virNetworkObjPtr network,
+                 const char *domain,
+                 const virMacAddr *mac)
+{
+    char macStr[VIR_MAC_STRING_BUFLEN];
+    char *file = NULL;
+    int ret = -1;
+
+    if (!network->macmap)
+        return 0;
+
+    virMacAddrFormat(mac, macStr);
+
+    if (!(file = networkMacMgrFileName(driver, network->def->bridge)))
+        goto cleanup;
+
+    if (virMacMapRemove(network->macmap, domain, macStr) < 0)
+        goto cleanup;
+
+    if (virMacMapWriteFile(network->macmap, file) < 0)
+        goto cleanup;
+
+    ret = 0;
+ cleanup:
+    VIR_FREE(file);
+    return ret;
+}
+
 static char *
 networkBridgeDummyNicName(const char *brname)
 {
@@ -430,11 +509,13 @@ networkUpdateState(virNetworkObjPtr obj,
     /* Try and read dnsmasq/radvd pids of active networks */
     if (obj->active && obj->def->ips && (obj->def->nips > 0)) {
         char *radvdpidbase;
+        char *macMapFile;
 
         ignore_value(virPidFileReadIfAlive(driver->pidDir,
                                            obj->def->name,
                                            &obj->dnsmasqPid,
                                            dnsmasqCapsGetBinaryPath(dnsmasq_caps)));
+
         radvdpidbase = networkRadvdPidfileBasename(obj->def->name);
         if (!radvdpidbase)
             goto cleanup;
@@ -443,6 +524,17 @@ networkUpdateState(virNetworkObjPtr obj,
                                            radvdpidbase,
                                            &obj->radvdPid, RADVD));
         VIR_FREE(radvdpidbase);
+
+        if (!(macMapFile = networkMacMgrFileName(driver, obj->def->bridge)))
+            goto cleanup;
+
+        if (virFileExists(macMapFile) &&
+            !(obj->macmap = virMacMapNew(macMapFile))) {
+            VIR_FREE(macMapFile);
+            goto cleanup;
+        }
+
+        VIR_FREE(macMapFile);
     }
 
     ret = 0;
@@ -2127,6 +2219,7 @@ networkStartNetworkVirtual(virNetworkDriverStatePtr driver,
     virNetworkIPDefPtr ipdef;
     virNetDevIPRoutePtr routedef;
     char *macTapIfName = NULL;
+    char *macMapFile = NULL;
     int tapfd = -1;
 
     /* Check to see if any network IP collides with an existing route */
@@ -2173,6 +2266,10 @@ networkStartNetworkVirtual(virNetworkDriverStatePtr driver,
         }
     }
 
+    if (!(macMapFile = networkMacMgrFileName(driver, network->def->bridge)) ||
+        !(network->macmap = virMacMapNew(macMapFile)))
+        goto err1;
+
     /* Set bridge options */
 
     /* delay is configured in seconds, but virNetDevBridgeSetSTPDelay
@@ -2272,6 +2369,7 @@ networkStartNetworkVirtual(virNetworkDriverStatePtr driver,
         goto err5;
 
     VIR_FREE(macTapIfName);
+    VIR_FREE(macMapFile);
 
     return 0;
 
@@ -2308,6 +2406,7 @@ networkStartNetworkVirtual(virNetworkDriverStatePtr driver,
         ignore_value(virNetDevTapDelete(macTapIfName, NULL));
         VIR_FREE(macTapIfName);
     }
+    VIR_FREE(macMapFile);
 
  err0:
     if (!save_err)
@@ -2329,6 +2428,8 @@ networkShutdownNetworkVirtual(virNetworkDriverStatePtr driver,
     if (network->def->bandwidth)
         virNetDevBandwidthClear(network->def->bridge);
 
+    virObjectUnref(network->macmap);
+
     if (network->radvdPid > 0) {
         char *radvdpidbase;
 
@@ -4353,6 +4454,9 @@ networkAllocateActualDevice(virDomainDefPtr dom,
         }
     }
 
+    if (networkMacMgrAdd(driver, network, dom->name, &iface->mac) < 0)
+        goto error;
+
     if (virNetDevVPortProfileCheckComplete(virtport, true) < 0)
         goto error;
 
@@ -4739,6 +4843,8 @@ networkReleaseActualDevice(virDomainDefPtr dom,
     }
 
  success:
+    networkMacMgrDel(driver, network, dom->name, &iface->mac);
+
     if (iface->data.network.actual) {
         netdef->connections--;
         if (dev)