summaryrefslogtreecommitdiff
path: root/usr.sbin/bgpd
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/bgpd')
-rw-r--r--usr.sbin/bgpd/rtr_proto.c48
1 files changed, 45 insertions, 3 deletions
diff --git a/usr.sbin/bgpd/rtr_proto.c b/usr.sbin/bgpd/rtr_proto.c
index f81b143bed6..5b65b167d76 100644
--- a/usr.sbin/bgpd/rtr_proto.c
+++ b/usr.sbin/bgpd/rtr_proto.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtr_proto.c,v 1.26 2024/01/09 14:43:41 claudio Exp $ */
+/* $OpenBSD: rtr_proto.c,v 1.27 2024/01/09 15:13:49 claudio Exp $ */
/*
* Copyright (c) 2020 Claudio Jeker <claudio@openbsd.org>
@@ -122,6 +122,11 @@ struct rtr_endofdata {
uint32_t expire;
} __packed;
+struct rtr_endofdata_v0 {
+ struct rtr_header hdr;
+ uint32_t serial;
+} __packed;
+
enum rtr_event {
RTR_EVNT_START,
RTR_EVNT_CON_OPEN,
@@ -457,8 +462,13 @@ rtr_parse_header(struct rtr_session *rs, struct ibuf *hdr,
goto badlen;
break;
case END_OF_DATA:
- if (len != sizeof(struct rtr_endofdata))
- goto badlen;
+ if (rs->version == 0) {
+ if (len != sizeof(struct rtr_endofdata_v0))
+ goto badlen;
+ } else {
+ if (len != sizeof(struct rtr_endofdata))
+ goto badlen;
+ }
break;
case CACHE_RESET:
if (len != sizeof(struct rtr_reset))
@@ -801,11 +811,43 @@ rtr_parse_aspa(struct rtr_session *rs, struct ibuf *pdu)
}
static int
+rtr_parse_end_of_data_v0(struct rtr_session *rs, struct ibuf *pdu)
+{
+ struct rtr_endofdata_v0 eod;
+
+ if (ibuf_get(pdu, &eod, sizeof(eod)) == -1) {
+ log_warnx("rtr %s: received %s: bad pdu length",
+ log_rtr(rs), log_rtr_type(END_OF_DATA));
+ rtr_send_error(rs, CORRUPT_DATA, "bad length", pdu);
+ return -1;
+ }
+
+ if (rtr_check_session_id(rs, rs->session_id, &eod.hdr, pdu) == -1)
+ return -1;
+
+ if (rs->state != RTR_STATE_EXCHANGE) {
+ log_warnx("rtr %s: received %s: out of context",
+ log_rtr(rs), log_rtr_type(END_OF_DATA));
+ rtr_send_error(rs, CORRUPT_DATA, "out of context", pdu);
+ return -1;
+ }
+
+ rs->serial = ntohl(eod.serial);
+
+ rtr_fsm(rs, RTR_EVNT_END_OF_DATA);
+ return 0;
+}
+
+static int
rtr_parse_end_of_data(struct rtr_session *rs, struct ibuf *pdu)
{
struct rtr_endofdata eod;
uint32_t t;
+ /* version 0 does not have the timing values */
+ if (rs->version == 0)
+ return rtr_parse_end_of_data_v0(rs, pdu);
+
if (ibuf_get(pdu, &eod, sizeof(eod)) == -1) {
log_warnx("rtr %s: received %s: bad pdu length",
log_rtr(rs), log_rtr_type(END_OF_DATA));