void
ofputil_wildcard_from_ofpfw10(uint32_t ofpfw, struct flow_wildcards *wc)
{
- BUILD_ASSERT_DECL(FLOW_WC_SEQ == 18);
+ BUILD_ASSERT_DECL(FLOW_WC_SEQ == 19);
/* Initialize most of wc. */
flow_wildcards_init_catchall(wc);
}
}
- if (match->flow.dl_type == htons(ETH_TYPE_MPLS) ||
- match->flow.dl_type == htons(ETH_TYPE_MPLS_MCAST)) {
+ if (eth_type_mpls(match->flow.dl_type)) {
enum { OFPFW11_MPLS_ALL = OFPFW11_MPLS_LABEL | OFPFW11_MPLS_TC };
if ((wc & OFPFW11_MPLS_ALL) != OFPFW11_MPLS_ALL) {
{
const struct flow_wildcards *wc = &match->wc;
- BUILD_ASSERT_DECL(FLOW_WC_SEQ == 18);
+ BUILD_ASSERT_DECL(FLOW_WC_SEQ == 19);
/* tunnel params other than tun_id can't be sent in a flow_mod */
if (!tun_parms_fully_wildcarded(wc)) {
| OFPUTIL_P_OF13_OXM;
}
+ /* NXM and OF1.1+ support matching MPLS label */
+ if (wc->masks.mpls_lse & htonl(MPLS_LABEL_MASK)) {
+ return OFPUTIL_P_OF10_NXM_ANY | OFPUTIL_P_OF12_OXM
+ | OFPUTIL_P_OF13_OXM;
+ }
+
+ /* NXM and OF1.1+ support matching MPLS TC */
+ if (wc->masks.mpls_lse & htonl(MPLS_TC_MASK)) {
+ return OFPUTIL_P_OF10_NXM_ANY | OFPUTIL_P_OF12_OXM
+ | OFPUTIL_P_OF13_OXM;
+ }
+
+ /* NXM and OF1.3+ support matching MPLS stack flag */
+ /* Allow for OF1.2 as there doesn't seem to be a
+ * particularly good reason not to */
+ if (wc->masks.mpls_lse & htonl(MPLS_BOS_MASK)) {
+ return OFPUTIL_P_OF10_NXM_ANY | OFPUTIL_P_OF12_OXM
+ | OFPUTIL_P_OF13_OXM;
+ }
+
/* Other formats can express this rule. */
return OFPUTIL_P_ANY;
}
MAY_ARP_SHA = 1 << 4, /* arp_sha */
MAY_ARP_THA = 1 << 5, /* arp_tha */
MAY_IPV6 = 1 << 6, /* ipv6_src, ipv6_dst, ipv6_label */
- MAY_ND_TARGET = 1 << 7 /* nd_target */
+ MAY_ND_TARGET = 1 << 7, /* nd_target */
+ MAY_MPLS = 1 << 8, /* mpls label and tc */
} may_match;
struct flow_wildcards wc;
} else if (match->flow.dl_type == htons(ETH_TYPE_ARP) ||
match->flow.dl_type == htons(ETH_TYPE_RARP)) {
may_match = MAY_NW_PROTO | MAY_NW_ADDR | MAY_ARP_SHA | MAY_ARP_THA;
+ } else if (eth_type_mpls(match->flow.dl_type)) {
+ may_match = MAY_MPLS;
} else {
may_match = 0;
}
if (!(may_match & MAY_ND_TARGET)) {
wc.masks.nd_target = in6addr_any;
}
+ if (!(may_match & MAY_MPLS)) {
+ wc.masks.mpls_lse = htonl(0);
+ wc.masks.mpls_depth = 0;
+ }
/* Log any changes. */
if (!flow_wildcards_equal(&wc, &match->wc)) {