11f0b7744SYi Yang #ifndef __NET_NSH_H
21f0b7744SYi Yang #define __NET_NSH_H 1
31f0b7744SYi Yang
41f0b7744SYi Yang #include <linux/skbuff.h>
51f0b7744SYi Yang
61f0b7744SYi Yang /*
71f0b7744SYi Yang * Network Service Header:
81f0b7744SYi Yang * 0 1 2 3
91f0b7744SYi Yang * 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
101f0b7744SYi Yang * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
111f0b7744SYi Yang * |Ver|O|U| TTL | Length |U|U|U|U|MD Type| Next Protocol |
121f0b7744SYi Yang * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
131f0b7744SYi Yang * | Service Path Identifier (SPI) | Service Index |
141f0b7744SYi Yang * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
151f0b7744SYi Yang * | |
161f0b7744SYi Yang * ~ Mandatory/Optional Context Headers ~
171f0b7744SYi Yang * | |
181f0b7744SYi Yang * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
191f0b7744SYi Yang *
201f0b7744SYi Yang * Version: The version field is used to ensure backward compatibility
211f0b7744SYi Yang * going forward with future NSH specification updates. It MUST be set
221f0b7744SYi Yang * to 0x0 by the sender, in this first revision of NSH. Given the
231f0b7744SYi Yang * widespread implementation of existing hardware that uses the first
241f0b7744SYi Yang * nibble after an MPLS label stack for ECMP decision processing, this
251f0b7744SYi Yang * document reserves version 01b and this value MUST NOT be used in
261f0b7744SYi Yang * future versions of the protocol. Please see [RFC7325] for further
271f0b7744SYi Yang * discussion of MPLS-related forwarding requirements.
281f0b7744SYi Yang *
291f0b7744SYi Yang * O bit: Setting this bit indicates an Operations, Administration, and
301f0b7744SYi Yang * Maintenance (OAM) packet. The actual format and processing of SFC
311f0b7744SYi Yang * OAM packets is outside the scope of this specification (see for
321f0b7744SYi Yang * example [I-D.ietf-sfc-oam-framework] for one approach).
331f0b7744SYi Yang *
341f0b7744SYi Yang * The O bit MUST be set for OAM packets and MUST NOT be set for non-OAM
351f0b7744SYi Yang * packets. The O bit MUST NOT be modified along the SFP.
361f0b7744SYi Yang *
371f0b7744SYi Yang * SF/SFF/SFC Proxy/Classifier implementations that do not support SFC
381f0b7744SYi Yang * OAM procedures SHOULD discard packets with O bit set, but MAY support
391f0b7744SYi Yang * a configurable parameter to enable forwarding received SFC OAM
401f0b7744SYi Yang * packets unmodified to the next element in the chain. Forwarding OAM
411f0b7744SYi Yang * packets unmodified by SFC elements that do not support SFC OAM
421f0b7744SYi Yang * procedures may be acceptable for a subset of OAM functions, but can
431f0b7744SYi Yang * result in unexpected outcomes for others, thus it is recommended to
441f0b7744SYi Yang * analyze the impact of forwarding an OAM packet for all OAM functions
451f0b7744SYi Yang * prior to enabling this behavior. The configurable parameter MUST be
461f0b7744SYi Yang * disabled by default.
471f0b7744SYi Yang *
481f0b7744SYi Yang * TTL: Indicates the maximum SFF hops for an SFP. This field is used
491f0b7744SYi Yang * for service plane loop detection. The initial TTL value SHOULD be
501f0b7744SYi Yang * configurable via the control plane; the configured initial value can
511f0b7744SYi Yang * be specific to one or more SFPs. If no initial value is explicitly
521f0b7744SYi Yang * provided, the default initial TTL value of 63 MUST be used. Each SFF
531f0b7744SYi Yang * involved in forwarding an NSH packet MUST decrement the TTL value by
541f0b7744SYi Yang * 1 prior to NSH forwarding lookup. Decrementing by 1 from an incoming
551f0b7744SYi Yang * value of 0 shall result in a TTL value of 63. The packet MUST NOT be
561f0b7744SYi Yang * forwarded if TTL is, after decrement, 0.
571f0b7744SYi Yang *
581f0b7744SYi Yang * All other flag fields, marked U, are unassigned and available for
591f0b7744SYi Yang * future use, see Section 11.2.1. Unassigned bits MUST be set to zero
601f0b7744SYi Yang * upon origination, and MUST be ignored and preserved unmodified by
611f0b7744SYi Yang * other NSH supporting elements. Elements which do not understand the
621f0b7744SYi Yang * meaning of any of these bits MUST NOT modify their actions based on
631f0b7744SYi Yang * those unknown bits.
641f0b7744SYi Yang *
651f0b7744SYi Yang * Length: The total length, in 4-byte words, of NSH including the Base
661f0b7744SYi Yang * Header, the Service Path Header, the Fixed Length Context Header or
671f0b7744SYi Yang * Variable Length Context Header(s). The length MUST be 0x6 for MD
681f0b7744SYi Yang * Type equal to 0x1, and MUST be 0x2 or greater for MD Type equal to
691f0b7744SYi Yang * 0x2. The length of the NSH header MUST be an integer multiple of 4
701f0b7744SYi Yang * bytes, thus variable length metadata is always padded out to a
711f0b7744SYi Yang * multiple of 4 bytes.
721f0b7744SYi Yang *
731f0b7744SYi Yang * MD Type: Indicates the format of NSH beyond the mandatory Base Header
741f0b7744SYi Yang * and the Service Path Header. MD Type defines the format of the
751f0b7744SYi Yang * metadata being carried.
761f0b7744SYi Yang *
771f0b7744SYi Yang * 0x0 - This is a reserved value. Implementations SHOULD silently
781f0b7744SYi Yang * discard packets with MD Type 0x0.
791f0b7744SYi Yang *
801f0b7744SYi Yang * 0x1 - This indicates that the format of the header includes a fixed
811f0b7744SYi Yang * length Context Header (see Figure 4 below).
821f0b7744SYi Yang *
831f0b7744SYi Yang * 0x2 - This does not mandate any headers beyond the Base Header and
841f0b7744SYi Yang * Service Path Header, but may contain optional variable length Context
851f0b7744SYi Yang * Header(s). The semantics of the variable length Context Header(s)
861f0b7744SYi Yang * are not defined in this document. The format of the optional
871f0b7744SYi Yang * variable length Context Headers is provided in Section 2.5.1.
881f0b7744SYi Yang *
891f0b7744SYi Yang * 0xF - This value is reserved for experimentation and testing, as per
901f0b7744SYi Yang * [RFC3692]. Implementations not explicitly configured to be part of
911f0b7744SYi Yang * an experiment SHOULD silently discard packets with MD Type 0xF.
921f0b7744SYi Yang *
931f0b7744SYi Yang * Next Protocol: indicates the protocol type of the encapsulated data.
941f0b7744SYi Yang * NSH does not alter the inner payload, and the semantics on the inner
951f0b7744SYi Yang * protocol remain unchanged due to NSH service function chaining.
961f0b7744SYi Yang * Please see the IANA Considerations section below, Section 11.2.5.
971f0b7744SYi Yang *
981f0b7744SYi Yang * This document defines the following Next Protocol values:
991f0b7744SYi Yang *
1001f0b7744SYi Yang * 0x1: IPv4
1011f0b7744SYi Yang * 0x2: IPv6
1021f0b7744SYi Yang * 0x3: Ethernet
1031f0b7744SYi Yang * 0x4: NSH
1041f0b7744SYi Yang * 0x5: MPLS
1051f0b7744SYi Yang * 0xFE: Experiment 1
1061f0b7744SYi Yang * 0xFF: Experiment 2
1071f0b7744SYi Yang *
1081f0b7744SYi Yang * Packets with Next Protocol values not supported SHOULD be silently
1091f0b7744SYi Yang * dropped by default, although an implementation MAY provide a
1101f0b7744SYi Yang * configuration parameter to forward them. Additionally, an
1111f0b7744SYi Yang * implementation not explicitly configured for a specific experiment
1121f0b7744SYi Yang * [RFC3692] SHOULD silently drop packets with Next Protocol values 0xFE
1131f0b7744SYi Yang * and 0xFF.
1141f0b7744SYi Yang *
1151f0b7744SYi Yang * Service Path Identifier (SPI): Identifies a service path.
1161f0b7744SYi Yang * Participating nodes MUST use this identifier for Service Function
1171f0b7744SYi Yang * Path selection. The initial classifier MUST set the appropriate SPI
1181f0b7744SYi Yang * for a given classification result.
1191f0b7744SYi Yang *
1201f0b7744SYi Yang * Service Index (SI): Provides location within the SFP. The initial
1211f0b7744SYi Yang * classifier for a given SFP SHOULD set the SI to 255, however the
1221f0b7744SYi Yang * control plane MAY configure the initial value of SI as appropriate
1231f0b7744SYi Yang * (i.e., taking into account the length of the service function path).
1241f0b7744SYi Yang * The Service Index MUST be decremented by a value of 1 by Service
1251f0b7744SYi Yang * Functions or by SFC Proxy nodes after performing required services
1261f0b7744SYi Yang * and the new decremented SI value MUST be used in the egress packet's
1271f0b7744SYi Yang * NSH. The initial Classifier MUST send the packet to the first SFF in
1281f0b7744SYi Yang * the identified SFP for forwarding along an SFP. If re-classification
1291f0b7744SYi Yang * occurs, and that re-classification results in a new SPI, the
1301f0b7744SYi Yang * (re)classifier is, in effect, the initial classifier for the
1311f0b7744SYi Yang * resultant SPI.
1321f0b7744SYi Yang *
1331f0b7744SYi Yang * The SI is used in conjunction the with Service Path Identifier for
1341f0b7744SYi Yang * Service Function Path Selection and for determining the next SFF/SF
1351f0b7744SYi Yang * in the path. The SI is also valuable when troubleshooting or
1361f0b7744SYi Yang * reporting service paths. Additionally, while the TTL field is the
1371f0b7744SYi Yang * main mechanism for service plane loop detection, the SI can also be
1381f0b7744SYi Yang * used for detecting service plane loops.
1391f0b7744SYi Yang *
1401f0b7744SYi Yang * When the Base Header specifies MD Type = 0x1, a Fixed Length Context
1411f0b7744SYi Yang * Header (16-bytes) MUST be present immediately following the Service
1421f0b7744SYi Yang * Path Header. The value of a Fixed Length Context
1431f0b7744SYi Yang * Header that carries no metadata MUST be set to zero.
1441f0b7744SYi Yang *
1451f0b7744SYi Yang * When the base header specifies MD Type = 0x2, zero or more Variable
1461f0b7744SYi Yang * Length Context Headers MAY be added, immediately following the
1471f0b7744SYi Yang * Service Path Header (see Figure 5). Therefore, Length = 0x2,
1481f0b7744SYi Yang * indicates that only the Base Header followed by the Service Path
1491f0b7744SYi Yang * Header are present. The optional Variable Length Context Headers
1501f0b7744SYi Yang * MUST be of an integer number of 4-bytes. The base header Length
1511f0b7744SYi Yang * field MUST be used to determine the offset to locate the original
1521f0b7744SYi Yang * packet or frame for SFC nodes that require access to that
1531f0b7744SYi Yang * information.
1541f0b7744SYi Yang *
1551f0b7744SYi Yang * The format of the optional variable length Context Headers
1561f0b7744SYi Yang *
1571f0b7744SYi Yang * 0 1 2 3
1581f0b7744SYi Yang * 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
1591f0b7744SYi Yang * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1601f0b7744SYi Yang * | Metadata Class | Type |U| Length |
1611f0b7744SYi Yang * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1621f0b7744SYi Yang * | Variable Metadata |
1631f0b7744SYi Yang * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1641f0b7744SYi Yang *
1651f0b7744SYi Yang * Metadata Class (MD Class): Defines the scope of the 'Type' field to
1661f0b7744SYi Yang * provide a hierarchical namespace. The IANA Considerations
1671f0b7744SYi Yang * Section 11.2.4 defines how the MD Class values can be allocated to
1681f0b7744SYi Yang * standards bodies, vendors, and others.
1691f0b7744SYi Yang *
1701f0b7744SYi Yang * Type: Indicates the explicit type of metadata being carried. The
1711f0b7744SYi Yang * definition of the Type is the responsibility of the MD Class owner.
1721f0b7744SYi Yang *
1731f0b7744SYi Yang * Unassigned bit: One unassigned bit is available for future use. This
1741f0b7744SYi Yang * bit MUST NOT be set, and MUST be ignored on receipt.
1751f0b7744SYi Yang *
1761f0b7744SYi Yang * Length: Indicates the length of the variable metadata, in bytes. In
1771f0b7744SYi Yang * case the metadata length is not an integer number of 4-byte words,
1781f0b7744SYi Yang * the sender MUST add pad bytes immediately following the last metadata
1791f0b7744SYi Yang * byte to extend the metadata to an integer number of 4-byte words.
1801f0b7744SYi Yang * The receiver MUST round up the length field to the nearest 4-byte
1811f0b7744SYi Yang * word boundary, to locate and process the next field in the packet.
1821f0b7744SYi Yang * The receiver MUST access only those bytes in the metadata indicated
1831f0b7744SYi Yang * by the length field (i.e., actual number of bytes) and MUST ignore
1841f0b7744SYi Yang * the remaining bytes up to the nearest 4-byte word boundary. The
1851f0b7744SYi Yang * Length may be 0 or greater.
1861f0b7744SYi Yang *
1871f0b7744SYi Yang * A value of 0 denotes a Context Header without a Variable Metadata
1881f0b7744SYi Yang * field.
1891f0b7744SYi Yang *
1901f0b7744SYi Yang * [0] https://datatracker.ietf.org/doc/draft-ietf-sfc-nsh/
1911f0b7744SYi Yang */
1921f0b7744SYi Yang
1931f0b7744SYi Yang /**
1941f0b7744SYi Yang * struct nsh_md1_ctx - Keeps track of NSH context data
195*d1533d72SRandy Dunlap * @context: NSH Contexts.
1961f0b7744SYi Yang */
1971f0b7744SYi Yang struct nsh_md1_ctx {
1981f0b7744SYi Yang __be32 context[4];
1991f0b7744SYi Yang };
2001f0b7744SYi Yang
2011f0b7744SYi Yang struct nsh_md2_tlv {
2021f0b7744SYi Yang __be16 md_class;
2031f0b7744SYi Yang u8 type;
2041f0b7744SYi Yang u8 length;
2051f0b7744SYi Yang u8 md_value[];
2061f0b7744SYi Yang };
2071f0b7744SYi Yang
2081f0b7744SYi Yang struct nshhdr {
2091f0b7744SYi Yang __be16 ver_flags_ttl_len;
2101f0b7744SYi Yang u8 mdtype;
2111f0b7744SYi Yang u8 np;
2121f0b7744SYi Yang __be32 path_hdr;
2131f0b7744SYi Yang union {
2141f0b7744SYi Yang struct nsh_md1_ctx md1;
2151f0b7744SYi Yang struct nsh_md2_tlv md2;
2161f0b7744SYi Yang };
2171f0b7744SYi Yang };
2181f0b7744SYi Yang
2191f0b7744SYi Yang /* Masking NSH header fields. */
2201f0b7744SYi Yang #define NSH_VER_MASK 0xc000
2211f0b7744SYi Yang #define NSH_VER_SHIFT 14
2221f0b7744SYi Yang #define NSH_FLAGS_MASK 0x3000
2231f0b7744SYi Yang #define NSH_FLAGS_SHIFT 12
2241f0b7744SYi Yang #define NSH_TTL_MASK 0x0fc0
2251f0b7744SYi Yang #define NSH_TTL_SHIFT 6
2261f0b7744SYi Yang #define NSH_LEN_MASK 0x003f
2271f0b7744SYi Yang #define NSH_LEN_SHIFT 0
2281f0b7744SYi Yang
2291f0b7744SYi Yang #define NSH_MDTYPE_MASK 0x0f
2301f0b7744SYi Yang #define NSH_MDTYPE_SHIFT 0
2311f0b7744SYi Yang
2321f0b7744SYi Yang #define NSH_SPI_MASK 0xffffff00
2331f0b7744SYi Yang #define NSH_SPI_SHIFT 8
2341f0b7744SYi Yang #define NSH_SI_MASK 0x000000ff
2351f0b7744SYi Yang #define NSH_SI_SHIFT 0
2361f0b7744SYi Yang
2371f0b7744SYi Yang /* MD Type Registry. */
2381f0b7744SYi Yang #define NSH_M_TYPE1 0x01
2391f0b7744SYi Yang #define NSH_M_TYPE2 0x02
2401f0b7744SYi Yang #define NSH_M_EXP1 0xFE
2411f0b7744SYi Yang #define NSH_M_EXP2 0xFF
2421f0b7744SYi Yang
2431f0b7744SYi Yang /* NSH Base Header Length */
2441f0b7744SYi Yang #define NSH_BASE_HDR_LEN 8
2451f0b7744SYi Yang
2461f0b7744SYi Yang /* NSH MD Type 1 header Length. */
2471f0b7744SYi Yang #define NSH_M_TYPE1_LEN 24
2481f0b7744SYi Yang
2491f0b7744SYi Yang /* NSH header maximum Length. */
2501f0b7744SYi Yang #define NSH_HDR_MAX_LEN 256
2511f0b7744SYi Yang
2521f0b7744SYi Yang /* NSH context headers maximum Length. */
2531f0b7744SYi Yang #define NSH_CTX_HDRS_MAX_LEN 248
2541f0b7744SYi Yang
nsh_hdr(struct sk_buff * skb)2551f0b7744SYi Yang static inline struct nshhdr *nsh_hdr(struct sk_buff *skb)
2561f0b7744SYi Yang {
2571f0b7744SYi Yang return (struct nshhdr *)skb_network_header(skb);
2581f0b7744SYi Yang }
2591f0b7744SYi Yang
nsh_hdr_len(const struct nshhdr * nsh)2601f0b7744SYi Yang static inline u16 nsh_hdr_len(const struct nshhdr *nsh)
2611f0b7744SYi Yang {
2621f0b7744SYi Yang return ((ntohs(nsh->ver_flags_ttl_len) & NSH_LEN_MASK)
2631f0b7744SYi Yang >> NSH_LEN_SHIFT) << 2;
2641f0b7744SYi Yang }
2651f0b7744SYi Yang
nsh_get_ver(const struct nshhdr * nsh)2661f0b7744SYi Yang static inline u8 nsh_get_ver(const struct nshhdr *nsh)
2671f0b7744SYi Yang {
2681f0b7744SYi Yang return (ntohs(nsh->ver_flags_ttl_len) & NSH_VER_MASK)
2691f0b7744SYi Yang >> NSH_VER_SHIFT;
2701f0b7744SYi Yang }
2711f0b7744SYi Yang
nsh_get_flags(const struct nshhdr * nsh)2721f0b7744SYi Yang static inline u8 nsh_get_flags(const struct nshhdr *nsh)
2731f0b7744SYi Yang {
2741f0b7744SYi Yang return (ntohs(nsh->ver_flags_ttl_len) & NSH_FLAGS_MASK)
2751f0b7744SYi Yang >> NSH_FLAGS_SHIFT;
2761f0b7744SYi Yang }
2771f0b7744SYi Yang
nsh_get_ttl(const struct nshhdr * nsh)2781f0b7744SYi Yang static inline u8 nsh_get_ttl(const struct nshhdr *nsh)
2791f0b7744SYi Yang {
2801f0b7744SYi Yang return (ntohs(nsh->ver_flags_ttl_len) & NSH_TTL_MASK)
2811f0b7744SYi Yang >> NSH_TTL_SHIFT;
2821f0b7744SYi Yang }
2831f0b7744SYi Yang
__nsh_set_xflag(struct nshhdr * nsh,u16 xflag,u16 xmask)2841f0b7744SYi Yang static inline void __nsh_set_xflag(struct nshhdr *nsh, u16 xflag, u16 xmask)
2851f0b7744SYi Yang {
2861f0b7744SYi Yang nsh->ver_flags_ttl_len
2871f0b7744SYi Yang = (nsh->ver_flags_ttl_len & ~htons(xmask)) | htons(xflag);
2881f0b7744SYi Yang }
2891f0b7744SYi Yang
nsh_set_flags_and_ttl(struct nshhdr * nsh,u8 flags,u8 ttl)2901f0b7744SYi Yang static inline void nsh_set_flags_and_ttl(struct nshhdr *nsh, u8 flags, u8 ttl)
2911f0b7744SYi Yang {
2921f0b7744SYi Yang __nsh_set_xflag(nsh, ((flags << NSH_FLAGS_SHIFT) & NSH_FLAGS_MASK) |
2931f0b7744SYi Yang ((ttl << NSH_TTL_SHIFT) & NSH_TTL_MASK),
2941f0b7744SYi Yang NSH_FLAGS_MASK | NSH_TTL_MASK);
2951f0b7744SYi Yang }
2961f0b7744SYi Yang
nsh_set_flags_ttl_len(struct nshhdr * nsh,u8 flags,u8 ttl,u8 len)2971f0b7744SYi Yang static inline void nsh_set_flags_ttl_len(struct nshhdr *nsh, u8 flags,
2981f0b7744SYi Yang u8 ttl, u8 len)
2991f0b7744SYi Yang {
3001f0b7744SYi Yang len = len >> 2;
3011f0b7744SYi Yang __nsh_set_xflag(nsh, ((flags << NSH_FLAGS_SHIFT) & NSH_FLAGS_MASK) |
3021f0b7744SYi Yang ((ttl << NSH_TTL_SHIFT) & NSH_TTL_MASK) |
3031f0b7744SYi Yang ((len << NSH_LEN_SHIFT) & NSH_LEN_MASK),
3041f0b7744SYi Yang NSH_FLAGS_MASK | NSH_TTL_MASK | NSH_LEN_MASK);
3051f0b7744SYi Yang }
3061f0b7744SYi Yang
307b2d0f5d5SYi Yang int nsh_push(struct sk_buff *skb, const struct nshhdr *pushed_nh);
308b2d0f5d5SYi Yang int nsh_pop(struct sk_buff *skb);
309b2d0f5d5SYi Yang
3101f0b7744SYi Yang #endif /* __NET_NSH_H */
311