(~0 == path->frp_sw_if_index) &&
(0 == ip46_address_cmp(&path->frp_addr, &prefix->fp_addr)))
{
- /* Prefix recurses via itse;f */
+ /* Prefix recurses via itself */
path->frp_flags |= FIB_ROUTE_PATH_DROP;
}
if (!(path->frp_flags & FIB_ROUTE_PATH_LOCAL) &&
path->frp_addr = prefix->fp_addr;
path->frp_flags |= FIB_ROUTE_PATH_ATTACHED;
}
+ else if ((*eflags & FIB_ENTRY_FLAG_CONNECTED) &&
+ !(*eflags & FIB_ENTRY_FLAG_LOCAL))
+ {
+ if (ip46_address_is_zero(&path->frp_addr))
+ {
+ path->frp_flags |= FIB_ROUTE_PATH_GLEAN;
+ fib_prefix_normalize(prefix, &path->frp_connected);
+ }
+ }
+ else if (fib_route_path_is_attached(path))
+ {
+ path->frp_flags |= FIB_ROUTE_PATH_GLEAN;
+ fib_prefix_normalize(prefix, &path->frp_connected);
+ }
if (*eflags & FIB_ENTRY_FLAG_DROP)
{
path->frp_flags |= FIB_ROUTE_PATH_DROP;
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)
{
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,
}
}
+typedef struct fib_table_walk_w_src_ctx_t_
+{
+ fib_table_walk_fn_t fn;
+ void *data;
+ fib_source_t src;
+} fib_table_walk_w_src_cxt_t;
+
+static fib_table_walk_rc_t
+fib_table_walk_w_src_cb (fib_node_index_t fei,
+ void *arg)
+{
+ fib_table_walk_w_src_cxt_t *ctx = arg;
+
+ if (ctx->src == fib_entry_get_best_source(fei))
+ {
+ return (ctx->fn(fei, ctx->data));
+ }
+ return (FIB_TABLE_WALK_CONTINUE);
+}
+
+void
+fib_table_walk_w_src (u32 fib_index,
+ fib_protocol_t proto,
+ fib_source_t src,
+ fib_table_walk_fn_t fn,
+ void *data)
+{
+ fib_table_walk_w_src_cxt_t ctx = {
+ .fn = fn,
+ .src = src,
+ .data = data,
+ };
+
+ fib_table_walk(fib_index, proto, fib_table_walk_w_src_cb, &ctx);
+}
+
void
fib_table_sub_tree_walk (u32 fib_index,
fib_protocol_t proto,
{
vec_validate(fib_table->ft_locks, source);
+ ASSERT(fib_table->ft_locks[source] > 0);
fib_table->ft_locks[source]--;
fib_table->ft_total_locks--;
}
{
vec_validate(fib_table->ft_locks, source);
- ASSERT(fib_table->ft_locks[source] < (0xffff - 1));
+ ASSERT(fib_table->ft_total_locks < (0xffffffff - 1));
fib_table->ft_locks[source]++;
fib_table->ft_total_locks++;
}
+
+static void
+fib_table_lock_clear (fib_table_t *fib_table,
+ fib_source_t source)
+{
+ vec_validate(fib_table->ft_locks, source);
+
+ ASSERT(fib_table->ft_locks[source] <= 1);
+ if (fib_table->ft_locks[source])
+ {
+ fib_table->ft_locks[source]--;
+ fib_table->ft_total_locks--;
+ }
+}
+
+static void
+fib_table_lock_set (fib_table_t *fib_table,
+ fib_source_t source)
+{
+ vec_validate(fib_table->ft_locks, source);
+
+ ASSERT(fib_table->ft_locks[source] <= 1);
+ ASSERT(fib_table->ft_total_locks < (0xffffffff - 1));
+ if (!fib_table->ft_locks[source])
+ {
+ 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_lock_dec(fib_table, source);
+
+ if (source == FIB_SOURCE_API || source == FIB_SOURCE_CLI)
+ fib_table_lock_clear(fib_table, source);
+ else
+ fib_table_lock_dec(fib_table, source);
if (0 == fib_table->ft_total_locks)
{
/*
- * no more locak from any source - kill it
+ * no more lock from any source - kill it
*/
fib_table_destroy(fib_table);
}
fib_table = fib_table_get(fib_index, proto);
- fib_table_lock_inc(fib_table, source);
+ if (source == FIB_SOURCE_API || source == FIB_SOURCE_CLI)
+ fib_table_lock_set(fib_table, source);
+ else
+ fib_table_lock_inc(fib_table, source);
}
u32