diff --git a/ovn_bgp_agent/drivers/openstack/watchers/nb_bgp_watcher.py b/ovn_bgp_agent/drivers/openstack/watchers/nb_bgp_watcher.py index ae32a11f..b717b62c 100644 --- a/ovn_bgp_agent/drivers/openstack/watchers/nb_bgp_watcher.py +++ b/ovn_bgp_agent/drivers/openstack/watchers/nb_bgp_watcher.py @@ -174,6 +174,15 @@ class LogicalSwitchPortFIPCreateEvent(base_watcher.LSPChassisEvent): So for migration flow we are only interested in event 7. Otherwise the floating ip would be added upon event 2, deleted with event 3 and re-added with event 7. + + For the live migration of a VIP (floating ip attached to virtual port), + the following events happen: + 1. port is set down (by ovn-controller on source host) + 2. external_ids update (neutron:host_id is removed) + 3. port is set up (by ovn-controller on dest host) + 4. external_ids update (neutron:host_id is added) + + In this case we only need to catch event 4. ''' def __init__(self, bgp_agent): events = (self.ROW_UPDATE,) @@ -210,8 +219,11 @@ class LogicalSwitchPortFIPCreateEvent(base_watcher.LSPChassisEvent): # to something else) we need to process this update. # If nothing else changed in the external_ids, we do not care # as it would just cause unnecessary events during migrations. + # Only case we are interested in is if the chassis has changed + # with this event. # (see the docstring of this class) - return False + old_chassis = self._get_chassis(old) + return old_chassis != current_chassis # Check if the current port_fip has not been exposed yet return not self.agent.is_ip_exposed( diff --git a/ovn_bgp_agent/tests/unit/drivers/openstack/watchers/test_nb_bgp_watcher.py b/ovn_bgp_agent/tests/unit/drivers/openstack/watchers/test_nb_bgp_watcher.py index 82c204aa..5fc2578f 100644 --- a/ovn_bgp_agent/tests/unit/drivers/openstack/watchers/test_nb_bgp_watcher.py +++ b/ovn_bgp_agent/tests/unit/drivers/openstack/watchers/test_nb_bgp_watcher.py @@ -310,9 +310,30 @@ class TestLogicalSwitchPortFIPCreateEvent(test_base.TestCase): constants.OVN_HOST_ID_EXT_ID_KEY: self.chassis, constants.OVN_FIP_EXT_ID_KEY: 'fip-ip'}, up=[True]) - old = utils.create_row(external_ids={}, up=[True]) + old = utils.create_row(external_ids={ + constants.OVN_FIP_EXT_ID_KEY: 'fip-ip', + }, up=[True]) self.assertTrue(self.event.match_fn(mock.Mock(), row, old)) + def test_match_fn_no_change_external_ids(self): + row = utils.create_row( + type=constants.OVN_VM_VIF_PORT_TYPE, + addresses=['mac 192.168.0.1'], + external_ids={ + constants.OVN_HOST_ID_EXT_ID_KEY: self.chassis, + constants.OVN_FIP_EXT_ID_KEY: 'fip-ip', + 'neutron:revision_number': '416', + }, + up=[True]) + old = utils.create_row( + external_ids={ + constants.OVN_FIP_EXT_ID_KEY: 'fip-ip', + constants.OVN_HOST_ID_EXT_ID_KEY: self.chassis, + 'neutron:revision_number': '417', + }, + up=[True]) + self.assertFalse(self.event.match_fn(mock.Mock(), row, old)) + def test_match_fn_status_change(self): row = utils.create_row(type=constants.OVN_VM_VIF_PORT_TYPE, addresses=['mac 192.168.0.1'],