network: wire up support for IPv6 NAT rules

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>
This commit is contained in:
Daniel P. Berrangé 2020-06-08 14:40:15 +01:00
parent 927acaedec
commit 8a4f331e8c
4 changed files with 262 additions and 7 deletions

View 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);

View File

@ -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

View File

@ -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>

View 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;