summaryrefslogtreecommitdiff
path: root/isisd/isis_pdu.c
diff options
context:
space:
mode:
Diffstat (limited to 'isisd/isis_pdu.c')
-rw-r--r--isisd/isis_pdu.c5310
1 files changed, 2606 insertions, 2704 deletions
diff --git a/isisd/isis_pdu.c b/isisd/isis_pdu.c
index d62682b10f..a3706179a6 100644
--- a/isisd/isis_pdu.c
+++ b/isisd/isis_pdu.c
@@ -1,19 +1,19 @@
/*
- * IS-IS Rout(e)ing protocol - isis_pdu.c
+ * IS-IS Rout(e)ing protocol - isis_pdu.c
* PDU processing
*
* Copyright (C) 2001,2002 Sampo Saaristo
- * Tampere University of Technology
+ * Tampere University of Technology
* Institute of Communications Engineering
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public Licenseas published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public Licenseas published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
- * This program is distributed in the hope that it will be useful,but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * This program is distributed in the hope that it will be useful,but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
@@ -69,253 +69,238 @@
/*
* Compares two sets of area addresses
*/
-static int
-area_match (struct list *left, struct list *right)
+static int area_match(struct list *left, struct list *right)
{
- struct area_addr *addr1, *addr2;
- struct listnode *node1, *node2;
-
- for (ALL_LIST_ELEMENTS_RO (left, node1, addr1))
- {
- for (ALL_LIST_ELEMENTS_RO (right, node2, addr2))
- {
- if (addr1->addr_len == addr2->addr_len &&
- !memcmp (addr1->area_addr, addr2->area_addr, (int) addr1->addr_len))
- return 1; /* match */
- }
- }
+ struct area_addr *addr1, *addr2;
+ struct listnode *node1, *node2;
+
+ for (ALL_LIST_ELEMENTS_RO(left, node1, addr1)) {
+ for (ALL_LIST_ELEMENTS_RO(right, node2, addr2)) {
+ if (addr1->addr_len == addr2->addr_len
+ && !memcmp(addr1->area_addr, addr2->area_addr,
+ (int)addr1->addr_len))
+ return 1; /* match */
+ }
+ }
- return 0; /* mismatch */
+ return 0; /* mismatch */
}
/*
- * Checks whether we should accept a PDU of given level
+ * Checks whether we should accept a PDU of given level
*/
-static int
-accept_level (int level, int circuit_t)
+static int accept_level(int level, int circuit_t)
{
- int retval = ((circuit_t & level) == level); /* simple approach */
+ int retval = ((circuit_t & level) == level); /* simple approach */
- return retval;
+ return retval;
}
/*
* Verify authentication information
* Support cleartext and HMAC MD5 authentication
*/
-static int
-authentication_check (struct isis_passwd *remote, struct isis_passwd *local,
- struct stream *stream, uint32_t auth_tlv_offset)
+static int authentication_check(struct isis_passwd *remote,
+ struct isis_passwd *local,
+ struct stream *stream, uint32_t auth_tlv_offset)
{
- unsigned char digest[ISIS_AUTH_MD5_SIZE];
-
- /* Auth fail () - passwd type mismatch */
- if (local->type != remote->type)
- return ISIS_ERROR;
-
- switch (local->type)
- {
- /* No authentication required */
- case ISIS_PASSWD_TYPE_UNUSED:
- break;
-
- /* Cleartext (ISO 10589) */
- case ISIS_PASSWD_TYPE_CLEARTXT:
- /* Auth fail () - passwd len mismatch */
- if (remote->len != local->len)
- return ISIS_ERROR;
- return memcmp (local->passwd, remote->passwd, local->len);
-
- /* HMAC MD5 (RFC 3567) */
- case ISIS_PASSWD_TYPE_HMAC_MD5:
- /* Auth fail () - passwd len mismatch */
- if (remote->len != ISIS_AUTH_MD5_SIZE)
- return ISIS_ERROR;
- /* Set the authentication value to 0 before the check */
- memset (STREAM_DATA (stream) + auth_tlv_offset + 3, 0,
- ISIS_AUTH_MD5_SIZE);
- /* Compute the digest */
- hmac_md5 (STREAM_DATA (stream), stream_get_endp (stream),
- (unsigned char *) &(local->passwd), local->len,
- (unsigned char *) &digest);
- /* Copy back the authentication value after the check */
- memcpy (STREAM_DATA (stream) + auth_tlv_offset + 3,
- remote->passwd, ISIS_AUTH_MD5_SIZE);
- return memcmp (digest, remote->passwd, ISIS_AUTH_MD5_SIZE);
-
- default:
- zlog_err ("Unsupported authentication type");
- return ISIS_ERROR;
- }
-
- /* Authentication pass when no authentication is configured */
- return ISIS_OK;
+ unsigned char digest[ISIS_AUTH_MD5_SIZE];
+
+ /* Auth fail () - passwd type mismatch */
+ if (local->type != remote->type)
+ return ISIS_ERROR;
+
+ switch (local->type) {
+ /* No authentication required */
+ case ISIS_PASSWD_TYPE_UNUSED:
+ break;
+
+ /* Cleartext (ISO 10589) */
+ case ISIS_PASSWD_TYPE_CLEARTXT:
+ /* Auth fail () - passwd len mismatch */
+ if (remote->len != local->len)
+ return ISIS_ERROR;
+ return memcmp(local->passwd, remote->passwd, local->len);
+
+ /* HMAC MD5 (RFC 3567) */
+ case ISIS_PASSWD_TYPE_HMAC_MD5:
+ /* Auth fail () - passwd len mismatch */
+ if (remote->len != ISIS_AUTH_MD5_SIZE)
+ return ISIS_ERROR;
+ /* Set the authentication value to 0 before the check */
+ memset(STREAM_DATA(stream) + auth_tlv_offset + 3, 0,
+ ISIS_AUTH_MD5_SIZE);
+ /* Compute the digest */
+ hmac_md5(STREAM_DATA(stream), stream_get_endp(stream),
+ (unsigned char *)&(local->passwd), local->len,
+ (unsigned char *)&digest);
+ /* Copy back the authentication value after the check */
+ memcpy(STREAM_DATA(stream) + auth_tlv_offset + 3,
+ remote->passwd, ISIS_AUTH_MD5_SIZE);
+ return memcmp(digest, remote->passwd, ISIS_AUTH_MD5_SIZE);
+
+ default:
+ zlog_err("Unsupported authentication type");
+ return ISIS_ERROR;
+ }
+
+ /* Authentication pass when no authentication is configured */
+ return ISIS_OK;
}
-static int
-lsp_authentication_check (struct stream *stream, struct isis_area *area,
- int level, struct isis_passwd *passwd)
+static int lsp_authentication_check(struct stream *stream,
+ struct isis_area *area, int level,
+ struct isis_passwd *passwd)
{
- struct isis_link_state_hdr *hdr;
- uint32_t expected = 0, found = 0, auth_tlv_offset = 0;
- uint16_t checksum, rem_lifetime, pdu_len;
- struct tlvs tlvs;
- int retval = ISIS_OK;
-
- hdr = (struct isis_link_state_hdr *) (STREAM_PNT (stream));
- pdu_len = ntohs (hdr->pdu_len);
- expected |= TLVFLAG_AUTH_INFO;
- auth_tlv_offset = stream_get_getp (stream) + ISIS_LSP_HDR_LEN;
- retval = parse_tlvs (area->area_tag, STREAM_PNT (stream) + ISIS_LSP_HDR_LEN,
- pdu_len - ISIS_FIXED_HDR_LEN - ISIS_LSP_HDR_LEN,
- &expected, &found, &tlvs, &auth_tlv_offset);
-
- if (retval != ISIS_OK)
- {
- zlog_err ("ISIS-Upd (%s): Parse failed L%d LSP %s, seq 0x%08x, "
- "cksum 0x%04x, lifetime %us, len %u",
- area->area_tag, level, rawlspid_print (hdr->lsp_id),
- ntohl (hdr->seq_num), ntohs (hdr->checksum),
- ntohs (hdr->rem_lifetime), pdu_len);
- if ((isis->debugs & DEBUG_UPDATE_PACKETS) &&
- (isis->debugs & DEBUG_PACKET_DUMP))
- zlog_dump_data (STREAM_DATA (stream), stream_get_endp (stream));
- return retval;
- }
+ struct isis_link_state_hdr *hdr;
+ uint32_t expected = 0, found = 0, auth_tlv_offset = 0;
+ uint16_t checksum, rem_lifetime, pdu_len;
+ struct tlvs tlvs;
+ int retval = ISIS_OK;
+
+ hdr = (struct isis_link_state_hdr *)(STREAM_PNT(stream));
+ pdu_len = ntohs(hdr->pdu_len);
+ expected |= TLVFLAG_AUTH_INFO;
+ auth_tlv_offset = stream_get_getp(stream) + ISIS_LSP_HDR_LEN;
+ retval = parse_tlvs(area->area_tag,
+ STREAM_PNT(stream) + ISIS_LSP_HDR_LEN,
+ pdu_len - ISIS_FIXED_HDR_LEN - ISIS_LSP_HDR_LEN,
+ &expected, &found, &tlvs, &auth_tlv_offset);
+
+ if (retval != ISIS_OK) {
+ zlog_err(
+ "ISIS-Upd (%s): Parse failed L%d LSP %s, seq 0x%08x, "
+ "cksum 0x%04x, lifetime %us, len %u",
+ area->area_tag, level, rawlspid_print(hdr->lsp_id),
+ ntohl(hdr->seq_num), ntohs(hdr->checksum),
+ ntohs(hdr->rem_lifetime), pdu_len);
+ if ((isis->debugs & DEBUG_UPDATE_PACKETS)
+ && (isis->debugs & DEBUG_PACKET_DUMP))
+ zlog_dump_data(STREAM_DATA(stream),
+ stream_get_endp(stream));
+ return retval;
+ }
- if (!(found & TLVFLAG_AUTH_INFO))
- {
- zlog_err ("No authentication tlv in LSP");
- return ISIS_ERROR;
- }
+ if (!(found & TLVFLAG_AUTH_INFO)) {
+ zlog_err("No authentication tlv in LSP");
+ return ISIS_ERROR;
+ }
- if (tlvs.auth_info.type != ISIS_PASSWD_TYPE_CLEARTXT &&
- tlvs.auth_info.type != ISIS_PASSWD_TYPE_HMAC_MD5)
- {
- zlog_err ("Unknown authentication type in LSP");
- return ISIS_ERROR;
- }
+ if (tlvs.auth_info.type != ISIS_PASSWD_TYPE_CLEARTXT
+ && tlvs.auth_info.type != ISIS_PASSWD_TYPE_HMAC_MD5) {
+ zlog_err("Unknown authentication type in LSP");
+ return ISIS_ERROR;
+ }
- /*
- * RFC 5304 set checksum and remaining lifetime to zero before
- * verification and reset to old values after verification.
- */
- checksum = hdr->checksum;
- rem_lifetime = hdr->rem_lifetime;
- hdr->checksum = 0;
- hdr->rem_lifetime = 0;
- retval = authentication_check (&tlvs.auth_info, passwd, stream,
- auth_tlv_offset);
- hdr->checksum = checksum;
- hdr->rem_lifetime = rem_lifetime;
-
- return retval;
+ /*
+ * RFC 5304 set checksum and remaining lifetime to zero before
+ * verification and reset to old values after verification.
+ */
+ checksum = hdr->checksum;
+ rem_lifetime = hdr->rem_lifetime;
+ hdr->checksum = 0;
+ hdr->rem_lifetime = 0;
+ retval = authentication_check(&tlvs.auth_info, passwd, stream,
+ auth_tlv_offset);
+ hdr->checksum = checksum;
+ hdr->rem_lifetime = rem_lifetime;
+
+ return retval;
}
/*
* Processing helper functions
*/
-static void
-del_addr (void *val)
+static void del_addr(void *val)
{
- XFREE (MTYPE_ISIS_TMP, val);
+ XFREE(MTYPE_ISIS_TMP, val);
}
-static void
-tlvs_to_adj_area_addrs (struct tlvs *tlvs, struct isis_adjacency *adj)
+static void tlvs_to_adj_area_addrs(struct tlvs *tlvs,
+ struct isis_adjacency *adj)
{
- struct listnode *node;
- struct area_addr *area_addr, *malloced;
+ struct listnode *node;
+ struct area_addr *area_addr, *malloced;
- if (adj->area_addrs)
- {
- adj->area_addrs->del = del_addr;
- list_delete (adj->area_addrs);
- }
- adj->area_addrs = list_new ();
- if (tlvs->area_addrs)
- {
- for (ALL_LIST_ELEMENTS_RO (tlvs->area_addrs, node, area_addr))
- {
- malloced = XMALLOC (MTYPE_ISIS_TMP, sizeof (struct area_addr));
- memcpy (malloced, area_addr, sizeof (struct area_addr));
- listnode_add (adj->area_addrs, malloced);
- }
- }
+ if (adj->area_addrs) {
+ adj->area_addrs->del = del_addr;
+ list_delete(adj->area_addrs);
+ }
+ adj->area_addrs = list_new();
+ if (tlvs->area_addrs) {
+ for (ALL_LIST_ELEMENTS_RO(tlvs->area_addrs, node, area_addr)) {
+ malloced = XMALLOC(MTYPE_ISIS_TMP,
+ sizeof(struct area_addr));
+ memcpy(malloced, area_addr, sizeof(struct area_addr));
+ listnode_add(adj->area_addrs, malloced);
+ }
+ }
}
-static int
-tlvs_to_adj_nlpids (struct tlvs *tlvs, struct isis_adjacency *adj)
+static int tlvs_to_adj_nlpids(struct tlvs *tlvs, struct isis_adjacency *adj)
{
- int i;
- struct nlpids *tlv_nlpids;
+ int i;
+ struct nlpids *tlv_nlpids;
- if (tlvs->nlpids)
- {
+ if (tlvs->nlpids) {
- tlv_nlpids = tlvs->nlpids;
- if (tlv_nlpids->count > array_size (adj->nlpids.nlpids))
- return 1;
+ tlv_nlpids = tlvs->nlpids;
+ if (tlv_nlpids->count > array_size(adj->nlpids.nlpids))
+ return 1;
- adj->nlpids.count = tlv_nlpids->count;
+ adj->nlpids.count = tlv_nlpids->count;
- for (i = 0; i < tlv_nlpids->count; i++)
- {
- adj->nlpids.nlpids[i] = tlv_nlpids->nlpids[i];
+ for (i = 0; i < tlv_nlpids->count; i++) {
+ adj->nlpids.nlpids[i] = tlv_nlpids->nlpids[i];
+ }
}
- }
- return 0;
+ return 0;
}
-static void
-tlvs_to_adj_ipv4_addrs (struct tlvs *tlvs, struct isis_adjacency *adj)
+static void tlvs_to_adj_ipv4_addrs(struct tlvs *tlvs,
+ struct isis_adjacency *adj)
{
- struct listnode *node;
- struct in_addr *ipv4_addr, *malloced;
+ struct listnode *node;
+ struct in_addr *ipv4_addr, *malloced;
- if (adj->ipv4_addrs)
- {
- adj->ipv4_addrs->del = del_addr;
- list_delete (adj->ipv4_addrs);
- }
- adj->ipv4_addrs = list_new ();
- if (tlvs->ipv4_addrs)
- {
- for (ALL_LIST_ELEMENTS_RO (tlvs->ipv4_addrs, node, ipv4_addr))
- {
- malloced = XMALLOC (MTYPE_ISIS_TMP, sizeof (struct in_addr));
- memcpy (malloced, ipv4_addr, sizeof (struct in_addr));
- listnode_add (adj->ipv4_addrs, malloced);
- }
- }
+ if (adj->ipv4_addrs) {
+ adj->ipv4_addrs->del = del_addr;
+ list_delete(adj->ipv4_addrs);
+ }
+ adj->ipv4_addrs = list_new();
+ if (tlvs->ipv4_addrs) {
+ for (ALL_LIST_ELEMENTS_RO(tlvs->ipv4_addrs, node, ipv4_addr)) {
+ malloced =
+ XMALLOC(MTYPE_ISIS_TMP, sizeof(struct in_addr));
+ memcpy(malloced, ipv4_addr, sizeof(struct in_addr));
+ listnode_add(adj->ipv4_addrs, malloced);
+ }
+ }
}
-static void
-tlvs_to_adj_ipv6_addrs (struct tlvs *tlvs, struct isis_adjacency *adj)
+static void tlvs_to_adj_ipv6_addrs(struct tlvs *tlvs,
+ struct isis_adjacency *adj)
{
- struct listnode *node;
- struct in6_addr *ipv6_addr, *malloced;
-
- if (adj->ipv6_addrs)
- {
- adj->ipv6_addrs->del = del_addr;
- list_delete (adj->ipv6_addrs);
- }
- adj->ipv6_addrs = list_new ();
- if (tlvs->ipv6_addrs)
- {
- for (ALL_LIST_ELEMENTS_RO (tlvs->ipv6_addrs, node, ipv6_addr))
- {
- malloced = XMALLOC (MTYPE_ISIS_TMP, sizeof (struct in6_addr));
- memcpy (malloced, ipv6_addr, sizeof (struct in6_addr));
- listnode_add (adj->ipv6_addrs, malloced);
- }
- }
+ struct listnode *node;
+ struct in6_addr *ipv6_addr, *malloced;
+ if (adj->ipv6_addrs) {
+ adj->ipv6_addrs->del = del_addr;
+ list_delete(adj->ipv6_addrs);
+ }
+ adj->ipv6_addrs = list_new();
+ if (tlvs->ipv6_addrs) {
+ for (ALL_LIST_ELEMENTS_RO(tlvs->ipv6_addrs, node, ipv6_addr)) {
+ malloced = XMALLOC(MTYPE_ISIS_TMP,
+ sizeof(struct in6_addr));
+ memcpy(malloced, ipv6_addr, sizeof(struct in6_addr));
+ listnode_add(adj->ipv6_addrs, malloced);
+ }
+ }
}
/*
- * RECEIVE SIDE
+ * RECEIVE SIDE
*/
/*
@@ -324,584 +309,559 @@ tlvs_to_adj_ipv6_addrs (struct tlvs *tlvs, struct isis_adjacency *adj)
* Section 8.2.5 - Receiving point-to-point IIH PDUs
*
*/
-static int
-process_p2p_hello (struct isis_circuit *circuit)
+static int process_p2p_hello(struct isis_circuit *circuit)
{
- int retval = ISIS_OK;
- struct isis_p2p_hello_hdr *hdr;
- struct isis_adjacency *adj;
- u_int32_t expected = 0, found = 0, auth_tlv_offset = 0;
- uint16_t pdu_len;
- struct tlvs tlvs;
- int v4_usable = 0, v6_usable = 0;
-
- if (isis->debugs & DEBUG_ADJ_PACKETS)
- {
- zlog_debug ("ISIS-Adj (%s): Rcvd P2P IIH on %s, cirType %s, cirID %u",
- circuit->area->area_tag, circuit->interface->name,
- circuit_t2string (circuit->is_type), circuit->circuit_id);
- if (isis->debugs & DEBUG_PACKET_DUMP)
- zlog_dump_data (STREAM_DATA (circuit->rcv_stream),
- stream_get_endp (circuit->rcv_stream));
- }
-
- if (circuit->circ_type != CIRCUIT_T_P2P)
- {
- zlog_warn ("p2p hello on non p2p circuit");
- return ISIS_WARNING;
- }
-
- if ((stream_get_endp (circuit->rcv_stream) -
- stream_get_getp (circuit->rcv_stream)) < ISIS_P2PHELLO_HDRLEN)
- {
- zlog_warn ("Packet too short");
- return ISIS_WARNING;
- }
-
- /* 8.2.5.1 PDU acceptance tests */
-
- /* 8.2.5.1 a) external domain untrue */
- /* FIXME: not useful at all? */
-
- /* 8.2.5.1 b) ID Length mismatch */
- /* checked at the handle_pdu */
-
- /* 8.2.5.2 IIH PDU Processing */
-
- /* 8.2.5.2 a) 1) Maximum Area Addresses */
- /* Already checked, and can also be ommited */
-
- /*
- * Get the header
- */
- hdr = (struct isis_p2p_hello_hdr *) STREAM_PNT (circuit->rcv_stream);
- pdu_len = ntohs (hdr->pdu_len);
-
- if (pdu_len < (ISIS_FIXED_HDR_LEN + ISIS_P2PHELLO_HDRLEN) ||
- pdu_len > ISO_MTU(circuit) ||
- pdu_len > stream_get_endp (circuit->rcv_stream))
- {
- zlog_warn ("ISIS-Adj (%s): Rcvd P2P IIH from (%s) with "
- "invalid pdu length %d",
- circuit->area->area_tag, circuit->interface->name, pdu_len);
- return ISIS_WARNING;
- }
-
- /*
- * Set the stream endp to PDU length, ignoring additional padding
- * introduced by transport chips.
- */
- if (pdu_len < stream_get_endp (circuit->rcv_stream))
- stream_set_endp (circuit->rcv_stream, pdu_len);
-
- stream_forward_getp (circuit->rcv_stream, ISIS_P2PHELLO_HDRLEN);
-
- /*
- * Lets get the TLVS now
- */
- expected |= TLVFLAG_AREA_ADDRS;
- expected |= TLVFLAG_AUTH_INFO;
- expected |= TLVFLAG_NLPID;
- expected |= TLVFLAG_IPV4_ADDR;
- expected |= TLVFLAG_IPV6_ADDR;
- expected |= TLVFLAG_MT_ROUTER_INFORMATION;
-
- auth_tlv_offset = stream_get_getp (circuit->rcv_stream);
- retval = parse_tlvs (circuit->area->area_tag,
- STREAM_PNT (circuit->rcv_stream),
- pdu_len - ISIS_P2PHELLO_HDRLEN - ISIS_FIXED_HDR_LEN,
- &expected, &found, &tlvs, &auth_tlv_offset);
-
- if (retval > ISIS_WARNING)
- {
- zlog_warn ("parse_tlvs() failed");
- free_tlvs (&tlvs);
- return retval;
- };
-
- if (!(found & TLVFLAG_AREA_ADDRS))
- {
- zlog_warn ("No Area addresses TLV in P2P IS to IS hello");
- free_tlvs (&tlvs);
- return ISIS_WARNING;
- }
+ int retval = ISIS_OK;
+ struct isis_p2p_hello_hdr *hdr;
+ struct isis_adjacency *adj;
+ u_int32_t expected = 0, found = 0, auth_tlv_offset = 0;
+ uint16_t pdu_len;
+ struct tlvs tlvs;
+ int v4_usable = 0, v6_usable = 0;
+
+ if (isis->debugs & DEBUG_ADJ_PACKETS) {
+ zlog_debug(
+ "ISIS-Adj (%s): Rcvd P2P IIH on %s, cirType %s, cirID %u",
+ circuit->area->area_tag, circuit->interface->name,
+ circuit_t2string(circuit->is_type),
+ circuit->circuit_id);
+ if (isis->debugs & DEBUG_PACKET_DUMP)
+ zlog_dump_data(STREAM_DATA(circuit->rcv_stream),
+ stream_get_endp(circuit->rcv_stream));
+ }
- if (!(found & TLVFLAG_NLPID))
- {
- zlog_warn ("No supported protocols TLV in P2P IS to IS hello");
- free_tlvs (&tlvs);
- return ISIS_WARNING;
- }
+ if (circuit->circ_type != CIRCUIT_T_P2P) {
+ zlog_warn("p2p hello on non p2p circuit");
+ return ISIS_WARNING;
+ }
- /* 8.2.5.1 c) Authentication */
- if (circuit->passwd.type)
- {
- if (!(found & TLVFLAG_AUTH_INFO) ||
- authentication_check (&tlvs.auth_info, &circuit->passwd,
- circuit->rcv_stream, auth_tlv_offset))
- {
- isis_event_auth_failure (circuit->area->area_tag,
- "P2P hello authentication failure",
- hdr->source_id);
- free_tlvs (&tlvs);
- return ISIS_OK;
- }
- }
+ if ((stream_get_endp(circuit->rcv_stream)
+ - stream_get_getp(circuit->rcv_stream))
+ < ISIS_P2PHELLO_HDRLEN) {
+ zlog_warn("Packet too short");
+ return ISIS_WARNING;
+ }
- /*
- * check if both ends have an IPv4 address
- */
- if (circuit->ip_addrs && listcount(circuit->ip_addrs)
- && tlvs.ipv4_addrs && listcount(tlvs.ipv4_addrs))
- {
- v4_usable = 1;
- }
+ /* 8.2.5.1 PDU acceptance tests */
- if (found & TLVFLAG_IPV6_ADDR)
- {
- /* TBA: check that we have a linklocal ourselves? */
- struct listnode *node;
- struct in6_addr *ip;
- for (ALL_LIST_ELEMENTS_RO (tlvs.ipv6_addrs, node, ip))
- if (IN6_IS_ADDR_LINKLOCAL (ip))
- {
- v6_usable = 1;
- break;
- }
-
- if (!v6_usable)
- zlog_warn ("ISIS-Adj: IPv6 addresses present but no link-local "
- "in P2P IIH from %s\n", circuit->interface->name);
- }
+ /* 8.2.5.1 a) external domain untrue */
+ /* FIXME: not useful at all? */
- if (!(found & (TLVFLAG_IPV4_ADDR | TLVFLAG_IPV6_ADDR)))
- zlog_warn ("ISIS-Adj: neither IPv4 nor IPv6 addr in P2P IIH from %s\n",
- circuit->interface->name);
+ /* 8.2.5.1 b) ID Length mismatch */
+ /* checked at the handle_pdu */
- if (!v6_usable && !v4_usable)
- {
- free_tlvs (&tlvs);
- return ISIS_WARNING;
- }
+ /* 8.2.5.2 IIH PDU Processing */
- /*
- * it's own p2p IIH PDU - discard
- */
- if (!memcmp (hdr->source_id, isis->sysid, ISIS_SYS_ID_LEN))
- {
- zlog_warn ("ISIS-Adj (%s): it's own IIH PDU - discarded",
- circuit->area->area_tag);
- free_tlvs (&tlvs);
- return ISIS_WARNING;
- }
+ /* 8.2.5.2 a) 1) Maximum Area Addresses */
+ /* Already checked, and can also be ommited */
- /*
- * My interpertation of the ISO, if no adj exists we will create one for
- * the circuit
- */
- adj = circuit->u.p2p.neighbor;
- /* If an adjacency exists, check it is with the source of the hello
- * packets */
- if (adj)
- {
- if (memcmp(hdr->source_id, adj->sysid, ISIS_SYS_ID_LEN))
- {
- zlog_debug("hello source and adjacency do not match, set adj down\n");
- isis_adj_state_change (adj, ISIS_ADJ_DOWN, "adj do not exist");
- return 0;
- }
- }
- if (!adj || adj->level != hdr->circuit_t)
- {
- if (!adj)
- {
- adj = isis_new_adj (hdr->source_id, NULL, hdr->circuit_t, circuit);
- if (adj == NULL)
- return ISIS_ERROR;
- }
- else
- {
- adj->level = hdr->circuit_t;
- }
- circuit->u.p2p.neighbor = adj;
- /* Build lsp with the new neighbor entry when a new
- * adjacency is formed. Set adjacency circuit type to
- * IIH PDU header circuit type before lsp is regenerated
- * when an adjacency is up. This will result in the new
- * adjacency entry getting added to the lsp tlv neighbor list.
- */
- adj->circuit_t = hdr->circuit_t;
- isis_adj_state_change (adj, ISIS_ADJ_INITIALIZING, NULL);
- adj->sys_type = ISIS_SYSTYPE_UNKNOWN;
- }
+ /*
+ * Get the header
+ */
+ hdr = (struct isis_p2p_hello_hdr *)STREAM_PNT(circuit->rcv_stream);
+ pdu_len = ntohs(hdr->pdu_len);
- /* 8.2.6 Monitoring point-to-point adjacencies */
- adj->hold_time = ntohs (hdr->hold_time);
- adj->last_upd = time (NULL);
+ if (pdu_len < (ISIS_FIXED_HDR_LEN + ISIS_P2PHELLO_HDRLEN)
+ || pdu_len > ISO_MTU(circuit)
+ || pdu_len > stream_get_endp(circuit->rcv_stream)) {
+ zlog_warn(
+ "ISIS-Adj (%s): Rcvd P2P IIH from (%s) with "
+ "invalid pdu length %d",
+ circuit->area->area_tag, circuit->interface->name,
+ pdu_len);
+ return ISIS_WARNING;
+ }
- /* we do this now because the adj may not survive till the end... */
- tlvs_to_adj_area_addrs (&tlvs, adj);
+ /*
+ * Set the stream endp to PDU length, ignoring additional padding
+ * introduced by transport chips.
+ */
+ if (pdu_len < stream_get_endp(circuit->rcv_stream))
+ stream_set_endp(circuit->rcv_stream, pdu_len);
+
+ stream_forward_getp(circuit->rcv_stream, ISIS_P2PHELLO_HDRLEN);
+
+ /*
+ * Lets get the TLVS now
+ */
+ expected |= TLVFLAG_AREA_ADDRS;
+ expected |= TLVFLAG_AUTH_INFO;
+ expected |= TLVFLAG_NLPID;
+ expected |= TLVFLAG_IPV4_ADDR;
+ expected |= TLVFLAG_IPV6_ADDR;
+ expected |= TLVFLAG_MT_ROUTER_INFORMATION;
+
+ auth_tlv_offset = stream_get_getp(circuit->rcv_stream);
+ retval = parse_tlvs(circuit->area->area_tag,
+ STREAM_PNT(circuit->rcv_stream),
+ pdu_len - ISIS_P2PHELLO_HDRLEN - ISIS_FIXED_HDR_LEN,
+ &expected, &found, &tlvs, &auth_tlv_offset);
+
+ if (retval > ISIS_WARNING) {
+ zlog_warn("parse_tlvs() failed");
+ free_tlvs(&tlvs);
+ return retval;
+ };
+
+ if (!(found & TLVFLAG_AREA_ADDRS)) {
+ zlog_warn("No Area addresses TLV in P2P IS to IS hello");
+ free_tlvs(&tlvs);
+ return ISIS_WARNING;
+ }
- /* which protocol are spoken ??? */
- if (tlvs_to_adj_nlpids (&tlvs, adj))
- {
- free_tlvs (&tlvs);
- return ISIS_WARNING;
- }
+ if (!(found & TLVFLAG_NLPID)) {
+ zlog_warn("No supported protocols TLV in P2P IS to IS hello");
+ free_tlvs(&tlvs);
+ return ISIS_WARNING;
+ }
- /* we need to copy addresses to the adj */
- if (found & TLVFLAG_IPV4_ADDR)
- tlvs_to_adj_ipv4_addrs (&tlvs, adj);
+ /* 8.2.5.1 c) Authentication */
+ if (circuit->passwd.type) {
+ if (!(found & TLVFLAG_AUTH_INFO)
+ || authentication_check(&tlvs.auth_info, &circuit->passwd,
+ circuit->rcv_stream,
+ auth_tlv_offset)) {
+ isis_event_auth_failure(
+ circuit->area->area_tag,
+ "P2P hello authentication failure",
+ hdr->source_id);
+ free_tlvs(&tlvs);
+ return ISIS_OK;
+ }
+ }
- /* Update MPLS TE Remote IP address parameter if possible */
- if (IS_MPLS_TE(isisMplsTE) && circuit->mtc && IS_CIRCUIT_TE(circuit->mtc))
- if (adj->ipv4_addrs != NULL && listcount(adj->ipv4_addrs) != 0)
- {
- struct in_addr *ip_addr;
- ip_addr = (struct in_addr *)listgetdata ((struct listnode *)listhead (adj->ipv4_addrs));
- set_circuitparams_rmt_ipaddr (circuit->mtc, *ip_addr);
- }
+ /*
+ * check if both ends have an IPv4 address
+ */
+ if (circuit->ip_addrs && listcount(circuit->ip_addrs) && tlvs.ipv4_addrs
+ && listcount(tlvs.ipv4_addrs)) {
+ v4_usable = 1;
+ }
- if (found & TLVFLAG_IPV6_ADDR)
- tlvs_to_adj_ipv6_addrs (&tlvs, adj);
+ if (found & TLVFLAG_IPV6_ADDR) {
+ /* TBA: check that we have a linklocal ourselves? */
+ struct listnode *node;
+ struct in6_addr *ip;
+ for (ALL_LIST_ELEMENTS_RO(tlvs.ipv6_addrs, node, ip))
+ if (IN6_IS_ADDR_LINKLOCAL(ip)) {
+ v6_usable = 1;
+ break;
+ }
+
+ if (!v6_usable)
+ zlog_warn(
+ "ISIS-Adj: IPv6 addresses present but no link-local "
+ "in P2P IIH from %s\n",
+ circuit->interface->name);
+ }
- bool mt_set_changed = tlvs_to_adj_mt_set(&tlvs, v4_usable, v6_usable, adj);
+ if (!(found & (TLVFLAG_IPV4_ADDR | TLVFLAG_IPV6_ADDR)))
+ zlog_warn(
+ "ISIS-Adj: neither IPv4 nor IPv6 addr in P2P IIH from %s\n",
+ circuit->interface->name);
- /* lets take care of the expiry */
- THREAD_TIMER_OFF (adj->t_expire);
- thread_add_timer(master, isis_adj_expire, adj, (long)adj->hold_time,
- &adj->t_expire);
+ if (!v6_usable && !v4_usable) {
+ free_tlvs(&tlvs);
+ return ISIS_WARNING;
+ }
- /* 8.2.5.2 a) a match was detected */
- if (area_match (circuit->area->area_addrs, tlvs.area_addrs))
- {
- /* 8.2.5.2 a) 2) If the system is L1 - table 5 */
- if (circuit->area->is_type == IS_LEVEL_1)
- {
- switch (hdr->circuit_t)
- {
- case IS_LEVEL_1:
- case IS_LEVEL_1_AND_2:
- if (adj->adj_state != ISIS_ADJ_UP)
- {
- /* (4) adj state up */
- isis_adj_state_change (adj, ISIS_ADJ_UP, NULL);
- /* (5) adj usage level 1 */
- adj->adj_usage = ISIS_ADJ_LEVEL1;
- }
- else if (adj->adj_usage == ISIS_ADJ_LEVEL1)
- {
- ; /* accept */
- }
- break;
- case IS_LEVEL_2:
- if (adj->adj_state != ISIS_ADJ_UP)
- {
- /* (7) reject - wrong system type event */
- zlog_warn ("wrongSystemType");
- free_tlvs (&tlvs);
- return ISIS_WARNING; /* Reject */
- }
- else if (adj->adj_usage == ISIS_ADJ_LEVEL1)
- {
- /* (6) down - wrong system */
- isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Wrong System");
- }
- break;
- }
+ /*
+ * it's own p2p IIH PDU - discard
+ */
+ if (!memcmp(hdr->source_id, isis->sysid, ISIS_SYS_ID_LEN)) {
+ zlog_warn("ISIS-Adj (%s): it's own IIH PDU - discarded",
+ circuit->area->area_tag);
+ free_tlvs(&tlvs);
+ return ISIS_WARNING;
}
- /* 8.2.5.2 a) 3) If the system is L1L2 - table 6 */
- if (circuit->area->is_type == IS_LEVEL_1_AND_2)
- {
- switch (hdr->circuit_t)
- {
- case IS_LEVEL_1:
- if (adj->adj_state != ISIS_ADJ_UP)
- {
- /* (6) adj state up */
- isis_adj_state_change (adj, ISIS_ADJ_UP, NULL);
- /* (7) adj usage level 1 */
- adj->adj_usage = ISIS_ADJ_LEVEL1;
- }
- else if (adj->adj_usage == ISIS_ADJ_LEVEL1)
- {
- ; /* accept */
+ /*
+ * My interpertation of the ISO, if no adj exists we will create one for
+ * the circuit
+ */
+ adj = circuit->u.p2p.neighbor;
+ /* If an adjacency exists, check it is with the source of the hello
+ * packets */
+ if (adj) {
+ if (memcmp(hdr->source_id, adj->sysid, ISIS_SYS_ID_LEN)) {
+ zlog_debug(
+ "hello source and adjacency do not match, set adj down\n");
+ isis_adj_state_change(adj, ISIS_ADJ_DOWN,
+ "adj do not exist");
+ return 0;
}
- else if ((adj->adj_usage == ISIS_ADJ_LEVEL1AND2) ||
- (adj->adj_usage == ISIS_ADJ_LEVEL2))
- {
- /* (8) down - wrong system */
- isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Wrong System");
- }
- break;
- case IS_LEVEL_2:
- if (adj->adj_state != ISIS_ADJ_UP)
- {
- /* (6) adj state up */
- isis_adj_state_change (adj, ISIS_ADJ_UP, NULL);
- /* (9) adj usage level 2 */
- adj->adj_usage = ISIS_ADJ_LEVEL2;
- }
- else if ((adj->adj_usage == ISIS_ADJ_LEVEL1) ||
- (adj->adj_usage == ISIS_ADJ_LEVEL1AND2))
- {
- /* (8) down - wrong system */
- isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Wrong System");
- }
- else if (adj->adj_usage == ISIS_ADJ_LEVEL2)
- {
- ; /* Accept */
- }
- break;
- case IS_LEVEL_1_AND_2:
- if (adj->adj_state != ISIS_ADJ_UP)
- {
- /* (6) adj state up */
- isis_adj_state_change (adj, ISIS_ADJ_UP, NULL);
- /* (10) adj usage level 1 */
- adj->adj_usage = ISIS_ADJ_LEVEL1AND2;
- }
- else if ((adj->adj_usage == ISIS_ADJ_LEVEL1) ||
- (adj->adj_usage == ISIS_ADJ_LEVEL2))
- {
- /* (8) down - wrong system */
- isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Wrong System");
- }
- else if (adj->adj_usage == ISIS_ADJ_LEVEL1AND2)
- {
- ; /* Accept */
+ }
+ if (!adj || adj->level != hdr->circuit_t) {
+ if (!adj) {
+ adj = isis_new_adj(hdr->source_id, NULL, hdr->circuit_t,
+ circuit);
+ if (adj == NULL)
+ return ISIS_ERROR;
+ } else {
+ adj->level = hdr->circuit_t;
}
- break;
- }
+ circuit->u.p2p.neighbor = adj;
+ /* Build lsp with the new neighbor entry when a new
+ * adjacency is formed. Set adjacency circuit type to
+ * IIH PDU header circuit type before lsp is regenerated
+ * when an adjacency is up. This will result in the new
+ * adjacency entry getting added to the lsp tlv neighbor list.
+ */
+ adj->circuit_t = hdr->circuit_t;
+ isis_adj_state_change(adj, ISIS_ADJ_INITIALIZING, NULL);
+ adj->sys_type = ISIS_SYSTYPE_UNKNOWN;
}
- /* 8.2.5.2 a) 4) If the system is L2 - table 7 */
- if (circuit->area->is_type == IS_LEVEL_2)
- {
- switch (hdr->circuit_t)
- {
- case IS_LEVEL_1:
- if (adj->adj_state != ISIS_ADJ_UP)
- {
- /* (5) reject - wrong system type event */
- zlog_warn ("wrongSystemType");
- free_tlvs (&tlvs);
- return ISIS_WARNING; /* Reject */
- }
- else if ((adj->adj_usage == ISIS_ADJ_LEVEL1AND2) ||
- (adj->adj_usage == ISIS_ADJ_LEVEL2))
- {
- /* (6) down - wrong system */
- isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Wrong System");
- }
- break;
- case IS_LEVEL_1_AND_2:
- case IS_LEVEL_2:
- if (adj->adj_state != ISIS_ADJ_UP)
- {
- /* (7) adj state up */
- isis_adj_state_change (adj, ISIS_ADJ_UP, NULL);
- /* (8) adj usage level 2 */
- adj->adj_usage = ISIS_ADJ_LEVEL2;
- }
- else if (adj->adj_usage == ISIS_ADJ_LEVEL1AND2)
- {
- /* (6) down - wrong system */
- isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Wrong System");
- }
- else if (adj->adj_usage == ISIS_ADJ_LEVEL2)
- {
- ; /* Accept */
- }
- break;
- }
+ /* 8.2.6 Monitoring point-to-point adjacencies */
+ adj->hold_time = ntohs(hdr->hold_time);
+ adj->last_upd = time(NULL);
+
+ /* we do this now because the adj may not survive till the end... */
+ tlvs_to_adj_area_addrs(&tlvs, adj);
+
+ /* which protocol are spoken ??? */
+ if (tlvs_to_adj_nlpids(&tlvs, adj)) {
+ free_tlvs(&tlvs);
+ return ISIS_WARNING;
}
- }
- /* 8.2.5.2 b) if no match was detected */
- else if (listcount (circuit->area->area_addrs) > 0)
- {
- if (circuit->area->is_type == IS_LEVEL_1)
- {
- /* 8.2.5.2 b) 1) is_type L1 and adj is not up */
- if (adj->adj_state != ISIS_ADJ_UP)
- {
- isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Area Mismatch");
- /* 8.2.5.2 b) 2)is_type L1 and adj is up */
- }
- else
- {
- isis_adj_state_change (adj, ISIS_ADJ_DOWN,
- "Down - Area Mismatch");
- }
- }
- /* 8.2.5.2 b 3 If the system is L2 or L1L2 - table 8 */
- else
- {
- switch (hdr->circuit_t)
- {
- case IS_LEVEL_1:
- if (adj->adj_state != ISIS_ADJ_UP)
- {
- /* (6) reject - Area Mismatch event */
- zlog_warn ("AreaMismatch");
- free_tlvs (&tlvs);
- return ISIS_WARNING; /* Reject */
- }
- else if (adj->adj_usage == ISIS_ADJ_LEVEL1)
- {
- /* (7) down - area mismatch */
- isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Area Mismatch");
+ /* we need to copy addresses to the adj */
+ if (found & TLVFLAG_IPV4_ADDR)
+ tlvs_to_adj_ipv4_addrs(&tlvs, adj);
+
+ /* Update MPLS TE Remote IP address parameter if possible */
+ if (IS_MPLS_TE(isisMplsTE) && circuit->mtc
+ && IS_CIRCUIT_TE(circuit->mtc))
+ if (adj->ipv4_addrs != NULL
+ && listcount(adj->ipv4_addrs) != 0) {
+ struct in_addr *ip_addr;
+ ip_addr = (struct in_addr *)listgetdata(
+ (struct listnode *)listhead(adj->ipv4_addrs));
+ set_circuitparams_rmt_ipaddr(circuit->mtc, *ip_addr);
}
- else if ((adj->adj_usage == ISIS_ADJ_LEVEL1AND2) ||
- (adj->adj_usage == ISIS_ADJ_LEVEL2))
- {
- /* (7) down - wrong system */
- isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Wrong System");
+
+ if (found & TLVFLAG_IPV6_ADDR)
+ tlvs_to_adj_ipv6_addrs(&tlvs, adj);
+
+ bool mt_set_changed =
+ tlvs_to_adj_mt_set(&tlvs, v4_usable, v6_usable, adj);
+
+ /* lets take care of the expiry */
+ THREAD_TIMER_OFF(adj->t_expire);
+ thread_add_timer(master, isis_adj_expire, adj, (long)adj->hold_time,
+ &adj->t_expire);
+
+ /* 8.2.5.2 a) a match was detected */
+ if (area_match(circuit->area->area_addrs, tlvs.area_addrs)) {
+ /* 8.2.5.2 a) 2) If the system is L1 - table 5 */
+ if (circuit->area->is_type == IS_LEVEL_1) {
+ switch (hdr->circuit_t) {
+ case IS_LEVEL_1:
+ case IS_LEVEL_1_AND_2:
+ if (adj->adj_state != ISIS_ADJ_UP) {
+ /* (4) adj state up */
+ isis_adj_state_change(adj, ISIS_ADJ_UP,
+ NULL);
+ /* (5) adj usage level 1 */
+ adj->adj_usage = ISIS_ADJ_LEVEL1;
+ } else if (adj->adj_usage == ISIS_ADJ_LEVEL1) {
+ ; /* accept */
+ }
+ break;
+ case IS_LEVEL_2:
+ if (adj->adj_state != ISIS_ADJ_UP) {
+ /* (7) reject - wrong system type event
+ */
+ zlog_warn("wrongSystemType");
+ free_tlvs(&tlvs);
+ return ISIS_WARNING; /* Reject */
+ } else if (adj->adj_usage == ISIS_ADJ_LEVEL1) {
+ /* (6) down - wrong system */
+ isis_adj_state_change(adj,
+ ISIS_ADJ_DOWN,
+ "Wrong System");
+ }
+ break;
+ }
}
- break;
- case IS_LEVEL_1_AND_2:
- case IS_LEVEL_2:
- if (adj->adj_state != ISIS_ADJ_UP)
- {
- /* (8) adj state up */
- isis_adj_state_change (adj, ISIS_ADJ_UP, NULL);
- /* (9) adj usage level 2 */
- adj->adj_usage = ISIS_ADJ_LEVEL2;
+
+ /* 8.2.5.2 a) 3) If the system is L1L2 - table 6 */
+ if (circuit->area->is_type == IS_LEVEL_1_AND_2) {
+ switch (hdr->circuit_t) {
+ case IS_LEVEL_1:
+ if (adj->adj_state != ISIS_ADJ_UP) {
+ /* (6) adj state up */
+ isis_adj_state_change(adj, ISIS_ADJ_UP,
+ NULL);
+ /* (7) adj usage level 1 */
+ adj->adj_usage = ISIS_ADJ_LEVEL1;
+ } else if (adj->adj_usage == ISIS_ADJ_LEVEL1) {
+ ; /* accept */
+ } else if ((adj->adj_usage
+ == ISIS_ADJ_LEVEL1AND2)
+ || (adj->adj_usage
+ == ISIS_ADJ_LEVEL2)) {
+ /* (8) down - wrong system */
+ isis_adj_state_change(adj,
+ ISIS_ADJ_DOWN,
+ "Wrong System");
+ }
+ break;
+ case IS_LEVEL_2:
+ if (adj->adj_state != ISIS_ADJ_UP) {
+ /* (6) adj state up */
+ isis_adj_state_change(adj, ISIS_ADJ_UP,
+ NULL);
+ /* (9) adj usage level 2 */
+ adj->adj_usage = ISIS_ADJ_LEVEL2;
+ } else if ((adj->adj_usage == ISIS_ADJ_LEVEL1)
+ || (adj->adj_usage
+ == ISIS_ADJ_LEVEL1AND2)) {
+ /* (8) down - wrong system */
+ isis_adj_state_change(adj,
+ ISIS_ADJ_DOWN,
+ "Wrong System");
+ } else if (adj->adj_usage == ISIS_ADJ_LEVEL2) {
+ ; /* Accept */
+ }
+ break;
+ case IS_LEVEL_1_AND_2:
+ if (adj->adj_state != ISIS_ADJ_UP) {
+ /* (6) adj state up */
+ isis_adj_state_change(adj, ISIS_ADJ_UP,
+ NULL);
+ /* (10) adj usage level 1 */
+ adj->adj_usage = ISIS_ADJ_LEVEL1AND2;
+ } else if ((adj->adj_usage == ISIS_ADJ_LEVEL1)
+ || (adj->adj_usage
+ == ISIS_ADJ_LEVEL2)) {
+ /* (8) down - wrong system */
+ isis_adj_state_change(adj,
+ ISIS_ADJ_DOWN,
+ "Wrong System");
+ } else if (adj->adj_usage
+ == ISIS_ADJ_LEVEL1AND2) {
+ ; /* Accept */
+ }
+ break;
+ }
}
- else if (adj->adj_usage == ISIS_ADJ_LEVEL1)
- {
- /* (7) down - wrong system */
- isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Wrong System");
+
+ /* 8.2.5.2 a) 4) If the system is L2 - table 7 */
+ if (circuit->area->is_type == IS_LEVEL_2) {
+ switch (hdr->circuit_t) {
+ case IS_LEVEL_1:
+ if (adj->adj_state != ISIS_ADJ_UP) {
+ /* (5) reject - wrong system type event
+ */
+ zlog_warn("wrongSystemType");
+ free_tlvs(&tlvs);
+ return ISIS_WARNING; /* Reject */
+ } else if ((adj->adj_usage
+ == ISIS_ADJ_LEVEL1AND2)
+ || (adj->adj_usage
+ == ISIS_ADJ_LEVEL2)) {
+ /* (6) down - wrong system */
+ isis_adj_state_change(adj,
+ ISIS_ADJ_DOWN,
+ "Wrong System");
+ }
+ break;
+ case IS_LEVEL_1_AND_2:
+ case IS_LEVEL_2:
+ if (adj->adj_state != ISIS_ADJ_UP) {
+ /* (7) adj state up */
+ isis_adj_state_change(adj, ISIS_ADJ_UP,
+ NULL);
+ /* (8) adj usage level 2 */
+ adj->adj_usage = ISIS_ADJ_LEVEL2;
+ } else if (adj->adj_usage
+ == ISIS_ADJ_LEVEL1AND2) {
+ /* (6) down - wrong system */
+ isis_adj_state_change(adj,
+ ISIS_ADJ_DOWN,
+ "Wrong System");
+ } else if (adj->adj_usage == ISIS_ADJ_LEVEL2) {
+ ; /* Accept */
+ }
+ break;
+ }
}
- else if (adj->adj_usage == ISIS_ADJ_LEVEL1AND2)
- {
- if (hdr->circuit_t == IS_LEVEL_2)
- {
- /* (7) down - wrong system */
- isis_adj_state_change (adj, ISIS_ADJ_DOWN,
- "Wrong System");
- }
- else
- {
- /* (7) down - area mismatch */
- isis_adj_state_change (adj, ISIS_ADJ_DOWN,
- "Area Mismatch");
- }
+ }
+ /* 8.2.5.2 b) if no match was detected */
+ else if (listcount(circuit->area->area_addrs) > 0) {
+ if (circuit->area->is_type == IS_LEVEL_1) {
+ /* 8.2.5.2 b) 1) is_type L1 and adj is not up */
+ if (adj->adj_state != ISIS_ADJ_UP) {
+ isis_adj_state_change(adj, ISIS_ADJ_DOWN,
+ "Area Mismatch");
+ /* 8.2.5.2 b) 2)is_type L1 and adj is up */
+ } else {
+ isis_adj_state_change(adj, ISIS_ADJ_DOWN,
+ "Down - Area Mismatch");
+ }
}
- else if (adj->adj_usage == ISIS_ADJ_LEVEL2)
- {
- ; /* Accept */
+ /* 8.2.5.2 b 3 If the system is L2 or L1L2 - table 8 */
+ else {
+ switch (hdr->circuit_t) {
+ case IS_LEVEL_1:
+ if (adj->adj_state != ISIS_ADJ_UP) {
+ /* (6) reject - Area Mismatch event */
+ zlog_warn("AreaMismatch");
+ free_tlvs(&tlvs);
+ return ISIS_WARNING; /* Reject */
+ } else if (adj->adj_usage == ISIS_ADJ_LEVEL1) {
+ /* (7) down - area mismatch */
+ isis_adj_state_change(adj,
+ ISIS_ADJ_DOWN,
+ "Area Mismatch");
+
+ } else if ((adj->adj_usage
+ == ISIS_ADJ_LEVEL1AND2)
+ || (adj->adj_usage
+ == ISIS_ADJ_LEVEL2)) {
+ /* (7) down - wrong system */
+ isis_adj_state_change(adj,
+ ISIS_ADJ_DOWN,
+ "Wrong System");
+ }
+ break;
+ case IS_LEVEL_1_AND_2:
+ case IS_LEVEL_2:
+ if (adj->adj_state != ISIS_ADJ_UP) {
+ /* (8) adj state up */
+ isis_adj_state_change(adj, ISIS_ADJ_UP,
+ NULL);
+ /* (9) adj usage level 2 */
+ adj->adj_usage = ISIS_ADJ_LEVEL2;
+ } else if (adj->adj_usage == ISIS_ADJ_LEVEL1) {
+ /* (7) down - wrong system */
+ isis_adj_state_change(adj,
+ ISIS_ADJ_DOWN,
+ "Wrong System");
+ } else if (adj->adj_usage
+ == ISIS_ADJ_LEVEL1AND2) {
+ if (hdr->circuit_t == IS_LEVEL_2) {
+ /* (7) down - wrong system */
+ isis_adj_state_change(
+ adj, ISIS_ADJ_DOWN,
+ "Wrong System");
+ } else {
+ /* (7) down - area mismatch */
+ isis_adj_state_change(
+ adj, ISIS_ADJ_DOWN,
+ "Area Mismatch");
+ }
+ } else if (adj->adj_usage == ISIS_ADJ_LEVEL2) {
+ ; /* Accept */
+ }
+ break;
+ }
}
- break;
- }
+ } else {
+ /* down - area mismatch */
+ isis_adj_state_change(adj, ISIS_ADJ_DOWN, "Area Mismatch");
}
- }
- else
- {
- /* down - area mismatch */
- isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Area Mismatch");
- }
- if (adj->adj_state == ISIS_ADJ_UP && mt_set_changed)
- {
- lsp_regenerate_schedule(adj->circuit->area,
- isis_adj_usage2levels(adj->adj_usage), 0);
- }
-
- /* 8.2.5.2 c) if the action was up - comparing circuit IDs */
- /* FIXME - Missing parts */
+ if (adj->adj_state == ISIS_ADJ_UP && mt_set_changed) {
+ lsp_regenerate_schedule(adj->circuit->area,
+ isis_adj_usage2levels(adj->adj_usage),
+ 0);
+ }
- /* some of my own understanding of the ISO, why the heck does
- * it not say what should I change the system_type to...
- */
- switch (adj->adj_usage)
- {
- case ISIS_ADJ_LEVEL1:
- adj->sys_type = ISIS_SYSTYPE_L1_IS;
- break;
- case ISIS_ADJ_LEVEL2:
- adj->sys_type = ISIS_SYSTYPE_L2_IS;
- break;
- case ISIS_ADJ_LEVEL1AND2:
- adj->sys_type = ISIS_SYSTYPE_L2_IS;
- break;
- case ISIS_ADJ_NONE:
- adj->sys_type = ISIS_SYSTYPE_UNKNOWN;
- break;
- }
+ /* 8.2.5.2 c) if the action was up - comparing circuit IDs */
+ /* FIXME - Missing parts */
+
+ /* some of my own understanding of the ISO, why the heck does
+ * it not say what should I change the system_type to...
+ */
+ switch (adj->adj_usage) {
+ case ISIS_ADJ_LEVEL1:
+ adj->sys_type = ISIS_SYSTYPE_L1_IS;
+ break;
+ case ISIS_ADJ_LEVEL2:
+ adj->sys_type = ISIS_SYSTYPE_L2_IS;
+ break;
+ case ISIS_ADJ_LEVEL1AND2:
+ adj->sys_type = ISIS_SYSTYPE_L2_IS;
+ break;
+ case ISIS_ADJ_NONE:
+ adj->sys_type = ISIS_SYSTYPE_UNKNOWN;
+ break;
+ }
- if (isis->debugs & DEBUG_ADJ_PACKETS)
- {
- zlog_debug ("ISIS-Adj (%s): Rcvd P2P IIH from (%s), cir type %s,"
- " cir id %02d, length %d",
- circuit->area->area_tag, circuit->interface->name,
- circuit_t2string (circuit->is_type),
- circuit->circuit_id, pdu_len);
- }
+ if (isis->debugs & DEBUG_ADJ_PACKETS) {
+ zlog_debug(
+ "ISIS-Adj (%s): Rcvd P2P IIH from (%s), cir type %s,"
+ " cir id %02d, length %d",
+ circuit->area->area_tag, circuit->interface->name,
+ circuit_t2string(circuit->is_type), circuit->circuit_id,
+ pdu_len);
+ }
- free_tlvs (&tlvs);
+ free_tlvs(&tlvs);
- return retval;
+ return retval;
}
/*
* Process IS-IS LAN Level 1/2 Hello PDU
*/
-static int
-process_lan_hello (int level, struct isis_circuit *circuit, const u_char *ssnpa)
+static int process_lan_hello(int level, struct isis_circuit *circuit,
+ const u_char *ssnpa)
{
- int retval = ISIS_OK;
- struct isis_lan_hello_hdr hdr;
- struct isis_adjacency *adj;
- u_int32_t expected = 0, found = 0, auth_tlv_offset = 0;
- struct tlvs tlvs;
- u_char *snpa;
- struct listnode *node;
- int v4_usable = 0, v6_usable = 0;
-
- if (isis->debugs & DEBUG_ADJ_PACKETS)
- {
- zlog_debug ("ISIS-Adj (%s): Rcvd L%d LAN IIH on %s, cirType %s, "
- "cirID %u",
- circuit->area->area_tag, level, circuit->interface->name,
- circuit_t2string (circuit->is_type), circuit->circuit_id);
- if (isis->debugs & DEBUG_PACKET_DUMP)
- zlog_dump_data (STREAM_DATA (circuit->rcv_stream),
- stream_get_endp (circuit->rcv_stream));
- }
+ int retval = ISIS_OK;
+ struct isis_lan_hello_hdr hdr;
+ struct isis_adjacency *adj;
+ u_int32_t expected = 0, found = 0, auth_tlv_offset = 0;
+ struct tlvs tlvs;
+ u_char *snpa;
+ struct listnode *node;
+ int v4_usable = 0, v6_usable = 0;
+
+ if (isis->debugs & DEBUG_ADJ_PACKETS) {
+ zlog_debug(
+ "ISIS-Adj (%s): Rcvd L%d LAN IIH on %s, cirType %s, "
+ "cirID %u",
+ circuit->area->area_tag, level,
+ circuit->interface->name,
+ circuit_t2string(circuit->is_type),
+ circuit->circuit_id);
+ if (isis->debugs & DEBUG_PACKET_DUMP)
+ zlog_dump_data(STREAM_DATA(circuit->rcv_stream),
+ stream_get_endp(circuit->rcv_stream));
+ }
- if (circuit->circ_type != CIRCUIT_T_BROADCAST)
- {
- zlog_warn ("lan hello on non broadcast circuit");
- return ISIS_WARNING;
- }
+ if (circuit->circ_type != CIRCUIT_T_BROADCAST) {
+ zlog_warn("lan hello on non broadcast circuit");
+ return ISIS_WARNING;
+ }
- if ((stream_get_endp (circuit->rcv_stream) -
- stream_get_getp (circuit->rcv_stream)) < ISIS_LANHELLO_HDRLEN)
- {
- zlog_warn ("Packet too short");
- return ISIS_WARNING;
- }
+ if ((stream_get_endp(circuit->rcv_stream)
+ - stream_get_getp(circuit->rcv_stream))
+ < ISIS_LANHELLO_HDRLEN) {
+ zlog_warn("Packet too short");
+ return ISIS_WARNING;
+ }
- if (circuit->ext_domain)
- {
- zlog_debug ("level %d LAN Hello received over circuit with "
- "externalDomain = true", level);
- return ISIS_WARNING;
- }
+ if (circuit->ext_domain) {
+ zlog_debug(
+ "level %d LAN Hello received over circuit with "
+ "externalDomain = true",
+ level);
+ return ISIS_WARNING;
+ }
- if (!accept_level (level, circuit->is_type))
- {
- if (isis->debugs & DEBUG_ADJ_PACKETS)
- {
- zlog_debug ("ISIS-Adj (%s): Interface level mismatch, %s",
- circuit->area->area_tag, circuit->interface->name);
+ if (!accept_level(level, circuit->is_type)) {
+ if (isis->debugs & DEBUG_ADJ_PACKETS) {
+ zlog_debug(
+ "ISIS-Adj (%s): Interface level mismatch, %s",
+ circuit->area->area_tag,
+ circuit->interface->name);
+ }
+ return ISIS_WARNING;
}
- return ISIS_WARNING;
- }
#if 0
/* Cisco's debug message compatability */
@@ -915,319 +875,304 @@ process_lan_hello (int level, struct isis_circuit *circuit, const u_char *ssnpa)
return ISIS_WARNING;
}
#endif
- /*
- * Fill the header
- */
- hdr.circuit_t = stream_getc (circuit->rcv_stream);
- stream_get (hdr.source_id, circuit->rcv_stream, ISIS_SYS_ID_LEN);
- hdr.hold_time = stream_getw (circuit->rcv_stream);
- hdr.pdu_len = stream_getw (circuit->rcv_stream);
- hdr.prio = stream_getc (circuit->rcv_stream);
- stream_get (hdr.lan_id, circuit->rcv_stream, ISIS_SYS_ID_LEN + 1);
-
- if (hdr.pdu_len < (ISIS_FIXED_HDR_LEN + ISIS_LANHELLO_HDRLEN) ||
- hdr.pdu_len > ISO_MTU(circuit) ||
- hdr.pdu_len > stream_get_endp (circuit->rcv_stream))
- {
- zlog_warn ("ISIS-Adj (%s): Rcvd LAN IIH from (%s) with "
- "invalid pdu length %d",
- circuit->area->area_tag, circuit->interface->name,
- hdr.pdu_len);
- return ISIS_WARNING;
- }
-
- /*
- * Set the stream endp to PDU length, ignoring additional padding
- * introduced by transport chips.
- */
- if (hdr.pdu_len < stream_get_endp (circuit->rcv_stream))
- stream_set_endp (circuit->rcv_stream, hdr.pdu_len);
-
- if (hdr.circuit_t != IS_LEVEL_1 &&
- hdr.circuit_t != IS_LEVEL_2 &&
- hdr.circuit_t != IS_LEVEL_1_AND_2 &&
- (level & hdr.circuit_t) == 0)
- {
- zlog_err ("Level %d LAN Hello with Circuit Type %d", level,
- hdr.circuit_t);
- return ISIS_ERROR;
- }
+ /*
+ * Fill the header
+ */
+ hdr.circuit_t = stream_getc(circuit->rcv_stream);
+ stream_get(hdr.source_id, circuit->rcv_stream, ISIS_SYS_ID_LEN);
+ hdr.hold_time = stream_getw(circuit->rcv_stream);
+ hdr.pdu_len = stream_getw(circuit->rcv_stream);
+ hdr.prio = stream_getc(circuit->rcv_stream);
+ stream_get(hdr.lan_id, circuit->rcv_stream, ISIS_SYS_ID_LEN + 1);
+
+ if (hdr.pdu_len < (ISIS_FIXED_HDR_LEN + ISIS_LANHELLO_HDRLEN)
+ || hdr.pdu_len > ISO_MTU(circuit)
+ || hdr.pdu_len > stream_get_endp(circuit->rcv_stream)) {
+ zlog_warn(
+ "ISIS-Adj (%s): Rcvd LAN IIH from (%s) with "
+ "invalid pdu length %d",
+ circuit->area->area_tag, circuit->interface->name,
+ hdr.pdu_len);
+ return ISIS_WARNING;
+ }
- /*
- * Then get the tlvs
- */
- expected |= TLVFLAG_AUTH_INFO;
- expected |= TLVFLAG_AREA_ADDRS;
- expected |= TLVFLAG_LAN_NEIGHS;
- expected |= TLVFLAG_NLPID;
- expected |= TLVFLAG_IPV4_ADDR;
- expected |= TLVFLAG_IPV6_ADDR;
- expected |= TLVFLAG_MT_ROUTER_INFORMATION;
-
- auth_tlv_offset = stream_get_getp (circuit->rcv_stream);
- retval = parse_tlvs (circuit->area->area_tag,
- STREAM_PNT (circuit->rcv_stream),
- hdr.pdu_len - ISIS_LANHELLO_HDRLEN - ISIS_FIXED_HDR_LEN,
- &expected, &found, &tlvs,
- &auth_tlv_offset);
-
- if (retval > ISIS_WARNING)
- {
- zlog_warn ("parse_tlvs() failed");
- goto out;
- }
+ /*
+ * Set the stream endp to PDU length, ignoring additional padding
+ * introduced by transport chips.
+ */
+ if (hdr.pdu_len < stream_get_endp(circuit->rcv_stream))
+ stream_set_endp(circuit->rcv_stream, hdr.pdu_len);
+
+ if (hdr.circuit_t != IS_LEVEL_1 && hdr.circuit_t != IS_LEVEL_2
+ && hdr.circuit_t != IS_LEVEL_1_AND_2
+ && (level & hdr.circuit_t) == 0) {
+ zlog_err("Level %d LAN Hello with Circuit Type %d", level,
+ hdr.circuit_t);
+ return ISIS_ERROR;
+ }
- if (!(found & TLVFLAG_AREA_ADDRS))
- {
- zlog_warn ("No Area addresses TLV in Level %d LAN IS to IS hello",
- level);
- retval = ISIS_WARNING;
- goto out;
- }
+ /*
+ * Then get the tlvs
+ */
+ expected |= TLVFLAG_AUTH_INFO;
+ expected |= TLVFLAG_AREA_ADDRS;
+ expected |= TLVFLAG_LAN_NEIGHS;
+ expected |= TLVFLAG_NLPID;
+ expected |= TLVFLAG_IPV4_ADDR;
+ expected |= TLVFLAG_IPV6_ADDR;
+ expected |= TLVFLAG_MT_ROUTER_INFORMATION;
+
+ auth_tlv_offset = stream_get_getp(circuit->rcv_stream);
+ retval = parse_tlvs(
+ circuit->area->area_tag, STREAM_PNT(circuit->rcv_stream),
+ hdr.pdu_len - ISIS_LANHELLO_HDRLEN - ISIS_FIXED_HDR_LEN,
+ &expected, &found, &tlvs, &auth_tlv_offset);
+
+ if (retval > ISIS_WARNING) {
+ zlog_warn("parse_tlvs() failed");
+ goto out;
+ }
- if (!(found & TLVFLAG_NLPID))
- {
- zlog_warn ("No supported protocols TLV in Level %d LAN IS to IS hello",
- level);
- retval = ISIS_WARNING;
- goto out;
- }
+ if (!(found & TLVFLAG_AREA_ADDRS)) {
+ zlog_warn(
+ "No Area addresses TLV in Level %d LAN IS to IS hello",
+ level);
+ retval = ISIS_WARNING;
+ goto out;
+ }
- /* Verify authentication, either cleartext of HMAC MD5 */
- if (circuit->passwd.type)
- {
- if (!(found & TLVFLAG_AUTH_INFO) ||
- authentication_check (&tlvs.auth_info, &circuit->passwd,
- circuit->rcv_stream, auth_tlv_offset))
- {
- isis_event_auth_failure (circuit->area->area_tag,
- "LAN hello authentication failure",
- hdr.source_id);
- retval = ISIS_WARNING;
- goto out;
- }
- }
+ if (!(found & TLVFLAG_NLPID)) {
+ zlog_warn(
+ "No supported protocols TLV in Level %d LAN IS to IS hello",
+ level);
+ retval = ISIS_WARNING;
+ goto out;
+ }
- if (!memcmp (hdr.source_id, isis->sysid, ISIS_SYS_ID_LEN))
- {
- zlog_warn ("ISIS-Adj (%s): duplicate system ID on interface %s",
- circuit->area->area_tag, circuit->interface->name);
- return ISIS_WARNING;
- }
+ /* Verify authentication, either cleartext of HMAC MD5 */
+ if (circuit->passwd.type) {
+ if (!(found & TLVFLAG_AUTH_INFO)
+ || authentication_check(&tlvs.auth_info, &circuit->passwd,
+ circuit->rcv_stream,
+ auth_tlv_offset)) {
+ isis_event_auth_failure(
+ circuit->area->area_tag,
+ "LAN hello authentication failure",
+ hdr.source_id);
+ retval = ISIS_WARNING;
+ goto out;
+ }
+ }
- /*
- * Accept the level 1 adjacency only if a match between local and
- * remote area addresses is found
- */
- if (listcount (circuit->area->area_addrs) == 0 ||
- (level == IS_LEVEL_1 &&
- area_match (circuit->area->area_addrs, tlvs.area_addrs) == 0))
- {
- if (isis->debugs & DEBUG_ADJ_PACKETS)
- {
- zlog_debug ("ISIS-Adj (%s): Area mismatch, level %d IIH on %s",
- circuit->area->area_tag, level,
- circuit->interface->name);
+ if (!memcmp(hdr.source_id, isis->sysid, ISIS_SYS_ID_LEN)) {
+ zlog_warn("ISIS-Adj (%s): duplicate system ID on interface %s",
+ circuit->area->area_tag, circuit->interface->name);
+ return ISIS_WARNING;
}
- retval = ISIS_OK;
- goto out;
- }
- /*
- * it's own IIH PDU - discard silently
- */
- if (!memcmp (circuit->u.bc.snpa, ssnpa, ETH_ALEN))
- {
- zlog_debug ("ISIS-Adj (%s): it's own IIH PDU - discarded",
- circuit->area->area_tag);
+ /*
+ * Accept the level 1 adjacency only if a match between local and
+ * remote area addresses is found
+ */
+ if (listcount(circuit->area->area_addrs) == 0
+ || (level == IS_LEVEL_1
+ && area_match(circuit->area->area_addrs, tlvs.area_addrs)
+ == 0)) {
+ if (isis->debugs & DEBUG_ADJ_PACKETS) {
+ zlog_debug(
+ "ISIS-Adj (%s): Area mismatch, level %d IIH on %s",
+ circuit->area->area_tag, level,
+ circuit->interface->name);
+ }
+ retval = ISIS_OK;
+ goto out;
+ }
- retval = ISIS_OK;
- goto out;
- }
+ /*
+ * it's own IIH PDU - discard silently
+ */
+ if (!memcmp(circuit->u.bc.snpa, ssnpa, ETH_ALEN)) {
+ zlog_debug("ISIS-Adj (%s): it's own IIH PDU - discarded",
+ circuit->area->area_tag);
- /*
- * check if both ends have an IPv4 address
- */
- if (circuit->ip_addrs && listcount(circuit->ip_addrs)
- && tlvs.ipv4_addrs && listcount(tlvs.ipv4_addrs))
- {
- v4_usable = 1;
- }
+ retval = ISIS_OK;
+ goto out;
+ }
- if (found & TLVFLAG_IPV6_ADDR)
- {
- /* TBA: check that we have a linklocal ourselves? */
- struct listnode *node;
- struct in6_addr *ip;
- for (ALL_LIST_ELEMENTS_RO (tlvs.ipv6_addrs, node, ip))
- if (IN6_IS_ADDR_LINKLOCAL (ip))
- {
- v6_usable = 1;
- break;
- }
-
- if (!v6_usable)
- zlog_warn ("ISIS-Adj: IPv6 addresses present but no link-local "
- "in LAN IIH from %s\n", circuit->interface->name);
- }
+ /*
+ * check if both ends have an IPv4 address
+ */
+ if (circuit->ip_addrs && listcount(circuit->ip_addrs) && tlvs.ipv4_addrs
+ && listcount(tlvs.ipv4_addrs)) {
+ v4_usable = 1;
+ }
- if (!(found & (TLVFLAG_IPV4_ADDR | TLVFLAG_IPV6_ADDR)))
- zlog_warn ("ISIS-Adj: neither IPv4 nor IPv6 addr in LAN IIH from %s\n",
- circuit->interface->name);
+ if (found & TLVFLAG_IPV6_ADDR) {
+ /* TBA: check that we have a linklocal ourselves? */
+ struct listnode *node;
+ struct in6_addr *ip;
+ for (ALL_LIST_ELEMENTS_RO(tlvs.ipv6_addrs, node, ip))
+ if (IN6_IS_ADDR_LINKLOCAL(ip)) {
+ v6_usable = 1;
+ break;
+ }
+
+ if (!v6_usable)
+ zlog_warn(
+ "ISIS-Adj: IPv6 addresses present but no link-local "
+ "in LAN IIH from %s\n",
+ circuit->interface->name);
+ }
- if (!v6_usable && !v4_usable)
- {
- free_tlvs (&tlvs);
- return ISIS_WARNING;
- }
+ if (!(found & (TLVFLAG_IPV4_ADDR | TLVFLAG_IPV6_ADDR)))
+ zlog_warn(
+ "ISIS-Adj: neither IPv4 nor IPv6 addr in LAN IIH from %s\n",
+ circuit->interface->name);
+ if (!v6_usable && !v4_usable) {
+ free_tlvs(&tlvs);
+ return ISIS_WARNING;
+ }
- adj = isis_adj_lookup (hdr.source_id, circuit->u.bc.adjdb[level - 1]);
- if ((adj == NULL) || (memcmp(adj->snpa, ssnpa, ETH_ALEN)) ||
- (adj->level != level))
- {
- if (!adj)
- {
- /*
- * Do as in 8.4.2.5
- */
- adj = isis_new_adj (hdr.source_id, ssnpa, level, circuit);
- if (adj == NULL)
- {
- retval = ISIS_ERROR;
- goto out;
- }
- }
- else
- {
- if (ssnpa) {
- memcpy (adj->snpa, ssnpa, 6);
- } else {
- memset (adj->snpa, ' ', 6);
- }
- adj->level = level;
- }
- isis_adj_state_change (adj, ISIS_ADJ_INITIALIZING, NULL);
-
- if (level == IS_LEVEL_1)
- adj->sys_type = ISIS_SYSTYPE_L1_IS;
- else
- adj->sys_type = ISIS_SYSTYPE_L2_IS;
- list_delete_all_node (circuit->u.bc.lan_neighs[level - 1]);
- isis_adj_build_neigh_list (circuit->u.bc.adjdb[level - 1],
- circuit->u.bc.lan_neighs[level - 1]);
- }
- if(adj->dis_record[level-1].dis==ISIS_IS_DIS)
- switch (level)
- {
- case 1:
- if (memcmp (circuit->u.bc.l1_desig_is, hdr.lan_id, ISIS_SYS_ID_LEN + 1))
- {
- thread_add_event(master, isis_event_dis_status_change, circuit, 0,
- NULL);
- memcpy (&circuit->u.bc.l1_desig_is, hdr.lan_id,
- ISIS_SYS_ID_LEN + 1);
- }
- break;
- case 2:
- if (memcmp (circuit->u.bc.l2_desig_is, hdr.lan_id, ISIS_SYS_ID_LEN + 1))
- {
- thread_add_event(master, isis_event_dis_status_change, circuit, 0,
- NULL);
- memcpy (&circuit->u.bc.l2_desig_is, hdr.lan_id,
- ISIS_SYS_ID_LEN + 1);
- }
- break;
- }
-
- adj->hold_time = hdr.hold_time;
- adj->last_upd = time (NULL);
- adj->prio[level - 1] = hdr.prio;
-
- memcpy (adj->lanid, hdr.lan_id, ISIS_SYS_ID_LEN + 1);
-
- tlvs_to_adj_area_addrs (&tlvs, adj);
-
- /* which protocol are spoken ??? */
- if (tlvs_to_adj_nlpids (&tlvs, adj))
- {
- retval = ISIS_WARNING;
- goto out;
- }
+ adj = isis_adj_lookup(hdr.source_id, circuit->u.bc.adjdb[level - 1]);
+ if ((adj == NULL) || (memcmp(adj->snpa, ssnpa, ETH_ALEN))
+ || (adj->level != level)) {
+ if (!adj) {
+ /*
+ * Do as in 8.4.2.5
+ */
+ adj = isis_new_adj(hdr.source_id, ssnpa, level,
+ circuit);
+ if (adj == NULL) {
+ retval = ISIS_ERROR;
+ goto out;
+ }
+ } else {
+ if (ssnpa) {
+ memcpy(adj->snpa, ssnpa, 6);
+ } else {
+ memset(adj->snpa, ' ', 6);
+ }
+ adj->level = level;
+ }
+ isis_adj_state_change(adj, ISIS_ADJ_INITIALIZING, NULL);
- /* we need to copy addresses to the adj */
- if (found & TLVFLAG_IPV4_ADDR)
- tlvs_to_adj_ipv4_addrs (&tlvs, adj);
+ if (level == IS_LEVEL_1)
+ adj->sys_type = ISIS_SYSTYPE_L1_IS;
+ else
+ adj->sys_type = ISIS_SYSTYPE_L2_IS;
+ list_delete_all_node(circuit->u.bc.lan_neighs[level - 1]);
+ isis_adj_build_neigh_list(circuit->u.bc.adjdb[level - 1],
+ circuit->u.bc.lan_neighs[level - 1]);
+ }
- if (found & TLVFLAG_IPV6_ADDR)
- tlvs_to_adj_ipv6_addrs (&tlvs, adj);
+ if (adj->dis_record[level - 1].dis == ISIS_IS_DIS)
+ switch (level) {
+ case 1:
+ if (memcmp(circuit->u.bc.l1_desig_is, hdr.lan_id,
+ ISIS_SYS_ID_LEN + 1)) {
+ thread_add_event(master,
+ isis_event_dis_status_change,
+ circuit, 0, NULL);
+ memcpy(&circuit->u.bc.l1_desig_is, hdr.lan_id,
+ ISIS_SYS_ID_LEN + 1);
+ }
+ break;
+ case 2:
+ if (memcmp(circuit->u.bc.l2_desig_is, hdr.lan_id,
+ ISIS_SYS_ID_LEN + 1)) {
+ thread_add_event(master,
+ isis_event_dis_status_change,
+ circuit, 0, NULL);
+ memcpy(&circuit->u.bc.l2_desig_is, hdr.lan_id,
+ ISIS_SYS_ID_LEN + 1);
+ }
+ break;
+ }
- adj->circuit_t = hdr.circuit_t;
+ adj->hold_time = hdr.hold_time;
+ adj->last_upd = time(NULL);
+ adj->prio[level - 1] = hdr.prio;
- bool mt_set_changed = tlvs_to_adj_mt_set(&tlvs, v4_usable, v6_usable, adj);
+ memcpy(adj->lanid, hdr.lan_id, ISIS_SYS_ID_LEN + 1);
- /* lets take care of the expiry */
- THREAD_TIMER_OFF (adj->t_expire);
- thread_add_timer(master, isis_adj_expire, adj, (long)adj->hold_time,
- &adj->t_expire);
+ tlvs_to_adj_area_addrs(&tlvs, adj);
- /*
- * If the snpa for this circuit is found from LAN Neighbours TLV
- * we have two-way communication -> adjacency can be put to state "up"
- */
+ /* which protocol are spoken ??? */
+ if (tlvs_to_adj_nlpids(&tlvs, adj)) {
+ retval = ISIS_WARNING;
+ goto out;
+ }
- if (found & TLVFLAG_LAN_NEIGHS)
- {
- if (adj->adj_state != ISIS_ADJ_UP)
- {
- for (ALL_LIST_ELEMENTS_RO (tlvs.lan_neighs, node, snpa))
- {
- if (!memcmp (snpa, circuit->u.bc.snpa, ETH_ALEN))
- {
- isis_adj_state_change (adj, ISIS_ADJ_UP,
- "own SNPA found in LAN Neighbours TLV");
- }
- }
- }
- else
- {
- int found = 0;
- for (ALL_LIST_ELEMENTS_RO (tlvs.lan_neighs, node, snpa))
- if (!memcmp (snpa, circuit->u.bc.snpa, ETH_ALEN))
- {
- found = 1;
- break;
- }
- if (found == 0)
- isis_adj_state_change (adj, ISIS_ADJ_INITIALIZING,
- "own SNPA not found in LAN Neighbours TLV");
- }
- }
- else if (adj->adj_state == ISIS_ADJ_UP)
- {
- isis_adj_state_change (adj, ISIS_ADJ_INITIALIZING,
- "no LAN Neighbours TLV found");
- }
+ /* we need to copy addresses to the adj */
+ if (found & TLVFLAG_IPV4_ADDR)
+ tlvs_to_adj_ipv4_addrs(&tlvs, adj);
+
+ if (found & TLVFLAG_IPV6_ADDR)
+ tlvs_to_adj_ipv6_addrs(&tlvs, adj);
+
+ adj->circuit_t = hdr.circuit_t;
+
+ bool mt_set_changed =
+ tlvs_to_adj_mt_set(&tlvs, v4_usable, v6_usable, adj);
+
+ /* lets take care of the expiry */
+ THREAD_TIMER_OFF(adj->t_expire);
+ thread_add_timer(master, isis_adj_expire, adj, (long)adj->hold_time,
+ &adj->t_expire);
+
+ /*
+ * If the snpa for this circuit is found from LAN Neighbours TLV
+ * we have two-way communication -> adjacency can be put to state "up"
+ */
+
+ if (found & TLVFLAG_LAN_NEIGHS) {
+ if (adj->adj_state != ISIS_ADJ_UP) {
+ for (ALL_LIST_ELEMENTS_RO(tlvs.lan_neighs, node,
+ snpa)) {
+ if (!memcmp(snpa, circuit->u.bc.snpa,
+ ETH_ALEN)) {
+ isis_adj_state_change(
+ adj, ISIS_ADJ_UP,
+ "own SNPA found in LAN Neighbours TLV");
+ }
+ }
+ } else {
+ int found = 0;
+ for (ALL_LIST_ELEMENTS_RO(tlvs.lan_neighs, node, snpa))
+ if (!memcmp(snpa, circuit->u.bc.snpa,
+ ETH_ALEN)) {
+ found = 1;
+ break;
+ }
+ if (found == 0)
+ isis_adj_state_change(
+ adj, ISIS_ADJ_INITIALIZING,
+ "own SNPA not found in LAN Neighbours TLV");
+ }
+ } else if (adj->adj_state == ISIS_ADJ_UP) {
+ isis_adj_state_change(adj, ISIS_ADJ_INITIALIZING,
+ "no LAN Neighbours TLV found");
+ }
- if (adj->adj_state == ISIS_ADJ_UP && mt_set_changed)
- lsp_regenerate_schedule(adj->circuit->area, level, 0);
+ if (adj->adj_state == ISIS_ADJ_UP && mt_set_changed)
+ lsp_regenerate_schedule(adj->circuit->area, level, 0);
out:
- if (isis->debugs & DEBUG_ADJ_PACKETS)
- {
- zlog_debug ("ISIS-Adj (%s): Rcvd L%d LAN IIH from %s on %s, cirType %s, "
- "cirID %u, length %zd",
- circuit->area->area_tag,
- level, snpa_print (ssnpa), circuit->interface->name,
- circuit_t2string (circuit->is_type),
- circuit->circuit_id,
- stream_get_endp (circuit->rcv_stream));
- }
+ if (isis->debugs & DEBUG_ADJ_PACKETS) {
+ zlog_debug(
+ "ISIS-Adj (%s): Rcvd L%d LAN IIH from %s on %s, cirType %s, "
+ "cirID %u, length %zd",
+ circuit->area->area_tag, level, snpa_print(ssnpa),
+ circuit->interface->name,
+ circuit_t2string(circuit->is_type), circuit->circuit_id,
+ stream_get_endp(circuit->rcv_stream));
+ }
- free_tlvs (&tlvs);
+ free_tlvs(&tlvs);
- return retval;
+ return retval;
}
/*
@@ -1235,364 +1180,363 @@ out:
* ISO - 10589
* Section 7.3.15.1 - Action on receipt of a link state PDU
*/
-static int
-process_lsp (int level, struct isis_circuit *circuit, const u_char *ssnpa)
+static int process_lsp(int level, struct isis_circuit *circuit,
+ const u_char *ssnpa)
{
- struct isis_link_state_hdr *hdr;
- struct isis_adjacency *adj = NULL;
- struct isis_lsp *lsp, *lsp0 = NULL;
- int retval = ISIS_OK, comp = 0;
- u_char lspid[ISIS_SYS_ID_LEN + 2];
- struct isis_passwd *passwd;
- uint16_t pdu_len;
- int lsp_confusion;
-
- if (isis->debugs & DEBUG_UPDATE_PACKETS)
- {
- zlog_debug ("ISIS-Upd (%s): Rcvd L%d LSP on %s, cirType %s, cirID %u",
- circuit->area->area_tag, level, circuit->interface->name,
- circuit_t2string (circuit->is_type), circuit->circuit_id);
- if (isis->debugs & DEBUG_PACKET_DUMP)
- zlog_dump_data (STREAM_DATA (circuit->rcv_stream),
- stream_get_endp (circuit->rcv_stream));
- }
-
- if ((stream_get_endp (circuit->rcv_stream) -
- stream_get_getp (circuit->rcv_stream)) < ISIS_LSP_HDR_LEN)
- {
- zlog_warn ("Packet too short");
- return ISIS_WARNING;
- }
-
- /* Reference the header */
- hdr = (struct isis_link_state_hdr *) STREAM_PNT (circuit->rcv_stream);
- pdu_len = ntohs (hdr->pdu_len);
-
- /* lsp length check */
- if (pdu_len < (ISIS_FIXED_HDR_LEN + ISIS_LSP_HDR_LEN) ||
- pdu_len > ISO_MTU(circuit) ||
- pdu_len > stream_get_endp (circuit->rcv_stream))
- {
- zlog_debug ("ISIS-Upd (%s): LSP %s invalid LSP length %d",
- circuit->area->area_tag,
- rawlspid_print (hdr->lsp_id), pdu_len);
-
- return ISIS_WARNING;
- }
-
- /*
- * Set the stream endp to PDU length, ignoring additional padding
- * introduced by transport chips.
- */
- if (pdu_len < stream_get_endp (circuit->rcv_stream))
- stream_set_endp (circuit->rcv_stream, pdu_len);
+ struct isis_link_state_hdr *hdr;
+ struct isis_adjacency *adj = NULL;
+ struct isis_lsp *lsp, *lsp0 = NULL;
+ int retval = ISIS_OK, comp = 0;
+ u_char lspid[ISIS_SYS_ID_LEN + 2];
+ struct isis_passwd *passwd;
+ uint16_t pdu_len;
+ int lsp_confusion;
+
+ if (isis->debugs & DEBUG_UPDATE_PACKETS) {
+ zlog_debug(
+ "ISIS-Upd (%s): Rcvd L%d LSP on %s, cirType %s, cirID %u",
+ circuit->area->area_tag, level,
+ circuit->interface->name,
+ circuit_t2string(circuit->is_type),
+ circuit->circuit_id);
+ if (isis->debugs & DEBUG_PACKET_DUMP)
+ zlog_dump_data(STREAM_DATA(circuit->rcv_stream),
+ stream_get_endp(circuit->rcv_stream));
+ }
- if (isis->debugs & DEBUG_UPDATE_PACKETS)
- {
- zlog_debug ("ISIS-Upd (%s): Rcvd L%d LSP %s, seq 0x%08x, cksum 0x%04x, "
- "lifetime %us, len %u, on %s",
- circuit->area->area_tag,
- level,
- rawlspid_print (hdr->lsp_id),
- ntohl (hdr->seq_num),
- ntohs (hdr->checksum),
- ntohs (hdr->rem_lifetime),
- pdu_len,
- circuit->interface->name);
- }
+ if ((stream_get_endp(circuit->rcv_stream)
+ - stream_get_getp(circuit->rcv_stream))
+ < ISIS_LSP_HDR_LEN) {
+ zlog_warn("Packet too short");
+ return ISIS_WARNING;
+ }
- /* lsp is_type check */
- if ((hdr->lsp_bits & IS_LEVEL_1_AND_2) != IS_LEVEL_1 &&
- (hdr->lsp_bits & IS_LEVEL_1_AND_2) != IS_LEVEL_1_AND_2)
- {
- zlog_debug ("ISIS-Upd (%s): LSP %s invalid LSP is type %x",
- circuit->area->area_tag,
- rawlspid_print (hdr->lsp_id), hdr->lsp_bits);
- /* continue as per RFC1122 Be liberal in what you accept, and
- * conservative in what you send */
- }
+ /* Reference the header */
+ hdr = (struct isis_link_state_hdr *)STREAM_PNT(circuit->rcv_stream);
+ pdu_len = ntohs(hdr->pdu_len);
- /* Checksum sanity check - FIXME: move to correct place */
- /* 12 = sysid+pdu+remtime */
- if (iso_csum_verify (STREAM_PNT (circuit->rcv_stream) + 4,
- pdu_len - 12, hdr->checksum,
- offsetof(struct isis_link_state_hdr, checksum) - 4))
- {
- zlog_debug ("ISIS-Upd (%s): LSP %s invalid LSP checksum 0x%04x",
- circuit->area->area_tag,
- rawlspid_print (hdr->lsp_id), ntohs (hdr->checksum));
+ /* lsp length check */
+ if (pdu_len < (ISIS_FIXED_HDR_LEN + ISIS_LSP_HDR_LEN)
+ || pdu_len > ISO_MTU(circuit)
+ || pdu_len > stream_get_endp(circuit->rcv_stream)) {
+ zlog_debug("ISIS-Upd (%s): LSP %s invalid LSP length %d",
+ circuit->area->area_tag, rawlspid_print(hdr->lsp_id),
+ pdu_len);
- return ISIS_WARNING;
- }
+ return ISIS_WARNING;
+ }
- /* 7.3.15.1 a) 1 - external domain circuit will discard lsps */
- if (circuit->ext_domain)
- {
- zlog_debug
- ("ISIS-Upd (%s): LSP %s received at level %d over circuit with "
- "externalDomain = true", circuit->area->area_tag,
- rawlspid_print (hdr->lsp_id), level);
+ /*
+ * Set the stream endp to PDU length, ignoring additional padding
+ * introduced by transport chips.
+ */
+ if (pdu_len < stream_get_endp(circuit->rcv_stream))
+ stream_set_endp(circuit->rcv_stream, pdu_len);
+
+ if (isis->debugs & DEBUG_UPDATE_PACKETS) {
+ zlog_debug(
+ "ISIS-Upd (%s): Rcvd L%d LSP %s, seq 0x%08x, cksum 0x%04x, "
+ "lifetime %us, len %u, on %s",
+ circuit->area->area_tag, level,
+ rawlspid_print(hdr->lsp_id), ntohl(hdr->seq_num),
+ ntohs(hdr->checksum), ntohs(hdr->rem_lifetime), pdu_len,
+ circuit->interface->name);
+ }
- return ISIS_WARNING;
- }
+ /* lsp is_type check */
+ if ((hdr->lsp_bits & IS_LEVEL_1_AND_2) != IS_LEVEL_1
+ && (hdr->lsp_bits & IS_LEVEL_1_AND_2) != IS_LEVEL_1_AND_2) {
+ zlog_debug("ISIS-Upd (%s): LSP %s invalid LSP is type %x",
+ circuit->area->area_tag, rawlspid_print(hdr->lsp_id),
+ hdr->lsp_bits);
+ /* continue as per RFC1122 Be liberal in what you accept, and
+ * conservative in what you send */
+ }
- /* 7.3.15.1 a) 2,3 - manualL2OnlyMode not implemented */
- if (!accept_level (level, circuit->is_type))
- {
- zlog_debug ("ISIS-Upd (%s): LSP %s received at level %d over circuit of"
- " type %s",
- circuit->area->area_tag,
- rawlspid_print (hdr->lsp_id),
- level, circuit_t2string (circuit->is_type));
+ /* Checksum sanity check - FIXME: move to correct place */
+ /* 12 = sysid+pdu+remtime */
+ if (iso_csum_verify(STREAM_PNT(circuit->rcv_stream) + 4, pdu_len - 12,
+ hdr->checksum,
+ offsetof(struct isis_link_state_hdr, checksum)
+ - 4)) {
+ zlog_debug("ISIS-Upd (%s): LSP %s invalid LSP checksum 0x%04x",
+ circuit->area->area_tag, rawlspid_print(hdr->lsp_id),
+ ntohs(hdr->checksum));
+
+ return ISIS_WARNING;
+ }
- return ISIS_WARNING;
- }
+ /* 7.3.15.1 a) 1 - external domain circuit will discard lsps */
+ if (circuit->ext_domain) {
+ zlog_debug(
+ "ISIS-Upd (%s): LSP %s received at level %d over circuit with "
+ "externalDomain = true",
+ circuit->area->area_tag, rawlspid_print(hdr->lsp_id),
+ level);
- /* 7.3.15.1 a) 4 - need to make sure IDLength matches */
+ return ISIS_WARNING;
+ }
- /* 7.3.15.1 a) 5 - maximum area match, can be ommited since we only use 3 */
+ /* 7.3.15.1 a) 2,3 - manualL2OnlyMode not implemented */
+ if (!accept_level(level, circuit->is_type)) {
+ zlog_debug(
+ "ISIS-Upd (%s): LSP %s received at level %d over circuit of"
+ " type %s",
+ circuit->area->area_tag, rawlspid_print(hdr->lsp_id),
+ level, circuit_t2string(circuit->is_type));
- /* 7.3.15.1 a) 7 - password check */
- (level == IS_LEVEL_1) ? (passwd = &circuit->area->area_passwd) :
- (passwd = &circuit->area->domain_passwd);
- if (passwd->type)
- {
- if (lsp_authentication_check (circuit->rcv_stream, circuit->area,
- level, passwd))
- {
- isis_event_auth_failure (circuit->area->area_tag,
- "LSP authentication failure", hdr->lsp_id);
- return ISIS_WARNING;
+ return ISIS_WARNING;
}
- }
- /* Find the LSP in our database and compare it to this Link State header */
- lsp = lsp_search (hdr->lsp_id, circuit->area->lspdb[level - 1]);
- if (lsp)
- comp = lsp_compare (circuit->area->area_tag, lsp, hdr->seq_num,
- hdr->checksum, hdr->rem_lifetime);
- if (lsp && (lsp->own_lsp))
- goto dontcheckadj;
-
- /* 7.3.15.1 a) 6 - Must check that we have an adjacency of the same level */
- /* for broadcast circuits, snpa should be compared */
-
- if (circuit->circ_type == CIRCUIT_T_BROADCAST)
- {
- adj = isis_adj_lookup_snpa (ssnpa, circuit->u.bc.adjdb[level - 1]);
- if (!adj)
- {
- zlog_debug ("(%s): DS ======= LSP %s, seq 0x%08x, cksum 0x%04x, "
- "lifetime %us on %s",
- circuit->area->area_tag,
- rawlspid_print (hdr->lsp_id),
- ntohl (hdr->seq_num),
- ntohs (hdr->checksum),
- ntohs (hdr->rem_lifetime), circuit->interface->name);
- return ISIS_WARNING; /* Silently discard */
+
+ /* 7.3.15.1 a) 4 - need to make sure IDLength matches */
+
+ /* 7.3.15.1 a) 5 - maximum area match, can be ommited since we only use
+ * 3 */
+
+ /* 7.3.15.1 a) 7 - password check */
+ (level == IS_LEVEL_1) ? (passwd = &circuit->area->area_passwd)
+ : (passwd = &circuit->area->domain_passwd);
+ if (passwd->type) {
+ if (lsp_authentication_check(circuit->rcv_stream, circuit->area,
+ level, passwd)) {
+ isis_event_auth_failure(circuit->area->area_tag,
+ "LSP authentication failure",
+ hdr->lsp_id);
+ return ISIS_WARNING;
+ }
}
- }
- /* for non broadcast, we just need to find same level adj */
- else
- {
- /* If no adj, or no sharing of level */
- if (!circuit->u.p2p.neighbor)
- {
- return ISIS_OK; /* Silently discard */
+ /* Find the LSP in our database and compare it to this Link State header
+ */
+ lsp = lsp_search(hdr->lsp_id, circuit->area->lspdb[level - 1]);
+ if (lsp)
+ comp = lsp_compare(circuit->area->area_tag, lsp, hdr->seq_num,
+ hdr->checksum, hdr->rem_lifetime);
+ if (lsp && (lsp->own_lsp))
+ goto dontcheckadj;
+
+ /* 7.3.15.1 a) 6 - Must check that we have an adjacency of the same
+ * level */
+ /* for broadcast circuits, snpa should be compared */
+
+ if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
+ adj = isis_adj_lookup_snpa(ssnpa,
+ circuit->u.bc.adjdb[level - 1]);
+ if (!adj) {
+ zlog_debug(
+ "(%s): DS ======= LSP %s, seq 0x%08x, cksum 0x%04x, "
+ "lifetime %us on %s",
+ circuit->area->area_tag,
+ rawlspid_print(hdr->lsp_id),
+ ntohl(hdr->seq_num), ntohs(hdr->checksum),
+ ntohs(hdr->rem_lifetime),
+ circuit->interface->name);
+ return ISIS_WARNING; /* Silently discard */
+ }
}
- else
- {
- if (((level == IS_LEVEL_1) &&
- (circuit->u.p2p.neighbor->adj_usage == ISIS_ADJ_LEVEL2)) ||
- ((level == IS_LEVEL_2) &&
- (circuit->u.p2p.neighbor->adj_usage == ISIS_ADJ_LEVEL1)))
- return ISIS_WARNING; /* Silently discard */
+ /* for non broadcast, we just need to find same level adj */
+ else {
+ /* If no adj, or no sharing of level */
+ if (!circuit->u.p2p.neighbor) {
+ return ISIS_OK; /* Silently discard */
+ } else {
+ if (((level == IS_LEVEL_1)
+ && (circuit->u.p2p.neighbor->adj_usage
+ == ISIS_ADJ_LEVEL2))
+ || ((level == IS_LEVEL_2)
+ && (circuit->u.p2p.neighbor->adj_usage
+ == ISIS_ADJ_LEVEL1)))
+ return ISIS_WARNING; /* Silently discard */
+ }
}
- }
dontcheckadj:
- /* 7.3.15.1 a) 7 - Passwords for level 1 - not implemented */
-
- /* 7.3.15.1 a) 8 - Passwords for level 2 - not implemented */
-
- /* 7.3.15.1 a) 9 - OriginatingLSPBufferSize - not implemented FIXME: do it */
-
- /* 7.3.16.2 - If this is an LSP from another IS with identical seq_num but
- * wrong checksum, initiate a purge. */
- if (lsp
- && (lsp->lsp_header->seq_num == hdr->seq_num)
- && (lsp->lsp_header->checksum != hdr->checksum))
- {
- zlog_warn("ISIS-Upd (%s): LSP %s seq 0x%08x with confused checksum received.",
- circuit->area->area_tag, rawlspid_print(hdr->lsp_id),
- ntohl(hdr->seq_num));
- hdr->rem_lifetime = 0;
- lsp_confusion = 1;
- }
- else
- lsp_confusion = 0;
-
- /* 7.3.15.1 b) - If the remaining life time is 0, we perform 7.3.16.4 */
- if (hdr->rem_lifetime == 0)
- {
- if (!lsp)
- {
- /* 7.3.16.4 a) 1) No LSP in db -> send an ack, but don't save */
- /* only needed on explicit update, eg - p2p */
- if (circuit->circ_type == CIRCUIT_T_P2P)
- ack_lsp (hdr, circuit, level);
- return retval; /* FIXME: do we need a purge? */
- }
- else
- {
- if (memcmp (hdr->lsp_id, isis->sysid, ISIS_SYS_ID_LEN))
- {
- /* LSP by some other system -> do 7.3.16.4 b) */
- /* 7.3.16.4 b) 1) */
- if (comp == LSP_NEWER)
- {
- lsp_update (lsp, circuit->rcv_stream, circuit->area, level);
- /* ii */
- lsp_set_all_srmflags (lsp);
- /* v */
- ISIS_FLAGS_CLEAR_ALL (lsp->SSNflags); /* FIXME: OTHER than c */
-
- /* For the case of lsp confusion, flood the purge back to its
- * originator so that it can react. Otherwise, don't reflood
- * through incoming circuit as usual */
- if (!lsp_confusion)
- {
- /* iii */
- ISIS_CLEAR_FLAG (lsp->SRMflags, circuit);
- /* iv */
- if (circuit->circ_type != CIRCUIT_T_BROADCAST)
- ISIS_SET_FLAG (lsp->SSNflags, circuit);
- }
- } /* 7.3.16.4 b) 2) */
- else if (comp == LSP_EQUAL)
- {
- /* i */
- ISIS_CLEAR_FLAG (lsp->SRMflags, circuit);
- /* ii */
- if (circuit->circ_type != CIRCUIT_T_BROADCAST)
- ISIS_SET_FLAG (lsp->SSNflags, circuit);
- } /* 7.3.16.4 b) 3) */
- else
- {
- ISIS_SET_FLAG (lsp->SRMflags, circuit);
- ISIS_CLEAR_FLAG (lsp->SSNflags, circuit);
+ /* 7.3.15.1 a) 7 - Passwords for level 1 - not implemented */
+
+ /* 7.3.15.1 a) 8 - Passwords for level 2 - not implemented */
+
+ /* 7.3.15.1 a) 9 - OriginatingLSPBufferSize - not implemented FIXME: do
+ * it */
+
+ /* 7.3.16.2 - If this is an LSP from another IS with identical seq_num
+ * but
+ * wrong checksum, initiate a purge. */
+ if (lsp && (lsp->lsp_header->seq_num == hdr->seq_num)
+ && (lsp->lsp_header->checksum != hdr->checksum)) {
+ zlog_warn(
+ "ISIS-Upd (%s): LSP %s seq 0x%08x with confused checksum received.",
+ circuit->area->area_tag, rawlspid_print(hdr->lsp_id),
+ ntohl(hdr->seq_num));
+ hdr->rem_lifetime = 0;
+ lsp_confusion = 1;
+ } else
+ lsp_confusion = 0;
+
+ /* 7.3.15.1 b) - If the remaining life time is 0, we perform 7.3.16.4 */
+ if (hdr->rem_lifetime == 0) {
+ if (!lsp) {
+ /* 7.3.16.4 a) 1) No LSP in db -> send an ack, but don't
+ * save */
+ /* only needed on explicit update, eg - p2p */
+ if (circuit->circ_type == CIRCUIT_T_P2P)
+ ack_lsp(hdr, circuit, level);
+ return retval; /* FIXME: do we need a purge? */
+ } else {
+ if (memcmp(hdr->lsp_id, isis->sysid, ISIS_SYS_ID_LEN)) {
+ /* LSP by some other system -> do 7.3.16.4 b) */
+ /* 7.3.16.4 b) 1) */
+ if (comp == LSP_NEWER) {
+ lsp_update(lsp, circuit->rcv_stream,
+ circuit->area, level);
+ /* ii */
+ lsp_set_all_srmflags(lsp);
+ /* v */
+ ISIS_FLAGS_CLEAR_ALL(
+ lsp
+ ->SSNflags); /* FIXME:
+ OTHER
+ than c
+ */
+
+ /* For the case of lsp confusion, flood
+ * the purge back to its
+ * originator so that it can react.
+ * Otherwise, don't reflood
+ * through incoming circuit as usual */
+ if (!lsp_confusion) {
+ /* iii */
+ ISIS_CLEAR_FLAG(lsp->SRMflags,
+ circuit);
+ /* iv */
+ if (circuit->circ_type
+ != CIRCUIT_T_BROADCAST)
+ ISIS_SET_FLAG(
+ lsp->SSNflags,
+ circuit);
+ }
+ } /* 7.3.16.4 b) 2) */
+ else if (comp == LSP_EQUAL) {
+ /* i */
+ ISIS_CLEAR_FLAG(lsp->SRMflags, circuit);
+ /* ii */
+ if (circuit->circ_type
+ != CIRCUIT_T_BROADCAST)
+ ISIS_SET_FLAG(lsp->SSNflags,
+ circuit);
+ } /* 7.3.16.4 b) 3) */
+ else {
+ ISIS_SET_FLAG(lsp->SRMflags, circuit);
+ ISIS_CLEAR_FLAG(lsp->SSNflags, circuit);
+ }
+ } else if (lsp->lsp_header->rem_lifetime != 0) {
+ /* our own LSP -> 7.3.16.4 c) */
+ if (comp == LSP_NEWER) {
+ lsp_inc_seqnum(lsp,
+ ntohl(hdr->seq_num));
+ lsp_set_all_srmflags(lsp);
+ } else {
+ ISIS_SET_FLAG(lsp->SRMflags, circuit);
+ ISIS_CLEAR_FLAG(lsp->SSNflags, circuit);
+ }
+ if (isis->debugs & DEBUG_UPDATE_PACKETS)
+ zlog_debug(
+ "ISIS-Upd (%s): (1) re-originating LSP %s new "
+ "seq 0x%08x",
+ circuit->area->area_tag,
+ rawlspid_print(hdr->lsp_id),
+ ntohl(lsp->lsp_header
+ ->seq_num));
+ }
}
- }
- else if (lsp->lsp_header->rem_lifetime != 0)
- {
- /* our own LSP -> 7.3.16.4 c) */
- if (comp == LSP_NEWER)
- {
- lsp_inc_seqnum (lsp, ntohl (hdr->seq_num));
- lsp_set_all_srmflags (lsp);
- }
- else
- {
- ISIS_SET_FLAG (lsp->SRMflags, circuit);
- ISIS_CLEAR_FLAG (lsp->SSNflags, circuit);
- }
- if (isis->debugs & DEBUG_UPDATE_PACKETS)
- zlog_debug ("ISIS-Upd (%s): (1) re-originating LSP %s new "
- "seq 0x%08x", circuit->area->area_tag,
- rawlspid_print (hdr->lsp_id),
- ntohl (lsp->lsp_header->seq_num));
- }
- }
- return retval;
- }
- /* 7.3.15.1 c) - If this is our own lsp and we don't have it initiate a
- * purge */
- if (memcmp (hdr->lsp_id, isis->sysid, ISIS_SYS_ID_LEN) == 0)
- {
- if (!lsp)
- {
- /* 7.3.16.4: initiate a purge */
- lsp_purge_non_exist(level, hdr, circuit->area);
- return ISIS_OK;
+ return retval;
}
- /* 7.3.15.1 d) - If this is our own lsp and we have it */
-
- /* In 7.3.16.1, If an Intermediate system R somewhere in the domain
- * has information that the current sequence number for source S is
- * "greater" than that held by S, ... */
-
- if (ntohl (hdr->seq_num) > ntohl (lsp->lsp_header->seq_num))
- {
- /* 7.3.16.1 */
- lsp_inc_seqnum (lsp, ntohl (hdr->seq_num));
- if (isis->debugs & DEBUG_UPDATE_PACKETS)
- zlog_debug ("ISIS-Upd (%s): (2) re-originating LSP %s new seq "
- "0x%08x", circuit->area->area_tag,
- rawlspid_print (hdr->lsp_id),
- ntohl (lsp->lsp_header->seq_num));
- }
- /* If the received LSP is older or equal,
- * resend the LSP which will act as ACK */
- lsp_set_all_srmflags (lsp);
- }
- else
- {
- /* 7.3.15.1 e) - This lsp originated on another system */
-
- /* 7.3.15.1 e) 1) LSP newer than the one in db or no LSP in db */
- if ((!lsp || comp == LSP_NEWER))
- {
- /*
- * If this lsp is a frag, need to see if we have zero lsp present
- */
- if (LSP_FRAGMENT (hdr->lsp_id) != 0)
- {
- memcpy (lspid, hdr->lsp_id, ISIS_SYS_ID_LEN + 1);
- LSP_FRAGMENT (lspid) = 0;
- lsp0 = lsp_search (lspid, circuit->area->lspdb[level - 1]);
- if (!lsp0)
- {
- zlog_debug ("Got lsp frag, while zero lsp not in database");
- return ISIS_OK;
+ /* 7.3.15.1 c) - If this is our own lsp and we don't have it initiate a
+ * purge */
+ if (memcmp(hdr->lsp_id, isis->sysid, ISIS_SYS_ID_LEN) == 0) {
+ if (!lsp) {
+ /* 7.3.16.4: initiate a purge */
+ lsp_purge_non_exist(level, hdr, circuit->area);
+ return ISIS_OK;
+ }
+ /* 7.3.15.1 d) - If this is our own lsp and we have it */
+
+ /* In 7.3.16.1, If an Intermediate system R somewhere in the
+ * domain
+ * has information that the current sequence number for source S
+ * is
+ * "greater" than that held by S, ... */
+
+ if (ntohl(hdr->seq_num) > ntohl(lsp->lsp_header->seq_num)) {
+ /* 7.3.16.1 */
+ lsp_inc_seqnum(lsp, ntohl(hdr->seq_num));
+ if (isis->debugs & DEBUG_UPDATE_PACKETS)
+ zlog_debug(
+ "ISIS-Upd (%s): (2) re-originating LSP %s new seq "
+ "0x%08x",
+ circuit->area->area_tag,
+ rawlspid_print(hdr->lsp_id),
+ ntohl(lsp->lsp_header->seq_num));
+ }
+ /* If the received LSP is older or equal,
+ * resend the LSP which will act as ACK */
+ lsp_set_all_srmflags(lsp);
+ } else {
+ /* 7.3.15.1 e) - This lsp originated on another system */
+
+ /* 7.3.15.1 e) 1) LSP newer than the one in db or no LSP in db
+ */
+ if ((!lsp || comp == LSP_NEWER)) {
+ /*
+ * If this lsp is a frag, need to see if we have zero
+ * lsp present
+ */
+ if (LSP_FRAGMENT(hdr->lsp_id) != 0) {
+ memcpy(lspid, hdr->lsp_id, ISIS_SYS_ID_LEN + 1);
+ LSP_FRAGMENT(lspid) = 0;
+ lsp0 = lsp_search(
+ lspid, circuit->area->lspdb[level - 1]);
+ if (!lsp0) {
+ zlog_debug(
+ "Got lsp frag, while zero lsp not in database");
+ return ISIS_OK;
+ }
+ }
+ /* i */
+ if (!lsp) {
+ lsp = lsp_new_from_stream_ptr(
+ circuit->rcv_stream, pdu_len, lsp0,
+ circuit->area, level);
+ lsp_insert(lsp,
+ circuit->area->lspdb[level - 1]);
+ } else /* exists, so we overwrite */
+ {
+ lsp_update(lsp, circuit->rcv_stream,
+ circuit->area, level);
+ }
+ /* ii */
+ lsp_set_all_srmflags(lsp);
+ /* iii */
+ ISIS_CLEAR_FLAG(lsp->SRMflags, circuit);
+
+ /* iv */
+ if (circuit->circ_type != CIRCUIT_T_BROADCAST)
+ ISIS_SET_FLAG(lsp->SSNflags, circuit);
+ /* FIXME: v) */
+ }
+ /* 7.3.15.1 e) 2) LSP equal to the one in db */
+ else if (comp == LSP_EQUAL) {
+ ISIS_CLEAR_FLAG(lsp->SRMflags, circuit);
+ lsp_update(lsp, circuit->rcv_stream, circuit->area,
+ level);
+ if (circuit->circ_type != CIRCUIT_T_BROADCAST)
+ ISIS_SET_FLAG(lsp->SSNflags, circuit);
+ }
+ /* 7.3.15.1 e) 3) LSP older than the one in db */
+ else {
+ ISIS_SET_FLAG(lsp->SRMflags, circuit);
+ ISIS_CLEAR_FLAG(lsp->SSNflags, circuit);
}
- }
- /* i */
- if (!lsp)
- {
- lsp = lsp_new_from_stream_ptr (circuit->rcv_stream,
- pdu_len, lsp0,
- circuit->area, level);
- lsp_insert (lsp, circuit->area->lspdb[level - 1]);
- }
- else /* exists, so we overwrite */
- {
- lsp_update (lsp, circuit->rcv_stream, circuit->area, level);
- }
- /* ii */
- lsp_set_all_srmflags (lsp);
- /* iii */
- ISIS_CLEAR_FLAG (lsp->SRMflags, circuit);
-
- /* iv */
- if (circuit->circ_type != CIRCUIT_T_BROADCAST)
- ISIS_SET_FLAG (lsp->SSNflags, circuit);
- /* FIXME: v) */
- }
- /* 7.3.15.1 e) 2) LSP equal to the one in db */
- else if (comp == LSP_EQUAL)
- {
- ISIS_CLEAR_FLAG (lsp->SRMflags, circuit);
- lsp_update (lsp, circuit->rcv_stream, circuit->area, level);
- if (circuit->circ_type != CIRCUIT_T_BROADCAST)
- ISIS_SET_FLAG (lsp->SSNflags, circuit);
- }
- /* 7.3.15.1 e) 3) LSP older than the one in db */
- else
- {
- ISIS_SET_FLAG (lsp->SRMflags, circuit);
- ISIS_CLEAR_FLAG (lsp->SSNflags, circuit);
}
- }
- return retval;
+ return retval;
}
/*
@@ -1601,1570 +1545,1528 @@ dontcheckadj:
* Section 7.3.15.2 - Action on receipt of a sequence numbers PDU
*/
-static int
-process_snp (int snp_type, int level, struct isis_circuit *circuit,
- const u_char *ssnpa)
+static int process_snp(int snp_type, int level, struct isis_circuit *circuit,
+ const u_char *ssnpa)
{
- int retval = ISIS_OK;
- int cmp, own_lsp;
- char typechar = ' ';
- uint16_t pdu_len;
- struct isis_adjacency *adj;
- struct isis_complete_seqnum_hdr *chdr = NULL;
- struct isis_partial_seqnum_hdr *phdr = NULL;
- uint32_t found = 0, expected = 0, auth_tlv_offset = 0;
- struct isis_lsp *lsp;
- struct lsp_entry *entry;
- struct listnode *node, *nnode;
- struct listnode *node2, *nnode2;
- struct tlvs tlvs;
- struct list *lsp_list = NULL;
- struct isis_passwd *passwd;
-
- if (snp_type == ISIS_SNP_CSNP_FLAG)
- {
- /* getting the header info */
- typechar = 'C';
- chdr =
- (struct isis_complete_seqnum_hdr *) STREAM_PNT (circuit->rcv_stream);
- stream_forward_getp (circuit->rcv_stream, ISIS_CSNP_HDRLEN);
- pdu_len = ntohs (chdr->pdu_len);
- if (pdu_len < (ISIS_FIXED_HDR_LEN + ISIS_CSNP_HDRLEN) ||
- pdu_len > ISO_MTU(circuit) ||
- pdu_len > stream_get_endp (circuit->rcv_stream))
- {
- zlog_warn ("Received a CSNP with bogus length %d", pdu_len);
- return ISIS_WARNING;
- }
- }
- else
- {
- typechar = 'P';
- phdr =
- (struct isis_partial_seqnum_hdr *) STREAM_PNT (circuit->rcv_stream);
- stream_forward_getp (circuit->rcv_stream, ISIS_PSNP_HDRLEN);
- pdu_len = ntohs (phdr->pdu_len);
- if (pdu_len < (ISIS_FIXED_HDR_LEN + ISIS_PSNP_HDRLEN) ||
- pdu_len > ISO_MTU(circuit) ||
- pdu_len > stream_get_endp (circuit->rcv_stream))
- {
- zlog_warn ("Received a PSNP with bogus length %d", pdu_len);
- return ISIS_WARNING;
+ int retval = ISIS_OK;
+ int cmp, own_lsp;
+ char typechar = ' ';
+ uint16_t pdu_len;
+ struct isis_adjacency *adj;
+ struct isis_complete_seqnum_hdr *chdr = NULL;
+ struct isis_partial_seqnum_hdr *phdr = NULL;
+ uint32_t found = 0, expected = 0, auth_tlv_offset = 0;
+ struct isis_lsp *lsp;
+ struct lsp_entry *entry;
+ struct listnode *node, *nnode;
+ struct listnode *node2, *nnode2;
+ struct tlvs tlvs;
+ struct list *lsp_list = NULL;
+ struct isis_passwd *passwd;
+
+ if (snp_type == ISIS_SNP_CSNP_FLAG) {
+ /* getting the header info */
+ typechar = 'C';
+ chdr = (struct isis_complete_seqnum_hdr *)STREAM_PNT(
+ circuit->rcv_stream);
+ stream_forward_getp(circuit->rcv_stream, ISIS_CSNP_HDRLEN);
+ pdu_len = ntohs(chdr->pdu_len);
+ if (pdu_len < (ISIS_FIXED_HDR_LEN + ISIS_CSNP_HDRLEN)
+ || pdu_len > ISO_MTU(circuit)
+ || pdu_len > stream_get_endp(circuit->rcv_stream)) {
+ zlog_warn("Received a CSNP with bogus length %d",
+ pdu_len);
+ return ISIS_WARNING;
+ }
+ } else {
+ typechar = 'P';
+ phdr = (struct isis_partial_seqnum_hdr *)STREAM_PNT(
+ circuit->rcv_stream);
+ stream_forward_getp(circuit->rcv_stream, ISIS_PSNP_HDRLEN);
+ pdu_len = ntohs(phdr->pdu_len);
+ if (pdu_len < (ISIS_FIXED_HDR_LEN + ISIS_PSNP_HDRLEN)
+ || pdu_len > ISO_MTU(circuit)
+ || pdu_len > stream_get_endp(circuit->rcv_stream)) {
+ zlog_warn("Received a PSNP with bogus length %d",
+ pdu_len);
+ return ISIS_WARNING;
+ }
}
- }
-
- /*
- * Set the stream endp to PDU length, ignoring additional padding
- * introduced by transport chips.
- */
- if (pdu_len < stream_get_endp (circuit->rcv_stream))
- stream_set_endp (circuit->rcv_stream, pdu_len);
- /* 7.3.15.2 a) 1 - external domain circuit will discard snp pdu */
- if (circuit->ext_domain)
- {
-
- zlog_debug ("ISIS-Snp (%s): Rcvd L%d %cSNP on %s, "
- "skipping: circuit externalDomain = true",
- circuit->area->area_tag,
- level, typechar, circuit->interface->name);
+ /*
+ * Set the stream endp to PDU length, ignoring additional padding
+ * introduced by transport chips.
+ */
+ if (pdu_len < stream_get_endp(circuit->rcv_stream))
+ stream_set_endp(circuit->rcv_stream, pdu_len);
- return ISIS_OK;
- }
+ /* 7.3.15.2 a) 1 - external domain circuit will discard snp pdu */
+ if (circuit->ext_domain) {
- /* 7.3.15.2 a) 2,3 - manualL2OnlyMode not implemented */
- if (!accept_level (level, circuit->is_type))
- {
+ zlog_debug(
+ "ISIS-Snp (%s): Rcvd L%d %cSNP on %s, "
+ "skipping: circuit externalDomain = true",
+ circuit->area->area_tag, level, typechar,
+ circuit->interface->name);
- zlog_debug ("ISIS-Snp (%s): Rcvd L%d %cSNP on %s, "
- "skipping: circuit type %s does not match level %d",
- circuit->area->area_tag,
- level,
- typechar,
- circuit->interface->name,
- circuit_t2string (circuit->is_type), level);
-
- return ISIS_OK;
- }
-
- /* 7.3.15.2 a) 4 - not applicable for CSNP only PSNPs on broadcast */
- if ((snp_type == ISIS_SNP_PSNP_FLAG) &&
- (circuit->circ_type == CIRCUIT_T_BROADCAST) &&
- (!circuit->u.bc.is_dr[level - 1]))
- {
- zlog_debug ("ISIS-Snp (%s): Rcvd L%d %cSNP from %s on %s, "
- "skipping: we are not the DIS",
- circuit->area->area_tag,
- level,
- typechar, snpa_print (ssnpa), circuit->interface->name);
-
- return ISIS_OK;
- }
+ return ISIS_OK;
+ }
- /* 7.3.15.2 a) 5 - need to make sure IDLength matches - already checked */
+ /* 7.3.15.2 a) 2,3 - manualL2OnlyMode not implemented */
+ if (!accept_level(level, circuit->is_type)) {
- /* 7.3.15.2 a) 6 - maximum area match, can be ommited since we only use 3
- * - already checked */
+ zlog_debug(
+ "ISIS-Snp (%s): Rcvd L%d %cSNP on %s, "
+ "skipping: circuit type %s does not match level %d",
+ circuit->area->area_tag, level, typechar,
+ circuit->interface->name,
+ circuit_t2string(circuit->is_type), level);
- /* 7.3.15.2 a) 7 - Must check that we have an adjacency of the same level */
- /* for broadcast circuits, snpa should be compared */
- /* FIXME : Do we need to check SNPA? */
- if (circuit->circ_type == CIRCUIT_T_BROADCAST)
- {
- if (snp_type == ISIS_SNP_CSNP_FLAG)
- {
- adj =
- isis_adj_lookup (chdr->source_id, circuit->u.bc.adjdb[level - 1]);
- }
- else
- {
- /* a psnp on a broadcast, how lovely of Juniper :) */
- adj =
- isis_adj_lookup (phdr->source_id, circuit->u.bc.adjdb[level - 1]);
+ return ISIS_OK;
}
- if (!adj)
- return ISIS_OK; /* Silently discard */
- }
- else
- {
- if (!circuit->u.p2p.neighbor)
- {
- zlog_warn ("no p2p neighbor on circuit %s", circuit->interface->name);
- return ISIS_OK; /* Silently discard */
- }
- }
- /* 7.3.15.2 a) 8 - Passwords for level 1 - not implemented */
-
- /* 7.3.15.2 a) 9 - Passwords for level 2 - not implemented */
+ /* 7.3.15.2 a) 4 - not applicable for CSNP only PSNPs on broadcast */
+ if ((snp_type == ISIS_SNP_PSNP_FLAG)
+ && (circuit->circ_type == CIRCUIT_T_BROADCAST)
+ && (!circuit->u.bc.is_dr[level - 1])) {
+ zlog_debug(
+ "ISIS-Snp (%s): Rcvd L%d %cSNP from %s on %s, "
+ "skipping: we are not the DIS",
+ circuit->area->area_tag, level, typechar,
+ snpa_print(ssnpa), circuit->interface->name);
+
+ return ISIS_OK;
+ }
- memset (&tlvs, 0, sizeof (struct tlvs));
+ /* 7.3.15.2 a) 5 - need to make sure IDLength matches - already checked
+ */
+
+ /* 7.3.15.2 a) 6 - maximum area match, can be ommited since we only use
+ * 3
+ * - already checked */
+
+ /* 7.3.15.2 a) 7 - Must check that we have an adjacency of the same
+ * level */
+ /* for broadcast circuits, snpa should be compared */
+ /* FIXME : Do we need to check SNPA? */
+ if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
+ if (snp_type == ISIS_SNP_CSNP_FLAG) {
+ adj = isis_adj_lookup(chdr->source_id,
+ circuit->u.bc.adjdb[level - 1]);
+ } else {
+ /* a psnp on a broadcast, how lovely of Juniper :) */
+ adj = isis_adj_lookup(phdr->source_id,
+ circuit->u.bc.adjdb[level - 1]);
+ }
+ if (!adj)
+ return ISIS_OK; /* Silently discard */
+ } else {
+ if (!circuit->u.p2p.neighbor) {
+ zlog_warn("no p2p neighbor on circuit %s",
+ circuit->interface->name);
+ return ISIS_OK; /* Silently discard */
+ }
+ }
- /* parse the SNP */
- expected |= TLVFLAG_LSP_ENTRIES;
- expected |= TLVFLAG_AUTH_INFO;
+ /* 7.3.15.2 a) 8 - Passwords for level 1 - not implemented */
- auth_tlv_offset = stream_get_getp (circuit->rcv_stream);
- retval = parse_tlvs (circuit->area->area_tag,
- STREAM_PNT (circuit->rcv_stream),
- pdu_len - stream_get_getp (circuit->rcv_stream),
- &expected, &found, &tlvs, &auth_tlv_offset);
+ /* 7.3.15.2 a) 9 - Passwords for level 2 - not implemented */
- if (retval > ISIS_WARNING)
- {
- zlog_warn ("something went very wrong processing SNP");
- free_tlvs (&tlvs);
- return retval;
- }
+ memset(&tlvs, 0, sizeof(struct tlvs));
- if (level == IS_LEVEL_1)
- passwd = &circuit->area->area_passwd;
- else
- passwd = &circuit->area->domain_passwd;
+ /* parse the SNP */
+ expected |= TLVFLAG_LSP_ENTRIES;
+ expected |= TLVFLAG_AUTH_INFO;
- if (CHECK_FLAG(passwd->snp_auth, SNP_AUTH_RECV))
- {
- if (passwd->type)
- {
- if (!(found & TLVFLAG_AUTH_INFO) ||
- authentication_check (&tlvs.auth_info, passwd,
- circuit->rcv_stream, auth_tlv_offset))
- {
- isis_event_auth_failure (circuit->area->area_tag,
- "SNP authentication" " failure",
- phdr ? phdr->source_id :
- chdr->source_id);
- free_tlvs (&tlvs);
- return ISIS_OK;
- }
- }
- }
+ auth_tlv_offset = stream_get_getp(circuit->rcv_stream);
+ retval = parse_tlvs(circuit->area->area_tag,
+ STREAM_PNT(circuit->rcv_stream),
+ pdu_len - stream_get_getp(circuit->rcv_stream),
+ &expected, &found, &tlvs, &auth_tlv_offset);
- /* debug isis snp-packets */
- if (isis->debugs & DEBUG_SNP_PACKETS)
- {
- zlog_debug ("ISIS-Snp (%s): Rcvd L%d %cSNP from %s on %s",
- circuit->area->area_tag,
- level,
- typechar, snpa_print (ssnpa), circuit->interface->name);
- if (tlvs.lsp_entries)
- {
- for (ALL_LIST_ELEMENTS_RO (tlvs.lsp_entries, node, entry))
- {
- zlog_debug ("ISIS-Snp (%s): %cSNP entry %s, seq 0x%08x,"
- " cksum 0x%04x, lifetime %us",
- circuit->area->area_tag,
- typechar,
- rawlspid_print (entry->lsp_id),
- ntohl (entry->seq_num),
- ntohs (entry->checksum), ntohs (entry->rem_lifetime));
- }
+ if (retval > ISIS_WARNING) {
+ zlog_warn("something went very wrong processing SNP");
+ free_tlvs(&tlvs);
+ return retval;
}
- }
- /* 7.3.15.2 b) Actions on LSP_ENTRIES reported */
- if (tlvs.lsp_entries)
- {
- for (ALL_LIST_ELEMENTS_RO (tlvs.lsp_entries, node, entry))
- {
- lsp = lsp_search (entry->lsp_id, circuit->area->lspdb[level - 1]);
- own_lsp = !memcmp (entry->lsp_id, isis->sysid, ISIS_SYS_ID_LEN);
- if (lsp)
- {
- /* 7.3.15.2 b) 1) is this LSP newer */
- cmp = lsp_compare (circuit->area->area_tag, lsp, entry->seq_num,
- entry->checksum, entry->rem_lifetime);
- /* 7.3.15.2 b) 2) if it equals, clear SRM on p2p */
- if (cmp == LSP_EQUAL)
- {
- /* if (circuit->circ_type != CIRCUIT_T_BROADCAST) */
- ISIS_CLEAR_FLAG (lsp->SRMflags, circuit);
- }
- /* 7.3.15.2 b) 3) if it is older, clear SSN and set SRM */
- else if (cmp == LSP_OLDER)
- {
- ISIS_CLEAR_FLAG (lsp->SSNflags, circuit);
- ISIS_SET_FLAG (lsp->SRMflags, circuit);
- }
- /* 7.3.15.2 b) 4) if it is newer, set SSN and clear SRM on p2p */
- else
- {
- if (own_lsp)
- {
- lsp_inc_seqnum (lsp, ntohl (entry->seq_num));
- ISIS_SET_FLAG (lsp->SRMflags, circuit);
- }
- else
- {
- ISIS_SET_FLAG (lsp->SSNflags, circuit);
- /* if (circuit->circ_type != CIRCUIT_T_BROADCAST) */
- ISIS_CLEAR_FLAG (lsp->SRMflags, circuit);
- }
- }
- }
+ if (level == IS_LEVEL_1)
+ passwd = &circuit->area->area_passwd;
else
- {
- /* 7.3.15.2 b) 5) if it was not found, and all of those are not 0,
- * insert it and set SSN on it */
- if (entry->rem_lifetime && entry->checksum && entry->seq_num &&
- memcmp (entry->lsp_id, isis->sysid, ISIS_SYS_ID_LEN))
- {
- lsp = lsp_new(circuit->area, entry->lsp_id,
- ntohs(entry->rem_lifetime),
- 0, 0, entry->checksum, level);
- lsp_insert (lsp, circuit->area->lspdb[level - 1]);
- ISIS_FLAGS_CLEAR_ALL (lsp->SRMflags);
- ISIS_SET_FLAG (lsp->SSNflags, circuit);
- }
- }
- }
- }
+ passwd = &circuit->area->domain_passwd;
+
+ if (CHECK_FLAG(passwd->snp_auth, SNP_AUTH_RECV)) {
+ if (passwd->type) {
+ if (!(found & TLVFLAG_AUTH_INFO)
+ || authentication_check(&tlvs.auth_info, passwd,
+ circuit->rcv_stream,
+ auth_tlv_offset)) {
+ isis_event_auth_failure(circuit->area->area_tag,
+ "SNP authentication"
+ " failure",
+ phdr ? phdr->source_id
+ : chdr->source_id);
+ free_tlvs(&tlvs);
+ return ISIS_OK;
+ }
+ }
+ }
- /* 7.3.15.2 c) on CSNP set SRM for all in range which were not reported */
- if (snp_type == ISIS_SNP_CSNP_FLAG)
- {
- /*
- * Build a list from our own LSP db bounded with
- * start_lsp_id and stop_lsp_id
- */
- lsp_list = list_new ();
- lsp_build_list_nonzero_ht (chdr->start_lsp_id, chdr->stop_lsp_id,
- lsp_list, circuit->area->lspdb[level - 1]);
-
- /* Fixme: Find a better solution */
- if (tlvs.lsp_entries)
- {
- for (ALL_LIST_ELEMENTS (tlvs.lsp_entries, node, nnode, entry))
- {
- for (ALL_LIST_ELEMENTS (lsp_list, node2, nnode2, lsp))
- {
- if (lsp_id_cmp (lsp->lsp_header->lsp_id, entry->lsp_id) == 0)
- {
- list_delete_node (lsp_list, node2);
- break;
+ /* debug isis snp-packets */
+ if (isis->debugs & DEBUG_SNP_PACKETS) {
+ zlog_debug("ISIS-Snp (%s): Rcvd L%d %cSNP from %s on %s",
+ circuit->area->area_tag, level, typechar,
+ snpa_print(ssnpa), circuit->interface->name);
+ if (tlvs.lsp_entries) {
+ for (ALL_LIST_ELEMENTS_RO(tlvs.lsp_entries, node,
+ entry)) {
+ zlog_debug(
+ "ISIS-Snp (%s): %cSNP entry %s, seq 0x%08x,"
+ " cksum 0x%04x, lifetime %us",
+ circuit->area->area_tag, typechar,
+ rawlspid_print(entry->lsp_id),
+ ntohl(entry->seq_num),
+ ntohs(entry->checksum),
+ ntohs(entry->rem_lifetime));
+ }
}
- }
- }
}
- /* on remaining LSPs we set SRM (neighbor knew not of) */
- for (ALL_LIST_ELEMENTS_RO (lsp_list, node, lsp))
- ISIS_SET_FLAG (lsp->SRMflags, circuit);
- /* lets free it */
- list_delete (lsp_list);
- }
+ /* 7.3.15.2 b) Actions on LSP_ENTRIES reported */
+ if (tlvs.lsp_entries) {
+ for (ALL_LIST_ELEMENTS_RO(tlvs.lsp_entries, node, entry)) {
+ lsp = lsp_search(entry->lsp_id,
+ circuit->area->lspdb[level - 1]);
+ own_lsp = !memcmp(entry->lsp_id, isis->sysid,
+ ISIS_SYS_ID_LEN);
+ if (lsp) {
+ /* 7.3.15.2 b) 1) is this LSP newer */
+ cmp = lsp_compare(circuit->area->area_tag, lsp,
+ entry->seq_num,
+ entry->checksum,
+ entry->rem_lifetime);
+ /* 7.3.15.2 b) 2) if it equals, clear SRM on p2p
+ */
+ if (cmp == LSP_EQUAL) {
+ /* if (circuit->circ_type !=
+ * CIRCUIT_T_BROADCAST) */
+ ISIS_CLEAR_FLAG(lsp->SRMflags, circuit);
+ }
+ /* 7.3.15.2 b) 3) if it is older, clear SSN and
+ set SRM */
+ else if (cmp == LSP_OLDER) {
+ ISIS_CLEAR_FLAG(lsp->SSNflags, circuit);
+ ISIS_SET_FLAG(lsp->SRMflags, circuit);
+ }
+ /* 7.3.15.2 b) 4) if it is newer, set SSN and
+ clear SRM on p2p */
+ else {
+ if (own_lsp) {
+ lsp_inc_seqnum(
+ lsp,
+ ntohl(entry->seq_num));
+ ISIS_SET_FLAG(lsp->SRMflags,
+ circuit);
+ } else {
+ ISIS_SET_FLAG(lsp->SSNflags,
+ circuit);
+ /* if (circuit->circ_type !=
+ * CIRCUIT_T_BROADCAST) */
+ ISIS_CLEAR_FLAG(lsp->SRMflags,
+ circuit);
+ }
+ }
+ } else {
+ /* 7.3.15.2 b) 5) if it was not found, and all
+ * of those are not 0,
+ * insert it and set SSN on it */
+ if (entry->rem_lifetime && entry->checksum
+ && entry->seq_num
+ && memcmp(entry->lsp_id, isis->sysid,
+ ISIS_SYS_ID_LEN)) {
+ lsp = lsp_new(
+ circuit->area, entry->lsp_id,
+ ntohs(entry->rem_lifetime), 0,
+ 0, entry->checksum, level);
+ lsp_insert(lsp,
+ circuit->area
+ ->lspdb[level - 1]);
+ ISIS_FLAGS_CLEAR_ALL(lsp->SRMflags);
+ ISIS_SET_FLAG(lsp->SSNflags, circuit);
+ }
+ }
+ }
+ }
- free_tlvs (&tlvs);
- return retval;
+ /* 7.3.15.2 c) on CSNP set SRM for all in range which were not reported
+ */
+ if (snp_type == ISIS_SNP_CSNP_FLAG) {
+ /*
+ * Build a list from our own LSP db bounded with
+ * start_lsp_id and stop_lsp_id
+ */
+ lsp_list = list_new();
+ lsp_build_list_nonzero_ht(chdr->start_lsp_id, chdr->stop_lsp_id,
+ lsp_list,
+ circuit->area->lspdb[level - 1]);
+
+ /* Fixme: Find a better solution */
+ if (tlvs.lsp_entries) {
+ for (ALL_LIST_ELEMENTS(tlvs.lsp_entries, node, nnode,
+ entry)) {
+ for (ALL_LIST_ELEMENTS(lsp_list, node2, nnode2,
+ lsp)) {
+ if (lsp_id_cmp(lsp->lsp_header->lsp_id,
+ entry->lsp_id)
+ == 0) {
+ list_delete_node(lsp_list,
+ node2);
+ break;
+ }
+ }
+ }
+ }
+ /* on remaining LSPs we set SRM (neighbor knew not of) */
+ for (ALL_LIST_ELEMENTS_RO(lsp_list, node, lsp))
+ ISIS_SET_FLAG(lsp->SRMflags, circuit);
+ /* lets free it */
+ list_delete(lsp_list);
+ }
+
+ free_tlvs(&tlvs);
+ return retval;
}
-static int
-process_csnp (int level, struct isis_circuit *circuit, const u_char *ssnpa)
+static int process_csnp(int level, struct isis_circuit *circuit,
+ const u_char *ssnpa)
{
- if (isis->debugs & DEBUG_SNP_PACKETS)
- {
- zlog_debug ("ISIS-Snp (%s): Rcvd L%d CSNP on %s, cirType %s, cirID %u",
- circuit->area->area_tag, level, circuit->interface->name,
- circuit_t2string (circuit->is_type), circuit->circuit_id);
- if (isis->debugs & DEBUG_PACKET_DUMP)
- zlog_dump_data (STREAM_DATA (circuit->rcv_stream),
- stream_get_endp (circuit->rcv_stream));
- }
+ if (isis->debugs & DEBUG_SNP_PACKETS) {
+ zlog_debug(
+ "ISIS-Snp (%s): Rcvd L%d CSNP on %s, cirType %s, cirID %u",
+ circuit->area->area_tag, level,
+ circuit->interface->name,
+ circuit_t2string(circuit->is_type),
+ circuit->circuit_id);
+ if (isis->debugs & DEBUG_PACKET_DUMP)
+ zlog_dump_data(STREAM_DATA(circuit->rcv_stream),
+ stream_get_endp(circuit->rcv_stream));
+ }
- /* Sanity check - FIXME: move to correct place */
- if ((stream_get_endp (circuit->rcv_stream) -
- stream_get_getp (circuit->rcv_stream)) < ISIS_CSNP_HDRLEN)
- {
- zlog_warn ("Packet too short ( < %d)", ISIS_CSNP_HDRLEN);
- return ISIS_WARNING;
- }
+ /* Sanity check - FIXME: move to correct place */
+ if ((stream_get_endp(circuit->rcv_stream)
+ - stream_get_getp(circuit->rcv_stream))
+ < ISIS_CSNP_HDRLEN) {
+ zlog_warn("Packet too short ( < %d)", ISIS_CSNP_HDRLEN);
+ return ISIS_WARNING;
+ }
- return process_snp (ISIS_SNP_CSNP_FLAG, level, circuit, ssnpa);
+ return process_snp(ISIS_SNP_CSNP_FLAG, level, circuit, ssnpa);
}
-static int
-process_psnp (int level, struct isis_circuit *circuit, const u_char *ssnpa)
+static int process_psnp(int level, struct isis_circuit *circuit,
+ const u_char *ssnpa)
{
- if (isis->debugs & DEBUG_SNP_PACKETS)
- {
- zlog_debug ("ISIS-Snp (%s): Rcvd L%d PSNP on %s, cirType %s, cirID %u",
- circuit->area->area_tag, level, circuit->interface->name,
- circuit_t2string (circuit->is_type), circuit->circuit_id);
- if (isis->debugs & DEBUG_PACKET_DUMP)
- zlog_dump_data (STREAM_DATA (circuit->rcv_stream),
- stream_get_endp (circuit->rcv_stream));
- }
+ if (isis->debugs & DEBUG_SNP_PACKETS) {
+ zlog_debug(
+ "ISIS-Snp (%s): Rcvd L%d PSNP on %s, cirType %s, cirID %u",
+ circuit->area->area_tag, level,
+ circuit->interface->name,
+ circuit_t2string(circuit->is_type),
+ circuit->circuit_id);
+ if (isis->debugs & DEBUG_PACKET_DUMP)
+ zlog_dump_data(STREAM_DATA(circuit->rcv_stream),
+ stream_get_endp(circuit->rcv_stream));
+ }
- if ((stream_get_endp (circuit->rcv_stream) -
- stream_get_getp (circuit->rcv_stream)) < ISIS_PSNP_HDRLEN)
- {
- zlog_warn ("Packet too short ( < %d)", ISIS_PSNP_HDRLEN);
- return ISIS_WARNING;
- }
+ if ((stream_get_endp(circuit->rcv_stream)
+ - stream_get_getp(circuit->rcv_stream))
+ < ISIS_PSNP_HDRLEN) {
+ zlog_warn("Packet too short ( < %d)", ISIS_PSNP_HDRLEN);
+ return ISIS_WARNING;
+ }
- return process_snp (ISIS_SNP_PSNP_FLAG, level, circuit, ssnpa);
+ return process_snp(ISIS_SNP_PSNP_FLAG, level, circuit, ssnpa);
}
/*
* PDU Dispatcher
*/
-static int
-isis_handle_pdu (struct isis_circuit *circuit, u_char * ssnpa)
+static int isis_handle_pdu(struct isis_circuit *circuit, u_char *ssnpa)
{
- struct isis_fixed_hdr *hdr;
+ struct isis_fixed_hdr *hdr;
- int retval = ISIS_OK;
+ int retval = ISIS_OK;
- /*
- * Let's first read data from stream to the header
- */
- hdr = (struct isis_fixed_hdr *) STREAM_DATA (circuit->rcv_stream);
+ /*
+ * Let's first read data from stream to the header
+ */
+ hdr = (struct isis_fixed_hdr *)STREAM_DATA(circuit->rcv_stream);
- if ((hdr->idrp != ISO10589_ISIS) && (hdr->idrp != ISO9542_ESIS))
- {
- zlog_err ("Not an IS-IS or ES-IS packet IDRP=%02x", hdr->idrp);
- return ISIS_ERROR;
- }
+ if ((hdr->idrp != ISO10589_ISIS) && (hdr->idrp != ISO9542_ESIS)) {
+ zlog_err("Not an IS-IS or ES-IS packet IDRP=%02x", hdr->idrp);
+ return ISIS_ERROR;
+ }
- /* now we need to know if this is an ISO 9542 packet and
- * take real good care of it, waaa!
- */
- if (hdr->idrp == ISO9542_ESIS)
- {
- zlog_err ("No support for ES-IS packet IDRP=%02x", hdr->idrp);
- return ISIS_ERROR;
- }
- stream_set_getp (circuit->rcv_stream, ISIS_FIXED_HDR_LEN);
+ /* now we need to know if this is an ISO 9542 packet and
+ * take real good care of it, waaa!
+ */
+ if (hdr->idrp == ISO9542_ESIS) {
+ zlog_err("No support for ES-IS packet IDRP=%02x", hdr->idrp);
+ return ISIS_ERROR;
+ }
+ stream_set_getp(circuit->rcv_stream, ISIS_FIXED_HDR_LEN);
- /*
- * and then process it
- */
+ /*
+ * and then process it
+ */
- if (hdr->length < ISIS_MINIMUM_FIXED_HDR_LEN)
- {
- zlog_err ("Fixed header length = %d", hdr->length);
- return ISIS_ERROR;
- }
+ if (hdr->length < ISIS_MINIMUM_FIXED_HDR_LEN) {
+ zlog_err("Fixed header length = %d", hdr->length);
+ return ISIS_ERROR;
+ }
- if (hdr->version1 != 1)
- {
- zlog_warn ("Unsupported ISIS version %u", hdr->version1);
- return ISIS_WARNING;
- }
- /* either 6 or 0 */
- if ((hdr->id_len != 0) && (hdr->id_len != ISIS_SYS_ID_LEN))
- {
- zlog_err
- ("IDFieldLengthMismatch: ID Length field in a received PDU %u, "
- "while the parameter for this IS is %u", hdr->id_len,
- ISIS_SYS_ID_LEN);
- return ISIS_ERROR;
- }
+ if (hdr->version1 != 1) {
+ zlog_warn("Unsupported ISIS version %u", hdr->version1);
+ return ISIS_WARNING;
+ }
+ /* either 6 or 0 */
+ if ((hdr->id_len != 0) && (hdr->id_len != ISIS_SYS_ID_LEN)) {
+ zlog_err(
+ "IDFieldLengthMismatch: ID Length field in a received PDU %u, "
+ "while the parameter for this IS is %u",
+ hdr->id_len, ISIS_SYS_ID_LEN);
+ return ISIS_ERROR;
+ }
- if (hdr->version2 != 1)
- {
- zlog_warn ("Unsupported ISIS version %u", hdr->version2);
- return ISIS_WARNING;
- }
+ if (hdr->version2 != 1) {
+ zlog_warn("Unsupported ISIS version %u", hdr->version2);
+ return ISIS_WARNING;
+ }
- if (circuit->is_passive)
- {
- zlog_warn ("Received ISIS PDU on passive circuit %s",
- circuit->interface->name);
- return ISIS_WARNING;
- }
+ if (circuit->is_passive) {
+ zlog_warn("Received ISIS PDU on passive circuit %s",
+ circuit->interface->name);
+ return ISIS_WARNING;
+ }
- /* either 3 or 0 */
- if ((hdr->max_area_addrs != 0)
- && (hdr->max_area_addrs != isis->max_area_addrs))
- {
- zlog_err ("maximumAreaAddressesMismatch: maximumAreaAdresses in a "
- "received PDU %u while the parameter for this IS is %u",
- hdr->max_area_addrs, isis->max_area_addrs);
- return ISIS_ERROR;
- }
+ /* either 3 or 0 */
+ if ((hdr->max_area_addrs != 0)
+ && (hdr->max_area_addrs != isis->max_area_addrs)) {
+ zlog_err(
+ "maximumAreaAddressesMismatch: maximumAreaAdresses in a "
+ "received PDU %u while the parameter for this IS is %u",
+ hdr->max_area_addrs, isis->max_area_addrs);
+ return ISIS_ERROR;
+ }
- switch (hdr->pdu_type)
- {
- case L1_LAN_HELLO:
- retval = process_lan_hello (ISIS_LEVEL1, circuit, ssnpa);
- break;
- case L2_LAN_HELLO:
- retval = process_lan_hello (ISIS_LEVEL2, circuit, ssnpa);
- break;
- case P2P_HELLO:
- retval = process_p2p_hello (circuit);
- break;
- case L1_LINK_STATE:
- retval = process_lsp (ISIS_LEVEL1, circuit, ssnpa);
- break;
- case L2_LINK_STATE:
- retval = process_lsp (ISIS_LEVEL2, circuit, ssnpa);
- break;
- case L1_COMPLETE_SEQ_NUM:
- retval = process_csnp (ISIS_LEVEL1, circuit, ssnpa);
- break;
- case L2_COMPLETE_SEQ_NUM:
- retval = process_csnp (ISIS_LEVEL2, circuit, ssnpa);
- break;
- case L1_PARTIAL_SEQ_NUM:
- retval = process_psnp (ISIS_LEVEL1, circuit, ssnpa);
- break;
- case L2_PARTIAL_SEQ_NUM:
- retval = process_psnp (ISIS_LEVEL2, circuit, ssnpa);
- break;
- default:
- return ISIS_ERROR;
- }
+ switch (hdr->pdu_type) {
+ case L1_LAN_HELLO:
+ retval = process_lan_hello(ISIS_LEVEL1, circuit, ssnpa);
+ break;
+ case L2_LAN_HELLO:
+ retval = process_lan_hello(ISIS_LEVEL2, circuit, ssnpa);
+ break;
+ case P2P_HELLO:
+ retval = process_p2p_hello(circuit);
+ break;
+ case L1_LINK_STATE:
+ retval = process_lsp(ISIS_LEVEL1, circuit, ssnpa);
+ break;
+ case L2_LINK_STATE:
+ retval = process_lsp(ISIS_LEVEL2, circuit, ssnpa);
+ break;
+ case L1_COMPLETE_SEQ_NUM:
+ retval = process_csnp(ISIS_LEVEL1, circuit, ssnpa);
+ break;
+ case L2_COMPLETE_SEQ_NUM:
+ retval = process_csnp(ISIS_LEVEL2, circuit, ssnpa);
+ break;
+ case L1_PARTIAL_SEQ_NUM:
+ retval = process_psnp(ISIS_LEVEL1, circuit, ssnpa);
+ break;
+ case L2_PARTIAL_SEQ_NUM:
+ retval = process_psnp(ISIS_LEVEL2, circuit, ssnpa);
+ break;
+ default:
+ return ISIS_ERROR;
+ }
- return retval;
+ return retval;
}
-int
-isis_receive (struct thread *thread)
+int isis_receive(struct thread *thread)
{
- struct isis_circuit *circuit;
- u_char ssnpa[ETH_ALEN];
- int retval;
+ struct isis_circuit *circuit;
+ u_char ssnpa[ETH_ALEN];
+ int retval;
- /*
- * Get the circuit
- */
- circuit = THREAD_ARG (thread);
- assert (circuit);
+ /*
+ * Get the circuit
+ */
+ circuit = THREAD_ARG(thread);
+ assert(circuit);
- circuit->t_read = NULL;
+ circuit->t_read = NULL;
- isis_circuit_stream(circuit, &circuit->rcv_stream);
+ isis_circuit_stream(circuit, &circuit->rcv_stream);
- retval = circuit->rx (circuit, ssnpa);
+ retval = circuit->rx(circuit, ssnpa);
- if (retval == ISIS_OK)
- retval = isis_handle_pdu (circuit, ssnpa);
+ if (retval == ISIS_OK)
+ retval = isis_handle_pdu(circuit, ssnpa);
- /*
- * prepare for next packet.
- */
- if (!circuit->is_passive)
- isis_circuit_prepare (circuit);
+ /*
+ * prepare for next packet.
+ */
+ if (!circuit->is_passive)
+ isis_circuit_prepare(circuit);
- return retval;
+ return retval;
}
- /* filling of the fixed isis header */
-void
-fill_fixed_hdr (struct isis_fixed_hdr *hdr, u_char pdu_type)
+/* filling of the fixed isis header */
+void fill_fixed_hdr(struct isis_fixed_hdr *hdr, u_char pdu_type)
{
- memset (hdr, 0, sizeof (struct isis_fixed_hdr));
-
- hdr->idrp = ISO10589_ISIS;
-
- switch (pdu_type)
- {
- case L1_LAN_HELLO:
- case L2_LAN_HELLO:
- hdr->length = ISIS_LANHELLO_HDRLEN;
- break;
- case P2P_HELLO:
- hdr->length = ISIS_P2PHELLO_HDRLEN;
- break;
- case L1_LINK_STATE:
- case L2_LINK_STATE:
- hdr->length = ISIS_LSP_HDR_LEN;
- break;
- case L1_COMPLETE_SEQ_NUM:
- case L2_COMPLETE_SEQ_NUM:
- hdr->length = ISIS_CSNP_HDRLEN;
- break;
- case L1_PARTIAL_SEQ_NUM:
- case L2_PARTIAL_SEQ_NUM:
- hdr->length = ISIS_PSNP_HDRLEN;
- break;
- default:
- zlog_warn ("fill_fixed_hdr(): unknown pdu type %d", pdu_type);
- return;
- }
- hdr->length += ISIS_FIXED_HDR_LEN;
- hdr->pdu_type = pdu_type;
- hdr->version1 = 1;
- hdr->id_len = 0; /* ISIS_SYS_ID_LEN - 0==6 */
- hdr->version2 = 1;
- hdr->max_area_addrs = 0; /* isis->max_area_addrs - 0==3 */
+ memset(hdr, 0, sizeof(struct isis_fixed_hdr));
+
+ hdr->idrp = ISO10589_ISIS;
+
+ switch (pdu_type) {
+ case L1_LAN_HELLO:
+ case L2_LAN_HELLO:
+ hdr->length = ISIS_LANHELLO_HDRLEN;
+ break;
+ case P2P_HELLO:
+ hdr->length = ISIS_P2PHELLO_HDRLEN;
+ break;
+ case L1_LINK_STATE:
+ case L2_LINK_STATE:
+ hdr->length = ISIS_LSP_HDR_LEN;
+ break;
+ case L1_COMPLETE_SEQ_NUM:
+ case L2_COMPLETE_SEQ_NUM:
+ hdr->length = ISIS_CSNP_HDRLEN;
+ break;
+ case L1_PARTIAL_SEQ_NUM:
+ case L2_PARTIAL_SEQ_NUM:
+ hdr->length = ISIS_PSNP_HDRLEN;
+ break;
+ default:
+ zlog_warn("fill_fixed_hdr(): unknown pdu type %d", pdu_type);
+ return;
+ }
+ hdr->length += ISIS_FIXED_HDR_LEN;
+ hdr->pdu_type = pdu_type;
+ hdr->version1 = 1;
+ hdr->id_len = 0; /* ISIS_SYS_ID_LEN - 0==6 */
+ hdr->version2 = 1;
+ hdr->max_area_addrs = 0; /* isis->max_area_addrs - 0==3 */
}
/*
- * SEND SIDE
+ * SEND SIDE
*/
-static void
-fill_fixed_hdr_andstream (struct isis_fixed_hdr *hdr, u_char pdu_type,
- struct stream *stream)
+static void fill_fixed_hdr_andstream(struct isis_fixed_hdr *hdr,
+ u_char pdu_type, struct stream *stream)
{
- fill_fixed_hdr (hdr, pdu_type);
-
- stream_putc (stream, hdr->idrp);
- stream_putc (stream, hdr->length);
- stream_putc (stream, hdr->version1);
- stream_putc (stream, hdr->id_len);
- stream_putc (stream, hdr->pdu_type);
- stream_putc (stream, hdr->version2);
- stream_putc (stream, hdr->reserved);
- stream_putc (stream, hdr->max_area_addrs);
-
- return;
+ fill_fixed_hdr(hdr, pdu_type);
+
+ stream_putc(stream, hdr->idrp);
+ stream_putc(stream, hdr->length);
+ stream_putc(stream, hdr->version1);
+ stream_putc(stream, hdr->id_len);
+ stream_putc(stream, hdr->pdu_type);
+ stream_putc(stream, hdr->version2);
+ stream_putc(stream, hdr->reserved);
+ stream_putc(stream, hdr->max_area_addrs);
+
+ return;
}
-int
-send_hello (struct isis_circuit *circuit, int level)
+int 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;
- unsigned char hmac_md5_hash[ISIS_AUTH_MD5_SIZE];
- size_t len_pointer, length, auth_tlv_offset = 0;
- u_int32_t interval;
- int retval;
-
- if (circuit->is_passive)
- return ISIS_OK;
-
- if (circuit->interface->mtu == 0)
- {
- zlog_warn ("circuit has zero MTU");
- return ISIS_WARNING;
- }
-
- isis_circuit_stream(circuit, &circuit->snd_stream);
-
- if (circuit->circ_type == CIRCUIT_T_BROADCAST)
- if (level == IS_LEVEL_1)
- fill_fixed_hdr_andstream (&fixed_hdr, L1_LAN_HELLO,
- circuit->snd_stream);
- else
- fill_fixed_hdr_andstream (&fixed_hdr, L2_LAN_HELLO,
- circuit->snd_stream);
- else
- fill_fixed_hdr_andstream (&fixed_hdr, P2P_HELLO, circuit->snd_stream);
-
- /*
- * Fill LAN Level 1 or 2 Hello PDU header
- */
- memset (&hello_hdr, 0, sizeof (struct isis_lan_hello_hdr));
- interval = circuit->hello_multiplier[level - 1] *
- circuit->hello_interval[level - 1];
- if (interval > USHRT_MAX)
- interval = USHRT_MAX;
- hello_hdr.circuit_t = circuit->is_type;
- memcpy (hello_hdr.source_id, isis->sysid, ISIS_SYS_ID_LEN);
- hello_hdr.hold_time = htons ((u_int16_t) interval);
-
- hello_hdr.pdu_len = 0; /* Update the PDU Length later */
- len_pointer = stream_get_endp (circuit->snd_stream) + 3 + ISIS_SYS_ID_LEN;
-
- /* copy the shared part of the hello to the p2p hello if needed */
- if (circuit->circ_type == CIRCUIT_T_P2P)
- {
- memcpy (&p2p_hello_hdr, &hello_hdr, 5 + ISIS_SYS_ID_LEN);
- p2p_hello_hdr.local_id = circuit->circuit_id;
- /* FIXME: need better understanding */
- stream_put (circuit->snd_stream, &p2p_hello_hdr, ISIS_P2PHELLO_HDRLEN);
- }
- else
- {
- hello_hdr.prio = circuit->priority[level - 1];
- if (level == IS_LEVEL_1)
- {
- memcpy (hello_hdr.lan_id, circuit->u.bc.l1_desig_is,
- ISIS_SYS_ID_LEN + 1);
- }
- else if (level == IS_LEVEL_2)
- {
- memcpy (hello_hdr.lan_id, circuit->u.bc.l2_desig_is,
- ISIS_SYS_ID_LEN + 1);
+ struct isis_fixed_hdr fixed_hdr;
+ struct isis_lan_hello_hdr hello_hdr;
+ struct isis_p2p_hello_hdr p2p_hello_hdr;
+ unsigned char hmac_md5_hash[ISIS_AUTH_MD5_SIZE];
+ size_t len_pointer, length, auth_tlv_offset = 0;
+ u_int32_t interval;
+ int retval;
+
+ if (circuit->is_passive)
+ return ISIS_OK;
+
+ if (circuit->interface->mtu == 0) {
+ zlog_warn("circuit has zero MTU");
+ return ISIS_WARNING;
}
- stream_put (circuit->snd_stream, &hello_hdr, ISIS_LANHELLO_HDRLEN);
- }
- /*
- * Then the variable length part.
- */
-
- /* add circuit password */
- switch (circuit->passwd.type)
- {
- /* Cleartext */
- case ISIS_PASSWD_TYPE_CLEARTXT:
- if (tlv_add_authinfo (circuit->passwd.type, circuit->passwd.len,
- circuit->passwd.passwd, circuit->snd_stream))
- return ISIS_WARNING;
- break;
-
- /* HMAC MD5 */
- case ISIS_PASSWD_TYPE_HMAC_MD5:
- /* Remember where TLV is written so we can later overwrite the MD5 hash */
- auth_tlv_offset = stream_get_endp (circuit->snd_stream);
- memset(&hmac_md5_hash, 0, ISIS_AUTH_MD5_SIZE);
- if (tlv_add_authinfo (circuit->passwd.type, ISIS_AUTH_MD5_SIZE,
- hmac_md5_hash, circuit->snd_stream))
- return ISIS_WARNING;
- break;
-
- default:
- break;
- }
-
- /* Area Addresses TLV */
- if (listcount (circuit->area->area_addrs) == 0)
- return ISIS_WARNING;
- 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)
- {
- if (level == IS_LEVEL_1 && circuit->u.bc.lan_neighs[0] &&
- listcount (circuit->u.bc.lan_neighs[0]) > 0)
- if (tlv_add_lan_neighs (circuit->u.bc.lan_neighs[0],
- circuit->snd_stream))
- return ISIS_WARNING;
- if (level == IS_LEVEL_2 && circuit->u.bc.lan_neighs[1] &&
- listcount (circuit->u.bc.lan_neighs[1]) > 0)
- if (tlv_add_lan_neighs (circuit->u.bc.lan_neighs[1],
- 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;
- /* IP interface Address TLV */
- if (circuit->ip_router && circuit->ip_addrs &&
- listcount (circuit->ip_addrs) > 0)
- if (tlv_add_ip_addrs (circuit->ip_addrs, circuit->snd_stream))
- return ISIS_WARNING;
+ isis_circuit_stream(circuit, &circuit->snd_stream);
- /*
- * MT Supported TLV
- *
- * TLV gets included if no topology is enabled on the interface,
- * if one topology other than #0 is enabled, or if multiple topologies
- * are enabled.
- */
- struct isis_circuit_mt_setting **mt_settings;
- unsigned int mt_count;
-
- mt_settings = circuit_mt_settings(circuit, &mt_count);
- if ((mt_count == 0 && area_is_mt(circuit->area))
- || (mt_count == 1 && mt_settings[0]->mtid != ISIS_MT_IPV4_UNICAST)
- || (mt_count > 1))
- {
- struct list *mt_info = list_new();
- mt_info->del = free_tlv;
-
- for (unsigned int i = 0; i < mt_count; i++)
- {
- struct mt_router_info *info;
-
- info = XCALLOC(MTYPE_ISIS_TLV, sizeof(*info));
- info->mtid = mt_settings[i]->mtid;
- /* overload info is not valid in IIH, so it's not included here */
- listnode_add(mt_info, info);
- }
- tlv_add_mt_router_info (mt_info, circuit->snd_stream);
- list_free(mt_info);
- }
-
- /* IPv6 Interface Address TLV */
- if (circuit->ipv6_router && circuit->ipv6_link &&
- listcount (circuit->ipv6_link) > 0)
- if (tlv_add_ipv6_addrs (circuit->ipv6_link, circuit->snd_stream))
- return ISIS_WARNING;
+ if (circuit->circ_type == CIRCUIT_T_BROADCAST)
+ if (level == IS_LEVEL_1)
+ fill_fixed_hdr_andstream(&fixed_hdr, L1_LAN_HELLO,
+ circuit->snd_stream);
+ else
+ fill_fixed_hdr_andstream(&fixed_hdr, L2_LAN_HELLO,
+ circuit->snd_stream);
+ else
+ fill_fixed_hdr_andstream(&fixed_hdr, P2P_HELLO,
+ circuit->snd_stream);
+
+ /*
+ * Fill LAN Level 1 or 2 Hello PDU header
+ */
+ memset(&hello_hdr, 0, sizeof(struct isis_lan_hello_hdr));
+ interval = circuit->hello_multiplier[level - 1]
+ * circuit->hello_interval[level - 1];
+ if (interval > USHRT_MAX)
+ interval = USHRT_MAX;
+ hello_hdr.circuit_t = circuit->is_type;
+ memcpy(hello_hdr.source_id, isis->sysid, ISIS_SYS_ID_LEN);
+ hello_hdr.hold_time = htons((u_int16_t)interval);
+
+ hello_hdr.pdu_len = 0; /* Update the PDU Length later */
+ len_pointer =
+ stream_get_endp(circuit->snd_stream) + 3 + ISIS_SYS_ID_LEN;
+
+ /* copy the shared part of the hello to the p2p hello if needed */
+ if (circuit->circ_type == CIRCUIT_T_P2P) {
+ memcpy(&p2p_hello_hdr, &hello_hdr, 5 + ISIS_SYS_ID_LEN);
+ p2p_hello_hdr.local_id = circuit->circuit_id;
+ /* FIXME: need better understanding */
+ stream_put(circuit->snd_stream, &p2p_hello_hdr,
+ ISIS_P2PHELLO_HDRLEN);
+ } else {
+ hello_hdr.prio = circuit->priority[level - 1];
+ if (level == IS_LEVEL_1) {
+ memcpy(hello_hdr.lan_id, circuit->u.bc.l1_desig_is,
+ ISIS_SYS_ID_LEN + 1);
+ } else if (level == IS_LEVEL_2) {
+ memcpy(hello_hdr.lan_id, circuit->u.bc.l2_desig_is,
+ ISIS_SYS_ID_LEN + 1);
+ }
+ stream_put(circuit->snd_stream, &hello_hdr,
+ ISIS_LANHELLO_HDRLEN);
+ }
- if (circuit->pad_hellos)
- if (tlv_add_padding (circuit->snd_stream))
- return ISIS_WARNING;
+ /*
+ * Then the variable length part.
+ */
+
+ /* add circuit password */
+ switch (circuit->passwd.type) {
+ /* Cleartext */
+ case ISIS_PASSWD_TYPE_CLEARTXT:
+ if (tlv_add_authinfo(circuit->passwd.type, circuit->passwd.len,
+ circuit->passwd.passwd,
+ circuit->snd_stream))
+ return ISIS_WARNING;
+ break;
+
+ /* HMAC MD5 */
+ case ISIS_PASSWD_TYPE_HMAC_MD5:
+ /* Remember where TLV is written so we can later overwrite the
+ * MD5 hash */
+ auth_tlv_offset = stream_get_endp(circuit->snd_stream);
+ memset(&hmac_md5_hash, 0, ISIS_AUTH_MD5_SIZE);
+ if (tlv_add_authinfo(circuit->passwd.type, ISIS_AUTH_MD5_SIZE,
+ hmac_md5_hash, circuit->snd_stream))
+ return ISIS_WARNING;
+ break;
+
+ default:
+ break;
+ }
- length = stream_get_endp (circuit->snd_stream);
- /* Update PDU length */
- stream_putw_at (circuit->snd_stream, len_pointer, (u_int16_t) length);
+ /* Area Addresses TLV */
+ if (listcount(circuit->area->area_addrs) == 0)
+ return ISIS_WARNING;
+ 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) {
+ if (level == IS_LEVEL_1 && circuit->u.bc.lan_neighs[0]
+ && listcount(circuit->u.bc.lan_neighs[0]) > 0)
+ if (tlv_add_lan_neighs(circuit->u.bc.lan_neighs[0],
+ circuit->snd_stream))
+ return ISIS_WARNING;
+ if (level == IS_LEVEL_2 && circuit->u.bc.lan_neighs[1]
+ && listcount(circuit->u.bc.lan_neighs[1]) > 0)
+ if (tlv_add_lan_neighs(circuit->u.bc.lan_neighs[1],
+ circuit->snd_stream))
+ return ISIS_WARNING;
+ }
- /* For HMAC MD5 we need to compute the md5 hash and store it */
- if (circuit->passwd.type == ISIS_PASSWD_TYPE_HMAC_MD5)
- {
- hmac_md5 (STREAM_DATA (circuit->snd_stream),
- 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 (STREAM_DATA (circuit->snd_stream) + auth_tlv_offset + 3,
- hmac_md5_hash, ISIS_AUTH_MD5_SIZE);
- }
+ /* Protocols Supported TLV */
+ if (circuit->nlpids.count > 0)
+ if (tlv_add_nlpid(&circuit->nlpids, circuit->snd_stream))
+ return ISIS_WARNING;
+ /* IP interface Address TLV */
+ if (circuit->ip_router && circuit->ip_addrs
+ && listcount(circuit->ip_addrs) > 0)
+ if (tlv_add_ip_addrs(circuit->ip_addrs, circuit->snd_stream))
+ return ISIS_WARNING;
+
+ /*
+ * MT Supported TLV
+ *
+ * TLV gets included if no topology is enabled on the interface,
+ * if one topology other than #0 is enabled, or if multiple topologies
+ * are enabled.
+ */
+ struct isis_circuit_mt_setting **mt_settings;
+ unsigned int mt_count;
+
+ mt_settings = circuit_mt_settings(circuit, &mt_count);
+ if ((mt_count == 0 && area_is_mt(circuit->area))
+ || (mt_count == 1 && mt_settings[0]->mtid != ISIS_MT_IPV4_UNICAST)
+ || (mt_count > 1)) {
+ struct list *mt_info = list_new();
+ mt_info->del = free_tlv;
+
+ for (unsigned int i = 0; i < mt_count; i++) {
+ struct mt_router_info *info;
+
+ info = XCALLOC(MTYPE_ISIS_TLV, sizeof(*info));
+ info->mtid = mt_settings[i]->mtid;
+ /* overload info is not valid in IIH, so it's not
+ * included here */
+ listnode_add(mt_info, info);
+ }
+ tlv_add_mt_router_info(mt_info, circuit->snd_stream);
+ list_free(mt_info);
+ }
- if (isis->debugs & DEBUG_ADJ_PACKETS)
- {
- if (circuit->circ_type == CIRCUIT_T_BROADCAST)
- {
- zlog_debug ("ISIS-Adj (%s): Sending L%d LAN IIH on %s, length %zd",
- circuit->area->area_tag, level, circuit->interface->name,
- length);
+ /* IPv6 Interface Address TLV */
+ if (circuit->ipv6_router && circuit->ipv6_link
+ && listcount(circuit->ipv6_link) > 0)
+ if (tlv_add_ipv6_addrs(circuit->ipv6_link, circuit->snd_stream))
+ return ISIS_WARNING;
+
+ if (circuit->pad_hellos)
+ if (tlv_add_padding(circuit->snd_stream))
+ return ISIS_WARNING;
+
+ length = stream_get_endp(circuit->snd_stream);
+ /* 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(STREAM_DATA(circuit->snd_stream),
+ 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(STREAM_DATA(circuit->snd_stream) + auth_tlv_offset + 3,
+ hmac_md5_hash, ISIS_AUTH_MD5_SIZE);
}
- else
- {
- zlog_debug ("ISIS-Adj (%s): Sending P2P IIH on %s, length %zd",
- circuit->area->area_tag, circuit->interface->name,
- length);
+
+ if (isis->debugs & DEBUG_ADJ_PACKETS) {
+ if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
+ zlog_debug(
+ "ISIS-Adj (%s): Sending L%d LAN IIH on %s, length %zd",
+ circuit->area->area_tag, level,
+ circuit->interface->name, length);
+ } else {
+ zlog_debug(
+ "ISIS-Adj (%s): Sending P2P IIH on %s, length %zd",
+ circuit->area->area_tag,
+ circuit->interface->name, length);
+ }
+ if (isis->debugs & DEBUG_PACKET_DUMP)
+ zlog_dump_data(STREAM_DATA(circuit->snd_stream),
+ stream_get_endp(circuit->snd_stream));
}
- if (isis->debugs & DEBUG_PACKET_DUMP)
- zlog_dump_data (STREAM_DATA (circuit->snd_stream),
- stream_get_endp (circuit->snd_stream));
- }
- retval = circuit->tx (circuit, level);
- if (retval != ISIS_OK)
- zlog_err ("ISIS-Adj (%s): Send L%d IIH on %s failed",
- circuit->area->area_tag, level, circuit->interface->name);
+ retval = circuit->tx(circuit, level);
+ if (retval != ISIS_OK)
+ zlog_err("ISIS-Adj (%s): Send L%d IIH on %s failed",
+ circuit->area->area_tag, level,
+ circuit->interface->name);
- return retval;
+ return retval;
}
-int
-send_lan_l1_hello (struct thread *thread)
+int send_lan_l1_hello(struct thread *thread)
{
- struct isis_circuit *circuit;
- int retval;
-
- circuit = THREAD_ARG (thread);
- assert (circuit);
- circuit->u.bc.t_send_lan_hello[0] = NULL;
-
- if (!(circuit->area->is_type & IS_LEVEL_1))
- {
- zlog_warn ("ISIS-Hello (%s): Trying to send L1 IIH in L2-only area",
- circuit->area->area_tag);
- return 1;
- }
+ struct isis_circuit *circuit;
+ int retval;
+
+ circuit = THREAD_ARG(thread);
+ assert(circuit);
+ circuit->u.bc.t_send_lan_hello[0] = NULL;
+
+ if (!(circuit->area->is_type & IS_LEVEL_1)) {
+ zlog_warn(
+ "ISIS-Hello (%s): Trying to send L1 IIH in L2-only area",
+ circuit->area->area_tag);
+ return 1;
+ }
- if (circuit->u.bc.run_dr_elect[0])
- isis_dr_elect (circuit, 1);
+ if (circuit->u.bc.run_dr_elect[0])
+ isis_dr_elect(circuit, 1);
- retval = send_hello (circuit, 1);
+ retval = send_hello(circuit, 1);
- /* set next timer thread */
- thread_add_timer(master, send_lan_l1_hello, circuit,
- isis_jitter(circuit->hello_interval[0], IIH_JITTER),
- &circuit->u.bc.t_send_lan_hello[0]);
+ /* set next timer thread */
+ thread_add_timer(master, send_lan_l1_hello, circuit,
+ isis_jitter(circuit->hello_interval[0], IIH_JITTER),
+ &circuit->u.bc.t_send_lan_hello[0]);
- return retval;
+ return retval;
}
-int
-send_lan_l2_hello (struct thread *thread)
+int send_lan_l2_hello(struct thread *thread)
{
- struct isis_circuit *circuit;
- int retval;
+ struct isis_circuit *circuit;
+ int retval;
- circuit = THREAD_ARG (thread);
- assert (circuit);
- circuit->u.bc.t_send_lan_hello[1] = NULL;
+ circuit = THREAD_ARG(thread);
+ assert(circuit);
+ circuit->u.bc.t_send_lan_hello[1] = NULL;
- if (!(circuit->area->is_type & IS_LEVEL_2))
- {
- zlog_warn ("ISIS-Hello (%s): Trying to send L2 IIH in L1 area",
- circuit->area->area_tag);
- return 1;
- }
+ if (!(circuit->area->is_type & IS_LEVEL_2)) {
+ zlog_warn("ISIS-Hello (%s): Trying to send L2 IIH in L1 area",
+ circuit->area->area_tag);
+ return 1;
+ }
- if (circuit->u.bc.run_dr_elect[1])
- isis_dr_elect (circuit, 2);
+ if (circuit->u.bc.run_dr_elect[1])
+ isis_dr_elect(circuit, 2);
- retval = send_hello (circuit, 2);
+ retval = send_hello(circuit, 2);
- /* set next timer thread */
- thread_add_timer(master, send_lan_l2_hello, circuit,
- isis_jitter(circuit->hello_interval[1], IIH_JITTER),
- &circuit->u.bc.t_send_lan_hello[1]);
+ /* set next timer thread */
+ thread_add_timer(master, send_lan_l2_hello, circuit,
+ isis_jitter(circuit->hello_interval[1], IIH_JITTER),
+ &circuit->u.bc.t_send_lan_hello[1]);
- return retval;
+ return retval;
}
-int
-send_p2p_hello (struct thread *thread)
+int send_p2p_hello(struct thread *thread)
{
- struct isis_circuit *circuit;
+ struct isis_circuit *circuit;
- circuit = THREAD_ARG (thread);
- assert (circuit);
- circuit->u.p2p.t_send_p2p_hello = NULL;
+ circuit = THREAD_ARG(thread);
+ assert(circuit);
+ circuit->u.p2p.t_send_p2p_hello = NULL;
- send_hello (circuit, 1);
+ send_hello(circuit, 1);
- /* set next timer thread */
- thread_add_timer(master, send_p2p_hello, circuit,
- isis_jitter(circuit->hello_interval[1], IIH_JITTER),
- &circuit->u.p2p.t_send_p2p_hello);
+ /* set next timer thread */
+ thread_add_timer(master, send_p2p_hello, circuit,
+ isis_jitter(circuit->hello_interval[1], IIH_JITTER),
+ &circuit->u.p2p.t_send_p2p_hello);
- return ISIS_OK;
+ return ISIS_OK;
}
-static int
-build_csnp (int level, u_char * start, u_char * stop, struct list *lsps,
- struct isis_circuit *circuit)
+static int build_csnp(int level, u_char *start, u_char *stop, struct list *lsps,
+ struct isis_circuit *circuit)
{
- struct isis_fixed_hdr fixed_hdr;
- struct isis_passwd *passwd;
- unsigned long lenp;
- u_int16_t length;
- unsigned char hmac_md5_hash[ISIS_AUTH_MD5_SIZE];
- unsigned long auth_tlv_offset = 0;
- int retval = ISIS_OK;
-
- isis_circuit_stream(circuit, &circuit->snd_stream);
-
- if (level == IS_LEVEL_1)
- fill_fixed_hdr_andstream (&fixed_hdr, L1_COMPLETE_SEQ_NUM,
- circuit->snd_stream);
- else
- fill_fixed_hdr_andstream (&fixed_hdr, L2_COMPLETE_SEQ_NUM,
- circuit->snd_stream);
-
- /*
- * Fill Level 1 or 2 Complete Sequence Numbers header
- */
-
- lenp = stream_get_endp (circuit->snd_stream);
- stream_putw (circuit->snd_stream, 0); /* PDU length - when we know it */
- /* no need to send the source here, it is always us if we csnp */
- stream_put (circuit->snd_stream, isis->sysid, ISIS_SYS_ID_LEN);
- /* with zero circuit id - ref 9.10, 9.11 */
- stream_putc (circuit->snd_stream, 0x00);
-
- stream_put (circuit->snd_stream, start, ISIS_SYS_ID_LEN + 2);
- stream_put (circuit->snd_stream, stop, ISIS_SYS_ID_LEN + 2);
-
- /*
- * And TLVs
- */
- if (level == IS_LEVEL_1)
- passwd = &circuit->area->area_passwd;
- else
- passwd = &circuit->area->domain_passwd;
-
- if (CHECK_FLAG(passwd->snp_auth, SNP_AUTH_SEND))
- {
- switch (passwd->type)
- {
- /* Cleartext */
- case ISIS_PASSWD_TYPE_CLEARTXT:
- if (tlv_add_authinfo (ISIS_PASSWD_TYPE_CLEARTXT, passwd->len,
- passwd->passwd, circuit->snd_stream))
- return ISIS_WARNING;
- break;
-
- /* HMAC MD5 */
- case ISIS_PASSWD_TYPE_HMAC_MD5:
- /* Remember where TLV is written so we can later overwrite the MD5 hash */
- auth_tlv_offset = 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;
- break;
-
- default:
- break;
- }
- }
-
- retval = tlv_add_lsp_entries (lsps, circuit->snd_stream);
- if (retval != ISIS_OK)
- return retval;
-
- length = (u_int16_t) stream_get_endp (circuit->snd_stream);
- /* Update PU length */
- stream_putw_at (circuit->snd_stream, lenp, length);
+ struct isis_fixed_hdr fixed_hdr;
+ struct isis_passwd *passwd;
+ unsigned long lenp;
+ u_int16_t length;
+ unsigned char hmac_md5_hash[ISIS_AUTH_MD5_SIZE];
+ unsigned long auth_tlv_offset = 0;
+ int retval = ISIS_OK;
+
+ isis_circuit_stream(circuit, &circuit->snd_stream);
+
+ if (level == IS_LEVEL_1)
+ fill_fixed_hdr_andstream(&fixed_hdr, L1_COMPLETE_SEQ_NUM,
+ circuit->snd_stream);
+ else
+ fill_fixed_hdr_andstream(&fixed_hdr, L2_COMPLETE_SEQ_NUM,
+ circuit->snd_stream);
+
+ /*
+ * Fill Level 1 or 2 Complete Sequence Numbers header
+ */
+
+ lenp = stream_get_endp(circuit->snd_stream);
+ stream_putw(circuit->snd_stream, 0); /* PDU length - when we know it */
+ /* no need to send the source here, it is always us if we csnp */
+ stream_put(circuit->snd_stream, isis->sysid, ISIS_SYS_ID_LEN);
+ /* with zero circuit id - ref 9.10, 9.11 */
+ stream_putc(circuit->snd_stream, 0x00);
+
+ stream_put(circuit->snd_stream, start, ISIS_SYS_ID_LEN + 2);
+ stream_put(circuit->snd_stream, stop, ISIS_SYS_ID_LEN + 2);
+
+ /*
+ * And TLVs
+ */
+ if (level == IS_LEVEL_1)
+ passwd = &circuit->area->area_passwd;
+ else
+ passwd = &circuit->area->domain_passwd;
+
+ if (CHECK_FLAG(passwd->snp_auth, SNP_AUTH_SEND)) {
+ switch (passwd->type) {
+ /* Cleartext */
+ case ISIS_PASSWD_TYPE_CLEARTXT:
+ if (tlv_add_authinfo(ISIS_PASSWD_TYPE_CLEARTXT,
+ passwd->len, passwd->passwd,
+ circuit->snd_stream))
+ return ISIS_WARNING;
+ break;
+
+ /* HMAC MD5 */
+ case ISIS_PASSWD_TYPE_HMAC_MD5:
+ /* Remember where TLV is written so we can later
+ * overwrite the MD5 hash */
+ auth_tlv_offset = 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;
+ break;
+
+ default:
+ break;
+ }
+ }
- /* For HMAC MD5 we need to compute the md5 hash and store it */
- if (CHECK_FLAG(passwd->snp_auth, SNP_AUTH_SEND) &&
- passwd->type == ISIS_PASSWD_TYPE_HMAC_MD5)
- {
- hmac_md5 (STREAM_DATA (circuit->snd_stream),
- stream_get_endp(circuit->snd_stream),
- (unsigned char *) &passwd->passwd, passwd->len,
- (unsigned char *) &hmac_md5_hash);
- /* Copy the hash into the stream */
- memcpy (STREAM_DATA (circuit->snd_stream) + auth_tlv_offset + 3,
- hmac_md5_hash, ISIS_AUTH_MD5_SIZE);
- }
+ retval = tlv_add_lsp_entries(lsps, circuit->snd_stream);
+ if (retval != ISIS_OK)
+ return retval;
+
+ length = (u_int16_t)stream_get_endp(circuit->snd_stream);
+ /* Update PU length */
+ stream_putw_at(circuit->snd_stream, lenp, length);
+
+ /* For HMAC MD5 we need to compute the md5 hash and store it */
+ if (CHECK_FLAG(passwd->snp_auth, SNP_AUTH_SEND)
+ && passwd->type == ISIS_PASSWD_TYPE_HMAC_MD5) {
+ hmac_md5(STREAM_DATA(circuit->snd_stream),
+ stream_get_endp(circuit->snd_stream),
+ (unsigned char *)&passwd->passwd, passwd->len,
+ (unsigned char *)&hmac_md5_hash);
+ /* Copy the hash into the stream */
+ memcpy(STREAM_DATA(circuit->snd_stream) + auth_tlv_offset + 3,
+ hmac_md5_hash, ISIS_AUTH_MD5_SIZE);
+ }
- return retval;
+ return retval;
}
/*
* Count the maximum number of lsps that can be accomodated by a given size.
*/
-static uint16_t
-get_max_lsp_count (uint16_t size)
+static uint16_t get_max_lsp_count(uint16_t size)
{
- uint16_t tlv_count;
- uint16_t lsp_count;
- uint16_t remaining_size;
+ uint16_t tlv_count;
+ uint16_t lsp_count;
+ uint16_t remaining_size;
- /* First count the full size TLVs */
- tlv_count = size / MAX_LSP_ENTRIES_TLV_SIZE;
- lsp_count = tlv_count * (MAX_LSP_ENTRIES_TLV_SIZE / LSP_ENTRIES_LEN);
+ /* First count the full size TLVs */
+ tlv_count = size / MAX_LSP_ENTRIES_TLV_SIZE;
+ lsp_count = tlv_count * (MAX_LSP_ENTRIES_TLV_SIZE / LSP_ENTRIES_LEN);
- /* The last TLV, if any */
- remaining_size = size % MAX_LSP_ENTRIES_TLV_SIZE;
- if (remaining_size - 2 >= LSP_ENTRIES_LEN)
- lsp_count += (remaining_size - 2) / LSP_ENTRIES_LEN;
+ /* The last TLV, if any */
+ remaining_size = size % MAX_LSP_ENTRIES_TLV_SIZE;
+ if (remaining_size - 2 >= LSP_ENTRIES_LEN)
+ lsp_count += (remaining_size - 2) / LSP_ENTRIES_LEN;
- return lsp_count;
+ return lsp_count;
}
/*
* Calculate the length of Authentication Info. TLV.
*/
-static uint16_t
-auth_tlv_length (int level, struct isis_circuit *circuit)
+static uint16_t auth_tlv_length(int level, struct isis_circuit *circuit)
{
- struct isis_passwd *passwd;
- uint16_t length;
-
- if (level == IS_LEVEL_1)
- passwd = &circuit->area->area_passwd;
- else
- passwd = &circuit->area->domain_passwd;
-
- /* Also include the length of TLV header */
- length = AUTH_INFO_HDRLEN;
- if (CHECK_FLAG(passwd->snp_auth, SNP_AUTH_SEND))
- {
- switch (passwd->type)
- {
- /* Cleartext */
- case ISIS_PASSWD_TYPE_CLEARTXT:
- length += passwd->len;
- break;
-
- /* HMAC MD5 */
- case ISIS_PASSWD_TYPE_HMAC_MD5:
- length += ISIS_AUTH_MD5_SIZE;
- break;
-
- default:
- break;
- }
- }
+ struct isis_passwd *passwd;
+ uint16_t length;
+
+ if (level == IS_LEVEL_1)
+ passwd = &circuit->area->area_passwd;
+ else
+ passwd = &circuit->area->domain_passwd;
+
+ /* Also include the length of TLV header */
+ length = AUTH_INFO_HDRLEN;
+ if (CHECK_FLAG(passwd->snp_auth, SNP_AUTH_SEND)) {
+ switch (passwd->type) {
+ /* Cleartext */
+ case ISIS_PASSWD_TYPE_CLEARTXT:
+ length += passwd->len;
+ break;
+
+ /* HMAC MD5 */
+ case ISIS_PASSWD_TYPE_HMAC_MD5:
+ length += ISIS_AUTH_MD5_SIZE;
+ break;
+
+ default:
+ break;
+ }
+ }
- return length;
+ return length;
}
/*
* Calculate the maximum number of lsps that can be accomodated in a CSNP/PSNP.
*/
-static uint16_t
-max_lsps_per_snp (int snp_type, int level, struct isis_circuit *circuit)
+static uint16_t max_lsps_per_snp(int snp_type, int level,
+ struct isis_circuit *circuit)
{
- int snp_hdr_len;
- int auth_tlv_len;
- uint16_t lsp_count;
-
- snp_hdr_len = ISIS_FIXED_HDR_LEN;
- if (snp_type == ISIS_SNP_CSNP_FLAG)
- snp_hdr_len += ISIS_CSNP_HDRLEN;
- else
- snp_hdr_len += ISIS_PSNP_HDRLEN;
-
- auth_tlv_len = auth_tlv_length (level, circuit);
- lsp_count = get_max_lsp_count (
- stream_get_size (circuit->snd_stream) - snp_hdr_len - auth_tlv_len);
- return lsp_count;
+ int snp_hdr_len;
+ int auth_tlv_len;
+ uint16_t lsp_count;
+
+ snp_hdr_len = ISIS_FIXED_HDR_LEN;
+ if (snp_type == ISIS_SNP_CSNP_FLAG)
+ snp_hdr_len += ISIS_CSNP_HDRLEN;
+ else
+ snp_hdr_len += ISIS_PSNP_HDRLEN;
+
+ auth_tlv_len = auth_tlv_length(level, circuit);
+ lsp_count = get_max_lsp_count(stream_get_size(circuit->snd_stream)
+ - snp_hdr_len - auth_tlv_len);
+ return lsp_count;
}
/*
* FIXME: support multiple CSNPs
*/
-int
-send_csnp (struct isis_circuit *circuit, int level)
+int send_csnp(struct isis_circuit *circuit, int level)
{
- u_char start[ISIS_SYS_ID_LEN + 2];
- u_char stop[ISIS_SYS_ID_LEN + 2];
- struct list *list = NULL;
- struct listnode *node;
- struct isis_lsp *lsp;
- u_char num_lsps, loop = 1;
- int i, retval = ISIS_OK;
+ u_char start[ISIS_SYS_ID_LEN + 2];
+ u_char stop[ISIS_SYS_ID_LEN + 2];
+ struct list *list = NULL;
+ struct listnode *node;
+ struct isis_lsp *lsp;
+ u_char num_lsps, loop = 1;
+ int i, retval = ISIS_OK;
+
+ if (circuit->area->lspdb[level - 1] == NULL
+ || dict_count(circuit->area->lspdb[level - 1]) == 0)
+ return retval;
+
+ memset(start, 0x00, ISIS_SYS_ID_LEN + 2);
+ memset(stop, 0xff, ISIS_SYS_ID_LEN + 2);
+
+ num_lsps = max_lsps_per_snp(ISIS_SNP_CSNP_FLAG, level, circuit);
+
+ while (loop) {
+ list = list_new();
+ lsp_build_list(start, stop, num_lsps, list,
+ circuit->area->lspdb[level - 1]);
+ /*
+ * Update the stop lsp_id before encoding this CSNP.
+ */
+ if (listcount(list) < num_lsps) {
+ memset(stop, 0xff, ISIS_SYS_ID_LEN + 2);
+ } else {
+ node = listtail(list);
+ lsp = listgetdata(node);
+ memcpy(stop, lsp->lsp_header->lsp_id,
+ ISIS_SYS_ID_LEN + 2);
+ }
- if (circuit->area->lspdb[level - 1] == NULL ||
- dict_count (circuit->area->lspdb[level - 1]) == 0)
- return retval;
+ retval = build_csnp(level, start, stop, list, circuit);
+ if (retval != ISIS_OK) {
+ zlog_err("ISIS-Snp (%s): Build L%d CSNP on %s failed",
+ circuit->area->area_tag, level,
+ circuit->interface->name);
+ list_delete(list);
+ return retval;
+ }
- memset (start, 0x00, ISIS_SYS_ID_LEN + 2);
- memset (stop, 0xff, ISIS_SYS_ID_LEN + 2);
+ if (isis->debugs & DEBUG_SNP_PACKETS) {
+ zlog_debug(
+ "ISIS-Snp (%s): Sending L%d CSNP on %s, length %zd",
+ circuit->area->area_tag, level,
+ circuit->interface->name,
+ stream_get_endp(circuit->snd_stream));
+ for (ALL_LIST_ELEMENTS_RO(list, node, lsp)) {
+ zlog_debug(
+ "ISIS-Snp (%s): CSNP entry %s, seq 0x%08x,"
+ " cksum 0x%04x, lifetime %us",
+ circuit->area->area_tag,
+ rawlspid_print(lsp->lsp_header->lsp_id),
+ ntohl(lsp->lsp_header->seq_num),
+ ntohs(lsp->lsp_header->checksum),
+ ntohs(lsp->lsp_header->rem_lifetime));
+ }
+ if (isis->debugs & DEBUG_PACKET_DUMP)
+ zlog_dump_data(
+ STREAM_DATA(circuit->snd_stream),
+ stream_get_endp(circuit->snd_stream));
+ }
- num_lsps = max_lsps_per_snp (ISIS_SNP_CSNP_FLAG, level, circuit);
+ retval = circuit->tx(circuit, level);
+ if (retval != ISIS_OK) {
+ zlog_err("ISIS-Snp (%s): Send L%d CSNP on %s failed",
+ circuit->area->area_tag, level,
+ circuit->interface->name);
+ list_delete(list);
+ return retval;
+ }
- while (loop)
- {
- list = list_new ();
- lsp_build_list (start, stop, num_lsps, list,
- circuit->area->lspdb[level - 1]);
- /*
- * Update the stop lsp_id before encoding this CSNP.
- */
- if (listcount (list) < num_lsps)
- {
- memset (stop, 0xff, ISIS_SYS_ID_LEN + 2);
- }
- else
- {
- node = listtail (list);
- lsp = listgetdata (node);
- memcpy (stop, lsp->lsp_header->lsp_id, ISIS_SYS_ID_LEN + 2);
- }
-
- retval = build_csnp (level, start, stop, list, circuit);
- if (retval != ISIS_OK)
- {
- zlog_err ("ISIS-Snp (%s): Build L%d CSNP on %s failed",
- circuit->area->area_tag, level, circuit->interface->name);
- list_delete (list);
- return retval;
- }
-
- if (isis->debugs & DEBUG_SNP_PACKETS)
- {
- zlog_debug ("ISIS-Snp (%s): Sending L%d CSNP on %s, length %zd",
- circuit->area->area_tag, level, circuit->interface->name,
- stream_get_endp (circuit->snd_stream));
- for (ALL_LIST_ELEMENTS_RO (list, node, lsp))
- {
- zlog_debug ("ISIS-Snp (%s): CSNP entry %s, seq 0x%08x,"
- " cksum 0x%04x, lifetime %us",
- circuit->area->area_tag,
- rawlspid_print (lsp->lsp_header->lsp_id),
- ntohl (lsp->lsp_header->seq_num),
- ntohs (lsp->lsp_header->checksum),
- ntohs (lsp->lsp_header->rem_lifetime));
- }
- if (isis->debugs & DEBUG_PACKET_DUMP)
- zlog_dump_data (STREAM_DATA (circuit->snd_stream),
- stream_get_endp (circuit->snd_stream));
- }
-
- retval = circuit->tx (circuit, level);
- if (retval != ISIS_OK)
- {
- zlog_err ("ISIS-Snp (%s): Send L%d CSNP on %s failed",
- circuit->area->area_tag, level,
- circuit->interface->name);
- list_delete (list);
- return retval;
- }
-
- /*
- * Start lsp_id of the next CSNP should be one plus the
- * stop lsp_id in this current CSNP.
- */
- memcpy (start, stop, ISIS_SYS_ID_LEN + 2);
- loop = 0;
- for (i = ISIS_SYS_ID_LEN + 1; i >= 0; --i)
- {
- if (start[i] < (u_char)0xff)
- {
- start[i] += 1;
- loop = 1;
- break;
- }
- }
- memset (stop, 0xff, ISIS_SYS_ID_LEN + 2);
- list_delete (list);
- }
+ /*
+ * Start lsp_id of the next CSNP should be one plus the
+ * stop lsp_id in this current CSNP.
+ */
+ memcpy(start, stop, ISIS_SYS_ID_LEN + 2);
+ loop = 0;
+ for (i = ISIS_SYS_ID_LEN + 1; i >= 0; --i) {
+ if (start[i] < (u_char)0xff) {
+ start[i] += 1;
+ loop = 1;
+ break;
+ }
+ }
+ memset(stop, 0xff, ISIS_SYS_ID_LEN + 2);
+ list_delete(list);
+ }
- return retval;
+ return retval;
}
-int
-send_l1_csnp (struct thread *thread)
+int send_l1_csnp(struct thread *thread)
{
- struct isis_circuit *circuit;
- int retval = ISIS_OK;
+ struct isis_circuit *circuit;
+ int retval = ISIS_OK;
- circuit = THREAD_ARG (thread);
- assert (circuit);
+ circuit = THREAD_ARG(thread);
+ assert(circuit);
- circuit->t_send_csnp[0] = NULL;
+ 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_add_timer(master, send_l1_csnp, circuit,
- isis_jitter(circuit->csnp_interval[0], CSNP_JITTER),
- &circuit->t_send_csnp[0]);
+ if (circuit->circ_type == CIRCUIT_T_BROADCAST
+ && circuit->u.bc.is_dr[0]) {
+ send_csnp(circuit, 1);
+ }
+ /* set next timer thread */
+ thread_add_timer(master, send_l1_csnp, circuit,
+ isis_jitter(circuit->csnp_interval[0], CSNP_JITTER),
+ &circuit->t_send_csnp[0]);
- return retval;
+ return retval;
}
-int
-send_l2_csnp (struct thread *thread)
+int send_l2_csnp(struct thread *thread)
{
- struct isis_circuit *circuit;
- int retval = ISIS_OK;
+ struct isis_circuit *circuit;
+ int retval = ISIS_OK;
- circuit = THREAD_ARG (thread);
- assert (circuit);
+ circuit = THREAD_ARG(thread);
+ assert(circuit);
- circuit->t_send_csnp[1] = NULL;
+ 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_add_timer(master, send_l2_csnp, circuit,
- isis_jitter(circuit->csnp_interval[1], CSNP_JITTER),
- &circuit->t_send_csnp[1]);
+ if (circuit->circ_type == CIRCUIT_T_BROADCAST
+ && circuit->u.bc.is_dr[1]) {
+ send_csnp(circuit, 2);
+ }
+ /* set next timer thread */
+ thread_add_timer(master, send_l2_csnp, circuit,
+ isis_jitter(circuit->csnp_interval[1], CSNP_JITTER),
+ &circuit->t_send_csnp[1]);
- return retval;
+ return retval;
}
-static int
-build_psnp (int level, struct isis_circuit *circuit, struct list *lsps)
+static int build_psnp(int level, struct isis_circuit *circuit,
+ struct list *lsps)
{
- struct isis_fixed_hdr fixed_hdr;
- unsigned long lenp;
- u_int16_t length;
- struct isis_lsp *lsp;
- struct isis_passwd *passwd;
- struct listnode *node;
- unsigned char hmac_md5_hash[ISIS_AUTH_MD5_SIZE];
- unsigned long auth_tlv_offset = 0;
- int retval = ISIS_OK;
-
- isis_circuit_stream(circuit, &circuit->snd_stream);
-
- if (level == IS_LEVEL_1)
- fill_fixed_hdr_andstream (&fixed_hdr, L1_PARTIAL_SEQ_NUM,
- circuit->snd_stream);
- else
- fill_fixed_hdr_andstream (&fixed_hdr, L2_PARTIAL_SEQ_NUM,
- circuit->snd_stream);
-
- /*
- * Fill Level 1 or 2 Partial Sequence Numbers header
- */
- lenp = stream_get_endp (circuit->snd_stream);
- stream_putw (circuit->snd_stream, 0); /* PDU length - when we know it */
- stream_put (circuit->snd_stream, isis->sysid, ISIS_SYS_ID_LEN);
- stream_putc (circuit->snd_stream, circuit->idx);
-
- /*
- * And TLVs
- */
-
- if (level == IS_LEVEL_1)
- passwd = &circuit->area->area_passwd;
- else
- passwd = &circuit->area->domain_passwd;
-
- if (CHECK_FLAG(passwd->snp_auth, SNP_AUTH_SEND))
- {
- switch (passwd->type)
- {
- /* Cleartext */
- case ISIS_PASSWD_TYPE_CLEARTXT:
- if (tlv_add_authinfo (ISIS_PASSWD_TYPE_CLEARTXT, passwd->len,
- passwd->passwd, circuit->snd_stream))
- return ISIS_WARNING;
- break;
-
- /* HMAC MD5 */
- case ISIS_PASSWD_TYPE_HMAC_MD5:
- /* Remember where TLV is written so we can later overwrite the MD5 hash */
- auth_tlv_offset = 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;
- break;
-
- default:
- break;
- }
- }
-
- retval = tlv_add_lsp_entries (lsps, circuit->snd_stream);
- if (retval != ISIS_OK)
- return retval;
-
- if (isis->debugs & DEBUG_SNP_PACKETS)
- {
- for (ALL_LIST_ELEMENTS_RO (lsps, node, lsp))
- {
- zlog_debug ("ISIS-Snp (%s): PSNP entry %s, seq 0x%08x,"
- " cksum 0x%04x, lifetime %us",
- circuit->area->area_tag,
- rawlspid_print (lsp->lsp_header->lsp_id),
- ntohl (lsp->lsp_header->seq_num),
- ntohs (lsp->lsp_header->checksum),
- ntohs (lsp->lsp_header->rem_lifetime));
- }
- }
+ struct isis_fixed_hdr fixed_hdr;
+ unsigned long lenp;
+ u_int16_t length;
+ struct isis_lsp *lsp;
+ struct isis_passwd *passwd;
+ struct listnode *node;
+ unsigned char hmac_md5_hash[ISIS_AUTH_MD5_SIZE];
+ unsigned long auth_tlv_offset = 0;
+ int retval = ISIS_OK;
+
+ isis_circuit_stream(circuit, &circuit->snd_stream);
+
+ if (level == IS_LEVEL_1)
+ fill_fixed_hdr_andstream(&fixed_hdr, L1_PARTIAL_SEQ_NUM,
+ circuit->snd_stream);
+ else
+ fill_fixed_hdr_andstream(&fixed_hdr, L2_PARTIAL_SEQ_NUM,
+ circuit->snd_stream);
+
+ /*
+ * Fill Level 1 or 2 Partial Sequence Numbers header
+ */
+ lenp = stream_get_endp(circuit->snd_stream);
+ stream_putw(circuit->snd_stream, 0); /* PDU length - when we know it */
+ stream_put(circuit->snd_stream, isis->sysid, ISIS_SYS_ID_LEN);
+ stream_putc(circuit->snd_stream, circuit->idx);
+
+ /*
+ * And TLVs
+ */
+
+ if (level == IS_LEVEL_1)
+ passwd = &circuit->area->area_passwd;
+ else
+ passwd = &circuit->area->domain_passwd;
+
+ if (CHECK_FLAG(passwd->snp_auth, SNP_AUTH_SEND)) {
+ switch (passwd->type) {
+ /* Cleartext */
+ case ISIS_PASSWD_TYPE_CLEARTXT:
+ if (tlv_add_authinfo(ISIS_PASSWD_TYPE_CLEARTXT,
+ passwd->len, passwd->passwd,
+ circuit->snd_stream))
+ return ISIS_WARNING;
+ break;
+
+ /* HMAC MD5 */
+ case ISIS_PASSWD_TYPE_HMAC_MD5:
+ /* Remember where TLV is written so we can later
+ * overwrite the MD5 hash */
+ auth_tlv_offset = 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;
+ break;
+
+ default:
+ break;
+ }
+ }
- length = (u_int16_t) stream_get_endp (circuit->snd_stream);
- /* Update PDU length */
- stream_putw_at (circuit->snd_stream, lenp, length);
+ retval = tlv_add_lsp_entries(lsps, circuit->snd_stream);
+ if (retval != ISIS_OK)
+ return retval;
+
+ if (isis->debugs & DEBUG_SNP_PACKETS) {
+ for (ALL_LIST_ELEMENTS_RO(lsps, node, lsp)) {
+ zlog_debug(
+ "ISIS-Snp (%s): PSNP entry %s, seq 0x%08x,"
+ " cksum 0x%04x, lifetime %us",
+ circuit->area->area_tag,
+ rawlspid_print(lsp->lsp_header->lsp_id),
+ ntohl(lsp->lsp_header->seq_num),
+ ntohs(lsp->lsp_header->checksum),
+ ntohs(lsp->lsp_header->rem_lifetime));
+ }
+ }
- /* For HMAC MD5 we need to compute the md5 hash and store it */
- if (CHECK_FLAG(passwd->snp_auth, SNP_AUTH_SEND) &&
- passwd->type == ISIS_PASSWD_TYPE_HMAC_MD5)
- {
- hmac_md5 (STREAM_DATA (circuit->snd_stream),
- stream_get_endp(circuit->snd_stream),
- (unsigned char *) &passwd->passwd, passwd->len,
- (unsigned char *) &hmac_md5_hash);
- /* Copy the hash into the stream */
- memcpy (STREAM_DATA (circuit->snd_stream) + auth_tlv_offset + 3,
- hmac_md5_hash, ISIS_AUTH_MD5_SIZE);
- }
+ length = (u_int16_t)stream_get_endp(circuit->snd_stream);
+ /* Update PDU length */
+ stream_putw_at(circuit->snd_stream, lenp, length);
+
+ /* For HMAC MD5 we need to compute the md5 hash and store it */
+ if (CHECK_FLAG(passwd->snp_auth, SNP_AUTH_SEND)
+ && passwd->type == ISIS_PASSWD_TYPE_HMAC_MD5) {
+ hmac_md5(STREAM_DATA(circuit->snd_stream),
+ stream_get_endp(circuit->snd_stream),
+ (unsigned char *)&passwd->passwd, passwd->len,
+ (unsigned char *)&hmac_md5_hash);
+ /* Copy the hash into the stream */
+ memcpy(STREAM_DATA(circuit->snd_stream) + auth_tlv_offset + 3,
+ hmac_md5_hash, ISIS_AUTH_MD5_SIZE);
+ }
- return ISIS_OK;
+ return ISIS_OK;
}
/*
* 7.3.15.4 action on expiration of partial SNP interval
* level 1
*/
-static int
-send_psnp (int level, struct isis_circuit *circuit)
+static int send_psnp(int level, struct isis_circuit *circuit)
{
- struct isis_lsp *lsp;
- struct list *list = NULL;
- struct listnode *node;
- u_char num_lsps;
- int retval = ISIS_OK;
+ struct isis_lsp *lsp;
+ struct list *list = NULL;
+ struct listnode *node;
+ u_char num_lsps;
+ int retval = ISIS_OK;
- if (circuit->circ_type == CIRCUIT_T_BROADCAST &&
- circuit->u.bc.is_dr[level - 1])
- return ISIS_OK;
+ if (circuit->circ_type == CIRCUIT_T_BROADCAST
+ && circuit->u.bc.is_dr[level - 1])
+ return ISIS_OK;
- if (circuit->area->lspdb[level - 1] == NULL ||
- dict_count (circuit->area->lspdb[level - 1]) == 0)
- return ISIS_OK;
+ if (circuit->area->lspdb[level - 1] == NULL
+ || dict_count(circuit->area->lspdb[level - 1]) == 0)
+ return ISIS_OK;
- if (! circuit->snd_stream)
- return ISIS_ERROR;
+ if (!circuit->snd_stream)
+ return ISIS_ERROR;
- num_lsps = max_lsps_per_snp (ISIS_SNP_PSNP_FLAG, level, circuit);
+ num_lsps = max_lsps_per_snp(ISIS_SNP_PSNP_FLAG, level, circuit);
- while (1)
- {
- list = list_new ();
- lsp_build_list_ssn (circuit, num_lsps, list,
- circuit->area->lspdb[level - 1]);
-
- if (listcount (list) == 0)
- {
- list_delete (list);
- return ISIS_OK;
- }
-
- retval = build_psnp (level, circuit, list);
- if (retval != ISIS_OK)
- {
- zlog_err ("ISIS-Snp (%s): Build L%d PSNP on %s failed",
- circuit->area->area_tag, level, circuit->interface->name);
- list_delete (list);
- return retval;
- }
-
- if (isis->debugs & DEBUG_SNP_PACKETS)
- {
- zlog_debug ("ISIS-Snp (%s): Sending L%d PSNP on %s, length %zd",
- circuit->area->area_tag, level,
- circuit->interface->name,
- stream_get_endp (circuit->snd_stream));
- if (isis->debugs & DEBUG_PACKET_DUMP)
- zlog_dump_data (STREAM_DATA (circuit->snd_stream),
- stream_get_endp (circuit->snd_stream));
- }
-
- retval = circuit->tx (circuit, level);
- if (retval != ISIS_OK)
- {
- zlog_err ("ISIS-Snp (%s): Send L%d PSNP on %s failed",
- circuit->area->area_tag, level,
- circuit->interface->name);
- list_delete (list);
- return retval;
- }
-
- /*
- * sending succeeded, we can clear SSN flags of this circuit
- * for the LSPs in list
- */
- for (ALL_LIST_ELEMENTS_RO (list, node, lsp))
- ISIS_CLEAR_FLAG (lsp->SSNflags, circuit);
- list_delete (list);
- }
+ while (1) {
+ list = list_new();
+ lsp_build_list_ssn(circuit, num_lsps, list,
+ circuit->area->lspdb[level - 1]);
+
+ if (listcount(list) == 0) {
+ list_delete(list);
+ return ISIS_OK;
+ }
+
+ retval = build_psnp(level, circuit, list);
+ if (retval != ISIS_OK) {
+ zlog_err("ISIS-Snp (%s): Build L%d PSNP on %s failed",
+ circuit->area->area_tag, level,
+ circuit->interface->name);
+ list_delete(list);
+ return retval;
+ }
+
+ if (isis->debugs & DEBUG_SNP_PACKETS) {
+ zlog_debug(
+ "ISIS-Snp (%s): Sending L%d PSNP on %s, length %zd",
+ circuit->area->area_tag, level,
+ circuit->interface->name,
+ stream_get_endp(circuit->snd_stream));
+ if (isis->debugs & DEBUG_PACKET_DUMP)
+ zlog_dump_data(
+ STREAM_DATA(circuit->snd_stream),
+ stream_get_endp(circuit->snd_stream));
+ }
+
+ retval = circuit->tx(circuit, level);
+ if (retval != ISIS_OK) {
+ zlog_err("ISIS-Snp (%s): Send L%d PSNP on %s failed",
+ circuit->area->area_tag, level,
+ circuit->interface->name);
+ list_delete(list);
+ return retval;
+ }
- return retval;
+ /*
+ * sending succeeded, we can clear SSN flags of this circuit
+ * for the LSPs in list
+ */
+ for (ALL_LIST_ELEMENTS_RO(list, node, lsp))
+ ISIS_CLEAR_FLAG(lsp->SSNflags, circuit);
+ list_delete(list);
+ }
+
+ return retval;
}
-int
-send_l1_psnp (struct thread *thread)
+int send_l1_psnp(struct thread *thread)
{
- struct isis_circuit *circuit;
- int retval = ISIS_OK;
+ struct isis_circuit *circuit;
+ int retval = ISIS_OK;
- circuit = THREAD_ARG (thread);
- assert (circuit);
+ circuit = THREAD_ARG(thread);
+ assert(circuit);
- circuit->t_send_psnp[0] = NULL;
+ circuit->t_send_psnp[0] = NULL;
- send_psnp (1, circuit);
- /* set next timer thread */
- thread_add_timer(master, send_l1_psnp, circuit,
- isis_jitter(circuit->psnp_interval[0], PSNP_JITTER),
- &circuit->t_send_psnp[0]);
+ send_psnp(1, circuit);
+ /* set next timer thread */
+ thread_add_timer(master, send_l1_psnp, circuit,
+ isis_jitter(circuit->psnp_interval[0], PSNP_JITTER),
+ &circuit->t_send_psnp[0]);
- return retval;
+ return retval;
}
/*
* 7.3.15.4 action on expiration of partial SNP interval
* level 2
*/
-int
-send_l2_psnp (struct thread *thread)
+int send_l2_psnp(struct thread *thread)
{
- struct isis_circuit *circuit;
- int retval = ISIS_OK;
+ struct isis_circuit *circuit;
+ int retval = ISIS_OK;
- circuit = THREAD_ARG (thread);
- assert (circuit);
+ circuit = THREAD_ARG(thread);
+ assert(circuit);
- circuit->t_send_psnp[1] = NULL;
+ circuit->t_send_psnp[1] = NULL;
- send_psnp (2, circuit);
+ send_psnp(2, circuit);
- /* set next timer thread */
- thread_add_timer(master, send_l2_psnp, circuit,
- isis_jitter(circuit->psnp_interval[1], PSNP_JITTER),
- &circuit->t_send_psnp[1]);
+ /* set next timer thread */
+ thread_add_timer(master, send_l2_psnp, circuit,
+ isis_jitter(circuit->psnp_interval[1], PSNP_JITTER),
+ &circuit->t_send_psnp[1]);
- return retval;
+ return retval;
}
/*
* ISO 10589 - 7.3.14.3
*/
-int
-send_lsp (struct thread *thread)
+int send_lsp(struct thread *thread)
{
- struct isis_circuit *circuit;
- struct isis_lsp *lsp;
- struct listnode *node;
- int clear_srm = 1;
- int retval = ISIS_OK;
-
- circuit = THREAD_ARG (thread);
- assert (circuit);
-
- if (!circuit->lsp_queue)
- return ISIS_OK;
-
- node = listhead (circuit->lsp_queue);
-
- /*
- * Handle case where there are no LSPs on the queue. This can
- * happen, for instance, if an adjacency goes down before this
- * thread gets a chance to run.
- */
- if (!node)
- return ISIS_OK;
-
- /*
- * Delete LSP from lsp_queue. If it's still in queue, it is assumed
- * as 'transmit pending', but send_lsp may never be called again.
- * Retry will happen because SRM flag will not be cleared.
- */
- lsp = listgetdata(node);
- list_delete_node (circuit->lsp_queue, node);
-
- /* Set the last-cleared time if the queue is empty. */
- /* TODO: Is is possible that new lsps keep being added to the queue
- * that the queue is never empty? */
- if (list_isempty (circuit->lsp_queue))
- circuit->lsp_queue_last_cleared = time (NULL);
-
- if (circuit->state != C_STATE_UP || circuit->is_passive == 1)
- goto out;
-
- /*
- * Do not send if levels do not match
- */
- if (!(lsp->level & circuit->is_type))
- goto out;
-
- /*
- * Do not send if we do not have adjacencies in state up on the circuit
- */
- if (circuit->upadjcount[lsp->level - 1] == 0)
- goto out;
-
- /* stream_copy will assert and stop program execution if LSP is larger than
- * the circuit's MTU. So handle and log this case here. */
- if (stream_get_endp(lsp->pdu) > stream_get_size(circuit->snd_stream))
- {
- zlog_err("ISIS-Upd (%s): Can't send L%d LSP %s, seq 0x%08x,"
- " cksum 0x%04x, lifetime %us on %s. LSP Size is %zu"
- " while interface stream size is %zu.",
- 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,
- stream_get_endp(lsp->pdu),
- stream_get_size(circuit->snd_stream));
- if (isis->debugs & DEBUG_PACKET_DUMP)
- zlog_dump_data(STREAM_DATA(lsp->pdu), stream_get_endp(lsp->pdu));
- retval = ISIS_ERROR;
- goto out;
- }
-
- /* copy our lsp to the send buffer */
- stream_copy (circuit->snd_stream, lsp->pdu);
+ struct isis_circuit *circuit;
+ struct isis_lsp *lsp;
+ struct listnode *node;
+ int clear_srm = 1;
+ int retval = ISIS_OK;
+
+ circuit = THREAD_ARG(thread);
+ assert(circuit);
+
+ if (!circuit->lsp_queue)
+ return ISIS_OK;
+
+ node = listhead(circuit->lsp_queue);
+
+ /*
+ * Handle case where there are no LSPs on the queue. This can
+ * happen, for instance, if an adjacency goes down before this
+ * thread gets a chance to run.
+ */
+ if (!node)
+ return ISIS_OK;
+
+ /*
+ * Delete LSP from lsp_queue. If it's still in queue, it is assumed
+ * as 'transmit pending', but send_lsp may never be called again.
+ * Retry will happen because SRM flag will not be cleared.
+ */
+ lsp = listgetdata(node);
+ list_delete_node(circuit->lsp_queue, node);
+
+ /* Set the last-cleared time if the queue is empty. */
+ /* TODO: Is is possible that new lsps keep being added to the queue
+ * that the queue is never empty? */
+ if (list_isempty(circuit->lsp_queue))
+ circuit->lsp_queue_last_cleared = time(NULL);
+
+ if (circuit->state != C_STATE_UP || circuit->is_passive == 1)
+ goto out;
+
+ /*
+ * Do not send if levels do not match
+ */
+ if (!(lsp->level & circuit->is_type))
+ goto out;
+
+ /*
+ * Do not send if we do not have adjacencies in state up on the circuit
+ */
+ if (circuit->upadjcount[lsp->level - 1] == 0)
+ goto out;
+
+ /* stream_copy will assert and stop program execution if LSP is larger
+ * than
+ * the circuit's MTU. So handle and log this case here. */
+ if (stream_get_endp(lsp->pdu) > stream_get_size(circuit->snd_stream)) {
+ zlog_err(
+ "ISIS-Upd (%s): Can't send L%d LSP %s, seq 0x%08x,"
+ " cksum 0x%04x, lifetime %us on %s. LSP Size is %zu"
+ " while interface stream size is %zu.",
+ 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, stream_get_endp(lsp->pdu),
+ stream_get_size(circuit->snd_stream));
+ if (isis->debugs & DEBUG_PACKET_DUMP)
+ zlog_dump_data(STREAM_DATA(lsp->pdu),
+ stream_get_endp(lsp->pdu));
+ retval = ISIS_ERROR;
+ goto out;
+ }
- if (isis->debugs & DEBUG_UPDATE_PACKETS)
- {
- zlog_debug
- ("ISIS-Upd (%s): Sending 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);
- if (isis->debugs & DEBUG_PACKET_DUMP)
- zlog_dump_data (STREAM_DATA (circuit->snd_stream),
- stream_get_endp (circuit->snd_stream));
- }
+ /* copy our lsp to the send buffer */
+ stream_copy(circuit->snd_stream, lsp->pdu);
+
+ if (isis->debugs & DEBUG_UPDATE_PACKETS) {
+ zlog_debug(
+ "ISIS-Upd (%s): Sending 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);
+ if (isis->debugs & DEBUG_PACKET_DUMP)
+ zlog_dump_data(STREAM_DATA(circuit->snd_stream),
+ stream_get_endp(circuit->snd_stream));
+ }
- clear_srm = 0;
- retval = circuit->tx (circuit, lsp->level);
- if (retval != ISIS_OK)
- {
- zlog_err ("ISIS-Upd (%s): Send L%d LSP on %s failed %s",
- circuit->area->area_tag, lsp->level,
- circuit->interface->name,
- (retval == ISIS_WARNING) ? "temporarily" : "permanently");
- }
+ clear_srm = 0;
+ retval = circuit->tx(circuit, lsp->level);
+ if (retval != ISIS_OK) {
+ zlog_err("ISIS-Upd (%s): Send L%d LSP on %s failed %s",
+ circuit->area->area_tag, lsp->level,
+ circuit->interface->name,
+ (retval == ISIS_WARNING) ? "temporarily"
+ : "permanently");
+ }
out:
- if (clear_srm
- || (retval == ISIS_OK && circuit->circ_type == CIRCUIT_T_BROADCAST)
- || (retval != ISIS_OK && retval != ISIS_WARNING))
- {
- /* SRM flag will trigger retransmission. We will not retransmit if we
- * encountered a fatal error.
- * On success, they should only be cleared if it's a broadcast circuit.
- * On a P2P circuit, we will wait for the ack from the neighbor to clear
- * the fag.
- */
- ISIS_CLEAR_FLAG (lsp->SRMflags, circuit);
- }
+ if (clear_srm
+ || (retval == ISIS_OK && circuit->circ_type == CIRCUIT_T_BROADCAST)
+ || (retval != ISIS_OK && retval != ISIS_WARNING)) {
+ /* SRM flag will trigger retransmission. We will not retransmit
+ * if we
+ * encountered a fatal error.
+ * On success, they should only be cleared if it's a broadcast
+ * circuit.
+ * On a P2P circuit, we will wait for the ack from the neighbor
+ * to clear
+ * the fag.
+ */
+ ISIS_CLEAR_FLAG(lsp->SRMflags, circuit);
+ }
- return retval;
+ return retval;
}
-int
-ack_lsp (struct isis_link_state_hdr *hdr, struct isis_circuit *circuit,
- int level)
+int ack_lsp(struct isis_link_state_hdr *hdr, struct isis_circuit *circuit,
+ int level)
{
- unsigned long lenp;
- int retval;
- u_int16_t length;
- struct isis_fixed_hdr fixed_hdr;
-
- isis_circuit_stream(circuit, &circuit->snd_stream);
-
- // fill_llc_hdr (stream);
- if (level == IS_LEVEL_1)
- fill_fixed_hdr_andstream (&fixed_hdr, L1_PARTIAL_SEQ_NUM,
- circuit->snd_stream);
- else
- fill_fixed_hdr_andstream (&fixed_hdr, L2_PARTIAL_SEQ_NUM,
- circuit->snd_stream);
-
-
- lenp = stream_get_endp (circuit->snd_stream);
- stream_putw (circuit->snd_stream, 0); /* PDU length */
- stream_put (circuit->snd_stream, isis->sysid, ISIS_SYS_ID_LEN);
- stream_putc (circuit->snd_stream, circuit->idx);
- stream_putc (circuit->snd_stream, 9); /* code */
- stream_putc (circuit->snd_stream, 16); /* len */
-
- stream_putw (circuit->snd_stream, ntohs (hdr->rem_lifetime));
- stream_put (circuit->snd_stream, hdr->lsp_id, ISIS_SYS_ID_LEN + 2);
- stream_putl (circuit->snd_stream, ntohl (hdr->seq_num));
- stream_putw (circuit->snd_stream, ntohs (hdr->checksum));
-
- length = (u_int16_t) stream_get_endp (circuit->snd_stream);
- /* Update PDU length */
- stream_putw_at (circuit->snd_stream, lenp, length);
-
- retval = circuit->tx (circuit, level);
- if (retval != ISIS_OK)
- zlog_err ("ISIS-Upd (%s): Send L%d LSP PSNP on %s failed",
- circuit->area->area_tag, level,
- circuit->interface->name);
-
- return retval;
+ unsigned long lenp;
+ int retval;
+ u_int16_t length;
+ struct isis_fixed_hdr fixed_hdr;
+
+ isis_circuit_stream(circuit, &circuit->snd_stream);
+
+ // fill_llc_hdr (stream);
+ if (level == IS_LEVEL_1)
+ fill_fixed_hdr_andstream(&fixed_hdr, L1_PARTIAL_SEQ_NUM,
+ circuit->snd_stream);
+ else
+ fill_fixed_hdr_andstream(&fixed_hdr, L2_PARTIAL_SEQ_NUM,
+ circuit->snd_stream);
+
+
+ lenp = stream_get_endp(circuit->snd_stream);
+ stream_putw(circuit->snd_stream, 0); /* PDU length */
+ stream_put(circuit->snd_stream, isis->sysid, ISIS_SYS_ID_LEN);
+ stream_putc(circuit->snd_stream, circuit->idx);
+ stream_putc(circuit->snd_stream, 9); /* code */
+ stream_putc(circuit->snd_stream, 16); /* len */
+
+ stream_putw(circuit->snd_stream, ntohs(hdr->rem_lifetime));
+ stream_put(circuit->snd_stream, hdr->lsp_id, ISIS_SYS_ID_LEN + 2);
+ stream_putl(circuit->snd_stream, ntohl(hdr->seq_num));
+ stream_putw(circuit->snd_stream, ntohs(hdr->checksum));
+
+ length = (u_int16_t)stream_get_endp(circuit->snd_stream);
+ /* Update PDU length */
+ stream_putw_at(circuit->snd_stream, lenp, length);
+
+ retval = circuit->tx(circuit, level);
+ if (retval != ISIS_OK)
+ zlog_err("ISIS-Upd (%s): Send L%d LSP PSNP on %s failed",
+ circuit->area->area_tag, level,
+ circuit->interface->name);
+
+ return retval;
}