#include <vnet/dpo/punt_dpo.h>
#include <vnet/dpo/receive_dpo.h>
#include <vnet/dpo/ip_null_dpo.h>
-#include <vnet/dpo/l3_proxy_dpo.h>
/**
* @file
*
*/
-clib_error_t *
-ip_interface_address_add_del (ip_lookup_main_t * lm,
- u32 sw_if_index,
- void *addr_fib,
- u32 address_length,
- u32 is_del, u32 * result_if_address_index)
-{
- vnet_main_t *vnm = vnet_get_main ();
- ip_interface_address_t *a, *prev, *next;
- uword *p = mhash_get (&lm->address_to_if_address_index, addr_fib);
-
- vec_validate_init_empty (lm->if_address_pool_index_by_sw_if_index,
- sw_if_index, ~0);
- a = p ? pool_elt_at_index (lm->if_address_pool, p[0]) : 0;
-
- /* Verify given length. */
- if ((a && (address_length != a->address_length)) ||
- (address_length == 0) ||
- (lm->is_ip6 && address_length > 128) ||
- (!lm->is_ip6 && address_length > 32))
- {
- vnm->api_errno = VNET_API_ERROR_ADDRESS_LENGTH_MISMATCH;
- return clib_error_create
- ("%U wrong length (expected %d) for interface %U",
- lm->format_address_and_length, addr_fib,
- address_length, a ? a->address_length : -1,
- format_vnet_sw_if_index_name, vnm, sw_if_index);
- }
-
- if (is_del)
- {
- if (!a)
- {
- vnet_sw_interface_t *si = vnet_get_sw_interface (vnm, sw_if_index);
- vnm->api_errno = VNET_API_ERROR_ADDRESS_NOT_FOUND_FOR_INTERFACE;
- return clib_error_create ("%U not found for interface %U",
- lm->format_address_and_length,
- addr_fib, address_length,
- format_vnet_sw_interface_name, vnm, si);
- }
-
- if (a->prev_this_sw_interface != ~0)
- {
- prev =
- pool_elt_at_index (lm->if_address_pool,
- a->prev_this_sw_interface);
- prev->next_this_sw_interface = a->next_this_sw_interface;
- }
- if (a->next_this_sw_interface != ~0)
- {
- next =
- pool_elt_at_index (lm->if_address_pool,
- a->next_this_sw_interface);
- next->prev_this_sw_interface = a->prev_this_sw_interface;
-
- if (a->prev_this_sw_interface == ~0)
- lm->if_address_pool_index_by_sw_if_index[sw_if_index] =
- a->next_this_sw_interface;
- }
-
- if ((a->next_this_sw_interface == ~0)
- && (a->prev_this_sw_interface == ~0))
- lm->if_address_pool_index_by_sw_if_index[sw_if_index] = ~0;
-
- mhash_unset (&lm->address_to_if_address_index, addr_fib,
- /* old_value */ 0);
- pool_put (lm->if_address_pool, a);
-
- if (result_if_address_index)
- *result_if_address_index = ~0;
- }
-
- else if (!a)
- {
- u32 pi; /* previous index */
- u32 ai;
- u32 hi; /* head index */
-
- pool_get (lm->if_address_pool, a);
- clib_memset (a, ~0, sizeof (a[0]));
- ai = a - lm->if_address_pool;
-
- hi = pi = lm->if_address_pool_index_by_sw_if_index[sw_if_index];
- prev = 0;
- while (pi != (u32) ~ 0)
- {
- prev = pool_elt_at_index (lm->if_address_pool, pi);
- pi = prev->next_this_sw_interface;
- }
- pi = prev ? prev - lm->if_address_pool : (u32) ~ 0;
-
- a->address_key = mhash_set (&lm->address_to_if_address_index,
- addr_fib, ai, /* old_value */ 0);
- a->address_length = address_length;
- a->sw_if_index = sw_if_index;
- a->flags = 0;
- a->prev_this_sw_interface = pi;
- a->next_this_sw_interface = ~0;
- if (prev)
- prev->next_this_sw_interface = ai;
-
- lm->if_address_pool_index_by_sw_if_index[sw_if_index] =
- (hi != ~0) ? hi : ai;
- if (result_if_address_index)
- *result_if_address_index = ai;
- }
- else
- {
- if (sw_if_index != a->sw_if_index)
- {
- if (result_if_address_index)
- *result_if_address_index = ~0;
- vnm->api_errno = VNET_API_ERROR_DUPLICATE_IF_ADDRESS;
- return clib_error_create
- ("Prefix %U already found on interface %U",
- lm->format_address_and_length, addr_fib, address_length,
- format_vnet_sw_if_index_name, vnm, a->sw_if_index);
- }
-
- if (result_if_address_index)
- *result_if_address_index = a - lm->if_address_pool;
- }
-
- return /* no error */ 0;
-}
-
static clib_error_t *
ip_sw_interface_add_del (vnet_main_t * vnm, u32 sw_if_index, u32 is_add)
{
{
flow_hash_config_t flow_hash_config = va_arg (*args, u32);
-#define _(n,v) if (flow_hash_config & v) s = format (s, "%s ", #n);
+#define _(n, b, v) \
+ if (flow_hash_config & v) \
+ s = format (s, "%s ", #n);
foreach_flow_hash_bit;
#undef _
}
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 (is_del)
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);
}
}
- 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;
}
return (vnet_ip_table_cmd (vm, main_input, cmd, FIB_PROTOCOL_IP6));
}
+clib_error_t *
+vnet_show_ip_table_cmd (vlib_main_t *vm, unformat_input_t *main_input,
+ vlib_cli_command_t *cmd, fib_protocol_t fproto)
+{
+ unformat_input_t _line_input, *line_input = &_line_input;
+ fib_table_t *fib, *fibs;
+ clib_error_t *error = NULL;
+ u32 table_id = ~0, fib_index;
+ /* Get a line of input. */
+ if (unformat_user (main_input, unformat_line_input, line_input))
+ {
+ while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (line_input, "%d", &table_id))
+ ;
+ else
+ {
+ error = unformat_parse_error (line_input);
+ goto done;
+ }
+ }
+ unformat_free (line_input);
+ }
+
+ fibs = (fproto == FIB_PROTOCOL_IP4) ? ip4_main.fibs : ip6_main.fibs;
+
+ if (table_id != (u32) ~0)
+ {
+ fib_index = fib_table_find (fproto, table_id);
+ if (fib_index == (u32) ~0)
+ {
+ error = clib_error_return (0, "Couldn't find table with table_id %u",
+ table_id);
+ goto done;
+ }
+
+ fib = fib_table_get (fib_index, fproto);
+ vlib_cli_output (vm, "[%3u] table_id:%3u %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,
+ fib->ft_table_id, fib->ft_desc);
+ }
+
+done:
+ return error;
+}
+
+clib_error_t *
+vnet_show_ip4_table_cmd (vlib_main_t *vm, unformat_input_t *main_input,
+ vlib_cli_command_t *cmd)
+{
+ return (vnet_show_ip_table_cmd (vm, main_input, cmd, FIB_PROTOCOL_IP4));
+}
+
+clib_error_t *
+vnet_show_ip6_table_cmd (vlib_main_t *vm, unformat_input_t *main_input,
+ vlib_cli_command_t *cmd)
+{
+ 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",
.path = "ip table",
.short_help = "ip table [add|del] <table-id>",
.function = vnet_ip4_table_cmd,
- .is_mp_safe = 1,
};
/* *INDENT-ON* */
.path = "ip6 table",
.short_help = "ip6 table [add|del] <table-id>",
.function = vnet_ip6_table_cmd,
- .is_mp_safe = 1,
+};
+
+VLIB_CLI_COMMAND (show_ip4_table_command, static) = {
+ .path = "show ip table",
+ .short_help = "show ip table <table-id>",
+ .function = vnet_show_ip4_table_cmd,
+};
+
+VLIB_CLI_COMMAND (show_ip6_table_command, static) = {
+ .path = "show ip6 table",
+ .short_help = "show ip6 table <table-id>",
+ .function = vnet_show_ip6_table_cmd,
};
static clib_error_t *
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)
{
&pfx.fp_src_addr.ip4,
unformat_ip4_address, &pfx.fp_grp_addr.ip4))
{
- pfx.fp_proto = FIB_PROTOCOL_IP4;
+ payload_proto = pfx.fp_proto = FIB_PROTOCOL_IP4;
pfx.fp_len = 64;
}
else if (unformat (line_input, "%U %U",
&pfx.fp_src_addr.ip6,
unformat_ip6_address, &pfx.fp_grp_addr.ip6))
{
- pfx.fp_proto = FIB_PROTOCOL_IP6;
+ payload_proto = pfx.fp_proto = FIB_PROTOCOL_IP6;
pfx.fp_len = 256;
}
else if (unformat (line_input, "%U/%d",
&pfx.fp_grp_addr.ip4, &pfx.fp_len))
{
clib_memset (&pfx.fp_src_addr.ip4, 0, sizeof (pfx.fp_src_addr.ip4));
- pfx.fp_proto = FIB_PROTOCOL_IP4;
+ payload_proto = pfx.fp_proto = FIB_PROTOCOL_IP4;
}
else if (unformat (line_input, "%U/%d",
unformat_ip6_address,
&pfx.fp_grp_addr.ip6, &pfx.fp_len))
{
clib_memset (&pfx.fp_src_addr.ip6, 0, sizeof (pfx.fp_src_addr.ip6));
- pfx.fp_proto = FIB_PROTOCOL_IP6;
+ payload_proto = pfx.fp_proto = FIB_PROTOCOL_IP6;
}
else if (unformat (line_input, "%U",
unformat_ip4_address, &pfx.fp_grp_addr.ip4))
{
clib_memset (&pfx.fp_src_addr.ip4, 0, sizeof (pfx.fp_src_addr.ip4));
- pfx.fp_proto = FIB_PROTOCOL_IP4;
+ payload_proto = pfx.fp_proto = FIB_PROTOCOL_IP4;
pfx.fp_len = 32;
}
else if (unformat (line_input, "%U",
unformat_ip6_address, &pfx.fp_grp_addr.ip6))
{
clib_memset (&pfx.fp_src_addr.ip6, 0, sizeof (pfx.fp_src_addr.ip6));
- pfx.fp_proto = FIB_PROTOCOL_IP6;
+ payload_proto = pfx.fp_proto = FIB_PROTOCOL_IP6;
pfx.fp_len = 128;
}
else if (unformat (line_input, "via local Forward"))
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)
};
/* *INDENT-ON* */
-clib_error_t *
-vnet_ip_container_proxy_add_del (vnet_ip_container_proxy_args_t * args)
-{
- u32 fib_index;
-
- if (!vnet_sw_interface_is_api_valid (vnet_get_main (), args->sw_if_index))
- return clib_error_return_code (0, VNET_API_ERROR_INVALID_INTERFACE, 0,
- "invalid sw_if_index");
-
- fib_index = fib_table_get_table_id_for_sw_if_index (args->prefix.fp_proto,
- args->sw_if_index);
- if (args->is_add)
- {
- dpo_id_t proxy_dpo = DPO_INVALID;
- l3_proxy_dpo_add_or_lock (fib_proto_to_dpo (args->prefix.fp_proto),
- args->sw_if_index, &proxy_dpo);
- fib_table_entry_special_dpo_add (fib_index,
- &args->prefix,
- FIB_SOURCE_PROXY,
- FIB_ENTRY_FLAG_EXCLUSIVE, &proxy_dpo);
- dpo_reset (&proxy_dpo);
- }
- else
- {
- fib_table_entry_special_remove (fib_index, &args->prefix,
- FIB_SOURCE_PROXY);
- }
- return 0;
-}
-
-u8
-ip_container_proxy_is_set (fib_prefix_t * pfx, u32 sw_if_index)
-{
- u32 fib_index;
- fib_node_index_t fei;
- const dpo_id_t *dpo;
- l3_proxy_dpo_t *l3p;
- load_balance_t *lb0;
-
- fib_index = fib_table_get_table_id_for_sw_if_index (pfx->fp_proto,
- sw_if_index);
- if (fib_index == ~0)
- return 0;
-
- fei = fib_table_lookup_exact_match (fib_index, pfx);
- if (fei == FIB_NODE_INDEX_INVALID)
- return 0;
-
- dpo = fib_entry_contribute_ip_forwarding (fei);
- lb0 = load_balance_get (dpo->dpoi_index);
- dpo = load_balance_get_bucket_i (lb0, 0);
- if (dpo->dpoi_type != DPO_L3_PROXY)
- return 0;
-
- l3p = l3_proxy_dpo_get (dpo->dpoi_index);
- return (l3p->l3p_sw_if_index == sw_if_index);
-}
-
-typedef struct ip_container_proxy_walk_ctx_t_
-{
- ip_container_proxy_cb_t cb;
- void *ctx;
-} ip_container_proxy_walk_ctx_t;
-
-static fib_table_walk_rc_t
-ip_container_proxy_fib_table_walk (fib_node_index_t fei, void *arg)
-{
- ip_container_proxy_walk_ctx_t *ctx = arg;
- const fib_prefix_t *pfx;
- const dpo_id_t *dpo;
- load_balance_t *lb;
- l3_proxy_dpo_t *l3p;
-
- pfx = fib_entry_get_prefix (fei);
- if (fib_entry_is_sourced (fei, FIB_SOURCE_PROXY))
- {
- dpo = fib_entry_contribute_ip_forwarding (fei);
- lb = load_balance_get (dpo->dpoi_index);
- dpo = load_balance_get_bucket_i (lb, 0);
- l3p = l3_proxy_dpo_get (dpo->dpoi_index);
- ctx->cb (pfx, l3p->l3p_sw_if_index, ctx->ctx);
- }
-
- return FIB_TABLE_WALK_CONTINUE;
-}
-
-void
-ip_container_proxy_walk (ip_container_proxy_cb_t cb, void *ctx)
-{
- fib_table_t *fib_table;
- ip_container_proxy_walk_ctx_t wctx = {
- .cb = cb,
- .ctx = ctx,
- };
-
- /* *INDENT-OFF* */
- pool_foreach (fib_table, ip4_main.fibs,
- ({
- fib_table_walk(fib_table->ft_index,
- FIB_PROTOCOL_IP4,
- ip_container_proxy_fib_table_walk,
- &wctx);
- }));
- pool_foreach (fib_table, ip6_main.fibs,
- ({
- fib_table_walk(fib_table->ft_index,
- FIB_PROTOCOL_IP6,
- ip_container_proxy_fib_table_walk,
- &wctx);
- }));
- /* *INDENT-ON* */
-}
-
-clib_error_t *
-ip_container_cmd (vlib_main_t * vm,
- unformat_input_t * main_input, vlib_cli_command_t * cmd)
-{
- unformat_input_t _line_input, *line_input = &_line_input;
- fib_prefix_t pfx;
- u32 is_del, addr_set = 0;
- vnet_main_t *vnm;
- u32 sw_if_index;
-
- vnm = vnet_get_main ();
- is_del = 0;
- sw_if_index = ~0;
- clib_memset (&pfx, 0, sizeof (pfx));
-
- /* Get a line of input. */
- if (!unformat_user (main_input, unformat_line_input, line_input))
- return 0;
-
- while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (line_input, "%U", unformat_ip4_address, &pfx.fp_addr.ip4))
- {
- pfx.fp_proto = FIB_PROTOCOL_IP4;
- pfx.fp_len = 32;
- addr_set = 1;
- }
- else if (unformat (line_input, "%U",
- unformat_ip6_address, &pfx.fp_addr.ip6))
- {
- pfx.fp_proto = FIB_PROTOCOL_IP6;
- pfx.fp_len = 128;
- addr_set = 1;
- }
- else if (unformat (line_input, "%U",
- unformat_vnet_sw_interface, vnm, &sw_if_index))
- ;
- else if (unformat (line_input, "del"))
- is_del = 1;
- else
- {
- unformat_free (line_input);
- return (clib_error_return (0, "unknown input '%U'",
- format_unformat_error, line_input));
- }
- }
-
- if (~0 == sw_if_index || !addr_set)
- {
- unformat_free (line_input);
- vlib_cli_output (vm, "interface and address must be set");
- return 0;
- }
-
- vnet_ip_container_proxy_args_t args = {
- .prefix = pfx,
- .sw_if_index = sw_if_index,
- .is_add = !is_del,
- };
- vnet_ip_container_proxy_add_del (&args);
- unformat_free (line_input);
- return (NULL);
-}
-
-/* *INDENT-OFF* */
-VLIB_CLI_COMMAND (ip_container_command_node, static) = {
- .path = "ip container",
- .function = ip_container_cmd,
- .short_help = "ip container <address> <interface>",
- .is_mp_safe = 1,
-};
-/* *INDENT-ON* */
-
-clib_error_t *
-show_ip_container_cmd_fn (vlib_main_t * vm, unformat_input_t * main_input,
- vlib_cli_command_t * cmd)
-{
- unformat_input_t _line_input, *line_input = &_line_input;
- vnet_main_t *vnm = vnet_get_main ();
- fib_prefix_t pfx;
- u32 sw_if_index = ~0;
- u8 has_proxy;
-
- if (!unformat_user (main_input, unformat_line_input, line_input))
- return 0;
- while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (line_input, "%U", unformat_ip4_address, &pfx.fp_addr.ip4))
- {
- pfx.fp_proto = FIB_PROTOCOL_IP4;
- pfx.fp_len = 32;
- }
- else if (unformat (line_input, "%U",
- unformat_ip6_address, &pfx.fp_addr.ip6))
- {
- pfx.fp_proto = FIB_PROTOCOL_IP6;
- pfx.fp_len = 128;
- }
- else if (unformat (line_input, "%U",
- unformat_vnet_sw_interface, vnm, &sw_if_index))
- ;
- else
- {
- unformat_free (line_input);
- return (clib_error_return (0, "unknown input '%U'",
- format_unformat_error, line_input));
- }
- }
-
- if (~0 == sw_if_index)
- {
- unformat_free (line_input);
- vlib_cli_output (vm, "no interface");
- return (clib_error_return (0, "no interface"));
- }
-
- has_proxy = ip_container_proxy_is_set (&pfx, sw_if_index);
- vlib_cli_output (vm, "ip container proxy is: %s", has_proxy ? "on" : "off");
-
- unformat_free (line_input);
- return 0;
-}
-
-/* *INDENT-OFF* */
-VLIB_CLI_COMMAND (show_ip_container_command, static) = {
- .path = "show ip container",
- .function = show_ip_container_cmd_fn,
- .short_help = "show ip container <address> <interface>",
- .is_mp_safe = 1,
-};
-/* *INDENT-ON* */
-
/*
* fd.io coding-style-patch-verification: ON
*