FD.io VPP  v18.10-34-gcce845e
Vector Packet Processing
gbp_endpoint.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 
22 #include <vnet/l2/l2_input.h>
23 #include <vnet/l2/l2_output.h>
24 #include <vnet/l2/feat_bitmap.h>
25 
29 
30 /**
31  * Pool of GBP endpoints
32  */
34 
35 /* void */
36 /* gbp_itf_epg_update (u32 sw_if_index, epg_id_t src_epg, u8 do_policy) */
37 /* { */
38 /* vec_validate_init_empty (gbp_itf_to_epg_db.gte_vec, */
39 /* sw_if_index, ITF_INVALID); */
40 
41 /* if (0 == gbp_itf_to_epg_db.gte_vec[sw_if_index].gi_ref_count) */
42 /* { */
43 /* l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_GBP_SRC_CLASSIFY, */
44 /* 1); */
45 /* l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_GBP_FWD, 1); */
46 /* if (do_policy) */
47 /* l2output_intf_bitmap_enable (sw_if_index, L2OUTPUT_FEAT_GBP_POLICY, */
48 /* 1); */
49 /* } */
50 /* gbp_itf_to_epg_db.gte_vec[sw_if_index].gi_epg = src_epg; */
51 /* gbp_itf_to_epg_db.gte_vec[sw_if_index].gi_ref_count++; */
52 /* } */
53 
54 /* void */
55 /* gbp_itf_epg_delete (u32 sw_if_index) */
56 /* { */
57 /* if (vec_len (gbp_itf_to_epg_db.gte_vec) <= sw_if_index) */
58 /* return; */
59 
60 /* if (1 == gbp_itf_to_epg_db.gte_vec[sw_if_index].gi_ref_count) */
61 /* { */
62 /* gbp_itf_to_epg_db.gte_vec[sw_if_index].gi_epg = EPG_INVALID; */
63 
64 /* l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_GBP_SRC_CLASSIFY, */
65 /* 0); */
66 /* l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_GBP_FWD, 0); */
67 /* l2output_intf_bitmap_enable (sw_if_index, L2OUTPUT_FEAT_GBP_POLICY, 0); */
68 /* } */
69 /* gbp_itf_to_epg_db.gte_vec[sw_if_index].gi_ref_count--; */
70 /* } */
71 
72 static void
75 {
76  key->key[0] = mac_address_as_u64 (mac);
77  key->key[1] = sw_if_index;
78 }
79 
80 static void
83 {
84  mac_address_from_u64 (key->key[0], mac);
85  *sw_if_index = key->key[1];
86 }
87 
90 {
91  clib_bihash_kv_16_8_t key, value;
92  int rv;
93 
94  gbp_endpoint_mk_key_mac_itf (mac, sw_if_index, &key);
95 
96  rv =
97  clib_bihash_search_16_8 (&gbp_ep_by_mac_itf_db.gte_table, &key, &value);
98 
99  if (0 != rv)
100  return NULL;
101 
102  return (gbp_endpoint_get (value.value));
103 }
104 
105 static void
106 gbp_endpoint_mk_key_ip_itf (const ip46_address_t * ip,
108 {
109  key->key[0] = ip->as_u64[0];
110  key->key[1] = ip->as_u64[1];
111  key->key[2] = sw_if_index;
112 }
113 
114 static void
116  ip46_address_t * ip, u32 * sw_if_index)
117 {
118  ip->as_u64[0] = key->key[0];
119  ip->as_u64[1] = key->key[1];
120  *sw_if_index = key->key[2];
121 }
122 
124 gbp_endpoint_find_ip_itf (const ip46_address_t * ip, u32 sw_if_index)
125 {
126  clib_bihash_kv_24_8_t key, value;
127  int rv;
128 
129  gbp_endpoint_mk_key_ip_itf (ip, sw_if_index, &key);
130 
131  rv = clib_bihash_search_24_8 (&gbp_ep_by_ip_itf_db.gte_table, &key, &value);
132 
133  if (0 != rv)
134  return NULL;
135 
136  return (gbp_endpoint_get (value.value));
137 }
138 
141 {
142  /* if (vec_len(gbp_ep_by_itf_db.gte_vec) >= sw_if_index) */
143  /* return NULL; */
144 
145  /* vec_search(gbp_ep_by_itf_db.gte_vec[sw_if_index], */
146  /* return (gbp_endpoint_get(gbp_ep_by_itf_db.gte_vec[sw_if_index][0])); */
147  return (NULL);
148 }
149 
150 static bool
152  u32 sw_if_index, index_t gbpei)
153 {
155  int rv;
156 
157  gbp_endpoint_mk_key_mac_itf (mac, sw_if_index, &key);
158  key.value = gbpei;
159 
160  rv = clib_bihash_add_del_16_8 (&gbp_ep_by_mac_itf_db.gte_table, &key, 1);
161 
162  return (0 == rv);
163 }
164 
165 static bool
166 gbp_endpoint_add_ip_itf (const ip46_address_t * ip,
167  u32 sw_if_index, index_t gbpei)
168 {
170  int rv;
171 
172  gbp_endpoint_mk_key_ip_itf (ip, sw_if_index, &key);
173  key.value = gbpei;
174 
175  rv = clib_bihash_add_del_24_8 (&gbp_ep_by_ip_itf_db.gte_table, &key, 1);
176 
177  return (0 == rv);
178 }
179 
180 static void
182 {
183  vec_validate_init_empty (gbp_ep_by_itf_db.gte_vec, sw_if_index,
184  INDEX_INVALID);
185 
186  if (INDEX_INVALID == gbp_ep_by_itf_db.gte_vec[sw_if_index])
187  {
188  l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_GBP_SRC_CLASSIFY,
189  1);
190  l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_GBP_FWD, 1);
191  l2output_intf_bitmap_enable (sw_if_index, L2OUTPUT_FEAT_GBP_POLICY, 1);
192  }
193  gbp_ep_by_itf_db.gte_vec[sw_if_index] = gbpei;
194 }
195 
196 static void
198 {
200 
201  gbp_endpoint_mk_key_mac_itf (mac, sw_if_index, &key);
202 
203  clib_bihash_add_del_16_8 (&gbp_ep_by_mac_itf_db.gte_table, &key, 0);
204 }
205 
206 static void
207 gbp_endpoint_del_ip_itf (const ip46_address_t * ip, u32 sw_if_index)
208 {
210 
211  gbp_endpoint_mk_key_ip_itf (ip, sw_if_index, &key);
212 
213  clib_bihash_add_del_24_8 (&gbp_ep_by_ip_itf_db.gte_table, &key, 0);
214 }
215 
216 static void
218 {
219  if (vec_len (gbp_ep_by_itf_db.gte_vec) <= sw_if_index)
220  return;
221 
222  l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_GBP_SRC_CLASSIFY, 0);
223  l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_GBP_FWD, 0);
224  l2output_intf_bitmap_enable (sw_if_index, L2OUTPUT_FEAT_GBP_POLICY, 0);
225 
226  gbp_ep_by_itf_db.gte_vec[sw_if_index] = INDEX_INVALID;
227 }
228 
229 static index_t
231 {
232  return (gbpe - gbp_endpoint_pool);
233 }
234 
235 int
237  const ip46_address_t * ips,
238  const mac_address_t * mac, epg_id_t epg_id, u32 * handle)
239 {
240  gbp_endpoint_group_t *gepg;
241  const ip46_address_t *ip;
242  gbp_endpoint_t *gbpe;
243 
244  gbpe = NULL;
245  gepg = gbp_endpoint_group_find (epg_id);
246 
247  if (NULL == gepg)
248  return (VNET_API_ERROR_NO_SUCH_ENTRY);
249 
250  /*
251  * find an existing endpoint matching one of the key types
252  */
253  if (NULL != mac)
254  {
255  gbpe = gbp_endpoint_find_mac_itf (mac, sw_if_index);
256  }
257  if (NULL == gbpe && NULL != ips)
258  {
259  vec_foreach (ip, ips)
260  {
261  gbpe = gbp_endpoint_find_ip_itf (ip, sw_if_index);
262 
263  if (NULL != gbpe)
264  break;
265  }
266  }
267  if (NULL == gbpe)
268  {
269  gbpe = gbp_endpoint_find_itf (sw_if_index);
270  }
271 
272  if (NULL == gbpe)
273  {
274  index_t gbpei;
275  u32 ii;
276  /*
277  * new entry
278  */
279  pool_get (gbp_endpoint_pool, gbpe);
280  gbpei = gbp_endpoint_index (gbpe);
281 
282  gbpe->ge_epg_id = epg_id;
283  gbpe->ge_sw_if_index = sw_if_index;
284  gbp_endpoint_add_itf (gbpe->ge_sw_if_index, gbpei);
285 
286  if (NULL != mac)
287  {
288  gbpe->ge_mac = *mac;
289 
290  // FIXME ERROR
291  gbp_endpoint_add_mac_itf (mac, sw_if_index, gbpei);
292  }
293 
294  if (NULL != ips)
295  {
296  vec_validate (gbpe->ge_ips, vec_len (ips) - 1);
297  vec_foreach_index (ii, ips)
298  {
299  ip46_address_copy (&gbpe->ge_ips[ii], &ips[ii]);
300 
301  // FIXME ERROR
302  gbp_endpoint_add_ip_itf (&ips[ii], sw_if_index, gbpei);
303 
304  /*
305  * send a gratuitous ARP on the EPG's uplink. this is done so
306  * that if this EP has moved from some other place in the
307  * 'fabric', upstream devices are informed
308  */
309  if (ip46_address_is_ip4 (&ips[ii]))
311  &ips[ii].ip4,
313  else
315  &ips[ii].ip6,
317  }
318  }
319  }
320  else
321  {
322  /*
323  * update existing entry..
324  */
325  ASSERT (0);
326  }
327 
328  *handle = (gbpe - gbp_endpoint_pool);
329 
330  return (0);
331 }
332 
333 void
335 {
336  gbp_endpoint_t *gbpe;
337 
338  if (pool_is_free_index (gbp_endpoint_pool, handle))
339  return;
340 
341  gbpe = pool_elt_at_index (gbp_endpoint_pool, handle);
342 
344 
345  if (!mac_address_is_zero (&gbpe->ge_mac))
346  {
348  }
349 
350  if (NULL != gbpe->ge_ips)
351  {
352  const ip46_address_t *ip;
353 
354  vec_foreach (ip, gbpe->ge_ips)
355  {
357  }
358  }
359  pool_put (gbp_endpoint_pool, gbpe);
360 }
361 
362 void
364 {
365  gbp_endpoint_t *gbpe;
366 
367  /* *INDENT-OFF* */
368  pool_foreach(gbpe, gbp_endpoint_pool,
369  {
370  if (!cb(gbpe, ctx))
371  break;
372  });
373  /* *INDENT-ON* */
374 }
375 
376 static clib_error_t *
378  unformat_input_t * input, vlib_cli_command_t * cmd)
379 {
380  ip46_address_t ip = ip46_address_initializer, *ips = NULL;
382  vnet_main_t *vnm = vnet_get_main ();
384  u32 handle = INDEX_INVALID;
385  u32 sw_if_index = ~0;
386  u8 add = 1;
387  int rv;
388 
390  {
391  ip46_address_reset (&ip);
392 
393  if (unformat (input, "%U", unformat_vnet_sw_interface,
394  vnm, &sw_if_index))
395  ;
396  else if (unformat (input, "add"))
397  add = 1;
398  else if (unformat (input, "del"))
399  add = 0;
400  else if (unformat (input, "epg %d", &epg_id))
401  ;
402  else if (unformat (input, "handle %d", &handle))
403  ;
404  else if (unformat (input, "ip %U", unformat_ip4_address, &ip.ip4))
405  vec_add1 (ips, ip);
406  else if (unformat (input, "ip %U", unformat_ip6_address, &ip.ip6))
407  vec_add1 (ips, ip);
408  else if (unformat (input, "mac %U", unformat_mac_address, &mac))
409  ;
410  else
411  break;
412  }
413 
414  if (add)
415  {
416  if (~0 == sw_if_index)
417  return clib_error_return (0, "interface must be specified");
418  if (EPG_INVALID == epg_id)
419  return clib_error_return (0, "EPG-ID must be specified");
420 
421  rv = gbp_endpoint_update (sw_if_index, ips, &mac, epg_id, &handle);
422 
423  if (rv)
424  return clib_error_return (0, "GBP Endpoint update returned %d", rv);
425  else
426  vlib_cli_output (vm, "handle %d\n", handle);
427  }
428  else
429  {
430  if (INDEX_INVALID == handle)
431  return clib_error_return (0, "handle must be specified");
432 
433  gbp_endpoint_delete (handle);
434  }
435 
436  vec_free (ips);
437 
438  return (NULL);
439 }
440 
441 
442 /*?
443  * Configure a GBP Endpoint
444  *
445  * @cliexpar
446  * @cliexstart{set gbp endpoint [del] <interface> epg <ID> ip <IP>}
447  * @cliexend
448  ?*/
449 /* *INDENT-OFF* */
450 VLIB_CLI_COMMAND (gbp_endpoint_cli_node, static) = {
451  .path = "gbp endpoint",
452  .short_help = "gbp endpoint [del] <interface> epg <ID> ip <IP> mac <MAC>",
453  .function = gbp_endpoint_cli,
454 };
455 /* *INDENT-ON* */
456 
457 u8 *
458 format_gbp_endpoint (u8 * s, va_list * args)
459 {
460  index_t gbpei = va_arg (*args, index_t);
461  vnet_main_t *vnm = vnet_get_main ();
462  const ip46_address_t *ip;
463  gbp_endpoint_t *gbpe;
464 
465  gbpe = gbp_endpoint_get (gbpei);
466 
467  s = format (s, "[@%d] ", gbpei);
468  s =
469  format (s, "%U", format_vnet_sw_if_index_name, vnm, gbpe->ge_sw_if_index);
470  s = format (s, ", IPs:[");
471 
472  vec_foreach (ip, gbpe->ge_ips)
473  {
474  s = format (s, "%U, ", format_ip46_address, ip, IP46_TYPE_ANY);
475  }
476  s = format (s, "]");
477 
478  s = format (s, " MAC:%U", format_mac_address_t, &gbpe->ge_mac);
479  s = format (s, " EPG-ID:%d", gbpe->ge_epg_id);
480 
481  return s;
482 }
483 
484 static walk_rc_t
486 {
487  vlib_main_t *vm;
488 
489  vm = ctx;
491 
492  return (WALK_CONTINUE);
493 }
494 
495 static void
497 {
498  ip46_address_t ip;
499  vlib_main_t *vm;
501 
502  vm = arg;
503 
504  gbp_endpoint_extract_key_ip_itf (kvp, &ip, &sw_if_index);
505 
506  vlib_cli_output (vm, " {%U, %U} -> %d",
509  sw_if_index, kvp->value);
510 }
511 
512 static void
514 {
516  vlib_main_t *vm;
518 
519  vm = arg;
520 
521  gbp_endpoint_extract_key_mac_itf (kvp, &mac, &sw_if_index);
522 
523  vlib_cli_output (vm, " {%U, %U} -> %d",
524  format_mac_address_t, &mac,
526  sw_if_index, kvp->value);
527 }
528 
529 static clib_error_t *
531  unformat_input_t * input, vlib_cli_command_t * cmd)
532 {
533  u32 sw_if_index, show_dbs, handle;
534 
535  handle = INDEX_INVALID;
536  show_dbs = 0;
537 
539  {
540  if (unformat (input, "%d", &handle))
541  ;
542  else if (unformat (input, "db", &handle))
543  show_dbs = 1;
544  else
545  break;
546  }
547 
548  if (INDEX_INVALID != handle)
549  {
550  vlib_cli_output (vm, "%U", format_gbp_endpoint, handle);
551  }
552  else if (show_dbs)
553  {
554  vlib_cli_output (vm, "\nDatabases:");
555  clib_bihash_foreach_key_value_pair_24_8 (&gbp_ep_by_ip_itf_db.gte_table,
557  clib_bihash_foreach_key_value_pair_16_8
558  (&gbp_ep_by_mac_itf_db.gte_table, gbp_endpoint_walk_mac_itf, vm);
559 
560  vec_foreach_index (sw_if_index, gbp_ep_by_itf_db.gte_vec)
561  {
562  if (INDEX_INVALID != gbp_ep_by_itf_db.gte_vec[sw_if_index])
563  vlib_cli_output (vm, " {%U} -> %d",
565  sw_if_index,
566  gbp_ep_by_itf_db.gte_vec[sw_if_index]);
567  }
568  }
569  else
570  {
571  vlib_cli_output (vm, "Endpoints:");
573  }
574 
575  return (NULL);
576 }
577 
578 /*?
579  * Show Group Based Policy Endpoints and derived information
580  *
581  * @cliexpar
582  * @cliexstart{show gbp endpoint}
583  * @cliexend
584  ?*/
585 /* *INDENT-OFF* */
586 VLIB_CLI_COMMAND (gbp_endpoint_show_node, static) = {
587  .path = "show gbp endpoint",
588  .short_help = "show gbp endpoint\n",
589  .function = gbp_endpoint_show,
590 };
591 /* *INDENT-ON* */
592 
593 #define GBP_EP_HASH_NUM_BUCKETS (2 * 1024)
594 #define GBP_EP_HASH_MEMORY_SIZE (1 << 20)
595 
596 static clib_error_t *
598 {
599  clib_bihash_init_24_8 (&gbp_ep_by_ip_itf_db.gte_table,
600  "GBP Endpoints - IP/Interface",
602 
603  clib_bihash_init_16_8 (&gbp_ep_by_mac_itf_db.gte_table,
604  "GBP Endpoints - MAC/Interface",
606 
607  return (NULL);
608 }
609 
611 
612 /*
613  * fd.io coding-style-patch-verification: ON
614  *
615  * Local Variables:
616  * eval: (c-set-style "gnu")
617  * End:
618  */
u32 ge_sw_if_index
The interface on which the EP is connected.
Definition: gbp_endpoint.h:51
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:437
static bool gbp_endpoint_add_mac_itf(const mac_address_t *mac, u32 sw_if_index, index_t gbpei)
Definition: gbp_endpoint.c:151
static void gbp_endpoint_mk_key_mac_itf(const mac_address_t *mac, u32 sw_if_index, clib_bihash_kv_16_8_t *key)
Definition: gbp_endpoint.c:73
#define vec_foreach_index(var, v)
Iterate over vector indices.
u16 epg_id_t
Definition: gbp_types.h:21
static gbp_endpoint_t * gbp_endpoint_get(index_t gbpei)
Get the endpoint from a port/interface.
Definition: gbp_endpoint.h:116
A Group Based Policy Endpoint.
Definition: gbp_endpoint.h:46
gbp_endpoint_t * gbp_endpoint_find_itf(u32 sw_if_index)
Definition: gbp_endpoint.c:140
#define GBP_EP_HASH_NUM_BUCKETS
Definition: gbp_endpoint.c:593
vnet_main_t * vnet_get_main(void)
Definition: misc.c:47
static void gbp_endpoint_walk_mac_itf(const clib_bihash_kv_16_8_t *kvp, void *arg)
Definition: gbp_endpoint.c:513
static void gbp_endpoint_walk_ip_itf(const clib_bihash_kv_24_8_t *kvp, void *arg)
Definition: gbp_endpoint.c:496
#define NULL
Definition: clib.h:57
void gbp_endpoint_delete(u32 handle)
Definition: gbp_endpoint.c:334
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:41
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:523
mac_address_t ge_mac
MAC address of the endpoint.
Definition: gbp_endpoint.h:61
format_function_t format_ip46_address
Definition: format.h:61
static_always_inline int mac_address_is_zero(const mac_address_t *mac)
Definition: mac_address.h:35
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
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 walk_rc_t_ walk_rc_t
Walk return code.
gbp_endpoint_t * gbp_endpoint_pool
Pool of GBP endpoints.
Definition: gbp_endpoint.c:33
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:443
unformat_function_t unformat_ip4_address
Definition: format.h:70
clib_bihash_24_8_t gte_table
Definition: gbp_endpoint.h:86
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:163
u32 sw_if_index
Definition: vxlan_gbp.api:39
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
static void gbp_endpoint_extract_key_ip_itf(const clib_bihash_kv_24_8_t *key, ip46_address_t *ip, u32 *sw_if_index)
Definition: gbp_endpoint.c:115
void l2output_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_output.c:615
static void gbp_endpoint_add_itf(u32 sw_if_index, index_t gbpei)
Definition: gbp_endpoint.c:181
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:464
static walk_rc_t gbp_endpoint_show_one(gbp_endpoint_t *gbpe, void *ctx)
Definition: gbp_endpoint.c:485
long ctx[MAX_CONNS]
Definition: main.c:144
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
gbp_ep_by_mac_itf_db_t gbp_ep_by_mac_itf_db
Definition: gbp_endpoint.c:27
gbp_ep_by_itf_db_t gbp_ep_by_itf_db
DP functions and databases.
Definition: gbp_endpoint.c:26
clib_bihash_16_8_t gte_table
Definition: gbp_endpoint.h:91
static void gbp_endpoint_del_ip_itf(const ip46_address_t *ip, u32 sw_if_index)
Definition: gbp_endpoint.c:207
An Endpoint Group representation.
#define ip46_address_initializer
Definition: ip6_packet.h:96
gbp_endpoint_t * gbp_endpoint_find_ip_itf(const ip46_address_t *ip, u32 sw_if_index)
Definition: gbp_endpoint.c:124
Interface to source EPG DB - a per-interface vector.
Definition: gbp_endpoint.h:79
#define ip46_address_is_ip4(ip46)
Definition: ip6_packet.h:88
unformat_function_t unformat_ip6_address
Definition: format.h:91
static void gbp_endpoint_del_itf(u32 sw_if_index)
Definition: gbp_endpoint.c:217
#define UNFORMAT_END_OF_INPUT
Definition: format.h:144
vlib_main_t * vm
Definition: buffer.c:294
void gbp_endpoint_walk(gbp_endpoint_cb_t cb, void *ctx)
Definition: gbp_endpoint.c:363
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:339
static_always_inline void mac_address_from_u64(u64 u, mac_address_t *mac)
Definition: mac_address.h:47
ip46_address_t * ge_ips
A vector of ip addresses that below to the endpoint.
Definition: gbp_endpoint.h:56
int gbp_endpoint_update(u32 sw_if_index, const ip46_address_t *ips, const mac_address_t *mac, epg_id_t epg_id, u32 *handle)
Definition: gbp_endpoint.c:236
void send_ip6_na_w_addr(vlib_main_t *vm, const ip6_address_t *addr, u32 sw_if_index)
static_always_inline void ip46_address_copy(ip46_address_t *dst, const ip46_address_t *src)
Definition: ip6_packet.h:99
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:271
uword unformat_mac_address(unformat_input_t *input, va_list *args)
Definition: format.c:241
static clib_error_t * gbp_endpoint_init(vlib_main_t *vm)
Definition: gbp_endpoint.c:597
walk_rc_t(* gbp_endpoint_cb_t)(gbp_endpoint_t *gbpe, void *ctx)
Definition: gbp_endpoint.h:100
void send_ip4_garp_w_addr(vlib_main_t *vm, const ip4_address_t *ip4_addr, u32 sw_if_index)
Definition: arp.c:2557
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:155
static void gbp_endpoint_del_mac_itf(const mac_address_t *mac, u32 sw_if_index)
Definition: gbp_endpoint.c:197
#define ASSERT(truth)
u8 * format_gbp_endpoint(u8 *s, va_list *args)
Definition: gbp_endpoint.c:458
const mac_address_t ZERO_MAC_ADDRESS
Definition: mac_address.c:18
#define EPG_INVALID
Definition: gbp_types.h:22
u32 gepg_uplink_sw_if_index
the uplink interface dedicated to the EPG
gbp_endpoint_t * gbp_endpoint_find_mac_itf(const mac_address_t *mac, u32 sw_if_index)
Definition: gbp_endpoint.c:89
static clib_error_t * gbp_endpoint_show(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: gbp_endpoint.c:530
static void gbp_endpoint_mk_key_ip_itf(const ip46_address_t *ip, u32 sw_if_index, clib_bihash_kv_24_8_t *key)
Definition: gbp_endpoint.c:106
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
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
#define ip46_address_reset(ip46)
Definition: ip6_packet.h:91
gbp_ep_by_ip_itf_db_t gbp_ep_by_ip_itf_db
Definition: gbp_endpoint.c:28
static_always_inline u64 mac_address_as_u64(const mac_address_t *mac)
Definition: mac_address.h:41
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
epg_id_t ge_epg_id
The endpoint&#39;s designated EPG.
Definition: gbp_endpoint.h:66
#define INDEX_INVALID
Invalid index - used when no index is known blazoned capitals INVALID speak volumes where ~0 does not...
Definition: dpo.h:47
u8 * format_mac_address_t(u8 *s, va_list *args)
Definition: mac_address.c:25
static bool gbp_endpoint_add_ip_itf(const ip46_address_t *ip, u32 sw_if_index, index_t gbpei)
Definition: gbp_endpoint.c:166
static index_t gbp_endpoint_index(const gbp_endpoint_t *gbpe)
Definition: gbp_endpoint.c:230
vl_api_address_t ips[n_ips]
Definition: gbp.api:33
#define vec_foreach(var, vec)
Vector iterator.
static void gbp_endpoint_extract_key_mac_itf(const clib_bihash_kv_16_8_t *key, mac_address_t *mac, u32 *sw_if_index)
Definition: gbp_endpoint.c:81
#define vec_validate_init_empty(V, I, INIT)
Make sure vector is long enough for given index and initialize empty space (no header, unspecified alignment)
Definition: vec.h:486
vl_api_mac_address_t mac
Definition: gbp.api:31
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:725
#define GBP_EP_HASH_MEMORY_SIZE
Definition: gbp_endpoint.c:594
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
static clib_error_t * gbp_endpoint_cli(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: gbp_endpoint.c:377
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:170