diff options
author | Renato Westphal <renato@opensourcerouting.org> | 2017-03-03 21:50:22 +0100 |
---|---|---|
committer | Renato Westphal <renato@opensourcerouting.org> | 2017-03-03 21:50:22 +0100 |
commit | 257799cdb69707f7bea43b118c9787458d1d81ba (patch) | |
tree | f3ded89e87ac55271d14630c5918ea48116cd4a0 /ldpd/init.c | |
parent | ldpd: implement RFC 6667 (Typed Wildcard FEC for PWid) (diff) | |
download | frr-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/init.c')
-rw-r--r-- | ldpd/init.c | 67 |
1 files changed, 66 insertions, 1 deletions
diff --git a/ldpd/init.c b/ldpd/init.c index 13104b4ee..bc3a69edc 100644 --- a/ldpd/init.c +++ b/ldpd/init.c @@ -26,6 +26,7 @@ static int gen_init_prms_tlv(struct ibuf *, struct nbr *); static int gen_cap_dynamic_tlv(struct ibuf *); static int gen_cap_twcard_tlv(struct ibuf *, int); +static int gen_cap_unotif_tlv(struct ibuf *, int); void send_init(struct nbr *nbr) @@ -37,7 +38,7 @@ send_init(struct nbr *nbr) debug_msg_send("initialization: lsr-id %s", inet_ntoa(nbr->id)); size = LDP_HDR_SIZE + LDP_MSG_SIZE + SESS_PRMS_SIZE + - CAP_TLV_DYNAMIC_SIZE + CAP_TLV_TWCARD_SIZE; + CAP_TLV_DYNAMIC_SIZE + CAP_TLV_TWCARD_SIZE + CAP_TLV_UNOTIF_SIZE; if ((buf = ibuf_open(size)) == NULL) fatal(__func__); @@ -47,6 +48,7 @@ send_init(struct nbr *nbr) err |= gen_init_prms_tlv(buf, nbr); err |= gen_cap_dynamic_tlv(buf); err |= gen_cap_twcard_tlv(buf, 1); + err |= gen_cap_unotif_tlv(buf, 1); if (err) { ibuf_free(buf); return; @@ -167,6 +169,26 @@ recv_init(struct nbr *nbr, char *buf, uint16_t len) log_debug("%s: lsr-id %s announced the Typed Wildcard " "FEC capability", __func__, inet_ntoa(nbr->id)); break; + case TLV_TYPE_UNOTIF_CAP: + if (tlv_len != CAP_TLV_UNOTIF_LEN) { + session_shutdown(nbr, S_BAD_TLV_LEN, msg.id, + msg.type); + return (-1); + } + + if (caps_rcvd & F_CAP_TLV_RCVD_UNOTIF) { + session_shutdown(nbr, S_BAD_TLV_VAL, msg.id, + msg.type); + return (-1); + } + caps_rcvd |= F_CAP_TLV_RCVD_UNOTIF; + + nbr->flags |= F_NBR_CAP_UNOTIF; + + log_debug("%s: lsr-id %s announced the Unrecognized " + "Notification capability", __func__, + inet_ntoa(nbr->id)); + break; default: if (!(ntohs(tlv.type) & UNKNOWN_FLAG)) send_notification_rtlvs(nbr, S_UNSSUPORTDCAP, @@ -217,6 +239,9 @@ send_capability(struct nbr *nbr, uint16_t capability, int enable) case TLV_TYPE_TWCARD_CAP: err |= gen_cap_twcard_tlv(buf, enable); break; + case TLV_TYPE_UNOTIF_CAP: + err |= gen_cap_unotif_tlv(buf, enable); + break; case TLV_TYPE_DYNAMIC_CAP: /* * RFC 5561 - Section 9: @@ -299,6 +324,32 @@ recv_capability(struct nbr *nbr, char *buf, uint16_t len) "capability", __func__, inet_ntoa(nbr->id), (enable) ? "announced" : "withdrew"); break; + case TLV_TYPE_UNOTIF_CAP: + if (tlv_len != CAP_TLV_UNOTIF_LEN) { + session_shutdown(nbr, S_BAD_TLV_LEN, msg.id, + msg.type); + return (-1); + } + + if (caps_rcvd & F_CAP_TLV_RCVD_UNOTIF) { + session_shutdown(nbr, S_BAD_TLV_VAL, msg.id, + msg.type); + return (-1); + } + caps_rcvd |= F_CAP_TLV_RCVD_UNOTIF; + + memcpy(&reserved, buf, sizeof(reserved)); + enable = reserved & STATE_BIT; + if (enable) + nbr->flags |= F_NBR_CAP_UNOTIF; + else + nbr->flags &= ~F_NBR_CAP_UNOTIF; + + log_debug("%s: lsr-id %s %s the Unrecognized " + "Notification capability", __func__, + inet_ntoa(nbr->id), (enable) ? "announced" : + "withdrew"); + break; case TLV_TYPE_DYNAMIC_CAP: /* * RFC 5561 - Section 9: @@ -371,3 +422,17 @@ gen_cap_twcard_tlv(struct ibuf *buf, int enable) return (ibuf_add(buf, &cap, CAP_TLV_TWCARD_SIZE)); } + +static int +gen_cap_unotif_tlv(struct ibuf *buf, int enable) +{ + struct capability_tlv cap; + + memset(&cap, 0, sizeof(cap)); + cap.type = htons(TLV_TYPE_UNOTIF_CAP); + cap.length = htons(CAP_TLV_UNOTIF_LEN); + if (enable) + cap.reserved = STATE_BIT; + + return (ibuf_add(buf, &cap, CAP_TLV_UNOTIF_SIZE)); +} |