Allow neutron managed ports to bypass PREROUTING chain

When deployed with k8s, k8s service types like NodePort
or ExternalIP will affect vm traffic on nat table's
PREROUTING chain. This PS try to mitigate the effect
by allowing vm traffic to bypass those rules.

Change-Id: Iae12d9c2f37bc0fca9c3d5e85e46c642263e4a77
Closes-Bug: #1908957
This commit is contained in:
shenjiatong 2020-12-22 09:01:50 +08:00 committed by Brian Haley
parent 21927e7907
commit 08032e9cc6
5 changed files with 226 additions and 62 deletions

View File

@ -155,6 +155,7 @@ class IptablesFirewallDriver(firewall.FirewallDriver):
jump_rule = self._generate_trusted_port_rules(port) jump_rule = self._generate_trusted_port_rules(port)
self._add_rules_to_chain_v4v6( self._add_rules_to_chain_v4v6(
'FORWARD', jump_rule, jump_rule, comment=ic.TRUSTED_ACCEPT) 'FORWARD', jump_rule, jump_rule, comment=ic.TRUSTED_ACCEPT)
self._add_nat_short_ciruit(port)
self.trusted_ports.append(port) self.trusted_ports.append(port)
def remove_trusted_ports(self, port_ids): def remove_trusted_ports(self, port_ids):
@ -163,8 +164,15 @@ class IptablesFirewallDriver(firewall.FirewallDriver):
jump_rule = self._generate_trusted_port_rules(port) jump_rule = self._generate_trusted_port_rules(port)
self._remove_rule_from_chain_v4v6( self._remove_rule_from_chain_v4v6(
'FORWARD', jump_rule, jump_rule) 'FORWARD', jump_rule, jump_rule)
self._remove_nat_short_ciruit(port)
self.trusted_ports.remove(port) self.trusted_ports.remove(port)
def _generate_nat_shortcircuit_port_rules(self, port):
rt = '-m physdev --%%s %s -j ACCEPT' % (
self._get_device_name(port))
return [rt % (self.IPTABLES_DIRECTION[constants.INGRESS_DIRECTION]),
rt % (self.IPTABLES_DIRECTION[constants.EGRESS_DIRECTION])]
def _generate_trusted_port_rules(self, port): def _generate_trusted_port_rules(self, port):
rt = '-m physdev --%%s %s --physdev-is-bridged -j ACCEPT' % ( rt = '-m physdev --%%s %s --physdev-is-bridged -j ACCEPT' % (
self._get_device_name(port)) self._get_device_name(port))
@ -248,12 +256,13 @@ class IptablesFirewallDriver(firewall.FirewallDriver):
def _remove_rule_port_sec(self, port, direction): def _remove_rule_port_sec(self, port, direction):
self._update_port_sec_rules(port, direction, add=False) self._update_port_sec_rules(port, direction, add=False)
def _remove_rule_from_chain_v4v6(self, chain_name, ipv4_rules, ipv6_rules): def _remove_rule_from_chain_v4v6(self, chain_name, ipv4_rules, ipv6_rules,
table='filter'):
for rule in ipv4_rules: for rule in ipv4_rules:
self.iptables.ipv4['filter'].remove_rule(chain_name, rule) self.iptables.ipv4[table].remove_rule(chain_name, rule)
for rule in ipv6_rules: for rule in ipv6_rules:
self.iptables.ipv6['filter'].remove_rule(chain_name, rule) self.iptables.ipv6[table].remove_rule(chain_name, rule)
def _setup_chains(self): def _setup_chains(self):
"""Setup ingress and egress chain for a port.""" """Setup ingress and egress chain for a port."""
@ -268,6 +277,7 @@ class IptablesFirewallDriver(firewall.FirewallDriver):
for pname in sorted(ports): for pname in sorted(ports):
port = ports[pname] port = ports[pname]
self._add_conntrack_jump(port) self._add_conntrack_jump(port)
self._add_nat_short_ciruit(port)
self._setup_chain(port, constants.INGRESS_DIRECTION) self._setup_chain(port, constants.INGRESS_DIRECTION)
self._setup_chain(port, constants.EGRESS_DIRECTION) self._setup_chain(port, constants.EGRESS_DIRECTION)
self.iptables.ipv4['filter'].add_rule(SG_CHAIN, '-j ACCEPT') self.iptables.ipv4['filter'].add_rule(SG_CHAIN, '-j ACCEPT')
@ -276,6 +286,7 @@ class IptablesFirewallDriver(firewall.FirewallDriver):
for port in unfiltered_ports.values(): for port in unfiltered_ports.values():
self._add_accept_rule_port_sec(port, constants.INGRESS_DIRECTION) self._add_accept_rule_port_sec(port, constants.INGRESS_DIRECTION)
self._add_accept_rule_port_sec(port, constants.EGRESS_DIRECTION) self._add_accept_rule_port_sec(port, constants.EGRESS_DIRECTION)
self._add_nat_short_ciruit(port)
def _remove_chains(self): def _remove_chains(self):
"""Remove ingress and egress chain for a port.""" """Remove ingress and egress chain for a port."""
@ -289,9 +300,11 @@ class IptablesFirewallDriver(firewall.FirewallDriver):
self._remove_chain(port, constants.EGRESS_DIRECTION) self._remove_chain(port, constants.EGRESS_DIRECTION)
self._remove_chain(port, SPOOF_FILTER) self._remove_chain(port, SPOOF_FILTER)
self._remove_conntrack_jump(port) self._remove_conntrack_jump(port)
self._remove_nat_short_ciruit(port)
for port in unfiltered_ports.values(): for port in unfiltered_ports.values():
self._remove_rule_port_sec(port, constants.INGRESS_DIRECTION) self._remove_rule_port_sec(port, constants.INGRESS_DIRECTION)
self._remove_rule_port_sec(port, constants.EGRESS_DIRECTION) self._remove_rule_port_sec(port, constants.EGRESS_DIRECTION)
self._remove_nat_short_ciruit(port)
self._remove_chain_by_name_v4v6(SG_CHAIN) self._remove_chain_by_name_v4v6(SG_CHAIN)
def _setup_chain(self, port, DIRECTION): def _setup_chain(self, port, DIRECTION):
@ -319,14 +332,14 @@ class IptablesFirewallDriver(firewall.FirewallDriver):
self.iptables.ipv6['filter'].remove_chain(chain_name) self.iptables.ipv6['filter'].remove_chain(chain_name)
def _add_rules_to_chain_v4v6(self, chain_name, ipv4_rules, ipv6_rules, def _add_rules_to_chain_v4v6(self, chain_name, ipv4_rules, ipv6_rules,
top=False, comment=None): top=False, comment=None, table='filter'):
for rule in ipv4_rules: for rule in ipv4_rules:
self.iptables.ipv4['filter'].add_rule(chain_name, rule, self.iptables.ipv4[table].add_rule(chain_name, rule,
top=top, comment=comment) top=top, comment=comment)
for rule in ipv6_rules: for rule in ipv6_rules:
self.iptables.ipv6['filter'].add_rule(chain_name, rule, self.iptables.ipv6[table].add_rule(chain_name, rule,
top=top, comment=comment) top=top, comment=comment)
def _get_device_name(self, port): def _get_device_name(self, port):
if not isinstance(port, dict): if not isinstance(port, dict):
@ -465,6 +478,16 @@ class IptablesFirewallDriver(firewall.FirewallDriver):
self.iptables.ipv4['raw'].remove_rule(chain, rule) self.iptables.ipv4['raw'].remove_rule(chain, rule)
self.iptables.ipv6['raw'].remove_rule(chain, rule) self.iptables.ipv6['raw'].remove_rule(chain, rule)
def _add_nat_short_ciruit(self, port):
jump_rule = self._generate_nat_shortcircuit_port_rules(port)
self._add_rules_to_chain_v4v6('PREROUTING', jump_rule, jump_rule,
comment=ic.TRUSTED_ACCEPT, table='nat')
def _remove_nat_short_ciruit(self, port):
jump_rule = self._generate_nat_shortcircuit_port_rules(port)
self._remove_rule_from_chain_v4v6('PREROUTING', jump_rule,
jump_rule, table='nat')
def _split_sgr_by_ethertype(self, security_group_rules): def _split_sgr_by_ethertype(self, security_group_rules):
ipv4_sg_rules = [] ipv4_sg_rules = []
ipv6_sg_rules = [] ipv6_sg_rules = []

View File

@ -335,11 +335,16 @@ class IptablesManager(object):
self.ipv4.update({'raw': IptablesTable(binary_name=self.wrap_name)}) self.ipv4.update({'raw': IptablesTable(binary_name=self.wrap_name)})
self.ipv6.update({'raw': IptablesTable(binary_name=self.wrap_name)}) self.ipv6.update({'raw': IptablesTable(binary_name=self.wrap_name)})
self.ipv4.update({'nat': IptablesTable(binary_name=self.wrap_name)})
self.ipv6.update({'nat': IptablesTable(binary_name=self.wrap_name)})
# Wrap the built-in chains # Wrap the built-in chains
builtin_chains = {4: {'filter': ['INPUT', 'OUTPUT', 'FORWARD']}, builtin_chains = {4: {'filter': ['INPUT', 'OUTPUT', 'FORWARD']},
6: {'filter': ['INPUT', 'OUTPUT', 'FORWARD']}} 6: {'filter': ['INPUT', 'OUTPUT', 'FORWARD']}}
builtin_chains[4].update({'raw': ['PREROUTING', 'OUTPUT']}) builtin_chains[4].update({'raw': ['PREROUTING', 'OUTPUT']})
builtin_chains[6].update({'raw': ['PREROUTING', 'OUTPUT']}) builtin_chains[6].update({'raw': ['PREROUTING', 'OUTPUT']})
builtin_chains[4].update({'nat': ['PREROUTING']})
builtin_chains[6].update({'nat': ['PREROUTING']})
self._configure_builtin_chains(builtin_chains) self._configure_builtin_chains(builtin_chains)
if not state_less: if not state_less:

View File

@ -84,10 +84,12 @@ class BaseIptablesFirewallTestCase(base.BaseTestCase):
self.v4filter_inst = mock.Mock() self.v4filter_inst = mock.Mock()
self.v6filter_inst = mock.Mock() self.v6filter_inst = mock.Mock()
self.iptables_inst.ipv4 = {'filter': self.v4filter_inst, self.iptables_inst.ipv4 = {'filter': self.v4filter_inst,
'raw': self.v4filter_inst 'raw': self.v4filter_inst,
'nat': self.v4filter_inst
} }
self.iptables_inst.ipv6 = {'filter': self.v6filter_inst, self.iptables_inst.ipv6 = {'filter': self.v6filter_inst,
'raw': self.v6filter_inst 'raw': self.v6filter_inst,
'nat': self.v6filter_inst
} }
iptables_cls.return_value = self.iptables_inst iptables_cls.return_value = self.iptables_inst
@ -141,6 +143,14 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):
comment=None), comment=None),
mock.call.add_rule('PREROUTING', mock.ANY, # zone set mock.call.add_rule('PREROUTING', mock.ANY, # zone set
comment=None), comment=None),
mock.call.add_rule('PREROUTING',
'-m physdev --physdev-out tapfake_dev '
'-j ACCEPT',
top=False, comment=ic.TRUSTED_ACCEPT),
mock.call.add_rule('PREROUTING',
'-m physdev --physdev-in tapfake_dev '
'-j ACCEPT',
top=False, comment=ic.TRUSTED_ACCEPT),
mock.call.add_chain('ifake_dev'), mock.call.add_chain('ifake_dev'),
mock.call.add_rule('FORWARD', mock.call.add_rule('FORWARD',
'-m physdev --physdev-out tapfake_dev ' '-m physdev --physdev-out tapfake_dev '
@ -1172,6 +1182,16 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):
'-m physdev --physdev-in tapfake_dev ' '-m physdev --physdev-in tapfake_dev '
'--physdev-is-bridged -j ACCEPT', '--physdev-is-bridged -j ACCEPT',
top=False, comment=ic.TRUSTED_ACCEPT)) top=False, comment=ic.TRUSTED_ACCEPT))
calls.append(
mock.call.add_rule('PREROUTING',
'-m physdev --physdev-out tapfake_dev '
'-j ACCEPT',
top=False, comment=ic.TRUSTED_ACCEPT))
calls.append(
mock.call.add_rule('PREROUTING',
'-m physdev --physdev-in tapfake_dev '
'-j ACCEPT',
top=False, comment=ic.TRUSTED_ACCEPT))
self.firewall.process_trusted_ports([port['id']]) self.firewall.process_trusted_ports([port['id']])
@ -1262,6 +1282,16 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):
comment=None), comment=None),
mock.call.add_rule('PREROUTING', mock.ANY, # zone set mock.call.add_rule('PREROUTING', mock.ANY, # zone set
comment=None), comment=None),
mock.call.add_rule('PREROUTING',
"-m physdev --physdev-out tapfake_dev "
"-j ACCEPT",
comment=ic.TRUSTED_ACCEPT,
top=False),
mock.call.add_rule('PREROUTING',
"-m physdev --physdev-in tapfake_dev "
"-j ACCEPT",
comment=ic.TRUSTED_ACCEPT,
top=False),
mock.call.add_chain('ifake_dev'), mock.call.add_chain('ifake_dev'),
mock.call.add_rule('FORWARD', mock.call.add_rule('FORWARD',
'-m physdev --physdev-out tapfake_dev ' '-m physdev --physdev-out tapfake_dev '
@ -1615,6 +1645,16 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):
comment=None), # zone set comment=None), # zone set
mock.call.add_rule('PREROUTING', mock.ANY, mock.call.add_rule('PREROUTING', mock.ANY,
comment=None), # zone set comment=None), # zone set
mock.call.add_rule(
'PREROUTING',
'-m physdev --physdev-out tapfake_dev '
'-j ACCEPT',
comment=ic.TRUSTED_ACCEPT, top=False),
mock.call.add_rule(
'PREROUTING',
'-m physdev --physdev-in tapfake_dev '
'-j ACCEPT',
comment=ic.TRUSTED_ACCEPT, top=False),
mock.call.add_chain('ifake_dev'), mock.call.add_chain('ifake_dev'),
mock.call.add_rule( mock.call.add_rule(
'FORWARD', 'FORWARD',
@ -1696,6 +1736,14 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):
mock.call.remove_rule('PREROUTING', mock.ANY), # zone set mock.call.remove_rule('PREROUTING', mock.ANY), # zone set
mock.call.remove_rule('PREROUTING', mock.ANY), # zone set mock.call.remove_rule('PREROUTING', mock.ANY), # zone set
mock.call.remove_rule('PREROUTING', mock.ANY), # zone set mock.call.remove_rule('PREROUTING', mock.ANY), # zone set
mock.call.remove_rule(
'PREROUTING',
'-m physdev --physdev-out tapfake_dev '
'-j ACCEPT'),
mock.call.remove_rule(
'PREROUTING',
'-m physdev --physdev-in tapfake_dev '
'-j ACCEPT'),
mock.call.remove_chain('sg-chain'), mock.call.remove_chain('sg-chain'),
mock.call.add_chain('sg-chain'), mock.call.add_chain('sg-chain'),
mock.call.add_rule('PREROUTING', mock.ANY, mock.call.add_rule('PREROUTING', mock.ANY,
@ -1704,6 +1752,16 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):
comment=None), # zone set comment=None), # zone set
mock.call.add_rule('PREROUTING', mock.ANY, mock.call.add_rule('PREROUTING', mock.ANY,
comment=None), # zone set comment=None), # zone set
mock.call.add_rule(
'PREROUTING',
'-m physdev --physdev-out tapfake_dev '
'-j ACCEPT',
comment=ic.TRUSTED_ACCEPT, top=False),
mock.call.add_rule(
'PREROUTING',
'-m physdev --physdev-in tapfake_dev '
'-j ACCEPT',
comment=ic.TRUSTED_ACCEPT, top=False),
mock.call.add_chain('ifake_dev'), mock.call.add_chain('ifake_dev'),
mock.call.add_rule( mock.call.add_rule(
'FORWARD', 'FORWARD',
@ -1786,6 +1844,14 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):
mock.call.remove_rule('PREROUTING', mock.ANY), # zone set mock.call.remove_rule('PREROUTING', mock.ANY), # zone set
mock.call.remove_rule('PREROUTING', mock.ANY), # zone set mock.call.remove_rule('PREROUTING', mock.ANY), # zone set
mock.call.remove_rule('PREROUTING', mock.ANY), # zone set mock.call.remove_rule('PREROUTING', mock.ANY), # zone set
mock.call.remove_rule(
'PREROUTING',
'-m physdev --physdev-out tapfake_dev '
'-j ACCEPT'),
mock.call.remove_rule(
'PREROUTING',
'-m physdev --physdev-in tapfake_dev '
'-j ACCEPT'),
mock.call.remove_chain('sg-chain'), mock.call.remove_chain('sg-chain'),
mock.call.add_chain('sg-chain')] mock.call.add_chain('sg-chain')]
@ -1926,6 +1992,14 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):
comment=None), comment=None),
mock.call.add_rule('PREROUTING', mock.ANY, # zone set mock.call.add_rule('PREROUTING', mock.ANY, # zone set
comment=None), comment=None),
mock.call.add_rule('PREROUTING',
'-m physdev --physdev-out tapfake_dev '
'-j ACCEPT',
top=False, comment=ic.TRUSTED_ACCEPT),
mock.call.add_rule('PREROUTING',
'-m physdev --physdev-in tapfake_dev '
'-j ACCEPT',
top=False, comment=ic.TRUSTED_ACCEPT),
mock.call.add_chain('ifake_dev'), mock.call.add_chain('ifake_dev'),
mock.call.add_rule('FORWARD', mock.call.add_rule('FORWARD',
'-m physdev --physdev-out tapfake_dev ' '-m physdev --physdev-out tapfake_dev '
@ -2019,6 +2093,14 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):
comment=None), comment=None),
mock.call.add_rule('PREROUTING', mock.ANY, # zone set mock.call.add_rule('PREROUTING', mock.ANY, # zone set
comment=None), comment=None),
mock.call.add_rule('PREROUTING',
'-m physdev --physdev-out '
'tapfake_dev -j ACCEPT',
comment=ic.TRUSTED_ACCEPT, top=False),
mock.call.add_rule('PREROUTING',
'-m physdev --physdev-in '
'tapfake_dev -j ACCEPT',
comment=ic.TRUSTED_ACCEPT, top=False),
mock.call.add_chain('ifake_dev'), mock.call.add_chain('ifake_dev'),
mock.call.add_rule('FORWARD', mock.call.add_rule('FORWARD',
'-m physdev --physdev-out tapfake_dev ' '-m physdev --physdev-out tapfake_dev '

View File

@ -1358,8 +1358,8 @@ class IptablesManagerStateLessTestCase(base.BaseTestCase):
cfg.CONF.set_override('comment_iptables_rules', False, 'AGENT') cfg.CONF.set_override('comment_iptables_rules', False, 'AGENT')
self.iptables = (iptables_manager.IptablesManager(state_less=True)) self.iptables = (iptables_manager.IptablesManager(state_less=True))
def test_nat_not_found(self): def test_nat_found(self):
self.assertNotIn('nat', self.iptables.ipv4) self.assertIn('nat', self.iptables.ipv4)
def test_mangle_not_found(self): def test_mangle_not_found(self):
self.assertNotIn('mangle', self.iptables.ipv4) self.assertNotIn('mangle', self.iptables.ipv4)
@ -1368,7 +1368,7 @@ class IptablesManagerStateLessTestCase(base.BaseTestCase):
iptables = iptables_manager.IptablesManager(state_less=True) iptables = iptables_manager.IptablesManager(state_less=True)
iptables.initialize_mangle_table() iptables.initialize_mangle_table()
self.assertIn('mangle', iptables.ipv4) self.assertIn('mangle', iptables.ipv4)
self.assertNotIn('nat', iptables.ipv4) self.assertIn('nat', iptables.ipv4)
def test_initialize_nat_table(self): def test_initialize_nat_table(self):
iptables = iptables_manager.IptablesManager(state_less=True) iptables = iptables_manager.IptablesManager(state_less=True)
@ -1384,8 +1384,8 @@ class IptablesManagerNoNatTestCase(base.BaseTestCase):
cfg.CONF.set_override('comment_iptables_rules', False, 'AGENT') cfg.CONF.set_override('comment_iptables_rules', False, 'AGENT')
self.iptables = (iptables_manager.IptablesManager(nat=False)) self.iptables = (iptables_manager.IptablesManager(nat=False))
def test_nat_not_found(self): def test_nat_found(self):
self.assertNotIn('nat', self.iptables.ipv4) self.assertIn('nat', self.iptables.ipv4)
def test_mangle_found(self): def test_mangle_found(self):
self.assertIn('mangle', self.iptables.ipv4) self.assertIn('mangle', self.iptables.ipv4)

View File

@ -1601,6 +1601,54 @@ COMMIT
# Completed by iptables_manager # Completed by iptables_manager
""" % IPTABLES_ARG """ % IPTABLES_ARG
IPTABLES_NAT_EMPTY = """# Generated by iptables_manager
*nat
:PREROUTING - [0:0]
:%(bn)s-PREROUTING - [0:0]
-I PREROUTING 1 -j %(bn)s-PREROUTING
COMMIT
# Completed by iptables_manager
""" % IPTABLES_ARG
IPTABLES_NAT_1 = """# Generated by iptables_manager
*nat
:PREROUTING - [0:0]
:%(bn)s-PREROUTING - [0:0]
-I PREROUTING 1 -j %(bn)s-PREROUTING
-I %(bn)s-PREROUTING 1 -m physdev --physdev-out tap_port1 -j ACCEPT
-I %(bn)s-PREROUTING 2 -m physdev --physdev-in tap_port1 -j ACCEPT
COMMIT
# Completed by iptables_manager
""" % IPTABLES_ARG
IPTABLES_NAT_2 = """# Generated by iptables_manager
*nat
:PREROUTING - [0:0]
:%(bn)s-PREROUTING - [0:0]
-I PREROUTING 1 -j %(bn)s-PREROUTING
-I %(bn)s-PREROUTING 1 -m physdev --physdev-out tap_port1 -j ACCEPT
-I %(bn)s-PREROUTING 2 -m physdev --physdev-in tap_port1 -j ACCEPT
-I %(bn)s-PREROUTING 3 -m physdev --physdev-out tap_port2 -j ACCEPT
-I %(bn)s-PREROUTING 4 -m physdev --physdev-in tap_port2 -j ACCEPT
COMMIT
# Completed by iptables_manager
""" % IPTABLES_ARG
IPTABLES_NAT_3 = """# Generated by iptables_manager
*nat
:PREROUTING - [0:0]
:%(bn)s-PREROUTING - [0:0]
-I PREROUTING 1 -j %(bn)s-PREROUTING
-I %(bn)s-PREROUTING 1 -m physdev --physdev-out tap_port3 -j ACCEPT
-I %(bn)s-PREROUTING 2 -m physdev --physdev-in tap_port3 -j ACCEPT
-I %(bn)s-PREROUTING 3 -m physdev --physdev-out tap_port1 -j ACCEPT
-I %(bn)s-PREROUTING 4 -m physdev --physdev-in tap_port1 -j ACCEPT
-I %(bn)s-PREROUTING 5 -m physdev --physdev-out tap_port2 -j ACCEPT
-I %(bn)s-PREROUTING 6 -m physdev --physdev-in tap_port2 -j ACCEPT
COMMIT
# Completed by iptables_manager
""" % IPTABLES_ARG
CHAINS_EMPTY = 'FORWARD|INPUT|OUTPUT|local|sg-chain|sg-fallback' CHAINS_EMPTY = 'FORWARD|INPUT|OUTPUT|local|sg-chain|sg-fallback'
CHAINS_1 = CHAINS_EMPTY + '|i_port1|o_port1|s_port1' CHAINS_1 = CHAINS_EMPTY + '|i_port1|o_port1|s_port1'
CHAINS_2 = CHAINS_1 + '|i_port2|o_port2|s_port2' CHAINS_2 = CHAINS_1 + '|i_port2|o_port2|s_port2'
@ -2925,21 +2973,27 @@ class TestSecurityGroupAgentWithIptables(base.BaseTestCase):
self.assertThat(kwargs['process_input'], self.assertThat(kwargs['process_input'],
matchers.MatchesRegex(expected_regex)) matchers.MatchesRegex(expected_regex))
def _replay_iptables(self, v4_filter, v6_filter, raw): def _replay_iptables(self, v4_filter, v6_filter, raw, nat):
self._register_mock_call( self._register_mock_call(
['iptables-save'], run_as_root=True, privsep_exec=True, ['iptables-save'], run_as_root=True, privsep_exec=True,
return_value='') return_value='')
self._register_mock_call( self._register_mock_call(
['iptables-restore', '-n'], ['iptables-restore', '-n'],
process_input=self._regex(v4_filter + raw), run_as_root=True, process_input=self._regex(v4_filter + nat + raw),
privsep_exec=True, log_fail_as_error=False, return_value='') run_as_root=True,
privsep_exec=True,
log_fail_as_error=False,
return_value='')
self._register_mock_call( self._register_mock_call(
['ip6tables-save'], run_as_root=True, privsep_exec=True, ['ip6tables-save'], run_as_root=True, privsep_exec=True,
return_value='') return_value='')
self._register_mock_call( self._register_mock_call(
['ip6tables-restore', '-n'], ['ip6tables-restore', '-n'],
process_input=self._regex(v6_filter + raw), run_as_root=True, process_input=self._regex(v6_filter + nat + raw),
privsep_exec=True, log_fail_as_error=False, return_value='') run_as_root=True,
privsep_exec=True,
log_fail_as_error=False,
return_value='')
def test_prepare_remove_port(self): def test_prepare_remove_port(self):
self.ipconntrack._device_zone_map = {} self.ipconntrack._device_zone_map = {}
@ -2947,9 +3001,9 @@ class TestSecurityGroupAgentWithIptables(base.BaseTestCase):
'devices': self.devices1, 'security_groups': {}, 'devices': self.devices1, 'security_groups': {},
'sg_member_ips': {}} 'sg_member_ips': {}}
self._replay_iptables(IPTABLES_FILTER_1, IPTABLES_FILTER_V6_1, self._replay_iptables(IPTABLES_FILTER_1, IPTABLES_FILTER_V6_1,
IPTABLES_RAW_BRIDGE_NET_1) IPTABLES_RAW_BRIDGE_NET_1, IPTABLES_NAT_1)
self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY, self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY,
IPTABLES_RAW_DEFAULT) IPTABLES_RAW_DEFAULT, IPTABLES_NAT_EMPTY)
self.agent.prepare_devices_filter(['tap_port1']) self.agent.prepare_devices_filter(['tap_port1'])
self.agent.remove_devices_filter(['tap_port1']) self.agent.remove_devices_filter(['tap_port1'])
@ -2961,17 +3015,17 @@ class TestSecurityGroupAgentWithIptables(base.BaseTestCase):
'devices': self.devices1, 'security_groups': {}, 'devices': self.devices1, 'security_groups': {},
'sg_member_ips': {}} 'sg_member_ips': {}}
self._replay_iptables(IPTABLES_FILTER_1, IPTABLES_FILTER_V6_1, self._replay_iptables(IPTABLES_FILTER_1, IPTABLES_FILTER_V6_1,
IPTABLES_RAW_BRIDGE_NET_1) IPTABLES_RAW_BRIDGE_NET_1, IPTABLES_NAT_1)
self._replay_iptables(IPTABLES_FILTER_1_2, IPTABLES_FILTER_V6_1, self._replay_iptables(IPTABLES_FILTER_1_2, IPTABLES_FILTER_V6_1,
IPTABLES_RAW_BRIDGE_NET_1) IPTABLES_RAW_BRIDGE_NET_1, IPTABLES_NAT_1)
self._replay_iptables(IPTABLES_FILTER_2, IPTABLES_FILTER_V6_2, self._replay_iptables(IPTABLES_FILTER_2, IPTABLES_FILTER_V6_2,
IPTABLES_RAW_BRIDGE_NET_2) IPTABLES_RAW_BRIDGE_NET_2, IPTABLES_NAT_2)
self._replay_iptables(IPTABLES_FILTER_2_2, IPTABLES_FILTER_V6_2, self._replay_iptables(IPTABLES_FILTER_2_2, IPTABLES_FILTER_V6_2,
IPTABLES_RAW_BRIDGE_NET_2) IPTABLES_RAW_BRIDGE_NET_2, IPTABLES_NAT_2)
self._replay_iptables(IPTABLES_FILTER_1, IPTABLES_FILTER_V6_1, self._replay_iptables(IPTABLES_FILTER_1, IPTABLES_FILTER_V6_1,
IPTABLES_RAW_BRIDGE_NET_1) IPTABLES_RAW_BRIDGE_NET_1, IPTABLES_NAT_1)
self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY, self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY,
IPTABLES_RAW_DEFAULT) IPTABLES_RAW_DEFAULT, IPTABLES_NAT_EMPTY)
self.agent.prepare_devices_filter(['tap_port1']) self.agent.prepare_devices_filter(['tap_port1'])
self.rpc.security_group_info_for_devices.return_value = { self.rpc.security_group_info_for_devices.return_value = {
@ -2994,10 +3048,10 @@ class TestSecurityGroupAgentWithIptables(base.BaseTestCase):
'sg_member_ips': {}} 'sg_member_ips': {}}
self._replay_iptables( self._replay_iptables(
IPTABLES_FILTER_2_TRUSTED, IPTABLES_FILTER_V6_2_TRUSTED, IPTABLES_FILTER_2_TRUSTED, IPTABLES_FILTER_V6_2_TRUSTED,
IPTABLES_RAW_BRIDGE_NET_2) IPTABLES_RAW_BRIDGE_NET_2, IPTABLES_NAT_3)
self._replay_iptables( self._replay_iptables(
IPTABLES_FILTER_2_3_TRUSTED, IPTABLES_FILTER_V6_2_TRUSTED, IPTABLES_FILTER_2_3_TRUSTED, IPTABLES_FILTER_V6_2_TRUSTED,
IPTABLES_RAW_BRIDGE_NET_2) IPTABLES_RAW_BRIDGE_NET_2, IPTABLES_NAT_3)
self.agent.prepare_devices_filter(['tap_port1', 'tap_port3']) self.agent.prepare_devices_filter(['tap_port1', 'tap_port3'])
self.rpc.security_group_info_for_devices.return_value = { self.rpc.security_group_info_for_devices.return_value = {
@ -3082,9 +3136,9 @@ class TestSecurityGroupAgentEnhancedRpcWithIptables(
self.ipconntrack._device_zone_map = {} self.ipconntrack._device_zone_map = {}
self.sg_info.return_value = self.devices_info1 self.sg_info.return_value = self.devices_info1
self._replay_iptables(IPTABLES_FILTER_1, IPTABLES_FILTER_V6_1, self._replay_iptables(IPTABLES_FILTER_1, IPTABLES_FILTER_V6_1,
IPTABLES_RAW_BRIDGE_NET_1) IPTABLES_RAW_BRIDGE_NET_1, IPTABLES_NAT_1)
self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY, self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY,
IPTABLES_RAW_DEFAULT) IPTABLES_RAW_DEFAULT, IPTABLES_NAT_EMPTY)
self.agent.prepare_devices_filter(['tap_port1']) self.agent.prepare_devices_filter(['tap_port1'])
self.agent.remove_devices_filter(['tap_port1']) self.agent.remove_devices_filter(['tap_port1'])
@ -3094,17 +3148,17 @@ class TestSecurityGroupAgentEnhancedRpcWithIptables(
def test_security_group_member_updated(self): def test_security_group_member_updated(self):
self.sg_info.return_value = self.devices_info1 self.sg_info.return_value = self.devices_info1
self._replay_iptables(IPTABLES_FILTER_1, IPTABLES_FILTER_V6_1, self._replay_iptables(IPTABLES_FILTER_1, IPTABLES_FILTER_V6_1,
IPTABLES_RAW_BRIDGE_NET_1) IPTABLES_RAW_BRIDGE_NET_1, IPTABLES_NAT_1)
self._replay_iptables(IPTABLES_FILTER_1_2, IPTABLES_FILTER_V6_1, self._replay_iptables(IPTABLES_FILTER_1_2, IPTABLES_FILTER_V6_1,
IPTABLES_RAW_BRIDGE_NET_1) IPTABLES_RAW_BRIDGE_NET_1, IPTABLES_NAT_1)
self._replay_iptables(IPTABLES_FILTER_2, IPTABLES_FILTER_V6_2, self._replay_iptables(IPTABLES_FILTER_2, IPTABLES_FILTER_V6_2,
IPTABLES_RAW_BRIDGE_NET_2) IPTABLES_RAW_BRIDGE_NET_2, IPTABLES_NAT_2)
self._replay_iptables(IPTABLES_FILTER_2_2, IPTABLES_FILTER_V6_2, self._replay_iptables(IPTABLES_FILTER_2_2, IPTABLES_FILTER_V6_2,
IPTABLES_RAW_BRIDGE_NET_2) IPTABLES_RAW_BRIDGE_NET_2, IPTABLES_NAT_2)
self._replay_iptables(IPTABLES_FILTER_1, IPTABLES_FILTER_V6_1, self._replay_iptables(IPTABLES_FILTER_1, IPTABLES_FILTER_V6_1,
IPTABLES_RAW_BRIDGE_NET_1) IPTABLES_RAW_BRIDGE_NET_1, IPTABLES_NAT_1)
self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY, self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY,
IPTABLES_RAW_DEFAULT) IPTABLES_RAW_DEFAULT, IPTABLES_NAT_EMPTY)
self.agent.prepare_devices_filter(['tap_port1']) self.agent.prepare_devices_filter(['tap_port1'])
self.sg_info.return_value = self.devices_info2 self.sg_info.return_value = self.devices_info2
@ -3123,10 +3177,10 @@ class TestSecurityGroupAgentEnhancedRpcWithIptables(
self.sg_info.return_value = self.devices_info2 self.sg_info.return_value = self.devices_info2
self._replay_iptables( self._replay_iptables(
IPTABLES_FILTER_2_TRUSTED, IPTABLES_FILTER_V6_2_TRUSTED, IPTABLES_FILTER_2_TRUSTED, IPTABLES_FILTER_V6_2_TRUSTED,
IPTABLES_RAW_BRIDGE_NET_2) IPTABLES_RAW_BRIDGE_NET_2, IPTABLES_NAT_3)
self._replay_iptables( self._replay_iptables(
IPTABLES_FILTER_2_3_TRUSTED, IPTABLES_FILTER_V6_2_TRUSTED, IPTABLES_FILTER_2_3_TRUSTED, IPTABLES_FILTER_V6_2_TRUSTED,
IPTABLES_RAW_BRIDGE_NET_2) IPTABLES_RAW_BRIDGE_NET_2, IPTABLES_NAT_3)
self.agent.prepare_devices_filter(['tap_port1', 'tap_port3']) self.agent.prepare_devices_filter(['tap_port1', 'tap_port3'])
self.sg_info.return_value = self.devices_info3 self.sg_info.return_value = self.devices_info3
@ -3151,9 +3205,9 @@ class TestSecurityGroupAgentEnhancedIpsetWithIptables(
self.ipconntrack._device_zone_map = {} self.ipconntrack._device_zone_map = {}
self.sg_info.return_value = self.devices_info1 self.sg_info.return_value = self.devices_info1
self._replay_iptables(IPSET_FILTER_1, IPTABLES_FILTER_V6_1, self._replay_iptables(IPSET_FILTER_1, IPTABLES_FILTER_V6_1,
IPTABLES_RAW_BRIDGE_NET_1) IPTABLES_RAW_BRIDGE_NET_1, IPTABLES_NAT_1)
self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY, self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY,
IPTABLES_RAW_DEFAULT) IPTABLES_RAW_DEFAULT, IPTABLES_NAT_EMPTY)
self.agent.prepare_devices_filter(['tap_port1']) self.agent.prepare_devices_filter(['tap_port1'])
self.agent.remove_devices_filter(['tap_port1']) self.agent.remove_devices_filter(['tap_port1'])
@ -3165,17 +3219,17 @@ class TestSecurityGroupAgentEnhancedIpsetWithIptables(
self.ipset._get_new_set_ips = mock.Mock(return_value=['10.0.0.3']) self.ipset._get_new_set_ips = mock.Mock(return_value=['10.0.0.3'])
self.ipset._get_deleted_set_ips = mock.Mock(return_value=[]) self.ipset._get_deleted_set_ips = mock.Mock(return_value=[])
self._replay_iptables(IPSET_FILTER_1, IPTABLES_FILTER_V6_1, self._replay_iptables(IPSET_FILTER_1, IPTABLES_FILTER_V6_1,
IPTABLES_RAW_BRIDGE_NET_1) IPTABLES_RAW_BRIDGE_NET_1, IPTABLES_NAT_1)
self._replay_iptables(IPSET_FILTER_1, IPTABLES_FILTER_V6_1, self._replay_iptables(IPSET_FILTER_1, IPTABLES_FILTER_V6_1,
IPTABLES_RAW_BRIDGE_NET_1) IPTABLES_RAW_BRIDGE_NET_1, IPTABLES_NAT_1)
self._replay_iptables(IPSET_FILTER_2, IPTABLES_FILTER_V6_2, self._replay_iptables(IPSET_FILTER_2, IPTABLES_FILTER_V6_2,
IPTABLES_RAW_BRIDGE_NET_2) IPTABLES_RAW_BRIDGE_NET_2, IPTABLES_NAT_2)
self._replay_iptables(IPSET_FILTER_2, IPTABLES_FILTER_V6_2, self._replay_iptables(IPSET_FILTER_2, IPTABLES_FILTER_V6_2,
IPTABLES_RAW_BRIDGE_NET_2) IPTABLES_RAW_BRIDGE_NET_2, IPTABLES_NAT_2)
self._replay_iptables(IPSET_FILTER_1, IPTABLES_FILTER_V6_1, self._replay_iptables(IPSET_FILTER_1, IPTABLES_FILTER_V6_1,
IPTABLES_RAW_BRIDGE_NET_1) IPTABLES_RAW_BRIDGE_NET_1, IPTABLES_NAT_1)
self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY, self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY,
IPTABLES_RAW_DEFAULT) IPTABLES_RAW_DEFAULT, IPTABLES_NAT_EMPTY)
self.agent.prepare_devices_filter(['tap_port1']) self.agent.prepare_devices_filter(['tap_port1'])
self.sg_info.return_value = self.devices_info2 self.sg_info.return_value = self.devices_info2
@ -3196,10 +3250,10 @@ class TestSecurityGroupAgentEnhancedIpsetWithIptables(
self.sg_info.return_value = self.devices_info2 self.sg_info.return_value = self.devices_info2
self._replay_iptables( self._replay_iptables(
IPSET_FILTER_2_TRUSTED, IPTABLES_FILTER_V6_2_TRUSTED, IPSET_FILTER_2_TRUSTED, IPTABLES_FILTER_V6_2_TRUSTED,
IPTABLES_RAW_BRIDGE_NET_2) IPTABLES_RAW_BRIDGE_NET_2, IPTABLES_NAT_3)
self._replay_iptables( self._replay_iptables(
IPSET_FILTER_2_3_TRUSTED, IPTABLES_FILTER_V6_2_TRUSTED, IPSET_FILTER_2_3_TRUSTED, IPTABLES_FILTER_V6_2_TRUSTED,
IPTABLES_RAW_BRIDGE_NET_2) IPTABLES_RAW_BRIDGE_NET_2, IPTABLES_NAT_3)
self.agent.prepare_devices_filter(['tap_port1', 'tap_port3']) self.agent.prepare_devices_filter(['tap_port1', 'tap_port3'])
self.sg_info.return_value = self.devices_info3 self.sg_info.return_value = self.devices_info3
@ -3281,9 +3335,9 @@ class TestSecurityGroupAgentWithOVSIptables(
'devices': self.devices1, 'security_groups': {}, 'devices': self.devices1, 'security_groups': {},
'sg_member_ips': {}} 'sg_member_ips': {}}
self._replay_iptables(IPTABLES_FILTER_1, IPTABLES_FILTER_V6_1, self._replay_iptables(IPTABLES_FILTER_1, IPTABLES_FILTER_V6_1,
IPTABLES_RAW_DEVICE_1) IPTABLES_RAW_DEVICE_1, IPTABLES_NAT_1)
self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY, self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY,
IPTABLES_RAW_DEFAULT) IPTABLES_RAW_DEFAULT, IPTABLES_NAT_EMPTY)
self.agent.prepare_devices_filter(['tap_port1']) self.agent.prepare_devices_filter(['tap_port1'])
self.agent.remove_devices_filter(['tap_port1']) self.agent.remove_devices_filter(['tap_port1'])
@ -3297,9 +3351,9 @@ class TestSecurityGroupAgentWithOVSIptables(
'devices': self.devices1, 'security_groups': {}, 'devices': self.devices1, 'security_groups': {},
'sg_member_ips': {}} 'sg_member_ips': {}}
self._replay_iptables(IPTABLES_FILTER_1, IPTABLES_FILTER_V6_1, self._replay_iptables(IPTABLES_FILTER_1, IPTABLES_FILTER_V6_1,
IPTABLES_RAW_DEFAULT) IPTABLES_RAW_DEFAULT, IPTABLES_NAT_1)
self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY, self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY,
IPTABLES_RAW_DEFAULT) IPTABLES_RAW_DEFAULT, IPTABLES_NAT_EMPTY)
self.agent.prepare_devices_filter(['tap_port1']) self.agent.prepare_devices_filter(['tap_port1'])
self.agent.remove_devices_filter(['tap_port1']) self.agent.remove_devices_filter(['tap_port1'])
@ -3312,17 +3366,17 @@ class TestSecurityGroupAgentWithOVSIptables(
'devices': self.devices1, 'security_groups': {}, 'devices': self.devices1, 'security_groups': {},
'sg_member_ips': {}} 'sg_member_ips': {}}
self._replay_iptables(IPTABLES_FILTER_1, IPTABLES_FILTER_V6_1, self._replay_iptables(IPTABLES_FILTER_1, IPTABLES_FILTER_V6_1,
IPTABLES_RAW_DEVICE_1) IPTABLES_RAW_DEVICE_1, IPTABLES_NAT_1)
self._replay_iptables(IPTABLES_FILTER_1_2, IPTABLES_FILTER_V6_1, self._replay_iptables(IPTABLES_FILTER_1_2, IPTABLES_FILTER_V6_1,
IPTABLES_RAW_DEVICE_1) IPTABLES_RAW_DEVICE_1, IPTABLES_NAT_1)
self._replay_iptables(IPTABLES_FILTER_2, IPTABLES_FILTER_V6_2, self._replay_iptables(IPTABLES_FILTER_2, IPTABLES_FILTER_V6_2,
IPTABLES_RAW_DEVICE_2) IPTABLES_RAW_DEVICE_2, IPTABLES_NAT_2)
self._replay_iptables(IPTABLES_FILTER_2_2, IPTABLES_FILTER_V6_2, self._replay_iptables(IPTABLES_FILTER_2_2, IPTABLES_FILTER_V6_2,
IPTABLES_RAW_DEVICE_2) IPTABLES_RAW_DEVICE_2, IPTABLES_NAT_2)
self._replay_iptables(IPTABLES_FILTER_1, IPTABLES_FILTER_V6_1, self._replay_iptables(IPTABLES_FILTER_1, IPTABLES_FILTER_V6_1,
IPTABLES_RAW_DEVICE_1) IPTABLES_RAW_DEVICE_1, IPTABLES_NAT_1)
self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY, self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY,
IPTABLES_RAW_DEFAULT) IPTABLES_RAW_DEFAULT, IPTABLES_NAT_EMPTY)
self.agent.prepare_devices_filter(['tap_port1']) self.agent.prepare_devices_filter(['tap_port1'])
self.rpc.security_group_info_for_devices.return_value = { self.rpc.security_group_info_for_devices.return_value = {
@ -3346,10 +3400,10 @@ class TestSecurityGroupAgentWithOVSIptables(
'sg_member_ips': {}} 'sg_member_ips': {}}
self._replay_iptables( self._replay_iptables(
IPTABLES_FILTER_2_TRUSTED, IPTABLES_FILTER_V6_2_TRUSTED, IPTABLES_FILTER_2_TRUSTED, IPTABLES_FILTER_V6_2_TRUSTED,
IPTABLES_RAW_DEVICE_2) IPTABLES_RAW_DEVICE_2, IPTABLES_NAT_3)
self._replay_iptables( self._replay_iptables(
IPTABLES_FILTER_2_3_TRUSTED, IPTABLES_FILTER_V6_2_TRUSTED, IPTABLES_FILTER_2_3_TRUSTED, IPTABLES_FILTER_V6_2_TRUSTED,
IPTABLES_RAW_DEVICE_2) IPTABLES_RAW_DEVICE_2, IPTABLES_NAT_3)
self.agent.prepare_devices_filter(['tap_port1', 'tap_port3']) self.agent.prepare_devices_filter(['tap_port1', 'tap_port3'])
self.rpc.security_group_info_for_devices.return_value = { self.rpc.security_group_info_for_devices.return_value = {