FD.io VPP  v18.07.1-19-g511ce25
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 <gbp/gbp_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 
67 
69 
70 #define GBP_MSG_BASE msg_id_base
71 
72 static void
74 {
75  vl_api_gbp_endpoint_add_del_reply_t *rmp;
76  ip46_address_t ip = { };
77  u32 sw_if_index;
78  int rv = 0;
79 
80  sw_if_index = ntohl (mp->endpoint.sw_if_index);
81  if (!vnet_sw_if_index_is_api_valid (sw_if_index))
82  goto bad_sw_if_index;
83 
84  if (mp->endpoint.is_ip6)
85  {
86  clib_memcpy (&ip.ip6, mp->endpoint.address, sizeof (ip.ip6));
87  }
88  else
89  {
90  clib_memcpy (&ip.ip4, mp->endpoint.address, sizeof (ip.ip4));
91  }
92 
93  if (mp->is_add)
94  {
95  rv =
96  gbp_endpoint_update (sw_if_index, &ip, ntohl (mp->endpoint.epg_id));
97  }
98  else
99  {
100  gbp_endpoint_delete (sw_if_index, &ip);
101  }
102 
104 
105  REPLY_MACRO (VL_API_GBP_ENDPOINT_ADD_DEL_REPLY + GBP_MSG_BASE);
106 }
107 
108 typedef struct gbp_walk_ctx_t_
109 {
113 
114 static int
116 {
119 
120  ctx = args;
121  mp = vl_msg_api_alloc (sizeof (*mp));
122  if (!mp)
123  return 1;
124 
125  memset (mp, 0, sizeof (*mp));
126  mp->_vl_msg_id = ntohs (VL_API_GBP_ENDPOINT_DETAILS + GBP_MSG_BASE);
127  mp->context = ctx->context;
128 
129  mp->endpoint.sw_if_index = ntohl (gbpe->ge_key->gek_sw_if_index);
131  if (mp->endpoint.is_ip6)
133  &gbpe->ge_key->gek_ip.ip6,
134  sizeof (gbpe->ge_key->gek_ip.ip6));
135  else
137  &gbpe->ge_key->gek_ip.ip4,
138  sizeof (gbpe->ge_key->gek_ip.ip4));
139 
140  mp->endpoint.epg_id = ntohl (gbpe->ge_epg_id);
141 
142  vl_api_send_msg (ctx->reg, (u8 *) mp);
143 
144  return (1);
145 }
146 
147 static void
149 {
151 
153  if (!reg)
154  return;
155 
156  gbp_walk_ctx_t ctx = {
157  .reg = reg,
158  .context = mp->context,
159  };
160 
162 }
163 
164 static void
167 {
168  vl_api_gbp_endpoint_group_add_del_reply_t *rmp;
169  u32 uplink_sw_if_index;
170  int rv = 0;
171 
172  uplink_sw_if_index = ntohl (mp->epg.uplink_sw_if_index);
173  if (!vnet_sw_if_index_is_api_valid (uplink_sw_if_index))
174  goto bad_sw_if_index;
175 
176  if (mp->is_add)
177  {
178  rv = gbp_endpoint_group_add (ntohl (mp->epg.epg_id),
179  ntohl (mp->epg.bd_id),
180  ntohl (mp->epg.ip4_table_id),
181  ntohl (mp->epg.ip6_table_id),
182  uplink_sw_if_index);
183  }
184  else
185  {
186  gbp_endpoint_group_delete (ntohl (mp->epg.epg_id));
187  }
188 
190 
191  REPLY_MACRO (VL_API_GBP_ENDPOINT_GROUP_ADD_DEL_REPLY + GBP_MSG_BASE);
192 }
193 
194 static void
196 {
197  vl_api_gbp_subnet_add_del_reply_t *rmp;
198  int rv = 0;
199  fib_prefix_t pfx = {
201  .fp_proto = (mp->subnet.is_ip6 ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4),
202  };
203 
204  if (mp->subnet.is_ip6)
205  clib_memcpy (&pfx.fp_addr.ip6, mp->subnet.address,
206  sizeof (pfx.fp_addr.ip6));
207  else
208  clib_memcpy (&pfx.fp_addr.ip4, mp->subnet.address,
209  sizeof (pfx.fp_addr.ip4));
210 
211  rv = gbp_subnet_add_del (ntohl (mp->subnet.table_id),
212  &pfx,
213  ntohl (mp->subnet.sw_if_index),
214  ntohl (mp->subnet.epg_id),
215  mp->is_add, mp->subnet.is_internal);
216 
217  REPLY_MACRO (VL_API_GBP_SUBNET_ADD_DEL_REPLY + GBP_MSG_BASE);
218 }
219 
220 static int
222  const fib_prefix_t * pfx,
223  u32 sw_if_index,
224  epg_id_t epg, u8 is_internal, void *args)
225 {
228 
229  ctx = args;
230  mp = vl_msg_api_alloc (sizeof (*mp));
231  if (!mp)
232  return 1;
233 
234  memset (mp, 0, sizeof (*mp));
235  mp->_vl_msg_id = ntohs (VL_API_GBP_SUBNET_DETAILS + GBP_MSG_BASE);
236  mp->context = ctx->context;
237 
238  mp->subnet.is_internal = is_internal;
239  mp->subnet.sw_if_index = ntohl (sw_if_index);
240  mp->subnet.epg_id = ntohl (epg);
241  mp->subnet.is_ip6 = (pfx->fp_proto == FIB_PROTOCOL_IP6);
242  mp->subnet.address_length = pfx->fp_len;
243  mp->subnet.table_id = ntohl (table_id);
244  if (mp->subnet.is_ip6)
245  clib_memcpy (&mp->subnet.address,
246  &pfx->fp_addr.ip6, sizeof (pfx->fp_addr.ip6));
247  else
248  clib_memcpy (&mp->subnet.address,
249  &pfx->fp_addr.ip4, sizeof (pfx->fp_addr.ip4));
250 
251 
252  vl_api_send_msg (ctx->reg, (u8 *) mp);
253 
254  return (1);
255 }
256 
257 static void
259 {
261 
263  if (!reg)
264  return;
265 
266  gbp_walk_ctx_t ctx = {
267  .reg = reg,
268  .context = mp->context,
269  };
270 
272 }
273 
274 static int
276 {
279 
280  ctx = args;
281  mp = vl_msg_api_alloc (sizeof (*mp));
282  if (!mp)
283  return 1;
284 
285  memset (mp, 0, sizeof (*mp));
286  mp->_vl_msg_id = ntohs (VL_API_GBP_ENDPOINT_GROUP_DETAILS + GBP_MSG_BASE);
287  mp->context = ctx->context;
288 
289  mp->epg.uplink_sw_if_index = ntohl (gepg->gepg_uplink_sw_if_index);
290  mp->epg.epg_id = ntohl (gepg->gepg_id);
291  mp->epg.bd_id = ntohl (gepg->gepg_bd);
292  mp->epg.ip4_table_id = ntohl (gepg->gepg_rd[FIB_PROTOCOL_IP4]);
293  mp->epg.ip6_table_id = ntohl (gepg->gepg_rd[FIB_PROTOCOL_IP6]);
294 
295  vl_api_send_msg (ctx->reg, (u8 *) mp);
296 
297  return (1);
298 }
299 
300 static void
302  mp)
303 {
305 
307  if (!reg)
308  return;
309 
310  gbp_walk_ctx_t ctx = {
311  .reg = reg,
312  .context = mp->context,
313  };
314 
316 }
317 
318 static void
320 {
321  vl_api_gbp_recirc_add_del_reply_t *rmp;
322  u32 sw_if_index;
323  int rv = 0;
324 
325  sw_if_index = ntohl (mp->recirc.sw_if_index);
326  if (!vnet_sw_if_index_is_api_valid (sw_if_index))
327  goto bad_sw_if_index;
328 
329  if (mp->is_add)
330  gbp_recirc_add (sw_if_index,
331  ntohl (mp->recirc.epg_id), mp->recirc.is_ext);
332  else
333  gbp_recirc_delete (sw_if_index);
334 
336 
337  REPLY_MACRO (VL_API_GBP_RECIRC_ADD_DEL_REPLY + GBP_MSG_BASE);
338 }
339 
340 static int
342 {
345 
346  ctx = args;
347  mp = vl_msg_api_alloc (sizeof (*mp));
348  if (!mp)
349  return 1;
350 
351  memset (mp, 0, sizeof (*mp));
352  mp->_vl_msg_id = ntohs (VL_API_GBP_RECIRC_DETAILS + GBP_MSG_BASE);
353  mp->context = ctx->context;
354 
355  mp->recirc.epg_id = ntohl (gr->gr_epg);
356  mp->recirc.sw_if_index = ntohl (gr->gr_sw_if_index);
357  mp->recirc.is_ext = ntohl (gr->gr_is_ext);
358 
359  vl_api_send_msg (ctx->reg, (u8 *) mp);
360 
361  return (1);
362 }
363 
364 static void
366 {
368 
370  if (!reg)
371  return;
372 
373  gbp_walk_ctx_t ctx = {
374  .reg = reg,
375  .context = mp->context,
376  };
377 
379 }
380 
381 static void
383 {
384  vl_api_gbp_contract_add_del_reply_t *rmp;
385  int rv = 0;
386 
387  if (mp->is_add)
388  gbp_contract_update (ntohl (mp->contract.src_epg),
389  ntohl (mp->contract.dst_epg),
390  ntohl (mp->contract.acl_index));
391  else
392  gbp_contract_delete (ntohl (mp->contract.src_epg),
393  ntohl (mp->contract.dst_epg));
394 
395  REPLY_MACRO (VL_API_GBP_CONTRACT_ADD_DEL_REPLY + GBP_MSG_BASE);
396 }
397 
398 static int
400 {
403 
404  ctx = args;
405  mp = vl_msg_api_alloc (sizeof (*mp));
406  if (!mp)
407  return 1;
408 
409  memset (mp, 0, sizeof (*mp));
410  mp->_vl_msg_id = ntohs (VL_API_GBP_CONTRACT_DETAILS + GBP_MSG_BASE);
411  mp->context = ctx->context;
412 
413  mp->contract.src_epg = ntohl (gbpc->gc_key.gck_src);
414  mp->contract.dst_epg = ntohl (gbpc->gc_key.gck_dst);
415  mp->contract.acl_index = ntohl (gbpc->gc_value.gc_acl_index);
416 
417  vl_api_send_msg (ctx->reg, (u8 *) mp);
418 
419  return (1);
420 }
421 
422 static void
424 {
426 
428  if (!reg)
429  return;
430 
431  gbp_walk_ctx_t ctx = {
432  .reg = reg,
433  .context = mp->context,
434  };
435 
437 }
438 
439 /*
440  * gbp_api_hookup
441  * Add vpe's API message handlers to the table.
442  * vlib has alread mapped shared memory and
443  * added the client registration handlers.
444  * See .../vlib-api/vlibmemory/memclnt_vlib.c:memclnt_process()
445  */
446 #define vl_msg_name_crc_list
447 #include <gbp/gbp_all_api_h.h>
448 #undef vl_msg_name_crc_list
449 
450 static void
452 {
453 #define _(id,n,crc) \
454  vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id + GBP_MSG_BASE);
455  foreach_vl_msg_name_crc_gbp;
456 #undef _
457 }
458 
459 static void
461 {
462 #define _(N,n) \
463  vl_msg_api_set_handlers(VL_API_##N + GBP_MSG_BASE, \
464  #n, \
465  vl_api_##n##_t_handler, \
466  vl_noop_handler, \
467  vl_api_##n##_t_endian, \
468  vl_api_##n##_t_print, \
469  sizeof(vl_api_##n##_t), 1);
471 #undef _
472 }
473 
474 static clib_error_t *
476 {
477  api_main_t *am = &api_main;
478  gbp_main_t *gbpm = &gbp_main;
479  u8 *name = format (0, "gbp_%08x%c", api_version, 0);
480 
481  gbpm->gbp_acl_user_id = ~0;
482 
483  /* Ask for a correctly-sized block of API message decode slots */
484  msg_id_base = vl_msg_api_get_msg_ids ((char *) name,
486  gbp_api_hookup (vm);
487 
488  /* Add our API messages to the global name_crc hash table */
490 
491  vec_free (name);
492  return (NULL);
493 }
494 
496 
497 /* *INDENT-OFF* */
499  .version = VPP_BUILD_VER,
500  .description = "Group Based Policy",
501 };
502 /* *INDENT-ON* */
503 
504 
505 /*
506  * fd.io coding-style-patch-verification: ON
507  *
508  * Local Variables:
509  * eval: (c-set-style "gnu")
510  * End:
511  */
VLIB_PLUGIN_REGISTER()
fib_protocol_t fp_proto
protocol type
Definition: fib_types.h:202
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:399
A Group Based Policy Endpoint.
Definition: gbp_endpoint.h:43
gbp_contract_key_t gc_key
source and destination EPGs
Definition: gbp_contract.h:68
gbp_main_t gbp_main
Definition: gbp_api.c:66
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:221
#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:365
static void vl_api_send_msg(vl_api_registration_t *rp, u8 *elem)
Definition: api.h:34
u32 gbp_acl_user_id
Definition: gbp.h:45
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:341
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:382
unsigned char u8
Definition: types.h:56
static u16 msg_id_base
Definition: gbp_api.c:68
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:193
u32 epg_id_t
Definition: gbp_types.h:21
static void setup_message_id_table(api_main_t *am)
Definition: gbp_api.c:451
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:197
gbp_contract_value_t gc_value
The ACL to apply for packets from the source to the destination EPG.
Definition: gbp_contract.h:73
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
ip46_address_t fp_addr
The address type is not deriveable from the fp_addr member.
Definition: fib_types.h:216
static void vl_api_gbp_contract_dump_t_handler(vl_api_gbp_contract_dump_t *mp)
Definition: gbp_api.c:423
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:70
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:319
#define ip46_address_is_ip4(ip46)
Definition: ip6_packet.h:81
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:275
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:195
#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:148
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:301
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:166
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:475
static void gbp_api_hookup(vlib_main_t *vm)
Definition: gbp_api.c:460
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:73
static void vl_api_gbp_subnet_dump_t_handler(vl_api_gbp_subnet_dump_t *mp)
Definition: gbp_api.c:258
static int gbp_endpoint_send_details(gbp_endpoint_t *gbpe, void *args)
Definition: gbp_api.c:115
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:110
Group Base Policy (GBP) defines:
Definition: gbp.h:43
int gbp_recirc_add(u32 sw_if_index, epg_id_t epg_id, u8 is_ext)
Definition: gbp_recirc.c:34
#define GBP_MSG_BASE
Definition: gbp_api.c:70
VLIB_API_INIT_FUNCTION(gbp_init)
void gbp_contract_walk(gbp_contract_cb_t cb, void *ctx)
Definition: gbp_contract.c:90
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:63
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