[libvirt] [PATCH v4] nwfilter: check for inverted ctdir

Laine Stump laine at laine.org
Thu May 16 00:58:21 UTC 2013


On 05/15/2013 08:39 PM, Stefan Berger wrote:
> Linux netfilter at some point (Linux 2.6.39) inverted the meaning of the
> '--ctdir reply' and newer netfilter implementations now expect
> '--ctdir original' instead and vice-versa.
> We check for the kernel version and assume that all Linux kernels with version
> 2.6.39 have the newer inverted logic.
>
> Any distro backporting the Linux kernel patch that inverts the --ctdir logic
> (Linux commit 96120d86f) must also backport this patch for Linux and

s/Linux/libvirt/ ?

ACK with that small nit fixed. (and thanks for putting up with our
pickiness, by the way :-)


> adapt the kernel version being tested for.
>
> Signed-off-by: Stefan Berger <stefanb at linux.vnet.ibm.com>
>
> ---
>  v2->v3:
>   - using uname now to check for Linux kernel version number
>
>  v1->v2:
>   - using virSocketAddrParseIPv4
>
> ---
>  src/nwfilter/nwfilter_ebiptables_driver.c |   52 ++++++++++++++++++++++++++++++
>  1 file changed, 52 insertions(+)
>
> Index: libvirt-acl/src/nwfilter/nwfilter_ebiptables_driver.c
> ===================================================================
> --- libvirt-acl.orig/src/nwfilter/nwfilter_ebiptables_driver.c
> +++ libvirt-acl/src/nwfilter/nwfilter_ebiptables_driver.c
> @@ -27,6 +27,7 @@
>  #include <string.h>
>  #include <sys/stat.h>
>  #include <fcntl.h>
> +#include <sys/utsname.h>
>  
>  #include "internal.h"
>  
> @@ -85,6 +86,17 @@ static char *iptables_cmd_path;
>  static char *ip6tables_cmd_path;
>  static char *grep_cmd_path;
>  
> +/*
> + * --ctdir original vs. --ctdir reply's meaning was inverted in netfilter
> + * at some point (Linux 2.6.39)
> + */
> +enum ctdirStatus {
> +    CTDIR_STATUS_UNKNOWN    = 0,
> +    CTDIR_STATUS_CORRECTED  = 1,
> +    CTDIR_STATUS_OLD        = 2,
> +};
> +static enum ctdirStatus iptables_ctdir_corrected;
> +
>  #define PRINT_ROOT_CHAIN(buf, prefix, ifname) \
>      snprintf(buf, sizeof(buf), "libvirt-%c-%s", prefix, ifname)
>  #define PRINT_CHAIN(buf, prefix, ifname, suffix) \
> @@ -1262,6 +1274,17 @@ iptablesEnforceDirection(int directionIn
>                           virNWFilterRuleDefPtr rule,
>                           virBufferPtr buf)
>  {
> +    switch (iptables_ctdir_corrected) {
> +    case CTDIR_STATUS_UNKNOWN:
> +        /* could not be determined or s.th. is seriously wrong */
> +        return;
> +    case CTDIR_STATUS_CORRECTED:
> +        directionIn = !directionIn;
> +        break;
> +    case CTDIR_STATUS_OLD:
> +        break;
> +    }
> +
>      if (rule->tt != VIR_NWFILTER_RULE_DIRECTION_INOUT)
>          virBufferAsprintf(buf, " -m conntrack --ctdir %s",
>                            (directionIn) ? "Original"
> @@ -4304,6 +4327,32 @@ ebiptablesDriverTestCLITools(void)
>      return ret;
>  }
>  
> +static void
> +ebiptablesDriverProbeCtdir(void)
> +{
> +    struct utsname utsname;
> +    unsigned long thisversion;
> +
> +    iptables_ctdir_corrected = CTDIR_STATUS_UNKNOWN;
> +
> +    if (uname(&utsname) < 0) {
> +        VIR_ERROR(_("Call to utsname failed: %d"), errno);
> +        return;
> +    }
> +
> +    /* following Linux lxr, the logic was inverted in 2.6.39 */
> +    if (virParseVersionString(utsname.release, &thisversion, true) < 0) {
> +        VIR_ERROR(_("Could not determine kernel version from string %s"),
> +                  utsname.release);
> +        return;
> +    }
> +
> +    if (thisversion >= 2 * 1000000 + 6 * 1000 + 39)
> +        iptables_ctdir_corrected = CTDIR_STATUS_CORRECTED;
> +    else
> +        iptables_ctdir_corrected = CTDIR_STATUS_OLD;
> +}
> +
>  static int
>  ebiptablesDriverInit(bool privileged)
>  {
> @@ -4341,6 +4390,9 @@ ebiptablesDriverInit(bool privileged)
>          return -ENOTSUP;
>      }
>  
> +    if (iptables_cmd_path)
> +        ebiptablesDriverProbeCtdir();
> +
>      ebiptables_driver.flags = TECHDRV_FLAG_INITIALIZED;
>  
>      return 0;
>
>




More information about the libvir-list mailing list