179b94c2dc7605f67a6f38710b7986b81feb9ba4
[vpp.git] / vnet / vnet / sr / sr_packet.h
1 #ifndef included_vnet_sr_packet_h
2 #define included_vnet_sr_packet_h
3
4 #include <vnet/ip/ip.h>
5
6 /*
7  * ipv6 segment-routing header format
8  *
9  * Copyright (c) 2013 Cisco and/or its affiliates.
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at:
13  *
14  *     http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  */
22
23 /**
24  *  @file
25  *  @brief The Segment Routing Header (SRH).
26  *
27  *  The Segment Routing Header (SRH) is defined in the diagram below.
28  *
29  *
30  *     0                   1                   2                   3
31  *     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
32  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
33  *    | Next Header   |  Hdr Ext Len  | Routing Type  | Segments Left |
34  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
35  *    | First Segment |             Flags             |  HMAC Key ID  |
36  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
37  *    |                                                               |
38  *    |            Segment List[0] (128 bits ipv6 address)            |
39  *    |                                                               |
40  *    |                                                               |
41  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
42  *    |                                                               |
43  *    |                                                               |
44  *                                  ...
45  *    |                                                               |
46  *    |                                                               |
47  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
48  *    |                                                               |
49  *    |            Segment List[n] (128 bits ipv6 address)            |
50  *    |                                                               |
51  *    |                                                               |
52  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
53  *    |                                                               |
54  *    |            Policy List[0] (optional)                          |
55  *    |                                                               |
56  *    |                                                               |
57  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
58  *    |                                                               |
59  *    |            Policy List[1] (optional)                          |
60  *    |                                                               |
61  *    |                                                               |
62  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
63  *    |                                                               |
64  *    |            Policy List[2] (optional)                          |
65  *    |                                                               |
66  *    |                                                               |
67  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
68  *    |                                                               |
69  *    |                                                               |
70  *    |                                                               |
71  *    |                       HMAC (256 bits)                         |
72  *    |                        (optional)                             |
73  *    |                                                               |
74  *    |                                                               |
75  *    |                                                               |
76  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
77  *
78  *   where:
79  *
80  *   o  Next Header: 8-bit selector.  Identifies the type of header
81  *      immediately following the SRH.
82  *
83  *   o  Hdr Ext Len: 8-bit unsigned integer, is the length of the SRH
84  *      header in 8-octet units, not including the first 8 octets.
85  *
86  *   o  Routing Type: TBD, to be assigned by IANA (suggested value: 4).
87  *
88  *   o  Segments Left.  Defined in [RFC2460], it contains the index, in
89  *      the Segment List, of the next segment to inspect.  Segments Left
90  *      is decremented at each segment and it is used as an index in the
91  *      segment list.
92  *
93  *   o  First Segment: offset in the SRH, not including the first 8 octets
94  *      and expressed in 16-octet units, pointing to the last element of
95  *      the segment list, which is in fact the first segment of the
96  *      segment routing path.
97  *
98  *   o  Flags: 16 bits of flags.  Following flags are defined:
99  *
100  *                              1
101  *          0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
102  *         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
103  *         |C|P|R|R|    Policy Flags       |
104  *         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
105  *
106  *         C-flag: Clean-up flag.  Set when the SRH has to be removed from
107  *         the packet when packet reaches the last segment.
108  *
109  *         P-flag: Protected flag.  Set when the packet has been rerouted
110  *         through FRR mechanism by a SR endpoint node.  See Section 6.3
111  *         for more details.
112  *
113  *         R-flags.  Reserved and for future use.
114  *
115  *         Policy Flags.  Define the type of the IPv6 addresses encoded
116  *         into the Policy List (see below).  The following have been
117  *         defined:
118  *
119  *            Bits 4-6: determine the type of the first element after the
120  *            segment list.
121  *
122  *            Bits 7-9: determine the type of the second element.
123  *
124  *            Bits 10-12: determine the type of the third element.
125  *
126  *            Bits 13-15: determine the type of the fourth element.
127  *
128  *         The following values are used for the type:
129  *
130  *            0x0: Not present.  If value is set to 0x0, it means the
131  *            element represented by these bits is not present.
132  *
133  *            0x1: SR Ingress.
134  *
135  *            0x2: SR Egress.
136  *
137  *            0x3: Original Source Address.
138  *
139  *   o  HMAC Key ID and HMAC field, and their use are defined in
140  *      [I-D.vyncke-6man-segment-routing-security].
141  *
142  *   o  Segment List[n]: 128 bit IPv6 addresses representing the nth
143  *      segment in the Segment List.  The Segment List is encoded starting
144  *      from the last segment of the path.  I.e., the first element of the
145  *      segment list (Segment List [0]) contains the last segment of the
146  *      path while the last segment of the Segment List (Segment List[n])
147  *      contains the first segment of the path.  The index contained in
148  *      "Segments Left" identifies the current active segment.
149  *
150  *   o  Policy List.  Optional addresses representing specific nodes in
151  *      the SR path such as:
152  *
153  *         SR Ingress: a 128 bit generic identifier representing the
154  *         ingress in the SR domain (i.e.: it needs not to be a valid IPv6
155  *         address).
156  *
157  *         SR Egress: a 128 bit generic identifier representing the egress
158  *         in the SR domain (i.e.: it needs not to be a valid IPv6
159  *         address).
160  *
161  *         Original Source Address: IPv6 address originally present in the
162  *         SA field of the packet.
163  *
164  *      The segments in the Policy List are encoded after the segment list
165  *      and they are optional.  If none are in the SRH, all bits of the
166  *      Policy List Flags MUST be set to 0x0.
167  */
168
169 #ifndef IPPROTO_IPV6_ROUTE
170 #define IPPROTO_IPV6_ROUTE        43
171 #endif
172
173 #define ROUTING_HEADER_TYPE_SR    4
174 /**
175     @brief SR header struct.
176 */
177 typedef struct
178 {
179   /** Protocol for next header. */
180   u8 protocol;
181
182   /**
183    * Length of routing header in 8 octet units,
184    * not including the first 8 octets
185    */
186   u8 length;
187
188   /** Type of routing header; type 4 = segement routing */
189   u8 type;
190
191   /** Next segment in the segment list */
192   u8 segments_left;
193
194   /**
195    * Policy list pointer: offset in the SRH of the policy
196    * list - in 16-octet units - not including the first 8 octets.
197    */
198   u8 first_segment;
199
200   /** Flag bits */
201 #define IP6_SR_HEADER_FLAG_CLEANUP    (0x8000)
202   /** Flag bits */
203 #define IP6_SR_HEADER_FLAG_PROTECTED  (0x4000)
204   /** Flag bits */
205 #define IP6_SR_HEADER_FLAG_RESERVED   (0x3000)
206   /** Flag bits */
207 #define IP6_SR_HEADER_FLAG_PL_ELT_NOT_PRESENT (0x0)
208     /** Flag bits */
209 #define IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE (0x1)
210     /** Flag bits */
211 #define IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE (0x2)
212     /** Flag bits */
213 #define IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR (0x3)
214   /** values 0x4 - 0x7 are reserved */
215   u16 flags;
216   u8 hmac_key;
217
218   /** The segment + policy list elts */
219   ip6_address_t segments[0];
220 } __attribute__ ((packed)) ip6_sr_header_t;
221
222 static inline int
223 ip6_sr_policy_list_shift_from_index (int pl_index)
224 {
225   return (-3 * pl_index) + 12;
226 }
227
228 /** pl_index is one-origined */
229 static inline int
230 ip6_sr_policy_list_flags (u16 flags_host_byte_order, int pl_index)
231 {
232   int shift;
233
234   if (pl_index <= 0 || pl_index > 4)
235     return 0;
236
237   shift = (-3 * pl_index) + 12;
238   flags_host_byte_order >>= shift;
239
240   return (flags_host_byte_order & 7);
241 }
242
243 #endif /* included_vnet_sr_packet_h */
244
245 /*
246  * fd.io coding-style-patch-verification: ON
247  *
248  * Local Variables:
249  * eval: (c-set-style "gnu")
250  * End:
251  */