/* Delete localsid registry */
pool_put (sm->localsids, ls);
mhash_unset (&sm->sr_localsids_index_hash, localsid_addr, NULL);
- return 1;
+ return 0;
}
else /* create with function already existing; complain */
return -1;
/* Create a new localsid registry */
pool_get (sm->localsids, ls);
- memset (ls, 0, sizeof (*ls));
+ clib_memset (ls, 0, sizeof (*ls));
clib_memcpy (&ls->localsid, localsid_addr, sizeof (ip6_address_t));
ls->end_psp = end_psp;
ls->sw_if_index = sw_if_index;
clib_memcpy (&ls->next_hop.ip6, &nh_addr->ip6, sizeof (ip6_address_t));
break;
+ case SR_BEHAVIOR_T:
+ ls->vrf_index = fib_table_find (FIB_PROTOCOL_IP6, sw_if_index);
+ break;
case SR_BEHAVIOR_DX4:
ls->sw_if_index = sw_if_index;
clib_memcpy (&ls->next_hop.ip4, &nh_addr->ip4, sizeof (ip4_address_t));
clib_memcpy (&ls->next_hop.ip6, &nh_addr->ip6, sizeof (ip6_address_t));
break;
case SR_BEHAVIOR_DT6:
- ls->vrf_index = sw_if_index;
+ ls->vrf_index = fib_table_find (FIB_PROTOCOL_IP6, sw_if_index);
+ break;
+ case SR_BEHAVIOR_DT4:
+ ls->vrf_index = fib_table_find (FIB_PROTOCOL_IP4, sw_if_index);
break;
case SR_BEHAVIOR_DX2:
ls->sw_if_index = sw_if_index;
int rv;
- memset (&resulting_address, 0, sizeof (ip6_address_t));
+ clib_memset (&resulting_address, 0, sizeof (ip6_address_t));
ip46_address_reset (&next_hop);
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
unformat_vnet_sw_interface, vnm, &sw_if_index,
unformat_ip6_address, &next_hop.ip6))
behavior = SR_BEHAVIOR_X;
+ else if (unformat (input, "end.t %u", &sw_if_index))
+ behavior = SR_BEHAVIOR_T;
else if (unformat (input, "end.dx6 %U %U",
unformat_vnet_sw_interface, vnm, &sw_if_index,
unformat_ip6_address, &next_hop.ip6))
format_vnet_sw_if_index_name, vnm, ls->sw_if_index,
format_ip6_address, &ls->next_hop.ip6);
break;
+ case SR_BEHAVIOR_T:
+ vlib_cli_output (vm,
+ "\tAddress: \t%U\n\tBehavior: \tT (Endpoint with specific IPv6 table lookup)"
+ "\n\tTable: \t%u",
+ format_ip6_address, &ls->localsid, ls->vrf_index);
+ break;
case SR_BEHAVIOR_DX4:
vlib_cli_output (vm,
"\tAddress: \t%U\n\tBehavior: \tDX4 (Endpoint with decapsulation and IPv4 cross-connect)"
vlib_cli_output (vm,
"\tAddress: \t%U\n\tBehavior: \tDT6 (Endpoint with decapsulation and specific IPv6 table lookup)"
"\n\tTable: %u", format_ip6_address, &ls->localsid,
- ls->fib_table);
+ ls->vrf_index);
break;
case SR_BEHAVIOR_DT4:
vlib_cli_output (vm,
"\tAddress: \t%U\n\tBehavior: \tDT4 (Endpoint with decapsulation and specific IPv4 table lookup)"
"\n\tTable: \t%u", format_ip6_address,
- &ls->localsid, ls->fib_table);
+ &ls->localsid, ls->vrf_index);
break;
default:
if (ls->behavior >= SR_BEHAVIOR_LAST)
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (clear_sr_localsid_counters_command, static) = {
- .path = "clear sr localsid counters",
- .short_help = "clear sr localsid counters",
+ .path = "clear sr localsid-counters",
+ .short_help = "clear sr localsid-counters",
.function = clear_sr_localsid_counters_command_fn,
};
/* *INDENT-ON* */
*/
typedef struct
{
- u32 localsid_index;
- ip6_address_t src, out_dst;
+ ip6_address_t localsid;
+ u16 behavior;
u8 sr[256];
u8 num_segments;
u8 segments_left;
- //With SRv6 header update include flags here.
} sr_localsid_trace_t;
#define foreach_sr_localsid_error \
{
CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
- ip6_sr_main_t *sm = &sr_main;
sr_localsid_trace_t *t = va_arg (*args, sr_localsid_trace_t *);
- ip6_sr_localsid_t *ls =
- pool_elt_at_index (sm->localsids, t->localsid_index);
-
s =
format (s, "SR-LOCALSID:\n\tLocalsid: %U\n", format_ip6_address,
- &ls->localsid);
- switch (ls->behavior)
+ &t->localsid);
+ switch (t->behavior)
{
case SR_BEHAVIOR_END:
s = format (s, "\tBehavior: End\n");
case SR_BEHAVIOR_X:
s = format (s, "\tBehavior: IPv6 L3 xconnect\n");
break;
+ case SR_BEHAVIOR_T:
+ s = format (s, "\tBehavior: IPv6 specific table lookup\n");
+ break;
case SR_BEHAVIOR_DT6:
s = format (s, "\tBehavior: Decapsulation with IPv6 Table lookup\n");
break;
{
if (t->num_segments > 0)
{
- s = format (s, "\tSegments left: %d\n", t->num_segments);
+ s = format (s, "\tSegments left: %d\n", t->segments_left);
s = format (s, "\tSID list: [in ietf order]");
int i = 0;
for (i = 0; i < t->num_segments; i++)
vlib_buffer_t * b0,
ip6_header_t * ip0,
ip6_sr_header_t * sr0,
- ip6_sr_localsid_t * ls0, u32 * next0)
+ ip6_sr_localsid_t * ls0,
+ u32 * next0, u8 psp, ip6_ext_header_t * prev0)
{
ip6_address_t *new_dst0;
if (PREDICT_TRUE (sr0->type == ROUTING_HEADER_TYPE_SR))
{
- if (PREDICT_TRUE (sr0->segments_left != 0))
+ if (sr0->segments_left == 1 && psp)
+ {
+ u32 new_l0, sr_len;
+ u64 *copy_dst0, *copy_src0;
+ u32 copy_len_u64s0 = 0;
+
+ ip0->dst_address.as_u64[0] = sr0->segments->as_u64[0];
+ ip0->dst_address.as_u64[1] = sr0->segments->as_u64[1];
+
+ /* Remove the SRH taking care of the rest of IPv6 ext header */
+ if (prev0)
+ prev0->next_hdr = sr0->protocol;
+ else
+ ip0->protocol = sr0->protocol;
+
+ sr_len = ip6_ext_header_len (sr0);
+ vlib_buffer_advance (b0, sr_len);
+ new_l0 = clib_net_to_host_u16 (ip0->payload_length) - sr_len;
+ ip0->payload_length = clib_host_to_net_u16 (new_l0);
+ copy_src0 = (u64 *) ip0;
+ copy_dst0 = copy_src0 + (sr0->length + 1);
+ /* number of 8 octet units to copy
+ * By default in absence of extension headers it is equal to length of ip6 header
+ * With extension headers it number of 8 octet units of ext headers preceding
+ * SR header
+ */
+ copy_len_u64s0 =
+ (((u8 *) sr0 - (u8 *) ip0) - sizeof (ip6_header_t)) >> 3;
+ copy_dst0[4 + copy_len_u64s0] = copy_src0[4 + copy_len_u64s0];
+ copy_dst0[3 + copy_len_u64s0] = copy_src0[3 + copy_len_u64s0];
+ copy_dst0[2 + copy_len_u64s0] = copy_src0[2 + copy_len_u64s0];
+ copy_dst0[1 + copy_len_u64s0] = copy_src0[1 + copy_len_u64s0];
+ copy_dst0[0 + copy_len_u64s0] = copy_src0[0 + copy_len_u64s0];
+
+ int i;
+ for (i = copy_len_u64s0 - 1; i >= 0; i--)
+ {
+ copy_dst0[i] = copy_src0[i];
+ }
+
+ if (ls0->behavior == SR_BEHAVIOR_X)
+ {
+ vnet_buffer (b0)->ip.adj_index[VLIB_TX] = ls0->nh_adj;
+ *next0 = SR_LOCALSID_NEXT_IP6_REWRITE;
+ }
+ else if (ls0->behavior == SR_BEHAVIOR_T)
+ {
+ vnet_buffer (b0)->sw_if_index[VLIB_TX] = ls0->vrf_index;
+ }
+ }
+ else if (PREDICT_TRUE (sr0->segments_left > 0))
{
sr0->segments_left -= 1;
new_dst0 = (ip6_address_t *) (sr0->segments);
vnet_buffer (b0)->ip.adj_index[VLIB_TX] = ls0->nh_adj;
*next0 = SR_LOCALSID_NEXT_IP6_REWRITE;
}
+ else if (ls0->behavior == SR_BEHAVIOR_T)
+ {
+ vnet_buffer (b0)->sw_if_index[VLIB_TX] = ls0->vrf_index;
+ }
}
else
{
/*
* @brief Function doing SRH processing for D* variants
*/
-//FixME. I must crosscheck that next_proto matches the localsid
static_always_inline void
end_decaps_srh_processing (vlib_node_runtime_t * node,
vlib_buffer_t * b0,
else if (ls0->behavior == SR_BEHAVIOR_DT6)
{
vlib_buffer_advance (b0, total_size);
- vnet_buffer (b0)->sw_if_index[VLIB_TX] = ls0->fib_table;
+ vnet_buffer (b0)->sw_if_index[VLIB_TX] = ls0->vrf_index;
return;
}
break;
else if (ls0->behavior == SR_BEHAVIOR_DT4)
{
vlib_buffer_advance (b0, total_size);
- vnet_buffer (b0)->sw_if_index[VLIB_TX] = ls0->fib_table;
+ vnet_buffer (b0)->sw_if_index[VLIB_TX] = ls0->vrf_index;
*next0 = SR_LOCALSID_NEXT_IP4_LOOKUP;
return;
}
}
/**
- * @brief Function doing End processing with PSP
- */
-static_always_inline void
-end_psp_srh_processing (vlib_node_runtime_t * node,
- vlib_buffer_t * b0,
- ip6_header_t * ip0,
- ip6_ext_header_t * prev0,
- ip6_sr_header_t * sr0,
- ip6_sr_localsid_t * ls0, u32 * next0)
-{
- u32 new_l0, sr_len;
- u64 *copy_dst0, *copy_src0;
- u32 copy_len_u64s0 = 0;
- int i;
-
- if (PREDICT_TRUE (sr0->type == ROUTING_HEADER_TYPE_SR))
- {
- if (PREDICT_TRUE (sr0->segments_left == 1))
- {
- ip0->dst_address.as_u64[0] = sr0->segments->as_u64[0];
- ip0->dst_address.as_u64[1] = sr0->segments->as_u64[1];
-
- /* Remove the SRH taking care of the rest of IPv6 ext header */
- if (prev0)
- prev0->next_hdr = sr0->protocol;
- else
- ip0->protocol = sr0->protocol;
-
- sr_len = ip6_ext_header_len (sr0);
- vlib_buffer_advance (b0, sr_len);
- new_l0 = clib_net_to_host_u16 (ip0->payload_length) - sr_len;
- ip0->payload_length = clib_host_to_net_u16 (new_l0);
- copy_src0 = (u64 *) ip0;
- copy_dst0 = copy_src0 + (sr0->length + 1);
- /* number of 8 octet units to copy
- * By default in absence of extension headers it is equal to length of ip6 header
- * With extension headers it number of 8 octet units of ext headers preceding
- * SR header
- */
- copy_len_u64s0 =
- (((u8 *) sr0 - (u8 *) ip0) - sizeof (ip6_header_t)) >> 3;
- copy_dst0[4 + copy_len_u64s0] = copy_src0[4 + copy_len_u64s0];
- copy_dst0[3 + copy_len_u64s0] = copy_src0[3 + copy_len_u64s0];
- copy_dst0[2 + copy_len_u64s0] = copy_src0[2 + copy_len_u64s0];
- copy_dst0[1 + copy_len_u64s0] = copy_src0[1 + copy_len_u64s0];
- copy_dst0[0 + copy_len_u64s0] = copy_src0[0 + copy_len_u64s0];
-
- for (i = copy_len_u64s0 - 1; i >= 0; i--)
- {
- copy_dst0[i] = copy_src0[i];
- }
-
- if (ls0->behavior == SR_BEHAVIOR_X)
- {
- vnet_buffer (b0)->ip.adj_index[VLIB_TX] = ls0->nh_adj;
- *next0 = SR_LOCALSID_NEXT_IP6_REWRITE;
- }
- return;
- }
- }
- /* Error. Routing header of type != SR */
- *next0 = SR_LOCALSID_NEXT_ERROR;
- b0->error = node->errors[SR_LOCALSID_ERROR_NO_PSP];
-}
-
-/**
- * @brief SR LocalSID graph node. Supports all default SR Endpoint variants
+ * @brief SR LocalSID graph node. Supports all default SR Endpoint variants with decaps
*/
static uword
sr_localsid_d_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
from = vlib_frame_vector_args (from_frame);
n_left_from = from_frame->n_vectors;
next_index = node->cached_next_index;
- u32 thread_index = vlib_get_thread_index ();
+ u32 thread_index = vm->thread_index;
while (n_left_from > 0)
{
vnet_buffer (b0)->ip.adj_index[VLIB_TX]);
ls1 =
pool_elt_at_index (sm->localsids,
- vnet_buffer (b0)->ip.adj_index[VLIB_TX]);
+ vnet_buffer (b1)->ip.adj_index[VLIB_TX]);
ls2 =
pool_elt_at_index (sm->localsids,
- vnet_buffer (b0)->ip.adj_index[VLIB_TX]);
+ vnet_buffer (b2)->ip.adj_index[VLIB_TX]);
ls3 =
pool_elt_at_index (sm->localsids,
- vnet_buffer (b0)->ip.adj_index[VLIB_TX]);
+ vnet_buffer (b3)->ip.adj_index[VLIB_TX]);
ip0 = vlib_buffer_get_current (b0);
ip1 = vlib_buffer_get_current (b1);
end_decaps_srh_processing (node, b2, ip2, sr2, ls2, &next2);
end_decaps_srh_processing (node, b3, ip3, sr3, ls3, &next3);
- //TODO: trace.
+ if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
+ {
+ sr_localsid_trace_t *tr =
+ vlib_add_trace (vm, node, b0, sizeof (*tr));
+ tr->num_segments = 0;
+ clib_memcpy (tr->localsid.as_u8, ls0->localsid.as_u8,
+ sizeof (tr->localsid.as_u8));
+ tr->behavior = ls0->behavior;
+ if (ip0 == vlib_buffer_get_current (b0))
+ {
+ if (ip0->protocol == IP_PROTOCOL_IPV6_ROUTE
+ && sr0->type == ROUTING_HEADER_TYPE_SR)
+ {
+ clib_memcpy (tr->sr, sr0->segments, sr0->length * 8);
+ tr->num_segments =
+ sr0->length * 8 / sizeof (ip6_address_t);
+ tr->segments_left = sr0->segments_left;
+ }
+ }
+ else
+ tr->num_segments = 0xFF;
+ }
+
+ if (PREDICT_FALSE (b1->flags & VLIB_BUFFER_IS_TRACED))
+ {
+ sr_localsid_trace_t *tr =
+ vlib_add_trace (vm, node, b1, sizeof (*tr));
+ tr->num_segments = 0;
+ clib_memcpy (tr->localsid.as_u8, ls1->localsid.as_u8,
+ sizeof (tr->localsid.as_u8));
+ tr->behavior = ls1->behavior;
+ if (ip1 == vlib_buffer_get_current (b1))
+ {
+ if (ip1->protocol == IP_PROTOCOL_IPV6_ROUTE
+ && sr1->type == ROUTING_HEADER_TYPE_SR)
+ {
+ clib_memcpy (tr->sr, sr1->segments, sr1->length * 8);
+ tr->num_segments =
+ sr1->length * 8 / sizeof (ip6_address_t);
+ tr->segments_left = sr1->segments_left;
+ }
+ }
+ else
+ tr->num_segments = 0xFF;
+ }
+
+ if (PREDICT_FALSE (b2->flags & VLIB_BUFFER_IS_TRACED))
+ {
+ sr_localsid_trace_t *tr =
+ vlib_add_trace (vm, node, b2, sizeof (*tr));
+ tr->num_segments = 0;
+ clib_memcpy (tr->localsid.as_u8, ls2->localsid.as_u8,
+ sizeof (tr->localsid.as_u8));
+ tr->behavior = ls2->behavior;
+ if (ip2 == vlib_buffer_get_current (b2))
+ {
+ if (ip2->protocol == IP_PROTOCOL_IPV6_ROUTE
+ && sr2->type == ROUTING_HEADER_TYPE_SR)
+ {
+ clib_memcpy (tr->sr, sr2->segments, sr2->length * 8);
+ tr->num_segments =
+ sr2->length * 8 / sizeof (ip6_address_t);
+ tr->segments_left = sr2->segments_left;
+ }
+ }
+ else
+ tr->num_segments = 0xFF;
+ }
+
+ if (PREDICT_FALSE (b3->flags & VLIB_BUFFER_IS_TRACED))
+ {
+ sr_localsid_trace_t *tr =
+ vlib_add_trace (vm, node, b3, sizeof (*tr));
+ tr->num_segments = 0;
+ clib_memcpy (tr->localsid.as_u8, ls3->localsid.as_u8,
+ sizeof (tr->localsid.as_u8));
+ tr->behavior = ls3->behavior;
+ if (ip3 == vlib_buffer_get_current (b3))
+ {
+ if (ip3->protocol == IP_PROTOCOL_IPV6_ROUTE
+ && sr3->type == ROUTING_HEADER_TYPE_SR)
+ {
+ clib_memcpy (tr->sr, sr3->segments, sr3->length * 8);
+ tr->num_segments =
+ sr3->length * 8 / sizeof (ip6_address_t);
+ tr->segments_left = sr3->segments_left;
+ }
+ }
+ else
+ tr->num_segments = 0xFF;
+ }
vlib_increment_combined_counter
(((next0 ==
sr_localsid_trace_t *tr =
vlib_add_trace (vm, node, b0, sizeof (*tr));
tr->num_segments = 0;
- tr->localsid_index = ls0 - sm->localsids;
-
+ clib_memcpy (tr->localsid.as_u8, ls0->localsid.as_u8,
+ sizeof (tr->localsid.as_u8));
+ tr->behavior = ls0->behavior;
if (ip0 == vlib_buffer_get_current (b0))
{
- clib_memcpy (tr->src.as_u8, ip0->src_address.as_u8,
- sizeof (tr->src.as_u8));
- clib_memcpy (tr->out_dst.as_u8, ip0->dst_address.as_u8,
- sizeof (tr->out_dst.as_u8));
if (ip0->protocol == IP_PROTOCOL_IPV6_ROUTE
&& sr0->type == ROUTING_HEADER_TYPE_SR)
{
/* *INDENT-ON* */
/**
- * @brief SR LocalSID graph node. Supports all default SR Endpoint variants
+ * @brief SR LocalSID graph node. Supports all default SR Endpoint without decaps
*/
static uword
sr_localsid_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
from = vlib_frame_vector_args (from_frame);
n_left_from = from_frame->n_vectors;
next_index = node->cached_next_index;
- u32 thread_index = vlib_get_thread_index ();
+ u32 thread_index = vm->thread_index;
while (n_left_from > 0)
{
vnet_buffer (b0)->ip.adj_index[VLIB_TX]);
ls1 =
pool_elt_at_index (sm->localsids,
- vnet_buffer (b0)->ip.adj_index[VLIB_TX]);
+ vnet_buffer (b1)->ip.adj_index[VLIB_TX]);
ls2 =
pool_elt_at_index (sm->localsids,
- vnet_buffer (b0)->ip.adj_index[VLIB_TX]);
+ vnet_buffer (b2)->ip.adj_index[VLIB_TX]);
ls3 =
pool_elt_at_index (sm->localsids,
- vnet_buffer (b0)->ip.adj_index[VLIB_TX]);
+ vnet_buffer (b3)->ip.adj_index[VLIB_TX]);
- if (ls0->end_psp)
- end_psp_srh_processing (node, b0, ip0, prev0, sr0, ls0, &next0);
- else
- end_srh_processing (node, b0, ip0, sr0, ls0, &next0);
+ end_srh_processing (node, b0, ip0, sr0, ls0, &next0, ls0->end_psp,
+ prev0);
+ end_srh_processing (node, b1, ip1, sr1, ls1, &next1, ls1->end_psp,
+ prev1);
+ end_srh_processing (node, b2, ip2, sr2, ls2, &next2, ls2->end_psp,
+ prev2);
+ end_srh_processing (node, b3, ip3, sr3, ls3, &next3, ls3->end_psp,
+ prev3);
- if (ls1->end_psp)
- end_psp_srh_processing (node, b1, ip1, prev1, sr1, ls1, &next1);
- else
- end_srh_processing (node, b1, ip1, sr1, ls1, &next1);
+ if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
+ {
+ sr_localsid_trace_t *tr =
+ vlib_add_trace (vm, node, b0, sizeof (*tr));
+ tr->num_segments = 0;
+ clib_memcpy (tr->localsid.as_u8, ls0->localsid.as_u8,
+ sizeof (tr->localsid.as_u8));
+ tr->behavior = ls0->behavior;
+ if (ip0 == vlib_buffer_get_current (b0))
+ {
+ if (ip0->protocol == IP_PROTOCOL_IPV6_ROUTE
+ && sr0->type == ROUTING_HEADER_TYPE_SR)
+ {
+ clib_memcpy (tr->sr, sr0->segments, sr0->length * 8);
+ tr->num_segments =
+ sr0->length * 8 / sizeof (ip6_address_t);
+ tr->segments_left = sr0->segments_left;
+ }
+ }
+ else
+ tr->num_segments = 0xFF;
+ }
- if (ls2->end_psp)
- end_psp_srh_processing (node, b2, ip2, prev2, sr2, ls2, &next2);
- else
- end_srh_processing (node, b2, ip2, sr2, ls2, &next2);
+ if (PREDICT_FALSE (b1->flags & VLIB_BUFFER_IS_TRACED))
+ {
+ sr_localsid_trace_t *tr =
+ vlib_add_trace (vm, node, b1, sizeof (*tr));
+ tr->num_segments = 0;
+ clib_memcpy (tr->localsid.as_u8, ls1->localsid.as_u8,
+ sizeof (tr->localsid.as_u8));
+ tr->behavior = ls1->behavior;
+ if (ip1 == vlib_buffer_get_current (b1))
+ {
+ if (ip1->protocol == IP_PROTOCOL_IPV6_ROUTE
+ && sr1->type == ROUTING_HEADER_TYPE_SR)
+ {
+ clib_memcpy (tr->sr, sr1->segments, sr1->length * 8);
+ tr->num_segments =
+ sr1->length * 8 / sizeof (ip6_address_t);
+ tr->segments_left = sr1->segments_left;
+ }
+ }
+ else
+ tr->num_segments = 0xFF;
+ }
- if (ls3->end_psp)
- end_psp_srh_processing (node, b3, ip3, prev3, sr3, ls3, &next3);
- else
- end_srh_processing (node, b3, ip3, sr3, ls3, &next3);
+ if (PREDICT_FALSE (b2->flags & VLIB_BUFFER_IS_TRACED))
+ {
+ sr_localsid_trace_t *tr =
+ vlib_add_trace (vm, node, b2, sizeof (*tr));
+ tr->num_segments = 0;
+ clib_memcpy (tr->localsid.as_u8, ls2->localsid.as_u8,
+ sizeof (tr->localsid.as_u8));
+ tr->behavior = ls2->behavior;
+ if (ip2 == vlib_buffer_get_current (b2))
+ {
+ if (ip2->protocol == IP_PROTOCOL_IPV6_ROUTE
+ && sr2->type == ROUTING_HEADER_TYPE_SR)
+ {
+ clib_memcpy (tr->sr, sr2->segments, sr2->length * 8);
+ tr->num_segments =
+ sr2->length * 8 / sizeof (ip6_address_t);
+ tr->segments_left = sr2->segments_left;
+ }
+ }
+ else
+ tr->num_segments = 0xFF;
+ }
- //TODO: proper trace.
+ if (PREDICT_FALSE (b3->flags & VLIB_BUFFER_IS_TRACED))
+ {
+ sr_localsid_trace_t *tr =
+ vlib_add_trace (vm, node, b3, sizeof (*tr));
+ tr->num_segments = 0;
+ clib_memcpy (tr->localsid.as_u8, ls3->localsid.as_u8,
+ sizeof (tr->localsid.as_u8));
+ tr->behavior = ls3->behavior;
+ if (ip3 == vlib_buffer_get_current (b3))
+ {
+ if (ip3->protocol == IP_PROTOCOL_IPV6_ROUTE
+ && sr3->type == ROUTING_HEADER_TYPE_SR)
+ {
+ clib_memcpy (tr->sr, sr3->segments, sr3->length * 8);
+ tr->num_segments =
+ sr3->length * 8 / sizeof (ip6_address_t);
+ tr->segments_left = sr3->segments_left;
+ }
+ }
+ else
+ tr->num_segments = 0xFF;
+ }
vlib_increment_combined_counter
(((next0 ==
vnet_buffer (b0)->ip.adj_index[VLIB_TX]);
/* SRH processing */
- if (ls0->end_psp)
- end_psp_srh_processing (node, b0, ip0, prev0, sr0, ls0, &next0);
- else
- end_srh_processing (node, b0, ip0, sr0, ls0, &next0);
+ end_srh_processing (node, b0, ip0, sr0, ls0, &next0, ls0->end_psp,
+ prev0);
if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
{
sr_localsid_trace_t *tr =
vlib_add_trace (vm, node, b0, sizeof (*tr));
tr->num_segments = 0;
- tr->localsid_index = ls0 - sm->localsids;
-
+ clib_memcpy (tr->localsid.as_u8, ls0->localsid.as_u8,
+ sizeof (tr->localsid.as_u8));
+ tr->behavior = ls0->behavior;
if (ip0 == vlib_buffer_get_current (b0))
{
- clib_memcpy (tr->src.as_u8, ip0->src_address.as_u8,
- sizeof (tr->src.as_u8));
- clib_memcpy (tr->out_dst.as_u8, ip0->dst_address.as_u8,
- sizeof (tr->out_dst.as_u8));
if (ip0->protocol == IP_PROTOCOL_IPV6_ROUTE
&& sr0->type == ROUTING_HEADER_TYPE_SR)
{
}
}
else
- {
- tr->num_segments = 0xFF;
- }
+ tr->num_segments = 0xFF;
}
vlib_increment_combined_counter
plugin - sm->plugin_functions);
}
- memset (plugin, 0, sizeof (*plugin));
+ clib_memset (plugin, 0, sizeof (*plugin));
plugin->sr_localsid_function_number = (plugin - sm->plugin_functions);
plugin->sr_localsid_function_number += SR_BEHAVIOR_LAST;
/* Print static behaviors */
vlib_cli_output (vm, "Default behaviors:\n"
"\tEnd\t-> Endpoint.\n"
- "\tEnd.X\t-> Endpoint with decapsulation and Layer-3 cross-connect.\n"
+ "\tEnd.X\t-> Endpoint with Layer-3 cross-connect.\n"
"\t\tParameters: '<iface> <ip6_next_hop>'\n"
+ "\tEnd.T\t-> Endpoint with specific IPv6 table lookup.\n"
+ "\t\tParameters: '<fib_table>'\n"
"\tEnd.DX2\t-> Endpoint with decapsulation and Layer-2 cross-connect.\n"
"\t\tParameters: '<iface>'\n"
"\tEnd.DX6\t-> Endpoint with decapsulation and IPv6 cross-connect.\n"