mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-07-25 22:01:08 +00:00
Merge pull request #1231 from opensourcerouting/isis-fixes
Isisd: assorted fixes
This commit is contained in:
commit
a97c617c2b
@ -447,6 +447,19 @@ static void lsp_update_data(struct isis_lsp *lsp, struct isis_lsp_hdr *hdr,
|
|||||||
return;
|
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,
|
void lsp_update(struct isis_lsp *lsp, struct isis_lsp_hdr *hdr,
|
||||||
struct isis_tlvs *tlvs, struct stream *stream,
|
struct isis_tlvs *tlvs, struct stream *stream,
|
||||||
struct isis_area *area, int level, bool confusion)
|
struct isis_area *area, int level, bool confusion)
|
||||||
@ -476,23 +489,21 @@ void lsp_update(struct isis_lsp *lsp, struct isis_lsp_hdr *hdr,
|
|||||||
put_lsp_hdr(lsp, NULL, true);
|
put_lsp_hdr(lsp, NULL, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (LSP_FRAGMENT(lsp->hdr.lsp_id) && !lsp->lspu.zero_lsp) {
|
||||||
|
uint8_t lspid[ISIS_SYS_ID_LEN + 2];
|
||||||
|
struct isis_lsp *lsp0;
|
||||||
|
|
||||||
|
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 */
|
/* insert the lsp back into the database */
|
||||||
lsp_insert(lsp, area->lspdb[level - 1]);
|
lsp_insert(lsp, area->lspdb[level - 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* creation of LSP directly from what we received */
|
/* creation of LSP directly from what we received */
|
||||||
struct isis_lsp *lsp_new_from_recv(struct isis_lsp_hdr *hdr,
|
struct isis_lsp *lsp_new_from_recv(struct isis_lsp_hdr *hdr,
|
||||||
struct isis_tlvs *tlvs,
|
struct isis_tlvs *tlvs,
|
||||||
@ -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]);
|
lsp = lsp_search(frag_id, area->lspdb[level - 1]);
|
||||||
if (lsp) {
|
if (lsp) {
|
||||||
lsp_clear_data(lsp);
|
lsp_clear_data(lsp);
|
||||||
|
if (!lsp->lspu.zero_lsp)
|
||||||
|
lsp_link_fragment(lsp, lsp0);
|
||||||
return lsp;
|
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.
|
* so that no fragment expires before the lsp is refreshed.
|
||||||
*/
|
*/
|
||||||
frag->hdr.rem_lifetime = rem_lifetime;
|
frag->hdr.rem_lifetime = rem_lifetime;
|
||||||
|
frag->age_out = ZERO_AGE_LIFETIME;
|
||||||
lsp_set_all_srmflags(frag);
|
lsp_set_all_srmflags(frag);
|
||||||
}
|
}
|
||||||
lsp_seqno_update(lsp);
|
lsp_seqno_update(lsp);
|
||||||
|
@ -208,9 +208,6 @@ static void adjinfo2nexthop(struct list *nexthops, struct isis_adjacency *adj)
|
|||||||
{
|
{
|
||||||
struct isis_nexthop *nh;
|
struct isis_nexthop *nh;
|
||||||
|
|
||||||
if (!adj->ipv4_address_count)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < adj->ipv4_address_count; i++) {
|
for (unsigned int i = 0; i < adj->ipv4_address_count; i++) {
|
||||||
struct in_addr *ipv4_addr = &adj->ipv4_addresses[i];
|
struct in_addr *ipv4_addr = &adj->ipv4_addresses[i];
|
||||||
if (!nexthoplookup(nexthops, ipv4_addr,
|
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);
|
ipv4_addr, adj->circuit->interface->ifindex);
|
||||||
nh->router_address = adj->router_address;
|
nh->router_address = adj->router_address;
|
||||||
listnode_add(nexthops, nh);
|
listnode_add(nexthops, nh);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -227,9 +225,6 @@ static void adjinfo2nexthop6(struct list *nexthops6, struct isis_adjacency *adj)
|
|||||||
{
|
{
|
||||||
struct isis_nexthop6 *nh6;
|
struct isis_nexthop6 *nh6;
|
||||||
|
|
||||||
if (!adj->ipv6_address_count)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < adj->ipv6_address_count; i++) {
|
for (unsigned int i = 0; i < adj->ipv6_address_count; i++) {
|
||||||
struct in6_addr *ipv6_addr = &adj->ipv6_addresses[i];
|
struct in6_addr *ipv6_addr = &adj->ipv6_addresses[i];
|
||||||
if (!nexthop6lookup(nexthops6, ipv6_addr,
|
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);
|
ipv6_addr, adj->circuit->interface->ifindex);
|
||||||
nh6->router_address6 = adj->router_address6;
|
nh6->router_address6 = adj->router_address6;
|
||||||
listnode_add(nexthops6, nh6);
|
listnode_add(nexthops6, nh6);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -278,7 +278,8 @@ struct isis_spftree {
|
|||||||
struct isis_vertex_queue tents; /* TENT */
|
struct isis_vertex_queue tents; /* TENT */
|
||||||
struct isis_area *area; /* back pointer to area */
|
struct isis_area *area; /* back pointer to area */
|
||||||
unsigned int runcount; /* number of runs since uptime */
|
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 */
|
time_t last_run_duration; /* last run duration in msec */
|
||||||
|
|
||||||
uint16_t mtid;
|
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);
|
isis_vertex_queue_init(&tree->paths, "IS-IS SPF paths", false);
|
||||||
tree->area = area;
|
tree->area = area;
|
||||||
tree->last_run_timestamp = 0;
|
tree->last_run_timestamp = 0;
|
||||||
|
tree->last_run_monotime = 0;
|
||||||
tree->last_run_duration = 0;
|
tree->last_run_duration = 0;
|
||||||
tree->runcount = 0;
|
tree->runcount = 0;
|
||||||
return tree;
|
return tree;
|
||||||
@ -703,8 +705,6 @@ static void isis_spf_add_local(struct isis_spftree *spftree,
|
|||||||
return;
|
return;
|
||||||
} else { /* vertex->d_N > cost */
|
} else { /* vertex->d_N > cost */
|
||||||
/* f) */
|
/* f) */
|
||||||
struct listnode *pnode, *pnextnode;
|
|
||||||
struct isis_vertex *pvertex;
|
|
||||||
isis_vertex_queue_delete(&spftree->tents, vertex);
|
isis_vertex_queue_delete(&spftree->tents, vertex);
|
||||||
isis_vertex_del(vertex);
|
isis_vertex_del(vertex);
|
||||||
}
|
}
|
||||||
@ -786,8 +786,6 @@ static void process_N(struct isis_spftree *spftree, enum vertextype vtype,
|
|||||||
return;
|
return;
|
||||||
/* 4) */
|
/* 4) */
|
||||||
} else {
|
} else {
|
||||||
struct listnode *pnode, *pnextnode;
|
|
||||||
struct isis_vertex *pvertex;
|
|
||||||
isis_vertex_queue_delete(&spftree->tents, vertex);
|
isis_vertex_queue_delete(&spftree->tents, vertex);
|
||||||
isis_vertex_del(vertex);
|
isis_vertex_del(vertex);
|
||||||
}
|
}
|
||||||
@ -1348,7 +1346,7 @@ out:
|
|||||||
isis_route_validate(area);
|
isis_route_validate(area);
|
||||||
spftree->runcount++;
|
spftree->runcount++;
|
||||||
spftree->last_run_timestamp = time(NULL);
|
spftree->last_run_timestamp = time(NULL);
|
||||||
monotime(&time_now);
|
spftree->last_run_monotime = monotime(&time_now);
|
||||||
end_time = time_now.tv_sec;
|
end_time = time_now.tv_sec;
|
||||||
end_time = (end_time * 1000000) + time_now.tv_usec;
|
end_time = (end_time * 1000000) + time_now.tv_usec;
|
||||||
spftree->last_run_duration = end_time - start_time;
|
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)
|
int isis_spf_schedule(struct isis_area *area, int level)
|
||||||
{
|
{
|
||||||
struct isis_spftree *spftree = area->spftree[level - 1];
|
struct isis_spftree *spftree = area->spftree[level - 1];
|
||||||
time_t now = time(NULL);
|
time_t now = monotime(NULL);
|
||||||
int diff = now - spftree->last_run_timestamp;
|
int diff = now - spftree->last_run_monotime;
|
||||||
|
|
||||||
assert(diff >= 0);
|
assert(diff >= 0);
|
||||||
assert(area->is_type & level);
|
assert(area->is_type & level);
|
||||||
@ -1429,22 +1427,16 @@ int isis_spf_schedule(struct isis_area *area, int level)
|
|||||||
return ISIS_OK;
|
return ISIS_OK;
|
||||||
|
|
||||||
/* wait configured min_spf_interval before doing the SPF */
|
/* wait configured min_spf_interval before doing the SPF */
|
||||||
|
long timer;
|
||||||
if (diff >= area->min_spf_interval[level - 1]) {
|
if (diff >= area->min_spf_interval[level - 1]) {
|
||||||
int retval = ISIS_OK;
|
/* Last run is more than min interval ago, schedule immediate run */
|
||||||
|
timer = 0;
|
||||||
if (area->ip_circuits)
|
} else {
|
||||||
retval =
|
timer = area->min_spf_interval[level - 1] - diff;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
thread_add_timer(master, isis_run_spf_cb, isis_run_spf_arg(area, level),
|
thread_add_timer(master, isis_run_spf_cb, isis_run_spf_arg(area, level),
|
||||||
area->min_spf_interval[level - 1] - diff,
|
timer, &area->spf_timer[level - 1]);
|
||||||
&area->spf_timer[level - 1]);
|
|
||||||
|
|
||||||
if (isis->debugs & DEBUG_SPF_EVENTS)
|
if (isis->debugs & DEBUG_SPF_EVENTS)
|
||||||
zlog_debug("ISIS-Spf (%s) L%d SPF scheduled %d sec from now",
|
zlog_debug("ISIS-Spf (%s) L%d SPF scheduled %d sec from now",
|
||||||
|
Loading…
Reference in New Issue
Block a user