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 64bd00b3e6d..6db62b79068 100644 --- a/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_neutron_agent.py +++ b/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_neutron_agent.py @@ -1576,28 +1576,13 @@ class OVSNeutronAgent(l2population_rpc.L2populationRpcCallBackTunnelMixin, self.int_ofports[physical_network] = int_ofport self.phys_ofports[physical_network] = phys_ofport - # following drop operations are not necessary for - # dvr agent setup_dvr_flows. So skip it if dvr enabled - # the reason is for br_int it is duplicate - # for br_physical drop_port is dangerous because when dvr - # enabled the highest flow on table=0 is 2 which means - # basically everything will be dropped until setup_dvr_flows - # got executed. + # Drop packets from physical bridges that have not matched a higher + # priority flow to set a local vlan. This prevents these stray + # packets from being forwarded to other physical bridges which + # could cause a network loop in the physical network. + self.int_br.drop_port(in_port=int_ofport) + if not self.enable_distributed_routing: - # These two drop flows are the root cause for the bug #1803919. - # And now we add a rpc check during agent start procedure. If - # ovs agent can not reach any neutron server, or all neutron - # servers are down, these flows will not be installed anymore. - # Bug #1803919 was fixed in that way. - # And as a reminder, we can not do much work on this. Because - # the bridge mappings can be varied. Provider (external) - # network can be implicitly set on any physical bridge - # due to the basic NORMAL flow. - # Different vlan range networks can also have many - # bridge map settings, these tenant network traffic can also be - # blocked by the following drop flows. - # block all untranslated traffic between bridges - self.int_br.drop_port(in_port=int_ofport) br.drop_port(in_port=phys_ofport) if self.use_veth_interconnection: 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 d8c85ccd1a9..c2bc9106cbf 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 @@ -1514,7 +1514,9 @@ class TestOvsNeutronAgent(object): self.assertIn('added_port_id', port_info['added']) self.assertNotIn('activated_port_id', port_info['added']) - def _test_setup_physical_bridges(self, port_exists=False): + def _test_setup_physical_bridges(self, port_exists=False, + dvr_enabled=False): + self.agent.enable_distributed_routing = dvr_enabled with mock.patch.object(ip_lib.IPDevice, "exists") as devex_fn,\ mock.patch.object(sys, "exit"),\ mock.patch.object(self.agent, 'br_phys_cls') as phys_br_cls,\ @@ -1571,8 +1573,13 @@ class TestOvsNeutronAgent(object): 'phy-br-eth', constants.NONEXISTENT_PEER), ] expected_calls += [ - mock.call.int_br.drop_port(in_port='int_ofport'), - mock.call.phys_br.drop_port(in_port='phy_ofport'), + mock.call.int_br.drop_port(in_port='int_ofport') + ] + if not dvr_enabled: + expected_calls += [ + mock.call.phys_br.drop_port(in_port='phy_ofport') + ] + expected_calls += [ mock.call.int_br.set_db_attribute('Interface', 'int-br-eth', 'options', {'peer': 'phy-br-eth'}), @@ -1592,6 +1599,9 @@ class TestOvsNeutronAgent(object): def test_setup_physical_bridges_port_exists(self): self._test_setup_physical_bridges(port_exists=True) + def test_setup_physical_bridges_dvr_enabled(self): + self._test_setup_physical_bridges(dvr_enabled=True) + def test_setup_physical_bridges_using_veth_interconnection(self): self.agent.use_veth_interconnection = True with mock.patch.object(ip_lib.IPDevice, "exists") as devex_fn,\