[libvirt] [PATCH V11 5/7] nwfilter: move code for IP address map into separate file

Daniel Veillard veillard at redhat.com
Thu Apr 19 09:58:07 UTC 2012


On Tue, Apr 17, 2012 at 10:44:06AM -0400, Stefan Berger wrote:
> 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                        |    4 
>  src/conf/nwfilter_ipaddrmap.c          |  167 +++++++++++++++++++++++++++++++++
>  src/conf/nwfilter_ipaddrmap.h          |   37 +++++++
>  src/libvirt_private.syms               |    8 +
>  src/nwfilter/nwfilter_driver.c         |   11 +-
>  src/nwfilter/nwfilter_gentech_driver.c |    5 
>  src/nwfilter/nwfilter_learnipaddr.c    |  126 ------------------------
>  src/nwfilter/nwfilter_learnipaddr.h    |    3 
>  8 files changed, 229 insertions(+), 132 deletions(-)
> 
> Index: libvirt-acl/src/Makefile.am
> ===================================================================
> --- libvirt-acl.orig/src/Makefile.am
> +++ libvirt-acl/src/Makefile.am
> @@ -159,9 +159,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
>  
> Index: libvirt-acl/src/nwfilter/nwfilter_driver.c
> ===================================================================
> --- libvirt-acl.orig/src/nwfilter/nwfilter_driver.c
> +++ libvirt-acl/src/nwfilter/nwfilter_driver.c
> @@ -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);
>  
> @@ -131,7 +134,10 @@ alloc_err_exit:
>  conf_init_err:
>      virNWFilterTechDriversShutdown();
>      virNWFilterDHCPSnoopShutdown();
> +err_exit_learnshutdown:
>      virNWFilterLearnShutdown();
> +err_exit_ipaddrmapshutdown:
> +    virNWFilterIPAddrMapShutdown();
>  
>      return -1;
>  }
> @@ -210,6 +216,7 @@ nwfilterDriverShutdown(void) {
>      virNWFilterTechDriversShutdown();
>      virNWFilterDHCPSnoopShutdown();
>      virNWFilterLearnShutdown();
> +    virNWFilterIPAddrMapShutdown();
>  
>      nwfilterDriverLock(driverState);
>  
> Index: libvirt-acl/src/nwfilter/nwfilter_gentech_driver.c
> ===================================================================
> --- libvirt-acl.orig/src/nwfilter/nwfilter_gentech_driver.c
> +++ libvirt-acl/src/nwfilter/nwfilter_gentech_driver.c
> @@ -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 uns
>          goto err_exit;
>      }
>  
> -    ipaddr = virNWFilterGetIpAddrForIfname(ifname);
> +    ipaddr = virNWFilterIPAddrMapGetIPAddr(ifname);
>  
>      vars1 = virNWFilterCreateVarHashmap(str_macaddr, ipaddr);
>      if (!vars1) {
> @@ -1132,7 +1133,7 @@ _virNWFilterTeardownFilter(const char *i
>  
>      techdriver->allTeardown(ifname);
>  
> -    virNWFilterDelIpAddrForIfname(ifname, NULL);
> +    virNWFilterIPAddrMapDelIPAddr(ifname, NULL);
>  
>      virNWFilterUnlockIface(ifname);
>  
> Index: libvirt-acl/src/nwfilter/nwfilter_learnipaddr.c
> ===================================================================
> --- libvirt-acl.orig/src/nwfilter/nwfilter_learnipaddr.c
> +++ libvirt-acl/src/nwfilter/nwfilter_learnipaddr.c
> @@ -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 ifinde
>      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: libvirt-acl/src/nwfilter/nwfilter_learnipaddr.h
> ===================================================================
> --- libvirt-acl.orig/src/nwfilter/nwfilter_learnipaddr.h
> +++ libvirt-acl/src/nwfilter/nwfilter_learnipaddr.h
> @@ -65,9 +65,6 @@ int virNWFilterLearnIPAddress(virNWFilte
>  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);
>  
> Index: libvirt-acl/src/libvirt_private.syms
> ===================================================================
> --- libvirt-acl.orig/src/libvirt_private.syms
> +++ libvirt-acl/src/libvirt_private.syms
> @@ -853,6 +853,14 @@ virNWFilterTestUnassignDef;
>  virNWFilterUnlockFilterUpdates;
>  
>  
> +# nwfilter_ipaddrmap
> +virNWFilterIPAddrMapAddIPAddr;
> +virNWFilterIPAddrMapDelIPAddr;
> +virNWFilterIPAddrMapGetIPAddr;
> +virNWFilterIPAddrMapInit;
> +virNWFilterIPAddrMapShutdown;
> +
> +
>  # nwfilter_params.h
>  virNWFilterHashTableCreate;
>  virNWFilterHashTableFree;

  Weird I would have expected some of the renamed/moved functions
to be removed from the libvirt_private.syms, I'm surprized to see
only additions :)

> Index: libvirt-acl/src/conf/nwfilter_ipaddrmap.c
> ===================================================================
> --- /dev/null
> +++ libvirt-acl/src/conf/nwfilter_ipaddrmap.c
> @@ -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 at 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;
> +}
> Index: libvirt-acl/src/conf/nwfilter_ipaddrmap.h
> ===================================================================
> --- /dev/null
> +++ libvirt-acl/src/conf/nwfilter_ipaddrmap.h
> @@ -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 at 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 */
> 

  ACK, but double check the syms, thanks,

Daniel

-- 
Daniel Veillard      | libxml Gnome XML XSLT toolkit  http://xmlsoft.org/
daniel at veillard.com  | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library  http://libvirt.org/




More information about the libvir-list mailing list