-/* $OpenBSD: bgpd.c,v 1.264 2024/05/15 09:09:38 job Exp $ */
+/* $OpenBSD: bgpd.c,v 1.265 2024/08/12 09:04:23 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
}
free_aspatree(&conf->aspa);
SIMPLEQ_FOREACH(rtr, &conf->rtrs, entry) {
+ struct rtr_config_msg rtrconf = { 0 };
+
+ strlcpy(rtrconf.descr, rtr->descr, sizeof(rtrconf.descr));
+ rtrconf.min_version = rtr->min_version;
if (imsg_compose(ibuf_rtr, IMSG_RECONF_RTR_CONFIG, rtr->id,
- 0, -1, rtr->descr, sizeof(rtr->descr)) == -1)
+ 0, -1, &rtrconf, sizeof(rtrconf)) == -1)
return (-1);
}
-.\" $OpenBSD: bgpd.conf.5,v 1.240 2024/04/24 10:41:34 claudio Exp $
+.\" $OpenBSD: bgpd.conf.5,v 1.241 2024/08/12 09:04:23 claudio Exp $
.\"
.\" Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
.\" Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: April 24 2024 $
+.Dd $Mdocdate: August 12 2024 $
.Dt BGPD.CONF 5
.Os
.Sh NAME
.Em rtr
server.
.Pp
+.Ic min-version Ar number
+Require a minimal RTR version of
+.Ar number .
+To ensure that ASPA records are synchronised over RTR a minimal version
+of 2 is required.
+.Pp
.It Ic port Ar number
Specify the TCP destination port for the
.Em rtr
-/* $OpenBSD: bgpd.h,v 1.493 2024/05/18 11:17:30 jsg Exp $ */
+/* $OpenBSD: bgpd.h,v 1.494 2024/08/12 09:04:23 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
#include <imsg.h>
#define BGP_VERSION 4
+#define RTR_MAX_VERSION 2
+#define RTR_DEFAULT_VERSION 1
#define BGP_PORT 179
#define RTR_PORT 323
#define CONFFILE "/etc/bgpd.conf"
struct bgpd_addr local_addr;
uint32_t id;
uint16_t remote_port;
+ uint8_t min_version;
+};
+
+struct rtr_config_msg {
+ char descr[PEER_DESCR_LEN];
+ uint8_t min_version;
};
struct ctl_show_rtr {
char descr[PEER_DESCR_LEN];
char state[PEER_DESCR_LEN];
+ char last_sent_msg[REASON_LEN];
+ char last_recv_msg[REASON_LEN];
struct bgpd_addr remote_addr;
struct bgpd_addr local_addr;
uint32_t serial;
uint32_t retry;
uint32_t expire;
int session_id;
- uint16_t remote_port;
- uint8_t version;
enum rtr_error last_sent_error;
enum rtr_error last_recv_error;
- char last_sent_msg[REASON_LEN];
- char last_recv_msg[REASON_LEN];
+ uint16_t remote_port;
+ uint8_t version;
+ uint8_t min_version;
};
enum imsg_type {
-/* $OpenBSD: parse.y,v 1.463 2024/05/22 08:41:14 claudio Exp $ */
+/* $OpenBSD: parse.y,v 1.464 2024/08/12 09:04:23 claudio Exp $ */
/*
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
%token AS ROUTERID HOLDTIME YMIN LISTEN ON FIBUPDATE FIBPRIORITY RTABLE
%token NONE UNICAST VPN RD EXPORT EXPORTTRGT IMPORTTRGT DEFAULTROUTE
-%token RDE RIB EVALUATE IGNORE COMPARE RTR PORT
+%token RDE RIB EVALUATE IGNORE COMPARE RTR PORT MINVERSION
%token GROUP NEIGHBOR NETWORK
%token EBGP IBGP
%token FLOWSPEC PROTO FLAGS FRAGMENT TOS LENGTH ICMPTYPE CODE
| PORT port {
currtr->remote_port = $2;
}
+ | MINVERSION NUMBER {
+ if ($2 < 0 || $2 > RTR_MAX_VERSION) {
+ yyerror("min-version must be between %u and %u",
+ 0, RTR_MAX_VERSION);
+ YYERROR;
+ }
+ currtr->min_version = $2;
+ }
;
conf_main : AS as4number {
{ "med", MED},
{ "metric", METRIC},
{ "min", YMIN},
+ { "min-version", MINVERSION},
{ "multihop", MULTIHOP},
{ "neighbor", NEIGHBOR},
{ "neighbor-as", NEIGHBORAS},
-/* $OpenBSD: rtr.c,v 1.21 2024/04/09 12:05:07 claudio Exp $ */
+/* $OpenBSD: rtr.c,v 1.22 2024/08/12 09:04:23 claudio Exp $ */
/*
* Copyright (c) 2020 Claudio Jeker <claudio@openbsd.org>
struct imsg imsg;
struct bgpd_config tconf;
struct roa roa;
- char descr[PEER_DESCR_LEN];
+ struct rtr_config_msg rtrconf;
struct rtr_session *rs;
uint32_t rtrid;
int n, fd;
aspa = NULL;
break;
case IMSG_RECONF_RTR_CONFIG:
- if (imsg_get_data(&imsg, descr, sizeof(descr)) == -1)
+ if (imsg_get_data(&imsg, &rtrconf,
+ sizeof(rtrconf)) == -1)
fatal("imsg_get_data");
rs = rtr_get(rtrid);
if (rs == NULL)
- rtr_new(rtrid, descr);
+ rtr_new(rtrid, &rtrconf);
else
- rtr_config_keep(rs);
+ rtr_config_keep(rs, &rtrconf);
break;
case IMSG_RECONF_DRAIN:
imsg_compose(ibuf_main, IMSG_RECONF_DRAIN, 0, 0,
-/* $OpenBSD: rtr_proto.c,v 1.37 2024/08/09 14:00:48 claudio Exp $ */
+/* $OpenBSD: rtr_proto.c,v 1.38 2024/08/12 09:04:23 claudio Exp $ */
/*
* Copyright (c) 2020 Claudio Jeker <claudio@openbsd.org>
uint32_t length;
} __packed;
-#define RTR_MAX_VERSION 2
#define RTR_MAX_PDU_SIZE 49152 /* XXX < IBUF_READ_SIZE */
#define RTR_MAX_PDU_ERROR_SIZE 256
#define RTR_DEFAULT_REFRESH 3600
char last_recv_msg[REASON_LEN];
uint8_t version;
uint8_t prev_version;
+ uint8_t min_version;
+ uint8_t errored;
+
};
TAILQ_HEAD(, rtr_session) rtrs = TAILQ_HEAD_INITIALIZER(rtrs);
}
};
+static uint8_t
+rtr_max_session_version(struct rtr_session *rs)
+{
+ if (rs->min_version > RTR_DEFAULT_VERSION)
+ return rs->min_version;
+ return RTR_DEFAULT_VERSION;
+}
+
static void
rtr_reset_cache(struct rtr_session *rs)
{
switch (event) {
case RTR_EVNT_UNSUPP_PROTO_VERSION:
- if (rs->prev_version == rs->version) {
+ if (rs->prev_version == rs->version ||
+ rs->version < rs->min_version) {
/*
* Can't downgrade anymore, fail connection.
* RFC requires sending the error with the
* highest supported version number.
*/
- rs->version = RTR_MAX_VERSION;
+ rs->version = rtr_max_session_version(rs);
rtr_send_error(rs, NULL, UNSUPP_PROTOCOL_VERS,
"negotiation failed");
return;
rs->fd = -1;
}
/* try to reopen session */
- timer_set(&rs->timers, Timer_Rtr_Retry,
- arc4random_uniform(10));
+ if (!rs->errored)
+ timer_set(&rs->timers, Timer_Rtr_Retry,
+ arc4random_uniform(10));
+ else
+ timer_set(&rs->timers, Timer_Rtr_Retry, rs->retry);
+
+ rs->errored = 1;
/*
* A close event during version negotiation needs to remain
* in the negotiation state else the same error will happen
rtr_sem_release(rs->active_lock);
rtr_recalc();
rs->active_lock = 0;
+ rs->errored = 0;
/* clear the last errors */
rs->last_sent_error = NO_ERROR;
rs->last_recv_error = NO_ERROR;
}
struct rtr_session *
-rtr_new(uint32_t id, char *descr)
+rtr_new(uint32_t id, struct rtr_config_msg *conf)
{
struct rtr_session *rs;
if ((rs = calloc(1, sizeof(*rs))) == NULL)
- fatal("RTR session %s", descr);
+ fatal("RTR session %s", conf->descr);
RB_INIT(&rs->roa_set);
RB_INIT(&rs->aspa);
TAILQ_INIT(&rs->timers);
msgbuf_init(&rs->w);
- strlcpy(rs->descr, descr, sizeof(rs->descr));
+ strlcpy(rs->descr, conf->descr, sizeof(rs->descr));
rs->id = id;
rs->session_id = -1;
- rs->version = RTR_MAX_VERSION;
- rs->prev_version = RTR_MAX_VERSION;
+ rs->min_version = conf->min_version; /* must be set before version */
+ rs->version = rtr_max_session_version(rs);
+ rs->prev_version = rtr_max_session_version(rs);
rs->refresh = RTR_DEFAULT_REFRESH;
rs->retry = RTR_DEFAULT_RETRY;
rs->expire = RTR_DEFAULT_EXPIRE;
}
if (rs->state == RTR_STATE_CLOSED) {
- rs->version = RTR_MAX_VERSION;
- rs->prev_version = RTR_MAX_VERSION;
+ rs->version = rtr_max_session_version(rs);
+ rs->prev_version = rtr_max_session_version(rs);
}
rs->fd = rs->w.fd = fd;
}
void
-rtr_config_keep(struct rtr_session *rs)
+rtr_config_keep(struct rtr_session *rs, struct rtr_config_msg *conf)
{
+ strlcpy(rs->descr, conf->descr, sizeof(rs->descr));
+ rs->min_version = conf->min_version;
rs->reconf_action = RECONF_KEEP;
}
/* descr, remote_addr, local_addr and remote_port set by parent */
msg.version = rs->version;
+ msg.min_version = rs->min_version;
msg.serial = rs->serial;
msg.refresh = rs->refresh;
msg.retry = rs->retry;
-/* $OpenBSD: session.h,v 1.170 2024/05/18 11:17:30 jsg Exp $ */
+/* $OpenBSD: session.h,v 1.171 2024/08/12 09:04:23 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
size_t rtr_count(void);
void rtr_check_events(struct pollfd *, size_t);
size_t rtr_poll_events(struct pollfd *, size_t, time_t *);
-struct rtr_session *rtr_new(uint32_t, char *);
+struct rtr_session *rtr_new(uint32_t, struct rtr_config_msg *);
struct rtr_session *rtr_get(uint32_t);
void rtr_free(struct rtr_session *);
void rtr_open(struct rtr_session *, int);
void rtr_config_prep(void);
void rtr_config_merge(void);
-void rtr_config_keep(struct rtr_session *);
+void rtr_config_keep(struct rtr_session *,
+ struct rtr_config_msg *);
void rtr_roa_merge(struct roa_tree *);
void rtr_aspa_merge(struct aspa_tree *);
void rtr_shutdown(void);