if (lsp->pdu)
stream_free(lsp->pdu);
+
+ fabricd_lsp_free(lsp);
XFREE(MTYPE_ISIS_LSP, lsp);
}
if (seqno > lsp->hdr.seqno
|| (seqno == lsp->hdr.seqno
&& ((lsp->hdr.rem_lifetime != 0 && rem_lifetime == 0)
- || lsp->hdr.checksum != checksum))) {
+ || (lsp->hdr.checksum != checksum
+ && lsp->hdr.rem_lifetime)))) {
if (isis->debugs & DEBUG_SNP_PACKETS) {
zlog_debug(
"ISIS-Snp (%s): Compare LSP %s seq 0x%08" PRIx32
else
newseq = seqno + 1;
+#ifndef FABRICD
+ /* check for overflow */
+ if (newseq < lsp->hdr.seqno) {
+ /* send northbound notification */
+ isis_notif_lsp_exceed_max(lsp->area,
+ rawlspid_print(lsp->hdr.lsp_id));
+ }
+#endif /* ifndef FABRICD */
+
lsp->hdr.seqno = newseq;
lsp_pack_pdu(lsp);
lsp->hdr.rem_lifetime = 0;
lsp->level = level;
lsp->age_out = lsp->area->max_lsp_lifetime[level - 1];
+ lsp->area->lsp_purge_count[level - 1]++;
lsp_purge_add_poi(lsp, sender);
for (ALL_LIST_ELEMENTS_RO(lsp0->lspu.frags, node, lsp)) {
if (lsp->tlvs)
lsp_inc_seqno(lsp, 0);
- else
+ else if (lsp->hdr.rem_lifetime) {
+ /* Purge should only be applied when the fragment has
+ * non-zero remaining lifetime.
+ */
lsp_purge(lsp, lsp0->level, NULL);
+ }
}
return;
void lsp_build_list_nonzero_ht(uint8_t *start_id, uint8_t *stop_id,
struct list *list, dict_t *lspdb)
{
- dnode_t *first, *last, *curr;
-
- first = dict_lower_bound(lspdb, start_id);
- if (!first)
- return;
-
- last = dict_upper_bound(lspdb, stop_id);
-
- curr = first;
-
- if (((struct isis_lsp *)(curr->dict_data))->hdr.rem_lifetime)
- listnode_add(list, first->dict_data);
+ for (dnode_t *curr = dict_lower_bound(lspdb, start_id);
+ curr; curr = dict_next(lspdb, curr)) {
+ struct isis_lsp *lsp = curr->dict_data;
- while (curr) {
- curr = dict_next(lspdb, curr);
- if (curr
- && ((struct isis_lsp *)(curr->dict_data))->hdr.rem_lifetime)
- listnode_add(list, curr->dict_data);
- if (curr == last)
+ if (memcmp(lsp->hdr.lsp_id, stop_id,
+ ISIS_SYS_ID_LEN + 2) > 0)
break;
- }
- return;
+ if (lsp->hdr.rem_lifetime)
+ listnode_add(list, lsp);
+ }
}
static void lsp_set_time(struct isis_lsp *lsp)
stream_putw_at(lsp->pdu, 10, lsp->hdr.rem_lifetime);
}
-static void lspid_print(uint8_t *lsp_id, uint8_t *trg, char dynhost, char frag)
+void lspid_print(uint8_t *lsp_id, char *dest, char dynhost, char frag)
{
struct isis_dynhn *dyn = NULL;
uint8_t id[SYSID_STRLEN];
else
memcpy(id, sysid_print(lsp_id), 15);
if (frag)
- sprintf((char *)trg, "%s.%02x-%02x", id, LSP_PSEUDO_ID(lsp_id),
+ sprintf(dest, "%s.%02x-%02x", id, LSP_PSEUDO_ID(lsp_id),
LSP_FRAGMENT(lsp_id));
else
- sprintf((char *)trg, "%s.%02x", id, LSP_PSEUDO_ID(lsp_id));
+ sprintf(dest, "%s.%02x", id, LSP_PSEUDO_ID(lsp_id));
}
/* Convert the lsp attribute bits to attribute string */
/* this function prints the lsp on show isis database */
void lsp_print(struct isis_lsp *lsp, struct vty *vty, char dynhost)
{
- uint8_t LSPid[255];
+ char LSPid[255];
char age_out[8];
char b[200];
lsp_seqno_update(newlsp);
newlsp->last_generated = time(NULL);
lsp_flood(newlsp, NULL);
+ area->lsp_gen_count[level - 1]++;
refresh_time = lsp_refresh_time(newlsp, rem_lifetime);
"ISIS (%s): Built L%d LSP. Set triggered regenerate to non-pending.",
area->area_tag, level);
+#ifndef FABRICD
+ /* send northbound notification */
+ isis_notif_lsp_gen(area, rawlspid_print(newlsp->hdr.lsp_id),
+ newlsp->hdr.seqno, newlsp->last_generated);
+#endif /* ifndef FABRICD */
+
return ISIS_OK;
}
lsp->hdr.rem_lifetime = rem_lifetime;
lsp->last_generated = time(NULL);
lsp_flood(lsp, NULL);
+ area->lsp_gen_count[level - 1]++;
for (ALL_LIST_ELEMENTS_RO(lsp->lspu.frags, node, frag)) {
+ if (!frag->tlvs) {
+ /* Updating and flooding should only affect fragments
+ * carrying data
+ */
+ continue;
+ }
+
frag->hdr.lsp_bits = lsp_bits_generate(
level, area->overload_bit, area->attached_bit);
/* Set the lifetime values of all the fragments to the same
if ((area->is_type & level) == 0)
return ISIS_ERROR;
- if (monotime_since(&area->last_lsp_refresh_event[level - 1], NULL) < 50000L) {
+ if (monotime_since(&area->last_lsp_refresh_event[level - 1], NULL) < 100000L) {
sched_debug("ISIS (%s): Still unstable, postpone LSP L%d refresh",
area->area_tag, level);
_lsp_regenerate_schedule(area, level, 0, false,
lsp->level = level;
lsp_adjust_stream(lsp);
lsp->age_out = ZERO_AGE_LIFETIME;
+ lsp->area->lsp_purge_count[level - 1]++;
memcpy(&lsp->hdr, hdr, sizeof(lsp->hdr));
lsp->hdr.rem_lifetime = 0;
}
}
-void lsp_flood(struct isis_lsp *lsp, struct isis_circuit *circuit)
+void _lsp_flood(struct isis_lsp *lsp, struct isis_circuit *circuit,
+ const char *func, const char *file, int line)
{
- if (!fabricd) {
- lsp_set_all_srmflags(lsp, true);
- if (circuit)
- isis_tx_queue_del(circuit->tx_queue, lsp);
- } else {
- fabricd_lsp_flood(lsp);
+ if (isis->debugs & DEBUG_FLOODING) {
+ zlog_debug("Flooding LSP %s%s%s (From %s %s:%d)",
+ rawlspid_print(lsp->hdr.lsp_id),
+ circuit ? " except on " : "",
+ circuit ? circuit->interface->name : "",
+ func, file, line);
}
+
+ if (!fabricd)
+ lsp_set_all_srmflags(lsp, true);
+ else
+ fabricd_lsp_flood(lsp, circuit);
+
+ if (circuit)
+ isis_tx_queue_del(circuit->tx_queue, lsp);
}
static int lsp_handle_adj_state_change(struct isis_adjacency *adj)