summaryrefslogtreecommitdiffstats
path: root/ldpd/notification.c
diff options
context:
space:
mode:
authorRenato Westphal <renato@opensourcerouting.org>2017-03-03 21:50:22 +0100
committerRenato Westphal <renato@opensourcerouting.org>2017-03-03 21:50:22 +0100
commit257799cdb69707f7bea43b118c9787458d1d81ba (patch)
treef3ded89e87ac55271d14630c5918ea48116cd4a0 /ldpd/notification.c
parentldpd: implement RFC 6667 (Typed Wildcard FEC for PWid) (diff)
downloadfrr-257799cdb69707f7bea43b118c9787458d1d81ba.tar.xz
frr-257799cdb69707f7bea43b118c9787458d1d81ba.zip
ldpd: implement RFC 5919 (LDP End-of-LIB)
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
Diffstat (limited to 'ldpd/notification.c')
-rw-r--r--ldpd/notification.c40
1 files changed, 28 insertions, 12 deletions
diff --git a/ldpd/notification.c b/ldpd/notification.c
index 69d4ab802..393994ed5 100644
--- a/ldpd/notification.c
+++ b/ldpd/notification.c
@@ -38,16 +38,8 @@ send_notification_full(struct tcp_conn *tcp, struct notify_msg *nm)
size = LDP_HDR_SIZE + LDP_MSG_SIZE + STATUS_SIZE;
if (nm->flags & F_NOTIF_PW_STATUS)
size += PW_STATUS_TLV_SIZE;
- if (nm->flags & F_NOTIF_FEC) {
- size += TLV_HDR_SIZE;
- switch (nm->fec.type) {
- case MAP_TYPE_PWID:
- size += FEC_PWID_ELM_MIN_LEN;
- if (nm->fec.flags & F_MAP_PW_ID)
- size += sizeof(uint32_t);
- break;
- }
- }
+ if (nm->flags & F_NOTIF_FEC)
+ size += len_fec_tlv(&nm->fec);
if (nm->flags & F_NOTIF_RETURNED_TLVS)
size += TLV_HDR_SIZE * 2 + nm->rtlvs.length;
@@ -204,7 +196,9 @@ recv_notification(struct nbr *nbr, char *buf, uint16_t len)
len -= tlv_len;
}
- if (nm.status_code == S_PW_STATUS) {
+ /* sanity checks */
+ switch (nm.status_code) {
+ case S_PW_STATUS:
if (!(nm.flags & (F_NOTIF_PW_STATUS|F_NOTIF_FEC))) {
send_notification(nbr->tcp, S_MISS_MSG,
msg.id, msg.type);
@@ -219,6 +213,21 @@ recv_notification(struct nbr *nbr, char *buf, uint16_t len)
msg.id, msg.type);
return (-1);
}
+ break;
+ case S_ENDOFLIB:
+ if (!(nm.flags & F_NOTIF_FEC)) {
+ send_notification(nbr->tcp, S_MISS_MSG,
+ msg.id, msg.type);
+ return (-1);
+ }
+ if (nm.fec.type != MAP_TYPE_TYPED_WCARD) {
+ send_notification(nbr->tcp, S_BAD_TLV_VAL,
+ msg.id, msg.type);
+ return (-1);
+ }
+ break;
+ default:
+ break;
}
log_msg_notification(0, nbr, &nm);
@@ -231,9 +240,16 @@ recv_notification(struct nbr *nbr, char *buf, uint16_t len)
return (-1);
}
- if (nm.status_code == S_PW_STATUS)
+ /* lde needs to know about a few notification messages */
+ switch (nm.status_code) {
+ case S_PW_STATUS:
+ case S_ENDOFLIB:
ldpe_imsg_compose_lde(IMSG_NOTIFICATION, nbr->peerid, 0,
&nm, sizeof(nm));
+ break;
+ default:
+ break;
+ }
return (0);
}