From d2073d655694f8b7e9b4c4440a81e31a4b582c81 Mon Sep 17 00:00:00 2001 From: LIU Yulong Date: Thu, 4 Feb 2021 14:09:10 +0800 Subject: [PATCH] Remove flows for ARP reply MAC change When router interface is removing, delete the related ARP reply MAC change flow. This is a follow-up of: https://review.opendev.org/c/openstack/neutron/+/773597 Closes-Bug: #1913646 Related-Bug: #1859638 Change-Id: Ieb8886f68a80ac213fa08013ea73099d29597395 --- .../agent/openflow/native/br_dvr_process.py | 10 ++++++++++ .../openvswitch/agent/ovs_dvr_neutron_agent.py | 7 +++++++ .../openvswitch/agent/test_ovs_neutron_agent.py | 15 +++++++++++++-- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/neutron/plugins/ml2/drivers/openvswitch/agent/openflow/native/br_dvr_process.py b/neutron/plugins/ml2/drivers/openvswitch/agent/openflow/native/br_dvr_process.py index 5182abee6c6..204fb956f7a 100644 --- a/neutron/plugins/ml2/drivers/openvswitch/agent/openflow/native/br_dvr_process.py +++ b/neutron/plugins/ml2/drivers/openvswitch/agent/openflow/native/br_dvr_process.py @@ -24,6 +24,16 @@ from neutron.plugins.ml2.drivers.openvswitch.agent.common import constants class OVSDVRInterfaceMixin(object): + def delete_arp_destination_change(self, target_mac_address, + orig_mac_address): + (_dp, _ofp, ofpp) = self._get_dp() + match = ofpp.OFPMatch(eth_dst=orig_mac_address, + eth_type=ether_types.ETH_TYPE_ARP, + arp_tha=target_mac_address, + arp_op=arp.ARP_REPLY) + self.uninstall_flows(table_id=constants.LOCAL_SWITCHING, + match=match) + def change_arp_destination_mac(self, target_mac_address, orig_mac_address): """Change destination MAC from dvr_host_mac to internal gateway MAC. diff --git a/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_dvr_neutron_agent.py b/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_dvr_neutron_agent.py index 268245a855d..aac83300ee6 100644 --- a/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_dvr_neutron_agent.py +++ b/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_dvr_neutron_agent.py @@ -742,6 +742,13 @@ class OVSDVRNeutronAgent(object): self.firewall.delete_accepted_egress_direct_flow( subnet_info['gateway_mac'], lvm.vlan) + if (ip_version == n_const.IP_VERSION_4 and + subnet_info.get('gateway_mac')): + # remove ARP reply destination MAC address change flow + self.int_br.delete_arp_destination_change( + target_mac_address=subnet_info['gateway_mac'], + orig_mac_address=self.dvr_mac_address) + if lvm.network_type in constants.DVR_PHYSICAL_NETWORK_TYPES: br = self.phys_brs[physical_network] if lvm.network_type in constants.TUNNEL_NETWORK_TYPES: 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 4ab67d866b6..5c119f86f6f 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 @@ -3501,6 +3501,7 @@ class TestOvsDvrNeutronAgent(object): phys_br = mock.create_autospec(self.br_phys_cls('br-phys')) int_br.set_db_attribute.return_value = True int_br.db_get_val.return_value = {} + int_br.delete_arp_destination_change = mock.Mock() with mock.patch.object(self.agent.dvr_agent.plugin_rpc, 'get_subnet_for_dvr', return_value={'gateway_ip': gateway_ip, @@ -3546,8 +3547,12 @@ class TestOvsDvrNeutronAgent(object): phys_br.reset_mock() ports_to_unbind = {} - expected_br_int_mock_calls_gateway_port = 2 - expected_br_int_mock_calls_nongateway_port = 1 + if ip_version == n_const.IP_VERSION_4: + expected_br_int_mock_calls_gateway_port = 3 + expected_br_int_mock_calls_nongateway_port = 2 + else: + expected_br_int_mock_calls_gateway_port = 2 + expected_br_int_mock_calls_nongateway_port = 1 if port_type == 'gateway': ports_to_unbind = { self._port: expected_br_int_mock_calls_gateway_port @@ -3576,6 +3581,12 @@ class TestOvsDvrNeutronAgent(object): vlan_tag=lvid, gateway_ip=gateway_ip), ] + host_mac = self.agent.dvr_agent.dvr_mac_address + expected_on_int_br += [ + mock.call.delete_arp_destination_change( + target_mac_address=gateway_mac, + orig_mac_address=host_mac) + ] else: expected_on_tun_br = [ mock.call.delete_dvr_process_ipv6(