To avaoid pasing LB multiple times store the struct ovn_controller_lb in hmap. This can be used later on for finding out which backend was removed for clearing the CT. During I-P store the "old" LBs between each run. That can be later on used for the I-P of the LB CT tuple node.
Signed-off-by: Ales Musil <[email protected]> --- Those patches are preparation for LB CT flush that are standalone enough. The goal is to get early review and if it's usefull enough to merge them in advance. --- controller/lflow.c | 137 +++++++++++++----------------------- controller/lflow.h | 1 + controller/local_data.c | 35 +++++++++ controller/local_data.h | 4 ++ controller/ovn-controller.c | 53 ++++++++++++++ lib/lb.c | 45 +++++++++++- lib/lb.h | 11 ++- 7 files changed, 196 insertions(+), 90 deletions(-) diff --git a/controller/lflow.c b/controller/lflow.c index 32664b080..107cfb085 100644 --- a/controller/lflow.c +++ b/controller/lflow.c @@ -1793,10 +1793,9 @@ add_lb_vip_hairpin_reply_action(struct in6_addr *vip6, ovs_be32 vip, * original destination tuple stored by ovn-northd. */ static void -add_lb_vip_hairpin_flows(struct ovn_controller_lb *lb, +add_lb_vip_hairpin_flows(const struct ovn_controller_lb *lb, struct ovn_lb_vip *lb_vip, struct ovn_lb_backend *lb_backend, - uint8_t lb_proto, bool use_ct_mark, struct ovn_desired_flow_table *flow_table) { @@ -1835,7 +1834,7 @@ add_lb_vip_hairpin_flows(struct ovn_controller_lb *lb, ntohl(vip4)); } - add_lb_vip_hairpin_reply_action(NULL, snat_vip4, lb_proto, + add_lb_vip_hairpin_reply_action(NULL, snat_vip4, lb->proto, lb_backend->port, lb->slb->header_.uuid.parts[0], &ofpacts); @@ -1860,17 +1859,17 @@ add_lb_vip_hairpin_flows(struct ovn_controller_lb *lb, ntoh128(vip6_value)); } - add_lb_vip_hairpin_reply_action(snat_vip6, 0, lb_proto, + add_lb_vip_hairpin_reply_action(snat_vip6, 0, lb->proto, lb_backend->port, lb->slb->header_.uuid.parts[0], &ofpacts); } if (lb_backend->port) { - match_set_nw_proto(&hairpin_match, lb_proto); + match_set_nw_proto(&hairpin_match, lb->proto); match_set_tp_dst(&hairpin_match, htons(lb_backend->port)); if (!lb->hairpin_orig_tuple) { - match_set_ct_nw_proto(&hairpin_match, lb_proto); + match_set_ct_nw_proto(&hairpin_match, lb->proto); match_set_ct_tp_dst(&hairpin_match, htons(lb_vip->vip_port)); } else { match_set_reg_masked(&hairpin_match, @@ -1930,7 +1929,7 @@ add_lb_ct_snat_hairpin_for_dp(const struct ovn_controller_lb *lb, } static void -add_lb_ct_snat_hairpin_dp_flows(struct ovn_controller_lb *lb, +add_lb_ct_snat_hairpin_dp_flows(const struct ovn_controller_lb *lb, uint32_t id, struct ovn_desired_flow_table *flow_table) { @@ -2023,10 +2022,9 @@ add_lb_ct_snat_hairpin_dp_flows(struct ovn_controller_lb *lb, * that this LB belongs to. These flows (and the actual SNAT flow) get added * by add_lb_ct_snat_hairpin_dp_flows(). */ static void -add_lb_ct_snat_hairpin_vip_flow(struct ovn_controller_lb *lb, +add_lb_ct_snat_hairpin_vip_flow(const struct ovn_controller_lb *lb, uint32_t id, struct ovn_lb_vip *lb_vip, - uint8_t lb_proto, struct ovn_desired_flow_table *flow_table) { uint64_t stub[1024 / 8]; @@ -2119,10 +2117,10 @@ add_lb_ct_snat_hairpin_vip_flow(struct ovn_controller_lb *lb, } } - match_set_nw_proto(&match, lb_proto); + match_set_nw_proto(&match, lb->proto); if (lb_vip->vip_port) { if (!lb->hairpin_orig_tuple) { - match_set_ct_nw_proto(&match, lb_proto); + match_set_ct_nw_proto(&match, lb->proto); match_set_ct_tp_dst(&match, htons(lb_vip->vip_port)); } else { match_set_reg_masked(&match, MFF_LOG_LB_ORIG_TP_DPORT - MFF_REG0, @@ -2153,9 +2151,8 @@ add_lb_ct_snat_hairpin_vip_flow(struct ovn_controller_lb *lb, * Note: 'conjunctive_id' must be a unique identifier for each LB as it is used * as a conjunctive flow id. */ static void -add_lb_ct_snat_hairpin_flows(struct ovn_controller_lb *lb, +add_lb_ct_snat_hairpin_flows(const struct ovn_controller_lb *lb, uint32_t conjunctive_id, - uint8_t lb_proto, struct ovn_desired_flow_table *flow_table) { /* We must add a flow for each LB VIP. In the general case, this flow @@ -2192,89 +2189,53 @@ add_lb_ct_snat_hairpin_flows(struct ovn_controller_lb *lb, for (int i = 0; i < lb->n_vips; i++) { struct ovn_lb_vip *lb_vip = &lb->vips[i]; add_lb_ct_snat_hairpin_vip_flow(lb, conjunctive_id, - lb_vip, lb_proto, flow_table); + lb_vip, flow_table); } add_lb_ct_snat_hairpin_dp_flows(lb, conjunctive_id, flow_table); } static void -consider_lb_hairpin_flows(const struct sbrec_load_balancer *sbrec_lb, - const struct hmap *local_datapaths, +consider_lb_hairpin_flows(const struct ovn_controller_lb *lb, bool use_ct_mark, struct ovn_desired_flow_table *flow_table, struct simap *ids) { - int id = simap_get(ids, sbrec_lb->name); + int id = simap_get(ids, lb->slb->name); VLOG_DBG("Load Balancer %s has conjunctive flow id %u", - sbrec_lb->name, id); + lb->slb->name, id); - /* Check if we need to add flows or not. If there is one datapath - * in the local_datapaths, it means all the datapaths of the lb - * will be in the local_datapaths. */ size_t i; - for (i = 0; i < sbrec_lb->n_datapaths; i++) { - if (get_local_datapath(local_datapaths, - sbrec_lb->datapaths[i]->tunnel_key)) { - break; - } - } - - if (sbrec_lb->n_datapaths && i == sbrec_lb->n_datapaths) { - return; - } - - struct sbrec_logical_dp_group *dp_group = sbrec_lb->datapath_group; - - for (i = 0; dp_group && i < dp_group->n_datapaths; i++) { - if (get_local_datapath(local_datapaths, - dp_group->datapaths[i]->tunnel_key)) { - break; - } - } - - if (dp_group && i == dp_group->n_datapaths) { - return; - } - - struct ovn_controller_lb *lb = ovn_controller_lb_create(sbrec_lb); - uint8_t lb_proto = IPPROTO_TCP; - if (lb->slb->protocol && lb->slb->protocol[0]) { - if (!strcmp(lb->slb->protocol, "udp")) { - lb_proto = IPPROTO_UDP; - } else if (!strcmp(lb->slb->protocol, "sctp")) { - lb_proto = IPPROTO_SCTP; - } - } - for (i = 0; i < lb->n_vips; i++) { struct ovn_lb_vip *lb_vip = &lb->vips[i]; for (size_t j = 0; j < lb_vip->n_backends; j++) { struct ovn_lb_backend *lb_backend = &lb_vip->backends[j]; - add_lb_vip_hairpin_flows(lb, lb_vip, lb_backend, lb_proto, + add_lb_vip_hairpin_flows(lb, lb_vip, lb_backend, use_ct_mark, flow_table); } } - add_lb_ct_snat_hairpin_flows(lb, id, lb_proto, flow_table); - - ovn_controller_lb_destroy(lb); + add_lb_ct_snat_hairpin_flows(lb, id, flow_table); } /* Adds OpenFlow flows to flow tables for each Load balancer VIPs and * backends to handle the load balanced hairpin traffic. */ static void -add_lb_hairpin_flows(const struct sbrec_load_balancer_table *lb_table, +add_lb_hairpin_flows(const struct hmap *ovn_controller_lbs, const struct hmap *local_datapaths, bool use_ct_mark, struct ovn_desired_flow_table *flow_table, struct simap *ids, struct id_pool *pool) { uint32_t id; - const struct sbrec_load_balancer *lb; - SBREC_LOAD_BALANCER_TABLE_FOR_EACH (lb, lb_table) { + const struct ovn_controller_lb *lb; + HMAP_FOR_EACH (lb, hmap_node, ovn_controller_lbs) { + if (!lb_is_local(lb->slb, local_datapaths)) { + continue; + } + /* Allocate a unique 32-bit integer to this load-balancer. This will * be used as a conjunctive flow id in the OFTABLE_CT_SNAT_HAIRPIN * table. @@ -2284,14 +2245,12 @@ add_lb_hairpin_flows(const struct sbrec_load_balancer_table *lb_table, * unlikely to happen as it would be mean that we have created * "UINT32_MAX" load-balancers. */ - - id = simap_get(ids, lb->name); + id = simap_get(ids, lb->slb->name); if (!id) { ovs_assert(id_pool_alloc_id(pool, &id)); - simap_put(ids, lb->name, id); + simap_put(ids, lb->slb->name, id); } - consider_lb_hairpin_flows(lb, local_datapaths, use_ct_mark, - flow_table, ids); + consider_lb_hairpin_flows(lb, use_ct_mark, flow_table, ids); } } @@ -2427,7 +2386,8 @@ lflow_run(struct lflow_ctx_in *l_ctx_in, struct lflow_ctx_out *l_ctx_out) l_ctx_in->static_mac_binding_table, l_ctx_in->local_datapaths, l_ctx_out->flow_table); - add_lb_hairpin_flows(l_ctx_in->lb_table, l_ctx_in->local_datapaths, + add_lb_hairpin_flows(l_ctx_in->ovn_controller_lbs, + l_ctx_in->local_datapaths, l_ctx_in->lb_hairpin_use_ct_mark, l_ctx_out->flow_table, l_ctx_out->hairpin_lb_ids, @@ -2559,9 +2519,14 @@ lflow_add_flows_for_datapath(const struct sbrec_datapath_binding *dp, /* Add load balancer hairpin flows if the datapath has any load balancers * associated. */ + const struct ovn_controller_lb *lb; for (size_t i = 0; i < n_dp_lbs; i++) { - consider_lb_hairpin_flows(dp_lbs[i], l_ctx_in->local_datapaths, - l_ctx_in->lb_hairpin_use_ct_mark, + lb = ovn_controller_lb_find(l_ctx_in->ovn_controller_lbs, + &dp_lbs[i]->header_.uuid); + if (!lb_is_local(lb->slb, l_ctx_in->local_datapaths)) { + continue; + } + consider_lb_hairpin_flows(lb, l_ctx_in->lb_hairpin_use_ct_mark, l_ctx_out->flow_table, l_ctx_out->hairpin_lb_ids); } @@ -2656,25 +2621,22 @@ lflow_handle_changed_lbs(struct lflow_ctx_in *l_ctx_in, struct simap *ids = l_ctx_out->hairpin_lb_ids; SBREC_LOAD_BALANCER_TABLE_FOR_EACH_TRACKED (lb, l_ctx_in->lb_table) { - if (sbrec_load_balancer_is_deleted(lb)) { - VLOG_DBG("Remove hairpin flows for deleted load balancer "UUID_FMT, + if (!sbrec_load_balancer_is_new(lb)) { + VLOG_DBG("Remove hairpin flows for updated load balancer "UUID_FMT, UUID_ARGS(&lb->header_.uuid)); ofctrl_remove_flows(l_ctx_out->flow_table, &lb->header_.uuid); - id_pool_free_id(pool, simap_get(ids, lb->name)); - simap_find_and_delete(ids, lb->name); } - } - SBREC_LOAD_BALANCER_TABLE_FOR_EACH_TRACKED (lb, l_ctx_in->lb_table) { if (sbrec_load_balancer_is_deleted(lb)) { + id_pool_free_id(pool, simap_get(ids, lb->name)); + simap_find_and_delete(ids, lb->name); continue; } - if (!sbrec_load_balancer_is_new(lb)) { - VLOG_DBG("Remove hairpin flows for updated load balancer "UUID_FMT, - UUID_ARGS(&lb->header_.uuid)); - ofctrl_remove_flows(l_ctx_out->flow_table, &lb->header_.uuid); - } else { + const struct ovn_controller_lb *clb = + ovn_controller_lb_find(l_ctx_in->ovn_controller_lbs, + &lb->header_.uuid); + if (clb && lb_is_local(clb->slb, l_ctx_in->local_datapaths)) { /* Allocate a unique 32-bit integer to this load-balancer. This * will be used as a conjunctive flow id in the * OFTABLE_CT_SNAT_HAIRPIN table. @@ -2687,14 +2649,13 @@ lflow_handle_changed_lbs(struct lflow_ctx_in *l_ctx_in, uint32_t id; ovs_assert(id_pool_alloc_id(pool, &id)); simap_put(ids, lb->name, id); - } - VLOG_DBG("Add load balancer hairpin flows for "UUID_FMT, - UUID_ARGS(&lb->header_.uuid)); - consider_lb_hairpin_flows(lb, l_ctx_in->local_datapaths, - l_ctx_in->lb_hairpin_use_ct_mark, - l_ctx_out->flow_table, - l_ctx_out->hairpin_lb_ids); + VLOG_DBG("Add load balancer hairpin flows for "UUID_FMT, + UUID_ARGS(&lb->header_.uuid)); + consider_lb_hairpin_flows(clb, l_ctx_in->lb_hairpin_use_ct_mark, + l_ctx_out->flow_table, + l_ctx_out->hairpin_lb_ids); + } } return true; diff --git a/controller/lflow.h b/controller/lflow.h index a25634a88..c5d415261 100644 --- a/controller/lflow.h +++ b/controller/lflow.h @@ -162,6 +162,7 @@ struct lflow_ctx_in { const struct hmap *dhcp_opts; const struct hmap *dhcpv6_opts; const struct controller_event_options *controller_event_opts; + const struct hmap *ovn_controller_lbs; bool lb_hairpin_use_ct_mark; }; diff --git a/controller/local_data.c b/controller/local_data.c index 9eee568d1..8b366c25b 100644 --- a/controller/local_data.c +++ b/controller/local_data.c @@ -640,3 +640,38 @@ datapath_is_transit_switch(const struct sbrec_datapath_binding *ldp) { return smap_get(&ldp->external_ids, "interconn-ts") != NULL; } + +bool +lb_is_local(const struct sbrec_load_balancer *sbrec_lb, + const struct hmap *local_datapaths) +{ + /* Check if the lb is local or not. If there is one datapath + * in the local_datapaths, it means all the datapaths of the lb + * will be in the local_datapaths. */ + size_t i; + for (i = 0; i < sbrec_lb->n_datapaths; i++) { + if (get_local_datapath(local_datapaths, + sbrec_lb->datapaths[i]->tunnel_key)) { + break; + } + } + + if (sbrec_lb->n_datapaths && i == sbrec_lb->n_datapaths) { + return false; + } + + struct sbrec_logical_dp_group *dp_group = sbrec_lb->datapath_group; + + for (i = 0; dp_group && i < dp_group->n_datapaths; i++) { + if (get_local_datapath(local_datapaths, + dp_group->datapaths[i]->tunnel_key)) { + break; + } + } + + if (dp_group && i == dp_group->n_datapaths) { + return false; + } + + return true; +} diff --git a/controller/local_data.h b/controller/local_data.h index d898c8aa5..4d0db8187 100644 --- a/controller/local_data.h +++ b/controller/local_data.h @@ -30,6 +30,7 @@ struct sbrec_chassis; struct ovsdb_idl_index; struct ovsrec_bridge; struct ovsrec_interface_table; +struct sbrec_load_balancer; /* A logical datapath that has some relevance to this hypervisor. A logical * datapath D is relevant to hypervisor H if: @@ -162,4 +163,7 @@ void add_local_datapath_multichassis_port(struct local_datapath *ld, void remove_local_datapath_multichassis_port(struct local_datapath *ld, char *logical_port); +bool lb_is_local(const struct sbrec_load_balancer *sbrec_lb, + const struct hmap *local_datapaths); + #endif /* controller/local_data.h */ diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c index e7bcb661e..959f9a842 100644 --- a/controller/ovn-controller.c +++ b/controller/ovn-controller.c @@ -53,6 +53,7 @@ #include "lib/chassis-index.h" #include "lib/extend-table.h" #include "lib/ip-mcast-index.h" +#include "lib/lb.h" #include "lib/mac-binding-index.h" #include "lib/mcast-group-index.h" #include "lib/ovn-sb-idl.h" @@ -1253,6 +1254,13 @@ struct ed_type_runtime_data { struct shash local_active_ports_ras; struct sset *postponed_ports; + + /* Hash map of "struct ovn_controller_lb" by uuid. */ + struct hmap ovn_controller_lbs; + + /* Hash map of "struct ovn_controller_lb" by uuid. It contains "old" data + * for LBs that were changed/removed during I-P run. */ + struct hmap old_ovn_controller_lbs; }; /* struct ed_type_runtime_data has the below members for tracking the @@ -1321,6 +1329,8 @@ en_runtime_data_clear_tracked_data(void *data_) { struct ed_type_runtime_data *data = data_; + ovn_controller_lbs_destroy(&data->old_ovn_controller_lbs); + hmap_init(&data->old_ovn_controller_lbs); tracked_datapaths_destroy(&data->tracked_dp_bindings); hmap_init(&data->tracked_dp_bindings); data->local_lports_changed = false; @@ -1342,6 +1352,8 @@ en_runtime_data_init(struct engine_node *node OVS_UNUSED, local_binding_data_init(&data->lbinding_data); shash_init(&data->local_active_ports_ipv6_pd); shash_init(&data->local_active_ports_ras); + hmap_init(&data->ovn_controller_lbs); + hmap_init(&data->old_ovn_controller_lbs); /* Init the tracked data. */ hmap_init(&data->tracked_dp_bindings); @@ -1363,6 +1375,7 @@ en_runtime_data_cleanup(void *data) shash_destroy(&rt_data->local_active_ports_ipv6_pd); shash_destroy(&rt_data->local_active_ports_ras); local_binding_data_destroy(&rt_data->lbinding_data); + ovn_controller_lbs_destroy(&rt_data->ovn_controller_lbs); } static void @@ -1484,6 +1497,8 @@ en_runtime_data_run(struct engine_node *node, void *data) sset_init(&rt_data->egress_ifaces); smap_init(&rt_data->local_iface_ids); local_binding_data_init(&rt_data->lbinding_data); + ovn_controller_lbs_destroy(&rt_data->ovn_controller_lbs); + hmap_init(&rt_data->ovn_controller_lbs); } struct ed_type_postponed_ports *pp_data = @@ -1509,6 +1524,11 @@ en_runtime_data_run(struct engine_node *node, void *data) binding_run(&b_ctx_in, &b_ctx_out); + const struct sbrec_load_balancer_table *lb_table = + EN_OVSDB_GET(engine_get_input("SB_load_balancer", node)); + + ovn_controller_lbs_create(lb_table, &rt_data->ovn_controller_lbs); + engine_set_node_state(node, EN_UPDATED); } @@ -1652,6 +1672,36 @@ runtime_data_sb_datapath_binding_handler(struct engine_node *node OVS_UNUSED, return true; } +static bool +runtime_data_sb_load_balancer_handler(struct engine_node *node, void *data) +{ + struct ed_type_runtime_data *rt_data = data; + const struct sbrec_load_balancer_table *lb_table = + EN_OVSDB_GET(engine_get_input("SB_load_balancer", node)); + + const struct sbrec_load_balancer *lb; + SBREC_LOAD_BALANCER_TABLE_FOR_EACH_TRACKED (lb, lb_table) { + struct ovn_controller_lb *clb; + if (!sbrec_load_balancer_is_new(lb)) { + clb = ovn_controller_lb_find(&rt_data->ovn_controller_lbs, + &lb->header_.uuid); + hmap_remove(&rt_data->ovn_controller_lbs, &clb->hmap_node); + hmap_insert(&rt_data->old_ovn_controller_lbs, &clb->hmap_node, + uuid_hash(&lb->header_.uuid)); + } + + if (sbrec_load_balancer_is_deleted(lb)) { + continue; + } + + clb = ovn_controller_lb_create(lb); + hmap_insert(&rt_data->ovn_controller_lbs, &clb->hmap_node, + uuid_hash(&lb->header_.uuid)); + } + + return true; +} + struct ed_type_addr_sets { struct shash addr_sets; bool change_tracked; @@ -2733,6 +2783,7 @@ init_lflow_ctx(struct engine_node *node, l_ctx_in->related_lport_ids = &rt_data->related_lports.lport_ids; l_ctx_in->binding_lports = &rt_data->lbinding_data.lports; l_ctx_in->chassis_tunnels = &non_vif_data->chassis_tunnels; + l_ctx_in->ovn_controller_lbs = &rt_data->ovn_controller_lbs; l_ctx_in->lb_hairpin_use_ct_mark = n_opts->lb_hairpin_use_ct_mark; l_ctx_in->nd_ra_opts = &fo->nd_ra_opts; l_ctx_in->dhcp_opts = &dhcp_opts->v4_opts; @@ -3849,6 +3900,8 @@ main(int argc, char *argv[]) runtime_data_sb_port_binding_handler); /* Run sb_ro_handler after port_binding_handler in case port get deleted */ engine_add_input(&en_runtime_data, &en_sb_ro, runtime_data_sb_ro_handler); + engine_add_input(&en_runtime_data, &en_sb_load_balancer, + runtime_data_sb_load_balancer_handler); /* The OVS interface handler for runtime_data changes MUST be executed * after the sb_port_binding_handler as port_binding deletes must be diff --git a/lib/lb.c b/lib/lb.c index ab5de38a8..adf2ee951 100644 --- a/lib/lb.c +++ b/lib/lb.c @@ -391,6 +391,15 @@ ovn_controller_lb_create(const struct sbrec_load_balancer *sbrec_lb) n_vips++; } + lb->proto = IPPROTO_TCP; + if (sbrec_lb->protocol && sbrec_lb->protocol[0]) { + if (!strcmp(sbrec_lb->protocol, "udp")) { + lb->proto = IPPROTO_UDP; + } else if (!strcmp(sbrec_lb->protocol, "sctp")) { + lb->proto = IPPROTO_SCTP; + } + } + /* It's possible that parsing VIPs fails. Update the lb->n_vips to the * correct value. */ @@ -404,7 +413,7 @@ ovn_controller_lb_create(const struct sbrec_load_balancer *sbrec_lb) return lb; } -void +static void ovn_controller_lb_destroy(struct ovn_controller_lb *lb) { for (size_t i = 0; i < lb->n_vips; i++) { @@ -414,3 +423,37 @@ ovn_controller_lb_destroy(struct ovn_controller_lb *lb) destroy_lport_addresses(&lb->hairpin_snat_ips); free(lb); } + +void +ovn_controller_lbs_destroy(struct hmap *ovn_controller_lbs) +{ + struct ovn_controller_lb *lb; + HMAP_FOR_EACH_POP (lb, hmap_node, ovn_controller_lbs) { + ovn_controller_lb_destroy(lb); + } + hmap_destroy(ovn_controller_lbs); +} + +struct ovn_controller_lb * +ovn_controller_lb_find(const struct hmap *ovn_controller_lbs, + const struct uuid *uuid) +{ + struct hmap_node *node = + hmap_first_with_hash(ovn_controller_lbs, uuid_hash(uuid)); + return (node + ? CONTAINER_OF(node, struct ovn_controller_lb, hmap_node) + : NULL); +} + + +void +ovn_controller_lbs_create(const struct sbrec_load_balancer_table *lb_table, + struct hmap *ovn_controller_lbs) +{ + const struct sbrec_load_balancer *sb_lb; + SBREC_LOAD_BALANCER_TABLE_FOR_EACH (sb_lb, lb_table) { + struct ovn_controller_lb *lb = ovn_controller_lb_create(sb_lb); + hmap_insert(ovn_controller_lbs, &lb->hmap_node, + uuid_hash(&sb_lb->header_.uuid)); + } +} diff --git a/lib/lb.h b/lib/lb.h index 80ac03399..a2745af90 100644 --- a/lib/lb.h +++ b/lib/lb.h @@ -28,6 +28,7 @@ struct nbrec_load_balancer; struct nbrec_load_balancer_group; struct sbrec_load_balancer; struct sbrec_datapath_binding; +struct sbrec_load_balancer_table; struct ovn_datapath; struct ovn_port; struct uuid; @@ -156,10 +157,13 @@ ovn_lb_group_add_lr(struct ovn_lb_group *lb_group, struct ovn_datapath *lr) } struct ovn_controller_lb { + struct hmap_node hmap_node; + const struct sbrec_load_balancer *slb; /* May be NULL. */ struct ovn_lb_vip *vips; size_t n_vips; + uint8_t proto; bool hairpin_orig_tuple; /* True if ovn-northd stores the original * destination tuple in registers. */ @@ -172,6 +176,11 @@ struct ovn_controller_lb { struct ovn_controller_lb *ovn_controller_lb_create( const struct sbrec_load_balancer *); -void ovn_controller_lb_destroy(struct ovn_controller_lb *); +void ovn_controller_lbs_destroy(struct hmap *ovn_controller_lbs); +struct ovn_controller_lb *ovn_controller_lb_find( + const struct hmap *ovn_controller_lbs, const struct uuid *uuid); +void ovn_controller_lbs_create( + const struct sbrec_load_balancer_table *lb_table, + struct hmap *ovn_controller_lbs); #endif /* OVN_LIB_LB_H 1 */ -- 2.37.2 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
