#include <vnet/fib/fib_node_list.h>
#include <vnet/fib/fib_walk.h>
#include <vnet/fib/fib_urpf_list.h>
+#include <vnet/fib/fib_path_ext.h>
/**
* The magic number of child entries that make a path-list popular.
*/
static uword *fib_path_list_db;
+/**
+ * the logger
+ */
+vlib_log_class_t fib_path_list_logger;
+
/*
* Debug macro
*/
-#ifdef FIB_DEBUG
-#define FIB_PATH_LIST_DBG(_pl, _fmt, _args...) \
-{ \
- u8 *_tmp = 0; \
- _tmp = fib_path_list_format( \
- fib_path_list_get_index(_pl), _tmp); \
- clib_warning("pl:[%d:%p:%p:%s]:" _fmt, \
- fib_path_list_get_index(_pl), \
- _pl, _pl->fpl_paths, _tmp, \
- ##_args); \
- vec_free(_tmp); \
+#define FIB_PATH_LIST_DBG(_pl, _fmt, _args...) \
+{ \
+ vlib_log_debug(fib_path_list_logger, \
+ "[%U]:" _fmt, \
+ format_fib_path_list, \
+ fib_path_list_get_index(_pl), 0, \
+ ##_args); \
}
-#else
-#define FIB_PATH_LIST_DBG(_pl, _fmt, _args...)
-#endif
static fib_path_list_t *
fib_path_list_get (fib_node_index_t index)
vec_foreach (path_index, path_list->fpl_paths)
{
- s = format(s, "%U", format_fib_path, *path_index, indent+2);
+ s = format(s, "%U", format_fib_path, *path_index, indent+2,
+ FIB_PATH_FORMAT_FLAGS_NONE);
s = format(s, "\n");
}
fib_path_list_destroy(path_list);
}
+static load_balance_flags_t
+fib_path_list_fwd_flags_2_load_balance (fib_path_list_fwd_flags_t pl_flags)
+{
+ load_balance_flags_t lb_flags = LOAD_BALANCE_FLAG_NONE;
+
+ if (pl_flags & FIB_PATH_LIST_FWD_FLAG_STICKY)
+ {
+ lb_flags |= LOAD_BALANCE_ATTR_STICKY;
+ }
+ return (lb_flags);
+}
+
/*
* fib_path_mk_lb
*
static void
fib_path_list_mk_lb (fib_path_list_t *path_list,
fib_forward_chain_type_t fct,
- dpo_id_t *dpo)
+ dpo_id_t *dpo,
+ fib_path_list_fwd_flags_t flags)
{
load_balance_path_t *nhs;
fib_node_index_t *path_index;
*/
vec_foreach (path_index, path_list->fpl_paths)
{
- nhs = fib_path_append_nh_for_multipath_hash(*path_index,
- fct,
- nhs);
+ if ((flags & FIB_PATH_LIST_FWD_FLAG_STICKY) ||
+ fib_path_is_resolved(*path_index))
+ {
+ nhs = fib_path_append_nh_for_multipath_hash(*path_index,
+ fct, nhs);
+ }
}
/*
load_balance_create(vec_len(nhs),
fib_forw_chain_type_to_dpo_proto(fct),
0 /* FIXME FLOW HASH */));
- load_balance_multipath_update(dpo, nhs, LOAD_BALANCE_FLAG_NONE);
+ load_balance_multipath_update(dpo, nhs,
+ fib_path_list_fwd_flags_2_load_balance(flags));
FIB_PATH_LIST_DBG(path_list, "mk lb: %d", dpo->dpoi_index);
fib_path_list_mk_urpf(path_list);
+ FIB_PATH_LIST_DBG(path_list, "bw:%U",
+ format_fib_node_bw_reason, ctx->fnbw_reason);
+
/*
* propagate the backwalk further
*/
fib_path_list_t *path_list;
pool_get(fib_path_list_pool, path_list);
- memset(path_list, 0, sizeof(*path_list));
+ clib_memset(path_list, 0, sizeof(*path_list));
fib_node_init(&path_list->fpl_node,
FIB_NODE_TYPE_PATH_LIST);
if (FIB_NODE_INDEX_INVALID != old_path_list_index)
{
fib_path_list_destroy(path_list);
-
+
path_list_index = old_path_list_index;
}
else
return (path_list_index);
}
-static fib_path_cfg_flags_t
+static fib_path_cfg_flags_t
fib_path_list_flags_2_path_flags (fib_path_list_flags_t plf)
{
fib_path_cfg_flags_t pf = FIB_PATH_CFG_FLAG_NONE;
ASSERT(1 == vec_len(rpaths));
ASSERT(!(path_list->fpl_flags & FIB_PATH_LIST_FLAG_SHARED));
- FIB_PATH_LIST_DBG(orig_path_list, "path-add");
+ FIB_PATH_LIST_DBG(path_list, "path-add");
new_path_index = fib_path_create(path_list_index,
rpaths);
ASSERT(1 == vec_len(rpaths));
ASSERT(!(path_list->fpl_flags & FIB_PATH_LIST_FLAG_SHARED));
- FIB_PATH_LIST_DBG(orig_path_list, "path-remove");
+ FIB_PATH_LIST_DBG(path_list, "path-remove");
/*
* create a representation of the path to be removed, so it
path_list = fib_path_list_get(path_list_index);
- fib_path_list_mk_lb(path_list, fct, dpo);
+ fib_path_list_mk_lb(path_list, fct, dpo, flags);
ASSERT(DPO_LOAD_BALANCE == dpo->dpoi_type);
vec_free(copy);
}
- FIB_PATH_LIST_DBG(path_list, "loop-detect: eval:%d", eval);
+ FIB_PATH_LIST_DBG(path_list, "loop-detect: eval:%d", list_looped);
if (list_looped)
{
path_list = fib_path_list_get(path_list_index);
fib_node_lock(&path_list->fpl_node);
- FIB_PATH_LIST_DBG(path_list, "lock");
}
}
if (FIB_NODE_INDEX_INVALID != path_list_index)
{
path_list = fib_path_list_get(path_list_index);
- FIB_PATH_LIST_DBG(path_list, "unlock");
fib_node_unlock(&path_list->fpl_node);
}
}
}
+void
+fib_path_list_walk_w_ext (fib_node_index_t path_list_index,
+ const fib_path_ext_list_t *ext_list,
+ fib_path_list_walk_w_ext_fn_t func,
+ void *ctx)
+{
+ fib_node_index_t *path_index;
+ fib_path_list_t *path_list;
+ fib_path_ext_t *path_ext;
+
+ path_list = fib_path_list_get(path_list_index);
+
+ vec_foreach(path_index, path_list->fpl_paths)
+ {
+ path_ext = fib_path_ext_list_find_by_path_index(ext_list, *path_index);
+
+ if (FIB_PATH_LIST_WALK_STOP == func(path_list_index,
+ *path_index,
+ path_ext,
+ ctx))
+ break;
+ }
+}
void
fib_path_list_module_init (void)
fib_path_list_db_hash_key_equal,
/* format pair/arg */
0, 0);
+ fib_path_list_logger = vlib_log_register_class("fib", "path-list");
}
static clib_error_t *