Line data Source code
1 : /*
2 : * Copyright (c) 2015 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 <vat/vat.h>
17 : #include <vlibapi/api.h>
18 : #include <vlibmemory/api.h>
19 : #include <vppinfra/error.h>
20 :
21 : #include <vnet/ip/ip_format_fns.h>
22 : #include <vnet/ethernet/ethernet_format_fns.h>
23 : #include <vnet/ethernet/mac_address.h>
24 : #include <lisp/lisp-cp/lisp_types.h>
25 :
26 : /* define message IDs */
27 : #include <lisp/lisp-gpe/lisp_gpe.api_enum.h>
28 : #include <lisp/lisp-gpe/lisp_gpe.api_types.h>
29 : #include <vlibmemory/vlib.api_types.h>
30 :
31 : typedef struct
32 : {
33 : /* API message ID base */
34 : u16 msg_id_base;
35 : vat_main_t *vat_main;
36 : u32 ping_id;
37 : } lisp_gpe_test_main_t;
38 :
39 : lisp_gpe_test_main_t lisp_gpe_test_main;
40 :
41 : #define __plugin_msg_base lisp_gpe_test_main.msg_id_base
42 : #include <vlibapi/vat_helper_macros.h>
43 :
44 : #define FINISH \
45 : vec_add1 (s, 0); \
46 : vlib_cli_output (handle, (char *) s); \
47 : vec_free (s); \
48 : return handle;
49 :
50 : #define LISP_PING(_lm, mp_ping) \
51 : if (!(_lm)->ping_id) \
52 : (_lm)->ping_id = vl_msg_api_get_msg_index ((u8 *) (VL_API_CONTROL_PING_CRC)); \
53 : mp_ping = vl_msg_api_alloc_as_if_client (sizeof (*mp_ping)); \
54 : mp_ping->_vl_msg_id = htons ((_lm)->ping_id); \
55 : mp_ping->client_index = vam->my_client_index; \
56 : fformat (vam->ofp, "Sending ping id=%d\n", (_lm)->ping_id); \
57 : vam->result_ready = 0; \
58 :
59 : typedef struct
60 : {
61 : u32 spi;
62 : u8 si;
63 : } __attribute__ ((__packed__)) lisp_nsh_api_t;
64 :
65 : static uword
66 0 : unformat_nsh_address (unformat_input_t * input, va_list * args)
67 : {
68 0 : lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
69 0 : return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
70 : }
71 :
72 : static u8 *
73 0 : format_nsh_address_vat (u8 * s, va_list * args)
74 : {
75 0 : nsh_t *a = va_arg (*args, nsh_t *);
76 0 : return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
77 : }
78 :
79 : static u8 *
80 0 : format_lisp_flat_eid (u8 * s, va_list * args)
81 : {
82 0 : vl_api_eid_t *eid = va_arg (*args, vl_api_eid_t *);
83 :
84 0 : switch (eid->type)
85 : {
86 0 : case EID_TYPE_API_PREFIX:
87 0 : if (eid->address.prefix.address.af)
88 0 : return format (s, "%U/%d", format_ip6_address,
89 0 : eid->address.prefix.address.un.ip6,
90 0 : eid->address.prefix.len);
91 0 : return format (s, "%U/%d", format_ip4_address,
92 0 : eid->address.prefix.address.un.ip4,
93 0 : eid->address.prefix.len);
94 0 : case EID_TYPE_API_MAC:
95 0 : return format (s, "%U", format_ethernet_address, eid->address.mac);
96 0 : case EID_TYPE_API_NSH:
97 0 : return format (s, "%U", format_nsh_address_vat, eid->address.nsh);
98 : }
99 0 : return 0;
100 : }
101 :
102 0 : static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
103 : (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
104 : {
105 0 : vat_main_t *vam = &vat_main;
106 0 : i32 retval = ntohl (mp->retval);
107 0 : if (vam->async_mode)
108 : {
109 0 : vam->async_errors += (retval < 0);
110 : }
111 : else
112 : {
113 0 : vam->retval = retval;
114 0 : vam->result_ready = 1;
115 : }
116 0 : }
117 :
118 : static void
119 0 : api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
120 : {
121 0 : e->dp_table = clib_net_to_host_u32 (e->dp_table);
122 0 : e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
123 0 : e->vni = clib_net_to_host_u32 (e->vni);
124 0 : }
125 :
126 : static void
127 0 : gpe_fwd_entries_get_reply_t_net_to_host
128 : (vl_api_gpe_fwd_entries_get_reply_t * mp)
129 : {
130 : u32 i;
131 :
132 0 : mp->count = clib_net_to_host_u32 (mp->count);
133 0 : for (i = 0; i < mp->count; i++)
134 : {
135 0 : api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
136 : }
137 0 : }
138 :
139 : static u8 *
140 0 : format_gpe_encap_mode (u8 * s, va_list * args)
141 : {
142 0 : u32 mode = va_arg (*args, u32);
143 :
144 0 : switch (mode)
145 : {
146 0 : case 0:
147 0 : return format (s, "lisp");
148 0 : case 1:
149 0 : return format (s, "vxlan");
150 : }
151 0 : return 0;
152 : }
153 :
154 : static void
155 0 : vl_api_gpe_get_encap_mode_reply_t_handler
156 : (vl_api_gpe_get_encap_mode_reply_t * mp)
157 : {
158 0 : vat_main_t *vam = &vat_main;
159 :
160 0 : print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
161 0 : vam->retval = ntohl (mp->retval);
162 0 : vam->result_ready = 1;
163 0 : }
164 :
165 : static void
166 0 : vl_api_gpe_fwd_entry_path_details_t_handler
167 : (vl_api_gpe_fwd_entry_path_details_t * mp)
168 : {
169 0 : vat_main_t *vam = &vat_main;
170 0 : u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
171 :
172 0 : if (mp->lcl_loc.addr.af)
173 0 : format_ip_address_fcn = format_ip6_address;
174 : else
175 0 : format_ip_address_fcn = format_ip4_address;
176 :
177 0 : print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
178 : format_ip_address_fcn, &mp->lcl_loc.addr.un,
179 : format_ip_address_fcn, &mp->rmt_loc.addr.un);
180 0 : }
181 :
182 : static void
183 0 : vl_api_gpe_fwd_entries_get_reply_t_handler
184 : (vl_api_gpe_fwd_entries_get_reply_t * mp)
185 : {
186 0 : vat_main_t *vam = &vat_main;
187 : u32 i;
188 0 : int retval = clib_net_to_host_u32 (mp->retval);
189 : vl_api_gpe_fwd_entry_t *e;
190 :
191 0 : if (retval)
192 0 : goto end;
193 :
194 0 : gpe_fwd_entries_get_reply_t_net_to_host (mp);
195 :
196 0 : for (i = 0; i < mp->count; i++)
197 : {
198 0 : e = &mp->entries[i];
199 0 : print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
200 : format_lisp_flat_eid, e->leid, format_lisp_flat_eid, e->reid);
201 : }
202 :
203 0 : end:
204 0 : vam->retval = retval;
205 0 : vam->result_ready = 1;
206 0 : }
207 :
208 : static void
209 0 : vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
210 : (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
211 : {
212 0 : vat_main_t *vam = &vat_main;
213 : u32 i, n;
214 0 : int retval = clib_net_to_host_u32 (mp->retval);
215 : vl_api_gpe_native_fwd_rpath_t *r;
216 :
217 0 : if (retval)
218 0 : goto end;
219 :
220 0 : n = clib_net_to_host_u32 (mp->count);
221 :
222 0 : for (i = 0; i < n; i++)
223 : {
224 0 : r = &mp->entries[i];
225 0 : print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
226 : clib_net_to_host_u32 (r->fib_index),
227 : clib_net_to_host_u32 (r->nh_sw_if_index),
228 0 : r->nh_addr.af ? format_ip6_address : format_ip4_address,
229 : r->nh_addr.un);
230 : }
231 :
232 0 : end:
233 0 : vam->retval = retval;
234 0 : vam->result_ready = 1;
235 0 : }
236 :
237 : static void
238 0 : vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
239 : (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
240 : {
241 0 : vat_main_t *vam = &vat_main;
242 : u32 i, n;
243 0 : int retval = clib_net_to_host_u32 (mp->retval);
244 :
245 0 : if (retval)
246 0 : goto end;
247 :
248 0 : n = clib_net_to_host_u32 (mp->count);
249 :
250 0 : for (i = 0; i < n; i++)
251 0 : print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
252 :
253 0 : end:
254 0 : vam->retval = retval;
255 0 : vam->result_ready = 1;
256 0 : }
257 :
258 :
259 : /* *INDENT-OFF* */
260 : /** Used for parsing LISP eids */
261 : typedef CLIB_PACKED(struct{
262 : union {
263 : ip46_address_t ip;
264 : mac_address_t mac;
265 : lisp_nsh_api_t nsh;
266 : } addr;
267 : u32 len; /**< prefix length if IP */
268 : u8 type; /**< type of eid */
269 : }) lisp_eid_vat_t;
270 : /* *INDENT-ON* */
271 :
272 : static uword
273 0 : unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
274 : {
275 0 : lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
276 :
277 0 : clib_memset (a, 0, sizeof (a[0]));
278 :
279 0 : if (unformat (input, "%U/%d", unformat_ip46_address, a->addr.ip, &a->len))
280 : {
281 0 : a->type = 0; /* ip prefix type */
282 : }
283 0 : else if (unformat (input, "%U", unformat_ethernet_address, &a->addr.mac))
284 : {
285 0 : a->type = 1; /* mac type */
286 : }
287 0 : else if (unformat (input, "%U", unformat_nsh_address, a->addr.nsh))
288 : {
289 0 : a->type = 2; /* NSH type */
290 0 : a->addr.nsh.spi = clib_host_to_net_u32 (a->addr.nsh.spi);
291 : }
292 : else
293 : {
294 0 : return 0;
295 : }
296 :
297 0 : if (a->type == 0)
298 : {
299 0 : if (ip46_address_is_ip4 (&a->addr.ip))
300 0 : return a->len > 32 ? 1 : 0;
301 : else
302 0 : return a->len > 128 ? 1 : 0;
303 : }
304 :
305 0 : return 1;
306 : }
307 :
308 : static void
309 0 : lisp_eid_put_vat (vl_api_eid_t * eid, const lisp_eid_vat_t * vat_eid)
310 : {
311 0 : eid->type = vat_eid->type;
312 0 : switch (eid->type)
313 : {
314 0 : case EID_TYPE_API_PREFIX:
315 0 : if (ip46_address_is_ip4 (&vat_eid->addr.ip))
316 : {
317 0 : clib_memcpy (&eid->address.prefix.address.un.ip4,
318 : &vat_eid->addr.ip.ip4, 4);
319 0 : eid->address.prefix.address.af = ADDRESS_IP4;
320 0 : eid->address.prefix.len = vat_eid->len;
321 : }
322 : else
323 : {
324 0 : clib_memcpy (&eid->address.prefix.address.un.ip6,
325 : &vat_eid->addr.ip.ip6, 16);
326 0 : eid->address.prefix.address.af = ADDRESS_IP6;
327 0 : eid->address.prefix.len = vat_eid->len;
328 : }
329 0 : return;
330 0 : case EID_TYPE_API_MAC:
331 0 : clib_memcpy (&eid->address.mac, &vat_eid->addr.mac,
332 : sizeof (eid->address.mac));
333 0 : return;
334 0 : case EID_TYPE_API_NSH:
335 0 : clib_memcpy (&eid->address.nsh, &vat_eid->addr.nsh,
336 : sizeof (eid->address.nsh));
337 0 : return;
338 0 : default:
339 0 : ASSERT (0);
340 0 : return;
341 : }
342 : }
343 :
344 : static int
345 0 : api_gpe_add_del_fwd_entry (vat_main_t * vam)
346 : {
347 0 : u32 dp_table = 0, vni = 0;;
348 0 : unformat_input_t *input = vam->input;
349 : vl_api_gpe_add_del_fwd_entry_t *mp;
350 0 : u8 is_add = 1;
351 0 : lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
352 0 : lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
353 0 : u8 rmt_eid_set = 0, lcl_eid_set = 0;
354 0 : u32 action = ~0, w;
355 : ip4_address_t rmt_rloc4, lcl_rloc4;
356 : ip6_address_t rmt_rloc6, lcl_rloc6;
357 0 : vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
358 : int ret;
359 :
360 0 : clib_memset (&rloc, 0, sizeof (rloc));
361 :
362 : /* Parse args required to build the message */
363 0 : while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
364 : {
365 0 : if (unformat (input, "del"))
366 0 : is_add = 0;
367 0 : else if (unformat (input, "add"))
368 0 : is_add = 1;
369 0 : else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
370 : {
371 0 : rmt_eid_set = 1;
372 : }
373 0 : else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
374 : {
375 0 : lcl_eid_set = 1;
376 : }
377 0 : else if (unformat (input, "vrf %d", &dp_table))
378 : ;
379 0 : else if (unformat (input, "bd %d", &dp_table))
380 : ;
381 0 : else if (unformat (input, "vni %d", &vni))
382 : ;
383 0 : else if (unformat (input, "w %d", &w))
384 : {
385 0 : if (!curr_rloc)
386 : {
387 0 : errmsg ("No RLOC configured for setting priority/weight!");
388 0 : return -99;
389 : }
390 0 : curr_rloc->weight = w;
391 : }
392 0 : else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
393 : &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
394 : {
395 0 : rloc.addr.af = 0;
396 0 : clib_memcpy (&rloc.addr.un.ip4, &lcl_rloc4, sizeof (lcl_rloc4));
397 0 : rloc.weight = 0;
398 0 : vec_add1 (lcl_locs, rloc);
399 :
400 0 : clib_memcpy (&rloc.addr.un.ip4, &rmt_rloc4, sizeof (rmt_rloc4));
401 0 : vec_add1 (rmt_locs, rloc);
402 : /* weight saved in rmt loc */
403 0 : curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
404 : }
405 0 : else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
406 : &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
407 : {
408 0 : rloc.addr.af = 1;
409 0 : clib_memcpy (&rloc.addr.un.ip6, &lcl_rloc6, sizeof (lcl_rloc6));
410 0 : rloc.weight = 0;
411 0 : vec_add1 (lcl_locs, rloc);
412 :
413 0 : clib_memcpy (&rloc.addr.un.ip6, &rmt_rloc6, sizeof (rmt_rloc6));
414 0 : vec_add1 (rmt_locs, rloc);
415 : /* weight saved in rmt loc */
416 0 : curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
417 : }
418 0 : else if (unformat (input, "action %d", &action))
419 : {
420 : ;
421 : }
422 : else
423 : {
424 0 : clib_warning ("parse error '%U'", format_unformat_error, input);
425 0 : return -99;
426 : }
427 : }
428 :
429 0 : if (!rmt_eid_set)
430 : {
431 0 : errmsg ("remote eid addresses not set");
432 0 : return -99;
433 : }
434 :
435 0 : if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
436 : {
437 0 : errmsg ("eid types don't match");
438 0 : return -99;
439 : }
440 :
441 0 : if (0 == rmt_locs && (u32) ~ 0 == action)
442 : {
443 0 : errmsg ("action not set for negative mapping");
444 0 : return -99;
445 : }
446 :
447 : /* Construct the API message */
448 0 : M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
449 : sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
450 :
451 0 : mp->is_add = is_add;
452 0 : lisp_eid_put_vat (&mp->rmt_eid, rmt_eid);
453 0 : lisp_eid_put_vat (&mp->lcl_eid, lcl_eid);
454 0 : mp->dp_table = clib_host_to_net_u32 (dp_table);
455 0 : mp->vni = clib_host_to_net_u32 (vni);
456 0 : mp->action = action;
457 :
458 0 : if (0 != rmt_locs && 0 != lcl_locs)
459 : {
460 0 : mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
461 0 : clib_memcpy (mp->locs, lcl_locs,
462 : (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
463 :
464 0 : u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
465 0 : clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
466 : (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
467 : }
468 0 : vec_free (lcl_locs);
469 0 : vec_free (rmt_locs);
470 :
471 : /* send it... */
472 0 : S (mp);
473 :
474 : /* Wait for a reply... */
475 0 : W (ret);
476 0 : return ret;
477 : }
478 :
479 : static int
480 0 : api_gpe_enable_disable (vat_main_t * vam)
481 : {
482 0 : unformat_input_t *input = vam->input;
483 : vl_api_gpe_enable_disable_t *mp;
484 0 : u8 is_set = 0;
485 0 : u8 is_enable = 1;
486 : int ret;
487 :
488 : /* Parse args required to build the message */
489 0 : while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
490 : {
491 0 : if (unformat (input, "enable"))
492 : {
493 0 : is_set = 1;
494 0 : is_enable = 1;
495 : }
496 0 : else if (unformat (input, "disable"))
497 : {
498 0 : is_set = 1;
499 0 : is_enable = 0;
500 : }
501 : else
502 0 : break;
503 : }
504 :
505 0 : if (is_set == 0)
506 : {
507 0 : errmsg ("Value not set");
508 0 : return -99;
509 : }
510 :
511 : /* Construct the API message */
512 0 : M (GPE_ENABLE_DISABLE, mp);
513 :
514 0 : mp->is_enable = is_enable;
515 :
516 : /* send it... */
517 0 : S (mp);
518 :
519 : /* Wait for a reply... */
520 0 : W (ret);
521 0 : return ret;
522 : }
523 :
524 : uword
525 0 : unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
526 : {
527 0 : u32 *mode = va_arg (*args, u32 *);
528 :
529 0 : if (unformat (input, "lisp"))
530 0 : *mode = 0;
531 0 : else if (unformat (input, "vxlan"))
532 0 : *mode = 1;
533 : else
534 0 : return 0;
535 :
536 0 : return 1;
537 : }
538 :
539 : static int
540 0 : api_gpe_get_encap_mode (vat_main_t * vam)
541 : {
542 : vl_api_gpe_get_encap_mode_t *mp;
543 : int ret;
544 :
545 : /* Construct the API message */
546 0 : M (GPE_GET_ENCAP_MODE, mp);
547 :
548 : /* send it... */
549 0 : S (mp);
550 :
551 : /* Wait for a reply... */
552 0 : W (ret);
553 0 : return ret;
554 : }
555 :
556 : static int
557 0 : api_gpe_set_encap_mode (vat_main_t * vam)
558 : {
559 0 : unformat_input_t *input = vam->input;
560 : vl_api_gpe_set_encap_mode_t *mp;
561 : int ret;
562 0 : u32 mode = 0;
563 :
564 : /* Parse args required to build the message */
565 0 : while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
566 : {
567 0 : if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
568 : ;
569 : else
570 0 : break;
571 : }
572 :
573 : /* Construct the API message */
574 0 : M (GPE_SET_ENCAP_MODE, mp);
575 :
576 0 : mp->is_vxlan = mode;
577 :
578 : /* send it... */
579 0 : S (mp);
580 :
581 : /* Wait for a reply... */
582 0 : W (ret);
583 0 : return ret;
584 : }
585 :
586 : static int
587 0 : api_gpe_add_del_iface (vat_main_t * vam)
588 : {
589 0 : unformat_input_t *input = vam->input;
590 : vl_api_gpe_add_del_iface_t *mp;
591 0 : u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
592 0 : u32 dp_table = 0, vni = 0;
593 : int ret;
594 :
595 : /* Parse args required to build the message */
596 0 : while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
597 : {
598 0 : if (unformat (input, "up"))
599 : {
600 0 : action_set = 1;
601 0 : is_add = 1;
602 : }
603 0 : else if (unformat (input, "down"))
604 : {
605 0 : action_set = 1;
606 0 : is_add = 0;
607 : }
608 0 : else if (unformat (input, "table_id %d", &dp_table))
609 : {
610 0 : dp_table_set = 1;
611 : }
612 0 : else if (unformat (input, "bd_id %d", &dp_table))
613 : {
614 0 : dp_table_set = 1;
615 0 : is_l2 = 1;
616 : }
617 0 : else if (unformat (input, "vni %d", &vni))
618 : {
619 0 : vni_set = 1;
620 : }
621 : else
622 0 : break;
623 : }
624 :
625 0 : if (action_set == 0)
626 : {
627 0 : errmsg ("Action not set");
628 0 : return -99;
629 : }
630 0 : if (dp_table_set == 0 || vni_set == 0)
631 : {
632 0 : errmsg ("vni and dp_table must be set");
633 0 : return -99;
634 : }
635 :
636 : /* Construct the API message */
637 0 : M (GPE_ADD_DEL_IFACE, mp);
638 :
639 0 : mp->is_add = is_add;
640 0 : mp->dp_table = clib_host_to_net_u32 (dp_table);
641 0 : mp->is_l2 = is_l2;
642 0 : mp->vni = clib_host_to_net_u32 (vni);
643 :
644 : /* send it... */
645 0 : S (mp);
646 :
647 : /* Wait for a reply... */
648 0 : W (ret);
649 0 : return ret;
650 : }
651 :
652 : static int
653 0 : api_gpe_fwd_entries_get (vat_main_t * vam)
654 : {
655 0 : unformat_input_t *i = vam->input;
656 : vl_api_gpe_fwd_entries_get_t *mp;
657 0 : u8 vni_set = 0;
658 0 : u32 vni = ~0;
659 : int ret;
660 :
661 0 : while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
662 : {
663 0 : if (unformat (i, "vni %d", &vni))
664 : {
665 0 : vni_set = 1;
666 : }
667 : else
668 : {
669 0 : errmsg ("parse error '%U'", format_unformat_error, i);
670 0 : return -99;
671 : }
672 : }
673 :
674 0 : if (!vni_set)
675 : {
676 0 : errmsg ("vni not set!");
677 0 : return -99;
678 : }
679 :
680 0 : if (!vam->json_output)
681 : {
682 0 : print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
683 : "leid", "reid");
684 : }
685 :
686 0 : M (GPE_FWD_ENTRIES_GET, mp);
687 0 : mp->vni = clib_host_to_net_u32 (vni);
688 :
689 : /* send it... */
690 0 : S (mp);
691 :
692 : /* Wait for a reply... */
693 0 : W (ret);
694 0 : return ret;
695 : }
696 :
697 : static int
698 0 : api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
699 : {
700 0 : unformat_input_t *i = vam->input;
701 : vl_api_gpe_native_fwd_rpaths_get_t *mp;
702 : int ret;
703 0 : u8 ip_family_set = 0, is_ip4 = 1;
704 :
705 0 : while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
706 : {
707 0 : if (unformat (i, "ip4"))
708 : {
709 0 : ip_family_set = 1;
710 0 : is_ip4 = 1;
711 : }
712 0 : else if (unformat (i, "ip6"))
713 : {
714 0 : ip_family_set = 1;
715 0 : is_ip4 = 0;
716 : }
717 : else
718 : {
719 0 : errmsg ("parse error '%U'", format_unformat_error, i);
720 0 : return -99;
721 : }
722 : }
723 :
724 0 : if (!ip_family_set)
725 : {
726 0 : errmsg ("ip family not set!");
727 0 : return -99;
728 : }
729 :
730 0 : M (GPE_NATIVE_FWD_RPATHS_GET, mp);
731 0 : mp->is_ip4 = is_ip4;
732 :
733 : /* send it... */
734 0 : S (mp);
735 :
736 : /* Wait for a reply... */
737 0 : W (ret);
738 0 : return ret;
739 : }
740 :
741 : static int
742 0 : api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
743 : {
744 : vl_api_gpe_fwd_entry_vnis_get_t *mp;
745 : int ret;
746 :
747 0 : if (!vam->json_output)
748 : {
749 0 : print (vam->ofp, "VNIs");
750 : }
751 :
752 0 : M (GPE_FWD_ENTRY_VNIS_GET, mp);
753 :
754 : /* send it... */
755 0 : S (mp);
756 :
757 : /* Wait for a reply... */
758 0 : W (ret);
759 0 : return ret;
760 : }
761 :
762 : static int
763 0 : api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
764 : {
765 0 : unformat_input_t *i = vam->input;
766 : vl_api_gpe_add_del_native_fwd_rpath_t *mp;
767 0 : int ret = 0;
768 0 : u8 is_add = 1, ip_set = 0, is_ip4 = 1;
769 : struct in_addr ip4;
770 : struct in6_addr ip6;
771 0 : u32 table_id = 0, nh_sw_if_index = ~0;
772 :
773 0 : clib_memset (&ip4, 0, sizeof (ip4));
774 0 : clib_memset (&ip6, 0, sizeof (ip6));
775 :
776 0 : while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
777 : {
778 0 : if (unformat (i, "del"))
779 0 : is_add = 0;
780 0 : else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
781 : unformat_sw_if_index, vam, &nh_sw_if_index))
782 : {
783 0 : ip_set = 1;
784 0 : is_ip4 = 1;
785 : }
786 0 : else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
787 : unformat_sw_if_index, vam, &nh_sw_if_index))
788 : {
789 0 : ip_set = 1;
790 0 : is_ip4 = 0;
791 : }
792 0 : else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
793 : {
794 0 : ip_set = 1;
795 0 : is_ip4 = 1;
796 0 : nh_sw_if_index = ~0;
797 : }
798 0 : else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
799 : {
800 0 : ip_set = 1;
801 0 : is_ip4 = 0;
802 0 : nh_sw_if_index = ~0;
803 : }
804 0 : else if (unformat (i, "table %d", &table_id))
805 : ;
806 : else
807 : {
808 0 : errmsg ("parse error '%U'", format_unformat_error, i);
809 0 : return -99;
810 : }
811 : }
812 :
813 0 : if (!ip_set)
814 : {
815 0 : errmsg ("nh addr not set!");
816 0 : return -99;
817 : }
818 :
819 0 : M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
820 0 : mp->is_add = is_add;
821 0 : mp->table_id = clib_host_to_net_u32 (table_id);
822 0 : mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
823 0 : mp->nh_addr.af = is_ip4 ? 0 : 1;
824 0 : if (is_ip4)
825 0 : clib_memcpy (mp->nh_addr.un.ip4, &ip4, sizeof (ip4));
826 : else
827 0 : clib_memcpy (mp->nh_addr.un.ip6, &ip6, sizeof (ip6));
828 :
829 : /* send it... */
830 0 : S (mp);
831 :
832 : /* Wait for a reply... */
833 0 : W (ret);
834 0 : return ret;
835 : }
836 :
837 : static int
838 0 : api_gpe_fwd_entry_path_dump (vat_main_t * vam)
839 : {
840 : vl_api_gpe_fwd_entry_path_dump_t *mp;
841 : vl_api_control_ping_t *mp_ping;
842 0 : unformat_input_t *i = vam->input;
843 0 : u32 fwd_entry_index = ~0;
844 : int ret;
845 :
846 0 : while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
847 : {
848 0 : if (unformat (i, "index %d", &fwd_entry_index))
849 : ;
850 : else
851 0 : break;
852 : }
853 :
854 0 : if (~0 == fwd_entry_index)
855 : {
856 0 : errmsg ("no index specified!");
857 0 : return -99;
858 : }
859 :
860 0 : if (!vam->json_output)
861 : {
862 0 : print (vam->ofp, "first line");
863 : }
864 :
865 0 : M (GPE_FWD_ENTRY_PATH_DUMP, mp);
866 :
867 : /* send it... */
868 0 : S (mp);
869 : /* Use a control ping for synchronization */
870 0 : LISP_PING (&lisp_gpe_test_main, mp_ping);
871 0 : S (mp_ping);
872 :
873 : /* Wait for a reply... */
874 0 : W (ret);
875 0 : return ret;
876 : }
877 :
878 : #define vat_plugin_register vat_plugin_register_gpe
879 : #include <lisp/lisp-gpe/lisp_gpe.api_test.c>
880 :
881 : /*
882 : * fd.io coding-style-patch-verification: ON
883 : *
884 : * Local Variables:
885 : * eval: (c-set-style "gnu")
886 : * End:
887 : */
|