diff options
author | Avneesh Sachdev <avneesh@opensourcerouting.org> | 2012-04-09 00:25:15 -0700 |
---|---|---|
committer | Avneesh Sachdev <avneesh@opensourcerouting.org> | 2012-04-09 00:25:15 -0700 |
commit | 3cf6c2b4e43f44a977d218c96c26250654ae333e (patch) | |
tree | e017cde2015fbf3ef6c250327428d7c6152aa8f7 /isisd/isis_spf.c | |
parent | 01d7ff0a2166a422c56bd26f04fc22832a9e690b (diff) | |
parent | e96b312150d8e376c1ef463793d1929eca3618d5 (diff) |
Merge branch 'quagga' into google-bgp-multipath
Conflicts:
bgpd/bgp_route.c
Diffstat (limited to 'isisd/isis_spf.c')
-rw-r--r-- | isisd/isis_spf.c | 65 |
1 files changed, 37 insertions, 28 deletions
diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c index 5d7e9da4..5d0b161f 100644 --- a/isisd/isis_spf.c +++ b/isisd/isis_spf.c @@ -405,12 +405,13 @@ isis_spf_add2tent (struct isis_spftree *spftree, enum vertextype vtype, if (adj) listnode_add (vertex->Adj_N, adj); + #ifdef EXTREME_DEBUG zlog_debug ("ISIS-Spf: add to TENT %s %s depth %d dist %d", vtype2string (vertex->type), vid2string (vertex, buff), vertex->depth, vertex->d_N); #endif /* EXTREME_DEBUG */ - listnode_add (spftree->tents, vertex); + if (list_isempty (spftree->tents)) { listnode_add (spftree->tents, vertex); @@ -549,7 +550,8 @@ process_N (struct isis_spftree *spftree, enum vertextype vtype, void *id, */ static int isis_spf_process_lsp (struct isis_spftree *spftree, struct isis_lsp *lsp, - uint32_t cost, uint16_t depth, int family) + uint32_t cost, uint16_t depth, int family, + struct isis_adjacency *adj) { struct listnode *node, *fragnode = NULL; u_int16_t dist; @@ -563,9 +565,6 @@ isis_spf_process_lsp (struct isis_spftree *spftree, struct isis_lsp *lsp, struct ipv6_reachability *ip6reach; #endif /* HAVE_IPV6 */ - - if (!lsp->adj) - return ISIS_WARNING; if (lsp->tlv_data.nlpids == NULL || !speaks (lsp->tlv_data.nlpids, family)) return ISIS_OK; @@ -591,7 +590,7 @@ lspfragloop: vtype = LSP_PSEUDO_ID (is_neigh->neigh_id) ? VTYPE_PSEUDO_IS : VTYPE_NONPSEUDO_IS; process_N (spftree, vtype, (void *) is_neigh->neigh_id, dist, - depth + 1, lsp->adj, family); + depth + 1, adj, family); } } if (lsp->tlv_data.te_is_neighs) @@ -607,7 +606,7 @@ lspfragloop: vtype = LSP_PSEUDO_ID (te_is_neigh->neigh_id) ? VTYPE_PSEUDO_TE_IS : VTYPE_NONPSEUDO_TE_IS; process_N (spftree, vtype, (void *) te_is_neigh->neigh_id, dist, - depth + 1, lsp->adj, family); + depth + 1, adj, family); } } if (family == AF_INET && lsp->tlv_data.ipv4_int_reachs) @@ -621,7 +620,7 @@ lspfragloop: prefix.u.prefix4 = ipreach->prefix; prefix.prefixlen = ip_masklen (ipreach->mask); process_N (spftree, vtype, (void *) &prefix, dist, depth + 1, - lsp->adj, family); + adj, family); } } @@ -636,7 +635,7 @@ lspfragloop: prefix.u.prefix4 = ipreach->prefix; prefix.prefixlen = ip_masklen (ipreach->mask); process_N (spftree, vtype, (void *) &prefix, dist, depth + 1, - lsp->adj, family); + adj, family); } } if (family == AF_INET && lsp->tlv_data.te_ipv4_reachs) @@ -651,7 +650,7 @@ lspfragloop: te_ipv4_reach->control); prefix.prefixlen = (te_ipv4_reach->control & 0x3F); process_N (spftree, vtype, (void *) &prefix, dist, depth + 1, - lsp->adj, family); + adj, family); } } #ifdef HAVE_IPV6 @@ -668,7 +667,7 @@ lspfragloop: memcpy (&prefix.u.prefix6.s6_addr, ip6reach->prefix, PSIZE (ip6reach->prefix_len)); process_N (spftree, vtype, (void *) &prefix, dist, depth + 1, - lsp->adj, family); + adj, family); } } #endif /* HAVE_IPV6 */ @@ -691,7 +690,8 @@ lspfragloop: static int isis_spf_process_pseudo_lsp (struct isis_spftree *spftree, struct isis_lsp *lsp, uint16_t cost, - uint16_t depth, int family) + uint16_t depth, int family, + struct isis_adjacency *adj) { struct listnode *node, *fragnode = NULL; struct is_neigh *is_neigh; @@ -715,13 +715,13 @@ pseudofragloop: /* Two way connectivity */ if (!memcmp (is_neigh->neigh_id, isis->sysid, ISIS_SYS_ID_LEN)) continue; - if (isis_find_vertex - (spftree->tents, (void *) is_neigh->neigh_id, vtype) == NULL + if ((depth > 0 || isis_find_vertex + (spftree->tents, (void *) is_neigh->neigh_id, vtype) == NULL) && isis_find_vertex (spftree->paths, (void *) is_neigh->neigh_id, vtype) == NULL) { /* C.2.5 i) */ - isis_spf_add2tent (spftree, vtype, is_neigh->neigh_id, lsp->adj, + isis_spf_add2tent (spftree, vtype, is_neigh->neigh_id, adj, cost, depth, family); } } @@ -733,13 +733,13 @@ pseudofragloop: /* Two way connectivity */ if (!memcmp (te_is_neigh->neigh_id, isis->sysid, ISIS_SYS_ID_LEN)) continue; - if (isis_find_vertex - (spftree->tents, (void *) te_is_neigh->neigh_id, vtype) == NULL + if ((depth > 0 || isis_find_vertex + (spftree->tents, (void *) te_is_neigh->neigh_id, vtype) == NULL) && isis_find_vertex (spftree->paths, (void *) te_is_neigh->neigh_id, vtype) == NULL) { /* C.2.5 i) */ - isis_spf_add2tent (spftree, vtype, te_is_neigh->neigh_id, lsp->adj, + isis_spf_add2tent (spftree, vtype, te_is_neigh->neigh_id, adj, cost, depth, family); } } @@ -860,9 +860,6 @@ isis_spf_preload_tent (struct isis_spftree *spftree, lsp = lsp_search (lsp_id, area->lspdb[level - 1]); if (!lsp) zlog_warn ("No lsp found for IS adjacency"); - /* else { - isis_spf_process_lsp (spftree, lsp, vertex->d_N, 1, family); - } */ break; case ISIS_SYSTYPE_UNKNOWN: default: @@ -885,14 +882,14 @@ isis_spf_preload_tent (struct isis_spftree *spftree, { zlog_warn ("ISIS-Spf: No adjacency found for DR"); } - if (lsp == NULL || lsp->lsp_header->rem_lifetime == 0) + else if (lsp == NULL || lsp->lsp_header->rem_lifetime == 0) { zlog_warn ("ISIS-Spf: No lsp found for DR"); } else { isis_spf_process_pseudo_lsp (spftree, lsp, - circuit->te_metric[level - 1], 0, family); + circuit->te_metric[level - 1], 0, family, adj); } } @@ -982,6 +979,7 @@ isis_run_spf (struct isis_area *area, int level, int family) struct isis_spftree *spftree = NULL; u_char lsp_id[ISIS_SYS_ID_LEN + 2]; struct isis_lsp *lsp; + struct isis_adjacency *adj = NULL; struct route_table *table = NULL; struct route_node *rode; struct isis_route_info *rinfo; @@ -1032,16 +1030,28 @@ isis_run_spf (struct isis_area *area, int level, int family) while (listcount (spftree->tents) > 0) { + /* C.2.7 a) 1) */ node = listhead (spftree->tents); vertex = listgetdata (node); - /* Remove from tent list */ + + /* C.2.7 a) 2) */ list_delete_node (spftree->tents, node); + + /* C.2.7 a) 3) */ if (isis_find_vertex (spftree->paths, vertex->N.id, vertex->type)) continue; add_to_paths (spftree, vertex, area, level); + if (vertex->type == VTYPE_PSEUDO_IS || - vertex->type == VTYPE_NONPSEUDO_IS) + vertex->type == VTYPE_NONPSEUDO_IS || + vertex->type == VTYPE_PSEUDO_TE_IS || + vertex->type == VTYPE_NONPSEUDO_TE_IS ) { + if (listcount(vertex->Adj_N) == 0) { + continue; + } + adj = listgetdata(vertex->Adj_N->head); + memcpy (lsp_id, vertex->N.id, ISIS_SYS_ID_LEN + 1); LSP_FRAGMENT (lsp_id) = 0; lsp = lsp_search (lsp_id, area->lspdb[level - 1]); @@ -1050,13 +1060,12 @@ isis_run_spf (struct isis_area *area, int level, int family) if (LSP_PSEUDO_ID (lsp_id)) { isis_spf_process_pseudo_lsp (spftree, lsp, vertex->d_N, - vertex->depth, family); - + vertex->depth, family, adj); } else { isis_spf_process_lsp (spftree, lsp, vertex->d_N, - vertex->depth, family); + vertex->depth, family, adj); } } else |