2007-02-14 16:26:42 +00:00
|
|
|
/*
|
2010-04-29 03:31:16 +00:00
|
|
|
* Copyright (C) 2007-2010 Red Hat, Inc.
|
2007-02-14 16:26:42 +00:00
|
|
|
*
|
|
|
|
* 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
|
|
|
|
*
|
|
|
|
* Authors:
|
|
|
|
* Mark McLoughlin <markmc@redhat.com>
|
|
|
|
*/
|
|
|
|
|
2008-01-29 18:15:54 +00:00
|
|
|
#include <config.h>
|
2007-02-14 16:26:42 +00:00
|
|
|
|
|
|
|
#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>
|
2010-04-29 03:31:16 +00:00
|
|
|
#include <sys/wait.h>
|
2007-12-07 14:45:39 +00:00
|
|
|
|
|
|
|
#ifdef HAVE_PATHS_H
|
2010-03-09 18:22:22 +00:00
|
|
|
# include <paths.h>
|
2007-12-07 14:45:39 +00:00
|
|
|
#endif
|
2007-02-14 16:26:42 +00:00
|
|
|
|
2007-03-30 16:25:02 +00:00
|
|
|
#include "internal.h"
|
2007-12-07 14:45:39 +00:00
|
|
|
#include "iptables.h"
|
2008-01-10 13:49:55 +00:00
|
|
|
#include "util.h"
|
2008-06-06 11:09:57 +00:00
|
|
|
#include "memory.h"
|
2009-02-05 16:27:51 +00:00
|
|
|
#include "virterror_internal.h"
|
2009-03-03 11:40:08 +00:00
|
|
|
#include "logging.h"
|
2007-06-26 23:48:46 +00:00
|
|
|
|
2010-10-25 14:10:33 +00:00
|
|
|
#define VIR_FROM_THIS VIR_FROM_NONE
|
Convert virNetwork to use virSocketAddr everywhere
Instead of storing the IP address string in virNetwork related
structs, store the parsed virSocketAddr. This will make it
easier to add IPv6 support in the future, by letting driver
code directly check what address family is present
* src/conf/network_conf.c, src/conf/network_conf.h,
src/network/bridge_driver.c: Convert to use virSocketAddr
in virNetwork, instead of char *.
* src/util/bridge.c, src/util/bridge.h,
src/util/dnsmasq.c, src/util/dnsmasq.h,
src/util/iptables.c, src/util/iptables.h: Convert to
take a virSocketAddr instead of char * for any IP
address parameters
* src/util/network.h: Add macros to determine if an address
is set, and what address family is set.
2010-10-21 12:14:33 +00:00
|
|
|
#define iptablesError(code, ...) \
|
2010-10-25 14:10:33 +00:00
|
|
|
virReportErrorHelper(NULL, VIR_FROM_THIS, code, __FILE__, \
|
Convert virNetwork to use virSocketAddr everywhere
Instead of storing the IP address string in virNetwork related
structs, store the parsed virSocketAddr. This will make it
easier to add IPv6 support in the future, by letting driver
code directly check what address family is present
* src/conf/network_conf.c, src/conf/network_conf.h,
src/network/bridge_driver.c: Convert to use virSocketAddr
in virNetwork, instead of char *.
* src/util/bridge.c, src/util/bridge.h,
src/util/dnsmasq.c, src/util/dnsmasq.h,
src/util/iptables.c, src/util/iptables.h: Convert to
take a virSocketAddr instead of char * for any IP
address parameters
* src/util/network.h: Add macros to determine if an address
is set, and what address family is set.
2010-10-21 12:14:33 +00:00
|
|
|
__FUNCTION__, __LINE__, __VA_ARGS__)
|
|
|
|
|
2007-02-14 16:26:42 +00:00
|
|
|
enum {
|
|
|
|
ADD = 0,
|
|
|
|
REMOVE
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
char *table;
|
|
|
|
char *chain;
|
|
|
|
} iptRules;
|
|
|
|
|
|
|
|
struct _iptablesContext
|
|
|
|
{
|
|
|
|
iptRules *input_filter;
|
|
|
|
iptRules *forward_filter;
|
|
|
|
iptRules *nat_postrouting;
|
2010-07-13 02:59:58 +00:00
|
|
|
iptRules *mangle_postrouting;
|
2007-02-14 16:26:42 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static void
|
|
|
|
iptRulesFree(iptRules *rules)
|
|
|
|
{
|
2009-02-03 13:08:07 +00:00
|
|
|
VIR_FREE(rules->table);
|
|
|
|
VIR_FREE(rules->chain);
|
2008-06-06 11:09:57 +00:00
|
|
|
VIR_FREE(rules);
|
2007-02-14 16:26:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static iptRules *
|
|
|
|
iptRulesNew(const char *table,
|
|
|
|
const char *chain)
|
|
|
|
{
|
|
|
|
iptRules *rules;
|
|
|
|
|
2008-06-06 11:09:57 +00:00
|
|
|
if (VIR_ALLOC(rules) < 0)
|
2007-02-14 16:26:42 +00:00
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (!(rules->table = strdup(table)))
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
if (!(rules->chain = strdup(chain)))
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
return rules;
|
|
|
|
|
|
|
|
error:
|
|
|
|
iptRulesFree(rules);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2009-11-06 09:39:13 +00:00
|
|
|
static int ATTRIBUTE_SENTINEL
|
2007-02-14 16:26:42 +00:00
|
|
|
iptablesAddRemoveRule(iptRules *rules, int action, const char *arg, ...)
|
|
|
|
{
|
|
|
|
va_list args;
|
|
|
|
int retval = ENOMEM;
|
2008-08-08 15:43:38 +00:00
|
|
|
const char **argv;
|
2007-02-14 16:26:42 +00:00
|
|
|
const char *s;
|
2009-12-10 11:27:18 +00:00
|
|
|
int n;
|
2007-02-14 16:26:42 +00:00
|
|
|
|
|
|
|
n = 1 + /* /sbin/iptables */
|
|
|
|
2 + /* --table foo */
|
|
|
|
2 + /* --insert bar */
|
|
|
|
1; /* arg */
|
|
|
|
|
|
|
|
va_start(args, arg);
|
2009-09-04 17:36:17 +00:00
|
|
|
while (va_arg(args, const char *))
|
2007-02-14 16:26:42 +00:00
|
|
|
n++;
|
|
|
|
|
|
|
|
va_end(args);
|
|
|
|
|
2008-06-06 11:09:57 +00:00
|
|
|
if (VIR_ALLOC_N(argv, n + 1) < 0)
|
2007-02-14 16:26:42 +00:00
|
|
|
goto error;
|
|
|
|
|
|
|
|
n = 0;
|
|
|
|
|
|
|
|
if (!(argv[n++] = strdup(IPTABLES_PATH)))
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
if (!(argv[n++] = strdup("--table")))
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
if (!(argv[n++] = strdup(rules->table)))
|
|
|
|
goto error;
|
|
|
|
|
2009-12-10 11:27:18 +00:00
|
|
|
if (!(argv[n++] = strdup(action == ADD ? "--insert" : "--delete")))
|
2007-02-14 16:26:42 +00:00
|
|
|
goto error;
|
|
|
|
|
|
|
|
if (!(argv[n++] = strdup(rules->chain)))
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
if (!(argv[n++] = strdup(arg)))
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
va_start(args, arg);
|
|
|
|
|
2010-05-18 12:42:33 +00:00
|
|
|
while ((s = va_arg(args, const char *))) {
|
|
|
|
if (!(argv[n++] = strdup(s))) {
|
|
|
|
va_end(args);
|
2007-02-14 16:26:42 +00:00
|
|
|
goto error;
|
2010-05-18 12:42:33 +00:00
|
|
|
}
|
|
|
|
}
|
2007-02-14 16:26:42 +00:00
|
|
|
|
|
|
|
va_end(args);
|
|
|
|
|
2010-02-04 22:41:52 +00:00
|
|
|
if (virRun(argv, NULL) < 0) {
|
2008-01-10 13:49:55 +00:00
|
|
|
retval = errno;
|
2007-02-14 16:26:42 +00:00
|
|
|
goto error;
|
2008-01-10 13:49:55 +00:00
|
|
|
}
|
2007-02-14 16:26:42 +00:00
|
|
|
|
2009-12-10 11:27:18 +00:00
|
|
|
retval = 0;
|
2007-02-14 16:26:42 +00:00
|
|
|
|
|
|
|
error:
|
|
|
|
if (argv) {
|
|
|
|
n = 0;
|
|
|
|
while (argv[n])
|
2008-06-06 11:09:57 +00:00
|
|
|
VIR_FREE(argv[n++]);
|
|
|
|
VIR_FREE(argv);
|
2007-02-14 16:26:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
/**
|
|
|
|
* iptablesContextNew:
|
|
|
|
*
|
|
|
|
* Create a new IPtable context
|
|
|
|
*
|
|
|
|
* Returns a pointer to the new structure or NULL in case of error
|
|
|
|
*/
|
2007-02-14 16:26:42 +00:00
|
|
|
iptablesContext *
|
|
|
|
iptablesContextNew(void)
|
|
|
|
{
|
|
|
|
iptablesContext *ctx;
|
|
|
|
|
2008-06-06 11:09:57 +00:00
|
|
|
if (VIR_ALLOC(ctx) < 0)
|
2007-02-14 16:26:42 +00:00
|
|
|
return NULL;
|
|
|
|
|
2008-01-10 13:56:22 +00:00
|
|
|
if (!(ctx->input_filter = iptRulesNew("filter", "INPUT")))
|
2007-02-14 16:26:42 +00:00
|
|
|
goto error;
|
|
|
|
|
2008-01-10 13:56:22 +00:00
|
|
|
if (!(ctx->forward_filter = iptRulesNew("filter", "FORWARD")))
|
2007-02-14 16:26:42 +00:00
|
|
|
goto error;
|
|
|
|
|
2008-01-10 13:56:22 +00:00
|
|
|
if (!(ctx->nat_postrouting = iptRulesNew("nat", "POSTROUTING")))
|
2007-02-14 16:26:42 +00:00
|
|
|
goto error;
|
|
|
|
|
2010-07-13 02:59:58 +00:00
|
|
|
if (!(ctx->mangle_postrouting = iptRulesNew("mangle", "POSTROUTING")))
|
|
|
|
goto error;
|
|
|
|
|
2007-02-14 16:26:42 +00:00
|
|
|
return ctx;
|
|
|
|
|
|
|
|
error:
|
|
|
|
iptablesContextFree(ctx);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
/**
|
|
|
|
* iptablesContextFree:
|
|
|
|
* @ctx: pointer to the IP table context
|
|
|
|
*
|
2008-02-27 10:37:19 +00:00
|
|
|
* Free the resources associated with an IP table context
|
2007-06-29 13:23:13 +00:00
|
|
|
*/
|
2007-02-14 16:26:42 +00:00
|
|
|
void
|
|
|
|
iptablesContextFree(iptablesContext *ctx)
|
|
|
|
{
|
2007-03-30 16:20:19 +00:00
|
|
|
if (ctx->input_filter)
|
|
|
|
iptRulesFree(ctx->input_filter);
|
|
|
|
if (ctx->forward_filter)
|
|
|
|
iptRulesFree(ctx->forward_filter);
|
|
|
|
if (ctx->nat_postrouting)
|
|
|
|
iptRulesFree(ctx->nat_postrouting);
|
2010-07-13 02:59:58 +00:00
|
|
|
if (ctx->mangle_postrouting)
|
|
|
|
iptRulesFree(ctx->mangle_postrouting);
|
2008-06-06 11:09:57 +00:00
|
|
|
VIR_FREE(ctx);
|
2007-02-14 16:26:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
iptablesInput(iptablesContext *ctx,
|
|
|
|
const char *iface,
|
|
|
|
int port,
|
|
|
|
int action,
|
|
|
|
int tcp)
|
|
|
|
{
|
|
|
|
char portstr[32];
|
|
|
|
|
|
|
|
snprintf(portstr, sizeof(portstr), "%d", port);
|
|
|
|
portstr[sizeof(portstr) - 1] = '\0';
|
|
|
|
|
2007-03-13 22:43:22 +00:00
|
|
|
return iptablesAddRemoveRule(ctx->input_filter,
|
|
|
|
action,
|
|
|
|
"--in-interface", iface,
|
|
|
|
"--protocol", tcp ? "tcp" : "udp",
|
|
|
|
"--destination-port", portstr,
|
|
|
|
"--jump", "ACCEPT",
|
|
|
|
NULL);
|
2007-02-14 16:26:42 +00:00
|
|
|
}
|
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
/**
|
|
|
|
* iptablesAddTcpInput:
|
|
|
|
* @ctx: pointer to the IP table context
|
|
|
|
* @iface: the interface name
|
|
|
|
* @port: the TCP port to add
|
|
|
|
*
|
|
|
|
* Add an input to the IP table allowing access to the given @port on
|
|
|
|
* the given @iface interface for TCP packets
|
|
|
|
*
|
|
|
|
* Returns 0 in case of success or an error code in case of error
|
|
|
|
*/
|
|
|
|
|
2007-02-14 16:26:42 +00:00
|
|
|
int
|
|
|
|
iptablesAddTcpInput(iptablesContext *ctx,
|
|
|
|
const char *iface,
|
|
|
|
int port)
|
|
|
|
{
|
|
|
|
return iptablesInput(ctx, iface, port, ADD, 1);
|
|
|
|
}
|
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
/**
|
|
|
|
* iptablesRemoveTcpInput:
|
|
|
|
* @ctx: pointer to the IP table context
|
|
|
|
* @iface: the interface name
|
|
|
|
* @port: the TCP port to remove
|
|
|
|
*
|
2008-02-27 10:37:19 +00:00
|
|
|
* Removes an input from the IP table, hence forbidding access to the given
|
2007-06-29 13:23:13 +00:00
|
|
|
* @port on the given @iface interface for TCP packets
|
|
|
|
*
|
|
|
|
* Returns 0 in case of success or an error code in case of error
|
|
|
|
*/
|
2007-02-14 16:26:42 +00:00
|
|
|
int
|
|
|
|
iptablesRemoveTcpInput(iptablesContext *ctx,
|
|
|
|
const char *iface,
|
|
|
|
int port)
|
|
|
|
{
|
|
|
|
return iptablesInput(ctx, iface, port, REMOVE, 1);
|
|
|
|
}
|
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
/**
|
|
|
|
* iptablesAddUdpInput:
|
|
|
|
* @ctx: pointer to the IP table context
|
|
|
|
* @iface: the interface name
|
|
|
|
* @port: the UDP port to add
|
|
|
|
*
|
|
|
|
* Add an input to the IP table allowing access to the given @port on
|
|
|
|
* the given @iface interface for UDP packets
|
|
|
|
*
|
|
|
|
* Returns 0 in case of success or an error code in case of error
|
|
|
|
*/
|
|
|
|
|
2007-02-14 16:26:42 +00:00
|
|
|
int
|
|
|
|
iptablesAddUdpInput(iptablesContext *ctx,
|
|
|
|
const char *iface,
|
|
|
|
int port)
|
|
|
|
{
|
|
|
|
return iptablesInput(ctx, iface, port, ADD, 0);
|
|
|
|
}
|
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
/**
|
|
|
|
* iptablesRemoveUdpInput:
|
|
|
|
* @ctx: pointer to the IP table context
|
|
|
|
* @iface: the interface name
|
|
|
|
* @port: the UDP port to remove
|
|
|
|
*
|
2008-02-27 10:37:19 +00:00
|
|
|
* Removes an input from the IP table, hence forbidding access to the given
|
2007-06-29 13:23:13 +00:00
|
|
|
* @port on the given @iface interface for UDP packets
|
|
|
|
*
|
|
|
|
* Returns 0 in case of success or an error code in case of error
|
|
|
|
*/
|
2007-02-14 16:26:42 +00:00
|
|
|
int
|
|
|
|
iptablesRemoveUdpInput(iptablesContext *ctx,
|
|
|
|
const char *iface,
|
|
|
|
int port)
|
|
|
|
{
|
|
|
|
return iptablesInput(ctx, iface, port, REMOVE, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-10-25 14:10:33 +00:00
|
|
|
static char *iptablesFormatNetwork(virSocketAddr *netaddr,
|
|
|
|
virSocketAddr *netmask)
|
|
|
|
{
|
|
|
|
virSocketAddr network;
|
|
|
|
int prefix;
|
|
|
|
char *netstr;
|
|
|
|
char *ret;
|
|
|
|
|
|
|
|
if (!VIR_SOCKET_IS_FAMILY(netaddr, AF_INET) ||
|
|
|
|
!VIR_SOCKET_IS_FAMILY(netmask, AF_INET)) {
|
|
|
|
iptablesError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
|
|
_("Only IPv4 addresses can be used with iptables"));
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
network = *netaddr;
|
|
|
|
network.data.inet4.sin_addr.s_addr &=
|
|
|
|
netmask->data.inet4.sin_addr.s_addr;
|
|
|
|
|
|
|
|
prefix = virSocketGetNumNetmaskBits(netmask);
|
|
|
|
|
|
|
|
netstr = virSocketFormatAddr(&network);
|
|
|
|
|
|
|
|
if (!netstr)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (virAsprintf(&ret, "%s/%d", netstr, prefix) < 0)
|
|
|
|
virReportOOMError();
|
|
|
|
|
|
|
|
VIR_FREE(netstr);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-10 23:17:46 +00:00
|
|
|
/* Allow all traffic coming from the bridge, with a valid network address
|
|
|
|
* to proceed to WAN
|
|
|
|
*/
|
2007-02-14 16:26:42 +00:00
|
|
|
static int
|
2007-04-10 23:17:46 +00:00
|
|
|
iptablesForwardAllowOut(iptablesContext *ctx,
|
2010-10-25 14:10:33 +00:00
|
|
|
virSocketAddr *netaddr,
|
|
|
|
virSocketAddr *netmask,
|
|
|
|
const char *iface,
|
|
|
|
const char *physdev,
|
|
|
|
int action)
|
2007-02-14 16:26:42 +00:00
|
|
|
{
|
Convert virNetwork to use virSocketAddr everywhere
Instead of storing the IP address string in virNetwork related
structs, store the parsed virSocketAddr. This will make it
easier to add IPv6 support in the future, by letting driver
code directly check what address family is present
* src/conf/network_conf.c, src/conf/network_conf.h,
src/network/bridge_driver.c: Convert to use virSocketAddr
in virNetwork, instead of char *.
* src/util/bridge.c, src/util/bridge.h,
src/util/dnsmasq.c, src/util/dnsmasq.h,
src/util/iptables.c, src/util/iptables.h: Convert to
take a virSocketAddr instead of char * for any IP
address parameters
* src/util/network.h: Add macros to determine if an address
is set, and what address family is set.
2010-10-21 12:14:33 +00:00
|
|
|
int ret;
|
|
|
|
char *networkstr;
|
|
|
|
|
2010-10-25 14:10:33 +00:00
|
|
|
if (!(networkstr = iptablesFormatNetwork(netaddr, netmask)))
|
Convert virNetwork to use virSocketAddr everywhere
Instead of storing the IP address string in virNetwork related
structs, store the parsed virSocketAddr. This will make it
easier to add IPv6 support in the future, by letting driver
code directly check what address family is present
* src/conf/network_conf.c, src/conf/network_conf.h,
src/network/bridge_driver.c: Convert to use virSocketAddr
in virNetwork, instead of char *.
* src/util/bridge.c, src/util/bridge.h,
src/util/dnsmasq.c, src/util/dnsmasq.h,
src/util/iptables.c, src/util/iptables.h: Convert to
take a virSocketAddr instead of char * for any IP
address parameters
* src/util/network.h: Add macros to determine if an address
is set, and what address family is set.
2010-10-21 12:14:33 +00:00
|
|
|
return -1;
|
|
|
|
|
2007-04-10 23:17:46 +00:00
|
|
|
if (physdev && physdev[0]) {
|
Convert virNetwork to use virSocketAddr everywhere
Instead of storing the IP address string in virNetwork related
structs, store the parsed virSocketAddr. This will make it
easier to add IPv6 support in the future, by letting driver
code directly check what address family is present
* src/conf/network_conf.c, src/conf/network_conf.h,
src/network/bridge_driver.c: Convert to use virSocketAddr
in virNetwork, instead of char *.
* src/util/bridge.c, src/util/bridge.h,
src/util/dnsmasq.c, src/util/dnsmasq.h,
src/util/iptables.c, src/util/iptables.h: Convert to
take a virSocketAddr instead of char * for any IP
address parameters
* src/util/network.h: Add macros to determine if an address
is set, and what address family is set.
2010-10-21 12:14:33 +00:00
|
|
|
ret = iptablesAddRemoveRule(ctx->forward_filter,
|
|
|
|
action,
|
|
|
|
"--source", networkstr,
|
|
|
|
"--in-interface", iface,
|
|
|
|
"--out-interface", physdev,
|
|
|
|
"--jump", "ACCEPT",
|
|
|
|
NULL);
|
2007-03-13 22:43:22 +00:00
|
|
|
} else {
|
Convert virNetwork to use virSocketAddr everywhere
Instead of storing the IP address string in virNetwork related
structs, store the parsed virSocketAddr. This will make it
easier to add IPv6 support in the future, by letting driver
code directly check what address family is present
* src/conf/network_conf.c, src/conf/network_conf.h,
src/network/bridge_driver.c: Convert to use virSocketAddr
in virNetwork, instead of char *.
* src/util/bridge.c, src/util/bridge.h,
src/util/dnsmasq.c, src/util/dnsmasq.h,
src/util/iptables.c, src/util/iptables.h: Convert to
take a virSocketAddr instead of char * for any IP
address parameters
* src/util/network.h: Add macros to determine if an address
is set, and what address family is set.
2010-10-21 12:14:33 +00:00
|
|
|
ret = iptablesAddRemoveRule(ctx->forward_filter,
|
|
|
|
action,
|
|
|
|
"--source", networkstr,
|
|
|
|
"--in-interface", iface,
|
|
|
|
"--jump", "ACCEPT",
|
|
|
|
NULL);
|
2007-03-13 22:43:22 +00:00
|
|
|
}
|
Convert virNetwork to use virSocketAddr everywhere
Instead of storing the IP address string in virNetwork related
structs, store the parsed virSocketAddr. This will make it
easier to add IPv6 support in the future, by letting driver
code directly check what address family is present
* src/conf/network_conf.c, src/conf/network_conf.h,
src/network/bridge_driver.c: Convert to use virSocketAddr
in virNetwork, instead of char *.
* src/util/bridge.c, src/util/bridge.h,
src/util/dnsmasq.c, src/util/dnsmasq.h,
src/util/iptables.c, src/util/iptables.h: Convert to
take a virSocketAddr instead of char * for any IP
address parameters
* src/util/network.h: Add macros to determine if an address
is set, and what address family is set.
2010-10-21 12:14:33 +00:00
|
|
|
VIR_FREE(networkstr);
|
|
|
|
return ret;
|
2007-02-14 16:26:42 +00:00
|
|
|
}
|
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
/**
|
|
|
|
* iptablesAddForwardAllowOut:
|
|
|
|
* @ctx: pointer to the IP table context
|
|
|
|
* @network: the source network name
|
|
|
|
* @iface: the source interface name
|
|
|
|
* @physdev: the physical output device
|
2008-02-05 19:27:37 +00:00
|
|
|
*
|
2007-06-29 13:23:13 +00:00
|
|
|
* 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
|
|
|
|
*/
|
2007-02-14 16:26:42 +00:00
|
|
|
int
|
2007-04-10 23:17:46 +00:00
|
|
|
iptablesAddForwardAllowOut(iptablesContext *ctx,
|
2010-10-25 14:10:33 +00:00
|
|
|
virSocketAddr *netaddr,
|
|
|
|
virSocketAddr *netmask,
|
|
|
|
const char *iface,
|
|
|
|
const char *physdev)
|
2007-02-14 16:26:42 +00:00
|
|
|
{
|
2010-10-25 14:10:33 +00:00
|
|
|
return iptablesForwardAllowOut(ctx, netaddr, netmask, iface, physdev, ADD);
|
2007-02-14 16:26:42 +00:00
|
|
|
}
|
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
/**
|
|
|
|
* iptablesRemoveForwardAllowOut:
|
|
|
|
* @ctx: pointer to the IP table context
|
|
|
|
* @network: the source network name
|
|
|
|
* @iface: the source interface name
|
|
|
|
* @physdev: the physical output device
|
2008-02-05 19:27:37 +00:00
|
|
|
*
|
2007-06-29 13:23:13 +00:00
|
|
|
* 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
|
|
|
|
*/
|
2007-02-14 16:26:42 +00:00
|
|
|
int
|
2007-04-10 23:17:46 +00:00
|
|
|
iptablesRemoveForwardAllowOut(iptablesContext *ctx,
|
2010-10-25 14:10:33 +00:00
|
|
|
virSocketAddr *netaddr,
|
|
|
|
virSocketAddr *netmask,
|
|
|
|
const char *iface,
|
|
|
|
const char *physdev)
|
2007-02-14 16:26:42 +00:00
|
|
|
{
|
2010-10-25 14:10:33 +00:00
|
|
|
return iptablesForwardAllowOut(ctx, netaddr, netmask, iface, physdev, REMOVE);
|
2007-02-14 16:26:42 +00:00
|
|
|
}
|
|
|
|
|
2007-04-10 23:17:46 +00:00
|
|
|
|
|
|
|
/* Allow all traffic destined to the bridge, with a valid network address
|
|
|
|
* and associated with an existing connection
|
|
|
|
*/
|
2007-02-14 16:26:42 +00:00
|
|
|
static int
|
2008-03-28 20:38:21 +00:00
|
|
|
iptablesForwardAllowRelatedIn(iptablesContext *ctx,
|
2010-10-25 14:10:33 +00:00
|
|
|
virSocketAddr *netaddr,
|
|
|
|
virSocketAddr *netmask,
|
|
|
|
const char *iface,
|
|
|
|
const char *physdev,
|
|
|
|
int action)
|
2007-02-14 16:26:42 +00:00
|
|
|
{
|
Convert virNetwork to use virSocketAddr everywhere
Instead of storing the IP address string in virNetwork related
structs, store the parsed virSocketAddr. This will make it
easier to add IPv6 support in the future, by letting driver
code directly check what address family is present
* src/conf/network_conf.c, src/conf/network_conf.h,
src/network/bridge_driver.c: Convert to use virSocketAddr
in virNetwork, instead of char *.
* src/util/bridge.c, src/util/bridge.h,
src/util/dnsmasq.c, src/util/dnsmasq.h,
src/util/iptables.c, src/util/iptables.h: Convert to
take a virSocketAddr instead of char * for any IP
address parameters
* src/util/network.h: Add macros to determine if an address
is set, and what address family is set.
2010-10-21 12:14:33 +00:00
|
|
|
int ret;
|
|
|
|
char *networkstr;
|
|
|
|
|
2010-10-25 14:10:33 +00:00
|
|
|
if (!(networkstr = iptablesFormatNetwork(netaddr, netmask)))
|
Convert virNetwork to use virSocketAddr everywhere
Instead of storing the IP address string in virNetwork related
structs, store the parsed virSocketAddr. This will make it
easier to add IPv6 support in the future, by letting driver
code directly check what address family is present
* src/conf/network_conf.c, src/conf/network_conf.h,
src/network/bridge_driver.c: Convert to use virSocketAddr
in virNetwork, instead of char *.
* src/util/bridge.c, src/util/bridge.h,
src/util/dnsmasq.c, src/util/dnsmasq.h,
src/util/iptables.c, src/util/iptables.h: Convert to
take a virSocketAddr instead of char * for any IP
address parameters
* src/util/network.h: Add macros to determine if an address
is set, and what address family is set.
2010-10-21 12:14:33 +00:00
|
|
|
return -1;
|
|
|
|
|
2007-04-10 23:17:46 +00:00
|
|
|
if (physdev && physdev[0]) {
|
Convert virNetwork to use virSocketAddr everywhere
Instead of storing the IP address string in virNetwork related
structs, store the parsed virSocketAddr. This will make it
easier to add IPv6 support in the future, by letting driver
code directly check what address family is present
* src/conf/network_conf.c, src/conf/network_conf.h,
src/network/bridge_driver.c: Convert to use virSocketAddr
in virNetwork, instead of char *.
* src/util/bridge.c, src/util/bridge.h,
src/util/dnsmasq.c, src/util/dnsmasq.h,
src/util/iptables.c, src/util/iptables.h: Convert to
take a virSocketAddr instead of char * for any IP
address parameters
* src/util/network.h: Add macros to determine if an address
is set, and what address family is set.
2010-10-21 12:14:33 +00:00
|
|
|
ret = iptablesAddRemoveRule(ctx->forward_filter,
|
|
|
|
action,
|
|
|
|
"--destination", networkstr,
|
|
|
|
"--in-interface", physdev,
|
|
|
|
"--out-interface", iface,
|
|
|
|
"--match", "state",
|
|
|
|
"--state", "ESTABLISHED,RELATED",
|
|
|
|
"--jump", "ACCEPT",
|
|
|
|
NULL);
|
2007-03-13 22:43:22 +00:00
|
|
|
} else {
|
Convert virNetwork to use virSocketAddr everywhere
Instead of storing the IP address string in virNetwork related
structs, store the parsed virSocketAddr. This will make it
easier to add IPv6 support in the future, by letting driver
code directly check what address family is present
* src/conf/network_conf.c, src/conf/network_conf.h,
src/network/bridge_driver.c: Convert to use virSocketAddr
in virNetwork, instead of char *.
* src/util/bridge.c, src/util/bridge.h,
src/util/dnsmasq.c, src/util/dnsmasq.h,
src/util/iptables.c, src/util/iptables.h: Convert to
take a virSocketAddr instead of char * for any IP
address parameters
* src/util/network.h: Add macros to determine if an address
is set, and what address family is set.
2010-10-21 12:14:33 +00:00
|
|
|
ret = iptablesAddRemoveRule(ctx->forward_filter,
|
|
|
|
action,
|
|
|
|
"--destination", networkstr,
|
|
|
|
"--out-interface", iface,
|
|
|
|
"--match", "state",
|
|
|
|
"--state", "ESTABLISHED,RELATED",
|
|
|
|
"--jump", "ACCEPT",
|
|
|
|
NULL);
|
2007-03-13 22:43:22 +00:00
|
|
|
}
|
Convert virNetwork to use virSocketAddr everywhere
Instead of storing the IP address string in virNetwork related
structs, store the parsed virSocketAddr. This will make it
easier to add IPv6 support in the future, by letting driver
code directly check what address family is present
* src/conf/network_conf.c, src/conf/network_conf.h,
src/network/bridge_driver.c: Convert to use virSocketAddr
in virNetwork, instead of char *.
* src/util/bridge.c, src/util/bridge.h,
src/util/dnsmasq.c, src/util/dnsmasq.h,
src/util/iptables.c, src/util/iptables.h: Convert to
take a virSocketAddr instead of char * for any IP
address parameters
* src/util/network.h: Add macros to determine if an address
is set, and what address family is set.
2010-10-21 12:14:33 +00:00
|
|
|
VIR_FREE(networkstr);
|
|
|
|
return ret;
|
2007-02-14 16:26:42 +00:00
|
|
|
}
|
|
|
|
|
2008-03-28 20:38:21 +00:00
|
|
|
/**
|
|
|
|
* iptablesAddForwardAllowRelatedIn:
|
|
|
|
* @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
|
|
|
|
iptablesAddForwardAllowRelatedIn(iptablesContext *ctx,
|
2010-10-25 14:10:33 +00:00
|
|
|
virSocketAddr *netaddr,
|
|
|
|
virSocketAddr *netmask,
|
|
|
|
const char *iface,
|
|
|
|
const char *physdev)
|
2008-03-28 20:38:21 +00:00
|
|
|
{
|
2010-10-25 14:10:33 +00:00
|
|
|
return iptablesForwardAllowRelatedIn(ctx, netaddr, netmask, iface, physdev, ADD);
|
2008-03-28 20:38:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* iptablesRemoveForwardAllowRelatedIn:
|
|
|
|
* @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
|
|
|
|
iptablesRemoveForwardAllowRelatedIn(iptablesContext *ctx,
|
2010-10-25 14:10:33 +00:00
|
|
|
virSocketAddr *netaddr,
|
|
|
|
virSocketAddr *netmask,
|
|
|
|
const char *iface,
|
|
|
|
const char *physdev)
|
2008-03-28 20:38:21 +00:00
|
|
|
{
|
2010-10-25 14:10:33 +00:00
|
|
|
return iptablesForwardAllowRelatedIn(ctx, netaddr, netmask, iface, physdev, REMOVE);
|
2008-03-28 20:38:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Allow all traffic destined to the bridge, with a valid network address
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
iptablesForwardAllowIn(iptablesContext *ctx,
|
2010-10-25 14:10:33 +00:00
|
|
|
virSocketAddr *netaddr,
|
|
|
|
virSocketAddr *netmask,
|
2008-03-28 20:38:21 +00:00
|
|
|
const char *iface,
|
|
|
|
const char *physdev,
|
|
|
|
int action)
|
|
|
|
{
|
Convert virNetwork to use virSocketAddr everywhere
Instead of storing the IP address string in virNetwork related
structs, store the parsed virSocketAddr. This will make it
easier to add IPv6 support in the future, by letting driver
code directly check what address family is present
* src/conf/network_conf.c, src/conf/network_conf.h,
src/network/bridge_driver.c: Convert to use virSocketAddr
in virNetwork, instead of char *.
* src/util/bridge.c, src/util/bridge.h,
src/util/dnsmasq.c, src/util/dnsmasq.h,
src/util/iptables.c, src/util/iptables.h: Convert to
take a virSocketAddr instead of char * for any IP
address parameters
* src/util/network.h: Add macros to determine if an address
is set, and what address family is set.
2010-10-21 12:14:33 +00:00
|
|
|
int ret;
|
|
|
|
char *networkstr;
|
|
|
|
|
2010-10-25 14:10:33 +00:00
|
|
|
if (!(networkstr = iptablesFormatNetwork(netaddr, netmask)))
|
Convert virNetwork to use virSocketAddr everywhere
Instead of storing the IP address string in virNetwork related
structs, store the parsed virSocketAddr. This will make it
easier to add IPv6 support in the future, by letting driver
code directly check what address family is present
* src/conf/network_conf.c, src/conf/network_conf.h,
src/network/bridge_driver.c: Convert to use virSocketAddr
in virNetwork, instead of char *.
* src/util/bridge.c, src/util/bridge.h,
src/util/dnsmasq.c, src/util/dnsmasq.h,
src/util/iptables.c, src/util/iptables.h: Convert to
take a virSocketAddr instead of char * for any IP
address parameters
* src/util/network.h: Add macros to determine if an address
is set, and what address family is set.
2010-10-21 12:14:33 +00:00
|
|
|
return -1;
|
|
|
|
|
2008-03-28 20:38:21 +00:00
|
|
|
if (physdev && physdev[0]) {
|
Convert virNetwork to use virSocketAddr everywhere
Instead of storing the IP address string in virNetwork related
structs, store the parsed virSocketAddr. This will make it
easier to add IPv6 support in the future, by letting driver
code directly check what address family is present
* src/conf/network_conf.c, src/conf/network_conf.h,
src/network/bridge_driver.c: Convert to use virSocketAddr
in virNetwork, instead of char *.
* src/util/bridge.c, src/util/bridge.h,
src/util/dnsmasq.c, src/util/dnsmasq.h,
src/util/iptables.c, src/util/iptables.h: Convert to
take a virSocketAddr instead of char * for any IP
address parameters
* src/util/network.h: Add macros to determine if an address
is set, and what address family is set.
2010-10-21 12:14:33 +00:00
|
|
|
ret = iptablesAddRemoveRule(ctx->forward_filter,
|
|
|
|
action,
|
|
|
|
"--destination", networkstr,
|
|
|
|
"--in-interface", physdev,
|
|
|
|
"--out-interface", iface,
|
|
|
|
"--jump", "ACCEPT",
|
|
|
|
NULL);
|
2008-03-28 20:38:21 +00:00
|
|
|
} else {
|
Convert virNetwork to use virSocketAddr everywhere
Instead of storing the IP address string in virNetwork related
structs, store the parsed virSocketAddr. This will make it
easier to add IPv6 support in the future, by letting driver
code directly check what address family is present
* src/conf/network_conf.c, src/conf/network_conf.h,
src/network/bridge_driver.c: Convert to use virSocketAddr
in virNetwork, instead of char *.
* src/util/bridge.c, src/util/bridge.h,
src/util/dnsmasq.c, src/util/dnsmasq.h,
src/util/iptables.c, src/util/iptables.h: Convert to
take a virSocketAddr instead of char * for any IP
address parameters
* src/util/network.h: Add macros to determine if an address
is set, and what address family is set.
2010-10-21 12:14:33 +00:00
|
|
|
ret = iptablesAddRemoveRule(ctx->forward_filter,
|
|
|
|
action,
|
|
|
|
"--destination", networkstr,
|
|
|
|
"--out-interface", iface,
|
|
|
|
"--jump", "ACCEPT",
|
|
|
|
NULL);
|
2008-03-28 20:38:21 +00:00
|
|
|
}
|
Convert virNetwork to use virSocketAddr everywhere
Instead of storing the IP address string in virNetwork related
structs, store the parsed virSocketAddr. This will make it
easier to add IPv6 support in the future, by letting driver
code directly check what address family is present
* src/conf/network_conf.c, src/conf/network_conf.h,
src/network/bridge_driver.c: Convert to use virSocketAddr
in virNetwork, instead of char *.
* src/util/bridge.c, src/util/bridge.h,
src/util/dnsmasq.c, src/util/dnsmasq.h,
src/util/iptables.c, src/util/iptables.h: Convert to
take a virSocketAddr instead of char * for any IP
address parameters
* src/util/network.h: Add macros to determine if an address
is set, and what address family is set.
2010-10-21 12:14:33 +00:00
|
|
|
VIR_FREE(networkstr);
|
|
|
|
return ret;
|
2008-03-28 20:38:21 +00:00
|
|
|
}
|
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
/**
|
|
|
|
* iptablesAddForwardAllowIn:
|
|
|
|
* @ctx: pointer to the IP table context
|
|
|
|
* @network: the source network name
|
|
|
|
* @iface: the output interface name
|
|
|
|
* @physdev: the physical input device or NULL
|
2008-02-05 19:27:37 +00:00
|
|
|
*
|
2007-06-29 13:23:13 +00:00
|
|
|
* 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
|
|
|
|
*/
|
2007-02-14 16:26:42 +00:00
|
|
|
int
|
2007-04-10 23:17:46 +00:00
|
|
|
iptablesAddForwardAllowIn(iptablesContext *ctx,
|
2010-10-25 14:10:33 +00:00
|
|
|
virSocketAddr *netaddr,
|
|
|
|
virSocketAddr *netmask,
|
2007-04-10 23:17:46 +00:00
|
|
|
const char *iface,
|
|
|
|
const char *physdev)
|
|
|
|
{
|
2010-10-25 14:10:33 +00:00
|
|
|
return iptablesForwardAllowIn(ctx, netaddr, netmask, iface, physdev, ADD);
|
2007-04-10 23:17:46 +00:00
|
|
|
}
|
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
/**
|
|
|
|
* iptablesRemoveForwardAllowIn:
|
|
|
|
* @ctx: pointer to the IP table context
|
|
|
|
* @network: the source network name
|
|
|
|
* @iface: the output interface name
|
|
|
|
* @physdev: the physical input device or NULL
|
2008-02-05 19:27:37 +00:00
|
|
|
*
|
2007-06-29 13:23:13 +00:00
|
|
|
* 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
|
|
|
|
*/
|
2007-04-10 23:17:46 +00:00
|
|
|
int
|
|
|
|
iptablesRemoveForwardAllowIn(iptablesContext *ctx,
|
2010-10-25 14:10:33 +00:00
|
|
|
virSocketAddr *netaddr,
|
|
|
|
virSocketAddr *netmask,
|
2007-04-10 23:17:46 +00:00
|
|
|
const char *iface,
|
|
|
|
const char *physdev)
|
|
|
|
{
|
2010-10-25 14:10:33 +00:00
|
|
|
return iptablesForwardAllowIn(ctx, netaddr, netmask, iface, physdev, REMOVE);
|
2007-04-10 23:17:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Allow all traffic between guests on the same bridge,
|
|
|
|
* with a valid network address
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
iptablesForwardAllowCross(iptablesContext *ctx,
|
|
|
|
const char *iface,
|
|
|
|
int action)
|
|
|
|
{
|
|
|
|
return iptablesAddRemoveRule(ctx->forward_filter,
|
|
|
|
action,
|
|
|
|
"--in-interface", iface,
|
|
|
|
"--out-interface", iface,
|
|
|
|
"--jump", "ACCEPT",
|
|
|
|
NULL);
|
|
|
|
}
|
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
/**
|
|
|
|
* iptablesAddForwardAllowCross:
|
|
|
|
* @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
|
|
|
|
*/
|
2007-04-10 23:17:46 +00:00
|
|
|
int
|
|
|
|
iptablesAddForwardAllowCross(iptablesContext *ctx,
|
|
|
|
const char *iface) {
|
|
|
|
return iptablesForwardAllowCross(ctx, iface, ADD);
|
|
|
|
}
|
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
/**
|
|
|
|
* iptablesRemoveForwardAllowCross:
|
|
|
|
* @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
|
|
|
|
*/
|
2007-04-10 23:17:46 +00:00
|
|
|
int
|
|
|
|
iptablesRemoveForwardAllowCross(iptablesContext *ctx,
|
|
|
|
const char *iface) {
|
|
|
|
return iptablesForwardAllowCross(ctx, iface, REMOVE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Drop all traffic trying to forward from the bridge.
|
|
|
|
* ie the bridge is the in interface
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
iptablesForwardRejectOut(iptablesContext *ctx,
|
|
|
|
const char *iface,
|
|
|
|
int action)
|
|
|
|
{
|
|
|
|
return iptablesAddRemoveRule(ctx->forward_filter,
|
|
|
|
action,
|
|
|
|
"--in-interface", iface,
|
|
|
|
"--jump", "REJECT",
|
|
|
|
NULL);
|
|
|
|
}
|
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
/**
|
|
|
|
* iptablesAddForwardRejectOut:
|
|
|
|
* @ctx: pointer to the IP table context
|
|
|
|
* @iface: the output interface name
|
|
|
|
*
|
|
|
|
* Add rules to the IP 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
|
|
|
|
*/
|
2007-04-10 23:17:46 +00:00
|
|
|
int
|
|
|
|
iptablesAddForwardRejectOut(iptablesContext *ctx,
|
|
|
|
const char *iface)
|
|
|
|
{
|
|
|
|
return iptablesForwardRejectOut(ctx, iface, ADD);
|
|
|
|
}
|
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
/**
|
|
|
|
* iptablesRemoveForwardRejectOut:
|
|
|
|
* @ctx: pointer to the IP table context
|
|
|
|
* @iface: the output interface name
|
|
|
|
*
|
|
|
|
* Remove rules from the IP 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
|
|
|
|
*/
|
2007-04-10 23:17:46 +00:00
|
|
|
int
|
|
|
|
iptablesRemoveForwardRejectOut(iptablesContext *ctx,
|
|
|
|
const char *iface)
|
|
|
|
{
|
|
|
|
return iptablesForwardRejectOut(ctx, iface, REMOVE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Drop all traffic trying to forward to the bridge.
|
|
|
|
* ie the bridge is the out interface
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
iptablesForwardRejectIn(iptablesContext *ctx,
|
2007-03-13 22:43:22 +00:00
|
|
|
const char *iface,
|
2007-04-10 23:17:46 +00:00
|
|
|
int action)
|
|
|
|
{
|
|
|
|
return iptablesAddRemoveRule(ctx->forward_filter,
|
|
|
|
action,
|
|
|
|
"--out-interface", iface,
|
|
|
|
"--jump", "REJECT",
|
|
|
|
NULL);
|
|
|
|
}
|
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
/**
|
|
|
|
* iptablesAddForwardRejectIn:
|
|
|
|
* @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
|
|
|
|
*/
|
2007-04-10 23:17:46 +00:00
|
|
|
int
|
|
|
|
iptablesAddForwardRejectIn(iptablesContext *ctx,
|
|
|
|
const char *iface)
|
2007-02-14 16:26:42 +00:00
|
|
|
{
|
2007-04-10 23:17:46 +00:00
|
|
|
return iptablesForwardRejectIn(ctx, iface, ADD);
|
2007-02-14 16:26:42 +00:00
|
|
|
}
|
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
/**
|
|
|
|
* iptablesRemoveForwardRejectIn:
|
|
|
|
* @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
|
|
|
|
*/
|
2007-02-14 16:26:42 +00:00
|
|
|
int
|
2007-04-10 23:17:46 +00:00
|
|
|
iptablesRemoveForwardRejectIn(iptablesContext *ctx,
|
|
|
|
const char *iface)
|
2007-02-14 16:26:42 +00:00
|
|
|
{
|
2007-04-10 23:17:46 +00:00
|
|
|
return iptablesForwardRejectIn(ctx, iface, REMOVE);
|
2007-02-14 16:26:42 +00:00
|
|
|
}
|
|
|
|
|
2007-04-10 23:17:46 +00:00
|
|
|
|
|
|
|
/* Masquerade all traffic coming from the network associated
|
|
|
|
* with the bridge
|
|
|
|
*/
|
2007-02-14 16:26:42 +00:00
|
|
|
static int
|
2007-04-10 23:17:46 +00:00
|
|
|
iptablesForwardMasquerade(iptablesContext *ctx,
|
2010-10-25 14:10:33 +00:00
|
|
|
virSocketAddr *netaddr,
|
|
|
|
virSocketAddr *netmask,
|
2010-06-10 16:50:38 +00:00
|
|
|
const char *physdev,
|
|
|
|
const char *protocol,
|
|
|
|
int action)
|
2007-02-14 16:26:42 +00:00
|
|
|
{
|
Convert virNetwork to use virSocketAddr everywhere
Instead of storing the IP address string in virNetwork related
structs, store the parsed virSocketAddr. This will make it
easier to add IPv6 support in the future, by letting driver
code directly check what address family is present
* src/conf/network_conf.c, src/conf/network_conf.h,
src/network/bridge_driver.c: Convert to use virSocketAddr
in virNetwork, instead of char *.
* src/util/bridge.c, src/util/bridge.h,
src/util/dnsmasq.c, src/util/dnsmasq.h,
src/util/iptables.c, src/util/iptables.h: Convert to
take a virSocketAddr instead of char * for any IP
address parameters
* src/util/network.h: Add macros to determine if an address
is set, and what address family is set.
2010-10-21 12:14:33 +00:00
|
|
|
int ret;
|
|
|
|
char *networkstr;
|
|
|
|
|
2010-10-25 14:10:33 +00:00
|
|
|
if (!(networkstr = iptablesFormatNetwork(netaddr, netmask)))
|
Convert virNetwork to use virSocketAddr everywhere
Instead of storing the IP address string in virNetwork related
structs, store the parsed virSocketAddr. This will make it
easier to add IPv6 support in the future, by letting driver
code directly check what address family is present
* src/conf/network_conf.c, src/conf/network_conf.h,
src/network/bridge_driver.c: Convert to use virSocketAddr
in virNetwork, instead of char *.
* src/util/bridge.c, src/util/bridge.h,
src/util/dnsmasq.c, src/util/dnsmasq.h,
src/util/iptables.c, src/util/iptables.h: Convert to
take a virSocketAddr instead of char * for any IP
address parameters
* src/util/network.h: Add macros to determine if an address
is set, and what address family is set.
2010-10-21 12:14:33 +00:00
|
|
|
return -1;
|
|
|
|
|
2010-06-10 16:50:38 +00:00
|
|
|
if (protocol && protocol[0]) {
|
|
|
|
if (physdev && physdev[0]) {
|
Convert virNetwork to use virSocketAddr everywhere
Instead of storing the IP address string in virNetwork related
structs, store the parsed virSocketAddr. This will make it
easier to add IPv6 support in the future, by letting driver
code directly check what address family is present
* src/conf/network_conf.c, src/conf/network_conf.h,
src/network/bridge_driver.c: Convert to use virSocketAddr
in virNetwork, instead of char *.
* src/util/bridge.c, src/util/bridge.h,
src/util/dnsmasq.c, src/util/dnsmasq.h,
src/util/iptables.c, src/util/iptables.h: Convert to
take a virSocketAddr instead of char * for any IP
address parameters
* src/util/network.h: Add macros to determine if an address
is set, and what address family is set.
2010-10-21 12:14:33 +00:00
|
|
|
ret = iptablesAddRemoveRule(ctx->nat_postrouting,
|
|
|
|
action,
|
|
|
|
"--source", networkstr,
|
|
|
|
"-p", protocol,
|
|
|
|
"!", "--destination", networkstr,
|
|
|
|
"--out-interface", physdev,
|
|
|
|
"--jump", "MASQUERADE",
|
|
|
|
"--to-ports", "1024-65535",
|
|
|
|
NULL);
|
2010-06-10 16:50:38 +00:00
|
|
|
} else {
|
Convert virNetwork to use virSocketAddr everywhere
Instead of storing the IP address string in virNetwork related
structs, store the parsed virSocketAddr. This will make it
easier to add IPv6 support in the future, by letting driver
code directly check what address family is present
* src/conf/network_conf.c, src/conf/network_conf.h,
src/network/bridge_driver.c: Convert to use virSocketAddr
in virNetwork, instead of char *.
* src/util/bridge.c, src/util/bridge.h,
src/util/dnsmasq.c, src/util/dnsmasq.h,
src/util/iptables.c, src/util/iptables.h: Convert to
take a virSocketAddr instead of char * for any IP
address parameters
* src/util/network.h: Add macros to determine if an address
is set, and what address family is set.
2010-10-21 12:14:33 +00:00
|
|
|
ret = iptablesAddRemoveRule(ctx->nat_postrouting,
|
|
|
|
action,
|
|
|
|
"--source", networkstr,
|
|
|
|
"-p", protocol,
|
|
|
|
"!", "--destination", networkstr,
|
|
|
|
"--jump", "MASQUERADE",
|
|
|
|
"--to-ports", "1024-65535",
|
|
|
|
NULL);
|
2010-06-10 16:50:38 +00:00
|
|
|
}
|
2007-03-13 22:43:22 +00:00
|
|
|
} else {
|
2010-06-10 16:50:38 +00:00
|
|
|
if (physdev && physdev[0]) {
|
Convert virNetwork to use virSocketAddr everywhere
Instead of storing the IP address string in virNetwork related
structs, store the parsed virSocketAddr. This will make it
easier to add IPv6 support in the future, by letting driver
code directly check what address family is present
* src/conf/network_conf.c, src/conf/network_conf.h,
src/network/bridge_driver.c: Convert to use virSocketAddr
in virNetwork, instead of char *.
* src/util/bridge.c, src/util/bridge.h,
src/util/dnsmasq.c, src/util/dnsmasq.h,
src/util/iptables.c, src/util/iptables.h: Convert to
take a virSocketAddr instead of char * for any IP
address parameters
* src/util/network.h: Add macros to determine if an address
is set, and what address family is set.
2010-10-21 12:14:33 +00:00
|
|
|
ret = iptablesAddRemoveRule(ctx->nat_postrouting,
|
|
|
|
action,
|
|
|
|
"--source", networkstr,
|
|
|
|
"!", "--destination", networkstr,
|
|
|
|
"--out-interface", physdev,
|
|
|
|
"--jump", "MASQUERADE",
|
|
|
|
NULL);
|
2010-06-10 16:50:38 +00:00
|
|
|
} else {
|
Convert virNetwork to use virSocketAddr everywhere
Instead of storing the IP address string in virNetwork related
structs, store the parsed virSocketAddr. This will make it
easier to add IPv6 support in the future, by letting driver
code directly check what address family is present
* src/conf/network_conf.c, src/conf/network_conf.h,
src/network/bridge_driver.c: Convert to use virSocketAddr
in virNetwork, instead of char *.
* src/util/bridge.c, src/util/bridge.h,
src/util/dnsmasq.c, src/util/dnsmasq.h,
src/util/iptables.c, src/util/iptables.h: Convert to
take a virSocketAddr instead of char * for any IP
address parameters
* src/util/network.h: Add macros to determine if an address
is set, and what address family is set.
2010-10-21 12:14:33 +00:00
|
|
|
ret = iptablesAddRemoveRule(ctx->nat_postrouting,
|
|
|
|
action,
|
|
|
|
"--source", networkstr,
|
|
|
|
"!", "--destination", networkstr,
|
|
|
|
"--jump", "MASQUERADE",
|
|
|
|
NULL);
|
2010-06-10 16:50:38 +00:00
|
|
|
}
|
2007-03-13 22:43:22 +00:00
|
|
|
}
|
Convert virNetwork to use virSocketAddr everywhere
Instead of storing the IP address string in virNetwork related
structs, store the parsed virSocketAddr. This will make it
easier to add IPv6 support in the future, by letting driver
code directly check what address family is present
* src/conf/network_conf.c, src/conf/network_conf.h,
src/network/bridge_driver.c: Convert to use virSocketAddr
in virNetwork, instead of char *.
* src/util/bridge.c, src/util/bridge.h,
src/util/dnsmasq.c, src/util/dnsmasq.h,
src/util/iptables.c, src/util/iptables.h: Convert to
take a virSocketAddr instead of char * for any IP
address parameters
* src/util/network.h: Add macros to determine if an address
is set, and what address family is set.
2010-10-21 12:14:33 +00:00
|
|
|
VIR_FREE(networkstr);
|
|
|
|
return ret;
|
2007-02-14 16:26:42 +00:00
|
|
|
}
|
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
/**
|
|
|
|
* iptablesAddForwardMasquerade:
|
|
|
|
* @ctx: pointer to the IP table context
|
|
|
|
* @network: the source network name
|
|
|
|
* @physdev: the physical input device or NULL
|
2010-06-10 16:50:38 +00:00
|
|
|
* @protocol: the network protocol or NULL
|
2008-02-05 19:27:37 +00:00
|
|
|
*
|
2007-06-29 13:23:13 +00:00
|
|
|
* Add rules to the IP table context to allow masquerading
|
|
|
|
* network @network on @physdev. This allow the bridge to
|
|
|
|
* masquerade for that network (on @physdev).
|
|
|
|
*
|
|
|
|
* Returns 0 in case of success or an error code otherwise
|
|
|
|
*/
|
2007-02-14 16:26:42 +00:00
|
|
|
int
|
2007-04-10 23:17:46 +00:00
|
|
|
iptablesAddForwardMasquerade(iptablesContext *ctx,
|
2010-10-25 14:10:33 +00:00
|
|
|
virSocketAddr *netaddr,
|
|
|
|
virSocketAddr *netmask,
|
2010-06-10 16:50:38 +00:00
|
|
|
const char *physdev,
|
|
|
|
const char *protocol)
|
2007-02-14 16:26:42 +00:00
|
|
|
{
|
2010-10-25 14:10:33 +00:00
|
|
|
return iptablesForwardMasquerade(ctx, netaddr, netmask, physdev, protocol, ADD);
|
2007-02-14 16:26:42 +00:00
|
|
|
}
|
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
/**
|
|
|
|
* iptablesRemoveForwardMasquerade:
|
|
|
|
* @ctx: pointer to the IP table context
|
|
|
|
* @network: the source network name
|
|
|
|
* @physdev: the physical input device or NULL
|
2010-06-10 16:50:38 +00:00
|
|
|
* @protocol: the network protocol or NULL
|
2008-02-05 19:27:37 +00:00
|
|
|
*
|
2007-06-29 13:23:13 +00:00
|
|
|
* Remove rules from the IP table context to stop masquerading
|
|
|
|
* network @network on @physdev. This stops the bridge from
|
|
|
|
* masquerading for that network (on @physdev).
|
|
|
|
*
|
|
|
|
* Returns 0 in case of success or an error code otherwise
|
|
|
|
*/
|
2007-02-14 16:26:42 +00:00
|
|
|
int
|
2007-04-10 23:17:46 +00:00
|
|
|
iptablesRemoveForwardMasquerade(iptablesContext *ctx,
|
2010-10-25 14:10:33 +00:00
|
|
|
virSocketAddr *netaddr,
|
|
|
|
virSocketAddr *netmask,
|
2010-06-10 16:50:38 +00:00
|
|
|
const char *physdev,
|
|
|
|
const char *protocol)
|
2007-02-14 16:26:42 +00:00
|
|
|
{
|
2010-10-25 14:10:33 +00:00
|
|
|
return iptablesForwardMasquerade(ctx, netaddr, netmask, physdev, protocol, REMOVE);
|
2007-02-14 16:26:42 +00:00
|
|
|
}
|
2010-07-13 02:59:58 +00:00
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
iptablesOutputFixUdpChecksum(iptablesContext *ctx,
|
|
|
|
const char *iface,
|
|
|
|
int port,
|
|
|
|
int action)
|
|
|
|
{
|
|
|
|
char portstr[32];
|
|
|
|
|
|
|
|
snprintf(portstr, sizeof(portstr), "%d", port);
|
|
|
|
portstr[sizeof(portstr) - 1] = '\0';
|
|
|
|
|
|
|
|
return iptablesAddRemoveRule(ctx->mangle_postrouting,
|
|
|
|
action,
|
|
|
|
"--out-interface", iface,
|
|
|
|
"--protocol", "udp",
|
|
|
|
"--destination-port", portstr,
|
|
|
|
"--jump", "CHECKSUM", "--checksum-fill",
|
|
|
|
NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* iptablesAddOutputFixUdpChecksum:
|
|
|
|
* @ctx: pointer to the IP table context
|
|
|
|
* @iface: the interface name
|
|
|
|
* @port: the UDP port to match
|
|
|
|
*
|
|
|
|
* Add an rule to the mangle table's POSTROUTING chain that fixes up the
|
|
|
|
* checksum of packets with the given destination @port.
|
|
|
|
* the given @iface interface for TCP packets.
|
|
|
|
*
|
|
|
|
* Returns 0 in case of success or an error code in case of error.
|
|
|
|
* (NB: if the system's iptables does not support checksum mangling,
|
|
|
|
* this will return an error, which should be ignored.)
|
|
|
|
*/
|
|
|
|
|
|
|
|
int
|
|
|
|
iptablesAddOutputFixUdpChecksum(iptablesContext *ctx,
|
|
|
|
const char *iface,
|
|
|
|
int port)
|
|
|
|
{
|
|
|
|
return iptablesOutputFixUdpChecksum(ctx, iface, port, ADD);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* iptablesRemoveOutputFixUdpChecksum:
|
|
|
|
* @ctx: pointer to the IP table context
|
|
|
|
* @iface: the interface name
|
|
|
|
* @port: the UDP port of the rule to remove
|
|
|
|
*
|
|
|
|
* Removes the checksum fixup rule that was previous added with
|
|
|
|
* iptablesAddOutputFixUdpChecksum.
|
|
|
|
*
|
|
|
|
* Returns 0 in case of success or an error code in case of error
|
|
|
|
* (again, if iptables doesn't support checksum fixup, this will
|
|
|
|
* return an error, which should be ignored)
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
iptablesRemoveOutputFixUdpChecksum(iptablesContext *ctx,
|
|
|
|
const char *iface,
|
|
|
|
int port)
|
|
|
|
{
|
|
|
|
return iptablesOutputFixUdpChecksum(ctx, iface, port, REMOVE);
|
|
|
|
}
|