|
|
bbaaef |
From b52c176dd76bc0321d9c8bfe1c9b4832daf64835 Mon Sep 17 00:00:00 2001
|
|
|
bbaaef |
From: Mark Michelson <mmichels@redhat.com>
|
|
|
bbaaef |
Date: Fri, 25 Oct 2019 13:25:12 -0400
|
|
|
bbaaef |
Subject: [PATCH 2/2] Combine conjunctions with identical matches into one
|
|
|
bbaaef |
flow.
|
|
|
bbaaef |
|
|
|
bbaaef |
As stated in previous commits, conjunctive matches have an issue where
|
|
|
bbaaef |
it is possible to install multiple flows that have identical matches.
|
|
|
bbaaef |
This results in ambiguity, and can lead to features (such as ACLs) not
|
|
|
bbaaef |
functioning properly.
|
|
|
bbaaef |
|
|
|
bbaaef |
This change fixes the problem by combining conjunctions with identical
|
|
|
bbaaef |
matches into a single flow. As an example, in the past we may have had
|
|
|
bbaaef |
something like:
|
|
|
bbaaef |
|
|
|
bbaaef |
nw_dst=10.0.0.1 actions=conjunction(2,1/2)
|
|
|
bbaaef |
nw_dst=10.0.0.1 actions=conjunction(3,1/2)
|
|
|
bbaaef |
|
|
|
bbaaef |
This commit changes this into
|
|
|
bbaaef |
|
|
|
bbaaef |
nw_dst=10.0.0.1 actions=conjunction(2,1/2),conjunction(3,1/2)
|
|
|
bbaaef |
|
|
|
bbaaef |
This way, there is only a single flow with the proscribed match, and
|
|
|
bbaaef |
there is no ambiguity.
|
|
|
bbaaef |
|
|
|
bbaaef |
Signed-off-by: Mark Michelson <mmichels@redhat.com>
|
|
|
bbaaef |
---
|
|
|
bbaaef |
ovn/controller/lflow.c | 5 ++--
|
|
|
bbaaef |
ovn/controller/ofctrl.c | 74 +++++++++++++++++++++++++++++++++++++++++++++--------
|
|
|
bbaaef |
ovn/controller/ofctrl.h | 6 +++++
|
|
|
bbaaef |
tests/ovn.at | 17 +++++-------
|
|
|
bbaaef |
4 files changed, 80 insertions(+), 22 deletions(-)
|
|
|
bbaaef |
|
|
|
bbaaef |
diff --git a/ovn/controller/lflow.c b/ovn/controller/lflow.c
|
|
|
bbaaef |
index 24e3a521e..f34abcebc 100644
|
|
|
bbaaef |
--- a/ovn/controller/lflow.c
|
|
|
bbaaef |
+++ b/ovn/controller/lflow.c
|
|
|
bbaaef |
@@ -734,8 +734,9 @@ consider_logical_flow(
|
|
|
bbaaef |
dst->clause = src->clause;
|
|
|
bbaaef |
dst->n_clauses = src->n_clauses;
|
|
|
bbaaef |
}
|
|
|
bbaaef |
- ofctrl_add_flow(flow_table, ptable, lflow->priority, 0, &m->match,
|
|
|
bbaaef |
- &conj, &lflow->header_.uuid);
|
|
|
bbaaef |
+
|
|
|
bbaaef |
+ ofctrl_add_or_append_flow(flow_table, ptable, lflow->priority, 0,
|
|
|
bbaaef |
+ &m->match, &conj, &lflow->header_.uuid);
|
|
|
bbaaef |
ofpbuf_uninit(&conj;;
|
|
|
bbaaef |
}
|
|
|
bbaaef |
}
|
|
|
bbaaef |
diff --git a/ovn/controller/ofctrl.c b/ovn/controller/ofctrl.c
|
|
|
bbaaef |
index 3131baff0..10edd84fb 100644
|
|
|
bbaaef |
--- a/ovn/controller/ofctrl.c
|
|
|
bbaaef |
+++ b/ovn/controller/ofctrl.c
|
|
|
bbaaef |
@@ -69,6 +69,11 @@ struct ovn_flow {
|
|
|
bbaaef |
uint64_t cookie;
|
|
|
bbaaef |
};
|
|
|
bbaaef |
|
|
|
bbaaef |
+static struct ovn_flow *ovn_flow_alloc(uint8_t table_id, uint16_t priority,
|
|
|
bbaaef |
+ uint64_t cookie,
|
|
|
bbaaef |
+ const struct match *match,
|
|
|
bbaaef |
+ const struct ofpbuf *actions,
|
|
|
bbaaef |
+ const struct uuid *sb_uuid);
|
|
|
bbaaef |
static uint32_t ovn_flow_match_hash(const struct ovn_flow *);
|
|
|
bbaaef |
static struct ovn_flow *ovn_flow_lookup(struct hmap *flow_table,
|
|
|
bbaaef |
const struct ovn_flow *target,
|
|
|
bbaaef |
@@ -657,16 +662,8 @@ ofctrl_check_and_add_flow(struct ovn_desired_flow_table *flow_table,
|
|
|
bbaaef |
const struct uuid *sb_uuid,
|
|
|
bbaaef |
bool log_duplicate_flow)
|
|
|
bbaaef |
{
|
|
|
bbaaef |
- struct ovn_flow *f = xmalloc(sizeof *f);
|
|
|
bbaaef |
- f->table_id = table_id;
|
|
|
bbaaef |
- f->priority = priority;
|
|
|
bbaaef |
- minimatch_init(&f->match, match);
|
|
|
bbaaef |
- f->ofpacts = xmemdup(actions->data, actions->size);
|
|
|
bbaaef |
- f->ofpacts_len = actions->size;
|
|
|
bbaaef |
- f->sb_uuid = *sb_uuid;
|
|
|
bbaaef |
- f->match_hmap_node.hash = ovn_flow_match_hash(f);
|
|
|
bbaaef |
- f->uuid_hindex_node.hash = uuid_hash(&f->sb_uuid);
|
|
|
bbaaef |
- f->cookie = cookie;
|
|
|
bbaaef |
+ struct ovn_flow *f = ovn_flow_alloc(table_id, priority, cookie, match,
|
|
|
bbaaef |
+ actions, sb_uuid);
|
|
|
bbaaef |
|
|
|
bbaaef |
ovn_flow_log(f, "ofctrl_add_flow");
|
|
|
bbaaef |
|
|
|
bbaaef |
@@ -721,9 +718,66 @@ ofctrl_add_flow(struct ovn_desired_flow_table *desired_flows,
|
|
|
bbaaef |
ofctrl_check_and_add_flow(desired_flows, table_id, priority, cookie,
|
|
|
bbaaef |
match, actions, sb_uuid, true);
|
|
|
bbaaef |
}
|
|
|
bbaaef |
+
|
|
|
bbaaef |
+void
|
|
|
bbaaef |
+ofctrl_add_or_append_flow(struct ovn_desired_flow_table *desired_flows,
|
|
|
bbaaef |
+ uint8_t table_id, uint16_t priority, uint64_t cookie,
|
|
|
bbaaef |
+ const struct match *match,
|
|
|
bbaaef |
+ const struct ofpbuf *actions,
|
|
|
bbaaef |
+ const struct uuid *sb_uuid)
|
|
|
bbaaef |
+{
|
|
|
bbaaef |
+ struct ovn_flow *f = ovn_flow_alloc(table_id, priority, cookie, match,
|
|
|
bbaaef |
+ actions, sb_uuid);
|
|
|
bbaaef |
+
|
|
|
bbaaef |
+ ovn_flow_log(f, "ofctrl_add_or_append_flow");
|
|
|
bbaaef |
+
|
|
|
bbaaef |
+ struct ovn_flow *existing;
|
|
|
bbaaef |
+ existing = ovn_flow_lookup(&desired_flows->match_flow_table, f, false);
|
|
|
bbaaef |
+ if (existing) {
|
|
|
bbaaef |
+ /* There's already a flow with this particular match. Append the
|
|
|
bbaaef |
+ * action to that flow rather than adding a new flow
|
|
|
bbaaef |
+ */
|
|
|
bbaaef |
+ uint64_t compound_stub[64 / 8];
|
|
|
bbaaef |
+ struct ofpbuf compound;
|
|
|
bbaaef |
+ ofpbuf_use_stub(&compound, compound_stub, sizeof(compound_stub));
|
|
|
bbaaef |
+ ofpbuf_put(&compound, existing->ofpacts, existing->ofpacts_len);
|
|
|
bbaaef |
+ ofpbuf_put(&compound, f->ofpacts, f->ofpacts_len);
|
|
|
bbaaef |
+
|
|
|
bbaaef |
+ free(existing->ofpacts);
|
|
|
bbaaef |
+ existing->ofpacts = xmemdup(compound.data, compound.size);
|
|
|
bbaaef |
+ existing->ofpacts_len = compound.size;
|
|
|
bbaaef |
+
|
|
|
bbaaef |
+ ofpbuf_uninit(&compound);
|
|
|
bbaaef |
+ ovn_flow_destroy(f);
|
|
|
bbaaef |
+ } else {
|
|
|
bbaaef |
+ hmap_insert(&desired_flows->match_flow_table, &f->match_hmap_node,
|
|
|
bbaaef |
+ f->match_hmap_node.hash);
|
|
|
bbaaef |
+ hindex_insert(&desired_flows->uuid_flow_table, &f->uuid_hindex_node,
|
|
|
bbaaef |
+ f->uuid_hindex_node.hash);
|
|
|
bbaaef |
+ }
|
|
|
bbaaef |
+}
|
|
|
bbaaef |
|
|
|
bbaaef |
/* ovn_flow. */
|
|
|
bbaaef |
|
|
|
bbaaef |
+static struct ovn_flow *
|
|
|
bbaaef |
+ovn_flow_alloc(uint8_t table_id, uint16_t priority, uint64_t cookie,
|
|
|
bbaaef |
+ const struct match *match, const struct ofpbuf *actions,
|
|
|
bbaaef |
+ const struct uuid *sb_uuid)
|
|
|
bbaaef |
+{
|
|
|
bbaaef |
+ struct ovn_flow *f = xmalloc(sizeof *f);
|
|
|
bbaaef |
+ f->table_id = table_id;
|
|
|
bbaaef |
+ f->priority = priority;
|
|
|
bbaaef |
+ minimatch_init(&f->match, match);
|
|
|
bbaaef |
+ f->ofpacts = xmemdup(actions->data, actions->size);
|
|
|
bbaaef |
+ f->ofpacts_len = actions->size;
|
|
|
bbaaef |
+ f->sb_uuid = *sb_uuid;
|
|
|
bbaaef |
+ f->match_hmap_node.hash = ovn_flow_match_hash(f);
|
|
|
bbaaef |
+ f->uuid_hindex_node.hash = uuid_hash(&f->sb_uuid);
|
|
|
bbaaef |
+ f->cookie = cookie;
|
|
|
bbaaef |
+
|
|
|
bbaaef |
+ return f;
|
|
|
bbaaef |
+}
|
|
|
bbaaef |
+
|
|
|
bbaaef |
/* Returns a hash of the match key in 'f'. */
|
|
|
bbaaef |
static uint32_t
|
|
|
bbaaef |
ovn_flow_match_hash(const struct ovn_flow *f)
|
|
|
bbaaef |
diff --git a/ovn/controller/ofctrl.h b/ovn/controller/ofctrl.h
|
|
|
bbaaef |
index 1e9ac16b9..21d2ce648 100644
|
|
|
bbaaef |
--- a/ovn/controller/ofctrl.h
|
|
|
bbaaef |
+++ b/ovn/controller/ofctrl.h
|
|
|
bbaaef |
@@ -70,6 +70,12 @@ void ofctrl_add_flow(struct ovn_desired_flow_table *, uint8_t table_id,
|
|
|
bbaaef |
const struct match *, const struct ofpbuf *ofpacts,
|
|
|
bbaaef |
const struct uuid *);
|
|
|
bbaaef |
|
|
|
bbaaef |
+void ofctrl_add_or_append_flow(struct ovn_desired_flow_table *desired_flows,
|
|
|
bbaaef |
+ uint8_t table_id, uint16_t priority,
|
|
|
bbaaef |
+ uint64_t cookie, const struct match *match,
|
|
|
bbaaef |
+ const struct ofpbuf *actions,
|
|
|
bbaaef |
+ const struct uuid *sb_uuid);
|
|
|
bbaaef |
+
|
|
|
bbaaef |
void ofctrl_remove_flows(struct ovn_desired_flow_table *, const struct uuid *);
|
|
|
bbaaef |
|
|
|
bbaaef |
void ovn_desired_flow_table_init(struct ovn_desired_flow_table *);
|
|
|
bbaaef |
diff --git a/tests/ovn.at b/tests/ovn.at
|
|
|
bbaaef |
index 641a646fc..50d8efeec 100644
|
|
|
bbaaef |
--- a/tests/ovn.at
|
|
|
bbaaef |
+++ b/tests/ovn.at
|
|
|
bbaaef |
@@ -12247,7 +12247,7 @@ ovn-nbctl create Address_Set name=set1 \
|
|
|
bbaaef |
addresses=\"10.0.0.4\",\"10.0.0.5\",\"10.0.0.6\"
|
|
|
bbaaef |
ovn-nbctl create Address_Set name=set2 \
|
|
|
bbaaef |
addresses=\"10.0.0.7\",\"10.0.0.8\",\"10.0.0.9\"
|
|
|
bbaaef |
-ovn-nbctl acl-add ls1 to-lport 1002 \
|
|
|
bbaaef |
+ovn-nbctl acl-add ls1 to-lport 1001 \
|
|
|
bbaaef |
'ip4 && ip4.src == $set1 && ip4.dst == $set1' allow
|
|
|
bbaaef |
ovn-nbctl acl-add ls1 to-lport 1001 \
|
|
|
bbaaef |
'ip4 && ip4.src == $set1 && ip4.dst == $set2' drop
|
|
|
bbaaef |
@@ -12296,7 +12296,7 @@ cat 2.expected > expout
|
|
|
bbaaef |
$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
|
|
|
bbaaef |
AT_CHECK([cat 2.packets], [0], [expout])
|
|
|
bbaaef |
|
|
|
bbaaef |
-# There should be total of 12 flows present with conjunction action and 2 flows
|
|
|
bbaaef |
+# There should be total of 9 flows present with conjunction action and 2 flows
|
|
|
bbaaef |
# with conj match. Eg.
|
|
|
bbaaef |
# table=44, priority=2002,conj_id=2,metadata=0x1 actions=resubmit(,45)
|
|
|
bbaaef |
# table=44, priority=2001,conj_id=3,metadata=0x1 actions=drop
|
|
|
bbaaef |
@@ -12306,14 +12306,11 @@ AT_CHECK([cat 2.packets], [0], [expout])
|
|
|
bbaaef |
# priority=2001,ip,metadata=0x1,nw_dst=10.0.0.7 actions=conjunction(3,2/2)
|
|
|
bbaaef |
# priority=2001,ip,metadata=0x1,nw_dst=10.0.0.9 actions=conjunction(3,2/2)
|
|
|
bbaaef |
# priority=2001,ip,metadata=0x1,nw_dst=10.0.0.8 actions=conjunction(3,2/2)
|
|
|
bbaaef |
-# priority=2002,ip,metadata=0x1,nw_src=10.0.0.6 actions=conjunction(2,1/2)
|
|
|
bbaaef |
-# priority=2002,ip,metadata=0x1,nw_src=10.0.0.4 actions=conjunction(2,1/2)
|
|
|
bbaaef |
-# priority=2002,ip,metadata=0x1,nw_src=10.0.0.5 actions=conjunction(2,1/2)
|
|
|
bbaaef |
-# priority=2001,ip,metadata=0x1,nw_src=10.0.0.6 actions=conjunction(3,1/2)
|
|
|
bbaaef |
-# priority=2001,ip,metadata=0x1,nw_src=10.0.0.4 actions=conjunction(3,1/2)
|
|
|
bbaaef |
-# priority=2001,ip,metadata=0x1,nw_src=10.0.0.5 actions=conjunction(3,1/2)
|
|
|
bbaaef |
-
|
|
|
bbaaef |
-OVS_WAIT_UNTIL([test 12 = `as hv1 ovs-ofctl dump-flows br-int | \
|
|
|
bbaaef |
+# priority=2002,ip,metadata=0x1,nw_src=10.0.0.6 actions=conjunction(2,1/2),conjunction(3,1/2)
|
|
|
bbaaef |
+# priority=2002,ip,metadata=0x1,nw_src=10.0.0.4 actions=conjunction(2,1/2),conjunction(3,1/2)
|
|
|
bbaaef |
+# priority=2002,ip,metadata=0x1,nw_src=10.0.0.5 actions=conjunction(2,1/2),conjunction(3,1/2)
|
|
|
bbaaef |
+
|
|
|
bbaaef |
+OVS_WAIT_UNTIL([test 9 = `as hv1 ovs-ofctl dump-flows br-int | \
|
|
|
bbaaef |
grep conjunction | wc -l`])
|
|
|
bbaaef |
OVS_WAIT_UNTIL([test 2 = `as hv1 ovs-ofctl dump-flows br-int | \
|
|
|
bbaaef |
grep conj_id | wc -l`])
|
|
|
bbaaef |
--
|
|
|
bbaaef |
2.14.5
|
|
|
bbaaef |
|