Skip to content

Commit

Permalink
ovn: Delete stale MAC_Bindings that result in Referential Integrity V…
Browse files Browse the repository at this point in the history
…iolation

The MAC_Bindings have a strong reference to the Datapath_Binding. However the
MAC_Bindings are never deleted anywhere, and when the Datapath (associated
with a MAC_Binding) is deleted, the ovsdb-server returns Referential
Integrity Violation. This prevents newer operations initiated from the CMS
from being committed to the Southbound DB.

The patch fixes this  by deleting the MAC_Binding entry when the
logical_port referred in the mac_binding entry is deleted.

Signed-off-by: Chandra Sekhar Vejendla <csvejend@us.ibm.com>
Signed-off-by: Ben Pfaff <blp@ovn.org>
  • Loading branch information
Chandra S Vejendla authored and blp committed Aug 26, 2016
1 parent 9dba438 commit 6e31816
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 0 deletions.
27 changes: 27 additions & 0 deletions ovn/northd/ovn-northd.c
Expand Up @@ -1219,6 +1219,19 @@ ovn_port_update_sbrec(const struct ovn_port *op)
} }
} }


/* Remove mac_binding entries that refer to logical_ports which are
* deleted. */
static void
cleanup_mac_bindings(struct northd_context *ctx, struct hmap *ports)
{
const struct sbrec_mac_binding *b, *n;
SBREC_MAC_BINDING_FOR_EACH_SAFE (b, n, ctx->ovnsb_idl) {
if (!ovn_port_find(ports, b->logical_port)) {
sbrec_mac_binding_delete(b);
}
}
}

/* Updates the southbound Port_Binding table so that it contains the logical /* Updates the southbound Port_Binding table so that it contains the logical
* switch ports specified by the northbound database. * switch ports specified by the northbound database.
* *
Expand Down Expand Up @@ -1259,12 +1272,20 @@ build_ports(struct northd_context *ctx, struct hmap *datapaths,
sbrec_port_binding_set_tunnel_key(op->sb, tunnel_key); sbrec_port_binding_set_tunnel_key(op->sb, tunnel_key);
} }


bool remove_mac_bindings = false;
if (!ovs_list_is_empty(&sb_only)) {
remove_mac_bindings = true;
}

/* Delete southbound records without northbound matches. */ /* Delete southbound records without northbound matches. */
LIST_FOR_EACH_SAFE(op, next, list, &sb_only) { LIST_FOR_EACH_SAFE(op, next, list, &sb_only) {
ovs_list_remove(&op->list); ovs_list_remove(&op->list);
sbrec_port_binding_delete(op->sb); sbrec_port_binding_delete(op->sb);
ovn_port_destroy(ports, op); ovn_port_destroy(ports, op);
} }
if (remove_mac_bindings) {
cleanup_mac_bindings(ctx, ports);
}
} }


#define OVN_MIN_MULTICAST 32768 #define OVN_MIN_MULTICAST 32768
Expand Down Expand Up @@ -4347,6 +4368,12 @@ main(int argc, char *argv[])
add_column_noalert(ovnsb_idl_loop.idl, &sbrec_port_binding_col_options); add_column_noalert(ovnsb_idl_loop.idl, &sbrec_port_binding_col_options);
add_column_noalert(ovnsb_idl_loop.idl, &sbrec_port_binding_col_mac); add_column_noalert(ovnsb_idl_loop.idl, &sbrec_port_binding_col_mac);
ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_port_binding_col_chassis); ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_port_binding_col_chassis);
ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_mac_binding);
add_column_noalert(ovnsb_idl_loop.idl, &sbrec_mac_binding_col_datapath);
add_column_noalert(ovnsb_idl_loop.idl, &sbrec_mac_binding_col_ip);
add_column_noalert(ovnsb_idl_loop.idl, &sbrec_mac_binding_col_mac);
add_column_noalert(ovnsb_idl_loop.idl,
&sbrec_mac_binding_col_logical_port);
ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_dhcp_options); ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_dhcp_options);
add_column_noalert(ovnsb_idl_loop.idl, &sbrec_dhcp_options_col_code); add_column_noalert(ovnsb_idl_loop.idl, &sbrec_dhcp_options_col_code);
add_column_noalert(ovnsb_idl_loop.idl, &sbrec_dhcp_options_col_type); add_column_noalert(ovnsb_idl_loop.idl, &sbrec_dhcp_options_col_type);
Expand Down
33 changes: 33 additions & 0 deletions tests/ovn.at
Expand Up @@ -4965,3 +4965,36 @@ cat packets
OVN_CLEANUP([hv1]) OVN_CLEANUP([hv1])


AT_CLEANUP AT_CLEANUP

AT_SETUP([ovn -- delete mac bindings])
AT_KEYWORDS([ovn])
ovn_start
net_add n1
sim_add hv1
as hv1
ovs-vsctl -- add-br br-phys
ovn_attach n1 br-phys 192.168.0.1
# Create logical switch ls0
ovn-nbctl ls-add ls0
# Create ports lp0, lp1 in ls0
ovn-nbctl lsp-add ls0 lp0
ovn-nbctl lsp-add ls0 lp1
ovn-nbctl lsp-set-addresses lp0 "f0:00:00:00:00:01 192.168.0.1"
ovn-nbctl lsp-set-addresses lp1 "f0:00:00:00:00:02 192.168.0.2"
dp_uuid=`ovn-sbctl find datapath | grep uuid | cut -f2 -d ":" | cut -f2 -d " "`
ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp0 mac="mac1"
ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp1 mac="mac2"
ovn-sbctl find MAC_Binding
#Delete port lp0
ovn-nbctl lsp-del lp0
ovn-sbctl find MAC_Binding
AT_CHECK([ovn-sbctl find MAC_Binding logical_port=lp0], [0], [])
#Delete ls0. This will verify that the mac_bindings are cleaned up when a
#datapath is deleted without explicitly removing the the logical ports
ovn-nbctl ls-del ls0
ovn-sbctl find MAC_Binding
AT_CHECK([ovn-sbctl find MAC_Binding], [0], [])

OVN_CLEANUP([hv1])

AT_CLEANUP

0 comments on commit 6e31816

Please sign in to comment.