X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fnx-match.c;h=893566da4b0daf66e38e15e0908280e7ecce7924;hb=4b9f923273fb79079fcfa15350299b71a0062969;hp=3d017c6a36bc95a81d6357d13bf9248290c7f124;hpb=32455024044444678a8d500d716dad7fb77e18d0;p=openvswitch diff --git a/lib/nx-match.c b/lib/nx-match.c index 3d017c6a..893566da 100644 --- a/lib/nx-match.c +++ b/lib/nx-match.c @@ -493,7 +493,7 @@ nx_put_match(struct ofpbuf *b, bool oxm, const struct cls_rule *cr, int match_len; int i; - BUILD_ASSERT_DECL(FLOW_WC_SEQ == 13); + BUILD_ASSERT_DECL(FLOW_WC_SEQ == 14); /* Metadata. */ if (!(wc & FWW_IN_PORT)) { @@ -515,10 +515,24 @@ 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 = 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)) { @@ -548,15 +562,13 @@ nx_put_match(struct ofpbuf *b, bool oxm, const struct cls_rule *cr, flow->tp_src == htons(ND_NEIGHBOR_ADVERT))) { nxm_put_ipv6(b, oxm ? OXM_OF_IPV6_ND_TARGET : NXM_NX_ND_TARGET, &flow->nd_target, &cr->wc.nd_target_mask); - if (!(wc & FWW_ARP_SHA) - && flow->tp_src == htons(ND_NEIGHBOR_SOLICIT)) { - nxm_put_eth(b, oxm ? OXM_OF_IPV6_ND_SLL : NXM_NX_ND_SLL, - flow->arp_sha); + if (flow->tp_src == htons(ND_NEIGHBOR_SOLICIT)) { + nxm_put_eth_masked(b, oxm ? OXM_OF_IPV6_ND_SLL : NXM_NX_ND_SLL, + flow->arp_sha, cr->wc.arp_sha_mask); } - if (!(wc & FWW_ARP_THA) - && flow->tp_src == htons(ND_NEIGHBOR_ADVERT)) { - nxm_put_eth(b, oxm ? OXM_OF_IPV6_ND_TLL : NXM_NX_ND_TLL, - flow->arp_tha); + if (flow->tp_src == htons(ND_NEIGHBOR_ADVERT)) { + nxm_put_eth_masked(b, oxm ? OXM_OF_IPV6_ND_TLL : NXM_NX_ND_TLL, + flow->arp_tha, cr->wc.arp_tha_mask); } } } else if (!(wc & FWW_DL_TYPE) && flow->dl_type == htons(ETH_TYPE_ARP)) { @@ -569,14 +581,10 @@ nx_put_match(struct ofpbuf *b, bool oxm, const struct cls_rule *cr, flow->nw_src, cr->wc.nw_src_mask); nxm_put_32m(b, oxm ? OXM_OF_ARP_TPA : NXM_OF_ARP_TPA, flow->nw_dst, cr->wc.nw_dst_mask); - if (!(wc & FWW_ARP_SHA)) { - nxm_put_eth(b, oxm ? OXM_OF_ARP_SHA : NXM_NX_ARP_SHA, - flow->arp_sha); - } - if (!(wc & FWW_ARP_THA)) { - nxm_put_eth(b, oxm ? OXM_OF_ARP_THA : NXM_NX_ARP_THA, - flow->arp_tha); - } + nxm_put_eth_masked(b, oxm ? OXM_OF_ARP_SHA : NXM_NX_ARP_SHA, + flow->arp_sha, cr->wc.arp_sha_mask); + nxm_put_eth_masked(b, oxm ? OXM_OF_ARP_THA : NXM_NX_ARP_THA, + flow->arp_tha, cr->wc.arp_tha_mask); } /* Tunnel ID. */