On Wed, Apr 30, 2025 at 7:54 AM Ales Musil <amu...@redhat.com> wrote:
> The vector has the same functionality as the x2nrealloc > for insert. Use vector instead which slightly simplifies > the final code. There is one exception that wasn't converted > that's the expr_constant_set. > > Signed-off-by: Ales Musil <amu...@redhat.com> > Acked-by: Mark Michelson <mmich...@redhat.com> > --- > v4: Rebase on top of current main. > Add ack from Mark. > v3: Rebase on top of current main. > v2: Rebase on top of current main. > --- > controller/lflow.c | 17 +++-- > controller/ovn-controller.c | 9 ++- > include/ovn/expr.h | 4 +- > lib/actions.c | 115 ++++++++++++++-------------------- > lib/expr.c | 56 ++++++++--------- > lib/inc-proc-eng.c | 120 ++++++++++++++++-------------------- > lib/lb.c | 49 ++++++--------- > lib/lb.h | 4 +- > northd/lb.c | 7 ++- > northd/northd.c | 44 +++++++------ > tests/test-ovn.c | 3 +- > 11 files changed, 187 insertions(+), 241 deletions(-) > > diff --git a/controller/lflow.c b/controller/lflow.c > index c24b2e212..0a3bf1c1c 100644 > --- a/controller/lflow.c > +++ b/controller/lflow.c > @@ -925,7 +925,7 @@ add_matches_to_flow_table(const struct > sbrec_logical_flow *lflow, > .ip = m->as_ip, > .mask = m->as_mask > }; > - if (!m->n) { > + if (vector_is_empty(&m->conjunctions)) { > ofctrl_add_flow_metered(l_ctx_out->flow_table, ptable, > lflow->priority, > lflow->header_.uuid.parts[0], > &m->match, > @@ -933,18 +933,16 @@ add_matches_to_flow_table(const struct > sbrec_logical_flow *lflow, > ctrl_meter_id, > as_info.name ? &as_info : NULL); > } else { > - if (m->n > 1) { > + if (vector_len(&m->conjunctions) > 1) { > ovs_assert(!as_info.name); > } > uint64_t conj_stubs[64 / 8]; > struct ofpbuf conj; > > ofpbuf_use_stub(&conj, conj_stubs, sizeof conj_stubs); > - for (int i = 0; i < m->n; i++) { > - const struct cls_conjunction *src = &m->conjunctions[i]; > - struct ofpact_conjunction *dst; > - > - dst = ofpact_put_CONJUNCTION(&conj); > + const struct cls_conjunction *src; > + VECTOR_FOR_EACH_PTR (&m->conjunctions, src) { > + struct ofpact_conjunction *dst = > ofpact_put_CONJUNCTION(&conj); > dst->id = src->id; > dst->clause = src->clause; > dst->n_clauses = src->n_clauses; > @@ -1941,9 +1939,8 @@ consider_lb_hairpin_flows(const struct > ovn_controller_lb *lb, > for (size_t 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]; > - > + struct ovn_lb_backend *lb_backend; > + VECTOR_FOR_EACH_PTR (&lb_vip->backends, lb_backend) { > add_lb_vip_hairpin_flows(lb, lb_vip, lb_backend, flow_table, > register_consolidation); > } > diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c > index 75b1ac750..180b8a8d2 100644 > --- a/controller/ovn-controller.c > +++ b/controller/ovn-controller.c > @@ -2683,9 +2683,9 @@ lb_data_removed_five_tuples_add(struct > ed_type_lb_data *lb_data, > > for (size_t i = 0; i < lb->n_vips; i++) { > struct ovn_lb_vip *vip = &lb->vips[i]; > - for (size_t j = 0; j < vip->n_backends; j++) { > - struct ovn_lb_backend *backend = &vip->backends[j]; > > + const struct ovn_lb_backend *backend; > + VECTOR_FOR_EACH_PTR (&vip->backends, backend) { > ovn_lb_5tuple_add(&lb_data->removed_tuples, vip, backend, > lb->proto); > } > @@ -2703,10 +2703,9 @@ lb_data_removed_five_tuples_remove(struct > ed_type_lb_data *lb_data, > > for (size_t i = 0; i < lb->n_vips; i++) { > struct ovn_lb_vip *vip = &lb->vips[i]; > - for (size_t j = 0; j < vip->n_backends; j++) { > - struct ovn_lb_backend *backend = &vip->backends[j]; > - > > + const struct ovn_lb_backend *backend; > + VECTOR_FOR_EACH_PTR (&vip->backends, backend) { > struct ovn_lb_5tuple tuple; > ovn_lb_5tuple_init(&tuple, vip, backend, lb->proto); > ovn_lb_5tuple_find_and_delete(&lb_data->removed_tuples, > &tuple); > diff --git a/include/ovn/expr.h b/include/ovn/expr.h > index e54edb5bf..9621a2c09 100644 > --- a/include/ovn/expr.h > +++ b/include/ovn/expr.h > @@ -60,6 +60,7 @@ > #include "openvswitch/meta-flow.h" > #include "logical-fields.h" > #include "smap.h" > +#include "vec.h" > > struct ds; > struct expr; > @@ -471,8 +472,7 @@ bool expr_evaluate(const struct expr *, const struct > flow *uflow, > struct expr_match { > struct hmap_node hmap_node; > struct match match; > - struct cls_conjunction *conjunctions; > - size_t n, allocated; > + struct vector conjunctions; /* Vector of struct cls_conjunction. */ > > /* Tracked address set information. */ > char *as_name; > diff --git a/lib/actions.c b/lib/actions.c > index 75d0951fc..cd969c684 100644 > --- a/lib/actions.c > +++ b/lib/actions.c > @@ -42,6 +42,7 @@ > #include "socket-util.h" > #include "lib/ovn-util.h" > #include "controller/lflow.h" > +#include "vec.h" > > VLOG_DEFINE_THIS_MODULE(actions); > > @@ -1208,9 +1209,7 @@ parse_ct_lb_action(struct action_context *ctx, bool > ct_lb_mark) > > add_prerequisite(ctx, "ip"); > > - struct ovnact_ct_lb_dst *dsts = NULL; > - size_t allocated_dsts = 0; > - size_t n_dsts = 0; > + struct vector dsts = VECTOR_EMPTY_INITIALIZER(struct > ovnact_ct_lb_dst); > char *hash_fields = NULL; > enum ovnact_ct_lb_flag ct_flag = OVNACT_CT_LB_FLAG_NONE; > > @@ -1229,7 +1228,7 @@ parse_ct_lb_action(struct action_context *ctx, bool > ct_lb_mark) > /* IPv6 address and port */ > if (ctx->lexer->token.type != LEX_T_INTEGER > || ctx->lexer->token.format != LEX_F_IPV6) { > - free(dsts); > + vector_destroy(&dsts); > lexer_syntax_error(ctx->lexer, "expecting IPv6 > address"); > return; > } > @@ -1238,7 +1237,7 @@ parse_ct_lb_action(struct action_context *ctx, bool > ct_lb_mark) > > lexer_get(ctx->lexer); > if (!lexer_match(ctx->lexer, LEX_T_RSQUARE)) { > - free(dsts); > + vector_destroy(&dsts); > lexer_syntax_error(ctx->lexer, "no closing square " > "bracket"); > return; > @@ -1246,14 +1245,14 @@ parse_ct_lb_action(struct action_context *ctx, > bool ct_lb_mark) > dst.port = 0; > if (lexer_match(ctx->lexer, LEX_T_COLON) > && !action_parse_uint16(ctx, &dst.port, "port > number")) { > - free(dsts); > + vector_destroy(&dsts); > return; > } > } else { > if (ctx->lexer->token.type != LEX_T_INTEGER > || (ctx->lexer->token.format != LEX_F_IPV4 > && ctx->lexer->token.format != LEX_F_IPV6)) { > - free(dsts); > + vector_destroy(&dsts); > lexer_syntax_error(ctx->lexer, "expecting IP > address"); > return; > } > @@ -1271,31 +1270,27 @@ parse_ct_lb_action(struct action_context *ctx, > bool ct_lb_mark) > dst.port = 0; > if (lexer_match(ctx->lexer, LEX_T_COLON)) { > if (dst.family == AF_INET6) { > - free(dsts); > + vector_destroy(&dsts);; > lexer_syntax_error(ctx->lexer, "IPv6 address > needs " > "square brackets if port is included"); > return; > } else if (!action_parse_uint16(ctx, &dst.port, > "port number")) { > - free(dsts); > + vector_destroy(&dsts); > return; > } > } > } > lexer_match(ctx->lexer, LEX_T_COMMA); > > - /* Append to dsts. */ > - if (n_dsts >= allocated_dsts) { > - dsts = x2nrealloc(dsts, &allocated_dsts, sizeof *dsts); > - } > - dsts[n_dsts++] = dst; > + vector_push(&dsts, &dst); > } > > if (lexer_match_id(ctx->lexer, "hash_fields")) { > if (!lexer_match(ctx->lexer, LEX_T_EQUALS) || > ctx->lexer->token.type != LEX_T_STRING) { > lexer_syntax_error(ctx->lexer, "invalid hash_fields"); > - free(dsts); > + vector_destroy(&dsts); > return; > } > > @@ -1318,8 +1313,8 @@ parse_ct_lb_action(struct action_context *ctx, bool > ct_lb_mark) > struct ovnact_ct_lb *cl = ct_lb_mark ? > ovnact_put_CT_LB_MARK(ctx->ovnacts) > : ovnact_put_CT_LB(ctx->ovnacts); > cl->ltable = ctx->pp->cur_ltable + 1; > - cl->dsts = dsts; > - cl->n_dsts = n_dsts; > + cl->n_dsts = vector_len(&dsts); > + cl->dsts = vector_steal_array(&dsts); > cl->hash_fields = hash_fields; > cl->ct_flag = ct_flag; > } > @@ -1542,9 +1537,7 @@ parse_select_action(struct action_context *ctx, > struct expr_field *res_field) > return; > } > > - struct ovnact_select_dst *dsts = NULL; > - size_t allocated_dsts = 0; > - size_t n_dsts = 0; > + struct vector dsts = VECTOR_EMPTY_INITIALIZER(struct > ovnact_select_dst); > bool requires_hash_fields = false; > char *hash_fields = NULL; > > @@ -1560,14 +1553,14 @@ parse_select_action(struct action_context *ctx, > struct expr_field *res_field) > while (!lexer_match(ctx->lexer, LEX_T_RPAREN)) { > struct ovnact_select_dst dst; > if (!action_parse_uint16(ctx, &dst.id, "id")) { > - free(dsts); > + vector_destroy(&dsts); > return; > } > > dst.weight = 0; > if (lexer_match(ctx->lexer, LEX_T_EQUALS)) { > if (!action_parse_uint16(ctx, &dst.weight, "weight")) { > - free(dsts); > + vector_destroy(&dsts); > return; > } > if (dst.weight == 0) { > @@ -1581,15 +1574,11 @@ parse_select_action(struct action_context *ctx, > struct expr_field *res_field) > > lexer_match(ctx->lexer, LEX_T_COMMA); > > - /* Append to dsts. */ > - if (n_dsts >= allocated_dsts) { > - dsts = x2nrealloc(dsts, &allocated_dsts, sizeof *dsts); > - } > - dsts[n_dsts++] = dst; > + vector_push(&dsts, &dst); > } > - if (n_dsts <= 1) { > + if (vector_len(&dsts) <= 1) { > lexer_syntax_error(ctx->lexer, "expecting at least 2 group > members"); > - free(dsts); > + vector_destroy(&dsts); > return; > } > > @@ -1597,14 +1586,14 @@ parse_select_action(struct action_context *ctx, > struct expr_field *res_field) > lexer_force_match(ctx->lexer, LEX_T_SEMICOLON); > if (!lexer_match_id(ctx->lexer, "hash_fields")) { > lexer_syntax_error(ctx->lexer, "expecting hash_fields"); > - free(dsts); > + vector_destroy(&dsts); > return; > } > if (!lexer_match(ctx->lexer, LEX_T_EQUALS) || > ctx->lexer->token.type != LEX_T_STRING || > lexer_lookahead(ctx->lexer) != LEX_T_RPAREN) { > lexer_syntax_error(ctx->lexer, "invalid hash_fields"); > - free(dsts); > + vector_destroy(&dsts); > return; > } > hash_fields = xstrdup(ctx->lexer->token.s); > @@ -1614,8 +1603,8 @@ parse_select_action(struct action_context *ctx, > struct expr_field *res_field) > > struct ovnact_select *select = ovnact_put_SELECT(ctx->ovnacts); > select->ltable = ctx->pp->cur_ltable + 1; > - select->dsts = dsts; > - select->n_dsts = n_dsts; > + select->n_dsts = vector_len(&dsts); > + select->dsts = vector_steal_array(&dsts); > select->res_field = *res_field; > select->hash_fields = hash_fields; > } > @@ -2681,26 +2670,23 @@ parse_trigger_event(struct action_context *ctx, > > lexer_match(ctx->lexer, LEX_T_COMMA); > > - size_t allocated_options = 0; > + struct vector options = VECTOR_EMPTY_INITIALIZER(struct > ovnact_gen_option); > while (!lexer_match(ctx->lexer, LEX_T_RPAREN)) { > - if (event->n_options >= allocated_options) { > - event->options = x2nrealloc(event->options, > &allocated_options, > - sizeof *event->options); > - } > - > - struct ovnact_gen_option *o = &event->options[event->n_options++]; > - memset(o, 0, sizeof *o); > - parse_gen_opt(ctx, o, > + struct ovnact_gen_option o = {0}; > + parse_gen_opt(ctx, &o, > > &ctx->pp->controller_event_opts->event_opts[event_type], > event_to_string(event_type)); > + vector_push(&options, &o); > > if (ctx->lexer->error) { > return; > } > - > lexer_match(ctx->lexer, LEX_T_COMMA); > } > > + event->n_options = vector_len(&options); > + event->options = vector_steal_array(&options); > + > switch (event_type) { > case OVN_EVENT_EMPTY_LB_BACKENDS: > validate_empty_lb_backends(ctx, event->options, event->n_options); > @@ -2838,22 +2824,21 @@ parse_put_opts(struct action_context *ctx, const > struct expr_field *dst, > } > po->dst = *dst; > > - size_t allocated_options = 0; > + struct vector options = VECTOR_EMPTY_INITIALIZER(struct > ovnact_gen_option); > while (!lexer_match(ctx->lexer, LEX_T_RPAREN)) { > - if (po->n_options >= allocated_options) { > - po->options = x2nrealloc(po->options, &allocated_options, > - sizeof *po->options); > - } > + struct ovnact_gen_option o = {0}; > + parse_gen_opt(ctx, &o, gen_opts, opts_type); > + vector_push(&options, &o); > > - struct ovnact_gen_option *o = &po->options[po->n_options++]; > - memset(o, 0, sizeof *o); > - parse_gen_opt(ctx, o, gen_opts, opts_type); > if (ctx->lexer->error) { > - return; > + break; > } > > lexer_match(ctx->lexer, LEX_T_COMMA); > } > + > + po->n_options = vector_len(&options); > + po->options = vector_steal_array(&options); > } > > /* Parses the "put_dhcp_opts" and "put_dhcpv6_opts" actions. > @@ -4134,9 +4119,8 @@ ovnact_handle_svc_check_free(struct > ovnact_handle_svc_check *sc OVS_UNUSED) > static void > parse_fwd_group_action(struct action_context *ctx) > { > - char *child_port, **child_port_list = NULL; > - size_t allocated_ports = 0; > - size_t n_child_ports = 0; > + struct vector child_port_list = VECTOR_EMPTY_INITIALIZER(char *); > + char *child_port = NULL; > bool liveness = false; > > if (lexer_match(ctx->lexer, LEX_T_LPAREN)) { > @@ -4165,25 +4149,18 @@ parse_fwd_group_action(struct action_context *ctx) > if (ctx->lexer->token.type != LEX_T_STRING) { > lexer_syntax_error(ctx->lexer, > "expecting logical switch port"); > - if (child_port_list) { > - for (int i = 0; i < n_child_ports; i++) { > - free(child_port_list[i]); > - } > - free(child_port_list); > + char *port; > + VECTOR_FOR_EACH (&child_port_list, port) { > + free(port); > } > + vector_destroy(&child_port_list); > return; > } > /* Parse child's logical ports */ > child_port = xstrdup(ctx->lexer->token.s); > lexer_get(ctx->lexer); > lexer_match(ctx->lexer, LEX_T_COMMA); > - > - if (n_child_ports >= allocated_ports) { > - child_port_list = x2nrealloc(child_port_list, > - &allocated_ports, > - sizeof *child_port_list); > - } > - child_port_list[n_child_ports++] = child_port; > + vector_push(&child_port_list, &child_port); > } > } > } > @@ -4191,8 +4168,8 @@ parse_fwd_group_action(struct action_context *ctx) > struct ovnact_fwd_group *fwd_group = > ovnact_put_FWD_GROUP(ctx->ovnacts); > fwd_group->ltable = ctx->pp->cur_ltable + 1; > fwd_group->liveness = liveness; > - fwd_group->child_ports = child_port_list; > - fwd_group->n_child_ports = n_child_ports; > + fwd_group->n_child_ports = vector_len(&child_port_list); > + fwd_group->child_ports = vector_steal_array(&child_port_list); > } > > static void > diff --git a/lib/expr.c b/lib/expr.c > index ecf8a6338..937fecb75 100644 > --- a/lib/expr.c > +++ b/lib/expr.c > @@ -3141,16 +3141,16 @@ expr_match_new(const struct match *m, uint8_t > clause, uint8_t n_clauses, > match_init_catchall(&match->match); > } > if (conj_id) { > - match->conjunctions = xmalloc(sizeof *match->conjunctions); > - match->conjunctions[0].id = conj_id; > - match->conjunctions[0].clause = clause; > - match->conjunctions[0].n_clauses = n_clauses; > - match->n = 1; > - match->allocated = 1; > + match->conjunctions = > + VECTOR_CAPACITY_INITIALIZER(struct cls_conjunction, 1); > + struct cls_conjunction conj = (struct cls_conjunction) { > + .id = conj_id, > + .clause = clause, > + .n_clauses = n_clauses, > + }; > + vector_push(&match->conjunctions, &conj); > } else { > - match->conjunctions = NULL; > - match->n = 0; > - match->allocated = 0; > + match->conjunctions = VECTOR_EMPTY_INITIALIZER(struct > cls_conjunction); > } > return match; > } > @@ -3159,7 +3159,7 @@ void > expr_match_destroy(struct expr_match *match) > { > free(match->as_name); > - free(match->conjunctions); > + vector_destroy(&match->conjunctions); > free(match); > } > > @@ -3176,19 +3176,13 @@ expr_match_add(struct hmap *matches, struct > expr_match *match) > > HMAP_FOR_EACH_WITH_HASH (m, hmap_node, hash, matches) { > if (match_equal(&m->match, &match->match)) { > - if (!m->n || !match->n) { > - free(m->conjunctions); > - m->conjunctions = NULL; > - m->n = 0; > - m->allocated = 0; > + if (vector_is_empty(&m->conjunctions) || > + vector_is_empty(&match->conjunctions)) { > + vector_destroy(&m->conjunctions); > } else { > - ovs_assert(match->n == 1); > - if (m->n >= m->allocated) { > - m->conjunctions = x2nrealloc(m->conjunctions, > - &m->allocated, > - sizeof *m->conjunctions); > - } > - m->conjunctions[m->n++] = match->conjunctions[0]; > + ovs_assert(vector_len(&match->conjunctions) == 1); > + vector_push(&m->conjunctions, > + vector_get_ptr(&match->conjunctions, 0)); > } > if (m->as_name) { > /* m is combined with match. so untracked the address > set. */ > @@ -3461,11 +3455,11 @@ expr_matches_prepare(struct hmap *matches, > uint32_t conj_id_ofs) > m->match.flow.conj_id += conj_id_ofs; > } > > - for (size_t i = 0; i < m->n; i++) { > - struct cls_conjunction *src = &m->conjunctions[i]; > + struct cls_conjunction *src; > + VECTOR_FOR_EACH_PTR (&m->conjunctions, src) { > src->id += conj_id_ofs; > } > - total_size += sizeof *m + m->allocated * sizeof *m->conjunctions; > + total_size += sizeof *m + vector_memory_usage(&m->conjunctions); > } > return total_size; > } > @@ -3503,12 +3497,12 @@ expr_matches_print(const struct hmap *matches, > FILE *stream) > fputs(s, stream); > free(s); > > - if (m->n) { > - for (int i = 0; i < m->n; i++) { > - const struct cls_conjunction *c = &m->conjunctions[i]; > - fprintf(stream, "%c conjunction(%"PRIu32", %d/%d)", > - i == 0 ? ':' : ',', c->id, c->clause, > c->n_clauses); > - } > + bool first = true; > + struct cls_conjunction *c; > + VECTOR_FOR_EACH_PTR (&m->conjunctions, c) { > + fprintf(stream, "%c conjunction(%"PRIu32", %d/%d)", > + first ? ':' : ',', c->id, c->clause, c->n_clauses); > + first = false; > } > putc('\n', stream); > } > diff --git a/lib/inc-proc-eng.c b/lib/inc-proc-eng.c > index 56dc62c4f..c410af5cd 100644 > --- a/lib/inc-proc-eng.c > +++ b/lib/inc-proc-eng.c > @@ -30,6 +30,7 @@ > #include "inc-proc-eng.h" > #include "timeval.h" > #include "unixctl.h" > +#include "vec.h" > > VLOG_DEFINE_THIS_MODULE(inc_proc_eng); > > @@ -37,8 +38,8 @@ static bool engine_force_recompute = false; > static bool engine_run_canceled = false; > static const struct engine_context *engine_context; > > -static struct engine_node **engine_nodes; > -static size_t engine_n_nodes; > +static struct vector engine_nodes = > + VECTOR_EMPTY_INITIALIZER(struct engine_node *); > > static const char *engine_node_state_name[EN_STATE_MAX] = { > [EN_STALE] = "Stale", > @@ -93,50 +94,32 @@ engine_set_context(const struct engine_context *ctx) > /* Builds the topologically sorted 'sorted_nodes' array starting from > * 'node'. > */ > -static struct engine_node ** > -engine_topo_sort(struct engine_node *node, struct engine_node > **sorted_nodes, > - size_t *n_count, size_t *n_size) > +static void > +engine_topo_sort(struct engine_node *node, struct vector *sorted_nodes) > { > /* It's not so efficient to walk the array of already sorted nodes but > * we know that sorting is done only once at startup so it's ok for > now. > */ > - for (size_t i = 0; i < *n_count; i++) { > - if (sorted_nodes[i] == node) { > - return sorted_nodes; > + struct engine_node *sorted_node; > + VECTOR_FOR_EACH (sorted_nodes, sorted_node) { > + if (sorted_node == node) { > + return; > } > } > > for (size_t i = 0; i < node->n_inputs; i++) { > - sorted_nodes = engine_topo_sort(node->inputs[i].node, > sorted_nodes, > - n_count, n_size); > - } > - if (*n_count == *n_size) { > - sorted_nodes = x2nrealloc(sorted_nodes, n_size, sizeof > *sorted_nodes); > + engine_topo_sort(node->inputs[i].node, sorted_nodes); > } > - sorted_nodes[(*n_count)] = node; > - (*n_count)++; > - return sorted_nodes; > -} > > -/* Return the array of topologically sorted nodes when starting from > - * 'node'. Stores the number of nodes in 'n_count'. > - */ > -static struct engine_node ** > -engine_get_nodes(struct engine_node *node, size_t *n_count) > -{ > - size_t n_size = 0; > - > - *n_count = 0; > - return engine_topo_sort(node, NULL, n_count, &n_size); > + vector_push(sorted_nodes, &node); > } > > static void > engine_clear_stats(struct unixctl_conn *conn, int argc OVS_UNUSED, > const char *argv[] OVS_UNUSED, void *arg OVS_UNUSED) > { > - for (size_t i = 0; i < engine_n_nodes; i++) { > - struct engine_node *node = engine_nodes[i]; > - > + struct engine_node *node; > + VECTOR_FOR_EACH (&engine_nodes, node) { > memset(&node->stats, 0, sizeof node->stats); > } > unixctl_command_reply(conn, NULL); > @@ -150,9 +133,8 @@ engine_dump_stats(struct unixctl_conn *conn, int argc, > const char *dump_eng_node_name = (argc > 1 ? argv[1] : NULL); > const char *dump_stat_type = (argc > 2 ? argv[2] : NULL); > > - for (size_t i = 0; i < engine_n_nodes; i++) { > - struct engine_node *node = engine_nodes[i]; > - > + struct engine_node *node; > + VECTOR_FOR_EACH (&engine_nodes, node) { > if (dump_eng_node_name && strcmp(node->name, dump_eng_node_name)) > { > continue; > } > @@ -213,14 +195,14 @@ engine_set_log_timeout_cmd(struct unixctl_conn > *conn, int argc OVS_UNUSED, > void > engine_init(struct engine_node *node, struct engine_arg *arg) > { > - engine_nodes = engine_get_nodes(node, &engine_n_nodes); > + engine_topo_sort(node, &engine_nodes); > > - for (size_t i = 0; i < engine_n_nodes; i++) { > - if (engine_nodes[i]->init) { > - engine_nodes[i]->data = > - engine_nodes[i]->init(engine_nodes[i], arg); > + struct engine_node *sorted_node; > + VECTOR_FOR_EACH (&engine_nodes, sorted_node) { > + if (sorted_node->init) { > + sorted_node->data = sorted_node->init(sorted_node, arg); > } else { > - engine_nodes[i]->data = NULL; > + sorted_node->data = NULL; > } > } > > @@ -237,19 +219,18 @@ engine_init(struct engine_node *node, struct > engine_arg *arg) > void > engine_cleanup(void) > { > - for (size_t i = 0; i < engine_n_nodes; i++) { > - if (engine_nodes[i]->clear_tracked_data) { > - engine_nodes[i]->clear_tracked_data(engine_nodes[i]->data); > + struct engine_node *node; > + VECTOR_FOR_EACH (&engine_nodes, node) { > + if (node->clear_tracked_data) { > + node->clear_tracked_data(node->data); > } > > - if (engine_nodes[i]->cleanup) { > - engine_nodes[i]->cleanup(engine_nodes[i]->data); > + if (node->cleanup) { > + node->cleanup(node->data); > } > - free(engine_nodes[i]->data); > + free(node->data); > } > - free(engine_nodes); > - engine_nodes = NULL; > - engine_n_nodes = 0; > + vector_destroy(&engine_nodes); > } > > struct engine_node * > @@ -346,8 +327,9 @@ engine_node_changed(struct engine_node *node) > bool > engine_has_run(void) > { > - for (size_t i = 0; i < engine_n_nodes; i++) { > - if (engine_nodes[i]->state != EN_STALE) { > + struct engine_node *node; > + VECTOR_FOR_EACH (&engine_nodes, node) { > + if (node->state != EN_STALE) { > return true; > } > } > @@ -357,8 +339,9 @@ engine_has_run(void) > bool > engine_has_updated(void) > { > - for (size_t i = 0; i < engine_n_nodes; i++) { > - if (engine_nodes[i]->state == EN_UPDATED) { > + struct engine_node *node; > + VECTOR_FOR_EACH (&engine_nodes, node) { > + if (node->state == EN_UPDATED) { > return true; > } > } > @@ -390,11 +373,12 @@ void > engine_init_run(void) > { > VLOG_DBG("Initializing new run"); > - for (size_t i = 0; i < engine_n_nodes; i++) { > - engine_set_node_state(engine_nodes[i], EN_STALE); > + struct engine_node *node; > + VECTOR_FOR_EACH (&engine_nodes, node) { > + engine_set_node_state(node, EN_STALE); > > - if (engine_nodes[i]->clear_tracked_data) { > - engine_nodes[i]->clear_tracked_data(engine_nodes[i]->data); > + if (node->clear_tracked_data) { > + node->clear_tracked_data(node->data); > } > } > } > @@ -539,11 +523,12 @@ engine_run(bool recompute_allowed) > } > > engine_run_canceled = false; > - for (size_t i = 0; i < engine_n_nodes; i++) { > - engine_run_node(engine_nodes[i], recompute_allowed); > + struct engine_node *node; > + VECTOR_FOR_EACH (&engine_nodes, node) { > + engine_run_node(node, recompute_allowed); > > - if (engine_nodes[i]->state == EN_CANCELED) { > - engine_nodes[i]->stats.cancel++; > + if (node->state == EN_CANCELED) { > + node->stats.cancel++; > engine_run_canceled = true; > return; > } > @@ -553,17 +538,18 @@ engine_run(bool recompute_allowed) > bool > engine_need_run(void) > { > - for (size_t i = 0; i < engine_n_nodes; i++) { > + struct engine_node *node; > + VECTOR_FOR_EACH (&engine_nodes, node) { > /* Check only leaf nodes for updates. */ > - if (engine_nodes[i]->n_inputs) { > + if (node->n_inputs) { > continue; > } > > - engine_nodes[i]->run(engine_nodes[i], engine_nodes[i]->data); > - engine_nodes[i]->stats.recompute++; > - VLOG_DBG("input node: %s, state: %s", engine_nodes[i]->name, > - engine_node_state_name[engine_nodes[i]->state]); > - if (engine_nodes[i]->state == EN_UPDATED) { > + node->run(node, node->data); > + node->stats.recompute++; > + VLOG_DBG("input node: %s, state: %s", node->name, > + engine_node_state_name[node->state]); > + if (node->state == EN_UPDATED) { > return true; > } > } > diff --git a/lib/lb.c b/lib/lb.c > index 6e7a4e296..cd234adb8 100644 > --- a/lib/lb.c > +++ b/lib/lb.c > @@ -77,27 +77,20 @@ static char * > ovn_lb_backends_init_explicit(struct ovn_lb_vip *lb_vip, const char > *value) > { > struct ds errors = DS_EMPTY_INITIALIZER; > - size_t n_allocated_backends = 0; > char *tokstr = xstrdup(value); > char *save_ptr = NULL; > - lb_vip->n_backends = 0; > + lb_vip->backends = VECTOR_EMPTY_INITIALIZER(struct ovn_lb_backend); > > for (char *token = strtok_r(tokstr, ",", &save_ptr); > token != NULL; > token = strtok_r(NULL, ",", &save_ptr)) { > > - if (lb_vip->n_backends == n_allocated_backends) { > - lb_vip->backends = x2nrealloc(lb_vip->backends, > - &n_allocated_backends, > - sizeof *lb_vip->backends); > - } > - > - struct ovn_lb_backend *backend = > &lb_vip->backends[lb_vip->n_backends]; > - if (!ovn_lb_backend_init_explicit(lb_vip, backend, token, > &errors)) { > + struct ovn_lb_backend backend = {0}; > + if (!ovn_lb_backend_init_explicit(lb_vip, &backend, token, > &errors)) { > continue; > } > > - lb_vip->n_backends++; > + vector_push(&lb_vip->backends, &backend); > } > free(tokstr); > > @@ -190,31 +183,25 @@ ovn_lb_backends_init_template(struct ovn_lb_vip > *lb_vip, const char *value_) > struct ds errors = DS_EMPTY_INITIALIZER; > char *value = xstrdup(value_); > char *save_ptr = NULL; > - size_t n_allocated_backends = 0; > - lb_vip->n_backends = 0; > + lb_vip->backends = VECTOR_EMPTY_INITIALIZER(struct ovn_lb_backend); > > for (char *token = strtok_r(value, ",", &save_ptr); token; > token = strtok_r(NULL, ",", &save_ptr)) { > > - if (lb_vip->n_backends == n_allocated_backends) { > - lb_vip->backends = x2nrealloc(lb_vip->backends, > - &n_allocated_backends, > - sizeof *lb_vip->backends); > - } > > - struct ovn_lb_backend *backend = > &lb_vip->backends[lb_vip->n_backends]; > + struct ovn_lb_backend backend = {0}; > if (token[0] && token[0] == '^') { > - if (!ovn_lb_backend_init_template(backend, token, &errors)) { > + if (!ovn_lb_backend_init_template(&backend, token, &errors)) { > continue; > } > } else { > - if (!ovn_lb_backend_init_explicit(lb_vip, backend, > + if (!ovn_lb_backend_init_explicit(lb_vip, &backend, > token, &errors)) { > continue; > } > } > > - lb_vip->n_backends++; > + vector_push(&lb_vip->backends, &backend); > } > > free(value); > @@ -292,11 +279,12 @@ ovn_lb_vip_init(struct ovn_lb_vip *lb_vip, const > char *lb_key, > static void > ovn_lb_backends_destroy(struct ovn_lb_vip *vip) > { > - for (size_t i = 0; i < vip->n_backends; i++) { > - free(vip->backends[i].ip_str); > - free(vip->backends[i].port_str); > + struct ovn_lb_backend *backend; > + VECTOR_FOR_EACH_PTR (&vip->backends, backend) { > + free(backend->ip_str); > + free(backend->port_str); > } > - free(vip->backends); > + vector_destroy(&vip->backends); > } > > void > @@ -334,8 +322,8 @@ ovn_lb_vip_format(const struct ovn_lb_vip *vip, struct > ds *s, bool template) > void > ovn_lb_vip_backends_format(const struct ovn_lb_vip *vip, struct ds *s) > { > - for (size_t i = 0; i < vip->n_backends; i++) { > - struct ovn_lb_backend *backend = &vip->backends[i]; > + const struct ovn_lb_backend *backend; > + VECTOR_FOR_EACH_PTR (&vip->backends, backend) { > bool needs_brackets = vip->address_family == AF_INET6 && > vip->port_str && > !ipv6_addr_equals(&backend->ip, > &in6addr_any); > @@ -349,10 +337,9 @@ ovn_lb_vip_backends_format(const struct ovn_lb_vip > *vip, struct ds *s) > if (backend->port_str) { > ds_put_format(s, ":%s", backend->port_str); > } > - if (i != vip->n_backends - 1) { > - ds_put_char(s, ','); > - } > + ds_put_char(s, ','); > } > + ds_chomp(s, ','); > } > > /* Formats the VIP in the way the ovn-controller expects it, that is, > diff --git a/lib/lb.h b/lib/lb.h > index b1a89d63c..ce5ad3580 100644 > --- a/lib/lb.h > +++ b/lib/lb.h > @@ -24,6 +24,7 @@ > #include "ovn-util.h" > #include "sset.h" > #include "uuid.h" > +#include "vec.h" > > struct uuid; > > @@ -37,8 +38,7 @@ struct ovn_lb_vip { > * in ovn-northd. > */ > bool template_vips; /* True if the vips are templates. */ > - struct ovn_lb_backend *backends; > - size_t n_backends; > + struct vector backends; /* Vector of struct ovn_lb_backend. */ > > bool empty_backend_rej; > int address_family; > diff --git a/northd/lb.c b/northd/lb.c > index af0c92954..ffd21c5bc 100644 > --- a/northd/lb.c > +++ b/northd/lb.c > @@ -93,7 +93,7 @@ void ovn_northd_lb_vip_init(struct ovn_northd_lb_vip > *lb_vip_nb, > bool template) > { > lb_vip_nb->backend_ips = xstrdup(backend_ips); > - lb_vip_nb->n_backends = lb_vip->n_backends; > + lb_vip_nb->n_backends = vector_len(&lb_vip->backends); > lb_vip_nb->backends_nb = xcalloc(lb_vip_nb->n_backends, > sizeof *lb_vip_nb->backends_nb); > lb_vip_nb->lb_health_check = > @@ -107,8 +107,9 @@ ovn_lb_vip_backends_health_check_init(const struct > ovn_northd_lb *lb, > { > struct ds key = DS_EMPTY_INITIALIZER; > > - for (size_t j = 0; j < lb_vip->n_backends; j++) { > - struct ovn_lb_backend *backend = &lb_vip->backends[j]; > + for (size_t j = 0; j < vector_len(&lb_vip->backends); j++) { > + const struct ovn_lb_backend *backend = > + vector_get_ptr(&lb_vip->backends, j); > ds_clear(&key); > ds_put_format(&key, IN6_IS_ADDR_V4MAPPED(&lb_vip->vip) > ? "%s" : "[%s]", backend->ip_str); > diff --git a/northd/northd.c b/northd/northd.c > index 464b3798a..9a49fb8f1 100644 > --- a/northd/northd.c > +++ b/northd/northd.c > @@ -3751,8 +3751,9 @@ ovn_lb_svc_create(struct ovsdb_idl_txn *ovnsb_txn, > struct ovn_lb_vip *lb_vip = &lb->vips[i]; > struct ovn_northd_lb_vip *lb_vip_nb = &lb->vips_nb[i]; > > - for (size_t j = 0; j < lb_vip->n_backends; j++) { > - struct ovn_lb_backend *backend = &lb_vip->backends[j]; > + for (size_t j = 0; j < vector_len(&lb_vip->backends); j++) { > + const struct ovn_lb_backend *backend = > + vector_get_ptr(&lb_vip->backends, j); > struct ovn_northd_lb_backend *backend_nb = > &lb_vip_nb->backends_nb[j]; > > @@ -3826,8 +3827,10 @@ build_lb_vip_actions(const struct ovn_northd_lb *lb, > bool ls_dp, > const struct hmap *svc_monitor_map) > { > - bool reject = !lb_vip->n_backends && lb_vip->empty_backend_rej; > - bool drop = !lb_vip->n_backends && !lb_vip->empty_backend_rej; > + bool reject = > + vector_is_empty(&lb_vip->backends) && lb_vip->empty_backend_rej; > + bool drop = > + vector_is_empty(&lb_vip->backends) && !lb_vip->empty_backend_rej; > > if (ls_dp || lb->affinity_timeout) { > const char *ip_reg = > @@ -3842,11 +3845,12 @@ build_lb_vip_actions(const struct ovn_northd_lb > *lb, > if (lb_vip_nb->lb_health_check) { > ds_put_cstr(action, "ct_lb_mark(backends="); > > + size_t i = 0; > size_t n_active_backends = 0; > - for (size_t i = 0; i < lb_vip->n_backends; i++) { > - struct ovn_lb_backend *backend = &lb_vip->backends[i]; > + const struct ovn_lb_backend *backend; > + VECTOR_FOR_EACH_PTR (&lb_vip->backends, backend) { > struct ovn_northd_lb_backend *backend_nb = > - &lb_vip_nb->backends_nb[i]; > + &lb_vip_nb->backends_nb[i++]; > > if (!backend_nb->health_check) { > continue; > @@ -6373,7 +6377,7 @@ build_empty_lb_event_flow(struct ovn_lb_vip *lb_vip, > { > bool controller_event = lb->controller_event || > controller_event_en; /* deprecated */ > - if (!controller_event || lb_vip->n_backends || > + if (!controller_event || !vector_is_empty(&lb_vip->backends) || > lb_vip->empty_backend_rej) { > return false; > } > @@ -8195,9 +8199,8 @@ build_lb_affinity_lr_flows(struct lflow_table > *lflows, > size_t aff_match_learn_len = aff_match_learn.length; > > > - for (size_t i = 0; i < lb_vip->n_backends; i++) { > - struct ovn_lb_backend *backend = &lb_vip->backends[i]; > - > + struct ovn_lb_backend *backend; > + VECTOR_FOR_EACH_PTR (&lb_vip->backends, backend) { > ds_put_cstr(&aff_match_learn, backend->ip_str); > ds_put_cstr(&aff_match, backend->ip_str); > > @@ -8370,9 +8373,8 @@ build_lb_affinity_ls_flows(struct lflow_table > *lflows, > size_t aff_match_len = aff_match.length; > size_t aff_match_learn_len = aff_match_learn.length; > > - for (size_t i = 0; i < lb_vip->n_backends; i++) { > - struct ovn_lb_backend *backend = &lb_vip->backends[i]; > - > + const struct ovn_lb_backend *backend; > + VECTOR_FOR_EACH_PTR (&lb_vip->backends, backend) { > ds_put_cstr(&aff_match_learn, backend->ip_str); > ds_put_cstr(&aff_match, backend->ip_str); > > @@ -12246,8 +12248,9 @@ build_distr_lrouter_nat_flows_for_lb(struct > lrouter_nat_lb_flows_ctx *ctx, > * (created by ct_lb_mark for the first rcv packet in this flow). > */ > if (stateless_nat) { > - if (ctx->lb_vip->n_backends) { > - struct ovn_lb_backend *backend = &ctx->lb_vip->backends[0]; > + if (!vector_is_empty(&ctx->lb_vip->backends)) { > + const struct ovn_lb_backend *backend = > + vector_get_ptr(&ctx->lb_vip->backends, 0); > bool ipv6 = !IN6_IS_ADDR_V4MAPPED(&backend->ip); > ds_put_format(&dnat_action, "%s.dst = %s; ", ipv6 ? "ip6" : > "ip4", > backend->ip_str); > @@ -12261,7 +12264,8 @@ build_distr_lrouter_nat_flows_for_lb(struct > lrouter_nat_lb_flows_ctx *ctx, > meter = copp_meter_get(COPP_REJECT, od->nbr->copp, > ctx->meter_groups); > } > > - if (ctx->lb_vip->n_backends || !ctx->lb_vip->empty_backend_rej) { > + if (!vector_is_empty(&ctx->lb_vip->backends) || > + !ctx->lb_vip->empty_backend_rej) { > ds_put_format(ctx->new_match, " && is_chassis_resident(%s)", > dgp->cr_port->json_key); > } > @@ -12274,7 +12278,7 @@ build_distr_lrouter_nat_flows_for_lb(struct > lrouter_nat_lb_flows_ctx *ctx, > ds_truncate(ctx->new_match, new_match_len); > > ds_destroy(&dnat_action); > - if (!ctx->lb_vip->n_backends) { > + if (vector_is_empty(&ctx->lb_vip->backends)) { > return; > } > > @@ -12466,8 +12470,8 @@ build_lrouter_nat_flows_for_lb( > */ > ds_put_format(&undnat_match, "%s && (", ip_match); > > - for (size_t i = 0; i < lb_vip->n_backends; i++) { > - struct ovn_lb_backend *backend = &lb_vip->backends[i]; > + const struct ovn_lb_backend *backend; > + VECTOR_FOR_EACH_PTR (&lb_vip->backends, backend) { > ds_put_format(&undnat_match, "(%s.src == %s", ip_match, > backend->ip_str); > > diff --git a/tests/test-ovn.c b/tests/test-ovn.c > index c4eb2a7df..1b63c05d2 100644 > --- a/tests/test-ovn.c > +++ b/tests/test-ovn.c > @@ -954,7 +954,8 @@ test_tree_shape_exhaustively(struct expr *expr, struct > shash *symtab, > test_rule = xmalloc(sizeof *test_rule); > cls_rule_init(&test_rule->cr, &m->match, 0); > classifier_insert(&cls, &test_rule->cr, OVS_VERSION_MIN, > - m->conjunctions, m->n); > + vector_get_array(&m->conjunctions), > + vector_len(&m->conjunctions)); > } > } > for (int subst = 0; subst < 1 << (n_bits * n_nvars + n_svars); > -- > 2.49.0 > > Recheck-request: github-robot _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev