X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fplugins%2Fgbp%2Fgbp_contract.c;h=e12b33145ce7d7b7021bbfd980f14062cb770e18;hb=59f71132e;hp=805e9b23d09b9f840ebc18e8e5e69fb23a667356;hpb=4ba67723d716660c56326ce498b99a060a9471b1;p=vpp.git diff --git a/src/plugins/gbp/gbp_contract.c b/src/plugins/gbp/gbp_contract.c index 805e9b23d09..e12b33145ce 100644 --- a/src/plugins/gbp/gbp_contract.c +++ b/src/plugins/gbp/gbp_contract.c @@ -19,10 +19,17 @@ #include #include #include +#include #include #include +char *gbp_contract_error_strings[] = { +#define _(sym,string) string, + foreach_gbp_contract_error +#undef _ +}; + /** * Single contract DB instance */ @@ -40,6 +47,17 @@ gbp_next_hop_t *gbp_next_hop_pool; #define GBP_CONTRACT_DBG(...) \ vlib_log_notice (gc_logger, __VA_ARGS__); +/* Adjacency packet/byte counters indexed by adjacency index. */ +vlib_combined_counter_main_t gbp_contract_permit_counters = { + .name = "gbp-contracts-permit", + .stat_segment_name = "/net/gbp/contract/permit", +}; + +vlib_combined_counter_main_t gbp_contract_drop_counters = { + .name = "gbp-contracts-drop", + .stat_segment_name = "/net/gbp/contract/drop", +}; + index_t gbp_rule_alloc (gbp_rule_action_t action, gbp_hash_mode_t hash_mode, index_t * nhs) @@ -55,6 +73,12 @@ gbp_rule_alloc (gbp_rule_action_t action, return (gu - gbp_rule_pool); } +void +gbp_rule_free (index_t gui) +{ + pool_put_index (gbp_rule_pool, gui); +} + index_t gbp_next_hop_alloc (const ip46_address_t * ip, index_t grd, const mac_address_t * mac, index_t gbd) @@ -121,6 +145,8 @@ gbp_contract_rules_free (index_t * rules) adj_unlock (gnh->gnh_ai[fproto]); } } + + gbp_rule_free (*gui); } vec_free (rules); } @@ -141,7 +167,7 @@ format_gbp_next_hop (u8 * s, va_list * args) return (s); } -static u8 * +u8 * format_gbp_rule_action (u8 * s, va_list * args) { gbp_rule_action_t action = va_arg (*args, gbp_rule_action_t); @@ -202,7 +228,7 @@ format_gbp_rule (u8 * s, va_list * args) { case GBP_RULE_PERMIT: case GBP_RULE_DENY: - break; + return (s); case GBP_RULE_REDIRECT: s = format (s, ", %U", format_gbp_hash_mode, gu->gu_hash_mode); break; @@ -210,19 +236,19 @@ format_gbp_rule (u8 * s, va_list * args) vec_foreach (gnhi, gu->gu_nhs) { - s = format (s, "\n [%U]", format_gbp_next_hop, *gnhi); + s = format (s, "\n [%U]", format_gbp_next_hop, *gnhi); } FOR_EACH_GBP_POLICY_NODE (pnode) { - s = format (s, "\n policy-%U", format_gbp_policy_node, pnode); + s = format (s, "\n policy-%U", format_gbp_policy_node, pnode); FOR_EACH_FIB_IP_PROTOCOL (fproto) { if (dpo_id_is_valid (&gu->gu_dpo[pnode][fproto])) { s = - format (s, "\n %U", format_dpo_id, + format (s, "\n %U", format_dpo_id, &gu->gu_dpo[pnode][fproto], 8); } } @@ -257,7 +283,10 @@ gbp_contract_mk_adj (gbp_next_hop_t * gnh, fib_protocol_t fproto) gnh->gnh_ai[fproto] = adj_nbr_add_or_lock_w_rewrite (fproto, fib_proto_to_link (fproto), - &gnh->gnh_ip, ge->ge_fwd.gef_itf, rewrite); + &gnh->gnh_ip, + gbp_itf_get_sw_if_index (ge-> + ge_fwd.gef_itf), + rewrite); adj_unlock (old_ai); } @@ -433,9 +462,12 @@ gbp_contract_mk_lbs (index_t * guis) } int -gbp_contract_update (sclass_t sclass, +gbp_contract_update (gbp_scope_t scope, + sclass_t sclass, sclass_t dclass, - u32 acl_index, index_t * rules, u16 * allowed_ethertypes) + u32 acl_index, + index_t * rules, + u16 * allowed_ethertypes, u32 * stats_index) { gbp_main_t *gm = &gbp_main; u32 *acl_vec = NULL; @@ -444,6 +476,7 @@ gbp_contract_update (sclass_t sclass, uword *p; gbp_contract_key_t key = { + .gck_scope = scope, .gck_src = sclass, .gck_dst = dclass, }; @@ -455,7 +488,7 @@ gbp_contract_update (sclass_t sclass, gm->acl_plugin.register_user_module ("GBP ACL", "src-epg", "dst-epg"); } - p = hash_get (gbp_contract_db.gc_hash, key.as_u32); + p = hash_get (gbp_contract_db.gc_hash, key.as_u64); if (p != NULL) { gci = p[0]; @@ -470,7 +503,12 @@ gbp_contract_update (sclass_t sclass, pool_get_zero (gbp_contract_pool, gc); gc->gc_key = key; gci = gc - gbp_contract_pool; - hash_set (gbp_contract_db.gc_hash, key.as_u32, gci); + hash_set (gbp_contract_db.gc_hash, key.as_u64, gci); + + vlib_validate_combined_counter (&gbp_contract_drop_counters, gci); + vlib_zero_combined_counter (&gbp_contract_drop_counters, gci); + vlib_validate_combined_counter (&gbp_contract_permit_counters, gci); + vlib_zero_combined_counter (&gbp_contract_permit_counters, gci); } GBP_CONTRACT_DBG ("update: %U", format_gbp_contract, gci); @@ -489,20 +527,23 @@ gbp_contract_update (sclass_t sclass, gm->acl_plugin.set_acl_vec_for_context (gc->gc_lc_index, acl_vec); vec_free (acl_vec); + *stats_index = gci; + return (0); } int -gbp_contract_delete (sclass_t sclass, sclass_t dclass) +gbp_contract_delete (gbp_scope_t scope, sclass_t sclass, sclass_t dclass) { gbp_contract_key_t key = { + .gck_scope = scope, .gck_src = sclass, .gck_dst = dclass, }; gbp_contract_t *gc; uword *p; - p = hash_get (gbp_contract_db.gc_hash, key.as_u32); + p = hash_get (gbp_contract_db.gc_hash, key.as_u64); if (p != NULL) { gc = gbp_contract_get (p[0]); @@ -511,7 +552,7 @@ gbp_contract_delete (sclass_t sclass, sclass_t dclass) gbp_main.acl_plugin.put_lookup_context_index (gc->gc_lc_index); vec_free (gc->gc_allowed_ethertypes); - hash_unset (gbp_contract_db.gc_hash, key.as_u32); + hash_unset (gbp_contract_db.gc_hash, key.as_u64); pool_put (gbp_contract_pool, gc); return (0); @@ -539,7 +580,7 @@ gbp_contract_cli (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { sclass_t sclass = SCLASS_INVALID, dclass = SCLASS_INVALID; - u32 acl_index = ~0; + u32 acl_index = ~0, stats_index, scope; u8 add = 1; while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) @@ -548,9 +589,11 @@ gbp_contract_cli (vlib_main_t * vm, add = 1; else if (unformat (input, "del")) add = 0; - else if (unformat (input, "src-epg %d", &sclass)) + else if (unformat (input, "scope %d", &scope)) ; - else if (unformat (input, "dst-epg %d", &dclass)) + else if (unformat (input, "sclass %d", &sclass)) + ; + else if (unformat (input, "dclass %d", &dclass)) ; else if (unformat (input, "acl-index %d", &acl_index)) ; @@ -565,11 +608,12 @@ gbp_contract_cli (vlib_main_t * vm, if (add) { - gbp_contract_update (sclass, dclass, acl_index, NULL, NULL); + gbp_contract_update (scope, sclass, dclass, acl_index, + NULL, NULL, &stats_index); } else { - gbp_contract_delete (sclass, dclass); + gbp_contract_delete (scope, sclass, dclass); } return (NULL); @@ -597,7 +641,7 @@ format_gbp_contract_key (u8 * s, va_list * args) { gbp_contract_key_t *gck = va_arg (*args, gbp_contract_key_t *); - s = format (s, "{%d,%d}", gck->gck_src, gck->gck_dst); + s = format (s, "{%d,%d,%d}", gck->gck_scope, gck->gck_src, gck->gck_dst); return (s); } @@ -606,28 +650,40 @@ u8 * format_gbp_contract (u8 * s, va_list * args) { index_t gci = va_arg (*args, index_t); + vlib_counter_t counts; gbp_contract_t *gc; index_t *gui; u16 *et; gc = gbp_contract_get (gci); - s = format (s, "%U: acl-index:%d", - format_gbp_contract_key, &gc->gc_key, gc->gc_acl_index); + s = format (s, "[%d] %U: acl-index:%d", + gci, format_gbp_contract_key, &gc->gc_key, gc->gc_acl_index); + s = format (s, "\n rules:"); vec_foreach (gui, gc->gc_rules) { - s = format (s, "\n %d: %U", *gui, format_gbp_rule, *gui); + s = format (s, "\n %d: %U", *gui, format_gbp_rule, *gui); } - s = format (s, "\n allowed-ethertypes:["); + s = format (s, "\n allowed-ethertypes:"); + s = format (s, "\n ["); vec_foreach (et, gc->gc_allowed_ethertypes) { int host_et = clib_net_to_host_u16 (*et); - s = format (s, "0x%x, ", host_et); + if (0 != host_et) + s = format (s, "0x%x, ", host_et); } s = format (s, "]"); + s = format (s, "\n stats:"); + vlib_get_combined_counter (&gbp_contract_drop_counters, gci, &counts); + s = format (s, "\n drop:[%Ld:%Ld]", counts.packets, counts.bytes); + vlib_get_combined_counter (&gbp_contract_permit_counters, gci, &counts); + s = format (s, "\n permit:[%Ld:%Ld]", counts.packets, counts.bytes); + + s = format (s, "]"); + return (s); } @@ -635,14 +691,47 @@ static clib_error_t * gbp_contract_show (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { + gbp_contract_t *gc; + u32 src, dst; index_t gci; + src = dst = SCLASS_INVALID; + + while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (input, "src %d", &src)) + ; + else if (unformat (input, "dst %d", &dst)) + ; + else + break; + } + vlib_cli_output (vm, "Contracts:"); /* *INDENT-OFF* */ - pool_foreach_index (gci, gbp_contract_pool, + pool_foreach (gc, gbp_contract_pool, ({ - vlib_cli_output (vm, " [%d] %U", gci, format_gbp_contract, gci); + gci = gc - gbp_contract_pool; + + if (SCLASS_INVALID != src && SCLASS_INVALID != dst) + { + if (gc->gc_key.gck_src == src && + gc->gc_key.gck_dst == dst) + vlib_cli_output (vm, " %U", format_gbp_contract, gci); + } + else if (SCLASS_INVALID != src) + { + if (gc->gc_key.gck_src == src) + vlib_cli_output (vm, " %U", format_gbp_contract, gci); + } + else if (SCLASS_INVALID != dst) + { + if (gc->gc_key.gck_dst == dst) + vlib_cli_output (vm, " %U", format_gbp_contract, gci); + } + else + vlib_cli_output (vm, " %U", format_gbp_contract, gci); })); /* *INDENT-ON* */ @@ -659,7 +748,7 @@ gbp_contract_show (vlib_main_t * vm, /* *INDENT-OFF* */ VLIB_CLI_COMMAND (gbp_contract_show_node, static) = { .path = "show gbp contract", - .short_help = "show gbp contract\n", + .short_help = "show gbp contract [src ] [dst ]\n", .function = gbp_contract_show, }; /* *INDENT-ON* */