xref: /linux/include/net/nsh.h (revision a1c613ae4c322ddd58d5a8539dbfba2a0380a8c0)
1  #ifndef __NET_NSH_H
2  #define __NET_NSH_H 1
3  
4  #include <linux/skbuff.h>
5  
6  /*
7   * Network Service Header:
8   *  0                   1                   2                   3
9   *  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
10   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
11   * |Ver|O|U|    TTL    |   Length  |U|U|U|U|MD Type| Next Protocol |
12   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
13   * |          Service Path Identifier (SPI)        | Service Index |
14   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
15   * |                                                               |
16   * ~               Mandatory/Optional Context Headers              ~
17   * |                                                               |
18   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
19   *
20   * Version: The version field is used to ensure backward compatibility
21   * going forward with future NSH specification updates.  It MUST be set
22   * to 0x0 by the sender, in this first revision of NSH.  Given the
23   * widespread implementation of existing hardware that uses the first
24   * nibble after an MPLS label stack for ECMP decision processing, this
25   * document reserves version 01b and this value MUST NOT be used in
26   * future versions of the protocol.  Please see [RFC7325] for further
27   * discussion of MPLS-related forwarding requirements.
28   *
29   * O bit: Setting this bit indicates an Operations, Administration, and
30   * Maintenance (OAM) packet.  The actual format and processing of SFC
31   * OAM packets is outside the scope of this specification (see for
32   * example [I-D.ietf-sfc-oam-framework] for one approach).
33   *
34   * The O bit MUST be set for OAM packets and MUST NOT be set for non-OAM
35   * packets.  The O bit MUST NOT be modified along the SFP.
36   *
37   * SF/SFF/SFC Proxy/Classifier implementations that do not support SFC
38   * OAM procedures SHOULD discard packets with O bit set, but MAY support
39   * a configurable parameter to enable forwarding received SFC OAM
40   * packets unmodified to the next element in the chain.  Forwarding OAM
41   * packets unmodified by SFC elements that do not support SFC OAM
42   * procedures may be acceptable for a subset of OAM functions, but can
43   * result in unexpected outcomes for others, thus it is recommended to
44   * analyze the impact of forwarding an OAM packet for all OAM functions
45   * prior to enabling this behavior.  The configurable parameter MUST be
46   * disabled by default.
47   *
48   * TTL: Indicates the maximum SFF hops for an SFP.  This field is used
49   * for service plane loop detection.  The initial TTL value SHOULD be
50   * configurable via the control plane; the configured initial value can
51   * be specific to one or more SFPs.  If no initial value is explicitly
52   * provided, the default initial TTL value of 63 MUST be used.  Each SFF
53   * involved in forwarding an NSH packet MUST decrement the TTL value by
54   * 1 prior to NSH forwarding lookup.  Decrementing by 1 from an incoming
55   * value of 0 shall result in a TTL value of 63.  The packet MUST NOT be
56   * forwarded if TTL is, after decrement, 0.
57   *
58   * All other flag fields, marked U, are unassigned and available for
59   * future use, see Section 11.2.1.  Unassigned bits MUST be set to zero
60   * upon origination, and MUST be ignored and preserved unmodified by
61   * other NSH supporting elements.  Elements which do not understand the
62   * meaning of any of these bits MUST NOT modify their actions based on
63   * those unknown bits.
64   *
65   * Length: The total length, in 4-byte words, of NSH including the Base
66   * Header, the Service Path Header, the Fixed Length Context Header or
67   * Variable Length Context Header(s).  The length MUST be 0x6 for MD
68   * Type equal to 0x1, and MUST be 0x2 or greater for MD Type equal to
69   * 0x2.  The length of the NSH header MUST be an integer multiple of 4
70   * bytes, thus variable length metadata is always padded out to a
71   * multiple of 4 bytes.
72   *
73   * MD Type: Indicates the format of NSH beyond the mandatory Base Header
74   * and the Service Path Header.  MD Type defines the format of the
75   * metadata being carried.
76   *
77   * 0x0 - This is a reserved value.  Implementations SHOULD silently
78   * discard packets with MD Type 0x0.
79   *
80   * 0x1 - This indicates that the format of the header includes a fixed
81   * length Context Header (see Figure 4 below).
82   *
83   * 0x2 - This does not mandate any headers beyond the Base Header and
84   * Service Path Header, but may contain optional variable length Context
85   * Header(s).  The semantics of the variable length Context Header(s)
86   * are not defined in this document.  The format of the optional
87   * variable length Context Headers is provided in Section 2.5.1.
88   *
89   * 0xF - This value is reserved for experimentation and testing, as per
90   * [RFC3692].  Implementations not explicitly configured to be part of
91   * an experiment SHOULD silently discard packets with MD Type 0xF.
92   *
93   * Next Protocol: indicates the protocol type of the encapsulated data.
94   * NSH does not alter the inner payload, and the semantics on the inner
95   * protocol remain unchanged due to NSH service function chaining.
96   * Please see the IANA Considerations section below, Section 11.2.5.
97   *
98   * This document defines the following Next Protocol values:
99   *
100   * 0x1: IPv4
101   * 0x2: IPv6
102   * 0x3: Ethernet
103   * 0x4: NSH
104   * 0x5: MPLS
105   * 0xFE: Experiment 1
106   * 0xFF: Experiment 2
107   *
108   * Packets with Next Protocol values not supported SHOULD be silently
109   * dropped by default, although an implementation MAY provide a
110   * configuration parameter to forward them.  Additionally, an
111   * implementation not explicitly configured for a specific experiment
112   * [RFC3692] SHOULD silently drop packets with Next Protocol values 0xFE
113   * and 0xFF.
114   *
115   * Service Path Identifier (SPI): Identifies a service path.
116   * Participating nodes MUST use this identifier for Service Function
117   * Path selection.  The initial classifier MUST set the appropriate SPI
118   * for a given classification result.
119   *
120   * Service Index (SI): Provides location within the SFP.  The initial
121   * classifier for a given SFP SHOULD set the SI to 255, however the
122   * control plane MAY configure the initial value of SI as appropriate
123   * (i.e., taking into account the length of the service function path).
124   * The Service Index MUST be decremented by a value of 1 by Service
125   * Functions or by SFC Proxy nodes after performing required services
126   * and the new decremented SI value MUST be used in the egress packet's
127   * NSH.  The initial Classifier MUST send the packet to the first SFF in
128   * the identified SFP for forwarding along an SFP.  If re-classification
129   * occurs, and that re-classification results in a new SPI, the
130   * (re)classifier is, in effect, the initial classifier for the
131   * resultant SPI.
132   *
133   * The SI is used in conjunction the with Service Path Identifier for
134   * Service Function Path Selection and for determining the next SFF/SF
135   * in the path.  The SI is also valuable when troubleshooting or
136   * reporting service paths.  Additionally, while the TTL field is the
137   * main mechanism for service plane loop detection, the SI can also be
138   * used for detecting service plane loops.
139   *
140   * When the Base Header specifies MD Type = 0x1, a Fixed Length Context
141   * Header (16-bytes) MUST be present immediately following the Service
142   * Path Header. The value of a Fixed Length Context
143   * Header that carries no metadata MUST be set to zero.
144   *
145   * When the base header specifies MD Type = 0x2, zero or more Variable
146   * Length Context Headers MAY be added, immediately following the
147   * Service Path Header (see Figure 5).  Therefore, Length = 0x2,
148   * indicates that only the Base Header followed by the Service Path
149   * Header are present.  The optional Variable Length Context Headers
150   * MUST be of an integer number of 4-bytes.  The base header Length
151   * field MUST be used to determine the offset to locate the original
152   * packet or frame for SFC nodes that require access to that
153   * information.
154   *
155   * The format of the optional variable length Context Headers
156   *
157   *  0                   1                   2                   3
158   *  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
159   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
160   * |          Metadata Class       |      Type     |U|    Length   |
161   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
162   * |                      Variable Metadata                        |
163   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
164   *
165   * Metadata Class (MD Class): Defines the scope of the 'Type' field to
166   * provide a hierarchical namespace.  The IANA Considerations
167   * Section 11.2.4 defines how the MD Class values can be allocated to
168   * standards bodies, vendors, and others.
169   *
170   * Type: Indicates the explicit type of metadata being carried.  The
171   * definition of the Type is the responsibility of the MD Class owner.
172   *
173   * Unassigned bit: One unassigned bit is available for future use. This
174   * bit MUST NOT be set, and MUST be ignored on receipt.
175   *
176   * Length: Indicates the length of the variable metadata, in bytes.  In
177   * case the metadata length is not an integer number of 4-byte words,
178   * the sender MUST add pad bytes immediately following the last metadata
179   * byte to extend the metadata to an integer number of 4-byte words.
180   * The receiver MUST round up the length field to the nearest 4-byte
181   * word boundary, to locate and process the next field in the packet.
182   * The receiver MUST access only those bytes in the metadata indicated
183   * by the length field (i.e., actual number of bytes) and MUST ignore
184   * the remaining bytes up to the nearest 4-byte word boundary.  The
185   * Length may be 0 or greater.
186   *
187   * A value of 0 denotes a Context Header without a Variable Metadata
188   * field.
189   *
190   * [0] https://datatracker.ietf.org/doc/draft-ietf-sfc-nsh/
191   */
192  
193  /**
194   * struct nsh_md1_ctx - Keeps track of NSH context data
195   * @context: NSH Contexts.
196   */
197  struct nsh_md1_ctx {
198  	__be32 context[4];
199  };
200  
201  struct nsh_md2_tlv {
202  	__be16 md_class;
203  	u8 type;
204  	u8 length;
205  	u8 md_value[];
206  };
207  
208  struct nshhdr {
209  	__be16 ver_flags_ttl_len;
210  	u8 mdtype;
211  	u8 np;
212  	__be32 path_hdr;
213  	union {
214  	    struct nsh_md1_ctx md1;
215  	    struct nsh_md2_tlv md2;
216  	};
217  };
218  
219  /* Masking NSH header fields. */
220  #define NSH_VER_MASK       0xc000
221  #define NSH_VER_SHIFT      14
222  #define NSH_FLAGS_MASK     0x3000
223  #define NSH_FLAGS_SHIFT    12
224  #define NSH_TTL_MASK       0x0fc0
225  #define NSH_TTL_SHIFT      6
226  #define NSH_LEN_MASK       0x003f
227  #define NSH_LEN_SHIFT      0
228  
229  #define NSH_MDTYPE_MASK    0x0f
230  #define NSH_MDTYPE_SHIFT   0
231  
232  #define NSH_SPI_MASK       0xffffff00
233  #define NSH_SPI_SHIFT      8
234  #define NSH_SI_MASK        0x000000ff
235  #define NSH_SI_SHIFT       0
236  
237  /* MD Type Registry. */
238  #define NSH_M_TYPE1     0x01
239  #define NSH_M_TYPE2     0x02
240  #define NSH_M_EXP1      0xFE
241  #define NSH_M_EXP2      0xFF
242  
243  /* NSH Base Header Length */
244  #define NSH_BASE_HDR_LEN  8
245  
246  /* NSH MD Type 1 header Length. */
247  #define NSH_M_TYPE1_LEN   24
248  
249  /* NSH header maximum Length. */
250  #define NSH_HDR_MAX_LEN 256
251  
252  /* NSH context headers maximum Length. */
253  #define NSH_CTX_HDRS_MAX_LEN 248
254  
nsh_hdr(struct sk_buff * skb)255  static inline struct nshhdr *nsh_hdr(struct sk_buff *skb)
256  {
257  	return (struct nshhdr *)skb_network_header(skb);
258  }
259  
nsh_hdr_len(const struct nshhdr * nsh)260  static inline u16 nsh_hdr_len(const struct nshhdr *nsh)
261  {
262  	return ((ntohs(nsh->ver_flags_ttl_len) & NSH_LEN_MASK)
263  		>> NSH_LEN_SHIFT) << 2;
264  }
265  
nsh_get_ver(const struct nshhdr * nsh)266  static inline u8 nsh_get_ver(const struct nshhdr *nsh)
267  {
268  	return (ntohs(nsh->ver_flags_ttl_len) & NSH_VER_MASK)
269  		>> NSH_VER_SHIFT;
270  }
271  
nsh_get_flags(const struct nshhdr * nsh)272  static inline u8 nsh_get_flags(const struct nshhdr *nsh)
273  {
274  	return (ntohs(nsh->ver_flags_ttl_len) & NSH_FLAGS_MASK)
275  		>> NSH_FLAGS_SHIFT;
276  }
277  
nsh_get_ttl(const struct nshhdr * nsh)278  static inline u8 nsh_get_ttl(const struct nshhdr *nsh)
279  {
280  	return (ntohs(nsh->ver_flags_ttl_len) & NSH_TTL_MASK)
281  		>> NSH_TTL_SHIFT;
282  }
283  
__nsh_set_xflag(struct nshhdr * nsh,u16 xflag,u16 xmask)284  static inline void __nsh_set_xflag(struct nshhdr *nsh, u16 xflag, u16 xmask)
285  {
286  	nsh->ver_flags_ttl_len
287  		= (nsh->ver_flags_ttl_len & ~htons(xmask)) | htons(xflag);
288  }
289  
nsh_set_flags_and_ttl(struct nshhdr * nsh,u8 flags,u8 ttl)290  static inline void nsh_set_flags_and_ttl(struct nshhdr *nsh, u8 flags, u8 ttl)
291  {
292  	__nsh_set_xflag(nsh, ((flags << NSH_FLAGS_SHIFT) & NSH_FLAGS_MASK) |
293  			     ((ttl << NSH_TTL_SHIFT) & NSH_TTL_MASK),
294  			NSH_FLAGS_MASK | NSH_TTL_MASK);
295  }
296  
nsh_set_flags_ttl_len(struct nshhdr * nsh,u8 flags,u8 ttl,u8 len)297  static inline void nsh_set_flags_ttl_len(struct nshhdr *nsh, u8 flags,
298  					 u8 ttl, u8 len)
299  {
300  	len = len >> 2;
301  	__nsh_set_xflag(nsh, ((flags << NSH_FLAGS_SHIFT) & NSH_FLAGS_MASK) |
302  			     ((ttl << NSH_TTL_SHIFT) & NSH_TTL_MASK) |
303  			     ((len << NSH_LEN_SHIFT) & NSH_LEN_MASK),
304  			NSH_FLAGS_MASK | NSH_TTL_MASK | NSH_LEN_MASK);
305  }
306  
307  int nsh_push(struct sk_buff *skb, const struct nshhdr *pushed_nh);
308  int nsh_pop(struct sk_buff *skb);
309  
310  #endif /* __NET_NSH_H */
311