Line data Source code
1 : /*
2 : * Copyright (c) 2016 Cisco and/or its affiliates.
3 : * Licensed under the Apache License, Version 2.0 (the "License");
4 : * you may not use this file except in compliance with the License.
5 : * You may obtain a copy of the License at:
6 : *
7 : * http://www.apache.org/licenses/LICENSE-2.0
8 : *
9 : * Unless required by applicable law or agreed to in writing, software
10 : * distributed under the License is distributed on an "AS IS" BASIS,
11 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : * See the License for the specific language governing permissions and
13 : * limitations under the License.
14 : */
15 :
16 : #ifndef __BIER_TYPES_H__
17 : #define __BIER_TYPES_H__
18 :
19 : #include <vlib/vlib.h>
20 : #include <vnet/dpo/dpo.h>
21 :
22 : /**
23 : * @brief Flags to control show output
24 : */
25 : typedef enum bier_show_flags_t_ {
26 : BIER_SHOW_BRIEF,
27 : BIER_SHOW_DETAIL = (1 << 0),
28 : } bier_show_flags_t;
29 :
30 : /**
31 : * Types of BIER tables
32 : */
33 : typedef enum bier_table_type_t_ {
34 : /**
35 : * BIER over MPLS with SPF
36 : */
37 : BIER_TABLE_MPLS_SPF,
38 :
39 : /**
40 : * BIER over MPLS for TE
41 : */
42 : BIER_TABLE_MPLS_TE,
43 : } __attribute__((packed)) bier_table_type_t;
44 :
45 : #define BIER_TABLE_TYPES { \
46 : [BIER_TABLE_MPLS_SPF] = "mpls-spf", \
47 : [BIER_TABLE_MPLS_TE] = "mpls-te", \
48 : }
49 :
50 : /**
51 : * bier_hdr_len_id_t enumerator
52 : **/
53 : typedef enum bier_hdr_len_id_t_ {
54 : BIER_HDR_LEN_64 = 0,
55 : BIER_HDR_LEN_128,
56 : BIER_HDR_LEN_256,
57 : BIER_HDR_LEN_512,
58 : BIER_HDR_LEN_1024,
59 : /**
60 : * Bit-string lengths greater than 1024 are not supported due to the
61 : * limited about pf space available in a vlib_buffer_t to prepend a
62 : * BIER header at imposition.
63 : */
64 : BIER_HDR_LEN_2048,
65 : BIER_HDR_LEN_4096,
66 : BIER_HDR_LEN_INVALID,
67 : } __attribute__((packed)) bier_hdr_len_id_t;
68 :
69 : #define BIER_HDR_LEN_IDS { \
70 : [BIER_HDR_LEN_INVALID] = "invalid",\
71 : [BIER_HDR_LEN_64] = "64", \
72 : [BIER_HDR_LEN_128] = "128", \
73 : [BIER_HDR_LEN_256] = "256", \
74 : [BIER_HDR_LEN_512] = "512", \
75 : [BIER_HDR_LEN_1024] = "1024", \
76 : [BIER_HDR_LEN_2048] = "2048", \
77 : [BIER_HDR_LEN_4096] = "4096", \
78 : }
79 :
80 : #define FOR_EACH_BIER_HDR_LEN(_len) \
81 : for (_item = BIER_HDR_LEN_64; \
82 : _item <= BIER_HDR_LEN_4096; \
83 : _item++)
84 :
85 : /**
86 : * Format the header length field
87 : */
88 : extern u8 *format_bier_hdr_len_id(u8 *s, va_list *ap);
89 :
90 : /*
91 : * convert from prefix len to hdr ID
92 : */
93 : static inline bier_hdr_len_id_t
94 : bier_prefix_len_to_hdr_id (u16 prfx_len) {
95 :
96 : switch (prfx_len) {
97 : case 7:
98 : return (BIER_HDR_LEN_64);
99 : case 8:
100 : return (BIER_HDR_LEN_128);
101 : case 9:
102 : return (BIER_HDR_LEN_256);
103 : case 10:
104 : return (BIER_HDR_LEN_512);
105 : case 11:
106 : return (BIER_HDR_LEN_1024);
107 : case 12:
108 : return (BIER_HDR_LEN_2048);
109 : case 13:
110 : return (BIER_HDR_LEN_4096);
111 : default:
112 : break;
113 : }
114 :
115 : return (BIER_HDR_LEN_INVALID);
116 : }
117 :
118 : static inline bier_hdr_len_id_t
119 : bier_hdr_byte_len_to_id (u32 bytes)
120 : {
121 : switch (bytes) {
122 : case 8:
123 : return (BIER_HDR_LEN_64);
124 : case 16:
125 : return (BIER_HDR_LEN_128);
126 : case 32:
127 : return (BIER_HDR_LEN_256);
128 : case 64:
129 : return (BIER_HDR_LEN_512);
130 : case 128:
131 : return (BIER_HDR_LEN_1024);
132 : case 256:
133 : return (BIER_HDR_LEN_2048);
134 : case 512:
135 : return (BIER_HDR_LEN_4096);
136 : }
137 :
138 : return (BIER_HDR_LEN_INVALID);
139 : }
140 :
141 : static inline bier_hdr_len_id_t
142 0 : bier_hdr_bit_len_to_id (u32 bytes)
143 : {
144 0 : switch (bytes) {
145 0 : case 64:
146 0 : return (BIER_HDR_LEN_64);
147 0 : case 128:
148 0 : return (BIER_HDR_LEN_128);
149 0 : case 256:
150 0 : return (BIER_HDR_LEN_256);
151 0 : case 512:
152 0 : return (BIER_HDR_LEN_512);
153 0 : case 1024:
154 0 : return (BIER_HDR_LEN_1024);
155 0 : case 2048:
156 0 : return (BIER_HDR_LEN_2048);
157 0 : case 4096:
158 0 : return (BIER_HDR_LEN_4096);
159 : }
160 :
161 0 : return (BIER_HDR_LEN_INVALID);
162 : }
163 :
164 : /**
165 : * bier_hdr_len_num_buckets_t enumerator
166 : **/
167 : typedef enum bier_hdr_len_num_buckets_t_ {
168 : BIER_HDR_BUCKETS_64 = 8,
169 : BIER_HDR_BUCKETS_128 = 16,
170 : BIER_HDR_BUCKETS_256 = 32,
171 : BIER_HDR_BUCKETS_512 = 64,
172 : BIER_HDR_BUCKETS_1024 = 128,
173 : BIER_HDR_BUCKETS_2048 = 256,
174 : BIER_HDR_BUCKETS_4096 = 512,
175 : } bier_hdr_len_num_buckets_t;
176 :
177 : /**
178 : * BIER header protocol payload types
179 : **/
180 : typedef enum bier_hdr_proto_id_t_ {
181 : BIER_HDR_PROTO_INVALID = 0,
182 : BIER_HDR_PROTO_MPLS_DOWN_STREAM,
183 : BIER_HDR_PROTO_MPLS_UP_STREAM,
184 : BIER_HDR_PROTO_ETHERNET,
185 : BIER_HDR_PROTO_IPV4,
186 : BIER_HDR_PROTO_IPV6,
187 : BIER_HDR_PROTO_VXLAN,
188 : BIER_HDR_PROTO_CTRL,
189 : BIER_HDR_PROTO_OAM,
190 : } __attribute__((packed)) bier_hdr_proto_id_t;
191 :
192 : #define BIER_HDR_N_PROTO (BIER_HDR_PROTO_OAM + 1)
193 :
194 : #define BIER_HDR_PROTO_ID_NAMES { \
195 : [BIER_HDR_PROTO_INVALID] = "invalid", \
196 : [BIER_HDR_PROTO_MPLS_DOWN_STREAM] = "mpls-down-stream", \
197 : [BIER_HDR_PROTO_MPLS_UP_STREAM] = "mpls-up-stream", \
198 : [BIER_HDR_PROTO_ETHERNET] = "ethernet", \
199 : [BIER_HDR_PROTO_IPV4] = "ipv4", \
200 : [BIER_HDR_PROTO_IPV6] = "ipv6", \
201 : [BIER_HDR_PROTO_VXLAN] = "vxlan", \
202 : [BIER_HDR_PROTO_CTRL] = "control-plane", \
203 : [BIER_HDR_PROTO_OAM] = "oam", \
204 : }
205 :
206 : #define FOR_EACH_BIER_HDR_PROTO(_proto) \
207 : for (_proto = BIER_HDR_PROTO_MPLS_DOWN_STREAM; \
208 : _proto <= BIER_HDR_PROTO_OAM; \
209 : _proto++)
210 :
211 : /**
212 : * Format the header length field
213 : */
214 : extern u8 *format_bier_hdr_proto(u8 *s, va_list *ap);
215 :
216 : /**
217 : * Convert from BIER next-hop proto to DPO proto
218 : */
219 : extern dpo_proto_t bier_hdr_proto_to_dpo(bier_hdr_proto_id_t bproto);
220 :
221 : /**
222 : * BIER header versions
223 : **/
224 : typedef enum bier_hdr_version_t_ {
225 : BIER_HDR_VERSION_1 = 0,
226 : } __attribute__((packed)) bier_hdr_version_t;
227 :
228 : /**
229 : * bier_hdr_code_t enumerator
230 : **/
231 : typedef enum bier_hdr_code_t_ {
232 : BIER_HDR_CODE_OAM_IPV4 = 0,
233 : BIER_HDR_CODE_OAM_IPV6 = 1,
234 : BIER_HDR_CODE_CTRL_IPV4 = 2,
235 : BIER_HDR_CODE_CTRL_IPV6 = 3,
236 : } __attribute__((packed)) bier_hdr_code_t;
237 :
238 : /**
239 : * bier_hdr_oam_sub_code_t enumerator
240 : */
241 : typedef enum bier_hdr_oam_sub_code_t_ {
242 : BIER_HDR_SUB_CODE_OAM_PING_REQ = 0,
243 : BIER_HDR_SUB_CODE_OAM_PING_RESP = 1,
244 : } __attribute__((packed)) bier_hdr_oam_sub_code_t;
245 :
246 : /**
247 : * bier_hdr_ctrl_sub_code_t enumerator
248 : */
249 : typedef enum bier_hdr_ctrl_sub_code_t_ {
250 : BIER_HDR_SUB_CODE_CTRL_MEMBER_REQ = 0,
251 : BIER_HDR_SUB_CODE_CTRL_ATTACHED_NET = 1,
252 : } __attribute__((packed)) bier_hdr_ctrl_sub_code_t;
253 :
254 : /**
255 : * A bucket is a byte. The byte string is thus always in network byte order.
256 : */
257 : typedef u8 bier_bit_mask_bucket_t;
258 :
259 : /**
260 : * 256 bits = 32 bytes
261 : */
262 : #define BIER_BIT_MASK_NUM_BUCKETS 32
263 : #define BIER_BIT_MASK_MAX_BUCKET (BIER_BIT_MASK_NUM_BUCKETS - 1)
264 :
265 : /**
266 : * number of bits in a bucket
267 : */
268 : #define BIER_BIT_MASK_BITS_PER_BUCKET 8
269 :
270 : /**
271 : * Supported bit-posiotn range
272 : */
273 : #define BIER_BIT_MASK_MIN_POS (1)
274 :
275 : /**
276 : * A Variable length BitString
277 : */
278 : typedef struct bier_bit_string_t_ {
279 : /**
280 : * The length of the string in BYTES
281 : */
282 : u16 bbs_len;
283 :
284 : /**
285 : * The buckets in the string
286 : */
287 : bier_bit_mask_bucket_t *bbs_buckets;
288 : } bier_bit_string_t;
289 :
290 : /**
291 : * A bit positon
292 : * as assigned to egress PEs
293 : */
294 : typedef u32 bier_bp_t;
295 :
296 : #define BIER_BP_TO_INDEX(bp) (bp - 1)
297 :
298 : /**
299 : * The maximum BP that can be assigned
300 : */
301 : #define BIER_BP_MAX 0x10000
302 :
303 : /**
304 : * An identifier of the sender of BIER packets
305 : * this is the source of the 'tree' - the BFIR
306 : */
307 : typedef u16 bier_hdr_src_id_t;
308 :
309 : /**
310 : * An entropy value in a BIER header
311 : */
312 : typedef u32 bier_hdr_entropy_t;
313 :
314 : #define BIER_BP_INVALID 0
315 :
316 : /**
317 : * A BIER header of variable length
318 : * The encoding follows:
319 : * https://tools.ietf.org/html/draft-ietf-bier-mpls-encapsulation-10
320 : */
321 : typedef struct bier_hdr_t_ {
322 : /**
323 : * The first nibble is always set to 0101
324 : * to ensure that when carried over MPLS, the BIER packet
325 : * is not mistaken for IPv[46]:
326 : * type: bier_hdr_version_t
327 : *
328 : * The second nibble is the version - this is 0:
329 : * type: bier_hdr_version_t
330 : *
331 : * The third nibble is header length ID
332 : * type: bier_hdr_len_id_t
333 : *
334 : * The next 20 bits are entropy
335 : * An entropy value, calculated by the head end, used
336 : * at the head and mid-points for load-balance hash
337 : * type: bier_hdr_entropy_t
338 : */
339 : u32 bh_first_word;
340 :
341 : /**
342 : * The second word comprises:
343 : * 2 bits of OAM for passive perf measurement
344 : * 2 reserved bits;
345 : * 6 bits of DSCP
346 : * 6 bits for the next-proto field of type;
347 : * bier_hdr_proto_id_t
348 : */
349 : u16 bh_oam_dscp_proto;
350 :
351 : /**
352 : * The BFR-ID of the sender
353 : */
354 : u16 bh_bfr_id;
355 :
356 : /**
357 : * The variable length bit-string
358 : */
359 : bier_bit_mask_bucket_t bh_bit_string[0];
360 : } bier_hdr_t;
361 :
362 : /**
363 : * Format a BIER header
364 : */
365 : extern u8 *format_bier_hdr(u8 *s, va_list *ap);
366 :
367 : /**
368 : * The BIER Set ID assigned to a BIER table
369 : */
370 : typedef u32 bier_table_set_id_t;
371 :
372 : #define BIER_TABLE_SET_INVALID_ID 0xffffffff
373 :
374 : /**
375 : * The BIER Sub-domain ID assigned to a BIER table
376 : */
377 : typedef u32 bier_table_sub_domain_id_t;
378 :
379 : #define BIER_TABLE_SUB_DOMAIN_INVALID_ID 0xffffffff
380 :
381 : /**
382 : * An ID or instance number of a BIER sub-table
383 : */
384 : typedef u32 bier_table_ecmp_id_t;
385 :
386 : /**
387 : * Definition of the ID of the BIER main table
388 : */
389 : #define BIER_ECMP_TABLE_ID_MAIN 0xFFFF
390 :
391 : /**
392 : * The ID of a table
393 : */
394 : typedef struct bier_table_id_t_ {
395 : /**
396 : * The SET-ID
397 : * The control plane divdies the bit-position space
398 : * into sets in the case the max bit-position is greater
399 : * than the table's bit-string size
400 : */
401 : bier_table_set_id_t bti_set;
402 :
403 : /**
404 : * The Sub-Domain-ID
405 : * The control plane has the configuration option to specify multiple
406 : * domains or topologies.
407 : */
408 : bier_table_sub_domain_id_t bti_sub_domain;
409 :
410 : /**
411 : * The SUB/ECMP-ID
412 : * Constructed by FIB to achieve ECMP between BFR-NBRs
413 : */
414 : bier_table_ecmp_id_t bti_ecmp;
415 :
416 : /**
417 : * The size of the bit string processed by this table.
418 : */
419 : bier_hdr_len_id_t bti_hdr_len;
420 :
421 : /**
422 : * The type of the table; SPF or TE, MPLS or IPv6
423 : */
424 : bier_table_type_t bti_type;
425 : } bier_table_id_t;
426 :
427 : /**
428 : * Format a BIER table ID
429 : */
430 : extern u8 *format_bier_table_id(u8 *s, va_list *ap);
431 :
432 : /**
433 : * Compare to BIER table IDs for equality
434 : */
435 : extern int bier_table_id_cmp(const bier_table_id_t *btid1,
436 : const bier_table_id_t *btid2);
437 :
438 : /**
439 : * Conversion functions for the enumerated bit-string length
440 : * values, to bit and bytes
441 : */
442 : extern u32 bier_hdr_len_id_to_num_buckets(bier_hdr_len_id_t id);
443 : extern u32 bier_hdr_len_id_to_num_bytes(bier_hdr_len_id_t id);
444 : extern u32 bier_hdr_len_id_to_max_bucket(bier_hdr_len_id_t id);
445 : extern u32 bier_hdr_len_id_to_num_bits(bier_hdr_len_id_t id);
446 : extern u32 bier_hdr_len_id_to_max_bit(bier_hdr_len_id_t id);
447 : extern u32 bier_hdr_len_id_to_prefix_len(bier_hdr_len_id_t id);
448 :
449 : #define BIER_OK 0
450 : #define BIER_ERR_NO_TABLE 1
451 : #define BIER_ERR_DUPLICATE_TABLE 2
452 : #define BIER_ERR_PANIC 3
453 : typedef int bier_rc;
454 :
455 : /**
456 : * The BIER universal 'label'
457 : */
458 : typedef u32 bier_bift_id_t;
459 :
460 : /**
461 : * An invalid value for the BIFT ID
462 : * all ones implies a BSL that's invalid.
463 : */
464 : #define BIER_BIFT_ID_INVALID (~0)
465 :
466 : extern u16 bier_bfit_id_get_sub_domain(bier_bift_id_t bift_id);
467 : extern u16 bier_bfit_id_get_set(bier_bift_id_t bift_id);
468 : extern bier_hdr_proto_id_t bier_bift_id_get_bit_string_length(bier_bift_id_t bift_id);
469 :
470 : /**
471 : * Encode a BIFT-ID as per draft-wijnandsxu-bier-non-mpls-bift-encoding-00.txt
472 : */
473 : extern bier_bift_id_t bier_bift_id_encode(bier_table_set_id_t set,
474 : bier_table_sub_domain_id_t sd,
475 : bier_hdr_len_id_t bsl);
476 : extern void bier_bift_id_decode(bier_bift_id_t id,
477 : bier_table_set_id_t *set,
478 : bier_table_sub_domain_id_t *sd,
479 : bier_hdr_len_id_t *bsl);
480 :
481 : extern u8* format_bier_bift_id(u8 *s, va_list *ap);
482 :
483 : #endif /* __BIER_TYPES_H__ */
|