mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
util: Introduce virMACMap module
This module will be used to track: <domain, mac address list> pairs. It will be important to know these mappings without libvirt connection (that is from a JSON file), because NSS module will use those to provide better host name translation. Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
parent
b9b664c5a8
commit
86980bc75c
@ -213,6 +213,7 @@ src/util/virkeyfile.c
|
|||||||
src/util/virlease.c
|
src/util/virlease.c
|
||||||
src/util/virlockspace.c
|
src/util/virlockspace.c
|
||||||
src/util/virlog.c
|
src/util/virlog.c
|
||||||
|
src/util/virmacmap.c
|
||||||
src/util/virnetdev.c
|
src/util/virnetdev.c
|
||||||
src/util/virnetdevbandwidth.c
|
src/util/virnetdevbandwidth.c
|
||||||
src/util/virnetdevbridge.c
|
src/util/virnetdevbridge.c
|
||||||
|
@ -137,6 +137,7 @@ UTIL_SOURCES = \
|
|||||||
util/virlockspace.c util/virlockspace.h \
|
util/virlockspace.c util/virlockspace.h \
|
||||||
util/virlog.c util/virlog.h \
|
util/virlog.c util/virlog.h \
|
||||||
util/virmacaddr.h util/virmacaddr.c \
|
util/virmacaddr.h util/virmacaddr.c \
|
||||||
|
util/virmacmap.h util/virmacmap.c \
|
||||||
util/virnetdev.h util/virnetdev.c \
|
util/virnetdev.h util/virnetdev.c \
|
||||||
util/virnetdevbandwidth.h util/virnetdevbandwidth.c \
|
util/virnetdevbandwidth.h util/virnetdevbandwidth.c \
|
||||||
util/virnetdevbridge.h util/virnetdevbridge.c \
|
util/virnetdevbridge.h util/virnetdevbridge.c \
|
||||||
|
@ -1927,6 +1927,15 @@ virMacAddrSet;
|
|||||||
virMacAddrSetRaw;
|
virMacAddrSetRaw;
|
||||||
|
|
||||||
|
|
||||||
|
# util/virmacmap.h
|
||||||
|
virMacMapAdd;
|
||||||
|
virMacMapDumpStr;
|
||||||
|
virMacMapLookup;
|
||||||
|
virMacMapNew;
|
||||||
|
virMacMapRemove;
|
||||||
|
virMacMapWriteFile;
|
||||||
|
|
||||||
|
|
||||||
# util/virnetdev.h
|
# util/virnetdev.h
|
||||||
virNetDevAddMulti;
|
virNetDevAddMulti;
|
||||||
virNetDevDelMulti;
|
virNetDevDelMulti;
|
||||||
|
388
src/util/virmacmap.c
Normal file
388
src/util/virmacmap.c
Normal file
@ -0,0 +1,388 @@
|
|||||||
|
/*
|
||||||
|
* virmacmap.c: MAC address <-> Domain name mapping
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Michal Privoznik <mprivozn@redhat.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include "virmacmap.h"
|
||||||
|
#include "virobject.h"
|
||||||
|
#include "virlog.h"
|
||||||
|
#include "virjson.h"
|
||||||
|
#include "virfile.h"
|
||||||
|
#include "virhash.h"
|
||||||
|
#include "virstring.h"
|
||||||
|
#include "viralloc.h"
|
||||||
|
|
||||||
|
#define VIR_FROM_THIS VIR_FROM_NETWORK
|
||||||
|
|
||||||
|
VIR_LOG_INIT("util.virmacmap");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VIR_MAC_MAP_FILE_SIZE_MAX:
|
||||||
|
*
|
||||||
|
* Macro providing the upper limit on the size of mac maps file
|
||||||
|
*/
|
||||||
|
#define VIR_MAC_MAP_FILE_SIZE_MAX (32 * 1024 * 1024)
|
||||||
|
|
||||||
|
struct virMacMap {
|
||||||
|
virObjectLockable parent;
|
||||||
|
|
||||||
|
virHashTablePtr macs;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static virClassPtr virMacMapClass;
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
virMacMapDispose(void *obj)
|
||||||
|
{
|
||||||
|
virMacMapPtr mgr = obj;
|
||||||
|
virHashFree(mgr->macs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
virMacMapHashFree(void *payload, const void *name ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
virStringListFree(payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int virMacMapOnceInit(void)
|
||||||
|
{
|
||||||
|
if (!(virMacMapClass = virClassNew(virClassForObjectLockable(),
|
||||||
|
"virMacMapClass",
|
||||||
|
sizeof(virMacMap),
|
||||||
|
virMacMapDispose)))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
VIR_ONCE_GLOBAL_INIT(virMacMap);
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virMacMapAddLocked(virMacMapPtr mgr,
|
||||||
|
const char *domain,
|
||||||
|
const char *mac)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
const char **macsList = NULL;
|
||||||
|
char **newMacsList = NULL;
|
||||||
|
|
||||||
|
if ((macsList = virHashLookup(mgr->macs, domain)) &&
|
||||||
|
virStringListHasString(macsList, mac)) {
|
||||||
|
ret = 0;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(newMacsList = virStringListAdd(macsList, mac)) ||
|
||||||
|
virHashUpdateEntry(mgr->macs, domain, newMacsList) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
newMacsList = NULL;
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
cleanup:
|
||||||
|
virStringListFree(newMacsList);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virMacMapRemoveLocked(virMacMapPtr mgr,
|
||||||
|
const char *domain,
|
||||||
|
const char *mac)
|
||||||
|
{
|
||||||
|
char **macsList = NULL;
|
||||||
|
char **newMacsList = NULL;
|
||||||
|
|
||||||
|
if (!(macsList = virHashLookup(mgr->macs, domain)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
newMacsList = macsList;
|
||||||
|
virStringListRemove(&macsList, mac);
|
||||||
|
if (!macsList) {
|
||||||
|
virHashSteal(mgr->macs, domain);
|
||||||
|
} else {
|
||||||
|
if (macsList != newMacsList &&
|
||||||
|
virHashUpdateEntry(mgr->macs, domain, newMacsList) < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virMacMapLoadFile(virMacMapPtr mgr,
|
||||||
|
const char *file)
|
||||||
|
{
|
||||||
|
char *map_str = NULL;
|
||||||
|
virJSONValuePtr map = NULL;
|
||||||
|
int map_str_len = 0;
|
||||||
|
size_t i;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (virFileExists(file) &&
|
||||||
|
(map_str_len = virFileReadAll(file,
|
||||||
|
VIR_MAC_MAP_FILE_SIZE_MAX,
|
||||||
|
&map_str)) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (map_str_len == 0) {
|
||||||
|
ret = 0;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(map = virJSONValueFromString(map_str))) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("invalid json in file: %s"),
|
||||||
|
file);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!virJSONValueIsArray(map)) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Malformed file structure: %s"),
|
||||||
|
file);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < virJSONValueArraySize(map); i++) {
|
||||||
|
virJSONValuePtr tmp = virJSONValueArrayGet(map, i);
|
||||||
|
virJSONValuePtr macs;
|
||||||
|
const char *domain;
|
||||||
|
size_t j;
|
||||||
|
|
||||||
|
if (!(domain = virJSONValueObjectGetString(tmp, "domain"))) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("Missing domain"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(macs = virJSONValueObjectGetArray(tmp, "macs"))) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("Missing macs"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = 0; j < virJSONValueArraySize(macs); j++) {
|
||||||
|
virJSONValuePtr macJSON = virJSONValueArrayGet(macs, j);
|
||||||
|
const char *mac = virJSONValueGetString(macJSON);
|
||||||
|
|
||||||
|
if (virMacMapAddLocked(mgr, domain, mac) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
cleanup:
|
||||||
|
VIR_FREE(map_str);
|
||||||
|
virJSONValueFree(map);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virMACMapHashDumper(void *payload,
|
||||||
|
const void *name,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
virJSONValuePtr obj = NULL;
|
||||||
|
virJSONValuePtr arr = NULL;
|
||||||
|
const char **macs = payload;
|
||||||
|
size_t i;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (!(obj = virJSONValueNewObject()) ||
|
||||||
|
!(arr = virJSONValueNewArray()))
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
for (i = 0; macs[i]; i++) {
|
||||||
|
virJSONValuePtr m = virJSONValueNewString(macs[i]);
|
||||||
|
|
||||||
|
if (!m ||
|
||||||
|
virJSONValueArrayAppend(arr, m) < 0) {
|
||||||
|
virJSONValueFree(m);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virJSONValueObjectAppendString(obj, "domain", name) < 0 ||
|
||||||
|
virJSONValueObjectAppend(obj, "macs", arr) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
arr = NULL;
|
||||||
|
|
||||||
|
if (virJSONValueArrayAppend(data, obj) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
obj = NULL;
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
cleanup:
|
||||||
|
virJSONValueFree(obj);
|
||||||
|
virJSONValueFree(arr);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virMacMapDumpStrLocked(virMacMapPtr mgr,
|
||||||
|
char **str)
|
||||||
|
{
|
||||||
|
virJSONValuePtr arr;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (!(arr = virJSONValueNewArray()))
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (virHashForEach(mgr->macs, virMACMapHashDumper, arr) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (!(*str = virJSONValueToString(arr, true)))
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
cleanup:
|
||||||
|
virJSONValueFree(arr);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virMacMapWriteFileLocked(virMacMapPtr mgr,
|
||||||
|
const char *file)
|
||||||
|
{
|
||||||
|
char *str;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (virMacMapDumpStrLocked(mgr, &str) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (virFileRewriteStr(file, 0644, str) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
cleanup:
|
||||||
|
VIR_FREE(str);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define VIR_MAC_HASH_TABLE_SIZE 10
|
||||||
|
|
||||||
|
virMacMapPtr
|
||||||
|
virMacMapNew(const char *file)
|
||||||
|
{
|
||||||
|
virMacMapPtr mgr;
|
||||||
|
|
||||||
|
if (virMacMapInitialize() < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!(mgr = virObjectLockableNew(virMacMapClass)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
virObjectLock(mgr);
|
||||||
|
if (!(mgr->macs = virHashCreate(VIR_MAC_HASH_TABLE_SIZE,
|
||||||
|
virMacMapHashFree)))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (file &&
|
||||||
|
virMacMapLoadFile(mgr, file) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
virObjectUnlock(mgr);
|
||||||
|
return mgr;
|
||||||
|
|
||||||
|
error:
|
||||||
|
virObjectUnlock(mgr);
|
||||||
|
virObjectUnref(mgr);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
virMacMapAdd(virMacMapPtr mgr,
|
||||||
|
const char *domain,
|
||||||
|
const char *mac)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
virObjectLock(mgr);
|
||||||
|
ret = virMacMapAddLocked(mgr, domain, mac);
|
||||||
|
virObjectUnlock(mgr);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
virMacMapRemove(virMacMapPtr mgr,
|
||||||
|
const char *domain,
|
||||||
|
const char *mac)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
virObjectLock(mgr);
|
||||||
|
ret = virMacMapRemoveLocked(mgr, domain, mac);
|
||||||
|
virObjectUnlock(mgr);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char *const *
|
||||||
|
virMacMapLookup(virMacMapPtr mgr,
|
||||||
|
const char *domain)
|
||||||
|
{
|
||||||
|
const char *const *ret;
|
||||||
|
|
||||||
|
virObjectLock(mgr);
|
||||||
|
ret = virHashLookup(mgr->macs, domain);
|
||||||
|
virObjectUnlock(mgr);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
virMacMapWriteFile(virMacMapPtr mgr,
|
||||||
|
const char *filename)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
virObjectLock(mgr);
|
||||||
|
ret = virMacMapWriteFileLocked(mgr, filename);
|
||||||
|
virObjectUnlock(mgr);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
virMacMapDumpStr(virMacMapPtr mgr,
|
||||||
|
char **str)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
virObjectLock(mgr);
|
||||||
|
ret = virMacMapDumpStrLocked(mgr, str);
|
||||||
|
virObjectUnlock(mgr);
|
||||||
|
return ret;
|
||||||
|
}
|
48
src/util/virmacmap.h
Normal file
48
src/util/virmacmap.h
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* virmacmap.h: MAC address <-> Domain name mapping
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Michal Privoznik <mprivozn@redhat.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __VIR_MACMAP_H__
|
||||||
|
# define __VIR_MACMAP_H__
|
||||||
|
|
||||||
|
typedef struct virMacMap virMacMap;
|
||||||
|
typedef virMacMap *virMacMapPtr;
|
||||||
|
|
||||||
|
virMacMapPtr virMacMapNew(const char *file);
|
||||||
|
|
||||||
|
int virMacMapAdd(virMacMapPtr mgr,
|
||||||
|
const char *domain,
|
||||||
|
const char *mac);
|
||||||
|
|
||||||
|
int virMacMapRemove(virMacMapPtr mgr,
|
||||||
|
const char *domain,
|
||||||
|
const char *mac);
|
||||||
|
|
||||||
|
const char *const *virMacMapLookup(virMacMapPtr mgr,
|
||||||
|
const char *domain);
|
||||||
|
|
||||||
|
int virMacMapWriteFile(virMacMapPtr mgr,
|
||||||
|
const char *filename);
|
||||||
|
|
||||||
|
int virMacMapDumpStr(virMacMapPtr mgr,
|
||||||
|
char **str);
|
||||||
|
#endif /* __VIR_MACMAPPING_H__ */
|
@ -144,6 +144,7 @@ EXTRA_DIST = \
|
|||||||
vircgroupdata \
|
vircgroupdata \
|
||||||
virconfdata \
|
virconfdata \
|
||||||
virfiledata \
|
virfiledata \
|
||||||
|
virmacmaptestdata \
|
||||||
virmock.h \
|
virmock.h \
|
||||||
virnetdaemondata \
|
virnetdaemondata \
|
||||||
virnetdevtestdata \
|
virnetdevtestdata \
|
||||||
@ -191,6 +192,7 @@ test_programs = virshtest sockettest \
|
|||||||
domainconftest \
|
domainconftest \
|
||||||
virhostdevtest \
|
virhostdevtest \
|
||||||
vircaps2xmltest \
|
vircaps2xmltest \
|
||||||
|
virmacmaptest \
|
||||||
virnetdevtest \
|
virnetdevtest \
|
||||||
virtypedparamtest \
|
virtypedparamtest \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
@ -406,6 +408,7 @@ test_libraries = libshunload.la \
|
|||||||
virhostcpumock.la \
|
virhostcpumock.la \
|
||||||
nssmock.la \
|
nssmock.la \
|
||||||
domaincapsmock.la \
|
domaincapsmock.la \
|
||||||
|
virmacmapmock.la \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
if WITH_QEMU
|
if WITH_QEMU
|
||||||
test_libraries += libqemumonitortestutils.la \
|
test_libraries += libqemumonitortestutils.la \
|
||||||
@ -1137,6 +1140,17 @@ nsslinktest_CFLAGS = \
|
|||||||
nsslinktest_LDADD = ../tools/nss/libnss_libvirt_impl.la
|
nsslinktest_LDADD = ../tools/nss/libnss_libvirt_impl.la
|
||||||
nsslinktest_LDFLAGS = $(NULL)
|
nsslinktest_LDFLAGS = $(NULL)
|
||||||
|
|
||||||
|
virmacmapmock_la_SOURCES = \
|
||||||
|
virmacmapmock.c
|
||||||
|
virmacmapmock_la_CFLAGS = $(AM_CFLAGS)
|
||||||
|
virmacmapmock_la_LDFLAGS = $(MOCKLIBS_LDFLAGS)
|
||||||
|
virmacmapmock_la_LIBADD = $(MOCKLIBS_LIBS)
|
||||||
|
|
||||||
|
virmacmaptest_SOURCES = \
|
||||||
|
virmacmaptest.c testutils.h testutils.c
|
||||||
|
virmacmaptest_CLFAGS = $(AM_CFLAGS);
|
||||||
|
virmacmaptest_LDADD = $(LDADDS)
|
||||||
|
|
||||||
virnetdevtest_SOURCES = \
|
virnetdevtest_SOURCES = \
|
||||||
virnetdevtest.c testutils.h testutils.c
|
virnetdevtest.c testutils.h testutils.c
|
||||||
virnetdevtest_CFLAGS = $(AM_CFLAGS) $(LIBNL_CFLAGS)
|
virnetdevtest_CFLAGS = $(AM_CFLAGS) $(LIBNL_CFLAGS)
|
||||||
|
29
tests/virmacmapmock.c
Normal file
29
tests/virmacmapmock.c
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* Author: Michal Privoznik <mprivozn@redhat.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include "virrandom.h"
|
||||||
|
|
||||||
|
uint64_t virRandomBits(int nbits ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return 4; /* chosen by fair dice roll.
|
||||||
|
guaranteed to be random. */
|
||||||
|
}
|
232
tests/virmacmaptest.c
Normal file
232
tests/virmacmaptest.c
Normal file
@ -0,0 +1,232 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* Author: Michal Privoznik <mprivozn@redhat.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include "testutils.h"
|
||||||
|
#include "virmacmap.h"
|
||||||
|
|
||||||
|
#define VIR_FROM_THIS VIR_FROM_NONE
|
||||||
|
|
||||||
|
struct testData {
|
||||||
|
const char *file;
|
||||||
|
const char *domain;
|
||||||
|
const char * const * macs;
|
||||||
|
virMacMapPtr mgr;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
testMACLookup(const void *opaque)
|
||||||
|
{
|
||||||
|
const struct testData *data = opaque;
|
||||||
|
virMacMapPtr mgr = NULL;
|
||||||
|
const char * const * macs;
|
||||||
|
size_t i, j;
|
||||||
|
char *file = NULL;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (virAsprintf(&file, "%s/virmacmaptestdata/%s.json",
|
||||||
|
abs_srcdir, data->file) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (!(mgr = virMacMapNew(file)))
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
macs = virMacMapLookup(mgr, data->domain);
|
||||||
|
|
||||||
|
for (i = 0; macs && macs[i]; i++) {
|
||||||
|
for (j = 0; data->macs && data->macs[j]; j++) {
|
||||||
|
if (STREQ(macs[i], data->macs[j]))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data->macs || !data->macs[j]) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Unexpected %s in the returned list of MACs\n", macs[i]);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; data->macs && data->macs[i]; i++) {
|
||||||
|
for (j = 0; macs && macs[j]; j++) {
|
||||||
|
if (STREQ(data->macs[i], macs[j]))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!macs || !macs[j]) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Expected %s in the returned list of MACs\n", data->macs[i]);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
cleanup:
|
||||||
|
VIR_FREE(file);
|
||||||
|
virObjectUnref(mgr);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
testMACRemove(const void *opaque)
|
||||||
|
{
|
||||||
|
const struct testData *data = opaque;
|
||||||
|
virMacMapPtr mgr = NULL;
|
||||||
|
const char * const * macs;
|
||||||
|
size_t i;
|
||||||
|
char *file = NULL;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (virAsprintf(&file, "%s/virmacmaptestdata/%s.json",
|
||||||
|
abs_srcdir, data->file) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (!(mgr = virMacMapNew(file)))
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
for (i = 0; data->macs && data->macs[i]; i++) {
|
||||||
|
if (virMacMapRemove(mgr, data->domain, data->macs[i]) < 0) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Error when removing %s from the list of MACs\n", data->macs[i]);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((macs = virMacMapLookup(mgr, data->domain))) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Not removed all MACs for domain %s: %s\n", data->domain, macs[0]);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
cleanup:
|
||||||
|
VIR_FREE(file);
|
||||||
|
virObjectUnref(mgr);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
testMACFlush(const void *opaque)
|
||||||
|
{
|
||||||
|
const struct testData *data = opaque;
|
||||||
|
char *file = NULL;
|
||||||
|
char *str = NULL;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (virAsprintf(&file, "%s/virmacmaptestdata/%s.json",
|
||||||
|
abs_srcdir, data->file) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (virMacMapDumpStr(data->mgr, &str) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (virTestCompareToFile(str, file) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
cleanup:
|
||||||
|
VIR_FREE(file);
|
||||||
|
VIR_FREE(str);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
mymain(void)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
virMacMapPtr mgr = NULL;
|
||||||
|
|
||||||
|
#define DO_TEST_BASIC(f, d, ...) \
|
||||||
|
do { \
|
||||||
|
const char * const m[] = {__VA_ARGS__, NULL }; \
|
||||||
|
struct testData data = {.file = f, .domain = d, .macs = m}; \
|
||||||
|
if (virTestRun("Lookup " #d " in " #f, \
|
||||||
|
testMACLookup, &data) < 0) \
|
||||||
|
ret = -1; \
|
||||||
|
if (virTestRun("Remove " #d " in " #f, \
|
||||||
|
testMACRemove, &data) < 0) \
|
||||||
|
ret = -1; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define DO_TEST_FLUSH_PROLOGUE \
|
||||||
|
if (!(mgr = virMacMapNew(NULL))) \
|
||||||
|
ret = -1;
|
||||||
|
|
||||||
|
#define DO_TEST_FLUSH(d, ...) \
|
||||||
|
do { \
|
||||||
|
const char * const m[] = {__VA_ARGS__, NULL }; \
|
||||||
|
size_t i; \
|
||||||
|
for (i = 0; m[i]; i++) { \
|
||||||
|
if (virMacMapAdd(mgr, d, m[i]) < 0) { \
|
||||||
|
virObjectUnref(mgr); \
|
||||||
|
mgr = NULL; \
|
||||||
|
ret = -1; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
|
#define DO_TEST_FLUSH_EPILOGUE(f) \
|
||||||
|
do { \
|
||||||
|
struct testData data = {.file = f, .mgr = mgr}; \
|
||||||
|
if (virTestRun("Flush " #f, testMACFlush, &data) < 0) \
|
||||||
|
ret = -1; \
|
||||||
|
virObjectUnref(mgr); \
|
||||||
|
mgr = NULL; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
DO_TEST_BASIC("empty", "none", NULL);
|
||||||
|
DO_TEST_BASIC("simple", "f24", "aa:bb:cc:dd:ee:ff");
|
||||||
|
DO_TEST_BASIC("simple2", "f24", "aa:bb:cc:dd:ee:ff", "a1:b2:c3:d4:e5:f6");
|
||||||
|
DO_TEST_BASIC("simple2", "f25", "00:11:22:33:44:55", "aa:bb:cc:00:11:22");
|
||||||
|
|
||||||
|
DO_TEST_FLUSH_PROLOGUE;
|
||||||
|
DO_TEST_FLUSH_EPILOGUE("empty");
|
||||||
|
|
||||||
|
DO_TEST_FLUSH_PROLOGUE;
|
||||||
|
DO_TEST_FLUSH("f24", "aa:bb:cc:dd:ee:ff");
|
||||||
|
DO_TEST_FLUSH_EPILOGUE("simple");
|
||||||
|
|
||||||
|
DO_TEST_FLUSH_PROLOGUE;
|
||||||
|
DO_TEST_FLUSH("f24", "aa:bb:cc:dd:ee:ff", "a1:b2:c3:d4:e5:f6");
|
||||||
|
DO_TEST_FLUSH("f25", "00:11:22:33:44:55", "aa:bb:cc:00:11:22");
|
||||||
|
DO_TEST_FLUSH_EPILOGUE("simple2");
|
||||||
|
|
||||||
|
DO_TEST_FLUSH_PROLOGUE;
|
||||||
|
DO_TEST_FLUSH("dom0", "e1:81:5d:f3:41:57", "76:0a:2a:a0:51:86", "01:c7:fc:01:c7:fc");
|
||||||
|
DO_TEST_FLUSH("dom0", "8e:82:53:60:32:4a", "14:7a:25:dc:7d:a0", "f8:d7:75:f8:d7:75");
|
||||||
|
DO_TEST_FLUSH("dom0", "73:d2:50:fb:0f:b1", "82:ee:a7:9b:e3:69", "a8:b4:cb:a8:b4:cb");
|
||||||
|
DO_TEST_FLUSH("dom0", "7e:81:86:0f:0b:fb", "94:e2:00:d9:4c:70", "dc:7b:83:dc:7b:83");
|
||||||
|
DO_TEST_FLUSH("dom0", "d1:19:a5:a1:52:a8", "22:03:a0:bf:cb:4a", "e3:c7:f8:e3:c7:f8");
|
||||||
|
DO_TEST_FLUSH("dom0", "aa:bf:3f:4f:21:8d", "28:67:45:72:8f:47", "eb:08:cd:eb:08:cd");
|
||||||
|
DO_TEST_FLUSH("dom0", "bd:f8:a7:e5:e2:bd", "c7:80:e3:b9:18:4d", "ce:da:c0:ce:da:c0");
|
||||||
|
DO_TEST_FLUSH("dom1", "8b:51:1d:9f:2f:29", "7c:ae:4c:3e:e1:11", "c6:68:4e:98:ff:6a");
|
||||||
|
DO_TEST_FLUSH("dom1", "43:0e:33:a1:3f:0f", "7a:3e:ed:bb:15:27", "b1:17:fd:95:d2:1b");
|
||||||
|
DO_TEST_FLUSH("dom1", "9e:89:49:99:51:0e", "89:b4:3f:08:88:2c", "54:0b:4c:e2:0a:39");
|
||||||
|
DO_TEST_FLUSH("dom1", "bb:88:07:19:51:9d", "b7:f1:1a:40:a2:95", "88:94:39:a3:90:b4");
|
||||||
|
DO_TEST_FLUSH_EPILOGUE("complex");
|
||||||
|
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
VIRT_TEST_MAIN_PRELOAD(mymain, abs_builddir "/.libs/virmacmapmock.so")
|
45
tests/virmacmaptestdata/complex.json
Normal file
45
tests/virmacmaptestdata/complex.json
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"domain": "dom0",
|
||||||
|
"macs": [
|
||||||
|
"e1:81:5d:f3:41:57",
|
||||||
|
"76:0a:2a:a0:51:86",
|
||||||
|
"01:c7:fc:01:c7:fc",
|
||||||
|
"8e:82:53:60:32:4a",
|
||||||
|
"14:7a:25:dc:7d:a0",
|
||||||
|
"f8:d7:75:f8:d7:75",
|
||||||
|
"73:d2:50:fb:0f:b1",
|
||||||
|
"82:ee:a7:9b:e3:69",
|
||||||
|
"a8:b4:cb:a8:b4:cb",
|
||||||
|
"7e:81:86:0f:0b:fb",
|
||||||
|
"94:e2:00:d9:4c:70",
|
||||||
|
"dc:7b:83:dc:7b:83",
|
||||||
|
"d1:19:a5:a1:52:a8",
|
||||||
|
"22:03:a0:bf:cb:4a",
|
||||||
|
"e3:c7:f8:e3:c7:f8",
|
||||||
|
"aa:bf:3f:4f:21:8d",
|
||||||
|
"28:67:45:72:8f:47",
|
||||||
|
"eb:08:cd:eb:08:cd",
|
||||||
|
"bd:f8:a7:e5:e2:bd",
|
||||||
|
"c7:80:e3:b9:18:4d",
|
||||||
|
"ce:da:c0:ce:da:c0"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"domain": "dom1",
|
||||||
|
"macs": [
|
||||||
|
"8b:51:1d:9f:2f:29",
|
||||||
|
"7c:ae:4c:3e:e1:11",
|
||||||
|
"c6:68:4e:98:ff:6a",
|
||||||
|
"43:0e:33:a1:3f:0f",
|
||||||
|
"7a:3e:ed:bb:15:27",
|
||||||
|
"b1:17:fd:95:d2:1b",
|
||||||
|
"9e:89:49:99:51:0e",
|
||||||
|
"89:b4:3f:08:88:2c",
|
||||||
|
"54:0b:4c:e2:0a:39",
|
||||||
|
"bb:88:07:19:51:9d",
|
||||||
|
"b7:f1:1a:40:a2:95",
|
||||||
|
"88:94:39:a3:90:b4"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
3
tests/virmacmaptestdata/empty.json
Normal file
3
tests/virmacmaptestdata/empty.json
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[
|
||||||
|
|
||||||
|
]
|
8
tests/virmacmaptestdata/simple.json
Normal file
8
tests/virmacmaptestdata/simple.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"domain": "f24",
|
||||||
|
"macs": [
|
||||||
|
"aa:bb:cc:dd:ee:ff"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
16
tests/virmacmaptestdata/simple2.json
Normal file
16
tests/virmacmaptestdata/simple2.json
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"domain": "f25",
|
||||||
|
"macs": [
|
||||||
|
"00:11:22:33:44:55",
|
||||||
|
"aa:bb:cc:00:11:22"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"domain": "f24",
|
||||||
|
"macs": [
|
||||||
|
"aa:bb:cc:dd:ee:ff",
|
||||||
|
"a1:b2:c3:d4:e5:f6"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
Loading…
Reference in New Issue
Block a user