diff options
author | Renato Westphal <renato@cvs.openbsd.org> | 2017-03-04 00:06:11 +0000 |
---|---|---|
committer | Renato Westphal <renato@cvs.openbsd.org> | 2017-03-04 00:06:11 +0000 |
commit | 512924baf176079550a3e543d949bc8ab73cf778 (patch) | |
tree | 99ae0fe570c15063f701ef6a06b3d4c5ac7c4f3b | |
parent | f0cbdab642f0c88a7edb19fb0e8cf2a44ee3acee (diff) |
Implement RFC 5561 (LDP Capabilities).
This patch per-se doesn't introduce any useful functionality, but prepares
the ground for new enhancements to ldpd (i.e. implementation of new RFCs
that make use of LDP capabilities).
-rw-r--r-- | usr.sbin/ldpd/init.c | 154 | ||||
-rw-r--r-- | usr.sbin/ldpd/labelmapping.c | 10 | ||||
-rw-r--r-- | usr.sbin/ldpd/ldp.h | 20 | ||||
-rw-r--r-- | usr.sbin/ldpd/ldpd.8 | 15 | ||||
-rw-r--r-- | usr.sbin/ldpd/ldpd.h | 8 | ||||
-rw-r--r-- | usr.sbin/ldpd/ldpe.h | 7 | ||||
-rw-r--r-- | usr.sbin/ldpd/logmsg.c | 6 | ||||
-rw-r--r-- | usr.sbin/ldpd/notification.c | 57 | ||||
-rw-r--r-- | usr.sbin/ldpd/packet.c | 15 |
9 files changed, 262 insertions, 30 deletions
diff --git a/usr.sbin/ldpd/init.c b/usr.sbin/ldpd/init.c index 721a6dfe298..ae1513720f1 100644 --- a/usr.sbin/ldpd/init.c +++ b/usr.sbin/ldpd/init.c @@ -1,4 +1,4 @@ -/* $OpenBSD: init.c,v 1.34 2017/03/03 23:44:35 renato Exp $ */ +/* $OpenBSD: init.c,v 1.35 2017/03/04 00:06:10 renato Exp $ */ /* * Copyright (c) 2009 Michele Marchetto <michele@openbsd.org> @@ -25,6 +25,7 @@ #include "log.h" static int gen_init_prms_tlv(struct ibuf *, struct nbr *); +static int gen_cap_dynamic_tlv(struct ibuf *); void send_init(struct nbr *nbr) @@ -35,15 +36,16 @@ 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; + size = LDP_HDR_SIZE + LDP_MSG_SIZE + SESS_PRMS_SIZE + + CAP_TLV_DYNAMIC_SIZE; if ((buf = ibuf_open(size)) == NULL) fatal(__func__); err |= gen_ldp_hdr(buf, size); size -= LDP_HDR_SIZE; err |= gen_msg_hdr(buf, MSG_TYPE_INIT, size); - size -= LDP_MSG_SIZE; err |= gen_init_prms_tlv(buf, nbr); + err |= gen_cap_dynamic_tlv(buf); if (err) { ibuf_free(buf); return; @@ -58,6 +60,7 @@ recv_init(struct nbr *nbr, char *buf, uint16_t len) struct ldp_msg msg; struct sess_prms_tlv sess; uint16_t max_pdu_len; + int caps_rcvd = 0; log_debug("%s: lsr-id %s", __func__, inet_ntoa(nbr->id)); @@ -94,6 +97,7 @@ recv_init(struct nbr *nbr, char *buf, uint16_t len) /* Optional Parameters */ while (len > 0) { struct tlv tlv; + uint16_t tlv_type; uint16_t tlv_len; if (len < sizeof(tlv)) { @@ -102,6 +106,7 @@ recv_init(struct nbr *nbr, char *buf, uint16_t len) } memcpy(&tlv, buf, TLV_HDR_SIZE); + tlv_type = ntohs(tlv.type); tlv_len = ntohs(tlv.length); if (tlv_len + TLV_HDR_SIZE > len) { session_shutdown(nbr, S_BAD_TLV_LEN, msg.id, msg.type); @@ -110,17 +115,42 @@ recv_init(struct nbr *nbr, char *buf, uint16_t len) buf += TLV_HDR_SIZE; len -= TLV_HDR_SIZE; - switch (ntohs(tlv.type)) { + /* + * RFC 5561 - Section 6: + * "The S-bit of a Capability Parameter in an Initialization + * message MUST be 1 and SHOULD be ignored on receipt". + */ + switch (tlv_type) { case TLV_TYPE_ATMSESSIONPAR: session_shutdown(nbr, S_BAD_TLV_VAL, msg.id, msg.type); return (-1); case TLV_TYPE_FRSESSION: session_shutdown(nbr, S_BAD_TLV_VAL, msg.id, msg.type); return (-1); + case TLV_TYPE_DYNAMIC_CAP: + if (tlv_len != CAP_TLV_DYNAMIC_LEN) { + session_shutdown(nbr, S_BAD_TLV_LEN, msg.id, + msg.type); + return (-1); + } + + if (caps_rcvd & F_CAP_TLV_RCVD_DYNAMIC) { + session_shutdown(nbr, S_BAD_TLV_VAL, msg.id, + msg.type); + return (-1); + } + caps_rcvd |= F_CAP_TLV_RCVD_DYNAMIC; + + nbr->flags |= F_NBR_CAP_DYNAMIC; + + log_debug("%s: lsr-id %s announced the Dynamic " + "Capability Announcement capability", __func__, + inet_ntoa(nbr->id)); + break; default: if (!(ntohs(tlv.type) & UNKNOWN_FLAG)) - send_notification(nbr->tcp, S_UNKNOWN_TLV, - msg.id, msg.type); + send_notification_rtlvs(nbr, S_UNSSUPORTDCAP, + msg.id, msg.type, tlv_type, tlv_len, buf); /* ignore unknown tlv */ break; } @@ -146,6 +176,104 @@ recv_init(struct nbr *nbr, char *buf, uint16_t len) return (0); } +void +send_capability(struct nbr *nbr, uint16_t capability, int enable) +{ + struct ibuf *buf; + uint16_t size; + int err = 0; + + log_debug("%s: lsr-id %s", __func__, inet_ntoa(nbr->id)); + + size = LDP_HDR_SIZE + LDP_MSG_SIZE + CAP_TLV_DYNAMIC_SIZE; + if ((buf = ibuf_open(size)) == NULL) + fatal(__func__); + + err |= gen_ldp_hdr(buf, size); + size -= LDP_HDR_SIZE; + err |= gen_msg_hdr(buf, MSG_TYPE_CAPABILITY, size); + + switch (capability) { + case TLV_TYPE_DYNAMIC_CAP: + /* + * RFC 5561 - Section 9: + * "An LDP speaker MUST NOT include the Dynamic Capability + * Announcement Parameter in Capability messages sent to + * its peers". + */ + /* FALLTHROUGH */ + default: + fatalx("send_capability: unsupported capability"); + } + + if (err) { + ibuf_free(buf); + return; + } + + evbuf_enqueue(&nbr->tcp->wbuf, buf); + nbr_fsm(nbr, NBR_EVT_PDU_SENT); +} + +int +recv_capability(struct nbr *nbr, char *buf, uint16_t len) +{ + struct ldp_msg msg; + + log_debug("%s: lsr-id %s", __func__, inet_ntoa(nbr->id)); + + memcpy(&msg, buf, sizeof(msg)); + buf += LDP_MSG_SIZE; + len -= LDP_MSG_SIZE; + + /* Optional Parameters */ + while (len > 0) { + struct tlv tlv; + uint16_t tlv_type; + uint16_t tlv_len; + + if (len < sizeof(tlv)) { + session_shutdown(nbr, S_BAD_TLV_LEN, msg.id, msg.type); + return (-1); + } + + memcpy(&tlv, buf, TLV_HDR_SIZE); + tlv_type = ntohs(tlv.type); + tlv_len = ntohs(tlv.length); + if (tlv_len + TLV_HDR_SIZE > len) { + session_shutdown(nbr, S_BAD_TLV_LEN, msg.id, msg.type); + return (-1); + } + buf += TLV_HDR_SIZE; + len -= TLV_HDR_SIZE; + + switch (tlv_type) { + case TLV_TYPE_DYNAMIC_CAP: + /* + * RFC 5561 - Section 9: + * "An LDP speaker that receives a Capability message + * from a peer that includes the Dynamic Capability + * Announcement Parameter SHOULD silently ignore the + * parameter and process any other Capability Parameters + * in the message". + */ + /* FALLTHROUGH */ + default: + if (!(ntohs(tlv.type) & UNKNOWN_FLAG)) + send_notification_rtlvs(nbr, S_UNSSUPORTDCAP, + msg.id, msg.type, tlv_type, tlv_len, buf); + /* ignore unknown tlv */ + break; + } + buf += tlv_len; + len -= tlv_len; + } + + nbr_fsm(nbr, NBR_EVT_PDU_RCVD); + + return (0); +} + static int gen_init_prms_tlv(struct ibuf *buf, struct nbr *nbr) { @@ -164,3 +292,17 @@ gen_init_prms_tlv(struct ibuf *buf, struct nbr *nbr) return (ibuf_add(buf, &parms, SESS_PRMS_SIZE)); } + +static int +gen_cap_dynamic_tlv(struct ibuf *buf) +{ + struct capability_tlv cap; + + memset(&cap, 0, sizeof(cap)); + cap.type = htons(TLV_TYPE_DYNAMIC_CAP); + cap.length = htons(CAP_TLV_DYNAMIC_LEN); + /* the S-bit is always 1 for the Dynamic Capability Announcement */ + cap.reserved = STATE_BIT; + + return (ibuf_add(buf, &cap, CAP_TLV_DYNAMIC_SIZE)); +} diff --git a/usr.sbin/ldpd/labelmapping.c b/usr.sbin/ldpd/labelmapping.c index 964cc44286e..580d3072452 100644 --- a/usr.sbin/ldpd/labelmapping.c +++ b/usr.sbin/ldpd/labelmapping.c @@ -1,4 +1,4 @@ -/* $OpenBSD: labelmapping.c,v 1.64 2017/03/03 23:50:45 renato Exp $ */ +/* $OpenBSD: labelmapping.c,v 1.65 2017/03/04 00:06:10 renato Exp $ */ /* * Copyright (c) 2014, 2015 Renato Westphal <renato@openbsd.org> @@ -241,6 +241,7 @@ recv_labelmessage(struct nbr *nbr, char *buf, uint16_t len, uint16_t type) /* Optional Parameters */ while (len > 0) { struct tlv tlv; + uint16_t tlv_type; uint16_t tlv_len; uint32_t reqbuf, labelbuf, statusbuf; @@ -250,6 +251,7 @@ recv_labelmessage(struct nbr *nbr, char *buf, uint16_t len, uint16_t type) } memcpy(&tlv, buf, TLV_HDR_SIZE); + tlv_type = ntohs(tlv.type); tlv_len = ntohs(tlv.length); if (tlv_len + TLV_HDR_SIZE > len) { session_shutdown(nbr, S_BAD_TLV_LEN, msg.id, msg.type); @@ -258,7 +260,7 @@ recv_labelmessage(struct nbr *nbr, char *buf, uint16_t len, uint16_t type) buf += TLV_HDR_SIZE; len -= TLV_HDR_SIZE; - switch (ntohs(tlv.type)) { + switch (tlv_type) { case TLV_TYPE_LABELREQUEST: switch (type) { case MSG_TYPE_LABELMAPPING: @@ -343,8 +345,8 @@ recv_labelmessage(struct nbr *nbr, char *buf, uint16_t len, uint16_t type) break; default: if (!(ntohs(tlv.type) & UNKNOWN_FLAG)) - send_notification(nbr->tcp, S_UNKNOWN_TLV, - msg.id, msg.type); + send_notification_rtlvs(nbr, S_UNKNOWN_TLV, + msg.id, msg.type, tlv_type, tlv_len, buf); /* ignore unknown tlv */ break; } diff --git a/usr.sbin/ldpd/ldp.h b/usr.sbin/ldpd/ldp.h index e8c007a9c08..dd00af9eb76 100644 --- a/usr.sbin/ldpd/ldp.h +++ b/usr.sbin/ldpd/ldp.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ldp.h,v 1.37 2017/03/03 23:56:54 renato Exp $ */ +/* $OpenBSD: ldp.h,v 1.38 2017/03/04 00:06:10 renato Exp $ */ /* * Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org> @@ -65,6 +65,7 @@ #define MSG_TYPE_HELLO 0x0100 #define MSG_TYPE_INIT 0x0200 #define MSG_TYPE_KEEPALIVE 0x0201 +#define MSG_TYPE_CAPABILITY 0x0202 /* RFC 5561 */ #define MSG_TYPE_ADDR 0x0300 #define MSG_TYPE_ADDRWITHDRAW 0x0301 #define MSG_TYPE_LABELMAPPING 0x0400 @@ -97,6 +98,9 @@ #define TLV_TYPE_PW_STATUS 0x896A #define TLV_TYPE_PW_IF_PARAM 0x096B #define TLV_TYPE_PW_GROUP_ID 0x096C +/* RFC 5561 */ +#define TLV_TYPE_RETURNED_TLVS 0x8304 +#define TLV_TYPE_DYNAMIC_CAP 0x8506 /* RFC 7552 */ #define TLV_TYPE_DUALSTACK 0x8701 @@ -198,6 +202,8 @@ struct hello_prms_opt16_tlv { #define S_UNASSIGN_TAI 0x00000029 #define S_MISCONF_ERR 0x0000002A #define S_WITHDRAW_MTHD 0x0000002B +/* RFC 5561 */ +#define S_UNSSUPORTDCAP 0x0000002E /* RFC 7552 */ #define S_TRANS_MISMTCH 0x80000032 #define S_DS_NONCMPLNCE 0x80000033 @@ -229,6 +235,18 @@ struct status_tlv { #define STATUS_TLV_LEN 10 #define STATUS_FATAL 0x80000000 +struct capability_tlv { + uint16_t type; + uint16_t length; + uint8_t reserved; +}; +#define STATE_BIT 0x80 + +#define F_CAP_TLV_RCVD_DYNAMIC 0x01 + +#define CAP_TLV_DYNAMIC_SIZE 5 +#define CAP_TLV_DYNAMIC_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 9382991a2de..c270cba5fbe 100644 --- a/usr.sbin/ldpd/ldpd.8 +++ b/usr.sbin/ldpd/ldpd.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ldpd.8,v 1.17 2017/03/03 23:30:57 renato Exp $ +.\" $OpenBSD: ldpd.8,v 1.18 2017/03/04 00:06:10 renato Exp $ .\" .\" Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org> .\" Copyright (c) 2009 Michele Marchetto <michele@openbsd.org> @@ -16,7 +16,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: March 3 2017 $ +.Dd $Mdocdate: March 4 2017 $ .Dt LDPD 8 .Os .Sh NAME @@ -132,6 +132,17 @@ socket used for communication with .Re .Pp .Rs +.%A B. Thomas +.%A K. Raza +.%A S. Aggarwal +.%A R. Aggarwal +.%A JL. Le Roux +.%D July 2009 +.%R RFC 5561 +.%T LDP Capabilities +.Re +.Pp +.Rs .%A C. Pignataro .%A R. Asati .%D August 2012 diff --git a/usr.sbin/ldpd/ldpd.h b/usr.sbin/ldpd/ldpd.h index f5b2a96cac1..88353d8ddaa 100644 --- a/usr.sbin/ldpd/ldpd.h +++ b/usr.sbin/ldpd/ldpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ldpd.h,v 1.83 2017/03/03 23:36:06 renato Exp $ */ +/* $OpenBSD: ldpd.h,v 1.84 2017/03/04 00:06:10 renato Exp $ */ /* * Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org> @@ -228,10 +228,16 @@ struct notify_msg { uint16_t msg_type; /* network byte order */ uint32_t pw_status; struct map fec; + struct { + uint16_t type; + uint16_t length; + char *data; + } rtlvs; uint8_t flags; }; #define F_NOTIF_PW_STATUS 0x01 /* pseudowire status tlv present */ #define F_NOTIF_FEC 0x02 /* fec tlv present */ +#define F_NOTIF_RETURNED_TLVS 0x04 /* returned tlvs present */ struct if_addr { LIST_ENTRY(if_addr) entry; diff --git a/usr.sbin/ldpd/ldpe.h b/usr.sbin/ldpd/ldpe.h index 25295375119..a298f6e3967 100644 --- a/usr.sbin/ldpd/ldpe.h +++ b/usr.sbin/ldpd/ldpe.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ldpe.h,v 1.71 2017/03/03 23:44:35 renato Exp $ */ +/* $OpenBSD: ldpe.h,v 1.72 2017/03/04 00:06:10 renato Exp $ */ /* * Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org> @@ -104,6 +104,7 @@ struct nbr { int flags; }; #define F_NBR_GTSM_NEGOTIATED 0x01 +#define F_NBR_CAP_DYNAMIC 0x02 RB_HEAD(nbr_id_head, nbr); RB_PROTOTYPE(nbr_id_head, nbr, id_tree, nbr_id_compare) @@ -152,6 +153,8 @@ void recv_hello(struct in_addr, struct ldp_msg *, int, union ldpd_addr *, /* init.c */ void send_init(struct nbr *); int recv_init(struct nbr *, char *, uint16_t); +void send_capability(struct nbr *, uint16_t, int); +int recv_capability(struct nbr *, char *, uint16_t); /* keepalive.c */ void send_keepalive(struct nbr *); @@ -160,6 +163,8 @@ int recv_keepalive(struct nbr *, char *, uint16_t); /* notification.c */ void send_notification_full(struct tcp_conn *, struct notify_msg *); void send_notification(struct tcp_conn *, uint32_t, uint32_t, uint16_t); +void send_notification_rtlvs(struct nbr *, uint32_t, uint32_t, uint16_t, + uint16_t, uint16_t, char *); int recv_notification(struct nbr *, char *, uint16_t); int gen_status_tlv(struct ibuf *, uint32_t, uint32_t, uint16_t); diff --git a/usr.sbin/ldpd/logmsg.c b/usr.sbin/ldpd/logmsg.c index 568533f2dee..e71b6f79c81 100644 --- a/usr.sbin/ldpd/logmsg.c +++ b/usr.sbin/ldpd/logmsg.c @@ -1,4 +1,4 @@ -/* $OpenBSD: logmsg.c,v 1.2 2017/03/04 00:03:04 renato Exp $ */ +/* $OpenBSD: logmsg.c,v 1.3 2017/03/04 00:06:10 renato Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -303,6 +303,8 @@ msg_name(uint16_t msg) return ("initialization"); case MSG_TYPE_KEEPALIVE: return ("keepalive"); + case MSG_TYPE_CAPABILITY: + return ("capability"); case MSG_TYPE_ADDR: return ("address"); case MSG_TYPE_ADDRWITHDRAW: @@ -396,6 +398,8 @@ status_code_name(uint32_t status) return ("Generic Misconfiguration Error"); case S_WITHDRAW_MTHD: return ("Label Withdraw PW Status Method"); + case S_UNSSUPORTDCAP: + return ("Unsupported Capability"); case S_TRANS_MISMTCH: return ("Transport Connection Mismatch"); case S_DS_NONCMPLNCE: diff --git a/usr.sbin/ldpd/notification.c b/usr.sbin/ldpd/notification.c index b8fab3476b5..962a1fea78c 100644 --- a/usr.sbin/ldpd/notification.c +++ b/usr.sbin/ldpd/notification.c @@ -1,4 +1,4 @@ -/* $OpenBSD: notification.c,v 1.44 2017/03/03 23:50:45 renato Exp $ */ +/* $OpenBSD: notification.c,v 1.45 2017/03/04 00:06:10 renato Exp $ */ /* * Copyright (c) 2009 Michele Marchetto <michele@openbsd.org> @@ -25,6 +25,7 @@ #include "log.h" #include "ldpe.h" +static int gen_returned_tlvs(struct ibuf *, uint16_t, uint16_t, char *); static void log_msg_notification(int, struct nbr *, struct notify_msg *); void @@ -48,6 +49,8 @@ send_notification_full(struct tcp_conn *tcp, struct notify_msg *nm) break; } } + if (nm->flags & F_NOTIF_RETURNED_TLVS) + size += TLV_HDR_SIZE * 2 + nm->rtlvs.length; if ((buf = ibuf_open(size)) == NULL) fatal(__func__); @@ -61,6 +64,9 @@ send_notification_full(struct tcp_conn *tcp, struct notify_msg *nm) err |= gen_pw_status_tlv(buf, nm->pw_status); if (nm->flags & F_NOTIF_FEC) err |= gen_fec_tlv(buf, &nm->fec); + if (nm->flags & F_NOTIF_RETURNED_TLVS) + err |= gen_returned_tlvs(buf, nm->rtlvs.type, nm->rtlvs.length, + nm->rtlvs.data); if (err) { ibuf_free(buf); return; @@ -89,6 +95,27 @@ send_notification(struct tcp_conn *tcp, uint32_t status_code, uint32_t msg_id, send_notification_full(tcp, &nm); } +void +send_notification_rtlvs(struct nbr *nbr, uint32_t status_code, uint32_t msg_id, + uint16_t msg_type, uint16_t tlv_type, uint16_t tlv_len, char *tlv_data) +{ + struct notify_msg nm; + + memset(&nm, 0, sizeof(nm)); + nm.status_code = status_code; + nm.msg_id = msg_id; + nm.msg_type = msg_type; + /* do not append the given TLV if it's too big (shouldn't happen) */ + if (tlv_len < 1024) { + nm.rtlvs.type = tlv_type; + nm.rtlvs.length = tlv_len; + nm.rtlvs.data = tlv_data; + nm.flags |= F_NOTIF_RETURNED_TLVS; + } + + send_notification_full(nbr->tcp, &nm); +} + int recv_notification(struct nbr *nbr, char *buf, uint16_t len) { @@ -121,6 +148,7 @@ recv_notification(struct nbr *nbr, char *buf, uint16_t len) /* Optional Parameters */ while (len > 0) { struct tlv tlv; + uint16_t tlv_type; uint16_t tlv_len; if (len < sizeof(tlv)) { @@ -129,6 +157,7 @@ recv_notification(struct nbr *nbr, char *buf, uint16_t len) } memcpy(&tlv, buf, TLV_HDR_SIZE); + tlv_type = ntohs(tlv.type); tlv_len = ntohs(tlv.length); if (tlv_len + TLV_HDR_SIZE > len) { session_shutdown(nbr, S_BAD_TLV_LEN, msg.id, msg.type); @@ -137,7 +166,7 @@ recv_notification(struct nbr *nbr, char *buf, uint16_t len) buf += TLV_HDR_SIZE; len -= TLV_HDR_SIZE; - switch (ntohs(tlv.type)) { + switch (tlv_type) { case TLV_TYPE_EXTSTATUS: case TLV_TYPE_RETURNEDPDU: case TLV_TYPE_RETURNEDMSG: @@ -167,8 +196,8 @@ recv_notification(struct nbr *nbr, char *buf, uint16_t len) break; default: if (!(ntohs(tlv.type) & UNKNOWN_FLAG)) - send_notification(nbr->tcp, S_UNKNOWN_TLV, - msg.id, msg.type); + send_notification_rtlvs(nbr, S_UNKNOWN_TLV, + msg.id, msg.type, tlv_type, tlv_len, buf); /* ignore unknown tlv */ break; } @@ -230,6 +259,26 @@ gen_status_tlv(struct ibuf *buf, uint32_t status_code, uint32_t msg_id, return (ibuf_add(buf, &st, STATUS_SIZE)); } +static int +gen_returned_tlvs(struct ibuf *buf, uint16_t type, uint16_t length, + char *tlv_data) +{ + struct tlv rtlvs; + struct tlv tlv; + int err; + + rtlvs.type = htons(TLV_TYPE_RETURNED_TLVS); + rtlvs.length = htons(length + TLV_HDR_SIZE); + tlv.type = htons(type); + tlv.length = htons(length); + + err = ibuf_add(buf, &rtlvs, sizeof(rtlvs)); + err |= ibuf_add(buf, &tlv, sizeof(tlv)); + err |= ibuf_add(buf, tlv_data, length); + + return (err); +} + void log_msg_notification(int out, struct nbr *nbr, struct notify_msg *nm) { diff --git a/usr.sbin/ldpd/packet.c b/usr.sbin/ldpd/packet.c index cfb9d2265d1..1e03a09bcee 100644 --- a/usr.sbin/ldpd/packet.c +++ b/usr.sbin/ldpd/packet.c @@ -1,4 +1,4 @@ -/* $OpenBSD: packet.c,v 1.69 2017/03/03 23:44:35 renato Exp $ */ +/* $OpenBSD: packet.c,v 1.70 2017/03/04 00:06:10 renato Exp $ */ /* * Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org> @@ -518,13 +518,7 @@ session_read(int fd, short event, void *arg) return; } break; - case MSG_TYPE_ADDR: - case MSG_TYPE_ADDRWITHDRAW: - case MSG_TYPE_LABELMAPPING: - case MSG_TYPE_LABELREQUEST: - case MSG_TYPE_LABELWITHDRAW: - case MSG_TYPE_LABELRELEASE: - case MSG_TYPE_LABELABORTREQ: + default: if (nbr->state != NBR_STA_OPER) { session_shutdown(nbr, S_SHUTDOWN, msg->id, msg->type); @@ -532,8 +526,6 @@ session_read(int fd, short event, void *arg) return; } break; - default: - break; } /* switch LDP packet type */ @@ -547,6 +539,9 @@ session_read(int fd, short event, void *arg) case MSG_TYPE_KEEPALIVE: ret = recv_keepalive(nbr, pdu, msg_size); break; + case MSG_TYPE_CAPABILITY: + ret = recv_capability(nbr, pdu, msg_size); + break; case MSG_TYPE_ADDR: case MSG_TYPE_ADDRWITHDRAW: ret = recv_address(nbr, pdu, msg_size); |