]> xenbits.xensource.com Git - libvirt.git/commitdiff
Update iptables.c to also support ip6tables.
authorLaine Stump <laine@laine.org>
Wed, 8 Dec 2010 19:09:25 +0000 (14:09 -0500)
committerLaine Stump <laine@laine.org>
Thu, 23 Dec 2010 20:54:32 +0000 (15:54 -0500)
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.

configure.ac
src/network/bridge_driver.c
src/util/iptables.c
src/util/iptables.h

index b6080c2345007457768a5475c66fc18966a18e68..c507891feb1bf515fb93ef323e077d609a1f53a7 100644 (file)
@@ -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])
 
index bd0e0028fb2664a7edfd1f59200efbf7e1e712b3..0c37eb6101990143de6ac4f01153e270f91813b7 100644 (file)
@@ -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
index f7b692c76bd79699edef07a570a952614f93f170..647e7aed6dec32f3a9c57ceb19ad06353eb6ed94 100644 (file)
@@ -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",
index 982acf1489f8d366c4fd1a6498092f6becd104b2..572d612fd1c01f1216dcc2c99a76f470eeb1f29f 100644 (file)
@@ -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,