aboutsummaryrefslogtreecommitdiffstats
path: root/vnet/vnet/fib/fib_table.c
diff options
context:
space:
mode:
authorDamjan Marion <damarion@cisco.com>2016-12-19 23:05:39 +0100
committerDamjan Marion <damarion@cisco.com>2016-12-28 12:25:14 +0100
commit7cd468a3d7dee7d6c92f69a0bb7061ae208ec727 (patch)
tree5de62f8dbd3a752f5a676ca600e43d2652d1ff1a /vnet/vnet/fib/fib_table.c
parent696f1adec0df3b8f161862566dd9c86174302658 (diff)
Reorganize source tree to use single autotools instance
Change-Id: I7b51f88292e057c6443b12224486f2d0c9f8ae23 Signed-off-by: Damjan Marion <damarion@cisco.com>
Diffstat (limited to 'vnet/vnet/fib/fib_table.c')
-rw-r--r--vnet/vnet/fib/fib_table.c1104
1 files changed, 0 insertions, 1104 deletions
diff --git a/vnet/vnet/fib/fib_table.c b/vnet/vnet/fib/fib_table.c
deleted file mode 100644
index 76db42d0ec7..00000000000
--- a/vnet/vnet/fib/fib_table.c
+++ /dev/null
@@ -1,1104 +0,0 @@
-/*
- * Copyright (c) 2016 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <vlib/vlib.h>
-#include <vnet/dpo/drop_dpo.h>
-
-#include <vnet/fib/fib_table.h>
-#include <vnet/fib/fib_entry_cover.h>
-#include <vnet/fib/fib_internal.h>
-#include <vnet/fib/ip4_fib.h>
-#include <vnet/fib/ip6_fib.h>
-#include <vnet/fib/mpls_fib.h>
-
-fib_table_t *
-fib_table_get (fib_node_index_t index,
- fib_protocol_t proto)
-{
- switch (proto)
- {
- case FIB_PROTOCOL_IP4:
- return (pool_elt_at_index(ip4_main.fibs, index));
- case FIB_PROTOCOL_IP6:
- return (pool_elt_at_index(ip6_main.fibs, index));
- case FIB_PROTOCOL_MPLS:
- return (pool_elt_at_index(mpls_main.fibs, index));
- }
- ASSERT(0);
- return (NULL);
-}
-
-static inline fib_node_index_t
-fib_table_lookup_i (fib_table_t *fib_table,
- const fib_prefix_t *prefix)
-{
- switch (prefix->fp_proto)
- {
- case FIB_PROTOCOL_IP4:
- return (ip4_fib_table_lookup(&fib_table->v4,
- &prefix->fp_addr.ip4,
- prefix->fp_len));
- case FIB_PROTOCOL_IP6:
- return (ip6_fib_table_lookup(fib_table->ft_index,
- &prefix->fp_addr.ip6,
- prefix->fp_len));
- case FIB_PROTOCOL_MPLS:
- return (mpls_fib_table_lookup(&fib_table->mpls,
- prefix->fp_label,
- prefix->fp_eos));
- }
- return (FIB_NODE_INDEX_INVALID);
-}
-
-fib_node_index_t
-fib_table_lookup (u32 fib_index,
- const fib_prefix_t *prefix)
-{
- return (fib_table_lookup_i(fib_table_get(fib_index, prefix->fp_proto), prefix));
-}
-
-static inline fib_node_index_t
-fib_table_lookup_exact_match_i (const fib_table_t *fib_table,
- const fib_prefix_t *prefix)
-{
- switch (prefix->fp_proto)
- {
- case FIB_PROTOCOL_IP4:
- return (ip4_fib_table_lookup_exact_match(&fib_table->v4,
- &prefix->fp_addr.ip4,
- prefix->fp_len));
- case FIB_PROTOCOL_IP6:
- return (ip6_fib_table_lookup_exact_match(fib_table->ft_index,
- &prefix->fp_addr.ip6,
- prefix->fp_len));
- case FIB_PROTOCOL_MPLS:
- return (mpls_fib_table_lookup(&fib_table->mpls,
- prefix->fp_label,
- prefix->fp_eos));
- }
- return (FIB_NODE_INDEX_INVALID);
-}
-
-fib_node_index_t
-fib_table_lookup_exact_match (u32 fib_index,
- const fib_prefix_t *prefix)
-{
- return (fib_table_lookup_exact_match_i(fib_table_get(fib_index,
- prefix->fp_proto),
- prefix));
-}
-
-static fib_node_index_t
-fib_table_get_less_specific_i (fib_table_t *fib_table,
- const fib_prefix_t *prefix)
-{
- fib_prefix_t pfx;
-
- pfx = *prefix;
-
- if (FIB_PROTOCOL_MPLS == pfx.fp_proto)
- {
- return (FIB_NODE_INDEX_INVALID);
- }
-
- /*
- * in the absence of a tree structure for the table that allows for an O(1)
- * parent get, a cheeky way to find the cover is to LPM for the prefix with
- * mask-1.
- * there should always be a cover, though it may be the default route. the
- * default route's cover is the default route.
- */
- if (pfx.fp_len != 0) {
- pfx.fp_len -= 1;
- }
-
- return (fib_table_lookup_i(fib_table, &pfx));
-}
-
-fib_node_index_t
-fib_table_get_less_specific (u32 fib_index,
- const fib_prefix_t *prefix)
-{
- return (fib_table_get_less_specific_i(fib_table_get(fib_index,
- prefix->fp_proto),
- prefix));
-}
-
-static void
-fib_table_entry_remove (fib_table_t *fib_table,
- const fib_prefix_t *prefix,
- fib_node_index_t fib_entry_index)
-{
- vlib_smp_unsafe_warning();
-
- fib_table->ft_total_route_counts--;
-
- switch (prefix->fp_proto)
- {
- case FIB_PROTOCOL_IP4:
- ip4_fib_table_entry_remove(&fib_table->v4,
- &prefix->fp_addr.ip4,
- prefix->fp_len);
- break;
- case FIB_PROTOCOL_IP6:
- ip6_fib_table_entry_remove(fib_table->ft_index,
- &prefix->fp_addr.ip6,
- prefix->fp_len);
- break;
- case FIB_PROTOCOL_MPLS:
- mpls_fib_table_entry_remove(&fib_table->mpls,
- prefix->fp_label,
- prefix->fp_eos);
- break;
- }
-
- fib_entry_unlock(fib_entry_index);
-}
-
-static void
-fib_table_post_insert_actions (fib_table_t *fib_table,
- const fib_prefix_t *prefix,
- fib_node_index_t fib_entry_index)
-{
- fib_node_index_t fib_entry_cover_index;
-
- /*
- * no cover relationships in the MPLS FIB
- */
- if (FIB_PROTOCOL_MPLS == prefix->fp_proto)
- return;
-
- /*
- * find and inform the covering entry that a new more specific
- * has been inserted beneath it
- */
- fib_entry_cover_index = fib_table_get_less_specific_i(fib_table, prefix);
- /*
- * the indicies are the same when the default route is first added
- */
- if (fib_entry_cover_index != fib_entry_index)
- {
- fib_entry_cover_change_notify(fib_entry_cover_index,
- fib_entry_index);
- }
-}
-
-static void
-fib_table_entry_insert (fib_table_t *fib_table,
- const fib_prefix_t *prefix,
- fib_node_index_t fib_entry_index)
-{
- vlib_smp_unsafe_warning();
-
- fib_entry_lock(fib_entry_index);
- fib_table->ft_total_route_counts++;
-
- switch (prefix->fp_proto)
- {
- case FIB_PROTOCOL_IP4:
- ip4_fib_table_entry_insert(&fib_table->v4,
- &prefix->fp_addr.ip4,
- prefix->fp_len,
- fib_entry_index);
- break;
- case FIB_PROTOCOL_IP6:
- ip6_fib_table_entry_insert(fib_table->ft_index,
- &prefix->fp_addr.ip6,
- prefix->fp_len,
- fib_entry_index);
- break;
- case FIB_PROTOCOL_MPLS:
- mpls_fib_table_entry_insert(&fib_table->mpls,
- prefix->fp_label,
- prefix->fp_eos,
- fib_entry_index);
- break;
- }
-
- fib_table_post_insert_actions(fib_table, prefix, fib_entry_index);
-}
-
-void
-fib_table_fwding_dpo_update (u32 fib_index,
- const fib_prefix_t *prefix,
- const dpo_id_t *dpo)
-{
- vlib_smp_unsafe_warning();
-
- switch (prefix->fp_proto)
- {
- case FIB_PROTOCOL_IP4:
- return (ip4_fib_table_fwding_dpo_update(ip4_fib_get(fib_index),
- &prefix->fp_addr.ip4,
- prefix->fp_len,
- dpo));
- case FIB_PROTOCOL_IP6:
- return (ip6_fib_table_fwding_dpo_update(fib_index,
- &prefix->fp_addr.ip6,
- prefix->fp_len,
- dpo));
- case FIB_PROTOCOL_MPLS:
- return (mpls_fib_forwarding_table_update(mpls_fib_get(fib_index),
- prefix->fp_label,
- prefix->fp_eos,
- dpo));
- }
-}
-
-void
-fib_table_fwding_dpo_remove (u32 fib_index,
- const fib_prefix_t *prefix,
- const dpo_id_t *dpo)
-{
- vlib_smp_unsafe_warning();
-
- switch (prefix->fp_proto)
- {
- case FIB_PROTOCOL_IP4:
- return (ip4_fib_table_fwding_dpo_remove(ip4_fib_get(fib_index),
- &prefix->fp_addr.ip4,
- prefix->fp_len,
- dpo));
- case FIB_PROTOCOL_IP6:
- return (ip6_fib_table_fwding_dpo_remove(fib_index,
- &prefix->fp_addr.ip6,
- prefix->fp_len,
- dpo));
- case FIB_PROTOCOL_MPLS:
- return (mpls_fib_forwarding_table_reset(mpls_fib_get(fib_index),
- prefix->fp_label,
- prefix->fp_eos));
- }
-}
-
-
-fib_node_index_t
-fib_table_entry_special_dpo_add (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);
- 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_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,
- fib_source_t source,
- fib_entry_flag_t flags,
- adj_index_t adj_index)
-{
- fib_node_index_t fib_entry_index;
- dpo_id_t tmp_dpo = DPO_INVALID;
-
- if (ADJ_INDEX_INVALID != adj_index)
- {
- dpo_set(&tmp_dpo,
- DPO_ADJACENCY,
- FIB_PROTOCOL_MAX,
- adj_index);
- }
- else
- {
- dpo_copy(&tmp_dpo, drop_dpo_get(fib_proto_to_dpo(prefix->fp_proto)));
- }
-
- fib_entry_index = fib_table_entry_special_dpo_add(fib_index, prefix, source,
- flags, &tmp_dpo);
-
- dpo_unlock(&tmp_dpo);
-
- return (fib_entry_index);
-}
-
-void
-fib_table_entry_special_remove (u32 fib_index,
- const fib_prefix_t *prefix,
- fib_source_t source)
-{
- /*
- * 1 is it present
- * yes => remove source
- * 2 - is it still sourced?
- * no => cover walk
- */
- 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)
- {
- /*
- * removing an etry that does not exist. i'll allow it.
- */
- }
- else
- {
- fib_entry_src_flag_t src_flag;
- int was_sourced;
-
- /*
- * don't nobody go nowhere
- */
- fib_entry_lock(fib_entry_index);
- was_sourced = fib_entry_is_sourced(fib_entry_index, source);
-
- src_flag = fib_entry_special_remove(fib_entry_index, source);
-
- if (!(FIB_ENTRY_SRC_FLAG_ADDED & src_flag))
- {
- /*
- * last source gone. remove from the table
- */
- fib_table_entry_remove(fib_table, prefix, fib_entry_index);
-
- /*
- * now the entry is no longer in the table, we can
- * inform the entries that it covers to re-calculate their cover
- */
- fib_entry_cover_change_notify(fib_entry_index,
- FIB_NODE_INDEX_INVALID);
- }
- /*
- * else
- * still has sources, leave it be.
- */
- if (was_sourced != fib_entry_is_sourced(fib_entry_index, source))
- {
- fib_table->ft_src_route_counts[source]--;
- }
-
- fib_entry_unlock(fib_entry_index);
- }
-}
-
-/**
- * fib_table_route_path_fixup
- *
- * Convert attached hosts to attached next-hops.
- *
- * This special case is required because an attached path will link to a
- * glean, and the FIB entry will have the interface or API/CLI source. When
- * the ARP/ND process is completes then that source (which will provide a
- * complete adjacency) will be lower priority and so the FIB entry will
- * remain linked to a glean and traffic will never reach the hosts. For
- * an ATTAHCED_HOST path we can link the path directly to the [incomplete]
- * adjacency.
- */
-static void
-fib_table_route_path_fixup (const fib_prefix_t *prefix,
- fib_route_path_t *path)
-{
- if (fib_prefix_is_host(prefix) &&
- ip46_address_is_zero(&path->frp_addr) &&
- path->frp_sw_if_index != ~0)
- {
- path->frp_addr = prefix->fp_addr;
- }
-}
-
-fib_node_index_t
-fib_table_entry_path_add (u32 fib_index,
- const fib_prefix_t *prefix,
- fib_source_t source,
- fib_entry_flag_t flags,
- fib_protocol_t next_hop_proto,
- const ip46_address_t *next_hop,
- u32 next_hop_sw_if_index,
- u32 next_hop_fib_index,
- u32 next_hop_weight,
- mpls_label_t *next_hop_labels,
- fib_route_path_flags_t path_flags)
-{
- fib_route_path_t path = {
- .frp_proto = next_hop_proto,
- .frp_addr = (NULL == next_hop? zero_addr : *next_hop),
- .frp_sw_if_index = next_hop_sw_if_index,
- .frp_fib_index = next_hop_fib_index,
- .frp_weight = next_hop_weight,
- .frp_flags = path_flags,
- .frp_label_stack = next_hop_labels,
- };
- fib_node_index_t fib_entry_index;
- fib_route_path_t *paths = NULL;
-
- vec_add1(paths, path);
-
- fib_entry_index = fib_table_entry_path_add2(fib_index, prefix,
- source, flags, paths);
-
- vec_free(paths);
- return (fib_entry_index);
-}
-
-fib_node_index_t
-fib_table_entry_path_add2 (u32 fib_index,
- const fib_prefix_t *prefix,
- fib_source_t source,
- fib_entry_flag_t flags,
- 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,
- source, flags,
- rpath);
-
- 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);
- fib_entry_path_add(fib_entry_index, source, flags, rpath);;
-
- if (was_sourced != fib_entry_is_sourced(fib_entry_index, source))
- {
- fib_table->ft_src_route_counts[source]++;
- }
- }
-
- return (fib_entry_index);
-}
-
-void
-fib_table_entry_path_remove2 (u32 fib_index,
- const fib_prefix_t *prefix,
- fib_source_t source,
- fib_route_path_t *rpath)
-{
- /*
- * 1 is it present
- * yes => remove source
- * 2 - is it still sourced?
- * no => cover walk
- */
- 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)
- {
- /*
- * removing an etry that does not exist. i'll allow it.
- */
- }
- else
- {
- fib_entry_src_flag_t src_flag;
- int was_sourced;
-
- /*
- * don't nobody go nowhere
- */
- fib_entry_lock(fib_entry_index);
- was_sourced = fib_entry_is_sourced(fib_entry_index, source);
-
- src_flag = fib_entry_path_remove(fib_entry_index, source, rpath);
-
- if (!(FIB_ENTRY_SRC_FLAG_ADDED & src_flag))
- {
- /*
- * last source gone. remove from the table
- */
- fib_table_entry_remove(fib_table, prefix, fib_entry_index);
-
- /*
- * now the entry is no longer in the table, we can
- * inform the entries that it covers to re-calculate their cover
- */
- fib_entry_cover_change_notify(fib_entry_index,
- FIB_NODE_INDEX_INVALID);
- }
- /*
- * else
- * still has sources, leave it be.
- */
- if (was_sourced != fib_entry_is_sourced(fib_entry_index, source))
- {
- fib_table->ft_src_route_counts[source]--;
- }
-
- fib_entry_unlock(fib_entry_index);
- }
-}
-
-void
-fib_table_entry_path_remove (u32 fib_index,
- const fib_prefix_t *prefix,
- fib_source_t source,
- fib_protocol_t next_hop_proto,
- const ip46_address_t *next_hop,
- u32 next_hop_sw_if_index,
- u32 next_hop_fib_index,
- u32 next_hop_weight,
- fib_route_path_flags_t path_flags)
-{
- /*
- * 1 is it present
- * yes => remove source
- * 2 - is it still sourced?
- * no => cover walk
- */
- fib_route_path_t path = {
- .frp_proto = next_hop_proto,
- .frp_addr = (NULL == next_hop? zero_addr : *next_hop),
- .frp_sw_if_index = next_hop_sw_if_index,
- .frp_fib_index = next_hop_fib_index,
- .frp_weight = next_hop_weight,
- .frp_flags = path_flags,
- };
- fib_route_path_t *paths = NULL;
-
- fib_table_route_path_fixup(prefix, &path);
- vec_add1(paths, path);
-
- fib_table_entry_path_remove2(fib_index, prefix, source, paths);
-
- 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,
- fib_source_t source,
- fib_entry_flag_t flags,
- 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(paths, fib_route_path_cmp_for_sort);
-
- if (FIB_NODE_INDEX_INVALID == fib_entry_index)
- {
- fib_entry_index = fib_entry_create(fib_index, prefix,
- source, flags,
- paths);
-
- 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);
- fib_entry_update(fib_entry_index, source, flags, paths);
-
- 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_update_one_path (u32 fib_index,
- const fib_prefix_t *prefix,
- fib_source_t source,
- fib_entry_flag_t flags,
- fib_protocol_t next_hop_proto,
- const ip46_address_t *next_hop,
- u32 next_hop_sw_if_index,
- u32 next_hop_fib_index,
- u32 next_hop_weight,
- mpls_label_t *next_hop_labels,
- fib_route_path_flags_t path_flags)
-{
- fib_node_index_t fib_entry_index;
- fib_route_path_t path = {
- .frp_proto = next_hop_proto,
- .frp_addr = (NULL == next_hop? zero_addr : *next_hop),
- .frp_sw_if_index = next_hop_sw_if_index,
- .frp_fib_index = next_hop_fib_index,
- .frp_weight = next_hop_weight,
- .frp_flags = path_flags,
- .frp_label_stack = next_hop_labels,
- };
- fib_route_path_t *paths = NULL;
-
- fib_table_route_path_fixup(prefix, &path);
- vec_add1(paths, path);
-
- fib_entry_index =
- fib_table_entry_update(fib_index, prefix, source, flags, paths);
-
- vec_free(paths);
-
- return (fib_entry_index);
-}
-
-static void
-fib_table_entry_delete_i (u32 fib_index,
- fib_node_index_t fib_entry_index,
- const fib_prefix_t *prefix,
- fib_source_t source)
-{
- fib_entry_src_flag_t src_flag;
- fib_table_t *fib_table;
- int was_sourced;
-
- fib_table = fib_table_get(fib_index, prefix->fp_proto);
- was_sourced = fib_entry_is_sourced(fib_entry_index, source);
-
- /*
- * don't nobody go nowhere
- */
- fib_entry_lock(fib_entry_index);
-
- src_flag = fib_entry_delete(fib_entry_index, source);
-
- if (!(FIB_ENTRY_SRC_FLAG_ADDED & src_flag))
- {
- /*
- * last source gone. remove from the table
- */
- fib_table_entry_remove(fib_table, prefix, fib_entry_index);
-
- /*
- * now the entry is no longer in the table, we can
- * inform the entries that it covers to re-calculate their cover
- */
- fib_entry_cover_change_notify(fib_entry_index,
- FIB_NODE_INDEX_INVALID);
- }
- /*
- * else
- * still has sources, leave it be.
- */
- if (was_sourced != fib_entry_is_sourced(fib_entry_index, source))
- {
- fib_table->ft_src_route_counts[source]--;
- }
-
- fib_entry_unlock(fib_entry_index);
-}
-
-void
-fib_table_entry_delete (u32 fib_index,
- const fib_prefix_t *prefix,
- fib_source_t source)
-{
- fib_node_index_t fib_entry_index;
-
- fib_entry_index = fib_table_lookup_exact_match(fib_index, prefix);
-
- if (FIB_NODE_INDEX_INVALID == fib_entry_index)
- {
- /*
- * removing an etry that does not exist.
- * i'll allow it, but i won't like it.
- */
- clib_warning("%U not in FIB", format_fib_prefix, prefix);
- }
- else
- {
- fib_table_entry_delete_i(fib_index, fib_entry_index, prefix, source);
- }
-}
-
-void
-fib_table_entry_delete_index (fib_node_index_t fib_entry_index,
- fib_source_t source)
-{
- fib_prefix_t prefix;
-
- fib_entry_get_prefix(fib_entry_index, &prefix);
-
- fib_table_entry_delete_i(fib_entry_get_fib_index(fib_entry_index),
- fib_entry_index, &prefix, source);
-}
-
-fib_node_index_t
-fib_table_entry_local_label_add (u32 fib_index,
- const fib_prefix_t *prefix,
- mpls_label_t label)
-{
- fib_node_index_t fib_entry_index;
-
- 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);
-}
-
-void
-fib_table_entry_local_label_remove (u32 fib_index,
- const fib_prefix_t *prefix,
- mpls_label_t label)
-{
- fib_node_index_t fib_entry_index;
- const void *data;
- mpls_label_t pl;
-
- fib_entry_index = fib_table_lookup_exact_match(fib_index, prefix);
-
- if (FIB_NODE_INDEX_INVALID == fib_entry_index)
- return;
-
- data = fib_entry_get_source_data(fib_entry_index, FIB_SOURCE_MPLS);
-
- if (NULL == data)
- return;
-
- pl = *(mpls_label_t*)data;
-
- if (pl != label)
- return;
-
- pl = MPLS_LABEL_INVALID;
-
- fib_entry_set_source_data(fib_entry_index, FIB_SOURCE_MPLS, &pl);
- fib_table_entry_special_remove(fib_index,
- prefix,
- FIB_SOURCE_MPLS);
-}
-
-u32
-fib_table_get_index_for_sw_if_index (fib_protocol_t proto,
- u32 sw_if_index)
-{
- switch (proto)
- {
- case FIB_PROTOCOL_IP4:
- return (ip4_fib_table_get_index_for_sw_if_index(sw_if_index));
- case FIB_PROTOCOL_IP6:
- return (ip6_fib_table_get_index_for_sw_if_index(sw_if_index));
- case FIB_PROTOCOL_MPLS:
- return (mpls_fib_table_get_index_for_sw_if_index(sw_if_index));
- }
- return (~0);
-}
-
-flow_hash_config_t
-fib_table_get_flow_hash_config (u32 fib_index,
- fib_protocol_t proto)
-{
- switch (proto)
- {
- case FIB_PROTOCOL_IP4:
- return (ip4_fib_table_get_flow_hash_config(fib_index));
- case FIB_PROTOCOL_IP6:
- return (ip6_fib_table_get_flow_hash_config(fib_index));
- case FIB_PROTOCOL_MPLS:
- return (mpls_fib_table_get_flow_hash_config(fib_index));
- }
- return (0);
-}
-
-
-u32
-fib_table_get_table_id_for_sw_if_index (fib_protocol_t proto,
- u32 sw_if_index)
-{
- fib_table_t *fib_table;
-
- fib_table = fib_table_get(fib_table_get_index_for_sw_if_index(
- proto, sw_if_index),
- proto);
-
- return ((NULL != fib_table ? fib_table->ft_table_id : ~0));
-}
-
-u32
-fib_table_find (fib_protocol_t proto,
- u32 table_id)
-{
- switch (proto)
- {
- case FIB_PROTOCOL_IP4:
- return (ip4_fib_index_from_table_id(table_id));
- case FIB_PROTOCOL_IP6:
- return (ip6_fib_index_from_table_id(table_id));
- case FIB_PROTOCOL_MPLS:
- return (mpls_fib_index_from_table_id(table_id));
- }
- return (~0);
-}
-
-u32
-fib_table_find_or_create_and_lock (fib_protocol_t proto,
- u32 table_id)
-{
- fib_table_t *fib_table;
- fib_node_index_t fi;
-
- switch (proto)
- {
- case FIB_PROTOCOL_IP4:
- fi = ip4_fib_table_find_or_create_and_lock(table_id);
- break;
- case FIB_PROTOCOL_IP6:
- fi = ip6_fib_table_find_or_create_and_lock(table_id);
- break;
- case FIB_PROTOCOL_MPLS:
- fi = mpls_fib_table_find_or_create_and_lock(table_id);
- break;
- default:
- return (~0);
- }
-
- fib_table = fib_table_get(fi, proto);
-
- fib_table->ft_desc = format(NULL, "%U-VRF:%d",
- format_fib_protocol, proto,
- table_id);
-
- return (fi);
-}
-
-u32
-fib_table_create_and_lock (fib_protocol_t proto,
- const char *const fmt,
- ...)
-{
- fib_table_t *fib_table;
- fib_node_index_t fi;
- va_list ap;
-
- va_start(ap, fmt);
-
- switch (proto)
- {
- case FIB_PROTOCOL_IP4:
- fi = ip4_fib_table_create_and_lock();
- break;
- case FIB_PROTOCOL_IP6:
- fi = ip6_fib_table_create_and_lock();
- break;
- case FIB_PROTOCOL_MPLS:
- fi = mpls_fib_table_create_and_lock();
- break;
- default:
- return (~0);
- }
-
- fib_table = fib_table_get(fi, proto);
-
- fib_table->ft_desc = va_format(fib_table->ft_desc, fmt, &ap);
-
- va_end(ap);
- return (fi);
-}
-
-static void
-fib_table_destroy (fib_table_t *fib_table)
-{
- vec_free(fib_table->ft_desc);
-
- switch (fib_table->ft_proto)
- {
- case FIB_PROTOCOL_IP4:
- ip4_fib_table_destroy(&fib_table->v4);
- break;
- case FIB_PROTOCOL_IP6:
- ip6_fib_table_destroy(fib_table->ft_index);
- break;
- case FIB_PROTOCOL_MPLS:
- mpls_fib_table_destroy(&fib_table->mpls);
- break;
- }
-}
-
-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--;
-
- if (0 == fib_table->ft_locks)
- {
- fib_table_destroy(fib_table);
- }
-}
-void
-fib_table_lock (u32 fib_index,
- fib_protocol_t proto)
-{
- fib_table_t *fib_table;
-
- fib_table = fib_table_get(fib_index, proto);
- fib_table->ft_locks++;
-}
-
-u32
-fib_table_get_num_entries (u32 fib_index,
- fib_protocol_t proto,
- fib_source_t source)
-{
- fib_table_t *fib_table;
-
- fib_table = fib_table_get(fib_index, proto);
-
- return (fib_table->ft_src_route_counts[source]);
-}
-
-u8*
-format_fib_table_name (u8* s, va_list ap)
-{
- fib_node_index_t fib_index = va_arg(ap, fib_node_index_t);
- fib_protocol_t proto = va_arg(ap, int); // int promotion
- fib_table_t *fib_table;
-
- fib_table = fib_table_get(fib_index, proto);
-
- s = format(s, "%v", fib_table->ft_desc);
-
- return (s);
-}
-
-void
-fib_table_flush (u32 fib_index,
- fib_protocol_t proto,
- fib_source_t source)
-{
- // FIXME
- ASSERT(0);
-}