Line data Source code
1 : /* 2 : * Copyright (c) 2015-2019 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 : #ifndef included_ip46_address_h 17 : #define included_ip46_address_h 18 : 19 : #include <vnet/ip/ip6_packet.h> 20 : #include <vnet/ip/ip4_packet.h> 21 : 22 : typedef enum 23 : { 24 : IP46_TYPE_ANY, 25 : IP46_TYPE_BOTH = IP46_TYPE_ANY, 26 : IP46_TYPE_IP4, 27 : IP46_TYPE_IP6 28 : } ip46_type_t; 29 : 30 : #define IP46_N_TYPES (IP46_TYPE_IP6+2) 31 : 32 : #define FOREACH_IP46_TYPE(_type) \ 33 : for (_type = IP46_TYPE_IP4; _type <= IP46_TYPE_IP6; _type++) 34 : 35 : extern u8 *format_ip46_type (u8 * s, va_list * args); 36 : 37 : /* *INDENT-OFF* */ 38 : typedef CLIB_PACKED (union ip46_address_t_ { 39 : struct { 40 : u32 pad[3]; 41 : ip4_address_t ip4; 42 : }; 43 : ip6_address_t ip6; 44 : u8 as_u8[16]; 45 : u64 as_u64[2]; 46 : }) ip46_address_t; 47 : /* *INDENT-ON* */ 48 : 49 : 50 : format_function_t format_ip46_address; 51 : 52 : #define ip46_address_initializer {{{ 0 }}} 53 : 54 : always_inline u8 55 256904 : ip46_address_is_ip4 (const ip46_address_t * ip46) 56 : { 57 256904 : return (((ip46)->pad[0] | (ip46)->pad[1] | (ip46)->pad[2]) == 0); 58 : } 59 : 60 : always_inline void 61 28398882 : ip46_address_mask_ip4 (ip46_address_t * ip46) 62 : { 63 28398882 : ((ip46)->pad[0] = (ip46)->pad[1] = (ip46)->pad[2] = 0); 64 28398882 : } 65 : 66 : always_inline void 67 28398143 : ip46_address_set_ip4 (ip46_address_t * ip46, const ip4_address_t * ip) 68 : { 69 28398143 : ip46_address_mask_ip4 (ip46); 70 28398143 : ip46->ip4 = *ip; 71 28398143 : } 72 : 73 : always_inline void 74 1171 : ip46_address_reset (ip46_address_t * ip46) 75 : { 76 1171 : ip46->as_u64[0] = ip46->as_u64[1] = 0; 77 1171 : } 78 : 79 : always_inline int 80 214404 : ip46_address_cmp (const ip46_address_t * ip46_1, 81 : const ip46_address_t * ip46_2) 82 : { 83 214404 : return (memcmp (ip46_1, ip46_2, sizeof (*ip46_1))); 84 : } 85 : 86 : always_inline u8 87 337081 : ip46_address_is_zero (const ip46_address_t * ip46) 88 : { 89 337081 : return (ip46->as_u64[0] == 0 && ip46->as_u64[1] == 0); 90 : } 91 : 92 : always_inline u8 93 10987 : ip46_address_is_equal (const ip46_address_t * ip46_1, 94 : const ip46_address_t * ip46_2) 95 : { 96 11765 : return ((ip46_1->as_u64[0] == ip46_2->as_u64[0]) && 97 778 : (ip46_1->as_u64[1] == ip46_2->as_u64[1])); 98 : } 99 : 100 : static_always_inline int 101 0 : ip4_address_is_equal (const ip4_address_t * ip4_1, 102 : const ip4_address_t * ip4_2) 103 : { 104 0 : return (ip4_1->as_u32 == ip4_2->as_u32); 105 : } 106 : 107 : static_always_inline int 108 1351 : ip46_address_is_equal_v4 (const ip46_address_t * ip46, 109 : const ip4_address_t * ip4) 110 : { 111 1351 : return (ip46->ip4.as_u32 == ip4->as_u32); 112 : } 113 : 114 : static_always_inline int 115 571 : ip46_address_is_equal_v6 (const ip46_address_t * ip46, 116 : const ip6_address_t * ip6) 117 : { 118 1079 : return ((ip46->ip6.as_u64[0] == ip6->as_u64[0]) && 119 508 : (ip46->ip6.as_u64[1] == ip6->as_u64[1])); 120 : } 121 : 122 : static_always_inline void 123 192574 : ip46_address_copy (ip46_address_t * dst, const ip46_address_t * src) 124 : { 125 192574 : dst->as_u64[0] = src->as_u64[0]; 126 192574 : dst->as_u64[1] = src->as_u64[1]; 127 192574 : } 128 : 129 : static_always_inline void 130 20957425 : ip46_address_set_ip6 (ip46_address_t * dst, const ip6_address_t * src) 131 : { 132 20957425 : dst->as_u64[0] = src->as_u64[0]; 133 20957425 : dst->as_u64[1] = src->as_u64[1]; 134 20957425 : } 135 : 136 : always_inline ip46_address_t 137 9674 : to_ip46 (u32 is_ipv6, u8 * buf) 138 : { 139 : ip46_address_t ip; 140 9674 : if (is_ipv6) 141 4030 : ip.ip6 = *((ip6_address_t *) buf); 142 : else 143 5644 : ip46_address_set_ip4 (&ip, (ip4_address_t *) buf); 144 9674 : return ip; 145 : } 146 : 147 : always_inline ip46_type_t 148 : ip46_address_get_type (const ip46_address_t * ip) 149 : { 150 : return (ip46_address_is_ip4 (ip) ? IP46_TYPE_IP4 : IP46_TYPE_IP6); 151 : } 152 : 153 : always_inline uword 154 25505 : ip46_address_is_multicast (const ip46_address_t * a) 155 : { 156 26753 : return ip46_address_is_ip4 (a) ? ip4_address_is_multicast (&a->ip4) : 157 1248 : ip6_address_is_multicast (&a->ip6); 158 : } 159 : 160 : extern void ip4_address_increment (ip4_address_t * i); 161 : extern void ip6_address_increment (ip6_address_t * i); 162 : extern void ip46_address_increment (ip46_type_t type, ip46_address_t * ip); 163 : 164 : #endif /* included_ip46_address_h */ 165 : 166 : /* 167 : * fd.io coding-style-patch-verification: ON 168 : * 169 : * Local Variables: 170 : * eval: (c-set-style "gnu") 171 : * End: 172 : */