]> git.proxmox.com Git - mirror_frr.git/blobdiff - ldpd/init.c
Merge pull request #5681 from opensourcerouting/manpage-rename
[mirror_frr.git] / ldpd / init.c
index 13104b4ee608257c675f173c5cf855b4b93db784..8b2abe85e596f7f91926e56672fdceb97a71d45b 100644 (file)
@@ -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:
@@ -236,6 +261,7 @@ send_capability(struct nbr *nbr, uint16_t capability, int enable)
 
        evbuf_enqueue(&nbr->tcp->wbuf, buf);
        nbr_fsm(nbr, NBR_EVT_PDU_SENT);
+       nbr->stats.capability_sent++;
 }
 
 int
@@ -299,6 +325,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 +423,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));
+}