From patchwork Mon Nov 6 23:24:56 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Scheurich X-Patchwork-Id: 835001 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3yW7wQ5NXfz9ryQ for ; Tue, 7 Nov 2017 10:25:58 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 6B253BC7; Mon, 6 Nov 2017 23:25:03 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 7307ABBE for ; Mon, 6 Nov 2017 23:25:02 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from sessmg23.ericsson.net (sessmg23.ericsson.net [193.180.251.45]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 9407F4FA for ; Mon, 6 Nov 2017 23:24:59 +0000 (UTC) X-AuditID: c1b4fb2d-bddff7000000268d-84-5a00ef49dc52 Received: from ESESSHC024.ericsson.se (Unknown_Domain [153.88.183.90]) by sessmg23.ericsson.net (Symantec Mail Security) with SMTP id A7.A2.09869.94FE00A5; Tue, 7 Nov 2017 00:24:57 +0100 (CET) Received: from ESESSMB107.ericsson.se ([169.254.7.134]) by ESESSHC024.ericsson.se ([153.88.183.90]) with mapi id 14.03.0352.000; Tue, 7 Nov 2017 00:24:57 +0100 From: Jan Scheurich To: "dev@openvswitch.org" Thread-Topic: [PATCH 2/2] NSH: Adjust NSH wire format to the latest IETF draft Thread-Index: AdNXVagCp+sydEy2QZit7KmFbcX6lw== Date: Mon, 6 Nov 2017 23:24:56 +0000 Message-ID: Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [153.88.183.154] MIME-Version: 1.0 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFupnkeLIzCtJLcpLzFFi42KZGbE9StfzPUOUwea7phavJjcwWhw9vYfZ YsWm08wWv79uY3Jg8Vi85yWTx7Ob/xk9nl/rYfF4v+8qWwBLFJdNSmpOZllqkb5dAlfG5H2f GQs2TmCuaO16wdLAOP88UxcjJ4eEgInE63MfWbsYuTiEBA4zSsxduZcRwlnMKPHySDdQFQcH m4CBxOzdDiANIgL6Eod6zrKA1DALzGGUOPl3ISNIQljAU2Jr01egBDtQUYDEYzmIcj2JM7+O g+1iEVCR2Li1EczmFfCVeHt0NQuIzSggJvH91BqwOLOAuMStJ/OhbhOQWLLnPDOELSrx8vE/ VghbSWLR7c9glzEL5Eucm+kBMVJQ4uTMJywTGIVmIZk0C6FqFpIqiBIdiQW7P7FB2NoSyxa+ Zoaxzxx4zIQsvoCRfRWjaHFqcXFuupGxXmpRZnJxcX6eXl5qySZGYDQd3PJbdwfj6teOhxgF OBiVeHgfPWaIEmJNLCuuzD3EKMHBrCTCu10dKMSbklhZlVqUH19UmpNafIhRmoNFSZzXYd+F CCGB9MSS1OzU1ILUIpgsEwenVAPjLMZFd0NE/mpHPp2p4XH5tcG6W0V7BXkb/J9VcRe/ilri pnzixCqzCbfWGwq+maei7Kt+9+tWBUGJpMlnuJdIz+QInd7ySac8fFaUj5hcrMBCWeX0TSqd J+a/+M7IfCH12+d/G6dea++bcGrptqnnpnV8PFDZ/fje5Lgp//hu75TfGSq/21mhU4mlOCPR UIu5qDgRAMxtyrGiAgAA X-Spam-Status: No, score=-2.3 required=5.0 tests=HTML_MESSAGE, RCVD_IN_DNSWL_MED autolearn=disabled version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org X-Content-Filtered-By: Mailman/MimeDel 2.1.12 Cc: "Jiri Benc \(jbenc@redhat.com\)" Subject: [ovs-dev] [PATCH 2/2] NSH: Adjust NSH wire format to the latest IETF draft X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org This commit adjusts the NSH user space implementation in OVS to the latest wire format defined in draft-ietf-sfc-nsh-28 (November 3 2017). The NSH_MDTYPE field was reduced from 8 to 4 bits. The FLAGS field is reduced from 8 to 2 bits. A new 6 bit TTL header field is added. The TTL field is set to 63 at encap(nsh). Match and set_field support for the newly introduced TTL header field and a corresponding dec_nsh_ttl action is not yet included and will be implemented in a future patch. Signed-off-by: Jan Scheurich Signed-off-by: Ben Pfaff --- include/openvswitch/nsh.h | 218 +++++++++++++++++++++++++++++++++++++++------- lib/flow.c | 2 +- lib/odp-execute.c | 15 ++-- lib/packets.c | 9 +- 4 files changed, 203 insertions(+), 41 deletions(-) -- 1.9.1 diff --git a/include/openvswitch/nsh.h b/include/openvswitch/nsh.h index a3611d0..4e18119 100644 --- a/include/openvswitch/nsh.h +++ b/include/openvswitch/nsh.h @@ -5,41 +5,189 @@ /* * Network Service Header: + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * |Ver|O|C|R|R|R|R|R|R| Length | MD Type | Next Proto | + * |Ver|O|U| TTL | Length |U|U|U|U|MD Type| Next Protocol | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Service Path ID | Service Index | + * | Service Path Identifier (SPI) | Service Index | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | | - * ~ Mandatory/Optional Context Header ~ + * ~ Mandatory/Optional Context Headers ~ * | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * Ver = The version field is used to ensure backward compatibility - * going forward with future NSH updates. It MUST be set to 0x0 - * by the sender, in this first revision of NSH. * - * O = OAM. when set to 0x1 indicates that this packet is an operations - * and management (OAM) packet. The receiving SFF and SFs nodes - * MUST examine the payload and take appropriate action. + * Version: The version field is used to ensure backward compatibility + * going forward with future NSH specification updates. It MUST be set + * to 0x0 by the sender, in this first revision of NSH. Given the + * widespread implementation of existing hardware that uses the first + * nibble after an MPLS label stack for ECMP decision processing, this + * document reserves version 01b and this value MUST NOT be used in + * future versions of the protocol. Please see [RFC7325] for further + * discussion of MPLS-related forwarding requirements. * - * C = context. Indicates that a critical metadata TLV is present. + * O bit: Setting this bit indicates an Operations, Administration, and + * Maintenance (OAM) packet. The actual format and processing of SFC + * OAM packets is outside the scope of this specification (see for + * example [I-D.ietf-sfc-oam-framework] for one approach). * - * Length : total length, in 4-byte words, of NSH including the Base - * Header, the Service Path Header and the optional variable - * TLVs. - * MD Type: indicates the format of NSH beyond the mandatory Base Header - * and the Service Path Header. + * The O bit MUST be set for OAM packets and MUST NOT be set for non-OAM + * packets. The O bit MUST NOT be modified along the SFP. * - * Next Protocol: indicates the protocol type of the original packet. A - * new IANA registry will be created for protocol type. + * SF/SFF/SFC Proxy/Classifier implementations that do not support SFC + * OAM procedures SHOULD discard packets with O bit set, but MAY support + * a configurable parameter to enable forwarding received SFC OAM + * packets unmodified to the next element in the chain. Forwarding OAM + * packets unmodified by SFC elements that do not support SFC OAM + * procedures may be acceptable for a subset of OAM functions, but can + * result in unexpected outcomes for others, thus it is recommended to + * analyze the impact of forwarding an OAM packet for all OAM functions + * prior to enabling this behavior. The configurable parameter MUST be + * disabled by default. * - * Service Path Identifier (SPI): identifies a service path. - * Participating nodes MUST use this identifier for Service - * Function Path selection. + * TTL: Indicates the maximum SFF hops for an SFP. This field is used + * for service plane loop detection. The initial TTL value SHOULD be + * configurable via the control plane; the configured initial value can + * be specific to one or more SFPs. If no initial value is explicitly + * provided, the default initial TTL value of 63 MUST be used. Each SFF + * involved in forwarding an NSH packet MUST decrement the TTL value by + * 1 prior to NSH forwarding lookup. Decrementing by 1 from an incoming + * value of 0 shall result in a TTL value of 63. The packet MUST NOT be + * forwarded if TTL is, after decrement, 0. * - * Service Index (SI): provides location within the SFP. + * All other flag fields, marked U, are unassigned and available for + * future use, see Section 11.2.1. Unassigned bits MUST be set to zero + * upon origination, and MUST be ignored and preserved unmodified by + * other NSH supporting elements. Elements which do not understand the + * meaning of any of these bits MUST NOT modify their actions based on + * those unknown bits. * - * [0] https://tools.ietf.org/html/draft-ietf-sfc-nsh-13 + * Length: The total length, in 4-byte words, of NSH including the Base + * Header, the Service Path Header, the Fixed Length Context Header or + * Variable Length Context Header(s). The length MUST be 0x6 for MD + * Type equal to 0x1, and MUST be 0x2 or greater for MD Type equal to + * 0x2. The length of the NSH header MUST be an integer multiple of 4 + * bytes, thus variable length metadata is always padded out to a + * multiple of 4 bytes. + * + * MD Type: Indicates the format of NSH beyond the mandatory Base Header + * and the Service Path Header. MD Type defines the format of the + * metadata being carried. + * + * 0x0 - This is a reserved value. Implementations SHOULD silently + * discard packets with MD Type 0x0. + * + * 0x1 - This indicates that the format of the header includes a fixed + * length Context Header (see Figure 4 below). + * + * 0x2 - This does not mandate any headers beyond the Base Header and + * Service Path Header, but may contain optional variable length Context + * Header(s). The semantics of the variable length Context Header(s) + * are not defined in this document. The format of the optional + * variable length Context Headers is provided in Section 2.5.1. + * + * 0xF - This value is reserved for experimentation and testing, as per + * [RFC3692]. Implementations not explicitly configured to be part of + * an experiment SHOULD silently discard packets with MD Type 0xF. + * + * Next Protocol: indicates the protocol type of the encapsulated data. + * NSH does not alter the inner payload, and the semantics on the inner + * protocol remain unchanged due to NSH service function chaining. + * Please see the IANA Considerations section below, Section 11.2.5. + * + * This document defines the following Next Protocol values: + * + * 0x1: IPv4 + * 0x2: IPv6 + * 0x3: Ethernet + * 0x4: NSH + * 0x5: MPLS + * 0xFE: Experiment 1 + * 0xFF: Experiment 2 + * + * Packets with Next Protocol values not supported SHOULD be silently + * dropped by default, although an implementation MAY provide a + * configuration parameter to forward them. Additionally, an + * implementation not explicitly configured for a specific experiment + * [RFC3692] SHOULD silently drop packets with Next Protocol values 0xFE + * and 0xFF. + * + * Service Path Identifier (SPI): Identifies a service path. + * Participating nodes MUST use this identifier for Service Function + * Path selection. The initial classifier MUST set the appropriate SPI + * for a given classification result. + * + * Service Index (SI): Provides location within the SFP. The initial + * classifier for a given SFP SHOULD set the SI to 255, however the + * control plane MAY configure the initial value of SI as appropriate + * (i.e., taking into account the length of the service function path). + * The Service Index MUST be decremented by a value of 1 by Service + * Functions or by SFC Proxy nodes after performing required services + * and the new decremented SI value MUST be used in the egress packet's + * NSH. The initial Classifier MUST send the packet to the first SFF in + * the identified SFP for forwarding along an SFP. If re-classification + * occurs, and that re-classification results in a new SPI, the + * (re)classifier is, in effect, the initial classifier for the + * resultant SPI. + * + * The SI is used in conjunction the with Service Path Identifier for + * Service Function Path Selection and for determining the next SFF/SF + * in the path. The SI is also valuable when troubleshooting or + * reporting service paths. Additionally, while the TTL field is the + * main mechanism for service plane loop detection, the SI can also be + * used for detecting service plane loops. + * + * When the Base Header specifies MD Type = 0x1, a Fixed Length Context + * Header (16-bytes) MUST be present immediately following the Service + * Path Header. The value of a Fixed Length Context + * Header that carries no metadata MUST be set to zero. + * + * When the base header specifies MD Type = 0x2, zero or more Variable + * Length Context Headers MAY be added, immediately following the + * Service Path Header (see Figure 5). Therefore, Length = 0x2, + * indicates that only the Base Header followed by the Service Path + * Header are present. The optional Variable Length Context Headers + * MUST be of an integer number of 4-bytes. The base header Length + * field MUST be used to determine the offset to locate the original + * packet or frame for SFC nodes that require access to that + * information. + * + * The format of the optional variable length Context Headers + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Metadata Class | Type |U| Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Variable Metadata | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * Metadata Class (MD Class): Defines the scope of the 'Type' field to + * provide a hierarchical namespace. The IANA Considerations + * Section 11.2.4 defines how the MD Class values can be allocated to + * standards bodies, vendors, and others. + * + * Type: Indicates the explicit type of metadata being carried. The + * definition of the Type is the responsibility of the MD Class owner. + * + * Unassigned bit: One unassigned bit is available for future use. This + * bit MUST NOT be set, and MUST be ignored on receipt. + * + * Length: Indicates the length of the variable metadata, in bytes. In + * case the metadata length is not an integer number of 4-byte words, + * the sender MUST add pad bytes immediately following the last metadata + * byte to extend the metadata to an integer number of 4-byte words. + * The receiver MUST round up the length field to the nearest 4-byte + * word boundary, to locate and process the next field in the packet. + * The receiver MUST access only those bytes in the metadata indicated + * by the length field (i.e., actual number of bytes) and MUST ignore + * the remaining bytes up to the nearest 4-byte word boundary. The + * Length may be 0 or greater. + * + * A value of 0 denotes a Context Header without a Variable Metadata + * field. + * + * [0] https://www.ietf.org/id/draft-ietf-sfc-nsh-28.txt */ #ifdef __cplusplus @@ -62,32 +210,36 @@ struct nsh_md2_tlv { }; struct nsh_hdr { - ovs_be16 ver_flags_len; + ovs_be16 ver_flags_ttl_len; uint8_t md_type; uint8_t next_proto; ovs_16aligned_be32 path_hdr; union { struct nsh_md1_ctx md1; - struct nsh_md2_tlv md2; + struct nsh_md2_tlv md2; /* This represents the first element of + a list of zero or more md2_tlv structs. + It may not be present. */ }; }; /* Masking NSH header fields. */ #define NSH_VER_MASK 0xc000 #define NSH_VER_SHIFT 14 -#define NSH_FLAGS_MASK 0x3fc0 -#define NSH_FLAGS_SHIFT 6 +#define NSH_FLAGS_MASK 0x3000 +#define NSH_FLAGS_SHIFT 12 +#define NSH_TTL_MASK 0x0fc0 +#define NSH_TTL_SHIFT 6 #define NSH_LEN_MASK 0x003f #define NSH_LEN_SHIFT 0 +#define NSH_MDTYPE_MASK 0x0f +#define NSH_MDTYPE_SHIFT 0 + #define NSH_SPI_MASK 0xffffff00 #define NSH_SPI_SHIFT 8 #define NSH_SI_MASK 0x000000ff #define NSH_SI_SHIFT 0 -#define NSH_DST_PORT 4790 /* UDP Port for NSH on VXLAN. */ -#define ETH_P_NSH 0x894F /* Ethertype for NSH. */ - /* NSH Base Header Next Protocol. */ #define NSH_P_IPV4 0x01 #define NSH_P_IPV6 0x02 @@ -113,7 +265,13 @@ struct nsh_hdr { static inline uint16_t nsh_hdr_len(const struct nsh_hdr *nsh) { - return ((ntohs(nsh->ver_flags_len) & NSH_LEN_MASK) >> NSH_LEN_SHIFT) << 2; + return ((ntohs(nsh->ver_flags_ttl_len) & NSH_LEN_MASK) >> NSH_LEN_SHIFT) << 2; +} + +static inline uint8_t +nsh_md_type(const struct nsh_hdr *nsh) +{ + return (nsh->md_type & NSH_MDTYPE_MASK) >> NSH_MDTYPE_SHIFT; } static inline struct nsh_md1_ctx * diff --git a/lib/flow.c b/lib/flow.c index e30ca98..1adc499 100644 --- a/lib/flow.c +++ b/lib/flow.c @@ -546,7 +546,7 @@ parse_nsh(const void **datap, size_t *sizep, struct flow_nsh *key) memset(key, 0, sizeof(struct flow_nsh)); - ver_flags_len = ntohs(nsh->ver_flags_len); + ver_flags_len = ntohs(nsh->ver_flags_ttl_len); version = (ver_flags_len & NSH_VER_MASK) >> NSH_VER_SHIFT; flags = (ver_flags_len & NSH_FLAGS_MASK) >> NSH_FLAGS_SHIFT; diff --git a/lib/odp-execute.c b/lib/odp-execute.c index 3109f39..e2c887c 100644 --- a/lib/odp-execute.c +++ b/lib/odp-execute.c @@ -277,12 +277,13 @@ odp_set_nsh(struct dp_packet *packet, const struct ovs_key_nsh *key, const struct ovs_key_nsh *mask) { struct nsh_hdr *nsh = dp_packet_l3(packet); + uint8_t mdtype = nsh_md_type(nsh); if (!mask) { - nsh->ver_flags_len = htons(key->flags << NSH_FLAGS_SHIFT) | - (nsh->ver_flags_len & ~htons(NSH_FLAGS_MASK)); + nsh->ver_flags_ttl_len = htons(key->flags << NSH_FLAGS_SHIFT) | + (nsh->ver_flags_ttl_len & ~htons(NSH_FLAGS_MASK)); put_16aligned_be32(&nsh->path_hdr, key->path_hdr); - switch (nsh->md_type) { + switch (mdtype) { case NSH_M_TYPE1: for (int i = 0; i < 4; i++) { put_16aligned_be32(&nsh->md1.c[i], key->c[i]); @@ -294,16 +295,16 @@ odp_set_nsh(struct dp_packet *packet, const struct ovs_key_nsh *key, break; } } else { - uint8_t flags = (ntohs(nsh->ver_flags_len) & NSH_FLAGS_MASK) >> + uint8_t flags = (ntohs(nsh->ver_flags_ttl_len) & NSH_FLAGS_MASK) >> NSH_FLAGS_SHIFT; flags = key->flags | (flags & ~mask->flags); - nsh->ver_flags_len = htons(flags << NSH_FLAGS_SHIFT) | - (nsh->ver_flags_len & ~htons(NSH_FLAGS_MASK)); + nsh->ver_flags_ttl_len = htons(flags << NSH_FLAGS_SHIFT) | + (nsh->ver_flags_ttl_len & ~htons(NSH_FLAGS_MASK)); ovs_be32 path_hdr = get_16aligned_be32(&nsh->path_hdr); path_hdr = key->path_hdr | (path_hdr & ~mask->path_hdr); put_16aligned_be32(&nsh->path_hdr, path_hdr); - switch (nsh->md_type) { + switch (mdtype) { case NSH_M_TYPE1: for (int i = 0; i < 4; i++) { ovs_be32 p = get_16aligned_be32(&nsh->md1.c[i]); diff --git a/lib/packets.c b/lib/packets.c index c991e9f..f589370 100644 --- a/lib/packets.c +++ b/lib/packets.c @@ -429,11 +429,14 @@ encap_nsh(struct dp_packet *packet, const struct ovs_action_encap_nsh *encap) } nsh = (struct nsh_hdr *) dp_packet_push_uninit(packet, length); - nsh->ver_flags_len = htons(encap->flags << NSH_FLAGS_SHIFT | length >> 2); + nsh->ver_flags_ttl_len = + htons(((encap->flags << NSH_FLAGS_SHIFT) & NSH_FLAGS_MASK) + | (63 << NSH_TTL_SHIFT) + | ((length >> 2) << NSH_LEN_SHIFT)); + nsh->md_type = (encap->mdtype << NSH_MDTYPE_SHIFT) & NSH_MDTYPE_MASK; nsh->next_proto = next_proto; put_16aligned_be32(&nsh->path_hdr, encap->path_hdr); - nsh->md_type = encap->mdtype; - switch (nsh->md_type) { + switch (encap->mdtype) { case NSH_M_TYPE1: nsh->md1 = *ALIGNED_CAST(struct nsh_md1_ctx *, encap->metadata); break;