From d73ec5000bcb3a6add158eb50057af0a619c7f7f Mon Sep 17 00:00:00 2001 From: Rodolfo Alonso Hernandez Date: Mon, 21 Mar 2022 04:48:11 +0000 Subject: [PATCH] [L3] Fix "NDPProxyAgentExtension.ha_state_change" call The parameter "data" passed to the method "ha_state_change" is not a router but a dictionary with "router_id" info. The method "NDPProxyAgentExtension._process_router" requires the router ID and the "enable_ndp_proxy" value, stored in the agent router cache. Closes-Bug: #1967839 Related-Bug: #1877301 Change-Id: Iab163e69f7e3641e2e1a451374231b6ccfa74c3e --- neutron/agent/l3/extensions/ndp_proxy.py | 19 +++++++++++-------- neutron/agent/l3/ha.py | 7 ++++--- neutron/tests/unit/agent/l3/test_agent.py | 11 ++++++----- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/neutron/agent/l3/extensions/ndp_proxy.py b/neutron/agent/l3/extensions/ndp_proxy.py index 648a39433d5..79fbe73db01 100644 --- a/neutron/agent/l3/extensions/ndp_proxy.py +++ b/neutron/agent/l3/extensions/ndp_proxy.py @@ -346,9 +346,8 @@ class NDPProxyAgentExtension(l3_extension.L3AgentExtension): 'FORWARD', subnet_rule) ip_wrapper.netns.execute(sysctl_cmd, privsep_exec=True) - def _process_router(self, context, data): - state = data.get('enable_ndp_proxy', False) - ri = self._get_router_info(data['id']) + def _process_router(self, context, router_id, enable_ndp_proxy): + ri = self._get_router_info(router_id) if not self._check_if_ri_need_process(ri): return agent_mode = ri.agent_conf.agent_mode @@ -362,14 +361,14 @@ class NDPProxyAgentExtension(l3_extension.L3AgentExtension): existing_ndp_proxies = self.mapping.get_ndp_proxies_by_router_id( ri.router_id) - if state: + if enable_ndp_proxy: self._init_ndp_proxy_rule( ri, interface_name, iptables_manager, is_distributed, ip_wrapper, namespace) ndp_proxies = self.resource_rpc.bulk_pull( context, resources.NDPPROXY, - filter_kwargs={'router_id': [data['id']]}) + filter_kwargs={'router_id': [router_id]}) need_create = set(ndp_proxies) - set(existing_ndp_proxies) need_delete = set(existing_ndp_proxies) - set(ndp_proxies) @@ -422,10 +421,12 @@ class NDPProxyAgentExtension(l3_extension.L3AgentExtension): ip_wrapper.netns.execute(sysctl_cmd, privsep_exec=True) def add_router(self, context, data): - self._process_router(context, data) + self._process_router(context, data['id'], + data.get('enable_ndp_proxy', False)) def update_router(self, context, data): - self._process_router(context, data) + self._process_router(context, data['id'], + data.get('enable_ndp_proxy', False)) def delete_router(self, context, data): # Just process dvr router, clear the fip-namespace related rules @@ -445,7 +446,9 @@ class NDPProxyAgentExtension(l3_extension.L3AgentExtension): def ha_state_change(self, context, data): if data['state'] == 'backup': return - self._process_router(context, data) + + self._process_router(context, data['router_id'], + data['enable_ndp_proxy']) def update_network(self, context, data): pass diff --git a/neutron/agent/l3/ha.py b/neutron/agent/l3/ha.py index 062f94818af..1b4bba24398 100644 --- a/neutron/agent/l3/ha.py +++ b/neutron/agent/l3/ha.py @@ -182,10 +182,11 @@ class AgentMixin(object): if ri is None: return - state_change_data = {"router_id": router_id, "state": state, - "host": ri.agent.host} + state_change_data = { + "router_id": router_id, "state": state, "host": ri.agent.host, + "enable_ndp_proxy": ri.router.get("enable_ndp_proxy", False)} LOG.info('Router %(router_id)s transitioned to %(state)s on ' - 'agent %(host)s', + 'agent %(host)s; NDP proxy enabled: %(enable_ndp_proxy)s', state_change_data) # Set external gateway port link up or down according to state diff --git a/neutron/tests/unit/agent/l3/test_agent.py b/neutron/tests/unit/agent/l3/test_agent.py index c05fc753d66..5aea51a943f 100644 --- a/neutron/tests/unit/agent/l3/test_agent.py +++ b/neutron/tests/unit/agent/l3/test_agent.py @@ -301,20 +301,21 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework): def test_enqueue_state_change_l3_extension(self): self.conf.set_override('ha_vrrp_advert_int', 1) agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - router = mock.Mock() + router_dict = {'id': 'router_id', 'enable_ndp_proxy': True} router_info = mock.MagicMock() router_info.agent = agent - agent.router_info[router.id] = router_info + router_info.router = router_dict + agent.router_info['router_id'] = router_info agent.l3_ext_manager.ha_state_change = mock.Mock() with mock.patch('neutron.agent.linux.ip_lib.' 'IpAddrCommand.wait_until_address_ready') as mock_wait: mock_wait.return_value = True - agent.enqueue_state_change(router.id, 'primary') + agent.enqueue_state_change('router_id', 'primary') eventlet.sleep(self.conf.ha_vrrp_advert_int + 2) agent.l3_ext_manager.ha_state_change.assert_called_once_with( agent.context, - {'router_id': router.id, 'state': 'primary', - 'host': agent.host}) + {'router_id': 'router_id', 'state': 'primary', + 'host': agent.host, 'enable_ndp_proxy': True}) def test_enqueue_state_change_router_active_ha(self): agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)