summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--isisd/isis_lsp.c40
-rw-r--r--isisd/isis_route.c8
-rw-r--r--isisd/isis_spf.c32
3 files changed, 41 insertions, 39 deletions
diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c
index 8e916d8fe0..33c52804e4 100644
--- a/isisd/isis_lsp.c
+++ b/isisd/isis_lsp.c
@@ -447,6 +447,19 @@ static void lsp_update_data(struct isis_lsp *lsp, struct isis_lsp_hdr *hdr,
return;
}
+static void lsp_link_fragment(struct isis_lsp *lsp, struct isis_lsp *lsp0)
+{
+ if (!LSP_FRAGMENT(lsp->hdr.lsp_id)) {
+ /* zero lsp -> create list to store fragments */
+ lsp->lspu.frags = list_new();
+ } else {
+ /* fragment -> set backpointer and add to zero lsps list */
+ assert(lsp0);
+ lsp->lspu.zero_lsp = lsp0;
+ listnode_add(lsp0->lspu.frags, lsp);
+ }
+}
+
void lsp_update(struct isis_lsp *lsp, struct isis_lsp_hdr *hdr,
struct isis_tlvs *tlvs, struct stream *stream,
struct isis_area *area, int level, bool confusion)
@@ -476,21 +489,19 @@ void lsp_update(struct isis_lsp *lsp, struct isis_lsp_hdr *hdr,
put_lsp_hdr(lsp, NULL, true);
}
- /* insert the lsp back into the database */
- lsp_insert(lsp, area->lspdb[level - 1]);
-}
+ if (LSP_FRAGMENT(lsp->hdr.lsp_id) && !lsp->lspu.zero_lsp) {
+ uint8_t lspid[ISIS_SYS_ID_LEN + 2];
+ struct isis_lsp *lsp0;
-static void lsp_link_fragment(struct isis_lsp *lsp, struct isis_lsp *lsp0)
-{
- if (!LSP_FRAGMENT(lsp->hdr.lsp_id)) {
- /* zero lsp -> create list to store fragments */
- lsp->lspu.frags = list_new();
- } else {
- /* fragment -> set backpointer and add to zero lsps list */
- assert(lsp0);
- lsp->lspu.zero_lsp = lsp0;
- listnode_add(lsp0->lspu.frags, lsp);
+ memcpy(lspid, lsp->hdr.lsp_id, ISIS_SYS_ID_LEN + 1);
+ LSP_FRAGMENT(lspid) = 0;
+ lsp0 = lsp_search(lspid, area->lspdb[level - 1]);
+ if (lsp0)
+ lsp_link_fragment(lsp, lsp0);
}
+
+ /* insert the lsp back into the database */
+ lsp_insert(lsp, area->lspdb[level - 1]);
}
/* creation of LSP directly from what we received */
@@ -809,6 +820,8 @@ static struct isis_lsp *lsp_next_frag(uint8_t frag_num, struct isis_lsp *lsp0,
lsp = lsp_search(frag_id, area->lspdb[level - 1]);
if (lsp) {
lsp_clear_data(lsp);
+ if (!lsp->lspu.zero_lsp)
+ lsp_link_fragment(lsp, lsp0);
return lsp;
}
@@ -1255,6 +1268,7 @@ static int lsp_regenerate(struct isis_area *area, int level)
* so that no fragment expires before the lsp is refreshed.
*/
frag->hdr.rem_lifetime = rem_lifetime;
+ frag->age_out = ZERO_AGE_LIFETIME;
lsp_set_all_srmflags(frag);
}
lsp_seqno_update(lsp);
diff --git a/isisd/isis_route.c b/isisd/isis_route.c
index 267e72002f..ff17572ef9 100644
--- a/isisd/isis_route.c
+++ b/isisd/isis_route.c
@@ -208,9 +208,6 @@ static void adjinfo2nexthop(struct list *nexthops, struct isis_adjacency *adj)
{
struct isis_nexthop *nh;
- if (!adj->ipv4_address_count)
- return;
-
for (unsigned int i = 0; i < adj->ipv4_address_count; i++) {
struct in_addr *ipv4_addr = &adj->ipv4_addresses[i];
if (!nexthoplookup(nexthops, ipv4_addr,
@@ -219,6 +216,7 @@ static void adjinfo2nexthop(struct list *nexthops, struct isis_adjacency *adj)
ipv4_addr, adj->circuit->interface->ifindex);
nh->router_address = adj->router_address;
listnode_add(nexthops, nh);
+ return;
}
}
}
@@ -227,9 +225,6 @@ static void adjinfo2nexthop6(struct list *nexthops6, struct isis_adjacency *adj)
{
struct isis_nexthop6 *nh6;
- if (!adj->ipv6_address_count)
- return;
-
for (unsigned int i = 0; i < adj->ipv6_address_count; i++) {
struct in6_addr *ipv6_addr = &adj->ipv6_addresses[i];
if (!nexthop6lookup(nexthops6, ipv6_addr,
@@ -238,6 +233,7 @@ static void adjinfo2nexthop6(struct list *nexthops6, struct isis_adjacency *adj)
ipv6_addr, adj->circuit->interface->ifindex);
nh6->router_address6 = adj->router_address6;
listnode_add(nexthops6, nh6);
+ return;
}
}
}
diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c
index 3158da6bfa..34fcf8f8c6 100644
--- a/isisd/isis_spf.c
+++ b/isisd/isis_spf.c
@@ -278,7 +278,8 @@ struct isis_spftree {
struct isis_vertex_queue tents; /* TENT */
struct isis_area *area; /* back pointer to area */
unsigned int runcount; /* number of runs since uptime */
- time_t last_run_timestamp; /* last run timestamp for scheduling */
+ 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 */
uint16_t mtid;
@@ -475,6 +476,7 @@ struct isis_spftree *isis_spftree_new(struct isis_area *area)
isis_vertex_queue_init(&tree->paths, "IS-IS SPF paths", false);
tree->area = area;
tree->last_run_timestamp = 0;
+ tree->last_run_monotime = 0;
tree->last_run_duration = 0;
tree->runcount = 0;
return tree;
@@ -703,8 +705,6 @@ static void isis_spf_add_local(struct isis_spftree *spftree,
return;
} else { /* vertex->d_N > cost */
/* f) */
- struct listnode *pnode, *pnextnode;
- struct isis_vertex *pvertex;
isis_vertex_queue_delete(&spftree->tents, vertex);
isis_vertex_del(vertex);
}
@@ -786,8 +786,6 @@ static void process_N(struct isis_spftree *spftree, enum vertextype vtype,
return;
/* 4) */
} else {
- struct listnode *pnode, *pnextnode;
- struct isis_vertex *pvertex;
isis_vertex_queue_delete(&spftree->tents, vertex);
isis_vertex_del(vertex);
}
@@ -1348,7 +1346,7 @@ out:
isis_route_validate(area);
spftree->runcount++;
spftree->last_run_timestamp = time(NULL);
- monotime(&time_now);
+ spftree->last_run_monotime = monotime(&time_now);
end_time = time_now.tv_sec;
end_time = (end_time * 1000000) + time_now.tv_usec;
spftree->last_run_duration = end_time - start_time;
@@ -1398,8 +1396,8 @@ static struct isis_spf_run *isis_run_spf_arg(struct isis_area *area, int level)
int isis_spf_schedule(struct isis_area *area, int level)
{
struct isis_spftree *spftree = area->spftree[level - 1];
- time_t now = time(NULL);
- int diff = now - spftree->last_run_timestamp;
+ time_t now = monotime(NULL);
+ int diff = now - spftree->last_run_monotime;
assert(diff >= 0);
assert(area->is_type & level);
@@ -1429,22 +1427,16 @@ int isis_spf_schedule(struct isis_area *area, int level)
return ISIS_OK;
/* wait configured min_spf_interval before doing the SPF */
+ long timer;
if (diff >= area->min_spf_interval[level - 1]) {
- int retval = ISIS_OK;
-
- if (area->ip_circuits)
- retval =
- isis_run_spf(area, level, AF_INET, isis->sysid);
- if (area->ipv6_circuits)
- retval = isis_run_spf(area, level, AF_INET6,
- isis->sysid);
-
- return retval;
+ /* Last run is more than min interval ago, schedule immediate run */
+ timer = 0;
+ } else {
+ timer = area->min_spf_interval[level - 1] - diff;
}
thread_add_timer(master, isis_run_spf_cb, isis_run_spf_arg(area, level),
- area->min_spf_interval[level - 1] - diff,
- &area->spf_timer[level - 1]);
+ timer, &area->spf_timer[level - 1]);
if (isis->debugs & DEBUG_SPF_EVENTS)
zlog_debug("ISIS-Spf (%s) L%d SPF scheduled %d sec from now",