aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/l2
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet/l2')
-rw-r--r--src/vnet/l2/feat_bitmap.c2
-rw-r--r--src/vnet/l2/l2.api49
-rw-r--r--src/vnet/l2/l2_api.c51
-rw-r--r--src/vnet/l2/l2_arp_term.c6
-rw-r--r--src/vnet/l2/l2_bd.c65
-rw-r--r--src/vnet/l2/l2_bd.h3
-rw-r--r--src/vnet/l2/l2_bvi.c25
-rw-r--r--src/vnet/l2/l2_classify.h1
-rw-r--r--src/vnet/l2/l2_efp_filter.c4
-rw-r--r--src/vnet/l2/l2_fib.c25
-rw-r--r--src/vnet/l2/l2_fib.h26
-rw-r--r--src/vnet/l2/l2_flood.c4
-rw-r--r--src/vnet/l2/l2_fwd.c9
-rw-r--r--src/vnet/l2/l2_in_out_acl.c6
-rw-r--r--src/vnet/l2/l2_in_out_feat_arc.c7
-rw-r--r--src/vnet/l2/l2_input.c12
-rw-r--r--src/vnet/l2/l2_input.h13
-rw-r--r--src/vnet/l2/l2_input_classify.c14
-rw-r--r--src/vnet/l2/l2_input_node.c17
-rw-r--r--src/vnet/l2/l2_input_vtr.c2
-rw-r--r--src/vnet/l2/l2_learn.c4
-rw-r--r--src/vnet/l2/l2_output.c5
-rw-r--r--src/vnet/l2/l2_output.h3
-rw-r--r--src/vnet/l2/l2_output_classify.c13
-rw-r--r--src/vnet/l2/l2_patch.c10
-rw-r--r--src/vnet/l2/l2_rw.c82
-rw-r--r--src/vnet/l2/l2_rw.h4
-rw-r--r--src/vnet/l2/l2_test.c1435
-rw-r--r--src/vnet/l2/l2_uu_fwd.c2
-rw-r--r--src/vnet/l2/l2_vtr.c4
-rw-r--r--src/vnet/l2/l2_xcrw.c18
31 files changed, 1657 insertions, 264 deletions
diff --git a/src/vnet/l2/feat_bitmap.c b/src/vnet/l2/feat_bitmap.c
index 349ec67462b..507fe365f07 100644
--- a/src/vnet/l2/feat_bitmap.c
+++ b/src/vnet/l2/feat_bitmap.c
@@ -155,7 +155,6 @@ feat_bitmap_drop_init (vlib_main_t * vm)
VLIB_INIT_FUNCTION (feat_bitmap_drop_init);
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (feat_bitmap_drop_node,static) = {
.function = feat_bitmap_drop_node_fn,
.name = "feature-bitmap-drop",
@@ -173,7 +172,6 @@ VLIB_REGISTER_NODE (feat_bitmap_drop_node,static) = {
[FEAT_BITMAP_DROP_NEXT_DROP] = "error-drop",
},
};
-/* *INDENT-ON* */
/*
* fd.io coding-style-patch-verification: ON
diff --git a/src/vnet/l2/l2.api b/src/vnet/l2/l2.api
index b0ac23f705a..ccba9aa3df1 100644
--- a/src/vnet/l2/l2.api
+++ b/src/vnet/l2/l2.api
@@ -1,6 +1,7 @@
/* Hey Emacs use -*- mode: C -*- */
/*
* Copyright (c) 2016 Cisco and/or its affiliates.
+ * Copyright (c) 2022 Nordix Foundation.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
@@ -14,7 +15,7 @@
* limitations under the License.
*/
-option version = "3.1.0";
+option version = "3.2.0";
import "vnet/ip/ip_types.api";
import "vnet/ethernet/ethernet_types.api";
@@ -304,7 +305,7 @@ autoreply define bridge_domain_set_learn_limit
u32 learn_limit;
};
-/** \brief L2 bridge domain add or delete request
+/** \brief L2 bridge domain add or delete request - will be deprecated
@param client_index - opaque cookie to identify the sender
@param context - sender context, to match reply w/ request
@param bd_id - the bridge domain to create
@@ -319,6 +320,7 @@ autoreply define bridge_domain_set_learn_limit
*/
autoreply define bridge_domain_add_del
{
+ option deprecated;
u32 client_index;
u32 context;
u32 bd_id;
@@ -333,6 +335,49 @@ autoreply define bridge_domain_add_del
bool is_add [default=true];
};
+/** \brief L2 bridge domain add delete request version 2
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+ @param bd_id - if the id == ~0 creates a bridge domain with an unused id
+ if the id != ~0 the id of the bridge domain to create/delete
+ @param flood - enable/disable bcast/mcast flooding in the bd
+ @param uu_flood - enable/disable unknown unicast flood in the bd
+ @param forward - enable/disable forwarding on all interfaces in the bd
+ @param learn - enable/disable learning on all interfaces in the bd
+ @param arp_term - enable/disable arp termination in the bd
+ @param arp_ufwd - enable/disable arp unicast forwarding in the bd
+ @param mac_age - mac aging time in min, 0 for disabled
+ @param is_add - add or delete flag
+*/
+define bridge_domain_add_del_v2
+{
+ u32 client_index;
+ u32 context;
+ u32 bd_id;
+ bool flood;
+ bool uu_flood;
+ bool forward;
+ bool learn;
+ bool arp_term;
+ bool arp_ufwd;
+ u8 mac_age;
+ string bd_tag[64];
+ bool is_add [default=true];
+};
+
+/** \brief L2 bridge domain add delete version 2 response
+ @param context - sender context, to match reply w/ request
+ @param retval - return code for the set bridge flags request
+ @param resulting_id - the id for the new bridge domain
+*/
+define bridge_domain_add_del_v2_reply
+{
+ u32 context;
+ i32 retval;
+ u32 bd_id;
+};
+
+
/** \brief L2 bridge domain request operational state details
@param client_index - opaque cookie to identify the sender
@param context - sender context, to match reply w/ request
diff --git a/src/vnet/l2/l2_api.c b/src/vnet/l2/l2_api.c
index 5a0432de43d..035542d298d 100644
--- a/src/vnet/l2/l2_api.c
+++ b/src/vnet/l2/l2_api.c
@@ -3,6 +3,7 @@
* l2_api.c - layer 2 forwarding api
*
* Copyright (c) 2016 Cisco and/or its affiliates.
+ * Copyright (c) 2022 Nordix Foundation.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
@@ -67,7 +68,6 @@ vl_api_l2_xconnect_dump_t_handler (vl_api_l2_xconnect_dump_t * mp)
if (!reg)
return;
- /* *INDENT-OFF* */
vec_foreach_index (sw_if_index, l2im->configs)
{
config = vec_elt_at_index (l2im->configs, sw_if_index);
@@ -75,7 +75,6 @@ vl_api_l2_xconnect_dump_t_handler (vl_api_l2_xconnect_dump_t * mp)
send_l2_xconnect_details (reg, mp->context, sw_if_index,
config->output_sw_if_index);
}
- /* *INDENT-ON* */
}
static void
@@ -413,12 +412,10 @@ vl_api_l2_flags_t_handler (vl_api_l2_flags_t * mp)
BAD_SW_IF_INDEX_LABEL;
- /* *INDENT-OFF* */
REPLY_MACRO2(VL_API_L2_FLAGS_REPLY,
({
rmp->resulting_feature_bitmap = ntohl(rbm);
}));
- /* *INDENT-ON* */
}
static void
@@ -511,6 +508,37 @@ vl_api_bridge_domain_add_del_t_handler (vl_api_bridge_domain_add_del_t * mp)
}
static void
+vl_api_bridge_domain_add_del_v2_t_handler (
+ vl_api_bridge_domain_add_del_v2_t *mp)
+{
+ vl_api_bridge_domain_add_del_v2_reply_t *rmp;
+ u32 bd_id = ntohl (mp->bd_id);
+ int rv = 0;
+
+ if ((~0 == bd_id) && (mp->is_add))
+ bd_id = bd_get_unused_id ();
+
+ if ((~0 == bd_id) && (mp->is_add))
+ rv = VNET_API_ERROR_EAGAIN;
+ else
+ {
+ l2_bridge_domain_add_del_args_t a = { .is_add = mp->is_add,
+ .flood = mp->flood,
+ .uu_flood = mp->uu_flood,
+ .forward = mp->forward,
+ .learn = mp->learn,
+ .arp_term = mp->arp_term,
+ .arp_ufwd = mp->arp_ufwd,
+ .mac_age = mp->mac_age,
+ .bd_id = bd_id,
+ .bd_tag = mp->bd_tag };
+ rv = bd_add_del (&a);
+ }
+ REPLY_MACRO2 (VL_API_BRIDGE_DOMAIN_ADD_DEL_V2_REPLY,
+ ({ rmp->bd_id = htonl (bd_id); }));
+}
+
+static void
send_bridge_domain_details (l2input_main_t * l2im,
vl_api_registration_t * reg,
l2_bridge_domain_t * bd_config,
@@ -651,12 +679,10 @@ vl_api_bridge_flags_t_handler (vl_api_bridge_flags_t * mp)
bitmap = bd_set_flags (vm, bd_index, flags, mp->is_set);
out:
- /* *INDENT-OFF* */
REPLY_MACRO2(VL_API_BRIDGE_FLAGS_REPLY,
({
rmp->resulting_feature_bitmap = ntohl(bitmap);
}));
- /* *INDENT-ON* */
}
static void
@@ -918,7 +944,6 @@ vl_api_bd_ip_mac_dump_t_handler (vl_api_bd_ip_mac_dump_t * mp)
u64 mac64;
bd_id = bd_config->bd_id;
- /* *INDENT-OFF* */
hash_foreach (ip4_addr.as_u32, mac64, bd_config->mac_by_ip4,
({
ip46_address_t ip = {
@@ -940,7 +965,6 @@ vl_api_bd_ip_mac_dump_t_handler (vl_api_bd_ip_mac_dump_t * mp)
send_bd_ip_mac_entry (am, reg, bd_id, &ip, IP46_TYPE_IP6,
&mac, mp->context);
}));
- /* *INDENT-ON* */
}
}
}
@@ -1094,12 +1118,10 @@ vl_api_bvi_create_t_handler (vl_api_bvi_create_t * mp)
rv = l2_bvi_create (ntohl (mp->user_instance), &mac, &sw_if_index);
- /* *INDENT-OFF* */
REPLY_MACRO2(VL_API_BVI_CREATE_REPLY,
({
rmp->sw_if_index = ntohl (sw_if_index);
}));
- /* *INDENT-ON* */
}
static void
@@ -1193,13 +1215,11 @@ l2_arp_term_process (vlib_main_t * vm, vlib_node_runtime_t * rt,
return 0;
}
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (l2_arp_term_process_node) = {
.function = l2_arp_term_process,
.type = VLIB_NODE_TYPE_PROCESS,
.name = "l2-arp-term-publisher",
};
-/* *INDENT-ON* */
static void
vl_api_want_l2_arp_term_events_t_handler (vl_api_want_l2_arp_term_events_t *
@@ -1280,14 +1300,15 @@ l2_api_hookup (vlib_main_t * vm)
{
api_main_t *am = vlibapi_get_main ();
- /* Mark VL_API_BRIDGE_DOMAIN_DUMP as mp safe */
- am->is_mp_safe[VL_API_BRIDGE_DOMAIN_DUMP] = 1;
-
/*
* Set up the (msg_name, crc, message-id) table
*/
REPLY_MSG_ID_BASE = setup_message_id_table ();
+ /* Mark VL_API_BRIDGE_DOMAIN_DUMP as mp safe */
+ vl_api_set_msg_thread_safe (
+ am, REPLY_MSG_ID_BASE + VL_API_BRIDGE_DOMAIN_DUMP, 1);
+
return 0;
}
diff --git a/src/vnet/l2/l2_arp_term.c b/src/vnet/l2/l2_arp_term.c
index 17c8b1d84d0..eed9b7af7c3 100644
--- a/src/vnet/l2/l2_arp_term.c
+++ b/src/vnet/l2/l2_arp_term.c
@@ -25,6 +25,7 @@
#include <vnet/ip/ip6_packet.h>
#include <vnet/ip/icmp6.h>
#include <vnet/ip/ip6.h>
+#include <vnet/ip/ip.api_enum.h>
#include <vnet/ip/format.h>
#include <vnet/ethernet/arp_packet.h>
@@ -289,6 +290,9 @@ arp_term_l2bd (vlib_main_t * vm,
ethertype0 = clib_net_to_host_u16 (*(u16 *) (l3h0 - 2));
arp0 = (ethernet_arp_header_t *) l3h0;
+ if (p0->flags & VNET_BUFFER_F_LOCALLY_ORIGINATED)
+ goto next_l2_feature;
+
if (ethertype0 != ETHERNET_TYPE_ARP)
goto check_ip6_nd;
@@ -445,7 +449,6 @@ arp_term_l2bd (vlib_main_t * vm,
return frame->n_vectors;
}
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (arp_term_l2bd_node, static) = {
.function = arp_term_l2bd,
.name = "arp-term-l2bd",
@@ -460,7 +463,6 @@ VLIB_REGISTER_NODE (arp_term_l2bd_node, static) = {
.format_buffer = format_ethernet_arp_header,
.format_trace = format_arp_term_input_trace,
};
-/* *INDENT-ON* */
clib_error_t *
arp_term_init (vlib_main_t * vm)
diff --git a/src/vnet/l2/l2_bd.c b/src/vnet/l2/l2_bd.c
index 7e6ea60b440..c7392c03b58 100644
--- a/src/vnet/l2/l2_bd.c
+++ b/src/vnet/l2/l2_bd.c
@@ -102,12 +102,10 @@ bd_free_ip_mac_tables (l2_bridge_domain_t * bd)
ip6_address_t *ip6_addr_key;
hash_free (bd->mac_by_ip4);
- /* *INDENT-OFF* */
hash_foreach_mem (ip6_addr_key, mac_addr, bd->mac_by_ip6,
({
clib_mem_free (ip6_addr_key); /* free memory used for ip6 addr key */
}));
- /* *INDENT-ON* */
hash_free (bd->mac_by_ip6);
}
@@ -454,13 +452,11 @@ done:
* Example of how to disable learning (where 200 is the bridge-domain-id):
* @cliexcmd{set bridge-domain learn 200 disable}
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (bd_learn_cli, static) = {
.path = "set bridge-domain learn",
.short_help = "set bridge-domain learn <bridge-domain-id> [disable]",
.function = bd_learn,
};
-/* *INDENT-ON* */
static clib_error_t *
bd_default_learn_limit (vlib_main_t *vm, unformat_input_t *input,
@@ -547,13 +543,11 @@ done:
* Example of how to disable forwarding (where 200 is the bridge-domain-id):
* @cliexcmd{set bridge-domain forward 200 disable}
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (bd_fwd_cli, static) = {
.path = "set bridge-domain forward",
.short_help = "set bridge-domain forward <bridge-domain-id> [disable]",
.function = bd_fwd,
};
-/* *INDENT-ON* */
/**
Set bridge-domain flood enable/disable.
@@ -612,13 +606,11 @@ done:
* Example of how to disable flooding (where 200 is the bridge-domain-id):
* @cliexcmd{set bridge-domain flood 200 disable}
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (bd_flood_cli, static) = {
.path = "set bridge-domain flood",
.short_help = "set bridge-domain flood <bridge-domain-id> [disable]",
.function = bd_flood,
};
-/* *INDENT-ON* */
/**
Set bridge-domain unknown-unicast flood enable/disable.
@@ -677,13 +669,11 @@ done:
* Example of how to disable unknown-unicast flooding (where 200 is the bridge-domain-id):
* @cliexcmd{set bridge-domain uu-flood 200 disable}
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (bd_uu_flood_cli, static) = {
.path = "set bridge-domain uu-flood",
.short_help = "set bridge-domain uu-flood <bridge-domain-id> [disable]",
.function = bd_uu_flood,
};
-/* *INDENT-ON* */
/**
Set bridge-domain arp-unicast forward enable/disable.
@@ -742,13 +732,11 @@ done:
* Example of how to disable arp-unicast forwarding (where 200 is the bridge-domain-id):
* @cliexcmd{set bridge-domain arp-ufwd 200 disable}
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (bd_arp_ufwd_cli, static) = {
.path = "set bridge-domain arp-ufwd",
.short_help = "set bridge-domain arp-ufwd <bridge-domain-id> [disable]",
.function = bd_arp_ufwd,
};
-/* *INDENT-ON* */
/**
Set bridge-domain arp term enable/disable.
@@ -854,13 +842,11 @@ done:
* Example of how to disable mac aging (where 200 is the bridge-domain-id):
* @cliexcmd{set bridge-domain flood 200 0}
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (bd_mac_age_cli, static) = {
.path = "set bridge-domain mac-age",
.short_help = "set bridge-domain mac-age <bridge-domain-id> <mins>",
.function = bd_mac_age,
};
-/* *INDENT-ON* */
static clib_error_t *
bd_learn_limit (vlib_main_t *vm, unformat_input_t *input,
@@ -921,13 +907,11 @@ VLIB_CLI_COMMAND (bd_learn_limit_cli, static) = {
* Example of how to disable ARP termination (where 200 is the bridge-domain-id):
* @cliexcmd{set bridge-domain arp term 200 disable}
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (bd_arp_term_cli, static) = {
.path = "set bridge-domain arp term",
.short_help = "set bridge-domain arp term <bridge-domain-id> [disable]",
.function = bd_arp_term,
};
-/* *INDENT-ON* */
/**
@@ -1119,13 +1103,11 @@ done:
* Example of how to delete an ARP entry (where 200 is the bridge-domain-id):
* @cliexcmd{set bridge-domain arp entry 200 192.168.72.45 52:54:00:3b:83:1a del}
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (bd_arp_entry_cli, static) = {
.path = "set bridge-domain arp entry",
.short_help = "set bridge-domain arp entry <bridge-domain-id> [<ip-addr> <mac-addr> [del] | del-all]",
.function = bd_arp_entry,
};
-/* *INDENT-ON* */
static u8 *
format_uu_cfg (u8 * s, va_list * args)
@@ -1289,7 +1271,6 @@ bd_show (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd)
vlib_cli_output (vm,
"\n IP4/IP6 to MAC table for ARP Termination");
- /* *INDENT-OFF* */
hash_foreach (ip4_addr, mac_addr, bd_config->mac_by_ip4,
({
vlib_cli_output (vm, "%=40U => %=20U",
@@ -1303,7 +1284,6 @@ bd_show (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd)
format_ip6_address, ip6_addr,
format_ethernet_address, &mac_addr);
}));
- /* *INDENT-ON* */
}
if ((detail || bd_tag) && (bd_config->bd_tag))
@@ -1349,13 +1329,11 @@ done:
* @cliexend
* @endparblock
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (bd_show_cli, static) = {
.path = "show bridge-domain",
.short_help = "show bridge-domain [bridge-domain-id [detail|int|arp|bd-tag]]",
.function = bd_show,
};
-/* *INDENT-ON* */
int
bd_add_del (l2_bridge_domain_add_del_args_t * a)
@@ -1493,8 +1471,15 @@ bd_add_del_command_fn (vlib_main_t * vm, unformat_input_t * input,
if (bd_id == ~0)
{
- error = clib_error_return (0, "bridge-domain-id not specified");
- goto done;
+ if (is_add)
+ {
+ bd_id = bd_get_unused_id ();
+ }
+ else
+ {
+ error = clib_error_return (0, "bridge-domain-id not specified");
+ goto done;
+ }
}
if (bd_id == 0)
@@ -1587,7 +1572,6 @@ done:
* @endparblock
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (bd_create_cli, static) = {
.path = "create bridge-domain",
.short_help = "create bridge-domain <bridge-domain-id>"
@@ -1595,9 +1579,38 @@ VLIB_CLI_COMMAND (bd_create_cli, static) = {
" [arp-ufwd <0|1>] [mac-age <nn>] [bd-tag <tag>] [del]",
.function = bd_add_del_command_fn,
};
-/* *INDENT-ON* */
+/*
+ * Returns an unused bridge domain id, and ~0 if it can't find one.
+ */
+u32
+bd_get_unused_id (void)
+{
+ bd_main_t *bdm = &bd_main;
+ int i, j;
+ static u32 seed = 0;
+ /* limit to 1M tries */
+ for (j = 0; j < 1 << 10; j++)
+ {
+ seed = random_u32 (&seed);
+ for (i = 0; i < 1 << 10; i++)
+ {
+ /*
+ * iterate seed+0, seed+1, seed-1, seed+2, seed-2, ... to generate id
+ */
+ seed += (2 * (i % 2) - 1) * i;
+ /* bd_id must be (1 <= bd_id <= L2_BD_ID_MAX) */
+ seed &= L2_BD_ID_MAX;
+ if (seed == 0)
+ continue;
+ if (bd_find_index (bdm, seed) == ~0)
+ return seed;
+ }
+ }
+
+ return ~0;
+}
/*
* fd.io coding-style-patch-verification: ON
diff --git a/src/vnet/l2/l2_bd.h b/src/vnet/l2/l2_bd.h
index 0d77292519d..082d210b972 100644
--- a/src/vnet/l2/l2_bd.h
+++ b/src/vnet/l2/l2_bd.h
@@ -2,6 +2,7 @@
* l2_bd.h : layer 2 bridge domain
*
* Copyright (c) 2013 Cisco and/or its affiliates.
+ * Copyright (c) 2022 Nordix Foundation.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
@@ -166,7 +167,7 @@ u32 bd_set_flags (vlib_main_t * vm, u32 bd_index, bd_flags_t flags,
void bd_set_mac_age (vlib_main_t * vm, u32 bd_index, u8 age);
void bd_set_learn_limit (vlib_main_t *vm, u32 bd_index, u32 learn_limit);
int bd_add_del (l2_bridge_domain_add_del_args_t * args);
-
+u32 bd_get_unused_id (void);
/**
* \brief Get a bridge domain.
*
diff --git a/src/vnet/l2/l2_bvi.c b/src/vnet/l2/l2_bvi.c
index e5623682657..e39c4aae39d 100644
--- a/src/vnet/l2/l2_bvi.c
+++ b/src/vnet/l2/l2_bvi.c
@@ -58,14 +58,12 @@ bvi_mac_change (vnet_hw_interface_t * hi,
return (NULL);
}
-/* *INDENT-OFF* */
VNET_DEVICE_CLASS (bvi_device_class) = {
.name = "BVI",
.format_device_name = format_bvi_name,
.admin_up_down_function = bvi_admin_up_down,
.mac_addr_change_function = bvi_mac_change,
};
-/* *INDENT-ON* */
/*
* Maintain a bitmap of allocated bvi instance numbers.
@@ -138,13 +136,11 @@ l2_bvi_create (u32 user_instance,
{
vnet_main_t *vnm = vnet_get_main ();
vlib_main_t *vm = vlib_get_main ();
+ vnet_eth_interface_registration_t eir = {};
u32 instance, hw_if_index, slot;
vnet_hw_interface_t *hw_if;
- clib_error_t *error;
mac_address_t mac;
- int rv = 0;
-
ASSERT (sw_if_indexp);
*sw_if_indexp = (u32) ~ 0;
@@ -178,17 +174,10 @@ l2_bvi_create (u32 user_instance,
mac_address_copy (&mac, mac_in);
}
- error = ethernet_register_interface (vnm,
- bvi_device_class.index,
- instance, mac.bytes, &hw_if_index,
- /* flag change */ 0);
-
- if (error)
- {
- rv = VNET_API_ERROR_INVALID_REGISTRATION;
- clib_error_report (error);
- return rv;
- }
+ eir.dev_class_index = bvi_device_class.index;
+ eir.dev_instance = instance;
+ eir.address = mac.bytes;
+ hw_if_index = vnet_eth_register_interface (vnm, &eir);
hw_if = vnet_get_hw_interface (vnm, hw_if_index);
@@ -282,13 +271,11 @@ l2_bvi_create_cli (vlib_main_t * vm,
* Example of how to create a bvi interface:
* @cliexcmd{bvi create}
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (l2_bvi_create_command, static) = {
.path = "bvi create",
.short_help = "bvi create [mac <mac-addr>] [instance <instance>]",
.function = l2_bvi_create_cli,
};
-/* *INDENT-ON* */
static clib_error_t *
l2_bvi_delete_cli (vlib_main_t * vm,
@@ -333,13 +320,11 @@ l2_bvi_delete_cli (vlib_main_t * vm,
* Example of how to create a bvi interface:
* @cliexcmd{bvi delete bvi0}
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (l2_bvi_delete_command, static) = {
.path = "bvi delete",
.short_help = "bvi delete <interface>",
.function = l2_bvi_delete_cli,
};
-/* *INDENT-ON* */
/*
diff --git a/src/vnet/l2/l2_classify.h b/src/vnet/l2/l2_classify.h
index 68a2bb98e64..3c86fb5ca86 100644
--- a/src/vnet/l2/l2_classify.h
+++ b/src/vnet/l2/l2_classify.h
@@ -39,7 +39,6 @@ typedef enum
L2_INPUT_CLASSIFY_NEXT_ETHERNET_INPUT,
L2_INPUT_CLASSIFY_NEXT_IP4_INPUT,
L2_INPUT_CLASSIFY_NEXT_IP6_INPUT,
- L2_INPUT_CLASSIFY_NEXT_LI,
L2_INPUT_CLASSIFY_N_NEXT,
} l2_input_classify_next_t;
diff --git a/src/vnet/l2/l2_efp_filter.c b/src/vnet/l2/l2_efp_filter.c
index ad325b83df2..47256ffa5d3 100644
--- a/src/vnet/l2/l2_efp_filter.c
+++ b/src/vnet/l2/l2_efp_filter.c
@@ -461,7 +461,6 @@ VLIB_NODE_FN (l2_efp_filter_node) (vlib_main_t * vm,
}
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (l2_efp_filter_node) = {
.name = "l2-efp-filter",
.vector_size = sizeof (u32),
@@ -478,7 +477,6 @@ VLIB_REGISTER_NODE (l2_efp_filter_node) = {
[L2_EFP_FILTER_NEXT_DROP] = "error-drop",
},
};
-/* *INDENT-ON* */
#ifndef CLIB_MARCH_VARIANT
clib_error_t *
@@ -559,13 +557,11 @@ done:
* Example of how to disable a Layer 2 efp-filter on a sub-interface:
* @cliexcmd{set interface l2 efp-filter GigabitEthernet0/8/0.200 disable}
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (int_l2_efp_filter_cli, static) = {
.path = "set interface l2 efp-filter",
.short_help = "set interface l2 efp-filter <interface> [disable]",
.function = int_l2_efp_filter,
};
-/* *INDENT-ON* */
#endif /* CLIB_MARCH_VARIANT */
diff --git a/src/vnet/l2/l2_fib.c b/src/vnet/l2/l2_fib.c
index d1ee82273b1..3dcd1e7ae26 100644
--- a/src/vnet/l2/l2_fib.c
+++ b/src/vnet/l2/l2_fib.c
@@ -95,8 +95,7 @@ format_vnet_sw_if_index_name_with_NA (u8 * s, va_list * args)
if (!swif)
return format (s, "Stale");
- return format (s, "%U", format_vnet_sw_interface_name, vnm,
- vnet_get_sw_interface_or_null (vnm, sw_if_index));
+ return format (s, "%U", format_vnet_sw_if_index_name, vnm, sw_if_index);
}
typedef struct l2fib_dump_walk_ctx_t_
@@ -353,13 +352,11 @@ show_l2fib (vlib_main_t * vm,
* 3 l2fib entries
* @cliexend
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (show_l2fib_cli, static) = {
.path = "show l2fib",
.short_help = "show l2fib [all] | [bd_id <nn> | bd_index <nn>] [learn | add] | [raw]",
.function = show_l2fib,
};
-/* *INDENT-ON* */
void
l2fib_table_init (void)
@@ -416,13 +413,11 @@ clear_l2fib (vlib_main_t * vm,
* no l2fib entries
* @cliexend
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (clear_l2fib_cli, static) = {
.path = "clear l2fib",
.short_help = "clear l2fib",
.function = clear_l2fib,
};
-/* *INDENT-ON* */
static l2fib_seq_num_t
l2fib_cur_seq_num (u32 bd_index, u32 sw_if_index)
@@ -593,20 +588,18 @@ done:
* 3 l2fib entries
* @cliexend
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (l2fib_add_cli, static) = {
.path = "l2fib add",
.short_help = "l2fib add <mac> <bridge-domain-id> filter | <intf> [static | bvi]",
.function = l2fib_add,
};
-/* *INDENT-ON* */
static clib_error_t *
l2fib_test_command_fn (vlib_main_t * vm,
unformat_input_t * input, vlib_cli_command_t * cmd)
{
- u8 mac[6], save_mac[6];
+ u8 mac[8], save_mac[6];
u32 bd_index = 0;
u32 sw_if_index = 8;
u32 is_add = 0;
@@ -724,13 +717,11 @@ l2fib_test_command_fn (vlib_main_t * vm,
* @cliexcmd{test l2fib del mac 52:54:00:53:00:00 count 4}
* @endparblock
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (l2fib_test_command, static) = {
.path = "test l2fib",
.short_help = "test l2fib [add|del|check] mac <base-addr> count <nn>",
.function = l2fib_test_command_fn,
};
-/* *INDENT-ON* */
/**
@@ -833,13 +824,11 @@ done:
* Example of how to delete a MAC Address entry from the L2 FIB table of a bridge-domain (where 200 is the bridge-domain-id):
* @cliexcmd{l2fib del 52:54:00:53:18:33 200}
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (l2fib_del_cli, static) = {
.path = "l2fib del",
.short_help = "l2fib del <mac> <bridge-domain-id> []",
.function = l2fib_del,
};
-/* *INDENT-ON* */
static clib_error_t *
l2fib_set_scan_delay (vlib_main_t *vm, unformat_input_t *input,
@@ -977,13 +966,11 @@ l2fib_flush_mac_all (vlib_main_t * vm,
* Example of how to flush MAC Address entries learned on an interface from the L2 FIB table:
* @cliexcmd{l2fib flush-mac interface GigabitEthernet2/1/0}
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (l2fib_flush_mac_all_cli, static) = {
.path = "l2fib flush-mac all",
.short_help = "l2fib flush-mac all",
.function = l2fib_flush_mac_all,
};
-/* *INDENT-ON* */
/*?
* This command kick off ager to delete all existing MAC Address entries,
@@ -993,13 +980,11 @@ VLIB_CLI_COMMAND (l2fib_flush_mac_all_cli, static) = {
* Example of how to flush MAC Address entries learned on an interface from the L2 FIB table:
* @cliexcmd{l2fib flush-mac interface GigabitEthernet2/1/0}
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (l2fib_flush_mac_int_cli, static) = {
.path = "l2fib flush-mac interface",
.short_help = "l2fib flush-mac interface <if-name>",
.function = l2fib_flush_mac_int,
};
-/* *INDENT-ON* */
/**
Flush bridge-domain MACs except static ones.
@@ -1042,13 +1027,11 @@ done:
* Example of how to flush MAC Address entries learned in a bridge domain from the L2 FIB table:
* @cliexcmd{l2fib flush-mac bridge-domain 1000}
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (l2fib_flush_mac_bd_cli, static) = {
.path = "l2fib flush-mac bridge-domain",
.short_help = "l2fib flush-mac bridge-domain <bd-id>",
.function = l2fib_flush_mac_bd,
};
-/* *INDENT-ON* */
clib_error_t *
l2fib_sw_interface_up_down (vnet_main_t * vnm, u32 sw_if_index, u32 flags)
@@ -1149,7 +1132,7 @@ l2fib_scan (vlib_main_t * vm, f64 start_time, u8 event_only)
{
for (k = 0; k < BIHASH_KVP_PER_PAGE; k++)
{
- if (v->kvp[k].key == ~0ULL && v->kvp[k].value == ~0ULL)
+ if (BV (clib_bihash_is_free) (&v->kvp[k]))
continue;
l2fib_entry_key_t key = {.raw = v->kvp[k].key };
@@ -1366,13 +1349,11 @@ l2fib_mac_age_scanner_process (vlib_main_t * vm, vlib_node_runtime_t * rt,
return 0;
}
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (l2fib_mac_age_scanner_process_node) = {
.function = l2fib_mac_age_scanner_process,
.type = VLIB_NODE_TYPE_PROCESS,
.name = "l2fib-mac-age-scanner-process",
};
-/* *INDENT-ON* */
clib_error_t *
l2fib_init (vlib_main_t * vm)
diff --git a/src/vnet/l2/l2_fib.h b/src/vnet/l2/l2_fib.h
index 7f7cd761e20..e24d427b4e2 100644
--- a/src/vnet/l2/l2_fib.h
+++ b/src/vnet/l2/l2_fib.h
@@ -240,29 +240,9 @@ l2fib_compute_hash_bucket (l2fib_entry_key_t * key)
always_inline u64
l2fib_make_key (const u8 * mac_address, u16 bd_index)
{
- u64 temp;
-
- /*
- * The mac address in memory is A:B:C:D:E:F
- * The bd id in register is H:L
- */
-#if CLIB_ARCH_IS_LITTLE_ENDIAN
- /*
- * Create the in-register key as F:E:D:C:B:A:H:L
- * In memory the key is L:H:A:B:C:D:E:F
- */
- temp = CLIB_MEM_OVERFLOW_LOAD (*, (u64 *) mac_address) << 16;
- temp = (temp & ~0xffff) | (u64) (bd_index);
-#else
- /*
- * Create the in-register key as H:L:A:B:C:D:E:F
- * In memory the key is H:L:A:B:C:D:E:F
- */
- temp = CLIB_MEM_OVERFLOW_LOAD (*, (u64 *) mac_address) >> 16;
- temp = temp | (((u64) bd_index) << 48);
-#endif
-
- return temp;
+ l2fib_entry_key_t key = { .fields.bd_index = bd_index };
+ clib_memcpy_fast (&key.fields.mac, mac_address, sizeof (key.fields.mac));
+ return key.raw;
}
diff --git a/src/vnet/l2/l2_flood.c b/src/vnet/l2/l2_flood.c
index c0d7bf8dfab..f8cb3cb5687 100644
--- a/src/vnet/l2/l2_flood.c
+++ b/src/vnet/l2/l2_flood.c
@@ -362,7 +362,6 @@ VLIB_NODE_FN (l2flood_node) (vlib_main_t * vm,
}
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (l2flood_node) = {
.name = "l2-flood",
.vector_size = sizeof (u32),
@@ -380,7 +379,6 @@ VLIB_REGISTER_NODE (l2flood_node) = {
[L2FLOOD_NEXT_DROP] = "error-drop",
},
};
-/* *INDENT-ON* */
#ifndef CLIB_MARCH_VARIANT
clib_error_t *
@@ -468,13 +466,11 @@ done:
* Example of how to disable flooding:
* @cliexcmd{set interface l2 flood GigabitEthernet0/8/0 disable}
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (int_flood_cli, static) = {
.path = "set interface l2 flood",
.short_help = "set interface l2 flood <interface> [disable]",
.function = int_flood,
};
-/* *INDENT-ON* */
/*
* fd.io coding-style-patch-verification: ON
diff --git a/src/vnet/l2/l2_fwd.c b/src/vnet/l2/l2_fwd.c
index 3414f6c490e..503dfc27957 100644
--- a/src/vnet/l2/l2_fwd.c
+++ b/src/vnet/l2/l2_fwd.c
@@ -215,8 +215,7 @@ l2fwd_process (vlib_main_t * vm,
* unless some other feature is inserted before uu_flood
*/
if (vnet_buffer (b0)->l2.feature_bitmap &
- (L2INPUT_FEAT_UU_FLOOD |
- L2INPUT_FEAT_UU_FWD | L2INPUT_FEAT_GBP_FWD))
+ (L2INPUT_FEAT_UU_FLOOD | L2INPUT_FEAT_UU_FWD))
{
*next0 = vnet_l2_feature_next (b0, msm->feat_next_node_index,
L2INPUT_FEAT_FWD);
@@ -289,7 +288,6 @@ l2fwd_node_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
#ifdef COUNTERS
em->counters[node_counter_base_index + L2FWD_ERROR_L2FWD] += 4;
#endif
- /* *INDENT-OFF* */
l2fib_lookup_4 (msm->mac_table, &cached_key, &cached_result,
h0->dst_address, h1->dst_address,
h2->dst_address, h3->dst_address,
@@ -305,7 +303,6 @@ l2fwd_node_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
&result1,
&result2,
&result3);
- /* *INDENT-ON* */
l2fwd_process (vm, node, msm, em, b[0], sw_if_index0, &result0, next);
l2fwd_process (vm, node, msm, em, b[1], sw_if_index1, &result1,
next + 1);
@@ -415,7 +412,6 @@ VLIB_NODE_FN (l2fwd_node) (vlib_main_t * vm,
return l2fwd_node_inline (vm, node, frame, 0 /* do_trace */ );
}
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (l2fwd_node) = {
.name = "l2-fwd",
.vector_size = sizeof (u32),
@@ -433,7 +429,6 @@ VLIB_REGISTER_NODE (l2fwd_node) = {
[L2FWD_NEXT_DROP] = "error-drop",
},
};
-/* *INDENT-ON* */
#ifndef CLIB_MARCH_VARIANT
clib_error_t *
@@ -528,13 +523,11 @@ done:
* Example of how to disable forwarding:
* @cliexcmd{set interface l2 forward GigabitEthernet0/8/0 disable}
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (int_fwd_cli, static) = {
.path = "set interface l2 forward",
.short_help = "set interface l2 forward <interface> [disable]",
.function = int_fwd,
};
-/* *INDENT-ON* */
#endif
diff --git a/src/vnet/l2/l2_in_out_acl.c b/src/vnet/l2/l2_in_out_acl.c
index f8293c1feee..2e2cb1e7f36 100644
--- a/src/vnet/l2/l2_in_out_acl.c
+++ b/src/vnet/l2/l2_in_out_acl.c
@@ -278,7 +278,7 @@ l2_in_out_acl_node_fn (vlib_main_t * vm,
u32 table_index0;
vnet_classify_table_t *t0;
vnet_classify_entry_t *e0;
- u64 hash0;
+ u32 hash0;
u8 *h0;
u8 error0;
@@ -288,7 +288,7 @@ l2_in_out_acl_node_fn (vlib_main_t * vm,
vlib_buffer_t *p1 = vlib_get_buffer (vm, from[3]);
vnet_classify_table_t *tp1;
u32 table_index1;
- u64 phash1;
+ u32 phash1;
table_index1 = vnet_buffer (p1)->l2_classify.table_index;
@@ -464,7 +464,6 @@ VLIB_NODE_FN (l2_outacl_node) (vlib_main_t * vm,
IN_OUT_ACL_OUTPUT_TABLE_GROUP);
}
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (l2_inacl_node) = {
.name = "l2-input-acl",
.vector_size = sizeof (u32),
@@ -498,7 +497,6 @@ VLIB_REGISTER_NODE (l2_outacl_node) = {
[ACL_NEXT_INDEX_DENY] = "error-drop",
},
};
-/* *INDENT-ON* */
#ifndef CLIB_MARCH_VARIANT
diff --git a/src/vnet/l2/l2_in_out_feat_arc.c b/src/vnet/l2/l2_in_out_feat_arc.c
index b3b4a8cbb73..26fbd3eb776 100644
--- a/src/vnet/l2/l2_in_out_feat_arc.c
+++ b/src/vnet/l2/l2_in_out_feat_arc.c
@@ -257,7 +257,8 @@ l2_in_out_feat_arc_node_fn (vlib_main_t * vm,
sw_if_index = sw_if_indices;
n_left = frame->n_vectors;
- CLIB_PREFETCH (next_node_indices, 2 * CLIB_CACHE_LINE_BYTES, LOAD);
+ CLIB_PREFETCH (next_node_indices,
+ sizeof (fam->feat_next_node_index[is_output]), LOAD);
while (n_left > 3 * L2_FEAT_ARC_VEC_SIZE)
{
@@ -395,7 +396,6 @@ vnet_l2_in_out_feat_arc_enable_disable (u32 sw_if_index, int is_output,
}
#endif /* CLIB_MARCH_VARIANT */
-/* *INDENT-OFF* */
VNET_FEATURE_ARC_INIT (l2_in_ip4_arc, static) =
{
.arc_name = "l2-input-ip4",
@@ -437,10 +437,8 @@ VNET_FEATURE_ARC_INIT (l2_in_nonip_arc, static) =
};
-/* *INDENT-ON* */
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (l2_in_feat_arc_node) = {
.name = "l2-input-feat-arc",
.vector_size = sizeof (u32),
@@ -520,7 +518,6 @@ VNET_FEATURE_INIT (l2_out_nonip_arc_end, static) =
.node_name = "l2-output-feat-arc-end",
.runs_before = 0, /* not before any other features */
};
-/* *INDENT-ON* */
#ifndef CLIB_MARCH_VARIANT
diff --git a/src/vnet/l2/l2_input.c b/src/vnet/l2/l2_input.c
index de22cef600e..23bd5cc9958 100644
--- a/src/vnet/l2/l2_input.c
+++ b/src/vnet/l2/l2_input.c
@@ -646,13 +646,11 @@ done:
* Example of how to remove an interface from a Layer2 bridge-domain:
* @cliexcmd{set interface l3 GigabitEthernet0/a/0.200}
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (int_l2_bridge_cli, static) = {
.path = "set interface l2 bridge",
.short_help = "set interface l2 bridge <interface> <bridge-domain-id> [bvi|uu-fwd] [shg]",
.function = int_l2_bridge,
};
-/* *INDENT-ON* */
/**
* Set subinterface in xconnect mode with another interface.
@@ -712,13 +710,11 @@ done:
* @cliexcmd{set interface l3 GigabitEthernet0/8/0.300}
* @cliexcmd{set interface l3 GigabitEthernet0/9/0.300}
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (int_l2_xc_cli, static) = {
.path = "set interface l2 xconnect",
.short_help = "set interface l2 xconnect <interface> <peer interface>",
.function = int_l2_xc,
};
-/* *INDENT-ON* */
/**
* Set subinterface in L3 mode.
@@ -762,13 +758,11 @@ done:
* Example of how to set the mode of an interface to Layer 3:
* @cliexcmd{set interface l3 GigabitEthernet0/8/0.200}
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (int_l3_cli, static) = {
.path = "set interface l3",
.short_help = "set interface l3 <interface>",
.function = int_l3,
};
-/* *INDENT-ON* */
/**
* Show interface mode.
@@ -809,10 +803,8 @@ show_int_mode (vlib_main_t * vm,
{
/* Gather interfaces. */
sis = vec_new (vnet_sw_interface_t, pool_elts (im->sw_interfaces));
- _vec_len (sis) = 0;
- /* *INDENT-OFF* */
+ vec_set_len (sis, 0);
pool_foreach (si, im->sw_interfaces) { vec_add1 (sis, si[0]); }
- /* *INDENT-ON* */
}
vec_foreach (si, sis)
@@ -878,13 +870,11 @@ done:
* l2 bridge GigabitEthernet0/8/0.200 bd_id 200 shg 0
* @cliexend
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (show_l2_mode, static) = {
.path = "show mode",
.short_help = "show mode [<if-name1> <if-name2> ...]",
.function = show_int_mode,
};
-/* *INDENT-ON* */
#define foreach_l2_init_function \
_(feat_bitmap_drop_init) \
diff --git a/src/vnet/l2/l2_input.h b/src/vnet/l2/l2_input.h
index ba4c4b6ed31..3de1537b45e 100644
--- a/src/vnet/l2/l2_input.h
+++ b/src/vnet/l2/l2_input.h
@@ -27,6 +27,7 @@
#include <vnet/ethernet/packet.h>
#include <vnet/ip/ip4_inlines.h>
#include <vnet/ip/ip6_inlines.h>
+#include <vnet/mpls/mpls_lookup.h>
/* l2 connection type */
typedef enum l2_input_flags_t_
@@ -136,17 +137,10 @@ l2input_bd_config (u32 bd_index)
_(ARP_UFWD, "l2-uu-fwd") \
_(ARP_TERM, "arp-term-l2bd") \
_(UU_FLOOD, "l2-flood") \
- _(GBP_FWD, "gbp-fwd") \
_(UU_FWD, "l2-uu-fwd") \
_(FWD, "l2-fwd") \
_(RW, "l2-rw") \
_(LEARN, "l2-learn") \
- _(L2_EMULATION, "l2-emulation") \
- _(GBP_LEARN, "gbp-learn-l2") \
- _(GBP_LPM_ANON_CLASSIFY, "l2-gbp-lpm-anon-classify") \
- _(GBP_NULL_CLASSIFY, "gbp-null-classify") \
- _(GBP_SRC_CLASSIFY, "gbp-src-classify") \
- _(GBP_LPM_CLASSIFY, "l2-gbp-lpm-classify") \
_(VTR, "l2-input-vtr") \
_(L2_IP_QOS_RECORD, "l2-ip-qos-record") \
_(VPATH, "vpath-input-l2") \
@@ -334,7 +328,7 @@ vnet_update_l2_len (vlib_buffer_t *b)
/*
* Compute flow hash of an ethernet packet, use 5-tuple hash if L3 packet
- * is ip4 or ip6. Otherwise hash on smac/dmac/etype.
+ * is ip4, ip6, or mpls. Otherwise hash on smac/dmac/etype.
* The vlib buffer current pointer is expected to be at ethernet header
* and vnet l2.l2_len is expected to be setup already.
*/
@@ -349,6 +343,9 @@ vnet_l2_compute_flow_hash (vlib_buffer_t * b)
return ip4_compute_flow_hash ((ip4_header_t *) l3h, IP_FLOW_HASH_DEFAULT);
else if (ethertype == ETHERNET_TYPE_IP6)
return ip6_compute_flow_hash ((ip6_header_t *) l3h, IP_FLOW_HASH_DEFAULT);
+ else if (ethertype == ETHERNET_TYPE_MPLS)
+ return mpls_compute_flow_hash ((mpls_unicast_header_t *) l3h,
+ IP_FLOW_HASH_DEFAULT);
else
{
u32 a, b, c;
diff --git a/src/vnet/l2/l2_input_classify.c b/src/vnet/l2/l2_input_classify.c
index 53d46399daf..cc031bd46a5 100644
--- a/src/vnet/l2/l2_input_classify.c
+++ b/src/vnet/l2/l2_input_classify.c
@@ -179,8 +179,7 @@ VLIB_NODE_FN (l2_input_classify_node) (vlib_main_t * vm,
int type_index0, type_index1;
vnet_classify_table_t *t0, *t1;
u32 table_index0, table_index1;
- u64 hash0, hash1;
-
+ u32 hash0, hash1;
/* prefetch next iteration */
{
@@ -265,7 +264,7 @@ VLIB_NODE_FN (l2_input_classify_node) (vlib_main_t * vm,
u32 type_index0;
vnet_classify_table_t *t0;
u32 table_index0;
- u64 hash0;
+ u32 hash0;
bi0 = from[0];
b0 = vlib_get_buffer (vm, bi0);
@@ -316,14 +315,14 @@ VLIB_NODE_FN (l2_input_classify_node) (vlib_main_t * vm,
u32 next0 = ~0; /* next l2 input feature, please... */
ethernet_header_t *h0;
u32 table_index0;
- u64 hash0;
+ u32 hash0;
vnet_classify_table_t *t0;
vnet_classify_entry_t *e0;
if (PREDICT_TRUE (n_left_from > 2))
{
vlib_buffer_t *p2 = vlib_get_buffer (vm, from[2]);
- u64 phash2;
+ u32 phash2;
u32 table_index2;
vnet_classify_table_t *tp2;
@@ -443,7 +442,6 @@ VLIB_NODE_FN (l2_input_classify_node) (vlib_main_t * vm,
return frame->n_vectors;
}
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (l2_input_classify_node) = {
.name = "l2-input-classify",
.vector_size = sizeof (u32),
@@ -463,10 +461,8 @@ VLIB_REGISTER_NODE (l2_input_classify_node) = {
[L2_INPUT_CLASSIFY_NEXT_ETHERNET_INPUT] = "ethernet-input-not-l2",
[L2_INPUT_CLASSIFY_NEXT_IP4_INPUT] = "ip4-input",
[L2_INPUT_CLASSIFY_NEXT_IP6_INPUT] = "ip6-input",
- [L2_INPUT_CLASSIFY_NEXT_LI] = "li-hit",
},
};
-/* *INDENT-ON* */
#ifndef CLIB_MARCH_VARIANT
/** l2 input classsifier feature initialization. */
@@ -643,7 +639,6 @@ int_l2_input_classify_command_fn (vlib_main_t * vm,
* @todo This is incomplete. This needs a detailed description and a
* practical example.
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (int_l2_input_classify_cli, static) = {
.path = "set interface l2 input classify",
.short_help =
@@ -651,7 +646,6 @@ VLIB_CLI_COMMAND (int_l2_input_classify_cli, static) = {
" [ip6-table <n>] [other-table <n>]",
.function = int_l2_input_classify_command_fn,
};
-/* *INDENT-ON* */
/*
* fd.io coding-style-patch-verification: ON
diff --git a/src/vnet/l2/l2_input_node.c b/src/vnet/l2/l2_input_node.c
index 3638a8aa00d..76b94809eb3 100644
--- a/src/vnet/l2/l2_input_node.c
+++ b/src/vnet/l2/l2_input_node.c
@@ -141,9 +141,8 @@ classify_and_dispatch (l2input_main_t * msm, vlib_buffer_t * b0, u16 * next0)
u8 protocol = ((ip6_header_t *) l3h0)->protocol;
/* Disable bridge forwarding (flooding will execute instead if not xconnect) */
- feat_mask &= ~(L2INPUT_FEAT_FWD |
- L2INPUT_FEAT_UU_FLOOD |
- L2INPUT_FEAT_UU_FWD | L2INPUT_FEAT_GBP_FWD);
+ feat_mask &=
+ ~(L2INPUT_FEAT_FWD | L2INPUT_FEAT_UU_FLOOD | L2INPUT_FEAT_UU_FWD);
if (ethertype != ETHERNET_TYPE_ARP)
feat_mask &= ~(L2INPUT_FEAT_ARP_UFWD);
@@ -252,11 +251,11 @@ l2input_node_inline (vlib_main_t * vm,
/* Prefetch next iteration. */
{
- /* Prefetch the buffer header and packet for the N+2 loop iteration */
- vlib_prefetch_buffer_header (b[4], LOAD);
- vlib_prefetch_buffer_header (b[5], LOAD);
- vlib_prefetch_buffer_header (b[6], LOAD);
- vlib_prefetch_buffer_header (b[7], LOAD);
+ /* Prefetch the buffer header for the N+2 loop iteration */
+ clib_prefetch_store (b[4]);
+ clib_prefetch_store (b[5]);
+ clib_prefetch_store (b[6]);
+ clib_prefetch_store (b[7]);
clib_prefetch_store (b[4]->data);
clib_prefetch_store (b[5]->data);
@@ -366,7 +365,6 @@ VLIB_NODE_FN (l2input_node) (vlib_main_t * vm,
return l2input_node_inline (vm, node, frame, 0 /* do_trace */ );
}
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (l2input_node) = {
.name = "l2-input",
.vector_size = sizeof (u32),
@@ -386,7 +384,6 @@ VLIB_REGISTER_NODE (l2input_node) = {
[L2INPUT_NEXT_DROP] = "error-drop",
},
};
-/* *INDENT-ON* */
/*
* fd.io coding-style-patch-verification: ON
diff --git a/src/vnet/l2/l2_input_vtr.c b/src/vnet/l2/l2_input_vtr.c
index 3c1235bfa32..ccf3efa2390 100644
--- a/src/vnet/l2/l2_input_vtr.c
+++ b/src/vnet/l2/l2_input_vtr.c
@@ -319,7 +319,6 @@ VLIB_NODE_FN (l2_invtr_node) (vlib_main_t * vm,
}
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (l2_invtr_node) = {
.name = "l2-input-vtr",
.vector_size = sizeof (u32),
@@ -336,7 +335,6 @@ VLIB_REGISTER_NODE (l2_invtr_node) = {
[L2_INVTR_NEXT_DROP] = "error-drop",
},
};
-/* *INDENT-ON* */
#ifndef CLIB_MARCH_VARIANT
clib_error_t *
diff --git a/src/vnet/l2/l2_learn.c b/src/vnet/l2/l2_learn.c
index 6d90cee62a7..24b5389e55a 100644
--- a/src/vnet/l2/l2_learn.c
+++ b/src/vnet/l2/l2_learn.c
@@ -439,7 +439,6 @@ VLIB_NODE_FN (l2learn_node) (vlib_main_t * vm,
return l2learn_node_inline (vm, node, frame, 0 /* do_trace */ );
}
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (l2learn_node) = {
.name = "l2-learn",
.vector_size = sizeof (u32),
@@ -457,7 +456,6 @@ VLIB_REGISTER_NODE (l2learn_node) = {
[L2LEARN_NEXT_L2FWD] = "l2-fwd",
},
};
-/* *INDENT-ON* */
#ifndef CLIB_MARCH_VARIANT
clib_error_t *
@@ -540,13 +538,11 @@ done:
* Example of how to disable learning:
* @cliexcmd{set interface l2 learn GigabitEthernet0/8/0 disable}
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (int_learn_cli, static) = {
.path = "set interface l2 learn",
.short_help = "set interface l2 learn <interface> [disable]",
.function = int_learn,
};
-/* *INDENT-ON* */
static clib_error_t *
diff --git a/src/vnet/l2/l2_output.c b/src/vnet/l2/l2_output.c
index ba40de316d1..7c70cf9f4c7 100644
--- a/src/vnet/l2/l2_output.c
+++ b/src/vnet/l2/l2_output.c
@@ -22,6 +22,7 @@
#include <vppinfra/error.h>
#include <vppinfra/hash.h>
+#include <vppinfra/vector/count_equal.h>
#include <vnet/l2/feat_bitmap.h>
#include <vnet/l2/l2_output.h>
@@ -442,7 +443,6 @@ VLIB_NODE_FN (l2output_node) (vlib_main_t * vm,
return frame->n_vectors;
}
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (l2output_node) = {
.name = "l2-output",
.vector_size = sizeof (u32),
@@ -460,7 +460,6 @@ VLIB_REGISTER_NODE (l2output_node) = {
[L2OUTPUT_NEXT_BAD_INTF] = "l2-output-bad-intf",
},
};
-/* *INDENT-ON* */
#define foreach_l2output_bad_intf_error \
@@ -548,7 +547,6 @@ VLIB_NODE_FN (l2output_bad_intf_node) (vlib_main_t * vm,
return frame->n_vectors;
}
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (l2output_bad_intf_node) = {
.name = "l2-output-bad-intf",
.vector_size = sizeof (u32),
@@ -564,7 +562,6 @@ VLIB_REGISTER_NODE (l2output_bad_intf_node) = {
[0] = "error-drop",
},
};
-/* *INDENT-ON* */
static clib_error_t *
l2output_init (vlib_main_t * vm)
diff --git a/src/vnet/l2/l2_output.h b/src/vnet/l2/l2_output.h
index 1cc1e738841..201f5e195a4 100644
--- a/src/vnet/l2/l2_output.h
+++ b/src/vnet/l2/l2_output.h
@@ -81,9 +81,6 @@ extern vlib_node_registration_t l2output_node;
#define foreach_l2output_feat \
_(OUTPUT, "interface-output") \
_(SPAN, "span-l2-output") \
- _(GBP_POLICY_LPM, "gbp-policy-lpm") \
- _(GBP_POLICY_PORT, "gbp-policy-port") \
- _(GBP_POLICY_MAC, "gbp-policy-mac") \
_(CFM, "feature-bitmap-drop") \
_(QOS, "feature-bitmap-drop") \
_(ACL, "l2-output-acl") \
diff --git a/src/vnet/l2/l2_output_classify.c b/src/vnet/l2/l2_output_classify.c
index 96d0b14753a..33a7c927386 100644
--- a/src/vnet/l2/l2_output_classify.c
+++ b/src/vnet/l2/l2_output_classify.c
@@ -172,8 +172,7 @@ VLIB_NODE_FN (l2_output_classify_node) (vlib_main_t * vm,
int type_index0, type_index1;
vnet_classify_table_t *t0, *t1;
u32 table_index0, table_index1;
- u64 hash0, hash1;
-
+ u32 hash0, hash1;
/* prefetch next iteration */
{
@@ -257,7 +256,7 @@ VLIB_NODE_FN (l2_output_classify_node) (vlib_main_t * vm,
u32 type_index0;
vnet_classify_table_t *t0;
u32 table_index0;
- u64 hash0;
+ u32 hash0;
bi0 = from[0];
b0 = vlib_get_buffer (vm, bi0);
@@ -308,14 +307,14 @@ VLIB_NODE_FN (l2_output_classify_node) (vlib_main_t * vm,
u32 next0 = ~0;
ethernet_header_t *h0;
u32 table_index0;
- u64 hash0;
+ u32 hash0;
vnet_classify_table_t *t0;
vnet_classify_entry_t *e0;
if (PREDICT_TRUE (n_left_from > 2))
{
vlib_buffer_t *p2 = vlib_get_buffer (vm, from[2]);
- u64 phash2;
+ u32 phash2;
u32 table_index2;
vnet_classify_table_t *tp2;
@@ -436,7 +435,6 @@ VLIB_NODE_FN (l2_output_classify_node) (vlib_main_t * vm,
return frame->n_vectors;
}
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (l2_output_classify_node) = {
.name = "l2-output-classify",
.vector_size = sizeof (u32),
@@ -455,7 +453,6 @@ VLIB_REGISTER_NODE (l2_output_classify_node) = {
[L2_OUTPUT_CLASSIFY_NEXT_DROP] = "error-drop",
},
};
-/* *INDENT-ON* */
#ifndef CLIB_MARCH_VARIANT
/** l2 output classsifier feature initialization. */
@@ -635,7 +632,6 @@ int_l2_output_classify_command_fn (vlib_main_t * vm,
* @todo This is incomplete. This needs a detailed description and a
* practical example.
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (int_l2_output_classify_cli, static) = {
.path = "set interface l2 output classify",
.short_help =
@@ -643,7 +639,6 @@ VLIB_CLI_COMMAND (int_l2_output_classify_cli, static) = {
" [ip6-table <n>] [other-table <n>]",
.function = int_l2_output_classify_command_fn,
};
-/* *INDENT-ON* */
/*
* fd.io coding-style-patch-verification: ON
diff --git a/src/vnet/l2/l2_patch.c b/src/vnet/l2/l2_patch.c
index 6de4e50a298..f85938ed799 100644
--- a/src/vnet/l2/l2_patch.c
+++ b/src/vnet/l2/l2_patch.c
@@ -206,7 +206,6 @@ VLIB_NODE_FN (l2_patch_node) (vlib_main_t * vm,
return frame->n_vectors;
}
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (l2_patch_node) = {
.name = "l2-patch",
.vector_size = sizeof (u32),
@@ -223,7 +222,6 @@ VLIB_REGISTER_NODE (l2_patch_node) = {
[L2_PATCH_NEXT_DROP] = "error-drop",
},
};
-/* *INDENT-ON* */
extern int
vnet_l2_patch_add_del (u32 rx_sw_if_index, u32 tx_sw_if_index, int is_add);
@@ -270,6 +268,8 @@ vnet_l2_patch_add_del (u32 rx_sw_if_index, u32 tx_sw_if_index, int is_add)
vnet_feature_enable_disable ("device-input", "l2-patch",
rxhi->sw_if_index, 1, 0, 0);
+ vnet_feature_enable_disable ("port-rx-eth", "l2-patch",
+ rxhi->sw_if_index, 1, 0, 0);
}
else
{
@@ -278,6 +278,8 @@ vnet_l2_patch_add_del (u32 rx_sw_if_index, u32 tx_sw_if_index, int is_add)
vnet_feature_enable_disable ("device-input", "l2-patch",
rxhi->sw_if_index, 0, 0, 0);
+ vnet_feature_enable_disable ("port-rx-eth", "l2-patch",
+ rxhi->sw_if_index, 0, 0, 0);
if (vec_len (l2pm->tx_next_by_rx_sw_if_index) > rx_sw_if_index)
{
l2pm->tx_next_by_rx_sw_if_index[rx_sw_if_index] = ~0;
@@ -369,13 +371,11 @@ done:
* @todo This is incomplete. This needs a detailed description and a
* practical example.
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (test_patch_command, static) = {
.path = "test l2patch",
.short_help = "test l2patch rx <intfc> tx <intfc> [del]",
.function = test_patch_command_fn,
};
-/* *INDENT-ON* */
/** Display the contents of the l2patch table. */
static clib_error_t *
@@ -421,13 +421,11 @@ show_l2patch (vlib_main_t * vm,
* @todo This is incomplete. This needs a detailed description and a
* practical example.
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (show_l2patch_cli, static) = {
.path = "show l2patch",
.short_help = "Show l2 interface cross-connect entries",
.function = show_l2patch,
};
-/* *INDENT-ON* */
static clib_error_t *
l2_patch_init (vlib_main_t * vm)
diff --git a/src/vnet/l2/l2_rw.c b/src/vnet/l2/l2_rw.c
index b6de2faffc5..c0e8ec489fc 100644
--- a/src/vnet/l2/l2_rw.c
+++ b/src/vnet/l2/l2_rw.c
@@ -109,6 +109,7 @@ l2_rw_rewrite (l2_rw_entry_t * rwe, u8 * h)
/* FALLTHROUGH */
case 1:
d[0] = (d[0] & ~rwe->mask[0]) | rwe->value[0];
+ rwe->hit_count++;
break;
default:
abort ();
@@ -332,6 +333,7 @@ l2_rw_mod_entry (u32 * index,
return 0;
}
+ e->hit_count = 0;
e->skip_n_vectors = skip / sizeof (u32x4);
skip -= e->skip_n_vectors * sizeof (u32x4);
e->rewrite_n_vectors = (skip + len - 1) / sizeof (u32x4) + 1;
@@ -398,17 +400,19 @@ l2_rw_entry_cli_fn (vlib_main_t * vm,
* the provisioned mask and value, modifies the packet header.
*
* @cliexpar
- * @todo This is incomplete. This needs a detailed description and a
- * practical example.
+ * Example of how to add an l2 rewrite entry to change the destination mac of
+ * the packet to 00:8a:00:0d:0e:02 (where parameter mask is Ethernet header's
+mask,
+ * parameter value is Ethernet header's value):
+ * @cliexcmd{l2 rewrite entry mask ffffffffffff00000000000000000000 value
+008a000d0e0200000000000000000000}
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (l2_rw_entry_cli, static) = {
.path = "l2 rewrite entry",
.short_help =
"l2 rewrite entry [index <index>] [mask <hex-mask>] [value <hex-value>] [skip <n_bytes>] [del]",
.function = l2_rw_entry_cli_fn,
};
-/* *INDENT-ON* */
#ifndef CLIB_MARCH_VARIANT
int
@@ -468,21 +472,36 @@ l2_rw_interface_cli_fn (vlib_main_t * vm,
}
/*?
- * Layer 2-Rewrite node uses classify tables to match packets. Then, using
- * the provisioned mask and value, modifies the packet header.
+ * Apply the rule to the interface. The following example shows how to use
+classify
+ * entry and Layer 2-Rewrite entry to modify the packet ethernet header on the
+ * interface.
*
* @cliexpar
- * @todo This is incomplete. This needs a detailed description and a
- * practical example.
+ * Example use the classify to filter packets that do not need to be modified
+(where
+ * 192.168.68.34 is the destination ip of the data packet, 8080 is the
+destination port
+ * of the packet):
+ * @cliexcmd{classify table mask l3 ip4 dst l4 dst_port}
+ * @cliexcmd{classify session acl-hit-next permit table-index 0 match l3 ip4
+dst 192.168.68.34 l4 dst_port 8080}
+ *
+ * @cliexpar
+ * Example apply classify and l2 rewrite rules to the interface (where
+YusurK2Eth6/0/1/3
+ * is interface, \"table 0\" means Table Id is 0, \"miss 0\" means the packet
+that matches
+ * the classify. miss will be modified according to the l2 rewrite entry with
+index 0):
+ * @cliexcmd{set interface l2 rewrite YusurK2Eth6/0/1/3 table 0 miss-index 0}
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (l2_rw_interface_cli, static) = {
.path = "set interface l2 rewrite",
.short_help =
"set interface l2 rewrite <interface> [table <table index>] [miss-index <entry-index>]",
.function = l2_rw_interface_cli_fn,
};
-/* *INDENT-ON* */
static clib_error_t *
l2_rw_show_interfaces_cli_fn (vlib_main_t * vm,
@@ -494,30 +513,27 @@ l2_rw_show_interfaces_cli_fn (vlib_main_t * vm,
vlib_cli_output (vm, "No interface is currently using l2 rewrite\n");
uword i;
- /* *INDENT-OFF* */
clib_bitmap_foreach (i, rw->configs_bitmap) {
vlib_cli_output (vm, "sw_if_index:%d %U\n", i, format_l2_rw_config, &rw->configs[i]);
}
- /* *INDENT-ON* */
return 0;
}
/*?
- * Layer 2-Rewrite node uses classify tables to match packets. Then, using
- * the provisioned mask and value, modifies the packet header.
+ * This command displays the l2 rewrite entries of the interfaces.
*
* @cliexpar
- * @todo This is incomplete. This needs a detailed description and a
- * practical example.
+ * Example of how to display the l2 rewrite rules on the interface:
+ * @cliexstart{show l2 rewrite interfaces}
+ * sw_if_index:4 table-index:0 miss-index:0
+ * @cliexend
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (l2_rw_show_interfaces_cli, static) = {
.path = "show l2 rewrite interfaces",
.short_help =
"show l2 rewrite interfaces",
.function = l2_rw_show_interfaces_cli_fn,
};
-/* *INDENT-ON* */
static clib_error_t *
l2_rw_show_entries_cli_fn (vlib_main_t * vm,
@@ -528,30 +544,29 @@ l2_rw_show_entries_cli_fn (vlib_main_t * vm,
if (pool_elts (rw->entries) == 0)
vlib_cli_output (vm, "No entries\n");
- /* *INDENT-OFF* */
pool_foreach (e, rw->entries) {
vlib_cli_output (vm, "%U\n", format_l2_rw_entry, e);
}
- /* *INDENT-ON* */
return 0;
}
/*?
- * Layer 2-Rewrite node uses classify tables to match packets. Then, using
- * the provisioned mask and value, modifies the packet header.
+ * This command displays all l2 rewrite entries.
*
* @cliexpar
- * @todo This is incomplete. This needs a detailed description and a
- * practical example.
+ * Example of how to display all l2 rewrite entries:
+ * @cliexstart{show l2 rewrite entries}
+ * 0 - mask:ffffffffffff00000000000000000000
+value:aabbccddeeff00000000000000000000
+ * hits:0 skip_bytes:0
+ * @cliexend
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (l2_rw_show_entries_cli, static) = {
.path = "show l2 rewrite entries",
.short_help =
"show l2 rewrite entries",
.function = l2_rw_show_entries_cli_fn,
};
-/* *INDENT-ON* */
static int
l2_rw_enable_disable (u32 bridge_domain, u8 disable)
@@ -587,21 +602,22 @@ l2_rw_set_cli_fn (vlib_main_t * vm,
}
/*?
- * Layer 2-Rewrite node uses classify tables to match packets. Then, using
- * the provisioned mask and value, modfies the packet header.
+ * Layer 2 rewrite can be enabled and disabled on each interface and on each
+bridge-domain.
+ * Use this command to manage l2 rewrite on bridge-domain.
*
* @cliexpar
- * @todo This is incomplete. This needs a detailed description and a
- * practical example.
+ * Example of how to enable rewrite (where 100 is the bridge-domain-id):
+ * @cliexcmd{set bridge-domain rewrite 100}
+ * Example of how to disable rewrite (where 100 is the bridge-domain-id):
+ * @cliexcmd{set bridge-domain rewrite 100 disable}
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (l2_rw_set_cli, static) = {
.path = "set bridge-domain rewrite",
.short_help =
"set bridge-domain rewrite <bridge-domain> [disable]",
.function = l2_rw_set_cli_fn,
};
-/* *INDENT-ON* */
static clib_error_t *
l2_rw_init (vlib_main_t * vm)
@@ -643,7 +659,6 @@ static char *l2_rw_error_strings[] = {
#undef _
};
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (l2_rw_node) = {
.name = "l2-rw",
.vector_size = sizeof (u32),
@@ -655,7 +670,6 @@ VLIB_REGISTER_NODE (l2_rw_node) = {
.n_next_nodes = L2_RW_N_NEXT,
.next_nodes = { [L2_RW_NEXT_DROP] = "error-drop"},
};
-/* *INDENT-ON* */
/*
* fd.io coding-style-patch-verification: ON
diff --git a/src/vnet/l2/l2_rw.h b/src/vnet/l2/l2_rw.h
index f9b10333f43..6d12a21fe55 100644
--- a/src/vnet/l2/l2_rw.h
+++ b/src/vnet/l2/l2_rw.h
@@ -27,7 +27,6 @@
#include <vnet/l2/l2_input.h>
-/* *INDENT-OFF* */
typedef CLIB_PACKED(struct _l2_rw_entry {
u16 skip_n_vectors;
u16 rewrite_n_vectors;
@@ -35,15 +34,12 @@ typedef CLIB_PACKED(struct _l2_rw_entry {
u32x4 *mask;
u32x4 *value;
}) l2_rw_entry_t;
-/* *INDENT-ON* */
/* l2_rw configuration for one interface */
-/* *INDENT-OFF* */
typedef CLIB_PACKED(struct _l2_rw_config {
u32 table_index; /* Which classify table to use */
u32 miss_index; /* Rewrite entry to use if table does not match */
}) l2_rw_config_t;
-/* *INDENT-ON* */
typedef struct
{
diff --git a/src/vnet/l2/l2_test.c b/src/vnet/l2/l2_test.c
new file mode 100644
index 00000000000..b78e388a9f1
--- /dev/null
+++ b/src/vnet/l2/l2_test.c
@@ -0,0 +1,1435 @@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright(c) 2021 Cisco Systems, Inc.
+ * Copyright(c) 2022 Nordix Foundation.
+ */
+
+#include <vat/vat.h>
+#include <vlibapi/api.h>
+#include <vlibmemory/api.h>
+#include <vppinfra/error.h>
+#include <vpp/api/types.h>
+#include <inttypes.h>
+
+#include <vnet/l2/l2_classify.h>
+#include <vnet/l2/l2_vtr.h>
+#include <vnet/ip/ip_types_api.h>
+
+#define __plugin_msg_base l2_test_main.msg_id_base
+#include <vlibapi/vat_helper_macros.h>
+
+#include <vlibmemory/vlib.api_enum.h>
+#include <vlibmemory/vlib.api_types.h>
+
+/* Declare message IDs */
+#include <vnet/format_fns.h>
+#include <vnet/l2/l2.api_enum.h>
+#include <vnet/l2/l2.api_types.h>
+
+#define vl_endianfun /* define message structures */
+#include <vnet/l2/l2.api.h>
+#undef vl_endianfun
+
+#define vl_calcsizefun
+#include <vnet/l2/l2.api.h>
+#undef vl_calcsizefun
+
+typedef struct
+{
+ /* API message ID base */
+ u16 msg_id_base;
+ u32 ping_id;
+ vat_main_t *vat_main;
+} l2_test_main_t;
+
+static l2_test_main_t l2_test_main;
+
+static void
+vl_api_l2_fib_table_details_t_handler (vl_api_l2_fib_table_details_t *mp)
+{
+ vat_main_t *vam = l2_test_main.vat_main;
+
+ fformat (
+ vam->ofp, "%3" PRIu32 " %U %3" PRIu32 " %d %d %d",
+ ntohl (mp->bd_id), format_ethernet_address, mp->mac,
+ ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac, mp->bvi_mac);
+}
+
+static int
+api_l2_fib_table_dump (vat_main_t *vam)
+{
+ unformat_input_t *i = vam->input;
+ vl_api_l2_fib_table_dump_t *mp;
+ vl_api_control_ping_t *mp_ping;
+ u32 bd_id;
+ u8 bd_id_set = 0;
+ int ret;
+
+ /* Parse args required to build the message */
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "bd_id %d", &bd_id))
+ bd_id_set = 1;
+ else
+ break;
+ }
+
+ if (bd_id_set == 0)
+ {
+ errmsg ("missing bridge domain");
+ return -99;
+ }
+
+ fformat (vam->ofp, "BD-ID Mac Address sw-ndx Static Filter BVI");
+
+ /* Get list of l2 fib entries */
+ M (L2_FIB_TABLE_DUMP, mp);
+
+ mp->bd_id = ntohl (bd_id);
+ S (mp);
+
+ /* Use a control ping for synchronization */
+ PING (&l2_test_main, mp_ping);
+ S (mp_ping);
+
+ W (ret);
+ return ret;
+}
+
+static void
+vl_api_l2_xconnect_details_t_handler (vl_api_l2_xconnect_details_t *mp)
+{
+ vat_main_t *vam = l2_test_main.vat_main;
+ fformat (vam->ofp, "%15d%15d", ntohl (mp->rx_sw_if_index),
+ ntohl (mp->tx_sw_if_index));
+}
+
+static int
+api_l2_xconnect_dump (vat_main_t *vam)
+{
+ vl_api_l2_xconnect_dump_t *mp;
+ vl_api_control_ping_t *mp_ping;
+ int ret;
+
+ if (!vam->json_output)
+ {
+ print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
+ }
+
+ M (L2_XCONNECT_DUMP, mp);
+
+ S (mp);
+
+ /* Use a control ping for synchronization */
+ PING (&l2_test_main, mp_ping);
+ S (mp_ping);
+
+ W (ret);
+ return ret;
+}
+
+static int
+api_want_l2_arp_term_events (vat_main_t *vam)
+{
+ return -1;
+}
+
+static int
+api_want_l2_macs_events (vat_main_t *vam)
+{
+ unformat_input_t *line_input = vam->input;
+ vl_api_want_l2_macs_events_t *mp;
+ u8 enable_disable = 1;
+ u32 scan_delay = 0;
+ u32 max_macs_in_event = 0;
+ u32 learn_limit = 0;
+ int ret;
+
+ while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (line_input, "learn-limit %d", &learn_limit))
+ ;
+ else if (unformat (line_input, "scan-delay %d", &scan_delay))
+ ;
+ else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
+ ;
+ else if (unformat (line_input, "disable"))
+ enable_disable = 0;
+ else
+ break;
+ }
+
+ M (WANT_L2_MACS_EVENTS, mp);
+ mp->enable_disable = enable_disable;
+ mp->pid = htonl (getpid ());
+ mp->learn_limit = htonl (learn_limit);
+ mp->scan_delay = (u8) scan_delay;
+ mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
+ S (mp);
+ W (ret);
+ return ret;
+}
+
+static int
+api_l2fib_flush_all (vat_main_t *vam)
+{
+ return -1;
+}
+
+static void
+increment_mac_address (u8 *mac)
+{
+ u64 tmp = *((u64 *) mac);
+ tmp = clib_net_to_host_u64 (tmp);
+ tmp += 1 << 16; /* skip unused (least significant) octets */
+ tmp = clib_host_to_net_u64 (tmp);
+
+ clib_memcpy (mac, &tmp, 6);
+}
+
+static int
+api_l2fib_add_del (vat_main_t *vam)
+{
+ vnet_main_t *vnm = vnet_get_main ();
+ unformat_input_t *i = vam->input;
+ vl_api_l2fib_add_del_t *mp;
+ f64 timeout;
+ u8 mac[8] = { 0 };
+ u8 mac_set = 0;
+ u32 bd_id;
+ u8 bd_id_set = 0;
+ u32 sw_if_index = 0;
+ u8 sw_if_index_set = 0;
+ u8 is_add = 1;
+ u8 static_mac = 0;
+ u8 filter_mac = 0;
+ u8 bvi_mac = 0;
+ int count = 1;
+ f64 before = 0;
+ int j;
+
+ /* Parse args required to build the message */
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "mac %U", unformat_ethernet_address, mac))
+ mac_set = 1;
+ else if (unformat (i, "bd_id %d", &bd_id))
+ bd_id_set = 1;
+ else if (unformat (i, "sw_if_index %d", &sw_if_index))
+ sw_if_index_set = 1;
+ else if (unformat (i, "sw_if"))
+ {
+ if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "%U", unformat_vnet_sw_interface, vnm,
+ &sw_if_index))
+ sw_if_index_set = 1;
+ }
+ else
+ break;
+ }
+ else if (unformat (i, "static"))
+ static_mac = 1;
+ else if (unformat (i, "filter"))
+ {
+ filter_mac = 1;
+ static_mac = 1;
+ }
+ else if (unformat (i, "bvi"))
+ {
+ bvi_mac = 1;
+ static_mac = 1;
+ }
+ else if (unformat (i, "del"))
+ is_add = 0;
+ else if (unformat (i, "count %d", &count))
+ ;
+ else
+ break;
+ }
+
+ if (mac_set == 0)
+ {
+ errmsg ("missing mac address");
+ return -99;
+ }
+
+ if (bd_id_set == 0)
+ {
+ errmsg ("missing bridge domain");
+ return -99;
+ }
+
+ if (is_add && sw_if_index_set == 0 && filter_mac == 0)
+ {
+ errmsg ("missing interface name or sw_if_index");
+ return -99;
+ }
+
+ if (count > 1)
+ {
+ /* Turn on async mode */
+ vam->async_mode = 1;
+ vam->async_errors = 0;
+ before = vat_time_now (vam);
+ }
+
+ for (j = 0; j < count; j++)
+ {
+ M (L2FIB_ADD_DEL, mp);
+
+ clib_memcpy (mp->mac, mac, 6);
+ mp->bd_id = ntohl (bd_id);
+ mp->is_add = is_add;
+ mp->sw_if_index = ntohl (sw_if_index);
+
+ if (is_add)
+ {
+ mp->static_mac = static_mac;
+ mp->filter_mac = filter_mac;
+ mp->bvi_mac = bvi_mac;
+ }
+ increment_mac_address (mac);
+ /* send it... */
+ S (mp);
+ }
+
+ if (count > 1)
+ {
+ vl_api_control_ping_t *mp_ping;
+ f64 after;
+
+ /* Shut off async mode */
+ vam->async_mode = 0;
+
+ PING (&l2_test_main, mp_ping);
+ S (mp_ping);
+
+ timeout = vat_time_now (vam) + 1.0;
+ while (vat_time_now (vam) < timeout)
+ if (vam->result_ready == 1)
+ goto out;
+ vam->retval = -99;
+
+ out:
+ if (vam->retval == -99)
+ errmsg ("timeout");
+
+ if (vam->async_errors > 0)
+ {
+ errmsg ("%d asynchronous errors", vam->async_errors);
+ vam->retval = -98;
+ }
+ vam->async_errors = 0;
+ after = vat_time_now (vam);
+
+ print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec", count,
+ after - before, count / (after - before));
+ }
+ else
+ {
+ int ret;
+
+ /* Wait for a reply... */
+ W (ret);
+ return ret;
+ }
+ /* Return the good/bad news */
+ return (vam->retval);
+}
+
+static int
+api_l2fib_flush_int (vat_main_t *vam)
+{
+ vnet_main_t *vnm = vnet_get_main ();
+ unformat_input_t *i = vam->input;
+ vl_api_l2fib_flush_int_t *mp;
+ u32 sw_if_index = ~0;
+ int ret;
+
+ /* Parse args required to build the message */
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "sw_if_index %d", &sw_if_index))
+ ;
+ else if (unformat (i, "%U", unformat_vnet_sw_interface, vnm,
+ &sw_if_index))
+ ;
+ else
+ break;
+ }
+
+ if (sw_if_index == ~0)
+ {
+ errmsg ("missing interface name or sw_if_index");
+ return -99;
+ }
+
+ M (L2FIB_FLUSH_INT, mp);
+
+ mp->sw_if_index = ntohl (sw_if_index);
+
+ S (mp);
+ W (ret);
+ return ret;
+}
+
+static int
+api_l2_fib_clear_table (vat_main_t *vam)
+{
+ vl_api_l2_fib_clear_table_t *mp;
+ int ret;
+
+ M (L2_FIB_CLEAR_TABLE, mp);
+
+ S (mp);
+ W (ret);
+ return ret;
+}
+
+static int
+api_bridge_domain_set_mac_age (vat_main_t *vam)
+{
+ unformat_input_t *i = vam->input;
+ vl_api_bridge_domain_set_mac_age_t *mp;
+ u32 bd_id = ~0;
+ u32 mac_age = 0;
+ int ret;
+
+ /* Parse args required to build the message */
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "bd_id %d", &bd_id))
+ ;
+ else if (unformat (i, "mac-age %d", &mac_age))
+ ;
+ else
+ break;
+ }
+
+ if (bd_id == ~0)
+ {
+ errmsg ("missing bridge domain");
+ return -99;
+ }
+
+ if (mac_age > 255)
+ {
+ errmsg ("mac age must be less than 256 ");
+ return -99;
+ }
+
+ M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
+
+ mp->bd_id = htonl (bd_id);
+ mp->mac_age = (u8) mac_age;
+
+ S (mp);
+ W (ret);
+ return ret;
+}
+
+static int
+api_l2fib_set_scan_delay (vat_main_t *vam)
+{
+ return -1;
+}
+
+static int
+api_want_l2_macs_events2 (vat_main_t *vam)
+{
+ return -1;
+}
+
+static int
+api_l2_flags (vat_main_t *vam)
+{
+ vnet_main_t *vnm = vnet_get_main ();
+ unformat_input_t *i = vam->input;
+ vl_api_l2_flags_t *mp;
+ u32 sw_if_index;
+ u32 flags = 0;
+ u8 sw_if_index_set = 0;
+ u8 is_set = 0;
+ int ret;
+
+ /* Parse args required to build the message */
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "sw_if_index %d", &sw_if_index))
+ sw_if_index_set = 1;
+ else if (unformat (i, "sw_if"))
+ {
+ if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "%U", unformat_vnet_sw_interface, vnm,
+ &sw_if_index))
+ sw_if_index_set = 1;
+ }
+ else
+ break;
+ }
+ else if (unformat (i, "learn"))
+ flags |= L2_LEARN;
+ else if (unformat (i, "forward"))
+ flags |= L2_FWD;
+ else if (unformat (i, "flood"))
+ flags |= L2_FLOOD;
+ else if (unformat (i, "uu-flood"))
+ flags |= L2_UU_FLOOD;
+ else if (unformat (i, "arp-term"))
+ flags |= L2_ARP_TERM;
+ else if (unformat (i, "off"))
+ is_set = 0;
+ else if (unformat (i, "disable"))
+ is_set = 0;
+ else
+ break;
+ }
+
+ if (sw_if_index_set == 0)
+ {
+ errmsg ("missing interface name or sw_if_index");
+ return -99;
+ }
+
+ M (L2_FLAGS, mp);
+
+ mp->sw_if_index = ntohl (sw_if_index);
+ mp->feature_bitmap = ntohl (flags);
+ mp->is_set = is_set;
+
+ S (mp);
+ W (ret);
+ return ret;
+}
+
+static void
+vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t *mp)
+{
+ vat_main_t *vam = l2_test_main.vat_main;
+ i32 retval = ntohl (mp->retval);
+ if (vam->async_mode)
+ {
+ vam->async_errors += (retval < 0);
+ }
+ else
+ {
+ vam->retval = retval;
+ vam->result_ready = 1;
+ }
+}
+
+static int
+api_l2fib_flush_bd (vat_main_t *vam)
+{
+ unformat_input_t *i = vam->input;
+ vl_api_l2fib_flush_bd_t *mp;
+ u32 bd_id = ~0;
+ int ret;
+
+ /* Parse args required to build the message */
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "bd_id %d", &bd_id))
+ ;
+ else
+ break;
+ }
+
+ if (bd_id == ~0)
+ {
+ errmsg ("missing bridge domain");
+ return -99;
+ }
+
+ M (L2FIB_FLUSH_BD, mp);
+
+ mp->bd_id = htonl (bd_id);
+
+ S (mp);
+ W (ret);
+ return ret;
+}
+
+static int
+api_bridge_domain_add_del (vat_main_t *vam)
+{
+ unformat_input_t *i = vam->input;
+ vl_api_bridge_domain_add_del_t *mp;
+ u32 bd_id = ~0;
+ u8 is_add = 1;
+ u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
+ u8 *bd_tag = NULL;
+ u32 mac_age = 0;
+ int ret;
+
+ /* Parse args required to build the message */
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "bd_id %d", &bd_id))
+ ;
+ else if (unformat (i, "flood %d", &flood))
+ ;
+ else if (unformat (i, "uu-flood %d", &uu_flood))
+ ;
+ else if (unformat (i, "forward %d", &forward))
+ ;
+ else if (unformat (i, "learn %d", &learn))
+ ;
+ else if (unformat (i, "arp-term %d", &arp_term))
+ ;
+ else if (unformat (i, "mac-age %d", &mac_age))
+ ;
+ else if (unformat (i, "bd-tag %s", &bd_tag))
+ ;
+ else if (unformat (i, "del"))
+ {
+ is_add = 0;
+ flood = uu_flood = forward = learn = 0;
+ }
+ else
+ break;
+ }
+
+ if (bd_id == ~0)
+ {
+ errmsg ("missing bridge domain");
+ ret = -99;
+ goto done;
+ }
+
+ if (mac_age > 255)
+ {
+ errmsg ("mac age must be less than 256 ");
+ ret = -99;
+ goto done;
+ }
+
+ if ((bd_tag) && (vec_len (bd_tag) > 63))
+ {
+ errmsg ("bd-tag cannot be longer than 63");
+ ret = -99;
+ goto done;
+ }
+
+ M (BRIDGE_DOMAIN_ADD_DEL, mp);
+
+ mp->bd_id = ntohl (bd_id);
+ mp->flood = flood;
+ mp->uu_flood = uu_flood;
+ mp->forward = forward;
+ mp->learn = learn;
+ mp->arp_term = arp_term;
+ mp->is_add = is_add;
+ mp->mac_age = (u8) mac_age;
+ if (bd_tag)
+ {
+ clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
+ mp->bd_tag[vec_len (bd_tag)] = 0;
+ }
+ S (mp);
+ W (ret);
+
+done:
+ vec_free (bd_tag);
+ return ret;
+}
+
+static int
+api_bridge_domain_add_del_v2 (vat_main_t *vam)
+{
+ return -1;
+}
+
+static void
+vl_api_bridge_domain_add_del_v2_reply_t_handler (
+ vl_api_bridge_domain_add_del_v2_reply_t *mp)
+{
+}
+
+#define foreach_pbb_vtr_op \
+ _ ("disable", L2_VTR_DISABLED) \
+ _ ("pop", L2_VTR_POP_2) \
+ _ ("push", L2_VTR_PUSH_2)
+
+static int
+api_l2_interface_pbb_tag_rewrite (vat_main_t *vam)
+{
+ vnet_main_t *vnm = vnet_get_main ();
+ unformat_input_t *i = vam->input;
+ vl_api_l2_interface_pbb_tag_rewrite_t *mp;
+ u32 sw_if_index = ~0, vtr_op = ~0;
+ u16 outer_tag = ~0;
+ u8 dmac[6], smac[6];
+ u8 dmac_set = 0, smac_set = 0;
+ u16 vlanid = 0;
+ u32 sid = ~0;
+ u32 tmp;
+ int ret;
+
+ /* Shut up coverity */
+ clib_memset (dmac, 0, sizeof (dmac));
+ clib_memset (smac, 0, sizeof (smac));
+
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
+ ;
+ else if (unformat (i, "sw_if_index %d", &sw_if_index))
+ ;
+ else if (unformat (i, "vtr_op %d", &vtr_op))
+ ;
+#define _(n, v) \
+ else if (unformat (i, n)) { vtr_op = v; }
+ foreach_pbb_vtr_op
+#undef _
+ else if (unformat (i, "translate_pbb_stag"))
+ {
+ if (unformat (i, "%d", &tmp))
+ {
+ vtr_op = L2_VTR_TRANSLATE_2_1;
+ outer_tag = tmp;
+ }
+ else
+ {
+ errmsg (
+ "translate_pbb_stag operation requires outer tag definition");
+ return -99;
+ }
+ }
+ else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
+ dmac_set++;
+ else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
+ smac_set++;
+ else if (unformat (i, "sid %d", &sid));
+ else if (unformat (i, "vlanid %d", &tmp)) vlanid = tmp;
+ else
+ {
+ clib_warning ("parse error '%U'", format_unformat_error, i);
+ return -99;
+ }
+ }
+
+ if ((sw_if_index == ~0) || (vtr_op == ~0))
+ {
+ errmsg ("missing sw_if_index or vtr operation");
+ return -99;
+ }
+ if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2)) &&
+ ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
+ {
+ errmsg ("push and translate_qinq operations require dmac, smac, sid and "
+ "optionally vlanid");
+ return -99;
+ }
+
+ M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
+ mp->sw_if_index = ntohl (sw_if_index);
+ mp->vtr_op = ntohl (vtr_op);
+ mp->outer_tag = ntohs (outer_tag);
+ clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
+ clib_memcpy (mp->b_smac, smac, sizeof (smac));
+ mp->b_vlanid = ntohs (vlanid);
+ mp->i_sid = ntohl (sid);
+
+ S (mp);
+ W (ret);
+ return ret;
+}
+
+static int
+api_sw_interface_set_l2_xconnect (vat_main_t *vam)
+{
+ vnet_main_t *vnm = vnet_get_main ();
+ unformat_input_t *i = vam->input;
+ vl_api_sw_interface_set_l2_xconnect_t *mp;
+ u32 rx_sw_if_index;
+ u8 rx_sw_if_index_set = 0;
+ u32 tx_sw_if_index;
+ u8 tx_sw_if_index_set = 0;
+ u8 enable = 1;
+ int ret;
+
+ /* Parse args required to build the message */
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
+ rx_sw_if_index_set = 1;
+ else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
+ tx_sw_if_index_set = 1;
+ else if (unformat (i, "rx"))
+ {
+ if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "%U", unformat_vnet_sw_interface, vnm,
+ &rx_sw_if_index))
+ rx_sw_if_index_set = 1;
+ }
+ else
+ break;
+ }
+ else if (unformat (i, "tx"))
+ {
+ if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "%U", unformat_vnet_sw_interface, vnm,
+ &tx_sw_if_index))
+ tx_sw_if_index_set = 1;
+ }
+ else
+ break;
+ }
+ else if (unformat (i, "enable"))
+ enable = 1;
+ else if (unformat (i, "disable"))
+ enable = 0;
+ else
+ break;
+ }
+
+ if (rx_sw_if_index_set == 0)
+ {
+ errmsg ("missing rx interface name or rx_sw_if_index");
+ return -99;
+ }
+
+ if (enable && (tx_sw_if_index_set == 0))
+ {
+ errmsg ("missing tx interface name or tx_sw_if_index");
+ return -99;
+ }
+
+ M (SW_INTERFACE_SET_L2_XCONNECT, mp);
+
+ mp->rx_sw_if_index = ntohl (rx_sw_if_index);
+ mp->tx_sw_if_index = ntohl (tx_sw_if_index);
+ mp->enable = enable;
+
+ S (mp);
+ W (ret);
+ return ret;
+}
+
+static int
+api_l2_interface_efp_filter (vat_main_t *vam)
+{
+ vnet_main_t *vnm = vnet_get_main ();
+ unformat_input_t *i = vam->input;
+ vl_api_l2_interface_efp_filter_t *mp;
+ u32 sw_if_index;
+ u8 enable = 1;
+ u8 sw_if_index_set = 0;
+ int ret;
+
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
+ sw_if_index_set = 1;
+ else if (unformat (i, "sw_if_index %d", &sw_if_index))
+ sw_if_index_set = 1;
+ else if (unformat (i, "enable"))
+ enable = 1;
+ else if (unformat (i, "disable"))
+ enable = 0;
+ else
+ {
+ clib_warning ("parse error '%U'", format_unformat_error, i);
+ return -99;
+ }
+ }
+
+ if (sw_if_index_set == 0)
+ {
+ errmsg ("missing sw_if_index");
+ return -99;
+ }
+
+ M (L2_INTERFACE_EFP_FILTER, mp);
+
+ mp->sw_if_index = ntohl (sw_if_index);
+ mp->enable_disable = enable;
+
+ S (mp);
+ W (ret);
+ return ret;
+}
+
+static void
+vl_api_bd_ip_mac_details_t_handler (vl_api_bd_ip_mac_details_t *mp)
+{
+ vat_main_t *vam = &vat_main;
+
+ print (vam->ofp, "\n%-5d %U %U", ntohl (mp->entry.bd_id),
+ format_vl_api_mac_address, mp->entry.mac, format_vl_api_address,
+ &mp->entry.ip);
+}
+
+static void
+vl_api_bvi_create_reply_t_handler (vl_api_bvi_create_reply_t *mp)
+{
+}
+
+static int
+api_sw_interface_set_l2_bridge (vat_main_t *vam)
+{
+ vnet_main_t *vnm = vnet_get_main ();
+ unformat_input_t *i = vam->input;
+ vl_api_sw_interface_set_l2_bridge_t *mp;
+ vl_api_l2_port_type_t port_type;
+ u32 rx_sw_if_index;
+ u8 rx_sw_if_index_set = 0;
+ u32 bd_id;
+ u8 bd_id_set = 0;
+ u32 shg = 0;
+ u8 enable = 1;
+ int ret;
+
+ port_type = L2_API_PORT_TYPE_NORMAL;
+
+ /* Parse args required to build the message */
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
+ rx_sw_if_index_set = 1;
+ else if (unformat (i, "bd_id %d", &bd_id))
+ bd_id_set = 1;
+ else if (unformat (i, "%U", unformat_vnet_sw_interface, vnm,
+ &rx_sw_if_index))
+ rx_sw_if_index_set = 1;
+ else if (unformat (i, "shg %d", &shg))
+ ;
+ else if (unformat (i, "bvi"))
+ port_type = L2_API_PORT_TYPE_BVI;
+ else if (unformat (i, "uu-fwd"))
+ port_type = L2_API_PORT_TYPE_UU_FWD;
+ else if (unformat (i, "enable"))
+ enable = 1;
+ else if (unformat (i, "disable"))
+ enable = 0;
+ else
+ break;
+ }
+
+ if (rx_sw_if_index_set == 0)
+ {
+ errmsg ("missing rx interface name or sw_if_index");
+ return -99;
+ }
+
+ if (enable && (bd_id_set == 0))
+ {
+ errmsg ("missing bridge domain");
+ return -99;
+ }
+
+ M (SW_INTERFACE_SET_L2_BRIDGE, mp);
+
+ mp->rx_sw_if_index = ntohl (rx_sw_if_index);
+ mp->bd_id = ntohl (bd_id);
+ mp->shg = (u8) shg;
+ mp->port_type = ntohl (port_type);
+ mp->enable = enable;
+
+ S (mp);
+ W (ret);
+ return ret;
+}
+
+static int
+api_sw_interface_set_vpath (vat_main_t *vam)
+{
+ vnet_main_t *vnm = vnet_get_main ();
+ unformat_input_t *i = vam->input;
+ vl_api_sw_interface_set_vpath_t *mp;
+ u32 sw_if_index = 0;
+ u8 sw_if_index_set = 0;
+ u8 is_enable = 0;
+ int ret;
+
+ /* Parse args required to build the message */
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
+ sw_if_index_set = 1;
+ else if (unformat (i, "sw_if_index %d", &sw_if_index))
+ sw_if_index_set = 1;
+ else if (unformat (i, "enable"))
+ is_enable = 1;
+ else if (unformat (i, "disable"))
+ is_enable = 0;
+ else
+ break;
+ }
+
+ if (sw_if_index_set == 0)
+ {
+ errmsg ("missing interface name or sw_if_index");
+ return -99;
+ }
+
+ /* Construct the API message */
+ M (SW_INTERFACE_SET_VPATH, mp);
+
+ mp->sw_if_index = ntohl (sw_if_index);
+ mp->enable = is_enable;
+
+ /* send it... */
+ S (mp);
+
+ /* Wait for a reply... */
+ W (ret);
+ return ret;
+}
+
+static int
+api_l2_patch_add_del (vat_main_t *vam)
+{
+ vnet_main_t *vnm = vnet_get_main ();
+ unformat_input_t *i = vam->input;
+ vl_api_l2_patch_add_del_t *mp;
+ u32 rx_sw_if_index;
+ u8 rx_sw_if_index_set = 0;
+ u32 tx_sw_if_index;
+ u8 tx_sw_if_index_set = 0;
+ u8 is_add = 1;
+ int ret;
+
+ /* Parse args required to build the message */
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
+ rx_sw_if_index_set = 1;
+ else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
+ tx_sw_if_index_set = 1;
+ else if (unformat (i, "rx"))
+ {
+ if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "%U", unformat_vnet_sw_interface, vnm,
+ &rx_sw_if_index))
+ rx_sw_if_index_set = 1;
+ }
+ else
+ break;
+ }
+ else if (unformat (i, "tx"))
+ {
+ if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "%U", unformat_vnet_sw_interface, vnm,
+ &tx_sw_if_index))
+ tx_sw_if_index_set = 1;
+ }
+ else
+ break;
+ }
+ else if (unformat (i, "del"))
+ is_add = 0;
+ else
+ break;
+ }
+
+ if (rx_sw_if_index_set == 0)
+ {
+ errmsg ("missing rx interface name or rx_sw_if_index");
+ return -99;
+ }
+
+ if (tx_sw_if_index_set == 0)
+ {
+ errmsg ("missing tx interface name or tx_sw_if_index");
+ return -99;
+ }
+
+ M (L2_PATCH_ADD_DEL, mp);
+
+ mp->rx_sw_if_index = ntohl (rx_sw_if_index);
+ mp->tx_sw_if_index = ntohl (tx_sw_if_index);
+ mp->is_add = is_add;
+
+ S (mp);
+ W (ret);
+ return ret;
+}
+
+static void
+vl_api_bridge_flags_reply_t_handler (vl_api_bridge_flags_reply_t *mp)
+{
+ vat_main_t *vam = &vat_main;
+ i32 retval = ntohl (mp->retval);
+ if (vam->async_mode)
+ {
+ vam->async_errors += (retval < 0);
+ }
+ else
+ {
+ vam->retval = retval;
+ vam->result_ready = 1;
+ }
+}
+
+#define foreach_vtr_op \
+ _ ("disable", L2_VTR_DISABLED) \
+ _ ("push-1", L2_VTR_PUSH_1) \
+ _ ("push-2", L2_VTR_PUSH_2) \
+ _ ("pop-1", L2_VTR_POP_1) \
+ _ ("pop-2", L2_VTR_POP_2) \
+ _ ("translate-1-1", L2_VTR_TRANSLATE_1_1) \
+ _ ("translate-1-2", L2_VTR_TRANSLATE_1_2) \
+ _ ("translate-2-1", L2_VTR_TRANSLATE_2_1) \
+ _ ("translate-2-2", L2_VTR_TRANSLATE_2_2)
+
+static int
+api_l2_interface_vlan_tag_rewrite (vat_main_t *vam)
+{
+ vnet_main_t *vnm = vnet_get_main ();
+ unformat_input_t *i = vam->input;
+ vl_api_l2_interface_vlan_tag_rewrite_t *mp;
+ u32 sw_if_index;
+ u8 sw_if_index_set = 0;
+ u8 vtr_op_set = 0;
+ u32 vtr_op = 0;
+ u32 push_dot1q = 1;
+ u32 tag1 = ~0;
+ u32 tag2 = ~0;
+ int ret;
+
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
+ sw_if_index_set = 1;
+ else if (unformat (i, "sw_if_index %d", &sw_if_index))
+ sw_if_index_set = 1;
+ else if (unformat (i, "vtr_op %d", &vtr_op))
+ vtr_op_set = 1;
+#define _(n, v) \
+ else if (unformat (i, n)) \
+ { \
+ vtr_op = v; \
+ vtr_op_set = 1; \
+ }
+ foreach_vtr_op
+#undef _
+ else if (unformat (i, "push_dot1q %d", &push_dot1q));
+ else if (unformat (i, "tag1 %d", &tag1));
+ else if (unformat (i, "tag2 %d", &tag2));
+ else
+ {
+ clib_warning ("parse error '%U'", format_unformat_error, i);
+ return -99;
+ }
+ }
+
+ if ((sw_if_index_set == 0) || (vtr_op_set == 0))
+ {
+ errmsg ("missing vtr operation or sw_if_index");
+ return -99;
+ }
+
+ M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
+ mp->sw_if_index = ntohl (sw_if_index);
+ mp->vtr_op = ntohl (vtr_op);
+ mp->push_dot1q = ntohl (push_dot1q);
+ mp->tag1 = ntohl (tag1);
+ mp->tag2 = ntohl (tag2);
+
+ S (mp);
+ W (ret);
+ return ret;
+}
+
+static int
+api_bridge_domain_set_learn_limit (vat_main_t *vam)
+{
+ return -1;
+}
+
+static int
+api_bd_ip_mac_add_del (vat_main_t *vam)
+{
+ vl_api_address_t ip = VL_API_ZERO_ADDRESS;
+ vl_api_mac_address_t mac = { 0 };
+ unformat_input_t *i = vam->input;
+ vl_api_bd_ip_mac_add_del_t *mp;
+ u32 bd_id;
+ u8 is_add = 1;
+ u8 bd_id_set = 0;
+ u8 ip_set = 0;
+ u8 mac_set = 0;
+ int ret;
+
+ /* Parse args required to build the message */
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "bd_id %d", &bd_id))
+ {
+ bd_id_set++;
+ }
+ else if (unformat (i, "%U", unformat_vl_api_address, &ip))
+ {
+ ip_set++;
+ }
+ else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
+ {
+ mac_set++;
+ }
+ else if (unformat (i, "del"))
+ is_add = 0;
+ else
+ break;
+ }
+
+ if (bd_id_set == 0)
+ {
+ errmsg ("missing bridge domain");
+ return -99;
+ }
+ else if (ip_set == 0)
+ {
+ errmsg ("missing IP address");
+ return -99;
+ }
+ else if (mac_set == 0)
+ {
+ errmsg ("missing MAC address");
+ return -99;
+ }
+
+ M (BD_IP_MAC_ADD_DEL, mp);
+
+ mp->entry.bd_id = ntohl (bd_id);
+ mp->is_add = is_add;
+
+ clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
+ clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
+
+ S (mp);
+ W (ret);
+ return ret;
+}
+
+static void
+vl_api_bridge_domain_details_t_handler (vl_api_bridge_domain_details_t *mp)
+{
+ vat_main_t *vam = l2_test_main.vat_main;
+ u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
+ int i;
+
+ print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s", " ID", "LRN", "FWD",
+ "FLD", "BVI", "UU-FWD", "#IF");
+
+ print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d", ntohl (mp->bd_id), mp->learn,
+ mp->forward, mp->flood, ntohl (mp->bvi_sw_if_index),
+ ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
+
+ if (n_sw_ifs)
+ {
+ vl_api_bridge_domain_sw_if_t *sw_ifs;
+ print (vam->ofp, "\n\n%s %s %s", "sw_if_index", "SHG",
+ "Interface Name");
+
+ sw_ifs = mp->sw_if_details;
+ for (i = 0; i < n_sw_ifs; i++)
+ {
+ u8 *sw_if_name = 0;
+ u32 sw_if_index;
+ hash_pair_t *p;
+
+ sw_if_index = ntohl (sw_ifs->sw_if_index);
+
+ hash_foreach_pair (p, vam->sw_if_index_by_interface_name, ({
+ if ((u32) p->value[0] == sw_if_index)
+ {
+ sw_if_name = (u8 *) (p->key);
+ break;
+ }
+ }));
+ print (vam->ofp, "%7d %3d %s", sw_if_index, sw_ifs->shg,
+ sw_if_name ? (char *) sw_if_name : "sw_if_index not found!");
+
+ sw_ifs++;
+ }
+ }
+}
+
+static int
+api_bridge_domain_dump (vat_main_t *vam)
+{
+ unformat_input_t *i = vam->input;
+ vl_api_bridge_domain_dump_t *mp;
+ vl_api_control_ping_t *mp_ping;
+ u32 bd_id = ~0;
+ int ret;
+
+ /* Parse args required to build the message */
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "bd_id %d", &bd_id))
+ ;
+ else
+ break;
+ }
+
+ M (BRIDGE_DOMAIN_DUMP, mp);
+ mp->bd_id = ntohl (bd_id);
+ S (mp);
+
+ /* Use a control ping for synchronization */
+ PING (&l2_test_main, mp_ping);
+ S (mp_ping);
+
+ W (ret);
+ return ret;
+}
+
+static int
+api_bridge_domain_set_default_learn_limit (vat_main_t *vam)
+{
+ return -1;
+}
+
+static int
+api_bd_ip_mac_flush (vat_main_t *vam)
+{
+ unformat_input_t *i = vam->input;
+ vl_api_bd_ip_mac_flush_t *mp;
+ u32 bd_id;
+ u8 bd_id_set = 0;
+ int ret;
+
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "bd_id %d", &bd_id))
+ {
+ bd_id_set++;
+ }
+ else
+ break;
+ }
+
+ if (bd_id_set == 0)
+ {
+ errmsg ("missing bridge domain");
+ return -99;
+ }
+
+ M (BD_IP_MAC_FLUSH, mp);
+
+ mp->bd_id = ntohl (bd_id);
+
+ S (mp);
+ W (ret);
+ return ret;
+}
+
+static int
+api_bd_ip_mac_dump (vat_main_t *vam)
+{
+ unformat_input_t *i = vam->input;
+ vl_api_bd_ip_mac_dump_t *mp;
+ vl_api_control_ping_t *mp_ping;
+ int ret;
+ u32 bd_id;
+ u8 bd_id_set = 0;
+
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "bd_id %d", &bd_id))
+ {
+ bd_id_set++;
+ }
+ else
+ break;
+ }
+
+ fformat (vam->ofp, "\n%-5s %-7s %-20s %-30s", "bd_id", "is_ipv6",
+ "mac_address", "ip_address");
+
+ /* Dump Bridge Domain Ip to Mac entries */
+ M (BD_IP_MAC_DUMP, mp);
+
+ if (bd_id_set)
+ mp->bd_id = htonl (bd_id);
+ else
+ mp->bd_id = ~0;
+
+ S (mp);
+
+ /* Use a control ping for synchronization */
+ PING (&l2_test_main, mp_ping);
+ S (mp_ping);
+
+ W (ret);
+ return ret;
+}
+
+static int
+api_bvi_create (vat_main_t *vam)
+{
+ return -1;
+}
+
+static int
+api_bvi_delete (vat_main_t *vam)
+{
+ return -1;
+}
+
+static int
+api_bridge_flags (vat_main_t *vam)
+{
+ unformat_input_t *i = vam->input;
+ vl_api_bridge_flags_t *mp;
+ u32 bd_id;
+ u8 bd_id_set = 0;
+ u8 is_set = 1;
+ bd_flags_t flags = 0;
+ int ret;
+
+ /* Parse args required to build the message */
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "bd_id %d", &bd_id))
+ bd_id_set = 1;
+ else if (unformat (i, "learn"))
+ flags |= BRIDGE_API_FLAG_LEARN;
+ else if (unformat (i, "forward"))
+ flags |= BRIDGE_API_FLAG_FWD;
+ else if (unformat (i, "flood"))
+ flags |= BRIDGE_API_FLAG_FLOOD;
+ else if (unformat (i, "uu-flood"))
+ flags |= BRIDGE_API_FLAG_UU_FLOOD;
+ else if (unformat (i, "arp-term"))
+ flags |= BRIDGE_API_FLAG_ARP_TERM;
+ else if (unformat (i, "off"))
+ is_set = 0;
+ else if (unformat (i, "disable"))
+ is_set = 0;
+ else
+ break;
+ }
+
+ if (bd_id_set == 0)
+ {
+ errmsg ("missing bridge domain");
+ return -99;
+ }
+
+ M (BRIDGE_FLAGS, mp);
+
+ mp->bd_id = ntohl (bd_id);
+ mp->flags = ntohl (flags);
+ mp->is_set = is_set;
+
+ S (mp);
+ W (ret);
+ return ret;
+}
+
+#include <vnet/l2/l2.api_test.c>
+
+/*
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/src/vnet/l2/l2_uu_fwd.c b/src/vnet/l2/l2_uu_fwd.c
index fb3571d159c..4a510b658d7 100644
--- a/src/vnet/l2/l2_uu_fwd.c
+++ b/src/vnet/l2/l2_uu_fwd.c
@@ -211,7 +211,6 @@ VLIB_NODE_FN (l2_uu_fwd_node) (vlib_main_t * vm,
return frame->n_vectors;
}
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (l2_uu_fwd_node) = {
.name = "l2-uu-fwd",
.vector_size = sizeof (u32),
@@ -228,7 +227,6 @@ VLIB_REGISTER_NODE (l2_uu_fwd_node) = {
[L2_UU_FWD_NEXT_L2_OUTPUT] = "l2-output",
},
};
-/* *INDENT-ON* */
/*
* fd.io coding-style-patch-verification: ON
diff --git a/src/vnet/l2/l2_vtr.c b/src/vnet/l2/l2_vtr.c
index bfd1dcb9280..4053c0fc1cb 100644
--- a/src/vnet/l2/l2_vtr.c
+++ b/src/vnet/l2/l2_vtr.c
@@ -670,13 +670,11 @@ done:
* @cliexend
* @endparblock
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (int_l2_vtr_cli, static) = {
.path = "set interface l2 tag-rewrite",
.short_help = "set interface l2 tag-rewrite <interface> [disable | pop {1|2} | push {dot1q|dot1ad} <tag> <tag>]",
.function = int_l2_vtr,
};
-/* *INDENT-ON* */
/**
* Get pbb tag rewrite on the given interface.
@@ -816,13 +814,11 @@ done:
return error;
}
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (int_l2_pbb_vtr_cli, static) = {
.path = "set interface l2 pbb-tag-rewrite",
.short_help = "set interface l2 pbb-tag-rewrite <interface> [disable | pop | push | translate_pbb_stag <outer_tag> dmac <address> smac <address> s_id <nn> [b_vlanid <nn>]]",
.function = int_l2_pbb_vtr,
};
-/* *INDENT-ON* */
/*
* fd.io coding-style-patch-verification: ON
diff --git a/src/vnet/l2/l2_xcrw.c b/src/vnet/l2/l2_xcrw.c
index c2c325a796f..9edd8b6ba57 100644
--- a/src/vnet/l2/l2_xcrw.c
+++ b/src/vnet/l2/l2_xcrw.c
@@ -238,7 +238,6 @@ VLIB_NODE_FN (l2_xcrw_node) (vlib_main_t * vm,
return frame->n_vectors;
}
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (l2_xcrw_node) = {
.name = "l2-xcrw",
.vector_size = sizeof (u32),
@@ -255,7 +254,6 @@ VLIB_REGISTER_NODE (l2_xcrw_node) = {
[L2_XCRW_NEXT_DROP] = "error-drop",
},
};
-/* *INDENT-ON* */
#ifndef CLIB_MARCH_VARIANT
clib_error_t *
@@ -279,18 +277,17 @@ format_xcrw_name (u8 * s, va_list * args)
return format (s, "xcrw%d", dev_instance);
}
-/* *INDENT-OFF* */
VNET_DEVICE_CLASS (xcrw_device_class,static) = {
.name = "Xcrw",
.format_device_name = format_xcrw_name,
};
-/* *INDENT-ON* */
/* Create a sham tunnel interface and return its sw_if_index */
static u32
create_xcrw_interface (vlib_main_t * vm)
{
vnet_main_t *vnm = vnet_get_main ();
+ vnet_eth_interface_registration_t eir = {};
static u32 instance;
u8 address[6];
u32 hw_if_index;
@@ -301,10 +298,9 @@ create_xcrw_interface (vlib_main_t * vm)
clib_memset (address, 0, sizeof (address));
address[2] = 0x12;
- /* can returns error iff phy != 0 */
- (void) ethernet_register_interface
- (vnm, xcrw_device_class.index, instance++, address, &hw_if_index,
- /* flag change */ 0);
+ eir.dev_class_index = xcrw_device_class.index;
+ eir.dev_instance = instance++, eir.address = address;
+ hw_if_index = vnet_eth_register_interface (vnm, &eir);
hi = vnet_get_hw_interface (vnm, hw_if_index);
sw_if_index = hi->sw_if_index;
@@ -496,7 +492,6 @@ done:
* @todo This is incomplete. This needs a detailed description and a
* practical example.
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (set_l2_xcrw_command, static) = {
.path = "set interface l2 xcrw",
.short_help =
@@ -504,7 +499,6 @@ VLIB_CLI_COMMAND (set_l2_xcrw_command, static) = {
" [del] [tx-fib-id <id>] [ipv6] rw <hex-bytes>",
.function = set_l2_xcrw_command_fn,
};
-/* *INDENT-ON* */
#endif /* CLIB_MARCH_VARIANT */
@@ -568,12 +562,10 @@ show_l2xcrw_command_fn (vlib_main_t * vm,
vlib_cli_output (vm, "%U", format_l2xcrw, 0, 0);
- /* *INDENT-OFF* */
pool_foreach (t, xcm->tunnels)
{
vlib_cli_output (vm, "%U", format_l2xcrw, vnm, t);
}
- /* *INDENT-ON* */
return 0;
}
@@ -585,13 +577,11 @@ show_l2xcrw_command_fn (vlib_main_t * vm,
* @todo This is incomplete. This needs a detailed description and a
* practical example.
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (show_l2xcrw_command, static) = {
.path = "show l2xcrw",
.short_help = "show l2xcrw",
.function = show_l2xcrw_command_fn,
};
-/* *INDENT-ON* */
/*
* fd.io coding-style-patch-verification: ON