Incrementally manage local_active_ports_ipv6_pd map for interfaces where IPv6 prefix-delegation has been enabled. This patch allows to avoid looping over all local interfaces to check if prefix-delegation is running on the current port binding.
Signed-off-by: Lorenzo Bianconi <lorenzo.bianc...@redhat.com> --- controller/binding.c | 32 +++++++++++ controller/binding.h | 1 + controller/ovn-controller.c | 11 +++- controller/ovn-controller.h | 6 ++ controller/pinctrl.c | 107 +++++++++++++++++------------------- controller/pinctrl.h | 4 +- 6 files changed, 103 insertions(+), 58 deletions(-) diff --git a/controller/binding.c b/controller/binding.c index 594babc98..f87eaec0c 100644 --- a/controller/binding.c +++ b/controller/binding.c @@ -574,6 +574,30 @@ remove_related_lport(const struct sbrec_port_binding *pb, } } +static void +update_active_pb_ras_pd(const struct sbrec_port_binding *pb, + struct hmap *local_datapaths, + struct shash *map, const char *conf) +{ + const char *ras_pd_conf = smap_get(&pb->options, conf); + struct shash_node *iter = shash_find(map, pb->logical_port); + + if (iter && (!ras_pd_conf || !strcmp(ras_pd_conf, "false"))) { + shash_delete(map, iter); + return; + } + struct pb_ld_binding *ras_pd = NULL; + if (!iter && ras_pd_conf && !strcmp(ras_pd_conf, "true")) { + ras_pd = xzalloc(sizeof *ras_pd); + ras_pd->pb = pb; + shash_add(map, pb->logical_port, ras_pd); + } + if (ras_pd) { + ras_pd->ld = get_local_datapath(local_datapaths, + pb->datapath->tunnel_key); + } +} + /* Corresponds to each Port_Binding.type. */ enum en_lport_type { LP_UNKNOWN, @@ -1645,6 +1669,10 @@ binding_run(struct binding_ctx_in *b_ctx_in, struct binding_ctx_out *b_ctx_out) const struct sbrec_port_binding *pb; SBREC_PORT_BINDING_TABLE_FOR_EACH (pb, b_ctx_in->port_binding_table) { + update_active_pb_ras_pd(pb, b_ctx_out->local_datapaths, + b_ctx_out->local_active_ports_ipv6_pd, + "ipv6_prefix_delegation"); + enum en_lport_type lport_type = get_lport_type(pb); switch (lport_type) { @@ -2482,6 +2510,10 @@ delete_done: continue; } + update_active_pb_ras_pd(pb, b_ctx_out->local_datapaths, + b_ctx_out->local_active_ports_ipv6_pd, + "ipv6_prefix_delegation"); + enum en_lport_type lport_type = get_lport_type(pb); struct binding_lport *b_lport = diff --git a/controller/binding.h b/controller/binding.h index a08011ae2..60ad49da0 100644 --- a/controller/binding.h +++ b/controller/binding.h @@ -72,6 +72,7 @@ void related_lports_destroy(struct related_lports *); struct binding_ctx_out { struct hmap *local_datapaths; + struct shash *local_active_ports_ipv6_pd; struct local_binding_data *lbinding_data; /* sset of (potential) local lports. */ diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c index 9050380f3..2bd402ab2 100644 --- a/controller/ovn-controller.c +++ b/controller/ovn-controller.c @@ -1028,6 +1028,8 @@ struct ed_type_runtime_data { bool tracked; bool local_lports_changed; struct hmap tracked_dp_bindings; + + struct shash local_active_ports_ipv6_pd; }; /* struct ed_type_runtime_data has the below members for tracking the @@ -1115,6 +1117,7 @@ en_runtime_data_init(struct engine_node *node OVS_UNUSED, sset_init(&data->egress_ifaces); smap_init(&data->local_iface_ids); local_binding_data_init(&data->lbinding_data); + shash_init(&data->local_active_ports_ipv6_pd); /* Init the tracked data. */ hmap_init(&data->tracked_dp_bindings); @@ -1140,6 +1143,7 @@ en_runtime_data_cleanup(void *data) free(cur_node); } hmap_destroy(&rt_data->local_datapaths); + shash_destroy(&rt_data->local_active_ports_ipv6_pd); local_binding_data_destroy(&rt_data->lbinding_data); } @@ -1218,6 +1222,8 @@ init_binding_ctx(struct engine_node *node, b_ctx_in->ovs_table = ovs_table; b_ctx_out->local_datapaths = &rt_data->local_datapaths; + b_ctx_out->local_active_ports_ipv6_pd = + &rt_data->local_active_ports_ipv6_pd; b_ctx_out->local_lports = &rt_data->local_lports; b_ctx_out->local_lports_changed = false; b_ctx_out->related_lports = &rt_data->related_lports; @@ -1235,6 +1241,7 @@ en_runtime_data_run(struct engine_node *node, void *data) { struct ed_type_runtime_data *rt_data = data; struct hmap *local_datapaths = &rt_data->local_datapaths; + struct shash *local_active_ipv6_pd = &rt_data->local_active_ports_ipv6_pd; struct sset *local_lports = &rt_data->local_lports; struct sset *active_tunnels = &rt_data->active_tunnels; @@ -1250,6 +1257,7 @@ en_runtime_data_run(struct engine_node *node, void *data) free(cur_node); } hmap_clear(local_datapaths); + shash_clear(local_active_ipv6_pd); local_binding_data_destroy(&rt_data->lbinding_data); sset_destroy(local_lports); related_lports_destroy(&rt_data->related_lports); @@ -3263,7 +3271,8 @@ main(int argc, char *argv[]) sbrec_bfd_table_get(ovnsb_idl_loop.idl), br_int, chassis, &runtime_data->local_datapaths, - &runtime_data->active_tunnels); + &runtime_data->active_tunnels, + &runtime_data->local_active_ports_ipv6_pd); /* Updating monitor conditions if runtime data or * logical datapath goups changed. */ if (engine_node_changed(&en_runtime_data) diff --git a/controller/ovn-controller.h b/controller/ovn-controller.h index 5d9466880..417c7aacb 100644 --- a/controller/ovn-controller.h +++ b/controller/ovn-controller.h @@ -87,4 +87,10 @@ enum chassis_tunnel_type { uint32_t get_tunnel_type(const char *name); +struct pb_ld_binding { + const struct sbrec_port_binding *pb; + const struct local_datapath *ld; + struct hmap_node hmap_node; +}; + #endif /* controller/ovn-controller.h */ diff --git a/controller/pinctrl.c b/controller/pinctrl.c index 78ecfed84..5f3eca4a0 100644 --- a/controller/pinctrl.c +++ b/controller/pinctrl.c @@ -1249,83 +1249,76 @@ fill_ipv6_prefix_state(struct ovsdb_idl_txn *ovnsb_idl_txn, static void prepare_ipv6_prefixd(struct ovsdb_idl_txn *ovnsb_idl_txn, struct ovsdb_idl_index *sbrec_port_binding_by_name, - const struct hmap *local_datapaths, + const struct shash *local_active_ports_ipv6_pd, const struct sbrec_chassis *chassis, const struct sset *active_tunnels) OVS_REQUIRES(pinctrl_mutex) { - const struct local_datapath *ld; bool changed = false; - HMAP_FOR_EACH (ld, hmap_node, local_datapaths) { - if (datapath_is_switch(ld->datapath)) { - /* logical switch */ + struct shash_node *iter; + SHASH_FOR_EACH (iter, local_active_ports_ipv6_pd) { + const struct pb_ld_binding *pb_ipv6 = iter->data; + const struct sbrec_port_binding *pb = pb_ipv6->pb; + int j; + + if (!pb_ipv6->ld) { continue; } - for (size_t i = 0; i < ld->n_peer_ports; i++) { - const struct sbrec_port_binding *pb = ld->peer_ports[i].local; - int j; + const char *peer_s = smap_get(&pb->options, "peer"); + if (!peer_s) { + continue; + } - if (!smap_get_bool(&pb->options, "ipv6_prefix_delegation", - false)) { - continue; - } + const struct sbrec_port_binding *peer + = lport_lookup_by_name(sbrec_port_binding_by_name, peer_s); + if (!peer) { + continue; + } - const char *peer_s = smap_get(&pb->options, "peer"); - if (!peer_s) { - continue; - } + char *redirect_name = xasprintf("cr-%s", pb->logical_port); + bool resident = lport_is_chassis_resident( + sbrec_port_binding_by_name, chassis, active_tunnels, + redirect_name); + free(redirect_name); + if (!resident && strcmp(pb->type, "l3gateway")) { + continue; + } - const struct sbrec_port_binding *peer - = lport_lookup_by_name(sbrec_port_binding_by_name, peer_s); - if (!peer) { - continue; - } + struct in6_addr ip6_addr; + struct eth_addr ea = eth_addr_zero; + for (j = 0; j < pb->n_mac; j++) { + struct lport_addresses laddrs; - char *redirect_name = xasprintf("cr-%s", pb->logical_port); - bool resident = lport_is_chassis_resident( - sbrec_port_binding_by_name, chassis, active_tunnels, - redirect_name); - free(redirect_name); - if (!resident && strcmp(pb->type, "l3gateway")) { + if (!extract_lsp_addresses(pb->mac[j], &laddrs)) { continue; } - struct in6_addr ip6_addr; - struct eth_addr ea = eth_addr_zero; - for (j = 0; j < pb->n_mac; j++) { - struct lport_addresses laddrs; - - if (!extract_lsp_addresses(pb->mac[j], &laddrs)) { - continue; - } - - ea = laddrs.ea; - if (laddrs.n_ipv6_addrs > 0) { - ip6_addr = laddrs.ipv6_addrs[0].addr; - destroy_lport_addresses(&laddrs); - break; - } + ea = laddrs.ea; + if (laddrs.n_ipv6_addrs > 0) { + ip6_addr = laddrs.ipv6_addrs[0].addr; destroy_lport_addresses(&laddrs); + break; } + destroy_lport_addresses(&laddrs); + } - if (eth_addr_is_zero(ea)) { - continue; - } - - if (j == pb->n_mac) { - in6_generate_lla(ea, &ip6_addr); - } + if (eth_addr_is_zero(ea)) { + continue; + } - changed |= fill_ipv6_prefix_state(ovnsb_idl_txn, ld, - ea, ip6_addr, - peer->tunnel_key, - peer->datapath->tunnel_key); + if (j == pb->n_mac) { + in6_generate_lla(ea, &ip6_addr); } + + changed |= fill_ipv6_prefix_state(ovnsb_idl_txn, pb_ipv6->ld, + ea, ip6_addr, + peer->tunnel_key, + peer->datapath->tunnel_key); } - struct shash_node *iter, *next; + struct shash_node *next; SHASH_FOR_EACH_SAFE (iter, next, &ipv6_prefixd) { struct ipv6_prefixd_state *pfd = iter->data; if (pfd->last_used + IPV6_PREFIXD_STALE_TIMEOUT < time_msec()) { @@ -3411,7 +3404,8 @@ pinctrl_run(struct ovsdb_idl_txn *ovnsb_idl_txn, const struct ovsrec_bridge *br_int, const struct sbrec_chassis *chassis, const struct hmap *local_datapaths, - const struct sset *active_tunnels) + const struct sset *active_tunnels, + const struct shash *local_active_ports_ipv6_pd) { ovs_mutex_lock(&pinctrl_mutex); pinctrl_set_br_int_name_(br_int->name); @@ -3426,7 +3420,8 @@ pinctrl_run(struct ovsdb_idl_txn *ovnsb_idl_txn, local_datapaths, active_tunnels); prepare_ipv6_ras(local_datapaths); prepare_ipv6_prefixd(ovnsb_idl_txn, sbrec_port_binding_by_name, - local_datapaths, chassis, active_tunnels); + local_active_ports_ipv6_pd, chassis, + active_tunnels); sync_dns_cache(dns_table); controller_event_run(ovnsb_idl_txn, ce_table, chassis); ip_mcast_sync(ovnsb_idl_txn, chassis, local_datapaths, diff --git a/controller/pinctrl.h b/controller/pinctrl.h index cc0a51984..0b9a57bdd 100644 --- a/controller/pinctrl.h +++ b/controller/pinctrl.h @@ -23,6 +23,7 @@ #include "openvswitch/meta-flow.h" struct hmap; +struct shash; struct lport_index; struct ovsdb_idl_index; struct ovsdb_idl_txn; @@ -49,7 +50,8 @@ void pinctrl_run(struct ovsdb_idl_txn *ovnsb_idl_txn, const struct sbrec_bfd_table *, const struct ovsrec_bridge *, const struct sbrec_chassis *, const struct hmap *local_datapaths, - const struct sset *active_tunnels); + const struct sset *active_tunnels, + const struct shash *local_active_ports_ipv6_pd); void pinctrl_wait(struct ovsdb_idl_txn *ovnsb_idl_txn); void pinctrl_destroy(void); void pinctrl_set_br_int_name(char *br_int_name); -- 2.31.1 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev