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 | 35 ++++++++++++ controller/binding.h | 1 + controller/ovn-controller.c | 25 ++++++++- controller/ovn-controller.h | 8 +++ controller/pinctrl.c | 109 ++++++++++++++++++------------------ controller/pinctrl.h | 3 +- 6 files changed, 124 insertions(+), 57 deletions(-) diff --git a/controller/binding.c b/controller/binding.c index 594babc98..2cec7ea84 100644 --- a/controller/binding.c +++ b/controller/binding.c @@ -574,6 +574,33 @@ 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 hmap *map, const char *conf) +{ + const char *ras_pd_conf = smap_get(&pb->options, conf); + if (!ras_pd_conf) { + return; + } + + struct pb_active_ra_pd *ras_pd = + get_pb_active_ras_pd(map, pb->logical_port); + if (ras_pd && !strcmp(ras_pd_conf, "false")) { + hmap_remove(map, &ras_pd->hmap_node); + return; + } + if (!ras_pd && !strcmp(ras_pd_conf, "true")) { + ras_pd = xzalloc(sizeof *ras_pd); + ras_pd->pb = pb; + hmap_insert(map, &ras_pd->hmap_node, hash_string(pb->logical_port, 0)); + } + 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 +1672,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 +2513,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..5a6f46a14 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 hmap *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..a42b96ddb 100644 --- a/controller/ovn-controller.c +++ b/controller/ovn-controller.c @@ -133,6 +133,20 @@ get_local_datapath(const struct hmap *local_datapaths, uint32_t tunnel_key) : NULL); } +struct pb_active_ra_pd * +get_pb_active_ras_pd(const struct hmap *map, const char *name) +{ + uint32_t key = hash_string(name, 0); + struct hmap_node *node; + + node = hmap_first_with_hash(map, key); + if (node) { + return CONTAINER_OF(node, struct pb_active_ra_pd, hmap_node); + } + + return NULL; +} + uint32_t get_tunnel_type(const char *name) { @@ -1028,6 +1042,8 @@ struct ed_type_runtime_data { bool tracked; bool local_lports_changed; struct hmap tracked_dp_bindings; + + struct hmap local_active_ports_ipv6_pd; }; /* struct ed_type_runtime_data has the below members for tracking the @@ -1115,6 +1131,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); + hmap_init(&data->local_active_ports_ipv6_pd); /* Init the tracked data. */ hmap_init(&data->tracked_dp_bindings); @@ -1140,6 +1157,7 @@ en_runtime_data_cleanup(void *data) free(cur_node); } hmap_destroy(&rt_data->local_datapaths); + hmap_destroy(&rt_data->local_active_ports_ipv6_pd); local_binding_data_destroy(&rt_data->lbinding_data); } @@ -1218,6 +1236,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 +1255,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 hmap *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 +1271,7 @@ en_runtime_data_run(struct engine_node *node, void *data) free(cur_node); } hmap_clear(local_datapaths); + hmap_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 +3285,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..cb054109e 100644 --- a/controller/ovn-controller.h +++ b/controller/ovn-controller.h @@ -71,6 +71,8 @@ struct local_datapath { struct local_datapath *get_local_datapath(const struct hmap *, uint32_t tunnel_key); +struct pb_active_ra_pd * +get_pb_active_ras_pd(const struct hmap *map, const char *name); const struct ovsrec_bridge *get_bridge(const struct ovsrec_bridge_table *, const char *br_name); @@ -87,4 +89,10 @@ enum chassis_tunnel_type { uint32_t get_tunnel_type(const char *name); +struct pb_active_ra_pd { + 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..1a74af872 100644 --- a/controller/pinctrl.c +++ b/controller/pinctrl.c @@ -1249,80 +1249,77 @@ 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 hmap *local_active_ports_ipv6_pd, const struct sbrec_chassis *chassis, const struct sset *active_tunnels) OVS_REQUIRES(pinctrl_mutex) { - const struct local_datapath *ld; + const struct pb_active_ra_pd *pb_ipv6; bool changed = false; - HMAP_FOR_EACH (ld, hmap_node, local_datapaths) { - if (datapath_is_switch(ld->datapath)) { - /* logical switch */ + HMAP_FOR_EACH (pb_ipv6, hmap_node, local_active_ports_ipv6_pd) { + const struct sbrec_port_binding *pb = pb_ipv6->pb; + int j; + + if (!smap_get_bool(&pb->options, "ipv6_prefix_delegation", + false)) { 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; + if (!pb_ipv6->ld) { + continue; + } - if (!smap_get_bool(&pb->options, "ipv6_prefix_delegation", - false)) { - continue; - } + const char *peer_s = smap_get(&pb->options, "peer"); + if (!peer_s) { + continue; + } - const char *peer_s = smap_get(&pb->options, "peer"); - if (!peer_s) { - continue; - } + const struct sbrec_port_binding *peer + = lport_lookup_by_name(sbrec_port_binding_by_name, peer_s); + if (!peer) { + continue; + } - const struct sbrec_port_binding *peer - = lport_lookup_by_name(sbrec_port_binding_by_name, peer_s); - if (!peer) { - 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; + } - 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")) { + 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; } - 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; @@ -3411,7 +3408,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 hmap *local_active_ports_ipv6_pd) { ovs_mutex_lock(&pinctrl_mutex); pinctrl_set_br_int_name_(br_int->name); @@ -3426,7 +3424,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..9d98ee72e 100644 --- a/controller/pinctrl.h +++ b/controller/pinctrl.h @@ -49,7 +49,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 hmap *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