nwfilter_ipaddrmap.c 4.4 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*
 * nwfilter_ipaddrmap.c: IP address map for mapping interfaces to their
 *                       detected/expected IP addresses
 *
 * Copyright (C) 2010, 2012 IBM Corp.
 *
 * Author:
 *     Stefan Berger <stefanb@linux.vnet.ibm.com>
 *
 * 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
21
 * License along with this library.  If not, see
O
Osier Yang 已提交
22
 * <http://www.gnu.org/licenses/>.
23 24 25 26 27 28
 */

#include <config.h>

#include "internal.h"

29
#include "virerror.h"
30 31 32 33 34 35
#include "datatypes.h"
#include "nwfilter_params.h"
#include "nwfilter_ipaddrmap.h"

#define VIR_FROM_THIS VIR_FROM_NWFILTER

36
static virMutex ipAddressMapLock = VIR_MUTEX_INITIALIZER;
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
static virNWFilterHashTablePtr 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)
{
    int ret = -1;
    virNWFilterVarValuePtr val;

    virMutexLock(&ipAddressMapLock);

    val = virHashLookup(ipAddressMap->hashTable, ifname);
    if (!val) {
        val = virNWFilterVarValueCreateSimple(addr);
61
        if (!val)
62
            goto cleanup;
63
        ret = virNWFilterHashTablePut(ipAddressMap, ifname, val);
64 65
        if (ret < 0)
            virNWFilterVarValueFree(val);
66 67 68 69 70 71 72 73
        goto cleanup;
    } else {
        if (virNWFilterVarValueAddValue(val, addr) < 0)
            goto cleanup;
    }

    ret = 0;

74
 cleanup:
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
    virMutexUnlock(&ipAddressMapLock);

    return ret;
}

/* 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)
{
    int ret = -1;
    virNWFilterVarValuePtr val = NULL;

    virMutexLock(&ipAddressMapLock);

    if (ipaddr != NULL) {
        val = virHashLookup(ipAddressMap->hashTable, ifname);
        if (val) {
            if (virNWFilterVarValueGetCardinality(val) == 1 &&
                STREQ(ipaddr,
                      virNWFilterVarValueGetNthValue(val, 0)))
                goto remove_entry;
            virNWFilterVarValueDelValue(val, ipaddr);
            ret = virNWFilterVarValueGetCardinality(val);
        }
    } else {
113
 remove_entry:
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
        /* remove whole entry */
        val = virNWFilterHashTableRemoveEntry(ipAddressMap, ifname);
        virNWFilterVarValueFree(val);
        ret = 0;
    }

    virMutexUnlock(&ipAddressMapLock);

    return ret;
}

/* 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 virNWFilterVarValuePtr otherwise
 * that then can contain one or multiple entries.
 */
virNWFilterVarValuePtr
virNWFilterIPAddrMapGetIPAddr(const char *ifname)
{
    virNWFilterVarValuePtr res;

    virMutexLock(&ipAddressMapLock);

    res = virHashLookup(ipAddressMap->hashTable, ifname);

    virMutexUnlock(&ipAddressMapLock);

    return res;
}

int
virNWFilterIPAddrMapInit(void)
{
    ipAddressMap = virNWFilterHashTableCreate(0);
149
    if (!ipAddressMap)
150 151 152 153 154 155 156 157 158 159 160
        return -1;

    return 0;
}

void
virNWFilterIPAddrMapShutdown(void)
{
    virNWFilterHashTableFree(ipAddressMap);
    ipAddressMap = NULL;
}