Signed-off-by: Simon Horman <ho...@verge.net.au> --- lib/classifier.c | 30 ++++++++++++++++++++++++++---- lib/classifier.h | 1 + lib/meta-flow.c | 5 ++++- 3 files changed, 31 insertions(+), 5 deletions(-)
diff --git a/lib/classifier.c b/lib/classifier.c index e74817e..964db25 100644 --- a/lib/classifier.c +++ b/lib/classifier.c @@ -229,14 +229,36 @@ cls_rule_set_any_vid(struct cls_rule *rule) * - Otherwise, makes 'rule' match only packets with an 802.1Q header whose * VID equals the low 12 bits of 'dl_vlan'. */ +static void +cls_rule_set_dl_vlan_masked__(struct cls_rule *rule, ovs_be16 dl_vlan, + ovs_be16 mask) +{ + mask |= htons(VLAN_CFI); + flow_set_vlan_vid(&rule->flow, dl_vlan & mask); + rule->wc.vlan_tci_mask = mask; +} + void cls_rule_set_dl_vlan(struct cls_rule *rule, ovs_be16 dl_vlan) { - flow_set_vlan_vid(&rule->flow, dl_vlan); - if (dl_vlan == htons(OFP_VLAN_NONE)) { - rule->wc.vlan_tci_mask = htons(UINT16_MAX); + ovs_be16 mask; + + if (dl_vlan == htons(OFPVID12_NONE)) { + mask = htons(UINT16_MAX); + } else { + mask = rule->wc.vlan_tci_mask |= htons(VLAN_VID_MASK); + } + cls_rule_set_dl_vlan_masked__(rule, dl_vlan, mask); +} + +void +cls_rule_set_dl_vlan_masked(struct cls_rule *rule, ovs_be16 dl_vlan, + ovs_be16 mask) +{ + if ((mask & htons(VLAN_VID_MASK)) == 0) { + cls_rule_set_dl_vlan(rule, htons(OFP_VLAN_NONE)); } else { - rule->wc.vlan_tci_mask |= htons(VLAN_VID_MASK | VLAN_CFI); + cls_rule_set_dl_vlan_masked__(rule, dl_vlan, mask); } } diff --git a/lib/classifier.h b/lib/classifier.h index 7aca7db..a8663d5 100644 --- a/lib/classifier.h +++ b/lib/classifier.h @@ -106,6 +106,7 @@ void cls_rule_set_dl_tci_masked(struct cls_rule *, ovs_be16 tci, ovs_be16 mask); void cls_rule_set_any_vid(struct cls_rule *); void cls_rule_set_dl_vlan(struct cls_rule *, ovs_be16); +void cls_rule_set_dl_vlan_masked(struct cls_rule *, ovs_be16, ovs_be16); void cls_rule_set_any_pcp(struct cls_rule *); void cls_rule_set_dl_vlan_pcp(struct cls_rule *, uint8_t); void cls_rule_set_dl_vlan_tpid(struct cls_rule *, ovs_be16); diff --git a/lib/meta-flow.c b/lib/meta-flow.c index eb34aa3..72ed108 100644 --- a/lib/meta-flow.c +++ b/lib/meta-flow.c @@ -1706,7 +1706,6 @@ mf_set(const struct mf_field *mf, switch (mf->id) { case MFF_IN_PORT: case MFF_ETH_TYPE: - case MFF_VLAN_VID: case MFF_VLAN_PCP: case MFF_VLAN_TPID: case MFF_VLAN_QINQ_VID: @@ -1747,6 +1746,10 @@ mf_set(const struct mf_field *mf, cls_rule_set_dl_src_masked(rule, value->mac, mask->mac); break; + case MFF_VLAN_VID: + cls_rule_set_dl_vlan_masked(rule, value->be16, mask->be16); + break; + case MFF_VLAN_TCI: cls_rule_set_dl_tci_masked(rule, value->be16, mask->be16); break; -- 1.7.10.2.484.gcd07cc5 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev