FD.io VPP  v19.04.1-1-ge4a0f9f
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>
22 
23 #include <vnet/dpo/load_balance.h>
24 #include <vnet/dpo/drop_dpo.h>
25 
26 /**
27  * Single contract DB instance
28  */
30 
32 
34 
36 
39 
40 #define GBP_CONTRACT_DBG(...) \
41  vlib_log_notice (gc_logger, __VA_ARGS__);
42 
43 /* Adjacency packet/byte counters indexed by adjacency index. */
44 vlib_combined_counter_main_t gbp_contract_permit_counters = {
45  .name = "gbp-contracts-permit",
46  .stat_segment_name = "/net/gbp/contract/permit",
47 };
48 
49 vlib_combined_counter_main_t gbp_contract_drop_counters = {
50  .name = "gbp-contracts-drop",
51  .stat_segment_name = "/net/gbp/contract/drop",
52 };
53 
54 index_t
56  gbp_hash_mode_t hash_mode, index_t * nhs)
57 {
58  gbp_rule_t *gu;
59 
60  pool_get_zero (gbp_rule_pool, gu);
61 
62  gu->gu_hash_mode = hash_mode;
63  gu->gu_nhs = nhs;
64  gu->gu_action = action;
65 
66  return (gu - gbp_rule_pool);
67 }
68 
69 index_t
70 gbp_next_hop_alloc (const ip46_address_t * ip,
71  index_t grd, const mac_address_t * mac, index_t gbd)
72 {
73  fib_protocol_t fproto;
74  gbp_next_hop_t *gnh;
75 
76  pool_get_zero (gbp_next_hop_pool, gnh);
77 
79 
80  ip46_address_copy (&gnh->gnh_ip, ip);
81  mac_address_copy (&gnh->gnh_mac, mac);
82 
83  gnh->gnh_rd = grd;
84  gnh->gnh_bd = gbd;
85 
86  FOR_EACH_FIB_IP_PROTOCOL (fproto) gnh->gnh_ai[fproto] = INDEX_INVALID;
87 
88  return (gnh - gbp_next_hop_pool);
89 }
90 
91 static inline gbp_next_hop_t *
93 {
94  return (pool_elt_at_index (gbp_next_hop_pool, gui));
95 }
96 
97 static void
99 {
100  index_t *gui, *gnhi;
101 
102  vec_foreach (gui, rules)
103  {
104  gbp_policy_node_t pnode;
105  fib_protocol_t fproto;
106  gbp_next_hop_t *gnh;
107  gbp_rule_t *gu;
108 
109  gu = gbp_rule_get (*gui);
110 
112  {
113  FOR_EACH_FIB_IP_PROTOCOL (fproto)
114  {
115  dpo_reset (&gu->gu_dpo[pnode][fproto]);
116  dpo_reset (&gu->gu_dpo[pnode][fproto]);
117  }
118  }
119 
120  vec_foreach (gnhi, gu->gu_nhs)
121  {
122  fib_protocol_t fproto;
123 
124  gnh = gbp_next_hop_get (*gnhi);
128  gbp_endpoint_unlock (GBP_ENDPOINT_SRC_RR, gnh->gnh_ge);
129 
130  FOR_EACH_FIB_IP_PROTOCOL (fproto)
131  {
132  adj_unlock (gnh->gnh_ai[fproto]);
133  }
134  }
135  }
136  vec_free (rules);
137 }
138 
139 static u8 *
140 format_gbp_next_hop (u8 * s, va_list * args)
141 {
142  index_t gnhi = va_arg (*args, index_t);
143  gbp_next_hop_t *gnh;
144 
145  gnh = gbp_next_hop_get (gnhi);
146 
147  s = format (s, "%U, %U, %U EP:%d",
151 
152  return (s);
153 }
154 
155 static u8 *
156 format_gbp_rule_action (u8 * s, va_list * args)
157 {
158  gbp_rule_action_t action = va_arg (*args, gbp_rule_action_t);
159 
160  switch (action)
161  {
162 #define _(v,a) case GBP_RULE_##v: return (format (s, "%s", a));
164 #undef _
165  }
166 
167  return (format (s, "unknown"));
168 }
169 
170 static u8 *
171 format_gbp_hash_mode (u8 * s, va_list * args)
172 {
173  gbp_hash_mode_t hash_mode = va_arg (*args, gbp_hash_mode_t);
174 
175  switch (hash_mode)
176  {
177 #define _(v,a) case GBP_HASH_MODE_##v: return (format (s, "%s", a));
179 #undef _
180  }
181 
182  return (format (s, "unknown"));
183 }
184 
185 static u8 *
186 format_gbp_policy_node (u8 * s, va_list * args)
187 {
188  gbp_policy_node_t action = va_arg (*args, gbp_policy_node_t);
189 
190  switch (action)
191  {
192 #define _(v,a) case GBP_POLICY_NODE_##v: return (format (s, "%s", a));
194 #undef _
195  }
196 
197  return (format (s, "unknown"));
198 }
199 
200 static u8 *
201 format_gbp_rule (u8 * s, va_list * args)
202 {
203  index_t gui = va_arg (*args, index_t);
204  gbp_policy_node_t pnode;
205  fib_protocol_t fproto;
206  gbp_rule_t *gu;
207  index_t *gnhi;
208 
209  gu = gbp_rule_get (gui);
210  s = format (s, "%U", format_gbp_rule_action, gu->gu_action);
211 
212  switch (gu->gu_action)
213  {
214  case GBP_RULE_PERMIT:
215  case GBP_RULE_DENY:
216  break;
217  case GBP_RULE_REDIRECT:
218  s = format (s, ", %U", format_gbp_hash_mode, gu->gu_hash_mode);
219  break;
220  }
221 
222  vec_foreach (gnhi, gu->gu_nhs)
223  {
224  s = format (s, "\n [%U]", format_gbp_next_hop, *gnhi);
225  }
226 
228  {
229  s = format (s, "\n policy-%U", format_gbp_policy_node, pnode);
230 
231  FOR_EACH_FIB_IP_PROTOCOL (fproto)
232  {
233  if (dpo_id_is_valid (&gu->gu_dpo[pnode][fproto]))
234  {
235  s =
236  format (s, "\n %U", format_dpo_id,
237  &gu->gu_dpo[pnode][fproto], 8);
238  }
239  }
240  }
241 
242  return (s);
243 }
244 
245 static void
247 {
248  ethernet_header_t *eth;
249  gbp_endpoint_t *ge;
250  index_t old_ai;
251  u8 *rewrite;
252 
253  old_ai = gnh->gnh_ai[fproto];
254  rewrite = NULL;
255  vec_validate (rewrite, sizeof (*eth) - 1);
256  eth = (ethernet_header_t *) rewrite;
257 
258  GBP_CONTRACT_DBG ("...mk-adj: %U", format_gbp_next_hop,
259  gnh - gbp_next_hop_pool);
260 
261  ge = gbp_endpoint_get (gnh->gnh_ge);
262 
263  eth->type = clib_host_to_net_u16 ((fproto == FIB_PROTOCOL_IP4 ?
264  ETHERNET_TYPE_IP4 : ETHERNET_TYPE_IP6));
267 
268  gnh->gnh_ai[fproto] =
270  fib_proto_to_link (fproto),
271  &gnh->gnh_ip, ge->ge_fwd.gef_itf, rewrite);
272 
273  adj_unlock (old_ai);
274 }
275 
276 static flow_hash_config_t
278 {
279  switch (gu_hash_mode)
280  {
281  case GBP_HASH_MODE_SRC_IP:
282  return IP_FLOW_HASH_SRC_ADDR;
283  case GBP_HASH_MODE_DST_IP:
284  return IP_FLOW_HASH_DST_ADDR;
285  case GBP_HASH_MODE_SYMMETRIC:
288  }
289 
290  return 0;
291 }
292 
293 static void
295 {
296  load_balance_path_t *paths = NULL;
297  gbp_policy_node_t pnode;
298  gbp_next_hop_t *gnh;
299  dpo_proto_t dproto;
300  gbp_rule_t *gu;
301  u32 ii;
302 
303  u32 policy_nodes[] = {
304  [GBP_POLICY_NODE_L2] = gbp_policy_port_node.index,
305  [GBP_POLICY_NODE_IP4] = ip4_gbp_policy_dpo_node.index,
306  [GBP_POLICY_NODE_IP6] = ip6_gbp_policy_dpo_node.index,
307  };
308 
309  GBP_CONTRACT_DBG ("..mk-lb: %U", format_gbp_rule, gui);
310 
311  gu = gbp_rule_get (gui);
312  dproto = fib_proto_to_dpo (fproto);
313 
314  if (GBP_RULE_REDIRECT != gu->gu_action)
315  return;
316 
317  vec_foreach_index (ii, gu->gu_nhs)
318  {
319  gnh = gbp_next_hop_get (gu->gu_nhs[ii]);
320 
323  }
324 
326  {
327  vec_validate (paths, vec_len (gu->gu_nhs) - 1);
328 
329  vec_foreach_index (ii, gu->gu_nhs)
330  {
331  gnh = gbp_next_hop_get (gu->gu_nhs[ii]);
332 
334  paths[ii].path_weight = 1;
335  dpo_set (&paths[ii].path_dpo, DPO_ADJACENCY,
336  dproto, gnh->gnh_ai[fproto]);
337  }
338 
339  if (!dpo_id_is_valid (&gu->gu_dpo[pnode][fproto]))
340  {
341  dpo_id_t dpo = DPO_INVALID;
342 
343  dpo_set (&dpo, DPO_LOAD_BALANCE, dproto,
344  load_balance_create (vec_len (paths),
345  dproto,
347  (gu->gu_hash_mode)));
348  dpo_stack_from_node (policy_nodes[pnode], &gu->gu_dpo[pnode][fproto],
349  &dpo);
350  dpo_reset (&dpo);
351  }
352 
353  load_balance_multipath_update (&gu->gu_dpo[pnode][fproto],
354  paths, LOAD_BALANCE_FLAG_NONE);
355  vec_free (paths);
356  }
357 }
358 
359 static void
361 {
364 }
365 
366 static int
368 {
369  gbp_bridge_domain_t *gbd;
370  gbp_next_hop_t *gnh;
371  ip46_address_t *ips;
372  int rv;
373 
374  ips = NULL;
375  gnh = gbp_next_hop_get (gnhi);
376  gbd = gbp_bridge_domain_get (gnh->gnh_bd);
377 
378  gnh->gnh_gu = gui;
379  vec_add1 (ips, gnh->gnh_ip);
380 
381  /*
382  * source the endpoint this contract needs to forward via.
383  * give ofrwarding details via the spine proxy. if this EP is known
384  * to us, then since we source here with a low priority, the learned
385  * info will take precedenc.
386  */
387  rv = gbp_endpoint_update_and_lock (GBP_ENDPOINT_SRC_RR,
389  ips,
390  &gnh->gnh_mac,
391  gnh->gnh_bd, gnh->gnh_rd, SCLASS_INVALID,
393  &gnh->gnh_ge);
394 
395  if (0 == rv)
396  {
398  gbp_next_hop_fib_type, gnhi);
399  }
400 
401  GBP_CONTRACT_DBG ("..resolve: %d: %d: %U", gui, gnhi, format_gbp_next_hop,
402  gnhi);
403 
404  vec_free (ips);
405  return (rv);
406 }
407 
408 static void
410 {
411  gbp_rule_t *gu;
412  index_t *gnhi;
413 
414  gu = gbp_rule_get (gui);
415 
416  GBP_CONTRACT_DBG ("..resolve: %U", format_gbp_rule, gui);
417 
418  vec_foreach (gnhi, gu->gu_nhs)
419  {
420  gbp_contract_next_hop_resolve (gui, *gnhi);
421  }
422 }
423 
424 static void
426 {
427  index_t *gui;
428 
429  vec_foreach (gui, guis)
430  {
432  }
433 }
434 
435 static void
437 {
438  index_t *gui;
439 
440  vec_foreach (gui, guis)
441  {
442  gbp_contract_mk_one_lb (*gui);
443  }
444 }
445 
446 int
449  u32 acl_index,
450  index_t * rules,
451  u16 * allowed_ethertypes, u32 * stats_index)
452 {
453  gbp_main_t *gm = &gbp_main;
454  u32 *acl_vec = NULL;
455  gbp_contract_t *gc;
456  index_t gci;
457  uword *p;
458 
460  .gck_src = sclass,
461  .gck_dst = dclass,
462  };
463 
464  if (~0 == gm->gbp_acl_user_id)
465  {
467  gm->gbp_acl_user_id =
468  gm->acl_plugin.register_user_module ("GBP ACL", "src-epg", "dst-epg");
469  }
470 
471  p = hash_get (gbp_contract_db.gc_hash, key.as_u32);
472  if (p != NULL)
473  {
474  gci = p[0];
475  gc = gbp_contract_get (gci);
477  gbp_main.acl_plugin.put_lookup_context_index (gc->gc_lc_index);
478  gc->gc_rules = NULL;
480  }
481  else
482  {
483  pool_get_zero (gbp_contract_pool, gc);
484  gc->gc_key = key;
485  gci = gc - gbp_contract_pool;
486  hash_set (gbp_contract_db.gc_hash, key.as_u32, gci);
487 
488  vlib_validate_combined_counter (&gbp_contract_drop_counters, gci);
489  vlib_zero_combined_counter (&gbp_contract_drop_counters, gci);
490  vlib_validate_combined_counter (&gbp_contract_permit_counters, gci);
491  vlib_zero_combined_counter (&gbp_contract_permit_counters, gci);
492  }
493 
494  GBP_CONTRACT_DBG ("update: %U", format_gbp_contract, gci);
495 
496  gc->gc_rules = rules;
500 
501  gc->gc_acl_index = acl_index;
502  gc->gc_lc_index =
503  gm->acl_plugin.get_lookup_context_index (gm->gbp_acl_user_id,
504  sclass, dclass);
505 
506  vec_add1 (acl_vec, gc->gc_acl_index);
507  gm->acl_plugin.set_acl_vec_for_context (gc->gc_lc_index, acl_vec);
508  vec_free (acl_vec);
509 
510  *stats_index = gci;
511 
512  return (0);
513 }
514 
515 int
517 {
519  .gck_src = sclass,
520  .gck_dst = dclass,
521  };
522  gbp_contract_t *gc;
523  uword *p;
524 
525  p = hash_get (gbp_contract_db.gc_hash, key.as_u32);
526  if (p != NULL)
527  {
528  gc = gbp_contract_get (p[0]);
529 
531  gbp_main.acl_plugin.put_lookup_context_index (gc->gc_lc_index);
533 
534  hash_unset (gbp_contract_db.gc_hash, key.as_u32);
535  pool_put (gbp_contract_pool, gc);
536 
537  return (0);
538  }
539 
540  return (VNET_API_ERROR_NO_SUCH_ENTRY);
541 }
542 
543 void
545 {
546  gbp_contract_t *gc;
547 
548  /* *INDENT-OFF* */
549  pool_foreach(gc, gbp_contract_pool,
550  ({
551  if (!cb(gc, ctx))
552  break;
553  }));
554  /* *INDENT-ON* */
555 }
556 
557 static clib_error_t *
559  unformat_input_t * input, vlib_cli_command_t * cmd)
560 {
562  u32 acl_index = ~0, stats_index;
563  u8 add = 1;
564 
566  {
567  if (unformat (input, "add"))
568  add = 1;
569  else if (unformat (input, "del"))
570  add = 0;
571  else if (unformat (input, "src-epg %d", &sclass))
572  ;
573  else if (unformat (input, "dst-epg %d", &dclass))
574  ;
575  else if (unformat (input, "acl-index %d", &acl_index))
576  ;
577  else
578  break;
579  }
580 
581  if (SCLASS_INVALID == sclass)
582  return clib_error_return (0, "Source EPG-ID must be specified");
583  if (SCLASS_INVALID == dclass)
584  return clib_error_return (0, "Destination EPG-ID must be specified");
585 
586  if (add)
587  {
588  gbp_contract_update (sclass, dclass, acl_index,
589  NULL, NULL, &stats_index);
590  }
591  else
592  {
593  gbp_contract_delete (sclass, dclass);
594  }
595 
596  return (NULL);
597 }
598 
599 /*?
600  * Configure a GBP Contract
601  *
602  * @cliexpar
603  * @cliexstart{set gbp contract [del] src-epg <ID> dst-epg <ID> acl-index <ACL>}
604  * @cliexend
605  ?*/
606 /* *INDENT-OFF* */
607 VLIB_CLI_COMMAND (gbp_contract_cli_node, static) =
608 {
609  .path = "gbp contract",
610  .short_help =
611  "gbp contract [del] src-epg <ID> dst-epg <ID> acl-index <ACL>",
612  .function = gbp_contract_cli,
613 };
614 /* *INDENT-ON* */
615 
616 static u8 *
617 format_gbp_contract_key (u8 * s, va_list * args)
618 {
619  gbp_contract_key_t *gck = va_arg (*args, gbp_contract_key_t *);
620 
621  s = format (s, "{%d,%d}", gck->gck_src, gck->gck_dst);
622 
623  return (s);
624 }
625 
626 u8 *
627 format_gbp_contract (u8 * s, va_list * args)
628 {
629  index_t gci = va_arg (*args, index_t);
630  vlib_counter_t counts;
631  gbp_contract_t *gc;
632  index_t *gui;
633  u16 *et;
634 
635  gc = gbp_contract_get (gci);
636 
637  s = format (s, "[%d] %U: acl-index:%d",
639 
640  vec_foreach (gui, gc->gc_rules)
641  {
642  s = format (s, "\n %d: %U", *gui, format_gbp_rule, *gui);
643  }
644 
645  s = format (s, "\n allowed-ethertypes:[");
647  {
648  int host_et = clib_net_to_host_u16 (*et);
649  if (0 != host_et)
650  s = format (s, "0x%x, ", host_et);
651  }
652 
653  vlib_get_combined_counter (&gbp_contract_drop_counters, gci, &counts);
654  s = format (s, "\n drop:[%Ld:%Ld]", counts.packets, counts.bytes);
655  vlib_get_combined_counter (&gbp_contract_permit_counters, gci, &counts);
656  s = format (s, "\n permit:[%Ld:%Ld]", counts.packets, counts.bytes);
657 
658  s = format (s, "]");
659 
660  return (s);
661 }
662 
663 static clib_error_t *
665  unformat_input_t * input, vlib_cli_command_t * cmd)
666 {
667  gbp_contract_t *gc;
668  u32 src, dst;
669  index_t gci;
670 
671  src = dst = SCLASS_INVALID;
672 
674  {
675  if (unformat (input, "src %d", &src))
676  ;
677  else if (unformat (input, "dst %d", &dst))
678  ;
679  else
680  break;
681  }
682 
683  vlib_cli_output (vm, "Contracts:");
684 
685  /* *INDENT-OFF* */
686  pool_foreach (gc, gbp_contract_pool,
687  ({
688  gci = gc - gbp_contract_pool;
689 
690  if (SCLASS_INVALID != src && SCLASS_INVALID != dst)
691  {
692  if (gc->gc_key.gck_src == src &&
693  gc->gc_key.gck_dst == dst)
694  vlib_cli_output (vm, " %U", format_gbp_contract, gci);
695  }
696  else if (SCLASS_INVALID != src)
697  {
698  if (gc->gc_key.gck_src == src)
699  vlib_cli_output (vm, " %U", format_gbp_contract, gci);
700  }
701  else if (SCLASS_INVALID != dst)
702  {
703  if (gc->gc_key.gck_dst == dst)
704  vlib_cli_output (vm, " %U", format_gbp_contract, gci);
705  }
706  else
707  vlib_cli_output (vm, " %U", format_gbp_contract, gci);
708  }));
709  /* *INDENT-ON* */
710 
711  return (NULL);
712 }
713 
714 /*?
715  * Show Group Based Policy Contracts
716  *
717  * @cliexpar
718  * @cliexstart{show gbp contract}
719  * @cliexend
720  ?*/
721 /* *INDENT-OFF* */
722 VLIB_CLI_COMMAND (gbp_contract_show_node, static) = {
723  .path = "show gbp contract",
724  .short_help = "show gbp contract [src <SRC>] [dst <DST>]\n",
725  .function = gbp_contract_show,
726 };
727 /* *INDENT-ON* */
728 
729 static fib_node_t *
731 {
732  gbp_next_hop_t *gnh;
733 
734  gnh = gbp_next_hop_get (index);
735 
736  return (&gnh->gnh_node);
737 }
738 
739 static void
741 {
742  ASSERT (0);
743 }
744 
745 static gbp_next_hop_t *
747 {
749  return ((gbp_next_hop_t *) node);
750 }
751 
755 {
756  gbp_next_hop_t *gnh;
757 
758  gnh = gbp_next_hop_from_fib_node (node);
759 
761 
763 }
764 
765 /*
766  * The FIB path's graph node virtual function table
767  */
768 static const fib_node_vft_t gbp_next_hop_vft = {
770  .fnv_last_lock = gbp_next_hop_last_lock_gone,
771  .fnv_back_walk = gbp_next_hop_back_walk_notify,
772  // .fnv_mem_show = fib_path_memory_show,
773 };
774 
775 static clib_error_t *
777 {
778  gc_logger = vlib_log_register_class ("gbp", "con");
780 
781  return (NULL);
782 }
783 
785 
786 /*
787  * fd.io coding-style-patch-verification: ON
788  *
789  * Local Variables:
790  * eval: (c-set-style "gnu")
791  * End:
792  */
vlib_log_class_t vlib_log_register_class(char *class, char *subclass)
Definition: log.c:227
static clib_error_t * gbp_contract_show(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: gbp_contract.c:664
#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:137
u32 acl_index
Definition: gbp.api:304
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:530
static int gbp_contract_next_hop_resolve(index_t gui, index_t gnhi)
Definition: gbp_contract.c:367
static void gbp_contract_rules_free(index_t *rules)
Definition: gbp_contract.c:98
#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:262
u16 sclass_t
Definition: gbp_types.h:24
A Group Based Policy Endpoint.
Definition: gbp_endpoint.h:187
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:124
void vlib_validate_combined_counter(vlib_combined_counter_main_t *cm, u32 index)
validate a combined counter
Definition: counter.c:106
const mac_address_t * gbp_route_domain_get_local_mac(void)
gbp_next_hop_t * gbp_next_hop_pool
Definition: gbp_contract.c:38
#define hash_unset(h, key)
Definition: hash.h:261
fib_node_t gnh_node
Definition: gbp_contract.h:52
void gbp_endpoint_unlock(gbp_endpoint_src_t src, index_t gei)
Definition: gbp_endpoint.c:920
static fib_node_t * gbp_next_hop_get_node(fib_node_index_t index)
Definition: gbp_contract.c:730
gbp_endpoint_fwd_t ge_fwd
Definition: gbp_endpoint.h:205
static void gbp_contract_mk_lb(index_t gui, fib_protocol_t fproto)
Definition: gbp_contract.c:294
#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:31
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:207
vlib_log_class_t gc_logger
Definition: gbp_contract.c:33
#define NULL
Definition: clib.h:58
gbp_contract_db_t gbp_contract_db
Single contract DB instance.
Definition: gbp_contract.c:29
The key for an Contract.
Definition: gbp_contract.h:34
index_t gef_itf
The interface on which the EP is connected.
Definition: gbp_endpoint.h:159
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:45
u8 src_address[6]
Definition: packet.h:56
A bridge Domain Representation.
ip46_address_t gnh_ip
Definition: gbp_contract.h:53
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
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:558
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
vl_api_ip4_address_t dst
Definition: ipsec_gre.api:39
EPG src,dst pair to ACL mapping table, aka contract DB.
Definition: gbp_contract.h:143
static gbp_rule_t * gbp_rule_get(index_t gui)
Definition: gbp_contract.h:198
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:140
enum fib_protocol_t_ fib_protocol_t
Protocol Type.
index_t load_balance_create(u32 n_buckets, dpo_proto_t lb_proto, flow_hash_config_t fhc)
Definition: load_balance.c:217
u32 vlib_log_class_t
Definition: vlib.h:50
int gbp_contract_update(sclass_t sclass, sclass_t dclass, u32 acl_index, index_t *rules, u16 *allowed_ethertypes, u32 *stats_index)
Definition: gbp_contract.c:447
#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:163
u8 dst_address[6]
Definition: packet.h:55
#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:580
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:148
The identity of a DPO is a combination of its type and its instance number/index of objects of that t...
Definition: dpo.h:168
#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:425
#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:132
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:43
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:436
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:286
u16 sclass
Definition: gbp.api:118
u8 * format_gbp_contract(u8 *s, va_list *args)
Definition: gbp_contract.c:627
gbp_rule_action_t gu_action
Definition: gbp_contract.h:105
static void gbp_contract_rule_resolve(index_t gui)
Definition: gbp_contract.c:409
vl_api_gbp_next_hop_t nhs[8]
Definition: gbp.api:284
vl_api_ip4_address_t src
Definition: ipsec_gre.api:38
#define SCLASS_INVALID
Definition: gbp_types.h:25
fib_node_type_t fn_type
The node&#39;s type.
Definition: fib_node.h:295
static u8 * format_gbp_policy_node(u8 *s, va_list *args)
Definition: gbp_contract.c:186
An node in the FIB graph.
Definition: fib_node.h:291
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:824
u32 gbp_endpoint_child_add(index_t gei, fib_node_type_t type, fib_node_index_t index)
static u8 * format_gbp_hash_mode(u8 *s, va_list *args)
Definition: gbp_contract.c:171
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:740
static void gbp_contract_mk_adj(gbp_next_hop_t *gnh, fib_protocol_t fproto)
Definition: gbp_contract.c:246
#define UNFORMAT_END_OF_INPUT
Definition: format.h:144
int gbp_contract_delete(sclass_t sclass, sclass_t dclass)
Definition: gbp_contract.c:516
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:277
#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:279
static_always_inline void ip46_address_copy(ip46_address_t *dst, const ip46_address_t *src)
Definition: ip6_packet.h:99
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:112
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:185
Context passed between object during a back walk.
Definition: fib_node.h:204
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:155
vl_api_gbp_rule_t rules[n_rules]
Definition: gbp.api:308
mac_address_t gnh_mac
Definition: gbp_contract.h:54
#define IP_FLOW_HASH_SYMMETRIC
Definition: lookup.h:67
#define FOR_EACH_GBP_POLICY_NODE(pnode)
Definition: gbp_contract.h:100
#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:87
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:92
index_t gbp_rule_alloc(gbp_rule_action_t action, gbp_hash_mode_t hash_mode, index_t *nhs)
Definition: gbp_contract.c:55
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:753
static u8 * format_gbp_contract_key(u8 *s, va_list *args)
Definition: gbp_contract.c:617
fib_node_type_t gbp_next_hop_fib_type
Definition: gbp_contract.c:35
static gbp_contract_t * gbp_contract_get(index_t gci)
Definition: gbp_contract.h:190
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:147
static gbp_next_hop_t * gbp_next_hop_from_fib_node(fib_node_t *node)
Definition: gbp_contract.c:746
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
counter_t bytes
byte counter
Definition: counter_types.h:29
#define GBP_CONTRACT_DBG(...)
Definition: gbp_contract.c:40
#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:46
#define INDEX_INVALID
Invalid index - used when no index is known blazoned capitals INVALID speak volumes where ~0 does not...
Definition: dpo.h:47
static u8 * format_gbp_rule_action(u8 *s, va_list *args)
Definition: gbp_contract.c:156
u64 uword
Definition: types.h:112
typedef key
Definition: ipsec.api:244
static void gbp_contract_mk_one_lb(index_t gui)
Definition: gbp_contract.c:360
#define DPO_INVALID
An initialiser for DPOs declared on the stack.
Definition: dpo.h:195
char * name
The counter collection&#39;s name.
Definition: counter.h:193
gbp_rule_t * gbp_rule_pool
Definition: gbp_contract.c:37
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:776
#define FOR_EACH_FIB_IP_PROTOCOL(_item)
Definition: fib_types.h:70
Group Base Policy (GBP) defines:
Definition: gbp.h:43
A FIB graph nodes virtual function table.
Definition: fib_node.h:278
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:106
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:60
vl_api_address_t ips[n_ips]
Definition: gbp.api:123
#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:231
#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:306
void gbp_bridge_domain_unlock(index_t index)
void gbp_contract_walk(gbp_contract_cb_t cb, void *ctx)
Definition: gbp_contract.c:544
vlib_node_registration_t ip6_gbp_policy_dpo_node
(constructor) VLIB_REGISTER_NODE (ip6_gbp_policy_dpo_node)
u16 dclass
Definition: gbp.api:303
vl_api_mac_address_t mac
Definition: gbp.api:120
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:725
static u8 * format_gbp_rule(u8 *s, va_list *args)
Definition: gbp_contract.c:201
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:70
index_t * gu_nhs
Definition: gbp_contract.h:107
void gbp_endpoint_child_remove(index_t gei, u32 sibling)
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
A Group Based Policy Contract.
Definition: gbp_contract.h:119
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:170
int(* gbp_contract_cb_t)(gbp_contract_t *gbpe, void *ctx)
Definition: gbp_contract.h:164