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_ {
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.
67 } __attribute__((packed)) bier_hdr_len_id_t;
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", \
80 #define FOR_EACH_BIER_HDR_LEN(_len) \
81 for (_item = BIER_HDR_LEN_64; \
82 _item <= BIER_HDR_LEN_4096; \
86 * Format the header length field
88 extern u8 *format_bier_hdr_len_id(u8 *s, va_list *ap);
91 * convert from prefix len to hdr ID
93 static inline bier_hdr_len_id_t
94 bier_prefix_len_to_hdr_id (u16 prfx_len) {
98 return (BIER_HDR_LEN_64);
100 return (BIER_HDR_LEN_128);
102 return (BIER_HDR_LEN_256);
104 return (BIER_HDR_LEN_512);
106 return (BIER_HDR_LEN_1024);
108 return (BIER_HDR_LEN_2048);
110 return (BIER_HDR_LEN_4096);
115 return (BIER_HDR_LEN_INVALID);
118 static inline bier_hdr_len_id_t
119 bier_hdr_byte_len_to_id (u32 bytes)
123 return (BIER_HDR_LEN_64);
125 return (BIER_HDR_LEN_128);
127 return (BIER_HDR_LEN_256);
129 return (BIER_HDR_LEN_512);
131 return (BIER_HDR_LEN_1024);
133 return (BIER_HDR_LEN_2048);
135 return (BIER_HDR_LEN_4096);
138 return (BIER_HDR_LEN_INVALID);
141 static inline bier_hdr_len_id_t
142 bier_hdr_bit_len_to_id (u32 bytes)
146 return (BIER_HDR_LEN_64);
148 return (BIER_HDR_LEN_128);
150 return (BIER_HDR_LEN_256);
152 return (BIER_HDR_LEN_512);
154 return (BIER_HDR_LEN_1024);
156 return (BIER_HDR_LEN_2048);
158 return (BIER_HDR_LEN_4096);
161 return (BIER_HDR_LEN_INVALID);
165 * bier_hdr_len_num_buckets_t enumerator
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;
178 * BIER header protocol payload types
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,
187 BIER_HDR_PROTO_VXLAN,
190 } __attribute__((packed)) bier_hdr_proto_id_t;
192 #define BIER_HDR_N_PROTO (BIER_HDR_PROTO_OAM + 1)
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", \
206 #define FOR_EACH_BIER_HDR_PROTO(_proto) \
207 for (_proto = BIER_HDR_PROTO_MPLS_DOWN_STREAM; \
208 _proto <= BIER_HDR_PROTO_OAM; \
212 * Format the header length field
214 extern u8 *format_bier_hdr_proto(u8 *s, va_list *ap);
217 * Convert from BIER next-hop proto to DPO proto
219 extern dpo_proto_t bier_hdr_proto_to_dpo(bier_hdr_proto_id_t bproto);
222 * BIER header versions
224 typedef enum bier_hdr_version_t_ {
225 BIER_HDR_VERSION_1 = 0,
226 } __attribute__((packed)) bier_hdr_version_t;
229 * bier_hdr_code_t enumerator
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;
239 * bier_hdr_oam_sub_code_t enumerator
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;
247 * bier_hdr_ctrl_sub_code_t enumerator
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;
255 * A bucket is a byte. The byte string is thus always in network byte order.
257 typedef u8 bier_bit_mask_bucket_t;
260 * 256 bits = 32 bytes
262 #define BIER_BIT_MASK_NUM_BUCKETS 32
263 #define BIER_BIT_MASK_MAX_BUCKET (BIER_BIT_MASK_NUM_BUCKETS - 1)
266 * number of bits in a bucket
268 #define BIER_BIT_MASK_BITS_PER_BUCKET 8
271 * Supported bit-posiotn range
273 #define BIER_BIT_MASK_MIN_POS (1)
276 * A Variable length BitString
278 typedef struct bier_bit_string_t_ {
280 * The length of the string in BYTES
285 * The buckets in the string
287 bier_bit_mask_bucket_t *bbs_buckets;
292 * as assigned to egress PEs
294 typedef u32 bier_bp_t;
296 #define BIER_BP_TO_INDEX(bp) (bp - 1)
299 * The maximum BP that can be assigned
301 #define BIER_BP_MAX 0x10000
304 * An identifier of the sender of BIER packets
305 * this is the source of the 'tree' - the BFIR
307 typedef u16 bier_hdr_src_id_t;
310 * An entropy value in a BIER header
312 typedef u32 bier_hdr_entropy_t;
314 #define BIER_BP_INVALID 0
317 * A BIER header of variable length
318 * The encoding follows:
319 * https://tools.ietf.org/html/draft-ietf-bier-mpls-encapsulation-10
321 typedef struct bier_hdr_t_ {
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
328 * The second nibble is the version - this is 0:
329 * type: bier_hdr_version_t
331 * The third nibble is header length ID
332 * type: bier_hdr_len_id_t
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
342 * The second word comprises:
343 * 2 bits of OAM for passive perf measurement
346 * 6 bits for the next-proto field of type;
347 * bier_hdr_proto_id_t
349 u16 bh_oam_dscp_proto;
352 * The BFR-ID of the sender
357 * The variable length bit-string
359 bier_bit_mask_bucket_t bh_bit_string[0];
363 * Format a BIER header
365 extern u8 *format_bier_hdr(u8 *s, va_list *ap);
368 * The BIER Set ID assigned to a BIER table
370 typedef u32 bier_table_set_id_t;
372 #define BIER_TABLE_SET_INVALID_ID 0xffffffff
375 * The BIER Sub-domain ID assigned to a BIER table
377 typedef u32 bier_table_sub_domain_id_t;
379 #define BIER_TABLE_SUB_DOMAIN_INVALID_ID 0xffffffff
382 * An ID or instance number of a BIER sub-table
384 typedef u32 bier_table_ecmp_id_t;
387 * Definition of the ID of the BIER main table
389 #define BIER_ECMP_TABLE_ID_MAIN 0xFFFF
394 typedef struct bier_table_id_t_ {
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
401 bier_table_set_id_t bti_set;
405 * The control plane has the configuration option to specify multiple
406 * domains or topologies.
408 bier_table_sub_domain_id_t bti_sub_domain;
412 * Constructed by FIB to achieve ECMP between BFR-NBRs
414 bier_table_ecmp_id_t bti_ecmp;
417 * The size of the bit string processed by this table.
419 bier_hdr_len_id_t bti_hdr_len;
422 * The type of the table; SPF or TE, MPLS or IPv6
424 bier_table_type_t bti_type;
428 * Format a BIER table ID
430 extern u8 *format_bier_table_id(u8 *s, va_list *ap);
433 * Compare to BIER table IDs for equality
435 extern int bier_table_id_cmp(const bier_table_id_t *btid1,
436 const bier_table_id_t *btid2);
439 * Conversion functions for the enumerated bit-string length
440 * values, to bit and bytes
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);
450 #define BIER_ERR_NO_TABLE 1
451 #define BIER_ERR_DUPLICATE_TABLE 2
452 #define BIER_ERR_PANIC 3
456 * The BIER universal 'label'
458 typedef u32 bier_bift_id_t;
461 * An invalid value for the BIFT ID
462 * all ones implies a BSL that's invalid.
464 #define BIER_BIFT_ID_INVALID (~0)
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);
471 * Encode a BIFT-ID as per draft-wijnandsxu-bier-non-mpls-bift-encoding-00.txt
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);
481 extern u8* format_bier_bift_id(u8 *s, va_list *ap);
483 #endif /* __BIER_TYPES_H__ */