ofputil_dl_type_to_openflow(flow->dl_type));
}
- /* 802.1Q.
- *
- * XXX missing OXM support */
- nxm_put_16m(b, NXM_OF_VLAN_TCI, flow->vlan_tci, cr->wc.vlan_tci_mask);
+ /* 802.1Q. */
+ if (oxm) {
+ ovs_be16 vid = flow->vlan_tci & htons(VLAN_VID_MASK | VLAN_CFI);
+ ovs_be16 mask = cr->wc.vlan_tci_mask & htons(VLAN_VID_MASK | VLAN_CFI);
+
+ if (mask == htons(VLAN_VID_MASK | VLAN_CFI)) {
+ nxm_put_16(b, OXM_OF_VLAN_VID, vid);
+ } else if (mask) {
+ nxm_put_16m(b, OXM_OF_VLAN_VID, vid, mask);
+ }
+
+ if (vid && vlan_tci_to_pcp(cr->wc.vlan_tci_mask)) {
+ nxm_put_8(b, OXM_OF_VLAN_PCP, vlan_tci_to_pcp(flow->vlan_tci));
+ }
+
+ } else {
+ nxm_put_16m(b, NXM_OF_VLAN_TCI, flow->vlan_tci, cr->wc.vlan_tci_mask);
+ }
/* L3. */
if (!(wc & FWW_DL_TYPE) && flow->dl_type == htons(ETH_TYPE_IP)) {
OXM_OF_ETH_TYPE(0800)
OXM_OF_ETH_TYPE(0800) OXM_OF_IN_PORT(00000012)
+# vlan
+OXM_OF_VLAN_VID(1009) OXM_OF_VLAN_VID(1009) # Duplicate Field
+OXM_OF_VLAN_VID(f009) # Bad Value
+OXM_OF_VLAN_VID(0000) # Packets without 802.1Q header or with VID=0
+OXM_OF_VLAN_VID(1123) # Packets with VID=123, any PCP
+OXM_OF_VLAN_VID(1123) OXM_OF_VLAN_PCP(01) # Packets with VID=123, PCP=1.
+OXM_OF_VLAN_VID(0123) # Does not make sense (but supported anyway)
+
# IP ECN
OXM_OF_ETH_TYPE(0800) OXM_OF_IP_ECN(03)
OXM_OF_ETH_TYPE(0800) OXM_OF_IP_ECN(06)
OXM_OF_ETH_TYPE(0800)
OXM_OF_IN_PORT(00000012), OXM_OF_ETH_TYPE(0800)
+# vlan
+nx_pull_match() returned error OFPBMC_DUP_FIELD
+nx_pull_match() returned error OFPBMC_BAD_VALUE
+OXM_OF_VLAN_VID(0000)
+OXM_OF_VLAN_VID(1123)
+OXM_OF_VLAN_VID(1123), OXM_OF_VLAN_PCP(01)
+OXM_OF_VLAN_VID(0123)
+
# IP ECN
OXM_OF_ETH_TYPE(0800), OXM_OF_IP_ECN(03)
nx_pull_match() returned error OFPBMC_BAD_VALUE