Back to home page

OSCL-LXR

 
 

    


0001 #ifndef __NET_NSH_H
0002 #define __NET_NSH_H 1
0003 
0004 #include <linux/skbuff.h>
0005 
0006 /*
0007  * Network Service Header:
0008  *  0                   1                   2                   3
0009  *  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
0010  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
0011  * |Ver|O|U|    TTL    |   Length  |U|U|U|U|MD Type| Next Protocol |
0012  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
0013  * |          Service Path Identifier (SPI)        | Service Index |
0014  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
0015  * |                                                               |
0016  * ~               Mandatory/Optional Context Headers              ~
0017  * |                                                               |
0018  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
0019  *
0020  * Version: The version field is used to ensure backward compatibility
0021  * going forward with future NSH specification updates.  It MUST be set
0022  * to 0x0 by the sender, in this first revision of NSH.  Given the
0023  * widespread implementation of existing hardware that uses the first
0024  * nibble after an MPLS label stack for ECMP decision processing, this
0025  * document reserves version 01b and this value MUST NOT be used in
0026  * future versions of the protocol.  Please see [RFC7325] for further
0027  * discussion of MPLS-related forwarding requirements.
0028  *
0029  * O bit: Setting this bit indicates an Operations, Administration, and
0030  * Maintenance (OAM) packet.  The actual format and processing of SFC
0031  * OAM packets is outside the scope of this specification (see for
0032  * example [I-D.ietf-sfc-oam-framework] for one approach).
0033  *
0034  * The O bit MUST be set for OAM packets and MUST NOT be set for non-OAM
0035  * packets.  The O bit MUST NOT be modified along the SFP.
0036  *
0037  * SF/SFF/SFC Proxy/Classifier implementations that do not support SFC
0038  * OAM procedures SHOULD discard packets with O bit set, but MAY support
0039  * a configurable parameter to enable forwarding received SFC OAM
0040  * packets unmodified to the next element in the chain.  Forwarding OAM
0041  * packets unmodified by SFC elements that do not support SFC OAM
0042  * procedures may be acceptable for a subset of OAM functions, but can
0043  * result in unexpected outcomes for others, thus it is recommended to
0044  * analyze the impact of forwarding an OAM packet for all OAM functions
0045  * prior to enabling this behavior.  The configurable parameter MUST be
0046  * disabled by default.
0047  *
0048  * TTL: Indicates the maximum SFF hops for an SFP.  This field is used
0049  * for service plane loop detection.  The initial TTL value SHOULD be
0050  * configurable via the control plane; the configured initial value can
0051  * be specific to one or more SFPs.  If no initial value is explicitly
0052  * provided, the default initial TTL value of 63 MUST be used.  Each SFF
0053  * involved in forwarding an NSH packet MUST decrement the TTL value by
0054  * 1 prior to NSH forwarding lookup.  Decrementing by 1 from an incoming
0055  * value of 0 shall result in a TTL value of 63.  The packet MUST NOT be
0056  * forwarded if TTL is, after decrement, 0.
0057  *
0058  * All other flag fields, marked U, are unassigned and available for
0059  * future use, see Section 11.2.1.  Unassigned bits MUST be set to zero
0060  * upon origination, and MUST be ignored and preserved unmodified by
0061  * other NSH supporting elements.  Elements which do not understand the
0062  * meaning of any of these bits MUST NOT modify their actions based on
0063  * those unknown bits.
0064  *
0065  * Length: The total length, in 4-byte words, of NSH including the Base
0066  * Header, the Service Path Header, the Fixed Length Context Header or
0067  * Variable Length Context Header(s).  The length MUST be 0x6 for MD
0068  * Type equal to 0x1, and MUST be 0x2 or greater for MD Type equal to
0069  * 0x2.  The length of the NSH header MUST be an integer multiple of 4
0070  * bytes, thus variable length metadata is always padded out to a
0071  * multiple of 4 bytes.
0072  *
0073  * MD Type: Indicates the format of NSH beyond the mandatory Base Header
0074  * and the Service Path Header.  MD Type defines the format of the
0075  * metadata being carried.
0076  *
0077  * 0x0 - This is a reserved value.  Implementations SHOULD silently
0078  * discard packets with MD Type 0x0.
0079  *
0080  * 0x1 - This indicates that the format of the header includes a fixed
0081  * length Context Header (see Figure 4 below).
0082  *
0083  * 0x2 - This does not mandate any headers beyond the Base Header and
0084  * Service Path Header, but may contain optional variable length Context
0085  * Header(s).  The semantics of the variable length Context Header(s)
0086  * are not defined in this document.  The format of the optional
0087  * variable length Context Headers is provided in Section 2.5.1.
0088  *
0089  * 0xF - This value is reserved for experimentation and testing, as per
0090  * [RFC3692].  Implementations not explicitly configured to be part of
0091  * an experiment SHOULD silently discard packets with MD Type 0xF.
0092  *
0093  * Next Protocol: indicates the protocol type of the encapsulated data.
0094  * NSH does not alter the inner payload, and the semantics on the inner
0095  * protocol remain unchanged due to NSH service function chaining.
0096  * Please see the IANA Considerations section below, Section 11.2.5.
0097  *
0098  * This document defines the following Next Protocol values:
0099  *
0100  * 0x1: IPv4
0101  * 0x2: IPv6
0102  * 0x3: Ethernet
0103  * 0x4: NSH
0104  * 0x5: MPLS
0105  * 0xFE: Experiment 1
0106  * 0xFF: Experiment 2
0107  *
0108  * Packets with Next Protocol values not supported SHOULD be silently
0109  * dropped by default, although an implementation MAY provide a
0110  * configuration parameter to forward them.  Additionally, an
0111  * implementation not explicitly configured for a specific experiment
0112  * [RFC3692] SHOULD silently drop packets with Next Protocol values 0xFE
0113  * and 0xFF.
0114  *
0115  * Service Path Identifier (SPI): Identifies a service path.
0116  * Participating nodes MUST use this identifier for Service Function
0117  * Path selection.  The initial classifier MUST set the appropriate SPI
0118  * for a given classification result.
0119  *
0120  * Service Index (SI): Provides location within the SFP.  The initial
0121  * classifier for a given SFP SHOULD set the SI to 255, however the
0122  * control plane MAY configure the initial value of SI as appropriate
0123  * (i.e., taking into account the length of the service function path).
0124  * The Service Index MUST be decremented by a value of 1 by Service
0125  * Functions or by SFC Proxy nodes after performing required services
0126  * and the new decremented SI value MUST be used in the egress packet's
0127  * NSH.  The initial Classifier MUST send the packet to the first SFF in
0128  * the identified SFP for forwarding along an SFP.  If re-classification
0129  * occurs, and that re-classification results in a new SPI, the
0130  * (re)classifier is, in effect, the initial classifier for the
0131  * resultant SPI.
0132  *
0133  * The SI is used in conjunction the with Service Path Identifier for
0134  * Service Function Path Selection and for determining the next SFF/SF
0135  * in the path.  The SI is also valuable when troubleshooting or
0136  * reporting service paths.  Additionally, while the TTL field is the
0137  * main mechanism for service plane loop detection, the SI can also be
0138  * used for detecting service plane loops.
0139  *
0140  * When the Base Header specifies MD Type = 0x1, a Fixed Length Context
0141  * Header (16-bytes) MUST be present immediately following the Service
0142  * Path Header. The value of a Fixed Length Context
0143  * Header that carries no metadata MUST be set to zero.
0144  *
0145  * When the base header specifies MD Type = 0x2, zero or more Variable
0146  * Length Context Headers MAY be added, immediately following the
0147  * Service Path Header (see Figure 5).  Therefore, Length = 0x2,
0148  * indicates that only the Base Header followed by the Service Path
0149  * Header are present.  The optional Variable Length Context Headers
0150  * MUST be of an integer number of 4-bytes.  The base header Length
0151  * field MUST be used to determine the offset to locate the original
0152  * packet or frame for SFC nodes that require access to that
0153  * information.
0154  *
0155  * The format of the optional variable length Context Headers
0156  *
0157  *  0                   1                   2                   3
0158  *  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
0159  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
0160  * |          Metadata Class       |      Type     |U|    Length   |
0161  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
0162  * |                      Variable Metadata                        |
0163  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
0164  *
0165  * Metadata Class (MD Class): Defines the scope of the 'Type' field to
0166  * provide a hierarchical namespace.  The IANA Considerations
0167  * Section 11.2.4 defines how the MD Class values can be allocated to
0168  * standards bodies, vendors, and others.
0169  *
0170  * Type: Indicates the explicit type of metadata being carried.  The
0171  * definition of the Type is the responsibility of the MD Class owner.
0172  *
0173  * Unassigned bit: One unassigned bit is available for future use. This
0174  * bit MUST NOT be set, and MUST be ignored on receipt.
0175  *
0176  * Length: Indicates the length of the variable metadata, in bytes.  In
0177  * case the metadata length is not an integer number of 4-byte words,
0178  * the sender MUST add pad bytes immediately following the last metadata
0179  * byte to extend the metadata to an integer number of 4-byte words.
0180  * The receiver MUST round up the length field to the nearest 4-byte
0181  * word boundary, to locate and process the next field in the packet.
0182  * The receiver MUST access only those bytes in the metadata indicated
0183  * by the length field (i.e., actual number of bytes) and MUST ignore
0184  * the remaining bytes up to the nearest 4-byte word boundary.  The
0185  * Length may be 0 or greater.
0186  *
0187  * A value of 0 denotes a Context Header without a Variable Metadata
0188  * field.
0189  *
0190  * [0] https://datatracker.ietf.org/doc/draft-ietf-sfc-nsh/
0191  */
0192 
0193 /**
0194  * struct nsh_md1_ctx - Keeps track of NSH context data
0195  * @nshc<1-4>: NSH Contexts.
0196  */
0197 struct nsh_md1_ctx {
0198     __be32 context[4];
0199 };
0200 
0201 struct nsh_md2_tlv {
0202     __be16 md_class;
0203     u8 type;
0204     u8 length;
0205     u8 md_value[];
0206 };
0207 
0208 struct nshhdr {
0209     __be16 ver_flags_ttl_len;
0210     u8 mdtype;
0211     u8 np;
0212     __be32 path_hdr;
0213     union {
0214         struct nsh_md1_ctx md1;
0215         struct nsh_md2_tlv md2;
0216     };
0217 };
0218 
0219 /* Masking NSH header fields. */
0220 #define NSH_VER_MASK       0xc000
0221 #define NSH_VER_SHIFT      14
0222 #define NSH_FLAGS_MASK     0x3000
0223 #define NSH_FLAGS_SHIFT    12
0224 #define NSH_TTL_MASK       0x0fc0
0225 #define NSH_TTL_SHIFT      6
0226 #define NSH_LEN_MASK       0x003f
0227 #define NSH_LEN_SHIFT      0
0228 
0229 #define NSH_MDTYPE_MASK    0x0f
0230 #define NSH_MDTYPE_SHIFT   0
0231 
0232 #define NSH_SPI_MASK       0xffffff00
0233 #define NSH_SPI_SHIFT      8
0234 #define NSH_SI_MASK        0x000000ff
0235 #define NSH_SI_SHIFT       0
0236 
0237 /* MD Type Registry. */
0238 #define NSH_M_TYPE1     0x01
0239 #define NSH_M_TYPE2     0x02
0240 #define NSH_M_EXP1      0xFE
0241 #define NSH_M_EXP2      0xFF
0242 
0243 /* NSH Base Header Length */
0244 #define NSH_BASE_HDR_LEN  8
0245 
0246 /* NSH MD Type 1 header Length. */
0247 #define NSH_M_TYPE1_LEN   24
0248 
0249 /* NSH header maximum Length. */
0250 #define NSH_HDR_MAX_LEN 256
0251 
0252 /* NSH context headers maximum Length. */
0253 #define NSH_CTX_HDRS_MAX_LEN 248
0254 
0255 static inline struct nshhdr *nsh_hdr(struct sk_buff *skb)
0256 {
0257     return (struct nshhdr *)skb_network_header(skb);
0258 }
0259 
0260 static inline u16 nsh_hdr_len(const struct nshhdr *nsh)
0261 {
0262     return ((ntohs(nsh->ver_flags_ttl_len) & NSH_LEN_MASK)
0263         >> NSH_LEN_SHIFT) << 2;
0264 }
0265 
0266 static inline u8 nsh_get_ver(const struct nshhdr *nsh)
0267 {
0268     return (ntohs(nsh->ver_flags_ttl_len) & NSH_VER_MASK)
0269         >> NSH_VER_SHIFT;
0270 }
0271 
0272 static inline u8 nsh_get_flags(const struct nshhdr *nsh)
0273 {
0274     return (ntohs(nsh->ver_flags_ttl_len) & NSH_FLAGS_MASK)
0275         >> NSH_FLAGS_SHIFT;
0276 }
0277 
0278 static inline u8 nsh_get_ttl(const struct nshhdr *nsh)
0279 {
0280     return (ntohs(nsh->ver_flags_ttl_len) & NSH_TTL_MASK)
0281         >> NSH_TTL_SHIFT;
0282 }
0283 
0284 static inline void __nsh_set_xflag(struct nshhdr *nsh, u16 xflag, u16 xmask)
0285 {
0286     nsh->ver_flags_ttl_len
0287         = (nsh->ver_flags_ttl_len & ~htons(xmask)) | htons(xflag);
0288 }
0289 
0290 static inline void nsh_set_flags_and_ttl(struct nshhdr *nsh, u8 flags, u8 ttl)
0291 {
0292     __nsh_set_xflag(nsh, ((flags << NSH_FLAGS_SHIFT) & NSH_FLAGS_MASK) |
0293                  ((ttl << NSH_TTL_SHIFT) & NSH_TTL_MASK),
0294             NSH_FLAGS_MASK | NSH_TTL_MASK);
0295 }
0296 
0297 static inline void nsh_set_flags_ttl_len(struct nshhdr *nsh, u8 flags,
0298                      u8 ttl, u8 len)
0299 {
0300     len = len >> 2;
0301     __nsh_set_xflag(nsh, ((flags << NSH_FLAGS_SHIFT) & NSH_FLAGS_MASK) |
0302                  ((ttl << NSH_TTL_SHIFT) & NSH_TTL_MASK) |
0303                  ((len << NSH_LEN_SHIFT) & NSH_LEN_MASK),
0304             NSH_FLAGS_MASK | NSH_TTL_MASK | NSH_LEN_MASK);
0305 }
0306 
0307 int nsh_push(struct sk_buff *skb, const struct nshhdr *pushed_nh);
0308 int nsh_pop(struct sk_buff *skb);
0309 
0310 #endif /* __NET_NSH_H */