Signed-off-by: Simon Horman <ho...@verge.net.au> --- lib/nx-match.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-)
diff --git a/lib/nx-match.c b/lib/nx-match.c index f7f3c88..dcdd0b4 100644 --- a/lib/nx-match.c +++ b/lib/nx-match.c @@ -516,10 +516,30 @@ nx_put_match(struct ofpbuf *b, bool oxm, const struct cls_rule *cr, 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_and_cfi = flow->vlan_tci & htons(VLAN_PCP_MASK | VLAN_CFI); + ovs_be16 mask = htons(vlan_tci_to_vid(cr->wc.vlan_tci_mask)); + + if (vid_and_cfi == htons(OFPVID12_NONE)) { + nxm_put_16(b, OXM_OF_VLAN_VID, htons(OFPVID12_NONE)); + } else if (vid_and_cfi == htons(OFPVID12_PRESENT) && + mask == htons(OFPVID12_PRESENT)) { + nxm_put_16m(b, OXM_OF_VLAN_VID, htons(OFPVID12_PRESENT), + htons(OFPVID12_PRESENT)); + } else if (mask) { + ovs_be16 vid = htons(vlan_tci_to_vid(flow->vlan_tci)); + + if (mask == htons(VLAN_PCP_MASK)) { + nxm_put_16(b, OXM_OF_VLAN_VID, vid); + } else { + nxm_put_16m(b, OXM_OF_VLAN_VID, vid, 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); + } /* 802.1AD */ if (!(wc & FWW_VLAN_TPID) && -- 1.7.10.2.484.gcd07cc5 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev