isisd: add a debug mode that traces LSP construction
Signed-off-by: Christian Franke <chris@opensourcerouting.org>
diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c
index 1c472c0..74a86c8 100644
--- a/isisd/isis_lsp.c
+++ b/isisd/isis_lsp.c
@@ -1170,6 +1170,9 @@
uint32_t metric;
u_char zero_id[ISIS_SYS_ID_LEN + 1];
int retval = ISIS_OK;
+ char buf[BUFSIZ];
+
+ lsp_debug("ISIS (%s): Constructing local system LSP for level %d", area->area_tag, level);
/*
* Building the zero lsp
@@ -1209,12 +1212,14 @@
lsp->tlv_data.nlpids->count = 0;
if (area->ip_circuits > 0)
{
+ lsp_debug("ISIS (%s): Found IPv4 circuit, adding IPv4 to NLPIDs", area->area_tag);
lsp->tlv_data.nlpids->count++;
lsp->tlv_data.nlpids->nlpids[0] = NLPID_IP;
}
#ifdef HAVE_IPV6
if (area->ipv6_circuits > 0)
{
+ lsp_debug("ISIS (%s): Found IPv6 circuit, adding IPv6 to NLPIDs", area->area_tag);
lsp->tlv_data.nlpids->count++;
lsp->tlv_data.nlpids->nlpids[lsp->tlv_data.nlpids->count - 1] =
NLPID_IPV6;
@@ -1239,14 +1244,22 @@
else
lsp->tlv_data.hostname->namelen = MAX_TLV_LEN;
+ lsp_debug("ISIS (%s): Adding dynamic hostname '%.*s'", area->area_tag,
+ lsp->tlv_data.hostname->namelen, lsp->tlv_data.hostname->name);
tlv_add_dynamic_hostname (lsp->tlv_data.hostname, lsp->pdu);
}
+ else
+ {
+ lsp_debug("ISIS (%s): Not adding dynamic hostname (disabled)", area->area_tag);
+ }
/* IPv4 address and TE router ID TLVs. In case of the first one we don't
* follow "C" vendor, but "J" vendor behavior - one IPv4 address is put into
* LSP and this address is same as router id. */
if (isis->router_id != 0)
{
+ inet_ntop(AF_INET, &isis->router_id, buf, sizeof(buf));
+ lsp_debug("ISIS (%s): Adding router ID %s as IPv4 tlv.", area->area_tag, buf);
if (lsp->tlv_data.ipv4_addrs == NULL)
{
lsp->tlv_data.ipv4_addrs = list_new ();
@@ -1262,6 +1275,7 @@
* TLV's are in use. */
if (area->newmetric)
{
+ lsp_debug("ISIS (%s): Adding router ID also as TE router ID tlv.", area->area_tag);
lsp->tlv_data.router_id = XMALLOC (MTYPE_ISIS_TLV,
sizeof (struct in_addr));
lsp->tlv_data.router_id->id.s_addr = isis->router_id;
@@ -1269,6 +1283,10 @@
TE_ROUTER_ID);
}
}
+ else
+ {
+ lsp_debug("ISIS (%s): Router ID is unset. Not adding tlv.", area->area_tag);
+ }
memset (&tlv_data, 0, sizeof (struct tlvs));
@@ -1295,13 +1313,25 @@
}
#endif /* TOPOLOGY_GENERATE */
+ lsp_debug("ISIS (%s): Adding circuit specific information.", area->area_tag);
+
/*
* Then build lists of tlvs related to circuits
*/
for (ALL_LIST_ELEMENTS_RO (area->circuit_list, node, circuit))
{
+ if (!circuit->interface)
+ lsp_debug("ISIS (%s): Processing %s circuit %p with unknown interface",
+ area->area_tag, circuit_type2string(circuit->circ_type), circuit);
+ else
+ lsp_debug("ISIS (%s): Processing %s circuit %s",
+ area->area_tag, circuit_type2string(circuit->circ_type), circuit->interface->name);
+
if (circuit->state != C_STATE_UP)
- continue;
+ {
+ lsp_debug("ISIS (%s): Circuit is not up, ignoring.", area->area_tag);
+ continue;
+ }
/*
* Add IPv4 internal reachability of this circuit
@@ -1309,6 +1339,7 @@
if (circuit->ip_router && circuit->ip_addrs &&
circuit->ip_addrs->count > 0)
{
+ lsp_debug("ISIS (%s): Circuit has IPv4 active, adding respective TLVs.", area->area_tag);
if (area->oldmetric)
{
if (tlv_data.ipv4_int_reachs == NULL)
@@ -1324,6 +1355,9 @@
masklen2ip (ipv4->prefixlen, &ipreach->mask);
ipreach->prefix.s_addr = ((ipreach->mask.s_addr) &
(ipv4->prefix.s_addr));
+ inet_ntop(AF_INET, &ipreach->prefix.s_addr, buf, sizeof(buf));
+ lsp_debug("ISIS (%s): Adding old-style IP reachability for %s/%d",
+ area->area_tag, buf, ipv4->prefixlen);
listnode_add (tlv_data.ipv4_int_reachs, ipreach);
}
}
@@ -1349,6 +1383,9 @@
te_ipreach->control = (ipv4->prefixlen & 0x3F);
memcpy (&te_ipreach->prefix_start, &ipv4->prefix.s_addr,
(ipv4->prefixlen + 7)/8);
+ inet_ntop(AF_INET, &ipv4->prefix.s_addr, buf, sizeof(buf));
+ lsp_debug("ISIS (%s): Adding te-style IP reachability for %s/%d",
+ area->area_tag, buf, ipv4->prefixlen);
listnode_add (tlv_data.te_ipv4_reachs, te_ipreach);
}
}
@@ -1382,6 +1419,11 @@
ip6reach->prefix_len = ipv6->prefixlen;
memcpy (&ip6prefix, &ipv6, sizeof(ip6prefix));
apply_mask_ipv6 (ip6prefix);
+
+ inet_ntop(AF_INET6, &ip6prefix->prefix.s6_addr, buf, sizeof(buf));
+ lsp_debug("ISIS (%s): Adding IPv6 reachability for %s/%d",
+ area->area_tag, buf, ipv6->prefixlen);
+
memcpy (ip6reach->prefix, ip6prefix->prefix.s6_addr,
sizeof (ip6reach->prefix));
listnode_add (tlv_data.ipv6_reachs, ip6reach);
@@ -1411,9 +1453,18 @@
is_neigh->metrics = circuit->metrics[level - 1];
if (!memcmp (is_neigh->neigh_id, zero_id,
ISIS_SYS_ID_LEN + 1))
- XFREE (MTYPE_ISIS_TLV, is_neigh);
+ {
+ XFREE (MTYPE_ISIS_TLV, is_neigh);
+ lsp_debug("ISIS (%s): No DIS for circuit, not adding old-style IS neighbor.",
+ area->area_tag);
+ }
else
- listnode_add (tlv_data.is_neighs, is_neigh);
+ {
+ listnode_add (tlv_data.is_neighs, is_neigh);
+ lsp_debug("ISIS (%s): Adding DIS %s.%02x as old-style neighbor",
+ area->area_tag, sysid_print(is_neigh->neigh_id),
+ LSP_PSEUDO_ID(is_neigh->neigh_id));
+ }
}
if (area->newmetric)
{
@@ -1437,11 +1488,25 @@
SET_TE_METRIC(te_is_neigh, metric);
if (!memcmp (te_is_neigh->neigh_id, zero_id,
ISIS_SYS_ID_LEN + 1))
- XFREE (MTYPE_ISIS_TLV, te_is_neigh);
+ {
+ XFREE (MTYPE_ISIS_TLV, te_is_neigh);
+ lsp_debug("ISIS (%s): No DIS for circuit, not adding te-style IS neighbor.",
+ area->area_tag);
+ }
else
- listnode_add (tlv_data.te_is_neighs, te_is_neigh);
+ {
+ listnode_add (tlv_data.te_is_neighs, te_is_neigh);
+ lsp_debug("ISIS (%s): Adding DIS %s.%02x as te-style neighbor",
+ area->area_tag, sysid_print(te_is_neigh->neigh_id),
+ LSP_PSEUDO_ID(te_is_neigh->neigh_id));
+ }
}
}
+ else
+ {
+ lsp_debug("ISIS (%s): Circuit is not active for current level. Not adding IS neighbors",
+ area->area_tag);
+ }
break;
case CIRCUIT_T_P2P:
nei = circuit->u.p2p.neighbor;
@@ -1458,6 +1523,8 @@
memcpy (is_neigh->neigh_id, nei->sysid, ISIS_SYS_ID_LEN);
is_neigh->metrics = circuit->metrics[level - 1];
listnode_add (tlv_data.is_neighs, is_neigh);
+ lsp_debug("ISIS (%s): Adding old-style is reach for %s", area->area_tag,
+ sysid_print(is_neigh->neigh_id));
}
if (area->newmetric)
{
@@ -1474,8 +1541,15 @@
metric = circuit->te_metric[level - 1];
SET_TE_METRIC(te_is_neigh, metric);
listnode_add (tlv_data.te_is_neighs, te_is_neigh);
+ lsp_debug("ISIS (%s): Adding te-style is reach for %s", area->area_tag,
+ sysid_print(te_is_neigh->neigh_id));
}
}
+ else
+ {
+ lsp_debug("ISIS (%s): No adjacency for given level on this circuit. Not adding IS neighbors",
+ area->area_tag);
+ }
break;
case CIRCUIT_T_LOOPBACK:
break;
@@ -1484,6 +1558,8 @@
}
}
+ lsp_debug("ISIS (%s): LSP construction is complete. Serializing...", area->area_tag);
+
while (tlv_data.ipv4_int_reachs && listcount (tlv_data.ipv4_int_reachs))
{
if (lsp->tlv_data.ipv4_int_reachs == NULL)
@@ -1833,6 +1909,11 @@
struct es_neigh *es_neigh;
struct list *adj_list;
struct listnode *node;
+ struct isis_area *area = circuit->area;
+
+ lsp_debug("ISIS (%s): Constructing pseudo LSP %s for interface %s level %d",
+ area->area_tag, rawlspid_print(lsp->lsp_header->lsp_id),
+ circuit->interface->name, level);
lsp->level = level;
/* RFC3787 section 4 SHOULD not set overload bit in pseudo LSPs */
@@ -1853,6 +1934,9 @@
memcpy (&is_neigh->neigh_id, isis->sysid, ISIS_SYS_ID_LEN);
listnode_add (lsp->tlv_data.is_neighs, is_neigh);
+ lsp_debug("ISIS (%s): Adding %s.%02x as old-style neighbor (self)",
+ area->area_tag, sysid_print(is_neigh->neigh_id),
+ LSP_PSEUDO_ID(is_neigh->neigh_id));
}
if (circuit->area->newmetric)
{
@@ -1865,6 +1949,9 @@
memcpy (&te_is_neigh->neigh_id, isis->sysid, ISIS_SYS_ID_LEN);
listnode_add (lsp->tlv_data.te_is_neighs, te_is_neigh);
+ lsp_debug("ISIS (%s): Adding %s.%02x as te-style neighbor (self)",
+ area->area_tag, sysid_print(te_is_neigh->neigh_id),
+ LSP_PSEUDO_ID(te_is_neigh->neigh_id));
}
adj_list = list_new ();
@@ -1886,6 +1973,9 @@
memcpy (&is_neigh->neigh_id, adj->sysid, ISIS_SYS_ID_LEN);
listnode_add (lsp->tlv_data.is_neighs, is_neigh);
+ lsp_debug("ISIS (%s): Adding %s.%02x as old-style neighbor (peer)",
+ area->area_tag, sysid_print(is_neigh->neigh_id),
+ LSP_PSEUDO_ID(is_neigh->neigh_id));
}
if (circuit->area->newmetric)
{
@@ -1893,6 +1983,9 @@
sizeof (struct te_is_neigh));
memcpy (&te_is_neigh->neigh_id, adj->sysid, ISIS_SYS_ID_LEN);
listnode_add (lsp->tlv_data.te_is_neighs, te_is_neigh);
+ lsp_debug("ISIS (%s): Adding %s.%02x as te-style neighbor (peer)",
+ area->area_tag, sysid_print(te_is_neigh->neigh_id),
+ LSP_PSEUDO_ID(te_is_neigh->neigh_id));
}
}
else if (level == IS_LEVEL_1 && adj->sys_type == ISIS_SYSTYPE_ES)
@@ -1908,11 +2001,25 @@
memcpy (&es_neigh->first_es_neigh, adj->sysid, ISIS_SYS_ID_LEN);
listnode_add (lsp->tlv_data.es_neighs, es_neigh);
+ lsp_debug("ISIS (%s): Adding %s as ES neighbor (peer)",
+ area->area_tag, sysid_print(es_neigh->first_es_neigh));
}
+ else
+ {
+ lsp_debug("ISIS (%s): Ignoring neighbor %s, level does not match",
+ area->area_tag, sysid_print(adj->sysid));
+ }
+ }
+ else
+ {
+ lsp_debug("ISIS (%s): Ignoring neighbor %s, level does not intersect",
+ area->area_tag, sysid_print(adj->sysid));
}
}
list_delete (adj_list);
+ lsp_debug("ISIS (%s): Pseudo LSP construction is complete.", area->area_tag);
+
/* Reset endp of stream to overwrite only TLV part of it. */
stream_reset (lsp->pdu);
stream_forward_endp (lsp->pdu, ISIS_FIXED_HDR_LEN + ISIS_LSP_HDR_LEN);
diff --git a/isisd/isisd.c b/isisd/isisd.c
index 7146689..b601032 100644
--- a/isisd/isisd.c
+++ b/isisd/isisd.c
@@ -772,6 +772,8 @@
vty_out (vty, "IS-IS Event debugging is %s%s", onoffs, VTY_NEWLINE);
if (flags & DEBUG_PACKET_DUMP)
vty_out (vty, "IS-IS Packet dump debugging is %s%s", onoffs, VTY_NEWLINE);
+ if (flags & DEBUG_LSP_GEN)
+ vty_out (vty, "IS-IS LSP generation debugging is %s%s", onoffs, VTY_NEWLINE);
}
DEFUN (show_debugging,
@@ -858,6 +860,11 @@
vty_out (vty, "debug isis packet-dump%s", VTY_NEWLINE);
write++;
}
+ if (flags & DEBUG_LSP_GEN)
+ {
+ vty_out (vty, "debug isis lsp-gen%s", VTY_NEWLINE);
+ write++;
+ }
return write;
}
@@ -1174,6 +1181,32 @@
return CMD_SUCCESS;
}
+DEFUN (debug_isis_lsp_gen,
+ debug_isis_lsp_gen_cmd,
+ "debug isis lsp-gen",
+ DEBUG_STR
+ "IS-IS information\n"
+ "IS-IS generation of own LSPs\n")
+{
+ isis->debugs |= DEBUG_LSP_GEN;
+ print_debug (vty, DEBUG_LSP_GEN, 1);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_debug_isis_lsp_gen,
+ no_debug_isis_lsp_gen_cmd,
+ "no debug isis lsp-gen",
+ UNDEBUG_STR
+ "IS-IS information\n"
+ "IS-IS generation of own LSPs\n")
+{
+ isis->debugs &= ~DEBUG_LSP_GEN;
+ print_debug (vty, DEBUG_LSP_GEN, 0);
+
+ return CMD_SUCCESS;
+}
+
DEFUN (show_hostname,
show_hostname_cmd,
"show isis hostname",
@@ -3260,6 +3293,8 @@
install_element (ENABLE_NODE, &no_debug_isis_events_cmd);
install_element (ENABLE_NODE, &debug_isis_packet_dump_cmd);
install_element (ENABLE_NODE, &no_debug_isis_packet_dump_cmd);
+ install_element (ENABLE_NODE, &debug_isis_lsp_gen_cmd);
+ install_element (ENABLE_NODE, &no_debug_isis_lsp_gen_cmd);
install_element (CONFIG_NODE, &debug_isis_adj_cmd);
install_element (CONFIG_NODE, &no_debug_isis_adj_cmd);
@@ -3285,6 +3320,8 @@
install_element (CONFIG_NODE, &no_debug_isis_events_cmd);
install_element (CONFIG_NODE, &debug_isis_packet_dump_cmd);
install_element (CONFIG_NODE, &no_debug_isis_packet_dump_cmd);
+ install_element (CONFIG_NODE, &debug_isis_lsp_gen_cmd);
+ install_element (CONFIG_NODE, &no_debug_isis_lsp_gen_cmd);
install_element (CONFIG_NODE, &router_isis_cmd);
install_element (CONFIG_NODE, &no_router_isis_cmd);
diff --git a/isisd/isisd.h b/isisd/isisd.h
index 6e95e8e..51a72ab 100644
--- a/isisd/isisd.h
+++ b/isisd/isisd.h
@@ -166,5 +166,14 @@
#define DEBUG_EVENTS (1<<10)
#define DEBUG_ZEBRA (1<<11)
#define DEBUG_PACKET_DUMP (1<<12)
+#define DEBUG_LSP_GEN (1<<13)
+
+#define lsp_debug(...) \
+ do \
+ { \
+ if (isis->debugs & DEBUG_LSP_GEN) \
+ zlog_debug(__VA_ARGS__); \
+ } \
+ while (0)
#endif /* ISISD_H */