Store the evpn_datapaths in I-P node data as it will be used by upcoming patches, as input for new I-P nodes. We also store a pointer to 'struct local_datapath' objects instead of just the datapath key in order to avoid looking up the datapath multiple time when reading the (SB) EVPN datapath configuration is needed. Instead of storing EVPN datapaths as a vector, store them in a hashmap to avoid linear lookups.
Signed-off-by: Dumitru Ceara <[email protected]> --- controller/evpn-binding.c | 84 ++++++++++++++++++++----------------- controller/evpn-binding.h | 13 ++++++ controller/ovn-controller.c | 6 +++ 3 files changed, 64 insertions(+), 39 deletions(-) diff --git a/controller/evpn-binding.c b/controller/evpn-binding.c index 4bd67b618c..4170239e1b 100644 --- a/controller/evpn-binding.c +++ b/controller/evpn-binding.c @@ -30,15 +30,8 @@ VLOG_DEFINE_THIS_MODULE(evpn_binding); static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1); -struct evpn_datapath { - uint32_t vni; - uint32_t dp_key; -}; - -static struct vector collect_evpn_datapaths( - const struct hmap *local_datapaths); -static const struct evpn_datapath *evpn_datapath_find( - const struct vector *evpn_datapaths, uint32_t vni); +static void collect_evpn_datapaths(const struct hmap *local_datapaths, + struct hmap *evpn_datapaths); struct evpn_tunnel { uint16_t dst_port; @@ -64,13 +57,13 @@ void evpn_binding_run(const struct evpn_binding_ctx_in *b_ctx_in, struct evpn_binding_ctx_out *b_ctx_out) { - struct vector datapaths = - collect_evpn_datapaths(b_ctx_in->local_datapaths); struct vector tunnels = collect_evpn_tunnel_interfaces(b_ctx_in->br_int); struct hmapx stale_bindings = HMAPX_INITIALIZER(&stale_bindings); struct hmapx stale_mc_groups = HMAPX_INITIALIZER(&stale_mc_groups); uint32_t hint = OVN_MIN_EVPN_KEY; + collect_evpn_datapaths(b_ctx_in->local_datapaths, b_ctx_out->datapaths); + struct evpn_binding *binding; HMAP_FOR_EACH (binding, hmap_node, b_ctx_out->bindings) { hmapx_add(&stale_bindings, binding); @@ -90,8 +83,8 @@ evpn_binding_run(const struct evpn_binding_ctx_in *b_ctx_in, continue; } - const struct evpn_datapath *edp = evpn_datapath_find(&datapaths, - vtep->vni); + const struct evpn_datapath *edp = + evpn_datapath_find(b_ctx_out->datapaths, vtep->vni); if (!edp) { VLOG_WARN_RL(&rl, "Couldn't find EVPN datapath for %"PRIu16" VNI", vtep->vni); @@ -123,8 +116,8 @@ evpn_binding_run(const struct evpn_binding_ctx_in *b_ctx_in, updated = true; } - if (binding->dp_key != edp->dp_key) { - binding->dp_key = edp->dp_key; + if (binding->dp_key != edp->ldp->datapath->tunnel_key) { + binding->dp_key = edp->ldp->datapath->tunnel_key; updated = true; } @@ -163,7 +156,6 @@ evpn_binding_run(const struct evpn_binding_ctx_in *b_ctx_in, free(binding); } - vector_destroy(&datapaths); vector_destroy(&tunnels); hmapx_destroy(&stale_bindings); hmapx_destroy(&stale_mc_groups); @@ -219,6 +211,35 @@ evpn_vtep_binding_list(struct unixctl_conn *conn, int argc OVS_UNUSED, ds_destroy(&ds); } +const struct evpn_datapath * +evpn_datapath_find(const struct hmap *evpn_datapaths, uint32_t vni) +{ + const struct evpn_datapath *edp; + HMAP_FOR_EACH_WITH_HASH (edp, hmap_node, vni, evpn_datapaths) { + if (edp->vni == vni) { + return edp; + } + } + + return NULL; +} + +void +evpn_datapaths_clear(struct hmap *evpn_datapaths) +{ + struct evpn_datapath *edp; + HMAP_FOR_EACH_POP (edp, hmap_node, evpn_datapaths) { + free(edp); + } +} + +void +evpn_datapaths_destroy(struct hmap *evpn_datapaths) +{ + evpn_datapaths_clear(evpn_datapaths); + hmap_destroy(evpn_datapaths); +} + void evpn_multicast_groups_destroy(struct hmap *multicast_groups) { @@ -257,12 +278,10 @@ evpn_multicast_group_list(struct unixctl_conn *conn, int argc OVS_UNUSED, ds_destroy(&ds); } -static struct vector -collect_evpn_datapaths(const struct hmap *local_datapaths) +static void +collect_evpn_datapaths(const struct hmap *local_datapaths, + struct hmap *evpn_datapaths) { - struct vector evpn_datapaths = - VECTOR_EMPTY_INITIALIZER(struct evpn_datapath); - struct local_datapath *ld; HMAP_FOR_EACH (ld, hmap_node, local_datapaths) { if (!ld->is_switch) { @@ -275,33 +294,20 @@ collect_evpn_datapaths(const struct hmap *local_datapaths) continue; } - if (evpn_datapath_find(&evpn_datapaths, vni)) { + if (evpn_datapath_find(evpn_datapaths, vni)) { VLOG_WARN_RL(&rl, "Datapath "UUID_FMT" with duplicate VNI %"PRIi64, UUID_ARGS(&ld->datapath->header_.uuid), vni); continue; } - struct evpn_datapath edp = { + struct evpn_datapath *edp = xmalloc(sizeof *edp); + *edp = (struct evpn_datapath) { + .ldp = ld, .vni = vni, - .dp_key = ld->datapath->tunnel_key, }; - vector_push(&evpn_datapaths, &edp); - } - return evpn_datapaths; -} - -static const struct evpn_datapath * -evpn_datapath_find(const struct vector *evpn_datapaths, uint32_t vni) -{ - const struct evpn_datapath *edp; - VECTOR_FOR_EACH_PTR (evpn_datapaths, edp) { - if (edp->vni == vni) { - return edp; - } + hmap_insert(evpn_datapaths, &edp->hmap_node, edp->vni); } - - return NULL; } static struct vector diff --git a/controller/evpn-binding.h b/controller/evpn-binding.h index 229d29b09c..38fbea0d2a 100644 --- a/controller/evpn-binding.h +++ b/controller/evpn-binding.h @@ -36,6 +36,8 @@ struct evpn_binding_ctx_in { struct evpn_binding_ctx_out { /* Contains 'struct evpn_binding'. */ struct hmap *bindings; + /* Contains 'struct evpn_datapath'. */ + struct hmap *datapaths; /* Contains pointers to 'struct evpn_binding'. */ struct hmapx *updated_bindings; /* Contains 'flow_uuid' from removed 'struct evpn_binding'. */ @@ -64,6 +66,13 @@ struct evpn_binding { uint32_t dp_key; }; +struct evpn_datapath { + struct hmap_node hmap_node; + + const struct local_datapath *ldp; + uint32_t vni; +}; + struct evpn_multicast_group { struct hmap_node hmap_node; /* UUID used to identify physical flows related to this mutlicast group. */ @@ -81,6 +90,10 @@ struct evpn_binding *evpn_binding_find(const struct hmap *evpn_bindings, void evpn_bindings_destroy(struct hmap *bindings); void evpn_vtep_binding_list(struct unixctl_conn *conn, int argc, const char *argv[], void *data_); +const struct evpn_datapath *evpn_datapath_find( + const struct hmap *evpn_datapaths, uint32_t vni); +void evpn_datapaths_clear(struct hmap *evpn_datapaths); +void evpn_datapaths_destroy(struct hmap *evpn_datapaths); void evpn_multicast_groups_destroy(struct hmap *multicast_groups); void evpn_multicast_group_list(struct unixctl_conn *conn, int argc, const char *argv[], void *data_); diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c index e2793c8837..c8b76feb52 100644 --- a/controller/ovn-controller.c +++ b/controller/ovn-controller.c @@ -4568,6 +4568,8 @@ struct ed_type_evpn_vtep_binding { struct hmapx updated_bindings; /* Contains 'flow_uuid' from removed 'struct evpn_binding'. */ struct uuidset removed_bindings; + /* Contains 'struct evpn_datapath'. */ + struct hmap datapaths; /* Contains 'struct evpn_multicast_group'. */ struct hmap multicast_groups; /* Contains pointers to 'struct evpn_multicast_group'. */ @@ -6136,6 +6138,7 @@ en_evpn_vtep_binding_init(struct engine_node *node OVS_UNUSED, .bindings = HMAP_INITIALIZER(&data->bindings), .updated_bindings = HMAPX_INITIALIZER(&data->updated_bindings), .removed_bindings = UUIDSET_INITIALIZER(&data->removed_bindings), + .datapaths = HMAP_INITIALIZER(&data->datapaths), .multicast_groups = HMAP_INITIALIZER(&data->multicast_groups), .updated_multicast_groups = HMAPX_INITIALIZER(&data->updated_multicast_groups), @@ -6153,6 +6156,7 @@ en_evpn_vtep_binding_clear_tracked_data(void *data_) struct ed_type_evpn_vtep_binding *data = data_; hmapx_clear(&data->updated_bindings); uuidset_clear(&data->removed_bindings); + evpn_datapaths_clear(&data->datapaths); hmapx_clear(&data->updated_multicast_groups); uuidset_clear(&data->removed_multicast_groups); } @@ -6164,6 +6168,7 @@ en_evpn_vtep_binding_cleanup(void *data_) evpn_bindings_destroy(&data->bindings); hmapx_destroy(&data->updated_bindings); uuidset_destroy(&data->removed_bindings); + evpn_datapaths_destroy(&data->datapaths); evpn_multicast_groups_destroy(&data->multicast_groups); hmapx_clear(&data->updated_multicast_groups); uuidset_clear(&data->removed_multicast_groups); @@ -6194,6 +6199,7 @@ en_evpn_vtep_binding_run(struct engine_node *node, void *data_) .bindings = &data->bindings, .updated_bindings = &data->updated_bindings, .removed_bindings = &data->removed_bindings, + .datapaths = &data->datapaths, .multicast_groups = &data->multicast_groups, .updated_multicast_groups = &data->updated_multicast_groups, .removed_multicast_groups = &data->removed_multicast_groups, -- 2.51.0 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
