return !wc->masks.skb_priority;
case MFF_PKT_MARK:
return !wc->masks.pkt_mark;
+ case MFF_CT_STATE:
+ return !wc->masks.ct_state;
+ case MFF_CT_ZONE:
+ return !wc->masks.ct_zone;
CASE_MFF_REGS:
return !wc->masks.regs[mf->id - MFF_REG0];
CASE_MFF_XREGS:
case MFF_IN_PORT:
case MFF_SKB_PRIORITY:
case MFF_PKT_MARK:
+ case MFF_CT_ZONE:
CASE_MFF_REGS:
CASE_MFF_XREGS:
case MFF_ETH_SRC:
case MFF_TUN_FLAGS:
return !(value->be16 & ~htons(FLOW_TNL_PUB_F_MASK));
+ case MFF_CT_STATE:
+ return !(value->be32 & ~htonl(CS_SUPPORTED_MASK));
+
case MFF_N_IDS:
default:
OVS_NOT_REACHED();
value->be32 = htonl(flow->pkt_mark);
break;
+ case MFF_CT_STATE:
+ value->be32 = htonl(flow->ct_state);
+ break;
+
+ case MFF_CT_ZONE:
+ value->be16 = htons(flow->ct_zone);
+ break;
+
CASE_MFF_REGS:
value->be32 = htonl(flow->regs[mf->id - MFF_REG0]);
break;
match_set_pkt_mark(match, ntohl(value->be32));
break;
+ case MFF_CT_STATE:
+ match_set_ct_state(match, ntohl(value->be32));
+ break;
+
+ case MFF_CT_ZONE:
+ match_set_ct_zone(match, ntohs(value->be16));
+ break;
+
CASE_MFF_REGS:
match_set_reg(match, mf->id - MFF_REG0, ntohl(value->be32));
break;
flow->pkt_mark = ntohl(value->be32);
break;
+ case MFF_CT_STATE:
+ flow->ct_state = ntohl(value->be32);
+ break;
+
+ case MFF_CT_ZONE:
+ flow->ct_zone = ntohs(value->be16);
+ break;
+
CASE_MFF_REGS:
flow->regs[mf->id - MFF_REG0] = ntohl(value->be32);
break;
match->wc.masks.pkt_mark = 0;
break;
+ case MFF_CT_STATE:
+ match->flow.ct_state = 0;
+ match->wc.masks.ct_state = 0;
+ break;
+
+ case MFF_CT_ZONE:
+ match->flow.ct_zone = 0;
+ match->wc.masks.ct_zone = 0;
+ break;
+
CASE_MFF_REGS:
match_set_reg_masked(match, mf->id - MFF_REG0, 0, 0);
break;
}
switch (mf->id) {
+ case MFF_CT_ZONE:
case MFF_RECIRC_ID:
case MFF_CONJ_ID:
case MFF_IN_PORT:
ntohl(mask->be32));
break;
+ case MFF_CT_STATE:
+ match_set_ct_state_masked(match, ntohl(value->be32), ntohl(mask->be32));
+ break;
+
case MFF_ETH_DST:
match_set_dl_dst_masked(match, value->mac, mask->mac);
break;
htons(FLOW_TNL_PUB_F_MASK), maskp);
}
+static char *
+mf_from_ct_state_string(const char *s, ovs_be32 *flagsp, ovs_be32 *maskp)
+{
+ int err;
+ char *err_str;
+ uint32_t flags, mask;
+
+ err = parse_flags(s, ct_state_to_string, '\0', "ct_state", &err_str,
+ &flags, CS_SUPPORTED_MASK, maskp ? &mask : NULL);
+ if (err < 0) {
+ return err_str;
+ }
+
+ *flagsp = htonl(flags);
+ if (maskp) {
+ *maskp = htonl(mask);
+ }
+
+ return NULL;
+}
+
/* Parses 's', a string value for field 'mf', into 'value' and 'mask'. Returns
* NULL if successful, otherwise a malloc()'d string describing the error. */
char *
(uint8_t *) value, (uint8_t *) mask);
break;
+ case MFS_CT_STATE:
+ ovs_assert(mf->n_bytes == sizeof(ovs_be32));
+ error = mf_from_ct_state_string(s, &value->be32, &mask->be32);
+ break;
+
case MFS_ETHERNET:
error = mf_from_ethernet_string(mf, s, &value->mac, &mask->mac);
break;
TCP_FLAGS(mask), TCP_FLAGS(OVS_BE16_MAX));
}
+static void
+mf_format_ct_state_string(ovs_be32 value, ovs_be32 mask, struct ds *s)
+{
+ format_flags_masked(s, NULL, ct_state_to_string, ntohl(value),
+ ntohl(mask), UINT16_MAX);
+}
+
/* Appends to 's' a string representation of field 'mf' whose value is in
* 'value' and 'mask'. 'mask' may be NULL to indicate an exact match. */
void
mf_format_integer_string(mf, (uint8_t *) value, (uint8_t *) mask, s);
break;
+ case MFS_CT_STATE:
+ mf_format_ct_state_string(value->be32,
+ mask ? mask->be32 : OVS_BE32_MAX, s);
+ break;
+
case MFS_ETHERNET:
eth_format_masked(value->mac, mask ? &mask->mac : NULL, s);
break;