From 65e845785f21e6b43c026f092e982171eec1f641 Mon Sep 17 00:00:00 2001 From: Pavel Kotucek Date: Mon, 16 Jan 2017 17:01:56 +0100 Subject: [PATCH] VPP-540 : pbb tag rewrite details Extended sw_interface_dump to provide 802.1ah (pbb) tag rewrite info if present. Extended log "l2-output" to provide raw data to display result of prospetive pbb tag rewrite. Tracing is moved after l2output_vtr to show these changes. Change-Id: I8b7cb865dc67ce21afab402cc086dac35f7c0f07 Signed-off-by: Pavel Kotucek --- src/vat/api_format.c | 13 +++++ src/vnet/ethernet/format.c | 38 ++++----------- src/vnet/interface.api | 19 +++++++- src/vnet/interface_api.c | 20 ++++++++ src/vnet/l2/l2_output.c | 115 +++++++++++++++++++++++++-------------------- src/vnet/l2/l2_vtr.c | 66 ++++++++++++++++++++++++++ src/vnet/l2/l2_vtr.h | 11 +++++ 7 files changed, 200 insertions(+), 82 deletions(-) diff --git a/src/vat/api_format.c b/src/vat/api_format.c index e3d8ab48eb9..0f03527913d 100644 --- a/src/vat/api_format.c +++ b/src/vat/api_format.c @@ -914,6 +914,19 @@ static void vl_api_sw_interface_details_t_handler_json ntohl (mp->vtr_push_dot1q)); vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1)); vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2)); + if (mp->sub_dot1ah) + { + vat_json_object_add_string_copy (node, "pbb_vtr_dmac", + format (0, "%U", + format_ethernet_address, + &mp->b_dmac)); + vat_json_object_add_string_copy (node, "pbb_vtr_smac", + format (0, "%U", + format_ethernet_address, + &mp->b_smac)); + vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid); + vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid); + } } static void vl_api_sw_interface_set_flags_t_handler diff --git a/src/vnet/ethernet/format.c b/src/vnet/ethernet/format.c index 4edef5adbeb..5b58999861a 100644 --- a/src/vnet/ethernet/format.c +++ b/src/vnet/ethernet/format.c @@ -87,30 +87,6 @@ format_ethernet_vlan_tci (u8 * s, va_list * va) return s; } -u8 * -format_ethernet_pbb (u8 * s, va_list * va) -{ - u32 b_tag = va_arg (*va, u32); - u32 i_tag = va_arg (*va, u32); - u32 vid = (b_tag & 0xfff); - u32 bdei = (b_tag >> 12) & 1; - u32 bpcp = (b_tag >> 13); - u32 sid = (i_tag & 0xffffff); - u8 ires = (i_tag >> 24) & 3; - u8 iuca = (i_tag >> 27) & 1; - u8 idei = (i_tag >> 28) & 1; - u8 ipcp = (i_tag >> 29); - - s = - format (s, "B_tag %04X (vid %d, dei %d, pcp %d), ", b_tag, vid, bdei, - bpcp); - s = - format (s, "I_tag %08X (sid %d, res %d, dei %d, pcp %d)", i_tag, sid, - ires, iuca, idei, ipcp); - - return s; -} - u8 * format_ethernet_header_with_length (u8 * s, va_list * args) { @@ -177,10 +153,16 @@ format_ethernet_header_with_length (u8 * s, va_list * args) } else { - s = format (s, "\n%UPBB header : %U", format_white_space, indent, - format_ethernet_pbb, - clib_net_to_host_u16 (ph->priority_dei_id), - clib_net_to_host_u32 (ph->priority_dei_uca_res_sid)); + s = + format (s, " %s b-tag %04X", + (clib_net_to_host_u16 (ph->b_type) == + ETHERNET_TYPE_DOT1AD) ? "802.1ad" : "", + clib_net_to_host_u16 (ph->priority_dei_id)); + s = + format (s, " %s i-tag %08X", + (clib_net_to_host_u16 (ph->i_type) == + ETHERNET_TYPE_DOT1AH) ? "802.1ah" : "", + clib_net_to_host_u32 (ph->priority_dei_uca_res_sid)); } return s; diff --git a/src/vnet/interface.api b/src/vnet/interface.api index 752e79c5ed1..afa8bb5e7c4 100644 --- a/src/vnet/interface.api +++ b/src/vnet/interface.api @@ -83,9 +83,10 @@ define want_interface_events_reply @param interface_name - name of the interface @param link_duplex - 1 if half duplex, 2 if full duplex @param link_speed - 1 = 10M, 2 = 100M, 4 = 1G, 8 = 10G, 16 = 40G, 32 = 100G - @param link_MTU - max. transmittion unit + @param link_MTU - max. transmittion unit @param sub_if_id - A number 0-N to uniquely identify this subif on super if - @param sub_dot1ad - 0 = dot1q, 1=dot1ad + @param sub_dot1ad - 0 = dot1q, 1 = dot1ad + @param sub_dot1ah - 1 = dot1ah, 0 = otherwise @param sub_number_of_tags - Number of tags (0 - 2) @param sub_outer_vlan_id @param sub_inner_vlan_id @@ -97,6 +98,11 @@ define want_interface_events_reply @param vtr_push_dot1q @param vtr_tag1 @param vtr_tag2 + @param pbb_outer_tag - translate pbb s-tag + @param pbb_b_dmac[6] - B-tag remote mac address + @param pbb_b_smac[6] - B-tag local mac address + @param pbb_b_vlanid - B-tag vlanid + @param pbb_i_sid - I-tag service id */ define sw_interface_details { @@ -132,6 +138,8 @@ define sw_interface_details /* 0 = dot1q, 1=dot1ad */ u8 sub_dot1ad; + /* 1 = dot1h, 1=otherwise */ + u8 sub_dot1ah; /* Number of tags 0-2 */ u8 sub_number_of_tags; @@ -148,6 +156,13 @@ define sw_interface_details u32 vtr_tag1; // first pushed tag u32 vtr_tag2; // second pushed tag u8 tag[64]; + + /* pbb tag rewrite info */ + u16 outer_tag; + u8 b_dmac[6]; + u8 b_smac[6]; + u16 b_vlanid; + u32 i_sid; }; /* works */ diff --git a/src/vnet/interface_api.c b/src/vnet/interface_api.c index 42fd14ee19d..63f7cad44a8 100644 --- a/src/vnet/interface_api.c +++ b/src/vnet/interface_api.c @@ -203,6 +203,26 @@ send_sw_interface_details (vpe_api_main_t * am, } } + /* pbb tag rewrite data */ + u32 vtr_op = L2_VTR_DISABLED; + u16 outer_tag = 0; + u8 b_dmac[6]; + u8 b_smac[6]; + u16 b_vlanid = 0; + u32 i_sid = 0; + memset (b_dmac, 0, sizeof (b_dmac)); + memset (b_smac, 0, sizeof (b_smac)); + + if (!l2pbb_get (am->vlib_main, am->vnet_main, swif->sw_if_index, + &vtr_op, &outer_tag, b_dmac, b_smac, &b_vlanid, &i_sid)) + { + mp->sub_dot1ah = 1; + clib_memcpy (mp->b_dmac, b_dmac, sizeof (b_dmac)); + clib_memcpy (mp->b_smac, b_smac, sizeof (b_smac)); + mp->b_vlanid = b_vlanid; + mp->i_sid = i_sid; + } + tag = vnet_get_sw_interface_tag (vnm, swif->sw_if_index); if (tag) strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1); diff --git a/src/vnet/l2/l2_output.c b/src/vnet/l2/l2_output.c index acfe3abad90..00f22571790 100644 --- a/src/vnet/l2/l2_output.c +++ b/src/vnet/l2/l2_output.c @@ -48,6 +48,7 @@ typedef struct u8 src[6]; u8 dst[6]; u32 sw_if_index; + u8 raw[12]; /* raw data */ } l2output_trace_t; /* packet trace format function */ @@ -58,10 +59,15 @@ format_l2output_trace (u8 * s, va_list * args) CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *); l2output_trace_t *t = va_arg (*args, l2output_trace_t *); - s = format (s, "l2-output: sw_if_index %d dst %U src %U", + s = format (s, "l2-output: sw_if_index %d dst %U src %U data " + "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", t->sw_if_index, format_ethernet_address, t->dst, - format_ethernet_address, t->src); + format_ethernet_address, t->src, + t->raw[0], t->raw[1], t->raw[2], t->raw[3], t->raw[4], + t->raw[5], t->raw[6], t->raw[7], t->raw[8], t->raw[9], + t->raw[10], t->raw[11]); + return s; } @@ -214,46 +220,6 @@ l2output_node_inline (vlib_main_t * vm, vlib_node_runtime_t * node, sw_if_index2 = vnet_buffer (b2)->sw_if_index[VLIB_TX]; sw_if_index3 = vnet_buffer (b3)->sw_if_index[VLIB_TX]; - if (do_trace) - { - h0 = vlib_buffer_get_current (b0); - h1 = vlib_buffer_get_current (b1); - h2 = vlib_buffer_get_current (b2); - h3 = vlib_buffer_get_current (b3); - if (b0->flags & VLIB_BUFFER_IS_TRACED) - { - l2output_trace_t *t = - vlib_add_trace (vm, node, b0, sizeof (*t)); - t->sw_if_index = sw_if_index0; - clib_memcpy (t->src, h0->src_address, 6); - clib_memcpy (t->dst, h0->dst_address, 6); - } - if (b1->flags & VLIB_BUFFER_IS_TRACED) - { - l2output_trace_t *t = - vlib_add_trace (vm, node, b1, sizeof (*t)); - t->sw_if_index = sw_if_index1; - clib_memcpy (t->src, h1->src_address, 6); - clib_memcpy (t->dst, h1->dst_address, 6); - } - if (b2->flags & VLIB_BUFFER_IS_TRACED) - { - l2output_trace_t *t = - vlib_add_trace (vm, node, b2, sizeof (*t)); - t->sw_if_index = sw_if_index2; - clib_memcpy (t->src, h2->src_address, 6); - clib_memcpy (t->dst, h2->dst_address, 6); - } - if (b3->flags & VLIB_BUFFER_IS_TRACED) - { - l2output_trace_t *t = - vlib_add_trace (vm, node, b3, sizeof (*t)); - t->sw_if_index = sw_if_index3; - clib_memcpy (t->src, h3->src_address, 6); - clib_memcpy (t->dst, h3->dst_address, 6); - } - } - vlib_node_increment_counter (vm, l2output_node.index, L2OUTPUT_ERROR_L2OUTPUT, 4); @@ -314,6 +280,50 @@ l2output_node_inline (vlib_main_t * vm, vlib_node_runtime_t * node, l2output_vtr (node, config2, feature_bitmap2, b2, &next2); l2output_vtr (node, config3, feature_bitmap3, b3, &next3); + if (do_trace) + { + h0 = vlib_buffer_get_current (b0); + h1 = vlib_buffer_get_current (b1); + h2 = vlib_buffer_get_current (b2); + h3 = vlib_buffer_get_current (b3); + if (b0->flags & VLIB_BUFFER_IS_TRACED) + { + l2output_trace_t *t = + vlib_add_trace (vm, node, b0, sizeof (*t)); + t->sw_if_index = sw_if_index0; + clib_memcpy (t->src, h0->src_address, 6); + clib_memcpy (t->dst, h0->dst_address, 6); + clib_memcpy (t->raw, &h0->type, sizeof (t->raw)); + } + if (b1->flags & VLIB_BUFFER_IS_TRACED) + { + l2output_trace_t *t = + vlib_add_trace (vm, node, b1, sizeof (*t)); + t->sw_if_index = sw_if_index1; + clib_memcpy (t->src, h1->src_address, 6); + clib_memcpy (t->dst, h1->dst_address, 6); + clib_memcpy (t->raw, &h1->type, sizeof (t->raw)); + } + if (b2->flags & VLIB_BUFFER_IS_TRACED) + { + l2output_trace_t *t = + vlib_add_trace (vm, node, b2, sizeof (*t)); + t->sw_if_index = sw_if_index2; + clib_memcpy (t->src, h2->src_address, 6); + clib_memcpy (t->dst, h2->dst_address, 6); + clib_memcpy (t->raw, &h2->type, sizeof (t->raw)); + } + if (b3->flags & VLIB_BUFFER_IS_TRACED) + { + l2output_trace_t *t = + vlib_add_trace (vm, node, b3, sizeof (*t)); + t->sw_if_index = sw_if_index3; + clib_memcpy (t->src, h3->src_address, 6); + clib_memcpy (t->dst, h3->dst_address, 6); + clib_memcpy (t->raw, &h3->type, sizeof (t->raw)); + } + } + /* * Perform the split horizon check * The check can only fail for non-zero shg's @@ -378,16 +388,6 @@ l2output_node_inline (vlib_main_t * vm, vlib_node_runtime_t * node, sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_TX]; - if (do_trace && PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED)) - { - l2output_trace_t *t = - vlib_add_trace (vm, node, b0, sizeof (*t)); - t->sw_if_index = sw_if_index0; - h0 = vlib_buffer_get_current (b0); - clib_memcpy (t->src, h0->src_address, 6); - clib_memcpy (t->dst, h0->dst_address, 6); - } - vlib_node_increment_counter (vm, l2output_node.index, L2OUTPUT_ERROR_L2OUTPUT, 1); @@ -412,6 +412,17 @@ l2output_node_inline (vlib_main_t * vm, vlib_node_runtime_t * node, l2output_vtr (node, config0, feature_bitmap0, b0, &next0); + if (do_trace && PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED)) + { + l2output_trace_t *t = + vlib_add_trace (vm, node, b0, sizeof (*t)); + t->sw_if_index = sw_if_index0; + h0 = vlib_buffer_get_current (b0); + clib_memcpy (t->src, h0->src_address, 6); + clib_memcpy (t->dst, h0->dst_address, 6); + clib_memcpy (t->raw, &h0->type, sizeof (t->raw)); + } + /* Perform the split horizon check */ if (PREDICT_FALSE (split_horizon_violation diff --git a/src/vnet/l2/l2_vtr.c b/src/vnet/l2/l2_vtr.c index 95a4f15700a..e03a4880a5e 100644 --- a/src/vnet/l2/l2_vtr.c +++ b/src/vnet/l2/l2_vtr.c @@ -681,6 +681,72 @@ VLIB_CLI_COMMAND (int_l2_vtr_cli, static) = { }; /* *INDENT-ON* */ +/** + * Get pbb tag rewrite on the given interface. + * Return 1 if there is an error, 0 if ok + */ +u32 +l2pbb_get (vlib_main_t * vlib_main, vnet_main_t * vnet_main, u32 sw_if_index, + u32 * vtr_op, u16 * outer_tag, u8 * b_dmac, u8 * b_smac, + u16 * b_vlanid, u32 * i_sid) +{ + u32 error = 1; + ptr_config_t *in_config; + + if (!vtr_op || !outer_tag || !b_vlanid || !i_sid) + { + clib_warning ("invalid arguments"); + error = VNET_API_ERROR_INVALID_ARGUMENT; + goto done; + } + + *vtr_op = L2_VTR_DISABLED; + *outer_tag = 0; + *b_dmac = 0; + *b_smac = 0; + *b_vlanid = 0; + *i_sid = 0; + + if (sw_if_index >= vec_len (l2output_main.configs)) + { + /* no specific config (return disabled) */ + goto done; + } + + /* Get the config for this interface */ + in_config = + &(vec_elt_at_index (l2output_main.configs, sw_if_index)->input_pbb_vtr); + + if (in_config->push_and_pop_bytes == 0) + { + /* DISABLED */ + goto done; + } + else + { + if (in_config->pop_bytes && in_config->push_bytes) + *vtr_op = L2_VTR_TRANSLATE_2_1; + else if (in_config->pop_bytes) + *vtr_op = L2_VTR_POP_2; + else if (in_config->push_bytes) + *vtr_op = L2_VTR_PUSH_2; + + clib_memcpy (b_dmac, in_config->macs_tags.b_dst_address, + sizeof (b_dmac)); + clib_memcpy (b_smac, in_config->macs_tags.b_src_address, + sizeof (b_smac)); + + *b_vlanid = + clib_host_to_net_u16 (in_config->macs_tags.priority_dei_id) & 0xFFF; + *i_sid = + clib_host_to_net_u32 (in_config-> + macs_tags.priority_dei_uca_res_sid) & 0xFFFFF; + error = 0; + } +done: + return error; +} + /** * Set subinterface pbb vtr enable/disable. * The CLI format is: diff --git a/src/vnet/l2/l2_vtr.h b/src/vnet/l2/l2_vtr.h index 893b2272b04..99aedc970db 100644 --- a/src/vnet/l2/l2_vtr.h +++ b/src/vnet/l2/l2_vtr.h @@ -258,6 +258,17 @@ u32 l2vtr_get (vlib_main_t * vlib_main, u32 * vtr_op, u32 * push_dot1q, u32 * vtr_tag1, u32 * vtr_tag2); +/** + * Get pbb tag rewrite on the given interface. + * Return 1 if there is an error, 0 if ok + */ +u32 l2pbb_get (vlib_main_t * vlib_main, + vnet_main_t * vnet_main, + u32 sw_if_index, + u32 * vtr_op, + u16 * outer_tag, + u8 * b_dmac, u8 * b_smac, u16 * b_vlanid, u32 * i_sid); + #endif /* included_vnet_l2_vtr_h */ -- 2.16.6