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:
parent
3c26ce8ace
commit
c76164c058
@ -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.
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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',
|
||||
|
@ -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))
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user