FD.io VPP  v21.06-3-gbb25fbf28
Vector Packet Processing
gbp_route_domain.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
18 
19 #include <vnet/dpo/dvr_dpo.h>
20 #include <vnet/fib/fib_table.h>
21 
22 /**
23  * A fixed MAC address to use as the source MAC for packets L3 switched
24  * onto the routed uu-fwd interfaces.
25  * Magic values - origin lost to the mists of time...
26  */
27 /* *INDENT-OFF* */
29  .bytes = {
30  0x0, 0x22, 0xBD, 0xF8, 0x19, 0xFF,
31  }
32 };
33 
35  .bytes = {
36  00, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
37  }
38 };
39 /* *INDENT-ON* */
40 
41 /**
42  * Pool of GBP route_domains
43  */
45 
46 /**
47  * DB of route_domains
48  */
49 typedef struct gbp_route_domain_db_t
50 {
53 
56 
57 /**
58  * logger
59  */
61 
62 #define GBP_BD_DBG(...) \
63  vlib_log_debug (grd_logger, __VA_ARGS__);
64 
65 index_t
67 {
68  return (grd - gbp_route_domain_pool);
69 }
70 
73 {
75 }
76 
77 static void
79 {
80  gbp_route_domain_t *grd;
81 
82  grd = gbp_route_domain_get (i);
83  grd->grd_locks++;
84 }
85 
86 index_t
88 {
89  uword *p;
90 
92 
93  if (NULL != p)
94  return p[0];
95 
96  return (INDEX_INVALID);
97 }
98 
99 index_t
101 {
102  index_t grdi;
103 
104  grdi = gbp_route_domain_find (rd_id);
105 
106  if (INDEX_INVALID != grdi)
107  {
108  gbp_route_domain_lock (grdi);
109  }
110  return (grdi);
111 }
112 
113 static void
115 {
116  index_t grdi = grd - gbp_route_domain_pool;
117 
119 }
120 
121 static void
123 {
125 }
126 
127 int
133 {
134  gbp_route_domain_t *grd;
135  index_t grdi;
136 
137  grdi = gbp_route_domain_find (rd_id);
138 
139  if (INDEX_INVALID == grdi)
140  {
141  fib_protocol_t fproto;
142 
144 
145  grd->grd_id = rd_id;
146  grd->grd_scope = scope;
151 
152  FOR_EACH_FIB_IP_PROTOCOL (fproto)
153  {
154  grd->grd_fib_index[fproto] =
156  grd->grd_table_id[fproto],
158 
159  if (~0 != grd->grd_uu_sw_if_index[fproto])
160  {
161  ethernet_header_t *eth;
162  u8 *rewrite;
163 
164  rewrite = NULL;
165  vec_validate (rewrite, sizeof (*eth) - 1);
166  eth = (ethernet_header_t *) rewrite;
167 
168  eth->type = clib_host_to_net_u16 ((fproto == FIB_PROTOCOL_IP4 ?
169  ETHERNET_TYPE_IP4 :
170  ETHERNET_TYPE_IP6));
171 
173  eth->src_address);
175  eth->dst_address);
176 
177  /*
178  * create an adjacency out of the uu-fwd interfaces that will
179  * be used when adding subnet routes.
180  */
181  grd->grd_adj[fproto] =
183  fib_proto_to_link (fproto),
185  grd->grd_uu_sw_if_index[fproto],
186  rewrite);
187  }
188  else
189  {
190  grd->grd_adj[fproto] = INDEX_INVALID;
191  }
192  }
193 
195  }
196  else
197  {
198  grd = gbp_route_domain_get (grdi);
199  }
200 
201  grd->grd_locks++;
202  GBP_BD_DBG ("add: %U", format_gbp_route_domain, grd);
203 
204  return (0);
205 }
206 
207 void
209 {
210  gbp_route_domain_t *grd;
211 
212  grd = gbp_route_domain_get (index);
213 
214  grd->grd_locks--;
215 
216  if (0 == grd->grd_locks)
217  {
218  fib_protocol_t fproto;
219 
220  GBP_BD_DBG ("destroy: %U", format_gbp_route_domain, grd);
221 
222  FOR_EACH_FIB_IP_PROTOCOL (fproto)
223  {
224  fib_table_unlock (grd->grd_fib_index[fproto], fproto, gbp_fib_source);
225  if (INDEX_INVALID != grd->grd_adj[fproto])
226  adj_unlock (grd->grd_adj[fproto]);
227  }
228 
230 
232  }
233 }
234 
235 u32
237 {
238  gbp_route_domain_t *grd;
239 
240  grd = gbp_route_domain_get (grdi);
241 
242  return (grd->grd_id);
243 }
244 
247 {
248  gbp_route_domain_t *grd;
249 
250  grd = gbp_route_domain_get (grdi);
251 
252  return (grd->grd_scope);
253 }
254 
255 int
257 {
258  index_t grdi;
259 
260  GBP_BD_DBG ("del: %d", rd_id);
261  grdi = gbp_route_domain_find (rd_id);
262 
263  if (INDEX_INVALID != grdi)
264  {
266  gbp_route_domain_get (grdi));
268 
269  return (0);
270  }
271 
272  return (VNET_API_ERROR_NO_SUCH_ENTRY);
273 }
274 
275 const mac_address_t *
277 {
278  return (&GBP_ROUTED_SRC_MAC);
279 }
280 
281 const mac_address_t *
283 {
284  return (&GBP_ROUTED_DST_MAC);
285 }
286 
287 void
289 {
290  gbp_route_domain_t *gbpe;
291 
292  /* *INDENT-OFF* */
294  {
295  if (!cb(gbpe, ctx))
296  break;
297  }
298  /* *INDENT-ON* */
299 }
300 
301 static clib_error_t *
303  unformat_input_t * input, vlib_cli_command_t * cmd)
304 {
305  vnet_main_t *vnm = vnet_get_main ();
306  u32 ip4_uu_sw_if_index = ~0;
307  u32 ip6_uu_sw_if_index = ~0;
308  u32 ip4_table_id = ~0;
309  u32 ip6_table_id = ~0;
310  u32 scope = ~0;
311  u32 rd_id = ~0;
312  u8 add = 1;
313 
315  {
316  if (unformat (input, "ip4-uu %U", unformat_vnet_sw_interface,
317  vnm, &ip4_uu_sw_if_index))
318  ;
319  else if (unformat (input, "ip6-uu %U", unformat_vnet_sw_interface,
320  vnm, &ip6_uu_sw_if_index))
321  ;
322  else if (unformat (input, "ip4-table-id %d", &ip4_table_id))
323  ;
324  else if (unformat (input, "ip6-table-id %d", &ip6_table_id))
325  ;
326  else if (unformat (input, "add"))
327  add = 1;
328  else if (unformat (input, "del"))
329  add = 0;
330  else if (unformat (input, "rd %d", &rd_id))
331  ;
332  else if (unformat (input, "scope %d", &scope))
333  ;
334  else
335  break;
336  }
337 
338  if (~0 == rd_id)
339  return clib_error_return (0, "RD-ID must be specified");
340 
341  if (add)
342  {
343  if (~0 == ip4_table_id)
344  return clib_error_return (0, "IP4 table-ID must be specified");
345  if (~0 == ip6_table_id)
346  return clib_error_return (0, "IP6 table-ID must be specified");
347 
349  ip4_table_id,
350  ip6_table_id,
352  }
353  else
355 
356  return (NULL);
357 }
358 
359 /*?
360  * Configure a GBP route-domain
361  *
362  * @cliexpar
363  * @cliexstart{gbp route-domain [del] rd <ID> ip4-table-id <ID> ip6-table-id <ID> [ip4-uu <interface>] [ip6-uu <interface>]}
364  * @cliexend
365  ?*/
366 /* *INDENT-OFF* */
368  .path = "gbp route-domain",
369  .short_help = "gbp route-domain [del] rd <ID> ip4-table-id <ID> ip6-table-id <ID> [ip4-uu <interface>] [ip6-uu <interface>]",
370  .function = gbp_route_domain_cli,
371 };
372 
373 u8 *
374 format_gbp_route_domain (u8 * s, va_list * args)
375 {
376  gbp_route_domain_t *grd = va_arg (*args, gbp_route_domain_t*);
377  vnet_main_t *vnm = vnet_get_main ();
378 
379  if (NULL != grd)
380  s = format (s, "[%d] rd:%d ip4-uu:%U ip6-uu:%U locks:%d",
381  grd - gbp_route_domain_pool,
382  grd->grd_id,
385  grd->grd_locks);
386  else
387  s = format (s, "NULL");
388 
389  return (s);
390 }
391 
392 static int
394 {
395  vlib_main_t *vm;
396 
397  vm = ctx;
399 
400  return (1);
401 }
402 
403 static clib_error_t *
405  unformat_input_t * input, vlib_cli_command_t * cmd)
406 {
407  vlib_cli_output (vm, "Route-Domains:");
409 
410  return (NULL);
411 }
412 
413 /*?
414  * Show Group Based Policy Route_Domains and derived information
415  *
416  * @cliexpar
417  * @cliexstart{show gbp route_domain}
418  * @cliexend
419  ?*/
420 /* *INDENT-OFF* */
422  .path = "show gbp route-domain",
423  .short_help = "show gbp route-domain\n",
424  .function = gbp_route_domain_show,
425 };
426 /* *INDENT-ON* */
427 
428 static clib_error_t *
430 {
431  grd_logger = vlib_log_register_class ("gbp", "rd");
435 
436  return (NULL);
437 }
438 
440 
441 /*
442  * fd.io coding-style-patch-verification: ON
443  *
444  * Local Variables:
445  * eval: (c-set-style "gnu")
446  * End:
447  */
ip6_uu_sw_if_index
vl_api_interface_index_t ip6_uu_sw_if_index
Definition: gbp.api:77
GBP_ROUTED_DST_MAC
const static mac_address_t GBP_ROUTED_DST_MAC
Definition: gbp_route_domain.c:34
gbp_route_domain_db_t::gbd_by_rd_id
uword * gbd_by_rd_id
Definition: gbp_route_domain.c:51
FOR_EACH_FIB_IP_PROTOCOL
#define FOR_EACH_FIB_IP_PROTOCOL(_item)
Definition: fib_types.h:69
gbp_route_domain_cli_node
static vlib_cli_command_t gbp_route_domain_cli_node
(constructor) VLIB_CLI_COMMAND (gbp_route_domain_cli_node)
Definition: gbp_route_domain.c:367
gpb_route_domain_t_::grd_fib_index
u32 grd_fib_index[FIB_PROTOCOL_IP_MAX]
Definition: gbp_route_domain.h:36
gbp_route_domain_index
index_t gbp_route_domain_index(const gbp_route_domain_t *grd)
Definition: gbp_route_domain.c:66
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
ethernet_header_t::dst_address
u8 dst_address[6]
Definition: packet.h:55
ethernet_header_t::src_address
u8 src_address[6]
Definition: packet.h:56
vlib_log_register_class
vlib_log_class_t vlib_log_register_class(char *class, char *subclass)
Definition: log.c:339
gbp_route_domain_walk
void gbp_route_domain_walk(gbp_route_domain_cb_t cb, void *ctx)
Definition: gbp_route_domain.c:288
clib_error_return
#define clib_error_return(e, args...)
Definition: error.h:99
vlib_cli_command_t::path
char * path
Definition: cli.h:96
dvr_dpo.h
adj_unlock
void adj_unlock(adj_index_t adj_index)
Release a reference counting lock on the adjacency.
Definition: adj.c:358
fib_table.h
ADJ_BCAST_ADDR
const ip46_address_t ADJ_BCAST_ADDR
The special broadcast address (to construct a broadcast adjacency.
Definition: adj.c:42
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
ethernet_header_t::type
u16 type
Definition: packet.h:59
vm
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
format_gbp_route_domain
u8 * format_gbp_route_domain(u8 *s, va_list *args)
Definition: gbp_route_domain.c:374
gpb_route_domain_t_::grd_id
u32 grd_id
Route-domain ID.
Definition: gbp_route_domain.h:34
GBP_BD_DBG
#define GBP_BD_DBG(...)
Definition: gbp_route_domain.c:62
unformat_input_t
struct _unformat_input_t unformat_input_t
gpb_route_domain_t_::grd_table_id
u32 grd_table_id[FIB_PROTOCOL_IP_MAX]
Definition: gbp_route_domain.h:37
gbp_route_domain_show_node
static vlib_cli_command_t gbp_route_domain_show_node
(constructor) VLIB_CLI_COMMAND (gbp_route_domain_show_node)
Definition: gbp_route_domain.c:421
gbp_route_domain_init
static clib_error_t * gbp_route_domain_init(vlib_main_t *vm)
Definition: gbp_route_domain.c:429
gbp_route_domain_pool
gbp_route_domain_t * gbp_route_domain_pool
Pool of GBP route_domains.
Definition: gbp_route_domain.c:44
gbp_route_domain_add_and_lock
int gbp_route_domain_add_and_lock(u32 rd_id, gbp_scope_t scope, u32 ip4_table_id, u32 ip6_table_id, u32 ip4_uu_sw_if_index, u32 ip6_uu_sw_if_index)
Definition: gbp_route_domain.c:128
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
FIB_SOURCE_BH_DROP
@ FIB_SOURCE_BH_DROP
If you're adding a new source from a plugin pick one of these.
Definition: fib_source.h:206
pool_foreach
#define pool_foreach(VAR, POOL)
Iterate through pool.
Definition: pool.h:534
grd_logger
vlib_log_class_t grd_logger
logger
Definition: gbp_route_domain.c:60
vnet_get_main
vnet_main_t * vnet_get_main(void)
Definition: pnat_test_stubs.h:56
fib_table_find_or_create_and_lock
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:1165
unformat_check_input
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:163
gpb_route_domain_t_::grd_uu_sw_if_index
u32 grd_uu_sw_if_index[FIB_PROTOCOL_IP_MAX]
The interfaces on which to send packets to unnknown EPs.
Definition: gbp_route_domain.h:42
adj_nbr_add_or_lock_w_rewrite
adj_index_t adj_nbr_add_or_lock_w_rewrite(fib_protocol_t nh_proto, vnet_link_t link_type, const ip46_address_t *nh_addr, u32 sw_if_index, u8 *rewrite)
Add (and lock) a new or lock an existing neighbour adjacency.
Definition: adj_nbr.c:303
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
uword
u64 uword
Definition: types.h:112
mac_address_to_bytes
static_always_inline void mac_address_to_bytes(const mac_address_t *mac, u8 *bytes)
Definition: mac_address.h:99
hash_get
#define hash_get(h, key)
Definition: hash.h:249
ethernet_header_t
Definition: packet.h:52
scope
vl_api_gbp_scope_t scope
Definition: gbp.api:78
i
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:261
fib_proto_to_link
vnet_link_t fib_proto_to_link(fib_protocol_t proto)
Convert from a protocol to a link type.
Definition: fib_types.c:377
vec_validate
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment)
Definition: vec.h:523
mac_address_t_::bytes
u8 bytes[6]
Definition: mac_address.h:25
VLIB_CLI_COMMAND
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:163
fib_protocol_t
enum fib_protocol_t_ fib_protocol_t
Protocol Type.
FIB_PROTOCOL_IP4
@ FIB_PROTOCOL_IP4
Definition: fib_types.h:36
gbp_fib_source
static fib_source_t gbp_fib_source
Definition: gbp_route_domain.c:55
ip4_uu_sw_if_index
vl_api_interface_index_t ip4_uu_sw_if_index
Definition: gbp.api:76
vlib_cli_output
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:716
fib_source_allocate
fib_source_t fib_source_allocate(const char *name, fib_source_priority_t prio, fib_source_behaviour_t bh)
Definition: fib_source.c:118
gbp_route_domain_get_scope
gbp_scope_t gbp_route_domain_get_scope(index_t grdi)
Definition: gbp_route_domain.c:246
FIB_SOURCE_PRIORITY_HI
#define FIB_SOURCE_PRIORITY_HI
Some priority values that plugins might use when they are not to concerned where in the list they'll ...
Definition: fib_source.h:284
gbp_route_domain_delete
int gbp_route_domain_delete(u32 rd_id)
Definition: gbp_route_domain.c:256
vnet_main_t
Definition: vnet.h:76
rd_id
u32 rd_id
Definition: gbp.api:35
index
u32 index
Definition: flow_types.api:221
gbp_route_domain_db
static gbp_route_domain_db_t gbp_route_domain_db
Definition: gbp_route_domain.c:54
gpb_route_domain_t_::grd_locks
u32 grd_locks
Definition: gbp_route_domain.h:49
gbp_route_domain_show
static clib_error_t * gbp_route_domain_show(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: gbp_route_domain.c:404
format_vnet_sw_if_index_name
format_function_t format_vnet_sw_if_index_name
Definition: interface_funcs.h:455
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_route_domain_cli
static clib_error_t * gbp_route_domain_cli(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: gbp_route_domain.c:302
u32
unsigned int u32
Definition: types.h:88
VLIB_INIT_FUNCTION
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:172
gbp_route_domain_db_add
static void gbp_route_domain_db_add(gbp_route_domain_t *grd)
Definition: gbp_route_domain.c:114
gbp_route_domain_lock
static void gbp_route_domain_lock(index_t i)
Definition: gbp_route_domain.c:78
gbp_route_domain_db_t
struct gbp_route_domain_db_t gbp_route_domain_db_t
DB of route_domains.
FIB_PROTOCOL_IP6
@ FIB_PROTOCOL_IP6
Definition: fib_types.h:37
ctx
long ctx[MAX_CONNS]
Definition: main.c:144
gpb_route_domain_t_::grd_scope
gbp_scope_t grd_scope
Definition: gbp_route_domain.h:35
ip6_table_id
u32 ip6_table_id
Definition: gbp.api:75
gbp_route_domain_get
gbp_route_domain_t * gbp_route_domain_get(index_t i)
Definition: gbp_route_domain.c:72
gbp_route_domain_db_t
DB of route_domains.
Definition: gbp_route_domain.c:49
gbp_route_domain_find_and_lock
index_t gbp_route_domain_find_and_lock(u32 rd_id)
Definition: gbp_route_domain.c:100
gbp_endpoint.h
mac_address_t_
Definition: mac_address.h:21
hash_unset
#define hash_unset(h, key)
Definition: hash.h:261
gpb_route_domain_t_::grd_adj
u32 grd_adj[FIB_PROTOCOL_IP_MAX]
adjacencies on the UU interfaces.
Definition: gbp_route_domain.h:47
vlib_main_t
Definition: main.h:102
gbp_route_domain_show_one
static int gbp_route_domain_show_one(gbp_route_domain_t *gb, void *ctx)
Definition: gbp_route_domain.c:393
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
vlib_init_function_t
clib_error_t *() vlib_init_function_t(struct vlib_main_t *vm)
Definition: init.h:51
fib_table_unlock
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:1336
ip4_table_id
u32 ip4_table_id
Definition: gbp.api:74
fib_source_t
enum fib_source_t_ fib_source_t
The different sources that can create a route.
gbp_route_domain.h
gbp_route_domain_db_remove
static void gbp_route_domain_db_remove(gbp_route_domain_t *grd)
Definition: gbp_route_domain.c:122
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
rewrite
rewrite
Definition: pnat.api:158
gbp_route_domain_get_remote_mac
const mac_address_t * gbp_route_domain_get_remote_mac(void)
Definition: gbp_route_domain.c:282
gbp_route_domain_find
index_t gbp_route_domain_find(u32 rd_id)
Definition: gbp_route_domain.c:87
GBP_ROUTED_SRC_MAC
const static mac_address_t GBP_ROUTED_SRC_MAC
A fixed MAC address to use as the source MAC for packets L3 switched onto the routed uu-fwd interface...
Definition: gbp_route_domain.c:28
gbp_scope_t
u16 gbp_scope_t
Definition: gbp_types.h:24
gbp_route_domain_cb_t
int(* gbp_route_domain_cb_t)(gbp_route_domain_t *gb, void *ctx)
Definition: gbp_route_domain.h:68
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_route_domain_get_rd_id
u32 gbp_route_domain_get_rd_id(index_t grdi)
Definition: gbp_route_domain.c:236
gbp_route_domain_get_local_mac
const mac_address_t * gbp_route_domain_get_local_mac(void)
Definition: gbp_route_domain.c:276