From: "RYAN D. MOATS" <rmo...@us.ibm.com> This code changes to allow incremental processing of the logical flow and physical binding tables whenver possible.
Note: flows created by physical_run for multicast_groups are *NOT* handled incrementally due to to be solved issues with GWs and local routers. Signed-off-by: Ryan Moats <rmo...@us.ibm.com> --- ovn/controller/binding.c | 6 ++++ ovn/controller/encaps.c | 5 +++ ovn/controller/lflow.c | 68 +++++++++++++++++++++++++++++++++---- ovn/controller/lflow.h | 1 + ovn/controller/lport.c | 14 ++++++-- ovn/controller/lport.h | 4 ++- ovn/controller/ovn-controller.c | 1 - ovn/controller/patch.c | 8 +++++ ovn/controller/physical.c | 75 +++++++++++++++++++++++++++++++++++++---- ovn/controller/physical.h | 1 + 10 files changed, 165 insertions(+), 18 deletions(-) diff --git a/ovn/controller/binding.c b/ovn/controller/binding.c index 80f38b9..4a2bd0d 100644 --- a/ovn/controller/binding.c +++ b/ovn/controller/binding.c @@ -15,6 +15,8 @@ #include <config.h> #include "binding.h" +#include "lflow.h" +#include "lport.h" #include "lib/bitmap.h" #include "lib/hmap.h" @@ -118,6 +120,7 @@ remove_local_datapath(struct hmap *local_datapaths, struct local_datapath *ld) hmap_remove(local_datapaths, &ld->hmap_node); hmap_remove(&local_datapaths_by_uuid, &ld->uuid_hmap_node); free(ld); + lflow_reset_processing(); } static void @@ -156,6 +159,9 @@ add_local_datapath(struct hmap *local_datapaths, binding_rec->datapath->tunnel_key); hmap_insert(&local_datapaths_by_uuid, &ld->uuid_hmap_node, uuid_hash(uuid)); + lport_index_reset(); + mcgroup_index_reset(); + lflow_reset_processing(); } static void diff --git a/ovn/controller/encaps.c b/ovn/controller/encaps.c index b5f874f..736da8e 100644 --- a/ovn/controller/encaps.c +++ b/ovn/controller/encaps.c @@ -17,6 +17,7 @@ #include "encaps.h" #include "binding.h" #include "lflow.h" +#include "lport.h" #include "lib/hash.h" #include "lib/sset.h" @@ -234,6 +235,9 @@ tunnel_add(const struct sbrec_chassis *chassis_rec, free(port_name); free(ports); binding_reset_processing(); + lport_index_reset(); + mcgroup_index_reset(); + lflow_reset_processing(); process_full_encaps = true; } @@ -417,6 +421,7 @@ encaps_run(struct controller_ctx *ctx, const struct ovsrec_bridge *br_int, &port_hash->uuid_node); free(port_hash); binding_reset_processing(); + lflow_reset_processing(); } continue; } diff --git a/ovn/controller/lflow.c b/ovn/controller/lflow.c index 464f9c8..702624d 100644 --- a/ovn/controller/lflow.c +++ b/ovn/controller/lflow.c @@ -26,6 +26,7 @@ #include "ovn/lib/expr.h" #include "ovn/lib/ovn-sb-idl.h" #include "packets.h" +#include "physical.h" #include "simap.h" VLOG_DEFINE_THIS_MODULE(lflow); @@ -35,6 +36,17 @@ VLOG_DEFINE_THIS_MODULE(lflow); /* Contains "struct expr_symbol"s for fields supported by OVN lflows. */ static struct shash symtab; +static bool full_flow_processing = false; +static bool full_logical_flow_processing = false; +static bool full_neighbor_flow_processing = false; + +void +lflow_reset_processing(void) +{ + full_flow_processing = true; + physical_reset_processing(); +} + static void add_logical_register(struct shash *symtab, enum mf_field_id id) { @@ -365,12 +377,30 @@ add_logical_flows(struct controller_ctx *ctx, const struct lport_index *lports, const struct simap *ct_zones) { uint32_t conj_id_ofs = 1; - const struct sbrec_logical_flow *lflow; - SBREC_LOGICAL_FLOW_FOR_EACH (lflow, ctx->ovnsb_idl) { - consider_logical_flow(lports, mcgroups, lflow, local_datapaths, - patched_datapaths, ct_zones, &conj_id_ofs, - true); + + if (full_logical_flow_processing) { + SBREC_LOGICAL_FLOW_FOR_EACH (lflow, ctx->ovnsb_idl) { + consider_logical_flow(lports, mcgroups, lflow, local_datapaths, + patched_datapaths, ct_zones, &conj_id_ofs, + true); + } + full_logical_flow_processing = false; + } else { + SBREC_LOGICAL_FLOW_FOR_EACH_TRACKED (lflow, ctx->ovnsb_idl) { + bool is_deleted = sbrec_logical_flow_row_get_seqno(lflow, + OVSDB_IDL_CHANGE_DELETE) > 0; + bool is_new = sbrec_logical_flow_row_get_seqno(lflow, + OVSDB_IDL_CHANGE_MODIFY) == 0; + + if (is_deleted) { + ofctrl_remove_flows(&lflow->header_.uuid); + continue; + } + consider_logical_flow(lports, mcgroups, lflow, local_datapaths, + patched_datapaths, ct_zones, &conj_id_ofs, + is_new); + } } } @@ -438,9 +468,26 @@ add_neighbor_flows(struct controller_ctx *ctx, ofpbuf_init(&ofpacts, 0); const struct sbrec_mac_binding *b; - SBREC_MAC_BINDING_FOR_EACH (b, ctx->ovnsb_idl) { - consider_neighbor_flow(lports, b, &ofpacts, &match, true); + if (full_neighbor_flow_processing) { + SBREC_MAC_BINDING_FOR_EACH (b, ctx->ovnsb_idl) { + consider_neighbor_flow(lports, b, &ofpacts, &match, true); + } + full_neighbor_flow_processing = false; + } else { + SBREC_MAC_BINDING_FOR_EACH_TRACKED (b, ctx->ovnsb_idl) { + bool is_deleted = sbrec_mac_binding_row_get_seqno(b, + OVSDB_IDL_CHANGE_DELETE) > 0; + bool is_new = sbrec_mac_binding_row_get_seqno(b, + OVSDB_IDL_CHANGE_MODIFY) == 0; + + if (is_deleted) { + ofctrl_remove_flows(&b->header_.uuid); + continue; + } + consider_neighbor_flow(lports, b, &ofpacts, &match, is_new); + } } + ofpbuf_uninit(&ofpacts); } @@ -453,6 +500,13 @@ lflow_run(struct controller_ctx *ctx, const struct lport_index *lports, const struct hmap *patched_datapaths, const struct simap *ct_zones) { + if (full_flow_processing) { + ovn_flow_table_clear(); + full_logical_flow_processing = true; + full_neighbor_flow_processing = true; + full_flow_processing = false; + physical_reset_processing(); + } add_logical_flows(ctx, lports, mcgroups, local_datapaths, patched_datapaths, ct_zones); add_neighbor_flows(ctx, lports); diff --git a/ovn/controller/lflow.h b/ovn/controller/lflow.h index 8f8f81a..abbb10a 100644 --- a/ovn/controller/lflow.h +++ b/ovn/controller/lflow.h @@ -65,5 +65,6 @@ void lflow_run(struct controller_ctx *, const struct lport_index *, const struct hmap *patched_datapaths, const struct simap *ct_zones); void lflow_destroy(void); +void lflow_reset_processing(void); #endif /* ovn/lflow.h */ diff --git a/ovn/controller/lport.c b/ovn/controller/lport.c index 461cabd..e81d306 100644 --- a/ovn/controller/lport.c +++ b/ovn/controller/lport.c @@ -49,7 +49,7 @@ lport_index_init(struct lport_index *lports) hmap_init(&lports->by_uuid); } -void +bool lport_index_remove(struct lport_index *lports, const struct uuid *uuid) { const struct lport *port = lport_lookup_by_uuid(lports, uuid); @@ -58,7 +58,9 @@ lport_index_remove(struct lport_index *lports, const struct uuid *uuid) hmap_remove(&lports->by_key, (struct hmap_node *) &port->key_node); hmap_remove(&lports->by_uuid, (struct hmap_node *) &port->uuid_node); free((void *) port); + return true; } + return false; } void @@ -74,6 +76,7 @@ lport_index_clear(struct lport_index *lports) hmap_remove(&lports->by_uuid, &port->uuid_node); free(port); } + lflow_reset_processing(); } static void @@ -93,6 +96,7 @@ consider_lport_index(struct lport_index *lports, uuid_hash(&pb->header_.uuid)); p->uuid = &pb->header_.uuid; p->pb = pb; + lflow_reset_processing(); } void @@ -111,7 +115,10 @@ lport_index_fill(struct lport_index *lports, struct ovsdb_idl *ovnsb_idl) OVSDB_IDL_CHANGE_DELETE) > 0; if (is_delete) { - lport_index_remove(lports, &pb->header_.uuid); + while (lport_index_remove(lports, &pb->header_.uuid)) { + ; + } + lflow_reset_processing(); continue; } consider_lport_index(lports, pb); @@ -204,6 +211,7 @@ mcgroup_index_remove(struct mcgroup_index *mcgroups, const struct uuid *uuid) (struct hmap_node *) &mcgroup->uuid_node); free((void *) mcgroup); } + lflow_reset_processing(); } void @@ -233,6 +241,7 @@ consider_mcgroup_index(struct mcgroup_index *mcgroups, uuid_hash(&mg->header_.uuid)); m->uuid = &mg->header_.uuid; m->mg = mg; + lflow_reset_processing(); } void @@ -252,6 +261,7 @@ mcgroup_index_fill(struct mcgroup_index *mcgroups, struct ovsdb_idl *ovnsb_idl) if (is_delete) { mcgroup_index_remove(mcgroups, &mg->header_.uuid); + lflow_reset_processing(); continue; } consider_mcgroup_index(mcgroups, mg); diff --git a/ovn/controller/lport.h b/ovn/controller/lport.h index 33f81d5..bb8d8cd 100644 --- a/ovn/controller/lport.h +++ b/ovn/controller/lport.h @@ -39,9 +39,10 @@ struct lport_index { void lport_index_reset(void); void lport_index_init(struct lport_index *); void lport_index_fill(struct lport_index *, struct ovsdb_idl *); -void lport_index_remove(struct lport_index *, const struct uuid *); +bool lport_index_remove(struct lport_index *, const struct uuid *); void lport_index_clear(struct lport_index *); void lport_index_destroy(struct lport_index *); +void lport_index_rebuild(void); const struct sbrec_port_binding *lport_lookup_by_name( const struct lport_index *, const char *name); @@ -73,6 +74,7 @@ void mcgroup_index_fill(struct mcgroup_index *, struct ovsdb_idl *); void mcgroup_index_remove(struct mcgroup_index *, const struct uuid *); void mcgroup_index_clear(struct mcgroup_index *); void mcgroup_index_destroy(struct mcgroup_index *); +void mcgroup_index_rebuild(void); const struct sbrec_multicast_group *mcgroup_lookup_by_dp_name( const struct mcgroup_index *, diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c index 1aa25dc..ba66fea 100644 --- a/ovn/controller/ovn-controller.c +++ b/ovn/controller/ovn-controller.c @@ -460,7 +460,6 @@ main(int argc, char *argv[]) update_ct_zones(&all_lports, &patched_datapaths, &ct_zones, ct_zone_bitmap); - ovn_flow_table_clear(); lflow_run(&ctx, &lports, &mcgroups, &local_datapaths, &patched_datapaths, &ct_zones); if (chassis_id) { diff --git a/ovn/controller/patch.c b/ovn/controller/patch.c index fa4e624..f80c8ae 100644 --- a/ovn/controller/patch.c +++ b/ovn/controller/patch.c @@ -18,8 +18,10 @@ #include "patch.h" #include "hash.h" +#include "lflow.h" #include "lib/hmap.h" #include "lib/vswitch-idl.h" +#include "lport.h" #include "openvswitch/vlog.h" #include "ovn-controller.h" @@ -93,6 +95,9 @@ create_patch_port(struct controller_ctx *ctx, ovsrec_bridge_verify_ports(src); ovsrec_bridge_set_ports(src, ports, src->n_ports + 1); + lport_index_reset(); + mcgroup_index_reset(); + lflow_reset_processing(); free(ports); } @@ -125,6 +130,9 @@ remove_port(struct controller_ctx *ctx, return; } } + lport_index_reset(); + mcgroup_index_reset(); + lflow_reset_processing(); } /* Obtains external-ids:ovn-bridge-mappings from OVSDB and adds patch ports for diff --git a/ovn/controller/physical.c b/ovn/controller/physical.c index 3aa0cad..8323fd2 100644 --- a/ovn/controller/physical.c +++ b/ovn/controller/physical.c @@ -58,6 +58,14 @@ static struct simap localvif_to_ofport = SIMAP_INITIALIZER(&localvif_to_ofport); static struct hmap tunnels = HMAP_INITIALIZER(&tunnels); +static bool full_binding_processing = false; + +void +physical_reset_processing(void) +{ + full_binding_processing = true; +} + /* Maps from a chassis to the OpenFlow port number of the tunnel that can be * used to reach that chassis. */ struct chassis_tunnel { @@ -621,11 +629,35 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve, bool is_patch = !strcmp(iface_rec->type, "patch"); if (is_patch && localnet) { /* localnet patch ports can be handled just like VIFs. */ - simap_put(&localvif_to_ofport, localnet, ofport); + if (simap_find(&localvif_to_ofport, localnet)) { + unsigned int old_port = simap_get(&localvif_to_ofport, + localnet); + if (old_port != ofport) { + simap_put(&localvif_to_ofport, localnet, ofport); + full_binding_processing = true; + lflow_reset_processing(); + } + } else { + simap_put(&localvif_to_ofport, localnet, ofport); + full_binding_processing = true; + lflow_reset_processing(); + } break; } else if (is_patch && logpatch) { /* Logical patch ports can be handled just like VIFs. */ - simap_put(&localvif_to_ofport, logpatch, ofport); + if (simap_find(&localvif_to_ofport, logpatch)) { + unsigned int old_port = simap_get(&localvif_to_ofport, + logpatch); + if (old_port != ofport) { + simap_put(&localvif_to_ofport, logpatch, ofport); + full_binding_processing = true; + lflow_reset_processing(); + } + } else { + simap_put(&localvif_to_ofport, logpatch, ofport); + full_binding_processing = true; + lflow_reset_processing(); + } break; } else if (chassis_id) { enum chassis_tunnel_type tunnel_type; @@ -653,7 +685,19 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve, const char *iface_id = smap_get(&iface_rec->external_ids, "iface-id"); if (iface_id) { - simap_put(&localvif_to_ofport, iface_id, ofport); + if (simap_find(&localvif_to_ofport, iface_id)) { + unsigned int old_port = simap_get(&localvif_to_ofport, + iface_id); + if (old_port != ofport) { + simap_put(&localvif_to_ofport, iface_id, ofport); + full_binding_processing = true; + lflow_reset_processing(); + } + } else { + simap_put(&localvif_to_ofport, iface_id, ofport); + full_binding_processing = true; + lflow_reset_processing(); + } } } } @@ -665,10 +709,28 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve, /* Set up flows in table 0 for physical-to-logical translation and in table * 64 for logical-to-physical translation. */ const struct sbrec_port_binding *binding; - SBREC_PORT_BINDING_FOR_EACH (binding, ctx->ovnsb_idl) { - consider_port_binding(mff_ovn_geneve, ct_zones, local_datapaths, - patched_datapaths, binding, &ofpacts, true); + if (full_binding_processing) { + SBREC_PORT_BINDING_FOR_EACH (binding, ctx->ovnsb_idl) { + consider_port_binding(mff_ovn_geneve, ct_zones, local_datapaths, + patched_datapaths, binding, &ofpacts, true); } + full_binding_processing = false; + } else { + SBREC_PORT_BINDING_FOR_EACH_TRACKED (binding, ctx->ovnsb_idl) { + bool is_deleted = sbrec_port_binding_row_get_seqno(binding, + OVSDB_IDL_CHANGE_DELETE) > 0; + bool is_new = sbrec_port_binding_row_get_seqno(binding, + OVSDB_IDL_CHANGE_MODIFY) == 0; + + if (is_deleted) { + ofctrl_remove_flows(&binding->header_.uuid); + continue; + } + consider_port_binding(mff_ovn_geneve, ct_zones, local_datapaths, + patched_datapaths, binding, &ofpacts, + is_new); + } + } /* Handle output to multicast groups, in tables 32 and 33. */ const struct sbrec_multicast_group *mc; @@ -784,7 +846,6 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve, hc_uuid, true); ofpbuf_uninit(&ofpacts); - simap_clear(&localvif_to_ofport); HMAP_FOR_EACH_POP (tun, hmap_node, &tunnels) { free(tun); } diff --git a/ovn/controller/physical.h b/ovn/controller/physical.h index 1f98f71..92680dc 100644 --- a/ovn/controller/physical.h +++ b/ovn/controller/physical.h @@ -45,5 +45,6 @@ void physical_run(struct controller_ctx *, enum mf_field_id mff_ovn_geneve, const struct ovsrec_bridge *br_int, const char *chassis_id, const struct simap *ct_zones, struct hmap *local_datapaths, struct hmap *patched_datapaths); +void physical_reset_processing(void); #endif /* ovn/physical.h */ -- 1.9.1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev