summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJarno Rajahalme <jrajahalme@nicira.com>2015-05-29 11:28:39 -0700
committerJarno Rajahalme <jrajahalme@nicira.com>2015-06-01 18:07:39 -0700
commitce59413fb48428f52c02e167cef6d6cf4d5984d1 (patch)
tree413b618467b3e66f0c540de70d0f6a2beb287e26
parentd99f64d7e01611ca9f7fe94999d029a9399a1275 (diff)
downloadopenvswitch-ce59413fb48428f52c02e167cef6d6cf4d5984d1.tar.gz
ofproto: Split delete_flow*().
Signed-off-by: Jarno Rajahalme <jrajahalme@nicira.com> Acked-by: Ben Pfaff <blp@nicira.com>
-rw-r--r--ofproto/ofproto.c79
1 files changed, 65 insertions, 14 deletions
diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
index d1cae0201..f98656648 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
@@ -3778,6 +3778,8 @@ rule_collection_destroy(struct rule_collection *rules)
* function verifies most of the criteria in 'c' itself, but the caller must
* check 'c->cr' itself.
*
+ * Rules that have already been marked as 'to_be_removed' are not collected.
+ *
* Increments '*n_readonly' if 'rule' wasn't added because it's read-only (and
* 'c' only includes modifiable rules). */
static void
@@ -3789,7 +3791,8 @@ collect_rule(struct rule *rule, const struct rule_criteria *c,
&& ofproto_rule_has_out_port(rule, c->out_port)
&& ofproto_rule_has_out_group(rule, c->out_group)
&& !((rule->flow_cookie ^ c->cookie) & c->cookie_mask)
- && (!rule_is_hidden(rule) || c->include_hidden)) {
+ && (!rule_is_hidden(rule) || c->include_hidden)
+ && !rule->cr.to_be_removed) {
/* Rule matches all the criteria... */
if (!rule_is_readonly(rule) || c->include_readonly) {
/* ...add it. */
@@ -4864,13 +4867,12 @@ delete_flows__(const struct rule_collection *rules,
/* Implements OFPFC_DELETE. */
static enum ofperr
-delete_flows_loose(struct ofproto *ofproto,
- const struct ofputil_flow_mod *fm,
- const struct flow_mod_requester *req)
+delete_flows_begin_loose(struct ofproto *ofproto,
+ const struct ofputil_flow_mod *fm,
+ struct rule_collection *rules)
OVS_REQUIRES(ofproto_mutex)
{
struct rule_criteria criteria;
- struct rule_collection rules;
enum ofperr error;
rule_criteria_init(&criteria, fm->table_id, &fm->match, 0,
@@ -4878,39 +4880,88 @@ delete_flows_loose(struct ofproto *ofproto,
fm->out_port, fm->out_group);
rule_criteria_require_rw(&criteria,
(fm->flags & OFPUTIL_FF_NO_READONLY) != 0);
- error = collect_rules_loose(ofproto, &criteria, &rules);
+ error = collect_rules_loose(ofproto, &criteria, rules);
rule_criteria_destroy(&criteria);
if (!error) {
- delete_flows__(&rules, fm->delete_reason, req);
+ for (size_t i = 0; i < rules->n; i++) {
+ struct rule *rule = rules->rules[i];
+
+ CONST_CAST(struct cls_rule *, &rule->cr)->to_be_removed = true;
+ }
}
- rule_collection_destroy(&rules);
return error;
}
-/* Implements OFPFC_DELETE_STRICT. */
+static void
+delete_flows_finish(const struct ofputil_flow_mod *fm,
+ const struct flow_mod_requester *req,
+ struct rule_collection *rules)
+ OVS_REQUIRES(ofproto_mutex)
+{
+ delete_flows__(rules, fm->delete_reason, req);
+ rule_collection_destroy(rules);
+}
+
static enum ofperr
-delete_flow_strict(struct ofproto *ofproto, const struct ofputil_flow_mod *fm,
+delete_flows_loose(struct ofproto *ofproto,
+ const struct ofputil_flow_mod *fm,
const struct flow_mod_requester *req)
OVS_REQUIRES(ofproto_mutex)
{
- struct rule_criteria criteria;
struct rule_collection rules;
enum ofperr error;
+ error = delete_flows_begin_loose(ofproto, fm, &rules);
+ if (!error) {
+ delete_flows_finish(fm, req, &rules);
+ }
+
+ return error;
+}
+
+/* Implements OFPFC_DELETE_STRICT. */
+static enum ofperr
+delete_flow_begin_strict(struct ofproto *ofproto,
+ const struct ofputil_flow_mod *fm,
+ struct rule_collection *rules)
+ OVS_REQUIRES(ofproto_mutex)
+{
+ struct rule_criteria criteria;
+ enum ofperr error;
+
rule_criteria_init(&criteria, fm->table_id, &fm->match, fm->priority,
fm->cookie, fm->cookie_mask,
fm->out_port, fm->out_group);
rule_criteria_require_rw(&criteria,
(fm->flags & OFPUTIL_FF_NO_READONLY) != 0);
- error = collect_rules_strict(ofproto, &criteria, &rules);
+ error = collect_rules_strict(ofproto, &criteria, rules);
rule_criteria_destroy(&criteria);
if (!error) {
- delete_flows__(&rules, fm->delete_reason, req);
+ for (size_t i = 0; i < rules->n; i++) {
+ struct rule *rule = rules->rules[i];
+
+ CONST_CAST(struct cls_rule *, &rule->cr)->to_be_removed = true;
+ }
+ }
+
+ return error;
+}
+
+static enum ofperr
+delete_flow_strict(struct ofproto *ofproto, const struct ofputil_flow_mod *fm,
+ const struct flow_mod_requester *req)
+ OVS_REQUIRES(ofproto_mutex)
+{
+ struct rule_collection rules;
+ enum ofperr error;
+
+ error = delete_flow_begin_strict(ofproto, fm, &rules);
+ if (!error) {
+ delete_flows_finish(fm, req, &rules);
}
- rule_collection_destroy(&rules);
return error;
}