diff options
Diffstat (limited to 'src/vnet/srv6/sr_localsid.c')
-rw-r--r-- | src/vnet/srv6/sr_localsid.c | 174 |
1 files changed, 113 insertions, 61 deletions
diff --git a/src/vnet/srv6/sr_localsid.c b/src/vnet/srv6/sr_localsid.c index 12349bb95e8..2172fa10ef1 100644 --- a/src/vnet/srv6/sr_localsid.c +++ b/src/vnet/srv6/sr_localsid.c @@ -100,10 +100,10 @@ sr_cli_localsid (char is_del, ip6_address_t * localsid_addr, { /* Retrieve localsid */ ls = pool_elt_at_index (sm->localsids, p[0]); - if (ls->behavior >= SR_BEHAVIOR_LAST) + if (ls->behavior >= SR_BEHAVIOR_CURRENT_LAST) { - plugin = pool_elt_at_index (sm->plugin_functions, - ls->behavior - SR_BEHAVIOR_LAST); + plugin = pool_elt_at_index ( + sm->plugin_functions, ls->behavior - SR_BEHAVIOR_CURRENT_LAST); pref_length = plugin->prefix_length; } @@ -130,7 +130,7 @@ sr_cli_localsid (char is_del, ip6_address_t * localsid_addr, || ls->behavior == SR_BEHAVIOR_DX4) adj_unlock (ls->nh_adj); - if (ls->behavior >= SR_BEHAVIOR_LAST) + if (ls->behavior >= SR_BEHAVIOR_CURRENT_LAST) { /* Callback plugin removal function */ rv = plugin->removal (ls); @@ -149,13 +149,13 @@ sr_cli_localsid (char is_del, ip6_address_t * localsid_addr, 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 (behavior >= SR_BEHAVIOR_CURRENT_LAST) + { + sr_localsid_fn_registration_t *plugin = 0; + plugin = pool_elt_at_index (sm->plugin_functions, + behavior - SR_BEHAVIOR_CURRENT_LAST); + pref_length = plugin->prefix_length; + } if (localsid_prefix_len != 0) { @@ -213,6 +213,23 @@ sr_cli_localsid (char is_del, ip6_address_t * localsid_addr, ls->usid_next_len = 16 - ls->usid_next_index; } break; + case SR_BEHAVIOR_UA: + if (usid_len) + { + int usid_width; + clib_memcpy (&ls->usid_block, localsid_addr, sizeof (ip6_address_t)); + + usid_width = pref_length - usid_len; + ip6_address_mask_from_width (&ls->usid_block_mask, usid_width); + + ls->usid_index = usid_width / 8; + ls->usid_len = usid_len / 8; + ls->usid_next_index = ls->usid_index + ls->usid_len; + ls->usid_next_len = 16 - ls->usid_next_index; + } + ls->sw_if_index = sw_if_index; + clib_memcpy (&ls->next_hop.ip6, &nh_addr->ip6, sizeof (ip6_address_t)); + break; case SR_BEHAVIOR_X: ls->sw_if_index = sw_if_index; clib_memcpy (&ls->next_hop.ip6, &nh_addr->ip6, sizeof (ip6_address_t)); @@ -241,13 +258,14 @@ sr_cli_localsid (char is_del, ip6_address_t * localsid_addr, } /* Figure out the adjacency magic for Xconnect variants */ - if (ls->behavior == SR_BEHAVIOR_X || ls->behavior == SR_BEHAVIOR_DX4 - || ls->behavior == SR_BEHAVIOR_DX6) + if (ls->behavior == SR_BEHAVIOR_X || ls->behavior == SR_BEHAVIOR_UA || + ls->behavior == SR_BEHAVIOR_DX4 || ls->behavior == SR_BEHAVIOR_DX6) { adj_index_t nh_adj_index = ADJ_INDEX_INVALID; /* Retrieve the adjacency corresponding to the (OIF, next_hop) */ - if (ls->behavior == SR_BEHAVIOR_DX6 || ls->behavior == SR_BEHAVIOR_X) + if (ls->behavior == SR_BEHAVIOR_DX6 || ls->behavior == SR_BEHAVIOR_UA || + ls->behavior == SR_BEHAVIOR_X) nh_adj_index = adj_nbr_add_or_lock (FIB_PROTOCOL_IP6, VNET_LINK_IP6, nh_addr, sw_if_index); @@ -272,17 +290,18 @@ sr_cli_localsid (char is_del, ip6_address_t * localsid_addr, else if (ls->behavior == SR_BEHAVIOR_END_UN) dpo_set (&dpo, sr_localsid_un_dpo_type, DPO_PROTO_IP6, ls - sm->localsids); - else if (ls->behavior == SR_BEHAVIOR_END_UN_PERF) + else if (ls->behavior == SR_BEHAVIOR_END_UN_PERF || + ls->behavior == SR_BEHAVIOR_UA) dpo_set (&dpo, sr_localsid_un_perf_dpo_type, DPO_PROTO_IP6, ls - sm->localsids); - else if (ls->behavior > SR_BEHAVIOR_D_FIRST - && ls->behavior < SR_BEHAVIOR_LAST) + else if (ls->behavior > SR_BEHAVIOR_D_FIRST && + ls->behavior < SR_BEHAVIOR_CURRENT_LAST) dpo_set (&dpo, sr_localsid_d_dpo_type, DPO_PROTO_IP6, ls - sm->localsids); - else if (ls->behavior >= SR_BEHAVIOR_LAST) + else if (ls->behavior >= SR_BEHAVIOR_CURRENT_LAST) { sr_localsid_fn_registration_t *plugin = 0; plugin = pool_elt_at_index (sm->plugin_functions, - ls->behavior - SR_BEHAVIOR_LAST); + ls->behavior - SR_BEHAVIOR_CURRENT_LAST); /* Copy the unformat memory result */ ls->plugin_mem = ls_plugin_mem; /* Callback plugin creation function */ @@ -389,6 +408,11 @@ sr_cli_localsid_command_fn (vlib_main_t * vm, unformat_input_t * input, behavior = SR_BEHAVIOR_END_UN_PERF; else if (unformat (input, "un.flex %u", &usid_size)) behavior = SR_BEHAVIOR_END_UN; + else if (unformat (input, "ua %u %U %U", &usid_size, + unformat_vnet_sw_interface, vnm, &sw_if_index, + unformat_ip6_address, &next_hop.ip6)) + behavior = SR_BEHAVIOR_UA; + else { /* Loop over all the plugin behavior format functions */ @@ -463,7 +487,7 @@ sr_cli_localsid_command_fn (vlib_main_t * vm, unformat_input_t * input, behavior, sw_if_index, vlan_index, fib_index, &next_hop, usid_size, ls_plugin_mem); - if (behavior == SR_BEHAVIOR_END_UN_PERF) + if (behavior == SR_BEHAVIOR_END_UN_PERF || behavior == SR_BEHAVIOR_UA) { if (rv == 0) { @@ -507,17 +531,19 @@ sr_cli_localsid_command_fn (vlib_main_t * vm, unformat_input_t * input, VLIB_CLI_COMMAND (sr_localsid_command, static) = { .path = "sr localsid", .short_help = "sr localsid (del) address XX:XX::YY:YY" - "(fib-table 8) behavior STRING", + "(fib-table 8) behavior STRING", .long_help = "Create SR LocalSID and binds it to a particular behavior\n" "Arguments:\n" "\tlocalSID IPv6_addr(128b) LocalSID IPv6 address\n" - "\t(fib-table X) Optional. VRF where to install SRv6 localsid\n" + "\t(fib-table X) Optional. VRF where to install SRv6 " + "localsid\n" "\tbehavior STRING Specifies the behavior\n" "\n\tBehaviors:\n" "\tEnd\t-> Endpoint.\n" "\tEnd.uN\t-> Endpoint with uSID.\n" - "\tEnd.X\t-> Endpoint with decapsulation and Layer-3 cross-connect.\n" + "\tuA\t-> Endpoint with uSID and Layer-3 cross-connect.\n" + "\tEnd.X\t-> Endpoint with Layer-3 cross-connect.\n" "\t\tParameters: '<iface> <ip6_next_hop>'\n" "\tEnd.DX2\t-> Endpoint with decapsulation and Layer-2 cross-connect.\n" "\t\tParameters: '<iface>'\n" @@ -525,9 +551,11 @@ VLIB_CLI_COMMAND (sr_localsid_command, static) = { "\t\tParameters: '<iface> <ip6_next_hop>'\n" "\tEnd.DX4\t-> Endpoint with decapsulation and IPv4 cross-connect.\n" "\t\tParameters: '<iface> <ip4_next_hop>'\n" - "\tEnd.DT6\t-> Endpoint with decapsulation and specific IPv6 table lookup.\n" + "\tEnd.DT6\t-> Endpoint with decapsulation and specific IPv6 table " + "lookup.\n" "\t\tParameters: '<ip6_fib_table>'\n" - "\tEnd.DT4\t-> Endpoint with decapsulation and specific IPv4 table lookup.\n" + "\tEnd.DT4\t-> Endpoint with decapsulation and specific IPv4 table " + "lookup.\n" "\t\tParameters: '<ip4_fib_table>'\n", .function = sr_cli_localsid_command_fn, }; @@ -554,22 +582,30 @@ show_sr_localsid_command_fn (vlib_main_t * vm, unformat_input_t * input, 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_END_UN: - vlib_cli_output (vm, - "\tAddress: \t%U\n\tBehavior: \tEnd (flex) [uSID:\t%U/%d, length: %d]", + vlib_cli_output (vm, "\tAddress: \t%U/%u\n\tBehavior: \tuN (flex)", format_ip6_address, &ls->localsid, - format_ip6_address, &ls->usid_block, - ls->usid_index * 8, ls->usid_len * 8); + ls->localsid_prefix_len); break; case SR_BEHAVIOR_END_UN_PERF: + vlib_cli_output ( + vm, "\tAddress: \t%U/%u\n\tBehavior: \tuN [End with uSID]", + format_ip6_address, &ls->localsid, ls->localsid_prefix_len, + ls->usid_len * 8); + break; + case SR_BEHAVIOR_UA: vlib_cli_output (vm, - "\tAddress: \t%U\n\tBehavior: \tEnd [uSID:\t%U/%d, length: %d]", + "\tAddress: \t%U/%u\n\tBehavior: \tuA [End with " + "uSID and Layer-3 cross-connect]" + "\n\tIface: \t%U\n\tNext hop: \t%U", format_ip6_address, &ls->localsid, - format_ip6_address, &ls->usid_block, - ls->usid_index * 8, ls->usid_len * 8); + 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_X: vlib_cli_output (vm, @@ -636,11 +672,10 @@ show_sr_localsid_command_fn (vlib_main_t * vm, unformat_input_t * input, FIB_PROTOCOL_IP4)); break; default: - if (ls->behavior >= SR_BEHAVIOR_LAST) + if (ls->behavior >= SR_BEHAVIOR_CURRENT_LAST) { - sr_localsid_fn_registration_t *plugin = - pool_elt_at_index (sm->plugin_functions, - ls->behavior - SR_BEHAVIOR_LAST); + sr_localsid_fn_registration_t *plugin = pool_elt_at_index ( + sm->plugin_functions, ls->behavior - SR_BEHAVIOR_CURRENT_LAST); vlib_cli_output (vm, "\tAddress: \t%U/%u\n" "\tBehavior: \t%s (%s)\n\t%U", @@ -781,6 +816,9 @@ format_sr_localsid_trace (u8 * s, va_list * args) case SR_BEHAVIOR_DX4: s = format (s, "\tBehavior: Decapsulation with IPv4 L3 xconnect\n"); break; + case SR_BEHAVIOR_UA: + s = format (s, "\tBehavior: uSID and IPv6 L3 xconnect\n"); + break; case SR_BEHAVIOR_X: s = format (s, "\tBehavior: IPv6 L3 xconnect\n"); break; @@ -1031,7 +1069,8 @@ end_un_srh_processing (vlib_node_runtime_t * node, } static_always_inline void -end_un_processing (ip6_header_t * ip0, ip6_sr_localsid_t * ls0) +end_un_processing (vlib_node_runtime_t *node, vlib_buffer_t *b0, + ip6_header_t *ip0, ip6_sr_localsid_t *ls0, u32 *next0) { u8 next_usid_index; u8 index; @@ -1052,6 +1091,11 @@ end_un_processing (ip6_header_t * ip0, ip6_sr_localsid_t * ls0) { ip0->dst_address.as_u8[index] = 0; } + if (ls0->behavior == SR_BEHAVIOR_UA) + { + vnet_buffer (b0)->ip.adj_index[VLIB_TX] = ls0->nh_adj; + *next0 = SR_LOCALSID_NEXT_IP6_REWRITE; + } return; } @@ -1471,6 +1515,7 @@ sr_localsid_fn (vlib_main_t * vm, vlib_node_runtime_t * node, ip6_header_t *ip0, *ip1, *ip2, *ip3; ip6_sr_header_t *sr0, *sr1, *sr2, *sr3; ip6_ext_header_t *prev0, *prev1, *prev2, *prev3; + prev0 = prev1 = prev2 = prev3 = 0; u32 next0, next1, next2, next3; next0 = next1 = next2 = next3 = SR_LOCALSID_NEXT_IP6_LOOKUP; ip6_sr_localsid_t *ls0, *ls1, *ls2, *ls3; @@ -1779,6 +1824,7 @@ sr_localsid_un_fn (vlib_main_t * vm, vlib_node_runtime_t * node, ip6_header_t *ip0, *ip1, *ip2, *ip3; ip6_sr_header_t *sr0, *sr1, *sr2, *sr3; ip6_ext_header_t *prev0, *prev1, *prev2, *prev3; + prev0 = prev1 = prev2 = prev3 = 0; u32 next0, next1, next2, next3; next0 = next1 = next2 = next3 = SR_LOCALSID_NEXT_IP6_LOOKUP; ip6_sr_localsid_t *ls0, *ls1, *ls2, *ls3; @@ -2139,10 +2185,10 @@ sr_localsid_un_perf_fn (vlib_main_t * vm, vlib_node_runtime_t * node, pool_elt_at_index (sm->localsids, vnet_buffer (b3)->ip.adj_index[VLIB_TX]); - end_un_processing (ip0, ls0); - end_un_processing (ip1, ls1); - end_un_processing (ip2, ls2); - end_un_processing (ip3, ls3); + end_un_processing (node, b0, ip0, ls0, &next0); + end_un_processing (node, b1, ip1, ls1, &next1); + end_un_processing (node, b2, ip2, ls2, &next2); + end_un_processing (node, b3, ip3, ls3, &next3); if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED)) { @@ -2230,7 +2276,7 @@ sr_localsid_un_perf_fn (vlib_main_t * vm, vlib_node_runtime_t * node, vnet_buffer (b0)->ip.adj_index[VLIB_TX]); /* SRH processing */ - end_un_processing (ip0, ls0); + end_un_processing (node, b0, ip0, ls0, &next0); if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED)) { @@ -2357,7 +2403,7 @@ sr_localsid_register_function (vlib_main_t * vm, u8 * fn_name, clib_memset (plugin, 0, sizeof (*plugin)); plugin->sr_localsid_function_number = (plugin - sm->plugin_functions); - plugin->sr_localsid_function_number += SR_BEHAVIOR_LAST; + plugin->sr_localsid_function_number += SR_BEHAVIOR_CURRENT_LAST; plugin->prefix_length = prefix_length; plugin->ls_format = ls_format; plugin->ls_unformat = ls_unformat; @@ -2392,22 +2438,28 @@ show_sr_localsid_behaviors_command_fn (vlib_main_t * vm, { vec_add1 (plugins_vec, plugin); } /* Print static behaviors */ - vlib_cli_output (vm, "Default behaviors:\n" - "\tEnd\t-> Endpoint.\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" - "\t\tParameters: '<iface> <ip6_next_hop>'\n" - "\tEnd.DX4\t-> Endpoint with decapsulation and IPv4 cross-connect.\n" - "\t\tParameters: '<iface> <ip4_next_hop>'\n" - "\tEnd.DT6\t-> Endpoint with decapsulation and specific IPv6 table lookup.\n" - "\t\tParameters: '<ip6_fib_table>'\n" - "\tEnd.DT4\t-> Endpoint with decapsulation and specific IPv4 table lookup.\n" - "\t\tParameters: '<ip4_fib_table>'\n"); + vlib_cli_output ( + vm, + "Default behaviors:\n" + "\tEnd\t-> Endpoint.\n" + "\tEnd.X\t-> Endpoint with Layer-3 cross-connect.\n" + "\tuN\t-> Endpoint with uSID.\n" + "\tuA\t-> Endpoint with uSID and 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" + "\t\tParameters: '<iface> <ip6_next_hop>'\n" + "\tEnd.DX4\t-> Endpoint with decapsulation and IPv4 cross-connect.\n" + "\t\tParameters: '<iface> <ip4_next_hop>'\n" + "\tEnd.DT6\t-> Endpoint with decapsulation and specific IPv6 table " + "lookup.\n" + "\t\tParameters: '<ip6_fib_table>'\n" + "\tEnd.DT4\t-> Endpoint with decapsulation and specific IPv4 table " + "lookup.\n" + "\t\tParameters: '<ip4_fib_table>'\n"); vlib_cli_output (vm, "Plugin behaviors:\n"); for (i = 0; i < vec_len (plugins_vec); i++) { |