[libvirt PATCH v2 3/3] network: wire up support for IPv6 NAT rules

Laine Stump laine at laine.org
Wed Jun 10 04:14:21 UTC 2020


On 6/9/20 12:17 PM, Daniel P. Berrangé wrote:
> 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.
>
> Signed-off-by: Daniel P. Berrangé <berrange at redhat.com>
> ---
>   src/network/bridge_driver_linux.c             |  23 +-
>   .../nat-ipv6-masquerade-linux.args            | 228 ++++++++++++++++++
>   .../nat-ipv6-masquerade.xml                   |  17 ++
>   tests/networkxml2firewalltest.c               |   1 +
>   4 files changed, 262 insertions(+), 7 deletions(-)
>   create mode 100644 tests/networkxml2firewalldata/nat-ipv6-masquerade-linux.args
>   create mode 100644 tests/networkxml2firewalldata/nat-ipv6-masquerade.xml
>
> diff --git a/src/network/bridge_driver_linux.c b/src/network/bridge_driver_linux.c
> index b0bd207250..fcb3803965 100644
> --- a/src/network/bridge_driver_linux.c
> +++ b/src/network/bridge_driver_linux.c
> @@ -307,7 +307,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[] = "ffx2::/16";


Once I got everything built and tried starting a network with ipv6 nat, 
I got this error message:


virsh net-start ipv6 error: Failed to start network ipv6 error: 
COMMAND_FAILED: '/usr/sbin/ip6tables -w10 -w --table nat --insert 
LIBVIRT_PRT --source 2001:4978:2ac:5::/80 --destination ffx2::/16 --jump 
RETURN' failed: ip6tables v1.8.3 (legacy): host/network `ffx2::' not 
found Try `ip6tables -h' or 'ip6tables --help' for more information.


Do we need to do something different for multicast traffic in the case 
of IPv6?


Other than that it all looks good, so


Reviewed-by: Laine Stump <laine at redhat.com>


once the problem with multicast ffx2::/16 as the destination of a rule 
is resolved.


>   static const char networkLocalBroadcast[] = "255.255.255.255/32";
>   
>   static int
> @@ -317,6 +318,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,
> @@ -406,7 +408,8 @@ networkAddMasqueradingFirewallRules(virFirewallPtr fw,
>           return -1;
>   
>       /* exempt local network broadcast address as destination */
> -    if (iptablesAddDontMasquerade(fw,
> +    if (isIPv4 &&
> +        iptablesAddDontMasquerade(fw,
>                                     &ipdef->address,
>                                     prefix,
>                                     forwardIf,
> @@ -418,7 +421,8 @@ networkAddMasqueradingFirewallRules(virFirewallPtr fw,
>                                     &ipdef->address,
>                                     prefix,
>                                     forwardIf,
> -                                  networkLocalMulticast) < 0)
> +                                  isIPv4 ? networkLocalMulticastIPv4 :
> +                                  networkLocalMulticastIPv6) < 0)
>           return -1;
>   
>       return 0;
> @@ -431,6 +435,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;
> @@ -439,10 +444,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,
> @@ -769,7 +776,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);
> @@ -786,7 +794,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
> index 0000000000..4ba4c3da30
> --- /dev/null
> +++ b/tests/networkxml2firewalldata/nat-ipv6-masquerade-linux.args
> @@ -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 ffx2::/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
> index 0000000000..03bcc8c67d
> --- /dev/null
> +++ b/tests/networkxml2firewalldata/nat-ipv6-masquerade.xml
> @@ -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>
> diff --git a/tests/networkxml2firewalltest.c b/tests/networkxml2firewalltest.c
> index 0ad5e2303b..697bfd7e03 100644
> --- a/tests/networkxml2firewalltest.c
> +++ b/tests/networkxml2firewalltest.c
> @@ -173,6 +173,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;





More information about the libvir-list mailing list