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>
---
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 13cf1a503..a0c142329 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 f6f413be2..967fca426 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 6f2458753..5190bc70a 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -3642,8 +3642,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];
@@ -3717,8 +3718,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 =
@@ -3733,11 +3736,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;
@@ -6081,7 +6085,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;
}
@@ -7903,9 +7907,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);
@@ -8078,9 +8081,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);
@@ -11954,8 +11956,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);
@@ -11969,7 +11972,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);
}
@@ -11982,7 +11986,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;
}
@@ -12174,8 +12178,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);