[libvirt] [PATCH 07/28] Rename ebtables.{c, h} to virebtables.{c, h}

Daniel P. Berrange berrange at redhat.com
Mon Dec 17 14:57:40 UTC 2012


From: "Daniel P. Berrange" <berrange at redhat.com>

---
 src/Makefile.am               |   2 +-
 src/qemu/qemu_bridge_filter.c |   2 +-
 src/qemu/qemu_conf.h          |   2 +-
 src/util/ebtables.c           | 486 ------------------------------------------
 src/util/ebtables.h           |  67 ------
 src/util/virebtables.c        | 486 ++++++++++++++++++++++++++++++++++++++++++
 src/util/virebtables.h        |  67 ++++++
 7 files changed, 556 insertions(+), 556 deletions(-)
 delete mode 100644 src/util/ebtables.c
 delete mode 100644 src/util/ebtables.h
 create mode 100644 src/util/virebtables.c
 create mode 100644 src/util/virebtables.h

diff --git a/src/Makefile.am b/src/Makefile.am
index ce16e87..daefa95 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -57,7 +57,6 @@ UTIL_SOURCES =							\
 		util/event_poll.c util/event_poll.h		\
 		util/hooks.c util/hooks.h			\
 		util/iptables.c util/iptables.h			\
-		util/ebtables.c util/ebtables.h			\
 		util/json.c util/json.h				\
 		util/logging.c util/logging.h			\
 		util/memory.c util/memory.h			\
@@ -83,6 +82,7 @@ UTIL_SOURCES =							\
 		util/vircommand.c util/vircommand.h		\
 		util/virconf.c util/virconf.h			\
 		util/virdnsmasq.c util/virdnsmasq.h             \
+		util/virebtables.c util/virebtables.h		\
 		util/virfile.c util/virfile.h			\
 		util/virnodesuspend.c util/virnodesuspend.h	\
 		util/virobject.c util/virobject.h		\
diff --git a/src/qemu/qemu_bridge_filter.c b/src/qemu/qemu_bridge_filter.c
index a34a92e..a6d0d4f 100644
--- a/src/qemu/qemu_bridge_filter.c
+++ b/src/qemu/qemu_bridge_filter.c
@@ -22,7 +22,7 @@
 
 #include <config.h>
 
-#include "ebtables.h"
+#include "virebtables.h"
 #include "qemu_conf.h"
 #include "qemu_driver.h"
 #include "util.h"
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index eafaf9f..5499203 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -26,7 +26,7 @@
 
 # include <config.h>
 
-# include "ebtables.h"
+# include "virebtables.h"
 # include "internal.h"
 # include "capabilities.h"
 # include "network_conf.h"
diff --git a/src/util/ebtables.c b/src/util/ebtables.c
deleted file mode 100644
index 4b427ee..0000000
--- a/src/util/ebtables.c
+++ /dev/null
@@ -1,486 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Red Hat, Inc.
- * Copyright (C) 2009 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/>.
- *
- * based on iptables.c
- * Authors:
- *     Gerhard Stenzel <gerhard.stenzel at de.ibm.com>
- */
-
-#include <config.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <errno.h>
-#include <limits.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-
-#ifdef HAVE_PATHS_H
-# include <paths.h>
-#endif
-
-#include "internal.h"
-#include "ebtables.h"
-#include "vircommand.h"
-#include "memory.h"
-#include "virterror_internal.h"
-#include "logging.h"
-#include "threads.h"
-
-#if HAVE_FIREWALLD
-static char *firewall_cmd_path = NULL;
-
-static int
-virEbTablesOnceInit(void)
-{
-    firewall_cmd_path = virFindFileInPath("firewall-cmd");
-    if (!firewall_cmd_path) {
-        VIR_INFO("firewall-cmd not found on system. "
-                 "firewalld support disabled for ebtables.");
-    } else {
-        virCommandPtr cmd = virCommandNew(firewall_cmd_path);
-        int status;
-
-        virCommandAddArgList(cmd, "--state", NULL);
-        if (virCommandRun(cmd, &status) < 0 || status != 0) {
-            VIR_INFO("firewall-cmd found but disabled for ebtables");
-            VIR_FREE(firewall_cmd_path);
-            firewall_cmd_path = NULL;
-        } else {
-            VIR_INFO("using firewalld for ebtables commands");
-        }
-        virCommandFree(cmd);
-    }
-    return 0;
-}
-
-VIR_ONCE_GLOBAL_INIT(virEbTables)
-
-#endif
-
-struct _ebtablesContext
-{
-    ebtRules *input_filter;
-    ebtRules *forward_filter;
-    ebtRules *nat_postrouting;
-};
-
-enum {
-    ADD = 0,
-    REMOVE,
-    CREATE,
-    POLICY,
-    INSERT
-};
-
-static void
-ebtRuleFree(ebtRule *rule)
-{
-    VIR_FREE(rule->rule);
-
-    if (rule->argv) {
-        int i = 0;
-        while (rule->argv[i])
-            VIR_FREE(rule->argv[i++]);
-        VIR_FREE(rule->argv);
-    }
-}
-
-static int
-ebtRulesAppend(ebtRules *rules,
-               char *rule,
-               const char **argv,
-               int command_idx)
-{
-    if (VIR_REALLOC_N(rules->rules, rules->nrules+1) < 0) {
-        int i = 0;
-        while (argv[i])
-            VIR_FREE(argv[i++]);
-        VIR_FREE(argv);
-        return ENOMEM;
-    }
-
-    rules->rules[rules->nrules].rule        = rule;
-    rules->rules[rules->nrules].argv        = argv;
-    rules->rules[rules->nrules].command_idx = command_idx;
-
-    rules->nrules++;
-
-    return 0;
-}
-
-static int
-ebtRulesRemove(ebtRules *rules,
-               char *rule)
-{
-    int i;
-
-    for (i = 0; i < rules->nrules; i++)
-        if (STREQ(rules->rules[i].rule, rule))
-            break;
-
-    if (i >= rules->nrules)
-        return EINVAL;
-
-    ebtRuleFree(&rules->rules[i]);
-
-    memmove(&rules->rules[i],
-            &rules->rules[i+1],
-            (rules->nrules - i - 1) * sizeof(ebtRule));
-
-    rules->nrules--;
-
-    return 0;
-}
-
-static void
-ebtRulesFree(ebtRules *rules)
-{
-    int i;
-
-    VIR_FREE(rules->table);
-    VIR_FREE(rules->chain);
-
-    if (rules->rules) {
-        for (i = 0; i < rules->nrules; i++)
-            ebtRuleFree(&rules->rules[i]);
-
-        VIR_FREE(rules->rules);
-
-        rules->nrules = 0;
-    }
-
-    VIR_FREE(rules);
-}
-
-static ebtRules *
-ebtRulesNew(const char *table,
-            const char *chain)
-{
-    ebtRules *rules;
-
-    if (VIR_ALLOC(rules) < 0)
-        return NULL;
-
-    if (!(rules->table = strdup(table)))
-        goto error;
-
-    if (!(rules->chain = strdup(chain)))
-        goto error;
-
-    rules->rules = NULL;
-    rules->nrules = 0;
-
-    return rules;
-
- error:
-    ebtRulesFree(rules);
-    return NULL;
-}
-
-static int ATTRIBUTE_SENTINEL
-ebtablesAddRemoveRule(ebtRules *rules, int action, const char *arg, ...)
-{
-    va_list args;
-    int retval = ENOMEM;
-    const char **argv;
-    char *rule = NULL;
-    const char *s;
-    int n, command_idx;
-
-    n = 1 + /* /sbin/ebtables  */
-        2 + /*   --table foo   */
-        2 + /*   --insert bar  */
-        1;  /*   arg           */
-
-#if HAVE_FIREWALLD
-    virEbTablesInitialize();
-    if (firewall_cmd_path)
-        n += 3; /* --direct --passthrough eb */
-#endif
-
-    va_start(args, arg);
-    while (va_arg(args, const char *))
-        n++;
-
-    va_end(args);
-
-    if (VIR_ALLOC_N(argv, n + 1) < 0)
-        goto error;
-
-    n = 0;
-
-#if HAVE_FIREWALLD
-    if (firewall_cmd_path) {
-        if (!(argv[n++] = strdup(firewall_cmd_path)))
-            goto error;
-        if (!(argv[n++] = strdup("--direct")))
-            goto error;
-        if (!(argv[n++] = strdup("--passthrough")))
-            goto error;
-        if (!(argv[n++] = strdup("eb")))
-            goto error;
-    } else
-#endif
-    if (!(argv[n++] = strdup(EBTABLES_PATH)))
-        goto error;
-
-    command_idx = n;
-
-    if (action == ADD || action == REMOVE) {
-        if (!(argv[n++] = strdup("--insert")))
-            goto error;
-
-        if (!(argv[n++] = strdup(rules->chain)))
-            goto error;
-    }
-
-    if (!(argv[n++] = strdup(arg)))
-        goto error;
-
-    va_start(args, arg);
-
-    while ((s = va_arg(args, const char *))) {
-        if (!(argv[n++] = strdup(s))) {
-            va_end(args);
-            goto error;
-        }
-    }
-
-    va_end(args);
-
-    if (!(rule = virArgvToString(&argv[command_idx])))
-        goto error;
-
-    if (action == REMOVE) {
-        VIR_FREE(argv[command_idx]);
-        if (!(argv[command_idx] = strdup("--delete")))
-            goto error;
-    }
-
-    if (virRun(argv, NULL) < 0) {
-        retval = errno;
-        goto error;
-    }
-
-    if (action == ADD || action == CREATE || action == POLICY ||
-        action == INSERT) {
-        retval = ebtRulesAppend(rules, rule, argv, command_idx);
-        rule = NULL;
-        argv = NULL;
-    } else {
-        retval = ebtRulesRemove(rules, rule);
-    }
-
- error:
-    VIR_FREE(rule);
-
-    if (argv) {
-        n = 0;
-        while (argv[n])
-            VIR_FREE(argv[n++]);
-        VIR_FREE(argv);
-    }
-
-    return retval;
-}
-
-
-/**
- * ebtablesContextNew:
- *
- * Create a new ebtable context
- *
- * Returns a pointer to the new structure or NULL in case of error
- */
-ebtablesContext *
-ebtablesContextNew(const char *driver)
-{
-    bool success = false;
-    ebtablesContext *ctx = NULL;
-    char *input_chain = NULL;
-    char *forward_chain = NULL;
-    char *nat_chain = NULL;
-
-    if (VIR_ALLOC(ctx) < 0)
-        return NULL;
-
-    if (virAsprintf(&input_chain, "libvirt_%s_INPUT", driver) < 0 ||
-        virAsprintf(&forward_chain, "libvirt_%s_FORWARD", driver) < 0 ||
-        virAsprintf(&nat_chain, "libvirt_%s_POSTROUTING", driver) < 0) {
-        goto cleanup;
-    }
-
-    if (!(ctx->input_filter = ebtRulesNew("filter", input_chain)))
-        goto cleanup;
-
-    if (!(ctx->forward_filter = ebtRulesNew("filter", forward_chain)))
-        goto cleanup;
-
-    if (!(ctx->nat_postrouting = ebtRulesNew("nat", nat_chain)))
-        goto cleanup;
-
-    success = true;
-
-cleanup:
-    VIR_FREE(input_chain);
-    VIR_FREE(forward_chain);
-    VIR_FREE(nat_chain);
-
-    if (!success) {
-        ebtablesContextFree(ctx);
-        ctx = NULL;
-    }
-
-    return ctx;
-}
-
-/**
- * ebtablesContextFree:
- * @ctx: pointer to the EB table context
- *
- * Free the resources associated with an EB table context
- */
-void
-ebtablesContextFree(ebtablesContext *ctx)
-{
-    if (!ctx)
-        return;
-    if (ctx->input_filter)
-        ebtRulesFree(ctx->input_filter);
-    if (ctx->forward_filter)
-        ebtRulesFree(ctx->forward_filter);
-    if (ctx->nat_postrouting)
-        ebtRulesFree(ctx->nat_postrouting);
-    VIR_FREE(ctx);
-}
-
-int
-ebtablesAddForwardPolicyReject(ebtablesContext *ctx)
-{
-    return ebtablesForwardPolicyReject(ctx, ADD);
-}
-
-
-int
-ebtablesRemoveForwardPolicyReject(ebtablesContext *ctx)
-{
-    return ebtablesForwardPolicyReject(ctx, REMOVE);
-}
-
-int
-ebtablesForwardPolicyReject(ebtablesContext *ctx,
-                            int action)
-{
-    /* create it, if it does not exist */
-    if (action == ADD) {
-        ebtablesAddRemoveRule(ctx->forward_filter,
-                              CREATE,
-                              "--new-chain", ctx->forward_filter->chain, NULL,
-                              NULL);
-        ebtablesAddRemoveRule(ctx->forward_filter,
-                              INSERT,
-                              "--insert", "FORWARD", "--jump",
-                              ctx->forward_filter->chain, NULL);
-    }
-
-    return ebtablesAddRemoveRule(ctx->forward_filter,
-                                 POLICY,
-                                 "-P", ctx->forward_filter->chain, "DROP",
-                                 NULL);
-}
-
-/*
- * Allow all traffic destined to the bridge, with a valid network address
- */
-static int
-ebtablesForwardAllowIn(ebtablesContext *ctx,
-                       const char *iface,
-                       const char *macaddr,
-                       int action)
-{
-    return ebtablesAddRemoveRule(ctx->forward_filter,
-                                     action,
-                                     "--in-interface", iface,
-                                     "--source", macaddr,
-                                     "--jump", "ACCEPT",
-                                     NULL);
-}
-
-/**
- * ebtablesAddForwardAllowIn:
- * @ctx: pointer to the EB table context
- * @iface: the output interface name
- * @physdev: the physical input device or NULL
- *
- * Add rules to the EB table context to allow the traffic on
- * @physdev device to be forwarded to interface @iface. This allows
- * the inbound traffic on a bridge.
- *
- * Returns 0 in case of success or an error code otherwise
- */
-int
-ebtablesAddForwardAllowIn(ebtablesContext *ctx,
-                          const char *iface,
-                          const virMacAddrPtr mac)
-{
-    char *macaddr;
-
-    if (virAsprintf(&macaddr,
-                    "%02x:%02x:%02x:%02x:%02x:%02x",
-                    mac->addr[0], mac->addr[1],
-                    mac->addr[2], mac->addr[3],
-                    mac->addr[4], mac->addr[5]) < 0) {
-        return -1;
-    }
-    return ebtablesForwardAllowIn(ctx, iface, macaddr, ADD);
-}
-
-/**
- * ebtablesRemoveForwardAllowIn:
- * @ctx: pointer to the EB table context
- * @iface: the output interface name
- * @physdev: the physical input device or NULL
- *
- * Remove rules from the EB table context hence forbidding the traffic
- * on the @physdev device to be forwarded to interface @iface. This
- * stops the inbound traffic on a bridge.
- *
- * Returns 0 in case of success or an error code otherwise
- */
-int
-ebtablesRemoveForwardAllowIn(ebtablesContext *ctx,
-                             const char *iface,
-                             const virMacAddrPtr mac)
-{
-    char *macaddr;
-
-    if (virAsprintf(&macaddr,
-                    "%02x:%02x:%02x:%02x:%02x:%02x",
-                    mac->addr[0], mac->addr[1],
-                    mac->addr[2], mac->addr[3],
-                    mac->addr[4], mac->addr[5]) < 0) {
-       return -1;
-    }
-    return ebtablesForwardAllowIn(ctx, iface, macaddr, REMOVE);
-}
diff --git a/src/util/ebtables.h b/src/util/ebtables.h
deleted file mode 100644
index 49dc8a0..0000000
--- a/src/util/ebtables.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2009 IBM Corp.
- * Copyright (C) 2007, 2008 Red Hat, Inc.
- *
- * 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/>.
- *
- * based on iptables.h
- * Authors:
- *     Gerhard Stenzel <gerhard.stenzel at de.ibm.com>
- */
-
-#ifndef __QEMUD_EBTABLES_H__
-# define __QEMUD_EBTABLES_H__
-
-# include "virmacaddr.h"
-
-typedef struct
-{
-    char  *rule;
-    const char **argv;
-    int    command_idx;
-} ebtRule;
-
-typedef struct
-{
-    char  *table;
-    char  *chain;
-
-    int      nrules;
-    ebtRule *rules;
-
-} ebtRules;
-
-typedef struct _ebtablesContext ebtablesContext;
-
-ebtablesContext *ebtablesContextNew              (const char *driver);
-void             ebtablesContextFree             (ebtablesContext *ctx);
-
-void             ebtablesSaveRules               (ebtablesContext *ctx);
-
-int              ebtablesAddForwardAllowIn       (ebtablesContext *ctx,
-                                                  const char *iface,
-                                                  const virMacAddrPtr mac);
-int              ebtablesRemoveForwardAllowIn    (ebtablesContext *ctx,
-                                                  const char *iface,
-                                                  const virMacAddrPtr mac);
-
-int              ebtablesAddForwardPolicyReject(ebtablesContext *ctx);
-
-int              ebtablesRemoveForwardPolicyReject(ebtablesContext *ctx);
-
-int              ebtablesForwardPolicyReject(ebtablesContext *ctx,
-                                                  int action);
-
-#endif /* __QEMUD_ebtabLES_H__ */
diff --git a/src/util/virebtables.c b/src/util/virebtables.c
new file mode 100644
index 0000000..8474b2a
--- /dev/null
+++ b/src/util/virebtables.c
@@ -0,0 +1,486 @@
+/*
+ * Copyright (C) 2007-2012 Red Hat, Inc.
+ * Copyright (C) 2009 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/>.
+ *
+ * based on iptables.c
+ * Authors:
+ *     Gerhard Stenzel <gerhard.stenzel at de.ibm.com>
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#ifdef HAVE_PATHS_H
+# include <paths.h>
+#endif
+
+#include "internal.h"
+#include "virebtables.h"
+#include "vircommand.h"
+#include "memory.h"
+#include "virterror_internal.h"
+#include "logging.h"
+#include "threads.h"
+
+#if HAVE_FIREWALLD
+static char *firewall_cmd_path = NULL;
+
+static int
+virEbTablesOnceInit(void)
+{
+    firewall_cmd_path = virFindFileInPath("firewall-cmd");
+    if (!firewall_cmd_path) {
+        VIR_INFO("firewall-cmd not found on system. "
+                 "firewalld support disabled for ebtables.");
+    } else {
+        virCommandPtr cmd = virCommandNew(firewall_cmd_path);
+        int status;
+
+        virCommandAddArgList(cmd, "--state", NULL);
+        if (virCommandRun(cmd, &status) < 0 || status != 0) {
+            VIR_INFO("firewall-cmd found but disabled for ebtables");
+            VIR_FREE(firewall_cmd_path);
+            firewall_cmd_path = NULL;
+        } else {
+            VIR_INFO("using firewalld for ebtables commands");
+        }
+        virCommandFree(cmd);
+    }
+    return 0;
+}
+
+VIR_ONCE_GLOBAL_INIT(virEbTables)
+
+#endif
+
+struct _ebtablesContext
+{
+    ebtRules *input_filter;
+    ebtRules *forward_filter;
+    ebtRules *nat_postrouting;
+};
+
+enum {
+    ADD = 0,
+    REMOVE,
+    CREATE,
+    POLICY,
+    INSERT
+};
+
+static void
+ebtRuleFree(ebtRule *rule)
+{
+    VIR_FREE(rule->rule);
+
+    if (rule->argv) {
+        int i = 0;
+        while (rule->argv[i])
+            VIR_FREE(rule->argv[i++]);
+        VIR_FREE(rule->argv);
+    }
+}
+
+static int
+ebtRulesAppend(ebtRules *rules,
+               char *rule,
+               const char **argv,
+               int command_idx)
+{
+    if (VIR_REALLOC_N(rules->rules, rules->nrules+1) < 0) {
+        int i = 0;
+        while (argv[i])
+            VIR_FREE(argv[i++]);
+        VIR_FREE(argv);
+        return ENOMEM;
+    }
+
+    rules->rules[rules->nrules].rule        = rule;
+    rules->rules[rules->nrules].argv        = argv;
+    rules->rules[rules->nrules].command_idx = command_idx;
+
+    rules->nrules++;
+
+    return 0;
+}
+
+static int
+ebtRulesRemove(ebtRules *rules,
+               char *rule)
+{
+    int i;
+
+    for (i = 0; i < rules->nrules; i++)
+        if (STREQ(rules->rules[i].rule, rule))
+            break;
+
+    if (i >= rules->nrules)
+        return EINVAL;
+
+    ebtRuleFree(&rules->rules[i]);
+
+    memmove(&rules->rules[i],
+            &rules->rules[i+1],
+            (rules->nrules - i - 1) * sizeof(ebtRule));
+
+    rules->nrules--;
+
+    return 0;
+}
+
+static void
+ebtRulesFree(ebtRules *rules)
+{
+    int i;
+
+    VIR_FREE(rules->table);
+    VIR_FREE(rules->chain);
+
+    if (rules->rules) {
+        for (i = 0; i < rules->nrules; i++)
+            ebtRuleFree(&rules->rules[i]);
+
+        VIR_FREE(rules->rules);
+
+        rules->nrules = 0;
+    }
+
+    VIR_FREE(rules);
+}
+
+static ebtRules *
+ebtRulesNew(const char *table,
+            const char *chain)
+{
+    ebtRules *rules;
+
+    if (VIR_ALLOC(rules) < 0)
+        return NULL;
+
+    if (!(rules->table = strdup(table)))
+        goto error;
+
+    if (!(rules->chain = strdup(chain)))
+        goto error;
+
+    rules->rules = NULL;
+    rules->nrules = 0;
+
+    return rules;
+
+ error:
+    ebtRulesFree(rules);
+    return NULL;
+}
+
+static int ATTRIBUTE_SENTINEL
+ebtablesAddRemoveRule(ebtRules *rules, int action, const char *arg, ...)
+{
+    va_list args;
+    int retval = ENOMEM;
+    const char **argv;
+    char *rule = NULL;
+    const char *s;
+    int n, command_idx;
+
+    n = 1 + /* /sbin/ebtables  */
+        2 + /*   --table foo   */
+        2 + /*   --insert bar  */
+        1;  /*   arg           */
+
+#if HAVE_FIREWALLD
+    virEbTablesInitialize();
+    if (firewall_cmd_path)
+        n += 3; /* --direct --passthrough eb */
+#endif
+
+    va_start(args, arg);
+    while (va_arg(args, const char *))
+        n++;
+
+    va_end(args);
+
+    if (VIR_ALLOC_N(argv, n + 1) < 0)
+        goto error;
+
+    n = 0;
+
+#if HAVE_FIREWALLD
+    if (firewall_cmd_path) {
+        if (!(argv[n++] = strdup(firewall_cmd_path)))
+            goto error;
+        if (!(argv[n++] = strdup("--direct")))
+            goto error;
+        if (!(argv[n++] = strdup("--passthrough")))
+            goto error;
+        if (!(argv[n++] = strdup("eb")))
+            goto error;
+    } else
+#endif
+    if (!(argv[n++] = strdup(EBTABLES_PATH)))
+        goto error;
+
+    command_idx = n;
+
+    if (action == ADD || action == REMOVE) {
+        if (!(argv[n++] = strdup("--insert")))
+            goto error;
+
+        if (!(argv[n++] = strdup(rules->chain)))
+            goto error;
+    }
+
+    if (!(argv[n++] = strdup(arg)))
+        goto error;
+
+    va_start(args, arg);
+
+    while ((s = va_arg(args, const char *))) {
+        if (!(argv[n++] = strdup(s))) {
+            va_end(args);
+            goto error;
+        }
+    }
+
+    va_end(args);
+
+    if (!(rule = virArgvToString(&argv[command_idx])))
+        goto error;
+
+    if (action == REMOVE) {
+        VIR_FREE(argv[command_idx]);
+        if (!(argv[command_idx] = strdup("--delete")))
+            goto error;
+    }
+
+    if (virRun(argv, NULL) < 0) {
+        retval = errno;
+        goto error;
+    }
+
+    if (action == ADD || action == CREATE || action == POLICY ||
+        action == INSERT) {
+        retval = ebtRulesAppend(rules, rule, argv, command_idx);
+        rule = NULL;
+        argv = NULL;
+    } else {
+        retval = ebtRulesRemove(rules, rule);
+    }
+
+ error:
+    VIR_FREE(rule);
+
+    if (argv) {
+        n = 0;
+        while (argv[n])
+            VIR_FREE(argv[n++]);
+        VIR_FREE(argv);
+    }
+
+    return retval;
+}
+
+
+/**
+ * ebtablesContextNew:
+ *
+ * Create a new ebtable context
+ *
+ * Returns a pointer to the new structure or NULL in case of error
+ */
+ebtablesContext *
+ebtablesContextNew(const char *driver)
+{
+    bool success = false;
+    ebtablesContext *ctx = NULL;
+    char *input_chain = NULL;
+    char *forward_chain = NULL;
+    char *nat_chain = NULL;
+
+    if (VIR_ALLOC(ctx) < 0)
+        return NULL;
+
+    if (virAsprintf(&input_chain, "libvirt_%s_INPUT", driver) < 0 ||
+        virAsprintf(&forward_chain, "libvirt_%s_FORWARD", driver) < 0 ||
+        virAsprintf(&nat_chain, "libvirt_%s_POSTROUTING", driver) < 0) {
+        goto cleanup;
+    }
+
+    if (!(ctx->input_filter = ebtRulesNew("filter", input_chain)))
+        goto cleanup;
+
+    if (!(ctx->forward_filter = ebtRulesNew("filter", forward_chain)))
+        goto cleanup;
+
+    if (!(ctx->nat_postrouting = ebtRulesNew("nat", nat_chain)))
+        goto cleanup;
+
+    success = true;
+
+cleanup:
+    VIR_FREE(input_chain);
+    VIR_FREE(forward_chain);
+    VIR_FREE(nat_chain);
+
+    if (!success) {
+        ebtablesContextFree(ctx);
+        ctx = NULL;
+    }
+
+    return ctx;
+}
+
+/**
+ * ebtablesContextFree:
+ * @ctx: pointer to the EB table context
+ *
+ * Free the resources associated with an EB table context
+ */
+void
+ebtablesContextFree(ebtablesContext *ctx)
+{
+    if (!ctx)
+        return;
+    if (ctx->input_filter)
+        ebtRulesFree(ctx->input_filter);
+    if (ctx->forward_filter)
+        ebtRulesFree(ctx->forward_filter);
+    if (ctx->nat_postrouting)
+        ebtRulesFree(ctx->nat_postrouting);
+    VIR_FREE(ctx);
+}
+
+int
+ebtablesAddForwardPolicyReject(ebtablesContext *ctx)
+{
+    return ebtablesForwardPolicyReject(ctx, ADD);
+}
+
+
+int
+ebtablesRemoveForwardPolicyReject(ebtablesContext *ctx)
+{
+    return ebtablesForwardPolicyReject(ctx, REMOVE);
+}
+
+int
+ebtablesForwardPolicyReject(ebtablesContext *ctx,
+                            int action)
+{
+    /* create it, if it does not exist */
+    if (action == ADD) {
+        ebtablesAddRemoveRule(ctx->forward_filter,
+                              CREATE,
+                              "--new-chain", ctx->forward_filter->chain, NULL,
+                              NULL);
+        ebtablesAddRemoveRule(ctx->forward_filter,
+                              INSERT,
+                              "--insert", "FORWARD", "--jump",
+                              ctx->forward_filter->chain, NULL);
+    }
+
+    return ebtablesAddRemoveRule(ctx->forward_filter,
+                                 POLICY,
+                                 "-P", ctx->forward_filter->chain, "DROP",
+                                 NULL);
+}
+
+/*
+ * Allow all traffic destined to the bridge, with a valid network address
+ */
+static int
+ebtablesForwardAllowIn(ebtablesContext *ctx,
+                       const char *iface,
+                       const char *macaddr,
+                       int action)
+{
+    return ebtablesAddRemoveRule(ctx->forward_filter,
+                                     action,
+                                     "--in-interface", iface,
+                                     "--source", macaddr,
+                                     "--jump", "ACCEPT",
+                                     NULL);
+}
+
+/**
+ * ebtablesAddForwardAllowIn:
+ * @ctx: pointer to the EB table context
+ * @iface: the output interface name
+ * @physdev: the physical input device or NULL
+ *
+ * Add rules to the EB table context to allow the traffic on
+ * @physdev device to be forwarded to interface @iface. This allows
+ * the inbound traffic on a bridge.
+ *
+ * Returns 0 in case of success or an error code otherwise
+ */
+int
+ebtablesAddForwardAllowIn(ebtablesContext *ctx,
+                          const char *iface,
+                          const virMacAddrPtr mac)
+{
+    char *macaddr;
+
+    if (virAsprintf(&macaddr,
+                    "%02x:%02x:%02x:%02x:%02x:%02x",
+                    mac->addr[0], mac->addr[1],
+                    mac->addr[2], mac->addr[3],
+                    mac->addr[4], mac->addr[5]) < 0) {
+        return -1;
+    }
+    return ebtablesForwardAllowIn(ctx, iface, macaddr, ADD);
+}
+
+/**
+ * ebtablesRemoveForwardAllowIn:
+ * @ctx: pointer to the EB table context
+ * @iface: the output interface name
+ * @physdev: the physical input device or NULL
+ *
+ * Remove rules from the EB table context hence forbidding the traffic
+ * on the @physdev device to be forwarded to interface @iface. This
+ * stops the inbound traffic on a bridge.
+ *
+ * Returns 0 in case of success or an error code otherwise
+ */
+int
+ebtablesRemoveForwardAllowIn(ebtablesContext *ctx,
+                             const char *iface,
+                             const virMacAddrPtr mac)
+{
+    char *macaddr;
+
+    if (virAsprintf(&macaddr,
+                    "%02x:%02x:%02x:%02x:%02x:%02x",
+                    mac->addr[0], mac->addr[1],
+                    mac->addr[2], mac->addr[3],
+                    mac->addr[4], mac->addr[5]) < 0) {
+       return -1;
+    }
+    return ebtablesForwardAllowIn(ctx, iface, macaddr, REMOVE);
+}
diff --git a/src/util/virebtables.h b/src/util/virebtables.h
new file mode 100644
index 0000000..49dc8a0
--- /dev/null
+++ b/src/util/virebtables.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2009 IBM Corp.
+ * Copyright (C) 2007, 2008 Red Hat, Inc.
+ *
+ * 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/>.
+ *
+ * based on iptables.h
+ * Authors:
+ *     Gerhard Stenzel <gerhard.stenzel at de.ibm.com>
+ */
+
+#ifndef __QEMUD_EBTABLES_H__
+# define __QEMUD_EBTABLES_H__
+
+# include "virmacaddr.h"
+
+typedef struct
+{
+    char  *rule;
+    const char **argv;
+    int    command_idx;
+} ebtRule;
+
+typedef struct
+{
+    char  *table;
+    char  *chain;
+
+    int      nrules;
+    ebtRule *rules;
+
+} ebtRules;
+
+typedef struct _ebtablesContext ebtablesContext;
+
+ebtablesContext *ebtablesContextNew              (const char *driver);
+void             ebtablesContextFree             (ebtablesContext *ctx);
+
+void             ebtablesSaveRules               (ebtablesContext *ctx);
+
+int              ebtablesAddForwardAllowIn       (ebtablesContext *ctx,
+                                                  const char *iface,
+                                                  const virMacAddrPtr mac);
+int              ebtablesRemoveForwardAllowIn    (ebtablesContext *ctx,
+                                                  const char *iface,
+                                                  const virMacAddrPtr mac);
+
+int              ebtablesAddForwardPolicyReject(ebtablesContext *ctx);
+
+int              ebtablesRemoveForwardPolicyReject(ebtablesContext *ctx);
+
+int              ebtablesForwardPolicyReject(ebtablesContext *ctx,
+                                                  int action);
+
+#endif /* __QEMUD_ebtabLES_H__ */
-- 
1.7.11.7




More information about the libvir-list mailing list