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)
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__);
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;
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,
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:
evbuf_enqueue(&nbr->tcp->wbuf, buf);
nbr_fsm(nbr, NBR_EVT_PDU_SENT);
+ nbr->stats.capability_sent++;
}
int
"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:
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));
+}