summaryrefslogtreecommitdiffstats
path: root/ldpd/notification.c
diff options
context:
space:
mode:
authorKaren Schoener <karen@voltanet.io>2021-03-15 18:44:12 +0100
committerKaren Schoener <karen@voltanet.io>2021-03-16 15:23:34 +0100
commitd4d6e7d87e6630944cbd5a53620ad4658c8dbf7a (patch)
treeb400f0f6d05659a57b493b4314f3c634d3cdd70e /ldpd/notification.c
parentMerge pull request #8260 from volta-networks/fix_isis_snmp_test (diff)
downloadfrr-d4d6e7d87e6630944cbd5a53620ad4658c8dbf7a.tar.xz
frr-d4d6e7d87e6630944cbd5a53620ad4658c8dbf7a.zip
ldpd: Add support for the read-only snmp mib objects that are statistics
Add support for the read-only snmp mib objects as described in RFC 3815 that are statistics. Signed-off-by: Lynne Morrison <lynne@voltanet.io> Signed-off-by: Karen Schoener <karen@voltanet.io>
Diffstat (limited to 'ldpd/notification.c')
-rw-r--r--ldpd/notification.c79
1 files changed, 76 insertions, 3 deletions
diff --git a/ldpd/notification.c b/ldpd/notification.c
index f84e0f893..3ecf5d4ba 100644
--- a/ldpd/notification.c
+++ b/ldpd/notification.c
@@ -69,6 +69,36 @@ send_notification_full(struct tcp_conn *tcp, struct notify_msg *nm)
tcp->nbr->stats.notif_sent++;
}
+ /* update SNMP session counters */
+ switch (nm->status_code) {
+ case S_NO_HELLO:
+ leconf->stats.session_rejects_hello++;
+ break;
+ case S_BAD_LDP_ID:
+ leconf->stats.bad_ldp_id++;
+ break;
+ case S_BAD_PDU_LEN:
+ leconf->stats.bad_pdu_len++;
+ break;
+ case S_BAD_MSG_LEN:
+ leconf->stats.bad_msg_len++;
+ break;
+ case S_BAD_TLV_LEN:
+ leconf->stats.bad_tlv_len++;
+ break;
+ case S_BAD_TLV_VAL:
+ leconf->stats.malformed_tlv++;
+ break;
+ case S_KEEPALIVE_TMR:
+ leconf->stats.keepalive_timer_exp++;
+ break;
+ case S_SHUTDOWN:
+ leconf->stats.shutdown_send_notify++;
+ break;
+ default:
+ break;
+ }
+
evbuf_enqueue(&tcp->wbuf, buf);
}
@@ -122,6 +152,7 @@ recv_notification(struct nbr *nbr, char *buf, uint16_t len)
if (len < STATUS_SIZE) {
session_shutdown(nbr, S_BAD_MSG_LEN, msg.id, msg.type);
+ leconf->stats.bad_msg_len++;
return (-1);
}
memcpy(&st, buf, sizeof(st));
@@ -129,6 +160,7 @@ recv_notification(struct nbr *nbr, char *buf, uint16_t len)
if (ntohs(st.length) > STATUS_SIZE - TLV_HDR_SIZE ||
ntohs(st.length) > len - TLV_HDR_SIZE) {
session_shutdown(nbr, S_BAD_TLV_LEN, msg.id, msg.type);
+ leconf->stats.bad_tlv_len++;
return (-1);
}
buf += STATUS_SIZE;
@@ -145,6 +177,7 @@ recv_notification(struct nbr *nbr, char *buf, uint16_t len)
if (len < sizeof(tlv)) {
session_shutdown(nbr, S_BAD_TLV_LEN, msg.id, msg.type);
+ leconf->stats.bad_tlv_len++;
return (-1);
}
@@ -153,6 +186,7 @@ recv_notification(struct nbr *nbr, char *buf, uint16_t len)
tlv_len = ntohs(tlv.length);
if (tlv_len + TLV_HDR_SIZE > len) {
session_shutdown(nbr, S_BAD_TLV_LEN, msg.id, msg.type);
+ leconf->stats.bad_tlv_len++;
return (-1);
}
buf += TLV_HDR_SIZE;
@@ -182,14 +216,17 @@ recv_notification(struct nbr *nbr, char *buf, uint16_t len)
if (tlen != tlv_len) {
session_shutdown(nbr, S_BAD_TLV_VAL,
msg.id, msg.type);
+ leconf->stats.bad_tlv_len++;
return (-1);
}
nm.flags |= F_NOTIF_FEC;
break;
default:
- if (!(ntohs(tlv.type) & UNKNOWN_FLAG))
+ if (!(ntohs(tlv.type) & UNKNOWN_FLAG)) {
+ nbr->stats.unknown_tlv++;
send_notification_rtlvs(nbr, S_UNKNOWN_TLV,
msg.id, msg.type, tlv_type, tlv_len, buf);
+ }
/* ignore unknown tlv */
break;
}
@@ -243,21 +280,57 @@ recv_notification(struct nbr *nbr, char *buf, uint16_t len)
* initialization, it SHOULD transmit a Shutdown message and
* then close the transport connection".
*/
- if (nbr->state != NBR_STA_OPER && nm.status_code == S_SHUTDOWN)
+ if (nbr->state != NBR_STA_OPER &&
+ nm.status_code == S_SHUTDOWN) {
+ leconf->stats.session_attempts++;
send_notification(nbr->tcp, S_SHUTDOWN,
msg.id, msg.type);
+ }
+ leconf->stats.shutdown_rcv_notify++;
nbr_fsm(nbr, NBR_EVT_CLOSE_SESSION);
return (-1);
}
- /* lde needs to know about a few notification messages */
+ /* lde needs to know about a few notification messages
+ * and update SNMP session counters
+ */
switch (nm.status_code) {
case S_PW_STATUS:
case S_ENDOFLIB:
ldpe_imsg_compose_lde(IMSG_NOTIFICATION, nbr->peerid, 0,
&nm, sizeof(nm));
break;
+ case S_NO_HELLO:
+ leconf->stats.session_rejects_hello++;
+ break;
+ case S_PARM_ADV_MODE:
+ leconf->stats.session_rejects_ad++;
+ break;
+ case S_MAX_PDU_LEN:
+ leconf->stats.session_rejects_max_pdu++;
+ break;
+ case S_PARM_L_RANGE:
+ leconf->stats.session_rejects_lr++;
+ break;
+ case S_BAD_LDP_ID:
+ leconf->stats.bad_ldp_id++;
+ break;
+ case S_BAD_PDU_LEN:
+ leconf->stats.bad_pdu_len++;
+ break;
+ case S_BAD_MSG_LEN:
+ leconf->stats.bad_msg_len++;
+ break;
+ case S_BAD_TLV_LEN:
+ leconf->stats.bad_tlv_len++;
+ break;
+ case S_BAD_TLV_VAL:
+ leconf->stats.malformed_tlv++;
+ break;
+ case S_SHUTDOWN:
+ leconf->stats.shutdown_rcv_notify++;
+ break;
default:
break;
}