FD.io VPP  v20.01-48-g3e0dafb74
Vector Packet Processing
ip_types.c
Go to the documentation of this file.
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  }
76  }
77  else
78  return 0;
79  return 1;
80 }
81 
82 u16
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
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
132 {
133  clib_memcpy (dst, src, ip_address_size (src));
134 }
135 
136 u16
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
153 {
154  clib_memcpy (dst, src, ip_version_to_size (version));
155  ip_addr_version (dst) = version;
156 }
157 
158 void
160  ip46_address_t * a, fib_protocol_t * proto)
161 {
162  *proto = (AF_IP4 == ip_addr_version (addr) ?
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
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
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
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
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  */
#define ip_addr_v6(_a)
Definition: ip_types.h:51
u8 proto
Definition: acl_types.api:47
a
Definition: bitmap.h:538
#define ip_prefix_addr(_a)
Definition: ip_types.h:74
void ip_address_set(ip_address_t *dst, const void *src, u8 version)
Definition: ip_types.c:152
u8 as_u8[16]
Definition: ip6_packet.h:48
option version
Definition: sample.api:19
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
u16 ip_version_to_size(u8 ver)
Definition: ip_types.c:137
vl_api_address_t src
Definition: gre.api:60
u16 ip_address_size(const ip_address_t *a)
Definition: ip_types.c:83
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:989
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
#define ip_prefix_v6(_a)
Definition: ip_types.h:78
#define ip_prefix_v4(_a)
Definition: ip_types.h:77
#define ip_addr_version(_a)
Definition: ip_types.h:52
vhost_vring_addr_t addr
Definition: vhost_user.h:147
unsigned char u8
Definition: types.h:56
enum fib_protocol_t_ fib_protocol_t
Protocol Type.
#define clib_memcpy(d, s, n)
Definition: string.h:180
format_function_t format_ip4_address
Definition: format.h:73
unformat_function_t unformat_ip4_address
Definition: format.h:68
void ip_prefix_copy(void *dst, void *src)
Definition: ip_types.c:252
static uword pow2_mask(uword x)
Definition: clib.h:220
void ip_prefix_normalize(ip_prefix_t *a)
Definition: ip_types.c:232
unsigned int u32
Definition: types.h:88
void ip_address_copy_addr(void *dst, const ip_address_t *src)
Definition: ip_types.c:131
void ip_address_to_46(const ip_address_t *addr, ip46_address_t *a, fib_protocol_t *proto)
Definition: ip_types.c:159
struct _unformat_input_t unformat_input_t
unsigned short u16
Definition: types.h:57
uword unformat_ip_address(unformat_input_t *input, va_list *args)
Definition: ip_types.c:40
vl_api_address_t dst
Definition: gre.api:61
unformat_function_t unformat_ip6_address
Definition: format.h:89
u8 ip6[16]
Definition: one.api:477
u8 * format_ip_prefix(u8 *s, va_list *args)
Definition: ip_types.c:55
format_function_t format_ip6_address
Definition: format.h:91
#define clib_warning(format, args...)
Definition: error.h:59
u8 * format_ip_address(u8 *s, va_list *args)
Definition: ip_types.c:20
ip6_address_t v6
Definition: ip_types.h:43
#define ASSERT(truth)
#define ip_addr_v4(_a)
Definition: ip_types.h:50
#define ip_addr_addr(_a)
Definition: ip_types.h:49
ip_address_family_t version
Definition: ip_types.h:45
int ip_address_cmp(const ip_address_t *ip1, const ip_address_t *ip2)
Definition: ip_types.c:98
ip4_address_t v4
Definition: ip_types.h:42
u64 uword
Definition: types.h:112
#define ip_prefix_len(_a)
Definition: ip_types.h:76
union ip_address::@304 ip
#define ip_prefix_version(_a)
Definition: ip_types.h:75
void ip_address_copy(ip_address_t *dst, const ip_address_t *src)
Definition: ip_types.c:115
static void ip_prefix_normalize_ip4(ip4_address_t *ip4, u8 preflen)
Definition: ip_types.c:179
uword unformat_ip_prefix(unformat_input_t *input, va_list *args)
Definition: ip_types.c:63
u32 ip4
Definition: one.api:440
static void ip_prefix_normalize_ip6(ip6_address_t *ip6, u8 preflen)
Definition: ip_types.c:196
static void ip46_address_set_ip4(ip46_address_t *ip46, const ip4_address_t *ip)
Definition: ip46_address.h:67
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
int ip_prefix_cmp(ip_prefix_t *p1, ip_prefix_t *p2)
Definition: ip_types.c:258