OXM: Add VLAN VID as a prerequisite for VLAN PCP
[openvswitch] / lib / meta-flow.c
index 27f3bca73ba128c543af5dee5b374ef9cff9f37a..c50cfc5359215119ae0210481cf232c4a9b1afd5 100644 (file)
@@ -163,6 +163,15 @@ static const struct mf_field mf_fields[MFF_N_IDS] = {
         MFS_DECIMAL,
         MFP_NONE,
         true,
+        0, NULL,
+        0, NULL,
+    }, {
+        MFF_VLAN_VID, "vlan_vid", NULL,
+        sizeof(ovs_be16), 12,
+        MFM_FULLY, 0,
+        MFS_DECIMAL,
+        MFP_NONE,
+        true,
         OXM_OF_VLAN_VID, "OXM_OF_VLAN_VID",
         OXM_OF_VLAN_VID, "OXM_OF_VLAN_VID",
     }, {
@@ -172,6 +181,15 @@ static const struct mf_field mf_fields[MFF_N_IDS] = {
         MFS_DECIMAL,
         MFP_NONE,
         true,
+        0, NULL,
+        0, NULL,
+    }, {
+        MFF_VLAN_PCP, "vlan_pcp", NULL,
+        1, 3,
+        MFM_NONE, 0,
+        MFS_DECIMAL,
+        MFP_VLAN_VID,
+        true,
         OXM_OF_VLAN_PCP, "OXM_OF_VLAN_PCP",
         OXM_OF_VLAN_PCP, "OXM_OF_VLAN_PCP",
     },
@@ -590,7 +608,10 @@ mf_is_all_wild(const struct mf_field *mf, const struct flow_wildcards *wc)
         return !wc->vlan_tci_mask;
     case MFF_DL_VLAN:
         return !(wc->vlan_tci_mask & htons(VLAN_VID_MASK));
+    case MFF_VLAN_VID:
+        return !(wc->vlan_tci_mask & htons(VLAN_VID_MASK | VLAN_CFI));
     case MFF_DL_VLAN_PCP:
+    case MFF_VLAN_PCP:
         return !(wc->vlan_tci_mask & htons(VLAN_PCP_MASK));
 
     case MFF_IPV4_SRC:
@@ -681,7 +702,11 @@ mf_get_mask(const struct mf_field *mf, const struct flow_wildcards *wc,
     case MFF_DL_VLAN:
         mask->be16 = wc->vlan_tci_mask & htons(VLAN_VID_MASK);
         break;
+    case MFF_VLAN_VID:
+        mask->be16 = wc->vlan_tci_mask & htons(VLAN_VID_MASK | VLAN_CFI);
+        break;
     case MFF_DL_VLAN_PCP:
+    case MFF_VLAN_PCP:
         mask->u8 = vlan_tci_to_pcp(wc->vlan_tci_mask);
         break;
 
@@ -801,6 +826,8 @@ mf_are_prereqs_ok(const struct mf_field *mf, const struct flow *flow)
         return flow->dl_type == htons(ETH_TYPE_IP);
     case MFP_IPV6:
         return flow->dl_type == htons(ETH_TYPE_IPV6);
+    case MFP_VLAN_VID:
+        return flow->vlan_tci & htons(VLAN_CFI);
     case MFP_IP_ANY:
         return is_ip_any(flow);
 
@@ -888,8 +915,11 @@ mf_is_value_valid(const struct mf_field *mf, const union mf_value *value)
 
     case MFF_DL_VLAN:
         return !(value->be16 & htons(VLAN_CFI | VLAN_PCP_MASK));
+    case MFF_VLAN_VID:
+        return !(value->be16 & htons(VLAN_PCP_MASK));
 
     case MFF_DL_VLAN_PCP:
+    case MFF_VLAN_PCP:
         return !(value->u8 & ~(VLAN_PCP_MASK >> VLAN_PCP_SHIFT));
 
     case MFF_IPV6_LABEL:
@@ -942,8 +972,12 @@ mf_get_value(const struct mf_field *mf, const struct flow *flow,
     case MFF_DL_VLAN:
         value->be16 = flow->vlan_tci & htons(VLAN_VID_MASK);
         break;
+    case MFF_VLAN_VID:
+        value->be16 = flow->vlan_tci & htons(VLAN_VID_MASK | VLAN_CFI);
+        break;
 
     case MFF_DL_VLAN_PCP:
+    case MFF_VLAN_PCP:
         value->u8 = vlan_tci_to_pcp(flow->vlan_tci);
         break;
 
@@ -1081,8 +1115,12 @@ mf_set_value(const struct mf_field *mf,
     case MFF_DL_VLAN:
         cls_rule_set_dl_vlan(rule, value->be16);
         break;
+    case MFF_VLAN_VID:
+        cls_rule_set_vlan_vid(rule, value->be16);
+        break;
 
     case MFF_DL_VLAN_PCP:
+    case MFF_VLAN_PCP:
         cls_rule_set_dl_vlan_pcp(rule, value->u8);
         break;
 
@@ -1220,8 +1258,12 @@ mf_set_flow_value(const struct mf_field *mf,
     case MFF_DL_VLAN:
         flow_set_dl_vlan(flow, value->be16);
         break;
+    case MFF_VLAN_VID:
+        flow_set_vlan_vid(flow, value->be16);
+        break;
 
     case MFF_DL_VLAN_PCP:
+    case MFF_VLAN_PCP:
         flow_set_vlan_pcp(flow, value->u8);
         break;
 
@@ -1375,10 +1417,12 @@ mf_set_wild(const struct mf_field *mf, struct cls_rule *rule)
         break;
 
     case MFF_DL_VLAN:
+    case MFF_VLAN_VID:
         cls_rule_set_any_vid(rule);
         break;
 
     case MFF_DL_VLAN_PCP:
+    case MFF_VLAN_PCP:
         cls_rule_set_any_pcp(rule);
         break;
 
@@ -1505,6 +1549,7 @@ mf_set(const struct mf_field *mf,
     case MFF_ETH_TYPE:
     case MFF_DL_VLAN:
     case MFF_DL_VLAN_PCP:
+    case MFF_VLAN_PCP:
     case MFF_IP_PROTO:
     case MFF_IP_TTL:
     case MFF_IP_DSCP:
@@ -1550,6 +1595,10 @@ mf_set(const struct mf_field *mf,
         cls_rule_set_dl_tci_masked(rule, value->be16, mask->be16);
         break;
 
+    case MFF_VLAN_VID:
+        cls_rule_set_vlan_vid_masked(rule, value->be16, mask->be16);
+        break;
+
     case MFF_IPV4_SRC:
         cls_rule_set_nw_src_masked(rule, value->be32, mask->be32);
         break;
@@ -1726,8 +1775,12 @@ mf_random_value(const struct mf_field *mf, union mf_value *value)
     case MFF_DL_VLAN:
         value->be16 &= htons(VLAN_VID_MASK);
         break;
+    case MFF_VLAN_VID:
+        value->be16 &= htons(VLAN_VID_MASK | VLAN_CFI);
+        break;
 
     case MFF_DL_VLAN_PCP:
+    case MFF_VLAN_PCP:
         value->u8 &= 0x07;
         break;