/* * nwfilter_ipaddrmap.c: IP address map for mapping interfaces to their * detected/expected IP addresses * * Copyright (C) 2010, 2012 IBM Corp. * * 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 * . */ #include #include "internal.h" #include "datatypes.h" #include "nwfilter_params.h" #include "nwfilter_ipaddrmap.h" #define VIR_FROM_THIS VIR_FROM_NWFILTER static virMutex ipAddressMapLock = VIR_MUTEX_INITIALIZER; static GHashTable *ipAddressMap; /* Add an IP address to the list of IP addresses an interface is * known to use. This function feeds the per-interface cache that * is used to instantiate filters with variable '$IP'. * * @ifname: The name of the (tap) interface * @addr: An IPv4 address in dotted decimal format that the (tap) * interface is known to use. * * This function returns 0 on success, -1 otherwise */ int virNWFilterIPAddrMapAddIPAddr(const char *ifname, char *addr) { g_autofree char *addrCopy = g_strdup(addr); VIR_LOCK_GUARD lock = virLockGuardLock(&ipAddressMapLock); virNWFilterVarValue *val; if ((val = virHashLookup(ipAddressMap, ifname)) != NULL) { if (virNWFilterVarValueAddValue(val, addrCopy) < 0) return -1; addrCopy = NULL; return 0; } if ((val = virNWFilterVarValueCreateSimple(addrCopy)) == NULL) return -1; addrCopy = NULL; if (virHashUpdateEntry(ipAddressMap, ifname, val) < 0) { virNWFilterVarValueFree(val); return -1; } return 0; } /* Delete all or a specific IP address from an interface. After this * call either all or the given IP address will not be associated * with the interface anymore. * * @ifname: The name of the (tap) interface * @addr: An IPv4 address in dotted decimal format that the (tap) * interface is not using anymore; provide NULL to remove all IP * addresses associated with the given interface * * This function returns the number of IP addresses that are still * known to be associated with this interface, in case of an error * -1 is returned. Error conditions are: * - IP addresses is not known to be associated with the interface */ int virNWFilterIPAddrMapDelIPAddr(const char *ifname, const char *ipaddr) { VIR_LOCK_GUARD lock = virLockGuardLock(&ipAddressMapLock); virNWFilterVarValue *val = NULL; if (!ipaddr) { /* remove whole entry */ virHashRemoveEntry(ipAddressMap, ifname); return 0; } if (!(val = virHashLookup(ipAddressMap, ifname))) { return -1; } if (virNWFilterVarValueGetCardinality(val) == 1 && STREQ(ipaddr, virNWFilterVarValueGetNthValue(val, 0))) { /* remove whole entry */ virHashRemoveEntry(ipAddressMap, ifname); return 0; } virNWFilterVarValueDelValue(val, ipaddr); return virNWFilterVarValueGetCardinality(val); } /* Get the list of IP addresses known to be in use by an interface * * This function returns NULL in case no IP address is known to be * associated with the interface, a virNWFilterVarValue *otherwise * that then can contain one or multiple entries. */ virNWFilterVarValue * virNWFilterIPAddrMapGetIPAddr(const char *ifname) { VIR_LOCK_GUARD lock = virLockGuardLock(&ipAddressMapLock); return virHashLookup(ipAddressMap, ifname); } int virNWFilterIPAddrMapInit(void) { ipAddressMap = virHashNew(virNWFilterVarValueHashFree); return 0; } void virNWFilterIPAddrMapShutdown(void) { g_clear_pointer(&ipAddressMap, g_hash_table_unref); }