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 : #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 : 33 : static inline int 34 68076 : bier_bit_pos_is_valid (bier_bp_t bp, const bier_bit_string_t *bbs) 35 : { 36 68076 : if (!((bp <= BIER_BBS_LEN_TO_BITS((bbs)->bbs_len)) && 37 : (bp >= 1))) { 38 0 : return (0); 39 : } 40 68076 : return (1); 41 : } 42 : 43 : /* 44 : * Validate a bit position 45 : */ 46 : #define BIER_BIT_POS_IS_VALID(_bp, _str) \ 47 : { \ 48 : if (!bier_bit_pos_is_valid(_bp, _str)) return; \ 49 : } 50 : 51 : void 52 80 : bier_bit_string_set_bit (bier_bit_string_t *bit_string, 53 : bier_bp_t bp) 54 : { 55 : bier_bit_mask_bucket_t bmask; 56 : u16 byte_pos, bit_pos; 57 : 58 80 : BIER_BIT_POS_IS_VALID(bp, bit_string); 59 80 : BIER_GET_STRING_POS(bp, byte_pos, bit_pos, bit_string); 60 : 61 80 : bmask = ((bier_bit_mask_bucket_t)1 << bit_pos); 62 80 : bit_string->bbs_buckets[byte_pos] |= bmask; 63 : } 64 : 65 : void 66 67996 : bier_bit_string_clear_bit (bier_bit_string_t *bit_string, 67 : bier_bp_t bp) 68 : { 69 : u16 byte_pos, bit_pos; 70 : 71 67996 : BIER_BIT_POS_IS_VALID(bp, bit_string); 72 67996 : BIER_GET_STRING_POS(bp, byte_pos, bit_pos, bit_string); 73 : 74 67996 : bit_string->bbs_buckets[byte_pos] &= ~(1 << bit_pos); 75 : } 76 : 77 : u8 * 78 171 : format_bier_bit_string (u8 * string, 79 : va_list * args) 80 : { 81 171 : bier_bit_string_t *bs = va_arg(*args, bier_bit_string_t *); 82 171 : int leading_marker = 0; 83 171 : int suppress_zero = 0; 84 : u16 index; 85 : u32 *ptr; 86 : 87 171 : ptr = (u32 *)bs->bbs_buckets; 88 : 89 171 : string = format(string, "%d#", (8 * bs->bbs_len)); 90 : 91 537 : for (index = 0; index < (bs->bbs_len/4); index++) { 92 366 : if (!ptr[index]) { 93 167 : if (!leading_marker) { 94 167 : leading_marker = 1; 95 167 : suppress_zero = 1; 96 167 : string = format(string, ":"); 97 167 : continue; 98 : } 99 0 : if (suppress_zero) continue; 100 : } else { 101 199 : suppress_zero = 0; 102 : } 103 : 104 199 : string = format(string, "%s%X", index ? ":" : "", 105 199 : clib_net_to_host_u32(ptr[index])); 106 : } 107 : 108 171 : return (string); 109 : }