@@ -73,6 +73,7 @@ void ds_swap(struct ds *, struct ds *);
int ds_last(const struct ds *);
bool ds_chomp(struct ds *, int c);
+void ds_copy(struct ds *, struct ds *);
/* Inline functions. */
@@ -456,3 +456,11 @@ ds_chomp(struct ds *ds, int c)
return false;
}
}
+
+void
+ds_copy(struct ds *dst, struct ds *source)
+{
+ dst->length = source->length;
+ dst->allocated = source->allocated;
+ dst->string = xmemdup(source->string, source->allocated + 1);
+}
@@ -383,6 +383,7 @@ add_logical_flows(struct controller_ctx *ctx, const struct lport_index *lports,
if (full_flow_processing) {
ovn_flow_table_clear();
+ ovn_group_table_clear(group_table, false);
full_logical_flow_processing = true;
full_neighbor_flow_processing = true;
full_flow_processing = false;
@@ -522,7 +523,8 @@ consider_logical_flow(const struct lport_index *lports,
.output_ptable = output_ptable,
.arp_ptable = OFTABLE_MAC_BINDING,
};
- error = actions_parse_string(lflow->actions, &ap, &ofpacts, &prereqs);
+ error = actions_parse_string(lflow->actions, &ap, &ofpacts, &prereqs,
+ &lflow->header_.uuid);
if (error) {
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
VLOG_WARN_RL(&rl, "error parsing actions \"%s\": %s",
@@ -118,9 +118,6 @@ static enum mf_field_id mff_ovn_geneve;
static void ovn_flow_table_destroy(void);
-static void ovn_group_table_clear(struct group_table *group_table,
- bool existing);
-
static void ofctrl_recv(const struct ofp_header *, enum ofptype);
static struct hmap match_flow_table = HMAP_INITIALIZER(&match_flow_table);
@@ -630,6 +627,16 @@ ofctrl_remove_flows(const struct uuid *uuid)
ovn_flow_destroy(f);
}
}
+
+ /* Remove any group_info information created by this logical flow. */
+ struct group_info *g, *next_g;
+ HMAP_FOR_EACH_SAFE (g, next_g, hmap_node, &groups->desired_groups) {
+ if (uuid_equals(&g->lflow_uuid, uuid)) {
+ hmap_remove(&groups->desired_groups, &g->hmap_node);
+ ds_destroy(&g->group);
+ free(g);
+ }
+ }
}
/* Shortcut to remove all flows matching the supplied UUID and add this
@@ -777,6 +784,15 @@ queue_flow_mod(struct ofputil_flow_mod *fm)
/* group_table. */
+static struct group_info *
+group_info_clone(struct group_info *source) {
+ struct group_info *clone = xmalloc(sizeof *clone);
+ ds_copy(&clone->group, &source->group);
+ clone->group_id = source->group_id;
+ clone->hmap_node.hash = source->hmap_node.hash;
+ return clone;
+}
+
/* Finds and returns a group_info in 'existing_groups' whose key is identical
* to 'target''s key, or NULL if there is none. */
static struct group_info *
@@ -795,7 +811,7 @@ ovn_group_lookup(struct hmap *exisiting_groups,
}
/* Clear either desired_groups or existing_groups in group_table. */
-static void
+void
ovn_group_table_clear(struct group_table *group_table, bool existing)
{
struct group_info *g, *next;
@@ -1000,13 +1016,10 @@ ofctrl_put(struct group_table *group_table)
/* Move the contents of desired_groups to existing_groups. */
HMAP_FOR_EACH_SAFE(desired, next_group, hmap_node,
&group_table->desired_groups) {
- hmap_remove(&group_table->desired_groups, &desired->hmap_node);
if (!ovn_group_lookup(&group_table->existing_groups, desired)) {
- hmap_insert(&group_table->existing_groups, &desired->hmap_node,
- desired->hmap_node.hash);
- } else {
- ds_destroy(&desired->group);
- free(desired);
+ struct group_info *clone = group_info_clone(desired);
+ hmap_insert(&group_table->existing_groups, &clone->hmap_node,
+ clone->hmap_node.hash);
}
}
}
@@ -53,4 +53,7 @@ void ofctrl_flow_table_clear(void);
void ovn_flow_table_clear(void);
+void ovn_group_table_clear(struct group_table *group_table,
+ bool existing);
+
#endif /* ovn/ofctrl.h */
@@ -42,6 +42,7 @@ struct action_context {
char *error; /* Error, if any, otherwise NULL. */
struct ofpbuf *ofpacts; /* Actions. */
struct expr *prereqs; /* Prerequisites to apply to match. */
+ struct uuid lflow_uuid; /* Parent lflow UUID (for group removal). */
};
static bool parse_action(struct action_context *);
@@ -761,6 +762,7 @@ parse_ct_lb_action(struct action_context *ctx)
group_info = xmalloc(sizeof *group_info);
group_info->group = ds;
group_info->group_id = group_id;
+ group_info->lflow_uuid = ctx->lflow_uuid;
group_info->hmap_node.hash = hash;
hmap_insert(&ctx->ap->group_table->desired_groups,
@@ -1120,7 +1122,8 @@ parse_actions(struct action_context *ctx)
*/
char * OVS_WARN_UNUSED_RESULT
actions_parse(struct lexer *lexer, const struct action_params *ap,
- struct ofpbuf *ofpacts, struct expr **prereqsp)
+ struct ofpbuf *ofpacts, struct expr **prereqsp,
+ const struct uuid *uuid)
{
size_t ofpacts_start = ofpacts->size;
@@ -1130,6 +1133,7 @@ actions_parse(struct lexer *lexer, const struct action_params *ap,
.error = NULL,
.ofpacts = ofpacts,
.prereqs = NULL,
+ .lflow_uuid = *uuid,
};
parse_actions(&ctx);
@@ -1147,14 +1151,15 @@ actions_parse(struct lexer *lexer, const struct action_params *ap,
/* Like actions_parse(), but the actions are taken from 's'. */
char * OVS_WARN_UNUSED_RESULT
actions_parse_string(const char *s, const struct action_params *ap,
- struct ofpbuf *ofpacts, struct expr **prereqsp)
+ struct ofpbuf *ofpacts, struct expr **prereqsp,
+ const struct uuid *uuid)
{
struct lexer lexer;
char *error;
lexer_init(&lexer, s);
lexer_get(&lexer);
- error = actions_parse(&lexer, ap, ofpacts, prereqsp);
+ error = actions_parse(&lexer, ap, ofpacts, prereqsp, uuid);
lexer_destroy(&lexer);
return error;
@@ -22,7 +22,9 @@
#include "compiler.h"
#include "openvswitch/hmap.h"
#include "openvswitch/dynamic-string.h"
+#include "openvswitch/uuid.h"
#include "util.h"
+#include "uuid.h"
struct expr;
struct lexer;
@@ -43,6 +45,7 @@ struct group_table {
struct group_info {
struct hmap_node hmap_node;
struct ds group;
+ struct uuid lflow_uuid;
uint32_t group_id;
};
@@ -132,10 +135,12 @@ struct action_params {
};
char *actions_parse(struct lexer *, const struct action_params *,
- struct ofpbuf *ofpacts, struct expr **prereqsp)
+ struct ofpbuf *ofpacts, struct expr **prereqsp,
+ const struct uuid *uuid)
OVS_WARN_UNUSED_RESULT;
char *actions_parse_string(const char *s, const struct action_params *,
- struct ofpbuf *ofpacts, struct expr **prereqsp)
+ struct ofpbuf *ofpacts, struct expr **prereqsp,
+ const struct uuid *uuid)
OVS_WARN_UNUSED_RESULT;
#endif /* ovn/actions.h */
@@ -1319,7 +1319,10 @@ test_parse_actions(struct ovs_cmdl_context *ctx OVS_UNUSED)
.output_ptable = 64,
.arp_ptable = 65,
};
- error = actions_parse_string(ds_cstr(&input), &ap, &ofpacts, &prereqs);
+ struct uuid uuid;
+ uuid_zero(&uuid);
+ error = actions_parse_string(ds_cstr(&input), &ap, &ofpacts, &prereqs,
+ &uuid);
if (!error) {
struct ds output;
[1] indicates that with incremental processing of logical flows desired conntrack groups are not being persisted. This patch adds this capability, with the side effect of adding a ds_copy method that this capability leverages. [1] http://openvswitch.org/pipermail/dev/2016-July/076320.html Signed-off-by: Ryan Moats <rmoats@us.ibm.com> --- include/openvswitch/dynamic-string.h | 1 + lib/dynamic-string.c | 8 ++++++++ ovn/controller/lflow.c | 4 +++- ovn/controller/ofctrl.c | 33 +++++++++++++++++++++++---------- ovn/controller/ofctrl.h | 3 +++ ovn/lib/actions.c | 11 ++++++++--- ovn/lib/actions.h | 9 +++++++-- tests/test-ovn.c | 5 ++++- 8 files changed, 57 insertions(+), 17 deletions(-)