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 <lb/util.h> 17 : 18 214 : void ip46_prefix_normalize(ip46_address_t *prefix, u8 plen) 19 : { 20 214 : if (plen == 0) { 21 0 : prefix->as_u64[0] = 0; 22 0 : prefix->as_u64[1] = 0; 23 214 : } else if (plen <= 64) { 24 87 : prefix->as_u64[0] &= clib_host_to_net_u64(0xffffffffffffffffL << (64 - plen)); 25 87 : prefix->as_u64[1] = 0; 26 : } else { 27 127 : prefix->as_u64[1] &= clib_host_to_net_u64(0xffffffffffffffffL << (128 - plen)); 28 : } 29 : 30 214 : } 31 : 32 160 : uword unformat_ip46_prefix (unformat_input_t * input, va_list * args) 33 : { 34 160 : ip46_address_t *ip46 = va_arg (*args, ip46_address_t *); 35 160 : u8 *len = va_arg (*args, u8 *); 36 160 : ip46_type_t type = va_arg (*args, ip46_type_t); 37 : 38 : u32 l; 39 160 : if ((type != IP46_TYPE_IP6) && unformat(input, "%U/%u", unformat_ip4_address, &ip46->ip4, &l)) { 40 96 : if (l > 32) 41 0 : return 0; 42 96 : *len = l + 96; 43 96 : ip46->pad[0] = ip46->pad[1] = ip46->pad[2] = 0; 44 64 : } else if ((type != IP46_TYPE_IP4) && unformat(input, "%U/%u", unformat_ip6_address, &ip46->ip6, &l)) { 45 64 : if (l > 128) 46 0 : return 0; 47 64 : *len = l; 48 : } else { 49 0 : return 0; 50 : } 51 160 : return 1; 52 : } 53 : 54 1391 : u8 *format_ip46_prefix (u8 * s, va_list * args) 55 : { 56 1391 : ip46_address_t *ip46 = va_arg (*args, ip46_address_t *); 57 1391 : u32 len = va_arg (*args, u32); //va_arg cannot use u8 or u16 58 1391 : ip46_type_t type = va_arg (*args, ip46_type_t); 59 : 60 1391 : int is_ip4 = 0; 61 1391 : if (type == IP46_TYPE_IP4) 62 0 : is_ip4 = 1; 63 1391 : else if (type == IP46_TYPE_IP6) 64 0 : is_ip4 = 0; 65 : else 66 1391 : is_ip4 = (len >= 96) && ip46_address_is_ip4(ip46); 67 : 68 : return is_ip4 ? 69 1906 : format(s, "%U/%d", format_ip4_address, &ip46->ip4, len - 96): 70 515 : format(s, "%U/%d", format_ip6_address, &ip46->ip6, len); 71 : } 72 :