FD.io VPP  v18.07-rc0-415-g6c78436
Vector Packet Processing
gbp_api.c
Go to the documentation of this file.
1 /*
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:
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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  *------------------------------------------------------------------
16  */
17 
18 #include <vnet/vnet.h>
19 #include <vnet/plugin/plugin.h>
20 
21 #include <vnet/interface.h>
22 #include <vnet/api_errno.h>
23 #include <vpp/app/version.h>
24 
25 #include <gbp/gbp.h>
26 
27 #include <vlibapi/api.h>
28 #include <vlibmemory/api.h>
29 
30 /* define message IDs */
31 #include <gbp/gbp_msg_enum.h>
32 
33 #define vl_typedefs /* define message structures */
34 #include <gbp/gbp_all_api_h.h>
35 #undef vl_typedefs
36 
37 #define vl_endianfun /* define message structures */
38 #include <gbp/gbp_all_api_h.h>
39 #undef vl_endianfun
40 
41 /* instantiate all the print functions we know about */
42 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
43 #define vl_printfun
44 #include <gbp/gbp_all_api_h.h>
45 #undef vl_printfun
46 
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>
50 #undef vl_api_version
51 
53 
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)
65 
66 /**
67  * L2 Emulation Main
68  */
69 typedef struct gbp_main_t_
70 {
72 } gbp_main_t;
73 
75 
76 #define GBP_MSG_BASE gbp_main.msg_id_base
77 
78 static void
80 {
81  vl_api_gbp_endpoint_add_del_reply_t *rmp;
82  ip46_address_t ip = { };
83  u32 sw_if_index;
84  int rv = 0;
85 
86  sw_if_index = ntohl (mp->endpoint.sw_if_index);
87  if (!vnet_sw_if_index_is_api_valid (sw_if_index))
88  goto bad_sw_if_index;
89 
90  if (mp->endpoint.is_ip6)
91  {
92  clib_memcpy (&ip.ip6, mp->endpoint.address, sizeof (ip.ip6));
93  }
94  else
95  {
96  clib_memcpy (&ip.ip4, mp->endpoint.address, sizeof (ip.ip4));
97  }
98 
99  if (mp->is_add)
100  {
101  rv =
102  gbp_endpoint_update (sw_if_index, &ip, ntohl (mp->endpoint.epg_id));
103  }
104  else
105  {
106  gbp_endpoint_delete (sw_if_index, &ip);
107  }
108 
110 
111  REPLY_MACRO (VL_API_GBP_ENDPOINT_ADD_DEL_REPLY + GBP_MSG_BASE);
112 }
113 
114 typedef struct gbp_walk_ctx_t_
115 {
119 
120 static int
122 {
125 
126  ctx = args;
127  mp = vl_msg_api_alloc (sizeof (*mp));
128  if (!mp)
129  return 1;
130 
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;
134 
135  mp->endpoint.sw_if_index = ntohl (gbpe->ge_key->gek_sw_if_index);
137  if (mp->endpoint.is_ip6)
139  &gbpe->ge_key->gek_ip.ip6,
140  sizeof (gbpe->ge_key->gek_ip.ip6));
141  else
143  &gbpe->ge_key->gek_ip.ip4,
144  sizeof (gbpe->ge_key->gek_ip.ip4));
145 
146  mp->endpoint.epg_id = ntohl (gbpe->ge_epg_id);
147 
148  vl_api_send_msg (ctx->reg, (u8 *) mp);
149 
150  return (1);
151 }
152 
153 static void
155 {
157 
159  if (!reg)
160  return;
161 
162  gbp_walk_ctx_t ctx = {
163  .reg = reg,
164  .context = mp->context,
165  };
166 
168 }
169 
170 static void
173 {
174  vl_api_gbp_endpoint_group_add_del_reply_t *rmp;
175  u32 uplink_sw_if_index;
176  int rv = 0;
177 
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;
181 
182  if (mp->is_add)
183  {
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),
188  uplink_sw_if_index);
189  }
190  else
191  {
192  gbp_endpoint_group_delete (ntohl (mp->epg.epg_id));
193  }
194 
196 
197  REPLY_MACRO (VL_API_GBP_ENDPOINT_GROUP_ADD_DEL_REPLY + GBP_MSG_BASE);
198 }
199 
200 static void
202 {
203  vl_api_gbp_subnet_add_del_reply_t *rmp;
204  int rv = 0;
205  fib_prefix_t pfx = {
207  .fp_proto = (mp->subnet.is_ip6 ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4),
208  };
209 
210  if (mp->subnet.is_ip6)
211  clib_memcpy (&pfx.fp_addr.ip6, mp->subnet.address,
212  sizeof (pfx.fp_addr.ip6));
213  else
214  clib_memcpy (&pfx.fp_addr.ip4, mp->subnet.address,
215  sizeof (pfx.fp_addr.ip4));
216 
217  rv = gbp_subnet_add_del (ntohl (mp->subnet.table_id),
218  &pfx,
219  ntohl (mp->subnet.sw_if_index),
220  ntohl (mp->subnet.epg_id),
221  mp->is_add, mp->subnet.is_internal);
222 
223  REPLY_MACRO (VL_API_GBP_SUBNET_ADD_DEL_REPLY + GBP_MSG_BASE);
224 }
225 
226 static int
228  const fib_prefix_t * pfx,
229  u32 sw_if_index,
230  epg_id_t epg, u8 is_internal, void *args)
231 {
234 
235  ctx = args;
236  mp = vl_msg_api_alloc (sizeof (*mp));
237  if (!mp)
238  return 1;
239 
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;
243 
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));
253  else
254  clib_memcpy (&mp->subnet.address,
255  &pfx->fp_addr.ip4, sizeof (pfx->fp_addr.ip4));
256 
257 
258  vl_api_send_msg (ctx->reg, (u8 *) mp);
259 
260  return (1);
261 }
262 
263 static void
265 {
267 
269  if (!reg)
270  return;
271 
272  gbp_walk_ctx_t ctx = {
273  .reg = reg,
274  .context = mp->context,
275  };
276 
278 }
279 
280 static int
282 {
285 
286  ctx = args;
287  mp = vl_msg_api_alloc (sizeof (*mp));
288  if (!mp)
289  return 1;
290 
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;
294 
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]);
300 
301  vl_api_send_msg (ctx->reg, (u8 *) mp);
302 
303  return (1);
304 }
305 
306 static void
308  mp)
309 {
311 
313  if (!reg)
314  return;
315 
316  gbp_walk_ctx_t ctx = {
317  .reg = reg,
318  .context = mp->context,
319  };
320 
322 }
323 
324 static void
326 {
327  vl_api_gbp_recirc_add_del_reply_t *rmp;
328  u32 sw_if_index;
329  int rv = 0;
330 
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;
334 
335  if (mp->is_add)
336  gbp_recirc_add (sw_if_index,
337  ntohl (mp->recirc.epg_id), mp->recirc.is_ext);
338  else
339  gbp_recirc_delete (sw_if_index);
340 
342 
343  REPLY_MACRO (VL_API_GBP_RECIRC_ADD_DEL_REPLY + GBP_MSG_BASE);
344 }
345 
346 static int
348 {
351 
352  ctx = args;
353  mp = vl_msg_api_alloc (sizeof (*mp));
354  if (!mp)
355  return 1;
356 
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;
360 
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);
364 
365  vl_api_send_msg (ctx->reg, (u8 *) mp);
366 
367  return (1);
368 }
369 
370 static void
372 {
374 
376  if (!reg)
377  return;
378 
379  gbp_walk_ctx_t ctx = {
380  .reg = reg,
381  .context = mp->context,
382  };
383 
385 }
386 
387 static void
389 {
390  vl_api_gbp_contract_add_del_reply_t *rmp;
391  int rv = 0;
392 
393  if (mp->is_add)
394  gbp_contract_update (ntohl (mp->contract.src_epg),
395  ntohl (mp->contract.dst_epg),
396  ntohl (mp->contract.acl_index));
397  else
398  gbp_contract_delete (ntohl (mp->contract.src_epg),
399  ntohl (mp->contract.dst_epg));
400 
401  REPLY_MACRO (VL_API_GBP_CONTRACT_ADD_DEL_REPLY + GBP_MSG_BASE);
402 }
403 
404 static int
406 {
409 
410  ctx = args;
411  mp = vl_msg_api_alloc (sizeof (*mp));
412  if (!mp)
413  return 1;
414 
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;
418 
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);
422 
423  vl_api_send_msg (ctx->reg, (u8 *) mp);
424 
425  return (1);
426 }
427 
428 static void
430 {
432 
434  if (!reg)
435  return;
436 
437  gbp_walk_ctx_t ctx = {
438  .reg = reg,
439  .context = mp->context,
440  };
441 
443 }
444 
445 /*
446  * gbp_api_hookup
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()
451  */
452 #define vl_msg_name_crc_list
453 #include <gbp/gbp_all_api_h.h>
454 #undef vl_msg_name_crc_list
455 
456 static void
458 {
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;
462 #undef _
463 }
464 
465 static void
467 {
468 #define _(N,n) \
469  vl_msg_api_set_handlers(VL_API_##N + GBP_MSG_BASE, \
470  #n, \
471  vl_api_##n##_t_handler, \
472  vl_noop_handler, \
473  vl_api_##n##_t_endian, \
474  vl_api_##n##_t_print, \
475  sizeof(vl_api_##n##_t), 1);
477 #undef _
478 }
479 
480 static clib_error_t *
482 {
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);
486 
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,
490 
491  gbp_api_hookup (vm);
492 
493  /* Add our API messages to the global name_crc hash table */
495 
496  vec_free (name);
497  return (NULL);
498 }
499 
501 
502 /* *INDENT-OFF* */
504  .version = VPP_BUILD_VER,
505  .description = "Group Based Policy",
506 };
507 /* *INDENT-ON* */
508 
509 
510 /*
511  * fd.io coding-style-patch-verification: ON
512  *
513  * Local Variables:
514  * eval: (c-set-style "gnu")
515  * End:
516  */
VLIB_PLUGIN_REGISTER()
fib_protocol_t fp_proto
protocol type
Definition: fib_types.h:197
void gbp_subnet_walk(gbp_subnet_cb_t cb, void *ctx)
Definition: gbp_subnet.c:143
static int gbp_contract_send_details(gbp_contract_t *gbpc, void *args)
Definition: gbp_api.c:405
A Group Based Policy Endpoint.
Definition: gbp_endpoint.h:43
gbp_contract_key_t gc_key
source and destination EPGs
Definition: gbp_contract.h:49
static gbp_main_t gbp_main
Definition: gbp_api.c:74
vl_api_gbp_subnet_t subnet
Definition: gbp.api:137
static int gbp_subnet_send_details(u32 table_id, const fib_prefix_t *pfx, u32 sw_if_index, epg_id_t epg, u8 is_internal, void *args)
Definition: gbp_api.c:227
#define NULL
Definition: clib.h:55
u32 gepg_bd
Bridge-domain ID the EPG is in.
static void vl_api_gbp_recirc_dump_t_handler(vl_api_gbp_recirc_dump_t *mp)
Definition: gbp_api.c:371
static void vl_api_send_msg(vl_api_registration_t *rp, u8 *elem)
Definition: api.h:34
gbp_endpoint_key_t * ge_key
The endpoint&#39;s interface and IP address.
Definition: gbp_endpoint.h:48
static int gbp_recirc_send_details(gbp_recirc_t *gr, void *args)
Definition: gbp_api.c:347
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
void * vl_msg_api_alloc(int nbytes)
static void vl_api_gbp_contract_add_del_t_handler(vl_api_gbp_contract_add_del_t *mp)
Definition: gbp_api.c:388
unsigned char u8
Definition: types.h:56
u8 gr_is_ext
Is the interface for packets post-NAT translatoin (i.e.
Definition: gbp_recirc.h:41
u32 gek_sw_if_index
The interface on which the EP is connected.
Definition: gbp_endpoint.h:30
int gbp_subnet_add_del(u32 table_id, const fib_prefix_t *pfx, u32 sw_if_index, epg_id_t epg, u8 is_add, u8 is_internal)
Definition: gbp_subnet.c:71
Aggregrate type for a prefix.
Definition: fib_types.h:188
u32 epg_id_t
Definition: gbp_types.h:21
static void setup_message_id_table(api_main_t *am)
Definition: gbp_api.c:457
An Endpoint Group representation.
Definition: gbp_recirc.h:25
unsigned int u32
Definition: types.h:88
u16 fp_len
The mask length.
Definition: fib_types.h:192
int gbp_endpoint_update(u32 sw_if_index, const ip46_address_t *ip, epg_id_t epg_id)
Definition: gbp_endpoint.c:135
epg_id_t gr_epg
EPG ID that packets will classify to when they arrive on this recirc.
Definition: gbp_recirc.h:30
u16 msg_id_base
Definition: gbp_api.c:71
ip46_address_t fp_addr
The address type is not deriveable from the fp_addr member.
Definition: fib_types.h:211
L2 Emulation Main.
Definition: gbp_api.c:69
static void vl_api_gbp_contract_dump_t_handler(vl_api_gbp_contract_dump_t *mp)
Definition: gbp_api.c:429
unsigned short u16
Definition: types.h:57
#define REPLY_MACRO(t)
void gbp_endpoint_group_delete(epg_id_t epg_id)
vl_api_gbp_endpoint_group_t epg
Definition: gbp.api:67
An Endpoint Group representation.
void gbp_contract_delete(epg_id_t src_epg, epg_id_t dst_epg)
Definition: gbp_contract.c:37
API main structure, used by both vpp and binary API clients.
Definition: api_common.h:201
static void vl_api_gbp_recirc_add_del_t_handler(vl_api_gbp_recirc_add_del_t *mp)
Definition: gbp_api.c:325
#define ip46_address_is_ip4(ip46)
Definition: ip6_packet.h:81
struct gbp_main_t_ gbp_main_t
L2 Emulation Main.
An API client registration, only in vpp/vlib.
Definition: api_common.h:44
#define BAD_SW_IF_INDEX_LABEL
static uword vnet_sw_if_index_is_api_valid(u32 sw_if_index)
static int gbp_endpoint_group_send_details(gbp_endpoint_group_t *gepg, void *args)
Definition: gbp_api.c:281
ip46_address_t gek_ip
The IP[46] address of the endpoint.
Definition: gbp_endpoint.h:35
vlib_main_t * vm
Definition: buffer.c:294
void gbp_endpoint_walk(gbp_endpoint_cb_t cb, void *ctx)
Definition: gbp_endpoint.c:220
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:339
int gbp_endpoint_group_add(epg_id_t epg_id, u32 bd_id, u32 ip4_table_id, u32 ip6_table_id, u32 uplink_sw_if_index)
static void vl_api_gbp_subnet_add_del_t_handler(vl_api_gbp_subnet_add_del_t *mp)
Definition: gbp_api.c:201
#define clib_memcpy(a, b, c)
Definition: string.h:75
static vl_api_registration_t * vl_api_client_index_to_registration(u32 index)
Definition: api.h:56
epg_id_t gck_src
source and destination EPGs for which the ACL applies
Definition: gbp_contract.h:33
vl_api_gbp_endpoint_group_t epg
Definition: gbp.api:79
vl_api_gbp_subnet_t subnet
Definition: gbp.api:125
u32 gr_sw_if_index
Definition: gbp_recirc.h:45
static void vl_api_gbp_endpoint_dump_t_handler(vl_api_gbp_endpoint_dump_t *mp)
Definition: gbp_api.c:154
vl_api_gbp_contract_t contract
Definition: gbp.api:152
static void vl_api_gbp_endpoint_group_dump_t_handler(vl_api_gbp_endpoint_group_dump_t *mp)
Definition: gbp_api.c:307
vl_api_gbp_endpoint_t endpoint
Definition: gbp.api:38
long ctx[MAX_CONNS]
Definition: main.c:126
static void vl_api_gbp_endpoint_group_add_del_t_handler(vl_api_gbp_endpoint_group_add_del_t *mp)
Definition: gbp_api.c:172
vl_api_gbp_recirc_t recirc
Definition: gbp.api:94
void gbp_endpoint_delete(u32 sw_if_index, const ip46_address_t *ip)
Definition: gbp_endpoint.c:192
static clib_error_t * gbp_init(vlib_main_t *vm)
Definition: gbp_api.c:481
static void gbp_api_hookup(vlib_main_t *vm)
Definition: gbp_api.c:466
u32 gepg_uplink_sw_if_index
the uplink interface dedicated to the EPG
void gbp_contract_update(epg_id_t src_epg, epg_id_t dst_epg, u32 acl_index)
Definition: gbp_contract.c:26
static void vl_api_gbp_endpoint_add_del_t_handler(vl_api_gbp_endpoint_add_del_t *mp)
Definition: gbp_api.c:79
static void vl_api_gbp_subnet_dump_t_handler(vl_api_gbp_subnet_dump_t *mp)
Definition: gbp_api.c:264
static int gbp_endpoint_send_details(gbp_endpoint_t *gbpe, void *args)
Definition: gbp_api.c:121
vl_api_gbp_contract_t contract
Definition: gbp.api:164
void gbp_recirc_walk(gbp_recirc_cb_t cb, void *ctx)
Definition: gbp_recirc.c:158
void gbp_recirc_delete(u32 sw_if_index)
Definition: gbp_recirc.c:118
vl_api_gbp_endpoint_t endpoint
Definition: gbp.api:50
epg_id_t ge_epg_id
The endpoint&#39;s designated EPG.
Definition: gbp_endpoint.h:53
u8 address[16]
Definition: gbp.api:117
vl_api_registration_t * reg
Definition: gbp_api.c:116
int gbp_recirc_add(u32 sw_if_index, epg_id_t epg_id, u8 is_ext)
Definition: gbp_recirc.c:34
u32 gc_acl_index
The ACL to apply for packets from the source to the destination EPG.
Definition: gbp_contract.h:54
#define GBP_MSG_BASE
Definition: gbp_api.c:76
VLIB_API_INIT_FUNCTION(gbp_init)
void gbp_contract_walk(gbp_contract_cb_t cb, void *ctx)
Definition: gbp_contract.c:48
struct gbp_walk_ctx_t_ gbp_walk_ctx_t
api_main_t api_main
Definition: api_shared.c:35
vl_api_gbp_recirc_t recirc
Definition: gbp.api:106
u32 gepg_rd[FIB_PROTOCOL_IP_MAX]
route-domain/IP-table ID the EPG is in
A Group Based Policy Contract.
Definition: gbp_contract.h:44
u16 vl_msg_api_get_msg_ids(const char *name, int n)
Definition: api_shared.c:872
void gbp_endpoint_group_walk(gbp_endpoint_group_cb_t cb, void *ctx)
#define foreach_gbp_api_msg
Definition: gbp_api.c:54