ipip: Unintialized return variable (coverity warning)
[vpp.git] / src / vnet / ip / ip_types.c
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/ip/ip_types.h>
17 #include <vnet/ip/format.h>
18
19 u8 *
20 format_ip_address (u8 * s, va_list * args)
21 {
22   ip_address_t *a = va_arg (*args, ip_address_t *);
23   u8 ver = ip_addr_version (a);
24   if (ver == AF_IP4)
25     {
26       return format (s, "%U", format_ip4_address, &ip_addr_v4 (a));
27     }
28   else if (ver == AF_IP6)
29     {
30       return format (s, "%U", format_ip6_address, &ip_addr_v6 (a));
31     }
32   else
33     {
34       clib_warning ("Can't format IP version %d!", ver);
35       return 0;
36     }
37 }
38
39 uword
40 unformat_ip_address (unformat_input_t * input, va_list * args)
41 {
42   ip_address_t *a = va_arg (*args, ip_address_t *);
43
44   clib_memset (a, 0, sizeof (*a));
45   if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (a)))
46     ip_addr_version (a) = AF_IP4;
47   else if (unformat_user (input, unformat_ip6_address, &ip_addr_v6 (a)))
48     ip_addr_version (a) = AF_IP6;
49   else
50     return 0;
51   return 1;
52 }
53
54 u8 *
55 format_ip_prefix (u8 * s, va_list * args)
56 {
57   ip_prefix_t *a = va_arg (*args, ip_prefix_t *);
58   return format (s, "%U/%d", format_ip_address, &ip_prefix_addr (a),
59                  ip_prefix_len (a));
60 }
61
62 uword
63 unformat_ip_prefix (unformat_input_t * input, va_list * args)
64 {
65   ip_prefix_t *a = va_arg (*args, ip_prefix_t *);
66   if (unformat (input, "%U/%d", unformat_ip_address, &ip_prefix_addr (a),
67                 &ip_prefix_len (a)))
68     {
69       if ((ip_prefix_version (a) == AF_IP4 && 32 < ip_prefix_len (a)) ||
70           (ip_prefix_version (a) == AF_IP6 && 128 < ip_prefix_len (a)))
71         {
72           clib_warning ("Prefix length to big: %d!", ip_prefix_len (a));
73           return 0;
74         }
75       ip_prefix_normalize (a);
76     }
77   else
78     return 0;
79   return 1;
80 }
81
82 u16
83 ip_address_size (const ip_address_t * a)
84 {
85   switch (ip_addr_version (a))
86     {
87     case AF_IP4:
88       return sizeof (ip4_address_t);
89       break;
90     case AF_IP6:
91       return sizeof (ip6_address_t);
92       break;
93     }
94   return 0;
95 }
96
97 int
98 ip_address_cmp (const ip_address_t * ip1, const ip_address_t * ip2)
99 {
100   int res = 0;
101   if (ip_addr_version (ip1) != ip_addr_version (ip2))
102     return -1;
103   res =
104     memcmp (&ip_addr_addr (ip1), &ip_addr_addr (ip2), ip_address_size (ip1));
105
106   if (res < 0)
107     res = 2;
108   else if (res > 0)
109     res = 1;
110
111   return res;
112 }
113
114 void
115 ip_address_copy (ip_address_t * dst, const ip_address_t * src)
116 {
117   if (AF_IP4 == ip_addr_version (src))
118     {
119       /* don't copy any garbage from the union */
120       clib_memset (dst, 0, sizeof (*dst));
121       dst->ip.v4 = src->ip.v4;
122       dst->version = AF_IP4;
123     }
124   else
125     {
126       clib_memcpy (dst, src, sizeof (ip_address_t));
127     }
128 }
129
130 void
131 ip_address_copy_addr (void *dst, const ip_address_t * src)
132 {
133   clib_memcpy (dst, src, ip_address_size (src));
134 }
135
136 u16
137 ip_version_to_size (u8 ver)
138 {
139   switch (ver)
140     {
141     case AF_IP4:
142       return sizeof (ip4_address_t);
143       break;
144     case AF_IP6:
145       return sizeof (ip6_address_t);
146       break;
147     }
148   return 0;
149 }
150
151 void
152 ip_address_set (ip_address_t * dst, const void *src, u8 version)
153 {
154   clib_memcpy (dst, src, ip_version_to_size (version));
155   ip_addr_version (dst) = version;
156 }
157
158 void
159 ip_address_to_46 (const ip_address_t * addr,
160                   ip46_address_t * a, fib_protocol_t * proto)
161 {
162   *proto = (AF_IP4 == ip_addr_version (addr) ?
163             FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6);
164   switch (*proto)
165     {
166     case FIB_PROTOCOL_IP4:
167       ip46_address_set_ip4 (a, &addr->ip.v4);
168       break;
169     case FIB_PROTOCOL_IP6:
170       a->ip6 = addr->ip.v6;
171       break;
172     default:
173       ASSERT (0);
174       break;
175     }
176 }
177
178 static void
179 ip_prefix_normalize_ip4 (ip4_address_t * ip4, u8 preflen)
180 {
181   u32 mask = ~0;
182
183   ASSERT (ip4);
184
185   if (32 <= preflen)
186     {
187       return;
188     }
189
190   mask = pow2_mask (preflen) << (32 - preflen);
191   mask = clib_host_to_net_u32 (mask);
192   ip4->data_u32 &= mask;
193 }
194
195 static void
196 ip_prefix_normalize_ip6 (ip6_address_t * ip6, u8 preflen)
197 {
198   u8 mask_6[16];
199   u32 *m;
200   u8 j, i0, i1;
201
202   ASSERT (ip6);
203
204   clib_memset (mask_6, 0, sizeof (mask_6));
205
206   if (128 <= preflen)
207     {
208       return;
209     }
210
211   i1 = preflen % 32;
212   i0 = preflen / 32;
213   m = (u32 *) & mask_6[0];
214
215   for (j = 0; j < i0; j++)
216     {
217       m[j] = ~0;
218     }
219
220   if (i1)
221     {
222       m[i0] = clib_host_to_net_u32 (pow2_mask (i1) << (32 - i1));
223     }
224
225   for (j = 0; j < sizeof (mask_6); j++)
226     {
227       ip6->as_u8[j] &= mask_6[j];
228     }
229 }
230
231 void
232 ip_prefix_normalize (ip_prefix_t * a)
233 {
234   u8 preflen = ip_prefix_len (a);
235
236   switch (ip_prefix_version (a))
237     {
238     case AF_IP4:
239       ip_prefix_normalize_ip4 (&ip_prefix_v4 (a), preflen);
240       break;
241
242     case AF_IP6:
243       ip_prefix_normalize_ip6 (&ip_prefix_v6 (a), preflen);
244       break;
245
246     default:
247       ASSERT (0);
248     }
249 }
250
251 void
252 ip_prefix_copy (void *dst, void *src)
253 {
254   clib_memcpy (dst, src, sizeof (ip_prefix_t));
255 }
256
257 int
258 ip_prefix_cmp (ip_prefix_t * p1, ip_prefix_t * p2)
259 {
260   int cmp = 0;
261
262   ip_prefix_normalize (p1);
263   ip_prefix_normalize (p2);
264
265   cmp = ip_address_cmp (&ip_prefix_addr (p1), &ip_prefix_addr (p2));
266   if (cmp == 0)
267     {
268       if (ip_prefix_len (p1) < ip_prefix_len (p2))
269         {
270           cmp = 1;
271         }
272       else
273         {
274           if (ip_prefix_len (p1) > ip_prefix_len (p2))
275             cmp = 2;
276         }
277     }
278   return cmp;
279 }
280
281 /*
282  * fd.io coding-style-patch-verification: ON
283  *
284  * Local Variables:
285  * eval: (c-set-style "gnu")
286  * End:
287  */