FD.io VPP  v18.04-17-g3a0d853
Vector Packet Processing
gbp.c
Go to the documentation of this file.
1 /*
2  * gbp.h : Group Based Policy
3  *
4  * Copyright (c) 2013 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 
18 #include <plugins/gbp/gbp.h>
19 
20 /**
21  * IP4 destintion address to destination EPG mapping table
22  */
23 typedef struct gbp_ip4_to_epg_db_t_
24 {
25  /**
26  * use a simple hash table
27  */
30 
32 
33 /**
34  * IP6 destintion address to destination EPG mapping table
35  */
36 typedef struct gbp_ip6_to_epg_db_t_
37 {
38  /**
39  * use a memroy hash table
40  */
43 
45 
46 /**
47  * Result of a interface to EPG mapping.
48  * multiple Endpoints can occur on the same interface, so this
49  * mapping needs to be reference counted.
50  */
51 typedef struct gbp_itf_t_
52 {
55 } gbp_itf_t;
56 
57 const static gbp_itf_t ITF_INVALID = {
59  .gi_ref_count = 0,
60 };
61 
62 /**
63  * Interface to source EPG DB - a per-interface vector
64  */
65 typedef struct gbp_itf_to_epg_db_t_
66 {
69 
71 
72 /**
73  * Pool of GBP endpoints
74  */
76 
77 /**
78  * DB of endpoints
79  */
81 
82 /**
83  * EPG src,dst pair to ACL mapping table, aka contract DB
84  */
85 typedef struct gbp_contract_db_t_
86 {
87  /**
88  * We can form a u64 key from the pair, so use a simple hash table
89  */
92 
93 /**
94  * Since contract DB instance
95  */
97 
98 static void
99 gbp_ip_epg_update (const ip46_address_t * ip, epg_id_t epg_id)
100 {
101  /*
102  * we are dealing only with addresses here so this limited
103  * is_ip4 check is ok
104  */
105  if (ip46_address_is_ip4 (ip))
106  {
107  hash_set (gbp_ip4_to_epg_db.g4ie_hash, ip->ip4.as_u32, epg_id);
108  }
109  else
110  {
111  hash_set_mem (gbp_ip6_to_epg_db.g6ie_hash, &ip->ip6, epg_id);
112  }
113 }
114 
115 static void
116 gbp_ip_epg_delete (const ip46_address_t * ip)
117 {
118  if (ip46_address_is_ip4 (ip))
119  {
120  hash_unset (gbp_ip4_to_epg_db.g4ie_hash, ip->ip4.as_u32);
121  }
122  else
123  {
124  hash_unset_mem (gbp_ip6_to_epg_db.g6ie_hash, &ip->ip6);
125  }
126 }
127 
128 static void
129 gbp_itf_epg_update (u32 sw_if_index, epg_id_t src_epg)
130 {
131  vec_validate_init_empty (gbp_itf_to_epg_db.gte_vec,
132  sw_if_index, ITF_INVALID);
133 
134  if (0 == gbp_itf_to_epg_db.gte_vec[sw_if_index].gi_ref_count)
135  {
136  vnet_feature_enable_disable ("ip4-unicast", "gbp4",
137  sw_if_index, 1, NULL, 0);
138  vnet_feature_enable_disable ("ip6-unicast", "gbp6",
139  sw_if_index, 1, NULL, 0);
140  }
141  gbp_itf_to_epg_db.gte_vec[sw_if_index].gi_epg = src_epg;
142  gbp_itf_to_epg_db.gte_vec[sw_if_index].gi_ref_count++;
143 }
144 
145 static void
146 gbp_itf_epg_delete (u32 sw_if_index)
147 {
148  if (vec_len (gbp_itf_to_epg_db.gte_vec) <= sw_if_index)
149  return;
150 
151  if (1 == gbp_itf_to_epg_db.gte_vec[sw_if_index].gi_ref_count)
152  {
153  gbp_itf_to_epg_db.gte_vec[sw_if_index].gi_epg = EPG_INVALID;
154 
155  vnet_feature_enable_disable ("ip4-unicast", "gbp4",
156  sw_if_index, 0, NULL, 0);
157  vnet_feature_enable_disable ("ip6-unicast", "gbp6",
158  sw_if_index, 0, NULL, 0);
159  }
160  gbp_itf_to_epg_db.gte_vec[sw_if_index].gi_ref_count--;
161 }
162 
163 void
165  const ip46_address_t * ip, epg_id_t epg_id)
166 {
167  gbp_endpoint_key_t key = {
168  .gek_ip = *ip,
169  .gek_sw_if_index = sw_if_index,
170  };
171  gbp_endpoint_t *gbpe;
172  uword *p;
173 
174  p = hash_get_mem (gbp_endpoint_db, &key);
175 
176  if (p)
177  {
178  gbpe = pool_elt_at_index (gbp_endpoint_pool, p[0]);
179  }
180  else
181  {
182  pool_get (gbp_endpoint_pool, gbpe);
183 
184  gbpe->ge_key = clib_mem_alloc (sizeof (gbp_endpoint_key_t));
185  clib_memcpy (gbpe->ge_key, &key, sizeof (gbp_endpoint_key_t));
186 
187  hash_set_mem (gbp_endpoint_db, gbpe->ge_key, gbpe - gbp_endpoint_pool);
188  }
189 
190  gbpe->ge_epg_id = epg_id;
191 
193  gbp_ip_epg_update (&gbpe->ge_key->gek_ip, gbpe->ge_epg_id);
194 }
195 
196 void
197 gbp_endpoint_delete (u32 sw_if_index, const ip46_address_t * ip)
198 {
199  gbp_endpoint_key_t key = {
200  .gek_ip = *ip,
201  .gek_sw_if_index = sw_if_index,
202  };
203  gbp_endpoint_t *gbpe;
204  uword *p;
205 
206  p = hash_get_mem (gbp_endpoint_db, &key);
207 
208  if (p)
209  {
210  gbpe = pool_elt_at_index (gbp_endpoint_pool, p[0]);
211 
213 
215  gbp_ip_epg_delete (&gbpe->ge_key->gek_ip);
216 
217  clib_mem_free (gbpe->ge_key);
218 
219  pool_put (gbp_endpoint_pool, gbpe);
220  }
221 }
222 
223 void
225 {
226  gbp_endpoint_t *gbpe;
227 
228  /* *INDENT-OFF* */
229  pool_foreach(gbpe, gbp_endpoint_pool,
230  {
231  if (!cb(gbpe, ctx))
232  break;
233  });
234  /* *INDENT-ON* */
235 }
236 
237 void
238 gbp_contract_update (epg_id_t src_epg, epg_id_t dst_epg, u32 acl_index)
239 {
240  gbp_contract_key_t key = {
241  .gck_src = src_epg,
242  .gck_dst = dst_epg,
243  };
244 
245  hash_set (gbp_contract_db.gc_hash, key.as_u64, acl_index);
246 }
247 
248 void
250 {
251  gbp_contract_key_t key = {
252  .gck_src = src_epg,
253  .gck_dst = dst_epg,
254  };
255 
256  hash_unset (gbp_contract_db.gc_hash, key.as_u64);
257 }
258 
259 void
261 {
262  gbp_contract_key_t key;
263  u32 acl_index;
264 
265  /* *INDENT-OFF* */
266  hash_foreach(key.as_u64, acl_index, gbp_contract_db.gc_hash,
267  ({
268  gbp_contract_t gbpc = {
269  .gc_key = key,
270  .gc_acl_index = acl_index,
271  };
272 
273  if (!cb(&gbpc, ctx))
274  break;
275  }));
276  /* *INDENT-ON* */
277 }
278 
279 static clib_error_t *
281  unformat_input_t * input, vlib_cli_command_t * cmd)
282 {
283  vnet_main_t *vnm = vnet_get_main ();
284  epg_id_t epg_id = EPG_INVALID;
285  ip46_address_t ip = { };
286  u32 sw_if_index = ~0;
287  u8 add = 1;
288 
290  {
291  if (unformat (input, "%U", unformat_vnet_sw_interface,
292  vnm, &sw_if_index))
293  ;
294  else if (unformat (input, "add"))
295  add = 1;
296  else if (unformat (input, "del"))
297  add = 0;
298  else if (unformat (input, "epg %d", &epg_id))
299  ;
300  else if (unformat (input, "ip %U", unformat_ip4_address, &ip.ip4))
301  ;
302  else if (unformat (input, "ip %U", unformat_ip6_address, &ip.ip6))
303  ;
304  else
305  break;
306  }
307 
308  if (~0 == sw_if_index)
309  return clib_error_return (0, "interface must be specified");
310  if (EPG_INVALID == epg_id)
311  return clib_error_return (0, "EPG-ID must be specified");
312  if (ip46_address_is_zero (&ip))
313  return clib_error_return (0, "IP address must be specified");
314 
315  if (add)
316  gbp_endpoint_update (sw_if_index, &ip, epg_id);
317  else
318  gbp_endpoint_delete (sw_if_index, &ip);
319 
320  return (NULL);
321 }
322 
323 static clib_error_t *
325  unformat_input_t * input, vlib_cli_command_t * cmd)
326 {
327  epg_id_t src_epg_id = EPG_INVALID, dst_epg_id = EPG_INVALID;
328  u32 acl_index = ~0;
329  u8 add = 1;
330 
332  {
333  if (unformat (input, "add"))
334  add = 1;
335  else if (unformat (input, "del"))
336  add = 0;
337  else if (unformat (input, "src-epg %d", &src_epg_id))
338  ;
339  else if (unformat (input, "dst-epg %d", &dst_epg_id))
340  ;
341  else if (unformat (input, "acl-index %d", &acl_index))
342  ;
343  else
344  break;
345  }
346 
347  if (EPG_INVALID == src_epg_id)
348  return clib_error_return (0, "Source EPG-ID must be specified");
349  if (EPG_INVALID == dst_epg_id)
350  return clib_error_return (0, "Destination EPG-ID must be specified");
351 
352  if (add)
353  {
354  gbp_contract_update (src_epg_id, dst_epg_id, acl_index);
355  }
356  else
357  {
358  gbp_contract_delete (src_epg_id, dst_epg_id);
359  }
360 
361  return (NULL);
362 }
363 
364 /*?
365  * Configure a GBP Endpoint
366  *
367  * @cliexpar
368  * @cliexstart{set gbp endpoint [del] <interface> epg <ID> ip <IP>}
369  * @cliexend
370  ?*/
371 /* *INDENT-OFF* */
372 VLIB_CLI_COMMAND (gbp_endpoint_cli_node, static) = {
373  .path = "gbp endpoint",
374  .short_help = "gbp endpoint [del] <interface> epg <ID> ip <IP>",
375  .function = gbp_endpoint_cli,
376 };
377 
378 /*?
379  * Configure a GBP Contract
380  *
381  * @cliexpar
382  * @cliexstart{set gbp contract [del] src-epg <ID> dst-epg <ID> acl-index <ACL>}
383  * @cliexend
384  ?*/
385 VLIB_CLI_COMMAND (gbp_contract_cli_node, static) = {
386  .path = "gbp contract",
387  .short_help = "gbp contract [del] src-epg <ID> dst-epg <ID> acl-index <ACL>",
388  .function = gbp_contract_cli,
389 };
390 /* *INDENT-ON* */
391 
392 static int
394 {
395  vnet_main_t *vnm = vnet_get_main ();
396  vlib_main_t *vm;
397 
398  vm = ctx;
399  vlib_cli_output (vm, " {%U, %U} -> %d",
401  gbpe->ge_key->gek_sw_if_index,
403  gbpe->ge_epg_id);
404 
405  return (1);
406 }
407 
408 static clib_error_t *
410  unformat_input_t * input, vlib_cli_command_t * cmd)
411 {
412  vnet_main_t *vnm = vnet_get_main ();
413  ip46_address_t ip, *ipp;
414  epg_id_t epg_id;
415  u32 sw_if_index;
416 
417  vlib_cli_output (vm, "Endpoints:");
419 
420  vlib_cli_output (vm, "\nSource interface to EPG:");
421 
422  vec_foreach_index (sw_if_index, gbp_itf_to_epg_db.gte_vec)
423  {
424  if (EPG_INVALID != gbp_itf_to_epg_db.gte_vec[sw_if_index].gi_epg)
425  {
426  vlib_cli_output (vm, " %U -> %d",
427  format_vnet_sw_if_index_name, vnm, sw_if_index,
428  gbp_itf_to_epg_db.gte_vec[sw_if_index].gi_epg);
429  }
430  }
431 
432  vlib_cli_output (vm, "\nDestination IP4 to EPG:");
433 
434  /* *INDENT-OFF* */
435  hash_foreach (ip.ip4.as_u32, epg_id, gbp_ip4_to_epg_db.g4ie_hash,
436  {
437  vlib_cli_output (vm, " %U -> %d", format_ip46_address, &ip,
438  IP46_TYPE_IP4, epg_id);
439  });
440  /* *INDENT-ON* */
441 
442  vlib_cli_output (vm, "\nDestination IP6 to EPG:");
443 
444  /* *INDENT-OFF* */
445  hash_foreach_mem (ipp, epg_id, gbp_ip6_to_epg_db.g6ie_hash,
446  {
447  vlib_cli_output (vm, " %U -> %d", format_ip46_address, ipp,
448  IP46_TYPE_IP6, epg_id);
449  });
450  /* *INDENT-ON* */
451 
452  return (NULL);
453 }
454 
455 static clib_error_t *
457  unformat_input_t * input, vlib_cli_command_t * cmd)
458 {
459  gbp_contract_key_t key;
460  epg_id_t epg_id;
461 
462  vlib_cli_output (vm, "Contracts:");
463 
464  /* *INDENT-OFF* */
465  hash_foreach (key.as_u64, epg_id, gbp_contract_db.gc_hash,
466  {
467  vlib_cli_output (vm, " {%d,%d} -> %d", key.gck_src,
468  key.gck_dst, epg_id);
469  });
470  /* *INDENT-ON* */
471 
472  return (NULL);
473 }
474 
475 /*?
476  * Show Group Based Policy Endpoints and derived information
477  *
478  * @cliexpar
479  * @cliexstart{show gbp endpoint}
480  * @cliexend
481  ?*/
482 /* *INDENT-OFF* */
483 VLIB_CLI_COMMAND (gbp_endpoint_show_node, static) = {
484  .path = "show gbp endpoint",
485  .short_help = "show gbp endpoint\n",
486  .function = gbp_endpoint_show,
487 };
488 /* *INDENT-ON* */
489 
490 /*?
491  * Show Group Based Policy Contracts
492  *
493  * @cliexpar
494  * @cliexstart{show gbp contract}
495  * @cliexend
496  ?*/
497 /* *INDENT-OFF* */
498 VLIB_CLI_COMMAND (gbp_contract_show_node, static) = {
499  .path = "show gbp contract",
500  .short_help = "show gbp contract\n",
501  .function = gbp_contract_show,
502 };
503 /* *INDENT-ON* */
504 
505 #define foreach_gbp \
506  _(DENY, "deny")
507 
508 typedef enum
509 {
510 #define _(sym,str) GBP_ERROR_##sym,
512 #undef _
514 } gbp_error_t;
515 
516 static char *gbp_error_strings[] = {
517 #define _(sym,string) string,
519 #undef _
520 };
521 
522 typedef enum
523 {
524 #define _(sym,str) GBP_NEXT_##sym,
526 #undef _
528 } gbp_next_t;
529 
530 /**
531  * per-packet trace data
532  */
533 typedef struct gbp_trace_t_
534 {
535  /* per-pkt trace data */
539 } gbp_trace_t;
540 
541 static inline uword
543  vlib_node_runtime_t * node, vlib_frame_t * frame, int is_ip6)
544 {
545  u32 n_left_from, *from, *to_next;
546  gbp_next_t next_index;
547 
548  next_index = 0;
549  n_left_from = frame->n_vectors;
550  from = vlib_frame_vector_args (frame);
551 
552  while (n_left_from > 0)
553  {
554  u32 n_left_to_next;
555 
556  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
557 
558  while (n_left_from > 0 && n_left_to_next > 0)
559  {
560  vlib_buffer_t *b0;
561  u32 sw_if_index0;
562  gbp_next_t next0;
563  u32 bi0;
564  ip4_header_t *ip4_0;
565  ip6_header_t *ip6_0;
566  gbp_contract_key_t key0;
567  u32 acl_index0;
568  uword *p;
569 
570  bi0 = from[0];
571  to_next[0] = bi0;
572  from += 1;
573  to_next += 1;
574  n_left_from -= 1;
575  n_left_to_next -= 1;
576 
577  /* deny by default */
578  next0 = GBP_NEXT_DENY;
579 
580  b0 = vlib_get_buffer (vm, bi0);
581  if (is_ip6)
582  ip6_0 = vlib_buffer_get_current (b0);
583  else
584  ip4_0 = vlib_buffer_get_current (b0);
585  sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
586 
587  /*
588  * determine the src and dst EPG
589  */
590  key0.gck_src = gbp_itf_to_epg_db.gte_vec[sw_if_index0].gi_epg;
591 
592  if (is_ip6)
593  p = hash_get_mem (gbp_ip6_to_epg_db.g6ie_hash,
594  &ip6_0->dst_address);
595  else
596  p = hash_get (gbp_ip4_to_epg_db.g4ie_hash,
597  ip4_0->dst_address.as_u32);
598 
599  if (NULL != p)
600  {
601  key0.gck_dst = p[0];
602 
603  /*
604  * If the src and dst are the same, then let it through
605  */
606  if (key0.gck_dst == key0.gck_src)
607  {
608  vnet_feature_next (sw_if_index0, &next0, b0);
609  acl_index0 = ~0;
610  }
611  else
612  {
613  /*
614  * find this src,dst pair in the egp->acl DB
615  */
616  p = hash_get (gbp_contract_db.gc_hash, key0.as_u64);
617 
618  if (NULL != p)
619  {
620  acl_index0 = p[0];
621 
622  /*
623  * the ACL index stored is NULL, this means any-any so let it pass
624  */
625  if (~0 == acl_index0)
626  {
627  vnet_feature_next (sw_if_index0, &next0, b0);
628  }
629  else
630  {
631  /*
632  * TODO tests against the ACL
633  */
634  /*
635  * ACL tables are not available outside of ACL plugin
636  * until then bypass the ACL to next node
637  */
638  vnet_feature_next (sw_if_index0, &next0, b0);
639  }
640  }
641  else
642  {
643  /*
644  * no ACL to apply for packets between these two EPGs.
645  * GBP is a whitelist model, so no ACL implies deny, which
646  * is the default result
647  */
648  acl_index0 = ~0;
649  }
650  }
651  }
652  else
653  {
654  /*
655  * cannot determine the destinaiotn EPG, so we cannot enforce policy
656  * on this node. permit.
657  */
658  vnet_feature_next (sw_if_index0, &next0, b0);
659 
660  key0.gck_dst = ~0;
661  acl_index0 = ~0;
662  }
663 
664  if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) &&
665  (b0->flags & VLIB_BUFFER_IS_TRACED)))
666  {
667  gbp_trace_t *t = vlib_add_trace (vm, node, b0, sizeof (*t));
668  t->src_epg = key0.gck_src;
669  t->dst_epg = key0.gck_dst;
670  t->acl_index = acl_index0;
671  }
672 
673  /* verify speculative enqueue, maybe switch current next frame */
674  vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
675  to_next, n_left_to_next,
676  bi0, next0);
677  }
678 
679  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
680  }
681 
682  return frame->n_vectors;
683 }
684 
685 /* packet trace format function */
686 static u8 *
687 format_gbp_trace (u8 * s, va_list * args)
688 {
689  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
690  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
691  gbp_trace_t *t = va_arg (*args, gbp_trace_t *);
692 
693  s = format (s, "gbp: src:%d dst:%d acl:%d",
694  t->src_epg, t->dst_epg, t->acl_index);
695 
696  return s;
697 }
698 
699 static inline uword
701 {
702  return (gbp_inline (vm, node, frame, 0));
703 }
704 
705 static inline uword
707 {
708  return (gbp_inline (vm, node, frame, 1));
709 }
710 
711 /* *INDENT-OFF* */
713  .function = gbp_4,
714  .name = "gbp4",
715  .vector_size = sizeof (u32),
716  .format_trace = format_gbp_trace,
717  .type = VLIB_NODE_TYPE_INTERNAL,
718 
719  .n_errors = ARRAY_LEN(gbp_error_strings),
720  .error_strings = gbp_error_strings,
721 
722  .n_next_nodes = GBP_N_NEXT,
723 
724  .next_nodes = {
725  [GBP_NEXT_DENY] = "ip4-drop",
726  },
727 };
728 
730 
731 VNET_FEATURE_INIT (gbp_4_node, static) = {
732  .arc_name = "ip4-unicast",
733  .node_name = "gbp4",
734  .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa"),
735 };
736 
738  .function = gbp_6,
739  .name = "gbp6",
740  .vector_size = sizeof (u32),
741  .format_trace = format_gbp_trace,
742  .type = VLIB_NODE_TYPE_INTERNAL,
743 
744  .n_errors = ARRAY_LEN(gbp_error_strings),
745  .error_strings = gbp_error_strings,
746 
747  .n_next_nodes = GBP_N_NEXT,
748 
749  .next_nodes = {
750  [GBP_NEXT_DENY] = "ip6-drop",
751  },
752 };
753 
755 
756 VNET_FEATURE_INIT (gbp_6_node, static) = {
757  .arc_name = "ip6-unicast",
758  .node_name = "gbp6",
759  .runs_after = VNET_FEATURES ("acl-plugin-in-ip6-fa"),
760 };
761 /* *INDENT-ON* */
762 
763 static clib_error_t *
765 {
767  sizeof (gbp_endpoint_key_t),
768  sizeof (u32));
769  gbp_ip6_to_epg_db.g6ie_hash =
770  hash_create_mem (0, sizeof (ip6_address_t), sizeof (u32));
771  return 0;
772 }
773 
775 
776 /*
777  * fd.io coding-style-patch-verification: ON
778  *
779  * Local Variables:
780  * eval: (c-set-style "gnu")
781  * End:
782  */
#define vec_foreach_index(var, v)
Iterate over vector indices.
#define hash_set(h, key, value)
Definition: hash.h:254
A Group Based Policy Endpoint.
Definition: gbp.h:62
#define CLIB_UNUSED(x)
Definition: clib.h:79
int(* gbp_endpoint_cb_t)(gbp_endpoint_t *gbpe, void *ctx)
Definition: gbp.h:79
#define hash_unset(h, key)
Definition: hash.h:260
vnet_main_t * vnet_get_main(void)
Definition: misc.c:47
static char * gbp_error_strings[]
Definition: gbp.c:516
#define NULL
Definition: clib.h:55
IP6 destintion address to destination EPG mapping table.
Definition: gbp.c:36
The key for an Contract.
Definition: gbp.h:86
static uword gbp_6(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: gbp.c:706
Interface to source EPG DB - a per-interface vector.
Definition: gbp.c:65
VLIB_NODE_FUNCTION_MULTIARCH(gbp_4_node, gbp_4)
gbp_endpoint_key_t * ge_key
The endpoint&#39;s interface and IP address.
Definition: gbp.h:67
struct gbp_ip6_to_epg_db_t_ gbp_ip6_to_epg_db_t
IP6 destintion address to destination EPG mapping table.
format_function_t format_ip46_address
Definition: format.h:61
#define hash_set_mem(h, key, value)
Definition: hash.h:274
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
unformat_function_t unformat_vnet_sw_interface
static clib_error_t * gbp_endpoint_show(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: gbp.c:409
EPG src,dst pair to ACL mapping table, aka contract DB.
Definition: gbp.c:85
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:227
static u8 * format_gbp_trace(u8 *s, va_list *args)
Definition: gbp.c:687
format_function_t format_vnet_sw_if_index_name
void gbp_contract_walk(gbp_contract_cb_t cb, void *ctx)
Definition: gbp.c:260
uword * g6ie_hash
use a memroy hash table
Definition: gbp.c:41
static gbp_ip6_to_epg_db_t gbp_ip6_to_epg_db
Definition: gbp.c:44
epg_id_t src_epg
Definition: gbp.c:536
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:440
unformat_function_t unformat_ip4_address
Definition: format.h:76
u32 acl_index
Definition: gbp.c:538
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
static void gbp_ip_epg_delete(const ip46_address_t *ip)
Definition: gbp.c:116
ip4_address_t dst_address
Definition: ip4_packet.h:164
vlib_node_registration_t gbp_4_node
(constructor) VLIB_REGISTER_NODE (gbp_4_node)
Definition: gbp.c:712
u32 gek_sw_if_index
The interface on which the EP is connected.
Definition: gbp.h:49
#define hash_foreach(key_var, value_var, h, body)
Definition: hash.h:441
gbp_next_t
Definition: gbp.c:522
#define clib_error_return(e, args...)
Definition: error.h:99
#define EPG_INVALID
Definition: gbp.h:39
void gbp_contract_delete(epg_id_t src_epg, epg_id_t dst_epg)
Definition: gbp.c:249
static int gbp_endpoint_show_one(gbp_endpoint_t *gbpe, void *ctx)
Definition: gbp.c:393
void gbp_endpoint_delete(u32 sw_if_index, const ip46_address_t *ip)
Definition: gbp.c:197
uword * gc_hash
We can form a u64 key from the pair, so use a simple hash table.
Definition: gbp.c:90
#define hash_create_mem(elts, key_bytes, value_bytes)
Definition: hash.h:660
#define hash_get(h, key)
Definition: hash.h:248
static gbp_itf_to_epg_db_t gbp_itf_to_epg_db
Definition: gbp.c:70
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:461
#define hash_unset_mem(h, key)
Definition: hash.h:290
static void gbp_itf_epg_update(u32 sw_if_index, epg_id_t src_epg)
Definition: gbp.c:129
epg_id_t gi_epg
Definition: gbp.c:53
struct _unformat_input_t unformat_input_t
static clib_error_t * gbp_endpoint_cli(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: gbp.c:280
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:209
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:273
struct gbp_ip4_to_epg_db_t_ gbp_ip4_to_epg_db_t
IP4 destintion address to destination EPG mapping table.
#define PREDICT_FALSE(x)
Definition: clib.h:105
static gbp_ip4_to_epg_db_t gbp_ip4_to_epg_db
Definition: gbp.c:31
static_always_inline void vnet_feature_next(u32 sw_if_index, u32 *next0, vlib_buffer_t *b0)
Definition: feature.h:221
#define vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next, n_left_to_next, bi0, next0)
Finish enqueueing one buffer forward in the graph.
Definition: buffer_node.h:218
#define vlib_get_next_frame(vm, node, next_index, vectors, n_vectors_left)
Get pointer to next frame vector data by (vlib_node_runtime_t, next_index).
Definition: node_funcs.h:364
#define hash_foreach_mem(key_var, value_var, h, body)
Definition: hash.h:460
#define ip46_address_is_ip4(ip46)
Definition: ip6_packet.h:76
unformat_function_t unformat_ip6_address
Definition: format.h:94
static uword gbp_4(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: gbp.c:700
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:143
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
u16 n_vectors
Definition: node.h:344
ip46_address_t gek_ip
The IP[46] address of the endpoint.
Definition: gbp.h:54
Result of a interface to EPG mapping.
Definition: gbp.c:51
vlib_main_t * vm
Definition: buffer.c:294
uword * g4ie_hash
use a simple hash table
Definition: gbp.c:28
static void gbp_ip_epg_update(const ip46_address_t *ip, epg_id_t epg_id)
Definition: gbp.c:99
#define clib_memcpy(a, b, c)
Definition: string.h:75
#define ARRAY_LEN(x)
Definition: clib.h:59
void vlib_put_next_frame(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, u32 n_vectors_left)
Release pointer to next frame vector data.
Definition: main.c:454
epg_id_t gck_src
source and destination EPGs for which the ACL applies
Definition: gbp.h:95
gbp_itf_t * gte_vec
Definition: gbp.c:67
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
The key for an Endpoint.
Definition: gbp.h:44
per-packet trace data
Definition: gbp.c:533
unsigned int u32
Definition: types.h:88
VNET_FEATURE_INIT(gbp_4_node, static)
long ctx[MAX_CONNS]
Definition: main.c:126
static void clib_mem_free(void *p)
Definition: mem.h:179
static void * clib_mem_alloc(uword size)
Definition: mem.h:112
#define VNET_FEATURES(...)
Definition: feature.h:375
u64 uword
Definition: types.h:112
static void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
Definition: trace_funcs.h:55
#define foreach_gbp
Definition: gbp.c:505
static clib_error_t * gbp_contract_cli(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: gbp.c:324
void gbp_endpoint_update(u32 sw_if_index, const ip46_address_t *ip, epg_id_t epg_id)
Definition: gbp.c:164
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
static clib_error_t * gbp_contract_show(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: gbp.c:456
unsigned char u8
Definition: types.h:56
epg_id_t ge_epg_id
The endpoint&#39;s designated EPG.
Definition: gbp.h:72
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:267
IP4 destintion address to destination EPG mapping table.
Definition: gbp.c:23
struct gbp_contract_db_t_ gbp_contract_db_t
EPG src,dst pair to ACL mapping table, aka contract DB.
u32 gi_ref_count
Definition: gbp.c:54
u32 epg_id_t
Group Base Policy (GBP) defines:
Definition: gbp.h:38
#define hash_get_mem(h, key)
Definition: hash.h:268
#define vnet_buffer(b)
Definition: buffer.h:372
vlib_node_registration_t gbp_6_node
(constructor) VLIB_REGISTER_NODE (gbp_6_node)
Definition: gbp.c:737
int(* gbp_contract_cb_t)(gbp_contract_t *gbpe, void *ctx)
Definition: gbp.h:124
static gbp_endpoint_t * gbp_endpoint_pool
Pool of GBP endpoints.
Definition: gbp.c:75
u16 flags
Copy of main node flags.
Definition: node.h:450
void gbp_endpoint_walk(gbp_endpoint_cb_t cb, void *ctx)
Definition: gbp.c:224
static uword * gbp_endpoint_db
DB of endpoints.
Definition: gbp.c:80
#define VLIB_NODE_FLAG_TRACE
Definition: node.h:259
static uword gbp_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, int is_ip6)
Definition: gbp.c:542
#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:483
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index, VLIB_BUFFER_IS_TRACED: trace this buffer.
Definition: buffer.h:111
struct gbp_trace_t_ gbp_trace_t
per-packet trace data
#define ip46_address_is_zero(ip46)
Definition: ip6_packet.h:81
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:680
struct gbp_itf_to_epg_db_t_ gbp_itf_to_epg_db_t
Interface to source EPG DB - a per-interface vector.
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:57
void gbp_contract_update(epg_id_t src_epg, epg_id_t dst_epg, u32 acl_index)
Definition: gbp.c:238
epg_id_t gck_dst
Definition: gbp.h:96
static void gbp_itf_epg_delete(u32 sw_if_index)
Definition: gbp.c:146
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
Definition: defs.h:46
int vnet_feature_enable_disable(const char *arc_name, const char *node_name, u32 sw_if_index, int enable_disable, void *feature_config, u32 n_feature_config_bytes)
Definition: feature.c:233
ip6_address_t dst_address
Definition: ip6_packet.h:342
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169
gbp_error_t
Definition: gbp.c:508
struct gbp_itf_t_ gbp_itf_t
Result of a interface to EPG mapping.
static gbp_contract_db_t gbp_contract_db
Since contract DB instance.
Definition: gbp.c:96
epg_id_t dst_epg
Definition: gbp.c:537
static clib_error_t * gbp_init(vlib_main_t *vm)
Definition: gbp.c:764