mirror of
https://github.com/openvswitch/ovs
synced 2025-08-31 06:15:47 +00:00
User-Space MPLS actions and matches
This patch implements use-space datapath and non-datapath code to match and use the datapath API set out in Leo Alterman's patch "user-space datapath: Add basic MPLS support to kernel". The resulting MPLS implementation supports: * Pushing a single MPLS label * Poping a single MPLS label * Modifying an MPLS lable using set-field or load actions that act on the label value, tc and bos bit. * There is no support for manipulating the TTL this is considered future work. The single-level push pop limitation is implemented by processing push, pop and set-field/load actions in order and discarding information that would require multiple levels of push/pop to be supported. e.g. push,push -> the first push is discarded pop,pop -> the first pop is discarded This patch is based heavily on work by Ravi K. Cc: Ravi K <rkerur@gmail.com> Reviewed-by: Isaku Yamahata <yamahata@valinux.co.jp> Signed-off-by: Simon Horman <horms@verge.net.au> Signed-off-by: Ben Pfaff <blp@nicira.com>
This commit is contained in:
@@ -85,7 +85,7 @@ ofputil_netmask_to_wcbits(ovs_be32 netmask)
|
||||
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);
|
||||
@@ -440,8 +440,7 @@ ofputil_match_from_ofp11_match(const struct ofp11_match *ofmatch,
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
@@ -1060,7 +1059,7 @@ ofputil_usable_protocols(const struct match *match)
|
||||
{
|
||||
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)) {
|
||||
@@ -1152,6 +1151,26 @@ ofputil_usable_protocols(const struct match *match)
|
||||
| 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;
|
||||
}
|
||||
@@ -4307,7 +4326,8 @@ ofputil_normalize_match__(struct match *match, bool may_log)
|
||||
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;
|
||||
@@ -4336,6 +4356,8 @@ ofputil_normalize_match__(struct match *match, bool may_log)
|
||||
} 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;
|
||||
}
|
||||
@@ -4368,6 +4390,10 @@ ofputil_normalize_match__(struct match *match, bool may_log)
|
||||
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)) {
|
||||
|
Reference in New Issue
Block a user