Merge pull request #101 from ryanpetrello/master
Properly route floating IP traffic between VMs on tenant networks.
This commit is contained in:
commit
f1c2a9b6e9
|
@ -57,7 +57,8 @@ class IPTablesManager(base.Manager):
|
|||
'''
|
||||
rules = itertools.chain(
|
||||
self._build_filter_table(config),
|
||||
self._build_nat_table(config)
|
||||
self._build_nat_table(config),
|
||||
self._build_raw_table(config)
|
||||
)
|
||||
|
||||
for version, rules in zip((4, 6), itertools.tee(rules)):
|
||||
|
@ -231,11 +232,16 @@ class IPTablesManager(base.Manager):
|
|||
'''
|
||||
rules = [
|
||||
Rule('*nat', ip_version=4),
|
||||
]
|
||||
|
||||
rules.extend(self._build_public_snat_chain(config))
|
||||
|
||||
rules.extend([
|
||||
Rule(':PREROUTING ACCEPT [0:0]', ip_version=4),
|
||||
Rule(':INPUT ACCEPT [0:0]', ip_version=4),
|
||||
Rule(':OUTPUT ACCEPT [0:0]', ip_version=4),
|
||||
Rule(':POSTROUTING ACCEPT [0:0]', ip_version=4),
|
||||
]
|
||||
])
|
||||
|
||||
rules.extend(self._build_floating_ips(config))
|
||||
rules.extend(self._build_v4_nat(config))
|
||||
|
@ -278,7 +284,7 @@ class IPTablesManager(base.Manager):
|
|||
rules = []
|
||||
ext_if = self.get_external_network(config).interface
|
||||
|
||||
# Route floating IP addresses
|
||||
# NAT floating IP addresses
|
||||
for fip in self.get_external_network(config).floating_ips:
|
||||
|
||||
# Neutron has a bug whereby you can create a floating ip that has
|
||||
|
@ -287,10 +293,8 @@ class IPTablesManager(base.Manager):
|
|||
# iptables will barf if it encounters them)
|
||||
if fip.fixed_ip.version == fip.floating_ip.version:
|
||||
rules.append(
|
||||
Rule('-A POSTROUTING -o %s -s %s -j SNAT --to %s' % (
|
||||
ext_if.ifname,
|
||||
fip.fixed_ip,
|
||||
fip.floating_ip
|
||||
Rule('-A POSTROUTING -s %s -j PUBLIC_SNAT' % (
|
||||
fip.fixed_ip
|
||||
), ip_version=4)
|
||||
)
|
||||
rules.append(Rule(
|
||||
|
@ -300,5 +304,69 @@ class IPTablesManager(base.Manager):
|
|||
fip.fixed_ip
|
||||
), ip_version=4
|
||||
))
|
||||
for network in self.networks_by_type(
|
||||
config, Network.TYPE_INTERNAL
|
||||
):
|
||||
rules.append(Rule(
|
||||
'-A PREROUTING -i %s -d %s -j DNAT '
|
||||
'--to-destination %s' % (
|
||||
network.interface.ifname,
|
||||
fip.floating_ip,
|
||||
fip.fixed_ip
|
||||
), ip_version=4
|
||||
))
|
||||
|
||||
return rules
|
||||
|
||||
def _build_public_snat_chain(self, config):
|
||||
'''
|
||||
Build a chain for SNAT for neutron FloatingIPs. This chain ignores NAT
|
||||
for traffic marked as private.
|
||||
'''
|
||||
rules = [
|
||||
Rule(':PUBLIC_SNAT - [0:0]', ip_version=4),
|
||||
Rule(
|
||||
'-A PUBLIC_SNAT -m mark --mark 0xACDA -j RETURN',
|
||||
ip_version=4
|
||||
)
|
||||
]
|
||||
|
||||
# NAT floating IP addresses
|
||||
for fip in self.get_external_network(config).floating_ips:
|
||||
|
||||
if fip.fixed_ip.version == fip.floating_ip.version:
|
||||
rules.append(
|
||||
Rule('-A PUBLIC_SNAT -s %s -j SNAT --to %s' % (
|
||||
fip.fixed_ip,
|
||||
fip.floating_ip
|
||||
), ip_version=4)
|
||||
)
|
||||
|
||||
return rules
|
||||
|
||||
def _build_raw_table(self, config):
|
||||
'''
|
||||
Add raw rules (so we can mark private traffic and avoid NATing it)
|
||||
'''
|
||||
rules = [
|
||||
Rule('*raw', ip_version=4),
|
||||
Rule(':INPUT - [0:0]', ip_version=4),
|
||||
Rule(':OUTPUT - [0:0]', ip_version=4),
|
||||
Rule(':FORWARD - [0:0]', ip_version=4),
|
||||
Rule(':PREROUTING - [0:0]', ip_version=4)
|
||||
]
|
||||
|
||||
for network in self.networks_by_type(config, Network.TYPE_INTERNAL):
|
||||
if network.interface.first_v4:
|
||||
address = sorted(
|
||||
str(a) for a in network.interface.addresses
|
||||
if a.version == 4
|
||||
)[0]
|
||||
rules.append(Rule(
|
||||
'-A PREROUTING -d %s -j MARK --set-mark 0xACDA' % address,
|
||||
ip_version=4
|
||||
))
|
||||
|
||||
rules.append(Rule(':POSTROUTING - [0:0]', ip_version=4))
|
||||
rules.append(Rule('COMMIT', ip_version=4))
|
||||
return rules
|
||||
|
|
|
@ -74,14 +74,26 @@ V4_OUTPUT = [
|
|||
'-A INPUT -i eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT',
|
||||
'COMMIT',
|
||||
'*nat',
|
||||
':PUBLIC_SNAT - [0:0]',
|
||||
'-A PUBLIC_SNAT -m mark --mark 0xACDA -j RETURN',
|
||||
'-A PUBLIC_SNAT -s 192.168.0.2 -j SNAT --to 172.16.77.50',
|
||||
':PREROUTING ACCEPT [0:0]',
|
||||
':INPUT ACCEPT [0:0]',
|
||||
':OUTPUT ACCEPT [0:0]',
|
||||
':POSTROUTING ACCEPT [0:0]',
|
||||
'-A POSTROUTING -o eth1 -s 192.168.0.2 -j SNAT --to 172.16.77.50',
|
||||
'-A POSTROUTING -s 192.168.0.2 -j PUBLIC_SNAT',
|
||||
'-A PREROUTING -i eth1 -d 172.16.77.50 -j DNAT --to-destination 192.168.0.2', # noqa
|
||||
'-A PREROUTING -i eth2 -d 172.16.77.50 -j DNAT --to-destination 192.168.0.2', # noqa
|
||||
'-A PREROUTING -i eth2 -d 169.254.169.254 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.0.1:9602', # noqa
|
||||
'-A POSTROUTING -o eth1 -j MASQUERADE',
|
||||
'COMMIT',
|
||||
'*raw',
|
||||
':INPUT - [0:0]',
|
||||
':OUTPUT - [0:0]',
|
||||
':FORWARD - [0:0]',
|
||||
':PREROUTING - [0:0]',
|
||||
'-A PREROUTING -d 192.168.0.1/24 -j MARK --set-mark 0xACDA',
|
||||
':POSTROUTING - [0:0]',
|
||||
'COMMIT'
|
||||
]
|
||||
|
||||
|
@ -167,7 +179,8 @@ class TestIPTablesConfiguration(TestCase):
|
|||
'fdca:3ba5:a17a:acda:f816:3eff:fe66:33b6'
|
||||
)
|
||||
assert map(str, mgr._build_floating_ips(CONFIG)) == [
|
||||
'-A POSTROUTING -o eth1 -s 192.168.0.2 -j SNAT --to 172.16.77.50',
|
||||
'-A PREROUTING -i eth1 -d 172.16.77.50 -j DNAT --to-destination 192.168.0.2' # noqa
|
||||
'-A POSTROUTING -s 192.168.0.2 -j PUBLIC_SNAT',
|
||||
'-A PREROUTING -i eth1 -d 172.16.77.50 -j DNAT --to-destination 192.168.0.2', # noqa
|
||||
'-A PREROUTING -i eth2 -d 172.16.77.50 -j DNAT --to-destination 192.168.0.2' # noqa
|
||||
]
|
||||
assert mgr._build_floating_ips(config) == []
|
||||
|
|
Loading…
Reference in New Issue