]> xenbits.xensource.com Git - libvirt.git/commitdiff
network: wire up support for IPv6 NAT rules
authorDaniel P. Berrangé <berrange@redhat.com>
Mon, 8 Jun 2020 13:40:15 +0000 (14:40 +0100)
committerDaniel P. Berrangé <berrange@redhat.com>
Mon, 15 Jun 2020 16:10:15 +0000 (17:10 +0100)
Now that we have support for IPv6 in the iptables helpers, and a new
option in the XML schema, we can wire up support for it in the network
driver.

Reviewed-by: Laine Stump <laine@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
src/network/bridge_driver_linux.c
tests/networkxml2firewalldata/nat-ipv6-masquerade-linux.args [new file with mode: 0644]
tests/networkxml2firewalldata/nat-ipv6-masquerade.xml [new file with mode: 0644]
tests/networkxml2firewalltest.c

index 4145411b4b3654ec3623193ffcb2a22f2ac5892c..30f6aa8fe156620173d007e70d1167316aeb50e3 100644 (file)
@@ -334,7 +334,8 @@ int networkCheckRouteCollision(virNetworkDefPtr def)
     return ret;
 }
 
-static const char networkLocalMulticast[] = "224.0.0.0/24";
+static const char networkLocalMulticastIPv4[] = "224.0.0.0/24";
+static const char networkLocalMulticastIPv6[] = "ff02::/16";
 static const char networkLocalBroadcast[] = "255.255.255.255/32";
 
 static int
@@ -344,6 +345,7 @@ networkAddMasqueradingFirewallRules(virFirewallPtr fw,
 {
     int prefix = virNetworkIPDefPrefix(ipdef);
     const char *forwardIf = virNetworkDefForwardIf(def, 0);
+    bool isIPv4 = VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET);
 
     if (prefix < 0) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
@@ -433,7 +435,8 @@ networkAddMasqueradingFirewallRules(virFirewallPtr fw,
         return -1;
 
     /* exempt local network broadcast address as destination */
-    if (iptablesAddDontMasquerade(fw,
+    if (isIPv4 &&
+        iptablesAddDontMasquerade(fw,
                                   &ipdef->address,
                                   prefix,
                                   forwardIf,
@@ -445,7 +448,8 @@ networkAddMasqueradingFirewallRules(virFirewallPtr fw,
                                   &ipdef->address,
                                   prefix,
                                   forwardIf,
-                                  networkLocalMulticast) < 0)
+                                  isIPv4 ? networkLocalMulticastIPv4 :
+                                  networkLocalMulticastIPv6) < 0)
         return -1;
 
     return 0;
@@ -458,6 +462,7 @@ networkRemoveMasqueradingFirewallRules(virFirewallPtr fw,
 {
     int prefix = virNetworkIPDefPrefix(ipdef);
     const char *forwardIf = virNetworkDefForwardIf(def, 0);
+    bool isIPv4 = VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET);
 
     if (prefix < 0)
         return 0;
@@ -466,10 +471,12 @@ networkRemoveMasqueradingFirewallRules(virFirewallPtr fw,
                                      &ipdef->address,
                                      prefix,
                                      forwardIf,
-                                     networkLocalMulticast) < 0)
+                                     isIPv4 ? networkLocalMulticastIPv4 :
+                                     networkLocalMulticastIPv6) < 0)
         return -1;
 
-    if (iptablesRemoveDontMasquerade(fw,
+    if (isIPv4 &&
+        iptablesRemoveDontMasquerade(fw,
                                      &ipdef->address,
                                      prefix,
                                      forwardIf,
@@ -796,7 +803,8 @@ networkAddIPSpecificFirewallRules(virFirewallPtr fw,
      */
 
     if (def->forward.type == VIR_NETWORK_FORWARD_NAT) {
-        if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET))
+        if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET) ||
+            def->forward.natIPv6 == VIR_TRISTATE_BOOL_YES)
             return networkAddMasqueradingFirewallRules(fw, def, ipdef);
         else if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET6))
             return networkAddRoutingFirewallRules(fw, def, ipdef);
@@ -813,7 +821,8 @@ networkRemoveIPSpecificFirewallRules(virFirewallPtr fw,
                                      virNetworkIPDefPtr ipdef)
 {
     if (def->forward.type == VIR_NETWORK_FORWARD_NAT) {
-        if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET))
+        if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET) ||
+            def->forward.natIPv6 == VIR_TRISTATE_BOOL_YES)
             return networkRemoveMasqueradingFirewallRules(fw, def, ipdef);
         else if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET6))
             return networkRemoveRoutingFirewallRules(fw, def, ipdef);
diff --git a/tests/networkxml2firewalldata/nat-ipv6-masquerade-linux.args b/tests/networkxml2firewalldata/nat-ipv6-masquerade-linux.args
new file mode 100644 (file)
index 0000000..f7b82c9
--- /dev/null
@@ -0,0 +1,228 @@
+iptables \
+--table filter \
+--insert LIBVIRT_INP \
+--in-interface virbr0 \
+--protocol tcp \
+--destination-port 67 \
+--jump ACCEPT
+iptables \
+--table filter \
+--insert LIBVIRT_INP \
+--in-interface virbr0 \
+--protocol udp \
+--destination-port 67 \
+--jump ACCEPT
+iptables \
+--table filter \
+--insert LIBVIRT_OUT \
+--out-interface virbr0 \
+--protocol tcp \
+--destination-port 68 \
+--jump ACCEPT
+iptables \
+--table filter \
+--insert LIBVIRT_OUT \
+--out-interface virbr0 \
+--protocol udp \
+--destination-port 68 \
+--jump ACCEPT
+iptables \
+--table filter \
+--insert LIBVIRT_INP \
+--in-interface virbr0 \
+--protocol tcp \
+--destination-port 53 \
+--jump ACCEPT
+iptables \
+--table filter \
+--insert LIBVIRT_INP \
+--in-interface virbr0 \
+--protocol udp \
+--destination-port 53 \
+--jump ACCEPT
+iptables \
+--table filter \
+--insert LIBVIRT_OUT \
+--out-interface virbr0 \
+--protocol tcp \
+--destination-port 53 \
+--jump ACCEPT
+iptables \
+--table filter \
+--insert LIBVIRT_OUT \
+--out-interface virbr0 \
+--protocol udp \
+--destination-port 53 \
+--jump ACCEPT
+iptables \
+--table filter \
+--insert LIBVIRT_FWO \
+--in-interface virbr0 \
+--jump REJECT
+iptables \
+--table filter \
+--insert LIBVIRT_FWI \
+--out-interface virbr0 \
+--jump REJECT
+iptables \
+--table filter \
+--insert LIBVIRT_FWX \
+--in-interface virbr0 \
+--out-interface virbr0 \
+--jump ACCEPT
+ip6tables \
+--table filter \
+--insert LIBVIRT_FWO \
+--in-interface virbr0 \
+--jump REJECT
+ip6tables \
+--table filter \
+--insert LIBVIRT_FWI \
+--out-interface virbr0 \
+--jump REJECT
+ip6tables \
+--table filter \
+--insert LIBVIRT_FWX \
+--in-interface virbr0 \
+--out-interface virbr0 \
+--jump ACCEPT
+ip6tables \
+--table filter \
+--insert LIBVIRT_INP \
+--in-interface virbr0 \
+--protocol tcp \
+--destination-port 53 \
+--jump ACCEPT
+ip6tables \
+--table filter \
+--insert LIBVIRT_INP \
+--in-interface virbr0 \
+--protocol udp \
+--destination-port 53 \
+--jump ACCEPT
+ip6tables \
+--table filter \
+--insert LIBVIRT_OUT \
+--out-interface virbr0 \
+--protocol tcp \
+--destination-port 53 \
+--jump ACCEPT
+ip6tables \
+--table filter \
+--insert LIBVIRT_OUT \
+--out-interface virbr0 \
+--protocol udp \
+--destination-port 53 \
+--jump ACCEPT
+ip6tables \
+--table filter \
+--insert LIBVIRT_INP \
+--in-interface virbr0 \
+--protocol udp \
+--destination-port 547 \
+--jump ACCEPT
+ip6tables \
+--table filter \
+--insert LIBVIRT_OUT \
+--out-interface virbr0 \
+--protocol udp \
+--destination-port 546 \
+--jump ACCEPT
+iptables \
+--table filter \
+--insert LIBVIRT_FWO \
+--source 192.168.122.0/24 \
+--in-interface virbr0 \
+--jump ACCEPT
+iptables \
+--table filter \
+--insert LIBVIRT_FWI \
+--destination 192.168.122.0/24 \
+--out-interface virbr0 \
+--match conntrack \
+--ctstate ESTABLISHED,RELATED \
+--jump ACCEPT
+iptables \
+--table nat \
+--insert LIBVIRT_PRT \
+--source 192.168.122.0/24 '!' \
+--destination 192.168.122.0/24 \
+--jump MASQUERADE
+iptables \
+--table nat \
+--insert LIBVIRT_PRT \
+--source 192.168.122.0/24 \
+-p udp '!' \
+--destination 192.168.122.0/24 \
+--jump MASQUERADE \
+--to-ports 1024-65535
+iptables \
+--table nat \
+--insert LIBVIRT_PRT \
+--source 192.168.122.0/24 \
+-p tcp '!' \
+--destination 192.168.122.0/24 \
+--jump MASQUERADE \
+--to-ports 1024-65535
+iptables \
+--table nat \
+--insert LIBVIRT_PRT \
+--source 192.168.122.0/24 \
+--destination 255.255.255.255/32 \
+--jump RETURN
+iptables \
+--table nat \
+--insert LIBVIRT_PRT \
+--source 192.168.122.0/24 \
+--destination 224.0.0.0/24 \
+--jump RETURN
+ip6tables \
+--table filter \
+--insert LIBVIRT_FWO \
+--source 2001:db8:ca2:2::/64 \
+--in-interface virbr0 \
+--jump ACCEPT
+ip6tables \
+--table filter \
+--insert LIBVIRT_FWI \
+--destination 2001:db8:ca2:2::/64 \
+--out-interface virbr0 \
+--match conntrack \
+--ctstate ESTABLISHED,RELATED \
+--jump ACCEPT
+ip6tables \
+--table nat \
+--insert LIBVIRT_PRT \
+--source 2001:db8:ca2:2::/64 '!' \
+--destination 2001:db8:ca2:2::/64 \
+--jump MASQUERADE
+ip6tables \
+--table nat \
+--insert LIBVIRT_PRT \
+--source 2001:db8:ca2:2::/64 \
+-p udp '!' \
+--destination 2001:db8:ca2:2::/64 \
+--jump MASQUERADE \
+--to-ports 1024-65535
+ip6tables \
+--table nat \
+--insert LIBVIRT_PRT \
+--source 2001:db8:ca2:2::/64 \
+-p tcp '!' \
+--destination 2001:db8:ca2:2::/64 \
+--jump MASQUERADE \
+--to-ports 1024-65535
+ip6tables \
+--table nat \
+--insert LIBVIRT_PRT \
+--source 2001:db8:ca2:2::/64 \
+--destination ff02::/16 \
+--jump RETURN
+iptables \
+--table mangle \
+--insert LIBVIRT_PRT \
+--out-interface virbr0 \
+--protocol udp \
+--destination-port 68 \
+--jump CHECKSUM \
+--checksum-fill
diff --git a/tests/networkxml2firewalldata/nat-ipv6-masquerade.xml b/tests/networkxml2firewalldata/nat-ipv6-masquerade.xml
new file mode 100644 (file)
index 0000000..03bcc8c
--- /dev/null
@@ -0,0 +1,17 @@
+<network>
+  <name>default</name>
+  <bridge name="virbr0"/>
+  <forward>
+    <nat ipv6="yes"/>
+  </forward>
+  <ip address="192.168.122.1" netmask="255.255.255.0">
+    <dhcp>
+      <range start="192.168.122.2" end="192.168.122.254"/>
+    </dhcp>
+  </ip>
+  <ip family="ipv6" address="2001:db8:ca2:2::1" prefix="64" >
+    <dhcp>
+      <range start="2001:db8:ca2:2:1::10" end="2001:db8:ca2:2:1::ff" />
+    </dhcp>
+  </ip>
+</network>
index 7b5ada7faa3c8c997d45a79b960f518715051f51..69fadd55c4a9e557f268f6615e7e2333010e829b 100644 (file)
@@ -171,6 +171,7 @@ mymain(void)
     DO_TEST("nat-many-ips");
     DO_TEST("nat-no-dhcp");
     DO_TEST("nat-ipv6");
+    DO_TEST("nat-ipv6-masquerade");
     DO_TEST("route-default");
 
     return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;