This patch adds the files which implement the ebtables wrapper. Signed-off-by: Gerhard Stenzel <gerhard.stenzel@xxxxxxxxxx> --- src/util/ebtables.c | 964 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/util/ebtables.h | 136 +++++++ 2 files changed, 1100 insertions(+), 0 deletions(-) create mode 100644 src/util/ebtables.c create mode 100644 src/util/ebtables.h diff --git a/src/util/ebtables.c b/src/util/ebtables.c new file mode 100644 index 0000000..930d046 --- /dev/null +++ b/src/util/ebtables.c @@ -0,0 +1,964 @@ +/* + * Copyright (C) 2009 IBM Corp. + * Copyright (C) 2007-2009 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * based on iptables.c + * Authors: + * Gerhard Stenzel <gerhard.stenzel@xxxxxxxxxx> + */ + +#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> + +#ifdef HAVE_SYS_WAIT_H +#include <sys/wait.h> +#endif + +#ifdef HAVE_PATHS_H +#include <paths.h> +#endif + +#include "internal.h" +#include "ebtables.h" +#include "util.h" +#include "memory.h" +#include "virterror_internal.h" +#include "logging.h" + +enum { + ADD = 0, + REMOVE +}; + + +#ifdef ENABLE_ebtabLES_LOKKIT +static void +notifyRulesUpdated(const char *table, + const char *path) +{ + char arg[PATH_MAX]; + const char *argv[4]; + + snprintf(arg, sizeof(arg), "--custom-rules=ipv4:%s:%s", table, path); + + argv[0] = (char *) LOKKIT_PATH; + argv[1] = (char *) "--nostart"; + argv[2] = arg; + argv[3] = NULL; + + char ebuf[1024]; + if (virRun(NULL, argv, NULL) < 0) + VIR_WARN(_("Failed to run '%s %s': %s"), + LOKKIT_PATH, arg, virStrerror(errno, ebuf, sizeof ebuf)); +} + +static int +stripLine(char *str, int len, const char *line) +{ + char *s, *p; + int changed; + + changed = 0; + s = str; + + while ((p = strchr(s, '\n'))) { + if (p == s || STRNEQLEN(s, line, p - s)) { + s = ++p; + continue; + } + + ++p; + memmove(s, p, len - (p - str) + 1); + len -= p - s; + changed = 1; + } + + if (STREQ(s, line)) { + *s = '\0'; + changed = 1; + } + + return changed; +} + +static void +notifyRulesRemoved(const char *table, + const char *path) +{ +/* 10 MB limit on config file size as a sanity check */ +#define MAX_FILE_LEN (1024*1024*10) + + char arg[PATH_MAX]; + char *content; + int len; + FILE *f = NULL; + + len = virFileReadAll(SYSCONF_DIR "/sysconfig/system-config-firewall", + MAX_FILE_LEN, &content); + if (len < 0) { + VIR_WARN("%s", _("Failed to read " SYSCONF_DIR + "/sysconfig/system-config-firewall")); + return; + } + + snprintf(arg, sizeof(arg), "--custom-rules=ipv4:%s:%s", table, path); + + if (!stripLine(content, len, arg)) { + VIR_FREE(content); + return; + } + + if (!(f = fopen(SYSCONF_DIR "/sysconfig/system-config-firewall", "w"))) + goto write_error; + + if (fputs(content, f) == EOF) + goto write_error; + + if (fclose(f) == EOF) { + f = NULL; + goto write_error; + } + + VIR_FREE(content); + + return; + + write_error:; + char ebuf[1024]; + VIR_WARN(_("Failed to write to " SYSCONF_DIR + "/sysconfig/system-config-firewall : %s"), + virStrerror(errno, ebuf, sizeof ebuf)); + if (f) + fclose(f); + VIR_FREE(content); + +#undef MAX_FILE_LEN +} + +static int +writeRules(const char *path, + const ebtRule *rules, + int nrules) +{ + char tmp[PATH_MAX]; + FILE *f; + int istmp; + int i; + + if (nrules == 0 && unlink(path) == 0) + return 0; + + if (snprintf(tmp, PATH_MAX, "%s.new", path) >= PATH_MAX) + return EINVAL; + + istmp = 1; + + if (!(f = fopen(tmp, "w"))) { + istmp = 0; + if (!(f = fopen(path, "w"))) + return errno; + } + + for (i = 0; i < nrules; i++) { + if (fputs(rules[i].rule, f) == EOF || + fputc('\n', f) == EOF) { + fclose(f); + if (istmp) + unlink(tmp); + return errno; + } + } + + fclose(f); + + if (istmp && rename(tmp, path) < 0) { + unlink(tmp); + return errno; + } + + if (istmp) + unlink(tmp); + + return 0; +} +#endif /* ENABLE_ebtabLES_LOKKIT */ + +static void +ebtRulesSave(ebtRules *rules) +{ +#ifdef ENABLE_ebtabLES_LOKKIT + int err; + + char ebuf[1024]; + if ((err = virFileMakePath(rules->dir))) { + VIR_WARN(_("Failed to create directory %s : %s"), + rules->dir, virStrerror(err, ebuf, sizeof ebuf)); + return; + } + + if ((err = writeRules(rules->path, rules->rules, rules->nrules))) { + VIR_WARN(_("Failed to saves ebtables rules to %s : %s"), + rules->path, virStrerror(err, ebuf, sizeof ebuf)); + return; + } + + if (rules->nrules > 0) + notifyRulesUpdated(rules->table, rules->path); + else + notifyRulesRemoved(rules->table, rules->path); +#else + (void) rules; +#endif /* ENABLE_ebtabLES_LOKKIT */ +} + +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; + } + +#ifdef ENABLE_ebtabLES_LOKKIT + rules->dir[0] = '\0'; + rules->path[0] = '\0'; +#endif /* ENABLE_ebtabLES_LOKKIT */ + + 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; + +#ifdef ENABLE_ebtabLES_LOKKIT + if (virFileBuildPath(LOCAL_STATE_DIR "/lib/libvirt/ebtables", table, NULL, + rules->dir, sizeof(rules->dir)) < 0) + goto error; + + if (virFileBuildPath(rules->dir, chain, ".chain", rules->path, sizeof(rules->path)) < 0) + goto error; +#endif /* ENABLE_ebtabLES_LOKKIT */ + + return rules; + + error: + ebtRulesFree(rules); + return NULL; +} + +static int +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 */ + + va_start(args, arg); + while ((s = va_arg(args, const char *))) + n++; + + va_end(args); + + if (VIR_ALLOC_N(argv, n + 1) < 0) + goto error; + + n = 0; + + if (!(argv[n++] = strdup(EBTABLES_PATH))) + goto error; + +/* + if (!(argv[n++] = strdup("--table"))) + goto error; + + if (!(argv[n++] = strdup(rules->table))) + goto error; +*/ + command_idx = n; +/* + 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))) + 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(NULL, argv, NULL) < 0) { + retval = errno; + goto error; + } + + if (action == ADD) { + 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(void) +{ + ebtablesContext *ctx; + + if (VIR_ALLOC(ctx) < 0) + return NULL; + + if (!(ctx->input_filter = ebtRulesNew("filter", "INPUT"))) + goto error; + + if (!(ctx->forward_filter = ebtRulesNew("filter", "FORWARD"))) + goto error; + + if (!(ctx->nat_postrouting = ebtRulesNew("nat", "POSTROUTING"))) + goto error; + + return ctx; + + error: + ebtablesContextFree(ctx); + return NULL; +} + +/** + * ebtablesContextFree: + * @ctx: pointer to the IP table context + * + * Free the resources associated with an IP table context + */ +void +ebtablesContextFree(ebtablesContext *ctx) +{ + 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); +} + +/** + * ebtablesSaveRules: + * @ctx: pointer to the IP table context + * + * Saves all the IP table rules associated with a context + * to disk so that if ebtables is restarted, the rules + * will automatically be reload. + */ +void +ebtablesSaveRules(ebtablesContext *ctx) +{ + ebtRulesSave(ctx->input_filter); + ebtRulesSave(ctx->forward_filter); + ebtRulesSave(ctx->nat_postrouting); +} + +static void +ebtRulesReload(ebtRules *rules) +{ + int i; + char ebuf[1024]; + + for (i = 0; i < rules->nrules; i++) { + ebtRule *rule = &rules->rules[i]; + const char *orig; + + orig = rule->argv[rule->command_idx]; + rule->argv[rule->command_idx] = (char *) "--delete"; + + if (virRun(NULL, rule->argv, NULL) < 0) + VIR_WARN(_("Failed to remove ebtables rule '%s'" + " from chain '%s' in table '%s': %s"), + rule->rule, rules->chain, rules->table, + virStrerror(errno, ebuf, sizeof ebuf)); + + rule->argv[rule->command_idx] = orig; + } + + for (i = 0; i < rules->nrules; i++) + if (virRun(NULL, rules->rules[i].argv, NULL) < 0) + VIR_WARN(_("Failed to add ebtables rule '%s'" + " to chain '%s' in table '%s': %s"), + rules->rules[i].rule, rules->chain, rules->table, + virStrerror(errno, ebuf, sizeof ebuf)); +} + +/** + * ebtablesReloadRules: + * @ctx: pointer to the IP table context + * + * Reloads all the IP table rules associated to a context + */ +void +ebtablesReloadRules(ebtablesContext *ctx) +{ + ebtRulesReload(ctx->input_filter); + ebtRulesReload(ctx->forward_filter); + ebtRulesReload(ctx->nat_postrouting); +} + +/* +static int +ebtablesInput(ebtablesContext *ctx, + const char *iface, + int port, + int action, + int tcp) +{ + char portstr[32]; + + snprintf(portstr, sizeof(portstr), "%d", port); + portstr[sizeof(portstr) - 1] = '\0'; + + return ebtablesAddRemoveRule(ctx->input_filter, + action, + "--in-interface", iface, + "--protocol", tcp ? "tcp" : "udp", + "--destination-port", portstr, + "--jump", "ACCEPT", + NULL); +} +*/ +/* Allow all traffic coming from the bridge, with a valid network address + * to proceed to WAN + */ +static int +ebtablesForwardAllowOut(ebtablesContext *ctx, + const char *network, + const char *iface, + const char *physdev, + int action) +{ + if (physdev && physdev[0]) { + return ebtablesAddRemoveRule(ctx->forward_filter, + action, + "--source", network, + "--in-interface", iface, + "--out-interface", physdev, + "--jump", "ACCEPT", + NULL); + } else { + return ebtablesAddRemoveRule(ctx->forward_filter, + action, + "--source", network, + "--in-interface", iface, + "--jump", "ACCEPT", + NULL); + } +} + +int +ebtablesAddForwardPolicyReject(ebtablesContext *ctx) +{ + return ebtablesForwardPolicyReject(ctx, ADD); +} + +int +ebtablesRemoveForwardPolicyReject(ebtablesContext *ctx) +{ + return ebtablesForwardPolicyReject(ctx, REMOVE); +} + +int +ebtablesForwardPolicyReject(ebtablesContext *ctx, + int action) +{ + return ebtablesAddRemoveRule(ctx->forward_filter, + action, + "-P", "FORWARD", "DROP", + NULL); +} + +/** + * ebtablesAddForwardAllowOut: + * @ctx: pointer to the IP table context + * @network: the source network name + * @iface: the source interface name + * @physdev: the physical output device + * + * Add a rule to the IP table context to allow the traffic for the + * network @network via interface @iface to be forwarded to + * @physdev device. This allow the outbound traffic on a bridge. + * + * Returns 0 in case of success or an error code otherwise + */ +int +ebtablesAddForwardAllowOut(ebtablesContext *ctx, + const char *network, + const char *iface, + const char *physdev) +{ + return ebtablesForwardAllowOut(ctx, network, iface, physdev, ADD); +} + +/** + * ebtablesRemoveForwardAllowOut: + * @ctx: pointer to the IP table context + * @network: the source network name + * @iface: the source interface name + * @physdev: the physical output device + * + * Remove a rule from the IP table context hence forbidding forwarding + * of the traffic for the network @network via interface @iface + * to the @physdev device output. This stops the outbound traffic on a bridge. + * + * Returns 0 in case of success or an error code otherwise + */ +int +ebtablesRemoveForwardAllowOut(ebtablesContext *ctx, + const char *network, + const char *iface, + const char *physdev) +{ + return ebtablesForwardAllowOut(ctx, network, iface, physdev, REMOVE); +} + + +/* Allow all traffic destined to the bridge, with a valid network address + * and associated with an existing connection + */ +static int +ebtablesForwardAllowRelatedIn(ebtablesContext *ctx, + const char *network, + const char *iface, + const char *physdev, + int action) +{ + if (physdev && physdev[0]) { + return ebtablesAddRemoveRule(ctx->forward_filter, + action, + "--destination", network, + "--in-interface", physdev, + "--out-interface", iface, + "--match", "state", + "--state", "ESTABLISHED,RELATED", + "--jump", "ACCEPT", + NULL); + } else { + return ebtablesAddRemoveRule(ctx->forward_filter, + action, + "--destination", network, + "--out-interface", iface, + "--match", "state", + "--state", "ESTABLISHED,RELATED", + "--jump", "ACCEPT", + NULL); + } +} + +/** + * ebtablesAddForwardAllowRelatedIn: + * @ctx: pointer to the IP table context + * @network: the source network name + * @iface: the output interface name + * @physdev: the physical input device or NULL + * + * Add rules to the IP table context to allow the traffic for the + * network @network on @physdev device to be forwarded to + * interface @iface, if it is part of an existing connection. + * + * Returns 0 in case of success or an error code otherwise + */ +int +ebtablesAddForwardAllowRelatedIn(ebtablesContext *ctx, + const char *network, + const char *iface, + const char *physdev) +{ + return ebtablesForwardAllowRelatedIn(ctx, network, iface, physdev, ADD); +} + +/** + * ebtablesRemoveForwardAllowRelatedIn: + * @ctx: pointer to the IP table context + * @network: the source network name + * @iface: the output interface name + * @physdev: the physical input device or NULL + * + * Remove rules from the IP table context hence forbidding the traffic for + * network @network on @physdev device to be forwarded to + * interface @iface, if it is part of an existing connection. + * + * Returns 0 in case of success or an error code otherwise + */ +int +ebtablesRemoveForwardAllowRelatedIn(ebtablesContext *ctx, + const char *network, + const char *iface, + const char *physdev) +{ + return ebtablesForwardAllowRelatedIn(ctx, network, iface, physdev, REMOVE); +} + +/* Allow all traffic destined to the bridge, with a valid network address + */ +static int +ebtablesForwardAllowIn(ebtablesContext *ctx, + const char *network, + const char *iface, + const char *macaddr, + int action) +{ + return ebtablesAddRemoveRule(ctx->forward_filter, + action, +/* "--destination", network,*/ + "--insert", "FORWARD", + "--in-interface", iface, +/* "--out-interface", network, */ + "--source", macaddr, + "--jump", "ACCEPT", + NULL); +} + +/** + * ebtablesAddForwardAllowIn: + * @ctx: pointer to the IP table context + * @network: the source network name + * @iface: the output interface name + * @physdev: the physical input device or NULL + * + * Add rules to the IP table context to allow the traffic for the + * network @network on @physdev device to be forwarded to + * interface @iface. This allow the inbound traffic on a bridge. + * + * Returns 0 in case of success or an error code otherwise + */ +int +ebtablesAddForwardAllowIn(ebtablesContext *ctx, + const char *network, + const char *iface, + const char *physdev) +{ + return ebtablesForwardAllowIn(ctx, network, iface, physdev, ADD); +} + +/** + * ebtablesRemoveForwardAllowIn: + * @ctx: pointer to the IP table context + * @network: the source network name + * @iface: the output interface name + * @physdev: the physical input device or NULL + * + * Remove rules from the IP table context hence forbidding the traffic for + * network @network on @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 *network, + const char *iface, + const char *physdev) +{ + return ebtablesForwardAllowIn(ctx, network, iface, physdev, REMOVE); +} + + +/* Allow all traffic between guests on the same bridge, + * with a valid network address + */ +static int +ebtablesForwardAllowCross(ebtablesContext *ctx, + const char *iface, + int action) +{ + return ebtablesAddRemoveRule(ctx->forward_filter, + action, + "--in-interface", iface, + "--out-interface", iface, + "--jump", "ACCEPT", + NULL); +} + +/** + * ebtablesAddForwardAllowCross: + * @ctx: pointer to the IP table context + * @iface: the input/output interface name + * + * Add rules to the IP table context to allow traffic to cross that + * interface. It allows all traffic between guests on the same bridge + * represented by that interface. + * + * Returns 0 in case of success or an error code otherwise + */ +int +ebtablesAddForwardAllowCross(ebtablesContext *ctx, + const char *iface) { + return ebtablesForwardAllowCross(ctx, iface, ADD); +} + +/** + * ebtablesRemoveForwardAllowCross: + * @ctx: pointer to the IP table context + * @iface: the input/output interface name + * + * Remove rules to the IP table context to block traffic to cross that + * interface. It forbids traffic between guests on the same bridge + * represented by that interface. + * + * Returns 0 in case of success or an error code otherwise + */ +int +ebtablesRemoveForwardAllowCross(ebtablesContext *ctx, + const char *iface) { + return ebtablesForwardAllowCross(ctx, iface, REMOVE); +} + + +/* Drop all traffic trying to forward from the bridge. + * ie the bridge is the in interface + */ +static int +ebtablesForwardRejectOut(ebtablesContext *ctx, + const char *iface, + int action) +{ + return ebtablesAddRemoveRule(ctx->forward_filter, + action, + "--in-interface", iface, + "--jump", "DROP", + NULL); +} + +/** + * ebtablesAddForwardRejectOut: + * @ctx: pointer to the EB table context + * @iface: the output interface name + * + * Add rules to the EB table context to forbid all traffic to that + * interface. It forbids forwarding from the bridge to that interface. + * + * Returns 0 in case of success or an error code otherwise + */ +int +ebtablesAddForwardRejectOut(ebtablesContext *ctx, + const char *iface) +{ + return ebtablesForwardRejectOut(ctx, iface, ADD); +} + +/** + * ebtablesRemoveForwardRejectOut: + * @ctx: pointer to the EB table context + * @iface: the output interface name + * + * Remove rules from the EB table context forbidding all traffic to that + * interface. It reallow forwarding from the bridge to that interface. + * + * Returns 0 in case of success or an error code otherwise + */ +int +ebtablesRemoveForwardRejectOut(ebtablesContext *ctx, + const char *iface) +{ + return ebtablesForwardRejectOut(ctx, iface, REMOVE); +} + + + + +/* Drop all traffic trying to forward to the bridge. + * ie the bridge is the out interface + */ +static int +ebtablesForwardRejectIn(ebtablesContext *ctx, + const char *iface, + int action) +{ + return ebtablesAddRemoveRule(ctx->forward_filter, + action, + "--out-interface", iface, + "--jump", "DROP", + NULL); +} + +/** + * ebtablesAddForwardRejectIn: + * @ctx: pointer to the IP table context + * @iface: the input interface name + * + * Add rules to the IP table context to forbid all traffic from that + * interface. It forbids forwarding from that interface to the bridge. + * + * Returns 0 in case of success or an error code otherwise + */ +int +ebtablesAddForwardRejectIn(ebtablesContext *ctx, + const char *iface) +{ + return ebtablesForwardRejectIn(ctx, iface, ADD); +} + +/** + * ebtablesRemoveForwardRejectIn: + * @ctx: pointer to the IP table context + * @iface: the input interface name + * + * Remove rules from the IP table context forbidding all traffic from that + * interface. It allows forwarding from that interface to the bridge. + * + * Returns 0 in case of success or an error code otherwise + */ +int +ebtablesRemoveForwardRejectIn(ebtablesContext *ctx, + const char *iface) +{ + return ebtablesForwardRejectIn(ctx, iface, REMOVE); +} diff --git a/src/util/ebtables.h b/src/util/ebtables.h new file mode 100644 index 0000000..30b1056 --- /dev/null +++ b/src/util/ebtables.h @@ -0,0 +1,136 @@ +/* + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * based on iptables.h + * Authors: + * Gerhard Stenzel <gerhard.stenzel@xxxxxxxxxx> + */ + +#ifndef __QEMUD_EBTABLES_H__ +#define __QEMUD_EBTABLES_H__ + +typedef struct +{ + char *rule; + const char **argv; + int command_idx; +} ebtRule; + +typedef struct +{ + char *table; + char *chain; + + int nrules; + ebtRule *rules; + +#ifdef ENABLE_ebtabLES_LOKKIT + + char dir[PATH_MAX]; + char path[PATH_MAX]; + +#endif /* ENABLE_ebtabLES_LOKKIT */ + +} ebtRules; + +struct _ebtablesContext +{ + ebtRules *input_filter; + ebtRules *forward_filter; + ebtRules *nat_postrouting; +}; + +typedef struct _ebtablesContext ebtablesContext; + +ebtablesContext *ebtablesContextNew (void); +void ebtablesContextFree (ebtablesContext *ctx); + +void ebtablesSaveRules (ebtablesContext *ctx); +void ebtablesReloadRules (ebtablesContext *ctx); + +int ebtablesAddTcpInput (ebtablesContext *ctx, + const char *iface, + int port); +int ebtablesRemoveTcpInput (ebtablesContext *ctx, + const char *iface, + int port); + +int ebtablesAddUdpInput (ebtablesContext *ctx, + const char *iface, + int port); +int ebtablesRemoveUdpInput (ebtablesContext *ctx, + const char *iface, + int port); + +int ebtablesAddForwardAllowOut (ebtablesContext *ctx, + const char *network, + const char *iface, + const char *physdev); +int ebtablesRemoveForwardAllowOut (ebtablesContext *ctx, + const char *network, + const char *iface, + const char *physdev); + +int ebtablesAddForwardAllowRelatedIn(ebtablesContext *ctx, + const char *network, + const char *iface, + const char *physdev); +int ebtablesRemoveForwardAllowRelatedIn(ebtablesContext *ctx, + const char *network, + const char *iface, + const char *physdev); + +int ebtablesAddForwardAllowIn (ebtablesContext *ctx, + const char *network, + const char *iface, + const char *physdev); +int ebtablesRemoveForwardAllowIn (ebtablesContext *ctx, + const char *network, + const char *iface, + const char *physdev); + +int ebtablesAddForwardAllowCross (ebtablesContext *ctx, + const char *iface); +int ebtablesRemoveForwardAllowCross (ebtablesContext *ctx, + const char *iface); + +int ebtablesAddForwardRejectOut (ebtablesContext *ctx, + const char *iface); +int ebtablesRemoveForwardRejectOut (ebtablesContext *ctx, + const char *iface); + +int ebtablesAddForwardRejectIn (ebtablesContext *ctx, + const char *iface); +int ebtablesRemoveForwardRejectIn (ebtablesContext *ctx, + const char *iface); + +int ebtablesAddForwardMasquerade (ebtablesContext *ctx, + const char *network, + const char *physdev); +int ebtablesRemoveForwardMasquerade (ebtablesContext *ctx, + const char *network, + const char *physdev); + +int ebtablesAddForwardPolicyReject(ebtablesContext *ctx); + +int ebtablesRemoveForwardPolicyReject(ebtablesContext *ctx); + +int ebtablesForwardPolicyReject(ebtablesContext *ctx, + int action); + +#endif /* __QEMUD_ebtabLES_H__ */ -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list