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@xxxxxxxxxx> --- src/conf/network_conf.h | 4 ++ src/network/bridge_driver.c | 93 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+) diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h index 3b227db6f..e95d68d8f 100644 --- a/src/conf/network_conf.h +++ b/src/conf/network_conf.h @@ -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 */ + virMACMapMgrPtr macmap; }; virNetworkObjPtr virNetworkObjNew(void); diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index 073f5019a..435601aae 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -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 (virMACMapMgrAdd(network->macmap, domain, macStr) < 0) + goto cleanup; + + if (virMACMapMgrFlush(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 (virMACMapMgrRemove(network->macmap, domain, macStr) < 0) + goto cleanup; + + if (virMACMapMgrFlush(network->macmap, file) < 0) + goto cleanup; + + ret = 0; + cleanup: + VIR_FREE(file); + return ret; +} + static char * networkBridgeDummyNicName(const char *brname) { @@ -2127,6 +2206,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 +2253,10 @@ networkStartNetworkVirtual(virNetworkDriverStatePtr driver, } } + if (!(macMapFile = networkMacMgrFileName(driver, network->def->bridge)) || + !(network->macmap = virMACMapMgrNew(macMapFile))) + goto err1; + /* Set bridge options */ /* delay is configured in seconds, but virNetDevBridgeSetSTPDelay @@ -2272,6 +2356,7 @@ networkStartNetworkVirtual(virNetworkDriverStatePtr driver, goto err5; VIR_FREE(macTapIfName); + VIR_FREE(macMapFile); return 0; @@ -2308,6 +2393,7 @@ networkStartNetworkVirtual(virNetworkDriverStatePtr driver, ignore_value(virNetDevTapDelete(macTapIfName, NULL)); VIR_FREE(macTapIfName); } + VIR_FREE(macMapFile); err0: if (!save_err) @@ -2329,6 +2415,8 @@ networkShutdownNetworkVirtual(virNetworkDriverStatePtr driver, if (network->def->bandwidth) virNetDevBandwidthClear(network->def->bridge); + virObjectUnref(network->macmap); + if (network->radvdPid > 0) { char *radvdpidbase; @@ -4353,6 +4441,9 @@ networkAllocateActualDevice(virDomainDefPtr dom, } } + if (networkMacMgrAdd(driver, network, dom->name, &iface->mac) < 0) + goto error; + if (virNetDevVPortProfileCheckComplete(virtport, true) < 0) goto error; @@ -4739,6 +4830,8 @@ networkReleaseActualDevice(virDomainDefPtr dom, } success: + networkMacMgrDel(driver, network, dom->name, &iface->mac); + if (iface->data.network.actual) { netdef->connections--; if (dev) -- 2.11.0 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list