blob: 24546fa94c248ede0dbf293587cb5ad8acf8d21f [file] [log] [blame]
Neale Rannsd792d9c2017-10-21 10:53:20 -07001/*
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#include <vnet/vnet.h>
17
18#include <vnet/bier/bier_types.h>
19#include <vnet/bier/bier_bit_string.h>
20
21/*
22 * the first bit in the first byte is bit position 1.
23 * bit position 0 is not valid
24 */
25#define BIER_GET_STRING_POS(_bp, _byte, _bit, _str) \
26{ \
27 _bp--; \
28 _byte = ((BIER_BBS_LEN_TO_BUCKETS((_str)->bbs_len) - 1 ) - \
29 (_bp / BIER_BIT_MASK_BITS_PER_BUCKET)); \
30 _bit = _bp % BIER_BIT_MASK_BITS_PER_BUCKET; \
31}
32
33static inline int
34bier_bit_pos_is_valid (bier_bp_t bp, const bier_bit_string_t *bbs)
35{
36 if (!((bp <= BIER_BBS_LEN_TO_BITS((bbs)->bbs_len)) &&
37 (bp >= 1))) {
38 return (0);
39 }
40 return (1);
41}
42
43/*
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -070044 * Validate a bit position
Neale Rannsd792d9c2017-10-21 10:53:20 -070045 */
46#define BIER_BIT_POS_IS_VALID(_bp, _str) \
47{ \
48 if (!bier_bit_pos_is_valid(_bp, _str)) return; \
49}
50
51void
52bier_bit_string_set_bit (bier_bit_string_t *bit_string,
53 bier_bp_t bp)
54{
55 bier_bit_mask_bucket_t bmask;
Neale Rannsa2a7db82017-11-10 02:34:04 -080056 u16 byte_pos, bit_pos;
Neale Rannsd792d9c2017-10-21 10:53:20 -070057
58 BIER_BIT_POS_IS_VALID(bp, bit_string);
59 BIER_GET_STRING_POS(bp, byte_pos, bit_pos, bit_string);
60
61 bmask = ((bier_bit_mask_bucket_t)1 << bit_pos);
62 bit_string->bbs_buckets[byte_pos] |= bmask;
63}
64
65void
66bier_bit_string_clear_bit (bier_bit_string_t *bit_string,
67 bier_bp_t bp)
68{
Neale Rannsa2a7db82017-11-10 02:34:04 -080069 u16 byte_pos, bit_pos;
Neale Rannsd792d9c2017-10-21 10:53:20 -070070
71 BIER_BIT_POS_IS_VALID(bp, bit_string);
72 BIER_GET_STRING_POS(bp, byte_pos, bit_pos, bit_string);
73
74 bit_string->bbs_buckets[byte_pos] &= ~(1 << bit_pos);
75}
76
77u8 *
78format_bier_bit_string (u8 * string,
79 va_list * args)
80{
81 bier_bit_string_t *bs = va_arg(*args, bier_bit_string_t *);
82 int leading_marker = 0;
83 int suppress_zero = 0;
84 u16 index;
85 u32 *ptr;
86
87 ptr = (u32 *)bs->bbs_buckets;
88
89 string = format(string, "%d#", (8 * bs->bbs_len));
90
91 for (index = 0; index < (bs->bbs_len/4); index++) {
92 if (!ptr[index]) {
93 if (!leading_marker) {
94 leading_marker = 1;
95 suppress_zero = 1;
96 string = format(string, ":");
97 continue;
98 }
99 if (suppress_zero) continue;
100 } else {
101 suppress_zero = 0;
102 }
103
104 string = format(string, "%s%X", index ? ":" : "",
105 clib_net_to_host_u32(ptr[index]));
106 }
107
108 return (string);
109}