ofproto: Allow ofproto_delete_flow() to delete hidden rules.
authorBen Pfaff <blp@nicira.com>
Tue, 24 Sep 2013 04:34:37 +0000 (21:34 -0700)
committerBen Pfaff <blp@nicira.com>
Tue, 24 Sep 2013 04:35:51 +0000 (21:35 -0700)
Commit 97f63e57a8 (ofproto: Remove soon-to-be-invalid optimizations.)
changed ofproto_delete_flow() to use the general-purpose flow_mod
implementation.  However, the general-purpose flow_mod never matches hidden
flows, which are exactly the flows that ofproto_delete_flow()'s callers
want to delete.

This commit fixes the problem by allowing flow_mods that specify a priority
that can only be for a hidden flow to delete a hidden flow.  (This doesn't
allow OpenFlow clients to meddle with hidden flows because OpenFlow uses
only a 16-bit field to specify priority.)

I verified that, without this commit, if I change from one controller to
another with "ovs-vsctl set-controller", then the in-band rules for the
old controller remain.  With this commit, the old rules are removed.

Reported-by: YAMAMOTO Takashi <yamamoto@valinux.co.jp>
Bug #19821.
Reported-by: Luca Giraudo <lgiraudo@vmware.com>
Bug #19888.
Reported-by: Ying Chen <yingchen@vmware.com>
Signed-off-by: Ben Pfaff <blp@nicira.com>
Acked-by: Justin Pettit <jpettit@nicira.com>
ofproto/ofproto.c

index c5e3bb3..cebf5a5 100644 (file)
@@ -3209,7 +3209,13 @@ collect_rule(struct rule *rule, const struct rule_criteria *c,
              struct rule_collection *rules)
     OVS_REQUIRES(ofproto_mutex)
 {
-    if (ofproto_rule_is_hidden(rule)) {
+    /* We ordinarily want to skip hidden rules, but there has to be a way for
+     * code internal to OVS to modify and delete them, so if the criteria
+     * specify a priority that can only be for a hidden flow, then allow hidden
+     * rules to be selected.  (This doesn't allow OpenFlow clients to meddle
+     * with hidden flows because OpenFlow uses only a 16-bit field to specify
+     * priority.) */
+    if (ofproto_rule_is_hidden(rule) && c->cr.priority <= UINT16_MAX) {
         return 0;
     } else if (rule->pending) {
         return OFPROTO_POSTPONE;