blob: 4ed480c4fd8d878442dbcbfda4181efc80def35b [file] [log] [blame]
Pavel Kotucekabea9662016-12-21 15:50:08 +01001/*
2 *------------------------------------------------------------------
3 * lisp_gpe_api.c - lisp_gpe 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-gpe/lisp_gpe.h>
Filip Tehlar5fae99c2017-01-18 12:57:37 +010026#include <vnet/lisp-gpe/lisp_gpe_adjacency.h>
27#include <vnet/lisp-gpe/lisp_gpe_tunnel.h>
Pavel Kotucekabea9662016-12-21 15:50:08 +010028#include <vnet/lisp-gpe/lisp_gpe_fwd_entry.h>
29#include <vnet/lisp-gpe/lisp_gpe_tenant.h>
Florin Corasa4e63e52017-06-07 21:50:57 -070030#include <vnet/fib/fib_table.h>
Pavel Kotucekabea9662016-12-21 15:50:08 +010031#include <vnet/vnet_msg_enum.h>
32
Filip Tehlar82786c42017-02-20 15:20:37 +010033#define vl_api_gpe_locator_pair_t_endian vl_noop_handler
34#define vl_api_gpe_locator_pair_t_print vl_noop_handler
35#define vl_api_gpe_add_del_fwd_entry_t_endian vl_noop_handler
36#define vl_api_gpe_add_del_fwd_entry_t_print vl_noop_handler
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010037
Pavel Kotucekabea9662016-12-21 15:50:08 +010038#define vl_typedefs /* define message structures */
39#include <vnet/vnet_all_api_h.h>
40#undef vl_typedefs
41
42#define vl_endianfun /* define message structures */
43#include <vnet/vnet_all_api_h.h>
44#undef vl_endianfun
45
46/* instantiate all the print functions we know about */
47#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
48#define vl_printfun
49#include <vnet/vnet_all_api_h.h>
50#undef vl_printfun
51
52#include <vlibapi/api_helper_macros.h>
53
Florin Corasa4e63e52017-06-07 21:50:57 -070054#define foreach_vpe_api_msg \
55_(GPE_ADD_DEL_FWD_ENTRY, gpe_add_del_fwd_entry) \
56_(GPE_FWD_ENTRIES_GET, gpe_fwd_entries_get) \
57_(GPE_FWD_ENTRY_PATH_DUMP, gpe_fwd_entry_path_dump) \
58_(GPE_ENABLE_DISABLE, gpe_enable_disable) \
59_(GPE_ADD_DEL_IFACE, gpe_add_del_iface) \
60_(GPE_FWD_ENTRY_VNIS_GET, gpe_fwd_entry_vnis_get) \
61_(GPE_SET_ENCAP_MODE, gpe_set_encap_mode) \
62_(GPE_GET_ENCAP_MODE, gpe_get_encap_mode) \
63_(GPE_ADD_DEL_NATIVE_FWD_RPATH, gpe_add_del_native_fwd_rpath) \
64_(GPE_NATIVE_FWD_RPATHS_GET, gpe_native_fwd_rpaths_get)
Pavel Kotucekabea9662016-12-21 15:50:08 +010065
66static locator_pair_t *
Filip Tehlar82786c42017-02-20 15:20:37 +010067unformat_gpe_loc_pairs (void *locs, u32 rloc_num)
Pavel Kotucekabea9662016-12-21 15:50:08 +010068{
69 u32 i;
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010070 locator_pair_t *pairs = 0, pair, *p;
Filip Tehlar82786c42017-02-20 15:20:37 +010071 vl_api_gpe_locator_t *r;
Pavel Kotucekabea9662016-12-21 15:50:08 +010072
73 for (i = 0; i < rloc_num; i++)
74 {
75 /* local locator */
Filip Tehlar82786c42017-02-20 15:20:37 +010076 r = &((vl_api_gpe_locator_t *) locs)[i];
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010077 memset (&pair, 0, sizeof (pair));
Pavel Kotucekabea9662016-12-21 15:50:08 +010078 ip_address_set (&pair.lcl_loc, &r->addr, r->is_ip4 ? IP4 : IP6);
79
Pavel Kotucekabea9662016-12-21 15:50:08 +010080 pair.weight = r->weight;
Pavel Kotucekabea9662016-12-21 15:50:08 +010081 vec_add1 (pairs, pair);
82 }
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010083
84 for (i = rloc_num; i < rloc_num * 2; i++)
85 {
86 /* remote locators */
Filip Tehlar82786c42017-02-20 15:20:37 +010087 r = &((vl_api_gpe_locator_t *) locs)[i];
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010088 p = &pairs[i - rloc_num];
89 ip_address_set (&p->rmt_loc, &r->addr, r->is_ip4 ? IP4 : IP6);
90 }
Pavel Kotucekabea9662016-12-21 15:50:08 +010091 return pairs;
92}
93
94static int
95unformat_lisp_eid_api (gid_address_t * dst, u32 vni, u8 type, void *src,
96 u8 len)
97{
98 switch (type)
99 {
100 case 0: /* ipv4 */
101 gid_address_type (dst) = GID_ADDR_IP_PREFIX;
102 gid_address_ip_set (dst, src, IP4);
103 gid_address_ippref_len (dst) = len;
104 ip_prefix_normalize (&gid_address_ippref (dst));
105 break;
106 case 1: /* ipv6 */
107 gid_address_type (dst) = GID_ADDR_IP_PREFIX;
108 gid_address_ip_set (dst, src, IP6);
109 gid_address_ippref_len (dst) = len;
110 ip_prefix_normalize (&gid_address_ippref (dst));
111 break;
112 case 2: /* l2 mac */
113 gid_address_type (dst) = GID_ADDR_MAC;
114 clib_memcpy (&gid_address_mac (dst), src, 6);
115 break;
116 default:
117 /* unknown type */
118 return VNET_API_ERROR_INVALID_VALUE;
119 }
120
121 gid_address_vni (dst) = vni;
122
123 return 0;
124}
125
126static void
Filip Tehlar82786c42017-02-20 15:20:37 +0100127 gpe_fwd_entry_path_dump_t_net_to_host
128 (vl_api_gpe_fwd_entry_path_dump_t * mp)
Filip Tehlar5fae99c2017-01-18 12:57:37 +0100129{
130 mp->fwd_entry_index = clib_net_to_host_u32 (mp->fwd_entry_index);
131}
132
133static void
Filip Tehlar82786c42017-02-20 15:20:37 +0100134lisp_api_set_locator (vl_api_gpe_locator_t * loc,
Filip Tehlar5fae99c2017-01-18 12:57:37 +0100135 const ip_address_t * addr, u8 weight)
136{
137 loc->weight = weight;
138 if (IP4 == ip_addr_version (addr))
139 {
140 loc->is_ip4 = 1;
141 memcpy (loc->addr, addr, 4);
142 }
143 else
144 {
145 loc->is_ip4 = 0;
146 memcpy (loc->addr, addr, 16);
147 }
148}
149
150static void
Filip Tehlar82786c42017-02-20 15:20:37 +0100151 vl_api_gpe_fwd_entry_path_dump_t_handler
152 (vl_api_gpe_fwd_entry_path_dump_t * mp)
Filip Tehlar5fae99c2017-01-18 12:57:37 +0100153{
154 lisp_fwd_path_t *path;
Filip Tehlar82786c42017-02-20 15:20:37 +0100155 vl_api_gpe_fwd_entry_path_details_t *rmp = NULL;
Filip Tehlar5fae99c2017-01-18 12:57:37 +0100156 lisp_gpe_main_t *lgm = &lisp_gpe_main;
157 unix_shared_memory_queue_t *q = NULL;
158 lisp_gpe_fwd_entry_t *lfe;
159
Filip Tehlar82786c42017-02-20 15:20:37 +0100160 gpe_fwd_entry_path_dump_t_net_to_host (mp);
Filip Tehlar5fae99c2017-01-18 12:57:37 +0100161
162 q = vl_api_client_index_to_input_queue (mp->client_index);
163 if (q == 0)
164 return;
165
166 if (pool_is_free_index (lgm->lisp_fwd_entry_pool, mp->fwd_entry_index))
167 return;
168
169 lfe = pool_elt_at_index (lgm->lisp_fwd_entry_pool, mp->fwd_entry_index);
170
171 if (LISP_GPE_FWD_ENTRY_TYPE_NEGATIVE == lfe->type)
172 return;
173
174 vec_foreach (path, lfe->paths)
175 {
176 rmp = vl_msg_api_alloc (sizeof (*rmp));
177 memset (rmp, 0, sizeof (*rmp));
178 const lisp_gpe_tunnel_t *lgt;
179
180 rmp->_vl_msg_id =
Filip Tehlar82786c42017-02-20 15:20:37 +0100181 clib_host_to_net_u16 (VL_API_GPE_FWD_ENTRY_PATH_DETAILS);
Filip Tehlar5fae99c2017-01-18 12:57:37 +0100182
183 const lisp_gpe_adjacency_t *ladj =
184 lisp_gpe_adjacency_get (path->lisp_adj);
185 lisp_api_set_locator (&rmp->rmt_loc, &ladj->remote_rloc, path->weight);
186 lgt = lisp_gpe_tunnel_get (ladj->tunnel_index);
187 lisp_api_set_locator (&rmp->lcl_loc, &lgt->key->lcl, path->weight);
188
189 rmp->context = mp->context;
190 vl_msg_api_send_shmem (q, (u8 *) & rmp);
191 }
192}
193
194static void
Filip Tehlar82786c42017-02-20 15:20:37 +0100195gpe_fwd_entries_copy (vl_api_gpe_fwd_entry_t * dst,
196 lisp_api_gpe_fwd_entry_t * src)
Filip Tehlar5fae99c2017-01-18 12:57:37 +0100197{
198 lisp_api_gpe_fwd_entry_t *e;
199 u32 i = 0;
200
201 vec_foreach (e, src)
202 {
Filip Tehlar719aef42017-06-05 09:50:38 +0200203 memset (&dst[i], 0, sizeof (*dst));
204 dst[i].dp_table = e->dp_table;
205 dst[i].fwd_entry_index = e->fwd_entry_index;
206 dst[i].vni = e->vni;
207 dst[i].action = e->action;
Filip Tehlar5fae99c2017-01-18 12:57:37 +0100208 switch (fid_addr_type (&e->leid))
209 {
210 case FID_ADDR_IP_PREF:
211 if (IP4 == ip_prefix_version (&fid_addr_ippref (&e->leid)))
212 {
213 memcpy (&dst[i].leid, &fid_addr_ippref (&e->leid), 4);
214 memcpy (&dst[i].reid, &fid_addr_ippref (&e->reid), 4);
215 dst[i].eid_type = 0;
216 }
217 else
218 {
219 memcpy (&dst[i].leid, &fid_addr_ippref (&e->leid), 16);
220 memcpy (&dst[i].reid, &fid_addr_ippref (&e->reid), 16);
221 dst[i].eid_type = 1;
222 }
223 dst[i].leid_prefix_len = ip_prefix_len (&fid_addr_ippref (&e->leid));
224 dst[i].reid_prefix_len = ip_prefix_len (&fid_addr_ippref (&e->reid));
225 break;
226 case FID_ADDR_MAC:
227 memcpy (&dst[i].leid, fid_addr_mac (&e->leid), 6);
228 memcpy (&dst[i].reid, fid_addr_mac (&e->reid), 6);
229 dst[i].eid_type = 2;
230 break;
231 default:
232 clib_warning ("unknown fid type %d!", fid_addr_type (&e->leid));
233 break;
234 }
235 i++;
236 }
237}
238
239static void
Filip Tehlar82786c42017-02-20 15:20:37 +0100240gpe_fwd_entries_get_t_net_to_host (vl_api_gpe_fwd_entries_get_t * mp)
Filip Tehlar5fae99c2017-01-18 12:57:37 +0100241{
242 mp->vni = clib_net_to_host_u32 (mp->vni);
243}
244
245static void
Filip Tehlar82786c42017-02-20 15:20:37 +0100246gpe_entry_t_host_to_net (vl_api_gpe_fwd_entry_t * e)
Filip Tehlar5fae99c2017-01-18 12:57:37 +0100247{
248 e->fwd_entry_index = clib_host_to_net_u32 (e->fwd_entry_index);
249 e->dp_table = clib_host_to_net_u32 (e->dp_table);
Filip Tehlar0eb874e2017-05-18 14:23:32 +0200250 e->vni = clib_host_to_net_u32 (e->vni);
Filip Tehlar5fae99c2017-01-18 12:57:37 +0100251}
252
253static void
Filip Tehlar82786c42017-02-20 15:20:37 +0100254 gpe_fwd_entries_get_reply_t_host_to_net
255 (vl_api_gpe_fwd_entries_get_reply_t * mp)
Filip Tehlar5fae99c2017-01-18 12:57:37 +0100256{
257 u32 i;
Filip Tehlar82786c42017-02-20 15:20:37 +0100258 vl_api_gpe_fwd_entry_t *e;
Filip Tehlar5fae99c2017-01-18 12:57:37 +0100259
260 for (i = 0; i < mp->count; i++)
261 {
262 e = &mp->entries[i];
Filip Tehlar82786c42017-02-20 15:20:37 +0100263 gpe_entry_t_host_to_net (e);
Filip Tehlar5fae99c2017-01-18 12:57:37 +0100264 }
265 mp->count = clib_host_to_net_u32 (mp->count);
266}
267
268static void
Filip Tehlar0eb874e2017-05-18 14:23:32 +0200269vl_api_gpe_fwd_entry_vnis_get_t_handler (vl_api_gpe_fwd_entry_vnis_get_t * mp)
270{
271 vl_api_gpe_fwd_entry_vnis_get_reply_t *rmp = 0;
272 hash_pair_t *p;
273 u32 i = 0;
274 int rv = 0;
275
276 u32 *vnis = vnet_lisp_gpe_get_fwd_entry_vnis ();
277 u32 size = hash_elts (vnis) * sizeof (u32);
278
279 /* *INDENT-OFF* */
280 REPLY_MACRO4 (VL_API_GPE_FWD_ENTRY_VNIS_GET_REPLY, size,
281 {
282 rmp->count = clib_host_to_net_u32 (hash_elts (vnis));
283 hash_foreach_pair (p, vnis,
284 ({
285 rmp->vnis[i++] = clib_host_to_net_u32 (p->key);
286 }));
287 });
288 /* *INDENT-ON* */
289
290 hash_free (vnis);
291}
292
293static void
Filip Tehlar82786c42017-02-20 15:20:37 +0100294vl_api_gpe_fwd_entries_get_t_handler (vl_api_gpe_fwd_entries_get_t * mp)
Filip Tehlar5fae99c2017-01-18 12:57:37 +0100295{
296 lisp_api_gpe_fwd_entry_t *e;
Filip Tehlar82786c42017-02-20 15:20:37 +0100297 vl_api_gpe_fwd_entries_get_reply_t *rmp = 0;
Filip Tehlar5fae99c2017-01-18 12:57:37 +0100298 u32 size = 0;
299 int rv = 0;
300
Filip Tehlar82786c42017-02-20 15:20:37 +0100301 gpe_fwd_entries_get_t_net_to_host (mp);
Filip Tehlar5fae99c2017-01-18 12:57:37 +0100302
303 e = vnet_lisp_gpe_fwd_entries_get_by_vni (mp->vni);
Filip Tehlar82786c42017-02-20 15:20:37 +0100304 size = vec_len (e) * sizeof (vl_api_gpe_fwd_entry_t);
Filip Tehlar5fae99c2017-01-18 12:57:37 +0100305
306 /* *INDENT-OFF* */
Filip Tehlar82786c42017-02-20 15:20:37 +0100307 REPLY_MACRO4 (VL_API_GPE_FWD_ENTRIES_GET_REPLY, size,
Filip Tehlar5fae99c2017-01-18 12:57:37 +0100308 {
309 rmp->count = vec_len (e);
Filip Tehlar82786c42017-02-20 15:20:37 +0100310 gpe_fwd_entries_copy (rmp->entries, e);
311 gpe_fwd_entries_get_reply_t_host_to_net (rmp);
Filip Tehlar5fae99c2017-01-18 12:57:37 +0100312 });
313 /* *INDENT-ON* */
314
315 vec_free (e);
316}
317
318static void
Filip Tehlar82786c42017-02-20 15:20:37 +0100319gpe_add_del_fwd_entry_t_net_to_host (vl_api_gpe_add_del_fwd_entry_t * mp)
Filip Tehlarc3af7bf2017-01-13 14:13:09 +0100320{
321 mp->vni = clib_net_to_host_u32 (mp->vni);
322 mp->dp_table = clib_net_to_host_u32 (mp->dp_table);
323 mp->loc_num = clib_net_to_host_u32 (mp->loc_num);
324}
325
326static void
Filip Tehlar82786c42017-02-20 15:20:37 +0100327vl_api_gpe_add_del_fwd_entry_t_handler (vl_api_gpe_add_del_fwd_entry_t * mp)
Pavel Kotucekabea9662016-12-21 15:50:08 +0100328{
Filip Tehlar82786c42017-02-20 15:20:37 +0100329 vl_api_gpe_add_del_fwd_entry_reply_t *rmp;
Pavel Kotucekabea9662016-12-21 15:50:08 +0100330 vnet_lisp_gpe_add_del_fwd_entry_args_t _a, *a = &_a;
331 locator_pair_t *pairs = 0;
332 int rv = 0;
333
Filip Tehlar82786c42017-02-20 15:20:37 +0100334 gpe_add_del_fwd_entry_t_net_to_host (mp);
Pavel Kotucekabea9662016-12-21 15:50:08 +0100335 memset (a, 0, sizeof (a[0]));
336
337 rv = unformat_lisp_eid_api (&a->rmt_eid, mp->vni, mp->eid_type,
338 mp->rmt_eid, mp->rmt_len);
339 rv |= unformat_lisp_eid_api (&a->lcl_eid, mp->vni, mp->eid_type,
340 mp->lcl_eid, mp->lcl_len);
341
Filip Tehlarc3af7bf2017-01-13 14:13:09 +0100342 if (mp->loc_num % 2 != 0)
343 {
344 rv = -1;
345 goto send_reply;
346 }
Filip Tehlar82786c42017-02-20 15:20:37 +0100347 pairs = unformat_gpe_loc_pairs (mp->locs, mp->loc_num / 2);
Pavel Kotucekabea9662016-12-21 15:50:08 +0100348
Filip Tehlar0eb874e2017-05-18 14:23:32 +0200349 if (rv)
Pavel Kotucekabea9662016-12-21 15:50:08 +0100350 goto send_reply;
351
352 a->is_add = mp->is_add;
353 a->locator_pairs = pairs;
354 a->dp_table = mp->dp_table;
355 a->vni = mp->vni;
356 a->action = mp->action;
Filip Tehlar0eb874e2017-05-18 14:23:32 +0200357 if (mp->loc_num == 0)
358 a->is_negative = 1;
Pavel Kotucekabea9662016-12-21 15:50:08 +0100359
360 rv = vnet_lisp_gpe_add_del_fwd_entry (a, 0);
361 vec_free (pairs);
362send_reply:
Filip Tehlar560274d2017-06-05 13:40:13 +0200363 /* *INDENT-OFF* */
364 REPLY_MACRO2 (VL_API_GPE_ADD_DEL_FWD_ENTRY_REPLY,
365 {
366 rmp->fwd_entry_index = clib_host_to_net_u32 (a->fwd_entry_index);
367 });
368 /* *INDENT-ON* */
Pavel Kotucekabea9662016-12-21 15:50:08 +0100369}
370
371static void
Filip Tehlar82786c42017-02-20 15:20:37 +0100372vl_api_gpe_enable_disable_t_handler (vl_api_gpe_enable_disable_t * mp)
Pavel Kotucekabea9662016-12-21 15:50:08 +0100373{
Filip Tehlar82786c42017-02-20 15:20:37 +0100374 vl_api_gpe_enable_disable_reply_t *rmp;
Pavel Kotucekabea9662016-12-21 15:50:08 +0100375 int rv = 0;
376 vnet_lisp_gpe_enable_disable_args_t _a, *a = &_a;
377
378 a->is_en = mp->is_en;
379 vnet_lisp_gpe_enable_disable (a);
380
Filip Tehlar82786c42017-02-20 15:20:37 +0100381 REPLY_MACRO (VL_API_GPE_ENABLE_DISABLE_REPLY);
Pavel Kotucekabea9662016-12-21 15:50:08 +0100382}
383
384static void
Filip Tehlar82786c42017-02-20 15:20:37 +0100385vl_api_gpe_add_del_iface_t_handler (vl_api_gpe_add_del_iface_t * mp)
Pavel Kotucekabea9662016-12-21 15:50:08 +0100386{
Filip Tehlar82786c42017-02-20 15:20:37 +0100387 vl_api_gpe_add_del_iface_reply_t *rmp;
Pavel Kotucekabea9662016-12-21 15:50:08 +0100388 int rv = 0;
Florin Corasf53a8ad2017-06-15 15:07:32 -0700389 u32 vni, dp_table;
390
391 vni = clib_net_to_host_u32 (mp->vni);
392 dp_table = clib_net_to_host_u32 (mp->dp_table);
Pavel Kotucekabea9662016-12-21 15:50:08 +0100393
394 if (mp->is_l2)
395 {
396 if (mp->is_add)
397 {
Florin Corasf53a8ad2017-06-15 15:07:32 -0700398 if (~0 == lisp_gpe_tenant_l2_iface_add_or_lock (vni, dp_table))
Pavel Kotucekabea9662016-12-21 15:50:08 +0100399 rv = 1;
400 }
401 else
Florin Corasf53a8ad2017-06-15 15:07:32 -0700402 lisp_gpe_tenant_l2_iface_unlock (vni);
Pavel Kotucekabea9662016-12-21 15:50:08 +0100403 }
404 else
405 {
406 if (mp->is_add)
407 {
Filip Tehlar0a8840d2017-10-16 05:48:23 -0700408 if (~0 == lisp_gpe_tenant_l3_iface_add_or_lock (vni, dp_table, 1))
Pavel Kotucekabea9662016-12-21 15:50:08 +0100409 rv = 1;
410 }
411 else
Florin Corasf53a8ad2017-06-15 15:07:32 -0700412 lisp_gpe_tenant_l3_iface_unlock (vni);
Pavel Kotucekabea9662016-12-21 15:50:08 +0100413 }
414
Filip Tehlar82786c42017-02-20 15:20:37 +0100415 REPLY_MACRO (VL_API_GPE_ADD_DEL_IFACE_REPLY);
Pavel Kotucekabea9662016-12-21 15:50:08 +0100416}
417
Filip Tehlar3e7b56932017-02-21 18:28:34 +0100418static void
419vl_api_gpe_set_encap_mode_t_handler (vl_api_gpe_set_encap_mode_t * mp)
420{
421 vl_api_gpe_set_encap_mode_reply_t *rmp;
422 int rv = 0;
423
424 rv = vnet_gpe_set_encap_mode (mp->mode);
425 REPLY_MACRO (VL_API_GPE_SET_ENCAP_MODE_REPLY);
426}
427
428static void
429vl_api_gpe_get_encap_mode_t_handler (vl_api_gpe_get_encap_mode_t * mp)
430{
431 vl_api_gpe_get_encap_mode_reply_t *rmp;
432 int rv = 0;
433
434 /* *INDENT-OFF* */
435 REPLY_MACRO2 (VL_API_GPE_GET_ENCAP_MODE_REPLY,
436 ({
437 rmp->encap_mode = vnet_gpe_get_encap_mode ();
438 }));
439 /* *INDENT-ON* */
440}
441
Florin Corasa4e63e52017-06-07 21:50:57 -0700442static void
443 vl_api_gpe_add_del_native_fwd_rpath_t_handler
444 (vl_api_gpe_add_del_native_fwd_rpath_t * mp)
445{
Filip Tehlarb4243aa2017-06-14 14:39:42 +0200446 vl_api_gpe_add_del_native_fwd_rpath_reply_t *rmp;
Florin Corasa4e63e52017-06-07 21:50:57 -0700447 vnet_gpe_native_fwd_rpath_args_t _a, *a = &_a;
448 int rv = 0;
449
450 memset (a, 0, sizeof (a[0]));
451
452 if (mp->is_ip4)
Filip Tehlarb4243aa2017-06-14 14:39:42 +0200453 clib_memcpy (&a->rpath.frp_addr.ip4, mp->nh_addr, sizeof (ip4_address_t));
Florin Corasa4e63e52017-06-07 21:50:57 -0700454 else
Filip Tehlarb4243aa2017-06-14 14:39:42 +0200455 clib_memcpy (&a->rpath.frp_addr.ip6, mp->nh_addr, sizeof (ip6_address_t));
Florin Corasa4e63e52017-06-07 21:50:57 -0700456
457 a->is_add = mp->is_add;
Neale Rannsda78f952017-05-24 09:15:43 -0700458 a->rpath.frp_proto = mp->is_ip4 ? DPO_PROTO_IP4 : DPO_PROTO_IP6;
459 a->rpath.frp_fib_index =
460 fib_table_find (dpo_proto_to_fib (a->rpath.frp_proto),
461 clib_net_to_host_u32 (mp->table_id));
Filip Tehlarb4243aa2017-06-14 14:39:42 +0200462 if (~0 == a->rpath.frp_fib_index)
463 {
464 rv = VNET_API_ERROR_INVALID_VALUE;
465 goto done;
466 }
467
Florin Corasa4e63e52017-06-07 21:50:57 -0700468 a->rpath.frp_sw_if_index = clib_net_to_host_u32 (mp->nh_sw_if_index);
469 a->rpath.frp_weight = 1;
470
471 rv = vnet_gpe_add_del_native_fwd_rpath (a);
Filip Tehlarb4243aa2017-06-14 14:39:42 +0200472done:
Florin Corasa4e63e52017-06-07 21:50:57 -0700473 REPLY_MACRO (VL_API_GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY);
474}
475
476static void
477gpe_native_fwd_rpaths_copy (vl_api_gpe_native_fwd_rpath_t * dst,
Florin Coras27b390e2017-06-09 10:22:22 -0700478 fib_route_path_t * src, u8 is_ip4)
Florin Corasa4e63e52017-06-07 21:50:57 -0700479{
480 fib_route_path_t *e;
Florin Corasb5c29f92017-06-15 15:44:14 -0700481 fib_table_t *table;
Florin Corasa4e63e52017-06-07 21:50:57 -0700482 u32 i = 0;
483
484 vec_foreach (e, src)
485 {
486 memset (&dst[i], 0, sizeof (*dst));
Neale Rannsda78f952017-05-24 09:15:43 -0700487 table = fib_table_get (e->frp_fib_index, dpo_proto_to_fib (e->frp_proto));
Florin Corasb5c29f92017-06-15 15:44:14 -0700488 dst[i].fib_index = table->ft_table_id;
Florin Coras27b390e2017-06-09 10:22:22 -0700489 dst[i].nh_sw_if_index = e->frp_sw_if_index;
490 dst[i].is_ip4 = is_ip4;
Filip Tehlarb4243aa2017-06-14 14:39:42 +0200491 if (is_ip4)
492 clib_memcpy (&dst[i].nh_addr, &e->frp_addr.ip4, sizeof (ip4_address_t));
493 else
494 clib_memcpy (&dst[i].nh_addr, &e->frp_addr.ip6, sizeof (ip6_address_t));
495 i++;
Florin Corasa4e63e52017-06-07 21:50:57 -0700496 }
497}
498
499static void
500gpe_native_fwd_rpath_t_host_to_net (vl_api_gpe_native_fwd_rpath_t * e)
501{
502 e->fib_index = clib_host_to_net_u32 (e->fib_index);
503 e->nh_sw_if_index = clib_host_to_net_u32 (e->nh_sw_if_index);
504}
505
506static void
507 gpe_native_fwd_rpaths_get_reply_t_host_to_net
508 (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
509{
510 u32 i;
511 vl_api_gpe_native_fwd_rpath_t *e;
512
513 for (i = 0; i < mp->count; i++)
514 {
515 e = &mp->entries[i];
516 gpe_native_fwd_rpath_t_host_to_net (e);
517 }
518 mp->count = clib_host_to_net_u32 (mp->count);
519}
520
521static void
522vl_api_gpe_native_fwd_rpaths_get_t_handler (vl_api_gpe_native_fwd_rpaths_get_t
523 * mp)
524{
525 lisp_gpe_main_t *lgm = vnet_lisp_gpe_get_main ();
526 vl_api_gpe_native_fwd_rpaths_get_reply_t *rmp;
527 u32 size = 0;
528 int rv = 0;
529
Filip Tehlarb4243aa2017-06-14 14:39:42 +0200530 u8 rpath_index = mp->is_ip4 ? 0 : 1;
531
532 size = vec_len (lgm->native_fwd_rpath[rpath_index])
Florin Corasa4e63e52017-06-07 21:50:57 -0700533 * sizeof (vl_api_gpe_native_fwd_rpath_t);
534
535 /* *INDENT-OFF* */
536 REPLY_MACRO4 (VL_API_GPE_NATIVE_FWD_RPATHS_GET_REPLY, size,
537 {
Filip Tehlarb4243aa2017-06-14 14:39:42 +0200538 rmp->count = vec_len (lgm->native_fwd_rpath[rpath_index]);
Florin Corasa4e63e52017-06-07 21:50:57 -0700539 gpe_native_fwd_rpaths_copy (rmp->entries,
Filip Tehlarb4243aa2017-06-14 14:39:42 +0200540 lgm->native_fwd_rpath[rpath_index],
Florin Coras27b390e2017-06-09 10:22:22 -0700541 mp->is_ip4);
Florin Corasa4e63e52017-06-07 21:50:57 -0700542 gpe_native_fwd_rpaths_get_reply_t_host_to_net (rmp);
543 });
544 /* *INDENT-ON* */
545}
546
Pavel Kotucekabea9662016-12-21 15:50:08 +0100547/*
Filip Tehlar82786c42017-02-20 15:20:37 +0100548 * gpe_api_hookup
Pavel Kotucekabea9662016-12-21 15:50:08 +0100549 * Add vpe's API message handlers to the table.
550 * vlib has alread mapped shared memory and
551 * added the client registration handlers.
552 * See .../vlib-api/vlibmemory/memclnt_vlib.c:memclnt_process()
553 */
554#define vl_msg_name_crc_list
555#include <vnet/vnet_all_api_h.h>
556#undef vl_msg_name_crc_list
557
558static void
559setup_message_id_table (api_main_t * am)
560{
561#define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
562 foreach_vl_msg_name_crc_lisp_gpe;
563#undef _
564}
565
566static clib_error_t *
Filip Tehlar82786c42017-02-20 15:20:37 +0100567gpe_api_hookup (vlib_main_t * vm)
Pavel Kotucekabea9662016-12-21 15:50:08 +0100568{
569 api_main_t *am = &api_main;
570
571#define _(N,n) \
572 vl_msg_api_set_handlers(VL_API_##N, #n, \
573 vl_api_##n##_t_handler, \
574 vl_noop_handler, \
575 vl_api_##n##_t_endian, \
576 vl_api_##n##_t_print, \
577 sizeof(vl_api_##n##_t), 1);
578 foreach_vpe_api_msg;
579#undef _
580
581 /*
582 * Set up the (msg_name, crc, message-id) table
583 */
584 setup_message_id_table (am);
585
586 return 0;
587}
588
Filip Tehlar82786c42017-02-20 15:20:37 +0100589VLIB_API_INIT_FUNCTION (gpe_api_hookup);
Pavel Kotucekabea9662016-12-21 15:50:08 +0100590
591/*
592 * fd.io coding-style-patch-verification: ON
593 *
594 * Local Variables:
595 * eval: (c-set-style "gnu")
596 * End:
597 */