diff options
author | Damjan Marion <damarion@cisco.com> | 2016-12-19 23:05:39 +0100 |
---|---|---|
committer | Damjan Marion <damarion@cisco.com> | 2016-12-28 12:25:14 +0100 |
commit | 7cd468a3d7dee7d6c92f69a0bb7061ae208ec727 (patch) | |
tree | 5de62f8dbd3a752f5a676ca600e43d2652d1ff1a /vnet/vnet/fib/fib_table.c | |
parent | 696f1adec0df3b8f161862566dd9c86174302658 (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.c | 1104 |
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); -} |