static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit,
uint8_t *ssnpa)
{
+ /* keep a copy of the raw pdu for NB notifications */
+ size_t pdu_start = stream_get_getp(circuit->rcv_stream);
+ size_t pdu_end = stream_get_endp(circuit->rcv_stream);
+ char raw_pdu[pdu_end - pdu_start];
bool p2p_hello = (pdu_type == P2P_HELLO);
int level = p2p_hello ? 0
: (pdu_type == L1_LAN_HELLO) ? ISIS_LEVEL1
? "P2P IIH"
: (level == ISIS_LEVEL1) ? "L1 LAN IIH" : "L2 LAN IIH";
+
+ stream_get_from(raw_pdu, circuit->rcv_stream, pdu_start,
+ pdu_end - pdu_start);
if (isis->debugs & DEBUG_ADJ_PACKETS) {
zlog_debug("ISIS-Adj (%s): Rcvd %s on %s, cirType %s, cirID %u",
circuit->area->area_tag, pdu_name,
if (p2p_hello) {
if (circuit->circ_type != CIRCUIT_T_P2P) {
zlog_warn("p2p hello on non p2p circuit");
+#ifndef FABRICD
+ isis_notif_reject_adjacency(
+ circuit, "p2p hello on non p2p circuit",
+ raw_pdu);
+#endif /* ifndef FABRICD */
return ISIS_WARNING;
}
} else {
if (circuit->circ_type != CIRCUIT_T_BROADCAST) {
zlog_warn("lan hello on non broadcast circuit");
+#ifndef FABRICD
+ isis_notif_reject_adjacency(
+ circuit, "lan hello on non broadcast circuit",
+ raw_pdu);
+#endif /* ifndef FABRICD */
return ISIS_WARNING;
}
zlog_debug(
"level %d LAN Hello received over circuit with externalDomain = true",
level);
+#ifndef FABRICD
+ isis_notif_reject_adjacency(
+ circuit,
+ "LAN Hello received over circuit with externalDomain = true",
+ raw_pdu);
+#endif /* ifndef FABRICD */
return ISIS_WARNING;
}
circuit->area->area_tag,
circuit->interface->name);
}
+#ifndef FABRICD
+ isis_notif_reject_adjacency(
+ circuit, "Interface level mismatch", raw_pdu);
+#endif /* ifndef FABRICD */
return ISIS_WARNING;
}
}
"ISIS-Adj (%s): Rcvd %s from (%s) with invalid pdu length %" PRIu16,
circuit->area->area_tag, pdu_name,
circuit->interface->name, iih.pdu_len);
+#ifndef FABRICD
+ isis_notif_reject_adjacency(circuit, "Invalid PDU length",
+ raw_pdu);
+#endif /* ifndef FABRICD */
return ISIS_WARNING;
}
flog_err(EC_ISIS_PACKET,
"Level %d LAN Hello with Circuit Type %d", level,
iih.circ_type);
+#ifndef FABRICD
+ isis_notif_reject_adjacency(
+ circuit, "LAN Hello with wrong IS-level", raw_pdu);
+#endif /* ifndef FABRICD */
return ISIS_ERROR;
}
if (isis_unpack_tlvs(STREAM_READABLE(circuit->rcv_stream),
circuit->rcv_stream, &iih.tlvs, &error_log)) {
zlog_warn("isis_unpack_tlvs() failed: %s", error_log);
+#ifndef FABRICD
+ isis_notif_reject_adjacency(circuit, "Failed to unpack TLVs",
+ raw_pdu);
+#endif /* ifndef FABRICD */
goto out;
}
if (!iih.tlvs->area_addresses.count) {
zlog_warn("No Area addresses TLV in %s", pdu_name);
+#ifndef FABRICD
+ /* send northbound notification */
+ isis_notif_area_mismatch(circuit, raw_pdu);
+#endif /* ifndef FABRICD */
goto out;
}
if (!iih.tlvs->protocols_supported.count) {
zlog_warn("No supported protocols TLV in %s", pdu_name);
+#ifndef FABRICD
+ isis_notif_reject_adjacency(
+ circuit, "No supported protocols TLV", raw_pdu);
+#endif /* ifndef FABRICD */
goto out;
}
- if (!isis_tlvs_auth_is_valid(iih.tlvs, &circuit->passwd,
- circuit->rcv_stream, false)) {
+ int auth_code = isis_tlvs_auth_is_valid(iih.tlvs, &circuit->passwd,
+ circuit->rcv_stream, false);
+ if (auth_code != ISIS_AUTH_OK) {
isis_event_auth_failure(circuit->area->area_tag,
"IIH authentication failure",
iih.sys_id);
+#ifndef FABRICD
+ /* send northbound notification */
+ stream_get_from(raw_pdu, circuit->rcv_stream, pdu_start,
+ pdu_end - pdu_start);
+ if (auth_code == ISIS_AUTH_FAILURE)
+ isis_notif_authentication_failure(circuit, raw_pdu);
+ else /* AUTH_TYPE_FAILURE or NO_VALIDATOR */
+ isis_notif_authentication_type_failure(circuit,
+ raw_pdu);
+#endif /* ifndef FABRICD */
goto out;
}
zlog_warn(
"ISIS-Adj (%s): Received IIH with own sysid - discard",
circuit->area->area_tag);
+#ifndef FABRICD
+ isis_notif_reject_adjacency(
+ circuit, "Received IIH with our own sysid", raw_pdu);
+#endif /* ifndef FABRICD */
goto out;
}
circuit->area->area_tag, level,
circuit->interface->name);
}
+#ifndef FABRICD
+ /* send northbound notification */
+ isis_notif_area_mismatch(circuit, raw_pdu);
+#endif /* ifndef FABRICD */
goto out;
}
"ISIS-Adj (%s): Neither IPv4 nor IPv6 considered usable. Ignoring IIH",
circuit->area->area_tag);
}
-
+#ifndef FABRICD
+ isis_notif_reject_adjacency(
+ circuit, "Neither IPv4 not IPv6 considered usable",
+ raw_pdu);
+#endif /* ifndef FABRICD */
goto out;
}
{
int level;
bool circuit_scoped;
+ size_t pdu_start = stream_get_getp(circuit->rcv_stream);
+ size_t pdu_end = stream_get_endp(circuit->rcv_stream);
+ char raw_pdu[pdu_end - pdu_start];
+
+ stream_get_from(raw_pdu, circuit->rcv_stream, pdu_start,
+ pdu_end - pdu_start);
if (pdu_type == FS_LINK_STATE) {
if (!fabricd)
hdr.checksum = stream_getw(circuit->rcv_stream);
hdr.lsp_bits = stream_getc(circuit->rcv_stream);
+#ifndef FABRICD
+ /* send northbound notification */
+ isis_notif_lsp_received(circuit, rawlspid_print(hdr.lsp_id), hdr.seqno,
+ time(NULL), sysid_print(hdr.lsp_id));
+#endif /* ifndef FABRICD */
+
if (pdu_len_validate(hdr.pdu_len, circuit)) {
zlog_debug("ISIS-Upd (%s): LSP %s invalid LSP length %" PRIu16,
circuit->area->area_tag, rawlspid_print(hdr.lsp_id),
struct isis_passwd *passwd = (level == ISIS_LEVEL1)
? &circuit->area->area_passwd
: &circuit->area->domain_passwd;
- if (!isis_tlvs_auth_is_valid(tlvs, passwd, circuit->rcv_stream, true)) {
+ int auth_code = isis_tlvs_auth_is_valid(tlvs, passwd,
+ circuit->rcv_stream, true);
+ if (auth_code != ISIS_AUTH_OK) {
isis_event_auth_failure(circuit->area->area_tag,
"LSP authentication failure",
hdr.lsp_id);
+#ifndef FABRICD
+ /* send northbound notification */
+ if (auth_code == ISIS_AUTH_FAILURE)
+ isis_notif_authentication_failure(circuit, raw_pdu);
+ else /* AUTH_TYPE_FAILURE or NO_VALIDATOR */
+ isis_notif_authentication_type_failure(circuit,
+ raw_pdu);
+#endif /* ifndef FABRICD */
goto out;
}
static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit,
const uint8_t *ssnpa)
{
+#ifndef FABRICD
+ size_t pdu_start = stream_get_getp(circuit->rcv_stream);
+ size_t pdu_end = stream_get_endp(circuit->rcv_stream);
+ char raw_pdu[pdu_end - pdu_start];
+#endif /* ifndef FABRICD */
+
bool is_csnp = (pdu_type == L1_COMPLETE_SEQ_NUM
|| pdu_type == L2_COMPLETE_SEQ_NUM);
char typechar = is_csnp ? 'C' : 'P';
uint16_t pdu_len = stream_getw(circuit->rcv_stream);
uint8_t rem_sys_id[ISIS_SYS_ID_LEN];
+
stream_get(rem_sys_id, circuit->rcv_stream, ISIS_SYS_ID_LEN);
stream_forward_getp(circuit->rcv_stream, 1); /* Circuit ID - unused */
struct isis_passwd *passwd = (level == IS_LEVEL_1)
? &circuit->area->area_passwd
: &circuit->area->domain_passwd;
- if (CHECK_FLAG(passwd->snp_auth, SNP_AUTH_RECV)
- && !isis_tlvs_auth_is_valid(tlvs, passwd, circuit->rcv_stream,
- false)) {
- isis_event_auth_failure(circuit->area->area_tag,
- "SNP authentication failure",
- rem_sys_id);
- goto out;
+ if (CHECK_FLAG(passwd->snp_auth, SNP_AUTH_RECV)) {
+ int auth_code = isis_tlvs_auth_is_valid(
+ tlvs, passwd, circuit->rcv_stream, false);
+ if (auth_code != ISIS_AUTH_OK) {
+ isis_event_auth_failure(circuit->area->area_tag,
+ "SNP authentication failure",
+ rem_sys_id);
+#ifndef FABRICD
+ /* send northbound notification */
+ stream_get_from(raw_pdu, circuit->rcv_stream, pdu_start,
+ pdu_end - pdu_start);
+ if (auth_code == ISIS_AUTH_FAILURE)
+ isis_notif_authentication_failure(circuit,
+ raw_pdu);
+ else /* AUTH_TYPE_FAILURE or NO_VALIDATOR */
+ isis_notif_authentication_type_failure(circuit,
+ raw_pdu);
+#endif /* ifndef FABRICD */
+ goto out;
+ }
}
struct isis_lsp_entry *entry_head =
int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa)
{
int retval = ISIS_OK;
+ size_t pdu_start = stream_get_getp(circuit->rcv_stream);
+ size_t pdu_end = stream_get_endp(circuit->rcv_stream);
+ char raw_pdu[pdu_end - pdu_start];
+
+ stream_get_from(raw_pdu, circuit->rcv_stream, pdu_start,
+ pdu_end - pdu_start);
/* Verify that at least the 8 bytes fixed header have been received */
if (stream_get_endp(circuit->rcv_stream) < ISIS_FIXED_HDR_LEN) {
uint8_t pdu_type = stream_getc(circuit->rcv_stream)
& 0x1f; /* bits 6-8 are reserved */
uint8_t version2 = stream_getc(circuit->rcv_stream);
+
stream_forward_getp(circuit->rcv_stream, 1); /* reserved */
uint8_t max_area_addrs = stream_getc(circuit->rcv_stream);
"maximumAreaAddressesMismatch: maximumAreaAdresses in a received PDU %" PRIu8
" while the parameter for this IS is %u",
max_area_addrs, isis->max_area_addrs);
+#ifndef FABRICD
+ /* send northbound notification */
+ isis_notif_max_area_addr_mismatch(circuit, max_area_addrs,
+ raw_pdu);
+#endif /* ifndef FABRICD */
return ISIS_ERROR;
}
lsp->hdr.checksum, lsp->hdr.rem_lifetime,
circuit->interface->name, stream_get_endp(lsp->pdu),
stream_get_size(circuit->snd_stream));
+#ifndef FABRICD
+ /* send a northbound notification */
+ isis_notif_lsp_too_large(circuit, stream_get_endp(lsp->pdu),
+ rawlspid_print(lsp->hdr.lsp_id));
+#endif /* ifndef FABRICD */
if (isis->debugs & DEBUG_PACKET_DUMP)
zlog_dump_data(STREAM_DATA(lsp->pdu),
stream_get_endp(lsp->pdu));