Use iptables zone to separate different ip_conntrack

ip_conntrack causes security group rule failures when packets share
the same 5-tuple. Use iptables zone option to separate different
conntrack zone. Currently this patch only works for OVS agent.

Co-authored-by: shihanzhang <shihanzhang@huawei.com>

Change-Id: I90b4d2485e3e491f496dfb7bdee03d57f393be35
Partial-Bug: #1359523
This commit is contained in:
yangxurong 2014-08-26 15:15:40 +08:00 committed by shihanzhang
parent 8978516e49
commit bd5373b670
9 changed files with 459 additions and 196 deletions

View File

@ -193,9 +193,17 @@ class IptablesFirewallDriver(firewall.FirewallDriver):
self.iptables.ipv6['filter'].add_rule('sg-fallback', '-j DROP', self.iptables.ipv6['filter'].add_rule('sg-fallback', '-j DROP',
comment=ic.UNMATCH_DROP) comment=ic.UNMATCH_DROP)
def _add_raw_chain(self, chain_name):
self.iptables.ipv4['raw'].add_chain(chain_name)
self.iptables.ipv6['raw'].add_chain(chain_name)
def _add_chain_by_name_v4v6(self, chain_name): def _add_chain_by_name_v4v6(self, chain_name):
self.iptables.ipv6['filter'].add_chain(chain_name)
self.iptables.ipv4['filter'].add_chain(chain_name) self.iptables.ipv4['filter'].add_chain(chain_name)
self.iptables.ipv6['filter'].add_chain(chain_name)
def _remove_raw_chain(self, chain_name):
self.iptables.ipv4['raw'].remove_chain(chain_name)
self.iptables.ipv6['raw'].remove_chain(chain_name)
def _remove_chain_by_name_v4v6(self, chain_name): def _remove_chain_by_name_v4v6(self, chain_name):
self.iptables.ipv4['filter'].remove_chain(chain_name) self.iptables.ipv4['filter'].remove_chain(chain_name)
@ -676,3 +684,39 @@ class OVSHybridIptablesFirewallDriver(IptablesFirewallDriver):
def _get_device_name(self, port): def _get_device_name(self, port):
return (self.OVS_HYBRID_TAP_PREFIX + port['device'])[:LINUX_DEV_LEN] return (self.OVS_HYBRID_TAP_PREFIX + port['device'])[:LINUX_DEV_LEN]
def _get_br_device_name(self, port):
return ('qvb' + port['device'])[:LINUX_DEV_LEN]
def _get_jump_rule(self, port, direction):
if direction == 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, port['zone_id'])
return jump_rule
def _add_raw_chain_rules(self, port, direction):
if port['zone_id']:
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):
if port['zone_id']:
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 [INGRESS_DIRECTION, 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 [INGRESS_DIRECTION, EGRESS_DIRECTION]:
self._remove_raw_chain_rules(port, direction)

View File

@ -326,10 +326,11 @@ class IptablesManager(object):
{'nat': IptablesTable(binary_name=self.wrap_name)}) {'nat': IptablesTable(binary_name=self.wrap_name)})
builtin_chains[4].update({'nat': ['PREROUTING', builtin_chains[4].update({'nat': ['PREROUTING',
'OUTPUT', 'POSTROUTING']}) 'OUTPUT', 'POSTROUTING']})
self.ipv4.update(
{'raw': IptablesTable(binary_name=self.wrap_name)}) self.ipv4.update({'raw': IptablesTable(binary_name=self.wrap_name)})
builtin_chains[4].update({'raw': ['PREROUTING', builtin_chains[4].update({'raw': ['PREROUTING', 'OUTPUT']})
'OUTPUT']}) self.ipv6.update({'raw': IptablesTable(binary_name=self.wrap_name)})
builtin_chains[6].update({'raw': ['PREROUTING', 'OUTPUT']})
for ip_version in builtin_chains: for ip_version in builtin_chains:
if ip_version == 4: if ip_version == 4:

View File

@ -84,10 +84,12 @@ def disable_security_group_extension_by_config(aliases):
class SecurityGroupAgentRpc(object): class SecurityGroupAgentRpc(object):
"""Enables SecurityGroup agent support in agent implementations.""" """Enables SecurityGroup agent support in agent implementations."""
def __init__(self, context, plugin_rpc, defer_refresh_firewall=False): def __init__(self, context, plugin_rpc, local_vlan_map=None,
defer_refresh_firewall=False,):
self.context = context self.context = context
self.plugin_rpc = plugin_rpc self.plugin_rpc = plugin_rpc
self.init_firewall(defer_refresh_firewall) self.init_firewall(defer_refresh_firewall)
self.local_vlan_map = local_vlan_map
def init_firewall(self, defer_refresh_firewall=False): def init_firewall(self, defer_refresh_firewall=False):
firewall_driver = cfg.CONF.SECURITYGROUP.firewall_driver firewall_driver = cfg.CONF.SECURITYGROUP.firewall_driver
@ -108,6 +110,23 @@ class SecurityGroupAgentRpc(object):
self.global_refresh_firewall = False self.global_refresh_firewall = False
self._use_enhanced_rpc = None self._use_enhanced_rpc = None
def set_local_zone(self, device):
"""Set local zone id for device
In order to separate conntrack in different networks, a local zone
id is needed to generate related iptables rules. This routine sets
zone id to device according to the network it belongs to. For OVS
agent, vlan id of each network can be used as zone id.
:param device: dictionary of device information, get network id by
device['network_id'], and set zone id by device['zone_id']
"""
net_id = device['network_id']
zone_id = None
if self.local_vlan_map and net_id in self.local_vlan_map:
zone_id = self.local_vlan_map[net_id].vlan
device['zone_id'] = zone_id
@property @property
def use_enhanced_rpc(self): def use_enhanced_rpc(self):
if self._use_enhanced_rpc is None: if self._use_enhanced_rpc is None:
@ -157,6 +176,7 @@ class SecurityGroupAgentRpc(object):
with self.firewall.defer_apply(): with self.firewall.defer_apply():
for device in devices.values(): for device in devices.values():
self.set_local_zone(device)
self.firewall.prepare_port_filter(device) self.firewall.prepare_port_filter(device)
if self.use_enhanced_rpc: if self.use_enhanced_rpc:
LOG.debug("Update security group information for ports %s", LOG.debug("Update security group information for ports %s",
@ -244,6 +264,7 @@ class SecurityGroupAgentRpc(object):
with self.firewall.defer_apply(): with self.firewall.defer_apply():
for device in devices.values(): for device in devices.values():
LOG.debug("Update port filter for %s", device['device']) LOG.debug("Update port filter for %s", device['device'])
self.set_local_zone(device)
self.firewall.update_port_filter(device) self.firewall.update_port_filter(device)
if self.use_enhanced_rpc: if self.use_enhanced_rpc:
LOG.debug("Update security group information for ports %s", LOG.debug("Update security group information for ports %s",

View File

@ -254,9 +254,14 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin,
# Collect additional bridges to monitor # Collect additional bridges to monitor
self.ancillary_brs = self.setup_ancillary_bridges(integ_br, tun_br) self.ancillary_brs = self.setup_ancillary_bridges(integ_br, tun_br)
# In order to keep existed device's local vlan unchanged,
# restore local vlan mapping at start
self._restore_local_vlan_map()
# Security group agent support # Security group agent support
self.sg_agent = sg_rpc.SecurityGroupAgentRpc(self.context, self.sg_agent = sg_rpc.SecurityGroupAgentRpc(self.context,
self.sg_plugin_rpc, defer_refresh_firewall=True) self.sg_plugin_rpc, self.local_vlan_map,
defer_refresh_firewall=True)
# Initialize iteration counter # Initialize iteration counter
self.iter_num = 0 self.iter_num = 0
@ -283,6 +288,21 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin,
except Exception: except Exception:
LOG.exception(_LE("Failed reporting state!")) LOG.exception(_LE("Failed reporting state!"))
def _restore_local_vlan_map(self):
cur_ports = self.int_br.get_vif_ports()
for port in cur_ports:
local_vlan_map = self.int_br.db_get_val("Port", port.port_name,
"other_config")
local_vlan = self.int_br.db_get_val("Port", port.port_name, "tag")
net_uuid = local_vlan_map.get('net_uuid')
if (net_uuid and net_uuid not in self.local_vlan_map
and local_vlan != DEAD_VLAN_TAG):
self.provision_local_vlan(local_vlan_map['net_uuid'],
local_vlan_map['network_type'],
local_vlan_map['physical_network'],
local_vlan_map['segmentation_id'],
local_vlan)
def setup_rpc(self): def setup_rpc(self):
self.agent_id = 'ovs-agent-%s' % cfg.CONF.host self.agent_id = 'ovs-agent-%s' % cfg.CONF.host
self.topic = topics.AGENT self.topic = topics.AGENT
@ -496,7 +516,7 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin,
LOG.warning(_LW('Action %s not supported'), action) LOG.warning(_LW('Action %s not supported'), action)
def provision_local_vlan(self, net_uuid, network_type, physical_network, def provision_local_vlan(self, net_uuid, network_type, physical_network,
segmentation_id): segmentation_id, local_vlan=None):
'''Provisions a local VLAN. '''Provisions a local VLAN.
:param net_uuid: the uuid of the network associated with this vlan. :param net_uuid: the uuid of the network associated with this vlan.
@ -513,11 +533,15 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin,
if lvm: if lvm:
lvid = lvm.vlan lvid = lvm.vlan
else: else:
if not self.available_local_vlans: if local_vlan in self.available_local_vlans:
LOG.error(_LE("No local VLAN available for net-id=%s"), lvid = local_vlan
net_uuid) self.available_local_vlans.remove(local_vlan)
return else:
lvid = self.available_local_vlans.pop() if not self.available_local_vlans:
LOG.error(_LE("No local VLAN available for net-id=%s"),
net_uuid)
return
lvid = self.available_local_vlans.pop()
self.local_vlan_map[net_uuid] = LocalVLANMapping(lvid, self.local_vlan_map[net_uuid] = LocalVLANMapping(lvid,
network_type, network_type,
physical_network, physical_network,
@ -697,14 +721,43 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin,
self.dvr_agent.bind_port_to_dvr(port, lvm, self.dvr_agent.bind_port_to_dvr(port, lvm,
fixed_ips, fixed_ips,
device_owner) device_owner)
port_other_config = self.int_br.db_get_val("Port", port.port_name,
"other_config")
vlan_mapping = {'net_uuid': net_uuid,
'network_type': network_type,
'physical_network': physical_network,
'segmentation_id': segmentation_id}
port_other_config.update(vlan_mapping)
self.int_br.set_db_attribute("Port", port.port_name, "other_config",
port_other_config)
# Do not bind a port if it's already bound def _bind_devices(self, need_binding_ports):
cur_tag = self.int_br.db_get_val("Port", port.port_name, "tag") for port_detail in need_binding_ports:
if cur_tag != lvm.vlan: lvm = self.local_vlan_map[port_detail['network_id']]
self.int_br.set_db_attribute("Port", port.port_name, "tag", port = port_detail['vif_port']
lvm.vlan) device = port_detail['device']
if port.ofport != -1: # Do not bind a port if it's already bound
self.int_br.delete_flows(in_port=port.ofport) cur_tag = self.int_br.db_get_val("Port", port.port_name, "tag")
if cur_tag != lvm.vlan:
self.int_br.set_db_attribute(
"Port", port.port_name, "tag", lvm.vlan)
if port.ofport != -1:
self.int_br.delete_flows(in_port=port.ofport)
# update plugin about port status
# FIXME(salv-orlando): Failures while updating device status
# must be handled appropriately. Otherwise this might prevent
# neutron server from sending network-vif-* events to the nova
# API server, thus possibly preventing instance spawn.
if port_detail.get('admin_state_up'):
LOG.debug("Setting status for %s to UP", device)
self.plugin_rpc.update_device_up(
self.context, device, self.agent_id, cfg.CONF.host)
else:
LOG.debug("Setting status for %s to DOWN", device)
self.plugin_rpc.update_device_down(
self.context, device, self.agent_id, cfg.CONF.host)
LOG.info(_LI("Configuration for device %s completed."), device)
@staticmethod @staticmethod
def setup_arp_spoofing_protection(bridge, vif, port_details): def setup_arp_spoofing_protection(bridge, vif, port_details):
@ -1150,6 +1203,7 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin,
# an OVS ofport configured, as only these ports were considered # an OVS ofport configured, as only these ports were considered
# for being treated. If that does not happen, it is a potential # for being treated. If that does not happen, it is a potential
# error condition of which operators should be aware # error condition of which operators should be aware
port_needs_binding = True
if not vif_port.ofport: if not vif_port.ofport:
LOG.warn(_LW("VIF port: %s has no ofport configured, " LOG.warn(_LW("VIF port: %s has no ofport configured, "
"and might not be able to transmit"), vif_port.vif_id) "and might not be able to transmit"), vif_port.vif_id)
@ -1160,8 +1214,10 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin,
fixed_ips, device_owner, ovs_restarted) fixed_ips, device_owner, ovs_restarted)
else: else:
self.port_dead(vif_port) self.port_dead(vif_port)
port_needs_binding = False
else: else:
LOG.debug("No VIF port for port %s defined on agent.", port_id) LOG.debug("No VIF port for port %s defined on agent.", port_id)
return port_needs_binding
def _setup_tunnel_port(self, br, port_name, remote_ip, tunnel_type): def _setup_tunnel_port(self, br, port_name, remote_ip, tunnel_type):
ofport = br.add_tunnel_port(port_name, ofport = br.add_tunnel_port(port_name,
@ -1222,6 +1278,7 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin,
def treat_devices_added_or_updated(self, devices, ovs_restarted): def treat_devices_added_or_updated(self, devices, ovs_restarted):
skipped_devices = [] skipped_devices = []
need_binding_devices = []
try: try:
devices_details_list = self.plugin_rpc.get_devices_details_list( devices_details_list = self.plugin_rpc.get_devices_details_list(
self.context, self.context,
@ -1244,37 +1301,26 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin,
if 'port_id' in details: if 'port_id' in details:
LOG.info(_LI("Port %(device)s updated. Details: %(details)s"), LOG.info(_LI("Port %(device)s updated. Details: %(details)s"),
{'device': device, 'details': details}) {'device': device, 'details': details})
self.treat_vif_port(port, details['port_id'], need_binding = self.treat_vif_port(port, details['port_id'],
details['network_id'], details['network_id'],
details['network_type'], details['network_type'],
details['physical_network'], details['physical_network'],
details['segmentation_id'], details['segmentation_id'],
details['admin_state_up'], details['admin_state_up'],
details['fixed_ips'], details['fixed_ips'],
details['device_owner'], details['device_owner'],
ovs_restarted) ovs_restarted)
if self.prevent_arp_spoofing: if self.prevent_arp_spoofing:
self.setup_arp_spoofing_protection(self.int_br, self.setup_arp_spoofing_protection(self.int_br,
port, details) port, details)
# update plugin about port status if need_binding:
# FIXME(salv-orlando): Failures while updating device status details['vif_port'] = port
# must be handled appropriately. Otherwise this might prevent need_binding_devices.append(details)
# neutron server from sending network-vif-* events to the nova
# API server, thus possibly preventing instance spawn.
if details.get('admin_state_up'):
LOG.debug("Setting status for %s to UP", device)
self.plugin_rpc.update_device_up(
self.context, device, self.agent_id, cfg.CONF.host)
else:
LOG.debug("Setting status for %s to DOWN", device)
self.plugin_rpc.update_device_down(
self.context, device, self.agent_id, cfg.CONF.host)
LOG.info(_LI("Configuration for device %s completed."), device)
else: else:
LOG.warn(_LW("Device %s not defined on plugin"), device) LOG.warn(_LW("Device %s not defined on plugin"), device)
if (port and port.ofport != -1): if (port and port.ofport != -1):
self.port_dead(port) self.port_dead(port)
return skipped_devices return skipped_devices, need_binding_devices
def treat_ancillary_devices_added(self, devices): def treat_ancillary_devices_added(self, devices):
try: try:
@ -1344,10 +1390,6 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin,
# sources: the neutron server, and the ovs db monitor process # sources: the neutron server, and the ovs db monitor process
# If there is an exception while processing security groups ports # If there is an exception while processing security groups ports
# will not be wired anyway, and a resync will be triggered # will not be wired anyway, and a resync will be triggered
# TODO(salv-orlando): Optimize avoiding applying filters unnecessarily
# (eg: when there are no IP address changes)
self.sg_agent.setup_port_filters(port_info.get('added', set()),
port_info.get('updated', set()))
# VIF wiring needs to be performed always for 'new' devices. # VIF wiring needs to be performed always for 'new' devices.
# For updated ports, re-wiring is not needed in most cases, but needs # For updated ports, re-wiring is not needed in most cases, but needs
# to be performed anyway when the admin state of a device is changed. # to be performed anyway when the admin state of a device is changed.
@ -1358,8 +1400,9 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin,
if devices_added_updated: if devices_added_updated:
start = time.time() start = time.time()
try: try:
skipped_devices = self.treat_devices_added_or_updated( skipped_devices, need_binding_devices = (
devices_added_updated, ovs_restarted) self.treat_devices_added_or_updated(
devices_added_updated, ovs_restarted))
LOG.debug("process_network_ports - iteration:%(iter_num)d - " LOG.debug("process_network_ports - iteration:%(iter_num)d - "
"treat_devices_added_or_updated completed. " "treat_devices_added_or_updated completed. "
"Skipped %(num_skipped)d devices of " "Skipped %(num_skipped)d devices of "
@ -1369,6 +1412,12 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin,
'num_skipped': len(skipped_devices), 'num_skipped': len(skipped_devices),
'num_current': len(port_info['current']), 'num_current': len(port_info['current']),
'elapsed': time.time() - start}) 'elapsed': time.time() - start})
# TODO(salv-orlando): Optimize avoiding applying filters
# unnecessarily, (eg: when there are no IP address changes)
self.sg_agent.setup_port_filters(
port_info.get('added', set()),
port_info.get('updated', set()))
self._bind_devices(need_binding_devices)
# Update the list of current ports storing only those which # Update the list of current ports storing only those which
# have been actually processed. # have been actually processed.
port_info['current'] = (port_info['current'] - port_info['current'] = (port_info['current'] -

View File

@ -56,8 +56,12 @@ class BaseIptablesFirewallTestCase(base.BaseTestCase):
self.iptables_inst = mock.Mock() self.iptables_inst = mock.Mock()
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,
self.iptables_inst.ipv6 = {'filter': self.v6filter_inst} 'raw': self.v4filter_inst
}
self.iptables_inst.ipv6 = {'filter': self.v6filter_inst,
'raw': self.v6filter_inst
}
iptables_cls.return_value = self.iptables_inst iptables_cls.return_value = self.iptables_inst
self.firewall = iptables_firewall.IptablesFirewallDriver() self.firewall = iptables_firewall.IptablesFirewallDriver()
@ -69,6 +73,7 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):
def _fake_port(self): def _fake_port(self):
return {'device': 'tapfake_dev', return {'device': 'tapfake_dev',
'mac_address': 'ff:ff:ff:ff:ff:ff', 'mac_address': 'ff:ff:ff:ff:ff:ff',
'network_id': 'fake_net',
'fixed_ips': [FAKE_IP['IPv4'], 'fixed_ips': [FAKE_IP['IPv4'],
FAKE_IP['IPv6']]} FAKE_IP['IPv6']]}
@ -921,7 +926,7 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):
'-m physdev --physdev-out tapfake_dev ' '-m physdev --physdev-out tapfake_dev '
'--physdev-is-bridged ' '--physdev-is-bridged '
'-j $ifake_dev', '-j $ifake_dev',
comment=ic.SG_TO_VM_SG), comment=ic.SG_TO_VM_SG)
] ]
if ethertype == 'IPv6': if ethertype == 'IPv6':
for icmp6_type in constants.ICMPV6_ALLOWED_TYPES: for icmp6_type in constants.ICMPV6_ALLOWED_TYPES:
@ -1247,8 +1252,8 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):
def test_defer_chain_apply_coalesce_multiple_ports(self): def test_defer_chain_apply_coalesce_multiple_ports(self):
chain_applies = self._mock_chain_applies() chain_applies = self._mock_chain_applies()
port1 = {'device': 'd1', 'mac_address': 'mac1'} port1 = {'device': 'd1', 'mac_address': 'mac1', 'network_id': 'net1'}
port2 = {'device': 'd2', 'mac_address': 'mac2'} port2 = {'device': 'd2', 'mac_address': 'mac2', 'network_id': 'net1'}
device2port = {'d1': port1, 'd2': port2} device2port = {'d1': port1, 'd2': port2}
with self.firewall.defer_apply(): with self.firewall.defer_apply():
self.firewall.prepare_port_filter(port1) self.firewall.prepare_port_filter(port1)
@ -1259,6 +1264,7 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):
def test_ip_spoofing_filter_with_multiple_ips(self): def test_ip_spoofing_filter_with_multiple_ips(self):
port = {'device': 'tapfake_dev', port = {'device': 'tapfake_dev',
'mac_address': 'ff:ff:ff:ff:ff:ff', 'mac_address': 'ff:ff:ff:ff:ff:ff',
'network_id': 'fake_net',
'fixed_ips': ['10.0.0.1', 'fe80::1', '10.0.0.2']} 'fixed_ips': ['10.0.0.1', 'fe80::1', '10.0.0.2']}
self.firewall.prepare_port_filter(port) self.firewall.prepare_port_filter(port)
calls = [mock.call.add_chain('sg-fallback'), calls = [mock.call.add_chain('sg-fallback'),
@ -1338,6 +1344,7 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):
def test_ip_spoofing_no_fixed_ips(self): def test_ip_spoofing_no_fixed_ips(self):
port = {'device': 'tapfake_dev', port = {'device': 'tapfake_dev',
'mac_address': 'ff:ff:ff:ff:ff:ff', 'mac_address': 'ff:ff:ff:ff:ff:ff',
'network_id': 'fake_net',
'fixed_ips': []} 'fixed_ips': []}
self.firewall.prepare_port_filter(port) self.firewall.prepare_port_filter(port)
calls = [mock.call.add_chain('sg-fallback'), calls = [mock.call.add_chain('sg-fallback'),
@ -1421,6 +1428,7 @@ class IptablesFirewallEnhancedIpsetTestCase(BaseIptablesFirewallTestCase):
def _fake_port(self, sg_id=FAKE_SGID): def _fake_port(self, sg_id=FAKE_SGID):
return {'device': 'tapfake_dev', return {'device': 'tapfake_dev',
'mac_address': 'ff:ff:ff:ff:ff:ff', 'mac_address': 'ff:ff:ff:ff:ff:ff',
'network_id': 'fake_net',
'fixed_ips': [FAKE_IP['IPv4'], 'fixed_ips': [FAKE_IP['IPv4'],
FAKE_IP['IPv6']], FAKE_IP['IPv6']],
'security_groups': [sg_id], 'security_groups': [sg_id],

View File

@ -314,7 +314,7 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
] ]
if use_ipv6: if use_ipv6:
self._extend_with_ip6tables_filter(expected_calls_and_values, self._extend_with_ip6tables_filter(expected_calls_and_values,
filter_dump_ipv6) raw_dump + filter_dump_ipv6)
tools.setup_mock_calls(self.execute, expected_calls_and_values) tools.setup_mock_calls(self.execute, expected_calls_and_values)
@ -374,7 +374,7 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
] ]
if use_ipv6: if use_ipv6:
self._extend_with_ip6tables_filter(expected_calls_and_values, self._extend_with_ip6tables_filter(expected_calls_and_values,
filter_dump) raw_dump + filter_dump)
tools.setup_mock_calls(self.execute, expected_calls_and_values) tools.setup_mock_calls(self.execute, expected_calls_and_values)
@ -421,7 +421,7 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
] ]
if use_ipv6: if use_ipv6:
self._extend_with_ip6tables_filter(expected_calls_and_values, self._extend_with_ip6tables_filter(expected_calls_and_values,
FILTER_DUMP) RAW_DUMP + FILTER_DUMP)
tools.setup_mock_calls(self.execute, expected_calls_and_values) tools.setup_mock_calls(self.execute, expected_calls_and_values)
@ -452,6 +452,8 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
iptables_args['filter_rules'] = filter_rules iptables_args['filter_rules'] = filter_rules
filter_dump_mod = FILTER_WITH_RULES_TEMPLATE % iptables_args filter_dump_mod = FILTER_WITH_RULES_TEMPLATE % iptables_args
raw_dump = RAW_DUMP % IPTABLES_ARG
expected_calls_and_values = [ expected_calls_and_values = [
(mock.call(['iptables-save', '-c'], (mock.call(['iptables-save', '-c'],
run_as_root=True), run_as_root=True),
@ -473,7 +475,7 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
] ]
if use_ipv6: if use_ipv6:
self._extend_with_ip6tables_filter(expected_calls_and_values, self._extend_with_ip6tables_filter(expected_calls_and_values,
FILTER_DUMP) raw_dump + FILTER_DUMP)
tools.setup_mock_calls(self.execute, expected_calls_and_values) tools.setup_mock_calls(self.execute, expected_calls_and_values)
@ -533,6 +535,8 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
'# Completed by iptables_manager\n' '# Completed by iptables_manager\n'
% iptables_args) % iptables_args)
raw_dump = RAW_DUMP % IPTABLES_ARG
expected_calls_and_values = [ expected_calls_and_values = [
(mock.call(['iptables-save', '-c'], (mock.call(['iptables-save', '-c'],
run_as_root=True), run_as_root=True),
@ -553,7 +557,7 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
] ]
if use_ipv6: if use_ipv6:
self._extend_with_ip6tables_filter(expected_calls_and_values, self._extend_with_ip6tables_filter(expected_calls_and_values,
FILTER_DUMP) raw_dump + FILTER_DUMP)
tools.setup_mock_calls(self.execute, expected_calls_and_values) tools.setup_mock_calls(self.execute, expected_calls_and_values)
@ -624,7 +628,7 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
] ]
if use_ipv6: if use_ipv6:
self._extend_with_ip6tables_filter(expected_calls_and_values, self._extend_with_ip6tables_filter(expected_calls_and_values,
FILTER_DUMP) RAW_DUMP + FILTER_DUMP)
tools.setup_mock_calls(self.execute, expected_calls_and_values) tools.setup_mock_calls(self.execute, expected_calls_and_values)
@ -680,6 +684,8 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
'# Completed by iptables_manager\n' '# Completed by iptables_manager\n'
% IPTABLES_ARG) % IPTABLES_ARG)
raw_dump = RAW_DUMP % IPTABLES_ARG
expected_calls_and_values = [ expected_calls_and_values = [
(mock.call(['iptables-save', '-c'], (mock.call(['iptables-save', '-c'],
run_as_root=True), run_as_root=True),
@ -700,7 +706,7 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
] ]
if use_ipv6: if use_ipv6:
self._extend_with_ip6tables_filter(expected_calls_and_values, self._extend_with_ip6tables_filter(expected_calls_and_values,
FILTER_DUMP) raw_dump + FILTER_DUMP)
tools.setup_mock_calls(self.execute, expected_calls_and_values) tools.setup_mock_calls(self.execute, expected_calls_and_values)
@ -769,7 +775,7 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
] ]
if use_ipv6: if use_ipv6:
self._extend_with_ip6tables_filter(expected_calls_and_values, self._extend_with_ip6tables_filter(expected_calls_and_values,
FILTER_DUMP) RAW_DUMP + FILTER_DUMP)
tools.setup_mock_calls(self.execute, expected_calls_and_values) tools.setup_mock_calls(self.execute, expected_calls_and_values)
@ -911,6 +917,10 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
''), ''),
] ]
if use_ipv6: if use_ipv6:
expected_calls_and_values.append(
(mock.call(['ip6tables', '-t', 'raw', '-L', 'OUTPUT',
'-n', '-v', '-x'], run_as_root=True),
''))
expected_calls_and_values.append( expected_calls_and_values.append(
(mock.call(['ip6tables', '-t', 'filter', '-L', 'OUTPUT', (mock.call(['ip6tables', '-t', 'filter', '-L', 'OUTPUT',
'-n', '-v', '-x'], '-n', '-v', '-x'],
@ -960,6 +970,10 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
'') '')
] ]
if use_ipv6: if use_ipv6:
expected_calls_and_values.append(
(mock.call(['ip6tables', '-t', 'raw', '-L', 'OUTPUT',
'-n', '-v', '-x', '-Z'], run_as_root=True),
''))
expected_calls_and_values.append( expected_calls_and_values.append(
(mock.call(['ip6tables', '-t', 'filter', '-L', 'OUTPUT', (mock.call(['ip6tables', '-t', 'filter', '-L', 'OUTPUT',
'-n', '-v', '-x', '-Z'], '-n', '-v', '-x', '-Z'],

View File

@ -13,9 +13,9 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import collections
import contextlib import contextlib
import collections
import mock import mock
from oslo_config import cfg from oslo_config import cfg
import oslo_messaging import oslo_messaging
@ -34,6 +34,7 @@ from neutron.db import securitygroups_rpc_base as sg_db_rpc
from neutron.extensions import allowedaddresspairs as addr_pair from neutron.extensions import allowedaddresspairs as addr_pair
from neutron.extensions import securitygroup as ext_sg from neutron.extensions import securitygroup as ext_sg
from neutron import manager from neutron import manager
from neutron.plugins.openvswitch.agent import ovs_neutron_agent
from neutron.tests import base from neutron.tests import base
from neutron.tests.unit.extensions import test_securitygroup as test_sg from neutron.tests.unit.extensions import test_securitygroup as test_sg
@ -1107,6 +1108,7 @@ class BaseSecurityGroupAgentRpcTestCase(base.BaseTestCase):
self.firewall.defer_apply.side_effect = firewall_object.defer_apply self.firewall.defer_apply.side_effect = firewall_object.defer_apply
self.agent.firewall = self.firewall self.agent.firewall = self.firewall
self.fake_device = {'device': 'fake_device', self.fake_device = {'device': 'fake_device',
'network_id': 'fake_net',
'security_groups': ['fake_sgid1', 'fake_sgid2'], 'security_groups': ['fake_sgid1', 'fake_sgid2'],
'security_group_source_groups': ['fake_sgid2'], 'security_group_source_groups': ['fake_sgid2'],
'security_group_rules': [{'security_group_id': 'security_group_rules': [{'security_group_id':
@ -1667,6 +1669,42 @@ IPTABLES_ARG['ip1'] = IPS.values()[0]
IPTABLES_ARG['ip2'] = IPS.values()[1] IPTABLES_ARG['ip2'] = IPS.values()[1]
IPTABLES_ARG['chains'] = CHAINS_NAT IPTABLES_ARG['chains'] = CHAINS_NAT
IPTABLES_RAW_DEFAULT = """# Generated by iptables_manager
*raw
:%(bn)s-OUTPUT - [0:0]
:%(bn)s-PREROUTING - [0:0]
[0:0] -A PREROUTING -j %(bn)s-PREROUTING
[0:0] -A OUTPUT -j %(bn)s-OUTPUT
COMMIT
# Completed by iptables_manager
""" % IPTABLES_ARG
IPTABLES_RAW_DEVICE_1 = """# Generated by iptables_manager
*raw
:%(bn)s-OUTPUT - [0:0]
:%(bn)s-PREROUTING - [0:0]
[0:0] -A PREROUTING -j %(bn)s-PREROUTING
[0:0] -A OUTPUT -j %(bn)s-OUTPUT
[0:0] -A %(bn)s-PREROUTING -m physdev --physdev-in qvbtap_port1 -j CT --zone 1
[0:0] -A %(bn)s-PREROUTING -m physdev --physdev-in tap_port1 -j CT --zone 1
COMMIT
# Completed by iptables_manager
""" % IPTABLES_ARG
IPTABLES_RAW_DEVICE_2 = """# Generated by iptables_manager
*raw
:%(bn)s-OUTPUT - [0:0]
:%(bn)s-PREROUTING - [0:0]
[0:0] -A PREROUTING -j %(bn)s-PREROUTING
[0:0] -A OUTPUT -j %(bn)s-OUTPUT
[0:0] -A %(bn)s-PREROUTING -m physdev --physdev-in qvbtap_port1 -j CT --zone 1
[0:0] -A %(bn)s-PREROUTING -m physdev --physdev-in tap_port1 -j CT --zone 1
[0:0] -A %(bn)s-PREROUTING -m physdev --physdev-in qvbtap_port2 -j CT --zone 1
[0:0] -A %(bn)s-PREROUTING -m physdev --physdev-in tap_port2 -j CT --zone 1
COMMIT
# Completed by iptables_manager
""" % IPTABLES_ARG
IPTABLES_NAT = """# Generated by iptables_manager IPTABLES_NAT = """# Generated by iptables_manager
*nat *nat
:neutron-postrouting-bottom - [0:0] :neutron-postrouting-bottom - [0:0]
@ -2469,9 +2507,7 @@ class TestSecurityGroupAgentWithIptables(base.BaseTestCase):
cfg.CONF.set_override('comment_iptables_rules', False, group='AGENT') cfg.CONF.set_override('comment_iptables_rules', False, group='AGENT')
self.rpc = mock.Mock() self.rpc = mock.Mock()
self.agent = sg_rpc.SecurityGroupAgentRpc( self._init_agent(defer_refresh_firewall)
context=None, plugin_rpc=self.rpc,
defer_refresh_firewall=defer_refresh_firewall)
if test_rpc_v1_1: if test_rpc_v1_1:
self.rpc.security_group_info_for_devices.side_effect = ( self.rpc.security_group_info_for_devices.side_effect = (
@ -2542,8 +2578,14 @@ class TestSecurityGroupAgentWithIptables(base.BaseTestCase):
'12:34:56:78:9a:bd', '12:34:56:78:9a:bd',
rule5)} rule5)}
def _init_agent(self, defer_refresh_firewall):
self.agent = sg_rpc.SecurityGroupAgentRpc(
context=None, plugin_rpc=self.rpc,
defer_refresh_firewall=defer_refresh_firewall)
def _device(self, device, ip, mac_address, rule): def _device(self, device, ip, mac_address, rule):
return {'device': device, return {'device': device,
'network_id': 'fakenet',
'fixed_ips': [ip], 'fixed_ips': [ip],
'mac_address': mac_address, 'mac_address': mac_address,
'security_groups': ['security_group1'], 'security_groups': ['security_group1'],
@ -2588,14 +2630,14 @@ 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): def _replay_iptables(self, v4_filter, v6_filter, raw):
self._register_mock_call( self._register_mock_call(
['iptables-save', '-c'], ['iptables-save', '-c'],
run_as_root=True, run_as_root=True,
return_value='') return_value='')
self._register_mock_call( self._register_mock_call(
['iptables-restore', '-c'], ['iptables-restore', '-c'],
process_input=self._regex(IPTABLES_RAW + IPTABLES_NAT + process_input=self._regex(raw + IPTABLES_NAT +
IPTABLES_MANGLE + v4_filter), IPTABLES_MANGLE + v4_filter),
run_as_root=True, run_as_root=True,
return_value='') return_value='')
@ -2605,14 +2647,16 @@ class TestSecurityGroupAgentWithIptables(base.BaseTestCase):
return_value='') return_value='')
self._register_mock_call( self._register_mock_call(
['ip6tables-restore', '-c'], ['ip6tables-restore', '-c'],
process_input=self._regex(v6_filter), process_input=self._regex(raw + v6_filter),
run_as_root=True, run_as_root=True,
return_value='') return_value='')
def test_prepare_remove_port(self): def test_prepare_remove_port(self):
self.rpc.security_group_rules_for_devices.return_value = self.devices1 self.rpc.security_group_rules_for_devices.return_value = self.devices1
self._replay_iptables(IPTABLES_FILTER_1, IPTABLES_FILTER_V6_1) self._replay_iptables(IPTABLES_FILTER_1, IPTABLES_FILTER_V6_1,
self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY) IPTABLES_RAW_DEFAULT)
self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY,
IPTABLES_RAW_DEFAULT)
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'])
@ -2621,12 +2665,18 @@ class TestSecurityGroupAgentWithIptables(base.BaseTestCase):
def test_security_group_member_updated(self): def test_security_group_member_updated(self):
self.rpc.security_group_rules_for_devices.return_value = self.devices1 self.rpc.security_group_rules_for_devices.return_value = self.devices1
self._replay_iptables(IPTABLES_FILTER_1, IPTABLES_FILTER_V6_1) self._replay_iptables(IPTABLES_FILTER_1, IPTABLES_FILTER_V6_1,
self._replay_iptables(IPTABLES_FILTER_1_2, IPTABLES_FILTER_V6_1) IPTABLES_RAW_DEFAULT)
self._replay_iptables(IPTABLES_FILTER_2, IPTABLES_FILTER_V6_2) self._replay_iptables(IPTABLES_FILTER_1_2, IPTABLES_FILTER_V6_1,
self._replay_iptables(IPTABLES_FILTER_2_2, IPTABLES_FILTER_V6_2) IPTABLES_RAW_DEFAULT)
self._replay_iptables(IPTABLES_FILTER_1, IPTABLES_FILTER_V6_1) self._replay_iptables(IPTABLES_FILTER_2, IPTABLES_FILTER_V6_2,
self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY) IPTABLES_RAW_DEFAULT)
self._replay_iptables(IPTABLES_FILTER_2_2, IPTABLES_FILTER_V6_2,
IPTABLES_RAW_DEFAULT)
self._replay_iptables(IPTABLES_FILTER_1, IPTABLES_FILTER_V6_1,
IPTABLES_RAW_DEFAULT)
self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY,
IPTABLES_RAW_DEFAULT)
self.agent.prepare_devices_filter(['tap_port1']) self.agent.prepare_devices_filter(['tap_port1'])
self.rpc.security_group_rules_for_devices.return_value = self.devices2 self.rpc.security_group_rules_for_devices.return_value = self.devices2
@ -2641,8 +2691,10 @@ class TestSecurityGroupAgentWithIptables(base.BaseTestCase):
def test_security_group_rule_updated(self): def test_security_group_rule_updated(self):
self.rpc.security_group_rules_for_devices.return_value = self.devices2 self.rpc.security_group_rules_for_devices.return_value = self.devices2
self._replay_iptables(IPTABLES_FILTER_2, IPTABLES_FILTER_V6_2) self._replay_iptables(IPTABLES_FILTER_2, IPTABLES_FILTER_V6_2,
self._replay_iptables(IPTABLES_FILTER_2_3, IPTABLES_FILTER_V6_2) IPTABLES_RAW_DEFAULT)
self._replay_iptables(IPTABLES_FILTER_2_3, IPTABLES_FILTER_V6_2,
IPTABLES_RAW_DEFAULT)
self.agent.prepare_devices_filter(['tap_port1', 'tap_port3']) self.agent.prepare_devices_filter(['tap_port1', 'tap_port3'])
self.rpc.security_group_rules_for_devices.return_value = self.devices3 self.rpc.security_group_rules_for_devices.return_value = self.devices3
@ -2713,8 +2765,10 @@ class TestSecurityGroupAgentEnhancedRpcWithIptables(
def test_prepare_remove_port(self): def test_prepare_remove_port(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,
self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY) IPTABLES_RAW_DEFAULT)
self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY,
IPTABLES_RAW_DEFAULT)
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'])
@ -2723,12 +2777,18 @@ 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,
self._replay_iptables(IPTABLES_FILTER_1_2, IPTABLES_FILTER_V6_1) IPTABLES_RAW_DEFAULT)
self._replay_iptables(IPTABLES_FILTER_2, IPTABLES_FILTER_V6_2) self._replay_iptables(IPTABLES_FILTER_1_2, IPTABLES_FILTER_V6_1,
self._replay_iptables(IPTABLES_FILTER_2_2, IPTABLES_FILTER_V6_2) IPTABLES_RAW_DEFAULT)
self._replay_iptables(IPTABLES_FILTER_1, IPTABLES_FILTER_V6_1) self._replay_iptables(IPTABLES_FILTER_2, IPTABLES_FILTER_V6_2,
self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY) IPTABLES_RAW_DEFAULT)
self._replay_iptables(IPTABLES_FILTER_2_2, IPTABLES_FILTER_V6_2,
IPTABLES_RAW_DEFAULT)
self._replay_iptables(IPTABLES_FILTER_1, IPTABLES_FILTER_V6_1,
IPTABLES_RAW_DEFAULT)
self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY,
IPTABLES_RAW_DEFAULT)
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
@ -2743,8 +2803,10 @@ class TestSecurityGroupAgentEnhancedRpcWithIptables(
def test_security_group_rule_updated(self): def test_security_group_rule_updated(self):
self.sg_info.return_value = self.devices_info2 self.sg_info.return_value = self.devices_info2
self._replay_iptables(IPTABLES_FILTER_2, IPTABLES_FILTER_V6_2) self._replay_iptables(IPTABLES_FILTER_2, IPTABLES_FILTER_V6_2,
self._replay_iptables(IPTABLES_FILTER_2_3, IPTABLES_FILTER_V6_2) IPTABLES_RAW_DEFAULT)
self._replay_iptables(IPTABLES_FILTER_2_3, IPTABLES_FILTER_V6_2,
IPTABLES_RAW_DEFAULT)
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
@ -2765,8 +2827,10 @@ class TestSecurityGroupAgentEnhancedIpsetWithIptables(
def test_prepare_remove_port(self): def test_prepare_remove_port(self):
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,
self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY) IPTABLES_RAW_DEFAULT)
self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY,
IPTABLES_RAW_DEFAULT)
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'])
@ -2775,12 +2839,18 @@ class TestSecurityGroupAgentEnhancedIpsetWithIptables(
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(IPSET_FILTER_1, IPTABLES_FILTER_V6_1) self._replay_iptables(IPSET_FILTER_1, IPTABLES_FILTER_V6_1,
self._replay_iptables(IPSET_FILTER_1, IPTABLES_FILTER_V6_1) IPTABLES_RAW_DEFAULT)
self._replay_iptables(IPSET_FILTER_2, IPTABLES_FILTER_V6_2) self._replay_iptables(IPSET_FILTER_1, IPTABLES_FILTER_V6_1,
self._replay_iptables(IPSET_FILTER_2, IPTABLES_FILTER_V6_2) IPTABLES_RAW_DEFAULT)
self._replay_iptables(IPSET_FILTER_1, IPTABLES_FILTER_V6_1) self._replay_iptables(IPSET_FILTER_2, IPTABLES_FILTER_V6_2,
self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY) IPTABLES_RAW_DEFAULT)
self._replay_iptables(IPSET_FILTER_2, IPTABLES_FILTER_V6_2,
IPTABLES_RAW_DEFAULT)
self._replay_iptables(IPSET_FILTER_1, IPTABLES_FILTER_V6_1,
IPTABLES_RAW_DEFAULT)
self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY,
IPTABLES_RAW_DEFAULT)
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
@ -2795,8 +2865,10 @@ class TestSecurityGroupAgentEnhancedIpsetWithIptables(
def test_security_group_rule_updated(self): def test_security_group_rule_updated(self):
self.sg_info.return_value = self.devices_info2 self.sg_info.return_value = self.devices_info2
self._replay_iptables(IPSET_FILTER_2, IPTABLES_FILTER_V6_2) self._replay_iptables(IPSET_FILTER_2, IPTABLES_FILTER_V6_2,
self._replay_iptables(IPSET_FILTER_2_3, IPTABLES_FILTER_V6_2) IPTABLES_RAW_DEFAULT)
self._replay_iptables(IPSET_FILTER_2_3, IPTABLES_FILTER_V6_2,
IPTABLES_RAW_DEFAULT)
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
@ -2858,11 +2930,77 @@ class TestSecurityGroupAgentWithOVSIptables(
FIREWALL_DRIVER = FIREWALL_HYBRID_DRIVER FIREWALL_DRIVER = FIREWALL_HYBRID_DRIVER
def setUp(self, defer_refresh_firewall=False, test_rpc_v1_1=True):
super(TestSecurityGroupAgentWithOVSIptables, self).setUp(
defer_refresh_firewall,
test_rpc_v1_1)
def _init_agent(self, defer_refresh_firewall):
fake_map = ovs_neutron_agent.LocalVLANMapping(1, 'network_type',
'physical_network', 1)
local_vlan_map = {'fakenet': fake_map}
self.agent = sg_rpc.SecurityGroupAgentRpc(
context=None, plugin_rpc=self.rpc,
local_vlan_map=local_vlan_map,
defer_refresh_firewall=defer_refresh_firewall)
def test_prepare_remove_port(self):
self.rpc.security_group_rules_for_devices.return_value = self.devices1
self._replay_iptables(IPTABLES_FILTER_1, IPTABLES_FILTER_V6_1,
IPTABLES_RAW_DEVICE_1)
self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY,
IPTABLES_RAW_DEFAULT)
self.agent.prepare_devices_filter(['tap_port1'])
self.agent.remove_devices_filter(['tap_port1'])
self._verify_mock_calls()
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_DEVICE_1)
self._replay_iptables(IPTABLES_FILTER_1_2, IPTABLES_FILTER_V6_1,
IPTABLES_RAW_DEVICE_1)
self._replay_iptables(IPTABLES_FILTER_2, IPTABLES_FILTER_V6_2,
IPTABLES_RAW_DEVICE_2)
self._replay_iptables(IPTABLES_FILTER_2_2, IPTABLES_FILTER_V6_2,
IPTABLES_RAW_DEVICE_2)
self._replay_iptables(IPTABLES_FILTER_1, IPTABLES_FILTER_V6_1,
IPTABLES_RAW_DEVICE_1)
self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY,
IPTABLES_RAW_DEFAULT)
self.agent.prepare_devices_filter(['tap_port1'])
self.rpc.security_group_rules_for_devices.return_value = self.devices2
self.agent.security_groups_member_updated(['security_group1'])
self.agent.prepare_devices_filter(['tap_port2'])
self.rpc.security_group_rules_for_devices.return_value = self.devices1
self.agent.security_groups_member_updated(['security_group1'])
self.agent.remove_devices_filter(['tap_port2'])
self.agent.remove_devices_filter(['tap_port1'])
self._verify_mock_calls()
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_DEVICE_2)
self._replay_iptables(IPTABLES_FILTER_2_3, IPTABLES_FILTER_V6_2,
IPTABLES_RAW_DEVICE_2)
self.agent.prepare_devices_filter(['tap_port1', 'tap_port3'])
self.rpc.security_group_rules_for_devices.return_value = self.devices3
self.agent.security_groups_rule_updated(['security_group1'])
self._verify_mock_calls()
def _regex(self, value): def _regex(self, value):
#Note(nati): tap is prefixed on the device #Note(nati): tap is prefixed on the device
# in the OVSHybridIptablesFirewallDriver # in the OVSHybridIptablesFirewallDriver
value = value.replace('tap_port', 'taptap_port') value = value.replace('tap_port', 'taptap_port')
value = value.replace('qvbtaptap_port', 'qvbtap_port')
value = value.replace('o_port', 'otap_port') value = value.replace('o_port', 'otap_port')
value = value.replace('i_port', 'itap_port') value = value.replace('i_port', 'itap_port')
value = value.replace('s_port', 'stap_port') value = value.replace('s_port', 'stap_port')

View File

@ -134,7 +134,9 @@ class TestOvsNeutronAgent(base.BaseTestCase):
mock.patch('neutron.agent.common.ovs_lib.BaseOVS.get_bridges'), mock.patch('neutron.agent.common.ovs_lib.BaseOVS.get_bridges'),
mock.patch('neutron.openstack.common.loopingcall.' mock.patch('neutron.openstack.common.loopingcall.'
'FixedIntervalLoopingCall', 'FixedIntervalLoopingCall',
new=MockFixedIntervalLoopingCall)): new=MockFixedIntervalLoopingCall),
mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
'get_vif_ports', return_value=[])):
self.agent = ovs_neutron_agent.OVSNeutronAgent(**kwargs) self.agent = ovs_neutron_agent.OVSNeutronAgent(**kwargs)
# set back to true because initial report state will succeed due # set back to true because initial report state will succeed due
# to mocked out RPC calls # to mocked out RPC calls
@ -157,22 +159,17 @@ class TestOvsNeutronAgent(base.BaseTestCase):
mock.patch('neutron.agent.common.ovs_lib.OVSBridge.' mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
'set_db_attribute', return_value=True), 'set_db_attribute', return_value=True),
mock.patch('neutron.agent.common.ovs_lib.OVSBridge.' mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
'db_get_val', return_value=old_local_vlan), 'db_get_val', return_value={}),
mock.patch.object(self.agent.int_br, 'delete_flows') mock.patch.object(self.agent.int_br, 'delete_flows')
) as (set_ovs_db_func, get_ovs_db_func, delete_flows_func): ) as (set_ovs_db_func, get_ovs_db_func, delete_flows_func):
self.agent.port_bound(port, net_uuid, 'local', None, None, self.agent.port_bound(port, net_uuid, 'local', None, None,
fixed_ips, "compute:None", False) fixed_ips, "compute:None", False)
get_ovs_db_func.assert_called_once_with("Port", mock.ANY, "tag") vlan_mapping = {'net_uuid': net_uuid,
if new_local_vlan != old_local_vlan: 'network_type': 'local',
set_ovs_db_func.assert_called_once_with( 'physical_network': None,
"Port", mock.ANY, "tag", new_local_vlan) 'segmentation_id': None}
if ofport != -1: set_ovs_db_func.assert_called_once_with(
delete_flows_func.assert_called_once_with(in_port=port.ofport) "Port", mock.ANY, "other_config", vlan_mapping)
else:
self.assertFalse(delete_flows_func.called)
else:
self.assertFalse(set_ovs_db_func.called)
self.assertFalse(delete_flows_func.called)
def test_check_agent_configurations_for_dvr_raises(self): def test_check_agent_configurations_for_dvr_raises(self):
self.agent.enable_distributed_routing = True self.agent.enable_distributed_routing = True
@ -339,7 +336,8 @@ class TestOvsNeutronAgent(base.BaseTestCase):
mock.patch.object(self.agent.plugin_rpc, 'update_device_down'), mock.patch.object(self.agent.plugin_rpc, 'update_device_down'),
mock.patch.object(self.agent, func_name) mock.patch.object(self.agent, func_name)
) as (get_dev_fn, get_vif_func, upd_dev_up, upd_dev_down, func): ) as (get_dev_fn, get_vif_func, upd_dev_up, upd_dev_down, func):
skip_devs = self.agent.treat_devices_added_or_updated([{}], False) skip_devs, need_bound_devices = (
self.agent.treat_devices_added_or_updated([{}], False))
# The function should not raise # The function should not raise
self.assertFalse(skip_devs) self.assertFalse(skip_devs)
return func.called return func.called
@ -379,18 +377,13 @@ class TestOvsNeutronAgent(base.BaseTestCase):
return_value=[dev_mock]), return_value=[dev_mock]),
mock.patch.object(self.agent.int_br, 'get_vif_port_by_id', mock.patch.object(self.agent.int_br, 'get_vif_port_by_id',
return_value=None), return_value=None),
mock.patch.object(self.agent.plugin_rpc, 'update_device_up'),
mock.patch.object(self.agent.plugin_rpc, 'update_device_down'),
mock.patch.object(self.agent, 'treat_vif_port') mock.patch.object(self.agent, 'treat_vif_port')
) as (get_dev_fn, get_vif_func, upd_dev_up, ) as (get_dev_fn, get_vif_func, treat_vif_port):
upd_dev_down, treat_vif_port):
skip_devs = self.agent.treat_devices_added_or_updated([{}], False) skip_devs = self.agent.treat_devices_added_or_updated([{}], False)
# The function should return False for resync and no device # The function should return False for resync and no device
# processed # processed
self.assertEqual(['the_skipped_one'], skip_devs) self.assertEqual((['the_skipped_one'], []), skip_devs)
self.assertFalse(treat_vif_port.called) self.assertFalse(treat_vif_port.called)
self.assertFalse(upd_dev_down.called)
self.assertFalse(upd_dev_up.called)
def test_treat_devices_added_updated_put_port_down(self): def test_treat_devices_added_updated_put_port_down(self):
fake_details_dict = {'admin_state_up': False, fake_details_dict = {'admin_state_up': False,
@ -411,16 +404,13 @@ class TestOvsNeutronAgent(base.BaseTestCase):
return_value=[fake_details_dict]), return_value=[fake_details_dict]),
mock.patch.object(self.agent.int_br, 'get_vif_port_by_id', mock.patch.object(self.agent.int_br, 'get_vif_port_by_id',
return_value=mock.MagicMock()), return_value=mock.MagicMock()),
mock.patch.object(self.agent.plugin_rpc, 'update_device_up'),
mock.patch.object(self.agent.plugin_rpc, 'update_device_down'),
mock.patch.object(self.agent, 'treat_vif_port') mock.patch.object(self.agent, 'treat_vif_port')
) as (get_dev_fn, get_vif_func, upd_dev_up, ) as (get_dev_fn, get_vif_func, treat_vif_port):
upd_dev_down, treat_vif_port): skip_devs, need_bound_devices = (
skip_devs = self.agent.treat_devices_added_or_updated([{}], False) self.agent.treat_devices_added_or_updated([{}], False))
# The function should return False for resync # The function should return False for resync
self.assertFalse(skip_devs) self.assertFalse(skip_devs)
self.assertTrue(treat_vif_port.called) self.assertTrue(treat_vif_port.called)
self.assertTrue(upd_dev_down.called)
def test_treat_devices_removed_returns_true_for_missing_device(self): def test_treat_devices_removed_returns_true_for_missing_device(self):
with mock.patch.object(self.agent.plugin_rpc, 'update_device_down', with mock.patch.object(self.agent.plugin_rpc, 'update_device_down',
@ -445,7 +435,7 @@ class TestOvsNeutronAgent(base.BaseTestCase):
with contextlib.nested( with contextlib.nested(
mock.patch.object(self.agent.sg_agent, "setup_port_filters"), mock.patch.object(self.agent.sg_agent, "setup_port_filters"),
mock.patch.object(self.agent, "treat_devices_added_or_updated", mock.patch.object(self.agent, "treat_devices_added_or_updated",
return_value=[]), return_value=([], [])),
mock.patch.object(self.agent, "treat_devices_removed", mock.patch.object(self.agent, "treat_devices_removed",
return_value=False) return_value=False)
) as (setup_port_filters, device_added_updated, device_removed): ) as (setup_port_filters, device_added_updated, device_removed):
@ -1267,7 +1257,9 @@ class AncillaryBridgesTest(base.BaseTestCase):
return_value=bridges), return_value=bridges),
mock.patch('neutron.agent.common.ovs_lib.BaseOVS.' mock.patch('neutron.agent.common.ovs_lib.BaseOVS.'
'get_bridge_external_bridge_id', 'get_bridge_external_bridge_id',
side_effect=pullup_side_effect)): side_effect=pullup_side_effect),
mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
'get_vif_ports', return_value=[])):
self.agent = ovs_neutron_agent.OVSNeutronAgent(**self.kwargs) self.agent = ovs_neutron_agent.OVSNeutronAgent(**self.kwargs)
self.assertEqual(len(ancillary), len(self.agent.ancillary_brs)) self.assertEqual(len(ancillary), len(self.agent.ancillary_brs))
if ancillary: if ancillary:
@ -1326,7 +1318,9 @@ class TestOvsDvrNeutronAgent(base.BaseTestCase):
mock.patch('neutron.agent.common.ovs_lib.BaseOVS.get_bridges'), mock.patch('neutron.agent.common.ovs_lib.BaseOVS.get_bridges'),
mock.patch('neutron.openstack.common.loopingcall.' mock.patch('neutron.openstack.common.loopingcall.'
'FixedIntervalLoopingCall', 'FixedIntervalLoopingCall',
new=MockFixedIntervalLoopingCall)): new=MockFixedIntervalLoopingCall),
mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
'get_vif_ports', return_value=[])):
self.agent = ovs_neutron_agent.OVSNeutronAgent(**kwargs) self.agent = ovs_neutron_agent.OVSNeutronAgent(**kwargs)
# set back to true because initial report state will succeed due # set back to true because initial report state will succeed due
# to mocked out RPC calls # to mocked out RPC calls
@ -1383,13 +1377,14 @@ class TestOvsDvrNeutronAgent(base.BaseTestCase):
physical_network = self._physical_network physical_network = self._physical_network
segmentation_id = self._segmentation_id segmentation_id = self._segmentation_id
network_type = p_const.TYPE_VLAN network_type = p_const.TYPE_VLAN
with mock.patch('neutron.agent.common.ovs_lib.OVSBridge.' with contextlib.nested(
mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
'set_db_attribute', 'set_db_attribute',
return_value=True): return_value=True),
with contextlib.nested(
mock.patch('neutron.agent.common.ovs_lib.OVSBridge.' mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
'db_get_val', 'db_get_val',
return_value=self._old_local_vlan), return_value={})):
with contextlib.nested(
mock.patch.object(self.agent.dvr_agent.plugin_rpc, mock.patch.object(self.agent.dvr_agent.plugin_rpc,
'get_subnet_for_dvr', 'get_subnet_for_dvr',
return_value={ return_value={
@ -1398,13 +1393,12 @@ class TestOvsDvrNeutronAgent(base.BaseTestCase):
'ip_version': ip_version, 'ip_version': ip_version,
'gateway_mac': gateway_mac}), 'gateway_mac': gateway_mac}),
mock.patch.object(self.agent.dvr_agent.plugin_rpc, mock.patch.object(self.agent.dvr_agent.plugin_rpc,
'get_ports_on_host_by_subnet', 'get_ports_on_host_by_subnet',
return_value=[]), return_value=[]),
mock.patch.object(self.agent.dvr_agent.int_br, mock.patch.object(self.agent.dvr_agent.int_br,
'get_vif_port_by_id', 'get_vif_port_by_id',
return_value=self._port), return_value=self._port),
mock.patch.object(self.agent.dvr_agent.int_br, 'add_flow'), mock.patch.object(self.agent.dvr_agent.int_br, 'add_flow'),
mock.patch.object(self.agent.dvr_agent.int_br, 'delete_flows'),
mock.patch.object(self.agent.dvr_agent.tun_br, 'add_flow'), mock.patch.object(self.agent.dvr_agent.tun_br, 'add_flow'),
mock.patch.object(self.agent.dvr_agent.tun_br, 'delete_flows'), mock.patch.object(self.agent.dvr_agent.tun_br, 'delete_flows'),
mock.patch.object( mock.patch.object(
@ -1413,8 +1407,8 @@ class TestOvsDvrNeutronAgent(base.BaseTestCase):
mock.patch.object( mock.patch.object(
self.agent.dvr_agent.phys_brs[physical_network], self.agent.dvr_agent.phys_brs[physical_network],
'delete_flows') 'delete_flows')
) as (get_ovs_db_func, get_subnet_fn, get_cphost_fn, ) as (get_subnet_fn, get_cphost_fn,
get_vif_fn, add_flow_int_fn, delete_flows_int_fn, get_vif_fn, add_flow_int_fn,
add_flow_tun_fn, delete_flows_tun_fn, add_flow_phys_fn, add_flow_tun_fn, delete_flows_tun_fn, add_flow_phys_fn,
delete_flows_phys_fn): delete_flows_phys_fn):
self.agent.port_bound( self.agent.port_bound(
@ -1479,12 +1473,6 @@ class TestOvsDvrNeutronAgent(base.BaseTestCase):
] ]
self.assertEqual(expected_on_int_br, self.assertEqual(expected_on_int_br,
add_flow_int_fn.call_args_list) add_flow_int_fn.call_args_list)
expected_on_int_br = [
mock.call(in_port=self._port.ofport),
mock.call(in_port=self._compute_port.ofport)
]
self.assertEqual(expected_on_int_br,
delete_flows_int_fn.call_args_list)
self.assertFalse(add_flow_tun_fn.called) self.assertFalse(add_flow_tun_fn.called)
self.assertFalse(delete_flows_tun_fn.called) self.assertFalse(delete_flows_tun_fn.called)
self.assertFalse(delete_flows_phys_fn.called) self.assertFalse(delete_flows_phys_fn.called)
@ -1503,13 +1491,14 @@ class TestOvsDvrNeutronAgent(base.BaseTestCase):
self._compute_port.vif_mac = '77:88:99:00:11:22' self._compute_port.vif_mac = '77:88:99:00:11:22'
physical_network = self._physical_network physical_network = self._physical_network
segmentation_id = self._segmentation_id segmentation_id = self._segmentation_id
with mock.patch('neutron.agent.common.ovs_lib.OVSBridge.' with contextlib.nested(
mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
'set_db_attribute', 'set_db_attribute',
return_value=True): return_value=True),
with contextlib.nested(
mock.patch('neutron.agent.common.ovs_lib.OVSBridge.' mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
'db_get_val', 'db_get_val',
return_value=self._old_local_vlan), return_value={})):
with contextlib.nested(
mock.patch.object(self.agent.dvr_agent.plugin_rpc, mock.patch.object(self.agent.dvr_agent.plugin_rpc,
'get_subnet_for_dvr', 'get_subnet_for_dvr',
return_value={ return_value={
@ -1524,7 +1513,6 @@ class TestOvsDvrNeutronAgent(base.BaseTestCase):
'get_vif_port_by_id', 'get_vif_port_by_id',
return_value=self._port), return_value=self._port),
mock.patch.object(self.agent.dvr_agent.int_br, 'add_flow'), mock.patch.object(self.agent.dvr_agent.int_br, 'add_flow'),
mock.patch.object(self.agent.dvr_agent.int_br, 'delete_flows'),
mock.patch.object(self.agent.dvr_agent.tun_br, 'add_flow'), mock.patch.object(self.agent.dvr_agent.tun_br, 'add_flow'),
mock.patch.object(self.agent.dvr_agent.tun_br, 'delete_flows'), mock.patch.object(self.agent.dvr_agent.tun_br, 'delete_flows'),
mock.patch.object( mock.patch.object(
@ -1533,8 +1521,8 @@ class TestOvsDvrNeutronAgent(base.BaseTestCase):
mock.patch.object( mock.patch.object(
self.agent.dvr_agent.phys_brs[physical_network], self.agent.dvr_agent.phys_brs[physical_network],
'delete_flows') 'delete_flows')
) as (get_ovs_db_func, get_subnet_fn, get_cphost_fn, ) as (get_subnet_fn, get_cphost_fn,
get_vif_fn, add_flow_int_fn, delete_flows_int_fn, get_vif_fn, add_flow_int_fn,
add_flow_tun_fn, delete_flows_tun_fn, add_flow_tun_fn, delete_flows_tun_fn,
add_flow_phys_fn, delete_flows_phys_fn): add_flow_phys_fn, delete_flows_phys_fn):
self.agent.port_bound( self.agent.port_bound(
@ -1593,12 +1581,6 @@ class TestOvsDvrNeutronAgent(base.BaseTestCase):
self.assertEqual(expected_on_int_br, self.assertEqual(expected_on_int_br,
add_flow_int_fn.call_args_list) add_flow_int_fn.call_args_list)
self.assertFalse(add_flow_phys_fn.called) self.assertFalse(add_flow_phys_fn.called)
expected_on_int_br = [
mock.call(in_port=self._port.ofport),
mock.call(in_port=self._compute_port.ofport)
]
self.assertEqual(expected_on_int_br,
delete_flows_int_fn.call_args_list)
self.assertFalse(add_flow_phys_fn.called) self.assertFalse(add_flow_phys_fn.called)
self.assertFalse(delete_flows_tun_fn.called) self.assertFalse(delete_flows_tun_fn.called)
self.assertFalse(delete_flows_phys_fn.called) self.assertFalse(delete_flows_phys_fn.called)
@ -1635,13 +1617,14 @@ class TestOvsDvrNeutronAgent(base.BaseTestCase):
def test_port_bound_for_dvr_with_csnat_ports(self, ofport=10): def test_port_bound_for_dvr_with_csnat_ports(self, ofport=10):
self._setup_for_dvr_test() self._setup_for_dvr_test()
with mock.patch('neutron.agent.common.ovs_lib.OVSBridge.' with contextlib.nested(
mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
'set_db_attribute', 'set_db_attribute',
return_value=True): return_value=True),
with contextlib.nested(
mock.patch('neutron.agent.common.ovs_lib.OVSBridge.' mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
'db_get_val', 'db_get_val',
return_value=self._old_local_vlan), return_value={})):
with contextlib.nested(
mock.patch.object( mock.patch.object(
self.agent.dvr_agent.plugin_rpc, 'get_subnet_for_dvr', self.agent.dvr_agent.plugin_rpc, 'get_subnet_for_dvr',
return_value={'gateway_ip': '1.1.1.1', return_value={'gateway_ip': '1.1.1.1',
@ -1655,11 +1638,10 @@ class TestOvsDvrNeutronAgent(base.BaseTestCase):
'get_vif_port_by_id', 'get_vif_port_by_id',
return_value=self._port), return_value=self._port),
mock.patch.object(self.agent.dvr_agent.int_br, 'add_flow'), mock.patch.object(self.agent.dvr_agent.int_br, 'add_flow'),
mock.patch.object(self.agent.dvr_agent.int_br, 'delete_flows'),
mock.patch.object(self.agent.dvr_agent.tun_br, 'add_flow'), mock.patch.object(self.agent.dvr_agent.tun_br, 'add_flow'),
mock.patch.object(self.agent.dvr_agent.tun_br, 'delete_flows') mock.patch.object(self.agent.dvr_agent.tun_br, 'delete_flows')
) as (get_ovs_db_func, get_subnet_fn, get_cphost_fn, ) as (get_subnet_fn, get_cphost_fn,
get_vif_fn, add_flow_int_fn, delete_flows_int_fn, get_vif_fn, add_flow_int_fn,
add_flow_tun_fn, delete_flows_tun_fn): add_flow_tun_fn, delete_flows_tun_fn):
self.agent.port_bound( self.agent.port_bound(
self._port, self._net_uuid, 'vxlan', self._port, self._net_uuid, 'vxlan',
@ -1667,7 +1649,6 @@ class TestOvsDvrNeutronAgent(base.BaseTestCase):
n_const.DEVICE_OWNER_ROUTER_SNAT, n_const.DEVICE_OWNER_ROUTER_SNAT,
False) False)
self.assertTrue(add_flow_int_fn.called) self.assertTrue(add_flow_int_fn.called)
self.assertTrue(delete_flows_int_fn.called)
def test_treat_devices_removed_for_dvr_interface(self, ofport=10): def test_treat_devices_removed_for_dvr_interface(self, ofport=10):
self._test_treat_devices_removed_for_dvr_interface(ofport) self._test_treat_devices_removed_for_dvr_interface(ofport)
@ -1683,13 +1664,14 @@ class TestOvsDvrNeutronAgent(base.BaseTestCase):
else: else:
gateway_ip = '2001:100::1' gateway_ip = '2001:100::1'
cidr = '2001:100::0/64' cidr = '2001:100::0/64'
with mock.patch('neutron.agent.common.ovs_lib.OVSBridge.' with contextlib.nested(
mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
'set_db_attribute', 'set_db_attribute',
return_value=True): return_value=True),
with contextlib.nested(
mock.patch('neutron.agent.common.ovs_lib.OVSBridge.' mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
'db_get_val', 'db_get_val',
return_value=self._old_local_vlan), return_value={})):
with contextlib.nested(
mock.patch.object( mock.patch.object(
self.agent.dvr_agent.plugin_rpc, 'get_subnet_for_dvr', self.agent.dvr_agent.plugin_rpc, 'get_subnet_for_dvr',
return_value={'gateway_ip': gateway_ip, return_value={'gateway_ip': gateway_ip,
@ -1703,11 +1685,10 @@ class TestOvsDvrNeutronAgent(base.BaseTestCase):
'get_vif_port_by_id', 'get_vif_port_by_id',
return_value=self._port), return_value=self._port),
mock.patch.object(self.agent.dvr_agent.int_br, 'add_flow'), mock.patch.object(self.agent.dvr_agent.int_br, 'add_flow'),
mock.patch.object(self.agent.dvr_agent.int_br, 'delete_flows'),
mock.patch.object(self.agent.dvr_agent.tun_br, 'add_flow'), mock.patch.object(self.agent.dvr_agent.tun_br, 'add_flow'),
mock.patch.object(self.agent.dvr_agent.tun_br, 'delete_flows') mock.patch.object(self.agent.dvr_agent.tun_br, 'delete_flows')
) as (get_ovs_db_func, get_subnet_fn, get_cphost_fn, ) as (get_subnet_fn, get_cphost_fn,
get_vif_fn, add_flow_int_fn, delete_flows_int_fn, get_vif_fn, add_flow_int_fn,
add_flow_tun_fn, delete_flows_tun_fn): add_flow_tun_fn, delete_flows_tun_fn):
self.agent.port_bound( self.agent.port_bound(
self._port, self._net_uuid, 'vxlan', self._port, self._net_uuid, 'vxlan',
@ -1715,7 +1696,6 @@ class TestOvsDvrNeutronAgent(base.BaseTestCase):
n_const.DEVICE_OWNER_DVR_INTERFACE, n_const.DEVICE_OWNER_DVR_INTERFACE,
False) False)
self.assertTrue(add_flow_tun_fn.called) self.assertTrue(add_flow_tun_fn.called)
self.assertTrue(delete_flows_int_fn.called)
with contextlib.nested( with contextlib.nested(
mock.patch.object(self.agent, 'reclaim_local_vlan'), mock.patch.object(self.agent, 'reclaim_local_vlan'),
@ -1764,13 +1744,14 @@ class TestOvsDvrNeutronAgent(base.BaseTestCase):
else: else:
gateway_ip = '2001:100::1' gateway_ip = '2001:100::1'
cidr = '2001:100::0/64' cidr = '2001:100::0/64'
with mock.patch('neutron.agent.common.ovs_lib.OVSBridge.' with contextlib.nested(
mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
'set_db_attribute', 'set_db_attribute',
return_value=True): return_value=True),
with contextlib.nested(
mock.patch('neutron.agent.common.ovs_lib.OVSBridge.' mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
'db_get_val', 'db_get_val',
return_value=self._old_local_vlan), return_value={})):
with contextlib.nested(
mock.patch.object( mock.patch.object(
self.agent.dvr_agent.plugin_rpc, 'get_subnet_for_dvr', self.agent.dvr_agent.plugin_rpc, 'get_subnet_for_dvr',
return_value={'gateway_ip': gateway_ip, return_value={'gateway_ip': gateway_ip,
@ -1784,11 +1765,10 @@ class TestOvsDvrNeutronAgent(base.BaseTestCase):
'get_vif_port_by_id', 'get_vif_port_by_id',
return_value=self._port), return_value=self._port),
mock.patch.object(self.agent.dvr_agent.int_br, 'add_flow'), mock.patch.object(self.agent.dvr_agent.int_br, 'add_flow'),
mock.patch.object(self.agent.dvr_agent.int_br, 'delete_flows'),
mock.patch.object(self.agent.dvr_agent.tun_br, 'add_flow'), mock.patch.object(self.agent.dvr_agent.tun_br, 'add_flow'),
mock.patch.object(self.agent.dvr_agent.tun_br, 'delete_flows') mock.patch.object(self.agent.dvr_agent.tun_br, 'delete_flows')
) as (get_ovs_db_func, get_subnet_fn, get_cphost_fn, ) as (get_subnet_fn, get_cphost_fn,
get_vif_fn, add_flow_int_fn, delete_flows_int_fn, get_vif_fn, add_flow_int_fn,
add_flow_tun_fn, delete_flows_tun_fn): add_flow_tun_fn, delete_flows_tun_fn):
self.agent.port_bound( self.agent.port_bound(
self._port, self._net_uuid, 'vxlan', self._port, self._net_uuid, 'vxlan',
@ -1802,7 +1782,6 @@ class TestOvsDvrNeutronAgent(base.BaseTestCase):
device_owner, False) device_owner, False)
self.assertTrue(add_flow_tun_fn.called) self.assertTrue(add_flow_tun_fn.called)
self.assertTrue(add_flow_int_fn.called) self.assertTrue(add_flow_int_fn.called)
self.assertTrue(delete_flows_int_fn.called)
with contextlib.nested( with contextlib.nested(
mock.patch.object(self.agent, 'reclaim_local_vlan'), mock.patch.object(self.agent, 'reclaim_local_vlan'),
@ -1841,13 +1820,14 @@ class TestOvsDvrNeutronAgent(base.BaseTestCase):
def test_treat_devices_removed_for_dvr_csnat_port(self, ofport=10): def test_treat_devices_removed_for_dvr_csnat_port(self, ofport=10):
self._setup_for_dvr_test() self._setup_for_dvr_test()
with mock.patch('neutron.agent.common.ovs_lib.OVSBridge.' with contextlib.nested(
mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
'set_db_attribute', 'set_db_attribute',
return_value=True): return_value=True),
with contextlib.nested(
mock.patch('neutron.agent.common.ovs_lib.OVSBridge.' mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
'db_get_val', 'db_get_val',
return_value=self._old_local_vlan), return_value={})):
with contextlib.nested(
mock.patch.object( mock.patch.object(
self.agent.dvr_agent.plugin_rpc, 'get_subnet_for_dvr', self.agent.dvr_agent.plugin_rpc, 'get_subnet_for_dvr',
return_value={'gateway_ip': '1.1.1.1', return_value={'gateway_ip': '1.1.1.1',
@ -1861,11 +1841,10 @@ class TestOvsDvrNeutronAgent(base.BaseTestCase):
'get_vif_port_by_id', 'get_vif_port_by_id',
return_value=self._port), return_value=self._port),
mock.patch.object(self.agent.dvr_agent.int_br, 'add_flow'), mock.patch.object(self.agent.dvr_agent.int_br, 'add_flow'),
mock.patch.object(self.agent.dvr_agent.int_br, 'delete_flows'),
mock.patch.object(self.agent.dvr_agent.tun_br, 'add_flow'), mock.patch.object(self.agent.dvr_agent.tun_br, 'add_flow'),
mock.patch.object(self.agent.dvr_agent.tun_br, 'delete_flows') mock.patch.object(self.agent.dvr_agent.tun_br, 'delete_flows')
) as (get_ovs_db_func, get_subnet_fn, get_cphost_fn, ) as (get_subnet_fn, get_cphost_fn,
get_vif_fn, add_flow_int_fn, delete_flows_int_fn, get_vif_fn, add_flow_int_fn,
add_flow_tun_fn, delete_flows_tun_fn): add_flow_tun_fn, delete_flows_tun_fn):
self.agent.port_bound( self.agent.port_bound(
self._port, self._net_uuid, 'vxlan', self._port, self._net_uuid, 'vxlan',
@ -1873,7 +1852,6 @@ class TestOvsDvrNeutronAgent(base.BaseTestCase):
n_const.DEVICE_OWNER_ROUTER_SNAT, n_const.DEVICE_OWNER_ROUTER_SNAT,
False) False)
self.assertTrue(add_flow_int_fn.called) self.assertTrue(add_flow_int_fn.called)
self.assertTrue(delete_flows_int_fn.called)
with contextlib.nested( with contextlib.nested(
mock.patch.object(self.agent, 'reclaim_local_vlan'), mock.patch.object(self.agent, 'reclaim_local_vlan'),

View File

@ -106,6 +106,8 @@ class TunnelTest(base.BaseTestCase):
self.mock_int_bridge.add_port.return_value = self.MAP_TUN_INT_OFPORT self.mock_int_bridge.add_port.return_value = self.MAP_TUN_INT_OFPORT
self.mock_int_bridge.add_patch_port.side_effect = ( self.mock_int_bridge.add_patch_port.side_effect = (
lambda tap, peer: self.ovs_int_ofports[tap]) lambda tap, peer: self.ovs_int_ofports[tap])
self.mock_int_bridge.get_vif_ports.return_value = []
self.mock_int_bridge.db_get_val.return_value = {}
self.mock_map_tun_bridge = self.ovs_bridges[self.MAP_TUN_BRIDGE] self.mock_map_tun_bridge = self.ovs_bridges[self.MAP_TUN_BRIDGE]
self.mock_map_tun_bridge.br_name = self.MAP_TUN_BRIDGE self.mock_map_tun_bridge.br_name = self.MAP_TUN_BRIDGE
@ -190,7 +192,10 @@ class TunnelTest(base.BaseTestCase):
mock.call.add_patch_port('patch-int', 'patch-tun'), mock.call.add_patch_port('patch-int', 'patch-tun'),
] ]
self.mock_int_bridge_expected += [ self.mock_int_bridge_expected += [
mock.call.add_patch_port('patch-tun', 'patch-int') mock.call.add_patch_port('patch-tun', 'patch-int'),
]
self.mock_int_bridge_expected += [
mock.call.get_vif_ports(),
] ]
self.mock_tun_bridge_expected += [ self.mock_tun_bridge_expected += [
@ -437,12 +442,15 @@ class TunnelTest(base.BaseTestCase):
self._verify_mock_calls() self._verify_mock_calls()
def test_port_bound(self): def test_port_bound(self):
vlan_mapping = {'segmentation_id': LS_ID,
'physical_network': None,
'net_uuid': NET_UUID,
'network_type': 'gre'}
self.mock_int_bridge_expected += [ self.mock_int_bridge_expected += [
mock.call.db_get_val('Port', VIF_PORT.port_name, 'tag'), mock.call.db_get_val('Port', 'port', 'other_config'),
mock.call.set_db_attribute('Port', VIF_PORT.port_name, mock.call.set_db_attribute('Port', VIF_PORT.port_name,
'tag', LVM.vlan), 'other_config',
mock.call.delete_flows(in_port=VIF_PORT.ofport) vlan_mapping)]
]
a = self._build_agent() a = self._build_agent()
a.local_vlan_map[NET_UUID] = LVM a.local_vlan_map[NET_UUID] = LVM
@ -610,7 +618,9 @@ class TunnelTestUseVethInterco(TunnelTest):
self.mock_int_bridge_expected += [ self.mock_int_bridge_expected += [
mock.call.add_patch_port('patch-tun', 'patch-int') mock.call.add_patch_port('patch-tun', 'patch-int')
] ]
self.mock_int_bridge_expected += [
mock.call.get_vif_ports(),
]
self.mock_tun_bridge_expected += [ self.mock_tun_bridge_expected += [
mock.call.remove_all_flows(), mock.call.remove_all_flows(),
mock.call.add_flow(priority=1, mock.call.add_flow(priority=1,