2 *------------------------------------------------------------------
3 * Copyright (c) 2018 Cisco and/or its affiliates.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *------------------------------------------------------------------
18 #include <vnet/vnet.h>
19 #include <vnet/plugin/plugin.h>
21 #include <vnet/interface.h>
22 #include <vnet/api_errno.h>
23 #include <vnet/ip/ip_types_api.h>
24 #include <vnet/ethernet/ethernet_types_api.h>
25 #include <vpp/app/version.h>
29 #include <vlibapi/api.h>
30 #include <vlibmemory/api.h>
32 /* define message IDs */
33 #include <gbp/gbp_msg_enum.h>
35 #define vl_typedefs /* define message structures */
36 #include <gbp/gbp_all_api_h.h>
39 #define vl_endianfun /* define message structures */
40 #include <gbp/gbp_all_api_h.h>
43 /* instantiate all the print functions we know about */
44 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
46 #include <gbp/gbp_all_api_h.h>
49 /* Get the API version number */
50 #define vl_api_version(n,v) static u32 api_version=(v);
51 #include <gbp/gbp_all_api_h.h>
54 #include <vlibapi/api_helper_macros.h>
56 #define foreach_gbp_api_msg \
57 _(GBP_ENDPOINT_ADD, gbp_endpoint_add) \
58 _(GBP_ENDPOINT_DEL, gbp_endpoint_del) \
59 _(GBP_ENDPOINT_DUMP, gbp_endpoint_dump) \
60 _(GBP_SUBNET_ADD_DEL, gbp_subnet_add_del) \
61 _(GBP_SUBNET_DUMP, gbp_subnet_dump) \
62 _(GBP_ENDPOINT_GROUP_ADD_DEL, gbp_endpoint_group_add_del) \
63 _(GBP_ENDPOINT_GROUP_DUMP, gbp_endpoint_group_dump) \
64 _(GBP_RECIRC_ADD_DEL, gbp_recirc_add_del) \
65 _(GBP_RECIRC_DUMP, gbp_recirc_dump) \
66 _(GBP_CONTRACT_ADD_DEL, gbp_contract_add_del) \
67 _(GBP_CONTRACT_DUMP, gbp_contract_dump)
71 static u16 msg_id_base;
73 #define GBP_MSG_BASE msg_id_base
76 vl_api_gbp_endpoint_add_t_handler (vl_api_gbp_endpoint_add_t * mp)
78 vl_api_gbp_endpoint_add_reply_t *rmp;
79 u32 sw_if_index, handle;
84 VALIDATE_SW_IF_INDEX (&(mp->endpoint));
86 sw_if_index = ntohl (mp->endpoint.sw_if_index);
90 if (mp->endpoint.n_ips)
92 vec_validate (ips, mp->endpoint.n_ips - 1);
94 vec_foreach_index (ii, ips)
96 ip_address_decode (&mp->endpoint.ips[ii], &ips[ii]);
99 mac_address_decode (&mp->endpoint.mac, &mac);
101 rv = gbp_endpoint_update (sw_if_index, ips, &mac,
102 ntohs (mp->endpoint.epg_id), &handle);
106 BAD_SW_IF_INDEX_LABEL;
109 REPLY_MACRO2 (VL_API_GBP_ENDPOINT_ADD_REPLY + GBP_MSG_BASE,
111 rmp->handle = htonl (handle);
117 vl_api_gbp_endpoint_del_t_handler (vl_api_gbp_endpoint_del_t * mp)
119 vl_api_gbp_endpoint_del_reply_t *rmp;
122 gbp_endpoint_delete (ntohl (mp->handle));
124 REPLY_MACRO (VL_API_GBP_ENDPOINT_DEL_REPLY + GBP_MSG_BASE);
127 typedef struct gbp_walk_ctx_t_
129 vl_api_registration_t *reg;
134 gbp_endpoint_send_details (gbp_endpoint_t * gbpe, void *args)
136 vl_api_gbp_endpoint_details_t *mp;
141 n_ips = vec_len (gbpe->ge_ips);
142 mp = vl_msg_api_alloc (sizeof (*mp) + (sizeof (*mp->endpoint.ips) * n_ips));
146 memset (mp, 0, sizeof (*mp));
147 mp->_vl_msg_id = ntohs (VL_API_GBP_ENDPOINT_DETAILS + GBP_MSG_BASE);
148 mp->context = ctx->context;
150 mp->endpoint.sw_if_index = ntohl (gbpe->ge_sw_if_index);
151 mp->endpoint.epg_id = ntohs (gbpe->ge_epg_id);
152 mp->endpoint.n_ips = n_ips;
153 mac_address_encode (&gbpe->ge_mac, &mp->endpoint.mac);
155 vec_foreach_index (ii, gbpe->ge_ips)
157 ip_address_encode (&gbpe->ge_ips[ii], IP46_TYPE_ANY,
158 &mp->endpoint.ips[ii]);
161 vl_api_send_msg (ctx->reg, (u8 *) mp);
163 return (WALK_CONTINUE);
167 vl_api_gbp_endpoint_dump_t_handler (vl_api_gbp_endpoint_dump_t * mp)
169 vl_api_registration_t *reg;
171 reg = vl_api_client_index_to_registration (mp->client_index);
175 gbp_walk_ctx_t ctx = {
177 .context = mp->context,
180 gbp_endpoint_walk (gbp_endpoint_send_details, &ctx);
184 vl_api_gbp_endpoint_group_add_del_t_handler
185 (vl_api_gbp_endpoint_group_add_del_t * mp)
187 vl_api_gbp_endpoint_group_add_del_reply_t *rmp;
188 u32 uplink_sw_if_index;
191 uplink_sw_if_index = ntohl (mp->epg.uplink_sw_if_index);
192 if (!vnet_sw_if_index_is_api_valid (uplink_sw_if_index))
193 goto bad_sw_if_index;
197 rv = gbp_endpoint_group_add (ntohs (mp->epg.epg_id),
198 ntohl (mp->epg.bd_id),
199 ntohl (mp->epg.ip4_table_id),
200 ntohl (mp->epg.ip6_table_id),
205 gbp_endpoint_group_delete (ntohs (mp->epg.epg_id));
208 BAD_SW_IF_INDEX_LABEL;
210 REPLY_MACRO (VL_API_GBP_ENDPOINT_GROUP_ADD_DEL_REPLY + GBP_MSG_BASE);
214 vl_api_gbp_subnet_add_del_t_handler (vl_api_gbp_subnet_add_del_t * mp)
216 vl_api_gbp_subnet_add_del_reply_t *rmp;
220 ip_prefix_decode (&mp->subnet.prefix, &pfx);
222 rv = gbp_subnet_add_del (ntohl (mp->subnet.table_id),
224 ntohl (mp->subnet.sw_if_index),
225 ntohs (mp->subnet.epg_id),
226 mp->is_add, mp->subnet.is_internal);
228 REPLY_MACRO (VL_API_GBP_SUBNET_ADD_DEL_REPLY + GBP_MSG_BASE);
232 gbp_subnet_send_details (u32 table_id,
233 const fib_prefix_t * pfx,
235 epg_id_t epg, u8 is_internal, void *args)
237 vl_api_gbp_subnet_details_t *mp;
241 mp = vl_msg_api_alloc (sizeof (*mp));
245 memset (mp, 0, sizeof (*mp));
246 mp->_vl_msg_id = ntohs (VL_API_GBP_SUBNET_DETAILS + GBP_MSG_BASE);
247 mp->context = ctx->context;
249 mp->subnet.is_internal = is_internal;
250 mp->subnet.sw_if_index = ntohl (sw_if_index);
251 mp->subnet.epg_id = ntohs (epg);
252 mp->subnet.table_id = ntohl (table_id);
253 ip_prefix_encode (pfx, &mp->subnet.prefix);
255 vl_api_send_msg (ctx->reg, (u8 *) mp);
261 vl_api_gbp_subnet_dump_t_handler (vl_api_gbp_subnet_dump_t * mp)
263 vl_api_registration_t *reg;
265 reg = vl_api_client_index_to_registration (mp->client_index);
269 gbp_walk_ctx_t ctx = {
271 .context = mp->context,
274 gbp_subnet_walk (gbp_subnet_send_details, &ctx);
278 gbp_endpoint_group_send_details (gbp_endpoint_group_t * gepg, void *args)
280 vl_api_gbp_endpoint_group_details_t *mp;
284 mp = vl_msg_api_alloc (sizeof (*mp));
288 memset (mp, 0, sizeof (*mp));
289 mp->_vl_msg_id = ntohs (VL_API_GBP_ENDPOINT_GROUP_DETAILS + GBP_MSG_BASE);
290 mp->context = ctx->context;
292 mp->epg.uplink_sw_if_index = ntohl (gepg->gepg_uplink_sw_if_index);
293 mp->epg.epg_id = ntohs (gepg->gepg_id);
294 mp->epg.bd_id = ntohl (gepg->gepg_bd);
295 mp->epg.ip4_table_id = ntohl (gepg->gepg_rd[FIB_PROTOCOL_IP4]);
296 mp->epg.ip6_table_id = ntohl (gepg->gepg_rd[FIB_PROTOCOL_IP6]);
298 vl_api_send_msg (ctx->reg, (u8 *) mp);
304 vl_api_gbp_endpoint_group_dump_t_handler (vl_api_gbp_endpoint_group_dump_t *
307 vl_api_registration_t *reg;
309 reg = vl_api_client_index_to_registration (mp->client_index);
313 gbp_walk_ctx_t ctx = {
315 .context = mp->context,
318 gbp_endpoint_group_walk (gbp_endpoint_group_send_details, &ctx);
322 vl_api_gbp_recirc_add_del_t_handler (vl_api_gbp_recirc_add_del_t * mp)
324 vl_api_gbp_recirc_add_del_reply_t *rmp;
328 sw_if_index = ntohl (mp->recirc.sw_if_index);
329 if (!vnet_sw_if_index_is_api_valid (sw_if_index))
330 goto bad_sw_if_index;
333 gbp_recirc_add (sw_if_index,
334 ntohs (mp->recirc.epg_id), mp->recirc.is_ext);
336 gbp_recirc_delete (sw_if_index);
338 BAD_SW_IF_INDEX_LABEL;
340 REPLY_MACRO (VL_API_GBP_RECIRC_ADD_DEL_REPLY + GBP_MSG_BASE);
344 gbp_recirc_send_details (gbp_recirc_t * gr, void *args)
346 vl_api_gbp_recirc_details_t *mp;
350 mp = vl_msg_api_alloc (sizeof (*mp));
354 memset (mp, 0, sizeof (*mp));
355 mp->_vl_msg_id = ntohs (VL_API_GBP_RECIRC_DETAILS + GBP_MSG_BASE);
356 mp->context = ctx->context;
358 mp->recirc.epg_id = ntohs (gr->gr_epg);
359 mp->recirc.sw_if_index = ntohl (gr->gr_sw_if_index);
360 mp->recirc.is_ext = ntohl (gr->gr_is_ext);
362 vl_api_send_msg (ctx->reg, (u8 *) mp);
368 vl_api_gbp_recirc_dump_t_handler (vl_api_gbp_recirc_dump_t * mp)
370 vl_api_registration_t *reg;
372 reg = vl_api_client_index_to_registration (mp->client_index);
376 gbp_walk_ctx_t ctx = {
378 .context = mp->context,
381 gbp_recirc_walk (gbp_recirc_send_details, &ctx);
385 vl_api_gbp_contract_add_del_t_handler (vl_api_gbp_contract_add_del_t * mp)
387 vl_api_gbp_contract_add_del_reply_t *rmp;
391 gbp_contract_update (ntohs (mp->contract.src_epg),
392 ntohs (mp->contract.dst_epg),
393 ntohl (mp->contract.acl_index));
395 gbp_contract_delete (ntohs (mp->contract.src_epg),
396 ntohs (mp->contract.dst_epg));
398 REPLY_MACRO (VL_API_GBP_CONTRACT_ADD_DEL_REPLY + GBP_MSG_BASE);
402 gbp_contract_send_details (gbp_contract_t * gbpc, void *args)
404 vl_api_gbp_contract_details_t *mp;
408 mp = vl_msg_api_alloc (sizeof (*mp));
412 memset (mp, 0, sizeof (*mp));
413 mp->_vl_msg_id = ntohs (VL_API_GBP_CONTRACT_DETAILS + GBP_MSG_BASE);
414 mp->context = ctx->context;
416 mp->contract.src_epg = ntohs (gbpc->gc_key.gck_src);
417 mp->contract.dst_epg = ntohs (gbpc->gc_key.gck_dst);
418 mp->contract.acl_index = ntohl (gbpc->gc_value.gc_acl_index);
420 vl_api_send_msg (ctx->reg, (u8 *) mp);
426 vl_api_gbp_contract_dump_t_handler (vl_api_gbp_contract_dump_t * mp)
428 vl_api_registration_t *reg;
430 reg = vl_api_client_index_to_registration (mp->client_index);
434 gbp_walk_ctx_t ctx = {
436 .context = mp->context,
439 gbp_contract_walk (gbp_contract_send_details, &ctx);
444 * Add vpe's API message handlers to the table.
445 * vlib has already mapped shared memory and
446 * added the client registration handlers.
447 * See .../vlib-api/vlibmemory/memclnt_vlib.c:memclnt_process()
449 #define vl_msg_name_crc_list
450 #include <gbp/gbp_all_api_h.h>
451 #undef vl_msg_name_crc_list
454 setup_message_id_table (api_main_t * am)
456 #define _(id,n,crc) \
457 vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id + GBP_MSG_BASE);
458 foreach_vl_msg_name_crc_gbp;
463 gbp_api_hookup (vlib_main_t * vm)
466 vl_msg_api_set_handlers(VL_API_##N + GBP_MSG_BASE, \
468 vl_api_##n##_t_handler, \
470 vl_api_##n##_t_endian, \
471 vl_api_##n##_t_print, \
472 sizeof(vl_api_##n##_t), 1);
477 static clib_error_t *
478 gbp_init (vlib_main_t * vm)
480 api_main_t *am = &api_main;
481 gbp_main_t *gbpm = &gbp_main;
482 u8 *name = format (0, "gbp_%08x%c", api_version, 0);
484 gbpm->gbp_acl_user_id = ~0;
486 /* Ask for a correctly-sized block of API message decode slots */
487 msg_id_base = vl_msg_api_get_msg_ids ((char *) name,
488 VL_MSG_FIRST_AVAILABLE);
491 /* Add our API messages to the global name_crc hash table */
492 setup_message_id_table (am);
498 VLIB_API_INIT_FUNCTION (gbp_init);
501 VLIB_PLUGIN_REGISTER () = {
502 .version = VPP_BUILD_VER,
503 .description = "Group Based Policy",
509 * fd.io coding-style-patch-verification: ON
512 * eval: (c-set-style "gnu")