1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
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
113
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
|
/*
* 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
* <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#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);
}
|