http: return more than url to server app
[vpp.git] / src / plugins / lisp / 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 <lisp/lisp-cp/control.h>
26 #include <lisp/lisp-gpe/lisp_gpe.h>
27 #include <vnet/ip/ip_types_api.h>
28 #include <vnet/ethernet/ethernet_types_api.h>
29 #include <lisp/lisp-cp/lisp_types_api.h>
30
31 /* define message IDs */
32 #include <vnet/format_fns.h>
33 #include <lisp/lisp-cp/lisp.api_enum.h>
34 #include <lisp/lisp-cp/lisp.api_types.h>
35
36 /**
37  * Base message ID fot the plugin
38  */
39 static u32 lisp_base_msg_id;
40 #define REPLY_MSG_ID_BASE lisp_base_msg_id
41
42 #include <vlibapi/api_helper_macros.h>
43
44 static locator_t *
45 unformat_lisp_locs (vl_api_remote_locator_t * rmt_locs, u32 rloc_num)
46 {
47   u32 i;
48   locator_t *locs = 0, loc;
49   vl_api_remote_locator_t *r;
50
51   for (i = 0; i < rloc_num; i++)
52     {
53       /* remote locators */
54       r = &rmt_locs[i];
55       clib_memset (&loc, 0, sizeof (loc));
56       ip_address_decode2 (&r->ip_address, &loc.address.ippref.addr);
57       loc.address.ippref.len =
58         ip_address_max_len (loc.address.ippref.addr.version);
59
60       loc.priority = r->priority;
61       loc.weight = r->weight;
62
63       vec_add1 (locs, loc);
64     }
65   return locs;
66 }
67
68 static void
69 vl_api_lisp_add_del_locator_set_t_handler (vl_api_lisp_add_del_locator_set_t *
70                                            mp)
71 {
72   vl_api_lisp_add_del_locator_set_reply_t *rmp;
73   int rv = 0;
74   vnet_lisp_add_del_locator_set_args_t _a, *a = &_a;
75   locator_t locator;
76   vl_api_local_locator_t *ls_loc;
77   u32 ls_index = ~0, locator_num;
78   u8 *locator_name = NULL;
79   int i;
80
81   clib_memset (a, 0, sizeof (a[0]));
82
83   mp->locator_set_name[sizeof (mp->locator_set_name) - 1] = 0;
84   locator_name = format (0, "%s", mp->locator_set_name);
85   vec_terminate_c_string (locator_name);
86
87   a->name = locator_name;
88   a->is_add = mp->is_add;
89   a->local = 1;
90   locator_num = clib_net_to_host_u32 (mp->locator_num);
91
92   clib_memset (&locator, 0, sizeof (locator));
93   for (i = 0; i < locator_num; i++)
94     {
95       ls_loc = &mp->locators[i];
96       VALIDATE_SW_IF_INDEX (ls_loc);
97
98       locator.sw_if_index = htonl (ls_loc->sw_if_index);
99       locator.priority = ls_loc->priority;
100       locator.weight = ls_loc->weight;
101       locator.local = 1;
102       vec_add1 (a->locators, locator);
103     }
104
105   rv = vnet_lisp_add_del_locator_set (a, &ls_index);
106
107   BAD_SW_IF_INDEX_LABEL;
108
109   vec_free (locator_name);
110   vec_free (a->locators);
111
112   REPLY_MACRO2 (VL_API_LISP_ADD_DEL_LOCATOR_SET_REPLY,
113   ({
114     rmp->ls_index = clib_host_to_net_u32 (ls_index);
115   }));
116 }
117
118 static void
119 vl_api_lisp_add_del_locator_t_handler (vl_api_lisp_add_del_locator_t * mp)
120 {
121   vl_api_lisp_add_del_locator_reply_t *rmp;
122   int rv = 0;
123   locator_t locator, *locators = NULL;
124   vnet_lisp_add_del_locator_set_args_t _a, *a = &_a;
125   u32 ls_index = ~0;
126   u8 *locator_name = NULL;
127
128   clib_memset (&locator, 0, sizeof (locator));
129   clib_memset (a, 0, sizeof (a[0]));
130
131   locator.sw_if_index = ntohl (mp->sw_if_index);
132   locator.priority = mp->priority;
133   locator.weight = mp->weight;
134   locator.local = 1;
135   vec_add1 (locators, locator);
136
137   mp->locator_set_name[sizeof (mp->locator_set_name) - 1] = 0;
138   locator_name = format (0, "%s", mp->locator_set_name);
139   vec_terminate_c_string (locator_name);
140
141   a->name = locator_name;
142   a->locators = locators;
143   a->is_add = mp->is_add;
144   a->local = 1;
145
146   rv = vnet_lisp_add_del_locator (a, NULL, &ls_index);
147
148   vec_free (locators);
149   vec_free (locator_name);
150
151   REPLY_MACRO (VL_API_LISP_ADD_DEL_LOCATOR_REPLY);
152 }
153
154 static void
155 vl_api_lisp_add_del_local_eid_t_handler (vl_api_lisp_add_del_local_eid_t * mp)
156 {
157   vl_api_lisp_add_del_local_eid_reply_t *rmp;
158   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
159   int rv = 0;
160   gid_address_t _gid, *gid = &_gid;
161   uword *p = NULL;
162   u32 locator_set_index = ~0, map_index = ~0;
163   vnet_lisp_add_del_mapping_args_t _a, *a = &_a;
164   u8 *name = NULL, *key = NULL;
165   clib_memset (a, 0, sizeof (a[0]));
166   clib_memset (gid, 0, sizeof (gid[0]));
167
168   rv = unformat_lisp_eid_api (gid, mp->vni, &mp->eid);
169   if (rv)
170     goto out;
171
172   mp->locator_set_name[sizeof (mp->locator_set_name) - 1] = 0;
173   name = format (0, "%s", mp->locator_set_name);
174   vec_terminate_c_string (name);
175   p = hash_get_mem (lcm->locator_set_index_by_name, name);
176   if (!p)
177     {
178       rv = VNET_API_ERROR_INVALID_VALUE;
179       goto out;
180     }
181   locator_set_index = p[0];
182
183   if (mp->key.id)
184     key = format (0, "%s", mp->key.key);
185
186   /* XXX treat batch configuration */
187   a->is_add = mp->is_add;
188   gid_address_copy (&a->eid, gid);
189   a->locator_set_index = locator_set_index;
190   a->local = 1;
191   a->key = key;
192   a->key_id = clib_net_to_host_u16 (mp->key.id);
193
194   rv = vnet_lisp_add_del_local_mapping (a, &map_index);
195
196 out:
197   vec_free (name);
198   vec_free (key);
199   gid_address_free (&a->eid);
200
201   REPLY_MACRO (VL_API_LISP_ADD_DEL_LOCAL_EID_REPLY);
202 }
203
204 static void
205   vl_api_lisp_eid_table_add_del_map_t_handler
206   (vl_api_lisp_eid_table_add_del_map_t * mp)
207 {
208   vl_api_lisp_eid_table_add_del_map_reply_t *rmp;
209   int rv = 0;
210   rv = vnet_lisp_eid_table_map (clib_net_to_host_u32 (mp->vni),
211                                 clib_net_to_host_u32 (mp->dp_table),
212                                 mp->is_l2, mp->is_add);
213 REPLY_MACRO (VL_API_LISP_EID_TABLE_ADD_DEL_MAP_REPLY)}
214
215 static void
216 vl_api_lisp_add_del_map_server_t_handler (vl_api_lisp_add_del_map_server_t
217                                           * mp)
218 {
219   vl_api_lisp_add_del_map_server_reply_t *rmp;
220   int rv = 0;
221   ip_address_t addr;
222
223   clib_memset (&addr, 0, sizeof (addr));
224
225   ip_address_decode2 (&mp->ip_address, &addr);
226   rv = vnet_lisp_add_del_map_server (&addr, mp->is_add);
227
228   REPLY_MACRO (VL_API_LISP_ADD_DEL_MAP_SERVER_REPLY);
229 }
230
231 static void
232 vl_api_lisp_add_del_map_resolver_t_handler (vl_api_lisp_add_del_map_resolver_t
233                                             * mp)
234 {
235   vl_api_lisp_add_del_map_resolver_reply_t *rmp;
236   int rv = 0;
237   vnet_lisp_add_del_map_resolver_args_t _a, *a = &_a;
238
239   clib_memset (a, 0, sizeof (a[0]));
240
241   a->is_add = mp->is_add;
242   ip_address_decode2 (&mp->ip_address, &a->address);
243
244   rv = vnet_lisp_add_del_map_resolver (a);
245
246   REPLY_MACRO (VL_API_LISP_ADD_DEL_MAP_RESOLVER_REPLY);
247 }
248
249 static void
250   vl_api_lisp_map_register_enable_disable_t_handler
251   (vl_api_lisp_map_register_enable_disable_t * mp)
252 {
253   vl_api_lisp_map_register_enable_disable_reply_t *rmp;
254   int rv = 0;
255
256   vnet_lisp_map_register_enable_disable (mp->is_enable);
257   REPLY_MACRO (VL_API_LISP_ENABLE_DISABLE_REPLY);
258 }
259
260 static void
261   vl_api_lisp_rloc_probe_enable_disable_t_handler
262   (vl_api_lisp_rloc_probe_enable_disable_t * mp)
263 {
264   vl_api_lisp_rloc_probe_enable_disable_reply_t *rmp;
265   int rv = 0;
266
267   vnet_lisp_rloc_probe_enable_disable (mp->is_enable);
268   REPLY_MACRO (VL_API_LISP_ENABLE_DISABLE_REPLY);
269 }
270
271 static void
272 vl_api_lisp_enable_disable_t_handler (vl_api_lisp_enable_disable_t * mp)
273 {
274   vl_api_lisp_enable_disable_reply_t *rmp;
275   int rv = 0;
276
277   vnet_lisp_enable_disable (mp->is_enable);
278   REPLY_MACRO (VL_API_LISP_ENABLE_DISABLE_REPLY);
279 }
280
281 static void
282   vl_api_show_lisp_map_request_mode_t_handler
283   (vl_api_show_lisp_map_request_mode_t * mp)
284 {
285   int rv = 0;
286   vl_api_show_lisp_map_request_mode_reply_t *rmp;
287
288   REPLY_MACRO2(VL_API_SHOW_LISP_MAP_REQUEST_MODE_REPLY,
289   ({
290     rmp->is_src_dst = vnet_lisp_get_map_request_mode ();
291   }));
292 }
293
294 static void
295 vl_api_lisp_map_request_mode_t_handler (vl_api_lisp_map_request_mode_t * mp)
296 {
297   vl_api_lisp_map_request_mode_reply_t *rmp;
298   int rv = 0;
299
300   rv = vnet_lisp_set_map_request_mode (mp->is_src_dst);
301
302   REPLY_MACRO (VL_API_LISP_MAP_REQUEST_MODE_REPLY);
303 }
304
305 static void
306 vl_api_lisp_pitr_set_locator_set_t_handler (vl_api_lisp_pitr_set_locator_set_t
307                                             * mp)
308 {
309   vl_api_lisp_pitr_set_locator_set_reply_t *rmp;
310   int rv = 0;
311   u8 *ls_name = 0;
312
313   mp->ls_name[sizeof (mp->ls_name) - 1] = 0;
314   ls_name = format (0, "%s", mp->ls_name);
315   vec_terminate_c_string (ls_name);
316   rv = vnet_lisp_pitr_set_locator_set (ls_name, mp->is_add);
317   vec_free (ls_name);
318
319   REPLY_MACRO (VL_API_LISP_PITR_SET_LOCATOR_SET_REPLY);
320 }
321
322 static void
323 vl_api_lisp_use_petr_t_handler (vl_api_lisp_use_petr_t * mp)
324 {
325   vl_api_lisp_use_petr_reply_t *rmp;
326   int rv = 0;
327   ip_address_t addr;
328
329   ip_address_decode2 (&mp->ip_address, &addr);
330   rv = vnet_lisp_use_petr (&addr, mp->is_add);
331
332   REPLY_MACRO (VL_API_LISP_USE_PETR_REPLY);
333 }
334
335 static void
336 vl_api_show_lisp_use_petr_t_handler (vl_api_show_lisp_use_petr_t * mp)
337 {
338   vl_api_show_lisp_use_petr_reply_t *rmp = NULL;
339   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
340   mapping_t *m;
341   locator_set_t *ls = 0;
342   int rv = 0;
343   locator_t *loc = 0;
344   u8 status = 0;
345   gid_address_t addr;
346
347   clib_memset (&addr, 0, sizeof (addr));
348   status = lcm->flags & LISP_FLAG_USE_PETR;
349   if (status)
350     {
351       m = pool_elt_at_index (lcm->mapping_pool, lcm->petr_map_index);
352       if (~0 != m->locator_set_index)
353         {
354           ls =
355             pool_elt_at_index (lcm->locator_set_pool, m->locator_set_index);
356           loc = pool_elt_at_index (lcm->locator_pool, ls->locator_indices[0]);
357           gid_address_copy (&addr, &loc->address);
358         }
359     }
360
361   REPLY_MACRO2 (VL_API_SHOW_LISP_USE_PETR_REPLY,
362   {
363     rmp->is_petr_enable = status;
364     ip_address_encode2 (&gid_address_ip (&addr), &rmp->ip_address);
365   });
366 }
367
368 static void
369   vl_api_lisp_add_del_map_request_itr_rlocs_t_handler
370   (vl_api_lisp_add_del_map_request_itr_rlocs_t * mp)
371 {
372   vl_api_lisp_add_del_map_request_itr_rlocs_reply_t *rmp;
373   int rv = 0;
374   u8 *locator_set_name = NULL;
375   vnet_lisp_add_del_mreq_itr_rloc_args_t _a, *a = &_a;
376
377   mp->locator_set_name[sizeof (mp->locator_set_name) - 1] = 0;
378   locator_set_name = format (0, "%s", mp->locator_set_name);
379   vec_terminate_c_string (locator_set_name);
380
381   a->is_add = mp->is_add;
382   a->locator_set_name = locator_set_name;
383
384   rv = vnet_lisp_add_del_mreq_itr_rlocs (a);
385
386   vec_free (locator_set_name);
387
388   REPLY_MACRO (VL_API_LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY);
389 }
390
391 static void
392   vl_api_lisp_add_del_remote_mapping_t_handler
393   (vl_api_lisp_add_del_remote_mapping_t * mp)
394 {
395   locator_t *rlocs = 0;
396   vl_api_lisp_add_del_remote_mapping_reply_t *rmp;
397   int rv = 0;
398   gid_address_t _eid, *eid = &_eid;
399   u32 rloc_num = clib_net_to_host_u32 (mp->rloc_num);
400
401   clib_memset (eid, 0, sizeof (eid[0]));
402
403   rv = unformat_lisp_eid_api (eid, mp->vni, &mp->deid);
404   if (rv)
405     goto send_reply;
406
407   rlocs = unformat_lisp_locs (mp->rlocs, rloc_num);
408
409   if (!mp->is_add)
410     {
411       vnet_lisp_add_del_adjacency_args_t _a, *a = &_a;
412       clib_memset (a, 0, sizeof (*a));
413       gid_address_copy (&a->reid, eid);
414       a->is_add = 0;
415       rv = vnet_lisp_add_del_adjacency (a);
416       if (rv)
417         {
418           goto out;
419         }
420     }
421
422   /* NOTE: for now this works as a static remote mapping, i.e.,
423    * not authoritative and ttl infinite. */
424   if (mp->is_add)
425     {
426       vnet_lisp_add_del_mapping_args_t _m_args, *m_args = &_m_args;
427       clib_memset (m_args, 0, sizeof (m_args[0]));
428       gid_address_copy (&m_args->eid, eid);
429       m_args->action = mp->action;
430       m_args->is_static = 1;
431       m_args->ttl = ~0;
432       m_args->authoritative = 0;
433       rv = vnet_lisp_add_mapping (m_args, rlocs, NULL, NULL);
434     }
435   else
436     {
437       rv = vnet_lisp_del_mapping (eid, NULL);
438     }
439
440   if (mp->del_all)
441     vnet_lisp_clear_all_remote_adjacencies ();
442
443 out:
444   vec_free (rlocs);
445 send_reply:
446   REPLY_MACRO (VL_API_LISP_ADD_DEL_REMOTE_MAPPING_REPLY);
447 }
448
449 static void
450 vl_api_lisp_add_del_adjacency_t_handler (vl_api_lisp_add_del_adjacency_t * mp)
451 {
452   vl_api_lisp_add_del_adjacency_reply_t *rmp;
453   vnet_lisp_add_del_adjacency_args_t _a, *a = &_a;
454
455   int rv = 0;
456   clib_memset (a, 0, sizeof (a[0]));
457
458   rv = unformat_lisp_eid_api (&a->leid, mp->vni, &mp->leid);
459   rv = unformat_lisp_eid_api (&a->reid, mp->vni, &mp->reid);
460
461   if (rv)
462     goto send_reply;
463
464   a->is_add = mp->is_add;
465   rv = vnet_lisp_add_del_adjacency (a);
466
467 send_reply:
468   REPLY_MACRO (VL_API_LISP_ADD_DEL_ADJACENCY_REPLY);
469 }
470
471 static void
472 send_lisp_locator_details (lisp_cp_main_t * lcm,
473                            locator_t * loc, vl_api_registration_t * reg,
474                            u32 context)
475 {
476   vl_api_lisp_locator_details_t *rmp;
477
478   rmp = vl_msg_api_alloc (sizeof (*rmp));
479   clib_memset (rmp, 0, sizeof (*rmp));
480   rmp->_vl_msg_id = ntohs (VL_API_LISP_LOCATOR_DETAILS + REPLY_MSG_ID_BASE);
481   rmp->context = context;
482
483   rmp->local = loc->local;
484   if (loc->local)
485     {
486       rmp->sw_if_index = ntohl (loc->sw_if_index);
487     }
488   else
489     {
490       ip_address_encode2 (&gid_address_ip (&loc->address), &rmp->ip_address);
491     }
492   rmp->priority = loc->priority;
493   rmp->weight = loc->weight;
494
495   vl_api_send_msg (reg, (u8 *) rmp);
496 }
497
498 static void
499 vl_api_lisp_locator_dump_t_handler (vl_api_lisp_locator_dump_t * mp)
500 {
501   u8 *ls_name = 0;
502   vl_api_registration_t *reg = 0;
503   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
504   locator_set_t *lsit = 0;
505   locator_t *loc = 0;
506   u32 ls_index = ~0, *locit = 0;
507   uword *p = 0;
508
509   reg = vl_api_client_index_to_registration (mp->client_index);
510   if (!reg)
511     return;
512
513   if (mp->is_index_set)
514     ls_index = htonl (mp->ls_index);
515   else
516     {
517       /* make sure we get a proper C-string */
518       mp->ls_name[sizeof (mp->ls_name) - 1] = 0;
519       ls_name = format (0, "%s", mp->ls_name);
520       vec_terminate_c_string (ls_name);
521       p = hash_get_mem (lcm->locator_set_index_by_name, ls_name);
522       if (!p)
523         goto out;
524       ls_index = p[0];
525     }
526
527   if (pool_is_free_index (lcm->locator_set_pool, ls_index))
528     return;
529
530   lsit = pool_elt_at_index (lcm->locator_set_pool, ls_index);
531
532   vec_foreach (locit, lsit->locator_indices)
533   {
534     loc = pool_elt_at_index (lcm->locator_pool, locit[0]);
535     send_lisp_locator_details (lcm, loc, reg, mp->context);
536   };
537 out:
538   vec_free (ls_name);
539 }
540
541 static void
542 send_lisp_locator_set_details (lisp_cp_main_t * lcm,
543                                locator_set_t * lsit,
544                                vl_api_registration_t * reg, u32 context,
545                                u32 ls_index)
546 {
547   vl_api_lisp_locator_set_details_t *rmp;
548   u8 *str = 0;
549
550   rmp = vl_msg_api_alloc (sizeof (*rmp));
551   clib_memset (rmp, 0, sizeof (*rmp));
552   rmp->_vl_msg_id =
553     ntohs (VL_API_LISP_LOCATOR_SET_DETAILS + REPLY_MSG_ID_BASE);
554   rmp->context = context;
555
556   rmp->ls_index = htonl (ls_index);
557   if (lsit->local)
558     {
559       ASSERT (lsit->name != NULL);
560       strncpy ((char *) rmp->ls_name, (char *) lsit->name,
561                vec_len (lsit->name));
562     }
563   else
564     {
565       str = format (0, "<remote-%d>", ls_index);
566       strncpy ((char *) rmp->ls_name, (char *) str, vec_len (str));
567       vec_free (str);
568     }
569
570   vl_api_send_msg (reg, (u8 *) rmp);
571 }
572
573 static void
574 vl_api_lisp_locator_set_dump_t_handler (vl_api_lisp_locator_set_dump_t * mp)
575 {
576   vl_api_registration_t *reg;
577   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
578   locator_set_t *lsit = NULL;
579   u8 filter;
580
581   reg = vl_api_client_index_to_registration (mp->client_index);
582   if (!reg)
583     return;
584
585   filter = mp->filter;
586   pool_foreach (lsit, lcm->locator_set_pool)
587    {
588     if (filter && !((1 == filter && lsit->local) ||
589                     (2 == filter && !lsit->local)))
590       {
591         continue;
592       }
593     send_lisp_locator_set_details (lcm, lsit, reg, mp->context,
594                                    lsit - lcm->locator_set_pool);
595   }
596 }
597
598 static void
599 send_lisp_eid_table_details (mapping_t * mapit,
600                              vl_api_registration_t * reg, u32 context,
601                              u8 filter)
602 {
603   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
604   locator_set_t *ls = 0;
605   vl_api_lisp_eid_table_details_t *rmp = NULL;
606   gid_address_t *gid = NULL;
607
608   switch (filter)
609     {
610     case 0:                     /* all mappings */
611       break;
612
613     case 1:                     /* local only */
614       if (!mapit->local)
615         return;
616       break;
617     case 2:                     /* remote only */
618       if (mapit->local)
619         return;
620       break;
621     default:
622       clib_warning ("Filter error, unknown filter: %d", filter);
623       return;
624     }
625
626   /* don't send PITR generated mapping */
627   if (mapit->pitr_set)
628     return;
629
630   gid = &mapit->eid;
631
632   rmp = vl_msg_api_alloc (sizeof (*rmp));
633   clib_memset (rmp, 0, sizeof (*rmp));
634   rmp->_vl_msg_id = ntohs (VL_API_LISP_EID_TABLE_DETAILS + REPLY_MSG_ID_BASE);
635
636   ls = pool_elt_at_index (lcm->locator_set_pool, mapit->locator_set_index);
637   if (vec_len (ls->locator_indices) == 0)
638     rmp->locator_set_index = ~0;
639   else
640     rmp->locator_set_index = clib_host_to_net_u32 (mapit->locator_set_index);
641
642   rmp->is_local = mapit->local;
643   rmp->ttl = clib_host_to_net_u32 (mapit->ttl);
644   rmp->action = mapit->action;
645   rmp->authoritative = mapit->authoritative;
646   switch (gid_address_type (gid))
647     {
648     case GID_ADDR_SRC_DST:
649       lisp_fid_put_api (&rmp->seid, &gid_address_sd_src (gid));
650       lisp_fid_put_api (&rmp->deid, &gid_address_sd_dst (gid));
651       rmp->is_src_dst = 1;
652       break;
653     case GID_ADDR_IP_PREFIX:
654       lisp_gid_put_api (&rmp->seid, gid);
655       break;
656     case GID_ADDR_MAC:
657       lisp_gid_put_api (&rmp->seid, gid);
658       break;
659     default:
660       ASSERT (0);
661     }
662   rmp->context = context;
663   rmp->vni = clib_host_to_net_u32 (gid_address_vni (gid));
664   rmp->key.id = clib_host_to_net_u16 (mapit->key_id);
665   memcpy (rmp->key.key, mapit->key, vec_len (mapit->key));
666   vl_api_send_msg (reg, (u8 *) rmp);
667 }
668
669 static void
670 vl_api_lisp_eid_table_dump_t_handler (vl_api_lisp_eid_table_dump_t * mp)
671 {
672   u32 mi;
673   vl_api_registration_t *reg;
674   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
675   mapping_t *mapit = NULL;
676   gid_address_t _eid, *eid = &_eid;
677
678   reg = vl_api_client_index_to_registration (mp->client_index);
679   if (!reg)
680     return;
681
682   if (mp->eid_set)
683     {
684       clib_memset (eid, 0, sizeof (*eid));
685
686       unformat_lisp_eid_api (eid, mp->vni, &mp->eid);
687
688       mi = gid_dictionary_lookup (&lcm->mapping_index_by_gid, eid);
689       if ((u32) ~ 0 == mi)
690         return;
691
692       mapit = pool_elt_at_index (lcm->mapping_pool, mi);
693       send_lisp_eid_table_details (mapit, reg, mp->context,
694                                    0 /* ignore filter */ );
695     }
696   else
697     {
698       pool_foreach (mapit, lcm->mapping_pool)
699        {
700         send_lisp_eid_table_details(mapit, reg, mp->context,
701                                     mp->filter);
702       }
703     }
704 }
705
706 static void
707 send_lisp_map_server_details (ip_address_t * ip, vl_api_registration_t * reg,
708                               u32 context)
709 {
710   vl_api_lisp_map_server_details_t *rmp = NULL;
711
712   rmp = vl_msg_api_alloc (sizeof (*rmp));
713   clib_memset (rmp, 0, sizeof (*rmp));
714   rmp->_vl_msg_id =
715     ntohs (VL_API_LISP_MAP_SERVER_DETAILS + REPLY_MSG_ID_BASE);
716
717   ip_address_encode2 (ip, &rmp->ip_address);
718   rmp->context = context;
719
720   vl_api_send_msg (reg, (u8 *) rmp);
721 }
722
723 static void
724 vl_api_lisp_map_server_dump_t_handler (vl_api_lisp_map_server_dump_t * mp)
725 {
726   vl_api_registration_t *reg;
727   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
728   lisp_msmr_t *mr;
729
730   reg = vl_api_client_index_to_registration (mp->client_index);
731   if (!reg)
732     return;
733
734   vec_foreach (mr, lcm->map_servers)
735   {
736     send_lisp_map_server_details (&mr->address, reg, mp->context);
737   }
738 }
739
740 static void
741 send_lisp_map_resolver_details (ip_address_t * ip,
742                                 vl_api_registration_t * reg, u32 context)
743 {
744   vl_api_lisp_map_resolver_details_t *rmp = NULL;
745
746   rmp = vl_msg_api_alloc (sizeof (*rmp));
747   clib_memset (rmp, 0, sizeof (*rmp));
748   rmp->_vl_msg_id =
749     ntohs (VL_API_LISP_MAP_RESOLVER_DETAILS + REPLY_MSG_ID_BASE);
750
751   ip_address_encode2 (ip, &rmp->ip_address);
752   rmp->context = context;
753
754   vl_api_send_msg (reg, (u8 *) rmp);
755 }
756
757 static void
758 vl_api_lisp_map_resolver_dump_t_handler (vl_api_lisp_map_resolver_dump_t * mp)
759 {
760   vl_api_registration_t *reg;
761   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
762   lisp_msmr_t *mr;
763
764   reg = vl_api_client_index_to_registration (mp->client_index);
765   if (!reg)
766     return;
767
768   vec_foreach (mr, lcm->map_resolvers)
769   {
770     send_lisp_map_resolver_details (&mr->address, reg, mp->context);
771   }
772 }
773
774 static void
775 send_eid_table_map_pair (hash_pair_t * p, vl_api_registration_t * reg,
776                          u32 context)
777 {
778   vl_api_lisp_eid_table_map_details_t *rmp = NULL;
779
780   rmp = vl_msg_api_alloc (sizeof (*rmp));
781   clib_memset (rmp, 0, sizeof (*rmp));
782   rmp->_vl_msg_id =
783     ntohs (VL_API_LISP_EID_TABLE_MAP_DETAILS + REPLY_MSG_ID_BASE);
784
785   rmp->vni = clib_host_to_net_u32 (p->key);
786   rmp->dp_table = clib_host_to_net_u32 (p->value[0]);
787   rmp->context = context;
788   vl_api_send_msg (reg, (u8 *) rmp);
789 }
790
791 static void
792 vl_api_lisp_eid_table_map_dump_t_handler (vl_api_lisp_eid_table_map_dump_t *
793                                           mp)
794 {
795   vl_api_registration_t *reg;
796   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
797   hash_pair_t *p;
798   uword *vni_table = 0;
799
800   reg = vl_api_client_index_to_registration (mp->client_index);
801   if (!reg)
802     return;
803
804   if (mp->is_l2)
805     {
806       vni_table = lcm->bd_id_by_vni;
807     }
808   else
809     {
810       vni_table = lcm->table_id_by_vni;
811     }
812
813   hash_foreach_pair (p, vni_table,
814   ({
815     send_eid_table_map_pair (p, reg, mp->context);
816   }));
817 }
818
819 static void
820 send_eid_table_vni (u32 vni, vl_api_registration_t * reg, u32 context)
821 {
822   vl_api_lisp_eid_table_vni_details_t *rmp = 0;
823
824   rmp = vl_msg_api_alloc (sizeof (*rmp));
825   clib_memset (rmp, 0, sizeof (*rmp));
826   rmp->_vl_msg_id =
827     ntohs (VL_API_LISP_EID_TABLE_VNI_DETAILS + REPLY_MSG_ID_BASE);
828   rmp->context = context;
829   rmp->vni = clib_host_to_net_u32 (vni);
830   vl_api_send_msg (reg, (u8 *) rmp);
831 }
832
833 static void
834 lisp_adjacency_copy (vl_api_lisp_adjacency_t * dst, lisp_adjacency_t * adjs)
835 {
836   lisp_adjacency_t *adj;
837   vl_api_lisp_adjacency_t a;
838   u32 i, n = vec_len (adjs);
839
840   for (i = 0; i < n; i++)
841     {
842       adj = vec_elt_at_index (adjs, i);
843       clib_memset (&a, 0, sizeof (a));
844
845       lisp_gid_put_api (&a.reid, &adj->reid);
846       lisp_gid_put_api (&a.leid, &adj->leid);
847
848       dst[i] = a;
849     }
850 }
851
852 static void
853   vl_api_show_lisp_rloc_probe_state_t_handler
854   (vl_api_show_lisp_rloc_probe_state_t * mp)
855 {
856   vl_api_show_lisp_rloc_probe_state_reply_t *rmp = 0;
857   int rv = 0;
858
859   REPLY_MACRO2 (VL_API_SHOW_LISP_RLOC_PROBE_STATE_REPLY,
860   {
861     rmp->is_enabled = vnet_lisp_rloc_probe_state_get ();
862   });
863 }
864
865 static void
866   vl_api_show_lisp_map_register_state_t_handler
867   (vl_api_show_lisp_map_register_state_t * mp)
868 {
869   vl_api_show_lisp_map_register_state_reply_t *rmp = 0;
870   int rv = 0;
871
872   REPLY_MACRO2 (VL_API_SHOW_LISP_MAP_REGISTER_STATE_REPLY,
873   {
874     rmp->is_enabled = vnet_lisp_map_register_state_get ();
875   });
876 }
877
878 static void
879 vl_api_lisp_adjacencies_get_t_handler (vl_api_lisp_adjacencies_get_t * mp)
880 {
881   vl_api_lisp_adjacencies_get_reply_t *rmp = 0;
882   lisp_adjacency_t *adjs = 0;
883   int rv = 0;
884   u32 size = ~0;
885   u32 vni = clib_net_to_host_u32 (mp->vni);
886
887   adjs = vnet_lisp_adjacencies_get_by_vni (vni);
888   size = vec_len (adjs) * sizeof (vl_api_lisp_adjacency_t);
889
890   REPLY_MACRO4 (VL_API_LISP_ADJACENCIES_GET_REPLY, size,
891   {
892     rmp->count = clib_host_to_net_u32 (vec_len (adjs));
893     lisp_adjacency_copy (rmp->adjacencies, adjs);
894   });
895
896   vec_free (adjs);
897 }
898
899 static void
900 vl_api_lisp_eid_table_vni_dump_t_handler (vl_api_lisp_eid_table_vni_dump_t *
901                                           mp)
902 {
903   hash_pair_t *p;
904   u32 *vnis = 0;
905   vl_api_registration_t *reg = 0;
906   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
907
908   reg = vl_api_client_index_to_registration (mp->client_index);
909   if (!reg)
910     return;
911
912   hash_foreach_pair (p, lcm->table_id_by_vni,
913   ({
914     hash_set (vnis, p->key, 0);
915   }));
916
917   hash_foreach_pair (p, lcm->bd_id_by_vni,
918   ({
919     hash_set (vnis, p->key, 0);
920   }));
921
922   hash_foreach_pair (p, vnis,
923   ({
924     send_eid_table_vni (p->key, reg, mp->context);
925   }));
926
927   hash_free (vnis);
928 }
929
930 static void
931 vl_api_show_lisp_status_t_handler (vl_api_show_lisp_status_t * mp)
932 {
933   vl_api_show_lisp_status_reply_t *rmp = NULL;
934   int rv = 0;
935
936   REPLY_MACRO2(VL_API_SHOW_LISP_STATUS_REPLY,
937   ({
938     rmp->is_gpe_enabled = vnet_lisp_gpe_enable_disable_status ();
939     rmp->is_lisp_enabled = vnet_lisp_enable_disable_status ();
940   }));
941 }
942
943 static void
944   vl_api_lisp_get_map_request_itr_rlocs_t_handler
945   (vl_api_lisp_get_map_request_itr_rlocs_t * mp)
946 {
947   vl_api_lisp_get_map_request_itr_rlocs_reply_t *rmp = NULL;
948   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
949   locator_set_t *loc_set = 0;
950   u8 *tmp_str = 0;
951   int rv = 0;
952
953   if (~0 == lcm->mreq_itr_rlocs)
954     {
955       tmp_str = format (0, " ");
956     }
957   else
958     {
959       loc_set =
960         pool_elt_at_index (lcm->locator_set_pool, lcm->mreq_itr_rlocs);
961       tmp_str = format (0, "%s", loc_set->name);
962     }
963
964   REPLY_MACRO2(VL_API_LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,
965   ({
966     strncpy((char *) rmp->locator_set_name, (char *) tmp_str,
967             ARRAY_LEN(rmp->locator_set_name) - 1);
968   }));
969
970   vec_free (tmp_str);
971 }
972
973 static void
974 vl_api_show_lisp_pitr_t_handler (vl_api_show_lisp_pitr_t * mp)
975 {
976   vl_api_show_lisp_pitr_reply_t *rmp = NULL;
977   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
978   mapping_t *m;
979   locator_set_t *ls = 0;
980   u8 *tmp_str = 0;
981   int rv = 0;
982
983   u8 is_enabled = (lcm->flags & LISP_FLAG_PITR_MODE)
984     && lcm->pitr_map_index != ~0;
985
986   if (!is_enabled)
987     {
988       tmp_str = format (0, "N/A");
989     }
990   else
991     {
992       m = pool_elt_at_index (lcm->mapping_pool, lcm->pitr_map_index);
993       if (~0 != m->locator_set_index)
994         {
995           ls =
996             pool_elt_at_index (lcm->locator_set_pool, m->locator_set_index);
997           tmp_str = format (0, "%s", ls->name);
998         }
999       else
1000         {
1001           tmp_str = format (0, "N/A");
1002         }
1003     }
1004   vec_add1 (tmp_str, 0);
1005
1006   REPLY_MACRO2(VL_API_SHOW_LISP_PITR_REPLY,
1007   ({
1008     rmp->is_enabled = lcm->flags & LISP_FLAG_PITR_MODE;
1009     strncpy((char *) rmp->locator_set_name, (char *) tmp_str,
1010             ARRAY_LEN(rmp->locator_set_name) - 1);
1011   }));
1012 }
1013
1014 /*
1015  * lisp_api_hookup
1016  * Add vpe's API message handlers to the table.
1017  * vlib has already mapped shared memory and
1018  * added the client registration handlers.
1019  * See .../vlib-api/vlibmemory/memclnt_vlib.c:memclnt_process()
1020  */
1021 #include <lisp/lisp-cp/lisp.api.c>
1022
1023 static clib_error_t *
1024 lisp_api_hookup (vlib_main_t * vm)
1025 {
1026   /*
1027    * Set up the (msg_name, crc, message-id) table
1028    */
1029   lisp_base_msg_id = setup_message_id_table ();
1030
1031   return NULL;
1032 }
1033
1034 VLIB_API_INIT_FUNCTION (lisp_api_hookup);
1035
1036 /*
1037  * fd.io coding-style-patch-verification: ON
1038  *
1039  * Local Variables:
1040  * eval: (c-set-style "gnu")
1041  * End:
1042  */