return (fib_entry_index);
}
+fib_node_index_t
+fib_table_entry_special_dpo_update (u32 fib_index,
+ const fib_prefix_t *prefix,
+ fib_source_t source,
+ fib_entry_flag_t flags,
+ const dpo_id_t *dpo)
+{
+ fib_node_index_t fib_entry_index;
+ fib_table_t *fib_table;
+
+ fib_table = fib_table_get(fib_index, prefix->fp_proto);
+ fib_entry_index = fib_table_lookup_exact_match_i(fib_table, prefix);
+
+ if (FIB_NODE_INDEX_INVALID == fib_entry_index)
+ {
+ fib_entry_index = fib_entry_create_special(fib_index, prefix,
+ source, flags,
+ dpo);
+
+ fib_table_entry_insert(fib_table, prefix, fib_entry_index);
+ fib_table->ft_src_route_counts[source]++;
+ }
+ else
+ {
+ int was_sourced;
+
+ was_sourced = fib_entry_is_sourced(fib_entry_index, source);
+
+ if (was_sourced)
+ fib_entry_special_update(fib_entry_index, source, flags, dpo);
+ else
+ fib_entry_special_add(fib_entry_index, source, flags, dpo);
+
+ if (was_sourced != fib_entry_is_sourced(fib_entry_index, source))
+ {
+ fib_table->ft_src_route_counts[source]++;
+ }
+ }
+
+ return (fib_entry_index);
+}
+
fib_node_index_t
fib_table_entry_special_add (u32 fib_index,
const fib_prefix_t *prefix,
adj_index_t adj_index)
{
fib_node_index_t fib_entry_index;
- dpo_id_t tmp_dpo = DPO_NULL;
+ dpo_id_t tmp_dpo = DPO_INVALID;
if (ADJ_INDEX_INVALID != adj_index)
{
return (fib_entry_index);
}
-void
-fib_table_entry_special_dpo_update (fib_node_index_t fib_entry_index,
- fib_source_t source,
- fib_entry_flag_t flags,
- const dpo_id_t *dpo)
-{
- fib_prefix_t prefix;
- u32 fib_index;
-
- fib_entry_get_prefix(fib_entry_index, &prefix);
- fib_index = fib_entry_get_fib_index(fib_entry_index);
-
- fib_table_entry_special_dpo_add(fib_index, &prefix, source, flags, dpo);
- fib_table_entry_special_remove(fib_index, &prefix, source);
-}
-
void
fib_table_entry_special_remove (u32 fib_index,
const fib_prefix_t *prefix,
u32 next_hop_sw_if_index,
u32 next_hop_fib_index,
u32 next_hop_weight,
- mpls_label_t next_hop_label,
+ mpls_label_t *next_hop_labels,
fib_route_path_flags_t path_flags)
{
fib_route_path_t path = {
.frp_fib_index = next_hop_fib_index,
.frp_weight = next_hop_weight,
.frp_flags = path_flags,
- .frp_label = next_hop_label,
+ .frp_label_stack = next_hop_labels,
};
fib_node_index_t fib_entry_index;
fib_route_path_t *paths = NULL;
- fib_table_route_path_fixup(prefix, &path);
vec_add1(paths, path);
fib_entry_index = fib_table_entry_path_add2(fib_index, prefix,
const fib_prefix_t *prefix,
fib_source_t source,
fib_entry_flag_t flags,
- const fib_route_path_t *rpath)
+ fib_route_path_t *rpath)
{
fib_node_index_t fib_entry_index;
fib_table_t *fib_table;
+ u32 ii;
fib_table = fib_table_get(fib_index, prefix->fp_proto);
fib_entry_index = fib_table_lookup_exact_match_i(fib_table, prefix);
+ for (ii = 0; ii < vec_len(rpath); ii++)
+ {
+ fib_table_route_path_fixup(prefix, &rpath[ii]);
+ }
+
if (FIB_NODE_INDEX_INVALID == fib_entry_index)
{
fib_entry_index = fib_entry_create(fib_index, prefix,
void
fib_table_entry_path_remove2 (u32 fib_index,
- const fib_prefix_t *prefix,
- fib_source_t source,
- const fib_route_path_t *rpath)
+ const fib_prefix_t *prefix,
+ fib_source_t source,
+ fib_route_path_t *rpath)
{
/*
* 1 is it present
*/
fib_node_index_t fib_entry_index;
fib_table_t *fib_table;
+ u32 ii;
fib_table = fib_table_get(fib_index, prefix->fp_proto);
fib_entry_index = fib_table_lookup_exact_match_i(fib_table, prefix);
+ for (ii = 0; ii < vec_len(rpath); ii++)
+ {
+ fib_table_route_path_fixup(prefix, &rpath[ii]);
+ }
+
if (FIB_NODE_INDEX_INVALID == fib_entry_index)
{
/*
const fib_prefix_t *prefix,
fib_source_t source,
fib_entry_flag_t flags,
- const fib_route_path_t *paths)
+ fib_route_path_t *paths)
{
fib_node_index_t fib_entry_index;
fib_table_t *fib_table;
+ u32 ii;
fib_table = fib_table_get(fib_index, prefix->fp_proto);
fib_entry_index = fib_table_lookup_exact_match_i(fib_table, prefix);
+ for (ii = 0; ii < vec_len(paths); ii++)
+ {
+ fib_table_route_path_fixup(prefix, &paths[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(((fib_route_path_t*)paths), // const cast
- fib_route_path_cmp_for_sort);
+ vec_sort_with_function(paths, fib_route_path_cmp_for_sort);
if (FIB_NODE_INDEX_INVALID == fib_entry_index)
{
u32 next_hop_sw_if_index,
u32 next_hop_fib_index,
u32 next_hop_weight,
- mpls_label_t next_hop_label,
+ mpls_label_t *next_hop_labels,
fib_route_path_flags_t path_flags)
{
fib_node_index_t fib_entry_index;
.frp_fib_index = next_hop_fib_index,
.frp_weight = next_hop_weight,
.frp_flags = path_flags,
- .frp_label = next_hop_label,
+ .frp_label_stack = next_hop_labels,
};
fib_route_path_t *paths = NULL;
{
fib_node_index_t fib_entry_index;
- fib_entry_index = fib_table_entry_special_dpo_add(fib_index, prefix,
- FIB_SOURCE_MPLS,
- FIB_ENTRY_FLAG_NONE,
- NULL);
+ fib_entry_index = fib_table_lookup_exact_match(fib_index, prefix);
+
+ if (FIB_NODE_INDEX_INVALID == fib_entry_index ||
+ !fib_entry_is_sourced(fib_entry_index, FIB_SOURCE_MPLS))
+ {
+ /*
+ * only source the prefix once. this allows the label change
+ * operation to work
+ */
+ fib_entry_index = fib_table_entry_special_dpo_add(fib_index, prefix,
+ FIB_SOURCE_MPLS,
+ FIB_ENTRY_FLAG_NONE,
+ NULL);
+ }
+
fib_entry_set_source_data(fib_entry_index, FIB_SOURCE_MPLS, &label);
return (fib_entry_index);