mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-05-01 14:40:24 +00:00
isisd: make the SPF code more modular
The goal of modularizing the SPF code is to make it possible for isisd to run SPF in the behalf of other nodes in the network, which is going to be necessary later when implementing the R-LFA/TI-LFA solutions. On top of that, a modularized SPF opens the door for much needed unit testing. Summary of the changes: * Change the isis_spf_preload_tent() function to use the local LSP as an input (as per the ISO specification) instead of populating the TENT based on the list of local interfaces; * Introduce the "isis_spf_adj" structure to represent an SPF adjacency. SPF adjacencies are inferred from the LSPDB, different from normal adjacencies formed using IIH messages; * Introduce the F_SPFTREE_NO_ROUTES flag to control whether the SPT should create routes or not; * Introduce the F_SPFTREE_NO_ADJACENCIES flag to specify whether IS-IS adjacency information is available or not. When running SPF in the behalf of other nodes, or under the context of an unit test, no adjacency information will be present. * On isis_area_create(), move some code around so that the area's isis backpointer is set as early as possible. Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
This commit is contained in:
parent
675269d483
commit
7b36d36e0e
@ -221,7 +221,9 @@ struct fabricd *fabricd_new(struct isis_area *area)
|
||||
rv->area = area;
|
||||
rv->initial_sync_state = FABRICD_SYNC_PENDING;
|
||||
|
||||
rv->spftree = isis_spftree_new(area);
|
||||
rv->spftree = isis_spftree_new(area, &area->lspdb[IS_LEVEL_2 - 1],
|
||||
area->isis->sysid, ISIS_LEVEL2,
|
||||
SPFTREE_IPV4, F_SPFTREE_HOPCOUNT_METRIC);
|
||||
rv->neighbors = skiplist_new(0, neighbor_entry_list_cmp,
|
||||
neighbor_entry_del_void);
|
||||
rv->neighbors_neighbors = hash_create(neighbor_entry_hash_key,
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include "isis_pdu.h"
|
||||
#include "isis_lsp.h"
|
||||
#include "isis_spf.h"
|
||||
#include "isis_spf_private.h"
|
||||
#include "isis_route.h"
|
||||
#include "isis_zebra.h"
|
||||
|
||||
@ -165,13 +166,16 @@ static struct isis_route_info *isis_route_info_new(struct prefix *prefix,
|
||||
struct list *adjacencies)
|
||||
{
|
||||
struct isis_route_info *rinfo;
|
||||
struct isis_adjacency *adj;
|
||||
struct isis_vertex_adj *vadj;
|
||||
struct listnode *node;
|
||||
|
||||
rinfo = XCALLOC(MTYPE_ISIS_ROUTE_INFO, sizeof(struct isis_route_info));
|
||||
|
||||
rinfo->nexthops = list_new();
|
||||
for (ALL_LIST_ELEMENTS_RO(adjacencies, node, adj)) {
|
||||
for (ALL_LIST_ELEMENTS_RO(adjacencies, node, vadj)) {
|
||||
struct isis_spf_adj *sadj = vadj->sadj;
|
||||
struct isis_adjacency *adj = sadj->adj;
|
||||
|
||||
/* check for force resync this route */
|
||||
if (CHECK_FLAG(adj->circuit->flags,
|
||||
ISIS_CIRCUIT_FLAPPED_AFTER_SPF))
|
||||
|
837
isisd/isis_spf.c
837
isisd/isis_spf.c
File diff suppressed because it is too large
Load Diff
@ -26,7 +26,24 @@
|
||||
|
||||
struct isis_spftree;
|
||||
|
||||
struct isis_spftree *isis_spftree_new(struct isis_area *area);
|
||||
struct isis_spf_adj {
|
||||
uint8_t id[ISIS_SYS_ID_LEN + 1];
|
||||
struct isis_adjacency *adj;
|
||||
uint32_t metric;
|
||||
struct isis_ext_subtlvs *subtlvs;
|
||||
struct {
|
||||
uint8_t desig_is_id[ISIS_SYS_ID_LEN + 1];
|
||||
struct isis_lsp *lsp_pseudo;
|
||||
} lan;
|
||||
uint8_t flags;
|
||||
#define F_ISIS_SPF_ADJ_BROADCAST 0x01
|
||||
#define F_ISIS_SPF_ADJ_OLDMETRIC 0x02
|
||||
};
|
||||
|
||||
struct isis_spftree *isis_spftree_new(struct isis_area *area,
|
||||
struct lspdb_head *lspdb,
|
||||
const uint8_t *sysid, int level,
|
||||
enum spf_tree_id tree_id, uint8_t flags);
|
||||
void isis_spf_invalidate_routes(struct isis_spftree *tree);
|
||||
void isis_spf_verify_routes(struct isis_area *area,
|
||||
struct isis_spftree **trees);
|
||||
@ -40,6 +57,7 @@ int _isis_spf_schedule(struct isis_area *area, int level,
|
||||
const char *func, const char *file, int line);
|
||||
void isis_spf_init(void);
|
||||
void isis_spf_print(struct isis_spftree *spftree, struct vty *vty);
|
||||
void isis_run_spf(struct isis_spftree *spftree);
|
||||
struct isis_spftree *isis_run_hopcount_spf(struct isis_area *area,
|
||||
uint8_t *sysid,
|
||||
struct isis_spftree *spftree);
|
||||
|
@ -50,6 +50,11 @@ struct prefix_pair {
|
||||
struct prefix_ipv6 src;
|
||||
};
|
||||
|
||||
struct isis_vertex_adj {
|
||||
struct isis_spf_adj *sadj;
|
||||
struct mpls_label_stack *label_stack;
|
||||
};
|
||||
|
||||
/*
|
||||
* Triple <N, d(N), {Adj(N)}>
|
||||
*/
|
||||
@ -180,6 +185,10 @@ static void isis_vertex_del(struct isis_vertex *vertex)
|
||||
XFREE(MTYPE_ISIS_VERTEX, vertex);
|
||||
}
|
||||
|
||||
bool isis_vertex_adj_exists(const struct isis_spftree *spftree,
|
||||
const struct isis_vertex *vertex,
|
||||
const struct isis_spf_adj *sadj);
|
||||
|
||||
__attribute__((__unused__))
|
||||
static void isis_vertex_queue_clear(struct isis_vertex_queue *queue)
|
||||
{
|
||||
@ -297,18 +306,25 @@ struct isis_spftree {
|
||||
struct isis_vertex_queue paths; /* the SPT */
|
||||
struct isis_vertex_queue tents; /* TENT */
|
||||
struct route_table *route_table;
|
||||
struct lspdb_head *lspdb; /* link-state db */
|
||||
struct list *sadj_list;
|
||||
struct isis_area *area; /* back pointer to area */
|
||||
unsigned int runcount; /* number of runs since uptime */
|
||||
time_t last_run_timestamp; /* last run timestamp as wall time for display */
|
||||
time_t last_run_monotime; /* last run as monotime for scheduling */
|
||||
time_t last_run_duration; /* last run duration in msec */
|
||||
|
||||
uint8_t sysid[ISIS_SYS_ID_LEN];
|
||||
uint16_t mtid;
|
||||
int family;
|
||||
int level;
|
||||
enum spf_tree_id tree_id;
|
||||
bool hopcount_metric;
|
||||
uint8_t flags;
|
||||
};
|
||||
#define F_SPFTREE_HOPCOUNT_METRIC 0x01
|
||||
#define F_SPFTREE_NO_ROUTES 0x02
|
||||
#define F_SPFTREE_NO_ADJACENCIES 0x04
|
||||
|
||||
__attribute__((__unused__))
|
||||
static void isis_vertex_id_init(struct isis_vertex *vertex, const void *id,
|
||||
@ -347,8 +363,7 @@ static struct isis_lsp *lsp_for_vertex(struct isis_spftree *spftree,
|
||||
memcpy(lsp_id, vertex->N.id, ISIS_SYS_ID_LEN + 1);
|
||||
LSP_FRAGMENT(lsp_id) = 0;
|
||||
|
||||
struct lspdb_head *lspdb = &spftree->area->lspdb[spftree->level - 1];
|
||||
struct isis_lsp *lsp = lsp_search(lspdb, lsp_id);
|
||||
struct isis_lsp *lsp = lsp_search(spftree->lspdb, lsp_id);
|
||||
|
||||
if (lsp && lsp->hdr.rem_lifetime != 0)
|
||||
return lsp;
|
||||
|
@ -218,6 +218,27 @@ struct isis_area *isis_area_create(const char *area_tag, const char *vrf_name)
|
||||
struct vrf *vrf = NULL;
|
||||
area = XCALLOC(MTYPE_ISIS_AREA, sizeof(struct isis_area));
|
||||
|
||||
if (vrf_name) {
|
||||
vrf = vrf_lookup_by_name(vrf_name);
|
||||
if (vrf) {
|
||||
isis = isis_lookup_by_vrfid(vrf->vrf_id);
|
||||
if (isis == NULL) {
|
||||
isis = isis_new(vrf->vrf_id);
|
||||
isis_add(isis);
|
||||
}
|
||||
} else
|
||||
return NULL;
|
||||
} else {
|
||||
isis = isis_lookup_by_vrfid(VRF_DEFAULT);
|
||||
if (isis == NULL) {
|
||||
isis = isis_new(VRF_DEFAULT);
|
||||
isis_add(isis);
|
||||
}
|
||||
}
|
||||
|
||||
listnode_add(isis->area_list, area);
|
||||
area->isis = isis;
|
||||
|
||||
/*
|
||||
* Fabricd runs only as level-2.
|
||||
* For IS-IS, the default is level-1-2
|
||||
@ -297,27 +318,6 @@ struct isis_area *isis_area_create(const char *area_tag, const char *vrf_name)
|
||||
|
||||
area->area_tag = strdup(area_tag);
|
||||
|
||||
if (vrf_name) {
|
||||
vrf = vrf_lookup_by_name(vrf_name);
|
||||
if (vrf) {
|
||||
isis = isis_lookup_by_vrfid(vrf->vrf_id);
|
||||
if (isis == NULL) {
|
||||
isis = isis_new(vrf->vrf_id);
|
||||
isis_add(isis);
|
||||
}
|
||||
} else
|
||||
return NULL;
|
||||
} else {
|
||||
isis = isis_lookup_by_vrfid(VRF_DEFAULT);
|
||||
if (isis == NULL) {
|
||||
isis = isis_new(VRF_DEFAULT);
|
||||
isis_add(isis);
|
||||
}
|
||||
}
|
||||
|
||||
listnode_add(isis->area_list, area);
|
||||
area->isis = isis;
|
||||
|
||||
if (fabricd)
|
||||
area->fabricd = fabricd_new(area);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user