18235fa4514250592167bfe6e13fcddc6e9cfb45
[vpp.git] / src / vnet / lisp-cp / one_api.c
1 /*
2  *------------------------------------------------------------------
3  * one_api.c - Overlay Network Engine API
4  *
5  * Copyright (c) 2016-2017 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vnet/vnet.h>
21 #include <vlibmemory/api.h>
22
23 #include <vnet/interface.h>
24 #include <vnet/api_errno.h>
25 #include <vnet/lisp-cp/control.h>
26 #include <vnet/lisp-gpe/lisp_gpe.h>
27
28 #include <vnet/vnet_msg_enum.h>
29
30 #define vl_api_one_remote_locator_t_endian vl_noop_handler
31 #define vl_api_one_remote_locator_t_print vl_noop_handler
32 #define vl_api_one_local_locator_t_endian vl_noop_handler
33 #define vl_api_one_local_locator_t_print vl_noop_handler
34
35 #define vl_api_one_add_del_locator_set_t_endian vl_noop_handler
36 #define vl_api_one_add_del_locator_set_t_print vl_noop_handler
37 #define vl_api_one_add_del_remote_mapping_t_endian vl_noop_handler
38 #define vl_api_one_add_del_remote_mapping_t_print vl_noop_handler
39
40 #define vl_api_one_add_del_locator_set_t_endian vl_noop_handler
41 #define vl_api_one_add_del_locator_set_t_print vl_noop_handler
42 #define vl_api_one_add_del_remote_mapping_t_endian vl_noop_handler
43 #define vl_api_one_add_del_remote_mapping_t_print vl_noop_handler
44
45 #define vl_api_one_l2_arp_entry_t_endian vl_noop_handler
46 #define vl_api_one_l2_arp_entry_t_print vl_noop_handler
47 #define vl_api_one_add_del_l2_arp_entry vl_noop_handler
48 #define vl_api_one_l2_arp_bd_get vl_noop_handler
49
50 #define vl_typedefs             /* define message structures */
51 #include <vnet/vnet_all_api_h.h>
52 #undef vl_typedefs
53
54 #define vl_endianfun            /* define message structures */
55 #include <vnet/vnet_all_api_h.h>
56 #undef vl_endianfun
57
58 /* instantiate all the print functions we know about */
59 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
60 #define vl_printfun
61 #include <vnet/vnet_all_api_h.h>
62 #undef vl_printfun
63
64 #include <vlibapi/api_helper_macros.h>
65
66 #define REPLY_DETAILS(t, body)                                  \
67 do {                                                            \
68     unix_shared_memory_queue_t * q;                             \
69     rv = vl_msg_api_pd_handler (mp, rv);                        \
70     q = vl_api_client_index_to_input_queue (mp->client_index);  \
71     if (!q)                                                     \
72         return;                                                 \
73                                                                 \
74     rmp = vl_msg_api_alloc (sizeof (*rmp));                     \
75     rmp->_vl_msg_id = ntohs((t));                               \
76     rmp->context = mp->context;                                 \
77     do {body;} while (0);                                       \
78     vl_msg_api_send_shmem (q, (u8 *)&rmp);                      \
79 } while(0);
80
81 #define foreach_vpe_api_msg                             \
82 _(ONE_ADD_DEL_LOCATOR_SET, one_add_del_locator_set)                     \
83 _(ONE_ADD_DEL_LOCATOR, one_add_del_locator)                             \
84 _(ONE_ADD_DEL_LOCAL_EID, one_add_del_local_eid)                         \
85 _(ONE_ADD_DEL_MAP_RESOLVER, one_add_del_map_resolver)                   \
86 _(ONE_ADD_DEL_MAP_SERVER, one_add_del_map_server)                       \
87 _(ONE_ENABLE_DISABLE, one_enable_disable)                               \
88 _(ONE_RLOC_PROBE_ENABLE_DISABLE, one_rloc_probe_enable_disable)         \
89 _(ONE_MAP_REGISTER_ENABLE_DISABLE, one_map_register_enable_disable)     \
90 _(ONE_ADD_DEL_REMOTE_MAPPING, one_add_del_remote_mapping)               \
91 _(ONE_ADD_DEL_ADJACENCY, one_add_del_adjacency)                         \
92 _(ONE_PITR_SET_LOCATOR_SET, one_pitr_set_locator_set)                   \
93 _(ONE_NSH_SET_LOCATOR_SET, one_nsh_set_locator_set)                     \
94 _(ONE_MAP_REQUEST_MODE, one_map_request_mode)                           \
95 _(ONE_EID_TABLE_ADD_DEL_MAP, one_eid_table_add_del_map)                 \
96 _(ONE_LOCATOR_SET_DUMP, one_locator_set_dump)                           \
97 _(ONE_LOCATOR_DUMP, one_locator_dump)                                   \
98 _(ONE_EID_TABLE_DUMP, one_eid_table_dump)                               \
99 _(ONE_MAP_RESOLVER_DUMP, one_map_resolver_dump)                         \
100 _(ONE_MAP_SERVER_DUMP, one_map_server_dump)                             \
101 _(ONE_EID_TABLE_MAP_DUMP, one_eid_table_map_dump)                       \
102 _(ONE_EID_TABLE_VNI_DUMP, one_eid_table_vni_dump)                       \
103 _(ONE_ADJACENCIES_GET, one_adjacencies_get)                             \
104 _(SHOW_ONE_NSH_MAPPING, show_one_nsh_mapping)                           \
105 _(SHOW_ONE_RLOC_PROBE_STATE, show_one_rloc_probe_state)                 \
106 _(SHOW_ONE_MAP_REGISTER_STATE, show_one_map_register_state)             \
107 _(SHOW_ONE_STATUS, show_one_status)                                     \
108 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS,                                    \
109   one_add_del_map_request_itr_rlocs)                                    \
110 _(ONE_GET_MAP_REQUEST_ITR_RLOCS, one_get_map_request_itr_rlocs)         \
111 _(SHOW_ONE_PITR, show_one_pitr)                                         \
112 _(SHOW_ONE_MAP_REQUEST_MODE, show_one_map_request_mode)                 \
113 _(ONE_USE_PETR, one_use_petr)                                           \
114 _(SHOW_ONE_USE_PETR, show_one_use_petr)                                 \
115 _(SHOW_ONE_STATS_ENABLE_DISABLE, show_one_stats_enable_disable)         \
116 _(ONE_STATS_ENABLE_DISABLE, one_stats_enable_disable)                   \
117 _(ONE_STATS_DUMP, one_stats_dump)                                       \
118 _(ONE_STATS_FLUSH, one_stats_flush)                                     \
119 _(ONE_L2_ARP_BD_GET, one_l2_arp_bd_get)                                 \
120 _(ONE_L2_ARP_ENTRIES_GET, one_l2_arp_entries_get)                       \
121 _(ONE_ADD_DEL_L2_ARP_ENTRY, one_add_del_l2_arp_entry)                   \
122
123
124 static locator_t *
125 unformat_one_locs (vl_api_one_remote_locator_t * rmt_locs, u32 rloc_num)
126 {
127   u32 i;
128   locator_t *locs = 0, loc;
129   vl_api_one_remote_locator_t *r;
130
131   for (i = 0; i < rloc_num; i++)
132     {
133       /* remote locators */
134       r = &rmt_locs[i];
135       memset (&loc, 0, sizeof (loc));
136       gid_address_ip_set (&loc.address, &r->addr, r->is_ip4 ? IP4 : IP6);
137
138       loc.priority = r->priority;
139       loc.weight = r->weight;
140
141       vec_add1 (locs, loc);
142     }
143   return locs;
144 }
145
146 static void
147 vl_api_one_add_del_locator_set_t_handler (vl_api_one_add_del_locator_set_t *
148                                           mp)
149 {
150   vl_api_one_add_del_locator_set_reply_t *rmp;
151   int rv = 0;
152   vnet_lisp_add_del_locator_set_args_t _a, *a = &_a;
153   locator_t locator;
154   vl_api_one_local_locator_t *ls_loc;
155   u32 ls_index = ~0, locator_num;
156   u8 *locator_name = NULL;
157   int i;
158
159   memset (a, 0, sizeof (a[0]));
160
161   locator_name = format (0, "%s", mp->locator_set_name);
162
163   a->name = locator_name;
164   a->is_add = mp->is_add;
165   a->local = 1;
166   locator_num = clib_net_to_host_u32 (mp->locator_num);
167
168   memset (&locator, 0, sizeof (locator));
169   for (i = 0; i < locator_num; i++)
170     {
171       ls_loc = &mp->locators[i];
172       VALIDATE_SW_IF_INDEX (ls_loc);
173
174       locator.sw_if_index = htonl (ls_loc->sw_if_index);
175       locator.priority = ls_loc->priority;
176       locator.weight = ls_loc->weight;
177       locator.local = 1;
178       vec_add1 (a->locators, locator);
179     }
180
181   rv = vnet_lisp_add_del_locator_set (a, &ls_index);
182
183   BAD_SW_IF_INDEX_LABEL;
184
185   vec_free (locator_name);
186   vec_free (a->locators);
187
188   /* *INDENT-OFF* */
189   REPLY_MACRO2 (VL_API_ONE_ADD_DEL_LOCATOR_SET_REPLY,
190   ({
191     rmp->ls_index = clib_host_to_net_u32 (ls_index);
192   }));
193   /* *INDENT-ON* */
194 }
195
196 static void
197 vl_api_one_add_del_locator_t_handler (vl_api_one_add_del_locator_t * mp)
198 {
199   vl_api_one_add_del_locator_reply_t *rmp;
200   int rv = 0;
201   locator_t locator, *locators = NULL;
202   vnet_lisp_add_del_locator_set_args_t _a, *a = &_a;
203   u32 ls_index = ~0;
204   u8 *locator_name = NULL;
205
206   memset (&locator, 0, sizeof (locator));
207   memset (a, 0, sizeof (a[0]));
208
209   locator.sw_if_index = ntohl (mp->sw_if_index);
210   locator.priority = mp->priority;
211   locator.weight = mp->weight;
212   locator.local = 1;
213   vec_add1 (locators, locator);
214
215   locator_name = format (0, "%s", mp->locator_set_name);
216
217   a->name = locator_name;
218   a->locators = locators;
219   a->is_add = mp->is_add;
220   a->local = 1;
221
222   rv = vnet_lisp_add_del_locator (a, NULL, &ls_index);
223
224   vec_free (locators);
225   vec_free (locator_name);
226
227   REPLY_MACRO (VL_API_ONE_ADD_DEL_LOCATOR_REPLY);
228 }
229
230 typedef struct
231 {
232   u32 spi;
233   u8 si;
234 } __attribute__ ((__packed__)) lisp_nsh_api_t;
235
236 static int
237 unformat_one_eid_api (gid_address_t * dst, u32 vni, u8 type, void *src,
238                       u8 len)
239 {
240   lisp_nsh_api_t *nsh;
241
242   switch (type)
243     {
244     case 0:                     /* ipv4 */
245       gid_address_type (dst) = GID_ADDR_IP_PREFIX;
246       gid_address_ip_set (dst, src, IP4);
247       gid_address_ippref_len (dst) = len;
248       ip_prefix_normalize (&gid_address_ippref (dst));
249       break;
250     case 1:                     /* ipv6 */
251       gid_address_type (dst) = GID_ADDR_IP_PREFIX;
252       gid_address_ip_set (dst, src, IP6);
253       gid_address_ippref_len (dst) = len;
254       ip_prefix_normalize (&gid_address_ippref (dst));
255       break;
256     case 2:                     /* l2 mac */
257       gid_address_type (dst) = GID_ADDR_MAC;
258       clib_memcpy (&gid_address_mac (dst), src, 6);
259       break;
260     case 3:                     /* NSH */
261       gid_address_type (dst) = GID_ADDR_NSH;
262       nsh = src;
263       gid_address_nsh_spi (dst) = clib_net_to_host_u32 (nsh->spi);
264       gid_address_nsh_si (dst) = nsh->si;
265       break;
266     default:
267       /* unknown type */
268       return VNET_API_ERROR_INVALID_VALUE;
269     }
270
271   gid_address_vni (dst) = vni;
272
273   return 0;
274 }
275
276 static void
277 vl_api_one_add_del_local_eid_t_handler (vl_api_one_add_del_local_eid_t * mp)
278 {
279   vl_api_one_add_del_local_eid_reply_t *rmp;
280   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
281   int rv = 0;
282   gid_address_t _eid, *eid = &_eid;
283   uword *p = NULL;
284   u32 locator_set_index = ~0, map_index = ~0;
285   vnet_lisp_add_del_mapping_args_t _a, *a = &_a;
286   u8 *name = NULL, *key = NULL;
287   memset (a, 0, sizeof (a[0]));
288   memset (eid, 0, sizeof (eid[0]));
289
290   rv = unformat_one_eid_api (eid, clib_net_to_host_u32 (mp->vni),
291                              mp->eid_type, mp->eid, mp->prefix_len);
292   if (rv)
293     goto out;
294
295   if (gid_address_type (eid) == GID_ADDR_NSH)
296     {
297       rv = VNET_API_ERROR_INVALID_VALUE;
298       goto out;
299     }
300
301   name = format (0, "%s", mp->locator_set_name);
302   p = hash_get_mem (lcm->locator_set_index_by_name, name);
303   if (!p)
304     {
305       rv = VNET_API_ERROR_INVALID_VALUE;
306       goto out;
307     }
308   locator_set_index = p[0];
309
310   if (*mp->key)
311     key = format (0, "%s", mp->key);
312
313   /* XXX treat batch configuration */
314   a->is_add = mp->is_add;
315   gid_address_copy (&a->eid, eid);
316   a->locator_set_index = locator_set_index;
317   a->local = 1;
318   a->key = key;
319   a->key_id = clib_net_to_host_u16 (mp->key_id);
320
321   rv = vnet_lisp_add_del_local_mapping (a, &map_index);
322
323 out:
324   vec_free (name);
325   vec_free (key);
326   gid_address_free (&a->eid);
327
328   REPLY_MACRO (VL_API_ONE_ADD_DEL_LOCAL_EID_REPLY);
329 }
330
331 static void
332   vl_api_one_eid_table_add_del_map_t_handler
333   (vl_api_one_eid_table_add_del_map_t * mp)
334 {
335   vl_api_one_eid_table_add_del_map_reply_t *rmp;
336   int rv = 0;
337   rv = vnet_lisp_eid_table_map (clib_net_to_host_u32 (mp->vni),
338                                 clib_net_to_host_u32 (mp->dp_table),
339                                 mp->is_l2, mp->is_add);
340 REPLY_MACRO (VL_API_ONE_EID_TABLE_ADD_DEL_MAP_REPLY)}
341
342 static void
343 vl_api_one_add_del_map_server_t_handler (vl_api_one_add_del_map_server_t * mp)
344 {
345   vl_api_one_add_del_map_server_reply_t *rmp;
346   int rv = 0;
347   ip_address_t addr;
348
349   memset (&addr, 0, sizeof (addr));
350
351   ip_address_set (&addr, mp->ip_address, mp->is_ipv6 ? IP6 : IP4);
352   rv = vnet_lisp_add_del_map_server (&addr, mp->is_add);
353
354   REPLY_MACRO (VL_API_ONE_ADD_DEL_MAP_SERVER_REPLY);
355 }
356
357 static void
358 vl_api_one_add_del_map_resolver_t_handler (vl_api_one_add_del_map_resolver_t
359                                            * mp)
360 {
361   vl_api_one_add_del_map_resolver_reply_t *rmp;
362   int rv = 0;
363   vnet_lisp_add_del_map_resolver_args_t _a, *a = &_a;
364
365   memset (a, 0, sizeof (a[0]));
366
367   a->is_add = mp->is_add;
368   ip_address_set (&a->address, mp->ip_address, mp->is_ipv6 ? IP6 : IP4);
369
370   rv = vnet_lisp_add_del_map_resolver (a);
371
372   REPLY_MACRO (VL_API_ONE_ADD_DEL_MAP_RESOLVER_REPLY);
373 }
374
375 static void
376   vl_api_one_map_register_enable_disable_t_handler
377   (vl_api_one_map_register_enable_disable_t * mp)
378 {
379   vl_api_one_map_register_enable_disable_reply_t *rmp;
380   int rv = 0;
381
382   vnet_lisp_map_register_enable_disable (mp->is_enabled);
383   REPLY_MACRO (VL_API_ONE_ENABLE_DISABLE_REPLY);
384 }
385
386 static void
387   vl_api_one_rloc_probe_enable_disable_t_handler
388   (vl_api_one_rloc_probe_enable_disable_t * mp)
389 {
390   vl_api_one_rloc_probe_enable_disable_reply_t *rmp;
391   int rv = 0;
392
393   vnet_lisp_rloc_probe_enable_disable (mp->is_enabled);
394   REPLY_MACRO (VL_API_ONE_ENABLE_DISABLE_REPLY);
395 }
396
397 static void
398 vl_api_one_enable_disable_t_handler (vl_api_one_enable_disable_t * mp)
399 {
400   vl_api_one_enable_disable_reply_t *rmp;
401   int rv = 0;
402
403   vnet_lisp_enable_disable (mp->is_en);
404   REPLY_MACRO (VL_API_ONE_ENABLE_DISABLE_REPLY);
405 }
406
407 static void
408   vl_api_show_one_map_request_mode_t_handler
409   (vl_api_show_one_map_request_mode_t * mp)
410 {
411   int rv = 0;
412   vl_api_show_one_map_request_mode_reply_t *rmp;
413
414   /* *INDENT-OFF* */
415   REPLY_MACRO2(VL_API_SHOW_ONE_MAP_REQUEST_MODE_REPLY,
416   ({
417     rmp->mode = vnet_lisp_get_map_request_mode ();
418   }));
419   /* *INDENT-ON* */
420 }
421
422 static void
423 vl_api_one_map_request_mode_t_handler (vl_api_one_map_request_mode_t * mp)
424 {
425   vl_api_one_map_request_mode_reply_t *rmp;
426   int rv = 0;
427
428   rv = vnet_lisp_set_map_request_mode (mp->mode);
429
430   REPLY_MACRO (VL_API_ONE_MAP_REQUEST_MODE_REPLY);
431 }
432
433 static void
434 vl_api_one_nsh_set_locator_set_t_handler (vl_api_one_nsh_set_locator_set_t
435                                           * mp)
436 {
437   vl_api_one_nsh_set_locator_set_reply_t *rmp;
438   int rv = 0;
439   u8 *ls_name = 0;
440
441   ls_name = format (0, "%s", mp->ls_name);
442   rv = vnet_lisp_nsh_set_locator_set (ls_name, mp->is_add);
443   vec_free (ls_name);
444
445   REPLY_MACRO (VL_API_ONE_PITR_SET_LOCATOR_SET_REPLY);
446 }
447
448 static void
449 vl_api_one_pitr_set_locator_set_t_handler (vl_api_one_pitr_set_locator_set_t
450                                            * mp)
451 {
452   vl_api_one_pitr_set_locator_set_reply_t *rmp;
453   int rv = 0;
454   u8 *ls_name = 0;
455
456   ls_name = format (0, "%s", mp->ls_name);
457   rv = vnet_lisp_pitr_set_locator_set (ls_name, mp->is_add);
458   vec_free (ls_name);
459
460   REPLY_MACRO (VL_API_ONE_PITR_SET_LOCATOR_SET_REPLY);
461 }
462
463 static void
464 vl_api_one_use_petr_t_handler (vl_api_one_use_petr_t * mp)
465 {
466   vl_api_one_use_petr_reply_t *rmp;
467   int rv = 0;
468   ip_address_t addr;
469
470   ip_address_set (&addr, &mp->address, mp->is_ip4 ? IP4 : IP6);
471   rv = vnet_lisp_use_petr (&addr, mp->is_add);
472
473   REPLY_MACRO (VL_API_ONE_USE_PETR_REPLY);
474 }
475
476 static void
477 vl_api_show_one_use_petr_t_handler (vl_api_show_one_use_petr_t * mp)
478 {
479   unix_shared_memory_queue_t *q = NULL;
480   vl_api_show_one_use_petr_reply_t *rmp = NULL;
481   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
482   mapping_t *m;
483   locator_set_t *ls = 0;
484   int rv = 0;
485   locator_t *loc = 0;
486   u8 status = 0;
487   gid_address_t addr;
488
489   q = vl_api_client_index_to_input_queue (mp->client_index);
490   if (q == 0)
491     {
492       return;
493     }
494
495   memset (&addr, 0, sizeof (addr));
496   status = lcm->flags & LISP_FLAG_USE_PETR;
497   if (status)
498     {
499       m = pool_elt_at_index (lcm->mapping_pool, lcm->petr_map_index);
500       if (~0 != m->locator_set_index)
501         {
502           ls =
503             pool_elt_at_index (lcm->locator_set_pool, m->locator_set_index);
504           loc = pool_elt_at_index (lcm->locator_pool, ls->locator_indices[0]);
505           gid_address_copy (&addr, &loc->address);
506         }
507     }
508
509   /* *INDENT-OFF* */
510   REPLY_MACRO2 (VL_API_SHOW_ONE_USE_PETR_REPLY,
511   {
512     rmp->status = status;
513     ip_address_t *ip = &gid_address_ip (&addr);
514     switch (ip_addr_version (ip))
515       {
516       case IP4:
517         clib_memcpy (rmp->address, &ip_addr_v4 (ip),
518                      sizeof (ip_addr_v4 (ip)));
519         break;
520
521       case IP6:
522         clib_memcpy (rmp->address, &ip_addr_v6 (ip),
523                      sizeof (ip_addr_v6 (ip)));
524         break;
525
526       default:
527         ASSERT (0);
528       }
529     rmp->is_ip4 = (gid_address_ip_version (&addr) == IP4);
530   });
531   /* *INDENT-ON* */
532 }
533
534 static void
535   vl_api_one_add_del_map_request_itr_rlocs_t_handler
536   (vl_api_one_add_del_map_request_itr_rlocs_t * mp)
537 {
538   vl_api_one_add_del_map_request_itr_rlocs_reply_t *rmp;
539   int rv = 0;
540   u8 *locator_set_name = NULL;
541   vnet_lisp_add_del_mreq_itr_rloc_args_t _a, *a = &_a;
542
543   locator_set_name = format (0, "%s", mp->locator_set_name);
544
545   a->is_add = mp->is_add;
546   a->locator_set_name = locator_set_name;
547
548   rv = vnet_lisp_add_del_mreq_itr_rlocs (a);
549
550   vec_free (locator_set_name);
551
552   REPLY_MACRO (VL_API_ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY);
553 }
554
555 static void
556   vl_api_one_add_del_remote_mapping_t_handler
557   (vl_api_one_add_del_remote_mapping_t * mp)
558 {
559   locator_t *rlocs = 0;
560   vl_api_one_add_del_remote_mapping_reply_t *rmp;
561   int rv = 0;
562   gid_address_t _eid, *eid = &_eid;
563   u32 rloc_num = clib_net_to_host_u32 (mp->rloc_num);
564
565   memset (eid, 0, sizeof (eid[0]));
566
567   rv = unformat_one_eid_api (eid, clib_net_to_host_u32 (mp->vni),
568                              mp->eid_type, mp->eid, mp->eid_len);
569   if (rv)
570     goto send_reply;
571
572   rlocs = unformat_one_locs (mp->rlocs, rloc_num);
573
574   if (!mp->is_add)
575     {
576       vnet_lisp_add_del_adjacency_args_t _a, *a = &_a;
577       gid_address_copy (&a->reid, eid);
578       a->is_add = 0;
579       rv = vnet_lisp_add_del_adjacency (a);
580       if (rv)
581         {
582           goto out;
583         }
584     }
585
586   /* NOTE: for now this works as a static remote mapping, i.e.,
587    * not authoritative and ttl infinite. */
588   rv = vnet_lisp_add_del_mapping (eid, rlocs, mp->action, 0, ~0,
589                                   mp->is_add, 1 /* is_static */ , 0);
590
591   if (mp->del_all)
592     vnet_lisp_clear_all_remote_adjacencies ();
593
594 out:
595   vec_free (rlocs);
596 send_reply:
597   REPLY_MACRO (VL_API_ONE_ADD_DEL_REMOTE_MAPPING_REPLY);
598 }
599
600 static void
601 vl_api_one_add_del_adjacency_t_handler (vl_api_one_add_del_adjacency_t * mp)
602 {
603   vl_api_one_add_del_adjacency_reply_t *rmp;
604   vnet_lisp_add_del_adjacency_args_t _a, *a = &_a;
605
606   int rv = 0;
607   memset (a, 0, sizeof (a[0]));
608
609   rv = unformat_one_eid_api (&a->leid, clib_net_to_host_u32 (mp->vni),
610                              mp->eid_type, mp->leid, mp->leid_len);
611   rv |= unformat_one_eid_api (&a->reid, clib_net_to_host_u32 (mp->vni),
612                               mp->eid_type, mp->reid, mp->reid_len);
613
614   if (rv)
615     goto send_reply;
616
617   a->is_add = mp->is_add;
618   rv = vnet_lisp_add_del_adjacency (a);
619
620 send_reply:
621   REPLY_MACRO (VL_API_ONE_ADD_DEL_ADJACENCY_REPLY);
622 }
623
624 static void
625 send_one_locator_details (lisp_cp_main_t * lcm,
626                           locator_t * loc,
627                           unix_shared_memory_queue_t * q, u32 context)
628 {
629   vl_api_one_locator_details_t *rmp;
630
631   rmp = vl_msg_api_alloc (sizeof (*rmp));
632   memset (rmp, 0, sizeof (*rmp));
633   rmp->_vl_msg_id = ntohs (VL_API_ONE_LOCATOR_DETAILS);
634   rmp->context = context;
635
636   rmp->local = loc->local;
637   if (loc->local)
638     {
639       rmp->sw_if_index = ntohl (loc->sw_if_index);
640     }
641   else
642     {
643       rmp->is_ipv6 = gid_address_ip_version (&loc->address);
644       ip_address_copy_addr (rmp->ip_address, &gid_address_ip (&loc->address));
645     }
646   rmp->priority = loc->priority;
647   rmp->weight = loc->weight;
648
649   vl_msg_api_send_shmem (q, (u8 *) & rmp);
650 }
651
652 static void
653 vl_api_one_locator_dump_t_handler (vl_api_one_locator_dump_t * mp)
654 {
655   u8 *ls_name = 0;
656   unix_shared_memory_queue_t *q = 0;
657   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
658   locator_set_t *lsit = 0;
659   locator_t *loc = 0;
660   u32 ls_index = ~0, *locit = 0;
661   uword *p = 0;
662
663   q = vl_api_client_index_to_input_queue (mp->client_index);
664   if (q == 0)
665     {
666       return;
667     }
668
669   if (mp->is_index_set)
670     ls_index = htonl (mp->ls_index);
671   else
672     {
673       /* make sure we get a proper C-string */
674       mp->ls_name[sizeof (mp->ls_name) - 1] = 0;
675       ls_name = format (0, "%s", mp->ls_name);
676       p = hash_get_mem (lcm->locator_set_index_by_name, ls_name);
677       if (!p)
678         goto out;
679       ls_index = p[0];
680     }
681
682   if (pool_is_free_index (lcm->locator_set_pool, ls_index))
683     return;
684
685   lsit = pool_elt_at_index (lcm->locator_set_pool, ls_index);
686
687   vec_foreach (locit, lsit->locator_indices)
688   {
689     loc = pool_elt_at_index (lcm->locator_pool, locit[0]);
690     send_one_locator_details (lcm, loc, q, mp->context);
691   };
692 out:
693   vec_free (ls_name);
694 }
695
696 static void
697 send_one_locator_set_details (lisp_cp_main_t * lcm,
698                               locator_set_t * lsit,
699                               unix_shared_memory_queue_t * q,
700                               u32 context, u32 ls_index)
701 {
702   vl_api_one_locator_set_details_t *rmp;
703   u8 *str = 0;
704
705   rmp = vl_msg_api_alloc (sizeof (*rmp));
706   memset (rmp, 0, sizeof (*rmp));
707   rmp->_vl_msg_id = ntohs (VL_API_ONE_LOCATOR_SET_DETAILS);
708   rmp->context = context;
709
710   rmp->ls_index = htonl (ls_index);
711   if (lsit->local)
712     {
713       ASSERT (lsit->name != NULL);
714       strncpy ((char *) rmp->ls_name, (char *) lsit->name,
715                vec_len (lsit->name));
716     }
717   else
718     {
719       str = format (0, "<remote-%d>", ls_index);
720       strncpy ((char *) rmp->ls_name, (char *) str, vec_len (str));
721       vec_free (str);
722     }
723
724   vl_msg_api_send_shmem (q, (u8 *) & rmp);
725 }
726
727 static void
728 vl_api_one_locator_set_dump_t_handler (vl_api_one_locator_set_dump_t * mp)
729 {
730   unix_shared_memory_queue_t *q = NULL;
731   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
732   locator_set_t *lsit = NULL;
733   u8 filter;
734
735   q = vl_api_client_index_to_input_queue (mp->client_index);
736   if (q == 0)
737     {
738       return;
739     }
740
741   filter = mp->filter;
742   /* *INDENT-OFF* */
743   pool_foreach (lsit, lcm->locator_set_pool,
744   ({
745     if (filter && !((1 == filter && lsit->local) ||
746                     (2 == filter && !lsit->local)))
747       {
748         continue;
749       }
750     send_one_locator_set_details (lcm, lsit, q, mp->context,
751                                    lsit - lcm->locator_set_pool);
752   }));
753   /* *INDENT-ON* */
754 }
755
756 static void
757 one_fid_put_api (u8 * dst, fid_address_t * src, u8 * prefix_length)
758 {
759   ASSERT (prefix_length);
760   ip_prefix_t *ippref = &fid_addr_ippref (src);
761
762   switch (fid_addr_type (src))
763     {
764     case FID_ADDR_IP_PREF:
765       if (ip_prefix_version (ippref) == IP4)
766         clib_memcpy (dst, &ip_prefix_v4 (ippref), 4);
767       else
768         clib_memcpy (dst, &ip_prefix_v6 (ippref), 16);
769       prefix_length[0] = ip_prefix_len (ippref);
770       break;
771
772     case FID_ADDR_MAC:
773       prefix_length[0] = 0;
774       clib_memcpy (dst, fid_addr_mac (src), 6);
775       break;
776
777     default:
778       clib_warning ("Unknown FID type %d!", fid_addr_type (src));
779       break;
780     }
781 }
782
783 static u8
784 fid_type_to_api_type (fid_address_t * fid)
785 {
786   ip_prefix_t *ippref;
787
788   switch (fid_addr_type (fid))
789     {
790     case FID_ADDR_IP_PREF:
791       ippref = &fid_addr_ippref (fid);
792       if (ip_prefix_version (ippref) == IP4)
793         return 0;
794       else if (ip_prefix_version (ippref) == IP6)
795         return 1;
796       else
797         return ~0;
798
799     case FID_ADDR_MAC:
800       return 2;
801     case FID_ADDR_NSH:
802       return 3;
803     }
804
805   return ~0;
806 }
807
808 static void
809 send_one_eid_table_details (mapping_t * mapit,
810                             unix_shared_memory_queue_t * q,
811                             u32 context, u8 filter)
812 {
813   fid_address_t *fid;
814   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
815   locator_set_t *ls = 0;
816   vl_api_one_eid_table_details_t *rmp = NULL;
817   gid_address_t *gid = NULL;
818   u8 *mac = 0;
819   ip_prefix_t *ip_prefix = NULL;
820
821   if (mapit->pitr_set || mapit->nsh_set)
822     return;
823
824   switch (filter)
825     {
826     case 0:                     /* all mappings */
827       break;
828
829     case 1:                     /* local only */
830       if (!mapit->local)
831         return;
832       break;
833     case 2:                     /* remote only */
834       if (mapit->local)
835         return;
836       break;
837     default:
838       clib_warning ("Filter error, unknown filter: %d", filter);
839       return;
840     }
841
842   gid = &mapit->eid;
843   ip_prefix = &gid_address_ippref (gid);
844   mac = gid_address_mac (gid);
845
846   rmp = vl_msg_api_alloc (sizeof (*rmp));
847   memset (rmp, 0, sizeof (*rmp));
848   rmp->_vl_msg_id = ntohs (VL_API_ONE_EID_TABLE_DETAILS);
849
850   ls = pool_elt_at_index (lcm->locator_set_pool, mapit->locator_set_index);
851   if (vec_len (ls->locator_indices) == 0)
852     rmp->locator_set_index = ~0;
853   else
854     rmp->locator_set_index = clib_host_to_net_u32 (mapit->locator_set_index);
855
856   rmp->is_local = mapit->local;
857   rmp->ttl = clib_host_to_net_u32 (mapit->ttl);
858   rmp->action = mapit->action;
859   rmp->authoritative = mapit->authoritative;
860
861   switch (gid_address_type (gid))
862     {
863     case GID_ADDR_SRC_DST:
864       rmp->is_src_dst = 1;
865       fid = &gid_address_sd_src (gid);
866       rmp->eid_type = fid_type_to_api_type (fid);
867       one_fid_put_api (rmp->seid, &gid_address_sd_src (gid),
868                        &rmp->seid_prefix_len);
869       one_fid_put_api (rmp->eid, &gid_address_sd_dst (gid),
870                        &rmp->eid_prefix_len);
871       break;
872     case GID_ADDR_IP_PREFIX:
873       rmp->eid_prefix_len = ip_prefix_len (ip_prefix);
874       if (ip_prefix_version (ip_prefix) == IP4)
875         {
876           rmp->eid_type = 0;    /* ipv4 type */
877           clib_memcpy (rmp->eid, &ip_prefix_v4 (ip_prefix),
878                        sizeof (ip_prefix_v4 (ip_prefix)));
879         }
880       else
881         {
882           rmp->eid_type = 1;    /* ipv6 type */
883           clib_memcpy (rmp->eid, &ip_prefix_v6 (ip_prefix),
884                        sizeof (ip_prefix_v6 (ip_prefix)));
885         }
886       break;
887     case GID_ADDR_MAC:
888       rmp->eid_type = 2;        /* l2 mac type */
889       clib_memcpy (rmp->eid, mac, 6);
890       break;
891     case GID_ADDR_NSH:
892       rmp->eid_type = 3;        /* NSH type */
893       lisp_nsh_api_t nsh;
894       nsh.spi = clib_host_to_net_u32 (gid_address_nsh_spi (gid));
895       nsh.si = gid_address_nsh_si (gid);
896       clib_memcpy (rmp->eid, &nsh, sizeof (nsh));
897       break;
898     default:
899       ASSERT (0);
900     }
901   rmp->context = context;
902   rmp->vni = clib_host_to_net_u32 (gid_address_vni (gid));
903   rmp->key_id = clib_host_to_net_u16 (mapit->key_id);
904   memcpy (rmp->key, mapit->key, vec_len (mapit->key));
905   vl_msg_api_send_shmem (q, (u8 *) & rmp);
906 }
907
908 static void
909 vl_api_one_eid_table_dump_t_handler (vl_api_one_eid_table_dump_t * mp)
910 {
911   u32 mi;
912   unix_shared_memory_queue_t *q = NULL;
913   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
914   mapping_t *mapit = NULL;
915   gid_address_t _eid, *eid = &_eid;
916
917   q = vl_api_client_index_to_input_queue (mp->client_index);
918   if (q == 0)
919     {
920       return;
921     }
922
923   if (mp->eid_set)
924     {
925       memset (eid, 0, sizeof (*eid));
926
927       unformat_one_eid_api (eid, clib_net_to_host_u32 (mp->vni),
928                             mp->eid_type, mp->eid, mp->prefix_length);
929
930       mi = gid_dictionary_lookup (&lcm->mapping_index_by_gid, eid);
931       if ((u32) ~ 0 == mi)
932         return;
933
934       mapit = pool_elt_at_index (lcm->mapping_pool, mi);
935       send_one_eid_table_details (mapit, q, mp->context,
936                                   0 /* ignore filter */ );
937     }
938   else
939     {
940       /* *INDENT-OFF* */
941       pool_foreach (mapit, lcm->mapping_pool,
942       ({
943         send_one_eid_table_details(mapit, q, mp->context,
944                                     mp->filter);
945       }));
946       /* *INDENT-ON* */
947     }
948 }
949
950 static void
951 send_one_map_server_details (ip_address_t * ip,
952                              unix_shared_memory_queue_t * q, u32 context)
953 {
954   vl_api_one_map_server_details_t *rmp = NULL;
955
956   rmp = vl_msg_api_alloc (sizeof (*rmp));
957   memset (rmp, 0, sizeof (*rmp));
958   rmp->_vl_msg_id = ntohs (VL_API_ONE_MAP_SERVER_DETAILS);
959
960   switch (ip_addr_version (ip))
961     {
962     case IP4:
963       rmp->is_ipv6 = 0;
964       clib_memcpy (rmp->ip_address, &ip_addr_v4 (ip),
965                    sizeof (ip_addr_v4 (ip)));
966       break;
967
968     case IP6:
969       rmp->is_ipv6 = 1;
970       clib_memcpy (rmp->ip_address, &ip_addr_v6 (ip),
971                    sizeof (ip_addr_v6 (ip)));
972       break;
973
974     default:
975       ASSERT (0);
976     }
977   rmp->context = context;
978
979   vl_msg_api_send_shmem (q, (u8 *) & rmp);
980 }
981
982 static void
983 vl_api_one_map_server_dump_t_handler (vl_api_one_map_server_dump_t * mp)
984 {
985   unix_shared_memory_queue_t *q = NULL;
986   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
987   lisp_msmr_t *mr;
988
989   q = vl_api_client_index_to_input_queue (mp->client_index);
990   if (q == 0)
991     {
992       return;
993     }
994
995   vec_foreach (mr, lcm->map_servers)
996   {
997     send_one_map_server_details (&mr->address, q, mp->context);
998   }
999 }
1000
1001 static void
1002 send_one_map_resolver_details (ip_address_t * ip,
1003                                unix_shared_memory_queue_t * q, u32 context)
1004 {
1005   vl_api_one_map_resolver_details_t *rmp = NULL;
1006
1007   rmp = vl_msg_api_alloc (sizeof (*rmp));
1008   memset (rmp, 0, sizeof (*rmp));
1009   rmp->_vl_msg_id = ntohs (VL_API_ONE_MAP_RESOLVER_DETAILS);
1010
1011   switch (ip_addr_version (ip))
1012     {
1013     case IP4:
1014       rmp->is_ipv6 = 0;
1015       clib_memcpy (rmp->ip_address, &ip_addr_v4 (ip),
1016                    sizeof (ip_addr_v4 (ip)));
1017       break;
1018
1019     case IP6:
1020       rmp->is_ipv6 = 1;
1021       clib_memcpy (rmp->ip_address, &ip_addr_v6 (ip),
1022                    sizeof (ip_addr_v6 (ip)));
1023       break;
1024
1025     default:
1026       ASSERT (0);
1027     }
1028   rmp->context = context;
1029
1030   vl_msg_api_send_shmem (q, (u8 *) & rmp);
1031 }
1032
1033 static void
1034 vl_api_one_map_resolver_dump_t_handler (vl_api_one_map_resolver_dump_t * mp)
1035 {
1036   unix_shared_memory_queue_t *q = NULL;
1037   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
1038   lisp_msmr_t *mr;
1039
1040   q = vl_api_client_index_to_input_queue (mp->client_index);
1041   if (q == 0)
1042     {
1043       return;
1044     }
1045
1046   vec_foreach (mr, lcm->map_resolvers)
1047   {
1048     send_one_map_resolver_details (&mr->address, q, mp->context);
1049   }
1050 }
1051
1052 static void
1053 send_eid_table_map_pair (hash_pair_t * p,
1054                          unix_shared_memory_queue_t * q, u32 context)
1055 {
1056   vl_api_one_eid_table_map_details_t *rmp = NULL;
1057
1058   rmp = vl_msg_api_alloc (sizeof (*rmp));
1059   memset (rmp, 0, sizeof (*rmp));
1060   rmp->_vl_msg_id = ntohs (VL_API_ONE_EID_TABLE_MAP_DETAILS);
1061
1062   rmp->vni = clib_host_to_net_u32 (p->key);
1063   rmp->dp_table = clib_host_to_net_u32 (p->value[0]);
1064   rmp->context = context;
1065   vl_msg_api_send_shmem (q, (u8 *) & rmp);
1066 }
1067
1068 static void
1069 vl_api_one_eid_table_map_dump_t_handler (vl_api_one_eid_table_map_dump_t * mp)
1070 {
1071   unix_shared_memory_queue_t *q = NULL;
1072   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
1073   hash_pair_t *p;
1074   uword *vni_table = 0;
1075
1076   q = vl_api_client_index_to_input_queue (mp->client_index);
1077   if (q == 0)
1078     {
1079       return;
1080     }
1081
1082   if (mp->is_l2)
1083     {
1084       vni_table = lcm->bd_id_by_vni;
1085     }
1086   else
1087     {
1088       vni_table = lcm->table_id_by_vni;
1089     }
1090
1091   /* *INDENT-OFF* */
1092   hash_foreach_pair (p, vni_table,
1093   ({
1094     send_eid_table_map_pair (p, q, mp->context);
1095   }));
1096   /* *INDENT-ON* */
1097 }
1098
1099 static void
1100 send_eid_table_vni (u32 vni, unix_shared_memory_queue_t * q, u32 context)
1101 {
1102   vl_api_one_eid_table_vni_details_t *rmp = 0;
1103
1104   rmp = vl_msg_api_alloc (sizeof (*rmp));
1105   memset (rmp, 0, sizeof (*rmp));
1106   rmp->_vl_msg_id = ntohs (VL_API_ONE_EID_TABLE_VNI_DETAILS);
1107   rmp->context = context;
1108   rmp->vni = clib_host_to_net_u32 (vni);
1109   vl_msg_api_send_shmem (q, (u8 *) & rmp);
1110 }
1111
1112 static void
1113 one_adjacency_copy (vl_api_one_adjacency_t * dst, lisp_adjacency_t * adjs)
1114 {
1115   lisp_adjacency_t *adj;
1116   vl_api_one_adjacency_t a;
1117   u32 i, n = vec_len (adjs);
1118   lisp_nsh_api_t nsh;
1119
1120   for (i = 0; i < n; i++)
1121     {
1122       adj = vec_elt_at_index (adjs, i);
1123       memset (&a, 0, sizeof (a));
1124
1125       switch (gid_address_type (&adj->reid))
1126         {
1127         case GID_ADDR_IP_PREFIX:
1128           a.reid_prefix_len = gid_address_ippref_len (&adj->reid);
1129           a.leid_prefix_len = gid_address_ippref_len (&adj->leid);
1130           if (gid_address_ip_version (&adj->reid) == IP4)
1131             {
1132               a.eid_type = 0;   /* ipv4 type */
1133               clib_memcpy (a.reid, &gid_address_ip (&adj->reid), 4);
1134               clib_memcpy (a.leid, &gid_address_ip (&adj->leid), 4);
1135             }
1136           else
1137             {
1138               a.eid_type = 1;   /* ipv6 type */
1139               clib_memcpy (a.reid, &gid_address_ip (&adj->reid), 16);
1140               clib_memcpy (a.leid, &gid_address_ip (&adj->leid), 16);
1141             }
1142           break;
1143         case GID_ADDR_MAC:
1144           a.eid_type = 2;       /* l2 mac type */
1145           mac_copy (a.reid, gid_address_mac (&adj->reid));
1146           mac_copy (a.leid, gid_address_mac (&adj->leid));
1147           break;
1148         case GID_ADDR_NSH:
1149           a.eid_type = 3;       /* NSH type */
1150           nsh.spi = clib_host_to_net_u32 (gid_address_nsh_spi (&adj->reid));
1151           nsh.si = gid_address_nsh_si (&adj->reid);
1152           clib_memcpy (a.reid, &nsh, sizeof (nsh));
1153
1154           nsh.spi = clib_host_to_net_u32 (gid_address_nsh_spi (&adj->leid));
1155           nsh.si = gid_address_nsh_si (&adj->leid);
1156           clib_memcpy (a.leid, &nsh, sizeof (nsh));
1157         default:
1158           ASSERT (0);
1159         }
1160       dst[i] = a;
1161     }
1162 }
1163
1164 static void
1165   vl_api_show_one_rloc_probe_state_t_handler
1166   (vl_api_show_one_rloc_probe_state_t * mp)
1167 {
1168   vl_api_show_one_rloc_probe_state_reply_t *rmp = 0;
1169   int rv = 0;
1170
1171   /* *INDENT-OFF* */
1172   REPLY_MACRO2 (VL_API_SHOW_ONE_RLOC_PROBE_STATE_REPLY,
1173   {
1174     rmp->is_enabled = vnet_lisp_rloc_probe_state_get ();
1175   });
1176   /* *INDENT-ON* */
1177 }
1178
1179 static void
1180   vl_api_show_one_map_register_state_t_handler
1181   (vl_api_show_one_map_register_state_t * mp)
1182 {
1183   vl_api_show_one_map_register_state_reply_t *rmp = 0;
1184   int rv = 0;
1185
1186   /* *INDENT-OFF* */
1187   REPLY_MACRO2 (VL_API_SHOW_ONE_MAP_REGISTER_STATE_REPLY,
1188   {
1189     rmp->is_enabled = vnet_lisp_map_register_state_get ();
1190   });
1191   /* *INDENT-ON* */
1192 }
1193
1194 static void
1195 vl_api_one_adjacencies_get_t_handler (vl_api_one_adjacencies_get_t * mp)
1196 {
1197   vl_api_one_adjacencies_get_reply_t *rmp = 0;
1198   lisp_adjacency_t *adjs = 0;
1199   int rv = 0;
1200   u32 size = ~0;
1201   u32 vni = clib_net_to_host_u32 (mp->vni);
1202
1203   adjs = vnet_lisp_adjacencies_get_by_vni (vni);
1204   size = vec_len (adjs) * sizeof (vl_api_one_adjacency_t);
1205
1206   /* *INDENT-OFF* */
1207   REPLY_MACRO4 (VL_API_ONE_ADJACENCIES_GET_REPLY, size,
1208   {
1209     rmp->count = clib_host_to_net_u32 (vec_len (adjs));
1210     one_adjacency_copy (rmp->adjacencies, adjs);
1211   });
1212   /* *INDENT-ON* */
1213
1214   vec_free (adjs);
1215 }
1216
1217 static void
1218 vl_api_one_eid_table_vni_dump_t_handler (vl_api_one_eid_table_vni_dump_t * mp)
1219 {
1220   hash_pair_t *p;
1221   u32 *vnis = 0;
1222   unix_shared_memory_queue_t *q = 0;
1223   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
1224
1225   q = vl_api_client_index_to_input_queue (mp->client_index);
1226   if (q == 0)
1227     {
1228       return;
1229     }
1230
1231   /* *INDENT-OFF* */
1232   hash_foreach_pair (p, lcm->table_id_by_vni,
1233   ({
1234     hash_set (vnis, p->key, 0);
1235   }));
1236
1237   hash_foreach_pair (p, lcm->bd_id_by_vni,
1238   ({
1239     hash_set (vnis, p->key, 0);
1240   }));
1241
1242   hash_foreach_pair (p, vnis,
1243   ({
1244     send_eid_table_vni (p->key, q, mp->context);
1245   }));
1246   /* *INDENT-ON* */
1247
1248   hash_free (vnis);
1249 }
1250
1251 static void
1252 vl_api_show_one_status_t_handler (vl_api_show_one_status_t * mp)
1253 {
1254   unix_shared_memory_queue_t *q = NULL;
1255   vl_api_show_one_status_reply_t *rmp = NULL;
1256   int rv = 0;
1257
1258   q = vl_api_client_index_to_input_queue (mp->client_index);
1259   if (q == 0)
1260     {
1261       return;
1262     }
1263
1264   /* *INDENT-OFF* */
1265   REPLY_MACRO2(VL_API_SHOW_ONE_STATUS_REPLY,
1266   ({
1267     rmp->gpe_status = vnet_lisp_gpe_enable_disable_status ();
1268     rmp->feature_status = vnet_lisp_enable_disable_status ();
1269   }));
1270   /* *INDENT-ON* */
1271 }
1272
1273 static void
1274   vl_api_one_get_map_request_itr_rlocs_t_handler
1275   (vl_api_one_get_map_request_itr_rlocs_t * mp)
1276 {
1277   unix_shared_memory_queue_t *q = NULL;
1278   vl_api_one_get_map_request_itr_rlocs_reply_t *rmp = NULL;
1279   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
1280   locator_set_t *loc_set = 0;
1281   u8 *tmp_str = 0;
1282   int rv = 0;
1283
1284   q = vl_api_client_index_to_input_queue (mp->client_index);
1285   if (q == 0)
1286     {
1287       return;
1288     }
1289
1290   if (~0 == lcm->mreq_itr_rlocs)
1291     {
1292       tmp_str = format (0, " ");
1293     }
1294   else
1295     {
1296       loc_set =
1297         pool_elt_at_index (lcm->locator_set_pool, lcm->mreq_itr_rlocs);
1298       tmp_str = format (0, "%s", loc_set->name);
1299     }
1300
1301   /* *INDENT-OFF* */
1302   REPLY_MACRO2(VL_API_ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,
1303   ({
1304     strncpy((char *) rmp->locator_set_name, (char *) tmp_str,
1305             ARRAY_LEN(rmp->locator_set_name) - 1);
1306   }));
1307   /* *INDENT-ON* */
1308
1309   vec_free (tmp_str);
1310 }
1311
1312 static void
1313 vl_api_show_one_nsh_mapping_t_handler (vl_api_show_one_nsh_mapping_t * mp)
1314 {
1315   unix_shared_memory_queue_t *q = NULL;
1316   vl_api_show_one_nsh_mapping_reply_t *rmp = NULL;
1317   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
1318   mapping_t *m;
1319   locator_set_t *ls = 0;
1320   u8 *tmp_str = 0;
1321   u8 is_set = 0;
1322   int rv = 0;
1323
1324   q = vl_api_client_index_to_input_queue (mp->client_index);
1325   if (q == 0)
1326     {
1327       return;
1328     }
1329
1330   if (lcm->nsh_map_index == (u32) ~ 0)
1331     {
1332       tmp_str = format (0, "N/A");
1333     }
1334   else
1335     {
1336       m = pool_elt_at_index (lcm->mapping_pool, lcm->nsh_map_index);
1337       if (~0 != m->locator_set_index)
1338         {
1339           ls =
1340             pool_elt_at_index (lcm->locator_set_pool, m->locator_set_index);
1341           tmp_str = format (0, "%s", ls->name);
1342           is_set = 1;
1343         }
1344       else
1345         {
1346           tmp_str = format (0, "N/A");
1347         }
1348     }
1349   vec_add1 (tmp_str, 0);
1350
1351   /* *INDENT-OFF* */
1352   REPLY_MACRO2(VL_API_SHOW_ONE_NSH_MAPPING_REPLY,
1353   ({
1354     rmp->is_set = is_set;
1355     strncpy((char *) rmp->locator_set_name, (char *) tmp_str,
1356             ARRAY_LEN(rmp->locator_set_name) - 1);
1357   }));
1358   /* *INDENT-ON* */
1359 }
1360
1361 static void
1362 vl_api_show_one_pitr_t_handler (vl_api_show_one_pitr_t * mp)
1363 {
1364   unix_shared_memory_queue_t *q = NULL;
1365   vl_api_show_one_pitr_reply_t *rmp = NULL;
1366   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
1367   mapping_t *m;
1368   locator_set_t *ls = 0;
1369   u8 *tmp_str = 0;
1370   int rv = 0;
1371
1372   q = vl_api_client_index_to_input_queue (mp->client_index);
1373   if (q == 0)
1374     {
1375       return;
1376     }
1377
1378   if (!lcm->lisp_pitr)
1379     {
1380       tmp_str = format (0, "N/A");
1381     }
1382   else
1383     {
1384       m = pool_elt_at_index (lcm->mapping_pool, lcm->pitr_map_index);
1385       if (~0 != m->locator_set_index)
1386         {
1387           ls =
1388             pool_elt_at_index (lcm->locator_set_pool, m->locator_set_index);
1389           tmp_str = format (0, "%s", ls->name);
1390         }
1391       else
1392         {
1393           tmp_str = format (0, "N/A");
1394         }
1395     }
1396   vec_add1 (tmp_str, 0);
1397
1398   /* *INDENT-OFF* */
1399   REPLY_MACRO2(VL_API_SHOW_ONE_PITR_REPLY,
1400   ({
1401     rmp->status = lcm->lisp_pitr;
1402     strncpy((char *) rmp->locator_set_name, (char *) tmp_str,
1403             ARRAY_LEN(rmp->locator_set_name) - 1);
1404   }));
1405   /* *INDENT-ON* */
1406 }
1407
1408 static void
1409   vl_api_show_one_stats_enable_disable_t_handler
1410   (vl_api_show_one_stats_enable_disable_t * mp)
1411 {
1412   vl_api_show_one_stats_enable_disable_reply_t *rmp = NULL;
1413   vnet_api_error_t rv = 0;
1414
1415   /* *INDENT-OFF* */
1416   REPLY_MACRO2 (VL_API_SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,
1417   ({
1418     rmp->is_en = vnet_lisp_stats_enable_disable_state ();
1419   }));
1420   /* *INDENT-ON* */
1421 }
1422
1423 static void
1424   vl_api_one_stats_enable_disable_t_handler
1425   (vl_api_one_stats_enable_disable_t * mp)
1426 {
1427   vl_api_one_enable_disable_reply_t *rmp = NULL;
1428
1429   vnet_api_error_t rv = vnet_lisp_stats_enable_disable (mp->is_en);
1430   REPLY_MACRO (VL_API_ONE_ENABLE_DISABLE_REPLY);
1431 }
1432
1433 static void
1434 lisp_fid_addr_to_api (fid_address_t * fid, u8 * dst, u8 * api_eid_type,
1435                       u8 * prefix_length)
1436 {
1437   switch (fid_addr_type (fid))
1438     {
1439     case FID_ADDR_IP_PREF:
1440       *prefix_length = fid_addr_prefix_length (fid);
1441       if (fid_addr_ip_version (fid) == IP4)
1442         {
1443           *api_eid_type = 0;    /* ipv4 type */
1444           clib_memcpy (dst, &fid_addr_ippref (fid), 4);
1445         }
1446       else
1447         {
1448           *api_eid_type = 1;    /* ipv6 type */
1449           clib_memcpy (dst, &fid_addr_ippref (fid), 16);
1450         }
1451       break;
1452     case FID_ADDR_MAC:
1453       *api_eid_type = 2;        /* l2 mac type */
1454       mac_copy (dst, fid_addr_mac (fid));
1455       break;
1456     default:
1457       ASSERT (0);
1458     }
1459 }
1460
1461 static void
1462 vl_api_one_stats_flush_t_handler (vl_api_one_stats_flush_t * mp)
1463 {
1464   vl_api_one_stats_flush_reply_t *rmp;
1465   u8 rv;
1466
1467   rv = vnet_lisp_flush_stats ();
1468   REPLY_MACRO (VL_API_ONE_STATS_FLUSH_REPLY);
1469 }
1470
1471 static void
1472 vl_api_one_stats_dump_t_handler (vl_api_one_stats_dump_t * mp)
1473 {
1474   vl_api_one_stats_details_t *rmp;
1475   lisp_api_stats_t *stats, *stat;
1476   u8 rv = 0;
1477
1478   stats = vnet_lisp_get_stats ();
1479   vec_foreach (stat, stats)
1480   {
1481       /* *INDENT-OFF* */
1482       REPLY_DETAILS (VL_API_ONE_STATS_DETAILS,
1483       ({
1484         lisp_fid_addr_to_api (&stat->deid, rmp->deid, &rmp->eid_type,
1485                               &rmp->deid_pref_len);
1486         lisp_fid_addr_to_api (&stat->seid, rmp->seid, &rmp->eid_type,
1487                               &rmp->seid_pref_len);
1488         rmp->vni = clib_host_to_net_u32 (stat->vni);
1489
1490         rmp->is_ip4 = ip_addr_version (&stat->rmt_rloc) == IP4 ? 1 : 0;
1491         ip_address_copy_addr (rmp->rloc, &stat->rmt_rloc);
1492         ip_address_copy_addr (rmp->lloc, &stat->loc_rloc);
1493
1494         rmp->pkt_count = clib_host_to_net_u32 (stat->counters.packets);
1495         rmp->bytes = clib_host_to_net_u32 (stat->counters.bytes);
1496       }));
1497       /* *INDENT-ON* */
1498   }
1499 }
1500
1501 static void
1502   vl_api_one_add_del_l2_arp_entry_t_handler
1503   (vl_api_one_add_del_l2_arp_entry_t * mp)
1504 {
1505   vl_api_one_add_del_l2_arp_entry_reply_t *rmp;
1506   int rv = 0;
1507   gid_address_t _arp, *arp = &_arp;
1508   memset (arp, 0, sizeof (*arp));
1509
1510   gid_address_type (arp) = GID_ADDR_ARP;
1511   gid_address_arp_bd (arp) = clib_net_to_host_u32 (mp->bd);
1512
1513   /* vpp keeps ip4 addresses in network byte order */
1514   clib_memcpy (&gid_address_arp_ip4 (arp), &mp->ip4, 4);
1515
1516   rv = vnet_lisp_add_del_l2_arp_entry (arp, mp->mac, mp->is_add);
1517
1518   REPLY_MACRO (VL_API_ONE_ADD_DEL_L2_ARP_ENTRY_REPLY);
1519 }
1520
1521 static void
1522 vl_api_one_l2_arp_bd_get_t_handler (vl_api_one_l2_arp_bd_get_t * mp)
1523 {
1524   vl_api_one_l2_arp_bd_get_reply_t *rmp;
1525   int rv = 0;
1526   u32 i = 0;
1527   hash_pair_t *p;
1528
1529   u32 *bds = vnet_lisp_l2_arp_bds_get ();
1530   u32 size = hash_elts (bds) * sizeof (u32);
1531
1532   /* *INDENT-OFF* */
1533   REPLY_MACRO4 (VL_API_ONE_L2_ARP_BD_GET_REPLY, size,
1534   {
1535     rmp->count = clib_host_to_net_u32 (hash_elts (bds));
1536     hash_foreach_pair (p, bds,
1537     ({
1538       rmp->bridge_domains[i++] = clib_host_to_net_u32 (p->key);
1539     }));
1540   });
1541   /* *INDENT-ON* */
1542
1543   hash_free (bds);
1544 }
1545
1546 static void
1547 vl_api_one_l2_arp_entries_get_t_handler (vl_api_one_l2_arp_entries_get_t * mp)
1548 {
1549   vl_api_one_l2_arp_entries_get_reply_t *rmp;
1550   lisp_api_l2_arp_entry_t *entries = 0, *e;
1551   u32 i = 0;
1552   int rv = 0;
1553
1554   u32 bd = clib_net_to_host_u32 (mp->bd);
1555
1556   entries = vnet_lisp_l2_arp_entries_get_by_bd (bd);
1557   u32 size = vec_len (entries) * sizeof (u32);
1558
1559   /* *INDENT-OFF* */
1560   REPLY_MACRO4 (VL_API_ONE_L2_ARP_ENTRIES_GET_REPLY, size,
1561   {
1562     rmp->count = clib_host_to_net_u32 (vec_len (entries));
1563     vec_foreach (e, entries)
1564       {
1565         mac_copy (rmp->entries[i].mac, e->mac);
1566         rmp->entries[i].ip4 = e->ip4;
1567         i++;
1568       }
1569   });
1570   /* *INDENT-ON* */
1571
1572   vec_free (entries);
1573 }
1574
1575 /*
1576  * one_api_hookup
1577  * Add vpe's API message handlers to the table.
1578  * vlib has alread mapped shared memory and
1579  * added the client registration handlers.
1580  * See .../vlib-api/vlibmemory/memclnt_vlib.c:memclnt_process()
1581  */
1582 #define vl_msg_name_crc_list
1583 #include <vnet/vnet_all_api_h.h>
1584 #undef vl_msg_name_crc_list
1585
1586 static void
1587 setup_message_id_table (api_main_t * am)
1588 {
1589 #define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
1590   foreach_vl_msg_name_crc_one;
1591 #undef _
1592 }
1593
1594 static clib_error_t *
1595 one_api_hookup (vlib_main_t * vm)
1596 {
1597   api_main_t *am = &api_main;
1598
1599 #define _(N,n)                                                  \
1600     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
1601                            vl_api_##n##_t_handler,              \
1602                            vl_noop_handler,                     \
1603                            vl_api_##n##_t_endian,               \
1604                            vl_api_##n##_t_print,                \
1605                            sizeof(vl_api_##n##_t), 1);
1606   foreach_vpe_api_msg;
1607 #undef _
1608
1609   /*
1610    * Set up the (msg_name, crc, message-id) table
1611    */
1612   setup_message_id_table (am);
1613
1614   return 0;
1615 }
1616
1617 VLIB_API_INIT_FUNCTION (one_api_hookup);
1618
1619 /*
1620  * fd.io coding-style-patch-verification: ON
1621  *
1622  * Local Variables:
1623  * eval: (c-set-style "gnu")
1624  * End:
1625  */