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:
7 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 #ifndef __BIER_TYPES_H__
17 #define __BIER_TYPES_H__
19 #include <vlib/vlib.h>
20 #include <vnet/dpo/dpo.h>
23 * @brief Flags to control show output
25 typedef enum bier_show_flags_t_ {
27 BIER_SHOW_DETAIL = (1 << 0),
31 * Types of BIER tables
33 typedef enum bier_table_type_t_ {
35 * BIER over MPLS with SPF
40 * BIER over MPLS for TE
43 } __attribute__((packed)) bier_table_type_t;
45 #define BIER_TABLE_TYPES { \
46 [BIER_TABLE_MPLS_SPF] = "mpls-spf", \
47 [BIER_TABLE_MPLS_TE] = "mpls-te", \
51 * bier_hdr_len_id_t enumerator
53 typedef enum bier_hdr_len_id_t_ {
62 } __attribute__((packed)) bier_hdr_len_id_t;
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", \
75 #define FOR_EACH_BIER_HDR_LEN(_len) \
76 for (_item = BIER_HDR_LEN_64; \
77 _item <= BIER_HDR_LEN_4096; \
81 * Format the header length field
83 extern u8 *format_bier_hdr_len_id(u8 *s, va_list *ap);
86 * convert from prefix len to hdr ID
88 static inline bier_hdr_len_id_t
89 bier_prefix_len_to_hdr_id (u16 prfx_len) {
93 return (BIER_HDR_LEN_64);
95 return (BIER_HDR_LEN_128);
97 return (BIER_HDR_LEN_256);
99 return (BIER_HDR_LEN_512);
101 return (BIER_HDR_LEN_1024);
103 return (BIER_HDR_LEN_2048);
105 return (BIER_HDR_LEN_4096);
110 return (BIER_HDR_LEN_INVALID);
113 static inline bier_hdr_len_id_t
114 bier_hdr_byte_len_to_id (u32 bytes)
118 return (BIER_HDR_LEN_64);
120 return (BIER_HDR_LEN_128);
122 return (BIER_HDR_LEN_256);
124 return (BIER_HDR_LEN_512);
126 return (BIER_HDR_LEN_1024);
128 return (BIER_HDR_LEN_2048);
130 return (BIER_HDR_LEN_4096);
133 return (BIER_HDR_LEN_INVALID);
136 static inline bier_hdr_len_id_t
137 bier_hdr_bit_len_to_id (u32 bytes)
141 return (BIER_HDR_LEN_64);
143 return (BIER_HDR_LEN_128);
145 return (BIER_HDR_LEN_256);
147 return (BIER_HDR_LEN_512);
149 return (BIER_HDR_LEN_1024);
151 return (BIER_HDR_LEN_2048);
153 return (BIER_HDR_LEN_4096);
156 return (BIER_HDR_LEN_INVALID);
160 * bier_hdr_len_num_buckets_t enumerator
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;
173 * BIER header protocol payload types
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,
182 BIER_HDR_PROTO_VXLAN,
185 } __attribute__((packed)) bier_hdr_proto_id_t;
187 #define BIER_HDR_N_PROTO (BIER_HDR_PROTO_OAM + 1)
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", \
201 #define FOR_EACH_BIER_HDR_PROTO(_proto) \
202 for (_proto = BIER_HDR_PROTO_MPLS_DOWN_STREAM; \
203 _proto <= BIER_HDR_PROTO_OAM; \
207 * Format the header length field
209 extern u8 *format_bier_hdr_proto(u8 *s, va_list *ap);
212 * Convert from BIER next-hop proto to DPO proto
214 extern dpo_proto_t bier_hdr_proto_to_dpo(bier_hdr_proto_id_t bproto);
217 * BIER header versions
219 typedef enum bier_hdr_version_t_ {
220 BIER_HDR_VERSION_1 = 0,
221 } __attribute__((packed)) bier_hdr_version_t;
224 * bier_hdr_code_t enumerator
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;
234 * bier_hdr_oam_sub_code_t enumerator
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;
242 * bier_hdr_ctrl_sub_code_t enumerator
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;
250 * A bucket is a byte. The byte string is thus always in network byte order.
252 typedef u8 bier_bit_mask_bucket_t;
255 * A BIER Bit-String value of length 64 bits.
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;
262 * A BIER Bit-String value of length 128 bits.
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;
269 * A BIER Bit-String value of length 256 bits.
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;
276 * A BIER Bit-String value of length 512 bits.
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;
283 * A BIER Bit-String value of length 1024 bits.
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;
290 * A BIER Bit-String value of length 2048 bits.
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;
297 * A BIER Bit-String value of length 4096 bits.
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;
305 * 256 bits = 32 bytes
307 #define BIER_BIT_MASK_NUM_BUCKETS 32
308 #define BIER_BIT_MASK_MAX_BUCKET (BIER_BIT_MASK_NUM_BUCKETS - 1)
311 * number of bits in a bucket
313 #define BIER_BIT_MASK_BITS_PER_BUCKET 8
316 * Supported bit-posiotn range
318 #define BIER_BIT_MASK_MIN_POS (1)
321 * A Variable length BitString
323 typedef struct bier_bit_string_t_ {
325 * The length of the string in BYTES
330 * The buckets in the string
332 bier_bit_mask_bucket_t *bbs_buckets;
336 * A BIER Bit-mask value
338 * The size of this mask represents this platforms BIER capabilities
340 typedef bier_bit_mask_256_t bier_bit_mask_t;
344 * as assigned to egress PEs
346 typedef u32 bier_bp_t;
348 #define BIER_BP_TO_INDEX(bp) (bp - 1)
351 * The maximum BP that can be assigned
353 #define BIER_BP_MAX 0x10000
356 * An identifier of the sender of BIER packets
357 * this is the source of the 'tree' - the BFIR
359 typedef u16 bier_hdr_src_id_t;
362 * An entropy value in a BIER header
364 typedef u32 bier_hdr_entropy_t;
366 #define BIER_BP_INVALID 0
369 * A BIER header of variable length
370 * The encoding follows:
371 * https://tools.ietf.org/html/draft-ietf-bier-mpls-encapsulation-10
373 typedef struct bier_hdr_t_ {
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
380 * The second nibble is the version - this is 0:
381 * type: bier_hdr_version_t
383 * The third nibble is header length ID
384 * type: bier_hdr_len_id_t
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
394 * The second word comprises:
395 * 2 bits of OAM for passive perf measurement
398 * 6 bits for the next-proto field of type;
399 * bier_hdr_proto_id_t
401 u16 bh_oam_dscp_proto;
404 * The BFR-ID of the sender
409 * The variable length bit-string
411 bier_bit_mask_bucket_t bh_bit_string[0];
415 * Format a BIER header
417 extern u8 *format_bier_hdr(u8 *s, va_list *ap);
420 * The BIER Set ID assigned to a BIER table
422 typedef u32 bier_table_set_id_t;
424 #define BIER_TABLE_SET_INVALID_ID 0xffffffff
427 * The BIER Sub-domain ID assigned to a BIER table
429 typedef u32 bier_table_sub_domain_id_t;
431 #define BIER_TABLE_SUB_DOMAIN_INVALID_ID 0xffffffff
434 * An ID or instance number of a BIER sub-table
436 typedef u32 bier_table_ecmp_id_t;
439 * Definition of the ID of the BIER main table
441 #define BIER_ECMP_TABLE_ID_MAIN 0xFFFF
446 typedef struct bier_table_id_t_ {
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
453 bier_table_set_id_t bti_set;
457 * The control plane has the configuration option to specify multiple
458 * domains or topologies.
460 bier_table_sub_domain_id_t bti_sub_domain;
464 * Constructed by FIB to achieve ECMP between BFR-NBRs
466 bier_table_ecmp_id_t bti_ecmp;
469 * The size of the bit string processed by this table.
471 bier_hdr_len_id_t bti_hdr_len;
474 * The type of the table; SPF or TE, MPLS or IPv6
476 bier_table_type_t bti_type;
480 * Format a BIER table ID
482 extern u8 *format_bier_table_id(u8 *s, va_list *ap);
485 * Compare to BIER table IDs for equality
487 extern int bier_table_id_cmp(const bier_table_id_t *btid1,
488 const bier_table_id_t *btid2);
491 * Conversion functions for the enumerated bit-string length
492 * values, to bit and bytes
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);
502 #define BIER_ERR_NO_TABLE 1
503 #define BIER_ERR_DUPLICATE_TABLE 2
504 #define BIER_ERR_PANIC 3
508 * The BIER universal 'label'
510 typedef u32 bier_bift_id_t;
513 * An invalid value for the BIFT ID
514 * all ones implies a BSL that's invalid.
516 #define BIER_BIFT_ID_INVALID (~0)
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);
523 * Encode a BIFT-ID as per draft-wijnandsxu-bier-non-mpls-bift-encoding-00.txt
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);
533 extern u8* format_bier_bift_id(u8 *s, va_list *ap);
535 #endif /* __BIER_TYPES_H__ */