interface: Allow VLAN tag-rewrite on non-sub-interfaces too.

This fix was first made in
    commit fdea5c6a00b74971dbb1b7ec4e25839a871006ca
but was subsequently lost in
    commit 053204ab039d34a990ff0e14c32ce3b294fcce0e

Added unit test for setting VTR on a non-sub-interface to
help ensure no future regressions of this ability.

Type: fix
Change-Id: I71ce2684fb72383741455829ae2d397ea2e95eae
Signed-off-by: Jon Loeliger <jdl@netgate.com>
This commit is contained in:
Jon Loeliger
2019-11-08 15:05:23 -06:00
committed by Ole Trøan
parent 592a909a30
commit 9485d99bd3
7 changed files with 134 additions and 56 deletions

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
option version = "3.2.1";
option version = "3.2.2";
import "vnet/interface_types.api";
import "vnet/ethernet/ethernet_types.api";

View File

@ -272,26 +272,26 @@ send_sw_interface_details (vpe_api_main_t * am,
mp->sub_inner_vlan_id = ntohs (sub->eth.inner_vlan_id);
mp->sub_if_flags =
ntohl (sub->eth.raw_flags & SUB_IF_API_FLAG_MASK_VNET);
}
/* vlan tag rewrite data */
u32 vtr_op = L2_VTR_DISABLED;
u32 vtr_push_dot1q = 0, vtr_tag1 = 0, vtr_tag2 = 0;
/* vlan tag rewrite data */
u32 vtr_op = L2_VTR_DISABLED;
u32 vtr_push_dot1q = 0, vtr_tag1 = 0, vtr_tag2 = 0;
if (l2vtr_get (am->vlib_main, am->vnet_main, swif->sw_if_index,
&vtr_op, &vtr_push_dot1q, &vtr_tag1, &vtr_tag2) != 0)
{
// error - default to disabled
mp->vtr_op = ntohl (L2_VTR_DISABLED);
clib_warning ("cannot get vlan tag rewrite for sw_if_index %d",
swif->sw_if_index);
}
else
{
mp->vtr_op = ntohl (vtr_op);
mp->vtr_push_dot1q = ntohl (vtr_push_dot1q);
mp->vtr_tag1 = ntohl (vtr_tag1);
mp->vtr_tag2 = ntohl (vtr_tag2);
}
if (l2vtr_get (am->vlib_main, am->vnet_main, swif->sw_if_index,
&vtr_op, &vtr_push_dot1q, &vtr_tag1, &vtr_tag2) != 0)
{
// error - default to disabled
mp->vtr_op = ntohl (L2_VTR_DISABLED);
clib_warning ("cannot get vlan tag rewrite for sw_if_index %d",
swif->sw_if_index);
}
else
{
mp->vtr_op = ntohl (vtr_op);
mp->vtr_push_dot1q = ntohl (vtr_push_dot1q);
mp->vtr_tag1 = ntohl (vtr_tag1);
mp->vtr_tag2 = ntohl (vtr_tag2);
}
/* pbb tag rewrite data */

View File

@ -277,6 +277,7 @@ show_sw_interfaces (vlib_main_t * vm,
u8 show_addresses = 0;
u8 show_features = 0;
u8 show_tag = 0;
u8 show_vtr = 0;
int verbose = 0;
/*
@ -300,6 +301,8 @@ show_sw_interfaces (vlib_main_t * vm,
show_features = 1;
else if (unformat (linput, "tag"))
show_tag = 1;
else if (unformat (linput, "vtr"))
show_vtr = 1;
else if (unformat (linput, "verbose"))
verbose = 1;
else
@ -312,7 +315,7 @@ show_sw_interfaces (vlib_main_t * vm,
}
unformat_free (linput);
}
if (show_features || show_tag)
if (show_features || show_tag || show_vtr)
{
if (sw_if_index == ~(u32) 0)
{
@ -353,6 +356,27 @@ show_sw_interfaces (vlib_main_t * vm,
return 0;
}
/*
* Show vlan tag rewrite data for one interface.
*/
if (show_vtr)
{
u32 vtr_op = L2_VTR_DISABLED;
u32 push_dot1q = 0, tag1 = 0, tag2 = 0;
if (l2vtr_get (vm, vnm, sw_if_index,
&vtr_op, &push_dot1q, &tag1, &tag2) != 0)
{
vlib_cli_output (vm, "%U: Problem getting vlan tag-rewrite data",
format_vnet_sw_if_index_name, vnm, sw_if_index);
return 0;
}
vlib_cli_output (vm, "%U: VTR %0U",
format_vnet_sw_if_index_name, vnm, sw_if_index,
format_vtr, vtr_op, push_dot1q, tag1, tag2);
return 0;
}
if (!show_addresses)
vlib_cli_output (vm, "%U\n", format_vnet_sw_interface, vnm, 0);
@ -474,7 +498,7 @@ done:
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (show_sw_interfaces_command, static) = {
.path = "show interface",
.short_help = "show interface [address|addr|features|feat] [<interface> [<interface> [..]]] [verbose]",
.short_help = "show interface [address|addr|features|feat|vtr] [<interface> [<interface> [..]]] [verbose]",
.function = show_sw_interfaces,
.is_mp_safe = 1,
};

View File

@ -41,6 +41,42 @@
#include <vppinfra/bitmap.h>
#include <vnet/l2/l2_input.h>
#include <vnet/l2/l2_output.h>
#include <vnet/l2/l2_vtr.h>
u8 *
format_vtr (u8 * s, va_list * args)
{
u32 vtr_op = va_arg (*args, u32);
u32 dot1q = va_arg (*args, u32);
u32 tag1 = va_arg (*args, u32);
u32 tag2 = va_arg (*args, u32);
switch (vtr_op)
{
case L2_VTR_DISABLED:
return format (s, "none");
case L2_VTR_PUSH_1:
return format (s, "push-1 %s %d", dot1q ? "dot1q" : "dot1ad", tag1);
case L2_VTR_PUSH_2:
return format (s, "push-2 %s %d %d", dot1q ? "dot1q" : "dot1ad", tag1,
tag2);
case L2_VTR_POP_1:
return format (s, "pop-1");
case L2_VTR_POP_2:
return format (s, "pop-2");
case L2_VTR_TRANSLATE_1_1:
return format (s, "trans-1-1 %s %d", dot1q ? "dot1q" : "dot1ad", tag1);
case L2_VTR_TRANSLATE_1_2:
return format (s, "trans-1-2 %s %d %d", dot1q ? "dot1q" : "dot1ad",
tag1, tag2);
case L2_VTR_TRANSLATE_2_1:
return format (s, "trans-2-1 %s %d", dot1q ? "dot1q" : "dot1ad", tag1);
case L2_VTR_TRANSLATE_2_2:
return format (s, "trans-2-2 %s %d %d", dot1q ? "dot1q" : "dot1ad",
tag1, tag2);
default:
return format (s, "none");
}
}
u8 *
format_vnet_sw_interface_flags (u8 * s, va_list * args)

View File

@ -448,6 +448,9 @@ unformat_function_t unformat_vnet_hw_interface;
unformat_function_t unformat_vnet_hw_interface_flags;
unformat_function_t unformat_vnet_sw_interface_flags;
/* VLAN tag-rewrite */
format_function_t format_vtr;
/* Node runtime for interface output function. */
typedef struct
{

View File

@ -994,41 +994,6 @@ VLIB_CLI_COMMAND (bd_arp_entry_cli, static) = {
};
/* *INDENT-ON* */
static u8 *
format_vtr (u8 * s, va_list * args)
{
u32 vtr_op = va_arg (*args, u32);
u32 dot1q = va_arg (*args, u32);
u32 tag1 = va_arg (*args, u32);
u32 tag2 = va_arg (*args, u32);
switch (vtr_op)
{
case L2_VTR_DISABLED:
return format (s, "none");
case L2_VTR_PUSH_1:
return format (s, "push-1 %s %d", dot1q ? "dot1q" : "dot1ad", tag1);
case L2_VTR_PUSH_2:
return format (s, "push-2 %s %d %d", dot1q ? "dot1q" : "dot1ad", tag1,
tag2);
case L2_VTR_POP_1:
return format (s, "pop-1");
case L2_VTR_POP_2:
return format (s, "pop-2");
case L2_VTR_TRANSLATE_1_1:
return format (s, "trans-1-1 %s %d", dot1q ? "dot1q" : "dot1ad", tag1);
case L2_VTR_TRANSLATE_1_2:
return format (s, "trans-1-2 %s %d %d", dot1q ? "dot1q" : "dot1ad",
tag1, tag2);
case L2_VTR_TRANSLATE_2_1:
return format (s, "trans-2-1 %s %d", dot1q ? "dot1q" : "dot1ad", tag1);
case L2_VTR_TRANSLATE_2_2:
return format (s, "trans-2-2 %s %d %d", dot1q ? "dot1q" : "dot1ad",
tag1, tag2);
default:
return format (s, "none");
}
}
static u8 *
format_uu_cfg (u8 * s, va_list * args)
{

View File

@ -331,6 +331,56 @@ class TestVtr(VppTestCase):
self.vtr_test(self.pg2, [Tag(dot1=DOT1AD, vlan=400),
Tag(dot1=DOT1Q, vlan=300)])
def test_if_vtr_disable(self):
""" Disable VTR on non-sub-interfaces
"""
# First set the VTR fields to junk
self.vapi.l2_interface_vlan_tag_rewrite(
sw_if_index=self.pg0.sw_if_index, vtr_op=L2_VTR_OP.L2_PUSH_2,
push_dot1q=1, tag1=19, tag2=630)
if_state = self.vapi.sw_interface_dump(
sw_if_index=self.pg0.sw_if_index)
self.assertEqual(if_state[0].sw_if_index, self.pg0.sw_if_index)
self.assertNotEqual(if_state[0].vtr_op, L2_VTR_OP.L2_DISABLED)
# Then ensure that a request to disable VTR is honored.
self.vapi.l2_interface_vlan_tag_rewrite(
sw_if_index=self.pg0.sw_if_index, vtr_op=L2_VTR_OP.L2_DISABLED)
if_state = self.vapi.sw_interface_dump(
sw_if_index=self.pg0.sw_if_index)
self.assertEqual(if_state[0].sw_if_index, self.pg0.sw_if_index)
self.assertEqual(if_state[0].vtr_op, L2_VTR_OP.L2_DISABLED)
def test_if_vtr_push_1q(self):
""" 1Q VTR push 1 on non-sub-interfaces
"""
self.vapi.l2_interface_vlan_tag_rewrite(
sw_if_index=self.pg0.sw_if_index, vtr_op=L2_VTR_OP.L2_PUSH_1,
push_dot1q=1, tag1=150)
if_state = self.vapi.sw_interface_dump(
sw_if_index=self.pg0.sw_if_index)
self.assertEqual(if_state[0].sw_if_index, self.pg0.sw_if_index)
self.assertEqual(if_state[0].vtr_op, L2_VTR_OP.L2_PUSH_1)
self.assertEqual(if_state[0].vtr_tag1, 150)
self.assertNotEqual(if_state[0].vtr_push_dot1q, 0)
def test_if_vtr_push_2ad(self):
""" 1AD VTR push 2 on non-sub-interfaces
"""
self.vapi.l2_interface_vlan_tag_rewrite(
sw_if_index=self.pg0.sw_if_index, vtr_op=L2_VTR_OP.L2_PUSH_2,
push_dot1q=0, tag1=450, tag2=350)
if_state = self.vapi.sw_interface_dump(
sw_if_index=self.pg0.sw_if_index)
self.assertEqual(if_state[0].sw_if_index, self.pg0.sw_if_index)
self.assertEqual(if_state[0].vtr_op, L2_VTR_OP.L2_PUSH_2)
self.assertEqual(if_state[0].vtr_tag1, 450) # outer
self.assertEqual(if_state[0].vtr_tag2, 350) # inner
self.assertEqual(if_state[0].vtr_push_dot1q, 0)
if __name__ == '__main__':
unittest.main(testRunner=VppTestRunner)