Move conntrack zones to IPTablesFirewall

The regular IPTablesFirewall needs zones to support safely
clearly conntrack entries.

In order to support the single bridge use case, the conntrack
manager had to be refactored slightly to allow zones to be
either unique to ports or unique to networks.

Since all ports in a network share a bridge in the IPTablesDriver
use case, a zone per port cannot be used since there is no way
to distinguish which zone traffic should be checked against when
traffic enters the bridge from outside the system.

A zone per network is adequate for the single bridge per network
solution since it implicitly does not suffer from the double-bridge
cross in a single network that led to per port usage in OVS.[1]

This had to adjust the functional firewall tests to use the correct
bridge name now that it's relevant in the non hybrid IPTables case.

1. Ibe9e49653b2a280ea72cb95c2da64cd94c7739da

Closes-Bug: #1668958
Closes-Bug: #1657260
Change-Id: Ie88237d3fe4807b712a7ec61eb932748c38952cc
This commit is contained in:
Kevin Benton 2017-03-03 11:18:28 -08:00
parent 3c26ce8ace
commit c76164c058
7 changed files with 236 additions and 108 deletions

View File

@ -29,14 +29,13 @@ MAX_CONNTRACK_ZONES = 65535
@lockutils.synchronized('conntrack')
def get_conntrack(get_rules_for_table_func, filtered_ports, unfiltered_ports,
execute=None, namespace=None):
execute=None, namespace=None, zone_per_port=False):
try:
return CONTRACK_MGRS[namespace]
except KeyError:
ipconntrack = IpConntrackManager(get_rules_for_table_func,
filtered_ports, unfiltered_ports,
execute, namespace)
execute, namespace, zone_per_port)
CONTRACK_MGRS[namespace] = ipconntrack
return CONTRACK_MGRS[namespace]
@ -45,12 +44,14 @@ class IpConntrackManager(object):
"""Smart wrapper for ip conntrack."""
def __init__(self, get_rules_for_table_func, filtered_ports,
unfiltered_ports, execute=None, namespace=None):
unfiltered_ports, execute=None, namespace=None,
zone_per_port=False):
self.get_rules_for_table_func = get_rules_for_table_func
self.execute = execute or linux_utils.execute
self.namespace = namespace
self.filtered_ports = filtered_ports
self.unfiltered_ports = unfiltered_ports
self.zone_per_port = zone_per_port # zone per port vs per network
self._populate_initial_zone_map()
@staticmethod
@ -74,8 +75,7 @@ class IpConntrackManager(object):
cmd = self._generate_conntrack_cmd_by_rule(rule, self.namespace)
ethertype = rule.get('ethertype')
for device_info in device_info_list:
zone_id = self._device_zone_map.get(
self._port_key(device_info['device']), None)
zone_id = self.get_device_zone(device_info, create=False)
if not zone_id:
LOG.debug("No zone for device %(dev)s. Will not try to "
"clear conntrack state. Zone map: %(zm)s",
@ -139,26 +139,30 @@ class IpConntrackManager(object):
self._device_zone_map[short_port_id] = int(match.group('zone'))
LOG.debug("Populated conntrack zone map: %s", self._device_zone_map)
@staticmethod
def _port_key(port_id):
# we have to key the device_zone_map based on the fragment of the port
def _device_key(self, port):
# we have to key the device_zone_map based on the fragment of the
# UUID that shows up in the interface name. This is because the initial
# map is populated strictly based on interface names that we don't know
# the full UUID of.
return port_id[:(n_const.LINUX_DEV_LEN -
n_const.LINUX_DEV_PREFIX_LEN)]
if self.zone_per_port:
identifier = port['device'][n_const.LINUX_DEV_PREFIX_LEN:]
else:
identifier = port['network_id']
return identifier[:(n_const.LINUX_DEV_LEN -
n_const.LINUX_DEV_PREFIX_LEN)]
def get_device_zone(self, port_id):
short_port_id = self._port_key(port_id)
def get_device_zone(self, port, create=True):
device_key = self._device_key(port)
try:
return self._device_zone_map[short_port_id]
return self._device_zone_map[device_key]
except KeyError:
return self._generate_device_zone(short_port_id)
if create:
return self._generate_device_zone(device_key)
def _free_zones_from_removed_ports(self):
"""Clears any entries from the zone map of removed ports."""
existing_ports = [
self._port_key(port['device'])
self._device_key(port)
for port in (list(self.filtered_ports.values()) +
list(self.unfiltered_ports.values()))
]
@ -166,7 +170,7 @@ class IpConntrackManager(object):
for dev in removed:
self._device_zone_map.pop(dev, None)
def _generate_device_zone(self, short_port_id):
def _generate_device_zone(self, short_device_id):
"""Generates a unique conntrack zone for the passed in ID."""
try:
zone = self._find_open_zone()
@ -175,10 +179,10 @@ class IpConntrackManager(object):
self._free_zones_from_removed_ports()
zone = self._find_open_zone()
self._device_zone_map[short_port_id] = zone
LOG.debug("Assigned CT zone %(z)s to port %(dev)s.",
{'z': zone, 'dev': short_port_id})
return self._device_zone_map[short_port_id]
self._device_zone_map[short_device_id] = zone
LOG.debug("Assigned CT zone %(z)s to device %(dev)s.",
{'z': zone, 'dev': short_device_id})
return self._device_zone_map[short_device_id]
def _find_open_zone(self):
# call set to dedup because old ports may be mapped to the same zone.

View File

@ -57,6 +57,7 @@ class IptablesFirewallDriver(firewall.FirewallDriver):
"""Driver which enforces security groups through iptables rules."""
IPTABLES_DIRECTION = {firewall.INGRESS_DIRECTION: 'physdev-out',
firewall.EGRESS_DIRECTION: 'physdev-in'}
CONNTRACK_ZONE_PER_PORT = False
def __init__(self, namespace=None):
self.iptables = iptables_manager.IptablesManager(state_less=True,
@ -70,7 +71,8 @@ class IptablesFirewallDriver(firewall.FirewallDriver):
self.unfiltered_ports = {}
self.ipconntrack = ip_conntrack.get_conntrack(
self.iptables.get_rules_for_table, self.filtered_ports,
self.unfiltered_ports, namespace=namespace)
self.unfiltered_ports, namespace=namespace,
zone_per_port=self.CONNTRACK_ZONE_PER_PORT)
self._add_fallback_chain_v4v6()
self._defer_apply = False
self._pre_defer_filtered_ports = None
@ -204,6 +206,7 @@ class IptablesFirewallDriver(firewall.FirewallDriver):
# agent restarts and don't cause unnecessary rule differences
for pname in sorted(ports):
port = ports[pname]
self._add_conntrack_jump(port)
self._setup_chain(port, firewall.INGRESS_DIRECTION)
self._setup_chain(port, firewall.EGRESS_DIRECTION)
self.iptables.ipv4['filter'].add_rule(SG_CHAIN, '-j ACCEPT')
@ -224,6 +227,7 @@ class IptablesFirewallDriver(firewall.FirewallDriver):
self._remove_chain(port, firewall.INGRESS_DIRECTION)
self._remove_chain(port, firewall.EGRESS_DIRECTION)
self._remove_chain(port, SPOOF_FILTER)
self._remove_conntrack_jump(port)
for port in unfiltered_ports.values():
self._remove_rule_port_sec(port, firewall.INGRESS_DIRECTION)
self._remove_rule_port_sec(port, firewall.EGRESS_DIRECTION)
@ -325,6 +329,43 @@ class IptablesFirewallDriver(firewall.FirewallDriver):
self._add_rules_to_chain_v4v6('INPUT', jump_rule, jump_rule,
comment=ic.INPUT_TO_SG)
def _get_br_device_name(self, port):
return ('brq' + port['network_id'])[:n_const.LINUX_DEV_LEN]
def _get_jump_rules(self, port):
zone = self.ipconntrack.get_device_zone(port)
br_dev = self._get_br_device_name(port)
port_dev = self._get_device_name(port)
# match by interface for bridge input
match_interface = '-i %s'
match_physdev = '-m physdev --physdev-in %s'
# comment to prevent duplicate warnings for different devices using
# same bridge. truncate start to remove prefixes
comment = '-m comment --comment "Set zone for %s"' % port['device'][4:]
rules = []
for dev, match in ((br_dev, match_physdev), (br_dev, match_interface),
(port_dev, match_physdev)):
match = match % dev
rule = '%s %s -j CT --zone %s' % (match, comment, zone)
rules.append(rule)
return rules
def _add_conntrack_jump(self, port):
for jump_rule in self._get_jump_rules(port):
self._add_raw_rule('PREROUTING', jump_rule)
def _remove_conntrack_jump(self, port):
for jump_rule in self._get_jump_rules(port):
self._remove_raw_rule('PREROUTING', jump_rule)
def _add_raw_rule(self, chain, rule, comment=None):
self.iptables.ipv4['raw'].add_rule(chain, rule, comment=comment)
self.iptables.ipv6['raw'].add_rule(chain, rule, comment=comment)
def _remove_raw_rule(self, chain, rule):
self.iptables.ipv4['raw'].remove_rule(chain, rule)
self.iptables.ipv6['raw'].remove_rule(chain, rule)
def _split_sgr_by_ethertype(self, security_group_rules):
ipv4_sg_rules = []
ipv6_sg_rules = []
@ -828,6 +869,7 @@ class IptablesFirewallDriver(firewall.FirewallDriver):
class OVSHybridIptablesFirewallDriver(IptablesFirewallDriver):
OVS_HYBRID_PLUG_REQUIRED = True
CONNTRACK_ZONE_PER_PORT = True
def _port_chain_name(self, port, direction):
return iptables_manager.get_chain_name(
@ -838,37 +880,3 @@ class OVSHybridIptablesFirewallDriver(IptablesFirewallDriver):
def _get_device_name(self, port):
return get_hybrid_port_name(port['device'])
def _get_jump_rule(self, port, direction):
if direction == firewall.INGRESS_DIRECTION:
device = self._get_br_device_name(port)
else:
device = self._get_device_name(port)
jump_rule = '-m physdev --physdev-in %s -j CT --zone %s' % (
device, self.ipconntrack.get_device_zone(
port['device']))
return jump_rule
def _add_raw_chain_rules(self, port, direction):
jump_rule = self._get_jump_rule(port, direction)
self.iptables.ipv4['raw'].add_rule('PREROUTING', jump_rule)
self.iptables.ipv6['raw'].add_rule('PREROUTING', jump_rule)
def _remove_raw_chain_rules(self, port, direction):
jump_rule = self._get_jump_rule(port, direction)
self.iptables.ipv4['raw'].remove_rule('PREROUTING', jump_rule)
self.iptables.ipv6['raw'].remove_rule('PREROUTING', jump_rule)
def _add_chain(self, port, direction):
super(OVSHybridIptablesFirewallDriver, self)._add_chain(port,
direction)
if direction in [firewall.INGRESS_DIRECTION,
firewall.EGRESS_DIRECTION]:
self._add_raw_chain_rules(port, direction)
def _remove_chain(self, port, direction):
super(OVSHybridIptablesFirewallDriver, self)._remove_chain(port,
direction)
if direction in [firewall.INGRESS_DIRECTION,
firewall.EGRESS_DIRECTION]:
self._remove_raw_chain_rules(port, direction)

View File

@ -513,9 +513,18 @@ class LinuxBridgeConnectionTester(ConnectionTester):
"""
def __init__(self, *args, **kwargs):
self.bridge_name = kwargs.pop('bridge_name', None)
super(LinuxBridgeConnectionTester, self).__init__(*args, **kwargs)
def _setUp(self):
super(LinuxBridgeConnectionTester, self)._setUp()
self.bridge = self.useFixture(net_helpers.LinuxBridgeFixture()).bridge
bridge_args = {}
if self.bridge_name:
bridge_args = {'prefix': self.bridge_name,
'prefix_is_full_name': True}
self.bridge = self.useFixture(
net_helpers.LinuxBridgeFixture(**bridge_args)).bridge
machines = self.useFixture(
machine_fixtures.PeerMachines(
self.bridge, self.ip_cidr)).machines

View File

@ -24,12 +24,14 @@ import netaddr
from neutron_lib import constants
from oslo_config import cfg
from oslo_log import log as logging
from oslo_utils import uuidutils
import testscenarios
from neutron.agent import firewall
from neutron.agent.linux import iptables_firewall
from neutron.agent.linux import openvswitch_firewall
from neutron.cmd.sanity import checks
from neutron.common import constants as n_const
from neutron.conf.agent import securitygroups_rpc as security_config
from neutron.tests.common import conn_testers
from neutron.tests.common import helpers
@ -95,6 +97,7 @@ class BaseFirewallTestCase(base.BaseSudoTestCase):
def setUp(self):
security_config.register_securitygroups_opts()
self.net_id = uuidutils.generate_uuid()
super(BaseFirewallTestCase, self).setUp()
self.tester, self.firewall = getattr(self, self.initialize)()
if self.firewall_name == "openvswitch":
@ -103,7 +106,8 @@ class BaseFirewallTestCase(base.BaseSudoTestCase):
self.tester.vm_port_id,
[self.tester.vm_ip_address],
self.tester.vm_mac_address,
[self.FAKE_SECURITY_GROUP_ID])
[self.FAKE_SECURITY_GROUP_ID],
self.net_id)
# FIXME(jlibosva): We should consider to call prepare_port_filter with
# deferred bridge depending on its performance
self.firewall.prepare_port_filter(self.src_port_desc)
@ -111,8 +115,10 @@ class BaseFirewallTestCase(base.BaseSudoTestCase):
def initialize_iptables(self):
cfg.CONF.set_override('enable_ipset', self.enable_ipset,
'SECURITYGROUP')
br_name = ('brq' + self.net_id)[:n_const.LINUX_DEV_LEN]
tester = self.useFixture(
conn_testers.LinuxBridgeConnectionTester(self.ip_cidr))
conn_testers.LinuxBridgeConnectionTester(self.ip_cidr,
bridge_name=br_name))
firewall_drv = iptables_firewall.IptablesFirewallDriver(
namespace=tester.bridge_namespace)
return tester, firewall_drv
@ -140,7 +146,8 @@ class BaseFirewallTestCase(base.BaseSudoTestCase):
self.tester.set_peer_tag(vlan)
@staticmethod
def _create_port_description(port_id, ip_addresses, mac_address, sg_ids):
def _create_port_description(port_id, ip_addresses, mac_address, sg_ids,
net_id):
return {'admin_state_up': True,
'device': port_id,
'device_owner': DEVICE_OWNER_COMPUTE,
@ -148,7 +155,8 @@ class BaseFirewallTestCase(base.BaseSudoTestCase):
'mac_address': mac_address,
'port_security_enabled': True,
'security_groups': sg_ids,
'status': 'ACTIVE'}
'status': 'ACTIVE',
'network_id': net_id}
def _apply_security_group_rules(self, sg_id, sg_rules):
with self.firewall.defer_apply():
@ -539,7 +547,8 @@ class FirewallTestCase(BaseFirewallTestCase):
self.tester.peer_port_id,
[self.tester.peer_ip_address],
self.tester.peer_mac_address,
[remote_sg_id])
[remote_sg_id],
self.net_id)
vm_sg_members = {'IPv4': [self.tester.peer_ip_address]}
peer_sg_rules = [{'ethertype': 'IPv4', 'direction': 'egress',

View File

@ -27,14 +27,15 @@ class IPConntrackTestCase(base.BaseTestCase):
self.unfiltered_port = {}
self.mgr = ip_conntrack.IpConntrackManager(
self._get_rule_for_table, self.filtered_port,
self.unfiltered_port, self.execute)
self.unfiltered_port, self.execute,
zone_per_port=True)
def _get_rule_for_table(self, table):
return ['test --physdev-in tapdevice -j CT --zone 100']
def test_delete_conntrack_state_dedupes(self):
rule = {'ethertype': 'IPv4', 'direction': 'ingress'}
dev_info = {'device': 'device', 'fixed_ips': ['1.2.3.4']}
dev_info = {'device': 'tapdevice', 'fixed_ips': ['1.2.3.4']}
dev_info_list = [dev_info for _ in range(10)]
self.mgr._delete_conntrack_state(dev_info_list, rule)
self.assertEqual(1, len(self.execute.mock_calls))

View File

@ -126,6 +126,12 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):
'sg-fallback', '-j DROP',
comment=ic.UNMATCH_DROP),
mock.call.add_chain('sg-chain'),
mock.call.add_rule('PREROUTING', mock.ANY, # zone set
comment=None),
mock.call.add_rule('PREROUTING', mock.ANY, # zone set
comment=None),
mock.call.add_rule('PREROUTING', mock.ANY, # zone set
comment=None),
mock.call.add_chain('ifake_dev'),
mock.call.add_rule('FORWARD',
'-m physdev --physdev-out tapfake_dev '
@ -1005,6 +1011,12 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):
'-j DROP',
comment=ic.UNMATCH_DROP),
mock.call.add_chain('sg-chain'),
mock.call.add_rule('PREROUTING', mock.ANY, # zone set
comment=None),
mock.call.add_rule('PREROUTING', mock.ANY, # zone set
comment=None),
mock.call.add_rule('PREROUTING', mock.ANY, # zone set
comment=None),
mock.call.add_chain('ifake_dev'),
mock.call.add_rule('FORWARD',
'-m physdev --physdev-out tapfake_dev '
@ -1127,7 +1139,7 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):
'protocol': protocol}]
with mock.patch.dict(self.firewall.ipconntrack._device_zone_map,
{port['device']: ct_zone}):
{port['network_id']: ct_zone}):
self.firewall.filter_defer_apply_on()
self.firewall.sg_rules['fake_sg_id'] = []
self.firewall.filter_defer_apply_off()
@ -1212,7 +1224,7 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):
self.firewall.filtered_ports[port['device']] = port
self.firewall.updated_sg_members = set(['tapfake_dev'])
with mock.patch.dict(self.firewall.ipconntrack._device_zone_map,
{port['device']: ct_zone}):
{port['network_id']: ct_zone}):
self.firewall.filter_defer_apply_on()
new_port = copy.deepcopy(port)
new_port['security_groups'] = ['fake_sg_id2']
@ -1274,7 +1286,7 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):
members_after_delete = {'IPv6': ['fe80::3']}
with mock.patch.dict(self.firewall.ipconntrack._device_zone_map,
{port['device']: ct_zone}):
{port['network_id']: ct_zone}):
# add ['10.0.0.2', '10.0.0.3'] or ['fe80::2', 'fe80::3']
self.firewall.security_group_updated('sg_member', ['fake_sg_id2'])
self.firewall.update_security_group_members(
@ -1331,6 +1343,12 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):
'-j DROP',
comment=ic.UNMATCH_DROP),
mock.call.add_chain('sg-chain'),
mock.call.add_rule('PREROUTING', mock.ANY,
comment=None), # zone set
mock.call.add_rule('PREROUTING', mock.ANY,
comment=None), # zone set
mock.call.add_rule('PREROUTING', mock.ANY,
comment=None), # zone set
mock.call.add_chain('ifake_dev'),
mock.call.add_rule(
'FORWARD',
@ -1408,8 +1426,17 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):
mock.call.remove_chain('ifake_dev'),
mock.call.remove_chain('ofake_dev'),
mock.call.remove_chain('sfake_dev'),
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_chain('sg-chain'),
mock.call.add_chain('sg-chain'),
mock.call.add_rule('PREROUTING', mock.ANY,
comment=None), # zone set
mock.call.add_rule('PREROUTING', mock.ANY,
comment=None), # zone set
mock.call.add_rule('PREROUTING', mock.ANY,
comment=None), # zone set
mock.call.add_chain('ifake_dev'),
mock.call.add_rule(
'FORWARD',
@ -1487,6 +1514,9 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):
mock.call.remove_chain('ifake_dev'),
mock.call.remove_chain('ofake_dev'),
mock.call.remove_chain('sfake_dev'),
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_chain('sg-chain'),
mock.call.add_chain('sg-chain')]
@ -1510,11 +1540,8 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):
new_port['fixed_ips'] = ['10.0.0.2', 'fe80::2']
self.firewall.sg_members['fake_sg_id2'] = {'IPv4': ['10.0.0.2'],
'IPv6': ['fe80::2']}
if ct_zone:
self.firewall.ipconntrack._device_zone_map['tapfake_dev'] = ct_zone
else:
self.firewall.ipconntrack._device_zone_map.pop('tapfake_dev', None)
mock.patch.object(self.firewall.ipconntrack, 'get_device_zone',
return_value=ct_zone).start()
self.firewall.remove_port_filter(port)
if not ct_zone:
self.assertFalse(self.utils_exec.called)
@ -1564,8 +1591,10 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):
def test_mock_chain_applies(self):
chain_applies = self._mock_chain_applies()
port_prepare = {'device': 'd1', 'mac_address': 'prepare'}
port_update = {'device': 'd1', 'mac_address': 'update'}
port_prepare = {'device': 'd1', 'mac_address': 'prepare',
'network_id': 'fake_net'}
port_update = {'device': 'd1', 'mac_address': 'update',
'network_id': 'fake_net'}
self.firewall.prepare_port_filter(port_prepare)
self.firewall.update_port_filter(port_update)
self.firewall.remove_port_filter(port_update)
@ -1619,6 +1648,12 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):
'sg-fallback', '-j DROP',
comment=ic.UNMATCH_DROP),
mock.call.add_chain('sg-chain'),
mock.call.add_rule('PREROUTING', mock.ANY, # zone set
comment=None),
mock.call.add_rule('PREROUTING', mock.ANY, # zone set
comment=None),
mock.call.add_rule('PREROUTING', mock.ANY, # zone set
comment=None),
mock.call.add_chain('ifake_dev'),
mock.call.add_rule('FORWARD',
'-m physdev --physdev-out tapfake_dev '
@ -1703,6 +1738,12 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):
'sg-fallback', '-j DROP',
comment=ic.UNMATCH_DROP),
mock.call.add_chain('sg-chain'),
mock.call.add_rule('PREROUTING', mock.ANY, # zone set
comment=None),
mock.call.add_rule('PREROUTING', mock.ANY, # zone set
comment=None),
mock.call.add_rule('PREROUTING', mock.ANY, # zone set
comment=None),
mock.call.add_chain('ifake_dev'),
mock.call.add_rule('FORWARD',
'-m physdev --physdev-out tapfake_dev '
@ -2088,9 +2129,9 @@ class OVSHybridIptablesFirewallTestCase(BaseIptablesFirewallTestCase):
self.firewall.ipconntrack._device_zone_map)
def test_get_device_zone(self):
dev = {'device': 'tap1234', 'network_id': '12345678901234567'}
# initial data has 1, 2, and 9 in use.
self.assertEqual(10,
self.firewall.ipconntrack.get_device_zone('12345678901234567'))
self.assertEqual(10, self.firewall.ipconntrack.get_device_zone(dev))
# should have been truncated to 11 chars
self._dev_zone_map.update({'12345678901': 10})
self.assertEqual(self._dev_zone_map,

View File

@ -27,6 +27,7 @@ from testtools import matchers
import webob.exc
from neutron.agent import firewall as firewall_base
from neutron.agent.linux import ip_conntrack
from neutron.agent.linux import iptables_manager
from neutron.agent import securitygroups_rpc as sg_rpc
from neutron.api.rpc.handlers import securitygroups_rpc
@ -1729,6 +1730,48 @@ COMMIT
# Completed by iptables_manager
""" % IPTABLES_ARG
IPTABLES_RAW_BRIDGE_NET_1 = """# Generated by iptables_manager
*raw
:OUTPUT - [0:0]
:PREROUTING - [0:0]
:%(bn)s-OUTPUT - [0:0]
:%(bn)s-PREROUTING - [0:0]
-I OUTPUT 1 -j %(bn)s-OUTPUT
-I PREROUTING 1 -j %(bn)s-PREROUTING
-I %(bn)s-PREROUTING 1 -m physdev --physdev-in brqfakenet1 \
-m comment --comment "Set zone for port1" -j CT --zone 1
-I %(bn)s-PREROUTING 2 -i brqfakenet1 \
-m comment --comment "Set zone for port1" -j CT --zone 1
-I %(bn)s-PREROUTING 3 -m physdev --physdev-in tap_port1 \
-m comment --comment "Set zone for port1" -j CT --zone 1
COMMIT
# Completed by iptables_manager
""" % IPTABLES_ARG
IPTABLES_RAW_BRIDGE_NET_2 = """# Generated by iptables_manager
*raw
:OUTPUT - [0:0]
:PREROUTING - [0:0]
:%(bn)s-OUTPUT - [0:0]
:%(bn)s-PREROUTING - [0:0]
-I OUTPUT 1 -j %(bn)s-OUTPUT
-I PREROUTING 1 -j %(bn)s-PREROUTING
-I %(bn)s-PREROUTING 1 -m physdev --physdev-in brqfakenet1 \
-m comment --comment "Set zone for port1" -j CT --zone 1
-I %(bn)s-PREROUTING 2 -i brqfakenet1 \
-m comment --comment "Set zone for port1" -j CT --zone 1
-I %(bn)s-PREROUTING 3 -m physdev --physdev-in tap_port1 \
-m comment --comment "Set zone for port1" -j CT --zone 1
-I %(bn)s-PREROUTING 4 -m physdev --physdev-in brqfakenet2 \
-m comment --comment "Set zone for port2" -j CT --zone 2
-I %(bn)s-PREROUTING 5 -i brqfakenet2 \
-m comment --comment "Set zone for port2" -j CT --zone 2
-I %(bn)s-PREROUTING 6 -m physdev --physdev-in tap_port2 \
-m comment --comment "Set zone for port2" -j CT --zone 2
COMMIT
# Completed by iptables_manager
""" % IPTABLES_ARG
IPTABLES_RAW_DEVICE_1 = """# Generated by iptables_manager
*raw
:OUTPUT - [0:0]
@ -1737,8 +1780,12 @@ IPTABLES_RAW_DEVICE_1 = """# Generated by iptables_manager
:%(bn)s-PREROUTING - [0:0]
-I OUTPUT 1 -j %(bn)s-OUTPUT
-I PREROUTING 1 -j %(bn)s-PREROUTING
-I %(bn)s-PREROUTING 1 -m physdev --physdev-in qvbtap_port1 -j CT --zone 1
-I %(bn)s-PREROUTING 2 -m physdev --physdev-in tap_port1 -j CT --zone 1
-I %(bn)s-PREROUTING 1 -m physdev --physdev-in qvbtap_port1 \
-m comment --comment "Set zone for %(port1)s" -j CT --zone 1
-I %(bn)s-PREROUTING 2 -i qvbtap_port1 \
-m comment --comment "Set zone for %(port1)s" -j CT --zone 1
-I %(bn)s-PREROUTING 3 -m physdev --physdev-in tap_port1 \
-m comment --comment "Set zone for %(port1)s" -j CT --zone 1
COMMIT
# Completed by iptables_manager
""" % IPTABLES_ARG
@ -1752,11 +1799,17 @@ IPTABLES_RAW_DEVICE_2 = """# Generated by iptables_manager
-I OUTPUT 1 -j %(bn)s-OUTPUT
-I PREROUTING 1 -j %(bn)s-PREROUTING
-I %(bn)s-PREROUTING 1 -m physdev --physdev-in qvbtap_%(port1)s \
-j CT --zone 1
-I %(bn)s-PREROUTING 2 -m physdev --physdev-in tap_%(port1)s -j CT --zone 1
-I %(bn)s-PREROUTING 3 -m physdev --physdev-in qvbtap_%(port2)s \
-j CT --zone 2
-I %(bn)s-PREROUTING 4 -m physdev --physdev-in tap_%(port2)s -j CT --zone 2
-m comment --comment "Set zone for %(port1)s" -j CT --zone 1
-I %(bn)s-PREROUTING 2 -i qvbtap_%(port1)s \
-m comment --comment "Set zone for %(port1)s" -j CT --zone 1
-I %(bn)s-PREROUTING 3 -m physdev --physdev-in tap_%(port1)s \
-m comment --comment "Set zone for %(port1)s" -j CT --zone 1
-I %(bn)s-PREROUTING 4 -m physdev --physdev-in qvbtap_%(port2)s \
-m comment --comment "Set zone for %(port2)s" -j CT --zone 2
-I %(bn)s-PREROUTING 5 -i qvbtap_%(port2)s \
-m comment --comment "Set zone for %(port2)s" -j CT --zone 2
-I %(bn)s-PREROUTING 6 -m physdev --physdev-in tap_%(port2)s \
-m comment --comment "Set zone for %(port2)s" -j CT --zone 2
COMMIT
# Completed by iptables_manager
""" % IPTABLES_ARG
@ -2592,6 +2645,9 @@ class TestSecurityGroupAgentWithIptables(base.BaseTestCase):
PHYSDEV_EGRESS = 'physdev-in'
def setUp(self, defer_refresh_firewall=False, test_rpc_v1_1=True):
clear_mgrs = lambda: ip_conntrack.CONTRACK_MGRS.clear()
self.addCleanup(clear_mgrs)
clear_mgrs() # clear before start in case other tests didn't clean up
super(TestSecurityGroupAgentWithIptables, self).setUp()
set_firewall_driver(self.FIREWALL_DRIVER)
cfg.CONF.set_override('enable_ipset', False, group='SECURITYGROUP')
@ -2695,7 +2751,7 @@ class TestSecurityGroupAgentWithIptables(base.BaseTestCase):
def _device(self, device, ip, mac_address, rule):
return {'device': device,
'network_id': 'fakenet',
'network_id': 'fakenet%s' % device[-1:],
'fixed_ips': [ip],
'mac_address': mac_address,
'security_groups': ['security_group1'],
@ -2767,7 +2823,7 @@ class TestSecurityGroupAgentWithIptables(base.BaseTestCase):
self.ipconntrack._device_zone_map = {}
self.rpc.security_group_rules_for_devices.return_value = self.devices1
self._replay_iptables(IPTABLES_FILTER_1, IPTABLES_FILTER_V6_1,
IPTABLES_RAW_DEFAULT)
IPTABLES_RAW_BRIDGE_NET_1)
self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY,
IPTABLES_RAW_DEFAULT)
@ -2779,15 +2835,15 @@ class TestSecurityGroupAgentWithIptables(base.BaseTestCase):
def test_security_group_member_updated(self):
self.rpc.security_group_rules_for_devices.return_value = self.devices1
self._replay_iptables(IPTABLES_FILTER_1, IPTABLES_FILTER_V6_1,
IPTABLES_RAW_DEFAULT)
IPTABLES_RAW_BRIDGE_NET_1)
self._replay_iptables(IPTABLES_FILTER_1_2, IPTABLES_FILTER_V6_1,
IPTABLES_RAW_DEFAULT)
IPTABLES_RAW_BRIDGE_NET_1)
self._replay_iptables(IPTABLES_FILTER_2, IPTABLES_FILTER_V6_2,
IPTABLES_RAW_DEFAULT)
IPTABLES_RAW_BRIDGE_NET_2)
self._replay_iptables(IPTABLES_FILTER_2_2, IPTABLES_FILTER_V6_2,
IPTABLES_RAW_DEFAULT)
IPTABLES_RAW_BRIDGE_NET_2)
self._replay_iptables(IPTABLES_FILTER_1, IPTABLES_FILTER_V6_1,
IPTABLES_RAW_DEFAULT)
IPTABLES_RAW_BRIDGE_NET_1)
self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY,
IPTABLES_RAW_DEFAULT)
@ -2805,9 +2861,9 @@ class TestSecurityGroupAgentWithIptables(base.BaseTestCase):
def test_security_group_rule_updated(self):
self.rpc.security_group_rules_for_devices.return_value = self.devices2
self._replay_iptables(IPTABLES_FILTER_2, IPTABLES_FILTER_V6_2,
IPTABLES_RAW_DEFAULT)
IPTABLES_RAW_BRIDGE_NET_2)
self._replay_iptables(IPTABLES_FILTER_2_3, IPTABLES_FILTER_V6_2,
IPTABLES_RAW_DEFAULT)
IPTABLES_RAW_BRIDGE_NET_2)
self.agent.prepare_devices_filter(['tap_port1', 'tap_port3'])
self.rpc.security_group_rules_for_devices.return_value = self.devices3
@ -2882,7 +2938,7 @@ class TestSecurityGroupAgentEnhancedRpcWithIptables(
self.ipconntrack._device_zone_map = {}
self.sg_info.return_value = self.devices_info1
self._replay_iptables(IPTABLES_FILTER_1, IPTABLES_FILTER_V6_1,
IPTABLES_RAW_DEFAULT)
IPTABLES_RAW_BRIDGE_NET_1)
self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY,
IPTABLES_RAW_DEFAULT)
@ -2894,15 +2950,15 @@ class TestSecurityGroupAgentEnhancedRpcWithIptables(
def test_security_group_member_updated(self):
self.sg_info.return_value = self.devices_info1
self._replay_iptables(IPTABLES_FILTER_1, IPTABLES_FILTER_V6_1,
IPTABLES_RAW_DEFAULT)
IPTABLES_RAW_BRIDGE_NET_1)
self._replay_iptables(IPTABLES_FILTER_1_2, IPTABLES_FILTER_V6_1,
IPTABLES_RAW_DEFAULT)
IPTABLES_RAW_BRIDGE_NET_1)
self._replay_iptables(IPTABLES_FILTER_2, IPTABLES_FILTER_V6_2,
IPTABLES_RAW_DEFAULT)
IPTABLES_RAW_BRIDGE_NET_2)
self._replay_iptables(IPTABLES_FILTER_2_2, IPTABLES_FILTER_V6_2,
IPTABLES_RAW_DEFAULT)
IPTABLES_RAW_BRIDGE_NET_2)
self._replay_iptables(IPTABLES_FILTER_1, IPTABLES_FILTER_V6_1,
IPTABLES_RAW_DEFAULT)
IPTABLES_RAW_BRIDGE_NET_1)
self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY,
IPTABLES_RAW_DEFAULT)
@ -2922,9 +2978,9 @@ class TestSecurityGroupAgentEnhancedRpcWithIptables(
def test_security_group_rule_updated(self):
self.sg_info.return_value = self.devices_info2
self._replay_iptables(IPTABLES_FILTER_2, IPTABLES_FILTER_V6_2,
IPTABLES_RAW_DEFAULT)
IPTABLES_RAW_BRIDGE_NET_2)
self._replay_iptables(IPTABLES_FILTER_2_3, IPTABLES_FILTER_V6_2,
IPTABLES_RAW_DEFAULT)
IPTABLES_RAW_BRIDGE_NET_2)
self.agent.prepare_devices_filter(['tap_port1', 'tap_port3'])
self.sg_info.return_value = self.devices_info3
@ -2949,7 +3005,7 @@ class TestSecurityGroupAgentEnhancedIpsetWithIptables(
self.ipconntrack._device_zone_map = {}
self.sg_info.return_value = self.devices_info1
self._replay_iptables(IPSET_FILTER_1, IPTABLES_FILTER_V6_1,
IPTABLES_RAW_DEFAULT)
IPTABLES_RAW_BRIDGE_NET_1)
self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY,
IPTABLES_RAW_DEFAULT)
@ -2963,15 +3019,15 @@ class TestSecurityGroupAgentEnhancedIpsetWithIptables(
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._replay_iptables(IPSET_FILTER_1, IPTABLES_FILTER_V6_1,
IPTABLES_RAW_DEFAULT)
IPTABLES_RAW_BRIDGE_NET_1)
self._replay_iptables(IPSET_FILTER_1, IPTABLES_FILTER_V6_1,
IPTABLES_RAW_DEFAULT)
IPTABLES_RAW_BRIDGE_NET_1)
self._replay_iptables(IPSET_FILTER_2, IPTABLES_FILTER_V6_2,
IPTABLES_RAW_DEFAULT)
IPTABLES_RAW_BRIDGE_NET_2)
self._replay_iptables(IPSET_FILTER_2, IPTABLES_FILTER_V6_2,
IPTABLES_RAW_DEFAULT)
IPTABLES_RAW_BRIDGE_NET_2)
self._replay_iptables(IPSET_FILTER_1, IPTABLES_FILTER_V6_1,
IPTABLES_RAW_DEFAULT)
IPTABLES_RAW_BRIDGE_NET_1)
self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY,
IPTABLES_RAW_DEFAULT)
@ -2993,9 +3049,9 @@ class TestSecurityGroupAgentEnhancedIpsetWithIptables(
self.ipset._get_deleted_set_ips = mock.Mock(return_value=[])
self.sg_info.return_value = self.devices_info2
self._replay_iptables(IPSET_FILTER_2, IPTABLES_FILTER_V6_2,
IPTABLES_RAW_DEFAULT)
IPTABLES_RAW_BRIDGE_NET_2)
self._replay_iptables(IPSET_FILTER_2_3, IPTABLES_FILTER_V6_2,
IPTABLES_RAW_DEFAULT)
IPTABLES_RAW_BRIDGE_NET_2)
self.agent.prepare_devices_filter(['tap_port1', 'tap_port3'])
self.sg_info.return_value = self.devices_info3