- 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;
+ support = &ofproto_dpif_get_support(ofproto)->odp;
+ ct_state = MINIFLOW_GET_U16(flow, ct_state);
+ if (support->ct_state && support->ct_zone && support->ct_mark
+ && support->ct_label && support->ct_state_nat) {
+ return ct_state & CS_UNSUPPORTED_MASK ? OFPERR_OFPBMC_BAD_MASK : 0;
+ }
+
+ ct_zone = MINIFLOW_GET_U16(flow, ct_zone);
+ ct_mark = MINIFLOW_GET_U32(flow, ct_mark);
+ ct_label = MINIFLOW_GET_U128(flow, ct_label);
+
+ if ((ct_state && !support->ct_state)
+ || (ct_state & CS_UNSUPPORTED_MASK)
+ || ((ct_state & (CS_SRC_NAT | CS_DST_NAT)) && !support->ct_state_nat)
+ || (ct_zone && !support->ct_zone)
+ || (ct_mark && !support->ct_mark)
+ || (!ovs_u128_is_zero(&ct_label) && !support->ct_label)) {
+ return OFPERR_OFPBMC_BAD_MASK;