1
0
mirror of https://github.com/openbsd/src.git synced 2024-12-22 16:42:56 -08:00

Adjust bgpd to the new msgbuf API

The tricky bit here is the fact that the peer wbuf needs to be allocated
and freed in the right places (when a peer is setup and when it is freed).
During lifetime we just flush the msgbuf with msgbuf_clear().
mrt has a similar issue. I think that freeing the msgbuf in mrt_clean is right.

OK tb@
This commit is contained in:
claudio 2024-11-21 13:29:52 +00:00
parent 3bba10cf94
commit 05453d673c
7 changed files with 66 additions and 57 deletions

View File

@ -1,4 +1,4 @@
/* $OpenBSD: bgpd.h,v 1.499 2024/11/21 13:28:34 claudio Exp $ */
/* $OpenBSD: bgpd.h,v 1.500 2024/11/21 13:29:52 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@ -1395,8 +1395,8 @@ enum mrt_state {
struct mrt {
char rib[PEER_DESCR_LEN];
struct msgbuf wbuf;
LIST_ENTRY(mrt) entry;
struct msgbuf *wbuf;
uint32_t peer_id;
uint32_t group_id;
int fd;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: control.c,v 1.127 2024/11/21 13:22:21 claudio Exp $ */
/* $OpenBSD: control.c,v 1.128 2024/11/21 13:29:52 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@ -568,7 +568,7 @@ control_imsg_relay(struct imsg *imsg, struct peer *p)
peer.stats.prefix_sent_eor = stats.prefix_sent_eor;
peer.stats.pending_update = stats.pending_update;
peer.stats.pending_withdraw = stats.pending_withdraw;
peer.stats.msg_queue_len = msgbuf_queuelen(&p->wbuf);
peer.stats.msg_queue_len = msgbuf_queuelen(p->wbuf);
return imsg_compose(&c->imsgbuf, type, 0, pid, -1,
&peer, sizeof(peer));

View File

@ -1,4 +1,4 @@
/* $OpenBSD: mrt.c,v 1.120 2024/11/21 13:28:34 claudio Exp $ */
/* $OpenBSD: mrt.c,v 1.121 2024/11/21 13:29:52 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
@ -192,7 +192,7 @@ mrt_dump_bgp_msg(struct mrt *mrt, void *pkg, uint16_t pkglen,
if (ibuf_add(buf, pkg, pkglen) == -1)
goto fail;
ibuf_close(&mrt->wbuf, buf);
ibuf_close(mrt->wbuf, buf);
return;
fail:
@ -219,7 +219,7 @@ mrt_dump_state(struct mrt *mrt, uint16_t old_state, uint16_t new_state,
if (ibuf_add_n16(buf, new_state) == -1)
goto fail;
ibuf_close(&mrt->wbuf, buf);
ibuf_close(mrt->wbuf, buf);
return;
fail:
@ -515,9 +515,9 @@ mrt_dump_entry_mp(struct mrt *mrt, struct prefix *p, uint16_t snum,
len) == -1)
goto fail;
ibuf_close(&mrt->wbuf, hbuf);
ibuf_close(&mrt->wbuf, h2buf);
ibuf_close(&mrt->wbuf, buf);
ibuf_close(mrt->wbuf, hbuf);
ibuf_close(mrt->wbuf, h2buf);
ibuf_close(mrt->wbuf, buf);
return (len + MRT_HEADER_SIZE);
@ -608,8 +608,8 @@ mrt_dump_entry(struct mrt *mrt, struct prefix *p, uint16_t snum,
if (ibuf_add_n16(hbuf, len) == -1)
goto fail;
ibuf_close(&mrt->wbuf, hbuf);
ibuf_close(&mrt->wbuf, buf);
ibuf_close(mrt->wbuf, hbuf);
ibuf_close(mrt->wbuf, buf);
return (len + MRT_HEADER_SIZE);
@ -755,8 +755,8 @@ mrt_dump_entry_v2(struct mrt *mrt, struct rib_entry *re, uint32_t snum)
if (ibuf_add_n16(hbuf, nump) == -1)
goto fail;
ibuf_close(&mrt->wbuf, hbuf);
ibuf_close(&mrt->wbuf, nbuf);
ibuf_close(mrt->wbuf, hbuf);
ibuf_close(mrt->wbuf, nbuf);
hbuf = NULL;
nbuf = NULL;
}
@ -774,8 +774,8 @@ mrt_dump_entry_v2(struct mrt *mrt, struct rib_entry *re, uint32_t snum)
if (ibuf_add_n16(hbuf, apnump) == -1)
goto fail;
ibuf_close(&mrt->wbuf, hbuf);
ibuf_close(&mrt->wbuf, apbuf);
ibuf_close(mrt->wbuf, hbuf);
ibuf_close(mrt->wbuf, apbuf);
hbuf = NULL;
apbuf = NULL;
}
@ -851,8 +851,8 @@ mrt_dump_v2_hdr(struct mrt *mrt, struct bgpd_config *conf)
MRT_DUMP_V2_PEER_INDEX_TABLE, len) == -1)
goto fail;
ibuf_close(&mrt->wbuf, hbuf);
ibuf_close(&mrt->wbuf, buf);
ibuf_close(mrt->wbuf, hbuf);
ibuf_close(mrt->wbuf, buf);
return (0);
fail:
@ -1110,7 +1110,7 @@ fail:
void
mrt_write(struct mrt *mrt)
{
if (ibuf_write(mrt->fd, &mrt->wbuf) == -1) {
if (ibuf_write(mrt->fd, mrt->wbuf) == -1) {
log_warn("mrt dump aborted, mrt_write");
mrt_clean(mrt);
mrt_done(mrt);
@ -1121,7 +1121,8 @@ void
mrt_clean(struct mrt *mrt)
{
close(mrt->fd);
msgbuf_clear(&mrt->wbuf);
msgbuf_free(mrt->wbuf);
mrt->wbuf = NULL;
}
static struct imsgbuf *mrt_imsgbuf[2];

View File

@ -1,4 +1,4 @@
/* $OpenBSD: rde.c,v 1.638 2024/11/21 13:28:34 claudio Exp $ */
/* $OpenBSD: rde.c,v 1.639 2024/11/21 13:29:52 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@ -245,12 +245,12 @@ rde_main(int debug, int verbose)
if (i >= pfd_elms)
fatalx("poll pfd too small");
if (msgbuf_queuelen(&mctx->mrt.wbuf) > 0) {
if (msgbuf_queuelen(mctx->mrt.wbuf) > 0) {
pfd[i].fd = mctx->mrt.fd;
pfd[i].events = POLLOUT;
i++;
} else if (mctx->mrt.state == MRT_STATE_REMOVE) {
close(mctx->mrt.fd);
mrt_clean(&mctx->mrt);
LIST_REMOVE(mctx, entry);
free(mctx);
rde_mrt_cnt--;
@ -344,8 +344,7 @@ rde_main(int debug, int verbose)
free(ibuf_main);
while ((mctx = LIST_FIRST(&rde_mrts)) != NULL) {
msgbuf_clear(&mctx->mrt.wbuf);
close(mctx->mrt.fd);
mrt_clean(&mctx->mrt);
LIST_REMOVE(mctx, entry);
free(mctx);
}
@ -3193,7 +3192,7 @@ rde_mrt_throttled(void *arg)
{
struct mrt *mrt = arg;
return (msgbuf_queuelen(&mrt->wbuf) > SESS_MSG_LOW_MARK);
return (msgbuf_queuelen(mrt->wbuf) > SESS_MSG_LOW_MARK);
}
static void
@ -3213,7 +3212,11 @@ rde_dump_mrt_new(struct mrt *mrt, pid_t pid, int fd)
return;
}
memcpy(&ctx->mrt, mrt, sizeof(struct mrt));
msgbuf_init(&ctx->mrt.wbuf);
if ((ctx->mrt.wbuf = msgbuf_new()) == NULL) {
log_warn("rde_dump_mrt_new");
free(ctx);
return;
}
ctx->mrt.fd = fd;
ctx->mrt.state = MRT_STATE_RUNNING;
rid = rib_find(ctx->mrt.rib);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: rtr_proto.c,v 1.44 2024/11/21 13:28:34 claudio Exp $ */
/* $OpenBSD: rtr_proto.c,v 1.45 2024/11/21 13:29:52 claudio Exp $ */
/*
* Copyright (c) 2020 Claudio Jeker <claudio@openbsd.org>
@ -190,7 +190,7 @@ struct rtr_session {
struct roa_tree roa_set;
struct aspa_tree aspa;
struct buf_read r;
struct msgbuf w;
struct msgbuf *w;
struct timer_head timers;
uint32_t id; /* rtr_config id */
uint32_t serial;
@ -360,7 +360,7 @@ rtr_send_error(struct rtr_session *rs, struct ibuf *pdu, enum rtr_error err,
goto fail;
if (ibuf_add(buf, rs->last_sent_msg, mlen) == -1)
goto fail;
ibuf_close(&rs->w, buf);
ibuf_close(rs->w, buf);
rtr_fsm(rs, RTR_EVNT_SEND_ERROR);
return;
@ -378,7 +378,7 @@ rtr_send_reset_query(struct rtr_session *rs)
buf = rtr_newmsg(rs, RESET_QUERY, 0, 0);
if (buf == NULL)
goto fail;
ibuf_close(&rs->w, buf);
ibuf_close(rs->w, buf);
return;
fail:
@ -397,7 +397,7 @@ rtr_send_serial_query(struct rtr_session *rs)
goto fail;
if (ibuf_add_n32(buf, rs->serial) == -1)
goto fail;
ibuf_close(&rs->w, buf);
ibuf_close(rs->w, buf);
return;
fail:
@ -1126,7 +1126,7 @@ rtr_fsm(struct rtr_session *rs, enum rtr_event event)
case RTR_EVNT_CON_CLOSE:
if (rs->fd != -1) {
/* flush buffers */
msgbuf_clear(&rs->w);
msgbuf_clear(rs->w);
rs->r.wpos = 0;
close(rs->fd);
rs->fd = -1;
@ -1271,14 +1271,14 @@ rtr_dispatch_msg(struct pollfd *pfd, struct rtr_session *rs)
rtr_fsm(rs, RTR_EVNT_CON_CLOSE);
return;
}
if (pfd->revents & POLLOUT && msgbuf_queuelen(&rs->w) > 0) {
if (ibuf_write(rs->fd, &rs->w) == -1) {
if (pfd->revents & POLLOUT && msgbuf_queuelen(rs->w) > 0) {
if (ibuf_write(rs->fd, rs->w) == -1) {
log_warn("rtr %s: write error", log_rtr(rs));
rtr_fsm(rs, RTR_EVNT_CON_CLOSE);
return;
}
if (rs->state == RTR_STATE_ERROR &&
msgbuf_queuelen(&rs->w) == 0)
msgbuf_queuelen(rs->w) == 0)
rtr_fsm(rs, RTR_EVNT_CON_CLOSE);
}
if (pfd->revents & POLLIN) {
@ -1384,7 +1384,7 @@ rtr_poll_events(struct pollfd *pfds, size_t npfds, time_t *timeout)
pfd->fd = rs->fd;
pfd->events = 0;
if (msgbuf_queuelen(&rs->w) > 0)
if (msgbuf_queuelen(rs->w) > 0)
pfd->events |= POLLOUT;
if (rs->state >= RTR_STATE_ESTABLISHED)
pfd->events |= POLLIN;
@ -1400,11 +1400,12 @@ rtr_new(uint32_t id, struct rtr_config_msg *conf)
if ((rs = calloc(1, sizeof(*rs))) == NULL)
fatal("RTR session %s", conf->descr);
if ((rs->w = msgbuf_new()) == NULL)
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, conf->descr, sizeof(rs->descr));
rs->id = id;
@ -1451,6 +1452,7 @@ rtr_free(struct rtr_session *rs)
rtr_reset_cache(rs);
rtr_fsm(rs, RTR_EVNT_CON_CLOSE);
timer_remove_all(&rs->timers);
msgbuf_free(rs->w);
free(rs);
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: session.c,v 1.492 2024/11/21 13:28:34 claudio Exp $ */
/* $OpenBSD: session.c,v 1.493 2024/11/21 13:29:52 claudio Exp $ */
/*
* Copyright (c) 2003, 2004, 2005 Henning Brauer <henning@openbsd.org>
@ -274,6 +274,7 @@ session_main(int debug, int verbose)
NULL);
timer_remove_all(&p->timers);
tcp_md5_del_listener(conf, p);
msgbuf_free(p->wbuf);
RB_REMOVE(peer_head, &conf->peers, p);
log_peer_warnx(&p->conf, "removed");
free(p);
@ -305,7 +306,7 @@ session_main(int debug, int verbose)
free(m);
continue;
}
if (msgbuf_queuelen(&m->wbuf) > 0)
if (msgbuf_queuelen(m->wbuf) > 0)
mrt_cnt++;
}
@ -415,7 +416,7 @@ session_main(int debug, int verbose)
/* are we waiting for a write? */
events = POLLIN;
if (msgbuf_queuelen(&p->wbuf) > 0 ||
if (msgbuf_queuelen(p->wbuf) > 0 ||
p->state == STATE_CONNECT)
events |= POLLOUT;
/* is there still work to do? */
@ -434,7 +435,7 @@ session_main(int debug, int verbose)
idx_peers = i;
LIST_FOREACH(m, &mrthead, entry)
if (msgbuf_queuelen(&m->wbuf) > 0) {
if (msgbuf_queuelen(m->wbuf) > 0) {
pfd[i].fd = m->fd;
pfd[i].events = POLLOUT;
mrt_l[i - idx_peers] = m;
@ -565,6 +566,10 @@ init_peer(struct peer *p)
{
TAILQ_INIT(&p->timers);
p->fd = -1;
if (p->wbuf != NULL)
fatal("%s: msgbuf already set", __func__);
if ((p->wbuf = msgbuf_new()) == NULL)
fatal(NULL);
if (p->conf.if_depend[0])
imsg_compose(ibuf_main, IMSG_SESSION_DEPENDON, 0, 0, -1,
@ -611,9 +616,6 @@ bgp_fsm(struct peer *peer, enum session_events event)
if (peer->rbuf == NULL)
fatal(NULL);
/* init write buffer */
msgbuf_init(&peer->wbuf);
if (!peer->depend_ok)
timer_stop(&peer->timers, Timer_ConnectRetry);
else if (peer->passive || peer->conf.passive ||
@ -886,8 +888,8 @@ change_state(struct peer *peer, enum session_state state,
* don't bother if it fails
*/
if (peer->state >= STATE_OPENSENT &&
msgbuf_queuelen(&peer->wbuf) > 0)
ibuf_write(peer->fd, &peer->wbuf);
msgbuf_queuelen(peer->wbuf) > 0)
ibuf_write(peer->fd, peer->wbuf);
/*
* we must start the timer for the next EVNT_START
@ -905,7 +907,7 @@ change_state(struct peer *peer, enum session_state state,
timer_stop(&peer->timers, Timer_IdleHold);
timer_stop(&peer->timers, Timer_IdleHoldReset);
session_close_connection(peer);
msgbuf_clear(&peer->wbuf);
msgbuf_clear(peer->wbuf);
free(peer->rbuf);
peer->rbuf = NULL;
peer->rpending = 0;
@ -952,7 +954,7 @@ change_state(struct peer *peer, enum session_state state,
timer_stop(&peer->timers, Timer_IdleHold);
timer_stop(&peer->timers, Timer_IdleHoldReset);
session_close_connection(peer);
msgbuf_clear(&peer->wbuf);
msgbuf_clear(peer->wbuf);
memset(&peer->capa.peer, 0, sizeof(peer->capa.peer));
}
break;
@ -1425,8 +1427,8 @@ session_sendmsg(struct bgp_msg *msg, struct peer *p)
msg->type);
}
ibuf_close(&p->wbuf, msg->buf);
if (!p->throttled && msgbuf_queuelen(&p->wbuf) > SESS_MSG_HIGH_MARK) {
ibuf_close(p->wbuf, msg->buf);
if (!p->throttled && msgbuf_queuelen(p->wbuf) > SESS_MSG_HIGH_MARK) {
if (imsg_rde(IMSG_XOFF, p->conf.id, NULL, 0) == -1)
log_peer_warn(&p->conf, "imsg_compose XOFF");
else
@ -1933,8 +1935,8 @@ session_dispatch_msg(struct pollfd *pfd, struct peer *p)
return (1);
}
if (pfd->revents & POLLOUT && msgbuf_queuelen(&p->wbuf) > 0) {
if (ibuf_write(p->fd, &p->wbuf) == -1) {
if (pfd->revents & POLLOUT && msgbuf_queuelen(p->wbuf) > 0) {
if (ibuf_write(p->fd, p->wbuf) == -1) {
if (errno == EPIPE)
log_peer_warnx(&p->conf, "Connection closed");
else
@ -1945,7 +1947,7 @@ session_dispatch_msg(struct pollfd *pfd, struct peer *p)
p->stats.last_write = getmonotime();
start_timer_sendholdtime(p);
if (p->throttled &&
msgbuf_queuelen(&p->wbuf) < SESS_MSG_LOW_MARK) {
msgbuf_queuelen(p->wbuf) < SESS_MSG_LOW_MARK) {
if (imsg_rde(IMSG_XON, p->conf.id, NULL, 0) == -1)
log_peer_warn(&p->conf, "imsg_compose XON");
else
@ -3164,7 +3166,8 @@ session_dispatch_imsg(struct imsgbuf *imsgbuf, int idx, u_int *listener_cnt)
if (mrt == NULL)
fatal("session_dispatch_imsg");
memcpy(mrt, &xmrt, sizeof(struct mrt));
msgbuf_init(&mrt->wbuf);
if ((mrt->wbuf = msgbuf_new()) == NULL)
fatal("session_dispatch_imsg");
LIST_INSERT_HEAD(&mrthead, mrt, entry);
} else {
/* old dump reopened */

View File

@ -1,4 +1,4 @@
/* $OpenBSD: session.h,v 1.175 2024/11/21 13:27:40 claudio Exp $ */
/* $OpenBSD: session.h,v 1.176 2024/11/21 13:29:52 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@ -218,7 +218,7 @@ struct peer {
struct bgpd_addr local_alt;
struct bgpd_addr remote;
struct timer_head timers;
struct msgbuf wbuf;
struct msgbuf *wbuf;
struct buf_read *rbuf;
struct peer *template;
int fd;