#include <vnet/fib/ip6_fib.h>
#include <vnet/fib/mpls_fib.h>
+const static char * fib_table_flags_strings[] = FIB_TABLE_ATTRIBUTES;
+
fib_table_t *
fib_table_get (fib_node_index_t index,
fib_protocol_t proto)
}
}
+static void
+fib_table_source_count_inc (fib_table_t *fib_table,
+ fib_source_t source)
+{
+ vec_validate (fib_table->ft_src_route_counts, source);
+ fib_table->ft_src_route_counts[source]++;
+}
+
+static void
+fib_table_source_count_dec (fib_table_t *fib_table,
+ fib_source_t source)
+{
+ vec_validate (fib_table->ft_src_route_counts, source);
+ fib_table->ft_src_route_counts[source]--;
+}
fib_node_index_t
fib_table_entry_special_dpo_add (u32 fib_index,
dpo);
fib_table_entry_insert(fib_table, prefix, fib_entry_index);
- fib_table->ft_src_route_counts[source]++;
+ fib_table_source_count_inc(fib_table, source);
}
else
{
if (was_sourced != fib_entry_is_sourced(fib_entry_index, source))
{
- fib_table->ft_src_route_counts[source]++;
+ fib_table_source_count_inc(fib_table, source);
}
}
dpo);
fib_table_entry_insert(fib_table, prefix, fib_entry_index);
- fib_table->ft_src_route_counts[source]++;
+ fib_table_source_count_inc(fib_table, source);
}
else
{
if (was_sourced != fib_entry_is_sourced(fib_entry_index, source))
{
- fib_table->ft_src_route_counts[source]++;
+ fib_table_source_count_inc(fib_table, source);
}
}
*/
if (was_sourced != fib_entry_is_sourced(fib_entry_index, source))
{
- fib_table->ft_src_route_counts[source]--;
+ fib_table_source_count_dec(fib_table, source);
}
fib_entry_unlock(fib_entry_index);
return (fib_entry_index);
}
+static int
+fib_route_path_cmp_for_sort (void * v1,
+ void * v2)
+{
+ return (fib_route_path_cmp(v1, v2));
+}
+
fib_node_index_t
fib_table_entry_path_add2 (u32 fib_index,
const fib_prefix_t *prefix,
{
fib_table_route_path_fixup(prefix, &flags, &rpaths[ii]);
}
+ /*
+ * sort the paths provided by the control plane. this means
+ * the paths and the extension on the entry will be sorted.
+ */
+ vec_sort_with_function(rpaths, fib_route_path_cmp_for_sort);
if (FIB_NODE_INDEX_INVALID == fib_entry_index)
{
rpaths);
fib_table_entry_insert(fib_table, prefix, fib_entry_index);
- fib_table->ft_src_route_counts[source]++;
+ fib_table_source_count_inc(fib_table, source);
}
else
{
if (was_sourced != fib_entry_is_sourced(fib_entry_index, source))
{
- fib_table->ft_src_route_counts[source]++;
+ fib_table_source_count_inc(fib_table, source);
}
}
*/
if (was_sourced != fib_entry_is_sourced(fib_entry_index, source))
{
- fib_table->ft_src_route_counts[source]--;
+ fib_table_source_count_dec(fib_table, source);
}
fib_entry_unlock(fib_entry_index);
vec_free(paths);
}
-static int
-fib_route_path_cmp_for_sort (void * v1,
- void * v2)
-{
- return (fib_route_path_cmp(v1, v2));
-}
-
fib_node_index_t
fib_table_entry_update (u32 fib_index,
const fib_prefix_t *prefix,
paths);
fib_table_entry_insert(fib_table, prefix, fib_entry_index);
- fib_table->ft_src_route_counts[source]++;
+ fib_table_source_count_inc(fib_table, source);
}
else
{
if (was_sourced != fib_entry_is_sourced(fib_entry_index, source))
{
- fib_table->ft_src_route_counts[source]++;
+ fib_table_source_count_inc(fib_table, source);
}
}
*/
if (was_sourced != fib_entry_is_sourced(fib_entry_index, source))
{
- fib_table->ft_src_route_counts[source]--;
+ fib_table_source_count_dec(fib_table, source);
}
fib_entry_unlock(fib_entry_index);
}
}
+static void
+fib_table_lock_dec (fib_table_t *fib_table,
+ fib_source_t source)
+{
+ vec_validate(fib_table->ft_locks, source);
+
+ fib_table->ft_locks[source]--;
+ fib_table->ft_total_locks--;
+}
+
+static void
+fib_table_lock_inc (fib_table_t *fib_table,
+ fib_source_t source)
+{
+ vec_validate(fib_table->ft_locks, source);
+
+ ASSERT(fib_table->ft_total_locks < (0xffffffff - 1));
+ fib_table->ft_locks[source]++;
+ fib_table->ft_total_locks++;
+}
+
void
fib_table_unlock (u32 fib_index,
fib_protocol_t proto,
fib_table_t *fib_table;
fib_table = fib_table_get(fib_index, proto);
- fib_table->ft_locks[source]--;
- fib_table->ft_locks[FIB_TABLE_TOTAL_LOCKS]--;
+ fib_table_lock_dec(fib_table, source);
- if (0 == fib_table->ft_locks[FIB_TABLE_TOTAL_LOCKS])
+ if (0 == fib_table->ft_total_locks)
{
/*
* no more locak from any source - kill it
fib_table = fib_table_get(fib_index, proto);
- ASSERT(fib_table->ft_locks[source] < (0xffff - 1));
-
- fib_table->ft_locks[source]++;
- fib_table->ft_locks[FIB_TABLE_TOTAL_LOCKS]++;
+ fib_table_lock_inc(fib_table, source);
}
u32
return (s);
}
+u8*
+format_fib_table_flags (u8 *s, va_list *args)
+{
+ fib_table_flags_t flags = va_arg(*args, int);
+ fib_table_attribute_t attr;
+
+ if (!flags)
+ {
+ return format(s, "none");
+ }
+
+ FOR_EACH_FIB_TABLE_ATTRIBUTE(attr) {
+ if (1 << attr & flags) {
+ s = format(s, "%s", fib_table_flags_strings[attr]);
+ }
+ }
+
+ return (s);
+}
+
/**
* @brief Table flush context. Store the indicies of matching FIB entries
* that need to be removed.
return (FIB_TABLE_WALK_CONTINUE);
}
-
void
fib_table_flush (u32 fib_index,
fib_protocol_t proto,
vec_free(ctx.ftf_entries);
}
+static fib_table_walk_rc_t
+fib_table_mark_cb (fib_node_index_t fib_entry_index,
+ void *arg)
+{
+ fib_table_flush_ctx_t *ctx = arg;
+
+ if (fib_entry_is_sourced(fib_entry_index, ctx->ftf_source))
+ {
+ fib_entry_mark(fib_entry_index, ctx->ftf_source);
+ }
+ return (FIB_TABLE_WALK_CONTINUE);
+}
+
+void
+fib_table_mark (u32 fib_index,
+ fib_protocol_t proto,
+ fib_source_t source)
+{
+ fib_table_flush_ctx_t ctx = {
+ .ftf_source = source,
+ };
+ fib_table_t *fib_table;
+
+ fib_table = fib_table_get(fib_index, proto);
+
+ fib_table->ft_epoch++;
+ fib_table->ft_flags |= FIB_TABLE_FLAG_RESYNC;
+
+ fib_table_walk(fib_index, proto,
+ fib_table_mark_cb,
+ &ctx);
+}
+
+static fib_table_walk_rc_t
+fib_table_sweep_cb (fib_node_index_t fib_entry_index,
+ void *arg)
+{
+ fib_table_flush_ctx_t *ctx = arg;
+
+ if (fib_entry_is_marked(fib_entry_index, ctx->ftf_source))
+ {
+ vec_add1(ctx->ftf_entries, fib_entry_index);
+ }
+ return (FIB_TABLE_WALK_CONTINUE);
+}
+
+void
+fib_table_sweep (u32 fib_index,
+ fib_protocol_t proto,
+ fib_source_t source)
+{
+ fib_table_flush_ctx_t ctx = {
+ .ftf_source = source,
+ };
+ fib_node_index_t *fib_entry_index;
+ fib_table_t *fib_table;
+
+ fib_table = fib_table_get(fib_index, proto);
+
+ fib_table->ft_flags &= ~FIB_TABLE_FLAG_RESYNC;
+
+ fib_table_walk(fib_index, proto,
+ fib_table_sweep_cb,
+ &ctx);
+
+ vec_foreach(fib_entry_index, ctx.ftf_entries)
+ {
+ fib_table_entry_delete_index(*fib_entry_index, source);
+ }
+
+ vec_free(ctx.ftf_entries);
+}
+
u8 *
format_fib_table_memory (u8 *s, va_list *args)
{