Index | Thread | Search

From:
Rafael Sadowski <rafael@sizeofvoid.org>
Subject:
relayd: use imsg_compose() instead of handcrafted imsg
To:
tech@openbsd.org
Date:
Wed, 29 Jul 2026 20:16:36 +0200

Download raw body.

Thread
pfe_sync() built a struct imsg by hand and pushed it through
control_imsg_forward(). That API is meant for relaying a *received*
imsg.

Add control_imsg_compose() which walks the notify-enabled control
connections and calls imsg_compose(3) properly. (like
control_imsg_forward).

If anyone has a better idea for a name for control_imsg_compose and
control_imsg_forward, please do let me know!

OK?

diff --git a/control.c b/control.c
index fb64608..56af7b6 100644
--- a/control.c
+++ b/control.c
@@ -400,6 +400,21 @@ control_dispatch_imsg(int fd, short event, void *arg)
 	imsg_event_add(&c->iev);
 }
 
+void
+control_imsg_compose(uint32_t type, void *data, uint16_t len)
+{
+	struct ctl_conn *c;
+
+	TAILQ_FOREACH(c, &ctl_conns, entry) {
+		if (c->flags & CTL_CONN_NOTIFY) {
+			if (imsg_compose(&c->iev.ibuf, type, 0, 0, -1, data,
+			    len) == -1)
+				fatal("%s: imsg_compose", __func__);
+			imsg_event_add(&c->iev);
+		}
+	}
+}
+
 void
 control_imsg_forward(struct imsg *imsg)
 {
diff --git a/pfe.c b/pfe.c
index c66ad06..e9d90df 100644
--- a/pfe.c
+++ b/pfe.c
@@ -715,12 +715,10 @@ pfe_sync(void)
 	struct table		*active;
 	struct table		*table;
 	struct ctl_id		 id;
-	struct imsg		 imsg;
 	struct ctl_demote	 demote;
 	struct router		*rt;
 
 	bzero(&id, sizeof(id));
-	bzero(&imsg, sizeof(imsg));
 	TAILQ_FOREACH(rdr, env->sc_rdrs, entry) {
 		rdr->conf.flags &= ~(F_BACKUP);
 		rdr->conf.flags &= ~(F_DOWN);
@@ -740,12 +738,10 @@ pfe_sync(void)
 			active = rdr->table;
 
 		if (active != NULL && active->conf.flags & F_CHANGED) {
-			id.id = active->conf.id;
-			imsg.hdr.type = IMSG_CTL_TABLE_CHANGED;
-			imsg.hdr.len = sizeof(id) + IMSG_HEADER_SIZE;
-			imsg.data = &id;
 			sync_table(env, rdr, active);
-			control_imsg_forward(&imsg);
+			id.id = active->conf.id;
+			control_imsg_compose(IMSG_CTL_TABLE_CHANGED, &id,
+			    sizeof(id));
 		}
 
 		if (rdr->conf.flags & F_DOWN) {
@@ -754,21 +750,17 @@ pfe_sync(void)
 				log_debug("%s: disabling ruleset", __func__);
 				rdr->conf.flags &= ~(F_ACTIVE_RULESET);
 				id.id = rdr->conf.id;
-				imsg.hdr.type = IMSG_CTL_PULL_RULESET;
-				imsg.hdr.len = sizeof(id) + IMSG_HEADER_SIZE;
-				imsg.data = &id;
 				sync_ruleset(env, rdr, 0);
-				control_imsg_forward(&imsg);
+				control_imsg_compose(IMSG_CTL_PULL_RULESET,
+				    &id, sizeof(id));
 			}
 		} else if (!(rdr->conf.flags & F_ACTIVE_RULESET)) {
 			log_debug("%s: enabling ruleset", __func__);
 			rdr->conf.flags |= F_ACTIVE_RULESET;
 			id.id = rdr->conf.id;
-			imsg.hdr.type = IMSG_CTL_PUSH_RULESET;
-			imsg.hdr.len = sizeof(id) + IMSG_HEADER_SIZE;
-			imsg.data = &id;
 			sync_ruleset(env, rdr, 1);
-			control_imsg_forward(&imsg);
+			control_imsg_compose(IMSG_CTL_PUSH_RULESET, &id,
+			    sizeof(id));
 		}
 	}
 
diff --git a/relayd.h b/relayd.h
index 2aa6eab..07508b5 100644
--- a/relayd.h
+++ b/relayd.h
@@ -1148,6 +1148,7 @@ int		 control_listen(struct control_sock *);
 void		 control_cleanup(struct control_sock *);
 void		 control_dispatch_imsg(int, short, void *);
 void		 control_imsg_forward(struct imsg *);
+void		 control_imsg_compose(uint32_t, void *, uint16_t);
 struct ctl_conn	*control_connbyfd(int);
 
 /* parse.y */