Add support for LCAF Instance ID
[vpp.git] / vnet / test / lisp-cp / test_lisp_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/vnet.h>
17 #include <vppinfra/error.h>
18 #include <vnet/lisp-cp/lisp_types.h>
19 #include <vnet/lisp-cp/lisp_cp_messages.h>
20
21 #define _assert(e)                    \
22   error = CLIB_ERROR_ASSERT (e);      \
23   if (error)                          \
24     goto done;
25
26 static clib_error_t * test_locator_type (void)
27 {
28   clib_error_t * error = 0;
29   gid_address_t _gid_addr, * gid = &_gid_addr;
30   ip_prefix_t * ippref;
31   gid_address_type (gid) = GID_ADDR_IP_PREFIX;
32   gid_address_ippref_len (gid) = 24;
33   ippref = &gid_address_ippref (gid);
34   ip_prefix_version (ippref) = IP4;
35   ip_prefix_len (ippref) = 0;
36   ip4_address_t * ip4 = &ip_prefix_v4 (ippref);
37   ip4->as_u32 = 0x20304050;
38
39   /* local locator */
40   locator_t loc1, loc2 = {
41     .local = 1,
42     .state = 2,
43     .sw_if_index = 8,
44     .priority = 3,
45     .weight = 100,
46     .mpriority = 4,
47     .mweight = 101
48   };
49   locator_copy (&loc1, &loc2);
50   _assert (0 == locator_cmp (&loc1, &loc2));
51
52   /* remote locator */
53   loc2.local = 0;
54
55   ip_prefix_t nested_ippref;
56   ip_prefix_version (&nested_ippref) = IP4;
57   ip_prefix_len (&nested_ippref) = 0;
58   ip4 = &ip_prefix_v4 (&nested_ippref);
59   ip4->as_u32 = 0x33882299;
60   gid_address_t nested_gid =
61     {
62       .type = GID_ADDR_IP_PREFIX,
63       .ippref = nested_ippref
64     };
65
66   lcaf_t lcaf =
67     {
68       .type = LCAF_INSTANCE_ID,
69       .uni =
70         {
71           .vni_mask_len = 5,
72           .vni = 0xa1b2c3d4,
73           .gid_addr = &nested_gid
74         }
75     };
76   gid_address_type (gid) = GID_ADDR_LCAF;
77   gid_address_lcaf (gid) = lcaf;
78
79   loc2.address = gid[0];
80   locator_copy(&loc1, &loc2);
81
82   _assert (0 == locator_cmp (&loc1, &loc2));
83
84 done:
85   locator_free (&loc1);
86   return error;
87 }
88
89 static clib_error_t * test_gid_parse_ip_pref ()
90 {
91   clib_error_t * error = 0;
92   gid_address_t _gid_addr, * gid_addr = &_gid_addr;
93   gid_address_t _gid_addr_copy, * gid_addr_copy = &_gid_addr_copy;
94   u8 data[] =
95     {
96       0x00, 0x01,             /* AFI = IPv4 */
97       0x10, 0xbb, 0xcc, 0xdd, /* ipv4 address */
98     };
99
100   u32 len = gid_address_parse (data, gid_addr);
101   _assert (6 == len);
102   gid_address_copy (gid_addr_copy, gid_addr);
103   _assert (0 == gid_address_cmp (gid_addr_copy, gid_addr));
104 done:
105   return error;
106 }
107
108 static clib_error_t * test_gid_parse_lcaf ()
109 {
110   clib_error_t * error = 0;
111   gid_address_t _gid_addr, * gid_addr = &_gid_addr;
112   gid_address_t _gid_addr_copy, * gid_addr_copy = &_gid_addr_copy;
113
114   memset (gid_addr, 0, sizeof (gid_addr[0]));
115   memset (gid_addr_copy, 0, sizeof (gid_addr_copy[0]));
116
117   u8 data[] =
118     {
119       0x40, 0x03,             /* AFI = LCAF*/
120
121       /* LCAF header*/
122       0x00, 0x00,             /* reserved1, flags */
123       0x02,                   /* type = Instance ID */
124       0x18,                   /* IID mask-len */
125       0x00, 0x0a,             /* iid length + next AFI lenght */
126       /* LCAF Instance ID */
127       0x00, 0x00, 0x00, 0x09, /* iid */
128       0x00, 0x01,             /* AFI = ipv4 */
129       0x10, 0xbb, 0xcc, 0xdd, /* ipv4 address */
130     };
131   u32 len = gid_address_parse (data, gid_addr);
132   _assert (18 == len);
133   gid_address_copy (gid_addr_copy, gid_addr);
134   _assert (0 == gid_address_cmp (gid_addr_copy, gid_addr));
135
136   lcaf_t * lcaf = &gid_address_lcaf (gid_addr_copy);
137   vni_t * vni = (vni_t *) lcaf;
138   _assert (lcaf->type == LCAF_INSTANCE_ID);
139   _assert (vni->vni == 9);
140   _assert (vni->vni_mask_len == 0x18);
141
142   gid_address_t * g = vni_gid (vni);
143   _assert (gid_address_type (g) == GID_ADDR_IP_PREFIX);
144 done:
145   gid_address_free (gid_addr);
146   gid_address_free (gid_addr_copy);
147   return error;
148 }
149
150 static clib_error_t * test_gid_parse_lcaf_complex ()
151 {
152   clib_error_t * error = 0;
153   gid_address_t _gid_addr, * gid_addr = &_gid_addr;
154   gid_address_t _gid_addr_copy, * gid_addr_copy = &_gid_addr_copy;
155
156   memset (gid_addr, 0, sizeof (gid_addr[0]));
157   memset (gid_addr_copy, 0, sizeof (gid_addr_copy[0]));
158
159   u8 data[] =
160     {
161       0x40, 0x03,             /* AFI = LCAF*/
162
163       /* LCAF header*/
164       0x00, 0x00,             /* reserved1, flags */
165       0x02,                   /* type = Instance ID */
166       0x18,                   /* IID mask-len */
167       0x00, 0x0a,             /* iid length + next AFI lenght */
168       /* LCAF Instance ID */
169       0x00, 0x00, 0x00, 0x0b, /* iid */
170
171       0x40, 0x03,             /* AFI = LCAF*/
172       /* LCAF header*/
173       0x00, 0x00,             /* reserved1, flags */
174       0x02,                   /* type = Instance ID */
175       0x17,                   /* IID mask-len */
176       0x00, 0x0a,             /* iid length + next AFI lenght */
177       /* LCAF Instance ID */
178       0x00, 0x00, 0x00, 0x0c, /* iid */
179
180       0x40, 0x03,             /* AFI = LCAF*/
181       /* LCAF header*/
182       0x00, 0x00,             /* reserved1, flags */
183       0x02,                   /* type = Instance ID */
184       0x16,                   /* IID mask-len */
185       0x00, 0x16,             /* iid length + next AFI lenght */
186       /* LCAF Instance ID */
187       0x00, 0x00, 0x00, 0x0d, /* iid */
188
189       0x00, 0x02,             /* AFI = IPv6 */
190
191       0x10, 0xbb, 0xcc, 0xdd,
192       0x10, 0xbb, 0xcc, 0xdd,
193       0x10, 0xbb, 0xcc, 0xdd,
194       0x10, 0xbb, 0xcc, 0xdd, /* ipv6 address */
195     };
196   u32 len = gid_address_parse (data, gid_addr);
197   _assert (54 == len);
198   _assert (gid_addr->type == GID_ADDR_LCAF);
199   gid_address_copy (gid_addr_copy, gid_addr);
200   _assert (0 == gid_address_cmp (gid_addr_copy, gid_addr));
201   _assert (gid_addr_copy->type == GID_ADDR_LCAF);
202
203   lcaf_t * lcaf = &gid_address_lcaf (gid_addr_copy);
204   _assert (lcaf->type == LCAF_INSTANCE_ID);
205   vni_t * v = (vni_t *) lcaf;
206   _assert (v->vni == 0x0b);
207   _assert (v->vni_mask_len == 0x18);
208
209   gid_address_t * tmp = vni_gid (v);
210   _assert (gid_address_type (tmp) == GID_ADDR_LCAF);
211   lcaf = &gid_address_lcaf (tmp);
212   _assert (lcaf->type == LCAF_INSTANCE_ID);
213
214   v = (vni_t *) lcaf;
215   _assert (v->vni == 0x0c);
216   _assert (v->vni_mask_len == 0x17);
217
218   tmp = vni_gid (v);
219   _assert (gid_address_type (tmp) == GID_ADDR_LCAF);
220   lcaf = &gid_address_lcaf (tmp);
221
222   _assert (lcaf->type == LCAF_INSTANCE_ID);
223   v = (vni_t *) lcaf;
224   _assert (v->vni == 0x0d);
225   _assert (v->vni_mask_len == 0x16);
226
227   tmp = vni_gid (v);
228   _assert (gid_address_type (tmp) == GID_ADDR_IP_PREFIX);
229
230   ip_prefix_t * ip_pref = &gid_address_ippref (tmp);
231   ip6_address_t * ip6 = &ip_prefix_v6 (ip_pref);
232   _assert (ip6->as_u32[0] == 0xddccbb10);
233   _assert (ip6->as_u32[1] == 0xddccbb10);
234   _assert (ip6->as_u32[2] == 0xddccbb10);
235   _assert (ip6->as_u32[3] == 0xddccbb10);
236   _assert (ip_prefix_version (ip_pref) == IP6);
237
238 done:
239   gid_address_free (gid_addr);
240   gid_address_free (gid_addr_copy);
241   return error;
242 }
243
244 static clib_error_t * test_format_unformat_gid_address (void)
245 {
246   u8 * s = 0;
247   clib_error_t * error = 0;
248   unformat_input_t _input;
249   unformat_input_t * input = &_input;
250   gid_address_t _gid_addr, * gid_addr = &_gid_addr;
251   gid_address_t unformated_gid;
252
253   /* format/unformat IPv4 global ID address */
254   gid_address_type(gid_addr) = GID_ADDR_IP_PREFIX;
255   gid_address_ippref_len(gid_addr) = 24;
256   ip_prefix_version(&gid_addr->ippref) = IP4;
257   gid_addr->ippref.addr.ip.v4.as_u32 = 0x20304050;
258
259   s = format(0, "%U", format_gid_address, gid_addr);
260   vec_add1(s, 0);
261   unformat_init_string(input, (char *)s, vec_len(s));
262
263   _assert (unformat(input, "%U",
264         unformat_gid_address, &unformated_gid));
265   _assert (0 == gid_address_cmp (&unformated_gid, gid_addr));
266
267   unformat_free(input);
268   vec_free(s);
269   s = 0;
270
271   /* format/unformat IPv6 global ID address */
272   gid_address_type(gid_addr) = GID_ADDR_IP_PREFIX;
273   gid_address_ippref_len(gid_addr) = 64;
274   ip_prefix_version(&gid_addr->ippref) = IP6;
275   u8 ipv6[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf};
276   clib_memcpy(gid_addr->ippref.addr.ip.v6.as_u8, ipv6, sizeof(ipv6));
277
278   s = format(0, "%U", format_gid_address, gid_addr);
279   vec_add1(s, 0);
280   unformat_init_string(input, (char *)s, vec_len(s));
281
282   _assert (unformat (input, "%U", unformat_gid_address,
283         &unformated_gid));
284   _assert (0 == gid_address_cmp(&unformated_gid, gid_addr));
285
286   /* test address copy */
287   gid_address_t gid_addr_copy;
288   gid_address_copy(&gid_addr_copy, gid_addr);
289   _assert (0 == gid_address_cmp (&gid_addr_copy, gid_addr));
290
291 done:
292   unformat_free(input);
293   vec_free(s);
294   return error;
295 }
296
297 static clib_error_t * test_gid_address_write (void)
298 {
299   clib_error_t * error = 0;
300   ip_prefix_t ippref_data, * ippref = &ippref_data;
301
302   u8 * b = clib_mem_alloc(500);
303   memset(b, 0, 500);
304
305   ip_prefix_version (ippref) = IP4;
306   ip4_address_t * ip4 = &ip_prefix_v4 (ippref);
307   ip4->as_u32 = 0xaabbccdd;
308
309   gid_address_t nested_gid =
310     {
311       .ippref = ippref[0],
312       .type = GID_ADDR_IP_PREFIX,
313     };
314
315   lcaf_t lcaf =
316     {
317       .type = LCAF_INSTANCE_ID,
318       .uni =
319         {
320           .vni_mask_len = 0x18,
321           .vni = 0x01020304,
322           .gid_addr = &nested_gid
323         }
324     };
325
326   gid_address_t gid =
327     {
328       .type = GID_ADDR_LCAF,
329       .lcaf = lcaf
330     };
331   _assert (18 == gid_address_size_to_put (&gid));
332
333   u16 write_len = gid_address_put (b, &gid);
334   _assert (18 == write_len);
335
336   u8 expected_gid_data[] =
337     {
338       0x40, 0x03,             /* AFI = LCAF */
339       0x00,                   /* reserved1 */
340       0x00,                   /* flags */
341       0x02,                   /* LCAF type = Instance ID */
342       0x18,                   /* IID/VNI mask len */
343       0x00, 0x0a,             /* length */
344       0x01, 0x02, 0x03, 0x04, /* Instance ID / VNI */
345
346       0x00, 0x01,             /* AFI = IPv4 */
347       0xdd, 0xcc, 0xbb, 0xaa, /* ipv4 addr */
348     };
349   _assert (0 == memcmp (expected_gid_data, b, sizeof (expected_gid_data)));
350 done:
351   clib_mem_free (b);
352   return error;
353 }
354
355 #define foreach_test_case                 \
356   _(format_unformat_gid_address)          \
357   _(locator_type)                         \
358   _(gid_parse_ip_pref)                    \
359   _(gid_parse_lcaf)                       \
360   _(gid_parse_lcaf_complex)               \
361   _(gid_address_write)
362
363 int run_tests (void)
364 {
365   clib_error_t * error;
366
367 #define _(_test_name)                   \
368   error = test_ ## _test_name ();       \
369   if (error)                            \
370     {                                   \
371       clib_error_report (error);        \
372       return 0;                         \
373     }
374
375   foreach_test_case
376 #undef _
377
378   return 0;
379 }
380
381 int main()
382 {
383   return run_tests ();
384 }
385