ofp-actions: Support mixing "conjunction" and "note" actions.
[cascardo/ovs.git] / ofproto / ofproto.c
index 523130b..acf504f 100644 (file)
@@ -4408,12 +4408,6 @@ evict_rules_from_table(struct oftable *table)
     return error;
 }
 
-static bool
-is_conjunction(const struct ofpact *ofpacts, size_t ofpacts_len)
-{
-    return ofpacts_len > 0 && ofpacts->type == OFPACT_CONJUNCTION;
-}
-
 static void
 get_conjunctions(const struct ofputil_flow_mod *fm,
                  struct cls_conjunction **conjsp, size_t *n_conjsp)
@@ -4422,23 +4416,29 @@ get_conjunctions(const struct ofputil_flow_mod *fm,
     struct cls_conjunction *conjs = NULL;
     int n_conjs = 0;
 
-    if (is_conjunction(fm->ofpacts, fm->ofpacts_len)) {
-        const struct ofpact *ofpact;
-        int i;
-
-        n_conjs = 0;
-        OFPACT_FOR_EACH (ofpact, fm->ofpacts, fm->ofpacts_len) {
+    const struct ofpact *ofpact;
+    OFPACT_FOR_EACH (ofpact, fm->ofpacts, fm->ofpacts_len) {
+        if (ofpact->type == OFPACT_CONJUNCTION) {
             n_conjs++;
+        } else if (ofpact->type != OFPACT_NOTE) {
+            /* "conjunction" may appear with "note" actions but not with any
+             * other type of actions. */
+            ovs_assert(!n_conjs);
+            break;
         }
+    }
+    if (n_conjs) {
+        int i = 0;
 
         conjs = xzalloc(n_conjs * sizeof *conjs);
-        i = 0;
         OFPACT_FOR_EACH (ofpact, fm->ofpacts, fm->ofpacts_len) {
-            struct ofpact_conjunction *oc = ofpact_get_CONJUNCTION(ofpact);
-            conjs[i].clause = oc->clause;
-            conjs[i].n_clauses = oc->n_clauses;
-            conjs[i].id = oc->id;
-            i++;
+            if (ofpact->type == OFPACT_CONJUNCTION) {
+                struct ofpact_conjunction *oc = ofpact_get_CONJUNCTION(ofpact);
+                conjs[i].clause = oc->clause;
+                conjs[i].n_clauses = oc->n_clauses;
+                conjs[i].id = oc->id;
+                i++;
+            }
         }
     }