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 <vpp/app/version.h>
27 #include <vlibapi/api.h>
28 #include <vlibmemory/api.h>
30 /* define message IDs */
31 #include <gbp/gbp_msg_enum.h>
33 #define vl_typedefs /* define message structures */
34 #include <gbp/gbp_all_api_h.h>
37 #define vl_endianfun /* define message structures */
38 #include <gbp/gbp_all_api_h.h>
41 /* instantiate all the print functions we know about */
42 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
44 #include <gbp/gbp_all_api_h.h>
47 /* Get the API version number */
48 #define vl_api_version(n,v) static u32 api_version=(v);
49 #include <acl/acl_all_api_h.h>
52 #include <vlibapi/api_helper_macros.h>
54 #define foreach_gbp_api_msg \
55 _(GBP_ENDPOINT_ADD_DEL, gbp_endpoint_add_del) \
56 _(GBP_ENDPOINT_DUMP, gbp_endpoint_dump) \
57 _(GBP_SUBNET_ADD_DEL, gbp_subnet_add_del) \
58 _(GBP_SUBNET_DUMP, gbp_subnet_dump) \
59 _(GBP_ENDPOINT_GROUP_ADD_DEL, gbp_endpoint_group_add_del) \
60 _(GBP_ENDPOINT_GROUP_DUMP, gbp_endpoint_group_dump) \
61 _(GBP_RECIRC_ADD_DEL, gbp_recirc_add_del) \
62 _(GBP_RECIRC_DUMP, gbp_recirc_dump) \
63 _(GBP_CONTRACT_ADD_DEL, gbp_contract_add_del) \
64 _(GBP_CONTRACT_DUMP, gbp_contract_dump)
69 typedef struct gbp_main_t_
74 static gbp_main_t gbp_main;
76 #define GBP_MSG_BASE gbp_main.msg_id_base
79 vl_api_gbp_endpoint_add_del_t_handler (vl_api_gbp_endpoint_add_del_t * mp)
81 vl_api_gbp_endpoint_add_del_reply_t *rmp;
82 ip46_address_t ip = { };
86 sw_if_index = ntohl (mp->endpoint.sw_if_index);
87 if (!vnet_sw_if_index_is_api_valid (sw_if_index))
90 if (mp->endpoint.is_ip6)
92 clib_memcpy (&ip.ip6, mp->endpoint.address, sizeof (ip.ip6));
96 clib_memcpy (&ip.ip4, mp->endpoint.address, sizeof (ip.ip4));
102 gbp_endpoint_update (sw_if_index, &ip, ntohl (mp->endpoint.epg_id));
106 gbp_endpoint_delete (sw_if_index, &ip);
109 BAD_SW_IF_INDEX_LABEL;
111 REPLY_MACRO (VL_API_GBP_ENDPOINT_ADD_DEL_REPLY + GBP_MSG_BASE);
114 typedef struct gbp_walk_ctx_t_
116 vl_api_registration_t *reg;
121 gbp_endpoint_send_details (gbp_endpoint_t * gbpe, void *args)
123 vl_api_gbp_endpoint_details_t *mp;
127 mp = vl_msg_api_alloc (sizeof (*mp));
131 memset (mp, 0, sizeof (*mp));
132 mp->_vl_msg_id = ntohs (VL_API_GBP_ENDPOINT_DETAILS + GBP_MSG_BASE);
133 mp->context = ctx->context;
135 mp->endpoint.sw_if_index = ntohl (gbpe->ge_key->gek_sw_if_index);
136 mp->endpoint.is_ip6 = !ip46_address_is_ip4 (&gbpe->ge_key->gek_ip);
137 if (mp->endpoint.is_ip6)
138 clib_memcpy (&mp->endpoint.address,
139 &gbpe->ge_key->gek_ip.ip6,
140 sizeof (gbpe->ge_key->gek_ip.ip6));
142 clib_memcpy (&mp->endpoint.address,
143 &gbpe->ge_key->gek_ip.ip4,
144 sizeof (gbpe->ge_key->gek_ip.ip4));
146 mp->endpoint.epg_id = ntohl (gbpe->ge_epg_id);
148 vl_api_send_msg (ctx->reg, (u8 *) mp);
154 vl_api_gbp_endpoint_dump_t_handler (vl_api_gbp_endpoint_dump_t * mp)
156 vl_api_registration_t *reg;
158 reg = vl_api_client_index_to_registration (mp->client_index);
162 gbp_walk_ctx_t ctx = {
164 .context = mp->context,
167 gbp_endpoint_walk (gbp_endpoint_send_details, &ctx);
171 vl_api_gbp_endpoint_group_add_del_t_handler
172 (vl_api_gbp_endpoint_group_add_del_t * mp)
174 vl_api_gbp_endpoint_group_add_del_reply_t *rmp;
175 u32 uplink_sw_if_index;
178 uplink_sw_if_index = ntohl (mp->epg.uplink_sw_if_index);
179 if (!vnet_sw_if_index_is_api_valid (uplink_sw_if_index))
180 goto bad_sw_if_index;
184 rv = gbp_endpoint_group_add (ntohl (mp->epg.epg_id),
185 ntohl (mp->epg.bd_id),
186 ntohl (mp->epg.ip4_table_id),
187 ntohl (mp->epg.ip6_table_id),
192 gbp_endpoint_group_delete (ntohl (mp->epg.epg_id));
195 BAD_SW_IF_INDEX_LABEL;
197 REPLY_MACRO (VL_API_GBP_ENDPOINT_GROUP_ADD_DEL_REPLY + GBP_MSG_BASE);
201 vl_api_gbp_subnet_add_del_t_handler (vl_api_gbp_subnet_add_del_t * mp)
203 vl_api_gbp_subnet_add_del_reply_t *rmp;
206 .fp_len = mp->subnet.address_length,
207 .fp_proto = (mp->subnet.is_ip6 ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4),
210 if (mp->subnet.is_ip6)
211 clib_memcpy (&pfx.fp_addr.ip6, mp->subnet.address,
212 sizeof (pfx.fp_addr.ip6));
214 clib_memcpy (&pfx.fp_addr.ip4, mp->subnet.address,
215 sizeof (pfx.fp_addr.ip4));
217 rv = gbp_subnet_add_del (ntohl (mp->subnet.table_id),
219 ntohl (mp->subnet.sw_if_index),
220 ntohl (mp->subnet.epg_id),
221 mp->is_add, mp->subnet.is_internal);
223 REPLY_MACRO (VL_API_GBP_SUBNET_ADD_DEL_REPLY + GBP_MSG_BASE);
227 gbp_subnet_send_details (u32 table_id,
228 const fib_prefix_t * pfx,
230 epg_id_t epg, u8 is_internal, void *args)
232 vl_api_gbp_subnet_details_t *mp;
236 mp = vl_msg_api_alloc (sizeof (*mp));
240 memset (mp, 0, sizeof (*mp));
241 mp->_vl_msg_id = ntohs (VL_API_GBP_SUBNET_DETAILS + GBP_MSG_BASE);
242 mp->context = ctx->context;
244 mp->subnet.is_internal = is_internal;
245 mp->subnet.sw_if_index = ntohl (sw_if_index);
246 mp->subnet.epg_id = ntohl (epg);
247 mp->subnet.is_ip6 = (pfx->fp_proto == FIB_PROTOCOL_IP6);
248 mp->subnet.address_length = pfx->fp_len;
249 mp->subnet.table_id = ntohl (table_id);
250 if (mp->subnet.is_ip6)
251 clib_memcpy (&mp->subnet.address,
252 &pfx->fp_addr.ip6, sizeof (pfx->fp_addr.ip6));
254 clib_memcpy (&mp->subnet.address,
255 &pfx->fp_addr.ip4, sizeof (pfx->fp_addr.ip4));
258 vl_api_send_msg (ctx->reg, (u8 *) mp);
264 vl_api_gbp_subnet_dump_t_handler (vl_api_gbp_subnet_dump_t * mp)
266 vl_api_registration_t *reg;
268 reg = vl_api_client_index_to_registration (mp->client_index);
272 gbp_walk_ctx_t ctx = {
274 .context = mp->context,
277 gbp_subnet_walk (gbp_subnet_send_details, &ctx);
281 gbp_endpoint_group_send_details (gbp_endpoint_group_t * gepg, void *args)
283 vl_api_gbp_endpoint_group_details_t *mp;
287 mp = vl_msg_api_alloc (sizeof (*mp));
291 memset (mp, 0, sizeof (*mp));
292 mp->_vl_msg_id = ntohs (VL_API_GBP_ENDPOINT_GROUP_DETAILS + GBP_MSG_BASE);
293 mp->context = ctx->context;
295 mp->epg.uplink_sw_if_index = ntohl (gepg->gepg_uplink_sw_if_index);
296 mp->epg.epg_id = ntohl (gepg->gepg_id);
297 mp->epg.bd_id = ntohl (gepg->gepg_bd);
298 mp->epg.ip4_table_id = ntohl (gepg->gepg_rd[FIB_PROTOCOL_IP4]);
299 mp->epg.ip6_table_id = ntohl (gepg->gepg_rd[FIB_PROTOCOL_IP6]);
301 vl_api_send_msg (ctx->reg, (u8 *) mp);
307 vl_api_gbp_endpoint_group_dump_t_handler (vl_api_gbp_endpoint_group_dump_t *
310 vl_api_registration_t *reg;
312 reg = vl_api_client_index_to_registration (mp->client_index);
316 gbp_walk_ctx_t ctx = {
318 .context = mp->context,
321 gbp_endpoint_group_walk (gbp_endpoint_group_send_details, &ctx);
325 vl_api_gbp_recirc_add_del_t_handler (vl_api_gbp_recirc_add_del_t * mp)
327 vl_api_gbp_recirc_add_del_reply_t *rmp;
331 sw_if_index = ntohl (mp->recirc.sw_if_index);
332 if (!vnet_sw_if_index_is_api_valid (sw_if_index))
333 goto bad_sw_if_index;
336 gbp_recirc_add (sw_if_index,
337 ntohl (mp->recirc.epg_id), mp->recirc.is_ext);
339 gbp_recirc_delete (sw_if_index);
341 BAD_SW_IF_INDEX_LABEL;
343 REPLY_MACRO (VL_API_GBP_RECIRC_ADD_DEL_REPLY + GBP_MSG_BASE);
347 gbp_recirc_send_details (gbp_recirc_t * gr, void *args)
349 vl_api_gbp_recirc_details_t *mp;
353 mp = vl_msg_api_alloc (sizeof (*mp));
357 memset (mp, 0, sizeof (*mp));
358 mp->_vl_msg_id = ntohs (VL_API_GBP_RECIRC_DETAILS + GBP_MSG_BASE);
359 mp->context = ctx->context;
361 mp->recirc.epg_id = ntohl (gr->gr_epg);
362 mp->recirc.sw_if_index = ntohl (gr->gr_sw_if_index);
363 mp->recirc.is_ext = ntohl (gr->gr_is_ext);
365 vl_api_send_msg (ctx->reg, (u8 *) mp);
371 vl_api_gbp_recirc_dump_t_handler (vl_api_gbp_recirc_dump_t * mp)
373 vl_api_registration_t *reg;
375 reg = vl_api_client_index_to_registration (mp->client_index);
379 gbp_walk_ctx_t ctx = {
381 .context = mp->context,
384 gbp_recirc_walk (gbp_recirc_send_details, &ctx);
388 vl_api_gbp_contract_add_del_t_handler (vl_api_gbp_contract_add_del_t * mp)
390 vl_api_gbp_contract_add_del_reply_t *rmp;
394 gbp_contract_update (ntohl (mp->contract.src_epg),
395 ntohl (mp->contract.dst_epg),
396 ntohl (mp->contract.acl_index));
398 gbp_contract_delete (ntohl (mp->contract.src_epg),
399 ntohl (mp->contract.dst_epg));
401 REPLY_MACRO (VL_API_GBP_CONTRACT_ADD_DEL_REPLY + GBP_MSG_BASE);
405 gbp_contract_send_details (gbp_contract_t * gbpc, void *args)
407 vl_api_gbp_contract_details_t *mp;
411 mp = vl_msg_api_alloc (sizeof (*mp));
415 memset (mp, 0, sizeof (*mp));
416 mp->_vl_msg_id = ntohs (VL_API_GBP_CONTRACT_DETAILS + GBP_MSG_BASE);
417 mp->context = ctx->context;
419 mp->contract.src_epg = ntohl (gbpc->gc_key.gck_src);
420 mp->contract.dst_epg = ntohl (gbpc->gc_key.gck_dst);
421 mp->contract.acl_index = ntohl (gbpc->gc_acl_index);
423 vl_api_send_msg (ctx->reg, (u8 *) mp);
429 vl_api_gbp_contract_dump_t_handler (vl_api_gbp_contract_dump_t * mp)
431 vl_api_registration_t *reg;
433 reg = vl_api_client_index_to_registration (mp->client_index);
437 gbp_walk_ctx_t ctx = {
439 .context = mp->context,
442 gbp_contract_walk (gbp_contract_send_details, &ctx);
447 * Add vpe's API message handlers to the table.
448 * vlib has alread mapped shared memory and
449 * added the client registration handlers.
450 * See .../vlib-api/vlibmemory/memclnt_vlib.c:memclnt_process()
452 #define vl_msg_name_crc_list
453 #include <gbp/gbp_all_api_h.h>
454 #undef vl_msg_name_crc_list
457 setup_message_id_table (api_main_t * am)
459 #define _(id,n,crc) \
460 vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id + GBP_MSG_BASE);
461 foreach_vl_msg_name_crc_gbp;
466 gbp_api_hookup (vlib_main_t * vm)
469 vl_msg_api_set_handlers(VL_API_##N + GBP_MSG_BASE, \
471 vl_api_##n##_t_handler, \
473 vl_api_##n##_t_endian, \
474 vl_api_##n##_t_print, \
475 sizeof(vl_api_##n##_t), 1);
480 static clib_error_t *
481 gbp_init (vlib_main_t * vm)
483 api_main_t *am = &api_main;
484 gbp_main_t *gbpm = &gbp_main;
485 u8 *name = format (0, "gbp_%08x%c", api_version, 0);
487 /* Ask for a correctly-sized block of API message decode slots */
488 gbpm->msg_id_base = vl_msg_api_get_msg_ids ((char *) name,
489 VL_MSG_FIRST_AVAILABLE);
493 /* Add our API messages to the global name_crc hash table */
494 setup_message_id_table (am);
500 VLIB_API_INIT_FUNCTION (gbp_init);
503 VLIB_PLUGIN_REGISTER () = {
504 .version = VPP_BUILD_VER,
505 .description = "Group Based Policy",
511 * fd.io coding-style-patch-verification: ON
514 * eval: (c-set-style "gnu")