1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2024-12-26 03:21:44 +03:00

network: Track MAC address map

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>
This commit is contained in:
Michal Privoznik 2016-11-28 17:56:14 +01:00
parent 86980bc75c
commit 1f9db235e7
2 changed files with 110 additions and 0 deletions

View 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);

View 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)