2
0
mirror of https://github.com/openvswitch/ovs synced 2025-10-23 14:57:06 +00:00

userspace: Add support for NSH MD1 match fields

This patch adds support for NSH packet header fields to the OVS
control plane and the userspace datapath. Initially we support the
fields of the NSH base header as defined in
https://www.ietf.org/id/draft-ietf-sfc-nsh-13.txt
and the fixed context headers specified for metadata format MD1.
The variable length MD2 format is parsed but the TLV context headers
are not yet available for matching.

The NSH fields are modelled as experimenter fields with the dedicated
experimenter class 0x005ad650 proposed for NSH in ONF. The following
fields are defined:

NXOXM code            ofctl name    Size      Comment
=====================================================================
NXOXM_NSH_FLAGS       nsh_flags       8       Bits 2-9 of 1st NSH word
(0x005ad650,1)
NXOXM_NSH_MDTYPE      nsh_mdtype      8       Bits 16-23
(0x005ad650,2)
NXOXM_NSH_NEXTPROTO   nsh_np          8       Bits 24-31
(0x005ad650,3)
NXOXM_NSH_SPI         nsh_spi         24      Bits 0-23 of 2nd NSH word
(0x005ad650,4)
NXOXM_NSH_SI          nsh_si          8       Bits 24-31
(0x005ad650,5)
NXOXM_NSH_C1          nsh_c1          32      Maskable, nsh_mdtype==1
(0x005ad650,6)
NXOXM_NSH_C2          nsh_c2          32      Maskable, nsh_mdtype==1
(0x005ad650,7)
NXOXM_NSH_C3          nsh_c3          32      Maskable, nsh_mdtype==1
(0x005ad650,8)
NXOXM_NSH_C4          nsh_c4          32      Maskable, nsh_mdtype==1
(0x005ad650,9)

Co-authored-by: Johnson Li <johnson.li@intel.com>
Signed-off-by: Yi Yang <yi.y.yang@intel.com>
Signed-off-by: Jan Scheurich <jan.scheurich@ericsson.com>
Signed-off-by: Ben Pfaff <blp@ovn.org>
This commit is contained in:
Jan Scheurich
2017-08-05 13:41:08 +08:00
committed by Ben Pfaff
parent 05f282c2e1
commit 3d2fbd70bd
24 changed files with 984 additions and 27 deletions

View File

@@ -24,6 +24,7 @@
#include "openvswitch/ofp-util.h"
#include "packets.h"
#include "tun-metadata.h"
#include "openvswitch/nsh.h"
/* Converts the flow in 'flow' into a match in 'match', with the given
* 'wildcards'. */
@@ -1088,6 +1089,21 @@ format_ipv6_netmask(struct ds *s, const char *name,
}
}
static void
format_uint8_masked(struct ds *s, const char *name,
uint8_t value, uint8_t mask)
{
if (mask != 0) {
ds_put_format(s, "%s%s=%s", colors.param, name, colors.end);
if (mask == UINT8_MAX) {
ds_put_format(s, "%"PRIu8, value);
} else {
ds_put_format(s, "0x%02"PRIx8"/0x%02"PRIx8, value, mask);
}
ds_put_char(s, ',');
}
}
static void
format_uint16_masked(struct ds *s, const char *name,
uint16_t value, uint16_t mask)
@@ -1127,6 +1143,22 @@ format_be32_masked(struct ds *s, const char *name,
ds_put_format(s, "%s%s=%s", colors.param, name, colors.end);
if (mask == OVS_BE32_MAX) {
ds_put_format(s, "%"PRIu32, ntohl(value));
} else {
ds_put_format(s, "0x%08"PRIx32"/0x%08"PRIx32,
ntohl(value), ntohl(mask));
}
ds_put_char(s, ',');
}
}
static void
format_be32_masked_hex(struct ds *s, const char *name,
ovs_be32 value, ovs_be32 mask)
{
if (mask != htonl(0)) {
ds_put_format(s, "%s%s=%s", colors.param, name, colors.end);
if (mask == OVS_BE32_MAX) {
ds_put_format(s, "0x%"PRIx32, ntohl(value));
} else {
ds_put_format(s, "0x%"PRIx32"/0x%"PRIx32,
ntohl(value), ntohl(mask));
@@ -1218,6 +1250,22 @@ format_ct_label_masked(struct ds *s, const ovs_u128 *key, const ovs_u128 *mask)
}
}
static void
format_nsh_masked(struct ds *s, const struct flow *f, const struct flow *m)
{
format_uint8_masked(s, "nsh_flags", f->nsh.flags, m->nsh.flags);
format_uint8_masked(s, "nsh_mdtype", f->nsh.mdtype, m->nsh.mdtype);
format_uint8_masked(s, "nsh_np", f->nsh.np, m->nsh.np);
format_be32_masked_hex(s, "nsh_spi", f->nsh.spi, m->nsh.spi);
format_uint8_masked(s, "nsh_si", f->nsh.si, m->nsh.si);
if (m->nsh.mdtype == UINT8_MAX && f->nsh.mdtype == NSH_M_TYPE1) {
format_be32_masked_hex(s, "nsh_c1", f->nsh.c[0], m->nsh.c[0]);
format_be32_masked_hex(s, "nsh_c2", f->nsh.c[1], m->nsh.c[1]);
format_be32_masked_hex(s, "nsh_c3", f->nsh.c[2], m->nsh.c[2]);
format_be32_masked_hex(s, "nsh_c4", f->nsh.c[3], m->nsh.c[3]);
}
}
/* Appends a string representation of 'match' to 's'. If 'priority' is
* different from OFP_DEFAULT_PRIORITY, includes it in 's'. If 'port_map' is
* nonnull, uses it to translate port numbers to names in output. */
@@ -1235,7 +1283,7 @@ match_format(const struct match *match,
int i;
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 39);
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 40);
if (priority != OFP_DEFAULT_PRIORITY) {
ds_put_format(s, "%spriority=%s%d,",
@@ -1321,7 +1369,6 @@ match_format(const struct match *match,
}
if (wc->masks.dl_type) {
dl_type = f->dl_type;
skip_type = true;
if (dl_type == htons(ETH_TYPE_IP)) {
if (wc->masks.nw_proto) {
@@ -1459,6 +1506,8 @@ match_format(const struct match *match,
dl_type == htons(ETH_TYPE_RARP)) {
format_ip_netmask(s, "arp_spa", f->nw_src, wc->masks.nw_src);
format_ip_netmask(s, "arp_tpa", f->nw_dst, wc->masks.nw_dst);
} else if (dl_type == htons(ETH_TYPE_NSH)) {
format_nsh_masked(s, f, &wc->masks);
} else {
format_ip_netmask(s, "nw_src", f->nw_src, wc->masks.nw_src);
format_ip_netmask(s, "nw_dst", f->nw_dst, wc->masks.nw_dst);