*/
int
sr_cli_localsid (char is_del, ip6_address_t * localsid_addr,
- char end_psp, u8 behavior, u32 sw_if_index, u32 vlan_index,
- u32 fib_table, ip46_address_t * nh_addr, void *ls_plugin_mem)
+ u16 localsid_prefix_len, char end_psp, u8 behavior,
+ u32 sw_if_index, u32 vlan_index, u32 fib_table,
+ ip46_address_t * nh_addr, void *ls_plugin_mem)
{
ip6_sr_main_t *sm = &sr_main;
uword *p;
int rv;
+ u8 pref_length = 128;
+ sr_localsid_fn_registration_t *plugin = 0;
ip6_sr_localsid_t *ls = 0;
{
/* Retrieve localsid */
ls = pool_elt_at_index (sm->localsids, p[0]);
+ if (ls->behavior >= SR_BEHAVIOR_LAST)
+ {
+ plugin = pool_elt_at_index (sm->plugin_functions,
+ ls->behavior - SR_BEHAVIOR_LAST);
+ pref_length = plugin->prefix_length;
+ }
+
+ if (localsid_prefix_len != 0)
+ {
+ pref_length = localsid_prefix_len;
+ }
+
/* Delete FIB entry */
fib_prefix_t pfx = {
.fp_proto = FIB_PROTOCOL_IP6,
- .fp_len = 128,
+ .fp_len = pref_length,
.fp_addr = {
.ip6 = *localsid_addr,
}
};
- fib_table_entry_delete (fib_table_find (FIB_PROTOCOL_IP6,
- fib_table),
- &pfx, FIB_SOURCE_SR);
+ fib_table_entry_delete (fib_table_find
+ (FIB_PROTOCOL_IP6, fib_table), &pfx,
+ FIB_SOURCE_SR);
/* In case it is a Xconnect iface remove the (OIF, NHOP) adj */
if (ls->behavior == SR_BEHAVIOR_X || ls->behavior == SR_BEHAVIOR_DX6
if (ls->behavior >= SR_BEHAVIOR_LAST)
{
- sr_localsid_fn_registration_t *plugin = 0;
- plugin = pool_elt_at_index (sm->plugin_functions,
- ls->behavior - SR_BEHAVIOR_LAST);
-
/* Callback plugin removal function */
rv = plugin->removal (ls);
}
if (is_del)
return -2;
+ if (behavior >= SR_BEHAVIOR_LAST)
+ {
+ sr_localsid_fn_registration_t *plugin = 0;
+ plugin =
+ pool_elt_at_index (sm->plugin_functions, behavior - SR_BEHAVIOR_LAST);
+ pref_length = plugin->prefix_length;
+ }
+
+ if (localsid_prefix_len != 0)
+ {
+ pref_length = localsid_prefix_len;
+ }
+
/* Check whether there exists a FIB entry with such address */
fib_prefix_t pfx = {
.fp_proto = FIB_PROTOCOL_IP6,
- .fp_len = 128,
+ .fp_len = pref_length,
};
pfx.fp_addr.as_u64[0] = localsid_addr->as_u64[0];
pfx.fp_addr.as_u64[1] = localsid_addr->as_u64[1];
+ pfx.fp_len = pref_length;
/* Lookup the FIB index associated to the table id provided */
u32 fib_index = fib_table_find (FIB_PROTOCOL_IP6, fib_table);
/* 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->localsid_prefix_len = pref_length;
ls->end_psp = end_psp;
ls->behavior = behavior;
ls->nh_adj = (u32) ~ 0;
}
/* Set DPO */
- if (ls->behavior == SR_BEHAVIOR_END || ls->behavior == SR_BEHAVIOR_X)
+ if (ls->behavior == SR_BEHAVIOR_END || ls->behavior == SR_BEHAVIOR_X
+ || ls->behavior == SR_BEHAVIOR_T)
dpo_set (&dpo, sr_localsid_dpo_type, DPO_PROTO_IP6, ls - sm->localsids);
else if (ls->behavior > SR_BEHAVIOR_D_FIRST
&& ls->behavior < SR_BEHAVIOR_LAST)
vnet_main_t *vnm = vnet_get_main ();
ip6_sr_main_t *sm = &sr_main;
u32 sw_if_index = (u32) ~ 0, vlan_index = (u32) ~ 0, fib_index = 0;
+ u16 prefix_len = 0;
int is_del = 0;
int end_psp = 0;
ip6_address_t resulting_address;
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)
{
if (unformat (input, "del"))
is_del = 1;
+ else if (!address_set
+ && unformat (input, "prefix %U/%u", unformat_ip6_address,
+ &resulting_address, &prefix_len))
+ address_set = 1;
else if (!address_set
&& unformat (input, "address %U", unformat_ip6_address,
&resulting_address))
sr_localsid_fn_registration_t **plugin_it = 0;
/* Create a vector out of the plugin pool as recommended */
- /* *INDENT-OFF* */
- pool_foreach (plugin, sm->plugin_functions,
- {
- vec_add1 (vec_plugins, plugin);
- });
- /* *INDENT-ON* */
+ /* *INDENT-OFF* */
+ pool_foreach (plugin, sm->plugin_functions,
+ {
+ vec_add1 (vec_plugins, plugin);
+ });
+ /* *INDENT-ON* */
vec_foreach (plugin_it, vec_plugins)
{
return clib_error_return (0,
"Error: SRv6 PSP only compatible with End and End.X");
- rv = sr_cli_localsid (is_del, &resulting_address, end_psp, behavior,
- sw_if_index, vlan_index, fib_index, &next_hop,
- ls_plugin_mem);
+ rv =
+ sr_cli_localsid (is_del, &resulting_address, prefix_len, end_psp,
+ behavior, sw_if_index, vlan_index, fib_index, &next_hop,
+ ls_plugin_mem);
switch (rv)
{
switch (ls->behavior)
{
case SR_BEHAVIOR_END:
- vlib_cli_output (vm, "\tAddress: \t%U\n\tBehavior: \tEnd",
- format_ip6_address, &ls->localsid);
+ vlib_cli_output (vm, "\tAddress: \t%U/%u\n\tBehavior: \tEnd",
+ format_ip6_address, &ls->localsid,
+ ls->localsid_prefix_len);
break;
case SR_BEHAVIOR_X:
vlib_cli_output (vm,
- "\tAddress: \t%U\n\tBehavior: \tX (Endpoint with Layer-3 cross-connect)"
+ "\tAddress: \t%U/%u\n\tBehavior: \tX (Endpoint with Layer-3 cross-connect)"
"\n\tIface: \t%U\n\tNext hop: \t%U",
format_ip6_address, &ls->localsid,
+ ls->localsid_prefix_len,
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)"
+ "\tAddress: \t%U/%u\n\tBehavior: \tT (Endpoint with specific IPv6 table lookup)"
"\n\tTable: \t%u",
format_ip6_address, &ls->localsid,
- format_vnet_sw_if_index_name, vnm, ls->vrf_index);
+ ls->localsid_prefix_len,
+ fib_table_get_table_id (ls->vrf_index,
+ FIB_PROTOCOL_IP6));
break;
case SR_BEHAVIOR_DX4:
vlib_cli_output (vm,
- "\tAddress: \t%U\n\tBehavior: \tDX4 (Endpoint with decapsulation and IPv4 cross-connect)"
+ "\tAddress: \t%U/%u\n\tBehavior: \tDX4 (Endpoint with decapsulation and IPv4 cross-connect)"
"\n\tIface: \t%U\n\tNext hop: \t%U",
format_ip6_address, &ls->localsid,
+ ls->localsid_prefix_len,
format_vnet_sw_if_index_name, vnm, ls->sw_if_index,
format_ip4_address, &ls->next_hop.ip4);
break;
case SR_BEHAVIOR_DX6:
vlib_cli_output (vm,
- "\tAddress: \t%U\n\tBehavior: \tDX6 (Endpoint with decapsulation and IPv6 cross-connect)"
+ "\tAddress: \t%U/%u\n\tBehavior: \tDX6 (Endpoint with decapsulation and IPv6 cross-connect)"
"\n\tIface: \t%U\n\tNext hop: \t%U",
format_ip6_address, &ls->localsid,
+ ls->localsid_prefix_len,
format_vnet_sw_if_index_name, vnm, ls->sw_if_index,
format_ip6_address, &ls->next_hop.ip6);
break;
case SR_BEHAVIOR_DX2:
if (ls->vlan_index == (u32) ~ 0)
vlib_cli_output (vm,
- "\tAddress: \t%U\n\tBehavior: \tDX2 (Endpoint with decapulation and Layer-2 cross-connect)"
+ "\tAddress: \t%U/%u\n\tBehavior: \tDX2 (Endpoint with decapulation and Layer-2 cross-connect)"
"\n\tIface: \t%U", format_ip6_address,
- &ls->localsid, format_vnet_sw_if_index_name, vnm,
+ &ls->localsid, ls->localsid_prefix_len,
+ format_vnet_sw_if_index_name, vnm,
ls->sw_if_index);
else
vlib_cli_output (vm,
break;
case SR_BEHAVIOR_DT6:
vlib_cli_output (vm,
- "\tAddress: \t%U\n\tBehavior: \tDT6 (Endpoint with decapsulation and specific IPv6 table lookup)"
+ "\tAddress: \t%U/%u\n\tBehavior: \tDT6 (Endpoint with decapsulation and specific IPv6 table lookup)"
"\n\tTable: %u", format_ip6_address, &ls->localsid,
- ls->vrf_index);
+ ls->localsid_prefix_len,
+ fib_table_get_table_id (ls->vrf_index,
+ FIB_PROTOCOL_IP6));
break;
case SR_BEHAVIOR_DT4:
vlib_cli_output (vm,
- "\tAddress: \t%U\n\tBehavior: \tDT4 (Endpoint with decapsulation and specific IPv4 table lookup)"
+ "\tAddress: \t%U/%u\n\tBehavior: \tDT4 (Endpoint with decapsulation and specific IPv4 table lookup)"
"\n\tTable: \t%u", format_ip6_address,
- &ls->localsid, ls->vrf_index);
+ &ls->localsid, ls->localsid_prefix_len,
+ fib_table_get_table_id (ls->vrf_index,
+ FIB_PROTOCOL_IP4));
break;
default:
if (ls->behavior >= SR_BEHAVIOR_LAST)
pool_elt_at_index (sm->plugin_functions,
ls->behavior - SR_BEHAVIOR_LAST);
- vlib_cli_output (vm, "\tAddress: \t%U\n"
+ vlib_cli_output (vm, "\tAddress: \t%U/%u\n"
"\tBehavior: \t%s (%s)\n\t%U",
format_ip6_address, &ls->localsid,
- plugin->keyword_str, plugin->def_str,
- plugin->ls_format, ls->plugin_mem);
+ ls->localsid_prefix_len, plugin->keyword_str,
+ plugin->def_str, plugin->ls_format,
+ ls->plugin_mem);
}
else
//Should never get here...
{
ip6_address_t *new_dst0;
- if (PREDICT_TRUE (sr0->type == ROUTING_HEADER_TYPE_SR))
+ if (PREDICT_TRUE (sr0 && sr0->type == ROUTING_HEADER_TYPE_SR))
{
if (sr0->segments_left == 1 && psp)
{
return;
}
break;
- case IP_PROTOCOL_IP6_NONXT:
+ case IP_PROTOCOL_IP6_ETHERNET:
/* L2 encaps */
if (ls0->behavior == SR_BEHAVIOR_DX2)
{
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)
{
u32 bi0, bi1, bi2, bi3;
vlib_buffer_t *b0, *b1, *b2, *b3;
ip6_header_t *ip0, *ip1, *ip2, *ip3;
- ip6_ext_header_t *prev0, *prev1, *prev2, *prev3;
ip6_sr_header_t *sr0, *sr1, *sr2, *sr3;
u32 next0, next1, next2, next3;
next0 = next1 = next2 = next3 = SR_LOCALSID_NEXT_IP6_LOOKUP;
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);
ip2 = vlib_buffer_get_current (b2);
ip3 = vlib_buffer_get_current (b3);
- ip6_ext_header_find_t (ip0, prev0, sr0, IP_PROTOCOL_IPV6_ROUTE);
- ip6_ext_header_find_t (ip1, prev1, sr1, IP_PROTOCOL_IPV6_ROUTE);
- ip6_ext_header_find_t (ip2, prev2, sr2, IP_PROTOCOL_IPV6_ROUTE);
- ip6_ext_header_find_t (ip3, prev3, sr3, IP_PROTOCOL_IPV6_ROUTE);
+ sr0 =
+ ip6_ext_header_find (vm, b0, ip0, IP_PROTOCOL_IPV6_ROUTE, NULL);
+ sr1 =
+ ip6_ext_header_find (vm, b1, ip1, IP_PROTOCOL_IPV6_ROUTE, NULL);
+ sr2 =
+ ip6_ext_header_find (vm, b2, ip2, IP_PROTOCOL_IPV6_ROUTE, NULL);
+ sr3 =
+ ip6_ext_header_find (vm, b3, ip3, IP_PROTOCOL_IPV6_ROUTE, NULL);
end_decaps_srh_processing (node, b0, ip0, sr0, ls0, &next0);
end_decaps_srh_processing (node, b1, ip1, sr1, ls1, &next1);
u32 bi0;
vlib_buffer_t *b0;
ip6_header_t *ip0;
- ip6_ext_header_t *prev0;
ip6_sr_header_t *sr0;
u32 next0 = SR_LOCALSID_NEXT_IP6_LOOKUP;
ip6_sr_localsid_t *ls0;
vnet_buffer (b0)->ip.adj_index[VLIB_TX]);
/* Find SRH as well as previous header */
- ip6_ext_header_find_t (ip0, prev0, sr0, IP_PROTOCOL_IPV6_ROUTE);
+ sr0 =
+ ip6_ext_header_find (vm, b0, ip0, IP_PROTOCOL_IPV6_ROUTE, NULL);
/* SRH processing and End variants */
end_decaps_srh_processing (node, b0, ip0, sr0, ls0, &next0);
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)
{
ip2 = vlib_buffer_get_current (b2);
ip3 = vlib_buffer_get_current (b3);
- ip6_ext_header_find_t (ip0, prev0, sr0, IP_PROTOCOL_IPV6_ROUTE);
- ip6_ext_header_find_t (ip1, prev1, sr1, IP_PROTOCOL_IPV6_ROUTE);
- ip6_ext_header_find_t (ip2, prev2, sr2, IP_PROTOCOL_IPV6_ROUTE);
- ip6_ext_header_find_t (ip3, prev3, sr3, IP_PROTOCOL_IPV6_ROUTE);
+ sr0 =
+ ip6_ext_header_find (vm, b0, ip0, IP_PROTOCOL_IPV6_ROUTE, &prev0);
+ sr1 =
+ ip6_ext_header_find (vm, b1, ip1, IP_PROTOCOL_IPV6_ROUTE, &prev1);
+ sr2 =
+ ip6_ext_header_find (vm, b2, ip2, IP_PROTOCOL_IPV6_ROUTE, &prev2);
+ sr3 =
+ ip6_ext_header_find (vm, b3, ip3, IP_PROTOCOL_IPV6_ROUTE, &prev3);
ls0 =
pool_elt_at_index (sm->localsids,
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]);
end_srh_processing (node, b0, ip0, sr0, ls0, &next0, ls0->end_psp,
prev0);
b0 = vlib_get_buffer (vm, bi0);
ip0 = vlib_buffer_get_current (b0);
- ip6_ext_header_find_t (ip0, prev0, sr0, IP_PROTOCOL_IPV6_ROUTE);
+ sr0 =
+ ip6_ext_header_find (vm, b0, ip0, IP_PROTOCOL_IPV6_ROUTE, &prev0);
/* Lookup the SR End behavior based on IP DA (adj) */
ls0 =
int
sr_localsid_register_function (vlib_main_t * vm, u8 * fn_name,
u8 * keyword_str, u8 * def_str,
- u8 * params_str, dpo_type_t * dpo,
+ u8 * params_str, u8 prefix_length,
+ dpo_type_t * dpo,
format_function_t * ls_format,
unformat_function_t * ls_unformat,
sr_plugin_callback_t * creation_fn,
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;
+ plugin->prefix_length = prefix_length;
plugin->ls_format = ls_format;
plugin->ls_unformat = ls_unformat;
plugin->creation = creation_fn;