]> xenbits.xensource.com Git - libvirt.git/commitdiff
nwfilter: move code for IP address map into separate file
authorStefan Berger <stefanb@linux.vnet.ibm.com>
Fri, 1 Jun 2012 23:32:06 +0000 (19:32 -0400)
committerStefan Berger <stefanb@us.ibm.com>
Fri, 1 Jun 2012 23:32:06 +0000 (19:32 -0400)
The goal of this patch is to prepare for support for multiple IP
addresses per interface in the DHCP snooping code.

Move the code for the IP address map that maps interface names to
IP addresses into their own file. Rename the functions on the way
but otherwise leave the code as-is. Initialize this new layer
separately before dependent layers (iplearning, dhcpsnooping)
and shut it down after them.

src/Makefile.am
src/conf/nwfilter_ipaddrmap.c [new file with mode: 0644]
src/conf/nwfilter_ipaddrmap.h [new file with mode: 0644]
src/libvirt_private.syms
src/nwfilter/nwfilter_driver.c
src/nwfilter/nwfilter_gentech_driver.c
src/nwfilter/nwfilter_learnipaddr.c
src/nwfilter/nwfilter_learnipaddr.h

index a873e2e281977337c0cf4f620b2b83de0f431d2b..d72788986a6d21bea8eacd1a87fc000e536a3f36 100644 (file)
@@ -160,9 +160,11 @@ NETWORK_CONF_SOURCES =                                             \
 # Network filter driver generic impl APIs
 NWFILTER_PARAM_CONF_SOURCES =                                  \
                conf/nwfilter_params.c conf/nwfilter_params.h   \
+               conf/nwfilter_ipaddrmap.c                       \
+               conf/nwfilter_ipaddrmap.h                       \
                conf/nwfilter_conf.h
 
-NWFILTER_CONF_SOURCES =                                        \
+NWFILTER_CONF_SOURCES =                                                \
                $(NWFILTER_PARAM_CONF_SOURCES)                  \
                conf/nwfilter_conf.c conf/nwfilter_conf.h
 
diff --git a/src/conf/nwfilter_ipaddrmap.c b/src/conf/nwfilter_ipaddrmap.c
new file mode 100644 (file)
index 0000000..c72958b
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ * 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
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ */
+
+#include <config.h>
+
+#include "internal.h"
+
+#include "virterror_internal.h"
+#include "datatypes.h"
+#include "nwfilter_params.h"
+#include "nwfilter_ipaddrmap.h"
+
+#define VIR_FROM_THIS VIR_FROM_NWFILTER
+
+static virMutex ipAddressMapLock;
+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);
+        if (!val) {
+            virReportOOMError();
+            goto cleanup;
+        }
+        ret = virNWFilterHashTablePut(ipAddressMap, ifname, val, 1);
+        goto cleanup;
+    } else {
+        if (virNWFilterVarValueAddValue(val, addr) < 0)
+            goto cleanup;
+    }
+
+    ret = 0;
+
+cleanup:
+    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 {
+remove_entry:
+        /* 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);
+    if (!ipAddressMap) {
+        virReportOOMError();
+        return -1;
+    }
+
+    if (virMutexInit(&ipAddressMapLock) < 0) {
+        virNWFilterIPAddrMapShutdown();
+        return -1;
+    }
+
+    return 0;
+}
+
+void
+virNWFilterIPAddrMapShutdown(void)
+{
+    virNWFilterHashTableFree(ipAddressMap);
+    ipAddressMap = NULL;
+}
diff --git a/src/conf/nwfilter_ipaddrmap.h b/src/conf/nwfilter_ipaddrmap.h
new file mode 100644 (file)
index 0000000..3411a99
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * nwfilter_ipaddrmap.h: 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
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ */
+
+#ifndef __VIR_NWFILTER_IPADDRMAP_H
+# define __VIR_NWFILTER_IPADDRMAP_H
+
+int virNWFilterIPAddrMapInit(void);
+void virNWFilterIPAddrMapShutdown(void);
+
+int virNWFilterIPAddrMapAddIPAddr(const char *ifname, char *addr);
+int virNWFilterIPAddrMapDelIPAddr(const char *ifname,
+                                  const char *ipaddr);
+virNWFilterVarValuePtr virNWFilterIPAddrMapGetIPAddr(const char *ifname);
+
+#endif /* __VIR_NWFILTER_IPADDRMAP_H */
index c6fe0e39f8a5aaef555c35dc22bc9f63417aa637..fdf21866ff64a70235075df52c41b0a63b4ea8d0 100644 (file)
@@ -873,6 +873,14 @@ virNWFilterTestUnassignDef;
 virNWFilterUnlockFilterUpdates;
 
 
+# nwfilter_ipaddrmap
+virNWFilterIPAddrMapAddIPAddr;
+virNWFilterIPAddrMapDelIPAddr;
+virNWFilterIPAddrMapGetIPAddr;
+virNWFilterIPAddrMapInit;
+virNWFilterIPAddrMapShutdown;
+
+
 # nwfilter_params.h
 virNWFilterHashTableCreate;
 virNWFilterHashTableFree;
index 677d03808b290047d2d9ded3df30e6c5acba1ac3..e24cd26dce040b11d6d85ba7591fec4c5ffa1b46 100644 (file)
@@ -39,6 +39,7 @@
 #include "nwfilter_gentech_driver.h"
 #include "configmake.h"
 
+#include "nwfilter_ipaddrmap.h"
 #include "nwfilter_dhcpsnoop.h"
 #include "nwfilter_learnipaddr.h"
 
@@ -67,10 +68,12 @@ static int
 nwfilterDriverStartup(int privileged) {
     char *base = NULL;
 
-    if (virNWFilterDHCPSnoopInit() < 0)
+    if (virNWFilterIPAddrMapInit() < 0)
         return -1;
     if (virNWFilterLearnInit() < 0)
-        return -1;
+        goto err_exit_ipaddrmapshutdown;
+    if (virNWFilterDHCPSnoopInit() < 0)
+        goto err_exit_learnshutdown;
 
     virNWFilterTechDriversInit(privileged);
 
@@ -123,7 +126,10 @@ alloc_err_exit:
 conf_init_err:
     virNWFilterTechDriversShutdown();
     virNWFilterDHCPSnoopShutdown();
+err_exit_learnshutdown:
     virNWFilterLearnShutdown();
+err_exit_ipaddrmapshutdown:
+    virNWFilterIPAddrMapShutdown();
 
     return -1;
 }
@@ -202,6 +208,7 @@ nwfilterDriverShutdown(void) {
     virNWFilterTechDriversShutdown();
     virNWFilterDHCPSnoopShutdown();
     virNWFilterLearnShutdown();
+    virNWFilterIPAddrMapShutdown();
 
     nwfilterDriverLock(driverState);
 
index 1738f5cba1932b6540ab52fe9d89aeb29b89a027..4769d21d4f50bdd64ae9e838c5a291bfdd39eec9 100644 (file)
@@ -33,6 +33,7 @@
 #include "nwfilter_gentech_driver.h"
 #include "nwfilter_ebiptables_driver.h"
 #include "nwfilter_dhcpsnoop.h"
+#include "nwfilter_ipaddrmap.h"
 #include "nwfilter_learnipaddr.h"
 #include "virnetdev.h"
 #include "datatypes.h"
@@ -870,7 +871,7 @@ __virNWFilterInstantiateFilter(const unsigned char *vmuuid,
         goto err_exit;
     }
 
-    ipaddr = virNWFilterGetIpAddrForIfname(ifname);
+    ipaddr = virNWFilterIPAddrMapGetIPAddr(ifname);
 
     vars1 = virNWFilterCreateVarHashmap(str_macaddr, ipaddr);
     if (!vars1) {
@@ -1132,7 +1133,7 @@ _virNWFilterTeardownFilter(const char *ifname)
 
     techdriver->allTeardown(ifname);
 
-    virNWFilterDelIpAddrForIfname(ifname, NULL);
+    virNWFilterIPAddrMapDelIPAddr(ifname, NULL);
 
     virNWFilterUnlockIface(ifname);
 
index 140aea8724afb21591e260d5891bd4d535573bbc..af13738122e3d11ab432d700bf8ce2e3ff880e21 100644 (file)
@@ -52,6 +52,7 @@
 #include "conf/domain_conf.h"
 #include "nwfilter_gentech_driver.h"
 #include "nwfilter_ebiptables_driver.h"
+#include "nwfilter_ipaddrmap.h"
 #include "nwfilter_learnipaddr.h"
 
 #define VIR_FROM_THIS VIR_FROM_NWFILTER
@@ -118,9 +119,6 @@ struct ether_vlan_header
 static virMutex pendingLearnReqLock;
 static virHashTablePtr pendingLearnReq;
 
-static virMutex ipAddressMapLock;
-static virNWFilterHashTablePtr ipAddressMap;
-
 static virMutex ifaceMapLock;
 static virHashTablePtr ifaceLockMap;
 
@@ -310,113 +308,8 @@ virNWFilterDeregisterLearnReq(int ifindex) {
     return res;
 }
 
-/* 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
- */
-static int
-virNWFilterAddIpAddrForIfname(const char *ifname, char *addr)
-{
-    int ret = -1;
-    virNWFilterVarValuePtr val;
-
-    virMutexLock(&ipAddressMapLock);
-
-    val = virHashLookup(ipAddressMap->hashTable, ifname);
-    if (!val) {
-        val = virNWFilterVarValueCreateSimple(addr);
-        if (!val) {
-            virReportOOMError();
-            goto cleanup;
-        }
-        ret = virNWFilterHashTablePut(ipAddressMap, ifname, val, 1);
-        goto cleanup;
-    } else {
-        if (virNWFilterVarValueAddValue(val, addr) < 0)
-            goto cleanup;
-    }
-
-    ret = 0;
-
-cleanup:
-    virMutexUnlock(&ipAddressMapLock);
-
-    return ret;
-}
 #endif
 
-/* 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
-virNWFilterDelIpAddrForIfname(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 {
-remove_entry:
-        /* 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
-virNWFilterGetIpAddrForIfname(const char *ifname)
-{
-    virNWFilterVarValuePtr res;
-
-    virMutexLock(&ipAddressMapLock);
-
-    res = virHashLookup(ipAddressMap->hashTable, ifname);
-
-    virMutexUnlock(&ipAddressMapLock);
-
-    return res;
-}
-
-
 #ifdef HAVE_LIBPCAP
 
 static void
@@ -699,7 +592,7 @@ learnIPAddressThread(void *arg)
         char *inetaddr;
 
         if ((inetaddr = virSocketAddrFormat(&sa)) != NULL) {
-            if (virNWFilterAddIpAddrForIfname(req->ifname, inetaddr) < 0) {
+            if (virNWFilterIPAddrMapAddIPAddr(req->ifname, inetaddr) < 0) {
                 VIR_ERROR(_("Failed to add IP address %s to IP address "
                           "cache for interface %s"), inetaddr, req->ifname);
             }
@@ -901,18 +794,6 @@ virNWFilterLearnInit(void) {
         return -1;
     }
 
-    ipAddressMap = virNWFilterHashTableCreate(0);
-    if (!ipAddressMap) {
-        virReportOOMError();
-        virNWFilterLearnShutdown();
-        return -1;
-    }
-
-    if (virMutexInit(&ipAddressMapLock) < 0) {
-        virNWFilterLearnShutdown();
-        return -1;
-    }
-
     ifaceLockMap = virHashCreate(0, freeIfaceLock);
     if (!ifaceLockMap) {
         virNWFilterLearnShutdown();
@@ -954,9 +835,6 @@ virNWFilterLearnShutdown(void)
     virHashFree(pendingLearnReq);
     pendingLearnReq = NULL;
 
-    virNWFilterHashTableFree(ipAddressMap);
-    ipAddressMap = NULL;
-
     virHashFree(ifaceLockMap);
     ifaceLockMap = NULL;
 }
index 5db9bf8c4b434b33c3d30dd4b09c3f61acefce65..ce78923ec0276ee4814caab26f5b6124fa0b4ca3 100644 (file)
@@ -65,9 +65,6 @@ int virNWFilterLearnIPAddress(virNWFilterTechDriverPtr techdriver,
 virNWFilterIPAddrLearnReqPtr virNWFilterLookupLearnReq(int ifindex);
 int virNWFilterTerminateLearnReq(const char *ifname);
 
-int virNWFilterDelIpAddrForIfname(const char *ifname, const char *ipaddr);
-virNWFilterVarValuePtr virNWFilterGetIpAddrForIfname(const char *ifname);
-
 int virNWFilterLockIface(const char *ifname) ATTRIBUTE_RETURN_CHECK;
 void virNWFilterUnlockIface(const char *ifname);