summaryrefslogtreecommitdiff
path: root/lib/nx-match.c
diff options
context:
space:
mode:
authorJan Scheurich <jan.scheurich@ericsson.com>2017-06-23 16:47:57 +0000
committerBen Pfaff <blp@ovn.org>2017-06-27 17:28:30 -0400
commit3d4b2e6eb74ed5bb5b35373aa8a489536938fee6 (patch)
treef086a8ec9d205140a69fd39db0c4c8be67ab855c /lib/nx-match.c
parentbe7ac2f3c105866542de5c1d4c7e2651250a3e92 (diff)
downloadopenvswitch-3d4b2e6eb74ed5bb5b35373aa8a489536938fee6.tar.gz
userspace: Add OXM field MFF_PACKET_TYPE
Allow packet type namespace OFPHTN_ETHERTYPE as alternative pre-requisite for matching L3 protocols (MPLS, IP, IPv6, ARP etc). Change the meta-flow definition of packet_type field to use the new custom format MFS_PACKET_TYPE representing "(NS,NS_TYPE)". Parsing routine for MFS_PACKET_TYPE added to meta-flow.c. Formatting routine for field packet_type extracted from match_format() and moved to flow.c to be used from meta-flow.c for formatting MFS_PACKET_TYPE. Updated the ovs-fields man page source meta-flow.xml with documentation for packet-type-aware bridges and added documentation for field packet_type. Added packet_type to the matching properties in tests/ofproto.at. If dl_type is unwildcarded due to later packet modification, make sure it is cleared again if the original packet_type was not PT_ETH. Signed-off-by: Jan Scheurich <jan.scheurich@ericsson.com> Signed-off-by: Ben Pfaff <blp@ovn.org>
Diffstat (limited to 'lib/nx-match.c')
-rw-r--r--lib/nx-match.c34
1 files changed, 29 insertions, 5 deletions
diff --git a/lib/nx-match.c b/lib/nx-match.c
index 6278b7758..cb0cad845 100644
--- a/lib/nx-match.c
+++ b/lib/nx-match.c
@@ -561,6 +561,8 @@ nx_pull_raw(const uint8_t *p, unsigned int match_len, bool strict,
free(err_str);
return OFPERR_OFPBMC_BAD_VALUE;
}
+
+ match_add_ethernet_prereq(match, field);
}
if (error) {
@@ -775,6 +777,7 @@ oxm_pull_field_array(const void *fields_data, size_t fields_len,
struct nxm_put_ctx {
struct ofpbuf *output;
+ bool implied_ethernet;
};
void
@@ -795,6 +798,9 @@ nxm_put__(struct nxm_put_ctx *ctx,
const void *value, const void *mask, size_t n_bytes)
{
nxm_put_entry_raw(ctx->output, field, version, value, mask, n_bytes);
+ if (!ctx->implied_ethernet && mf_from_id(field)->prereqs != MFP_NONE) {
+ ctx->implied_ethernet = true;
+ }
}
static void
@@ -904,8 +910,9 @@ nxm_put_ip(struct nxm_put_ctx *ctx,
const struct match *match, enum ofp_version oxm)
{
const struct flow *flow = &match->flow;
+ ovs_be16 dl_type = get_dl_type(flow);
- if (flow->dl_type == htons(ETH_TYPE_IP)) {
+ if (dl_type == htons(ETH_TYPE_IP)) {
nxm_put_32m(ctx, MFF_IPV4_SRC, oxm,
flow->nw_src, match->wc.masks.nw_src);
nxm_put_32m(ctx, MFF_IPV4_DST, oxm,
@@ -1014,12 +1021,19 @@ nx_put_raw(struct ofpbuf *b, enum ofp_version oxm, const struct match *match,
{
const struct flow *flow = &match->flow;
const size_t start_len = b->size;
+ ovs_be16 dl_type = get_dl_type(flow);
int match_len;
int i;
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 39);
- struct nxm_put_ctx ctx = { .output = b };
+ struct nxm_put_ctx ctx = { .output = b, .implied_ethernet = false };
+
+ /* OpenFlow Packet Type. Must be first. */
+ if (match->wc.masks.packet_type && !match_has_default_packet_type(match)) {
+ nxm_put_32m(&ctx, MFF_PACKET_TYPE, oxm, flow->packet_type,
+ match->wc.masks.packet_type);
+ }
/* Metadata. */
if (match->wc.masks.dp_hash) {
@@ -1082,7 +1096,7 @@ nx_put_raw(struct ofpbuf *b, enum ofp_version oxm, const struct match *match,
}
/* MPLS. */
- if (eth_type_mpls(flow->dl_type)) {
+ if (eth_type_mpls(dl_type)) {
if (match->wc.masks.mpls_lse[0] & htonl(MPLS_TC_MASK)) {
nxm_put_8(&ctx, MFF_MPLS_TC, oxm,
mpls_lse_to_tc(flow->mpls_lse[0]));
@@ -1102,8 +1116,8 @@ nx_put_raw(struct ofpbuf *b, enum ofp_version oxm, const struct match *match,
/* L3. */
if (is_ip_any(flow)) {
nxm_put_ip(&ctx, match, oxm);
- } else if (flow->dl_type == htons(ETH_TYPE_ARP) ||
- flow->dl_type == htons(ETH_TYPE_RARP)) {
+ } else if (dl_type == htons(ETH_TYPE_ARP) ||
+ dl_type == htons(ETH_TYPE_RARP)) {
/* ARP. */
if (match->wc.masks.nw_proto) {
nxm_put_16(&ctx, MFF_ARP_OP, oxm,
@@ -1198,6 +1212,16 @@ nx_put_raw(struct ofpbuf *b, enum ofp_version oxm, const struct match *match,
}
}
+ if (match_has_default_packet_type(match) && !ctx.implied_ethernet) {
+ uint64_t pt_stub[16 / 8];
+ struct ofpbuf pt;
+ ofpbuf_use_stack(&pt, pt_stub, sizeof pt_stub);
+ nxm_put_entry_raw(&pt, MFF_PACKET_TYPE, oxm, &flow->packet_type,
+ NULL, sizeof flow->packet_type);
+
+ ofpbuf_insert(b, start_len, pt.data, pt.size);
+ }
+
match_len = b->size - start_len;
return match_len;
}