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