diff options
author | Neale Ranns <nranns@cisco.com> | 2019-03-12 02:34:07 -0700 |
---|---|---|
committer | Neale Ranns <nranns@cisco.com> | 2019-03-12 16:50:23 +0000 |
commit | 36abbf10045ba81733410f50a3f5a9463f7137d1 (patch) | |
tree | 3adcabaa69bcbe4cbe801c45866a1f4c46c12443 /src/plugins/gbp | |
parent | 7bd343509fa30f9713b6efa9a4acb83e0ab86cfb (diff) |
GBP: L3 out fixes
Change-Id: I0562d597fd45c7ddcb6db42cf17d3ffb569eb140
Signed-off-by: Neale Ranns <nranns@cisco.com>
Diffstat (limited to 'src/plugins/gbp')
-rw-r--r-- | src/plugins/gbp/gbp_classify_node.c | 89 | ||||
-rw-r--r-- | src/plugins/gbp/gbp_endpoint.c | 13 | ||||
-rw-r--r-- | src/plugins/gbp/gbp_endpoint.h | 5 | ||||
-rw-r--r-- | src/plugins/gbp/gbp_ext_itf.c | 12 | ||||
-rw-r--r-- | src/plugins/gbp/gbp_itf.c | 35 |
5 files changed, 129 insertions, 25 deletions
diff --git a/src/plugins/gbp/gbp_classify_node.c b/src/plugins/gbp/gbp_classify_node.c index 1b2cb0a2bc7..58b1f7ac545 100644 --- a/src/plugins/gbp/gbp_classify_node.c +++ b/src/plugins/gbp/gbp_classify_node.c @@ -308,6 +308,28 @@ ethertype_to_dpo_proto (const ethernet_header_t * eh0) return (DPO_PROTO_NONE); } +/** + * per-packet trace data + */ +typedef struct gbp_lpm_classify_trace_t_ +{ + sclass_t sclass; + index_t lbi; +} gbp_lpm_classify_trace_t; + +/* packet trace format function */ +static u8 * +format_gbp_lpm_classify_trace (u8 * s, va_list * args) +{ + CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *); + CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *); + gbp_lpm_classify_trace_t *t = va_arg (*args, gbp_lpm_classify_trace_t *); + + s = format (s, "sclass:%d lb:%d", t->sclass, t->lbi); + + return s; +} + /* * Determine the SRC EPG from a LPM */ @@ -335,8 +357,9 @@ gbp_lpm_classify_inline (vlib_main_t * vm, { u32 bi0, sw_if_index0, fib_index0, lbi0; gbp_lpm_classify_next_t next0; + const ethernet_header_t *eh0; const gbp_policy_dpo_t *gpd0; - const gbp_ext_itf_t *gx0; + const gbp_endpoint_t *ge0; const gbp_recirc_t *gr0; const dpo_id_t *dpo0; load_balance_t *lb0; @@ -355,6 +378,8 @@ gbp_lpm_classify_inline (vlib_main_t * vm, ip6_0 = NULL; next0 = GPB_LPM_CLASSIFY_DROP; + lbi0 = ~0; + eh0 = NULL; b0 = vlib_get_buffer (vm, bi0); sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX]; @@ -366,8 +391,6 @@ gbp_lpm_classify_inline (vlib_main_t * vm, ip6_0 = vlib_buffer_get_current (b0); else if (DPO_PROTO_ETHERNET == dproto) { - const ethernet_header_t *eh0; - eh0 = vlib_buffer_get_current (b0); dproto = ethertype_to_dpo_proto (eh0); @@ -393,17 +416,61 @@ gbp_lpm_classify_inline (vlib_main_t * vm, { gr0 = gbp_recirc_get (sw_if_index0); fib_index0 = gr0->gr_fib_index[dproto]; + ge0 = NULL; vnet_feature_next (&next0, b0); } else { - gx0 = gbp_ext_itf_get (sw_if_index0); - fib_index0 = gx0->gx_fib_index[dproto]; + if (NULL == eh0) + { + /* packet should be l2 */ + sclass0 = SCLASS_INVALID; + goto trace; + } + + ge0 = gbp_endpoint_find_mac (eh0->src_address, + vnet_buffer (b0)->l2.bd_index); + + if (NULL == ge0) + { + /* packet must have come from an EP's mac */ + sclass0 = SCLASS_INVALID; + goto trace; + } + + fib_index0 = ge0->ge_fwd.gef_fib_index; + + if (~0 == fib_index0) + { + sclass0 = SCLASS_INVALID; + goto trace; + } + + if (DPO_PROTO_IP4 == dproto) + { + ge0 = + gbp_endpoint_find_ip4 (&ip4_0->src_address, fib_index0); + } + else if (DPO_PROTO_IP6 == dproto) + { + ge0 = + gbp_endpoint_find_ip6 (&ip6_0->src_address, fib_index0); + } next0 = vnet_l2_feature_next (b0, gscm->l2_input_feat_next[GBP_SRC_CLASSIFY_LPM], L2INPUT_FEAT_GBP_LPM_CLASSIFY); + + /* + * if we found the EP by IP lookup, it must be from the EP + * not a network behind it + */ + if (NULL != ge0) + { + sclass0 = ge0->ge_fwd.gef_sclass; + goto trace; + } } if (DPO_PROTO_IP4 == dproto) @@ -420,6 +487,7 @@ gbp_lpm_classify_inline (vlib_main_t * vm, { /* not IP so no LPM classify possible */ sclass0 = SCLASS_INVALID; + next0 = GPB_LPM_CLASSIFY_DROP; goto trace; } lb0 = load_balance_get (lbi0); @@ -434,7 +502,7 @@ gbp_lpm_classify_inline (vlib_main_t * vm, { /* could not classify => drop */ sclass0 = SCLASS_INVALID; - next0 = GPB_LPM_CLASSIFY_DROP; + goto trace; } trace: @@ -442,9 +510,10 @@ gbp_lpm_classify_inline (vlib_main_t * vm, if (PREDICT_FALSE ((b0->flags & VLIB_BUFFER_IS_TRACED))) { - gbp_classify_trace_t *t = + gbp_lpm_classify_trace_t *t = vlib_add_trace (vm, node, b0, sizeof (*t)); t->sclass = sclass0; + t->lbi = lbi0; } vlib_validate_buffer_enqueue_x1 (vm, node, next_index, @@ -483,7 +552,7 @@ VLIB_NODE_FN (gbp_l2_lpm_classify_node) (vlib_main_t * vm, VLIB_REGISTER_NODE (gbp_ip4_lpm_classify_node) = { .name = "ip4-gbp-lpm-classify", .vector_size = sizeof (u32), - .format_trace = format_gbp_classify_trace, + .format_trace = format_gbp_lpm_classify_trace, .type = VLIB_NODE_TYPE_INTERNAL, .n_errors = 0, @@ -496,7 +565,7 @@ VLIB_REGISTER_NODE (gbp_ip4_lpm_classify_node) = { VLIB_REGISTER_NODE (gbp_ip6_lpm_classify_node) = { .name = "ip6-gbp-lpm-classify", .vector_size = sizeof (u32), - .format_trace = format_gbp_classify_trace, + .format_trace = format_gbp_lpm_classify_trace, .type = VLIB_NODE_TYPE_INTERNAL, .n_errors = 0, @@ -509,7 +578,7 @@ VLIB_REGISTER_NODE (gbp_ip6_lpm_classify_node) = { VLIB_REGISTER_NODE (gbp_l2_lpm_classify_node) = { .name = "l2-gbp-lpm-classify", .vector_size = sizeof (u32), - .format_trace = format_gbp_classify_trace, + .format_trace = format_gbp_lpm_classify_trace, .type = VLIB_NODE_TYPE_INTERNAL, .n_errors = 0, diff --git a/src/plugins/gbp/gbp_endpoint.c b/src/plugins/gbp/gbp_endpoint.c index 36e0050c39d..2472199e320 100644 --- a/src/plugins/gbp/gbp_endpoint.c +++ b/src/plugins/gbp/gbp_endpoint.c @@ -254,7 +254,8 @@ gbp_endpoint_alloc (const ip46_address_t * ips, fib_node_init (&ge->ge_node, gbp_endpoint_fib_type); gei = gbp_endpoint_index (ge); ge->ge_key.gek_gbd = - ge->ge_key.gek_grd = ge->ge_fwd.gef_itf = INDEX_INVALID; + ge->ge_key.gek_grd = + ge->ge_fwd.gef_itf = ge->ge_fwd.gef_fib_index = INDEX_INVALID; ge->ge_last_time = vlib_time_now (vlib_get_main ()); ge->ge_key.gek_gbd = gbp_bridge_domain_index (gbd); @@ -602,7 +603,7 @@ gbb_endpoint_fwd_reset (gbp_endpoint_t * ge) { l2fib_del_entry (ge->ge_key.gek_mac.bytes, gbd->gb_bd_index, gef->gef_itf); - gbp_itf_set_l2_input_feature (gef->gef_itf, gei, (L2INPUT_FEAT_NONE)); + gbp_itf_set_l2_input_feature (gef->gef_itf, gei, L2INPUT_FEAT_NONE); gbp_itf_set_l2_output_feature (gef->gef_itf, gei, L2OUTPUT_FEAT_NONE); gbp_itf_unlock (gef->gef_itf); @@ -681,6 +682,7 @@ gbb_endpoint_fwd_recalc (gbp_endpoint_t * ge) rewrite = NULL; grd = gbp_route_domain_get (ge->ge_key.gek_grd); fib_index = grd->grd_fib_index[pfx->fp_proto]; + gef->gef_fib_index = fib_index; bd_add_del_ip_mac (gbd->gb_bd_index, fib_proto_to_ip46 (pfx->fp_proto), &pfx->fp_addr, &ge->ge_key.gek_mac, 1); @@ -786,7 +788,12 @@ gbb_endpoint_fwd_recalc (gbp_endpoint_t * ge) } } - if (gbp_endpoint_is_local (ge) && !gbp_endpoint_is_external (ge)) + if (gbp_endpoint_is_external (ge)) + { + gbp_itf_set_l2_input_feature (gef->gef_itf, gei, + L2INPUT_FEAT_GBP_LPM_CLASSIFY); + } + else if (gbp_endpoint_is_local (ge)) { /* * non-remote endpoints (i.e. those not arriving on iVXLAN diff --git a/src/plugins/gbp/gbp_endpoint.h b/src/plugins/gbp/gbp_endpoint.h index aba1f9d498c..a0d354ab8ab 100644 --- a/src/plugins/gbp/gbp_endpoint.h +++ b/src/plugins/gbp/gbp_endpoint.h @@ -168,6 +168,11 @@ typedef struct gbp_endpoint_fwd_t_ */ sclass_t gef_sclass; + /** + * FIB index the EP is in + */ + u32 gef_fib_index; + gbp_endpoint_flags_t gef_flags; } gbp_endpoint_fwd_t; diff --git a/src/plugins/gbp/gbp_ext_itf.c b/src/plugins/gbp/gbp_ext_itf.c index 16cdaa87b77..be2d614e1fa 100644 --- a/src/plugins/gbp/gbp_ext_itf.c +++ b/src/plugins/gbp/gbp_ext_itf.c @@ -60,7 +60,6 @@ gbp_ext_itf_add (u32 sw_if_index, u32 bd_id, u32 rd_id) if (INDEX_INVALID == gxi) { - gbp_bridge_domain_t *gb; gbp_route_domain_t *gr; fib_protocol_t fproto; index_t gbi, gri; @@ -81,11 +80,11 @@ gbp_ext_itf_add (u32 sw_if_index, u32 bd_id, u32 rd_id) pool_get_zero (gbp_ext_itf_pool, gx); gxi = gx - gbp_ext_itf_pool; - gb = gbp_bridge_domain_get (gbi); gr = gbp_route_domain_get (gri); gx->gx_bd = gbi; gx->gx_rd = gri; + gx->gx_itf = sw_if_index; FOR_EACH_FIB_IP_PROTOCOL (fproto) { @@ -93,10 +92,6 @@ gbp_ext_itf_add (u32 sw_if_index, u32 bd_id, u32 rd_id) gr->grd_fib_index[fib_proto_to_dpo (fproto)]; } - gx->gx_itf = gbp_itf_add_and_lock (sw_if_index, gb->gb_bd_index); - gbp_itf_set_l2_input_feature (gx->gx_itf, (gxi | GBP_EXT_ITF_ID), - L2INPUT_FEAT_GBP_LPM_CLASSIFY); - gbp_ext_itf_db[sw_if_index] = gxi; GBP_EXT_ITF_DBG ("add: %U", format_gbp_ext_itf, gx); @@ -124,11 +119,6 @@ gbp_ext_itf_delete (u32 sw_if_index) GBP_EXT_ITF_DBG ("del: %U", format_gbp_ext_itf, gx); - gbp_itf_set_l2_input_feature (gx->gx_itf, - (gxi | GBP_EXT_ITF_ID), - L2INPUT_FEAT_NONE); - gbp_itf_unlock (gx->gx_itf); - gbp_route_domain_unlock (gx->gx_rd); gbp_bridge_domain_unlock (gx->gx_bd); diff --git a/src/plugins/gbp/gbp_itf.c b/src/plugins/gbp/gbp_itf.c index 7cfe9da0ab0..4944f278144 100644 --- a/src/plugins/gbp/gbp_itf.c +++ b/src/plugins/gbp/gbp_itf.c @@ -194,15 +194,48 @@ format_gbp_itf (u8 * s, va_list * args) gi = gbp_itf_get (gii); - s = format (s, "%U locks:%d input-feats:%U output-feats:%U", + s = format (s, "%U locks:%d bd-index:%d input-feats:%U output-feats:%U", format_vnet_sw_if_index_name, vnet_get_main (), gi->gi_sw_if_index, gi->gi_locks, + gi->gi_bd_index, format_l2_input_features, gi->gi_l2_input_fb, 0, format_l2_output_features, gi->gi_l2_output_fb, 0); return (s); } +static clib_error_t * +gbp_itf_show (vlib_main_t * vm, + unformat_input_t * input, vlib_cli_command_t * cmd) +{ + u32 gii; + + vlib_cli_output (vm, "Interfaces:"); + + vec_foreach_index (gii, gbp_itfs) + { + vlib_cli_output (vm, " [%d] %U", gii, format_gbp_itf, gii); + } + + return (NULL); +} + +/*? + * Show Group Based Interfaces + * + * @cliexpar + * @cliexstart{show gbp contract} + * @cliexend + ?*/ +/* *INDENT-OFF* */ +VLIB_CLI_COMMAND (gbp_contract_show_node, static) = { + .path = "show gbp interface", + .short_help = "show gbp interface\n", + .function = gbp_itf_show, +}; +/* *INDENT-ON* */ + + /* * fd.io coding-style-patch-verification: ON * |