d484ba9ed03f60c9933a2d0081e84b05418b34e0
[vpp.git] / src / vnet / bier / bier_types.h
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     BIER_HDR_LEN_2048,
60     BIER_HDR_LEN_4096,
61     BIER_HDR_LEN_INVALID,
62 } __attribute__((packed)) bier_hdr_len_id_t;
63
64 #define BIER_HDR_LEN_IDS {             \
65     [BIER_HDR_LEN_INVALID] = "invalid",\
66     [BIER_HDR_LEN_64]      = "64",     \
67     [BIER_HDR_LEN_128]     = "128",    \
68     [BIER_HDR_LEN_256]     = "256",    \
69     [BIER_HDR_LEN_512]     = "512",    \
70     [BIER_HDR_LEN_1024]    = "1024",   \
71     [BIER_HDR_LEN_2048]    = "2048",   \
72     [BIER_HDR_LEN_4096]    = "4096",   \
73 }
74
75 #define FOR_EACH_BIER_HDR_LEN(_len)    \
76     for (_item = BIER_HDR_LEN_64;      \
77          _item <= BIER_HDR_LEN_4096;   \
78          _item++)
79
80 /**
81  * Format the header length field
82  */
83 extern u8 *format_bier_hdr_len_id(u8 *s, va_list *ap);
84
85 /*
86  * convert from prefix len to hdr ID
87  */
88 static inline bier_hdr_len_id_t
89 bier_prefix_len_to_hdr_id (u16 prfx_len) {
90
91     switch (prfx_len) {
92     case 7:
93         return (BIER_HDR_LEN_64);
94     case 8:
95         return (BIER_HDR_LEN_128);
96     case 9:
97         return (BIER_HDR_LEN_256);
98     case 10:
99         return (BIER_HDR_LEN_512);
100     case 11:
101         return (BIER_HDR_LEN_1024);
102     case 12:
103         return (BIER_HDR_LEN_2048);
104     case 13:
105         return (BIER_HDR_LEN_4096);
106     default:
107         break;
108     }
109
110     return (BIER_HDR_LEN_INVALID);
111 }
112
113 static inline bier_hdr_len_id_t
114 bier_hdr_byte_len_to_id (u32 bytes)
115 {
116     switch (bytes) {
117     case 8:
118         return (BIER_HDR_LEN_64);
119     case 16:
120         return (BIER_HDR_LEN_128);
121     case 32:
122         return (BIER_HDR_LEN_256);
123     case 64:
124         return (BIER_HDR_LEN_512);
125     case 128:
126         return (BIER_HDR_LEN_1024);
127     case 256:
128         return (BIER_HDR_LEN_2048);
129     case 512:
130         return (BIER_HDR_LEN_4096);
131     }
132
133     return (BIER_HDR_LEN_INVALID);
134 }
135
136 static inline bier_hdr_len_id_t
137 bier_hdr_bit_len_to_id (u32 bytes)
138 {
139     switch (bytes) {
140     case 64:
141         return (BIER_HDR_LEN_64);
142     case 128:
143         return (BIER_HDR_LEN_128);
144     case 256:
145         return (BIER_HDR_LEN_256);
146     case 512:
147         return (BIER_HDR_LEN_512);
148     case 1024:
149         return (BIER_HDR_LEN_1024);
150     case 2048:
151         return (BIER_HDR_LEN_2048);
152     case 4096:
153         return (BIER_HDR_LEN_4096);
154     }
155
156     return (BIER_HDR_LEN_INVALID);
157 }
158
159 /**
160  * bier_hdr_len_num_buckets_t enumerator
161  **/
162 typedef enum bier_hdr_len_num_buckets_t_ {
163     BIER_HDR_BUCKETS_64 = 8,
164     BIER_HDR_BUCKETS_128 = 16,
165     BIER_HDR_BUCKETS_256 = 32,
166     BIER_HDR_BUCKETS_512 = 64,
167     BIER_HDR_BUCKETS_1024 = 128,
168     BIER_HDR_BUCKETS_2048 = 256,
169     BIER_HDR_BUCKETS_4096 = 512,
170 } bier_hdr_len_num_buckets_t;
171
172 /**
173  * BIER header protocol payload types
174  **/
175 typedef enum bier_hdr_proto_id_t_ {
176     BIER_HDR_PROTO_INVALID = 0,
177     BIER_HDR_PROTO_MPLS_DOWN_STREAM,
178     BIER_HDR_PROTO_MPLS_UP_STREAM,
179     BIER_HDR_PROTO_ETHERNET,
180     BIER_HDR_PROTO_IPV4,
181     BIER_HDR_PROTO_IPV6,
182     BIER_HDR_PROTO_VXLAN,
183     BIER_HDR_PROTO_CTRL,
184     BIER_HDR_PROTO_OAM,
185 } __attribute__((packed)) bier_hdr_proto_id_t;
186
187 #define BIER_HDR_N_PROTO (BIER_HDR_PROTO_OAM + 1)
188
189 #define BIER_HDR_PROTO_ID_NAMES {                               \
190     [BIER_HDR_PROTO_INVALID] = "invalid",                       \
191     [BIER_HDR_PROTO_MPLS_DOWN_STREAM] = "mpls-down-stream",     \
192     [BIER_HDR_PROTO_MPLS_UP_STREAM] = "mpls-up-stream",         \
193     [BIER_HDR_PROTO_ETHERNET] = "ethernet",                     \
194     [BIER_HDR_PROTO_IPV4] = "ipv4",                             \
195     [BIER_HDR_PROTO_IPV6] = "ipv6",                             \
196     [BIER_HDR_PROTO_VXLAN] = "vxlan",                           \
197     [BIER_HDR_PROTO_CTRL] = "control-plane",                    \
198     [BIER_HDR_PROTO_OAM] = "oam",                               \
199 }
200
201 #define FOR_EACH_BIER_HDR_PROTO(_proto)                 \
202     for (_proto = BIER_HDR_PROTO_MPLS_DOWN_STREAM;      \
203          _proto <= BIER_HDR_PROTO_OAM;                  \
204          _proto++)
205
206 /**
207  * Format the header length field
208  */
209 extern u8 *format_bier_hdr_proto(u8 *s, va_list *ap);
210
211 /**
212  * Convert from BIER next-hop proto to DPO proto
213  */
214 extern dpo_proto_t bier_hdr_proto_to_dpo(bier_hdr_proto_id_t bproto);
215
216 /**
217  * BIER header versions
218  **/
219 typedef enum bier_hdr_version_t_ {
220     BIER_HDR_VERSION_1 = 0,
221 } __attribute__((packed)) bier_hdr_version_t;
222
223 /**
224  * bier_hdr_code_t enumerator
225  **/
226 typedef enum bier_hdr_code_t_ {
227     BIER_HDR_CODE_OAM_IPV4 = 0,
228     BIER_HDR_CODE_OAM_IPV6 = 1,
229     BIER_HDR_CODE_CTRL_IPV4 = 2,
230     BIER_HDR_CODE_CTRL_IPV6 = 3,
231 } __attribute__((packed)) bier_hdr_code_t;
232
233 /**
234  * bier_hdr_oam_sub_code_t enumerator
235  */
236 typedef enum bier_hdr_oam_sub_code_t_ {
237     BIER_HDR_SUB_CODE_OAM_PING_REQ = 0,
238     BIER_HDR_SUB_CODE_OAM_PING_RESP = 1,
239 } __attribute__((packed)) bier_hdr_oam_sub_code_t;
240
241 /**
242  * bier_hdr_ctrl_sub_code_t enumerator
243  */
244 typedef enum bier_hdr_ctrl_sub_code_t_ {
245     BIER_HDR_SUB_CODE_CTRL_MEMBER_REQ = 0,
246     BIER_HDR_SUB_CODE_CTRL_ATTACHED_NET = 1,
247 } __attribute__((packed)) bier_hdr_ctrl_sub_code_t;
248
249 /**
250  * A bucket is a byte. The byte string is thus always in network byte order.
251  */
252 typedef u8 bier_bit_mask_bucket_t;
253
254 /**
255  * A BIER Bit-String value of length 64 bits.
256  */
257 typedef struct bier_bit_mask_64_t_ {
258     bier_bit_mask_bucket_t bits[BIER_HDR_BUCKETS_64];
259 } bier_bit_mask_64_t;
260
261 /**
262  * A BIER Bit-String value of length 128 bits.
263  */
264 typedef struct bier_bit_mask_128_t_ {
265     bier_bit_mask_bucket_t bits[BIER_HDR_BUCKETS_128];
266 } bier_bit_mask_128_t;
267
268 /**
269  * A BIER Bit-String value of length 256 bits.
270  */
271 typedef struct bier_bit_mask_256_t_ {
272     bier_bit_mask_bucket_t bits[BIER_HDR_BUCKETS_256];
273 } bier_bit_mask_256_t;
274
275 /**
276  * A BIER Bit-String value of length 512 bits.
277  */
278 typedef struct bier_bit_mask_512_t_ {
279     bier_bit_mask_bucket_t bits[BIER_HDR_BUCKETS_512];
280 } bier_bit_mask_512_t;
281
282 /**
283  * A BIER Bit-String value of length 1024 bits.
284  */
285 typedef struct bier_bit_mask_1024_t_ {
286     bier_bit_mask_bucket_t bits[BIER_HDR_BUCKETS_1024];
287 } bier_bit_mask_1024_t;
288
289 /**
290  * A BIER Bit-String value of length 2048 bits.
291  */
292 typedef struct bier_bit_mask_2048_t_ {
293     bier_bit_mask_bucket_t bits[BIER_HDR_BUCKETS_2048];
294 } bier_bit_mask_2048_t;
295
296 /**
297  * A BIER Bit-String value of length 4096 bits.
298  */
299 typedef struct bier_bit_mask_4096_t_ {
300     bier_bit_mask_bucket_t bits[BIER_HDR_BUCKETS_4096];
301 } bier_bit_mask_4096_t;
302
303
304 /**
305  * 256 bits = 32 bytes
306  */
307 #define BIER_BIT_MASK_NUM_BUCKETS 32
308 #define BIER_BIT_MASK_MAX_BUCKET (BIER_BIT_MASK_NUM_BUCKETS - 1)
309
310 /**
311  * number of bits in a bucket
312  */
313 #define BIER_BIT_MASK_BITS_PER_BUCKET 8
314
315 /**
316  * Supported bit-posiotn range
317  */
318 #define BIER_BIT_MASK_MIN_POS (1)
319
320 /**
321  * A Variable length BitString
322  */
323 typedef struct bier_bit_string_t_ {
324     /**
325      * The length of the string in BYTES
326      */
327     u16 bbs_len;
328
329     /**
330      * The buckets in the string
331      */
332     bier_bit_mask_bucket_t *bbs_buckets;
333 } bier_bit_string_t;
334
335 /**
336  * A BIER Bit-mask value
337  *
338  * The size of this mask represents this platforms BIER capabilities
339  */
340 typedef bier_bit_mask_256_t bier_bit_mask_t;
341
342 /**
343  * A bit positon
344  *  as assigned to egress PEs
345  */
346 typedef u32 bier_bp_t;
347
348 #define BIER_BP_TO_INDEX(bp) (bp - 1)
349
350 /**
351  * The maximum BP that can be assigned
352  */
353 #define BIER_BP_MAX 0x10000
354
355 /**
356  * An identifier of the sender of BIER packets
357  * this is the source of the 'tree' - the BFIR
358  */
359 typedef u16 bier_hdr_src_id_t;
360
361 /**
362  * An entropy value in a BIER header
363  */
364 typedef u32 bier_hdr_entropy_t;
365
366 #define BIER_BP_INVALID 0
367
368 /**
369  * A BIER header of variable length
370  * The encoding follows:
371  *   https://tools.ietf.org/html/draft-ietf-bier-mpls-encapsulation-10
372  */
373 typedef struct bier_hdr_t_ {
374     /**
375      * The first nibble is always set to 0101
376      * to ensure that when carried over MPLS, the BIER packet
377      * is not mistaken for IPv[46]:
378      *   type: bier_hdr_version_t
379      *
380      * The second nibble is the version - this is 0:
381      *   type: bier_hdr_version_t
382      *
383      * The third nibble is header length ID
384      *   type: bier_hdr_len_id_t
385      *
386      * The next 20 bits are entropy
387      * An entropy value, calculated by the head end, used
388      * at the head and mid-points for load-balance hash
389      *   type: bier_hdr_entropy_t
390      */
391     u32 bh_first_word;
392
393     /**
394      * The second word comprises:
395      *  2 bits of OAM for passive perf measurement
396      *  2 reserved bits;
397      *  6 bits of DSCP
398      *  6 bits for the next-proto field of type;
399      *     bier_hdr_proto_id_t
400      */
401     u16 bh_oam_dscp_proto;
402
403     /**
404      * The BFR-ID of the sender
405      */
406     u16 bh_bfr_id;
407
408     /**
409      * The variable length bit-string
410      */
411     bier_bit_mask_bucket_t bh_bit_string[0];
412 } bier_hdr_t;
413
414 /**
415  * Format a BIER header
416  */
417 extern u8 *format_bier_hdr(u8 *s, va_list *ap);
418
419 /**
420  * The BIER Set ID assigned to a BIER table
421  */
422 typedef u32 bier_table_set_id_t;
423
424 #define BIER_TABLE_SET_INVALID_ID 0xffffffff
425
426 /**
427  * The BIER Sub-domain ID assigned to a BIER table
428  */
429 typedef u32 bier_table_sub_domain_id_t;
430
431 #define BIER_TABLE_SUB_DOMAIN_INVALID_ID 0xffffffff
432
433 /**
434  * An ID or instance number of a BIER sub-table
435  */
436 typedef u32 bier_table_ecmp_id_t;
437
438 /**
439  * Definition of the ID of the BIER main table
440  */
441 #define BIER_ECMP_TABLE_ID_MAIN 0xFFFF
442
443 /**
444  * The ID of a table
445  */
446 typedef struct bier_table_id_t_ {
447     /**
448      * The SET-ID
449      *  The control plane divdies the bit-position space
450      * into sets in the case the max bit-position is greater
451      * than the table's bit-string size
452      */
453     bier_table_set_id_t bti_set;
454
455     /**
456      * The Sub-Domain-ID
457      * The control plane has the configuration option to specify multiple
458      * domains or topologies.
459      */
460     bier_table_sub_domain_id_t bti_sub_domain;
461
462     /**
463      * The SUB/ECMP-ID
464      * Constructed by FIB to achieve ECMP between BFR-NBRs
465      */
466     bier_table_ecmp_id_t bti_ecmp;
467
468     /**
469      * The size of the bit string processed by this table.
470      */
471     bier_hdr_len_id_t bti_hdr_len;
472
473    /**
474      * The type of the table; SPF or TE, MPLS or IPv6
475      */
476     bier_table_type_t bti_type;
477 } bier_table_id_t;
478
479 /**
480  * Format a BIER table ID
481  */
482 extern u8 *format_bier_table_id(u8 *s, va_list *ap);
483
484 /**
485  * Compare to BIER table IDs for equality
486  */
487 extern int bier_table_id_cmp(const bier_table_id_t *btid1,
488                              const bier_table_id_t *btid2);
489
490 /**
491  * Conversion functions for the enumerated bit-string length
492  * values, to bit and bytes
493  */
494 extern u32 bier_hdr_len_id_to_num_buckets(bier_hdr_len_id_t id);
495 extern u32 bier_hdr_len_id_to_num_bytes(bier_hdr_len_id_t id);
496 extern u32 bier_hdr_len_id_to_max_bucket(bier_hdr_len_id_t id);
497 extern u32 bier_hdr_len_id_to_num_bits(bier_hdr_len_id_t id);
498 extern u32 bier_hdr_len_id_to_max_bit(bier_hdr_len_id_t id);
499 extern u32 bier_hdr_len_id_to_prefix_len(bier_hdr_len_id_t id);
500
501 #define BIER_OK 0
502 #define BIER_ERR_NO_TABLE 1
503 #define BIER_ERR_DUPLICATE_TABLE 2
504 #define BIER_ERR_PANIC 3
505 typedef int bier_rc;
506
507 /**
508  * The BIER universal 'label'
509  */
510 typedef u32 bier_bift_id_t;
511
512 /**
513  * An invalid value for the BIFT ID
514  * all ones implies a BSL that's invalid.
515  */
516 #define BIER_BIFT_ID_INVALID (~0)
517
518 extern u16 bier_bfit_id_get_sub_domain(bier_bift_id_t bift_id);
519 extern u16 bier_bfit_id_get_set(bier_bift_id_t bift_id);
520 extern bier_hdr_proto_id_t bier_bift_id_get_bit_string_length(bier_bift_id_t bift_id);
521
522 /**
523  * Encode a BIFT-ID as per draft-wijnandsxu-bier-non-mpls-bift-encoding-00.txt
524  */
525 extern bier_bift_id_t bier_bift_id_encode(bier_table_set_id_t set,
526                                           bier_table_sub_domain_id_t sd,
527                                           bier_hdr_len_id_t bsl);
528 extern void bier_bift_id_decode(bier_bift_id_t id,
529                                 bier_table_set_id_t *set,
530                                 bier_table_sub_domain_id_t *sd,
531                                 bier_hdr_len_id_t *bsl);
532
533 extern u8* format_bier_bift_id(u8 *s, va_list *ap);
534
535 #endif /* __BIER_TYPES_H__ */