FD.io VPP  v18.10-34-gcce845e
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 
20 
21 #include <vnet/dpo/dvr_dpo.h>
22 #include <vnet/fib/fib_table.h>
23 #include <vnet/l2/l2_input.h>
24 #include <vnet/l2/feat_bitmap.h>
25 
26 /**
27  * Pool of GBP endpoint_groups
28  */
30 
31 /**
32  * DB of endpoint_groups
33  */
35 
38 {
39  uword *p;
40 
41  p = hash_get (gbp_endpoint_group_db.gepg_hash, epg_id);
42 
43  if (NULL != p)
44  return (pool_elt_at_index (gbp_endpoint_group_pool, p[0]));
45 
46  return (NULL);
47 }
48 
49 int
51  u32 bd_id,
52  u32 ip4_table_id,
53  u32 ip6_table_id, u32 uplink_sw_if_index)
54 {
56 
57  gepg = gbp_endpoint_group_find (epg_id);
58 
59  if (NULL == gepg)
60  {
61  fib_protocol_t fproto;
62 
63  pool_get (gbp_endpoint_group_pool, gepg);
64  memset (gepg, 0, sizeof (*gepg));
65 
66  gepg->gepg_id = epg_id;
67  gepg->gepg_bd = bd_id;
68  gepg->gepg_rd[FIB_PROTOCOL_IP4] = ip4_table_id;
69  gepg->gepg_rd[FIB_PROTOCOL_IP6] = ip6_table_id;
70  gepg->gepg_uplink_sw_if_index = uplink_sw_if_index;
71 
72  /*
73  * an egress DVR dpo for internal subnets to use when sending
74  * on the uplink interface
75  */
77  {
78  gepg->gepg_fib_index[fproto] =
80  gepg->gepg_rd[fproto],
82 
83  if (~0 == gepg->gepg_fib_index[fproto])
84  {
85  return (VNET_API_ERROR_NO_SUCH_FIB);
86  }
87 
88  dvr_dpo_add_or_lock (uplink_sw_if_index,
89  fib_proto_to_dpo (fproto),
90  &gepg->gepg_dpo[fproto]);
91  }
92 
93  /*
94  * packets direct from the uplink have had policy applied
95  */
97  L2INPUT_FEAT_GBP_NULL_CLASSIFY, 1);
98 
99  hash_set (gbp_endpoint_group_db.gepg_hash,
100  gepg->gepg_id, gepg - gbp_endpoint_group_pool);
101 
102  }
103 
104  return (0);
105 }
106 
107 void
109 {
110  gbp_endpoint_group_t *gepg;
111  uword *p;
112 
113  p = hash_get (gbp_endpoint_group_db.gepg_hash, epg_id);
114 
115  if (NULL != p)
116  {
117  fib_protocol_t fproto;
118 
119  gepg = pool_elt_at_index (gbp_endpoint_group_pool, p[0]);
120 
122  L2INPUT_FEAT_GBP_NULL_CLASSIFY, 0);
123 
124  FOR_EACH_FIB_IP_PROTOCOL (fproto)
125  {
126  dpo_reset (&gepg->gepg_dpo[fproto]);
127  fib_table_unlock (gepg->gepg_fib_index[fproto],
128  fproto, FIB_SOURCE_PLUGIN_HI);
129  }
130 
131  hash_unset (gbp_endpoint_group_db.gepg_hash, epg_id);
132 
133  pool_put (gbp_endpoint_group_pool, gepg);
134  }
135 }
136 
137 void
139 {
140  gbp_endpoint_group_t *gbpe;
141 
142  /* *INDENT-OFF* */
143  pool_foreach(gbpe, gbp_endpoint_group_pool,
144  {
145  if (!cb(gbpe, ctx))
146  break;
147  });
148  /* *INDENT-ON* */
149 }
150 
151 static clib_error_t *
153  unformat_input_t * input, vlib_cli_command_t * cmd)
154 {
155  vnet_main_t *vnm = vnet_get_main ();
157  u32 uplink_sw_if_index = ~0;
158  u32 bd_id = ~0;
159  u32 rd_id = ~0;
160  u8 add = 1;
161 
163  {
164  if (unformat (input, "%U", unformat_vnet_sw_interface,
165  vnm, &uplink_sw_if_index))
166  ;
167  else if (unformat (input, "add"))
168  add = 1;
169  else if (unformat (input, "del"))
170  add = 0;
171  else if (unformat (input, "epg %d", &epg_id))
172  ;
173  else if (unformat (input, "bd %d", &bd_id))
174  ;
175  else if (unformat (input, "rd %d", &rd_id))
176  ;
177  else
178  break;
179  }
180 
181  if (EPG_INVALID == epg_id)
182  return clib_error_return (0, "EPG-ID must be specified");
183 
184  if (add)
185  {
186  if (~0 == uplink_sw_if_index)
187  return clib_error_return (0, "interface must be specified");
188  if (~0 == bd_id)
189  return clib_error_return (0, "Bridge-domain must be specified");
190  if (~0 == rd_id)
191  return clib_error_return (0, "route-domain must be specified");
192 
193  gbp_endpoint_group_add (epg_id, bd_id, rd_id, rd_id,
194  uplink_sw_if_index);
195  }
196  else
197  gbp_endpoint_group_delete (epg_id);
198 
199  return (NULL);
200 }
201 
202 /*?
203  * Configure a GBP Endpoint Group
204  *
205  * @cliexpar
206  * @cliexstart{set gbp endpoint-group [del] epg <ID> bd <ID> <interface>}
207  * @cliexend
208  ?*/
209 /* *INDENT-OFF* */
210 VLIB_CLI_COMMAND (gbp_endpoint_group_cli_node, static) = {
211  .path = "gbp endpoint-group",
212  .short_help = "gbp endpoint-group [del] epg <ID> bd <ID> rd <ID> <interface>",
213  .function = gbp_endpoint_group_cli,
214 };
215 
216 static int
218 {
219  vnet_main_t *vnm = vnet_get_main ();
220  vlib_main_t *vm;
221 
222  vm = ctx;
223  vlib_cli_output (vm, " %d, bd:%d, ip4:%d ip6:%d uplink:%U",
224  gepg->gepg_id,
225  gepg->gepg_bd,
226  gepg->gepg_rd[FIB_PROTOCOL_IP4],
227  gepg->gepg_rd[FIB_PROTOCOL_IP6],
229 
230  return (1);
231 }
232 
233 static clib_error_t *
235  unformat_input_t * input, vlib_cli_command_t * cmd)
236 {
237  vlib_cli_output (vm, "Endpoint-Groups:");
239 
240  return (NULL);
241 }
242 
243 
244 /*?
245  * Show Group Based Policy Endpoint_Groups and derived information
246  *
247  * @cliexpar
248  * @cliexstart{show gbp endpoint_group}
249  * @cliexend
250  ?*/
251 /* *INDENT-OFF* */
252 VLIB_CLI_COMMAND (gbp_endpoint_group_show_node, static) = {
253  .path = "show gbp endpoint-group",
254  .short_help = "show gbp endpoint-group\n",
255  .function = gbp_endpoint_group_show,
256 };
257 /* *INDENT-ON* */
258 
259 /*
260  * fd.io coding-style-patch-verification: ON
261  *
262  * Local Variables:
263  * eval: (c-set-style "gnu")
264  * End:
265  */
EPG DB, key&#39;d on EGP-ID.
#define hash_set(h, key, value)
Definition: hash.h:255
u16 epg_id_t
Definition: gbp_types.h:21
#define hash_unset(h, key)
Definition: hash.h:261
vnet_main_t * vnet_get_main(void)
Definition: misc.c:47
#define NULL
Definition: clib.h:57
u32 gepg_bd
Bridge-domain ID the EPG is in.
unformat_function_t unformat_vnet_sw_interface
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:228
format_function_t format_vnet_sw_if_index_name
unsigned char u8
Definition: types.h:56
enum fib_protocol_t_ fib_protocol_t
Protocol Type.
memset(h->entries, 0, sizeof(h->entries[0])*entries)
u32 gepg_fib_index[FIB_PROTOCOL_IP_MAX]
resulting FIB indices
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:443
A high priority source a plugin can use.
Definition: fib_entry.h:62
gbp_endpoint_group_t * gbp_endpoint_group_find(epg_id_t epg_id)
#define clib_error_return(e, args...)
Definition: error.h:99
unsigned int u32
Definition: types.h:88
int(* gbp_endpoint_group_cb_t)(gbp_endpoint_group_t *gbpe, void *ctx)
#define hash_get(h, key)
Definition: hash.h:249
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:464
long ctx[MAX_CONNS]
Definition: main.c:144
static int gbp_endpoint_group_show_one(gbp_endpoint_group_t *gepg, void *ctx)
struct _unformat_input_t unformat_input_t
u16 epg_id
Definition: gbp.api:30
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:274
void gbp_endpoint_group_delete(epg_id_t epg_id)
void fib_table_unlock(u32 fib_index, fib_protocol_t proto, fib_source_t source)
Take a reference counting lock on the table.
Definition: fib_table.c:1236
gbp_endpoint_group_db_t gbp_endpoint_group_db
DB of endpoint_groups.
An Endpoint Group representation.
void dvr_dpo_add_or_lock(u32 sw_if_index, dpo_proto_t dproto, dpo_id_t *dpo)
Definition: dvr_dpo.c:87
#define UNFORMAT_END_OF_INPUT
Definition: format.h:144
vlib_main_t * vm
Definition: buffer.c:294
static clib_error_t * gbp_endpoint_group_show(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
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)
dpo_id_t gepg_dpo[FIB_PROTOCOL_IP_MAX]
The DPO used in the L3 path for forwarding internal subnets.
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:155
#define EPG_INVALID
Definition: gbp_types.h:22
u32 gepg_uplink_sw_if_index
the uplink interface dedicated to the EPG
u32 fib_table_find_or_create_and_lock(fib_protocol_t proto, u32 table_id, fib_source_t src)
Get the index of the FIB for a Table-ID.
Definition: fib_table.c:1123
dpo_proto_t fib_proto_to_dpo(fib_protocol_t fib_proto)
Definition: fib_types.c:237
static clib_error_t * gbp_endpoint_group_cli(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
u32 l2input_intf_bitmap_enable(u32 sw_if_index, u32 feature_bitmap, u32 enable)
Enable (or disable) the feature in the bitmap for the given interface.
Definition: l2_input.c:520
u64 uword
Definition: types.h:112
#define FOR_EACH_FIB_IP_PROTOCOL(_item)
Definition: fib_types.h:70
void dpo_reset(dpo_id_t *dpo)
reset a DPO ID The DPO will be unlocked.
Definition: dpo.c:231
gbp_endpoint_group_t * gbp_endpoint_group_pool
Pool of GBP endpoint_groups.
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:725
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
u32 gepg_rd[FIB_PROTOCOL_IP_MAX]
route-domain/IP-table ID the EPG is in
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:170
void gbp_endpoint_group_walk(gbp_endpoint_group_cb_t cb, void *ctx)