2017-02-28 21:20:44 +00:00
|
|
|
/*
|
|
|
|
* virinterfaceobj.c: interface object handling
|
|
|
|
* (derived from interface_conf.c)
|
|
|
|
*
|
|
|
|
* 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/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
|
|
|
#include "datatypes.h"
|
|
|
|
#include "interface_conf.h"
|
|
|
|
|
|
|
|
#include "viralloc.h"
|
|
|
|
#include "virerror.h"
|
|
|
|
#include "virinterfaceobj.h"
|
|
|
|
#include "virlog.h"
|
|
|
|
#include "virstring.h"
|
|
|
|
|
|
|
|
#define VIR_FROM_THIS VIR_FROM_INTERFACE
|
|
|
|
|
|
|
|
VIR_LOG_INIT("conf.virinterfaceobj");
|
|
|
|
|
2017-04-25 21:45:02 +00:00
|
|
|
struct _virInterfaceObj {
|
2017-05-15 18:31:44 +00:00
|
|
|
virObjectLockable parent;
|
2017-04-25 21:45:02 +00:00
|
|
|
|
|
|
|
bool active; /* true if interface is active (up) */
|
|
|
|
virInterfaceDefPtr def; /* The interface definition */
|
|
|
|
};
|
2017-02-28 21:20:44 +00:00
|
|
|
|
2017-04-14 19:45:27 +00:00
|
|
|
struct _virInterfaceObjList {
|
|
|
|
size_t count;
|
|
|
|
virInterfaceObjPtr *objs;
|
|
|
|
};
|
2017-02-28 21:20:44 +00:00
|
|
|
|
|
|
|
/* virInterfaceObj manipulation */
|
|
|
|
|
2017-05-15 18:31:44 +00:00
|
|
|
static virClassPtr virInterfaceObjClass;
|
|
|
|
static void virInterfaceObjDispose(void *obj);
|
|
|
|
|
|
|
|
static int
|
|
|
|
virInterfaceObjOnceInit(void)
|
|
|
|
{
|
|
|
|
if (!(virInterfaceObjClass = virClassNew(virClassForObjectLockable(),
|
|
|
|
"virInterfaceObj",
|
|
|
|
sizeof(virInterfaceObj),
|
|
|
|
virInterfaceObjDispose)))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
VIR_ONCE_GLOBAL_INIT(virInterfaceObj)
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
virInterfaceObjDispose(void *opaque)
|
|
|
|
{
|
|
|
|
virInterfaceObjPtr obj = opaque;
|
|
|
|
|
|
|
|
virInterfaceDefFree(obj->def);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-04-20 14:40:22 +00:00
|
|
|
static virInterfaceObjPtr
|
2017-07-29 11:20:59 +00:00
|
|
|
virInterfaceObjNew(void)
|
2017-04-20 14:40:22 +00:00
|
|
|
{
|
|
|
|
virInterfaceObjPtr obj;
|
|
|
|
|
2017-05-15 18:31:44 +00:00
|
|
|
if (virInterfaceObjInitialize() < 0)
|
2017-04-20 14:40:22 +00:00
|
|
|
return NULL;
|
|
|
|
|
2017-05-15 18:31:44 +00:00
|
|
|
if (!(obj = virObjectLockableNew(virInterfaceObjClass)))
|
2017-04-20 14:40:22 +00:00
|
|
|
return NULL;
|
|
|
|
|
2017-05-15 18:31:44 +00:00
|
|
|
virObjectLock(obj);
|
2017-04-20 14:40:22 +00:00
|
|
|
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-03-02 16:44:11 +00:00
|
|
|
void
|
2017-05-15 18:31:44 +00:00
|
|
|
virInterfaceObjEndAPI(virInterfaceObjPtr *obj)
|
2017-02-28 21:20:44 +00:00
|
|
|
{
|
2017-05-15 18:31:44 +00:00
|
|
|
if (!*obj)
|
2017-02-28 21:20:44 +00:00
|
|
|
return;
|
|
|
|
|
2017-05-15 18:31:44 +00:00
|
|
|
virObjectUnlock(*obj);
|
|
|
|
virObjectUnref(*obj);
|
|
|
|
*obj = NULL;
|
2017-02-28 21:20:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-04-25 21:45:02 +00:00
|
|
|
virInterfaceDefPtr
|
|
|
|
virInterfaceObjGetDef(virInterfaceObjPtr obj)
|
|
|
|
{
|
|
|
|
return obj->def;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
virInterfaceObjIsActive(virInterfaceObjPtr obj)
|
|
|
|
{
|
|
|
|
return obj->active;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
virInterfaceObjSetActive(virInterfaceObjPtr obj,
|
|
|
|
bool active)
|
|
|
|
{
|
|
|
|
obj->active = active;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-03-02 16:44:11 +00:00
|
|
|
/* virInterfaceObjList manipulation */
|
2017-04-14 19:45:27 +00:00
|
|
|
virInterfaceObjListPtr
|
|
|
|
virInterfaceObjListNew(void)
|
|
|
|
{
|
|
|
|
virInterfaceObjListPtr interfaces;
|
|
|
|
|
|
|
|
if (VIR_ALLOC(interfaces) < 0)
|
|
|
|
return NULL;
|
|
|
|
return interfaces;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-03-02 16:44:11 +00:00
|
|
|
int
|
2017-04-14 20:49:48 +00:00
|
|
|
virInterfaceObjListFindByMACString(virInterfaceObjListPtr interfaces,
|
|
|
|
const char *mac,
|
2017-04-15 11:08:01 +00:00
|
|
|
char **const matches,
|
2017-04-14 20:49:48 +00:00
|
|
|
int maxmatches)
|
2017-02-28 21:20:44 +00:00
|
|
|
{
|
|
|
|
size_t i;
|
2017-04-15 11:08:01 +00:00
|
|
|
int matchct = 0;
|
2017-02-28 21:20:44 +00:00
|
|
|
|
|
|
|
for (i = 0; i < interfaces->count; i++) {
|
2017-04-19 02:32:17 +00:00
|
|
|
virInterfaceObjPtr obj = interfaces->objs[i];
|
|
|
|
virInterfaceDefPtr def;
|
2017-02-28 21:20:44 +00:00
|
|
|
|
2017-05-15 18:31:44 +00:00
|
|
|
virObjectLock(obj);
|
2017-04-19 02:32:17 +00:00
|
|
|
def = obj->def;
|
|
|
|
if (STRCASEEQ(def->mac, mac)) {
|
2017-04-15 11:08:01 +00:00
|
|
|
if (matchct < maxmatches) {
|
|
|
|
if (VIR_STRDUP(matches[matchct], def->name) < 0) {
|
2017-05-15 18:31:44 +00:00
|
|
|
virObjectUnlock(obj);
|
2017-04-15 11:08:01 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
matchct++;
|
2017-02-28 21:20:44 +00:00
|
|
|
}
|
|
|
|
}
|
2017-05-15 18:31:44 +00:00
|
|
|
virObjectUnlock(obj);
|
2017-02-28 21:20:44 +00:00
|
|
|
}
|
|
|
|
return matchct;
|
2017-04-15 11:08:01 +00:00
|
|
|
|
|
|
|
error:
|
|
|
|
while (--matchct >= 0)
|
|
|
|
VIR_FREE(matches[matchct]);
|
|
|
|
|
|
|
|
return -1;
|
2017-02-28 21:20:44 +00:00
|
|
|
}
|
|
|
|
|
2017-03-02 16:44:11 +00:00
|
|
|
|
|
|
|
virInterfaceObjPtr
|
2017-04-14 20:49:48 +00:00
|
|
|
virInterfaceObjListFindByName(virInterfaceObjListPtr interfaces,
|
|
|
|
const char *name)
|
2017-02-28 21:20:44 +00:00
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
for (i = 0; i < interfaces->count; i++) {
|
2017-04-19 02:32:17 +00:00
|
|
|
virInterfaceObjPtr obj = interfaces->objs[i];
|
|
|
|
virInterfaceDefPtr def;
|
|
|
|
|
2017-05-15 18:31:44 +00:00
|
|
|
virObjectLock(obj);
|
2017-04-19 02:32:17 +00:00
|
|
|
def = obj->def;
|
|
|
|
if (STREQ(def->name, name))
|
2017-05-15 18:31:44 +00:00
|
|
|
return virObjectRef(obj);
|
|
|
|
virObjectUnlock(obj);
|
2017-02-28 21:20:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2017-03-02 16:44:11 +00:00
|
|
|
|
|
|
|
void
|
|
|
|
virInterfaceObjListFree(virInterfaceObjListPtr interfaces)
|
2017-02-28 21:20:44 +00:00
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
for (i = 0; i < interfaces->count; i++)
|
2017-05-15 18:31:44 +00:00
|
|
|
virObjectUnref(interfaces->objs[i]);
|
2017-02-28 21:20:44 +00:00
|
|
|
VIR_FREE(interfaces->objs);
|
2017-04-14 19:45:27 +00:00
|
|
|
VIR_FREE(interfaces);
|
2017-02-28 21:20:44 +00:00
|
|
|
}
|
|
|
|
|
2017-03-02 16:44:11 +00:00
|
|
|
|
2017-04-14 19:45:27 +00:00
|
|
|
virInterfaceObjListPtr
|
|
|
|
virInterfaceObjListClone(virInterfaceObjListPtr interfaces)
|
2017-02-28 21:20:44 +00:00
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
unsigned int cnt;
|
2017-04-14 19:45:27 +00:00
|
|
|
virInterfaceObjListPtr dest;
|
2017-02-28 21:20:44 +00:00
|
|
|
|
2017-04-14 19:45:27 +00:00
|
|
|
if (!interfaces)
|
|
|
|
return NULL;
|
2017-02-28 21:20:44 +00:00
|
|
|
|
2017-04-14 19:45:27 +00:00
|
|
|
if (!(dest = virInterfaceObjListNew()))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
cnt = interfaces->count;
|
2017-02-28 21:20:44 +00:00
|
|
|
for (i = 0; i < cnt; i++) {
|
2017-04-14 19:45:27 +00:00
|
|
|
virInterfaceObjPtr srcobj = interfaces->objs[i];
|
2017-02-28 21:20:44 +00:00
|
|
|
virInterfaceDefPtr backup;
|
2017-04-19 02:29:44 +00:00
|
|
|
virInterfaceObjPtr obj;
|
2017-04-19 02:32:17 +00:00
|
|
|
char *xml = virInterfaceDefFormat(srcobj->def);
|
2017-02-28 21:20:44 +00:00
|
|
|
|
|
|
|
if (!xml)
|
2017-04-14 19:45:27 +00:00
|
|
|
goto error;
|
2017-02-28 21:20:44 +00:00
|
|
|
|
2017-04-14 19:45:27 +00:00
|
|
|
if (!(backup = virInterfaceDefParseString(xml))) {
|
2017-02-28 21:20:44 +00:00
|
|
|
VIR_FREE(xml);
|
2017-04-14 19:45:27 +00:00
|
|
|
goto error;
|
2017-02-28 21:20:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
VIR_FREE(xml);
|
2017-04-14 20:49:48 +00:00
|
|
|
if (!(obj = virInterfaceObjListAssignDef(dest, backup)))
|
2017-04-14 19:45:27 +00:00
|
|
|
goto error;
|
2017-05-15 18:31:44 +00:00
|
|
|
virInterfaceObjEndAPI(&obj);
|
2017-02-28 21:20:44 +00:00
|
|
|
}
|
|
|
|
|
2017-04-14 19:45:27 +00:00
|
|
|
return dest;
|
|
|
|
|
|
|
|
error:
|
|
|
|
virInterfaceObjListFree(dest);
|
|
|
|
return NULL;
|
2017-02-28 21:20:44 +00:00
|
|
|
}
|
|
|
|
|
2017-03-02 16:44:11 +00:00
|
|
|
|
|
|
|
virInterfaceObjPtr
|
2017-04-14 20:49:48 +00:00
|
|
|
virInterfaceObjListAssignDef(virInterfaceObjListPtr interfaces,
|
|
|
|
virInterfaceDefPtr def)
|
2017-02-28 21:20:44 +00:00
|
|
|
{
|
2017-04-19 02:29:44 +00:00
|
|
|
virInterfaceObjPtr obj;
|
2017-02-28 21:20:44 +00:00
|
|
|
|
2017-04-14 20:49:48 +00:00
|
|
|
if ((obj = virInterfaceObjListFindByName(interfaces, def->name))) {
|
2017-04-19 02:29:44 +00:00
|
|
|
virInterfaceDefFree(obj->def);
|
|
|
|
obj->def = def;
|
2017-02-28 21:20:44 +00:00
|
|
|
|
2017-04-19 02:29:44 +00:00
|
|
|
return obj;
|
2017-02-28 21:20:44 +00:00
|
|
|
}
|
|
|
|
|
2017-07-29 11:20:59 +00:00
|
|
|
if (!(obj = virInterfaceObjNew()))
|
2017-02-28 21:20:44 +00:00
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (VIR_APPEND_ELEMENT_COPY(interfaces->objs,
|
2017-04-19 02:29:44 +00:00
|
|
|
interfaces->count, obj) < 0) {
|
2017-05-15 18:31:44 +00:00
|
|
|
virInterfaceObjEndAPI(&obj);
|
2017-02-28 21:20:44 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2017-07-29 11:20:59 +00:00
|
|
|
obj->def = def;
|
2017-05-15 18:31:44 +00:00
|
|
|
return virObjectRef(obj);
|
2017-02-28 21:20:44 +00:00
|
|
|
}
|
|
|
|
|
2017-03-02 16:44:11 +00:00
|
|
|
|
|
|
|
void
|
2017-04-14 20:49:48 +00:00
|
|
|
virInterfaceObjListRemove(virInterfaceObjListPtr interfaces,
|
|
|
|
virInterfaceObjPtr obj)
|
2017-02-28 21:20:44 +00:00
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
|
2017-05-15 18:31:44 +00:00
|
|
|
virObjectUnlock(obj);
|
2017-02-28 21:20:44 +00:00
|
|
|
for (i = 0; i < interfaces->count; i++) {
|
2017-05-15 18:31:44 +00:00
|
|
|
virObjectLock(interfaces->objs[i]);
|
2017-04-19 02:29:44 +00:00
|
|
|
if (interfaces->objs[i] == obj) {
|
2017-05-15 18:31:44 +00:00
|
|
|
virObjectUnlock(interfaces->objs[i]);
|
|
|
|
virObjectUnref(interfaces->objs[i]);
|
2017-02-28 21:20:44 +00:00
|
|
|
|
|
|
|
VIR_DELETE_ELEMENT(interfaces->objs, i, interfaces->count);
|
|
|
|
break;
|
|
|
|
}
|
2017-05-15 18:31:44 +00:00
|
|
|
virObjectUnlock(interfaces->objs[i]);
|
2017-02-28 21:20:44 +00:00
|
|
|
}
|
|
|
|
}
|
2017-04-06 13:23:17 +00:00
|
|
|
|
|
|
|
|
|
|
|
int
|
2017-04-14 20:49:48 +00:00
|
|
|
virInterfaceObjListNumOfInterfaces(virInterfaceObjListPtr interfaces,
|
|
|
|
bool wantActive)
|
2017-04-06 13:23:17 +00:00
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
int ninterfaces = 0;
|
|
|
|
|
|
|
|
for (i = 0; (i < interfaces->count); i++) {
|
|
|
|
virInterfaceObjPtr obj = interfaces->objs[i];
|
2017-05-15 18:31:44 +00:00
|
|
|
virObjectLock(obj);
|
2017-04-06 13:23:17 +00:00
|
|
|
if (wantActive == virInterfaceObjIsActive(obj))
|
|
|
|
ninterfaces++;
|
2017-05-15 18:31:44 +00:00
|
|
|
virObjectUnlock(obj);
|
2017-04-06 13:23:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return ninterfaces;
|
|
|
|
}
|
2017-04-06 13:37:57 +00:00
|
|
|
|
|
|
|
|
|
|
|
int
|
2017-04-14 20:49:48 +00:00
|
|
|
virInterfaceObjListGetNames(virInterfaceObjListPtr interfaces,
|
|
|
|
bool wantActive,
|
|
|
|
char **const names,
|
|
|
|
int maxnames)
|
2017-04-06 13:37:57 +00:00
|
|
|
{
|
|
|
|
int nnames = 0;
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
for (i = 0; i < interfaces->count && nnames < maxnames; i++) {
|
|
|
|
virInterfaceObjPtr obj = interfaces->objs[i];
|
2017-04-19 02:32:17 +00:00
|
|
|
virInterfaceDefPtr def;
|
|
|
|
|
2017-05-15 18:31:44 +00:00
|
|
|
virObjectLock(obj);
|
2017-04-19 02:32:17 +00:00
|
|
|
def = obj->def;
|
2017-04-06 13:37:57 +00:00
|
|
|
if (wantActive == virInterfaceObjIsActive(obj)) {
|
2017-04-19 02:32:17 +00:00
|
|
|
if (VIR_STRDUP(names[nnames], def->name) < 0) {
|
2017-05-15 18:31:44 +00:00
|
|
|
virObjectUnlock(obj);
|
2017-04-06 13:37:57 +00:00
|
|
|
goto failure;
|
|
|
|
}
|
|
|
|
nnames++;
|
|
|
|
}
|
2017-05-15 18:31:44 +00:00
|
|
|
virObjectUnlock(obj);
|
2017-04-06 13:37:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return nnames;
|
|
|
|
|
|
|
|
failure:
|
|
|
|
while (--nnames >= 0)
|
|
|
|
VIR_FREE(names[nnames]);
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|