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