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