version 1.1.1.2, 2012/10/09 09:22:28
|
version 1.1.1.4, 2016/11/02 10:09:10
|
Line 62
|
Line 62
|
#endif /* PNBBY */ |
#endif /* PNBBY */ |
|
|
/* Utility mask array. */ |
/* Utility mask array. */ |
static u_char maskbit[] = { | static const u_char maskbit[] = { |
0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff |
0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff |
}; |
}; |
|
|
Line 204 authentication_check (struct isis_passwd *remote, stru
|
Line 204 authentication_check (struct isis_passwd *remote, stru
|
/* Compute the digest */ |
/* Compute the digest */ |
hmac_md5 (STREAM_DATA (stream), stream_get_endp (stream), |
hmac_md5 (STREAM_DATA (stream), stream_get_endp (stream), |
(unsigned char *) &(local->passwd), local->len, |
(unsigned char *) &(local->passwd), local->len, |
(caddr_t) &digest); | (unsigned char *) &digest); |
/* Copy back the authentication value after the check */ |
/* Copy back the authentication value after the check */ |
memcpy (STREAM_DATA (stream) + auth_tlv_offset + 3, |
memcpy (STREAM_DATA (stream) + auth_tlv_offset + 3, |
remote->passwd, ISIS_AUTH_MD5_SIZE); |
remote->passwd, ISIS_AUTH_MD5_SIZE); |
Line 311 tlvs_to_adj_area_addrs (struct tlvs *tlvs, struct isis
|
Line 311 tlvs_to_adj_area_addrs (struct tlvs *tlvs, struct isis
|
} |
} |
} |
} |
|
|
static void | static int |
tlvs_to_adj_nlpids (struct tlvs *tlvs, struct isis_adjacency *adj) |
tlvs_to_adj_nlpids (struct tlvs *tlvs, struct isis_adjacency *adj) |
{ |
{ |
int i; |
int i; |
Line 321 tlvs_to_adj_nlpids (struct tlvs *tlvs, struct isis_adj
|
Line 321 tlvs_to_adj_nlpids (struct tlvs *tlvs, struct isis_adj
|
{ |
{ |
|
|
tlv_nlpids = tlvs->nlpids; |
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; |
|
|
Line 329 tlvs_to_adj_nlpids (struct tlvs *tlvs, struct isis_adj
|
Line 331 tlvs_to_adj_nlpids (struct tlvs *tlvs, struct isis_adj
|
adj->nlpids.nlpids[i] = tlv_nlpids->nlpids[i]; |
adj->nlpids.nlpids[i] = tlv_nlpids->nlpids[i]; |
} |
} |
} |
} |
|
return 0; |
} |
} |
|
|
static void |
static void |
Line 399 process_p2p_hello (struct isis_circuit *circuit)
|
Line 402 process_p2p_hello (struct isis_circuit *circuit)
|
u_int32_t expected = 0, found = 0, auth_tlv_offset = 0; |
u_int32_t expected = 0, found = 0, auth_tlv_offset = 0; |
uint16_t pdu_len; |
uint16_t pdu_len; |
struct tlvs tlvs; |
struct tlvs tlvs; |
|
int v4_usable = 0, v6_usable = 0; |
|
|
if (isis->debugs & DEBUG_ADJ_PACKETS) |
if (isis->debugs & DEBUG_ADJ_PACKETS) |
{ |
{ |
Line 442 process_p2p_hello (struct isis_circuit *circuit)
|
Line 446 process_p2p_hello (struct isis_circuit *circuit)
|
hdr = (struct isis_p2p_hello_hdr *) STREAM_PNT (circuit->rcv_stream); |
hdr = (struct isis_p2p_hello_hdr *) STREAM_PNT (circuit->rcv_stream); |
pdu_len = ntohs (hdr->pdu_len); |
pdu_len = ntohs (hdr->pdu_len); |
|
|
if (pdu_len > ISO_MTU(circuit) || | if (pdu_len < (ISIS_FIXED_HDR_LEN + ISIS_P2PHELLO_HDRLEN) || |
| pdu_len > ISO_MTU(circuit) || |
pdu_len > stream_get_endp (circuit->rcv_stream)) |
pdu_len > stream_get_endp (circuit->rcv_stream)) |
{ |
{ |
zlog_warn ("ISIS-Adj (%s): Rcvd P2P IIH from (%s) with " |
zlog_warn ("ISIS-Adj (%s): Rcvd P2P IIH from (%s) with " |
Line 489 process_p2p_hello (struct isis_circuit *circuit)
|
Line 494 process_p2p_hello (struct isis_circuit *circuit)
|
return ISIS_WARNING; |
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; |
|
} |
|
|
/* 8.2.5.1 c) Authentication */ |
/* 8.2.5.1 c) Authentication */ |
if (circuit->passwd.type) |
if (circuit->passwd.type) |
{ |
{ |
Line 507 process_p2p_hello (struct isis_circuit *circuit)
|
Line 519 process_p2p_hello (struct isis_circuit *circuit)
|
/* |
/* |
* check if it's own interface ip match iih ip addrs |
* check if it's own interface ip match iih ip addrs |
*/ |
*/ |
if ((found & TLVFLAG_IPV4_ADDR) == 0 || | if (found & TLVFLAG_IPV4_ADDR) |
ip_match (circuit->ip_addrs, tlvs.ipv4_addrs) == 0) | |
{ |
{ |
zlog_warn ("ISIS-Adj: No usable IP interface addresses " | if (ip_match (circuit->ip_addrs, tlvs.ipv4_addrs)) |
"in LAN IIH from %s\n", circuit->interface->name); | v4_usable = 1; |
| else |
| zlog_warn ("ISIS-Adj: IPv4 addresses present but no overlap " |
| "in P2P IIH from %s\n", circuit->interface->name); |
| } |
| #ifndef HAVE_IPV6 |
| else /* !(found & TLVFLAG_IPV4_ADDR) */ |
| zlog_warn ("ISIS-Adj: no IPv4 in P2P IIH from %s " |
| "(this isisd has no IPv6)\n", circuit->interface->name); |
| |
| #else |
| 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); |
| } |
| |
| 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); |
| #endif |
| |
| if (!v6_usable && !v4_usable) |
| { |
free_tlvs (&tlvs); |
free_tlvs (&tlvs); |
return ISIS_WARNING; |
return ISIS_WARNING; |
} |
} |
|
|
/* |
/* |
|
* 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; |
|
} |
|
|
|
/* |
* My interpertation of the ISO, if no adj exists we will create one for |
* My interpertation of the ISO, if no adj exists we will create one for |
* the circuit |
* the circuit |
*/ |
*/ |
adj = circuit->u.p2p.neighbor; |
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->level != hdr->circuit_t) |
{ |
{ |
if (!adj) |
if (!adj) |
Line 534 process_p2p_hello (struct isis_circuit *circuit)
|
Line 601 process_p2p_hello (struct isis_circuit *circuit)
|
adj->level = hdr->circuit_t; |
adj->level = hdr->circuit_t; |
} |
} |
circuit->u.p2p.neighbor = adj; |
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); |
isis_adj_state_change (adj, ISIS_ADJ_INITIALIZING, NULL); |
adj->sys_type = ISIS_SYSTYPE_UNKNOWN; |
adj->sys_type = ISIS_SYSTYPE_UNKNOWN; |
} |
} |
Line 546 process_p2p_hello (struct isis_circuit *circuit)
|
Line 620 process_p2p_hello (struct isis_circuit *circuit)
|
tlvs_to_adj_area_addrs (&tlvs, adj); |
tlvs_to_adj_area_addrs (&tlvs, adj); |
|
|
/* which protocol are spoken ??? */ |
/* which protocol are spoken ??? */ |
if (found & TLVFLAG_NLPID) | if (tlvs_to_adj_nlpids (&tlvs, adj)) |
tlvs_to_adj_nlpids (&tlvs, adj); | { |
| free_tlvs (&tlvs); |
| return ISIS_WARNING; |
| } |
|
|
/* we need to copy addresses to the adj */ |
/* we need to copy addresses to the adj */ |
if (found & TLVFLAG_IPV4_ADDR) |
if (found & TLVFLAG_IPV4_ADDR) |
Line 816 process_p2p_hello (struct isis_circuit *circuit)
|
Line 893 process_p2p_hello (struct isis_circuit *circuit)
|
break; |
break; |
} |
} |
|
|
adj->circuit_t = hdr->circuit_t; |
|
|
|
if (isis->debugs & DEBUG_ADJ_PACKETS) |
if (isis->debugs & DEBUG_ADJ_PACKETS) |
{ |
{ |
Line 836 process_p2p_hello (struct isis_circuit *circuit)
|
Line 912 process_p2p_hello (struct isis_circuit *circuit)
|
* Process IS-IS LAN Level 1/2 Hello PDU |
* Process IS-IS LAN Level 1/2 Hello PDU |
*/ |
*/ |
static int |
static int |
process_lan_hello (int level, struct isis_circuit *circuit, u_char * ssnpa) | process_lan_hello (int level, struct isis_circuit *circuit, const u_char *ssnpa) |
{ |
{ |
int retval = ISIS_OK; |
int retval = ISIS_OK; |
struct isis_lan_hello_hdr hdr; |
struct isis_lan_hello_hdr hdr; |
Line 845 process_lan_hello (int level, struct isis_circuit *cir
|
Line 921 process_lan_hello (int level, struct isis_circuit *cir
|
struct tlvs tlvs; |
struct tlvs tlvs; |
u_char *snpa; |
u_char *snpa; |
struct listnode *node; |
struct listnode *node; |
|
int v4_usable = 0, v6_usable = 0; |
|
|
if (isis->debugs & DEBUG_ADJ_PACKETS) |
if (isis->debugs & DEBUG_ADJ_PACKETS) |
{ |
{ |
Line 909 process_lan_hello (int level, struct isis_circuit *cir
|
Line 986 process_lan_hello (int level, struct isis_circuit *cir
|
hdr.prio = stream_getc (circuit->rcv_stream); |
hdr.prio = stream_getc (circuit->rcv_stream); |
stream_get (hdr.lan_id, circuit->rcv_stream, ISIS_SYS_ID_LEN + 1); |
stream_get (hdr.lan_id, circuit->rcv_stream, ISIS_SYS_ID_LEN + 1); |
|
|
if (hdr.pdu_len > ISO_MTU(circuit) || | 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)) |
hdr.pdu_len > stream_get_endp (circuit->rcv_stream)) |
{ |
{ |
zlog_warn ("ISIS-Adj (%s): Rcvd LAN IIH from (%s) with " |
zlog_warn ("ISIS-Adj (%s): Rcvd LAN IIH from (%s) with " |
Line 967 process_lan_hello (int level, struct isis_circuit *cir
|
Line 1045 process_lan_hello (int level, struct isis_circuit *cir
|
goto out; |
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; |
|
} |
|
|
/* Verify authentication, either cleartext of HMAC MD5 */ |
/* Verify authentication, either cleartext of HMAC MD5 */ |
if (circuit->passwd.type) |
if (circuit->passwd.type) |
{ |
{ |
Line 982 process_lan_hello (int level, struct isis_circuit *cir
|
Line 1068 process_lan_hello (int level, struct isis_circuit *cir
|
} |
} |
} |
} |
|
|
|
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; |
|
} |
|
|
/* |
/* |
* Accept the level 1 adjacency only if a match between local and |
* Accept the level 1 adjacency only if a match between local and |
* remote area addresses is found |
* remote area addresses is found |
Line 1015 process_lan_hello (int level, struct isis_circuit *cir
|
Line 1108 process_lan_hello (int level, struct isis_circuit *cir
|
/* |
/* |
* check if it's own interface ip match iih ip addrs |
* check if it's own interface ip match iih ip addrs |
*/ |
*/ |
if ((found & TLVFLAG_IPV4_ADDR) == 0 || | if (found & TLVFLAG_IPV4_ADDR) |
ip_match (circuit->ip_addrs, tlvs.ipv4_addrs) == 0) | |
{ |
{ |
zlog_debug ("ISIS-Adj: No usable IP interface addresses " | if (ip_match (circuit->ip_addrs, tlvs.ipv4_addrs)) |
"in LAN IIH from %s\n", circuit->interface->name); | v4_usable = 1; |
retval = ISIS_WARNING; | else |
goto out; | zlog_warn ("ISIS-Adj: IPv4 addresses present but no overlap " |
| "in LAN IIH from %s\n", circuit->interface->name); |
} |
} |
|
#ifndef HAVE_IPV6 |
|
else /* !(found & TLVFLAG_IPV4_ADDR) */ |
|
zlog_warn ("ISIS-Adj: no IPv4 in LAN IIH from %s " |
|
"(this isisd has no IPv6)\n", circuit->interface->name); |
|
|
|
#else |
|
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 (!(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); |
|
#endif |
|
|
|
if (!v6_usable && !v4_usable) |
|
{ |
|
free_tlvs (&tlvs); |
|
return ISIS_WARNING; |
|
} |
|
|
|
|
adj = isis_adj_lookup (hdr.source_id, circuit->u.bc.adjdb[level - 1]); |
adj = isis_adj_lookup (hdr.source_id, circuit->u.bc.adjdb[level - 1]); |
if ((adj == NULL) || (memcmp(adj->snpa, ssnpa, ETH_ALEN)) || |
if ((adj == NULL) || (memcmp(adj->snpa, ssnpa, ETH_ALEN)) || |
(adj->level != level)) |
(adj->level != level)) |
Line 1090 process_lan_hello (int level, struct isis_circuit *cir
|
Line 1217 process_lan_hello (int level, struct isis_circuit *cir
|
tlvs_to_adj_area_addrs (&tlvs, adj); |
tlvs_to_adj_area_addrs (&tlvs, adj); |
|
|
/* which protocol are spoken ??? */ |
/* which protocol are spoken ??? */ |
if (found & TLVFLAG_NLPID) | if (tlvs_to_adj_nlpids (&tlvs, adj)) |
tlvs_to_adj_nlpids (&tlvs, adj); | { |
| retval = ISIS_WARNING; |
| goto out; |
| } |
|
|
/* we need to copy addresses to the adj */ |
/* we need to copy addresses to the adj */ |
if (found & TLVFLAG_IPV4_ADDR) |
if (found & TLVFLAG_IPV4_ADDR) |
Line 1151 out:
|
Line 1281 out:
|
if (isis->debugs & DEBUG_ADJ_PACKETS) |
if (isis->debugs & DEBUG_ADJ_PACKETS) |
{ |
{ |
zlog_debug ("ISIS-Adj (%s): Rcvd L%d LAN IIH from %s on %s, cirType %s, " |
zlog_debug ("ISIS-Adj (%s): Rcvd L%d LAN IIH from %s on %s, cirType %s, " |
"cirID %u, length %ld", | "cirID %u, length %zd", |
circuit->area->area_tag, |
circuit->area->area_tag, |
level, snpa_print (ssnpa), circuit->interface->name, |
level, snpa_print (ssnpa), circuit->interface->name, |
circuit_t2string (circuit->is_type), |
circuit_t2string (circuit->is_type), |
Line 1170 out:
|
Line 1300 out:
|
* Section 7.3.15.1 - Action on receipt of a link state PDU |
* Section 7.3.15.1 - Action on receipt of a link state PDU |
*/ |
*/ |
static int |
static int |
process_lsp (int level, struct isis_circuit *circuit, u_char * ssnpa) | process_lsp (int level, struct isis_circuit *circuit, const u_char *ssnpa) |
{ |
{ |
struct isis_link_state_hdr *hdr; |
struct isis_link_state_hdr *hdr; |
struct isis_adjacency *adj = NULL; |
struct isis_adjacency *adj = NULL; |
Line 1179 process_lsp (int level, struct isis_circuit *circuit,
|
Line 1309 process_lsp (int level, struct isis_circuit *circuit,
|
u_char lspid[ISIS_SYS_ID_LEN + 2]; |
u_char lspid[ISIS_SYS_ID_LEN + 2]; |
struct isis_passwd *passwd; |
struct isis_passwd *passwd; |
uint16_t pdu_len; |
uint16_t pdu_len; |
|
int lsp_confusion; |
|
|
if (isis->debugs & DEBUG_UPDATE_PACKETS) |
if (isis->debugs & DEBUG_UPDATE_PACKETS) |
{ |
{ |
Line 1202 process_lsp (int level, struct isis_circuit *circuit,
|
Line 1333 process_lsp (int level, struct isis_circuit *circuit,
|
pdu_len = ntohs (hdr->pdu_len); |
pdu_len = ntohs (hdr->pdu_len); |
|
|
/* lsp length check */ |
/* lsp length check */ |
if (pdu_len < ISIS_LSP_HDR_LEN || | if (pdu_len < (ISIS_FIXED_HDR_LEN + ISIS_LSP_HDR_LEN) || |
pdu_len > ISO_MTU(circuit) || |
pdu_len > ISO_MTU(circuit) || |
pdu_len > stream_get_endp (circuit->rcv_stream)) |
pdu_len > stream_get_endp (circuit->rcv_stream)) |
{ |
{ |
Line 1353 dontcheckadj:
|
Line 1484 dontcheckadj:
|
|
|
/* 7.3.15.1 a) 9 - OriginatingLSPBufferSize - not implemented FIXME: do it */ |
/* 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 */ |
/* 7.3.15.1 b) - If the remaining life time is 0, we perform 7.3.16.4 */ |
if (hdr->rem_lifetime == 0) |
if (hdr->rem_lifetime == 0) |
{ |
{ |
Line 1375 dontcheckadj:
|
Line 1521 dontcheckadj:
|
lsp_update (lsp, circuit->rcv_stream, circuit->area, level); |
lsp_update (lsp, circuit->rcv_stream, circuit->area, level); |
/* ii */ |
/* ii */ |
lsp_set_all_srmflags (lsp); |
lsp_set_all_srmflags (lsp); |
/* iii */ |
|
ISIS_CLEAR_FLAG (lsp->SRMflags, circuit); |
|
/* v */ |
/* v */ |
ISIS_FLAGS_CLEAR_ALL (lsp->SSNflags); /* FIXME: OTHER than c */ |
ISIS_FLAGS_CLEAR_ALL (lsp->SSNflags); /* FIXME: OTHER than c */ |
/* iv */ |
|
if (circuit->circ_type != CIRCUIT_T_BROADCAST) |
|
ISIS_SET_FLAG (lsp->SSNflags, circuit); |
|
|
|
|
/* 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) */ |
} /* 7.3.16.4 b) 2) */ |
else if (comp == LSP_EQUAL) |
else if (comp == LSP_EQUAL) |
{ |
{ |
Line 1427 dontcheckadj:
|
Line 1579 dontcheckadj:
|
if (!lsp) |
if (!lsp) |
{ |
{ |
/* 7.3.16.4: initiate a purge */ |
/* 7.3.16.4: initiate a purge */ |
lsp_purge_non_exist (hdr, circuit->area); | lsp_purge_non_exist(level, hdr, circuit->area); |
return ISIS_OK; |
return ISIS_OK; |
} |
} |
/* 7.3.15.1 d) - If this is our own lsp and we have it */ |
/* 7.3.15.1 d) - If this is our own lsp and we have it */ |
Line 1519 dontcheckadj:
|
Line 1671 dontcheckadj:
|
|
|
static int |
static int |
process_snp (int snp_type, int level, struct isis_circuit *circuit, |
process_snp (int snp_type, int level, struct isis_circuit *circuit, |
u_char * ssnpa) | const u_char *ssnpa) |
{ |
{ |
int retval = ISIS_OK; |
int retval = ISIS_OK; |
int cmp, own_lsp; |
int cmp, own_lsp; |
Line 1545 process_snp (int snp_type, int level, struct isis_circ
|
Line 1697 process_snp (int snp_type, int level, struct isis_circ
|
(struct isis_complete_seqnum_hdr *) STREAM_PNT (circuit->rcv_stream); |
(struct isis_complete_seqnum_hdr *) STREAM_PNT (circuit->rcv_stream); |
stream_forward_getp (circuit->rcv_stream, ISIS_CSNP_HDRLEN); |
stream_forward_getp (circuit->rcv_stream, ISIS_CSNP_HDRLEN); |
pdu_len = ntohs (chdr->pdu_len); |
pdu_len = ntohs (chdr->pdu_len); |
if (pdu_len < ISIS_CSNP_HDRLEN || | if (pdu_len < (ISIS_FIXED_HDR_LEN + ISIS_CSNP_HDRLEN) || |
pdu_len > ISO_MTU(circuit) || |
pdu_len > ISO_MTU(circuit) || |
pdu_len > stream_get_endp (circuit->rcv_stream)) |
pdu_len > stream_get_endp (circuit->rcv_stream)) |
{ |
{ |
Line 1560 process_snp (int snp_type, int level, struct isis_circ
|
Line 1712 process_snp (int snp_type, int level, struct isis_circ
|
(struct isis_partial_seqnum_hdr *) STREAM_PNT (circuit->rcv_stream); |
(struct isis_partial_seqnum_hdr *) STREAM_PNT (circuit->rcv_stream); |
stream_forward_getp (circuit->rcv_stream, ISIS_PSNP_HDRLEN); |
stream_forward_getp (circuit->rcv_stream, ISIS_PSNP_HDRLEN); |
pdu_len = ntohs (phdr->pdu_len); |
pdu_len = ntohs (phdr->pdu_len); |
if (pdu_len < ISIS_PSNP_HDRLEN || | if (pdu_len < (ISIS_FIXED_HDR_LEN + ISIS_PSNP_HDRLEN) || |
pdu_len > ISO_MTU(circuit) || |
pdu_len > ISO_MTU(circuit) || |
pdu_len > stream_get_endp (circuit->rcv_stream)) |
pdu_len > stream_get_endp (circuit->rcv_stream)) |
{ |
{ |
zlog_warn ("Received a CSNP with bogus length %d", pdu_len); | zlog_warn ("Received a PSNP with bogus length %d", pdu_len); |
return ISIS_WARNING; |
return ISIS_WARNING; |
} |
} |
} |
} |
Line 1765 process_snp (int snp_type, int level, struct isis_circ
|
Line 1917 process_snp (int snp_type, int level, struct isis_circ
|
if (entry->rem_lifetime && entry->checksum && entry->seq_num && |
if (entry->rem_lifetime && entry->checksum && entry->seq_num && |
memcmp (entry->lsp_id, isis->sysid, ISIS_SYS_ID_LEN)) |
memcmp (entry->lsp_id, isis->sysid, ISIS_SYS_ID_LEN)) |
{ |
{ |
lsp = lsp_new (entry->lsp_id, ntohs (entry->rem_lifetime), | lsp = lsp_new(circuit->area, entry->lsp_id, |
0, 0, entry->checksum, level); | ntohs(entry->rem_lifetime), |
lsp->area = circuit->area; | 0, 0, entry->checksum, level); |
lsp_insert (lsp, circuit->area->lspdb[level - 1]); |
lsp_insert (lsp, circuit->area->lspdb[level - 1]); |
ISIS_FLAGS_CLEAR_ALL (lsp->SRMflags); |
ISIS_FLAGS_CLEAR_ALL (lsp->SRMflags); |
ISIS_SET_FLAG (lsp->SSNflags, circuit); |
ISIS_SET_FLAG (lsp->SSNflags, circuit); |
Line 1815 process_snp (int snp_type, int level, struct isis_circ
|
Line 1967 process_snp (int snp_type, int level, struct isis_circ
|
} |
} |
|
|
static int |
static int |
process_csnp (int level, struct isis_circuit *circuit, u_char * ssnpa) | process_csnp (int level, struct isis_circuit *circuit, const u_char *ssnpa) |
{ |
{ |
if (isis->debugs & DEBUG_SNP_PACKETS) |
if (isis->debugs & DEBUG_SNP_PACKETS) |
{ |
{ |
Line 1839 process_csnp (int level, struct isis_circuit *circuit,
|
Line 1991 process_csnp (int level, struct isis_circuit *circuit,
|
} |
} |
|
|
static int |
static int |
process_psnp (int level, struct isis_circuit *circuit, u_char * ssnpa) | process_psnp (int level, struct isis_circuit *circuit, const u_char *ssnpa) |
{ |
{ |
if (isis->debugs & DEBUG_SNP_PACKETS) |
if (isis->debugs & DEBUG_SNP_PACKETS) |
{ |
{ |
Line 1862 process_psnp (int level, struct isis_circuit *circuit,
|
Line 2014 process_psnp (int level, struct isis_circuit *circuit,
|
} |
} |
|
|
/* |
/* |
* Process ISH |
|
* ISO - 10589 |
|
* Section 8.2.2 - Receiving ISH PDUs by an intermediate system |
|
* FIXME: sample packet dump, need to figure 0x81 - looks like NLPid |
|
* 0x82 0x15 0x01 0x00 0x04 0x01 0x2c 0x59 |
|
* 0x38 0x08 0x47 0x00 0x01 0x00 0x02 0x00 |
|
* 0x03 0x00 0x81 0x01 0xcc |
|
*/ |
|
static int |
|
process_is_hello (struct isis_circuit *circuit) |
|
{ |
|
struct isis_adjacency *adj; |
|
int retval = ISIS_OK; |
|
u_char neigh_len; |
|
u_char *sysid; |
|
|
|
if (isis->debugs & DEBUG_ADJ_PACKETS) |
|
{ |
|
zlog_debug ("ISIS-Adj (%s): Rcvd ISH 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)); |
|
} |
|
|
|
/* In this point in time we are not yet able to handle is_hellos |
|
* on lan - Sorry juniper... |
|
*/ |
|
if (circuit->circ_type == CIRCUIT_T_BROADCAST) |
|
return retval; |
|
|
|
neigh_len = stream_getc (circuit->rcv_stream); |
|
sysid = STREAM_PNT (circuit->rcv_stream) + neigh_len - 1 - ISIS_SYS_ID_LEN; |
|
adj = circuit->u.p2p.neighbor; |
|
if (!adj) |
|
{ |
|
/* 8.2.2 */ |
|
adj = isis_new_adj (sysid, NULL, 0, circuit); |
|
if (adj == NULL) |
|
return ISIS_ERROR; |
|
|
|
isis_adj_state_change (adj, ISIS_ADJ_INITIALIZING, NULL); |
|
adj->sys_type = ISIS_SYSTYPE_UNKNOWN; |
|
circuit->u.p2p.neighbor = adj; |
|
} |
|
/* 8.2.2 a) */ |
|
if ((adj->adj_state == ISIS_ADJ_UP) && memcmp (adj->sysid, sysid, |
|
ISIS_SYS_ID_LEN)) |
|
{ |
|
/* 8.2.2 a) 1) FIXME: adjStateChange(down) event */ |
|
/* 8.2.2 a) 2) delete the adj */ |
|
XFREE (MTYPE_ISIS_ADJACENCY, adj); |
|
/* 8.2.2 a) 3) create a new adj */ |
|
adj = isis_new_adj (sysid, NULL, 0, circuit); |
|
if (adj == NULL) |
|
return ISIS_ERROR; |
|
|
|
/* 8.2.2 a) 3) i */ |
|
isis_adj_state_change (adj, ISIS_ADJ_INITIALIZING, NULL); |
|
/* 8.2.2 a) 3) ii */ |
|
adj->sys_type = ISIS_SYSTYPE_UNKNOWN; |
|
/* 8.2.2 a) 4) quite meaningless */ |
|
} |
|
/* 8.2.2 b) ignore on condition */ |
|
if ((adj->adj_state == ISIS_ADJ_INITIALIZING) && |
|
(adj->sys_type == ISIS_SYSTYPE_IS)) |
|
{ |
|
/* do nothing */ |
|
} |
|
else |
|
{ |
|
/* 8.2.2 c) respond with a p2p IIH */ |
|
send_hello (circuit, 1); |
|
} |
|
/* 8.2.2 d) type is IS */ |
|
adj->sys_type = ISIS_SYSTYPE_IS; |
|
/* 8.2.2 e) FIXME: Circuit type of? */ |
|
|
|
return retval; |
|
} |
|
|
|
/* |
|
* PDU Dispatcher |
* PDU Dispatcher |
*/ |
*/ |
|
|
Line 2074 isis_receive (struct thread *thread)
|
Line 2143 isis_receive (struct thread *thread)
|
circuit = THREAD_ARG (thread); |
circuit = THREAD_ARG (thread); |
assert (circuit); |
assert (circuit); |
|
|
if (circuit->rcv_stream == NULL) | isis_circuit_stream(circuit, &circuit->rcv_stream); |
circuit->rcv_stream = stream_new (ISO_MTU (circuit)); | |
else | |
stream_reset (circuit->rcv_stream); | |
|
|
retval = circuit->rx (circuit, ssnpa); |
retval = circuit->rx (circuit, ssnpa); |
circuit->t_read = NULL; |
circuit->t_read = NULL; |
Line 2113 isis_receive (struct thread *thread)
|
Line 2179 isis_receive (struct thread *thread)
|
|
|
circuit->t_read = NULL; |
circuit->t_read = NULL; |
|
|
if (circuit->rcv_stream == NULL) | isis_circuit_stream(circuit, &circuit->rcv_stream); |
circuit->rcv_stream = stream_new (ISO_MTU (circuit)); | |
else | |
stream_reset (circuit->rcv_stream); | |
|
|
retval = circuit->rx (circuit, ssnpa); |
retval = circuit->rx (circuit, ssnpa); |
|
|
Line 2208 send_hello (struct isis_circuit *circuit, int level)
|
Line 2271 send_hello (struct isis_circuit *circuit, int level)
|
struct isis_lan_hello_hdr hello_hdr; |
struct isis_lan_hello_hdr hello_hdr; |
struct isis_p2p_hello_hdr p2p_hello_hdr; |
struct isis_p2p_hello_hdr p2p_hello_hdr; |
unsigned char hmac_md5_hash[ISIS_AUTH_MD5_SIZE]; |
unsigned char hmac_md5_hash[ISIS_AUTH_MD5_SIZE]; |
unsigned long len_pointer, length, auth_tlv_offset = 0; | size_t len_pointer, length, auth_tlv_offset = 0; |
u_int32_t interval; |
u_int32_t interval; |
int retval; |
int retval; |
|
|
Line 2221 send_hello (struct isis_circuit *circuit, int level)
|
Line 2284 send_hello (struct isis_circuit *circuit, int level)
|
return ISIS_WARNING; |
return ISIS_WARNING; |
} |
} |
|
|
if (!circuit->snd_stream) | isis_circuit_stream(circuit, &circuit->snd_stream); |
circuit->snd_stream = stream_new (ISO_MTU (circuit)); | |
else | |
stream_reset (circuit->snd_stream); | |
|
|
if (circuit->circ_type == CIRCUIT_T_BROADCAST) |
if (circuit->circ_type == CIRCUIT_T_BROADCAST) |
if (level == IS_LEVEL_1) |
if (level == IS_LEVEL_1) |
Line 2356 send_hello (struct isis_circuit *circuit, int level)
|
Line 2416 send_hello (struct isis_circuit *circuit, int level)
|
hmac_md5 (STREAM_DATA (circuit->snd_stream), |
hmac_md5 (STREAM_DATA (circuit->snd_stream), |
stream_get_endp (circuit->snd_stream), |
stream_get_endp (circuit->snd_stream), |
(unsigned char *) &circuit->passwd.passwd, circuit->passwd.len, |
(unsigned char *) &circuit->passwd.passwd, circuit->passwd.len, |
(caddr_t) &hmac_md5_hash); | (unsigned char *) &hmac_md5_hash); |
/* Copy the hash into the stream */ |
/* Copy the hash into the stream */ |
memcpy (STREAM_DATA (circuit->snd_stream) + auth_tlv_offset + 3, |
memcpy (STREAM_DATA (circuit->snd_stream) + auth_tlv_offset + 3, |
hmac_md5_hash, ISIS_AUTH_MD5_SIZE); |
hmac_md5_hash, ISIS_AUTH_MD5_SIZE); |
Line 2366 send_hello (struct isis_circuit *circuit, int level)
|
Line 2426 send_hello (struct isis_circuit *circuit, int level)
|
{ |
{ |
if (circuit->circ_type == CIRCUIT_T_BROADCAST) |
if (circuit->circ_type == CIRCUIT_T_BROADCAST) |
{ |
{ |
zlog_debug ("ISIS-Adj (%s): Sent L%d LAN IIH on %s, length %ld", | zlog_debug ("ISIS-Adj (%s): Sending L%d LAN IIH on %s, length %zd", |
circuit->area->area_tag, level, circuit->interface->name, |
circuit->area->area_tag, level, circuit->interface->name, |
/* FIXME: use %z when we stop supporting old compilers. */ |
|
length); |
length); |
} |
} |
else |
else |
{ |
{ |
zlog_debug ("ISIS-Adj (%s): Sent P2P IIH on %s, length %ld", | zlog_debug ("ISIS-Adj (%s): Sending P2P IIH on %s, length %zd", |
circuit->area->area_tag, circuit->interface->name, |
circuit->area->area_tag, circuit->interface->name, |
/* FIXME: use %z when we stop supporting old compilers. */ |
|
length); |
length); |
} |
} |
if (isis->debugs & DEBUG_PACKET_DUMP) |
if (isis->debugs & DEBUG_PACKET_DUMP) |
Line 2401 send_lan_l1_hello (struct thread *thread)
|
Line 2459 send_lan_l1_hello (struct thread *thread)
|
assert (circuit); |
assert (circuit); |
circuit->u.bc.t_send_lan_hello[0] = NULL; |
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]) |
if (circuit->u.bc.run_dr_elect[0]) |
retval = isis_dr_elect (circuit, 1); |
retval = isis_dr_elect (circuit, 1); |
|
|
Line 2424 send_lan_l2_hello (struct thread *thread)
|
Line 2489 send_lan_l2_hello (struct thread *thread)
|
assert (circuit); |
assert (circuit); |
circuit->u.bc.t_send_lan_hello[1] = NULL; |
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->u.bc.run_dr_elect[1]) |
if (circuit->u.bc.run_dr_elect[1]) |
retval = isis_dr_elect (circuit, 2); |
retval = isis_dr_elect (circuit, 2); |
|
|
Line 2468 build_csnp (int level, u_char * start, u_char * stop,
|
Line 2540 build_csnp (int level, u_char * start, u_char * stop,
|
unsigned long auth_tlv_offset = 0; |
unsigned long auth_tlv_offset = 0; |
int retval = ISIS_OK; |
int retval = ISIS_OK; |
|
|
if (circuit->snd_stream == NULL) | isis_circuit_stream(circuit, &circuit->snd_stream); |
circuit->snd_stream = stream_new (ISO_MTU (circuit)); | |
else | |
stream_reset (circuit->snd_stream); | |
|
|
if (level == IS_LEVEL_1) |
if (level == IS_LEVEL_1) |
fill_fixed_hdr_andstream (&fixed_hdr, L1_COMPLETE_SEQ_NUM, |
fill_fixed_hdr_andstream (&fixed_hdr, L1_COMPLETE_SEQ_NUM, |
Line 2543 build_csnp (int level, u_char * start, u_char * stop,
|
Line 2612 build_csnp (int level, u_char * start, u_char * stop,
|
hmac_md5 (STREAM_DATA (circuit->snd_stream), |
hmac_md5 (STREAM_DATA (circuit->snd_stream), |
stream_get_endp(circuit->snd_stream), |
stream_get_endp(circuit->snd_stream), |
(unsigned char *) &passwd->passwd, passwd->len, |
(unsigned char *) &passwd->passwd, passwd->len, |
(caddr_t) &hmac_md5_hash); | (unsigned char *) &hmac_md5_hash); |
/* Copy the hash into the stream */ |
/* Copy the hash into the stream */ |
memcpy (STREAM_DATA (circuit->snd_stream) + auth_tlv_offset + 3, |
memcpy (STREAM_DATA (circuit->snd_stream) + auth_tlv_offset + 3, |
hmac_md5_hash, ISIS_AUTH_MD5_SIZE); |
hmac_md5_hash, ISIS_AUTH_MD5_SIZE); |
Line 2688 send_csnp (struct isis_circuit *circuit, int level)
|
Line 2757 send_csnp (struct isis_circuit *circuit, int level)
|
|
|
if (isis->debugs & DEBUG_SNP_PACKETS) |
if (isis->debugs & DEBUG_SNP_PACKETS) |
{ |
{ |
zlog_debug ("ISIS-Snp (%s): Sent L%d CSNP on %s, length %ld", | zlog_debug ("ISIS-Snp (%s): Sending L%d CSNP on %s, length %zd", |
circuit->area->area_tag, level, circuit->interface->name, |
circuit->area->area_tag, level, circuit->interface->name, |
stream_get_endp (circuit->snd_stream)); |
stream_get_endp (circuit->snd_stream)); |
for (ALL_LIST_ELEMENTS_RO (list, node, lsp)) |
for (ALL_LIST_ELEMENTS_RO (list, node, lsp)) |
Line 2795 build_psnp (int level, struct isis_circuit *circuit, s
|
Line 2864 build_psnp (int level, struct isis_circuit *circuit, s
|
unsigned long auth_tlv_offset = 0; |
unsigned long auth_tlv_offset = 0; |
int retval = ISIS_OK; |
int retval = ISIS_OK; |
|
|
if (circuit->snd_stream == NULL) | isis_circuit_stream(circuit, &circuit->snd_stream); |
circuit->snd_stream = stream_new (ISO_MTU (circuit)); | |
else | |
stream_reset (circuit->snd_stream); | |
|
|
if (level == IS_LEVEL_1) |
if (level == IS_LEVEL_1) |
fill_fixed_hdr_andstream (&fixed_hdr, L1_PARTIAL_SEQ_NUM, |
fill_fixed_hdr_andstream (&fixed_hdr, L1_PARTIAL_SEQ_NUM, |
Line 2879 build_psnp (int level, struct isis_circuit *circuit, s
|
Line 2945 build_psnp (int level, struct isis_circuit *circuit, s
|
hmac_md5 (STREAM_DATA (circuit->snd_stream), |
hmac_md5 (STREAM_DATA (circuit->snd_stream), |
stream_get_endp(circuit->snd_stream), |
stream_get_endp(circuit->snd_stream), |
(unsigned char *) &passwd->passwd, passwd->len, |
(unsigned char *) &passwd->passwd, passwd->len, |
(caddr_t) &hmac_md5_hash); | (unsigned char *) &hmac_md5_hash); |
/* Copy the hash into the stream */ |
/* Copy the hash into the stream */ |
memcpy (STREAM_DATA (circuit->snd_stream) + auth_tlv_offset + 3, |
memcpy (STREAM_DATA (circuit->snd_stream) + auth_tlv_offset + 3, |
hmac_md5_hash, ISIS_AUTH_MD5_SIZE); |
hmac_md5_hash, ISIS_AUTH_MD5_SIZE); |
Line 2937 send_psnp (int level, struct isis_circuit *circuit)
|
Line 3003 send_psnp (int level, struct isis_circuit *circuit)
|
|
|
if (isis->debugs & DEBUG_SNP_PACKETS) |
if (isis->debugs & DEBUG_SNP_PACKETS) |
{ |
{ |
zlog_debug ("ISIS-Snp (%s): Sent L%d PSNP on %s, length %ld", | zlog_debug ("ISIS-Snp (%s): Sending L%d PSNP on %s, length %zd", |
circuit->area->area_tag, level, |
circuit->area->area_tag, level, |
circuit->interface->name, |
circuit->interface->name, |
stream_get_endp (circuit->snd_stream)); |
stream_get_endp (circuit->snd_stream)); |
Line 3021 send_lsp (struct thread *thread)
|
Line 3087 send_lsp (struct thread *thread)
|
struct isis_circuit *circuit; |
struct isis_circuit *circuit; |
struct isis_lsp *lsp; |
struct isis_lsp *lsp; |
struct listnode *node; |
struct listnode *node; |
|
int clear_srm = 1; |
int retval = ISIS_OK; |
int retval = ISIS_OK; |
|
|
circuit = THREAD_ARG (thread); |
circuit = THREAD_ARG (thread); |
assert (circuit); |
assert (circuit); |
|
|
if (circuit->state != C_STATE_UP || circuit->is_passive == 1) | if (!circuit->lsp_queue) |
{ | return ISIS_OK; |
return retval; | |
} | |
|
|
lsp = listgetdata ((node = listhead (circuit->lsp_queue))); | 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 |
* Do not send if levels do not match |
*/ |
*/ |
if (!(lsp->level & circuit->is_type)) |
if (!(lsp->level & circuit->is_type)) |
{ | goto out; |
list_delete_node (circuit->lsp_queue, node); | |
return retval; | |
} | |
|
|
/* |
/* |
* Do not send if we do not have adjacencies in state up on the circuit |
* Do not send if we do not have adjacencies in state up on the circuit |
*/ |
*/ |
if (circuit->upadjcount[lsp->level - 1] == 0) |
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)) |
{ |
{ |
list_delete_node (circuit->lsp_queue, node); | zlog_err("ISIS-Upd (%s): Can't send L%d LSP %s, seq 0x%08x," |
return retval; | " 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 */ |
/* copy our lsp to the send buffer */ |
Line 3057 send_lsp (struct thread *thread)
|
Line 3162 send_lsp (struct thread *thread)
|
if (isis->debugs & DEBUG_UPDATE_PACKETS) |
if (isis->debugs & DEBUG_UPDATE_PACKETS) |
{ |
{ |
zlog_debug |
zlog_debug |
("ISIS-Upd (%s): Sent L%d LSP %s, seq 0x%08x, cksum 0x%04x," | ("ISIS-Upd (%s): Sending L%d LSP %s, seq 0x%08x, cksum 0x%04x," |
" lifetime %us on %s", circuit->area->area_tag, lsp->level, |
" lifetime %us on %s", circuit->area->area_tag, lsp->level, |
rawlspid_print (lsp->lsp_header->lsp_id), |
rawlspid_print (lsp->lsp_header->lsp_id), |
ntohl (lsp->lsp_header->seq_num), |
ntohl (lsp->lsp_header->seq_num), |
Line 3069 send_lsp (struct thread *thread)
|
Line 3174 send_lsp (struct thread *thread)
|
stream_get_endp (circuit->snd_stream)); |
stream_get_endp (circuit->snd_stream)); |
} |
} |
|
|
|
clear_srm = 0; |
retval = circuit->tx (circuit, lsp->level); |
retval = circuit->tx (circuit, lsp->level); |
if (retval != ISIS_OK) |
if (retval != ISIS_OK) |
{ |
{ |
zlog_err ("ISIS-Upd (%s): Send L%d LSP on %s failed", | zlog_err ("ISIS-Upd (%s): Send L%d LSP on %s failed %s", |
circuit->area->area_tag, lsp->level, |
circuit->area->area_tag, lsp->level, |
circuit->interface->name); | circuit->interface->name, |
return retval; | (retval == ISIS_WARNING) ? "temporarily" : "permanently"); |
} |
} |
|
|
/* | out: |
* If the sending succeeded, we can del the lsp from circuits | if (clear_srm |
* lsp_queue | || (retval == ISIS_OK && circuit->circ_type == CIRCUIT_T_BROADCAST) |
*/ | || (retval != ISIS_OK && retval != ISIS_WARNING)) |
list_delete_node (circuit->lsp_queue, node); | { |
| /* 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); |
| } |
|
|
/* 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); |
|
|
|
/* |
|
* On broadcast circuits also the SRMflag can be cleared |
|
*/ |
|
if (circuit->circ_type == CIRCUIT_T_BROADCAST) |
|
ISIS_CLEAR_FLAG (lsp->SRMflags, circuit); |
|
|
|
return retval; |
return retval; |
} |
} |
|
|
Line 3108 ack_lsp (struct isis_link_state_hdr *hdr, struct isis_
|
Line 3210 ack_lsp (struct isis_link_state_hdr *hdr, struct isis_
|
u_int16_t length; |
u_int16_t length; |
struct isis_fixed_hdr fixed_hdr; |
struct isis_fixed_hdr fixed_hdr; |
|
|
if (!circuit->snd_stream) | isis_circuit_stream(circuit, &circuit->snd_stream); |
circuit->snd_stream = stream_new (ISO_MTU (circuit)); | |
else | |
stream_reset (circuit->snd_stream); | |
|
|
// fill_llc_hdr (stream); |
// fill_llc_hdr (stream); |
if (level == IS_LEVEL_1) |
if (level == IS_LEVEL_1) |