]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Use iptables zone to separate different ip_conntrack
authoryangxurong <yangxurong@huawei.com>
Tue, 26 Aug 2014 07:15:40 +0000 (15:15 +0800)
committershihanzhang <shihanzhang@huawei.com>
Tue, 5 May 2015 08:59:37 +0000 (16:59 +0800)
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

neutron/agent/linux/iptables_firewall.py
neutron/agent/linux/iptables_manager.py
neutron/agent/securitygroups_rpc.py
neutron/plugins/openvswitch/agent/ovs_neutron_agent.py
neutron/tests/unit/agent/linux/test_iptables_firewall.py
neutron/tests/unit/agent/linux/test_iptables_manager.py
neutron/tests/unit/agent/test_securitygroups_rpc.py
neutron/tests/unit/plugins/openvswitch/agent/test_ovs_neutron_agent.py
neutron/tests/unit/plugins/openvswitch/test_ovs_tunnel.py

index 4368dad856ae751e398774dbaaf552b21e02c0f5..323d3501909c4a8e0200ffadddaa5e7e7fe358af 100644 (file)
@@ -193,9 +193,17 @@ class IptablesFirewallDriver(firewall.FirewallDriver):
         self.iptables.ipv6['filter'].add_rule('sg-fallback', '-j 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):
-        self.iptables.ipv6['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):
         self.iptables.ipv4['filter'].remove_chain(chain_name)
@@ -676,3 +684,39 @@ class OVSHybridIptablesFirewallDriver(IptablesFirewallDriver):
 
     def _get_device_name(self, port):
         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)
index 28b89952ed9a3961435c2af8559c58d85e29fe8f..ed99155d174a7dd98265d4f35feedeb4a8e1e330 100644 (file)
@@ -326,10 +326,11 @@ class IptablesManager(object):
                 {'nat': IptablesTable(binary_name=self.wrap_name)})
             builtin_chains[4].update({'nat': ['PREROUTING',
                                       'OUTPUT', 'POSTROUTING']})
-            self.ipv4.update(
-                {'raw': IptablesTable(binary_name=self.wrap_name)})
-            builtin_chains[4].update({'raw': ['PREROUTING',
-                                      'OUTPUT']})
+
+        self.ipv4.update({'raw': IptablesTable(binary_name=self.wrap_name)})
+        builtin_chains[4].update({'raw': ['PREROUTING', 'OUTPUT']})
+        self.ipv6.update({'raw': IptablesTable(binary_name=self.wrap_name)})
+        builtin_chains[6].update({'raw': ['PREROUTING', 'OUTPUT']})
 
         for ip_version in builtin_chains:
             if ip_version == 4:
index 5b24dbe3af29bee1acdf21b73233590e07866d77..a7d2fb46dacee22f6b49c7deabf212d4fc75c92d 100644 (file)
@@ -84,10 +84,12 @@ def disable_security_group_extension_by_config(aliases):
 class SecurityGroupAgentRpc(object):
     """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.plugin_rpc = plugin_rpc
         self.init_firewall(defer_refresh_firewall)
+        self.local_vlan_map = local_vlan_map
 
     def init_firewall(self, defer_refresh_firewall=False):
         firewall_driver = cfg.CONF.SECURITYGROUP.firewall_driver
@@ -108,6 +110,23 @@ class SecurityGroupAgentRpc(object):
         self.global_refresh_firewall = False
         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
     def use_enhanced_rpc(self):
         if self._use_enhanced_rpc is None:
@@ -157,6 +176,7 @@ class SecurityGroupAgentRpc(object):
 
         with self.firewall.defer_apply():
             for device in devices.values():
+                self.set_local_zone(device)
                 self.firewall.prepare_port_filter(device)
             if self.use_enhanced_rpc:
                 LOG.debug("Update security group information for ports %s",
@@ -244,6 +264,7 @@ class SecurityGroupAgentRpc(object):
         with self.firewall.defer_apply():
             for device in devices.values():
                 LOG.debug("Update port filter for %s", device['device'])
+                self.set_local_zone(device)
                 self.firewall.update_port_filter(device)
             if self.use_enhanced_rpc:
                 LOG.debug("Update security group information for ports %s",
index 0be1b9c7e54dfa76fe241952a101418e8bca8835..0cfd824a6a389e679ab8f302797628de6c6b599c 100644 (file)
@@ -254,9 +254,14 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin,
         # Collect additional bridges to monitor
         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
         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
         self.iter_num = 0
@@ -283,6 +288,21 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin,
         except Exception:
             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):
         self.agent_id = 'ovs-agent-%s' % cfg.CONF.host
         self.topic = topics.AGENT
@@ -496,7 +516,7 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin,
             LOG.warning(_LW('Action %s not supported'), action)
 
     def provision_local_vlan(self, net_uuid, network_type, physical_network,
-                             segmentation_id):
+                             segmentation_id, local_vlan=None):
         '''Provisions a local VLAN.
 
         :param net_uuid: the uuid of the network associated with this vlan.
@@ -513,11 +533,15 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin,
         if lvm:
             lvid = lvm.vlan
         else:
-            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()
+            if local_vlan in self.available_local_vlans:
+                lvid = local_vlan
+                self.available_local_vlans.remove(local_vlan)
+            else:
+                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,
                                                              network_type,
                                                              physical_network,
@@ -697,14 +721,43 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin,
         self.dvr_agent.bind_port_to_dvr(port, lvm,
                                         fixed_ips,
                                         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)
+
+    def _bind_devices(self, need_binding_ports):
+        for port_detail in need_binding_ports:
+            lvm = self.local_vlan_map[port_detail['network_id']]
+            port = port_detail['vif_port']
+            device = port_detail['device']
+            # Do not bind a port if it's already bound
+            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)
 
-        # Do not bind a port if it's already bound
-        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
     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
         # for being treated. If that does not happen, it is a potential
         # error condition of which operators should be aware
+        port_needs_binding = True
         if not vif_port.ofport:
             LOG.warn(_LW("VIF port: %s has no ofport configured, "
                          "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)
             else:
                 self.port_dead(vif_port)
+                port_needs_binding = False
         else:
             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):
         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):
         skipped_devices = []
+        need_binding_devices = []
         try:
             devices_details_list = self.plugin_rpc.get_devices_details_list(
                 self.context,
@@ -1244,37 +1301,26 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin,
             if 'port_id' in details:
                 LOG.info(_LI("Port %(device)s updated. Details: %(details)s"),
                          {'device': device, 'details': details})
-                self.treat_vif_port(port, details['port_id'],
-                                    details['network_id'],
-                                    details['network_type'],
-                                    details['physical_network'],
-                                    details['segmentation_id'],
-                                    details['admin_state_up'],
-                                    details['fixed_ips'],
-                                    details['device_owner'],
-                                    ovs_restarted)
+                need_binding = self.treat_vif_port(port, details['port_id'],
+                                                   details['network_id'],
+                                                   details['network_type'],
+                                                   details['physical_network'],
+                                                   details['segmentation_id'],
+                                                   details['admin_state_up'],
+                                                   details['fixed_ips'],
+                                                   details['device_owner'],
+                                                   ovs_restarted)
                 if self.prevent_arp_spoofing:
                     self.setup_arp_spoofing_protection(self.int_br,
                                                        port, details)
-                # 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 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)
+                if need_binding:
+                    details['vif_port'] = port
+                    need_binding_devices.append(details)
             else:
                 LOG.warn(_LW("Device %s not defined on plugin"), device)
                 if (port and port.ofport != -1):
                     self.port_dead(port)
-        return skipped_devices
+        return skipped_devices, need_binding_devices
 
     def treat_ancillary_devices_added(self, devices):
         try:
@@ -1344,10 +1390,6 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin,
         # sources: the neutron server, and the ovs db monitor process
         # If there is an exception while processing security groups ports
         # 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.
         # 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.
@@ -1358,8 +1400,9 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin,
         if devices_added_updated:
             start = time.time()
             try:
-                skipped_devices = self.treat_devices_added_or_updated(
-                    devices_added_updated, ovs_restarted)
+                skipped_devices, need_binding_devices = (
+                    self.treat_devices_added_or_updated(
+                        devices_added_updated, ovs_restarted))
                 LOG.debug("process_network_ports - iteration:%(iter_num)d - "
                           "treat_devices_added_or_updated completed. "
                           "Skipped %(num_skipped)d devices of "
@@ -1369,6 +1412,12 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin,
                            'num_skipped': len(skipped_devices),
                            'num_current': len(port_info['current']),
                            '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
                 # have been actually processed.
                 port_info['current'] = (port_info['current'] -
index cca76a4e5b269e7d1a5a9eab7892d6baf2001eb1..4fa622ccdbb34eb9a81d50bde952b63e953cf03b 100644 (file)
@@ -56,8 +56,12 @@ class BaseIptablesFirewallTestCase(base.BaseTestCase):
         self.iptables_inst = mock.Mock()
         self.v4filter_inst = mock.Mock()
         self.v6filter_inst = mock.Mock()
-        self.iptables_inst.ipv4 = {'filter': self.v4filter_inst}
-        self.iptables_inst.ipv6 = {'filter': self.v6filter_inst}
+        self.iptables_inst.ipv4 = {'filter': self.v4filter_inst,
+                                   'raw': self.v4filter_inst
+                                   }
+        self.iptables_inst.ipv6 = {'filter': self.v6filter_inst,
+                                   'raw': self.v6filter_inst
+                                   }
         iptables_cls.return_value = self.iptables_inst
 
         self.firewall = iptables_firewall.IptablesFirewallDriver()
@@ -69,6 +73,7 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):
     def _fake_port(self):
         return {'device': 'tapfake_dev',
                 'mac_address': 'ff:ff:ff:ff:ff:ff',
+                'network_id': 'fake_net',
                 'fixed_ips': [FAKE_IP['IPv4'],
                               FAKE_IP['IPv6']]}
 
@@ -921,7 +926,7 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):
                                     '-m physdev --physdev-out tapfake_dev '
                                     '--physdev-is-bridged '
                                     '-j $ifake_dev',
-                                    comment=ic.SG_TO_VM_SG),
+                                    comment=ic.SG_TO_VM_SG)
                  ]
         if ethertype == 'IPv6':
             for icmp6_type in constants.ICMPV6_ALLOWED_TYPES:
@@ -1247,8 +1252,8 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):
 
     def test_defer_chain_apply_coalesce_multiple_ports(self):
         chain_applies = self._mock_chain_applies()
-        port1 = {'device': 'd1', 'mac_address': 'mac1'}
-        port2 = {'device': 'd2', 'mac_address': 'mac2'}
+        port1 = {'device': 'd1', 'mac_address': 'mac1', 'network_id': 'net1'}
+        port2 = {'device': 'd2', 'mac_address': 'mac2', 'network_id': 'net1'}
         device2port = {'d1': port1, 'd2': port2}
         with self.firewall.defer_apply():
             self.firewall.prepare_port_filter(port1)
@@ -1259,6 +1264,7 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):
     def test_ip_spoofing_filter_with_multiple_ips(self):
         port = {'device': 'tapfake_dev',
                 'mac_address': 'ff:ff:ff:ff:ff:ff',
+                'network_id': 'fake_net',
                 'fixed_ips': ['10.0.0.1', 'fe80::1', '10.0.0.2']}
         self.firewall.prepare_port_filter(port)
         calls = [mock.call.add_chain('sg-fallback'),
@@ -1338,6 +1344,7 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):
     def test_ip_spoofing_no_fixed_ips(self):
         port = {'device': 'tapfake_dev',
                 'mac_address': 'ff:ff:ff:ff:ff:ff',
+                'network_id': 'fake_net',
                 'fixed_ips': []}
         self.firewall.prepare_port_filter(port)
         calls = [mock.call.add_chain('sg-fallback'),
@@ -1421,6 +1428,7 @@ class IptablesFirewallEnhancedIpsetTestCase(BaseIptablesFirewallTestCase):
     def _fake_port(self, sg_id=FAKE_SGID):
         return {'device': 'tapfake_dev',
                 'mac_address': 'ff:ff:ff:ff:ff:ff',
+                'network_id': 'fake_net',
                 'fixed_ips': [FAKE_IP['IPv4'],
                               FAKE_IP['IPv6']],
                 'security_groups': [sg_id],
index 4a1457c07b7bb10db7002886c5912ec369e36989..5b8dcb1df2a618ea7e3aae459b377808ab0d6269 100644 (file)
@@ -314,7 +314,7 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
         ]
         if use_ipv6:
             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)
 
@@ -374,7 +374,7 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
         ]
         if use_ipv6:
             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)
 
@@ -421,7 +421,7 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
         ]
         if use_ipv6:
             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)
 
@@ -452,6 +452,8 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
         iptables_args['filter_rules'] = filter_rules
         filter_dump_mod = FILTER_WITH_RULES_TEMPLATE % iptables_args
 
+        raw_dump = RAW_DUMP % IPTABLES_ARG
+
         expected_calls_and_values = [
             (mock.call(['iptables-save', '-c'],
                        run_as_root=True),
@@ -473,7 +475,7 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
         ]
         if use_ipv6:
             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)
 
@@ -533,6 +535,8 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
                            '# Completed by iptables_manager\n'
                            % iptables_args)
 
+        raw_dump = RAW_DUMP % IPTABLES_ARG
+
         expected_calls_and_values = [
             (mock.call(['iptables-save', '-c'],
                        run_as_root=True),
@@ -553,7 +557,7 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
         ]
         if use_ipv6:
             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)
 
@@ -624,7 +628,7 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
         ]
         if use_ipv6:
             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)
 
@@ -680,6 +684,8 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
                         '# Completed by iptables_manager\n'
                         % IPTABLES_ARG)
 
+        raw_dump = RAW_DUMP % IPTABLES_ARG
+
         expected_calls_and_values = [
             (mock.call(['iptables-save', '-c'],
                        run_as_root=True),
@@ -700,7 +706,7 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
         ]
         if use_ipv6:
             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)
 
@@ -769,7 +775,7 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
         ]
         if use_ipv6:
             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)
 
@@ -911,6 +917,10 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
              ''),
         ]
         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(
                 (mock.call(['ip6tables', '-t', 'filter', '-L', 'OUTPUT',
                            '-n', '-v', '-x'],
@@ -960,6 +970,10 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
              '')
         ]
         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(
                 (mock.call(['ip6tables', '-t', 'filter', '-L', 'OUTPUT',
                             '-n', '-v', '-x', '-Z'],
index 8dd6c90b0a651df325cdfe099ebc760addf99715..0cb587f7de57f715b304efd6b92828dd0db0a91f 100644 (file)
@@ -13,9 +13,9 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import collections
 import contextlib
 
-import collections
 import mock
 from oslo_config import cfg
 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 securitygroup as ext_sg
 from neutron import manager
+from neutron.plugins.openvswitch.agent import ovs_neutron_agent
 from neutron.tests import base
 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.agent.firewall = self.firewall
         self.fake_device = {'device': 'fake_device',
+                            'network_id': 'fake_net',
                             'security_groups': ['fake_sgid1', 'fake_sgid2'],
                             'security_group_source_groups': ['fake_sgid2'],
                             'security_group_rules': [{'security_group_id':
@@ -1667,6 +1669,42 @@ IPTABLES_ARG['ip1'] = IPS.values()[0]
 IPTABLES_ARG['ip2'] = IPS.values()[1]
 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
 *nat
 :neutron-postrouting-bottom - [0:0]
@@ -2469,9 +2507,7 @@ class TestSecurityGroupAgentWithIptables(base.BaseTestCase):
         cfg.CONF.set_override('comment_iptables_rules', False, group='AGENT')
 
         self.rpc = mock.Mock()
-        self.agent = sg_rpc.SecurityGroupAgentRpc(
-                context=None, plugin_rpc=self.rpc,
-                defer_refresh_firewall=defer_refresh_firewall)
+        self._init_agent(defer_refresh_firewall)
 
         if test_rpc_v1_1:
             self.rpc.security_group_info_for_devices.side_effect = (
@@ -2542,8 +2578,14 @@ class TestSecurityGroupAgentWithIptables(base.BaseTestCase):
                                                    '12:34:56:78:9a:bd',
                                                    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):
         return {'device': device,
+                'network_id': 'fakenet',
                 'fixed_ips': [ip],
                 'mac_address': mac_address,
                 'security_groups': ['security_group1'],
@@ -2588,14 +2630,14 @@ class TestSecurityGroupAgentWithIptables(base.BaseTestCase):
             self.assertThat(kwargs['process_input'],
                             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(
             ['iptables-save', '-c'],
             run_as_root=True,
             return_value='')
         self._register_mock_call(
             ['iptables-restore', '-c'],
-            process_input=self._regex(IPTABLES_RAW + IPTABLES_NAT +
+            process_input=self._regex(raw + IPTABLES_NAT +
                                       IPTABLES_MANGLE + v4_filter),
             run_as_root=True,
             return_value='')
@@ -2605,14 +2647,16 @@ class TestSecurityGroupAgentWithIptables(base.BaseTestCase):
             return_value='')
         self._register_mock_call(
             ['ip6tables-restore', '-c'],
-            process_input=self._regex(v6_filter),
+            process_input=self._regex(raw + v6_filter),
             run_as_root=True,
             return_value='')
 
     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)
-        self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY)
+        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.remove_devices_filter(['tap_port1'])
@@ -2621,12 +2665,18 @@ 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)
-        self._replay_iptables(IPTABLES_FILTER_1_2, IPTABLES_FILTER_V6_1)
-        self._replay_iptables(IPTABLES_FILTER_2, IPTABLES_FILTER_V6_2)
-        self._replay_iptables(IPTABLES_FILTER_2_2, IPTABLES_FILTER_V6_2)
-        self._replay_iptables(IPTABLES_FILTER_1, IPTABLES_FILTER_V6_1)
-        self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY)
+        self._replay_iptables(IPTABLES_FILTER_1, IPTABLES_FILTER_V6_1,
+                              IPTABLES_RAW_DEFAULT)
+        self._replay_iptables(IPTABLES_FILTER_1_2, IPTABLES_FILTER_V6_1,
+                              IPTABLES_RAW_DEFAULT)
+        self._replay_iptables(IPTABLES_FILTER_2, IPTABLES_FILTER_V6_2,
+                              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.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):
         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_3, IPTABLES_FILTER_V6_2)
+        self._replay_iptables(IPTABLES_FILTER_2, 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.rpc.security_group_rules_for_devices.return_value = self.devices3
@@ -2713,8 +2765,10 @@ class TestSecurityGroupAgentEnhancedRpcWithIptables(
 
     def test_prepare_remove_port(self):
         self.sg_info.return_value = self.devices_info1
-        self._replay_iptables(IPTABLES_FILTER_1, IPTABLES_FILTER_V6_1)
-        self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY)
+        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.remove_devices_filter(['tap_port1'])
@@ -2723,12 +2777,18 @@ 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)
-        self._replay_iptables(IPTABLES_FILTER_1_2, IPTABLES_FILTER_V6_1)
-        self._replay_iptables(IPTABLES_FILTER_2, IPTABLES_FILTER_V6_2)
-        self._replay_iptables(IPTABLES_FILTER_2_2, IPTABLES_FILTER_V6_2)
-        self._replay_iptables(IPTABLES_FILTER_1, IPTABLES_FILTER_V6_1)
-        self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY)
+        self._replay_iptables(IPTABLES_FILTER_1, IPTABLES_FILTER_V6_1,
+                              IPTABLES_RAW_DEFAULT)
+        self._replay_iptables(IPTABLES_FILTER_1_2, IPTABLES_FILTER_V6_1,
+                              IPTABLES_RAW_DEFAULT)
+        self._replay_iptables(IPTABLES_FILTER_2, IPTABLES_FILTER_V6_2,
+                              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.sg_info.return_value = self.devices_info2
@@ -2743,8 +2803,10 @@ 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)
-        self._replay_iptables(IPTABLES_FILTER_2_3, IPTABLES_FILTER_V6_2)
+        self._replay_iptables(IPTABLES_FILTER_2, 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.sg_info.return_value = self.devices_info3
@@ -2765,8 +2827,10 @@ class TestSecurityGroupAgentEnhancedIpsetWithIptables(
 
     def test_prepare_remove_port(self):
         self.sg_info.return_value = self.devices_info1
-        self._replay_iptables(IPSET_FILTER_1, IPTABLES_FILTER_V6_1)
-        self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY)
+        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.remove_devices_filter(['tap_port1'])
@@ -2775,12 +2839,18 @@ class TestSecurityGroupAgentEnhancedIpsetWithIptables(
 
     def test_security_group_member_updated(self):
         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_2, IPTABLES_FILTER_V6_2)
-        self._replay_iptables(IPSET_FILTER_2, IPTABLES_FILTER_V6_2)
-        self._replay_iptables(IPSET_FILTER_1, IPTABLES_FILTER_V6_1)
-        self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY)
+        self._replay_iptables(IPSET_FILTER_1, IPTABLES_FILTER_V6_1,
+                              IPTABLES_RAW_DEFAULT)
+        self._replay_iptables(IPSET_FILTER_1, IPTABLES_FILTER_V6_1,
+                              IPTABLES_RAW_DEFAULT)
+        self._replay_iptables(IPSET_FILTER_2, IPTABLES_FILTER_V6_2,
+                              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.sg_info.return_value = self.devices_info2
@@ -2795,8 +2865,10 @@ class TestSecurityGroupAgentEnhancedIpsetWithIptables(
 
     def test_security_group_rule_updated(self):
         self.sg_info.return_value = self.devices_info2
-        self._replay_iptables(IPSET_FILTER_2, IPTABLES_FILTER_V6_2)
-        self._replay_iptables(IPSET_FILTER_2_3, IPTABLES_FILTER_V6_2)
+        self._replay_iptables(IPSET_FILTER_2, 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.sg_info.return_value = self.devices_info3
@@ -2858,11 +2930,77 @@ class TestSecurityGroupAgentWithOVSIptables(
 
     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):
         #Note(nati): tap is prefixed on the device
         # in the OVSHybridIptablesFirewallDriver
 
         value = value.replace('tap_port', 'taptap_port')
+        value = value.replace('qvbtaptap_port', 'qvbtap_port')
         value = value.replace('o_port', 'otap_port')
         value = value.replace('i_port', 'itap_port')
         value = value.replace('s_port', 'stap_port')
index 1b8b73f16cf2d5d4a0a8eb2623e17a3da496d6c5..d201574527e7f9e560a33265139802d50c86106b 100644 (file)
@@ -134,7 +134,9 @@ class TestOvsNeutronAgent(base.BaseTestCase):
             mock.patch('neutron.agent.common.ovs_lib.BaseOVS.get_bridges'),
             mock.patch('neutron.openstack.common.loopingcall.'
                        '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)
             # set back to true because initial report state will succeed due
             # to mocked out RPC calls
@@ -157,22 +159,17 @@ class TestOvsNeutronAgent(base.BaseTestCase):
             mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
                        'set_db_attribute', return_value=True),
             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')
         ) as (set_ovs_db_func, get_ovs_db_func, delete_flows_func):
             self.agent.port_bound(port, net_uuid, 'local', None, None,
                                   fixed_ips, "compute:None", False)
-        get_ovs_db_func.assert_called_once_with("Port", mock.ANY, "tag")
-        if new_local_vlan != old_local_vlan:
-            set_ovs_db_func.assert_called_once_with(
-                "Port", mock.ANY, "tag", new_local_vlan)
-            if ofport != -1:
-                delete_flows_func.assert_called_once_with(in_port=port.ofport)
-            else:
-                self.assertFalse(delete_flows_func.called)
-        else:
-            self.assertFalse(set_ovs_db_func.called)
-            self.assertFalse(delete_flows_func.called)
+        vlan_mapping = {'net_uuid': net_uuid,
+                        'network_type': 'local',
+                        'physical_network': None,
+                        'segmentation_id': None}
+        set_ovs_db_func.assert_called_once_with(
+            "Port", mock.ANY, "other_config", vlan_mapping)
 
     def test_check_agent_configurations_for_dvr_raises(self):
         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, func_name)
         ) 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
             self.assertFalse(skip_devs)
         return func.called
@@ -379,18 +377,13 @@ class TestOvsNeutronAgent(base.BaseTestCase):
                               return_value=[dev_mock]),
             mock.patch.object(self.agent.int_br, 'get_vif_port_by_id',
                               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')
-        ) as (get_dev_fn, get_vif_func, upd_dev_up,
-              upd_dev_down, treat_vif_port):
+        ) as (get_dev_fn, get_vif_func, treat_vif_port):
             skip_devs = self.agent.treat_devices_added_or_updated([{}], False)
             # The function should return False for resync and no device
             # processed
-            self.assertEqual(['the_skipped_one'], skip_devs)
+            self.assertEqual((['the_skipped_one'], []), skip_devs)
             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):
         fake_details_dict = {'admin_state_up': False,
@@ -411,16 +404,13 @@ class TestOvsNeutronAgent(base.BaseTestCase):
                               return_value=[fake_details_dict]),
             mock.patch.object(self.agent.int_br, 'get_vif_port_by_id',
                               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')
-        ) as (get_dev_fn, get_vif_func, upd_dev_up,
-              upd_dev_down, treat_vif_port):
-            skip_devs = self.agent.treat_devices_added_or_updated([{}], False)
+        ) as (get_dev_fn, get_vif_func, treat_vif_port):
+            skip_devs, need_bound_devices = (
+                self.agent.treat_devices_added_or_updated([{}], False))
             # The function should return False for resync
             self.assertFalse(skip_devs)
             self.assertTrue(treat_vif_port.called)
-            self.assertTrue(upd_dev_down.called)
 
     def test_treat_devices_removed_returns_true_for_missing_device(self):
         with mock.patch.object(self.agent.plugin_rpc, 'update_device_down',
@@ -445,7 +435,7 @@ class TestOvsNeutronAgent(base.BaseTestCase):
         with contextlib.nested(
             mock.patch.object(self.agent.sg_agent, "setup_port_filters"),
             mock.patch.object(self.agent, "treat_devices_added_or_updated",
-                              return_value=[]),
+                              return_value=([], [])),
             mock.patch.object(self.agent, "treat_devices_removed",
                               return_value=False)
         ) as (setup_port_filters, device_added_updated, device_removed):
@@ -1267,7 +1257,9 @@ class AncillaryBridgesTest(base.BaseTestCase):
                        return_value=bridges),
             mock.patch('neutron.agent.common.ovs_lib.BaseOVS.'
                        '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.assertEqual(len(ancillary), len(self.agent.ancillary_brs))
             if ancillary:
@@ -1326,7 +1318,9 @@ class TestOvsDvrNeutronAgent(base.BaseTestCase):
             mock.patch('neutron.agent.common.ovs_lib.BaseOVS.get_bridges'),
             mock.patch('neutron.openstack.common.loopingcall.'
                        '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)
             # set back to true because initial report state will succeed due
             # to mocked out RPC calls
@@ -1383,13 +1377,14 @@ class TestOvsDvrNeutronAgent(base.BaseTestCase):
         physical_network = self._physical_network
         segmentation_id = self._segmentation_id
         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',
-                        return_value=True):
-            with contextlib.nested(
+                        return_value=True),
                 mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
                            'db_get_val',
-                           return_value=self._old_local_vlan),
+                           return_value={})):
+            with contextlib.nested(
                 mock.patch.object(self.agent.dvr_agent.plugin_rpc,
                                   'get_subnet_for_dvr',
                                   return_value={
@@ -1398,13 +1393,12 @@ class TestOvsDvrNeutronAgent(base.BaseTestCase):
                                       'ip_version': ip_version,
                                       'gateway_mac': gateway_mac}),
                 mock.patch.object(self.agent.dvr_agent.plugin_rpc,
-                    'get_ports_on_host_by_subnet',
-                    return_value=[]),
+                                  'get_ports_on_host_by_subnet',
+                                  return_value=[]),
                 mock.patch.object(self.agent.dvr_agent.int_br,
                                   'get_vif_port_by_id',
                                   return_value=self._port),
                 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, 'delete_flows'),
                 mock.patch.object(
@@ -1413,8 +1407,8 @@ class TestOvsDvrNeutronAgent(base.BaseTestCase):
                 mock.patch.object(
                     self.agent.dvr_agent.phys_brs[physical_network],
                     'delete_flows')
-            ) as (get_ovs_db_func, get_subnet_fn, get_cphost_fn,
-                  get_vif_fn, add_flow_int_fn, delete_flows_int_fn,
+            ) as (get_subnet_fn, get_cphost_fn,
+                  get_vif_fn, add_flow_int_fn,
                   add_flow_tun_fn, delete_flows_tun_fn, add_flow_phys_fn,
                   delete_flows_phys_fn):
                 self.agent.port_bound(
@@ -1479,12 +1473,6 @@ class TestOvsDvrNeutronAgent(base.BaseTestCase):
                                       ]
                 self.assertEqual(expected_on_int_br,
                                  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(delete_flows_tun_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'
         physical_network = self._physical_network
         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',
-                        return_value=True):
-            with contextlib.nested(
+                        return_value=True),
                 mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
                            'db_get_val',
-                           return_value=self._old_local_vlan),
+                           return_value={})):
+            with contextlib.nested(
                 mock.patch.object(self.agent.dvr_agent.plugin_rpc,
                                   'get_subnet_for_dvr',
                                   return_value={
@@ -1524,7 +1513,6 @@ class TestOvsDvrNeutronAgent(base.BaseTestCase):
                                   'get_vif_port_by_id',
                                   return_value=self._port),
                 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, 'delete_flows'),
                 mock.patch.object(
@@ -1533,8 +1521,8 @@ class TestOvsDvrNeutronAgent(base.BaseTestCase):
                 mock.patch.object(
                     self.agent.dvr_agent.phys_brs[physical_network],
                     'delete_flows')
-            ) as (get_ovs_db_func, get_subnet_fn, get_cphost_fn,
-                  get_vif_fn, add_flow_int_fn, delete_flows_int_fn,
+            ) as (get_subnet_fn, get_cphost_fn,
+                  get_vif_fn, add_flow_int_fn,
                   add_flow_tun_fn, delete_flows_tun_fn,
                   add_flow_phys_fn, delete_flows_phys_fn):
                 self.agent.port_bound(
@@ -1593,12 +1581,6 @@ class TestOvsDvrNeutronAgent(base.BaseTestCase):
                 self.assertEqual(expected_on_int_br,
                                  add_flow_int_fn.call_args_list)
                 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(delete_flows_tun_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):
         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',
-                        return_value=True):
-            with contextlib.nested(
+                        return_value=True),
                 mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
                            'db_get_val',
-                           return_value=self._old_local_vlan),
+                           return_value={})):
+            with contextlib.nested(
                 mock.patch.object(
                     self.agent.dvr_agent.plugin_rpc, 'get_subnet_for_dvr',
                     return_value={'gateway_ip': '1.1.1.1',
@@ -1655,11 +1638,10 @@ class TestOvsDvrNeutronAgent(base.BaseTestCase):
                                   'get_vif_port_by_id',
                                   return_value=self._port),
                 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, 'delete_flows')
-            ) as (get_ovs_db_func, get_subnet_fn, get_cphost_fn,
-                  get_vif_fn, add_flow_int_fn, delete_flows_int_fn,
+            ) as (get_subnet_fn, get_cphost_fn,
+                  get_vif_fn, add_flow_int_fn,
                   add_flow_tun_fn, delete_flows_tun_fn):
                 self.agent.port_bound(
                     self._port, self._net_uuid, 'vxlan',
@@ -1667,7 +1649,6 @@ class TestOvsDvrNeutronAgent(base.BaseTestCase):
                     n_const.DEVICE_OWNER_ROUTER_SNAT,
                     False)
                 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):
         self._test_treat_devices_removed_for_dvr_interface(ofport)
@@ -1683,13 +1664,14 @@ class TestOvsDvrNeutronAgent(base.BaseTestCase):
         else:
             gateway_ip = '2001:100::1'
             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',
-                        return_value=True):
-            with contextlib.nested(
+                        return_value=True),
                 mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
                            'db_get_val',
-                           return_value=self._old_local_vlan),
+                           return_value={})):
+            with contextlib.nested(
                 mock.patch.object(
                     self.agent.dvr_agent.plugin_rpc, 'get_subnet_for_dvr',
                     return_value={'gateway_ip': gateway_ip,
@@ -1703,11 +1685,10 @@ class TestOvsDvrNeutronAgent(base.BaseTestCase):
                                   'get_vif_port_by_id',
                                   return_value=self._port),
                 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, 'delete_flows')
-            ) as (get_ovs_db_func, get_subnet_fn, get_cphost_fn,
-                  get_vif_fn, add_flow_int_fn, delete_flows_int_fn,
+            ) as (get_subnet_fn, get_cphost_fn,
+                  get_vif_fn, add_flow_int_fn,
                   add_flow_tun_fn, delete_flows_tun_fn):
                 self.agent.port_bound(
                     self._port, self._net_uuid, 'vxlan',
@@ -1715,7 +1696,6 @@ class TestOvsDvrNeutronAgent(base.BaseTestCase):
                     n_const.DEVICE_OWNER_DVR_INTERFACE,
                     False)
                 self.assertTrue(add_flow_tun_fn.called)
-                self.assertTrue(delete_flows_int_fn.called)
 
         with contextlib.nested(
             mock.patch.object(self.agent, 'reclaim_local_vlan'),
@@ -1764,13 +1744,14 @@ class TestOvsDvrNeutronAgent(base.BaseTestCase):
         else:
             gateway_ip = '2001:100::1'
             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',
-                        return_value=True):
-            with contextlib.nested(
+                        return_value=True),
                 mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
                            'db_get_val',
-                           return_value=self._old_local_vlan),
+                           return_value={})):
+            with contextlib.nested(
                 mock.patch.object(
                     self.agent.dvr_agent.plugin_rpc, 'get_subnet_for_dvr',
                     return_value={'gateway_ip': gateway_ip,
@@ -1784,11 +1765,10 @@ class TestOvsDvrNeutronAgent(base.BaseTestCase):
                                   'get_vif_port_by_id',
                                   return_value=self._port),
                 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, 'delete_flows')
-            ) as (get_ovs_db_func, get_subnet_fn, get_cphost_fn,
-                  get_vif_fn, add_flow_int_fn, delete_flows_int_fn,
+            ) as (get_subnet_fn, get_cphost_fn,
+                  get_vif_fn, add_flow_int_fn,
                   add_flow_tun_fn, delete_flows_tun_fn):
                 self.agent.port_bound(
                     self._port, self._net_uuid, 'vxlan',
@@ -1802,7 +1782,6 @@ class TestOvsDvrNeutronAgent(base.BaseTestCase):
                                       device_owner, False)
                 self.assertTrue(add_flow_tun_fn.called)
                 self.assertTrue(add_flow_int_fn.called)
-                self.assertTrue(delete_flows_int_fn.called)
 
         with contextlib.nested(
             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):
         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',
-                        return_value=True):
-            with contextlib.nested(
+                        return_value=True),
                 mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
                            'db_get_val',
-                           return_value=self._old_local_vlan),
+                           return_value={})):
+            with contextlib.nested(
                 mock.patch.object(
                     self.agent.dvr_agent.plugin_rpc, 'get_subnet_for_dvr',
                     return_value={'gateway_ip': '1.1.1.1',
@@ -1861,11 +1841,10 @@ class TestOvsDvrNeutronAgent(base.BaseTestCase):
                                   'get_vif_port_by_id',
                                   return_value=self._port),
                 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, 'delete_flows')
-            ) as (get_ovs_db_func, get_subnet_fn, get_cphost_fn,
-                  get_vif_fn, add_flow_int_fn, delete_flows_int_fn,
+            ) as (get_subnet_fn, get_cphost_fn,
+                  get_vif_fn, add_flow_int_fn,
                   add_flow_tun_fn, delete_flows_tun_fn):
                 self.agent.port_bound(
                     self._port, self._net_uuid, 'vxlan',
@@ -1873,7 +1852,6 @@ class TestOvsDvrNeutronAgent(base.BaseTestCase):
                     n_const.DEVICE_OWNER_ROUTER_SNAT,
                     False)
                 self.assertTrue(add_flow_int_fn.called)
-                self.assertTrue(delete_flows_int_fn.called)
 
         with contextlib.nested(
             mock.patch.object(self.agent, 'reclaim_local_vlan'),
index cd21d0477caa82c3de31335595f361efa3c762de..7773d5a0ea73eb14cea099e166e18fcf3d69fdeb 100644 (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_patch_port.side_effect = (
             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.br_name = self.MAP_TUN_BRIDGE
@@ -190,7 +192,10 @@ class TunnelTest(base.BaseTestCase):
             mock.call.add_patch_port('patch-int', 'patch-tun'),
         ]
         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 += [
@@ -437,12 +442,15 @@ class TunnelTest(base.BaseTestCase):
         self._verify_mock_calls()
 
     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 += [
-            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,
-                                       'tag', LVM.vlan),
-            mock.call.delete_flows(in_port=VIF_PORT.ofport)
-        ]
+                                       'other_config',
+                                       vlan_mapping)]
 
         a = self._build_agent()
         a.local_vlan_map[NET_UUID] = LVM
@@ -610,7 +618,9 @@ class TunnelTestUseVethInterco(TunnelTest):
         self.mock_int_bridge_expected += [
             mock.call.add_patch_port('patch-tun', 'patch-int')
         ]
-
+        self.mock_int_bridge_expected += [
+            mock.call.get_vif_ports(),
+        ]
         self.mock_tun_bridge_expected += [
             mock.call.remove_all_flows(),
             mock.call.add_flow(priority=1,