All of the iptables functions eventually call down to a single
bottom-level function, and fortunately, ip6tables syntax (for all the
args that we use) is identical to iptables format (except the
addresses), so all we need to do is:
1) Get an address family down to the lowest level function in each
case, either implied through an address, or explicitly when no
address is in the parameter list, and
2) At the lowest level, just decide whether to call "iptables" or
"ip6tables" based on the family.
The location of the ip6tables binary is determined at build time by
autoconf. If a particular target system happens to not have ip6tables
installed, any attempts to run it will generate an error, but that
won't happen unless someone tries to define an IPv6 address for a
network. This is identical behavior to IPv4 addresses and iptables.
---
No changes from V1.
configure.ac | 3 ++
src/network/bridge_driver.c | 54 ++++++++++++++++++-------------
src/util/iptables.c | 75 +++++++++++++++++++++++++++++++-----------
src/util/iptables.h | 10 ++++++
4 files changed, 99 insertions(+), 43 deletions(-)
diff --git a/configure.ac b/configure.ac
index 4db613a..76652f4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -312,6 +312,9 @@ AC_DEFINE_UNQUOTED([IP_PATH], "$IP_PATH", [path to ip
binary])
AC_PATH_PROG([IPTABLES_PATH], [iptables], /sbin/iptables, [/usr/sbin:$PATH])
AC_DEFINE_UNQUOTED([IPTABLES_PATH], "$IPTABLES_PATH", [path to iptables
binary])
+AC_PATH_PROG([IP6TABLES_PATH], [ip6tables], /sbin/ip6tables, [/usr/sbin:$PATH])
+AC_DEFINE_UNQUOTED([IP6TABLES_PATH], "$IP6TABLES_PATH", [path to ip6tables
binary])
+
AC_PATH_PROG([EBTABLES_PATH], [ebtables], /sbin/ebtables, [/usr/sbin:$PATH])
AC_DEFINE_UNQUOTED([EBTABLES_PATH], "$EBTABLES_PATH", [path to ebtables
binary])
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 03afe6c..e0d5aaf 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -842,14 +842,16 @@ networkAddGeneralIptablesRules(struct network_driver *driver,
/* allow DHCP requests through to dnsmasq */
- if (iptablesAddTcpInput(driver->iptables, network->def->bridge, 67) < 0)
{
+ if (iptablesAddTcpInput(driver->iptables, AF_INET,
+ network->def->bridge, 67) < 0) {
networkReportError(VIR_ERR_SYSTEM_ERROR,
_("failed to add iptables rule to allow DHCP requests
from '%s'"),
network->def->bridge);
goto err1;
}
- if (iptablesAddUdpInput(driver->iptables, network->def->bridge, 67) < 0)
{
+ if (iptablesAddUdpInput(driver->iptables, AF_INET,
+ network->def->bridge, 67) < 0) {
networkReportError(VIR_ERR_SYSTEM_ERROR,
_("failed to add iptables rule to allow DHCP requests
from '%s'"),
network->def->bridge);
@@ -871,14 +873,16 @@ networkAddGeneralIptablesRules(struct network_driver *driver,
}
/* allow DNS requests through to dnsmasq */
- if (iptablesAddTcpInput(driver->iptables, network->def->bridge, 53) < 0)
{
+ if (iptablesAddTcpInput(driver->iptables, AF_INET,
+ network->def->bridge, 53) < 0) {
networkReportError(VIR_ERR_SYSTEM_ERROR,
_("failed to add iptables rule to allow DNS requests from
'%s'"),
network->def->bridge);
goto err3;
}
- if (iptablesAddUdpInput(driver->iptables, network->def->bridge, 53) < 0)
{
+ if (iptablesAddUdpInput(driver->iptables, AF_INET,
+ network->def->bridge, 53) < 0) {
networkReportError(VIR_ERR_SYSTEM_ERROR,
_("failed to add iptables rule to allow DNS requests from
'%s'"),
network->def->bridge);
@@ -887,7 +891,8 @@ networkAddGeneralIptablesRules(struct network_driver *driver,
/* allow TFTP requests through to dnsmasq if necessary */
if (ipv4def && ipv4def->tftproot &&
- iptablesAddUdpInput(driver->iptables, network->def->bridge, 69) < 0)
{
+ iptablesAddUdpInput(driver->iptables, AF_INET,
+ network->def->bridge, 69) < 0) {
networkReportError(VIR_ERR_SYSTEM_ERROR,
_("failed to add iptables rule to allow TFTP requests
from '%s'"),
network->def->bridge);
@@ -896,14 +901,16 @@ networkAddGeneralIptablesRules(struct network_driver *driver,
/* Catch all rules to block forwarding to/from bridges */
- if (iptablesAddForwardRejectOut(driver->iptables, network->def->bridge) <
0) {
+ if (iptablesAddForwardRejectOut(driver->iptables, AF_INET,
+ network->def->bridge) < 0) {
networkReportError(VIR_ERR_SYSTEM_ERROR,
_("failed to add iptables rule to block outbound traffic
from '%s'"),
network->def->bridge);
goto err6;
}
- if (iptablesAddForwardRejectIn(driver->iptables, network->def->bridge) <
0) {
+ if (iptablesAddForwardRejectIn(driver->iptables, AF_INET,
+ network->def->bridge) < 0) {
networkReportError(VIR_ERR_SYSTEM_ERROR,
_("failed to add iptables rule to block inbound traffic
to '%s'"),
network->def->bridge);
@@ -911,7 +918,8 @@ networkAddGeneralIptablesRules(struct network_driver *driver,
}
/* Allow traffic between guests on the same bridge */
- if (iptablesAddForwardAllowCross(driver->iptables, network->def->bridge)
< 0) {
+ if (iptablesAddForwardAllowCross(driver->iptables, AF_INET,
+ network->def->bridge) < 0) {
networkReportError(VIR_ERR_SYSTEM_ERROR,
_("failed to add iptables rule to allow cross bridge
traffic on '%s'"),
network->def->bridge);
@@ -922,21 +930,21 @@ networkAddGeneralIptablesRules(struct network_driver *driver,
/* unwind in reverse order from the point of failure */
err8:
- iptablesRemoveForwardRejectIn(driver->iptables, network->def->bridge);
+ iptablesRemoveForwardRejectIn(driver->iptables, AF_INET,
network->def->bridge);
err7:
- iptablesRemoveForwardRejectOut(driver->iptables, network->def->bridge);
+ iptablesRemoveForwardRejectOut(driver->iptables, AF_INET,
network->def->bridge);
err6:
if (ipv4def && ipv4def->tftproot) {
- iptablesRemoveUdpInput(driver->iptables, network->def->bridge, 69);
+ iptablesRemoveUdpInput(driver->iptables, AF_INET, network->def->bridge,
69);
}
err5:
- iptablesRemoveUdpInput(driver->iptables, network->def->bridge, 53);
+ iptablesRemoveUdpInput(driver->iptables, AF_INET, network->def->bridge,
53);
err4:
- iptablesRemoveTcpInput(driver->iptables, network->def->bridge, 53);
+ iptablesRemoveTcpInput(driver->iptables, AF_INET, network->def->bridge,
53);
err3:
- iptablesRemoveUdpInput(driver->iptables, network->def->bridge, 67);
+ iptablesRemoveUdpInput(driver->iptables, AF_INET, network->def->bridge,
67);
err2:
- iptablesRemoveTcpInput(driver->iptables, network->def->bridge, 67);
+ iptablesRemoveTcpInput(driver->iptables, AF_INET, network->def->bridge,
67);
err1:
return -1;
}
@@ -955,20 +963,20 @@ networkRemoveGeneralIptablesRules(struct network_driver *driver,
break;
}
- iptablesRemoveForwardAllowCross(driver->iptables, network->def->bridge);
- iptablesRemoveForwardRejectIn(driver->iptables, network->def->bridge);
- iptablesRemoveForwardRejectOut(driver->iptables, network->def->bridge);
+ iptablesRemoveForwardAllowCross(driver->iptables, AF_INET,
network->def->bridge);
+ iptablesRemoveForwardRejectIn(driver->iptables, AF_INET,
network->def->bridge);
+ iptablesRemoveForwardRejectOut(driver->iptables, AF_INET,
network->def->bridge);
if (ipv4def && ipv4def->tftproot) {
- iptablesRemoveUdpInput(driver->iptables, network->def->bridge, 69);
+ iptablesRemoveUdpInput(driver->iptables, AF_INET, network->def->bridge,
69);
}
- iptablesRemoveUdpInput(driver->iptables, network->def->bridge, 53);
- iptablesRemoveTcpInput(driver->iptables, network->def->bridge, 53);
+ iptablesRemoveUdpInput(driver->iptables, AF_INET, network->def->bridge,
53);
+ iptablesRemoveTcpInput(driver->iptables, AF_INET, network->def->bridge,
53);
if (ipv4def && (ipv4def->nranges || ipv4def->nhosts)) {
iptablesRemoveOutputFixUdpChecksum(driver->iptables,
network->def->bridge, 68);
}
- iptablesRemoveUdpInput(driver->iptables, network->def->bridge, 67);
- iptablesRemoveTcpInput(driver->iptables, network->def->bridge, 67);
+ iptablesRemoveUdpInput(driver->iptables, AF_INET, network->def->bridge,
67);
+ iptablesRemoveTcpInput(driver->iptables, AF_INET, network->def->bridge,
67);
}
static int
diff --git a/src/util/iptables.c b/src/util/iptables.c
index f7b692c..647e7ae 100644
--- a/src/util/iptables.c
+++ b/src/util/iptables.c
@@ -99,14 +99,17 @@ iptRulesNew(const char *table,
}
static int ATTRIBUTE_SENTINEL
-iptablesAddRemoveRule(iptRules *rules, int action, const char *arg, ...)
+iptablesAddRemoveRule(iptRules *rules, int family, int action,
+ const char *arg, ...)
{
va_list args;
int ret;
virCommandPtr cmd;
const char *s;
- cmd = virCommandNew(IPTABLES_PATH);
+ cmd = virCommandNew((family == AF_INET6)
+ ? IP6TABLES_PATH : IPTABLES_PATH);
+
virCommandAddArgList(cmd, "--table", rules->table,
action == ADD ? "--insert" : "--delete",
rules->chain, arg, NULL);
@@ -177,6 +180,7 @@ iptablesContextFree(iptablesContext *ctx)
static int
iptablesInput(iptablesContext *ctx,
+ int family,
const char *iface,
int port,
int action,
@@ -188,6 +192,7 @@ iptablesInput(iptablesContext *ctx,
portstr[sizeof(portstr) - 1] = '\0';
return iptablesAddRemoveRule(ctx->input_filter,
+ family,
action,
"--in-interface", iface,
"--protocol", tcp ? "tcp" :
"udp",
@@ -210,10 +215,11 @@ iptablesInput(iptablesContext *ctx,
int
iptablesAddTcpInput(iptablesContext *ctx,
+ int family,
const char *iface,
int port)
{
- return iptablesInput(ctx, iface, port, ADD, 1);
+ return iptablesInput(ctx, family, iface, port, ADD, 1);
}
/**
@@ -229,10 +235,11 @@ iptablesAddTcpInput(iptablesContext *ctx,
*/
int
iptablesRemoveTcpInput(iptablesContext *ctx,
+ int family,
const char *iface,
int port)
{
- return iptablesInput(ctx, iface, port, REMOVE, 1);
+ return iptablesInput(ctx, family, iface, port, REMOVE, 1);
}
/**
@@ -249,10 +256,11 @@ iptablesRemoveTcpInput(iptablesContext *ctx,
int
iptablesAddUdpInput(iptablesContext *ctx,
+ int family,
const char *iface,
int port)
{
- return iptablesInput(ctx, iface, port, ADD, 0);
+ return iptablesInput(ctx, family, iface, port, ADD, 0);
}
/**
@@ -268,10 +276,11 @@ iptablesAddUdpInput(iptablesContext *ctx,
*/
int
iptablesRemoveUdpInput(iptablesContext *ctx,
+ int family,
const char *iface,
int port)
{
- return iptablesInput(ctx, iface, port, REMOVE, 0);
+ return iptablesInput(ctx, family, iface, port, REMOVE, 0);
}
@@ -282,9 +291,10 @@ static char *iptablesFormatNetwork(virSocketAddr *netaddr,
char *netstr;
char *ret;
- if (!VIR_SOCKET_IS_FAMILY(netaddr, AF_INET)) {
+ if (!(VIR_SOCKET_IS_FAMILY(netaddr, AF_INET) ||
+ VIR_SOCKET_IS_FAMILY(netaddr, AF_INET6))) {
iptablesError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("Only IPv4 addresses can be used with iptables"));
+ _("Only IPv4 or IPv6 addresses can be used with
iptables"));
return NULL;
}
@@ -327,6 +337,7 @@ iptablesForwardAllowOut(iptablesContext *ctx,
if (physdev && physdev[0]) {
ret = iptablesAddRemoveRule(ctx->forward_filter,
+ VIR_SOCKET_FAMILY(netaddr),
action,
"--source", networkstr,
"--in-interface", iface,
@@ -335,6 +346,7 @@ iptablesForwardAllowOut(iptablesContext *ctx,
NULL);
} else {
ret = iptablesAddRemoveRule(ctx->forward_filter,
+ VIR_SOCKET_FAMILY(netaddr),
action,
"--source", networkstr,
"--in-interface", iface,
@@ -411,6 +423,7 @@ iptablesForwardAllowRelatedIn(iptablesContext *ctx,
if (physdev && physdev[0]) {
ret = iptablesAddRemoveRule(ctx->forward_filter,
+ VIR_SOCKET_FAMILY(netaddr),
action,
"--destination", networkstr,
"--in-interface", physdev,
@@ -421,6 +434,7 @@ iptablesForwardAllowRelatedIn(iptablesContext *ctx,
NULL);
} else {
ret = iptablesAddRemoveRule(ctx->forward_filter,
+ VIR_SOCKET_FAMILY(netaddr),
action,
"--destination", networkstr,
"--out-interface", iface,
@@ -497,6 +511,7 @@ iptablesForwardAllowIn(iptablesContext *ctx,
if (physdev && physdev[0]) {
ret = iptablesAddRemoveRule(ctx->forward_filter,
+ VIR_SOCKET_FAMILY(netaddr),
action,
"--destination", networkstr,
"--in-interface", physdev,
@@ -505,6 +520,7 @@ iptablesForwardAllowIn(iptablesContext *ctx,
NULL);
} else {
ret = iptablesAddRemoveRule(ctx->forward_filter,
+ VIR_SOCKET_FAMILY(netaddr),
action,
"--destination", networkstr,
"--out-interface", iface,
@@ -567,10 +583,12 @@ iptablesRemoveForwardAllowIn(iptablesContext *ctx,
*/
static int
iptablesForwardAllowCross(iptablesContext *ctx,
+ int family,
const char *iface,
int action)
{
return iptablesAddRemoveRule(ctx->forward_filter,
+ family,
action,
"--in-interface", iface,
"--out-interface", iface,
@@ -591,8 +609,10 @@ iptablesForwardAllowCross(iptablesContext *ctx,
*/
int
iptablesAddForwardAllowCross(iptablesContext *ctx,
- const char *iface) {
- return iptablesForwardAllowCross(ctx, iface, ADD);
+ int family,
+ const char *iface)
+{
+ return iptablesForwardAllowCross(ctx, family, iface, ADD);
}
/**
@@ -608,8 +628,10 @@ iptablesAddForwardAllowCross(iptablesContext *ctx,
*/
int
iptablesRemoveForwardAllowCross(iptablesContext *ctx,
- const char *iface) {
- return iptablesForwardAllowCross(ctx, iface, REMOVE);
+ int family,
+ const char *iface)
+{
+ return iptablesForwardAllowCross(ctx, family, iface, REMOVE);
}
@@ -618,14 +640,16 @@ iptablesRemoveForwardAllowCross(iptablesContext *ctx,
*/
static int
iptablesForwardRejectOut(iptablesContext *ctx,
+ int family,
const char *iface,
int action)
{
return iptablesAddRemoveRule(ctx->forward_filter,
- action,
- "--in-interface", iface,
- "--jump", "REJECT",
- NULL);
+ family,
+ action,
+ "--in-interface", iface,
+ "--jump", "REJECT",
+ NULL);
}
/**
@@ -640,9 +664,10 @@ iptablesForwardRejectOut(iptablesContext *ctx,
*/
int
iptablesAddForwardRejectOut(iptablesContext *ctx,
+ int family,
const char *iface)
{
- return iptablesForwardRejectOut(ctx, iface, ADD);
+ return iptablesForwardRejectOut(ctx, family, iface, ADD);
}
/**
@@ -657,9 +682,10 @@ iptablesAddForwardRejectOut(iptablesContext *ctx,
*/
int
iptablesRemoveForwardRejectOut(iptablesContext *ctx,
+ int family,
const char *iface)
{
- return iptablesForwardRejectOut(ctx, iface, REMOVE);
+ return iptablesForwardRejectOut(ctx, family, iface, REMOVE);
}
@@ -670,10 +696,12 @@ iptablesRemoveForwardRejectOut(iptablesContext *ctx,
*/
static int
iptablesForwardRejectIn(iptablesContext *ctx,
+ int family,
const char *iface,
int action)
{
return iptablesAddRemoveRule(ctx->forward_filter,
+ family,
action,
"--out-interface", iface,
"--jump", "REJECT",
@@ -692,9 +720,10 @@ iptablesForwardRejectIn(iptablesContext *ctx,
*/
int
iptablesAddForwardRejectIn(iptablesContext *ctx,
+ int family,
const char *iface)
{
- return iptablesForwardRejectIn(ctx, iface, ADD);
+ return iptablesForwardRejectIn(ctx, family, iface, ADD);
}
/**
@@ -709,9 +738,10 @@ iptablesAddForwardRejectIn(iptablesContext *ctx,
*/
int
iptablesRemoveForwardRejectIn(iptablesContext *ctx,
+ int family,
const char *iface)
{
- return iptablesForwardRejectIn(ctx, iface, REMOVE);
+ return iptablesForwardRejectIn(ctx, family, iface, REMOVE);
}
@@ -735,6 +765,7 @@ iptablesForwardMasquerade(iptablesContext *ctx,
if (protocol && protocol[0]) {
if (physdev && physdev[0]) {
ret = iptablesAddRemoveRule(ctx->nat_postrouting,
+ VIR_SOCKET_FAMILY(netaddr),
action,
"--source", networkstr,
"-p", protocol,
@@ -745,6 +776,7 @@ iptablesForwardMasquerade(iptablesContext *ctx,
NULL);
} else {
ret = iptablesAddRemoveRule(ctx->nat_postrouting,
+ VIR_SOCKET_FAMILY(netaddr),
action,
"--source", networkstr,
"-p", protocol,
@@ -756,6 +788,7 @@ iptablesForwardMasquerade(iptablesContext *ctx,
} else {
if (physdev && physdev[0]) {
ret = iptablesAddRemoveRule(ctx->nat_postrouting,
+ VIR_SOCKET_FAMILY(netaddr),
action,
"--source", networkstr,
"!", "--destination",
networkstr,
@@ -764,6 +797,7 @@ iptablesForwardMasquerade(iptablesContext *ctx,
NULL);
} else {
ret = iptablesAddRemoveRule(ctx->nat_postrouting,
+ VIR_SOCKET_FAMILY(netaddr),
action,
"--source", networkstr,
"!", "--destination",
networkstr,
@@ -834,6 +868,7 @@ iptablesOutputFixUdpChecksum(iptablesContext *ctx,
portstr[sizeof(portstr) - 1] = '\0';
return iptablesAddRemoveRule(ctx->mangle_postrouting,
+ AF_INET,
action,
"--out-interface", iface,
"--protocol", "udp",
diff --git a/src/util/iptables.h b/src/util/iptables.h
index 982acf1..572d612 100644
--- a/src/util/iptables.h
+++ b/src/util/iptables.h
@@ -30,16 +30,20 @@ iptablesContext *iptablesContextNew (void);
void iptablesContextFree (iptablesContext *ctx);
int iptablesAddTcpInput (iptablesContext *ctx,
+ int family,
const char *iface,
int port);
int iptablesRemoveTcpInput (iptablesContext *ctx,
+ int family,
const char *iface,
int port);
int iptablesAddUdpInput (iptablesContext *ctx,
+ int family,
const char *iface,
int port);
int iptablesRemoveUdpInput (iptablesContext *ctx,
+ int family,
const char *iface,
int port);
@@ -77,18 +81,24 @@ int iptablesRemoveForwardAllowIn (iptablesContext
*ctx,
const char *physdev);
int iptablesAddForwardAllowCross (iptablesContext *ctx,
+ int family,
const char *iface);
int iptablesRemoveForwardAllowCross (iptablesContext *ctx,
+ int family,
const char *iface);
int iptablesAddForwardRejectOut (iptablesContext *ctx,
+ int family,
const char *iface);
int iptablesRemoveForwardRejectOut (iptablesContext *ctx,
+ int family,
const char *iface);
int iptablesAddForwardRejectIn (iptablesContext *ctx,
+ int family,
const char *iface);
int iptablesRemoveForwardRejectIn (iptablesContext *ctx,
+ int family,
const char *iface);
int iptablesAddForwardMasquerade (iptablesContext *ctx,
--
1.7.3.4