diff options
Diffstat (limited to 'src/vnet/ip/lookup.c')
-rw-r--r-- | src/vnet/ip/lookup.c | 158 |
1 files changed, 98 insertions, 60 deletions
diff --git a/src/vnet/ip/lookup.c b/src/vnet/ip/lookup.c index 1753ffd9232..c225c222a38 100644 --- a/src/vnet/ip/lookup.c +++ b/src/vnet/ip/lookup.c @@ -128,6 +128,42 @@ format_ip_flow_hash_config (u8 * s, va_list * args) return s; } +uword +unformat_ip_flow_hash_config (unformat_input_t *input, va_list *args) +{ + flow_hash_config_t *flow_hash_config = va_arg (*args, flow_hash_config_t *); + uword start_index = unformat_check_input (input); + int matched_once = 0; + + if (unformat (input, "default")) + { + *flow_hash_config = IP_FLOW_HASH_DEFAULT; + return 1; + } + while (!unformat_is_eof (input) && + !is_white_space (unformat_peek_input (input))) + { + if (unformat (input, "%_,")) + ; +#define _(a, b, c) \ + else if (unformat (input, "%_" #a)) \ + { \ + *flow_hash_config |= c; \ + matched_once = 1; \ + } + foreach_flow_hash_bit +#undef _ + else + { + /* Roll back to our start */ + input->index = start_index; + return 0; + } + } + + return matched_once; +} + u8 * format_ip_adjacency_packet_data (u8 * s, va_list * args) { @@ -184,6 +220,27 @@ const ip46_address_t zero_addr = { 0, 0}, }; +bool +fib_prefix_validate (const fib_prefix_t *prefix) +{ + if (FIB_PROTOCOL_IP4 == prefix->fp_proto) + { + if (prefix->fp_len > 32) + { + return false; + } + } + + if (FIB_PROTOCOL_IP6 == prefix->fp_proto) + { + if (prefix->fp_len > 128) + { + return false; + } + } + return true; +} + static clib_error_t * vnet_ip_route_cmd (vlib_main_t * vm, unformat_input_t * main_input, vlib_cli_command_t * cmd) @@ -304,22 +361,25 @@ vnet_ip_route_cmd (vlib_main_t * vm, } else if (0 < vec_len (rpaths)) { - u32 k, n, incr; - ip46_address_t dst = prefixs[i].fp_addr; + u32 k, n; f64 t[2]; n = count; t[0] = vlib_time_now (vm); - incr = 1 << ((FIB_PROTOCOL_IP4 == prefixs[0].fp_proto ? 32 : 128) - - prefixs[i].fp_len); for (k = 0; k < n; k++) { fib_prefix_t rpfx = { .fp_len = prefixs[i].fp_len, .fp_proto = prefixs[i].fp_proto, - .fp_addr = dst, + .fp_addr = prefixs[i].fp_addr, }; + if (!fib_prefix_validate (&rpfx)) + { + vlib_cli_output (vm, "Invalid prefix len: %d", rpfx.fp_len); + continue; + } + if (is_del) fib_table_entry_path_remove2 (fib_index, &rpfx, FIB_SOURCE_CLI, rpaths); @@ -329,21 +389,7 @@ vnet_ip_route_cmd (vlib_main_t * vm, FIB_SOURCE_CLI, FIB_ENTRY_FLAG_NONE, rpaths); - if (FIB_PROTOCOL_IP4 == prefixs[0].fp_proto) - { - dst.ip4.as_u32 = - clib_host_to_net_u32 (incr + - clib_net_to_host_u32 (dst. - ip4.as_u32)); - } - else - { - int bucket = (incr < 64 ? 0 : 1); - dst.ip6.as_u64[bucket] = - clib_host_to_net_u64 (incr + - clib_net_to_host_u64 (dst.ip6.as_u64 - [bucket])); - } + fib_prefix_increment (&prefixs[i]); } t[1] = vlib_time_now (vm); @@ -399,29 +445,35 @@ vnet_ip_table_cmd (vlib_main_t * vm, } } - if (~0 == table_id) - { - error = clib_error_return (0, "No table id"); - goto done; - } - else if (0 == table_id) + if (0 == table_id) { error = clib_error_return (0, "Can't change the default table"); goto done; } else - { - if (is_add) - { - ip_table_create (fproto, table_id, 0, name); - } - else { - ip_table_delete (fproto, table_id, 0); + if (is_add) + { + if (~0 == table_id) + { + table_id = ip_table_get_unused_id (fproto); + vlib_cli_output (vm, "%u\n", table_id); + } + ip_table_create (fproto, table_id, 0, name); + } + else + { + if (~0 == table_id) + { + error = clib_error_return (0, "No table id"); + goto done; + } + ip_table_delete (fproto, table_id, 0); + } } - } done: + vec_free (name); unformat_free (line_input); return error; } @@ -477,13 +529,13 @@ vnet_show_ip_table_cmd (vlib_main_t *vm, unformat_input_t *main_input, } fib = fib_table_get (fib_index, fproto); - vlib_cli_output (vm, "[%3u] table_id:%3u %v", fib->ft_index, + vlib_cli_output (vm, "[%u] table_id:%u %v", fib->ft_index, fib->ft_table_id, fib->ft_desc); } else { pool_foreach (fib, fibs) - vlib_cli_output (vm, "[%3u] table_id:%3u %v", fib->ft_index, + vlib_cli_output (vm, "[%u] table_id:%u %v", fib->ft_index, fib->ft_table_id, fib->ft_desc); } @@ -505,33 +557,25 @@ vnet_show_ip6_table_cmd (vlib_main_t *vm, unformat_input_t *main_input, return (vnet_show_ip_table_cmd (vm, main_input, cmd, FIB_PROTOCOL_IP6)); } -/* *INDENT-OFF* */ VLIB_CLI_COMMAND (vlib_cli_ip_command, static) = { .path = "ip", .short_help = "Internet protocol (IP) commands", }; -/* *INDENT-ON* */ -/* *INDENT-OFF* */ VLIB_CLI_COMMAND (vlib_cli_ip6_command, static) = { .path = "ip6", .short_help = "Internet protocol version 6 (IPv6) commands", }; -/* *INDENT-ON* */ -/* *INDENT-OFF* */ VLIB_CLI_COMMAND (vlib_cli_show_ip_command, static) = { .path = "show ip", .short_help = "Internet protocol (IP) show commands", }; -/* *INDENT-ON* */ -/* *INDENT-OFF* */ VLIB_CLI_COMMAND (vlib_cli_show_ip6_command, static) = { .path = "show ip6", .short_help = "Internet protocol version 6 (IPv6) show commands", }; -/* *INDENT-ON* */ /*? * This command is used to add or delete IPv4 or IPv6 routes. All @@ -560,37 +604,37 @@ VLIB_CLI_COMMAND (vlib_cli_show_ip6_command, static) = { * To add a route to a particular FIB table (VRF), use: * @cliexcmd{ip route add 172.16.24.0/24 table 7 via GigabitEthernet2/0/0} ?*/ -/* *INDENT-OFF* */ VLIB_CLI_COMMAND (ip_route_command, static) = { .path = "ip route", - .short_help = "ip route [add|del] [count <n>] <dst-ip-addr>/<width> [table <table-id>] via [next-hop-address] [next-hop-interface] [next-hop-table <value>] [weight <value>] [preference <value>] [udp-encap-id <value>] [ip4-lookup-in-table <value>] [ip6-lookup-in-table <value>] [mpls-lookup-in-table <value>] [resolve-via-host] [resolve-via-connected] [rx-ip4 <interface>] [out-labels <value value value>]", + .short_help = "ip route [add|del] [count <n>] <dst-ip-addr>/<width> [table " + "<table-id>] via [next-hop-address] [next-hop-interface] " + "[next-hop-table <value>] [weight <value>] [preference " + "<value>] [udp-encap <value>] [ip4-lookup-in-table <value>] " + "[ip6-lookup-in-table <value>] [mpls-lookup-in-table <value>] " + "[resolve-via-host] [resolve-via-connected] [rx-ip4|rx-ip6 " + "<interface>] [out-labels <value value value>]", .function = vnet_ip_route_cmd, .is_mp_safe = 1, }; -/* *INDENT-ON* */ /*? * This command is used to add or delete IPv4 Tables. All * Tables must be explicitly added before that can be used. Creating a * table will add both unicast and multicast FIBs * ?*/ -/* *INDENT-OFF* */ VLIB_CLI_COMMAND (ip4_table_command, static) = { .path = "ip table", .short_help = "ip table [add|del] <table-id>", .function = vnet_ip4_table_cmd, }; -/* *INDENT-ON* */ -/* *INDENT-ON* */ /*? * This command is used to add or delete IPv4 Tables. All * Tables must be explicitly added before that can be used. Creating a * table will add both unicast and multicast FIBs * ?*/ -/* *INDENT-OFF* */ VLIB_CLI_COMMAND (ip6_table_command, static) = { .path = "ip6 table", .short_help = "ip6 table [add|del] <table-id>", @@ -638,7 +682,7 @@ ip_table_bind_cmd (vlib_main_t * vm, goto done; } - rv = ip_table_bind (fproto, sw_if_index, table_id, 0); + rv = ip_table_bind (fproto, sw_if_index, table_id); if (VNET_API_ERROR_ADDRESS_FOUND_FOR_INTERFACE == rv) { @@ -695,14 +739,12 @@ ip6_table_bind_cmd (vlib_main_t * vm, * Example of how to add an interface to an IPv4 FIB table (where 2 is the table-id): * @cliexcmd{set interface ip table GigabitEthernet2/0/0 2} ?*/ -/* *INDENT-OFF* */ VLIB_CLI_COMMAND (set_interface_ip_table_command, static) = { .path = "set interface ip table", .function = ip4_table_bind_cmd, .short_help = "set interface ip table <interface> <table-id>", }; -/* *INDENT-ON* */ /*? * Place the indicated interface into the supplied IPv6 FIB table (also known @@ -723,14 +765,12 @@ VLIB_CLI_COMMAND (set_interface_ip_table_command, static) = * Example of how to add an interface to an IPv6 FIB table (where 2 is the table-id): * @cliexcmd{set interface ip6 table GigabitEthernet2/0/0 2} ?*/ -/* *INDENT-OFF* */ VLIB_CLI_COMMAND (set_interface_ip6_table_command, static) = { .path = "set interface ip6 table", .function = ip6_table_bind_cmd, .short_help = "set interface ip6 table <interface> <table-id>" }; -/* *INDENT-ON* */ clib_error_t * vnet_ip_mroute_cmd (vlib_main_t * vm, @@ -894,8 +934,8 @@ vnet_ip_mroute_cmd (vlib_main_t * vm, mfib_table_entry_path_remove (fib_index, &pfx, MFIB_SOURCE_CLI, rpaths); else - mfib_table_entry_path_update (fib_index, - &pfx, MFIB_SOURCE_CLI, rpaths); + mfib_table_entry_path_update (fib_index, &pfx, MFIB_SOURCE_CLI, + MFIB_ENTRY_FLAG_NONE, rpaths); } if (FIB_PROTOCOL_IP4 == pfx.fp_proto) @@ -967,7 +1007,6 @@ done: * @cliexcmd{ip mroute add 232.1.1.1 Signal} ?*/ -/* *INDENT-OFF* */ VLIB_CLI_COMMAND (ip_mroute_command, static) = { .path = "ip mroute", @@ -975,7 +1014,6 @@ VLIB_CLI_COMMAND (ip_mroute_command, static) = .function = vnet_ip_mroute_cmd, .is_mp_safe = 1, }; -/* *INDENT-ON* */ /* * fd.io coding-style-patch-verification: ON |