Make sure we remove the stale Static MAC Bindings if there is SB datapath re-creation in a single transaction. Otherwise, northd would be stuck in a commit failed loop due to "referential integrity violation" as the static mac binding would still reference the old datapath.
At the same time unify the check if dynamic/static mac binding is stale as it was different up until now. Both of them use the same columns as an indication of logical port and datapath. Fixes: b22684d4e37c ("Add a northbound interface to program MAC_Binding table") Reported-at: https://issues.redhat.com/browse/FDP-1623 Signed-off-by: Ales Musil <amu...@redhat.com> --- v2: Replace the Fixes tags. Remove the redundant check for op->nbrp. Update the commit message with more details. --- northd/northd.c | 28 +++++++++++++++++++--------- tests/ovn-northd.at | 8 ++++++++ 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/northd/northd.c b/northd/northd.c index 015f30a35..4b5b6584e 100644 --- a/northd/northd.c +++ b/northd/northd.c @@ -2867,6 +2867,19 @@ common: } } +static bool +mac_binding_is_stale(const struct hmap *lr_datapaths, + const struct hmap *lr_ports, + const struct sbrec_datapath_binding *dp, + const char *logical_port) +{ + const struct ovn_datapath *od = + ovn_datapath_from_sbrec(NULL, lr_datapaths, dp); + + return !od || ovn_datapath_is_stale(od) || + !ovn_port_find(lr_ports, logical_port); +} + /* Remove mac_binding entries that refer to logical_ports which are * deleted. */ static void @@ -2876,11 +2889,8 @@ cleanup_mac_bindings( { const struct sbrec_mac_binding *b; SBREC_MAC_BINDING_TABLE_FOR_EACH_SAFE (b, sbrec_mac_binding_table) { - const struct ovn_datapath *od = - ovn_datapath_from_sbrec(NULL, lr_datapaths, b->datapath); - - if (!od || ovn_datapath_is_stale(od) || - !ovn_port_find(lr_ports, b->logical_port)) { + if (mac_binding_is_stale(lr_datapaths, lr_ports, b->datapath, + b->logical_port)) { sbrec_mac_binding_delete(b); } } @@ -18850,7 +18860,7 @@ build_static_mac_binding_table( struct ovsdb_idl_txn *ovnsb_txn, const struct nbrec_static_mac_binding_table *nbrec_static_mb_table, const struct sbrec_static_mac_binding_table *sbrec_static_mb_table, - struct hmap *lr_ports) + const struct hmap *lr_datapaths, const struct hmap *lr_ports) { /* Cleanup SB Static_MAC_Binding entries which do not have corresponding * NB Static_MAC_Binding entries, and SB Static_MAC_Binding entries for @@ -18866,8 +18876,8 @@ build_static_mac_binding_table( continue; } - struct ovn_port *op = ovn_port_find(lr_ports, nb_smb->logical_port); - if (!op || !op->nbrp || !op->od || !op->od->sdp->sb_dp) { + if (mac_binding_is_stale(lr_datapaths, lr_ports, sb_smb->datapath, + sb_smb->logical_port)) { sbrec_static_mac_binding_delete(sb_smb); } } @@ -19187,7 +19197,7 @@ ovnnb_db_run(struct northd_input *input_data, build_static_mac_binding_table(ovnsb_txn, input_data->nbrec_static_mac_binding_table, input_data->sbrec_static_mac_binding_table, - &data->lr_ports); + &data->lr_datapaths.datapaths, &data->lr_ports); stopwatch_stop(BUILD_LFLOWS_CTX_STOPWATCH_NAME, time_msec()); stopwatch_start(CLEAR_LFLOWS_CTX_STOPWATCH_NAME, time_msec()); diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at index 11bbb211d..1a4910924 100644 --- a/tests/ovn-northd.at +++ b/tests/ovn-northd.at @@ -8518,6 +8518,14 @@ wait_row_count sb:Static_MAC_Binding 1 logical_port=lr-lrp ip=1.1.1.2 mac="00\:0 check ovn-nbctl lr-del lr wait_row_count sb:Static_MAC_Binding 0 +dnl Also check for router (and router port) being recreated in the same +dnl transaction. +check ovn-nbctl lr-add lr -- lrp-add lr lr-lrp 00:00:00:00:00:01 1.1.1.1/24 +wait_row_count sb:Static_MAC_Binding 1 logical_port=lr-lrp ip=1.1.1.2 mac="00\:00\:00\:00\:00\:02" +check ovn-nbctl lrp-del lr-lrp -- lr-del lr -- lr-add lr -- lrp-add lr lr-lrp 00:00:00:00:00:01 1.1.1.1/24 +wait_row_count sb:Static_MAC_Binding 1 +check ovn-nbctl --wait=sb sync + AT_CLEANUP ]) -- 2.50.1 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev