ofproto: Check actions also for packet outs and traces.
[cascardo/ovs.git] / ofproto / ofproto-dpif.c
index 2b731d1..49001e8 100644 (file)
@@ -1122,6 +1122,7 @@ check_variable_length_userdata(struct dpif_backer *backer)
     execute.packet = &packet;
     execute.needs_help = false;
     execute.probe = true;
+    execute.mtu = 0;
 
     error = dpif_execute(backer->dpif, &execute);
 
@@ -1220,6 +1221,7 @@ check_masked_set_action(struct dpif_backer *backer)
     execute.packet = &packet;
     execute.needs_help = false;
     execute.probe = true;
+    execute.mtu = 0;
 
     error = dpif_execute(backer->dpif, &execute);
 
@@ -1269,6 +1271,8 @@ check_##NAME(struct dpif_backer *backer)                                    \
 
 CHECK_FEATURE(ct_state)
 CHECK_FEATURE(ct_zone)
+CHECK_FEATURE(ct_mark)
+CHECK_FEATURE__(ct_label, ct_label.u64.lo)
 
 #undef CHECK_FEATURE
 #undef CHECK_FEATURE__
@@ -1287,6 +1291,8 @@ check_support(struct dpif_backer *backer)
 
     backer->support.odp.ct_state = check_ct_state(backer);
     backer->support.odp.ct_zone = check_ct_zone(backer);
+    backer->support.odp.ct_mark = check_ct_mark(backer);
+    backer->support.odp.ct_label = check_ct_label(backer);
 }
 
 static int
@@ -3733,6 +3739,7 @@ ofproto_dpif_execute_actions__(struct ofproto_dpif *ofproto,
     execute.packet = packet;
     execute.needs_help = (xout.slow & SLOW_ACTION) != 0;
     execute.probe = false;
+    execute.mtu = 0;
 
     /* Fix up in_port. */
     in_port = flow->in_port.ofp_port;
@@ -4008,16 +4015,27 @@ static enum ofperr
 rule_check(struct rule *rule)
 {
     uint16_t ct_state, ct_zone;
+    const ovs_u128 *labelp;
+    ovs_u128 ct_label = { { 0, 0 } };
+    uint32_t ct_mark;
 
     ct_state = MINIFLOW_GET_U16(rule->cr.match.flow, ct_state);
     ct_zone = MINIFLOW_GET_U16(rule->cr.match.flow, ct_zone);
+    ct_mark = MINIFLOW_GET_U32(rule->cr.match.flow, ct_mark);
+    labelp = MINIFLOW_GET_U128_PTR(rule->cr.match.flow, ct_label);
+    if (labelp) {
+        ct_label = *labelp;
+    }
 
-    if (ct_state || ct_zone) {
+    if (ct_state || ct_zone || ct_mark
+        || !ovs_u128_is_zero(&ct_label)) {
         struct ofproto_dpif *ofproto = ofproto_dpif_cast(rule->ofproto);
         const struct odp_support *support = &ofproto_dpif_get_support(ofproto)->odp;
 
         if ((ct_state && !support->ct_state)
-            || (ct_zone && !support->ct_zone)) {
+            || (ct_zone && !support->ct_zone)
+            || (ct_mark && !support->ct_mark)
+            || (!ovs_u128_is_zero(&ct_label) && !support->ct_label)) {
             return OFPERR_OFPBMC_BAD_FIELD;
         }
         if (ct_state & CS_UNSUPPORTED_MASK) {
@@ -4928,13 +4946,18 @@ ofproto_unixctl_trace_actions(struct unixctl_conn *conn, int argc,
         goto exit;
     }
     if (enforce_consistency) {
-        retval = ofpacts_check_consistency(ofpacts.data, ofpacts.size,
-                                           &flow, u16_to_ofp(ofproto->up.max_ports),
-                                           0, 0, usable_protocols);
+        retval = ofpacts_check_consistency(ofpacts.data, ofpacts.size, &flow,
+                                           u16_to_ofp(ofproto->up.max_ports),
+                                           0, ofproto->up.n_tables,
+                                           usable_protocols);
     } else {
         retval = ofpacts_check(ofpacts.data, ofpacts.size, &flow,
-                               u16_to_ofp(ofproto->up.max_ports), 0, 0,
-                               &usable_protocols);
+                               u16_to_ofp(ofproto->up.max_ports), 0,
+                               ofproto->up.n_tables, &usable_protocols);
+    }
+    if (!retval) {
+        retval = ofproto_check_ofpacts(&ofproto->up, ofpacts.data,
+                                       ofpacts.size);
     }
 
     if (retval) {