FD.io VPP  v21.06-3-gbb25fbf28
Vector Packet Processing
gbp_endpoint_group.c
Go to the documentation of this file.
1 /*
2  * gbp.h : Group Based Policy
3  *
4  * Copyright (c) 2018 Cisco and/or its affiliates.
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
22 #include <plugins/gbp/gbp_itf.h>
23 
24 #include <vnet/dpo/dvr_dpo.h>
25 #include <vnet/fib/fib_table.h>
26 #include <vnet/l2/l2_input.h>
27 
28 /**
29  * Pool of GBP endpoint_groups
30  */
32 
33 /**
34  * DB of endpoint_groups
35  */
37 
38 /**
39  * Map sclass to EPG
40  */
42 
44 
45 #define GBP_EPG_DBG(...) \
46  vlib_log_debug (gg_logger, __VA_ARGS__);
47 
50 {
52 }
53 
54 void
56 {
58 
59  if (INDEX_INVALID == ggi)
60  return;
61 
62  gg = gbp_endpoint_group_get (ggi);
63  gg->gg_locks++;
64 }
65 
66 index_t
68 {
69  uword *p;
70 
72 
73  if (NULL != p)
74  return p[0];
75 
76  return (INDEX_INVALID);
77 }
78 
79 int
81  u16 sclass,
82  u32 bd_id,
83  u32 rd_id,
86 {
88  index_t ggi;
89 
91 
92  if (INDEX_INVALID == ggi)
93  {
94  fib_protocol_t fproto;
95  index_t gbi, grdi;
96 
98 
99  if (~0 == gbi)
100  return (VNET_API_ERROR_BD_NOT_MODIFIABLE);
101 
103 
104  if (~0 == grdi)
105  {
107  return (VNET_API_ERROR_NO_SUCH_FIB);
108  }
109 
111 
112  gg->gg_vnid = vnid;
113  gg->gg_rd = grdi;
114  gg->gg_gbd = gbi;
115 
118  gg->gg_locks = 1;
119  gg->gg_sclass = sclass;
120  gg->gg_retention = *retention;
121 
122  if (SCLASS_INVALID != gg->gg_sclass)
124 
125  /*
126  * an egress DVR dpo for internal subnets to use when sending
127  * on the uplink interface
128  */
129  if (~0 != gg->gg_uplink_sw_if_index)
130  {
131  FOR_EACH_FIB_IP_PROTOCOL (fproto)
132  {
134  fib_proto_to_dpo (fproto),
135  &gg->gg_dpo[fproto]);
136  }
137 
138  /*
139  * Add the uplink to the BD
140  * packets direct from the uplink have had policy applied
141  */
142  gg->gg_uplink_itf =
144 
146  L2INPUT_FEAT_GBP_NULL_CLASSIFY);
147  }
148 
151  }
152  else
153  {
154  gg = gbp_endpoint_group_get (ggi);
155  gg->gg_locks++;
156  }
157 
158  GBP_EPG_DBG ("add: %U", format_gbp_endpoint_group, gg);
159 
160  return (0);
161 }
162 
163 void
165 {
167 
168  if (INDEX_INVALID == ggi)
169  return;
170 
171  gg = gbp_endpoint_group_get (ggi);
172 
173  gg->gg_locks--;
174 
175  if (0 == gg->gg_locks)
176  {
177  fib_protocol_t fproto;
178 
180 
182 
183  FOR_EACH_FIB_IP_PROTOCOL (fproto)
184  {
185  dpo_reset (&gg->gg_dpo[fproto]);
186  }
189 
190  if (SCLASS_INVALID != gg->gg_sclass)
193 
195  }
196 }
197 
198 int
200 {
201  index_t ggi;
202 
204 
205  if (INDEX_INVALID != ggi)
206  {
208  gbp_endpoint_group_get (ggi));
210 
211  return (0);
212  }
213 
214  return (VNET_API_ERROR_NO_SUCH_ENTRY);
215 }
216 
217 u32
219 {
220  const gbp_bridge_domain_t *gb;
221 
222  gb = gbp_bridge_domain_get (gg->gg_gbd);
223 
224  return (gb->gb_bd_id);
225 }
226 
227 index_t
229  fib_protocol_t fproto)
230 {
231  const gbp_route_domain_t *grd;
232 
233  grd = gbp_route_domain_get (gg->gg_rd);
234 
235  return (grd->grd_fib_index[fproto]);
236 }
237 
238 void
240 {
241  gbp_endpoint_group_t *gbpe;
242 
243  /* *INDENT-OFF* */
245  {
246  if (!cb(gbpe, ctx))
247  break;
248  }
249  /* *INDENT-ON* */
250 }
251 
252 static clib_error_t *
254  unformat_input_t * input, vlib_cli_command_t * cmd)
255 {
257  vnid_t vnid = VNID_INVALID, sclass;
258  vnet_main_t *vnm = vnet_get_main ();
259  u32 uplink_sw_if_index = ~0;
260  u32 bd_id = ~0;
261  u32 rd_id = ~0;
262  u8 add = 1;
263 
265  {
266  if (unformat (input, "%U", unformat_vnet_sw_interface,
267  vnm, &uplink_sw_if_index))
268  ;
269  else if (unformat (input, "add"))
270  add = 1;
271  else if (unformat (input, "del"))
272  add = 0;
273  else if (unformat (input, "epg %d", &vnid))
274  ;
275  else if (unformat (input, "sclass %d", &sclass))
276  ;
277  else if (unformat (input, "bd %d", &bd_id))
278  ;
279  else if (unformat (input, "rd %d", &rd_id))
280  ;
281  else
282  break;
283  }
284 
285  if (VNID_INVALID == vnid)
286  return clib_error_return (0, "EPG-ID must be specified");
287 
288  if (add)
289  {
290  if (~0 == bd_id)
291  return clib_error_return (0, "Bridge-domain must be specified");
292  if (~0 == rd_id)
293  return clib_error_return (0, "route-domain must be specified");
294 
297  }
298  else
300 
301  return (NULL);
302 }
303 
304 /*?
305  * Configure a GBP Endpoint Group
306  *
307  * @cliexpar
308  * @cliexstart{gbp endpoint-group [del] epg <ID> bd <ID> rd <ID> [sclass <ID>] [<interface>]}
309  * @cliexend
310  ?*/
311 /* *INDENT-OFF* */
313  .path = "gbp endpoint-group",
314  .short_help = "gbp endpoint-group [del] epg <ID> bd <ID> rd <ID> [sclass <ID>] [<interface>]",
315  .function = gbp_endpoint_group_cli,
316 };
317 
318 static u8 *
319 format_gbp_endpoint_retention (u8 * s, va_list * args)
320 {
322 
323  s = format (s, "[remote-EP-timeout:%d]", rt->remote_ep_timeout);
324 
325  return (s);
326 }
327 
328 u8 *
329 format_gbp_endpoint_group (u8 * s, va_list * args)
330 {
331  gbp_endpoint_group_t *gg = va_arg (*args, gbp_endpoint_group_t*);
332 
333  if (NULL != gg)
334  s = format (s, "[%d] %d, sclass:%d bd:%d rd:%d uplink:%U retention:%U locks:%d",
336  gg->gg_vnid,
337  gg->gg_sclass,
338  gg->gg_gbd,
339  gg->gg_rd,
342  gg->gg_locks);
343  else
344  s = format (s, "NULL");
345 
346  return (s);
347 }
348 
349 static int
351 {
352  vlib_main_t *vm;
353 
354  vm = ctx;
356 
357  return (1);
358 }
359 
360 static clib_error_t *
362  unformat_input_t * input, vlib_cli_command_t * cmd)
363 {
364  vlib_cli_output (vm, "Endpoint-Groups:");
366 
367  return (NULL);
368 }
369 
370 
371 /*?
372  * Show Group Based Policy Endpoint_Groups and derived information
373  *
374  * @cliexpar
375  * @cliexstart{show gbp endpoint_group}
376  * @cliexend
377  ?*/
378 /* *INDENT-OFF* */
380  .path = "show gbp endpoint-group",
381  .short_help = "show gbp endpoint-group\n",
382  .function = gbp_endpoint_group_show,
383 };
384 /* *INDENT-ON* */
385 
386 static clib_error_t *
388 {
389  gg_logger = vlib_log_register_class ("gbp", "epg");
390 
391  return (NULL);
392 }
393 
395 
396 /*
397  * fd.io coding-style-patch-verification: ON
398  *
399  * Local Variables:
400  * eval: (c-set-style "gnu")
401  * End:
402  */
gbp_endpoint_group_delete
int gbp_endpoint_group_delete(sclass_t sclass)
Definition: gbp_endpoint_group.c:199
gbp_itf_l2_set_input_feature
void gbp_itf_l2_set_input_feature(gbp_itf_hdl_t gh, l2input_feat_masks_t feats)
Definition: gbp_itf.c:384
gbp_endpoint_group_cli
static clib_error_t * gbp_endpoint_group_cli(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: gbp_endpoint_group.c:253
gpb_endpoint_group_t_::gg_uplink_itf
gbp_itf_hdl_t gg_uplink_itf
Definition: gbp_endpoint_group.h:67
gbp_endpoint_group_find
index_t gbp_endpoint_group_find(sclass_t sclass)
Definition: gbp_endpoint_group.c:67
gbp_endpoint_group_show_node
static vlib_cli_command_t gbp_endpoint_group_show_node
(constructor) VLIB_CLI_COMMAND (gbp_endpoint_group_show_node)
Definition: gbp_endpoint_group.c:379
uplink_sw_if_index
vl_api_interface_index_t uplink_sw_if_index
Definition: gbp.api:190
gpb_endpoint_group_t_::gg_vnid
vnid_t gg_vnid
ID.
Definition: gbp_endpoint_group.h:41
gbp_endpoint_group_pool
gbp_endpoint_group_t * gbp_endpoint_group_pool
Pool of GBP endpoint_groups.
Definition: gbp_endpoint_group.c:31
FOR_EACH_FIB_IP_PROTOCOL
#define FOR_EACH_FIB_IP_PROTOCOL(_item)
Definition: fib_types.h:69
VNID_INVALID
#define VNID_INVALID
Definition: gbp_types.h:22
SCLASS_INVALID
#define SCLASS_INVALID
Definition: gbp_types.h:26
gpb_route_domain_t_::grd_fib_index
u32 grd_fib_index[FIB_PROTOCOL_IP_MAX]
Definition: gbp_route_domain.h:36
pool_elt_at_index
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:553
vlib_log_class_t
u32 vlib_log_class_t
Definition: vlib.h:52
gg_logger
vlib_log_class_t gg_logger
Definition: gbp_endpoint_group.c:43
gbp_endpoint_group_walk
void gbp_endpoint_group_walk(gbp_endpoint_group_cb_t cb, void *ctx)
Definition: gbp_endpoint_group.c:239
vlib_log_register_class
vlib_log_class_t vlib_log_register_class(char *class, char *subclass)
Definition: log.c:339
gpb_endpoint_group_t_::gg_gbd
index_t gg_gbd
Bridge-domain ID the EPG is in.
Definition: gbp_endpoint_group.h:51
gpb_endpoint_group_t_::gg_sclass
u16 gg_sclass
Sclass.
Definition: gbp_endpoint_group.h:46
clib_error_return
#define clib_error_return(e, args...)
Definition: error.h:99
gbp_endpoint_group_cb_t
int(* gbp_endpoint_group_cb_t)(gbp_endpoint_group_t *gbpe, void *ctx)
Definition: gbp_endpoint_group.h:110
vlib_cli_command_t::path
char * path
Definition: cli.h:96
dvr_dpo.h
fib_table.h
u16
unsigned short u16
Definition: types.h:57
gbp_endpoint_group_add_and_lock
int gbp_endpoint_group_add_and_lock(vnid_t vnid, u16 sclass, u32 bd_id, u32 rd_id, u32 uplink_sw_if_index, const gbp_endpoint_retention_t *retention)
Definition: gbp_endpoint_group.c:80
gpb_endpoint_group_t_::gg_uplink_sw_if_index
u32 gg_uplink_sw_if_index
the uplink interface dedicated to the EPG
Definition: gbp_endpoint_group.h:66
pool_put
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:305
gpb_route_domain_t_
A route Domain Representation.
Definition: gbp_route_domain.h:29
vm
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
vnid_t
u32 vnid_t
Definition: gbp_types.h:21
format_gbp_endpoint_retention
static u8 * format_gbp_endpoint_retention(u8 *s, va_list *args)
Definition: gbp_endpoint_group.c:319
gbp_bridge_domain_get
static gbp_bridge_domain_t * gbp_bridge_domain_get(index_t i)
Definition: gbp_bridge_domain.h:128
unformat_input_t
struct _unformat_input_t unformat_input_t
format_gbp_endpoint_group
u8 * format_gbp_endpoint_group(u8 *s, va_list *args)
Definition: gbp_endpoint_group.c:329
gbp_bridge_domain_t_::gb_bd_id
u32 gb_bd_id
Bridge-domain ID.
Definition: gbp_bridge_domain.h:47
gbp_endpoint_group_show
static clib_error_t * gbp_endpoint_group_show(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: gbp_endpoint_group.c:361
unformat
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
hash_set
#define hash_set(h, key, value)
Definition: hash.h:255
pool_foreach
#define pool_foreach(VAR, POOL)
Iterate through pool.
Definition: pool.h:534
dvr_dpo_add_or_lock
void dvr_dpo_add_or_lock(u32 sw_if_index, dpo_proto_t dproto, dpo_id_t *dpo)
Definition: dvr_dpo.c:91
gbp_itf_hdl_reset
void gbp_itf_hdl_reset(gbp_itf_hdl_t *gh)
Definition: gbp_itf.c:110
bd_id
u32 bd_id
Definition: gbp.api:188
gbp_endpoint_group_cli_node
static vlib_cli_command_t gbp_endpoint_group_cli_node
(constructor) VLIB_CLI_COMMAND (gbp_endpoint_group_cli_node)
Definition: gbp_endpoint_group.c:312
vnet_get_main
vnet_main_t * vnet_get_main(void)
Definition: pnat_test_stubs.h:56
unformat_check_input
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:163
index_t
u32 index_t
A Data-Path Object is an object that represents actions that are applied to packets are they are swit...
Definition: dpo.h:43
gbp_endpoint_group_db_t_
EPG DB, key'd on EGP-ID.
Definition: gbp_endpoint_group.h:88
uword
u64 uword
Definition: types.h:112
hash_get
#define hash_get(h, key)
Definition: hash.h:249
gpb_endpoint_group_t_
An Endpoint Group representation.
Definition: gbp_endpoint_group.h:36
format_gbp_itf_hdl
u8 * format_gbp_itf_hdl(u8 *s, va_list *args)
Definition: gbp_itf.c:522
i
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:261
gbp_itf.h
retention
vl_api_gbp_endpoint_retention_t retention
Definition: gbp.api:191
VLIB_CLI_COMMAND
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:163
gbp_endpoint_group.h
gpb_endpoint_group_t_::gg_dpo
dpo_id_t gg_dpo[FIB_PROTOCOL_IP_MAX]
The DPO used in the L3 path for forwarding internal subnets.
Definition: gbp_endpoint_group.h:72
fib_protocol_t
enum fib_protocol_t_ fib_protocol_t
Protocol Type.
sclass
u16 sclass
Definition: gbp.api:131
gbp_bridge_domain.h
vlib_cli_output
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:716
fib_proto_to_dpo
dpo_proto_t fib_proto_to_dpo(fib_protocol_t fib_proto)
Definition: fib_types.c:343
gbp_endpoint_group_show_one
static int gbp_endpoint_group_show_one(gbp_endpoint_group_t *gg, void *ctx)
Definition: gbp_endpoint_group.c:350
gbp_endpoint_group_get
gbp_endpoint_group_t * gbp_endpoint_group_get(index_t i)
Definition: gbp_endpoint_group.c:49
l2_input.h
GBP_EPG_DBG
#define GBP_EPG_DBG(...)
Definition: gbp_endpoint_group.c:45
gbp_endpoint_group_db
gbp_endpoint_group_db_t gbp_endpoint_group_db
DB of endpoint_groups.
Definition: gbp_endpoint_group.c:36
vnet_main_t
Definition: vnet.h:76
rd_id
u32 rd_id
Definition: gbp.api:35
gpb_endpoint_group_t_::gg_locks
u32 gg_locks
Locks/references to this EPG.
Definition: gbp_endpoint_group.h:77
sclass_t
u16 sclass_t
Definition: gbp_types.h:25
unformat_vnet_sw_interface
unformat_function_t unformat_vnet_sw_interface
Definition: interface_funcs.h:459
format
description fragment has unexpected format
Definition: map.api:433
gbp_endpoint_group_get_bd_id
u32 gbp_endpoint_group_get_bd_id(const gbp_endpoint_group_t *gg)
Definition: gbp_endpoint_group.c:218
u32
unsigned int u32
Definition: types.h:88
VLIB_INIT_FUNCTION
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:172
gpb_endpoint_group_t_::gg_retention
gbp_endpoint_retention_t gg_retention
EP retention policy.
Definition: gbp_endpoint_group.h:82
gbp_endpoint_group_lock
void gbp_endpoint_group_lock(index_t ggi)
Definition: gbp_endpoint_group.c:55
ctx
long ctx[MAX_CONNS]
Definition: main.c:144
gbp_itf_l2_add_and_lock
gbp_itf_hdl_t gbp_itf_l2_add_and_lock(u32 sw_if_index, index_t gbi)
Definition: gbp_itf.c:198
gbp_route_domain_get
gbp_route_domain_t * gbp_route_domain_get(index_t i)
Definition: gbp_route_domain.c:72
gbp_bridge_domain_find_and_lock
index_t gbp_bridge_domain_find_and_lock(u32 bd_id)
Definition: gbp_bridge_domain.c:91
gbp_bridge_domain_t_
A bridge Domain Representation.
Definition: gbp_bridge_domain.h:42
gbp_route_domain_find_and_lock
index_t gbp_route_domain_find_and_lock(u32 rd_id)
Definition: gbp_route_domain.c:100
gbp_epg_sclass_db
uword * gbp_epg_sclass_db
Map sclass to EPG.
Definition: gbp_endpoint_group.c:41
gbp_endpoint_group_get_fib_index
index_t gbp_endpoint_group_get_fib_index(const gbp_endpoint_group_t *gg, fib_protocol_t fproto)
Definition: gbp_endpoint_group.c:228
gbp_endpoint.h
hash_unset
#define hash_unset(h, key)
Definition: hash.h:261
vlib_main_t
Definition: main.h:102
gbp_endpoint_retention_t_
Endpoint Retnetion Policy.
Definition: gbp_endpoint_group.h:27
pool_get_zero
#define pool_get_zero(P, E)
Allocate an object E from a pool P and zero it.
Definition: pool.h:258
u8
unsigned char u8
Definition: types.h:56
clib_error_t
Definition: clib_error.h:21
gpb_endpoint_group_t_::gg_rd
index_t gg_rd
route-domain/IP-table ID the EPG is in
Definition: gbp_endpoint_group.h:56
rt
vnet_interface_output_runtime_t * rt
Definition: interface_output.c:399
gbp_endpoint_group_unlock
void gbp_endpoint_group_unlock(index_t ggi)
Definition: gbp_endpoint_group.c:164
vlib_init_function_t
clib_error_t *() vlib_init_function_t(struct vlib_main_t *vm)
Definition: init.h:51
gbp_route_domain.h
gbp_endpoint_group_init
static clib_error_t * gbp_endpoint_group_init(vlib_main_t *vm)
Definition: gbp_endpoint_group.c:387
vlib_cli_command_t
Definition: cli.h:92
INDEX_INVALID
#define INDEX_INVALID
Invalid index - used when no index is known blazoned capitals INVALID speak volumes where ~0 does not...
Definition: dpo.h:49
dpo_reset
void dpo_reset(dpo_id_t *dpo)
reset a DPO ID The DPO will be unlocked.
Definition: dpo.c:234
gbp_endpoint_group_db_t_::gg_hash_sclass
uword * gg_hash_sclass
Definition: gbp_endpoint_group.h:90
UNFORMAT_END_OF_INPUT
#define UNFORMAT_END_OF_INPUT
Definition: format.h:137
gbp_route_domain_unlock
void gbp_route_domain_unlock(index_t index)
Definition: gbp_route_domain.c:208
gbp_itf_unlock
void gbp_itf_unlock(gbp_itf_hdl_t *gh)
Definition: gbp_itf.c:288
gbp_bridge_domain_unlock
void gbp_bridge_domain_unlock(index_t gbdi)
Definition: gbp_bridge_domain.c:312