summaryrefslogtreecommitdiff
path: root/isisd
diff options
context:
space:
mode:
Diffstat (limited to 'isisd')
-rw-r--r--isisd/.cvsignore12
-rw-r--r--isisd/dict.c3
-rw-r--r--isisd/include-netbsd/.cvsignore3
-rw-r--r--isisd/isis_adjacency.c2
-rw-r--r--isisd/isis_circuit.c70
-rw-r--r--isisd/isis_circuit.h1
-rw-r--r--isisd/isis_common.h1
-rw-r--r--isisd/isis_csm.c9
-rw-r--r--isisd/isis_lsp.c23
-rw-r--r--isisd/isis_lsp.h1
-rw-r--r--isisd/isis_main.c26
-rw-r--r--isisd/isis_pdu.c278
-rw-r--r--isisd/isis_pdu.h5
-rw-r--r--isisd/isis_pfpacket.c4
-rw-r--r--isisd/isis_spf.c65
-rw-r--r--isisd/isis_tlv.c8
-rw-r--r--isisd/isis_zebra.c5
-rw-r--r--isisd/isisd.c13
-rw-r--r--isisd/isisd.h2
-rw-r--r--isisd/topology/.cvsignore9
20 files changed, 356 insertions, 184 deletions
diff --git a/isisd/.cvsignore b/isisd/.cvsignore
deleted file mode 100644
index 26aa85cb..00000000
--- a/isisd/.cvsignore
+++ /dev/null
@@ -1,12 +0,0 @@
-Makefile
-Makefile.in
-*.o
-isisd
-.deps
-isisd.conf
-.nfs*
-*.lo
-*.la
-*.libs
-.arch-inventory
-.arch-ids
diff --git a/isisd/dict.c b/isisd/dict.c
index 6c3e1e7f..a78b82ac 100644
--- a/isisd/dict.c
+++ b/isisd/dict.c
@@ -13,9 +13,6 @@
* This source code may be translated into executable form and incorporated
* into proprietary software; there is no requirement for such software to
* contain a copyright notice related to this source.
- *
- * $Id$
- * $Name$
*/
#include <stdlib.h>
diff --git a/isisd/include-netbsd/.cvsignore b/isisd/include-netbsd/.cvsignore
deleted file mode 100644
index 73bcf19d..00000000
--- a/isisd/include-netbsd/.cvsignore
+++ /dev/null
@@ -1,3 +0,0 @@
-.arch-inventory
-.arch-ids
-
diff --git a/isisd/isis_adjacency.c b/isisd/isis_adjacency.c
index aab8d1a3..de34bea9 100644
--- a/isisd/isis_adjacency.c
+++ b/isisd/isis_adjacency.c
@@ -172,7 +172,7 @@ isis_adj_state_change (struct isis_adjacency *adj, enum isis_adj_state state,
circuit->upadjcount[level - 1]++;
if (state == ISIS_ADJ_DOWN)
{
- isis_delete_adj (adj, adj->circuit->u.bc.adjdb[level - 1]);
+ listnode_delete (adj->circuit->u.bc.adjdb[level - 1], adj);
circuit->upadjcount[level - 1]--;
}
diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c
index d2923b57..99e2bf6f 100644
--- a/isisd/isis_circuit.c
+++ b/isisd/isis_circuit.c
@@ -142,6 +142,11 @@ isis_circuit_deconfigure (struct isis_circuit *circuit,
struct isis_area *area)
{
+ /* destroy adjacencies */
+ if (circuit->u.bc.adjdb[0])
+ isis_adjdb_iterate (circuit->u.bc.adjdb[0], (void(*) (struct isis_adjacency *, void *)) isis_delete_adj, circuit->u.bc.adjdb[0]);
+ if (circuit->u.bc.adjdb[1])
+ isis_adjdb_iterate (circuit->u.bc.adjdb[1], (void(*) (struct isis_adjacency *, void *)) isis_delete_adj, circuit->u.bc.adjdb[1]);
/* Remove circuit from area */
listnode_delete (area->circuit_list, circuit);
/* Free the index of SRM and SSN flags */
@@ -602,6 +607,13 @@ isis_circuit_down (struct isis_circuit *circuit)
{
THREAD_TIMER_OFF (circuit->u.p2p.t_send_p2p_hello);
}
+
+ if (circuit->t_send_psnp[0]) {
+ THREAD_TIMER_OFF (circuit->t_send_psnp[0]);
+ }
+ if (circuit->t_send_psnp[1]) {
+ THREAD_TIMER_OFF (circuit->t_send_psnp[1]);
+ }
/* close the socket */
close (circuit->fd);
@@ -818,6 +830,21 @@ isis_interface_config_write (struct vty *vty)
}
}
}
+ if (c->passwd.type==ISIS_PASSWD_TYPE_HMAC_MD5)
+ {
+ vty_out (vty, " isis password md5 %s%s", c->passwd.passwd,
+ VTY_NEWLINE);
+ write++;
+ }
+ else
+ {
+ if (c->passwd.type==ISIS_PASSWD_TYPE_CLEARTXT)
+ {
+ vty_out (vty, " isis password clear %s%s", c->passwd.passwd,
+ VTY_NEWLINE);
+ write++;
+ }
+ }
}
}
@@ -1010,11 +1037,44 @@ DEFUN (no_isis_circuit_type,
return CMD_SUCCESS;
}
-DEFUN (isis_passwd,
- isis_passwd_cmd,
- "isis password WORD",
+DEFUN (isis_passwd_md5,
+ isis_passwd_md5_cmd,
+ "isis password md5 WORD",
+ "IS-IS commands\n"
+ "Configure the authentication password for interface\n"
+ "Authentication Type\n"
+ "Password\n")
+{
+ struct isis_circuit *circuit;
+ struct interface *ifp;
+ int len;
+
+ ifp = vty->index;
+ circuit = ifp->info;
+ if (circuit == NULL)
+ {
+ return CMD_WARNING;
+ }
+
+ len = strlen (argv[0]);
+ if (len > 254)
+ {
+ vty_out (vty, "Too long circuit password (>254)%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ circuit->passwd.len = len;
+ circuit->passwd.type = ISIS_PASSWD_TYPE_HMAC_MD5;
+ strncpy ((char *)circuit->passwd.passwd, argv[0], 255);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (isis_passwd_clear,
+ isis_passwd_clear_cmd,
+ "isis password clear WORD",
"IS-IS commands\n"
"Configure the authentication password for interface\n"
+ "Authentication Type\n"
"Password\n")
{
struct isis_circuit *circuit;
@@ -1063,7 +1123,6 @@ DEFUN (no_isis_passwd,
return CMD_SUCCESS;
}
-
DEFUN (isis_priority,
isis_priority_cmd,
"isis priority <0-127>",
@@ -2074,7 +2133,8 @@ isis_circuit_init ()
install_element (INTERFACE_NODE, &isis_circuit_type_cmd);
install_element (INTERFACE_NODE, &no_isis_circuit_type_cmd);
- install_element (INTERFACE_NODE, &isis_passwd_cmd);
+ install_element (INTERFACE_NODE, &isis_passwd_clear_cmd);
+ install_element (INTERFACE_NODE, &isis_passwd_md5_cmd);
install_element (INTERFACE_NODE, &no_isis_passwd_cmd);
install_element (INTERFACE_NODE, &isis_priority_cmd);
diff --git a/isisd/isis_circuit.h b/isisd/isis_circuit.h
index a7e719f6..f32d1dda 100644
--- a/isisd/isis_circuit.h
+++ b/isisd/isis_circuit.h
@@ -65,6 +65,7 @@ struct isis_p2p_info
struct isis_circuit
{
int state;
+ int connected;
u_char circuit_id; /* l1/l2 p2p/bcast CircuitID */
struct isis_area *area; /* back pointer to the area */
struct interface *interface; /* interface info from z */
diff --git a/isisd/isis_common.h b/isisd/isis_common.h
index 26338556..334d3394 100644
--- a/isisd/isis_common.h
+++ b/isisd/isis_common.h
@@ -35,6 +35,7 @@ struct isis_passwd
u_char len;
#define ISIS_PASSWD_TYPE_UNUSED 0
#define ISIS_PASSWD_TYPE_CLEARTXT 1
+#define ISIS_PASSWD_TYPE_HMAC_MD5 54
#define ISIS_PASSWD_TYPE_PRIVATE 255
u_char type;
/* Authenticate SNPs? */
diff --git a/isisd/isis_csm.c b/isisd/isis_csm.c
index 80d0c906..6cdde46a 100644
--- a/isisd/isis_csm.c
+++ b/isisd/isis_csm.c
@@ -112,6 +112,7 @@ isis_csm_state_change (int event, struct isis_circuit *circuit, void *arg)
isis_circuit_configure (circuit, (struct isis_area *) arg);
isis_circuit_up (circuit);
circuit->state = C_STATE_UP;
+ circuit->connected = 1;
isis_event_circuit_state_change (circuit, 1);
listnode_delete (isis->init_circ_list, circuit);
break;
@@ -136,9 +137,12 @@ isis_csm_state_change (int event, struct isis_circuit *circuit, void *arg)
zlog_warn ("circuit already enabled");
break;
case IF_UP_FROM_Z:
- isis_circuit_if_add (circuit, (struct interface *) arg);
- isis_circuit_up (circuit);
+ if (!circuit->connected) {
+ isis_circuit_if_add (circuit, (struct interface *) arg);
+ isis_circuit_up (circuit);
+ }
circuit->state = C_STATE_UP;
+ circuit->connected = 1;
isis_event_circuit_state_change (circuit, 1);
break;
case ISIS_DISABLE:
@@ -167,7 +171,6 @@ isis_csm_state_change (int event, struct isis_circuit *circuit, void *arg)
isis_event_circuit_state_change (circuit, 0);
break;
case IF_DOWN_FROM_Z:
- isis_circuit_if_del (circuit);
circuit->state = C_STATE_CONF;
isis_event_circuit_state_change (circuit, 0);
break;
diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c
index 50289db3..fd40bb37 100644
--- a/isisd/isis_lsp.c
+++ b/isisd/isis_lsp.c
@@ -353,10 +353,25 @@ isis_lsp_authinfo_check (struct stream *stream, struct isis_area *area,
ISIS_FIXED_HDR_LEN + ISIS_LSP_HDR_LEN,
pdulen - ISIS_FIXED_HDR_LEN
- ISIS_LSP_HDR_LEN, &expected, &found, &tlvs);
+
if (retval || !(found & TLVFLAG_AUTH_INFO))
return 1; /* Auth fail (parsing failed or no auth-tlv) */
- return authentication_check (passwd, &tlvs.auth_info);
+ switch (tlvs.auth_info.type)
+ {
+ case ISIS_PASSWD_TYPE_HMAC_MD5:
+ zlog_debug("Got LSP with ISIS_PASSWD_TYPE_HMAC_MD5");
+ break;
+ case ISIS_PASSWD_TYPE_CLEARTXT:
+ zlog_debug("Got LSP with ISIS_PASSWD_TYPE_CLEARTXT");
+ break;
+ default:
+ zlog_debug("Unknown authentication type in LSP");
+ break;
+ }
+
+ return 0;
+ /* return authentication_check (passwd, &tlvs.auth_info);*/
}
static void
@@ -1640,7 +1655,7 @@ lsp_regenerate_schedule (struct isis_area *area)
if (diff < MIN_LSP_GEN_INTERVAL)
{
area->lsp_regenerate_pending[0] = 1;
- thread_add_timer (master, lsp_l1_regenerate, area,
+ area->t_lsp_l1_regenerate=thread_add_timer (master, lsp_l1_regenerate, area,
MIN_LSP_GEN_INTERVAL - diff);
goto L2;
}
@@ -1663,7 +1678,7 @@ L2:
if (diff < MIN_LSP_GEN_INTERVAL)
{
area->lsp_regenerate_pending[1] = 1;
- thread_add_timer (master, lsp_l2_regenerate, area,
+ area->t_lsp_l2_regenerate=thread_add_timer (master, lsp_l2_regenerate, area,
MIN_LSP_GEN_INTERVAL - diff);
return ISIS_OK;
}
@@ -2037,6 +2052,8 @@ lsp_tick (struct thread *thread)
{
for (ALL_LIST_ELEMENTS_RO (area->circuit_list, cnode, circuit))
{
+ if (circuit->state != C_STATE_UP)
+ continue;
for (ALL_LIST_ELEMENTS_RO (lsp_list, lspnode, lsp))
{
if (ISIS_CHECK_FLAG (lsp->SRMflags, circuit))
diff --git a/isisd/isis_lsp.h b/isisd/isis_lsp.h
index adbde78e..8d648d05 100644
--- a/isisd/isis_lsp.h
+++ b/isisd/isis_lsp.h
@@ -58,7 +58,6 @@ struct isis_lsp
#endif
/* used for 60 second counting when rem_lifetime is zero */
int age_out;
- struct isis_adjacency *adj;
/* FIXME: For now only topology LSP's use this. Is it helpful for others? */
struct isis_area *area;
struct tlvs tlv_data; /* Simplifies TLV access */
diff --git a/isisd/isis_main.c b/isisd/isis_main.c
index c5e824c1..15d85d6d 100644
--- a/isisd/isis_main.c
+++ b/isisd/isis_main.c
@@ -34,6 +34,7 @@
#include "privs.h"
#include "sigevent.h"
#include "filter.h"
+#include "zclient.h"
#include "isisd/dict.h"
#include "include-netbsd/iso.h"
@@ -72,16 +73,17 @@ struct zebra_privs_t isisd_privs = {
/* isisd options */
struct option longopts[] = {
- {"daemon", no_argument, NULL, 'd'},
+ {"daemon", no_argument, NULL, 'd'},
{"config_file", required_argument, NULL, 'f'},
- {"pid_file", required_argument, NULL, 'i'},
- {"vty_addr", required_argument, NULL, 'A'},
- {"vty_port", required_argument, NULL, 'P'},
- {"user", required_argument, NULL, 'u'},
- {"group", required_argument, NULL, 'g'},
- {"version", no_argument, NULL, 'v'},
- {"dryrun", no_argument, NULL, 'C'},
- {"help", no_argument, NULL, 'h'},
+ {"pid_file", required_argument, NULL, 'i'},
+ {"socket", required_argument, NULL, 'z'},
+ {"vty_addr", required_argument, NULL, 'A'},
+ {"vty_port", required_argument, NULL, 'P'},
+ {"user", required_argument, NULL, 'u'},
+ {"group", required_argument, NULL, 'g'},
+ {"version", no_argument, NULL, 'v'},
+ {"dryrun", no_argument, NULL, 'C'},
+ {"help", no_argument, NULL, 'h'},
{0}
};
@@ -130,6 +132,7 @@ Daemon which manages IS-IS routing\n\n\
-d, --daemon Runs in daemon mode\n\
-f, --config_file Set configuration file name\n\
-i, --pid_file Set process identifier file name\n\
+-z, --socket Set path of zebra socket\n\
-A, --vty_addr Set vty's bind address\n\
-P, --vty_port Set vty's port number\n\
-u, --user User to run as\n\
@@ -246,7 +249,7 @@ main (int argc, char **argv, char **envp)
/* Command line argument treatment. */
while (1)
{
- opt = getopt_long (argc, argv, "df:i:hA:p:P:u:g:vC", longopts, 0);
+ opt = getopt_long (argc, argv, "df:i:z:hA:p:P:u:g:vC", longopts, 0);
if (opt == EOF)
break;
@@ -264,6 +267,9 @@ main (int argc, char **argv, char **envp)
case 'i':
pid_file = optarg;
break;
+ case 'z':
+ zclient_serv_path_set (optarg);
+ break;
case 'A':
vty_addr = optarg;
break;
diff --git a/isisd/isis_pdu.c b/isisd/isis_pdu.c
index a2ab0649..d67df31b 100644
--- a/isisd/isis_pdu.c
+++ b/isisd/isis_pdu.c
@@ -29,10 +29,11 @@
#include "log.h"
#include "stream.h"
#include "vty.h"
-#include "hash.c"
+#include "hash.h"
#include "prefix.h"
#include "if.h"
#include "checksum.h"
+#include "md5.h"
#include "isisd/dict.h"
#include "isisd/include-netbsd/iso.h"
@@ -168,26 +169,38 @@ accept_level (int level, int circuit_t)
return retval;
}
+
+/*
+ * Verify authentication information
+ * Support cleartext and HMAC MD5 authentication
+ */
int
-authentication_check (struct isis_passwd *one, struct isis_passwd *theother)
+authentication_check (struct isis_passwd *remote, struct isis_passwd *local, struct isis_circuit* c)
{
- if (one->type != theother->type)
+ unsigned char digest[ISIS_AUTH_MD5_SIZE];
+
+ if (c->passwd.type)
{
- zlog_warn ("Unsupported authentication type %d", theother->type);
- return 1; /* Auth fail (different authentication types) */
- }
- switch (one->type)
+ switch (c->passwd.type)
{
+ case ISIS_PASSWD_TYPE_HMAC_MD5:
+ /* HMAC MD5 (RFC 3567) */
+ /* MD5 computation according to RFC 2104 */
+ hmac_md5(c->rcv_stream->data, stream_get_endp(c->rcv_stream), (unsigned char *) &(local->passwd), c->passwd.len, (unsigned char *) &digest);
+ return memcmp (digest, remote->passwd, ISIS_AUTH_MD5_SIZE);
+ break;
case ISIS_PASSWD_TYPE_CLEARTXT:
- if (one->len != theother->len)
+ /* Cleartext (ISO 10589) */
+ if (local->len != remote->len)
return 1; /* Auth fail () - passwd len mismatch */
- return memcmp (one->passwd, theother->passwd, one->len);
+ return memcmp (local->passwd, remote->passwd, local->len);
break;
default:
zlog_warn ("Unsupported authentication type");
break;
}
- return 0; /* Auth pass */
+ }
+ return 0; /* Authentication pass when no authentication is configured */
}
/*
@@ -372,7 +385,7 @@ process_p2p_hello (struct isis_circuit *circuit)
if (circuit->passwd.type)
{
if (!(found & TLVFLAG_AUTH_INFO) ||
- authentication_check (&circuit->passwd, &tlvs.auth_info))
+ authentication_check (&tlvs.auth_info, &circuit->passwd, circuit))
{
isis_event_auth_failure (circuit->area->area_tag,
"P2P hello authentication failure",
@@ -744,10 +757,11 @@ process_lan_hello (int level, struct isis_circuit *circuit, u_char * ssnpa)
goto out;
}
+ /* Verify authentication, either cleartext of HMAC MD5 */
if (circuit->passwd.type)
{
if (!(found & TLVFLAG_AUTH_INFO) ||
- authentication_check (&circuit->passwd, &tlvs.auth_info))
+ authentication_check (&tlvs.auth_info, &circuit->passwd, circuit))
{
isis_event_auth_failure (circuit->area->area_tag,
"LAN hello authentication failure",
@@ -1187,6 +1201,7 @@ dontcheckadj:
/* 7.3.15.1 e) 1) LSP newer than the one in db or no LSP in db */
if ((!lsp || comp == LSP_NEWER))
{
+ int regenerate = (lsp == NULL);
/* i */
if (lsp)
{
@@ -1221,7 +1236,6 @@ dontcheckadj:
ntohs (hdr->pdu_len), lsp0,
circuit->area);
lsp->level = level;
- lsp->adj = adj;
lsp_insert (lsp, circuit->area->lspdb[level - 1]);
/* ii */
ISIS_FLAGS_SET_ALL (lsp->SRMflags);
@@ -1232,6 +1246,9 @@ dontcheckadj:
if (circuit->circ_type != CIRCUIT_T_BROADCAST)
ISIS_SET_FLAG (lsp->SSNflags, circuit);
/* FIXME: v) */
+ if (regenerate && circuit->u.bc.is_dr[level - 1]) {
+ lsp_l1_pseudo_generate (circuit);
+ }
}
/* 7.3.15.1 e) 2) LSP equal to the one in db */
else if (comp == LSP_EQUAL)
@@ -1250,8 +1267,7 @@ dontcheckadj:
ISIS_CLEAR_FLAG (lsp->SSNflags, circuit);
}
}
- if (lsp)
- lsp->adj = adj;
+
return retval;
}
@@ -1414,7 +1430,7 @@ process_snp (int snp_type, int level, struct isis_circuit *circuit,
if (passwd->type)
{
if (!(found & TLVFLAG_AUTH_INFO) ||
- authentication_check (passwd, &tlvs.auth_info))
+ authentication_check (&tlvs.auth_info, passwd, circuit))
{
isis_event_auth_failure (circuit->area->area_tag,
"SNP authentication" " failure",
@@ -1781,6 +1797,9 @@ isis_receive (struct thread *thread)
circuit = THREAD_ARG (thread);
assert (circuit);
+ if (!circuit->area)
+ return ISIS_OK;
+
if (circuit->rcv_stream == NULL)
circuit->rcv_stream = stream_new (ISO_MTU (circuit));
else
@@ -1908,11 +1927,15 @@ send_hello (struct isis_circuit *circuit, int level)
struct isis_fixed_hdr fixed_hdr;
struct isis_lan_hello_hdr hello_hdr;
struct isis_p2p_hello_hdr p2p_hello_hdr;
+ char hmac_md5_hash[ISIS_AUTH_MD5_SIZE];
u_int32_t interval;
- unsigned long len_pointer, length;
+ unsigned long len_pointer, length, auth_tlv;
int retval;
+ if (circuit->state != C_STATE_UP || circuit->interface == NULL)
+ return ISIS_WARNING;
+
if (circuit->interface->mtu == 0)
{
zlog_warn ("circuit has zero MTU");
@@ -1940,6 +1963,9 @@ send_hello (struct isis_circuit *circuit, int level)
memset (&hello_hdr, 0, sizeof (struct isis_lan_hello_hdr));
interval = circuit->hello_multiplier[level - 1] *
circuit->hello_interval[level - 1];
+ /* If we are the DIS then hello interval is divided by three, as is the hold-timer */
+ if (circuit->u.bc.is_dr[level - 1])
+ interval=interval/3;
if (interval > USHRT_MAX)
interval = USHRT_MAX;
hello_hdr.circuit_t = circuit->circuit_is_type;
@@ -1976,34 +2002,36 @@ send_hello (struct isis_circuit *circuit, int level)
/*
* Then the variable length part
*/
+
/* add circuit password */
- if (circuit->passwd.type)
- if (tlv_add_authinfo (circuit->passwd.type, circuit->passwd.len,
+ /* Cleartext */
+ if (circuit->passwd.type == ISIS_PASSWD_TYPE_CLEARTXT)
+ if (tlv_add_authinfo (ISIS_PASSWD_TYPE_CLEARTXT, circuit->passwd.len,
circuit->passwd.passwd, circuit->snd_stream))
return ISIS_WARNING;
- /* Area Addresses TLV */
- assert (circuit->area);
- if (circuit->area->area_addrs && circuit->area->area_addrs->count > 0)
- if (tlv_add_area_addrs (circuit->area->area_addrs, circuit->snd_stream))
- return ISIS_WARNING;
- /* LAN Neighbors TLV */
- if (circuit->circ_type == CIRCUIT_T_BROADCAST)
+ /* or HMAC MD5 */
+ if (circuit->passwd.type == ISIS_PASSWD_TYPE_HMAC_MD5)
{
- if (level == 1 && circuit->u.bc.lan_neighs[0]->count > 0)
- if (tlv_add_lan_neighs (circuit->u.bc.lan_neighs[0],
- circuit->snd_stream))
- return ISIS_WARNING;
- if (level == 2 && circuit->u.bc.lan_neighs[1]->count > 0)
- if (tlv_add_lan_neighs (circuit->u.bc.lan_neighs[1],
- circuit->snd_stream))
- return ISIS_WARNING;
+ /* Remember where TLV is written so we can later overwrite the MD5 hash */
+ auth_tlv = stream_get_endp (circuit->snd_stream);
+ memset(&hmac_md5_hash, 0, ISIS_AUTH_MD5_SIZE);
+ if (tlv_add_authinfo (ISIS_PASSWD_TYPE_HMAC_MD5, ISIS_AUTH_MD5_SIZE,
+ hmac_md5_hash, circuit->snd_stream))
+ return ISIS_WARNING;
}
/* Protocols Supported TLV */
if (circuit->nlpids.count > 0)
if (tlv_add_nlpid (&circuit->nlpids, circuit->snd_stream))
return ISIS_WARNING;
+
+ /* Area Addresses TLV */
+ assert (circuit->area);
+ if (circuit->area->area_addrs && circuit->area->area_addrs->count > 0)
+ if (tlv_add_area_addrs (circuit->area->area_addrs, circuit->snd_stream))
+ return ISIS_WARNING;
+
/* IP interface Address TLV */
if (circuit->ip_router && circuit->ip_addrs && circuit->ip_addrs->count > 0)
if (tlv_add_ip_addrs (circuit->ip_addrs, circuit->snd_stream))
@@ -2017,6 +2045,22 @@ send_hello (struct isis_circuit *circuit, int level)
return ISIS_WARNING;
#endif /* HAVE_IPV6 */
+ /* Restart signaling, vendor C sends it too */
+ retval = add_tlv (211, 3, 0, circuit->snd_stream);
+
+ /* LAN Neighbors TLV */
+ if (circuit->circ_type == CIRCUIT_T_BROADCAST)
+ {
+ if (level == 1 && circuit->u.bc.lan_neighs[0]->count > 0)
+ if (tlv_add_lan_neighs (circuit->u.bc.lan_neighs[0],
+ circuit->snd_stream))
+ return ISIS_WARNING;
+ if (level == 2 && circuit->u.bc.lan_neighs[1]->count > 0)
+ if (tlv_add_lan_neighs (circuit->u.bc.lan_neighs[1],
+ circuit->snd_stream))
+ return ISIS_WARNING;
+ }
+
if (circuit->u.bc.pad_hellos)
if (tlv_add_padding (circuit->snd_stream))
return ISIS_WARNING;
@@ -2025,6 +2069,14 @@ send_hello (struct isis_circuit *circuit, int level)
/* Update PDU length */
stream_putw_at (circuit->snd_stream, len_pointer, (u_int16_t) length);
+ /* For HMAC MD5 we need to compute the md5 hash and store it */
+ if (circuit->passwd.type == ISIS_PASSWD_TYPE_HMAC_MD5)
+ {
+ hmac_md5(circuit->snd_stream->data, stream_get_endp(circuit->snd_stream), (unsigned char *) &circuit->passwd.passwd, circuit->passwd.len, (unsigned char *) &hmac_md5_hash);
+ /* Copy the hash into the stream */
+ memcpy(circuit->snd_stream->data+auth_tlv+3,hmac_md5_hash,ISIS_AUTH_MD5_SIZE);
+ }
+
retval = circuit->tx (circuit, level);
if (retval)
zlog_warn ("sending of LAN Level %d Hello failed", level);
@@ -2062,9 +2114,21 @@ send_lan_l1_hello (struct thread *thread)
{
struct isis_circuit *circuit;
int retval;
+ unsigned long next_hello;
circuit = THREAD_ARG (thread);
assert (circuit);
+
+ if (!circuit->area) {
+ return ISIS_OK;
+ }
+
+ /* Pseudonode sends hellos three times more than the other nodes */
+ if (circuit->u.bc.is_dr[0])
+ next_hello=circuit->hello_interval[0]/3+1;
+ else
+ next_hello=circuit->hello_interval[0];
+
circuit->u.bc.t_send_lan_hello[0] = NULL;
if (circuit->u.bc.run_dr_elect[0])
@@ -2075,7 +2139,7 @@ send_lan_l1_hello (struct thread *thread)
/* set next timer thread */
THREAD_TIMER_ON (master, circuit->u.bc.t_send_lan_hello[0],
send_lan_l1_hello, circuit,
- isis_jitter (circuit->hello_interval[0], IIH_JITTER));
+ isis_jitter (next_hello, IIH_JITTER));
return retval;
}
@@ -2085,9 +2149,21 @@ send_lan_l2_hello (struct thread *thread)
{
struct isis_circuit *circuit;
int retval;
+ unsigned long next_hello;
circuit = THREAD_ARG (thread);
assert (circuit);
+
+ if (!circuit->area) {
+ return ISIS_OK;
+ }
+
+ /* Pseudonode sends hellos three times more than the other nodes */
+ if (circuit->u.bc.is_dr[1])
+ next_hello=circuit->hello_interval[1]/3+1;
+ else
+ next_hello=circuit->hello_interval[1];
+
circuit->u.bc.t_send_lan_hello[1] = NULL;
if (circuit->u.bc.run_dr_elect[1])
@@ -2098,7 +2174,7 @@ send_lan_l2_hello (struct thread *thread)
/* set next timer thread */
THREAD_TIMER_ON (master, circuit->u.bc.t_send_lan_hello[1],
send_lan_l2_hello, circuit,
- isis_jitter (circuit->hello_interval[1], IIH_JITTER));
+ isis_jitter (next_hello, IIH_JITTER));
return retval;
}
@@ -2192,6 +2268,9 @@ send_csnp (struct isis_circuit *circuit, int level)
struct listnode *node;
struct isis_lsp *lsp;
+ if (circuit->state != C_STATE_UP || circuit->interface == NULL)
+ return ISIS_WARNING;
+
memset (start, 0x00, ISIS_SYS_ID_LEN + 2);
memset (stop, 0xff, ISIS_SYS_ID_LEN + 2);
@@ -2246,9 +2325,7 @@ send_l1_csnp (struct thread *thread)
circuit->t_send_csnp[0] = NULL;
if (circuit->circ_type == CIRCUIT_T_BROADCAST && circuit->u.bc.is_dr[0])
- {
send_csnp (circuit, 1);
- }
/* set next timer thread */
THREAD_TIMER_ON (master, circuit->t_send_csnp[0], send_l1_csnp, circuit,
isis_jitter (circuit->csnp_interval[0], CSNP_JITTER));
@@ -2268,9 +2345,7 @@ send_l2_csnp (struct thread *thread)
circuit->t_send_csnp[1] = NULL;
if (circuit->circ_type == CIRCUIT_T_BROADCAST && circuit->u.bc.is_dr[1])
- {
send_csnp (circuit, 2);
- }
/* set next timer thread */
THREAD_TIMER_ON (master, circuit->t_send_csnp[1], send_l2_csnp, circuit,
isis_jitter (circuit->csnp_interval[1], CSNP_JITTER));
@@ -2357,6 +2432,9 @@ send_psnp (int level, struct isis_circuit *circuit)
struct list *list = NULL;
struct listnode *node;
+ if (circuit->state != C_STATE_UP || circuit->interface == NULL)
+ return ISIS_WARNING;
+
if ((circuit->circ_type == CIRCUIT_T_BROADCAST &&
!circuit->u.bc.is_dr[level - 1]) ||
circuit->circ_type != CIRCUIT_T_BROADCAST)
@@ -2463,85 +2541,85 @@ send_lsp (struct thread *thread)
circuit = THREAD_ARG (thread);
assert (circuit);
- if (circuit->state == C_STATE_UP)
+ if (circuit->state != C_STATE_UP || circuit->interface == NULL)
+ return ISIS_WARNING;
+
+ lsp = listgetdata ((node = listhead (circuit->lsp_queue)));
+
+ /*
+ * Do not send if levels do not match
+ */
+ if (!(lsp->level & circuit->circuit_is_type))
+ goto dontsend;
+
+ /*
+ * Do not send if we do not have adjacencies in state up on the circuit
+ */
+ if (circuit->upadjcount[lsp->level - 1] == 0)
+ goto dontsend;
+ /* only send if it needs sending */
+ if ((time (NULL) - lsp->last_sent) >=
+ circuit->area->lsp_gen_interval[lsp->level - 1])
{
- lsp = listgetdata ((node = listhead (circuit->lsp_queue)));
- /*
- * Do not send if levels do not match
- */
- if (!(lsp->level & circuit->circuit_is_type))
- goto dontsend;
+ if (isis->debugs & DEBUG_UPDATE_PACKETS)
+ {
+ zlog_debug
+ ("ISIS-Upd (%s): Sent L%d LSP %s, seq 0x%08x, cksum 0x%04x,"
+ " lifetime %us on %s", circuit->area->area_tag, lsp->level,
+ rawlspid_print (lsp->lsp_header->lsp_id),
+ ntohl (lsp->lsp_header->seq_num),
+ ntohs (lsp->lsp_header->checksum),
+ ntohs (lsp->lsp_header->rem_lifetime),
+ circuit->interface->name);
+ }
+ /* copy our lsp to the send buffer */
+ stream_copy (circuit->snd_stream, lsp->pdu);
+
+ retval = circuit->tx (circuit, lsp->level);
/*
- * Do not send if we do not have adjacencies in state up on the circuit
+ * If the sending succeeded, we can del the lsp from circuits
+ * lsp_queue
*/
- if (circuit->upadjcount[lsp->level - 1] == 0)
- goto dontsend;
- /* only send if it needs sending */
- if ((time (NULL) - lsp->last_sent) >=
- circuit->area->lsp_gen_interval[lsp->level - 1])
+ if (retval == ISIS_OK)
{
-
- if (isis->debugs & DEBUG_UPDATE_PACKETS)
- {
- zlog_debug
- ("ISIS-Upd (%s): Sent L%d LSP %s, seq 0x%08x, cksum 0x%04x,"
- " lifetime %us on %s", circuit->area->area_tag, lsp->level,
- rawlspid_print (lsp->lsp_header->lsp_id),
- ntohl (lsp->lsp_header->seq_num),
- ntohs (lsp->lsp_header->checksum),
- ntohs (lsp->lsp_header->rem_lifetime),
- circuit->interface->name);
- }
- /* copy our lsp to the send buffer */
- stream_copy (circuit->snd_stream, lsp->pdu);
-
- retval = circuit->tx (circuit, lsp->level);
+ list_delete_node (circuit->lsp_queue, node);
/*
- * If the sending succeeded, we can del the lsp from circuits
- * lsp_queue
+ * On broadcast circuits also the SRMflag can be cleared
*/
- if (retval == ISIS_OK)
- {
- list_delete_node (circuit->lsp_queue, node);
+ if (circuit->circ_type == CIRCUIT_T_BROADCAST)
+ ISIS_CLEAR_FLAG (lsp->SRMflags, circuit);
+ if (flags_any_set (lsp->SRMflags) == 0)
+ {
/*
- * On broadcast circuits also the SRMflag can be cleared
+ * need to remember when we were last sent
*/
- if (circuit->circ_type == CIRCUIT_T_BROADCAST)
- ISIS_CLEAR_FLAG (lsp->SRMflags, circuit);
-
- if (flags_any_set (lsp->SRMflags) == 0)
- {
- /*
- * need to remember when we were last sent
- */
- lsp->last_sent = time (NULL);
- }
- }
- else
- {
- zlog_debug ("sending of level %d link state failed", lsp->level);
+ lsp->last_sent = time (NULL);
}
}
else
{
- /* my belief is that if it wasn't his time, the lsp can be removed
- * from the queue
- */
- dontsend:
- list_delete_node (circuit->lsp_queue, node);
+ zlog_debug ("sending of level %d link state failed", lsp->level);
}
-#if 0
- /*
- * If there are still LSPs send next one after lsp-interval (33 msecs)
+ }
+ else
+ {
+ /* my belief is that if it wasn't his time, the lsp can be removed
+ * from the queue
*/
- if (listcount (circuit->lsp_queue) > 0)
- thread_add_timer (master, send_lsp, circuit, 1);
-#endif
+ dontsend:
+ list_delete_node (circuit->lsp_queue, node);
}
+#if 0
+ /*
+ * If there are still LSPs send next one after lsp-interval (33 msecs)
+ */
+ if (listcount (circuit->lsp_queue) > 0)
+ thread_add_timer (master, send_lsp, circuit, 1);
+#endif
return retval;
}
diff --git a/isisd/isis_pdu.h b/isisd/isis_pdu.h
index 95c1ee4f..c4c38e22 100644
--- a/isisd/isis_pdu.h
+++ b/isisd/isis_pdu.h
@@ -258,8 +258,7 @@ int ack_lsp (struct isis_link_state_hdr *hdr,
void fill_fixed_hdr (struct isis_fixed_hdr *hdr, u_char pdu_type);
int send_hello (struct isis_circuit *circuit, int level);
-
-int authentication_check (struct isis_passwd *one,
- struct isis_passwd *theother);
+#define ISIS_AUTH_MD5_SIZE 16U
+int authentication_check (struct isis_passwd *remote, struct isis_passwd *local, struct isis_circuit *c);
#endif /* _ZEBRA_ISIS_PDU_H */
diff --git a/isisd/isis_pfpacket.c b/isisd/isis_pfpacket.c
index 9e4165e3..8a5c3ed0 100644
--- a/isisd/isis_pfpacket.c
+++ b/isisd/isis_pfpacket.c
@@ -232,6 +232,10 @@ isis_recv_pdu_bcast (struct isis_circuit *circuit, u_char * ssnpa)
LLC_LEN, MSG_PEEK,
(struct sockaddr *) &s_addr, (socklen_t *) &addr_len);
+ if (!circuit->area) {
+ return ISIS_OK;
+ }
+
if (bytesread < 0)
{
zlog_warn ("isis_recv_packet_bcast(): fd %d, recvfrom (): %s",
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
diff --git a/isisd/isis_tlv.c b/isisd/isis_tlv.c
index 94fa65ed..3fc717e3 100644
--- a/isisd/isis_tlv.c
+++ b/isisd/isis_tlv.c
@@ -446,6 +446,10 @@ parse_tlvs (char *areatag, u_char * stream, int size, u_int32_t * expected,
tlvs->auth_info.len = length-1;
pnt++;
memcpy (tlvs->auth_info.passwd, pnt, length - 1);
+ /* Fill authentication with 0 for later computation
+ * of MD5 (RFC 5304, 2)
+ */
+ memset (pnt, 0, length - 1);
pnt += length - 1;
}
else
@@ -741,7 +745,7 @@ add_tlv (u_char tag, u_char len, u_char * value, struct stream *stream)
stream_putc (stream, len); /* LENGTH */
stream_put (stream, value, (int) len); /* VALUE */
-#ifdef EXTREME_DEBUG
+#ifdef EXTREME_TLV_DEBUG
zlog_debug ("Added TLV %d len %d", tag, len);
#endif /* EXTREME DEBUG */
return ISIS_OK;
@@ -878,7 +882,7 @@ tlv_add_authinfo (char auth_type, char auth_len, u_char *auth_value,
{
u_char value[255];
u_char *pos = value;
- *pos++ = ISIS_PASSWD_TYPE_CLEARTXT;
+ *pos++ = auth_type;
memcpy (pos, auth_value, auth_len);
return add_tlv (AUTH_INFO, auth_len + 1, value, stream);
diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c
index 9ee5ffc5..d5ccef9e 100644
--- a/isisd/isis_zebra.c
+++ b/isisd/isis_zebra.c
@@ -274,6 +274,8 @@ isis_zebra_route_add_ipv4 (struct prefix *prefix,
stream_putc (stream, flags);
/* message */
stream_putc (stream, message);
+ /* SAFI */
+ stream_putw (stream, SAFI_UNICAST);
/* prefix information */
psize = PSIZE (prefix->prefixlen);
stream_putc (stream, prefix->prefixlen);
@@ -321,6 +323,7 @@ isis_zebra_route_del_ipv4 (struct prefix *prefix,
api.type = ZEBRA_ROUTE_ISIS;
api.flags = 0;
api.message = 0;
+ api.safi = SAFI_UNICAST;
prefix4.family = AF_INET;
prefix4.prefixlen = prefix->prefixlen;
prefix4.prefix = prefix->u.prefix4;
@@ -350,6 +353,7 @@ isis_zebra_route_add_ipv6 (struct prefix *prefix,
api.type = ZEBRA_ROUTE_ISIS;
api.flags = 0;
api.message = 0;
+ api.safi = SAFI_UNICAST;
SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
@@ -433,6 +437,7 @@ isis_zebra_route_del_ipv6 (struct prefix *prefix,
api.type = ZEBRA_ROUTE_ISIS;
api.flags = 0;
api.message = 0;
+ api.safi = SAFI_UNICAST;
SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
api.nexthop_num = listcount (route_info->nexthops6);
diff --git a/isisd/isisd.c b/isisd/isisd.c
index 1e84a1ce..20a32809 100644
--- a/isisd/isisd.c
+++ b/isisd/isisd.c
@@ -52,6 +52,7 @@
#include "isisd/isis_route.h"
#include "isisd/isis_zebra.h"
#include "isisd/isis_events.h"
+#include "isisd/isis_csm.h"
#ifdef TOPOLOGY_GENERATE
#include "spgrid.h"
@@ -217,21 +218,31 @@ isis_area_destroy (struct vty *vty, const char *area_tag)
for (ALL_LIST_ELEMENTS (area->circuit_list, node, nnode, circuit))
{
/* The fact that it's in circuit_list means that it was configured */
+ isis_csm_state_change (ISIS_DISABLE, circuit, area);
+ isis_circuit_down (circuit);
isis_circuit_deconfigure (circuit, area);
- isis_circuit_del (circuit);
}
list_delete (area->circuit_list);
}
listnode_delete (isis->area_list, area);
+
THREAD_TIMER_OFF (area->t_tick);
if (area->t_remove_aged)
thread_cancel (area->t_remove_aged);
THREAD_TIMER_OFF (area->t_lsp_refresh[0]);
THREAD_TIMER_OFF (area->t_lsp_refresh[1]);
+ THREAD_TIMER_OFF (area->spftree[0]->t_spf);
+ THREAD_TIMER_OFF (area->spftree[1]->t_spf);
+
+ THREAD_TIMER_OFF (area->t_lsp_l1_regenerate);
+ THREAD_TIMER_OFF (area->t_lsp_l2_regenerate);
+
XFREE (MTYPE_ISIS_AREA, area);
+ isis->sysid_set=0;
+
return CMD_SUCCESS;
}
diff --git a/isisd/isisd.h b/isisd/isisd.h
index 2277f27c..b17982e2 100644
--- a/isisd/isisd.h
+++ b/isisd/isisd.h
@@ -93,6 +93,8 @@ struct isis_area
struct flags flags;
struct thread *t_tick; /* LSP walker */
struct thread *t_remove_aged;
+ struct thread *t_lsp_l1_regenerate;
+ struct thread *t_lsp_l2_regenerate;
int lsp_regenerate_pending[ISIS_LEVELS];
struct thread *t_lsp_refresh[ISIS_LEVELS];
diff --git a/isisd/topology/.cvsignore b/isisd/topology/.cvsignore
deleted file mode 100644
index b0ae823b..00000000
--- a/isisd/topology/.cvsignore
+++ /dev/null
@@ -1,9 +0,0 @@
-Makefile
-Makefile.in
-*.o
-tags
-TAGS
-.deps
-.nfs*
-.arch-inventory
-.arch-ids