mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-04-28 11:50:21 +00:00
isisd: merge algorithm tables
Create a temporary "merge" route table that contains the routing information from all algorithms and install the merge route table into the FIB. Signed-off-by: Hiroki Shirokura <hiroki.shirokura@linecorp.com> Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
This commit is contained in:
parent
860b75b40e
commit
80ef2e89ee
@ -36,6 +36,7 @@
|
||||
#include "isis_spf_private.h"
|
||||
#include "isis_route.h"
|
||||
#include "isis_zebra.h"
|
||||
#include "isis_flex_algo.h"
|
||||
|
||||
DEFINE_MTYPE_STATIC(ISISD, ISIS_NEXTHOP, "ISIS nexthop");
|
||||
DEFINE_MTYPE_STATIC(ISISD, ISIS_ROUTE_INFO, "ISIS route info");
|
||||
@ -725,7 +726,7 @@ static void _isis_route_verify_table(struct isis_area *area,
|
||||
if (CHECK_FLAG(rinfo->flag, ISIS_ROUTE_FLAG_ACTIVE))
|
||||
continue;
|
||||
|
||||
/* Area is either L1 or L2 => we use level route tables
|
||||
/* In case the verify is not for a merge, we use a single table
|
||||
* directly for
|
||||
* validating => no problems with deleting routes. */
|
||||
if (!tables) {
|
||||
@ -733,13 +734,12 @@ static void _isis_route_verify_table(struct isis_area *area,
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If area is L1L2, we work with merge table and
|
||||
* therefore must
|
||||
* delete node from level tables as well before deleting
|
||||
/* If we work on a merged table,
|
||||
* therefore we must
|
||||
* delete node from each table as well before deleting
|
||||
* route info. */
|
||||
for (int level = ISIS_LEVEL1; level <= ISIS_LEVEL2; level++) {
|
||||
drnode = srcdest_rnode_lookup(tables[level - 1],
|
||||
dst_p, src_p);
|
||||
for (int i = 0; tables[i]; i++) {
|
||||
drnode = srcdest_rnode_lookup(tables[i], dst_p, src_p);
|
||||
if (!drnode)
|
||||
continue;
|
||||
|
||||
@ -756,10 +756,36 @@ static void _isis_route_verify_table(struct isis_area *area,
|
||||
}
|
||||
}
|
||||
|
||||
static void _isis_route_verify_merge(struct isis_area *area,
|
||||
struct route_table **tables,
|
||||
struct route_table **tables_backup,
|
||||
int tree);
|
||||
|
||||
void isis_route_verify_table(struct isis_area *area, struct route_table *table,
|
||||
struct route_table *table_backup)
|
||||
struct route_table *table_backup, int tree)
|
||||
{
|
||||
_isis_route_verify_table(area, table, table_backup, NULL);
|
||||
struct route_table *tables[SR_ALGORITHM_COUNT] = {table};
|
||||
struct route_table *tables_backup[SR_ALGORITHM_COUNT] = {table_backup};
|
||||
#ifndef FABRICD
|
||||
int tables_next = 1;
|
||||
int level = area->is_type == IS_LEVEL_1 ? ISIS_LEVEL1 : ISIS_LEVEL2;
|
||||
struct listnode *node;
|
||||
struct flex_algo *fa;
|
||||
struct isis_flex_algo_data *data;
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO(area->flex_algos->flex_algos, node, fa)) {
|
||||
data = fa->data;
|
||||
tables[tables_next] =
|
||||
data->spftree[tree][level - 1]->route_table;
|
||||
tables_backup[tables_next] =
|
||||
data->spftree[tree][level - 1]->route_table_backup;
|
||||
_isis_route_verify_table(area, tables[tables_next],
|
||||
tables_backup[tables_next], NULL);
|
||||
tables_next++;
|
||||
}
|
||||
#endif /* ifndef FABRICD */
|
||||
|
||||
_isis_route_verify_merge(area, tables, tables_backup, tree);
|
||||
}
|
||||
|
||||
/* Function to validate route tables for L1L2 areas. In this case we can't use
|
||||
@ -776,20 +802,27 @@ void isis_route_verify_merge(struct isis_area *area,
|
||||
struct route_table *level1_table,
|
||||
struct route_table *level1_table_backup,
|
||||
struct route_table *level2_table,
|
||||
struct route_table *level2_table_backup)
|
||||
struct route_table *level2_table_backup, int tree)
|
||||
{
|
||||
struct route_table *tables[] = {level1_table, level2_table};
|
||||
struct route_table *tables[] = {level1_table, level2_table, NULL};
|
||||
struct route_table *tables_backup[] = {level1_table_backup,
|
||||
level2_table_backup};
|
||||
level2_table_backup, NULL};
|
||||
_isis_route_verify_merge(area, tables, tables_backup, tree);
|
||||
}
|
||||
|
||||
static void _isis_route_verify_merge(struct isis_area *area,
|
||||
struct route_table **tables,
|
||||
struct route_table **tables_backup,
|
||||
int tree)
|
||||
{
|
||||
struct route_table *merge;
|
||||
struct route_node *rnode, *mrnode;
|
||||
|
||||
merge = srcdest_table_init();
|
||||
|
||||
for (int level = ISIS_LEVEL1; level <= ISIS_LEVEL2; level++) {
|
||||
uint8_t algorithm =
|
||||
isis_route_table_algorithm(tables[level - 1]);
|
||||
for (rnode = route_top(tables[level - 1]); rnode;
|
||||
for (int i = 0; tables[i]; i++) {
|
||||
uint8_t algorithm = isis_route_table_algorithm(tables[i]);
|
||||
for (rnode = route_top(tables[i]); rnode;
|
||||
rnode = srcdest_route_next(rnode)) {
|
||||
struct isis_route_info *rinfo = rnode->info;
|
||||
struct route_node *rnode_bck;
|
||||
@ -805,8 +838,8 @@ void isis_route_verify_merge(struct isis_area *area,
|
||||
(const struct prefix **)&src_p);
|
||||
|
||||
/* Link primary route to backup route. */
|
||||
rnode_bck = srcdest_rnode_lookup(
|
||||
tables_backup[level - 1], prefix, src_p);
|
||||
rnode_bck = srcdest_rnode_lookup(tables_backup[i],
|
||||
prefix, src_p);
|
||||
if (rnode_bck) {
|
||||
rinfo->backup = rnode_bck->info;
|
||||
rinfo->sr_algo[algorithm].nexthops_backup =
|
||||
|
@ -60,14 +60,14 @@ void isis_route_delete(struct isis_area *area, struct route_node *rode,
|
||||
/* Walk the given table and install new routes to zebra and remove old ones.
|
||||
* route status is tracked using ISIS_ROUTE_FLAG_ACTIVE */
|
||||
void isis_route_verify_table(struct isis_area *area, struct route_table *table,
|
||||
struct route_table *table_backup);
|
||||
struct route_table *table_backup, int tree);
|
||||
|
||||
/* Same as isis_route_verify_table, but merge L1 and L2 routes before */
|
||||
void isis_route_verify_merge(struct isis_area *area,
|
||||
struct route_table *level1_table,
|
||||
struct route_table *level1_table_backup,
|
||||
struct route_table *level2_table,
|
||||
struct route_table *level2_table_backup);
|
||||
struct route_table *level2_table_backup, int tree);
|
||||
|
||||
/* Unset ISIS_ROUTE_FLAG_ACTIVE on all routes. Used before running spf. */
|
||||
void isis_route_invalidate_table(struct isis_area *area,
|
||||
|
@ -1933,19 +1933,20 @@ static void isis_run_spf_with_protection(struct isis_area *area,
|
||||
isis_spf_run_lfa(area, spftree);
|
||||
}
|
||||
|
||||
void isis_spf_verify_routes(struct isis_area *area, struct isis_spftree **trees)
|
||||
void isis_spf_verify_routes(struct isis_area *area, struct isis_spftree **trees,
|
||||
int tree)
|
||||
{
|
||||
if (area->is_type == IS_LEVEL_1) {
|
||||
isis_route_verify_table(area, trees[0]->route_table,
|
||||
trees[0]->route_table_backup);
|
||||
trees[0]->route_table_backup, tree);
|
||||
} else if (area->is_type == IS_LEVEL_2) {
|
||||
isis_route_verify_table(area, trees[1]->route_table,
|
||||
trees[1]->route_table_backup);
|
||||
trees[1]->route_table_backup, tree);
|
||||
} else {
|
||||
isis_route_verify_merge(area, trees[0]->route_table,
|
||||
trees[0]->route_table_backup,
|
||||
trees[1]->route_table,
|
||||
trees[1]->route_table_backup);
|
||||
trees[1]->route_table_backup, tree);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -44,8 +44,8 @@ isis_spftree_new(struct isis_area *area, struct lspdb_head *lspdb,
|
||||
struct isis_vertex *isis_spf_prefix_sid_lookup(struct isis_spftree *spftree,
|
||||
struct isis_prefix_sid *psid);
|
||||
void isis_spf_invalidate_routes(struct isis_spftree *tree);
|
||||
void isis_spf_verify_routes(struct isis_area *area,
|
||||
struct isis_spftree **trees);
|
||||
void isis_spf_verify_routes(struct isis_area *area, struct isis_spftree **trees,
|
||||
int tree);
|
||||
void isis_spf_switchover_routes(struct isis_area *area,
|
||||
struct isis_spftree **trees, int family,
|
||||
union g_addr *nexthop_ip, ifindex_t ifindex,
|
||||
|
@ -3097,7 +3097,7 @@ void isis_area_invalidate_routes(struct isis_area *area, int levels)
|
||||
void isis_area_verify_routes(struct isis_area *area)
|
||||
{
|
||||
for (int tree = SPFTREE_IPV4; tree < SPFTREE_COUNT; tree++)
|
||||
isis_spf_verify_routes(area, area->spftree[tree]);
|
||||
isis_spf_verify_routes(area, area->spftree[tree], tree);
|
||||
}
|
||||
|
||||
void isis_area_switchover_routes(struct isis_area *area, int family,
|
||||
|
Loading…
Reference in New Issue
Block a user