api: multiple connections per process
[vpp.git] / src / vnet / lisp-cp / lisp_api.c
1 /*
2  *------------------------------------------------------------------
3  * lisp_api.c - lisp api
4  *
5  * Copyright (c) 2016 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
31 #define vl_api_lisp_add_del_locator_set_t_endian vl_noop_handler
32 #define vl_api_lisp_add_del_locator_set_t_print vl_noop_handler
33 #define vl_api_lisp_add_del_remote_mapping_t_endian vl_noop_handler
34 #define vl_api_lisp_add_del_remote_mapping_t_print vl_noop_handler
35
36 #define vl_api_one_add_del_locator_set_t_endian vl_noop_handler
37 #define vl_api_one_add_del_locator_set_t_print vl_noop_handler
38 #define vl_api_one_add_del_remote_mapping_t_endian vl_noop_handler
39 #define vl_api_one_add_del_remote_mapping_t_print vl_noop_handler
40
41 #define vl_typedefs             /* define message structures */
42 #include <vnet/vnet_all_api_h.h>
43 #undef vl_typedefs
44
45 #define vl_endianfun            /* define message structures */
46 #include <vnet/vnet_all_api_h.h>
47 #undef vl_endianfun
48
49 /* instantiate all the print functions we know about */
50 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
51 #define vl_printfun
52 #include <vnet/vnet_all_api_h.h>
53 #undef vl_printfun
54
55 #include <vlibapi/api_helper_macros.h>
56
57 #define foreach_vpe_api_msg                             \
58 _(LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set)                   \
59 _(LISP_ADD_DEL_LOCATOR, lisp_add_del_locator)                           \
60 _(LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid)                       \
61 _(LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver)                 \
62 _(LISP_ADD_DEL_MAP_SERVER, lisp_add_del_map_server)                     \
63 _(LISP_ENABLE_DISABLE, lisp_enable_disable)                             \
64 _(LISP_RLOC_PROBE_ENABLE_DISABLE, lisp_rloc_probe_enable_disable)       \
65 _(LISP_MAP_REGISTER_ENABLE_DISABLE, lisp_map_register_enable_disable)   \
66 _(LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping)             \
67 _(LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency)                       \
68 _(LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set)                 \
69 _(LISP_MAP_REQUEST_MODE, lisp_map_request_mode)                         \
70 _(LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map)               \
71 _(LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump)                         \
72 _(LISP_LOCATOR_DUMP, lisp_locator_dump)                                 \
73 _(LISP_EID_TABLE_DUMP, lisp_eid_table_dump)                             \
74 _(LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump)                       \
75 _(LISP_MAP_SERVER_DUMP, lisp_map_server_dump)                           \
76 _(LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump)                     \
77 _(LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump)                     \
78 _(LISP_ADJACENCIES_GET, lisp_adjacencies_get)                           \
79 _(SHOW_LISP_RLOC_PROBE_STATE, show_lisp_rloc_probe_state)               \
80 _(SHOW_LISP_MAP_REGISTER_STATE, show_lisp_map_register_state)           \
81 _(SHOW_LISP_STATUS, show_lisp_status)                                   \
82 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS,                                   \
83   lisp_add_del_map_request_itr_rlocs)                                   \
84 _(LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs)       \
85 _(SHOW_LISP_PITR, show_lisp_pitr)                                       \
86 _(SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode)               \
87 _(LISP_USE_PETR, lisp_use_petr)                                         \
88 _(SHOW_LISP_USE_PETR, show_lisp_use_petr)                               \
89
90 static locator_t *
91 unformat_lisp_locs (vl_api_remote_locator_t * rmt_locs, u32 rloc_num)
92 {
93   u32 i;
94   locator_t *locs = 0, loc;
95   vl_api_remote_locator_t *r;
96
97   for (i = 0; i < rloc_num; i++)
98     {
99       /* remote locators */
100       r = &rmt_locs[i];
101       clib_memset (&loc, 0, sizeof (loc));
102       gid_address_ip_set (&loc.address, &r->addr,
103                           r->is_ip4 ? AF_IP4 : AF_IP6);
104
105       loc.priority = r->priority;
106       loc.weight = r->weight;
107
108       vec_add1 (locs, loc);
109     }
110   return locs;
111 }
112
113 static void
114 vl_api_lisp_add_del_locator_set_t_handler (vl_api_lisp_add_del_locator_set_t *
115                                            mp)
116 {
117   vl_api_lisp_add_del_locator_set_reply_t *rmp;
118   int rv = 0;
119   vnet_lisp_add_del_locator_set_args_t _a, *a = &_a;
120   locator_t locator;
121   vl_api_local_locator_t *ls_loc;
122   u32 ls_index = ~0, locator_num;
123   u8 *locator_name = NULL;
124   int i;
125
126   clib_memset (a, 0, sizeof (a[0]));
127
128   mp->locator_set_name[sizeof (mp->locator_set_name) - 1] = 0;
129   locator_name = format (0, "%s", mp->locator_set_name);
130   vec_terminate_c_string (locator_name);
131
132   a->name = locator_name;
133   a->is_add = mp->is_add;
134   a->local = 1;
135   locator_num = clib_net_to_host_u32 (mp->locator_num);
136
137   clib_memset (&locator, 0, sizeof (locator));
138   for (i = 0; i < locator_num; i++)
139     {
140       ls_loc = &mp->locators[i];
141       VALIDATE_SW_IF_INDEX (ls_loc);
142
143       locator.sw_if_index = htonl (ls_loc->sw_if_index);
144       locator.priority = ls_loc->priority;
145       locator.weight = ls_loc->weight;
146       locator.local = 1;
147       vec_add1 (a->locators, locator);
148     }
149
150   rv = vnet_lisp_add_del_locator_set (a, &ls_index);
151
152   BAD_SW_IF_INDEX_LABEL;
153
154   vec_free (locator_name);
155   vec_free (a->locators);
156
157   /* *INDENT-OFF* */
158   REPLY_MACRO2 (VL_API_LISP_ADD_DEL_LOCATOR_SET_REPLY,
159   ({
160     rmp->ls_index = clib_host_to_net_u32 (ls_index);
161   }));
162   /* *INDENT-ON* */
163 }
164
165 static void
166 vl_api_lisp_add_del_locator_t_handler (vl_api_lisp_add_del_locator_t * mp)
167 {
168   vl_api_lisp_add_del_locator_reply_t *rmp;
169   int rv = 0;
170   locator_t locator, *locators = NULL;
171   vnet_lisp_add_del_locator_set_args_t _a, *a = &_a;
172   u32 ls_index = ~0;
173   u8 *locator_name = NULL;
174
175   clib_memset (&locator, 0, sizeof (locator));
176   clib_memset (a, 0, sizeof (a[0]));
177
178   locator.sw_if_index = ntohl (mp->sw_if_index);
179   locator.priority = mp->priority;
180   locator.weight = mp->weight;
181   locator.local = 1;
182   vec_add1 (locators, locator);
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->locators = locators;
190   a->is_add = mp->is_add;
191   a->local = 1;
192
193   rv = vnet_lisp_add_del_locator (a, NULL, &ls_index);
194
195   vec_free (locators);
196   vec_free (locator_name);
197
198   REPLY_MACRO (VL_API_LISP_ADD_DEL_LOCATOR_REPLY);
199 }
200
201 static int
202 unformat_lisp_eid_api (gid_address_t * dst, u32 vni, u8 type, void *src,
203                        u8 len)
204 {
205   switch (type)
206     {
207     case 0:                     /* ipv4 */
208       gid_address_type (dst) = GID_ADDR_IP_PREFIX;
209       gid_address_ip_set (dst, src, AF_IP4);
210       gid_address_ippref_len (dst) = len;
211       ip_prefix_normalize (&gid_address_ippref (dst));
212       break;
213     case 1:                     /* ipv6 */
214       gid_address_type (dst) = GID_ADDR_IP_PREFIX;
215       gid_address_ip_set (dst, src, AF_IP6);
216       gid_address_ippref_len (dst) = len;
217       ip_prefix_normalize (&gid_address_ippref (dst));
218       break;
219     case 2:                     /* l2 mac */
220       gid_address_type (dst) = GID_ADDR_MAC;
221       clib_memcpy (&gid_address_mac (dst), src, 6);
222       break;
223     default:
224       /* unknown type */
225       return VNET_API_ERROR_INVALID_VALUE;
226     }
227
228   gid_address_vni (dst) = vni;
229
230   return 0;
231 }
232
233 static void
234 vl_api_lisp_add_del_local_eid_t_handler (vl_api_lisp_add_del_local_eid_t * mp)
235 {
236   vl_api_lisp_add_del_local_eid_reply_t *rmp;
237   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
238   int rv = 0;
239   gid_address_t _eid, *eid = &_eid;
240   uword *p = NULL;
241   u32 locator_set_index = ~0, map_index = ~0;
242   vnet_lisp_add_del_mapping_args_t _a, *a = &_a;
243   u8 *name = NULL, *key = NULL;
244   clib_memset (a, 0, sizeof (a[0]));
245   clib_memset (eid, 0, sizeof (eid[0]));
246
247   rv = unformat_lisp_eid_api (eid, clib_net_to_host_u32 (mp->vni),
248                               mp->eid_type, mp->eid, mp->prefix_len);
249   if (rv)
250     goto out;
251
252   mp->locator_set_name[sizeof (mp->locator_set_name) - 1] = 0;
253   name = format (0, "%s", mp->locator_set_name);
254   vec_terminate_c_string (name);
255   p = hash_get_mem (lcm->locator_set_index_by_name, name);
256   if (!p)
257     {
258       rv = VNET_API_ERROR_INVALID_VALUE;
259       goto out;
260     }
261   locator_set_index = p[0];
262
263   if (*mp->key)
264     key = format (0, "%s", mp->key);
265
266   /* XXX treat batch configuration */
267   a->is_add = mp->is_add;
268   gid_address_copy (&a->eid, eid);
269   a->locator_set_index = locator_set_index;
270   a->local = 1;
271   a->key = key;
272   a->key_id = clib_net_to_host_u16 (mp->key_id);
273
274   rv = vnet_lisp_add_del_local_mapping (a, &map_index);
275
276 out:
277   vec_free (name);
278   vec_free (key);
279   gid_address_free (&a->eid);
280
281   REPLY_MACRO (VL_API_LISP_ADD_DEL_LOCAL_EID_REPLY);
282 }
283
284 static void
285   vl_api_lisp_eid_table_add_del_map_t_handler
286   (vl_api_lisp_eid_table_add_del_map_t * mp)
287 {
288   vl_api_lisp_eid_table_add_del_map_reply_t *rmp;
289   int rv = 0;
290   rv = vnet_lisp_eid_table_map (clib_net_to_host_u32 (mp->vni),
291                                 clib_net_to_host_u32 (mp->dp_table),
292                                 mp->is_l2, mp->is_add);
293 REPLY_MACRO (VL_API_LISP_EID_TABLE_ADD_DEL_MAP_REPLY)}
294
295 static void
296 vl_api_lisp_add_del_map_server_t_handler (vl_api_lisp_add_del_map_server_t
297                                           * mp)
298 {
299   vl_api_lisp_add_del_map_server_reply_t *rmp;
300   int rv = 0;
301   ip_address_t addr;
302
303   clib_memset (&addr, 0, sizeof (addr));
304
305   ip_address_set (&addr, mp->ip_address, mp->is_ipv6 ? AF_IP6 : AF_IP4);
306   rv = vnet_lisp_add_del_map_server (&addr, mp->is_add);
307
308   REPLY_MACRO (VL_API_LISP_ADD_DEL_MAP_SERVER_REPLY);
309 }
310
311 static void
312 vl_api_lisp_add_del_map_resolver_t_handler (vl_api_lisp_add_del_map_resolver_t
313                                             * mp)
314 {
315   vl_api_lisp_add_del_map_resolver_reply_t *rmp;
316   int rv = 0;
317   vnet_lisp_add_del_map_resolver_args_t _a, *a = &_a;
318
319   clib_memset (a, 0, sizeof (a[0]));
320
321   a->is_add = mp->is_add;
322   ip_address_set (&a->address, mp->ip_address, mp->is_ipv6 ? AF_IP6 : AF_IP4);
323
324   rv = vnet_lisp_add_del_map_resolver (a);
325
326   REPLY_MACRO (VL_API_LISP_ADD_DEL_MAP_RESOLVER_REPLY);
327 }
328
329 static void
330   vl_api_lisp_map_register_enable_disable_t_handler
331   (vl_api_lisp_map_register_enable_disable_t * mp)
332 {
333   vl_api_lisp_map_register_enable_disable_reply_t *rmp;
334   int rv = 0;
335
336   vnet_lisp_map_register_enable_disable (mp->is_enabled);
337   REPLY_MACRO (VL_API_LISP_ENABLE_DISABLE_REPLY);
338 }
339
340 static void
341   vl_api_lisp_rloc_probe_enable_disable_t_handler
342   (vl_api_lisp_rloc_probe_enable_disable_t * mp)
343 {
344   vl_api_lisp_rloc_probe_enable_disable_reply_t *rmp;
345   int rv = 0;
346
347   vnet_lisp_rloc_probe_enable_disable (mp->is_enabled);
348   REPLY_MACRO (VL_API_LISP_ENABLE_DISABLE_REPLY);
349 }
350
351 static void
352 vl_api_lisp_enable_disable_t_handler (vl_api_lisp_enable_disable_t * mp)
353 {
354   vl_api_lisp_enable_disable_reply_t *rmp;
355   int rv = 0;
356
357   vnet_lisp_enable_disable (mp->is_en);
358   REPLY_MACRO (VL_API_LISP_ENABLE_DISABLE_REPLY);
359 }
360
361 static void
362   vl_api_show_lisp_map_request_mode_t_handler
363   (vl_api_show_lisp_map_request_mode_t * mp)
364 {
365   int rv = 0;
366   vl_api_show_lisp_map_request_mode_reply_t *rmp;
367
368   /* *INDENT-OFF* */
369   REPLY_MACRO2(VL_API_SHOW_LISP_MAP_REQUEST_MODE_REPLY,
370   ({
371     rmp->mode = vnet_lisp_get_map_request_mode ();
372   }));
373   /* *INDENT-ON* */
374 }
375
376 static void
377 vl_api_lisp_map_request_mode_t_handler (vl_api_lisp_map_request_mode_t * mp)
378 {
379   vl_api_lisp_map_request_mode_reply_t *rmp;
380   int rv = 0;
381
382   rv = vnet_lisp_set_map_request_mode (mp->mode);
383
384   REPLY_MACRO (VL_API_LISP_MAP_REQUEST_MODE_REPLY);
385 }
386
387 static void
388 vl_api_lisp_pitr_set_locator_set_t_handler (vl_api_lisp_pitr_set_locator_set_t
389                                             * mp)
390 {
391   vl_api_lisp_pitr_set_locator_set_reply_t *rmp;
392   int rv = 0;
393   u8 *ls_name = 0;
394
395   mp->ls_name[sizeof (mp->ls_name) - 1] = 0;
396   ls_name = format (0, "%s", mp->ls_name);
397   vec_terminate_c_string (ls_name);
398   rv = vnet_lisp_pitr_set_locator_set (ls_name, mp->is_add);
399   vec_free (ls_name);
400
401   REPLY_MACRO (VL_API_LISP_PITR_SET_LOCATOR_SET_REPLY);
402 }
403
404 static void
405 vl_api_lisp_use_petr_t_handler (vl_api_lisp_use_petr_t * mp)
406 {
407   vl_api_lisp_use_petr_reply_t *rmp;
408   int rv = 0;
409   ip_address_t addr;
410
411   ip_address_set (&addr, &mp->address, mp->is_ip4 ? AF_IP4 : AF_IP6);
412   rv = vnet_lisp_use_petr (&addr, mp->is_add);
413
414   REPLY_MACRO (VL_API_LISP_USE_PETR_REPLY);
415 }
416
417 static void
418 vl_api_show_lisp_use_petr_t_handler (vl_api_show_lisp_use_petr_t * mp)
419 {
420   vl_api_show_lisp_use_petr_reply_t *rmp = NULL;
421   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
422   mapping_t *m;
423   locator_set_t *ls = 0;
424   int rv = 0;
425   locator_t *loc = 0;
426   u8 status = 0;
427   gid_address_t addr;
428
429   clib_memset (&addr, 0, sizeof (addr));
430   status = lcm->flags & LISP_FLAG_USE_PETR;
431   if (status)
432     {
433       m = pool_elt_at_index (lcm->mapping_pool, lcm->petr_map_index);
434       if (~0 != m->locator_set_index)
435         {
436           ls =
437             pool_elt_at_index (lcm->locator_set_pool, m->locator_set_index);
438           loc = pool_elt_at_index (lcm->locator_pool, ls->locator_indices[0]);
439           gid_address_copy (&addr, &loc->address);
440         }
441     }
442
443   /* *INDENT-OFF* */
444   REPLY_MACRO2 (VL_API_SHOW_LISP_USE_PETR_REPLY,
445   {
446     rmp->status = status;
447     ip_address_t *ip = &gid_address_ip (&addr);
448     switch (ip_addr_version (ip))
449       {
450       case AF_IP4:
451         clib_memcpy (rmp->address, &ip_addr_v4 (ip),
452                      sizeof (ip_addr_v4 (ip)));
453         break;
454
455       case AF_IP6:
456         clib_memcpy (rmp->address, &ip_addr_v6 (ip),
457                      sizeof (ip_addr_v6 (ip)));
458         break;
459
460       default:
461         ASSERT (0);
462       }
463     rmp->is_ip4 = (gid_address_ip_version (&addr) == AF_IP4);
464   });
465   /* *INDENT-ON* */
466 }
467
468 static void
469   vl_api_lisp_add_del_map_request_itr_rlocs_t_handler
470   (vl_api_lisp_add_del_map_request_itr_rlocs_t * mp)
471 {
472   vl_api_lisp_add_del_map_request_itr_rlocs_reply_t *rmp;
473   int rv = 0;
474   u8 *locator_set_name = NULL;
475   vnet_lisp_add_del_mreq_itr_rloc_args_t _a, *a = &_a;
476
477   mp->locator_set_name[sizeof (mp->locator_set_name) - 1] = 0;
478   locator_set_name = format (0, "%s", mp->locator_set_name);
479   vec_terminate_c_string (locator_set_name);
480
481   a->is_add = mp->is_add;
482   a->locator_set_name = locator_set_name;
483
484   rv = vnet_lisp_add_del_mreq_itr_rlocs (a);
485
486   vec_free (locator_set_name);
487
488   REPLY_MACRO (VL_API_LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY);
489 }
490
491 static void
492   vl_api_lisp_add_del_remote_mapping_t_handler
493   (vl_api_lisp_add_del_remote_mapping_t * mp)
494 {
495   locator_t *rlocs = 0;
496   vl_api_lisp_add_del_remote_mapping_reply_t *rmp;
497   int rv = 0;
498   gid_address_t _eid, *eid = &_eid;
499   u32 rloc_num = clib_net_to_host_u32 (mp->rloc_num);
500
501   clib_memset (eid, 0, sizeof (eid[0]));
502
503   rv = unformat_lisp_eid_api (eid, clib_net_to_host_u32 (mp->vni),
504                               mp->eid_type, mp->eid, mp->eid_len);
505   if (rv)
506     goto send_reply;
507
508   rlocs = unformat_lisp_locs (mp->rlocs, rloc_num);
509
510   if (!mp->is_add)
511     {
512       vnet_lisp_add_del_adjacency_args_t _a, *a = &_a;
513       clib_memset (a, 0, sizeof (*a));
514       gid_address_copy (&a->reid, eid);
515       a->is_add = 0;
516       rv = vnet_lisp_add_del_adjacency (a);
517       if (rv)
518         {
519           goto out;
520         }
521     }
522
523   /* NOTE: for now this works as a static remote mapping, i.e.,
524    * not authoritative and ttl infinite. */
525   if (mp->is_add)
526     {
527       vnet_lisp_add_del_mapping_args_t _m_args, *m_args = &_m_args;
528       clib_memset (m_args, 0, sizeof (m_args[0]));
529       gid_address_copy (&m_args->eid, eid);
530       m_args->action = mp->action;
531       m_args->is_static = 1;
532       m_args->ttl = ~0;
533       m_args->authoritative = 0;
534       rv = vnet_lisp_add_mapping (m_args, rlocs, NULL, NULL);
535     }
536   else
537     {
538       rv = vnet_lisp_del_mapping (eid, NULL);
539     }
540
541   if (mp->del_all)
542     vnet_lisp_clear_all_remote_adjacencies ();
543
544 out:
545   vec_free (rlocs);
546 send_reply:
547   REPLY_MACRO (VL_API_LISP_ADD_DEL_REMOTE_MAPPING_REPLY);
548 }
549
550 static void
551 vl_api_lisp_add_del_adjacency_t_handler (vl_api_lisp_add_del_adjacency_t * mp)
552 {
553   vl_api_lisp_add_del_adjacency_reply_t *rmp;
554   vnet_lisp_add_del_adjacency_args_t _a, *a = &_a;
555
556   int rv = 0;
557   clib_memset (a, 0, sizeof (a[0]));
558
559   rv = unformat_lisp_eid_api (&a->leid, clib_net_to_host_u32 (mp->vni),
560                               mp->eid_type, mp->leid, mp->leid_len);
561   rv |= unformat_lisp_eid_api (&a->reid, clib_net_to_host_u32 (mp->vni),
562                                mp->eid_type, mp->reid, mp->reid_len);
563
564   if (rv)
565     goto send_reply;
566
567   a->is_add = mp->is_add;
568   rv = vnet_lisp_add_del_adjacency (a);
569
570 send_reply:
571   REPLY_MACRO (VL_API_LISP_ADD_DEL_ADJACENCY_REPLY);
572 }
573
574 static void
575 send_lisp_locator_details (lisp_cp_main_t * lcm,
576                            locator_t * loc, vl_api_registration_t * reg,
577                            u32 context)
578 {
579   vl_api_lisp_locator_details_t *rmp;
580
581   rmp = vl_msg_api_alloc (sizeof (*rmp));
582   clib_memset (rmp, 0, sizeof (*rmp));
583   rmp->_vl_msg_id = ntohs (VL_API_LISP_LOCATOR_DETAILS);
584   rmp->context = context;
585
586   rmp->local = loc->local;
587   if (loc->local)
588     {
589       rmp->sw_if_index = ntohl (loc->sw_if_index);
590     }
591   else
592     {
593       rmp->is_ipv6 = gid_address_ip_version (&loc->address);
594       ip_address_copy_addr (rmp->ip_address, &gid_address_ip (&loc->address));
595     }
596   rmp->priority = loc->priority;
597   rmp->weight = loc->weight;
598
599   vl_api_send_msg (reg, (u8 *) rmp);
600 }
601
602 static void
603 vl_api_lisp_locator_dump_t_handler (vl_api_lisp_locator_dump_t * mp)
604 {
605   u8 *ls_name = 0;
606   vl_api_registration_t *reg = 0;
607   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
608   locator_set_t *lsit = 0;
609   locator_t *loc = 0;
610   u32 ls_index = ~0, *locit = 0;
611   uword *p = 0;
612
613   reg = vl_api_client_index_to_registration (mp->client_index);
614   if (!reg)
615     return;
616
617   if (mp->is_index_set)
618     ls_index = htonl (mp->ls_index);
619   else
620     {
621       /* make sure we get a proper C-string */
622       mp->ls_name[sizeof (mp->ls_name) - 1] = 0;
623       ls_name = format (0, "%s", mp->ls_name);
624       vec_terminate_c_string (ls_name);
625       p = hash_get_mem (lcm->locator_set_index_by_name, ls_name);
626       if (!p)
627         goto out;
628       ls_index = p[0];
629     }
630
631   if (pool_is_free_index (lcm->locator_set_pool, ls_index))
632     return;
633
634   lsit = pool_elt_at_index (lcm->locator_set_pool, ls_index);
635
636   vec_foreach (locit, lsit->locator_indices)
637   {
638     loc = pool_elt_at_index (lcm->locator_pool, locit[0]);
639     send_lisp_locator_details (lcm, loc, reg, mp->context);
640   };
641 out:
642   vec_free (ls_name);
643 }
644
645 static void
646 send_lisp_locator_set_details (lisp_cp_main_t * lcm,
647                                locator_set_t * lsit,
648                                vl_api_registration_t * reg, u32 context,
649                                u32 ls_index)
650 {
651   vl_api_lisp_locator_set_details_t *rmp;
652   u8 *str = 0;
653
654   rmp = vl_msg_api_alloc (sizeof (*rmp));
655   clib_memset (rmp, 0, sizeof (*rmp));
656   rmp->_vl_msg_id = ntohs (VL_API_LISP_LOCATOR_SET_DETAILS);
657   rmp->context = context;
658
659   rmp->ls_index = htonl (ls_index);
660   if (lsit->local)
661     {
662       ASSERT (lsit->name != NULL);
663       strncpy ((char *) rmp->ls_name, (char *) lsit->name,
664                vec_len (lsit->name));
665     }
666   else
667     {
668       str = format (0, "<remote-%d>", ls_index);
669       strncpy ((char *) rmp->ls_name, (char *) str, vec_len (str));
670       vec_free (str);
671     }
672
673   vl_api_send_msg (reg, (u8 *) rmp);
674 }
675
676 static void
677 vl_api_lisp_locator_set_dump_t_handler (vl_api_lisp_locator_set_dump_t * mp)
678 {
679   vl_api_registration_t *reg;
680   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
681   locator_set_t *lsit = NULL;
682   u8 filter;
683
684   reg = vl_api_client_index_to_registration (mp->client_index);
685   if (!reg)
686     return;
687
688   filter = mp->filter;
689   /* *INDENT-OFF* */
690   pool_foreach (lsit, lcm->locator_set_pool,
691   ({
692     if (filter && !((1 == filter && lsit->local) ||
693                     (2 == filter && !lsit->local)))
694       {
695         continue;
696       }
697     send_lisp_locator_set_details (lcm, lsit, reg, mp->context,
698                                    lsit - lcm->locator_set_pool);
699   }));
700   /* *INDENT-ON* */
701 }
702
703 static void
704 lisp_fid_put_api (u8 * dst, fid_address_t * src, u8 * prefix_length)
705 {
706   ASSERT (prefix_length);
707   ip_prefix_t *ippref = &fid_addr_ippref (src);
708
709   switch (fid_addr_type (src))
710     {
711     case FID_ADDR_IP_PREF:
712       if (ip_prefix_version (ippref) == AF_IP4)
713         clib_memcpy (dst, &ip_prefix_v4 (ippref), 4);
714       else
715         clib_memcpy (dst, &ip_prefix_v6 (ippref), 16);
716       prefix_length[0] = ip_prefix_len (ippref);
717       break;
718
719     case FID_ADDR_MAC:
720       prefix_length[0] = 0;
721       clib_memcpy (dst, fid_addr_mac (src), 6);
722       break;
723
724     default:
725       clib_warning ("Unknown FID type %d!", fid_addr_type (src));
726       break;
727     }
728 }
729
730 static u8
731 fid_type_to_api_type (fid_address_t * fid)
732 {
733   ip_prefix_t *ippref;
734
735   switch (fid_addr_type (fid))
736     {
737     case FID_ADDR_IP_PREF:
738       ippref = &fid_addr_ippref (fid);
739       if (ip_prefix_version (ippref) == AF_IP4)
740         return 0;
741       else if (ip_prefix_version (ippref) == AF_IP6)
742         return 1;
743       else
744         return ~0;
745
746     case FID_ADDR_MAC:
747       return 2;
748     case FID_ADDR_NSH:
749       return 3;
750     }
751
752   return ~0;
753 }
754
755 static void
756 send_lisp_eid_table_details (mapping_t * mapit,
757                              vl_api_registration_t * reg, u32 context,
758                              u8 filter)
759 {
760   fid_address_t *fid;
761   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
762   locator_set_t *ls = 0;
763   vl_api_lisp_eid_table_details_t *rmp = NULL;
764   gid_address_t *gid = NULL;
765   u8 *mac = 0;
766   ip_prefix_t *ip_prefix = NULL;
767
768   switch (filter)
769     {
770     case 0:                     /* all mappings */
771       break;
772
773     case 1:                     /* local only */
774       if (!mapit->local)
775         return;
776       break;
777     case 2:                     /* remote only */
778       if (mapit->local)
779         return;
780       break;
781     default:
782       clib_warning ("Filter error, unknown filter: %d", filter);
783       return;
784     }
785
786   /* don't send PITR generated mapping */
787   if (mapit->pitr_set)
788     return;
789
790   gid = &mapit->eid;
791   ip_prefix = &gid_address_ippref (gid);
792   mac = gid_address_mac (gid);
793
794   rmp = vl_msg_api_alloc (sizeof (*rmp));
795   clib_memset (rmp, 0, sizeof (*rmp));
796   rmp->_vl_msg_id = ntohs (VL_API_LISP_EID_TABLE_DETAILS);
797
798   ls = pool_elt_at_index (lcm->locator_set_pool, mapit->locator_set_index);
799   if (vec_len (ls->locator_indices) == 0)
800     rmp->locator_set_index = ~0;
801   else
802     rmp->locator_set_index = clib_host_to_net_u32 (mapit->locator_set_index);
803
804   rmp->is_local = mapit->local;
805   rmp->ttl = clib_host_to_net_u32 (mapit->ttl);
806   rmp->action = mapit->action;
807   rmp->authoritative = mapit->authoritative;
808
809   switch (gid_address_type (gid))
810     {
811     case GID_ADDR_SRC_DST:
812       rmp->is_src_dst = 1;
813       fid = &gid_address_sd_src (gid);
814       rmp->eid_type = fid_type_to_api_type (fid);
815       lisp_fid_put_api (rmp->seid, &gid_address_sd_src (gid),
816                         &rmp->seid_prefix_len);
817       lisp_fid_put_api (rmp->eid, &gid_address_sd_dst (gid),
818                         &rmp->eid_prefix_len);
819       break;
820     case GID_ADDR_IP_PREFIX:
821       rmp->eid_prefix_len = ip_prefix_len (ip_prefix);
822       if (ip_prefix_version (ip_prefix) == AF_IP4)
823         {
824           rmp->eid_type = 0;    /* ipv4 type */
825           clib_memcpy (rmp->eid, &ip_prefix_v4 (ip_prefix),
826                        sizeof (ip_prefix_v4 (ip_prefix)));
827         }
828       else
829         {
830           rmp->eid_type = 1;    /* ipv6 type */
831           clib_memcpy (rmp->eid, &ip_prefix_v6 (ip_prefix),
832                        sizeof (ip_prefix_v6 (ip_prefix)));
833         }
834       break;
835     case GID_ADDR_MAC:
836       rmp->eid_type = 2;        /* l2 mac type */
837       clib_memcpy (rmp->eid, mac, 6);
838       break;
839     default:
840       ASSERT (0);
841     }
842   rmp->context = context;
843   rmp->vni = clib_host_to_net_u32 (gid_address_vni (gid));
844   rmp->key_id = clib_host_to_net_u16 (mapit->key_id);
845   memcpy (rmp->key, mapit->key, vec_len (mapit->key));
846   vl_api_send_msg (reg, (u8 *) rmp);
847 }
848
849 static void
850 vl_api_lisp_eid_table_dump_t_handler (vl_api_lisp_eid_table_dump_t * mp)
851 {
852   u32 mi;
853   vl_api_registration_t *reg;
854   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
855   mapping_t *mapit = NULL;
856   gid_address_t _eid, *eid = &_eid;
857
858   reg = vl_api_client_index_to_registration (mp->client_index);
859   if (!reg)
860     return;
861
862   if (mp->eid_set)
863     {
864       clib_memset (eid, 0, sizeof (*eid));
865
866       unformat_lisp_eid_api (eid, clib_net_to_host_u32 (mp->vni),
867                              mp->eid_type, mp->eid, mp->prefix_length);
868
869       mi = gid_dictionary_lookup (&lcm->mapping_index_by_gid, eid);
870       if ((u32) ~ 0 == mi)
871         return;
872
873       mapit = pool_elt_at_index (lcm->mapping_pool, mi);
874       send_lisp_eid_table_details (mapit, reg, mp->context,
875                                    0 /* ignore filter */ );
876     }
877   else
878     {
879       /* *INDENT-OFF* */
880       pool_foreach (mapit, lcm->mapping_pool,
881       ({
882         send_lisp_eid_table_details(mapit, reg, mp->context,
883                                     mp->filter);
884       }));
885       /* *INDENT-ON* */
886     }
887 }
888
889 static void
890 send_lisp_map_server_details (ip_address_t * ip, vl_api_registration_t * reg,
891                               u32 context)
892 {
893   vl_api_lisp_map_server_details_t *rmp = NULL;
894
895   rmp = vl_msg_api_alloc (sizeof (*rmp));
896   clib_memset (rmp, 0, sizeof (*rmp));
897   rmp->_vl_msg_id = ntohs (VL_API_LISP_MAP_SERVER_DETAILS);
898
899   switch (ip_addr_version (ip))
900     {
901     case AF_IP4:
902       rmp->is_ipv6 = 0;
903       clib_memcpy (rmp->ip_address, &ip_addr_v4 (ip),
904                    sizeof (ip_addr_v4 (ip)));
905       break;
906
907     case AF_IP6:
908       rmp->is_ipv6 = 1;
909       clib_memcpy (rmp->ip_address, &ip_addr_v6 (ip),
910                    sizeof (ip_addr_v6 (ip)));
911       break;
912
913     default:
914       ASSERT (0);
915     }
916   rmp->context = context;
917
918   vl_api_send_msg (reg, (u8 *) rmp);
919 }
920
921 static void
922 vl_api_lisp_map_server_dump_t_handler (vl_api_lisp_map_server_dump_t * mp)
923 {
924   vl_api_registration_t *reg;
925   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
926   lisp_msmr_t *mr;
927
928   reg = vl_api_client_index_to_registration (mp->client_index);
929   if (!reg)
930     return;
931
932   vec_foreach (mr, lcm->map_servers)
933   {
934     send_lisp_map_server_details (&mr->address, reg, mp->context);
935   }
936 }
937
938 static void
939 send_lisp_map_resolver_details (ip_address_t * ip,
940                                 vl_api_registration_t * reg, u32 context)
941 {
942   vl_api_lisp_map_resolver_details_t *rmp = NULL;
943
944   rmp = vl_msg_api_alloc (sizeof (*rmp));
945   clib_memset (rmp, 0, sizeof (*rmp));
946   rmp->_vl_msg_id = ntohs (VL_API_LISP_MAP_RESOLVER_DETAILS);
947
948   switch (ip_addr_version (ip))
949     {
950     case AF_IP4:
951       rmp->is_ipv6 = 0;
952       clib_memcpy (rmp->ip_address, &ip_addr_v4 (ip),
953                    sizeof (ip_addr_v4 (ip)));
954       break;
955
956     case AF_IP6:
957       rmp->is_ipv6 = 1;
958       clib_memcpy (rmp->ip_address, &ip_addr_v6 (ip),
959                    sizeof (ip_addr_v6 (ip)));
960       break;
961
962     default:
963       ASSERT (0);
964     }
965   rmp->context = context;
966
967   vl_api_send_msg (reg, (u8 *) rmp);
968 }
969
970 static void
971 vl_api_lisp_map_resolver_dump_t_handler (vl_api_lisp_map_resolver_dump_t * mp)
972 {
973   vl_api_registration_t *reg;
974   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
975   lisp_msmr_t *mr;
976
977   reg = vl_api_client_index_to_registration (mp->client_index);
978   if (!reg)
979     return;
980
981   vec_foreach (mr, lcm->map_resolvers)
982   {
983     send_lisp_map_resolver_details (&mr->address, reg, mp->context);
984   }
985 }
986
987 static void
988 send_eid_table_map_pair (hash_pair_t * p, vl_api_registration_t * reg,
989                          u32 context)
990 {
991   vl_api_lisp_eid_table_map_details_t *rmp = NULL;
992
993   rmp = vl_msg_api_alloc (sizeof (*rmp));
994   clib_memset (rmp, 0, sizeof (*rmp));
995   rmp->_vl_msg_id = ntohs (VL_API_LISP_EID_TABLE_MAP_DETAILS);
996
997   rmp->vni = clib_host_to_net_u32 (p->key);
998   rmp->dp_table = clib_host_to_net_u32 (p->value[0]);
999   rmp->context = context;
1000   vl_api_send_msg (reg, (u8 *) rmp);
1001 }
1002
1003 static void
1004 vl_api_lisp_eid_table_map_dump_t_handler (vl_api_lisp_eid_table_map_dump_t *
1005                                           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   /* *INDENT-OFF* */
1026   hash_foreach_pair (p, vni_table,
1027   ({
1028     send_eid_table_map_pair (p, reg, mp->context);
1029   }));
1030   /* *INDENT-ON* */
1031 }
1032
1033 static void
1034 send_eid_table_vni (u32 vni, vl_api_registration_t * reg, u32 context)
1035 {
1036   vl_api_lisp_eid_table_vni_details_t *rmp = 0;
1037
1038   rmp = vl_msg_api_alloc (sizeof (*rmp));
1039   clib_memset (rmp, 0, sizeof (*rmp));
1040   rmp->_vl_msg_id = ntohs (VL_API_LISP_EID_TABLE_VNI_DETAILS);
1041   rmp->context = context;
1042   rmp->vni = clib_host_to_net_u32 (vni);
1043   vl_api_send_msg (reg, (u8 *) rmp);
1044 }
1045
1046 static void
1047 lisp_adjacency_copy (vl_api_lisp_adjacency_t * dst, lisp_adjacency_t * adjs)
1048 {
1049   lisp_adjacency_t *adj;
1050   vl_api_lisp_adjacency_t a;
1051   u32 i, n = vec_len (adjs);
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           a.reid_prefix_len = gid_address_ippref_len (&adj->reid);
1062           a.leid_prefix_len = gid_address_ippref_len (&adj->leid);
1063           if (gid_address_ip_version (&adj->reid) == AF_IP4)
1064             {
1065               a.eid_type = 0;   /* ipv4 type */
1066               clib_memcpy (a.reid, &gid_address_ip (&adj->reid), 4);
1067               clib_memcpy (a.leid, &gid_address_ip (&adj->leid), 4);
1068             }
1069           else
1070             {
1071               a.eid_type = 1;   /* ipv6 type */
1072               clib_memcpy (a.reid, &gid_address_ip (&adj->reid), 16);
1073               clib_memcpy (a.leid, &gid_address_ip (&adj->leid), 16);
1074             }
1075           break;
1076         case GID_ADDR_MAC:
1077           a.eid_type = 2;       /* l2 mac type */
1078           mac_copy (a.reid, gid_address_mac (&adj->reid));
1079           mac_copy (a.leid, gid_address_mac (&adj->leid));
1080           break;
1081         default:
1082           ASSERT (0);
1083         }
1084       dst[i] = a;
1085     }
1086 }
1087
1088 static void
1089   vl_api_show_lisp_rloc_probe_state_t_handler
1090   (vl_api_show_lisp_rloc_probe_state_t * mp)
1091 {
1092   vl_api_show_lisp_rloc_probe_state_reply_t *rmp = 0;
1093   int rv = 0;
1094
1095   /* *INDENT-OFF* */
1096   REPLY_MACRO2 (VL_API_SHOW_LISP_RLOC_PROBE_STATE_REPLY,
1097   {
1098     rmp->is_enabled = vnet_lisp_rloc_probe_state_get ();
1099   });
1100   /* *INDENT-ON* */
1101 }
1102
1103 static void
1104   vl_api_show_lisp_map_register_state_t_handler
1105   (vl_api_show_lisp_map_register_state_t * mp)
1106 {
1107   vl_api_show_lisp_map_register_state_reply_t *rmp = 0;
1108   int rv = 0;
1109
1110   /* *INDENT-OFF* */
1111   REPLY_MACRO2 (VL_API_SHOW_LISP_MAP_REGISTER_STATE_REPLY,
1112   {
1113     rmp->is_enabled = vnet_lisp_map_register_state_get ();
1114   });
1115   /* *INDENT-ON* */
1116 }
1117
1118 static void
1119 vl_api_lisp_adjacencies_get_t_handler (vl_api_lisp_adjacencies_get_t * mp)
1120 {
1121   vl_api_lisp_adjacencies_get_reply_t *rmp = 0;
1122   lisp_adjacency_t *adjs = 0;
1123   int rv = 0;
1124   u32 size = ~0;
1125   u32 vni = clib_net_to_host_u32 (mp->vni);
1126
1127   adjs = vnet_lisp_adjacencies_get_by_vni (vni);
1128   size = vec_len (adjs) * sizeof (vl_api_lisp_adjacency_t);
1129
1130   /* *INDENT-OFF* */
1131   REPLY_MACRO4 (VL_API_LISP_ADJACENCIES_GET_REPLY, size,
1132   {
1133     rmp->count = clib_host_to_net_u32 (vec_len (adjs));
1134     lisp_adjacency_copy (rmp->adjacencies, adjs);
1135   });
1136   /* *INDENT-ON* */
1137
1138   vec_free (adjs);
1139 }
1140
1141 static void
1142 vl_api_lisp_eid_table_vni_dump_t_handler (vl_api_lisp_eid_table_vni_dump_t *
1143                                           mp)
1144 {
1145   hash_pair_t *p;
1146   u32 *vnis = 0;
1147   vl_api_registration_t *reg = 0;
1148   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
1149
1150   reg = vl_api_client_index_to_registration (mp->client_index);
1151   if (!reg)
1152     return;
1153
1154   /* *INDENT-OFF* */
1155   hash_foreach_pair (p, lcm->table_id_by_vni,
1156   ({
1157     hash_set (vnis, p->key, 0);
1158   }));
1159
1160   hash_foreach_pair (p, lcm->bd_id_by_vni,
1161   ({
1162     hash_set (vnis, p->key, 0);
1163   }));
1164
1165   hash_foreach_pair (p, vnis,
1166   ({
1167     send_eid_table_vni (p->key, reg, mp->context);
1168   }));
1169   /* *INDENT-ON* */
1170
1171   hash_free (vnis);
1172 }
1173
1174 static void
1175 vl_api_show_lisp_status_t_handler (vl_api_show_lisp_status_t * mp)
1176 {
1177   vl_api_show_lisp_status_reply_t *rmp = NULL;
1178   int rv = 0;
1179
1180   /* *INDENT-OFF* */
1181   REPLY_MACRO2(VL_API_SHOW_LISP_STATUS_REPLY,
1182   ({
1183     rmp->gpe_status = vnet_lisp_gpe_enable_disable_status ();
1184     rmp->feature_status = vnet_lisp_enable_disable_status ();
1185   }));
1186   /* *INDENT-ON* */
1187 }
1188
1189 static void
1190   vl_api_lisp_get_map_request_itr_rlocs_t_handler
1191   (vl_api_lisp_get_map_request_itr_rlocs_t * mp)
1192 {
1193   vl_api_lisp_get_map_request_itr_rlocs_reply_t *rmp = NULL;
1194   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
1195   locator_set_t *loc_set = 0;
1196   u8 *tmp_str = 0;
1197   int rv = 0;
1198
1199   if (~0 == lcm->mreq_itr_rlocs)
1200     {
1201       tmp_str = format (0, " ");
1202     }
1203   else
1204     {
1205       loc_set =
1206         pool_elt_at_index (lcm->locator_set_pool, lcm->mreq_itr_rlocs);
1207       tmp_str = format (0, "%s", loc_set->name);
1208     }
1209
1210   /* *INDENT-OFF* */
1211   REPLY_MACRO2(VL_API_LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,
1212   ({
1213     strncpy((char *) rmp->locator_set_name, (char *) tmp_str,
1214             ARRAY_LEN(rmp->locator_set_name) - 1);
1215   }));
1216   /* *INDENT-ON* */
1217
1218   vec_free (tmp_str);
1219 }
1220
1221 static void
1222 vl_api_show_lisp_pitr_t_handler (vl_api_show_lisp_pitr_t * mp)
1223 {
1224   vl_api_show_lisp_pitr_reply_t *rmp = NULL;
1225   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
1226   mapping_t *m;
1227   locator_set_t *ls = 0;
1228   u8 *tmp_str = 0;
1229   int rv = 0;
1230
1231   u8 is_enabled = (lcm->flags & LISP_FLAG_PITR_MODE)
1232     && lcm->pitr_map_index != ~0;
1233
1234   if (!is_enabled)
1235     {
1236       tmp_str = format (0, "N/A");
1237     }
1238   else
1239     {
1240       m = pool_elt_at_index (lcm->mapping_pool, lcm->pitr_map_index);
1241       if (~0 != m->locator_set_index)
1242         {
1243           ls =
1244             pool_elt_at_index (lcm->locator_set_pool, m->locator_set_index);
1245           tmp_str = format (0, "%s", ls->name);
1246         }
1247       else
1248         {
1249           tmp_str = format (0, "N/A");
1250         }
1251     }
1252   vec_add1 (tmp_str, 0);
1253
1254   /* *INDENT-OFF* */
1255   REPLY_MACRO2(VL_API_SHOW_LISP_PITR_REPLY,
1256   ({
1257     rmp->status = lcm->flags & LISP_FLAG_PITR_MODE;
1258     strncpy((char *) rmp->locator_set_name, (char *) tmp_str,
1259             ARRAY_LEN(rmp->locator_set_name) - 1);
1260   }));
1261   /* *INDENT-ON* */
1262 }
1263
1264 /*
1265  * lisp_api_hookup
1266  * Add vpe's API message handlers to the table.
1267  * vlib has already mapped shared memory and
1268  * added the client registration handlers.
1269  * See .../vlib-api/vlibmemory/memclnt_vlib.c:memclnt_process()
1270  */
1271 #define vl_msg_name_crc_list
1272 #include <vnet/vnet_all_api_h.h>
1273 #undef vl_msg_name_crc_list
1274
1275 static void
1276 setup_message_id_table (api_main_t * am)
1277 {
1278 #define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
1279   foreach_vl_msg_name_crc_lisp;
1280 #undef _
1281 }
1282
1283 static clib_error_t *
1284 lisp_api_hookup (vlib_main_t * vm)
1285 {
1286   api_main_t *am = vlibapi_get_main ();
1287
1288 #define _(N,n)                                                  \
1289     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
1290                            vl_api_##n##_t_handler,              \
1291                            vl_noop_handler,                     \
1292                            vl_api_##n##_t_endian,               \
1293                            vl_api_##n##_t_print,                \
1294                            sizeof(vl_api_##n##_t), 1);
1295   foreach_vpe_api_msg;
1296 #undef _
1297
1298   /*
1299    * Set up the (msg_name, crc, message-id) table
1300    */
1301   setup_message_id_table (am);
1302
1303   return 0;
1304 }
1305
1306 VLIB_API_INIT_FUNCTION (lisp_api_hookup);
1307
1308 /*
1309  * fd.io coding-style-patch-verification: ON
1310  *
1311  * Local Variables:
1312  * eval: (c-set-style "gnu")
1313  * End:
1314  */