diff --git a/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_neutron_agent.py b/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_neutron_agent.py index ae1a2899e39..e27b8584a2e 100644 --- a/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_neutron_agent.py +++ b/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_neutron_agent.py @@ -470,6 +470,7 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin, if not self.l2_pop: self._setup_tunnel_port(self.tun_br, tun_name, tunnel_ip, tunnel_type) + self._setup_tunnel_flood_flow(self.tun_br, tunnel_type) def tunnel_delete(self, context, **kwargs): LOG.debug("tunnel_delete received") @@ -1440,7 +1441,9 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin, # Add flow in default table to resubmit to the right # tunneling table (lvid will be set in the latter) br.setup_tunnel_port(tunnel_type, ofport) + return ofport + def _setup_tunnel_flood_flow(self, br, tunnel_type): ofports = self.tun_br_ofports[tunnel_type].values() if ofports and not self.l2_pop: # Update flooding flows to include the new tunnel @@ -1449,7 +1452,6 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin, br.install_flood_to_tun(vlan_mapping.vlan, vlan_mapping.segmentation_id, ofports) - return ofport def setup_tunnel_port(self, br, remote_ip, network_type): port_name = self.get_tunnel_name( @@ -1460,6 +1462,7 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin, port_name, remote_ip, network_type) + self._setup_tunnel_flood_flow(br, network_type) return ofport def cleanup_tunnel_port(self, br, tun_ofport, tunnel_type): @@ -1712,6 +1715,7 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin, tun_name, tunnel['ip_address'], tunnel_type) + self._setup_tunnel_flood_flow(self.tun_br, tunnel_type) except Exception as e: LOG.debug("Unable to sync tunnel IP %(local_ip)s: %(e)s", {'local_ip': self.local_ip, 'e': e}) diff --git a/neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/test_ovs_neutron_agent.py b/neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/test_ovs_neutron_agent.py index f08b205fd37..6c097ff7cd2 100644 --- a/neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/test_ovs_neutron_agent.py +++ b/neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/test_ovs_neutron_agent.py @@ -1735,6 +1735,28 @@ class TestOvsNeutronAgent(object): 'vxlan') self.assertEqual([], cleanup.mock_calls) + def test_tunnel_sync_setup_tunnel_flood_flow_once(self): + fake_tunnel_details = {'tunnels': [{'ip_address': '200.200.200.200'}, + {'ip_address': '100.100.100.100'}]} + with mock.patch.object(self.agent.plugin_rpc, + 'tunnel_sync', + return_value=fake_tunnel_details),\ + mock.patch.object( + self.agent, + '_setup_tunnel_port') as _setup_tunnel_port_fn,\ + mock.patch.object( + self.agent, + '_setup_tunnel_flood_flow') as _setup_tunnel_flood_flow: + self.agent.tunnel_types = ['vxlan'] + self.agent.tunnel_sync() + expected_calls = [mock.call(self.agent.tun_br, 'vxlan-c8c8c8c8', + '200.200.200.200', 'vxlan'), + mock.call(self.agent.tun_br, 'vxlan-64646464', + '100.100.100.100', 'vxlan')] + _setup_tunnel_port_fn.assert_has_calls(expected_calls) + _setup_tunnel_flood_flow.assert_called_once_with(self.agent.tun_br, + 'vxlan') + def test_tunnel_update(self): kwargs = {'tunnel_ip': '10.10.10.10', 'tunnel_type': 'gre'} @@ -2053,6 +2075,7 @@ class TestOvsNeutronAgent(object): bridge.install_flood_to_tun.side_effect = add_new_vlan_mapping self.agent._setup_tunnel_port(bridge, 1, '1.2.3.4', tunnel_type=tunnel_type) + self.agent._setup_tunnel_flood_flow(bridge, tunnel_type) self.assertIn('bar', self.agent.vlan_manager) def test_setup_entry_for_arp_reply_ignores_ipv6_addresses(self):