FD.io VPP  v20.05-21-gb1500e9ff
Vector Packet Processing
gbp_contract.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 
18 #include <plugins/gbp/gbp.h>
23 
24 #include <vnet/dpo/load_balance.h>
25 #include <vnet/dpo/drop_dpo.h>
26 
28 #define _(sym,string) string,
30 #undef _
31 };
32 
33 /**
34  * Single contract DB instance
35  */
37 
39 
41 
43 
46 
47 #define GBP_CONTRACT_DBG(...) \
48  vlib_log_notice (gc_logger, __VA_ARGS__);
49 
50 /* Adjacency packet/byte counters indexed by adjacency index. */
51 vlib_combined_counter_main_t gbp_contract_permit_counters = {
52  .name = "gbp-contracts-permit",
53  .stat_segment_name = "/net/gbp/contract/permit",
54 };
55 
56 vlib_combined_counter_main_t gbp_contract_drop_counters = {
57  .name = "gbp-contracts-drop",
58  .stat_segment_name = "/net/gbp/contract/drop",
59 };
60 
61 index_t
63  gbp_hash_mode_t hash_mode, index_t * nhs)
64 {
65  gbp_rule_t *gu;
66 
67  pool_get_zero (gbp_rule_pool, gu);
68 
69  gu->gu_hash_mode = hash_mode;
70  gu->gu_nhs = nhs;
71  gu->gu_action = action;
72 
73  return (gu - gbp_rule_pool);
74 }
75 
76 void
78 {
79  pool_put_index (gbp_rule_pool, gui);
80 }
81 
82 index_t
83 gbp_next_hop_alloc (const ip46_address_t * ip,
84  index_t grd, const mac_address_t * mac, index_t gbd)
85 {
86  fib_protocol_t fproto;
87  gbp_next_hop_t *gnh;
88 
89  pool_get_zero (gbp_next_hop_pool, gnh);
90 
92 
93  ip46_address_copy (&gnh->gnh_ip, ip);
94  mac_address_copy (&gnh->gnh_mac, mac);
95 
96  gnh->gnh_rd = grd;
97  gnh->gnh_bd = gbd;
98 
99  FOR_EACH_FIB_IP_PROTOCOL (fproto) gnh->gnh_ai[fproto] = INDEX_INVALID;
100 
101  return (gnh - gbp_next_hop_pool);
102 }
103 
104 static inline gbp_next_hop_t *
106 {
107  return (pool_elt_at_index (gbp_next_hop_pool, gui));
108 }
109 
110 static void
112 {
113  index_t *gui, *gnhi;
114 
115  vec_foreach (gui, rules)
116  {
117  gbp_policy_node_t pnode;
118  fib_protocol_t fproto;
119  gbp_next_hop_t *gnh;
120  gbp_rule_t *gu;
121 
122  gu = gbp_rule_get (*gui);
123 
125  {
126  FOR_EACH_FIB_IP_PROTOCOL (fproto)
127  {
128  dpo_reset (&gu->gu_dpo[pnode][fproto]);
129  dpo_reset (&gu->gu_dpo[pnode][fproto]);
130  }
131  }
132 
133  vec_foreach (gnhi, gu->gu_nhs)
134  {
135  fib_protocol_t fproto;
136 
137  gnh = gbp_next_hop_get (*gnhi);
141  gbp_endpoint_unlock (GBP_ENDPOINT_SRC_RR, gnh->gnh_ge);
142 
143  FOR_EACH_FIB_IP_PROTOCOL (fproto)
144  {
145  adj_unlock (gnh->gnh_ai[fproto]);
146  }
147  }
148 
149  gbp_rule_free (*gui);
150  }
151  vec_free (rules);
152 }
153 
154 static u8 *
155 format_gbp_next_hop (u8 * s, va_list * args)
156 {
157  index_t gnhi = va_arg (*args, index_t);
158  gbp_next_hop_t *gnh;
159 
160  gnh = gbp_next_hop_get (gnhi);
161 
162  s = format (s, "%U, %U, %U EP:%d",
166 
167  return (s);
168 }
169 
170 u8 *
171 format_gbp_rule_action (u8 * s, va_list * args)
172 {
173  gbp_rule_action_t action = va_arg (*args, gbp_rule_action_t);
174 
175  switch (action)
176  {
177 #define _(v,a) case GBP_RULE_##v: return (format (s, "%s", a));
179 #undef _
180  }
181 
182  return (format (s, "unknown"));
183 }
184 
185 static u8 *
186 format_gbp_hash_mode (u8 * s, va_list * args)
187 {
188  gbp_hash_mode_t hash_mode = va_arg (*args, gbp_hash_mode_t);
189 
190  switch (hash_mode)
191  {
192 #define _(v,a) case GBP_HASH_MODE_##v: return (format (s, "%s", a));
194 #undef _
195  }
196 
197  return (format (s, "unknown"));
198 }
199 
200 static u8 *
201 format_gbp_policy_node (u8 * s, va_list * args)
202 {
203  gbp_policy_node_t action = va_arg (*args, gbp_policy_node_t);
204 
205  switch (action)
206  {
207 #define _(v,a) case GBP_POLICY_NODE_##v: return (format (s, "%s", a));
209 #undef _
210  }
211 
212  return (format (s, "unknown"));
213 }
214 
215 static u8 *
216 format_gbp_rule (u8 * s, va_list * args)
217 {
218  index_t gui = va_arg (*args, index_t);
219  gbp_policy_node_t pnode;
220  fib_protocol_t fproto;
221  gbp_rule_t *gu;
222  index_t *gnhi;
223 
224  gu = gbp_rule_get (gui);
225  s = format (s, "%U", format_gbp_rule_action, gu->gu_action);
226 
227  switch (gu->gu_action)
228  {
229  case GBP_RULE_PERMIT:
230  case GBP_RULE_DENY:
231  return (s);
232  case GBP_RULE_REDIRECT:
233  s = format (s, ", %U", format_gbp_hash_mode, gu->gu_hash_mode);
234  break;
235  }
236 
237  vec_foreach (gnhi, gu->gu_nhs)
238  {
239  s = format (s, "\n [%U]", format_gbp_next_hop, *gnhi);
240  }
241 
243  {
244  s = format (s, "\n policy-%U", format_gbp_policy_node, pnode);
245 
246  FOR_EACH_FIB_IP_PROTOCOL (fproto)
247  {
248  if (dpo_id_is_valid (&gu->gu_dpo[pnode][fproto]))
249  {
250  s =
251  format (s, "\n %U", format_dpo_id,
252  &gu->gu_dpo[pnode][fproto], 8);
253  }
254  }
255  }
256 
257  return (s);
258 }
259 
260 static void
262 {
263  ethernet_header_t *eth;
265  index_t old_ai;
266  u8 *rewrite;
267 
268  old_ai = gnh->gnh_ai[fproto];
269  rewrite = NULL;
270  vec_validate (rewrite, sizeof (*eth) - 1);
271  eth = (ethernet_header_t *) rewrite;
272 
273  GBP_CONTRACT_DBG ("...mk-adj: %U", format_gbp_next_hop,
274  gnh - gbp_next_hop_pool);
275 
276  ge = gbp_endpoint_get (gnh->gnh_ge);
277 
278  eth->type = clib_host_to_net_u16 ((fproto == FIB_PROTOCOL_IP4 ?
279  ETHERNET_TYPE_IP4 : ETHERNET_TYPE_IP6));
282 
283  gnh->gnh_ai[fproto] =
285  fib_proto_to_link (fproto),
286  &gnh->gnh_ip,
288  ge_fwd.gef_itf),
289  rewrite);
290 
291  adj_unlock (old_ai);
292 }
293 
294 static flow_hash_config_t
296 {
297  switch (gu_hash_mode)
298  {
299  case GBP_HASH_MODE_SRC_IP:
300  return IP_FLOW_HASH_SRC_ADDR;
301  case GBP_HASH_MODE_DST_IP:
302  return IP_FLOW_HASH_DST_ADDR;
303  case GBP_HASH_MODE_SYMMETRIC:
306  }
307 
308  return 0;
309 }
310 
311 static void
313 {
314  load_balance_path_t *paths = NULL;
315  gbp_policy_node_t pnode;
316  gbp_next_hop_t *gnh;
317  dpo_proto_t dproto;
318  gbp_rule_t *gu;
319  u32 ii;
320 
321  u32 policy_nodes[] = {
322  [GBP_POLICY_NODE_L2] = gbp_policy_port_node.index,
323  [GBP_POLICY_NODE_IP4] = ip4_gbp_policy_dpo_node.index,
324  [GBP_POLICY_NODE_IP6] = ip6_gbp_policy_dpo_node.index,
325  };
326 
327  GBP_CONTRACT_DBG ("..mk-lb: %U", format_gbp_rule, gui);
328 
329  gu = gbp_rule_get (gui);
330  dproto = fib_proto_to_dpo (fproto);
331 
332  if (GBP_RULE_REDIRECT != gu->gu_action)
333  return;
334 
335  vec_foreach_index (ii, gu->gu_nhs)
336  {
337  gnh = gbp_next_hop_get (gu->gu_nhs[ii]);
338 
341  }
342 
344  {
345  vec_validate (paths, vec_len (gu->gu_nhs) - 1);
346 
347  vec_foreach_index (ii, gu->gu_nhs)
348  {
349  gnh = gbp_next_hop_get (gu->gu_nhs[ii]);
350 
352  paths[ii].path_weight = 1;
353  dpo_set (&paths[ii].path_dpo, DPO_ADJACENCY,
354  dproto, gnh->gnh_ai[fproto]);
355  }
356 
357  if (!dpo_id_is_valid (&gu->gu_dpo[pnode][fproto]))
358  {
359  dpo_id_t dpo = DPO_INVALID;
360 
361  dpo_set (&dpo, DPO_LOAD_BALANCE, dproto,
362  load_balance_create (vec_len (paths),
363  dproto,
365  (gu->gu_hash_mode)));
366  dpo_stack_from_node (policy_nodes[pnode], &gu->gu_dpo[pnode][fproto],
367  &dpo);
368  dpo_reset (&dpo);
369  }
370 
371  load_balance_multipath_update (&gu->gu_dpo[pnode][fproto],
372  paths, LOAD_BALANCE_FLAG_NONE);
373  vec_free (paths);
374  }
375 }
376 
377 static void
379 {
382 }
383 
384 static int
386 {
387  gbp_bridge_domain_t *gbd;
388  gbp_next_hop_t *gnh;
389  ip46_address_t *ips;
390  int rv;
391 
392  ips = NULL;
393  gnh = gbp_next_hop_get (gnhi);
394  gbd = gbp_bridge_domain_get (gnh->gnh_bd);
395 
396  gnh->gnh_gu = gui;
397  vec_add1 (ips, gnh->gnh_ip);
398 
399  /*
400  * source the endpoint this contract needs to forward via.
401  * give ofrwarding details via the spine proxy. if this EP is known
402  * to us, then since we source here with a low priority, the learned
403  * info will take precedenc.
404  */
405  rv = gbp_endpoint_update_and_lock (GBP_ENDPOINT_SRC_RR,
407  ips,
408  &gnh->gnh_mac,
409  gnh->gnh_bd, gnh->gnh_rd, SCLASS_INVALID,
410  GBP_ENDPOINT_FLAG_NONE, NULL, NULL,
411  &gnh->gnh_ge);
412 
413  if (0 == rv)
414  {
416  gbp_next_hop_fib_type, gnhi);
417  }
418 
419  GBP_CONTRACT_DBG ("..resolve: %d: %d: %U", gui, gnhi, format_gbp_next_hop,
420  gnhi);
421 
422  vec_free (ips);
423  return (rv);
424 }
425 
426 static void
428 {
429  gbp_rule_t *gu;
430  index_t *gnhi;
431 
432  gu = gbp_rule_get (gui);
433 
434  GBP_CONTRACT_DBG ("..resolve: %U", format_gbp_rule, gui);
435 
436  vec_foreach (gnhi, gu->gu_nhs)
437  {
438  gbp_contract_next_hop_resolve (gui, *gnhi);
439  }
440 }
441 
442 static void
444 {
445  index_t *gui;
446 
447  vec_foreach (gui, guis)
448  {
450  }
451 }
452 
453 static void
455 {
456  index_t *gui;
457 
458  vec_foreach (gui, guis)
459  {
460  gbp_contract_mk_one_lb (*gui);
461  }
462 }
463 
464 int
468  u32 acl_index,
469  index_t * rules,
471 {
472  gbp_main_t *gm = &gbp_main;
473  u32 *acl_vec = NULL;
474  gbp_contract_t *gc;
475  index_t gci;
476  uword *p;
477 
479  .gck_scope = scope,
480  .gck_src = sclass,
481  .gck_dst = dclass,
482  };
483 
484  if (~0 == gm->gbp_acl_user_id)
485  {
487  gm->gbp_acl_user_id =
488  gm->acl_plugin.register_user_module ("GBP ACL", "src-epg", "dst-epg");
489  }
490 
491  p = hash_get (gbp_contract_db.gc_hash, key.as_u64);
492  if (p != NULL)
493  {
494  gci = p[0];
495  gc = gbp_contract_get (gci);
497  gbp_main.acl_plugin.put_lookup_context_index (gc->gc_lc_index);
498  gc->gc_rules = NULL;
500  }
501  else
502  {
503  pool_get_zero (gbp_contract_pool, gc);
504  gc->gc_key = key;
505  gci = gc - gbp_contract_pool;
506  hash_set (gbp_contract_db.gc_hash, key.as_u64, gci);
507 
508  vlib_validate_combined_counter (&gbp_contract_drop_counters, gci);
509  vlib_zero_combined_counter (&gbp_contract_drop_counters, gci);
510  vlib_validate_combined_counter (&gbp_contract_permit_counters, gci);
511  vlib_zero_combined_counter (&gbp_contract_permit_counters, gci);
512  }
513 
514  GBP_CONTRACT_DBG ("update: %U", format_gbp_contract, gci);
515 
516  gc->gc_rules = rules;
520 
521  gc->gc_acl_index = acl_index;
522  gc->gc_lc_index =
523  gm->acl_plugin.get_lookup_context_index (gm->gbp_acl_user_id,
524  sclass, dclass);
525 
526  vec_add1 (acl_vec, gc->gc_acl_index);
527  gm->acl_plugin.set_acl_vec_for_context (gc->gc_lc_index, acl_vec);
528  vec_free (acl_vec);
529 
530  *stats_index = gci;
531 
532  return (0);
533 }
534 
535 int
537 {
539  .gck_scope = scope,
540  .gck_src = sclass,
541  .gck_dst = dclass,
542  };
543  gbp_contract_t *gc;
544  uword *p;
545 
546  p = hash_get (gbp_contract_db.gc_hash, key.as_u64);
547  if (p != NULL)
548  {
549  gc = gbp_contract_get (p[0]);
550 
552  gbp_main.acl_plugin.put_lookup_context_index (gc->gc_lc_index);
554 
555  hash_unset (gbp_contract_db.gc_hash, key.as_u64);
556  pool_put (gbp_contract_pool, gc);
557 
558  return (0);
559  }
560 
561  return (VNET_API_ERROR_NO_SUCH_ENTRY);
562 }
563 
564 void
566 {
567  gbp_contract_t *gc;
568 
569  /* *INDENT-OFF* */
570  pool_foreach(gc, gbp_contract_pool,
571  ({
572  if (!cb(gc, ctx))
573  break;
574  }));
575  /* *INDENT-ON* */
576 }
577 
578 static clib_error_t *
580  unformat_input_t * input, vlib_cli_command_t * cmd)
581 {
584  u8 add = 1;
585 
587  {
588  if (unformat (input, "add"))
589  add = 1;
590  else if (unformat (input, "del"))
591  add = 0;
592  else if (unformat (input, "scope %d", &scope))
593  ;
594  else if (unformat (input, "sclass %d", &sclass))
595  ;
596  else if (unformat (input, "dclass %d", &dclass))
597  ;
598  else if (unformat (input, "acl-index %d", &acl_index))
599  ;
600  else
601  break;
602  }
603 
604  if (SCLASS_INVALID == sclass)
605  return clib_error_return (0, "Source EPG-ID must be specified");
606  if (SCLASS_INVALID == dclass)
607  return clib_error_return (0, "Destination EPG-ID must be specified");
608 
609  if (add)
610  {
611  gbp_contract_update (scope, sclass, dclass, acl_index,
612  NULL, NULL, &stats_index);
613  }
614  else
615  {
616  gbp_contract_delete (scope, sclass, dclass);
617  }
618 
619  return (NULL);
620 }
621 
622 /*?
623  * Configure a GBP Contract
624  *
625  * @cliexpar
626  * @cliexstart{set gbp contract [del] src-epg <ID> dst-epg <ID> acl-index <ACL>}
627  * @cliexend
628  ?*/
629 /* *INDENT-OFF* */
630 VLIB_CLI_COMMAND (gbp_contract_cli_node, static) =
631 {
632  .path = "gbp contract",
633  .short_help =
634  "gbp contract [del] src-epg <ID> dst-epg <ID> acl-index <ACL>",
635  .function = gbp_contract_cli,
636 };
637 /* *INDENT-ON* */
638 
639 static u8 *
640 format_gbp_contract_key (u8 * s, va_list * args)
641 {
642  gbp_contract_key_t *gck = va_arg (*args, gbp_contract_key_t *);
643 
644  s = format (s, "{%d,%d,%d}", gck->gck_scope, gck->gck_src, gck->gck_dst);
645 
646  return (s);
647 }
648 
649 u8 *
650 format_gbp_contract (u8 * s, va_list * args)
651 {
652  index_t gci = va_arg (*args, index_t);
653  vlib_counter_t counts;
654  gbp_contract_t *gc;
655  index_t *gui;
656  u16 *et;
657 
658  gc = gbp_contract_get (gci);
659 
660  s = format (s, "[%d] %U: acl-index:%d",
662 
663  s = format (s, "\n rules:");
664  vec_foreach (gui, gc->gc_rules)
665  {
666  s = format (s, "\n %d: %U", *gui, format_gbp_rule, *gui);
667  }
668 
669  s = format (s, "\n allowed-ethertypes:");
670  s = format (s, "\n [");
672  {
673  int host_et = clib_net_to_host_u16 (*et);
674  if (0 != host_et)
675  s = format (s, "0x%x, ", host_et);
676  }
677  s = format (s, "]");
678 
679  s = format (s, "\n stats:");
680  vlib_get_combined_counter (&gbp_contract_drop_counters, gci, &counts);
681  s = format (s, "\n drop:[%Ld:%Ld]", counts.packets, counts.bytes);
682  vlib_get_combined_counter (&gbp_contract_permit_counters, gci, &counts);
683  s = format (s, "\n permit:[%Ld:%Ld]", counts.packets, counts.bytes);
684 
685  s = format (s, "]");
686 
687  return (s);
688 }
689 
690 static clib_error_t *
692  unformat_input_t * input, vlib_cli_command_t * cmd)
693 {
694  gbp_contract_t *gc;
695  u32 src, dst;
696  index_t gci;
697 
698  src = dst = SCLASS_INVALID;
699 
701  {
702  if (unformat (input, "src %d", &src))
703  ;
704  else if (unformat (input, "dst %d", &dst))
705  ;
706  else
707  break;
708  }
709 
710  vlib_cli_output (vm, "Contracts:");
711 
712  /* *INDENT-OFF* */
713  pool_foreach (gc, gbp_contract_pool,
714  ({
715  gci = gc - gbp_contract_pool;
716 
717  if (SCLASS_INVALID != src && SCLASS_INVALID != dst)
718  {
719  if (gc->gc_key.gck_src == src &&
720  gc->gc_key.gck_dst == dst)
721  vlib_cli_output (vm, " %U", format_gbp_contract, gci);
722  }
723  else if (SCLASS_INVALID != src)
724  {
725  if (gc->gc_key.gck_src == src)
726  vlib_cli_output (vm, " %U", format_gbp_contract, gci);
727  }
728  else if (SCLASS_INVALID != dst)
729  {
730  if (gc->gc_key.gck_dst == dst)
731  vlib_cli_output (vm, " %U", format_gbp_contract, gci);
732  }
733  else
734  vlib_cli_output (vm, " %U", format_gbp_contract, gci);
735  }));
736  /* *INDENT-ON* */
737 
738  return (NULL);
739 }
740 
741 /*?
742  * Show Group Based Policy Contracts
743  *
744  * @cliexpar
745  * @cliexstart{show gbp contract}
746  * @cliexend
747  ?*/
748 /* *INDENT-OFF* */
749 VLIB_CLI_COMMAND (gbp_contract_show_node, static) = {
750  .path = "show gbp contract",
751  .short_help = "show gbp contract [src <SRC>] [dst <DST>]\n",
752  .function = gbp_contract_show,
753 };
754 /* *INDENT-ON* */
755 
756 static fib_node_t *
758 {
759  gbp_next_hop_t *gnh;
760 
761  gnh = gbp_next_hop_get (index);
762 
763  return (&gnh->gnh_node);
764 }
765 
766 static void
768 {
769  ASSERT (0);
770 }
771 
772 static gbp_next_hop_t *
774 {
776  return ((gbp_next_hop_t *) node);
777 }
778 
782 {
783  gbp_next_hop_t *gnh;
784 
785  gnh = gbp_next_hop_from_fib_node (node);
786 
788 
790 }
791 
792 /*
793  * The FIB path's graph node virtual function table
794  */
795 static const fib_node_vft_t gbp_next_hop_vft = {
797  .fnv_last_lock = gbp_next_hop_last_lock_gone,
798  .fnv_back_walk = gbp_next_hop_back_walk_notify,
799  // .fnv_mem_show = fib_path_memory_show,
800 };
801 
802 static clib_error_t *
804 {
805  gc_logger = vlib_log_register_class ("gbp", "con");
807 
808  return (NULL);
809 }
810 
812 
813 /*
814  * fd.io coding-style-patch-verification: ON
815  *
816  * Local Variables:
817  * eval: (c-set-style "gnu")
818  * End:
819  */
vlib_log_class_t vlib_log_register_class(char *class, char *subclass)
Definition: log.c:209
static clib_error_t * gbp_contract_show(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: gbp_contract.c:691
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:507
u16 * gc_allowed_ethertypes
An ethertype whitelist.
Definition: gbp_contract.h:152
void dpo_stack_from_node(u32 child_node_index, dpo_id_t *dpo, const dpo_id_t *parent)
Stack one DPO object on another, and thus establish a child parent relationship.
Definition: dpo.c:531
static int gbp_contract_next_hop_resolve(index_t gui, index_t gnhi)
Definition: gbp_contract.c:385
static void gbp_contract_rules_free(index_t *rules)
Definition: gbp_contract.c:111
#define vec_foreach_index(var, v)
Iterate over vector indices.
u32 gb_uu_fwd_sw_if_index
The BD&#39;s MAC spine-proxy interface (optional)
void gbp_route_domain_unlock(index_t index)
#define hash_set(h, key, value)
Definition: hash.h:255
static gbp_endpoint_t * gbp_endpoint_get(index_t gbpei)
Get the endpoint from a port/interface.
Definition: gbp_endpoint.h:265
u32 acl_index
Definition: abf.api:58
u16 sclass_t
Definition: gbp_types.h:25
A Group Based Policy Endpoint.
Definition: gbp_endpoint.h:190
fib_node_index_t path_index
The index of the FIB path.
Definition: load_balance.h:71
gbp_contract_key_t gc_key
source and destination EPGs
Definition: gbp_contract.h:139
void vlib_validate_combined_counter(vlib_combined_counter_main_t *cm, u32 index)
validate a combined counter
Definition: counter.c:108
const mac_address_t * gbp_route_domain_get_local_mac(void)
vl_api_mac_address_t mac
Definition: l2.api:502
gbp_next_hop_t * gbp_next_hop_pool
Definition: gbp_contract.c:45
#define hash_unset(h, key)
Definition: hash.h:261
fib_node_t gnh_node
Definition: gbp_contract.h:67
void gbp_endpoint_unlock(gbp_endpoint_src_t src, index_t gei)
Definition: gbp_endpoint.c:909
static fib_node_t * gbp_next_hop_get_node(fib_node_index_t index)
Definition: gbp_contract.c:757
static void gbp_contract_mk_lb(index_t gui, fib_protocol_t fproto)
Definition: gbp_contract.c:312
#define pool_get_zero(P, E)
Allocate an object E from a pool P and zero it.
Definition: pool.h:255
gbp_contract_t * gbp_contract_pool
Definition: gbp_contract.c:38
void fib_node_init(fib_node_t *node, fib_node_type_t type)
Definition: fib_node.c:185
static int dpo_id_is_valid(const dpo_id_t *dpoi)
Return true if the DPO object is valid, i.e.
Definition: dpo.h:209
vlib_log_class_t gc_logger
Definition: gbp_contract.c:40
gbp_contract_db_t gbp_contract_db
Single contract DB instance.
Definition: gbp_contract.c:36
The key for an Contract.
Definition: gbp_contract.h:48
enum fib_node_back_walk_rc_t_ fib_node_back_walk_rc_t
Return code from a back walk function.
u32 gbp_acl_user_id
Definition: gbp.h:44
u8 src_address[6]
Definition: packet.h:56
A bridge Domain Representation.
ip46_address_t gnh_ip
Definition: gbp_contract.h:68
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:590
Combined counter to hold both packets and byte differences.
Definition: counter_types.h:26
vl_api_address_t src
Definition: gre.api:54
static_always_inline void mac_address_copy(mac_address_t *dst, const mac_address_t *src)
Definition: mac_address.h:128
static clib_error_t * gbp_contract_cli(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: gbp_contract.c:579
vlib_node_registration_t gbp_policy_port_node
(constructor) VLIB_REGISTER_NODE (gbp_policy_port_node)
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
char * gbp_contract_error_strings[]
Definition: gbp_contract.c:27
EPG src,dst pair to ACL mapping table, aka contract DB.
Definition: gbp_contract.h:158
static gbp_rule_t * gbp_rule_get(index_t gui)
Definition: gbp_contract.h:217
static gbp_bridge_domain_t * gbp_bridge_domain_get(index_t i)
u8 * format_gbp_rule_action(u8 *s, va_list *args)
Definition: gbp_contract.c:171
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:263
unsigned char u8
Definition: types.h:56
fib_node_type_t fib_node_register_new_type(const fib_node_vft_t *vft)
Create a new FIB node type and Register the function table for it.
Definition: fib_node.c:80
static u8 * format_gbp_next_hop(u8 *s, va_list *args)
Definition: gbp_contract.c:155
enum fib_protocol_t_ fib_protocol_t
Protocol Type.
u32 gbp_itf_get_sw_if_index(gbp_itf_hdl_t hdl)
Definition: gbp_itf.c:148
index_t load_balance_create(u32 n_buckets, dpo_proto_t lb_proto, flow_hash_config_t fhc)
Definition: load_balance.c:239
void gbp_bridge_domain_unlock(index_t gbdi)
u32 vlib_log_class_t
Definition: vlib.h:51
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:513
#define IP_FLOW_HASH_DST_ADDR
Definition: lookup.h:62
static_always_inline void mac_address_to_bytes(const mac_address_t *mac, u8 *bytes)
Definition: mac_address.h:99
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:173
u8 dst_address[6]
Definition: packet.h:55
u16 gbp_scope_t
Definition: gbp_types.h:24
#define clib_error_return(e, args...)
Definition: error.h:99
void load_balance_multipath_update(const dpo_id_t *dpo, const load_balance_path_t *raw_nhs, load_balance_flags_t flags)
Definition: load_balance.c:602
void adj_unlock(adj_index_t adj_index)
Release a reference counting lock on the adjacency.
Definition: adj.c:325
unsigned int u32
Definition: types.h:88
enum dpo_proto_t_ dpo_proto_t
Data path protocol.
uword * gc_hash
We can form a u64 key from the pair, so use a simple hash table.
Definition: gbp_contract.h:163
The identity of a DPO is a combination of its type and its instance number/index of objects of that t...
Definition: dpo.h:170
#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:534
static void vlib_zero_combined_counter(vlib_combined_counter_main_t *cm, u32 index)
Clear a combined counter Clears the set of per-thread counters.
Definition: counter.h:285
static_always_inline void ip46_address_copy(ip46_address_t *dst, const ip46_address_t *src)
Definition: ip46_address.h:123
counter_t packets
packet counter
Definition: counter_types.h:28
static void gbp_contract_resolve(index_t *guis)
Definition: gbp_contract.c:443
#define gm
Definition: dlmalloc.c:1219
long ctx[MAX_CONNS]
Definition: main.c:144
index_t * gc_rules
The ACL to apply for packets from the source to the destination EPG.
Definition: gbp_contract.h:147
int gbp_contract_delete(gbp_scope_t scope, sclass_t sclass, sclass_t dclass)
Definition: gbp_contract.c:536
struct _unformat_input_t unformat_input_t
unsigned short u16
Definition: types.h:57
sclass_t gck_src
source and destination EPGs for which the ACL applies
Definition: gbp_contract.h:58
load-balancing over a choice of [un]equal cost paths
Definition: dpo.h:102
static void gbp_contract_mk_lbs(index_t *guis)
Definition: gbp_contract.c:454
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:302
u16 sclass
Definition: gbp.api:123
u8 * format_gbp_contract(u8 *s, va_list *args)
Definition: gbp_contract.c:650
gbp_rule_action_t gu_action
Definition: gbp_contract.h:120
static void gbp_contract_rule_resolve(index_t gui)
Definition: gbp_contract.c:427
vl_api_gbp_next_hop_t nhs[8]
Definition: gbp.api:290
#define SCLASS_INVALID
Definition: gbp_types.h:26
fib_node_type_t fn_type
The node&#39;s type.
Definition: fib_node.h:299
static u8 * format_gbp_policy_node(u8 *s, va_list *args)
Definition: gbp_contract.c:201
An node in the FIB graph.
Definition: fib_node.h:295
vl_api_address_t dst
Definition: gre.api:55
vlib_main_t * vm
Definition: in2out_ed.c:1599
int gbp_endpoint_update_and_lock(gbp_endpoint_src_t src, u32 sw_if_index, const ip46_address_t *ips, const mac_address_t *mac, index_t gbdi, index_t grdi, sclass_t sclass, gbp_endpoint_flags_t flags, const ip46_address_t *tun_src, const ip46_address_t *tun_dst, u32 *handle)
Definition: gbp_endpoint.c:813
u32 gbp_endpoint_child_add(index_t gei, fib_node_type_t type, fib_node_index_t index)
Definition: gbp_endpoint.c:990
static u8 * format_gbp_hash_mode(u8 *s, va_list *args)
Definition: gbp_contract.c:186
enum gbp_hash_mode_t_ gbp_hash_mode_t
static void gbp_next_hop_last_lock_gone(fib_node_t *node)
Definition: gbp_contract.c:767
format_function_t format_ip46_address
Definition: ip46_address.h:50
static void gbp_contract_mk_adj(gbp_next_hop_t *gnh, fib_protocol_t fproto)
Definition: gbp_contract.c:261
#define UNFORMAT_END_OF_INPUT
Definition: format.h:145
int gbp_contract_update(gbp_scope_t scope, sclass_t sclass, sclass_t dclass, u32 acl_index, index_t *rules, u16 *allowed_ethertypes, u32 *stats_index)
Definition: gbp_contract.c:465
static void vlib_get_combined_counter(const vlib_combined_counter_main_t *cm, u32 index, vlib_counter_t *result)
Get the value of a combined counter, never called in the speed path Scrapes the entire set of per-thr...
Definition: counter.h:259
u8 * format_gbp_bridge_domain(u8 *s, va_list *args)
static flow_hash_config_t gbp_contract_mk_lb_hp(gbp_hash_mode_t gu_hash_mode)
Definition: gbp_contract.c:295
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:380
fib_node_get_t fnv_get
Definition: fib_node.h:283
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:30
dpo_id_t gu_dpo[GBP_POLICY_N_NODES][FIB_PROTOCOL_IP_MAX]
DPO of the load-balance object used to redirect.
Definition: gbp_contract.h:127
static clib_error_t * acl_plugin_exports_init(acl_plugin_methods_t *m)
void dpo_set(dpo_id_t *dpo, dpo_type_t type, dpo_proto_t proto, index_t index)
Set/create a DPO ID The DPO will be locked.
Definition: dpo.c:186
vlib_main_t vlib_node_runtime_t * node
Definition: in2out_ed.c:1599
Context passed between object during a back walk.
Definition: fib_node.h:208
vl_api_fib_path_t paths[n_paths]
Definition: ip.api:146
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:152
vl_api_gbp_rule_t rules[n_rules]
Definition: gbp.api:315
mac_address_t gnh_mac
Definition: gbp_contract.h:69
#define IP_FLOW_HASH_SYMMETRIC
Definition: lookup.h:67
u32 stats_index
Definition: ip.api:143
#define FOR_EACH_GBP_POLICY_NODE(pnode)
Definition: gbp_contract.h:115
#define pool_put_index(p, i)
Free pool element with given index.
Definition: pool.h:331
#define ASSERT(truth)
#define IP_FLOW_HASH_SRC_ADDR
Flow hash configuration.
Definition: lookup.h:61
gbp_main_t gbp_main
Definition: gbp_api.c:47
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:689
vlib_node_registration_t ip4_gbp_policy_dpo_node
(constructor) VLIB_REGISTER_NODE (ip4_gbp_policy_dpo_node)
static gbp_next_hop_t * gbp_next_hop_get(index_t gui)
Definition: gbp_contract.c:105
index_t gbp_rule_alloc(gbp_rule_action_t action, gbp_hash_mode_t hash_mode, index_t *nhs)
Definition: gbp_contract.c:62
static fib_node_back_walk_rc_t gbp_next_hop_back_walk_notify(fib_node_t *node, fib_node_back_walk_ctx_t *ctx)
Definition: gbp_contract.c:780
static u8 * format_gbp_contract_key(u8 *s, va_list *args)
Definition: gbp_contract.c:640
fib_node_type_t gbp_next_hop_fib_type
Definition: gbp_contract.c:42
static gbp_contract_t * gbp_contract_get(index_t gci)
Definition: gbp_contract.h:209
dpo_proto_t fib_proto_to_dpo(fib_protocol_t fib_proto)
Definition: fib_types.c:324
u8 * format_dpo_id(u8 *s, va_list *args)
Format a DPO_id_t oject.
Definition: dpo.c:148
static gbp_next_hop_t * gbp_next_hop_from_fib_node(fib_node_t *node)
Definition: gbp_contract.c:773
u32 flow_hash_config_t
A flow hash configuration is a mask of the flow hash options.
Definition: lookup.h:84
enum gbp_rule_action_t_ gbp_rule_action_t
typedef key
Definition: ipsec_types.api:85
counter_t bytes
byte counter
Definition: counter_types.h:29
#define GBP_CONTRACT_DBG(...)
Definition: gbp_contract.c:47
#define foreach_gbp_contract_error
Definition: gbp_contract.h:22
vl_api_address_t ip
Definition: l2.api:501
#define FIB_NODE_INDEX_INVALID
Definition: fib_types.h:31
vl_api_mac_event_action_t action
Definition: l2.api:181
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
u32 path_weight
weight for the path.
Definition: load_balance.h:76
acl_plugin_methods_t acl_plugin
Definition: gbp.h:45
#define INDEX_INVALID
Invalid index - used when no index is known blazoned capitals INVALID speak volumes where ~0 does not...
Definition: dpo.h:47
gbp_scope_t gck_scope
Definition: gbp_contract.h:54
u64 uword
Definition: types.h:112
static void gbp_contract_mk_one_lb(index_t gui)
Definition: gbp_contract.c:378
#define DPO_INVALID
An initialiser for DPOs declared on the stack.
Definition: dpo.h:197
char * name
The counter collection&#39;s name.
Definition: counter.h:193
gbp_rule_t * gbp_rule_pool
Definition: gbp_contract.c:44
One path from an [EU]CMP set that the client wants to add to a load-balance object.
Definition: load_balance.h:62
A collection of combined counters.
Definition: counter.h:188
static clib_error_t * gbp_contract_init(vlib_main_t *vm)
Definition: gbp_contract.c:803
#define FOR_EACH_FIB_IP_PROTOCOL(_item)
Definition: fib_types.h:70
Group Base Policy (GBP) defines:
Definition: gbp.h:42
A FIB graph nodes virtual function table.
Definition: fib_node.h:282
enum gbp_policy_node_t_ gbp_policy_node_t
enum fib_node_type_t_ fib_node_type_t
The types of nodes in a FIB graph.
gbp_hash_mode_t gu_hash_mode
Definition: gbp_contract.h:121
u8 * format_mac_address_t(u8 *s, va_list *args)
Definition: mac_address.c:27
index_t gnh_ai[FIB_PROTOCOL_IP_MAX]
Definition: gbp_contract.h:75
vl_api_address_t ips[n_ips]
Definition: gbp.api:128
#define IP_FLOW_HASH_PROTO
Definition: lookup.h:63
void dpo_reset(dpo_id_t *dpo)
reset a DPO ID The DPO will be unlocked.
Definition: dpo.c:232
#define vec_foreach(var, vec)
Vector iterator.
vnet_link_t fib_proto_to_link(fib_protocol_t proto)
Convert from a protocol to a link type.
Definition: fib_types.c:358
u16 allowed_ethertypes[16]
Definition: gbp.api:313
u8 ge
Definition: ip_types.api:137
void gbp_contract_walk(gbp_contract_cb_t cb, void *ctx)
Definition: gbp_contract.c:565
vlib_node_registration_t ip6_gbp_policy_dpo_node
(constructor) VLIB_REGISTER_NODE (ip6_gbp_policy_dpo_node)
u16 dclass
Definition: gbp.api:310
vl_api_gbp_scope_t scope
Definition: gbp.api:74
static u8 * format_gbp_rule(u8 *s, va_list *args)
Definition: gbp_contract.c:216
index_t gbp_next_hop_alloc(const ip46_address_t *ip, index_t grd, const mac_address_t *mac, index_t gbd)
Definition: gbp_contract.c:83
index_t * gu_nhs
Definition: gbp_contract.h:122
void gbp_endpoint_child_remove(index_t gei, u32 sibling)
Definition: gbp_endpoint.c:997
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
A Group Based Policy Contract.
Definition: gbp_contract.h:134
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:171
void gbp_rule_free(index_t gui)
Definition: gbp_contract.c:77
int(* gbp_contract_cb_t)(gbp_contract_t *gbpe, void *ctx)
Definition: gbp_contract.h:182