summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/ldpd/init.c69
-rw-r--r--usr.sbin/ldpd/labelmapping.c74
-rw-r--r--usr.sbin/ldpd/lde.c42
-rw-r--r--usr.sbin/ldpd/lde.h5
-rw-r--r--usr.sbin/ldpd/lde_lib.c45
-rw-r--r--usr.sbin/ldpd/ldp.h10
-rw-r--r--usr.sbin/ldpd/ldpd.812
-rw-r--r--usr.sbin/ldpd/ldpe.h4
-rw-r--r--usr.sbin/ldpd/logmsg.c4
-rw-r--r--usr.sbin/ldpd/neighbor.c3
-rw-r--r--usr.sbin/ldpd/notification.c42
11 files changed, 256 insertions, 54 deletions
diff --git a/usr.sbin/ldpd/init.c b/usr.sbin/ldpd/init.c
index 6905c906530..a19d1daa87d 100644
--- a/usr.sbin/ldpd/init.c
+++ b/usr.sbin/ldpd/init.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: init.c,v 1.36 2017/03/04 00:09:17 renato Exp $ */
+/* $OpenBSD: init.c,v 1.37 2017/03/04 00:15:35 renato Exp $ */
/*
* Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
@@ -27,6 +27,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)
@@ -38,7 +39,7 @@ send_init(struct nbr *nbr)
log_debug("%s: lsr-id %s", __func__, 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__);
@@ -48,6 +49,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;
@@ -168,6 +170,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,
@@ -218,6 +240,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:
@@ -300,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:
@@ -372,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));
+}
diff --git a/usr.sbin/ldpd/labelmapping.c b/usr.sbin/ldpd/labelmapping.c
index 17b2db940f8..cfafb4366c0 100644
--- a/usr.sbin/ldpd/labelmapping.c
+++ b/usr.sbin/ldpd/labelmapping.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: labelmapping.c,v 1.67 2017/03/04 00:12:25 renato Exp $ */
+/* $OpenBSD: labelmapping.c,v 1.68 2017/03/04 00:15:35 renato Exp $ */
/*
* Copyright (c) 2014, 2015 Renato Westphal <renato@openbsd.org>
@@ -75,36 +75,8 @@ send_labelmessage(struct nbr *nbr, uint16_t type, struct mapping_head *mh)
}
/* calculate size */
- msg_size = LDP_MSG_SIZE + TLV_HDR_SIZE;
- switch (me->map.type) {
- case MAP_TYPE_WILDCARD:
- msg_size += FEC_ELM_WCARD_LEN;
- break;
- case MAP_TYPE_PREFIX:
- msg_size += FEC_ELM_PREFIX_MIN_LEN +
- PREFIX_SIZE(me->map.fec.prefix.prefixlen);
- break;
- case MAP_TYPE_PWID:
- msg_size += FEC_PWID_ELM_MIN_LEN;
- if (me->map.flags & F_MAP_PW_ID)
- msg_size += PW_STATUS_TLV_LEN;
- if (me->map.flags & F_MAP_PW_IFMTU)
- msg_size += FEC_SUBTLV_IFMTU_SIZE;
- if (me->map.flags & F_MAP_PW_STATUS)
- msg_size += PW_STATUS_TLV_SIZE;
- break;
- case MAP_TYPE_TYPED_WCARD:
- msg_size += FEC_ELM_TWCARD_MIN_LEN;
- switch (me->map.fec.twcard.type) {
- case MAP_TYPE_PREFIX:
- case MAP_TYPE_PWID:
- msg_size += sizeof(uint16_t);
- break;
- default:
- fatalx("send_labelmessage: unexpected fec type");
- }
- break;
- }
+ msg_size = LDP_MSG_SIZE;
+ msg_size += len_fec_tlv(&me->map);
if (me->map.label != NO_LABEL)
msg_size += LABEL_TLV_SIZE;
if (me->map.flags & F_MAP_REQ_ID)
@@ -551,6 +523,46 @@ gen_pw_status_tlv(struct ibuf *buf, uint32_t status)
return (ibuf_add(buf, &st, sizeof(st)));
}
+uint16_t
+len_fec_tlv(struct map *map)
+{
+ uint16_t len = TLV_HDR_SIZE;
+
+ switch (map->type) {
+ case MAP_TYPE_WILDCARD:
+ len += FEC_ELM_WCARD_LEN;
+ break;
+ case MAP_TYPE_PREFIX:
+ len += FEC_ELM_PREFIX_MIN_LEN +
+ PREFIX_SIZE(map->fec.prefix.prefixlen);
+ break;
+ case MAP_TYPE_PWID:
+ len += FEC_PWID_ELM_MIN_LEN;
+ if (map->flags & F_MAP_PW_ID)
+ len += PW_STATUS_TLV_LEN;
+ if (map->flags & F_MAP_PW_IFMTU)
+ len += FEC_SUBTLV_IFMTU_SIZE;
+ if (map->flags & F_MAP_PW_STATUS)
+ len += PW_STATUS_TLV_SIZE;
+ break;
+ case MAP_TYPE_TYPED_WCARD:
+ len += FEC_ELM_TWCARD_MIN_LEN;
+ switch (map->fec.twcard.type) {
+ case MAP_TYPE_PREFIX:
+ case MAP_TYPE_PWID:
+ len += sizeof(uint16_t);
+ break;
+ default:
+ fatalx("len_fec_tlv: unexpected fec type");
+ }
+ break;
+ default:
+ fatalx("len_fec_tlv: unexpected fec type");
+ }
+
+ return (len);
+}
+
int
gen_fec_tlv(struct ibuf *buf, struct map *map)
{
diff --git a/usr.sbin/ldpd/lde.c b/usr.sbin/ldpd/lde.c
index 2ce30c9e5c0..e6b45719700 100644
--- a/usr.sbin/ldpd/lde.c
+++ b/usr.sbin/ldpd/lde.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: lde.c,v 1.72 2017/03/04 00:12:26 renato Exp $ */
+/* $OpenBSD: lde.c,v 1.73 2017/03/04 00:15:35 renato Exp $ */
/*
* Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
@@ -313,6 +313,13 @@ lde_dispatch_imsg(int fd, short event, void *bula)
case S_PW_STATUS:
l2vpn_recv_pw_status(ln, &nm);
break;
+ case S_ENDOFLIB:
+ /*
+ * Do nothing for now. Should be useful in
+ * the future when we implement LDP-IGP
+ * Synchronization (RFC 5443) and Graceful
+ * Restart (RFC 3478).
+ */
default:
break;
}
@@ -990,6 +997,38 @@ lde_send_notification(struct lde_nbr *ln, uint32_t status_code, uint32_t msg_id,
&nm, sizeof(nm));
}
+void
+lde_send_notification_eol_prefix(struct lde_nbr *ln, int af)
+{
+ struct notify_msg nm;
+
+ memset(&nm, 0, sizeof(nm));
+ nm.status_code = S_ENDOFLIB;
+ nm.fec.type = MAP_TYPE_TYPED_WCARD;
+ nm.fec.fec.twcard.type = MAP_TYPE_PREFIX;
+ nm.fec.fec.twcard.u.prefix_af = af;
+ nm.flags |= F_NOTIF_FEC;
+
+ lde_imsg_compose_ldpe(IMSG_NOTIFICATION_SEND, ln->peerid, 0,
+ &nm, sizeof(nm));
+}
+
+void
+lde_send_notification_eol_pwid(struct lde_nbr *ln, uint16_t pw_type)
+{
+ struct notify_msg nm;
+
+ memset(&nm, 0, sizeof(nm));
+ nm.status_code = S_ENDOFLIB;
+ nm.fec.type = MAP_TYPE_TYPED_WCARD;
+ nm.fec.fec.twcard.type = MAP_TYPE_PWID;
+ nm.fec.fec.twcard.u.pw_type = pw_type;
+ nm.flags |= F_NOTIF_FEC;
+
+ lde_imsg_compose_ldpe(IMSG_NOTIFICATION_SEND, ln->peerid, 0,
+ &nm, sizeof(nm));
+}
+
static __inline int
lde_nbr_compare(struct lde_nbr *a, struct lde_nbr *b)
{
@@ -1007,6 +1046,7 @@ lde_nbr_new(uint32_t peerid, struct lde_nbr *new)
ln->id = new->id;
ln->v4_enabled = new->v4_enabled;
ln->v6_enabled = new->v6_enabled;
+ ln->flags = new->flags;
ln->peerid = peerid;
fec_init(&ln->recv_map);
fec_init(&ln->sent_map);
diff --git a/usr.sbin/ldpd/lde.h b/usr.sbin/ldpd/lde.h
index 785236ef372..ec76293560f 100644
--- a/usr.sbin/ldpd/lde.h
+++ b/usr.sbin/ldpd/lde.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: lde.h,v 1.48 2017/03/04 00:12:26 renato Exp $ */
+/* $OpenBSD: lde.h,v 1.49 2017/03/04 00:15:35 renato Exp $ */
/*
* Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
@@ -87,6 +87,7 @@ struct lde_nbr {
struct in_addr id;
int v4_enabled; /* announce/process v4 msgs */
int v6_enabled; /* announce/process v6 msgs */
+ int flags; /* capabilities */
struct fec_tree recv_req;
struct fec_tree sent_req;
struct fec_tree recv_map;
@@ -146,6 +147,8 @@ void lde_send_labelrelease(struct lde_nbr *, struct fec_node *,
struct map *, uint32_t);
void lde_send_notification(struct lde_nbr *, uint32_t, uint32_t,
uint16_t);
+void lde_send_notification_eol_prefix(struct lde_nbr *, int);
+void lde_send_notification_eol_pwid(struct lde_nbr *, uint16_t);
struct lde_nbr *lde_nbr_find_by_lsrid(struct in_addr);
struct lde_nbr *lde_nbr_find_by_addr(int, union ldpd_addr *);
struct lde_map *lde_map_add(struct lde_nbr *, struct fec_node *, int);
diff --git a/usr.sbin/ldpd/lde_lib.c b/usr.sbin/ldpd/lde_lib.c
index 254f71bd896..5b58205eee9 100644
--- a/usr.sbin/ldpd/lde_lib.c
+++ b/usr.sbin/ldpd/lde_lib.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: lde_lib.c,v 1.68 2017/03/04 00:12:26 renato Exp $ */
+/* $OpenBSD: lde_lib.c,v 1.69 2017/03/04 00:15:35 renato Exp $ */
/*
* Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
@@ -26,6 +26,7 @@
#include "ldpd.h"
#include "lde.h"
+#include "ldpe.h"
#include "log.h"
static __inline int fec_compare(struct fec *, struct fec *);
@@ -215,6 +216,22 @@ fec_snap(struct lde_nbr *ln)
}
lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END, ln->peerid, 0, NULL, 0);
+
+ /*
+ * RFC 5919 - Section 4:
+ * "An LDP speaker that conforms to this specification SHOULD signal
+ * completion of its label advertisements to a peer by means of a
+ * Notification message, if its peer has advertised the Unrecognized
+ * Notification capability during session establishment. The LDP
+ * speaker SHOULD send the Notification message (per Forwarding
+ * Equivalence Class (FEC) Type) to a peer even if the LDP speaker has
+ * zero Label bindings to advertise to that peer".
+ */
+ if (ln->flags & F_NBR_CAP_UNOTIF) {
+ lde_send_notification_eol_prefix(ln, AF_INET);
+ lde_send_notification_eol_prefix(ln, AF_INET6);
+ lde_send_notification_eol_pwid(ln, PW_TYPE_WILDCARD);
+ }
}
static void
@@ -612,6 +629,32 @@ lde_check_request_wcard(struct map *map, struct lde_nbr *ln)
/* LRq.9: perform LSR label distribution */
lde_send_labelmapping(ln, fn, 1);
}
+
+ /*
+ * RFC 5919 - Section 5.3:
+ * "When an LDP speaker receives a Label Request message for a Typed
+ * Wildcard FEC (e.g., a particular FEC Element Type) from a peer, the
+ * LDP speaker determines the set of bindings (as per any local
+ * filtering policy) to advertise to the peer for the FEC type specified
+ * by the request. Assuming the peer had advertised the Unrecognized
+ * Notification capability at session initialization time, the speaker
+ * should send the peer an End-of-LIB Notification for the FEC type when
+ * it completes advertisement of the permitted bindings".
+ */
+ if (ln->flags & F_NBR_CAP_UNOTIF) {
+ switch (map->fec.twcard.type) {
+ case MAP_TYPE_PREFIX:
+ lde_send_notification_eol_prefix(ln,
+ map->fec.twcard.u.prefix_af);
+ break;
+ case MAP_TYPE_PWID:
+ lde_send_notification_eol_pwid(ln,
+ map->fec.twcard.u.pw_type);
+ break;
+ default:
+ break;
+ }
+ }
}
void
diff --git a/usr.sbin/ldpd/ldp.h b/usr.sbin/ldpd/ldp.h
index 1ce18242fa4..ef6374c7f9a 100644
--- a/usr.sbin/ldpd/ldp.h
+++ b/usr.sbin/ldpd/ldp.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ldp.h,v 1.40 2017/03/04 00:12:26 renato Exp $ */
+/* $OpenBSD: ldp.h,v 1.41 2017/03/04 00:15:35 renato Exp $ */
/*
* Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
@@ -103,6 +103,8 @@
#define TLV_TYPE_DYNAMIC_CAP 0x8506
/* RFC 5918 */
#define TLV_TYPE_TWCARD_CAP 0x850B
+/* RFC 5919 */
+#define TLV_TYPE_UNOTIF_CAP 0x8603
/* RFC 7552 */
#define TLV_TYPE_DUALSTACK 0x8701
@@ -206,6 +208,8 @@ struct hello_prms_opt16_tlv {
#define S_WITHDRAW_MTHD 0x0000002B
/* RFC 5561 */
#define S_UNSSUPORTDCAP 0x0000002E
+/* RFC 5919 */
+#define S_ENDOFLIB 0x0000002F
/* RFC 7552 */
#define S_TRANS_MISMTCH 0x80000032
#define S_DS_NONCMPLNCE 0x80000033
@@ -246,6 +250,7 @@ struct capability_tlv {
#define F_CAP_TLV_RCVD_DYNAMIC 0x01
#define F_CAP_TLV_RCVD_TWCARD 0x02
+#define F_CAP_TLV_RCVD_UNOTIF 0x04
#define CAP_TLV_DYNAMIC_SIZE 5
#define CAP_TLV_DYNAMIC_LEN 1
@@ -253,6 +258,9 @@ struct capability_tlv {
#define CAP_TLV_TWCARD_SIZE 5
#define CAP_TLV_TWCARD_LEN 1
+#define CAP_TLV_UNOTIF_SIZE 5
+#define CAP_TLV_UNOTIF_LEN 1
+
#define AF_IPV4 0x1
#define AF_IPV6 0x2
diff --git a/usr.sbin/ldpd/ldpd.8 b/usr.sbin/ldpd/ldpd.8
index 87e5535ec2f..de74fcfa553 100644
--- a/usr.sbin/ldpd/ldpd.8
+++ b/usr.sbin/ldpd/ldpd.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ldpd.8,v 1.20 2017/03/04 00:12:26 renato Exp $
+.\" $OpenBSD: ldpd.8,v 1.21 2017/03/04 00:15:35 renato Exp $
.\"
.\" Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
.\" Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
@@ -152,6 +152,16 @@ socket used for communication with
.Re
.Pp
.Rs
+.%A R. Asati
+.%A P. Mohapatra
+.%A E. Chen
+.%A B. Thomas
+.%D August 2010
+.%R RFC 5919
+.%T Signaling LDP Label Advertisement Completion
+.Re
+.Pp
+.Rs
.%A K. Raza
.%A S. Boutros
.%A C. Pignataro
diff --git a/usr.sbin/ldpd/ldpe.h b/usr.sbin/ldpd/ldpe.h
index 10dd050c7e6..cc9882d6c22 100644
--- a/usr.sbin/ldpd/ldpe.h
+++ b/usr.sbin/ldpd/ldpe.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ldpe.h,v 1.73 2017/03/04 00:09:17 renato Exp $ */
+/* $OpenBSD: ldpe.h,v 1.74 2017/03/04 00:15:35 renato Exp $ */
/*
* Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
@@ -106,6 +106,7 @@ struct nbr {
#define F_NBR_GTSM_NEGOTIATED 0x01
#define F_NBR_CAP_DYNAMIC 0x02
#define F_NBR_CAP_TWCARD 0x04
+#define F_NBR_CAP_UNOTIF 0x08
RB_HEAD(nbr_id_head, nbr);
RB_PROTOTYPE(nbr_id_head, nbr, id_tree, nbr_id_compare)
@@ -179,6 +180,7 @@ int recv_address(struct nbr *, char *, uint16_t);
void send_labelmessage(struct nbr *, uint16_t, struct mapping_head *);
int recv_labelmessage(struct nbr *, char *, uint16_t, uint16_t);
int gen_pw_status_tlv(struct ibuf *, uint32_t);
+uint16_t len_fec_tlv(struct map *);
int gen_fec_tlv(struct ibuf *, struct map *);
int tlv_decode_fec_elm(struct nbr *, struct ldp_msg *, char *,
uint16_t, struct map *);
diff --git a/usr.sbin/ldpd/logmsg.c b/usr.sbin/ldpd/logmsg.c
index 539d875993c..b8a75369726 100644
--- a/usr.sbin/ldpd/logmsg.c
+++ b/usr.sbin/ldpd/logmsg.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: logmsg.c,v 1.5 2017/03/04 00:12:26 renato Exp $ */
+/* $OpenBSD: logmsg.c,v 1.6 2017/03/04 00:15:35 renato Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -423,6 +423,8 @@ status_code_name(uint32_t status)
return ("Label Withdraw PW Status Method");
case S_UNSSUPORTDCAP:
return ("Unsupported Capability");
+ case S_ENDOFLIB:
+ return ("End-of-LIB");
case S_TRANS_MISMTCH:
return ("Transport Connection Mismatch");
case S_DS_NONCMPLNCE:
diff --git a/usr.sbin/ldpd/neighbor.c b/usr.sbin/ldpd/neighbor.c
index 361cf5660e2..37d7260fcfb 100644
--- a/usr.sbin/ldpd/neighbor.c
+++ b/usr.sbin/ldpd/neighbor.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: neighbor.c,v 1.78 2016/09/03 16:07:08 renato Exp $ */
+/* $OpenBSD: neighbor.c,v 1.79 2017/03/04 00:15:35 renato Exp $ */
/*
* Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
@@ -740,6 +740,7 @@ nbr_act_session_operational(struct nbr *nbr)
lde_nbr.id = nbr->id;
lde_nbr.v4_enabled = nbr->v4_enabled;
lde_nbr.v6_enabled = nbr->v6_enabled;
+ lde_nbr.flags = nbr->flags;
return (ldpe_imsg_compose_lde(IMSG_NEIGHBOR_UP, nbr->peerid, 0,
&lde_nbr, sizeof(lde_nbr)));
}
diff --git a/usr.sbin/ldpd/notification.c b/usr.sbin/ldpd/notification.c
index 962a1fea78c..afda48f8416 100644
--- a/usr.sbin/ldpd/notification.c
+++ b/usr.sbin/ldpd/notification.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: notification.c,v 1.45 2017/03/04 00:06:10 renato Exp $ */
+/* $OpenBSD: notification.c,v 1.46 2017/03/04 00:15:35 renato Exp $ */
/*
* Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
@@ -39,16 +39,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;
@@ -205,7 +197,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);
@@ -220,6 +214,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);
@@ -232,9 +241,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);
}