FD.io VPP  v19.08-27-gf4dcae4
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 index_t
77 gbp_next_hop_alloc (const ip46_address_t * ip,
78  index_t grd, const mac_address_t * mac, index_t gbd)
79 {
80  fib_protocol_t fproto;
81  gbp_next_hop_t *gnh;
82 
83  pool_get_zero (gbp_next_hop_pool, gnh);
84 
86 
87  ip46_address_copy (&gnh->gnh_ip, ip);
88  mac_address_copy (&gnh->gnh_mac, mac);
89 
90  gnh->gnh_rd = grd;
91  gnh->gnh_bd = gbd;
92 
93  FOR_EACH_FIB_IP_PROTOCOL (fproto) gnh->gnh_ai[fproto] = INDEX_INVALID;
94 
95  return (gnh - gbp_next_hop_pool);
96 }
97 
98 static inline gbp_next_hop_t *
100 {
101  return (pool_elt_at_index (gbp_next_hop_pool, gui));
102 }
103 
104 static void
106 {
107  index_t *gui, *gnhi;
108 
109  vec_foreach (gui, rules)
110  {
111  gbp_policy_node_t pnode;
112  fib_protocol_t fproto;
113  gbp_next_hop_t *gnh;
114  gbp_rule_t *gu;
115 
116  gu = gbp_rule_get (*gui);
117 
119  {
120  FOR_EACH_FIB_IP_PROTOCOL (fproto)
121  {
122  dpo_reset (&gu->gu_dpo[pnode][fproto]);
123  dpo_reset (&gu->gu_dpo[pnode][fproto]);
124  }
125  }
126 
127  vec_foreach (gnhi, gu->gu_nhs)
128  {
129  fib_protocol_t fproto;
130 
131  gnh = gbp_next_hop_get (*gnhi);
135  gbp_endpoint_unlock (GBP_ENDPOINT_SRC_RR, gnh->gnh_ge);
136 
137  FOR_EACH_FIB_IP_PROTOCOL (fproto)
138  {
139  adj_unlock (gnh->gnh_ai[fproto]);
140  }
141  }
142  }
143  vec_free (rules);
144 }
145 
146 static u8 *
147 format_gbp_next_hop (u8 * s, va_list * args)
148 {
149  index_t gnhi = va_arg (*args, index_t);
150  gbp_next_hop_t *gnh;
151 
152  gnh = gbp_next_hop_get (gnhi);
153 
154  s = format (s, "%U, %U, %U EP:%d",
158 
159  return (s);
160 }
161 
162 static u8 *
163 format_gbp_rule_action (u8 * s, va_list * args)
164 {
165  gbp_rule_action_t action = va_arg (*args, gbp_rule_action_t);
166 
167  switch (action)
168  {
169 #define _(v,a) case GBP_RULE_##v: return (format (s, "%s", a));
171 #undef _
172  }
173 
174  return (format (s, "unknown"));
175 }
176 
177 static u8 *
178 format_gbp_hash_mode (u8 * s, va_list * args)
179 {
180  gbp_hash_mode_t hash_mode = va_arg (*args, gbp_hash_mode_t);
181 
182  switch (hash_mode)
183  {
184 #define _(v,a) case GBP_HASH_MODE_##v: return (format (s, "%s", a));
186 #undef _
187  }
188 
189  return (format (s, "unknown"));
190 }
191 
192 static u8 *
193 format_gbp_policy_node (u8 * s, va_list * args)
194 {
195  gbp_policy_node_t action = va_arg (*args, gbp_policy_node_t);
196 
197  switch (action)
198  {
199 #define _(v,a) case GBP_POLICY_NODE_##v: return (format (s, "%s", a));
201 #undef _
202  }
203 
204  return (format (s, "unknown"));
205 }
206 
207 static u8 *
208 format_gbp_rule (u8 * s, va_list * args)
209 {
210  index_t gui = va_arg (*args, index_t);
211  gbp_policy_node_t pnode;
212  fib_protocol_t fproto;
213  gbp_rule_t *gu;
214  index_t *gnhi;
215 
216  gu = gbp_rule_get (gui);
217  s = format (s, "%U", format_gbp_rule_action, gu->gu_action);
218 
219  switch (gu->gu_action)
220  {
221  case GBP_RULE_PERMIT:
222  case GBP_RULE_DENY:
223  return (s);
224  case GBP_RULE_REDIRECT:
225  s = format (s, ", %U", format_gbp_hash_mode, gu->gu_hash_mode);
226  break;
227  }
228 
229  vec_foreach (gnhi, gu->gu_nhs)
230  {
231  s = format (s, "\n [%U]", format_gbp_next_hop, *gnhi);
232  }
233 
235  {
236  s = format (s, "\n policy-%U", format_gbp_policy_node, pnode);
237 
238  FOR_EACH_FIB_IP_PROTOCOL (fproto)
239  {
240  if (dpo_id_is_valid (&gu->gu_dpo[pnode][fproto]))
241  {
242  s =
243  format (s, "\n %U", format_dpo_id,
244  &gu->gu_dpo[pnode][fproto], 8);
245  }
246  }
247  }
248 
249  return (s);
250 }
251 
252 static void
254 {
255  ethernet_header_t *eth;
257  index_t old_ai;
258  u8 *rewrite;
259 
260  old_ai = gnh->gnh_ai[fproto];
261  rewrite = NULL;
262  vec_validate (rewrite, sizeof (*eth) - 1);
263  eth = (ethernet_header_t *) rewrite;
264 
265  GBP_CONTRACT_DBG ("...mk-adj: %U", format_gbp_next_hop,
266  gnh - gbp_next_hop_pool);
267 
268  ge = gbp_endpoint_get (gnh->gnh_ge);
269 
270  eth->type = clib_host_to_net_u16 ((fproto == FIB_PROTOCOL_IP4 ?
271  ETHERNET_TYPE_IP4 : ETHERNET_TYPE_IP6));
274 
275  gnh->gnh_ai[fproto] =
277  fib_proto_to_link (fproto),
278  &gnh->gnh_ip,
280  ge_fwd.gef_itf),
281  rewrite);
282 
283  adj_unlock (old_ai);
284 }
285 
286 static flow_hash_config_t
288 {
289  switch (gu_hash_mode)
290  {
291  case GBP_HASH_MODE_SRC_IP:
292  return IP_FLOW_HASH_SRC_ADDR;
293  case GBP_HASH_MODE_DST_IP:
294  return IP_FLOW_HASH_DST_ADDR;
295  case GBP_HASH_MODE_SYMMETRIC:
298  }
299 
300  return 0;
301 }
302 
303 static void
305 {
307  gbp_policy_node_t pnode;
308  gbp_next_hop_t *gnh;
309  dpo_proto_t dproto;
310  gbp_rule_t *gu;
311  u32 ii;
312 
313  u32 policy_nodes[] = {
314  [GBP_POLICY_NODE_L2] = gbp_policy_port_node.index,
315  [GBP_POLICY_NODE_IP4] = ip4_gbp_policy_dpo_node.index,
316  [GBP_POLICY_NODE_IP6] = ip6_gbp_policy_dpo_node.index,
317  };
318 
319  GBP_CONTRACT_DBG ("..mk-lb: %U", format_gbp_rule, gui);
320 
321  gu = gbp_rule_get (gui);
322  dproto = fib_proto_to_dpo (fproto);
323 
324  if (GBP_RULE_REDIRECT != gu->gu_action)
325  return;
326 
327  vec_foreach_index (ii, gu->gu_nhs)
328  {
329  gnh = gbp_next_hop_get (gu->gu_nhs[ii]);
330 
333  }
334 
336  {
337  vec_validate (paths, vec_len (gu->gu_nhs) - 1);
338 
339  vec_foreach_index (ii, gu->gu_nhs)
340  {
341  gnh = gbp_next_hop_get (gu->gu_nhs[ii]);
342 
344  paths[ii].path_weight = 1;
345  dpo_set (&paths[ii].path_dpo, DPO_ADJACENCY,
346  dproto, gnh->gnh_ai[fproto]);
347  }
348 
349  if (!dpo_id_is_valid (&gu->gu_dpo[pnode][fproto]))
350  {
351  dpo_id_t dpo = DPO_INVALID;
352 
353  dpo_set (&dpo, DPO_LOAD_BALANCE, dproto,
354  load_balance_create (vec_len (paths),
355  dproto,
357  (gu->gu_hash_mode)));
358  dpo_stack_from_node (policy_nodes[pnode], &gu->gu_dpo[pnode][fproto],
359  &dpo);
360  dpo_reset (&dpo);
361  }
362 
363  load_balance_multipath_update (&gu->gu_dpo[pnode][fproto],
364  paths, LOAD_BALANCE_FLAG_NONE);
365  vec_free (paths);
366  }
367 }
368 
369 static void
371 {
374 }
375 
376 static int
378 {
379  gbp_bridge_domain_t *gbd;
380  gbp_next_hop_t *gnh;
381  ip46_address_t *ips;
382  int rv;
383 
384  ips = NULL;
385  gnh = gbp_next_hop_get (gnhi);
386  gbd = gbp_bridge_domain_get (gnh->gnh_bd);
387 
388  gnh->gnh_gu = gui;
389  vec_add1 (ips, gnh->gnh_ip);
390 
391  /*
392  * source the endpoint this contract needs to forward via.
393  * give ofrwarding details via the spine proxy. if this EP is known
394  * to us, then since we source here with a low priority, the learned
395  * info will take precedenc.
396  */
397  rv = gbp_endpoint_update_and_lock (GBP_ENDPOINT_SRC_RR,
399  ips,
400  &gnh->gnh_mac,
401  gnh->gnh_bd, gnh->gnh_rd, SCLASS_INVALID,
403  &gnh->gnh_ge);
404 
405  if (0 == rv)
406  {
408  gbp_next_hop_fib_type, gnhi);
409  }
410 
411  GBP_CONTRACT_DBG ("..resolve: %d: %d: %U", gui, gnhi, format_gbp_next_hop,
412  gnhi);
413 
414  vec_free (ips);
415  return (rv);
416 }
417 
418 static void
420 {
421  gbp_rule_t *gu;
422  index_t *gnhi;
423 
424  gu = gbp_rule_get (gui);
425 
426  GBP_CONTRACT_DBG ("..resolve: %U", format_gbp_rule, gui);
427 
428  vec_foreach (gnhi, gu->gu_nhs)
429  {
430  gbp_contract_next_hop_resolve (gui, *gnhi);
431  }
432 }
433 
434 static void
436 {
437  index_t *gui;
438 
439  vec_foreach (gui, guis)
440  {
442  }
443 }
444 
445 static void
447 {
448  index_t *gui;
449 
450  vec_foreach (gui, guis)
451  {
452  gbp_contract_mk_one_lb (*gui);
453  }
454 }
455 
456 int
460  u32 acl_index,
461  index_t * rules,
462  u16 * allowed_ethertypes, u32 * stats_index)
463 {
464  gbp_main_t *gm = &gbp_main;
465  u32 *acl_vec = NULL;
466  gbp_contract_t *gc;
467  index_t gci;
468  uword *p;
469 
471  .gck_scope = scope,
472  .gck_src = sclass,
473  .gck_dst = dclass,
474  };
475 
476  if (~0 == gm->gbp_acl_user_id)
477  {
479  gm->gbp_acl_user_id =
480  gm->acl_plugin.register_user_module ("GBP ACL", "src-epg", "dst-epg");
481  }
482 
483  p = hash_get (gbp_contract_db.gc_hash, key.as_u64);
484  if (p != NULL)
485  {
486  gci = p[0];
487  gc = gbp_contract_get (gci);
489  gbp_main.acl_plugin.put_lookup_context_index (gc->gc_lc_index);
490  gc->gc_rules = NULL;
492  }
493  else
494  {
495  pool_get_zero (gbp_contract_pool, gc);
496  gc->gc_key = key;
497  gci = gc - gbp_contract_pool;
498  hash_set (gbp_contract_db.gc_hash, key.as_u64, gci);
499 
500  vlib_validate_combined_counter (&gbp_contract_drop_counters, gci);
501  vlib_zero_combined_counter (&gbp_contract_drop_counters, gci);
502  vlib_validate_combined_counter (&gbp_contract_permit_counters, gci);
503  vlib_zero_combined_counter (&gbp_contract_permit_counters, gci);
504  }
505 
506  GBP_CONTRACT_DBG ("update: %U", format_gbp_contract, gci);
507 
508  gc->gc_rules = rules;
512 
513  gc->gc_acl_index = acl_index;
514  gc->gc_lc_index =
515  gm->acl_plugin.get_lookup_context_index (gm->gbp_acl_user_id,
516  sclass, dclass);
517 
518  vec_add1 (acl_vec, gc->gc_acl_index);
519  gm->acl_plugin.set_acl_vec_for_context (gc->gc_lc_index, acl_vec);
520  vec_free (acl_vec);
521 
522  *stats_index = gci;
523 
524  return (0);
525 }
526 
527 int
529 {
531  .gck_scope = scope,
532  .gck_src = sclass,
533  .gck_dst = dclass,
534  };
535  gbp_contract_t *gc;
536  uword *p;
537 
538  p = hash_get (gbp_contract_db.gc_hash, key.as_u64);
539  if (p != NULL)
540  {
541  gc = gbp_contract_get (p[0]);
542 
544  gbp_main.acl_plugin.put_lookup_context_index (gc->gc_lc_index);
546 
547  hash_unset (gbp_contract_db.gc_hash, key.as_u64);
548  pool_put (gbp_contract_pool, gc);
549 
550  return (0);
551  }
552 
553  return (VNET_API_ERROR_NO_SUCH_ENTRY);
554 }
555 
556 void
558 {
559  gbp_contract_t *gc;
560 
561  /* *INDENT-OFF* */
562  pool_foreach(gc, gbp_contract_pool,
563  ({
564  if (!cb(gc, ctx))
565  break;
566  }));
567  /* *INDENT-ON* */
568 }
569 
570 static clib_error_t *
572  unformat_input_t * input, vlib_cli_command_t * cmd)
573 {
575  u32 acl_index = ~0, stats_index, scope;
576  u8 add = 1;
577 
579  {
580  if (unformat (input, "add"))
581  add = 1;
582  else if (unformat (input, "del"))
583  add = 0;
584  else if (unformat (input, "scope %d", &scope))
585  ;
586  else if (unformat (input, "sclass %d", &sclass))
587  ;
588  else if (unformat (input, "dclass %d", &dclass))
589  ;
590  else if (unformat (input, "acl-index %d", &acl_index))
591  ;
592  else
593  break;
594  }
595 
596  if (SCLASS_INVALID == sclass)
597  return clib_error_return (0, "Source EPG-ID must be specified");
598  if (SCLASS_INVALID == dclass)
599  return clib_error_return (0, "Destination EPG-ID must be specified");
600 
601  if (add)
602  {
603  gbp_contract_update (scope, sclass, dclass, acl_index,
604  NULL, NULL, &stats_index);
605  }
606  else
607  {
608  gbp_contract_delete (scope, sclass, dclass);
609  }
610 
611  return (NULL);
612 }
613 
614 /*?
615  * Configure a GBP Contract
616  *
617  * @cliexpar
618  * @cliexstart{set gbp contract [del] src-epg <ID> dst-epg <ID> acl-index <ACL>}
619  * @cliexend
620  ?*/
621 /* *INDENT-OFF* */
622 VLIB_CLI_COMMAND (gbp_contract_cli_node, static) =
623 {
624  .path = "gbp contract",
625  .short_help =
626  "gbp contract [del] src-epg <ID> dst-epg <ID> acl-index <ACL>",
627  .function = gbp_contract_cli,
628 };
629 /* *INDENT-ON* */
630 
631 static u8 *
632 format_gbp_contract_key (u8 * s, va_list * args)
633 {
634  gbp_contract_key_t *gck = va_arg (*args, gbp_contract_key_t *);
635 
636  s = format (s, "{%d,%d,%d}", gck->gck_scope, gck->gck_src, gck->gck_dst);
637 
638  return (s);
639 }
640 
641 u8 *
642 format_gbp_contract (u8 * s, va_list * args)
643 {
644  index_t gci = va_arg (*args, index_t);
645  vlib_counter_t counts;
646  gbp_contract_t *gc;
647  index_t *gui;
648  u16 *et;
649 
650  gc = gbp_contract_get (gci);
651 
652  s = format (s, "[%d] %U: acl-index:%d",
654 
655  s = format (s, "\n rules:");
656  vec_foreach (gui, gc->gc_rules)
657  {
658  s = format (s, "\n %d: %U", *gui, format_gbp_rule, *gui);
659  }
660 
661  s = format (s, "\n allowed-ethertypes:");
662  s = format (s, "\n [");
664  {
665  int host_et = clib_net_to_host_u16 (*et);
666  if (0 != host_et)
667  s = format (s, "0x%x, ", host_et);
668  }
669  s = format (s, "]");
670 
671  s = format (s, "\n stats:");
672  vlib_get_combined_counter (&gbp_contract_drop_counters, gci, &counts);
673  s = format (s, "\n drop:[%Ld:%Ld]", counts.packets, counts.bytes);
674  vlib_get_combined_counter (&gbp_contract_permit_counters, gci, &counts);
675  s = format (s, "\n permit:[%Ld:%Ld]", counts.packets, counts.bytes);
676 
677  s = format (s, "]");
678 
679  return (s);
680 }
681 
682 static clib_error_t *
684  unformat_input_t * input, vlib_cli_command_t * cmd)
685 {
686  gbp_contract_t *gc;
687  u32 src, dst;
688  index_t gci;
689 
690  src = dst = SCLASS_INVALID;
691 
693  {
694  if (unformat (input, "src %d", &src))
695  ;
696  else if (unformat (input, "dst %d", &dst))
697  ;
698  else
699  break;
700  }
701 
702  vlib_cli_output (vm, "Contracts:");
703 
704  /* *INDENT-OFF* */
705  pool_foreach (gc, gbp_contract_pool,
706  ({
707  gci = gc - gbp_contract_pool;
708 
709  if (SCLASS_INVALID != src && SCLASS_INVALID != dst)
710  {
711  if (gc->gc_key.gck_src == src &&
712  gc->gc_key.gck_dst == dst)
713  vlib_cli_output (vm, " %U", format_gbp_contract, gci);
714  }
715  else if (SCLASS_INVALID != src)
716  {
717  if (gc->gc_key.gck_src == src)
718  vlib_cli_output (vm, " %U", format_gbp_contract, gci);
719  }
720  else if (SCLASS_INVALID != dst)
721  {
722  if (gc->gc_key.gck_dst == dst)
723  vlib_cli_output (vm, " %U", format_gbp_contract, gci);
724  }
725  else
726  vlib_cli_output (vm, " %U", format_gbp_contract, gci);
727  }));
728  /* *INDENT-ON* */
729 
730  return (NULL);
731 }
732 
733 /*?
734  * Show Group Based Policy Contracts
735  *
736  * @cliexpar
737  * @cliexstart{show gbp contract}
738  * @cliexend
739  ?*/
740 /* *INDENT-OFF* */
741 VLIB_CLI_COMMAND (gbp_contract_show_node, static) = {
742  .path = "show gbp contract",
743  .short_help = "show gbp contract [src <SRC>] [dst <DST>]\n",
744  .function = gbp_contract_show,
745 };
746 /* *INDENT-ON* */
747 
748 static fib_node_t *
750 {
751  gbp_next_hop_t *gnh;
752 
753  gnh = gbp_next_hop_get (index);
754 
755  return (&gnh->gnh_node);
756 }
757 
758 static void
760 {
761  ASSERT (0);
762 }
763 
764 static gbp_next_hop_t *
766 {
768  return ((gbp_next_hop_t *) node);
769 }
770 
774 {
775  gbp_next_hop_t *gnh;
776 
777  gnh = gbp_next_hop_from_fib_node (node);
778 
780 
782 }
783 
784 /*
785  * The FIB path's graph node virtual function table
786  */
787 static const fib_node_vft_t gbp_next_hop_vft = {
789  .fnv_last_lock = gbp_next_hop_last_lock_gone,
790  .fnv_back_walk = gbp_next_hop_back_walk_notify,
791  // .fnv_mem_show = fib_path_memory_show,
792 };
793 
794 static clib_error_t *
796 {
797  gc_logger = vlib_log_register_class ("gbp", "con");
799 
800  return (NULL);
801 }
802 
804 
805 /*
806  * fd.io coding-style-patch-verification: ON
807  *
808  * Local Variables:
809  * eval: (c-set-style "gnu")
810  * End:
811  */
vlib_log_class_t vlib_log_register_class(char *class, char *subclass)
Definition: log.c:176
static clib_error_t * gbp_contract_show(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: gbp_contract.c:683
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:439
u16 * gc_allowed_ethertypes
An ethertype whitelist.
Definition: gbp_contract.h:151
u32 acl_index
Definition: gbp.api:310
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:377
static void gbp_contract_rules_free(index_t *rules)
Definition: gbp_contract.c:105
#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
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:138
void vlib_validate_combined_counter(vlib_combined_counter_main_t *cm, u32 index)
validate a combined counter
Definition: counter.c:94
const mac_address_t * gbp_route_domain_get_local_mac(void)
vl_api_mac_address_t mac
Definition: l2.api:490
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:66
void gbp_endpoint_unlock(gbp_endpoint_src_t src, index_t gei)
Definition: gbp_endpoint.c:918
static fib_node_t * gbp_next_hop_get_node(fib_node_index_t index)
Definition: gbp_contract.c:749
static void gbp_contract_mk_lb(index_t gui, fib_protocol_t fproto)
Definition: gbp_contract.c:304
#define pool_get_zero(P, E)
Allocate an object E from a pool P and zero it.
Definition: pool.h:239
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
#define NULL
Definition: clib.h:58
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:47
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:67
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:522
Combined counter to hold both packets and byte differences.
Definition: counter_types.h:26
vl_api_address_t src
Definition: gre.api:51
static_always_inline void mac_address_copy(mac_address_t *dst, const mac_address_t *src)
Definition: mac_address.h:128
format_function_t format_ip46_address
Definition: format.h:61
static clib_error_t * gbp_contract_cli(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: gbp_contract.c:571
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:157
static gbp_rule_t * gbp_rule_get(index_t gui)
Definition: gbp_contract.h:214
static gbp_bridge_domain_t * gbp_bridge_domain_get(index_t i)
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:147
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:493
#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:318
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:162
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:514
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
counter_t packets
packet counter
Definition: counter_types.h:28
static void gbp_contract_resolve(index_t *guis)
Definition: gbp_contract.c:435
#define gm
Definition: dlmalloc.c:1217
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:146
int gbp_contract_delete(gbp_scope_t scope, sclass_t sclass, sclass_t dclass)
Definition: gbp_contract.c:528
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:57
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:446
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:286
u16 sclass
Definition: gbp.api:122
u8 * format_gbp_contract(u8 *s, va_list *args)
Definition: gbp_contract.c:642
gbp_rule_action_t gu_action
Definition: gbp_contract.h:119
static void gbp_contract_rule_resolve(index_t gui)
Definition: gbp_contract.c:419
vl_api_gbp_next_hop_t nhs[8]
Definition: gbp.api:289
#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:193
An node in the FIB graph.
Definition: fib_node.h:295
vl_api_address_t dst
Definition: gre.api:52
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:822
u32 gbp_endpoint_child_add(index_t gei, fib_node_type_t type, fib_node_index_t index)
Definition: gbp_endpoint.c:999
static u8 * format_gbp_hash_mode(u8 *s, va_list *args)
Definition: gbp_contract.c:178
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:759
static void gbp_contract_mk_adj(gbp_next_hop_t *gnh, fib_protocol_t fproto)
Definition: gbp_contract.c:253
#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:457
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
vlib_main_t * vm
Definition: buffer.c:312
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:287
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:341
fib_node_get_t fnv_get
Definition: fib_node.h:283
static_always_inline void ip46_address_copy(ip46_address_t *dst, const ip46_address_t *src)
Definition: ip6_packet.h:114
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:126
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
Context passed between object during a back walk.
Definition: fib_node.h:208
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:155
vl_api_gbp_rule_t rules[n_rules]
Definition: gbp.api:314
mac_address_t gnh_mac
Definition: gbp_contract.h:68
#define IP_FLOW_HASH_SYMMETRIC
Definition: lookup.h:67
#define FOR_EACH_GBP_POLICY_NODE(pnode)
Definition: gbp_contract.h:114
#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:88
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:99
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:772
static u8 * format_gbp_contract_key(u8 *s, va_list *args)
Definition: gbp_contract.c:632
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:206
dpo_proto_t fib_proto_to_dpo(fib_protocol_t fib_proto)
Definition: fib_types.c:237
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:765
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
vl_api_mfib_path_t paths[n_paths]
Definition: ip.api:458
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:489
#define FIB_NODE_INDEX_INVALID
Definition: fib_types.h:31
#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:53
static u8 * format_gbp_rule_action(u8 *s, va_list *args)
Definition: gbp_contract.c:163
u64 uword
Definition: types.h:112
typedef key
Definition: ipsec.api:245
static void gbp_contract_mk_one_lb(index_t gui)
Definition: gbp_contract.c:370
#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:795
#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:120
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:74
vl_api_address_t ips[n_ips]
Definition: gbp.api:127
#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:271
u16 allowed_ethertypes[16]
Definition: gbp.api:312
u8 ge
Definition: ip_types.api:135
void gbp_contract_walk(gbp_contract_cb_t cb, void *ctx)
Definition: gbp_contract.c:557
vlib_node_registration_t ip6_gbp_policy_dpo_node
(constructor) VLIB_REGISTER_NODE (ip6_gbp_policy_dpo_node)
u16 dclass
Definition: gbp.api:309
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:768
vl_api_gbp_scope_t scope
Definition: gbp.api:73
static u8 * format_gbp_rule(u8 *s, va_list *args)
Definition: gbp_contract.c:208
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:77
index_t * gu_nhs
Definition: gbp_contract.h:121
void gbp_endpoint_child_remove(index_t gei, u32 sibling)
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
A Group Based Policy Contract.
Definition: gbp_contract.h:133
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:171
int(* gbp_contract_cb_t)(gbp_contract_t *gbpe, void *ctx)
Definition: gbp_contract.h:180