FD.io VPP  v18.07-rc0-415-g6c78436
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 
24 /**
25  * Pool of GBP endpoint_groups
26  */
28 
29 /**
30  * DB of endpoint_groups
31  */
33 
36 {
37  uword *p;
38 
39  p = hash_get (gbp_endpoint_group_db.gepg_hash, epg_id);
40 
41  if (NULL != p)
42  return (pool_elt_at_index (gbp_endpoint_group_pool, p[0]));
43 
44  return (NULL);
45 }
46 
47 int
49  u32 bd_id,
50  u32 ip4_table_id,
51  u32 ip6_table_id, u32 uplink_sw_if_index)
52 {
54 
55  gepg = gbp_endpoint_group_find (epg_id);
56 
57  if (NULL == gepg)
58  {
59  fib_protocol_t fproto;
60 
61  pool_get (gbp_endpoint_group_pool, gepg);
62  memset (gepg, 0, sizeof (*gepg));
63 
64  gepg->gepg_id = epg_id;
65  gepg->gepg_bd = bd_id;
66  gepg->gepg_rd[FIB_PROTOCOL_IP4] = ip4_table_id;
67  gepg->gepg_rd[FIB_PROTOCOL_IP6] = ip6_table_id;
68  gepg->gepg_uplink_sw_if_index = uplink_sw_if_index;
69 
70  /*
71  * an egress DVR dpo for internal subnets to use when sending
72  * on the uplink interface
73  */
75  {
76  gepg->gepg_fib_index[fproto] =
78  gepg->gepg_rd[fproto],
80 
81  if (~0 == gepg->gepg_fib_index[fproto])
82  {
83  return (VNET_API_ERROR_NO_SUCH_FIB);
84  }
85 
86  dvr_dpo_add_or_lock (uplink_sw_if_index,
87  fib_proto_to_dpo (fproto),
88  &gepg->gepg_dpo[fproto]);
89  }
90 
91  /*
92  * packets direct from the uplink have had policy applied
93  */
95  L2INPUT_FEAT_GBP_NULL_CLASSIFY, 1);
96 
97  hash_set (gbp_endpoint_group_db.gepg_hash,
98  gepg->gepg_id, gepg - gbp_endpoint_group_pool);
99 
100  }
101 
102  return (0);
103 }
104 
105 void
107 {
108  gbp_endpoint_group_t *gepg;
109  uword *p;
110 
111  p = hash_get (gbp_endpoint_group_db.gepg_hash, epg_id);
112 
113  if (NULL != p)
114  {
115  fib_protocol_t fproto;
116 
117  gepg = pool_elt_at_index (gbp_endpoint_group_pool, p[0]);
118 
120  L2INPUT_FEAT_GBP_NULL_CLASSIFY, 0);
121 
122  FOR_EACH_FIB_IP_PROTOCOL (fproto)
123  {
124  dpo_reset (&gepg->gepg_dpo[fproto]);
125  fib_table_unlock (gepg->gepg_fib_index[fproto],
126  fproto, FIB_SOURCE_PLUGIN_HI);
127  }
128 
129  hash_unset (gbp_endpoint_group_db.gepg_hash, epg_id);
130 
131  pool_put (gbp_endpoint_group_pool, gepg);
132  }
133 }
134 
135 void
137 {
138  gbp_endpoint_group_t *gbpe;
139 
140  /* *INDENT-OFF* */
141  pool_foreach(gbpe, gbp_endpoint_group_pool,
142  {
143  if (!cb(gbpe, ctx))
144  break;
145  });
146  /* *INDENT-ON* */
147 }
148 
149 static clib_error_t *
151  unformat_input_t * input, vlib_cli_command_t * cmd)
152 {
153  vnet_main_t *vnm = vnet_get_main ();
154  epg_id_t epg_id = EPG_INVALID;
155  u32 uplink_sw_if_index = ~0;
156  u32 bd_id = ~0;
157  u32 rd_id = ~0;
158  u8 add = 1;
159 
161  {
162  if (unformat (input, "%U", unformat_vnet_sw_interface,
163  vnm, &uplink_sw_if_index))
164  ;
165  else if (unformat (input, "add"))
166  add = 1;
167  else if (unformat (input, "del"))
168  add = 0;
169  else if (unformat (input, "epg %d", &epg_id))
170  ;
171  else if (unformat (input, "bd %d", &bd_id))
172  ;
173  else if (unformat (input, "rd %d", &rd_id))
174  ;
175  else
176  break;
177  }
178 
179  if (EPG_INVALID == epg_id)
180  return clib_error_return (0, "EPG-ID must be specified");
181 
182  if (add)
183  {
184  if (~0 == uplink_sw_if_index)
185  return clib_error_return (0, "interface must be specified");
186  if (~0 == bd_id)
187  return clib_error_return (0, "Bridge-domain must be specified");
188  if (~0 == rd_id)
189  return clib_error_return (0, "route-domain must be specified");
190 
191  gbp_endpoint_group_add (epg_id, bd_id, rd_id, rd_id,
192  uplink_sw_if_index);
193  }
194  else
195  gbp_endpoint_group_delete (epg_id);
196 
197  return (NULL);
198 }
199 
200 /*?
201  * Configure a GBP Endpoint Group
202  *
203  * @cliexpar
204  * @cliexstart{set gbp endpoint-group [del] epg <ID> bd <ID> <interface>}
205  * @cliexend
206  ?*/
207 /* *INDENT-OFF* */
208 VLIB_CLI_COMMAND (gbp_endpoint_group_cli_node, static) = {
209  .path = "gbp endpoint-group",
210  .short_help = "gbp endpoint-group [del] epg <ID> bd <ID> <interface>",
211  .function = gbp_endpoint_group_cli,
212 };
213 
214 static int
216 {
217  vnet_main_t *vnm = vnet_get_main ();
218  vlib_main_t *vm;
219 
220  vm = ctx;
221  vlib_cli_output (vm, " %d, bd:%d, ip4:%d ip6:%d uplink:%U",
222  gepg->gepg_id,
223  gepg->gepg_bd,
224  gepg->gepg_rd[FIB_PROTOCOL_IP4],
225  gepg->gepg_rd[FIB_PROTOCOL_IP6],
227 
228  return (1);
229 }
230 
231 static clib_error_t *
233  unformat_input_t * input, vlib_cli_command_t * cmd)
234 {
235  vlib_cli_output (vm, "Endpoint-Groups:");
237 
238  return (NULL);
239 }
240 
241 
242 /*?
243  * Show Group Based Policy Endpoint_Groups and derived information
244  *
245  * @cliexpar
246  * @cliexstart{show gbp endpoint_group}
247  * @cliexend
248  ?*/
249 /* *INDENT-OFF* */
250 VLIB_CLI_COMMAND (gbp_endpoint_group_show_node, static) = {
251  .path = "show gbp endpoint-group",
252  .short_help = "show gbp endpoint-group\n",
253  .function = gbp_endpoint_group_show,
254 };
255 /* *INDENT-ON* */
256 
257 /*
258  * fd.io coding-style-patch-verification: ON
259  *
260  * Local Variables:
261  * eval: (c-set-style "gnu")
262  * End:
263  */
EPG DB, key&#39;d on EGP-ID.
#define hash_set(h, key, value)
Definition: hash.h:255
#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:55
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:227
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.
u32 gepg_fib_index[FIB_PROTOCOL_IP_MAX]
resulting FIB indices
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:440
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
u32 epg_id_t
Definition: gbp_types.h:21
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:461
static int gbp_endpoint_group_show_one(gbp_endpoint_group_t *gepg, void *ctx)
struct _unformat_input_t unformat_input_t
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:273
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:1228
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:143
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:154
long ctx[MAX_CONNS]
Definition: main.c:126
#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:1115
dpo_proto_t fib_proto_to_dpo(fib_protocol_t fib_proto)
Definition: fib_types.c:236
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:681
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:169
void gbp_endpoint_group_walk(gbp_endpoint_group_cb_t cb, void *ctx)