In IMSG_CTL_SHOW_NEIGHBOR a struct peer is sent from the SE to the RDE to
fill out 10 values. This is a waste of IO, struct peer is over 1000 bytes
large. Instead just pass the peerid to the RDE, let the rde send back a
stats object and have the control code do the merge.
Introduce struct rde_peer_stats to hold all these values and adjust the
code accordingly.

This should improve calls like bgpctl show and bgpctl metrics.
-- 
:wq Claudio

Index: bgpd.h
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v
retrieving revision 1.460
diff -u -p -r1.460 bgpd.h
--- bgpd.h      24 Jan 2023 14:13:11 -0000      1.460
+++ bgpd.h      8 Feb 2023 17:36:34 -0000
@@ -480,6 +480,19 @@ struct peer_config {
 #define PEERFLAG_EVALUATE_ALL  0x04
 #define PEERFLAG_NO_AS_SET     0x08
 
+struct rde_peer_stats {
+       uint64_t                         prefix_rcvd_update;
+       uint64_t                         prefix_rcvd_withdraw;
+       uint64_t                         prefix_rcvd_eor;
+       uint64_t                         prefix_sent_update;
+       uint64_t                         prefix_sent_withdraw;
+       uint64_t                         prefix_sent_eor;
+       uint32_t                         prefix_cnt;
+       uint32_t                         prefix_out_cnt;
+       uint32_t                         pending_update;
+       uint32_t                         pending_withdraw;
+};
+
 enum network_type {
        NETWORK_DEFAULT,        /* from network statements */
        NETWORK_STATIC,
@@ -1301,7 +1314,7 @@ void               set_pollfd(struct pollfd *, struc
 int             handle_pollfd(struct pollfd *, struct imsgbuf *);
 
 /* control.c */
-int    control_imsg_relay(struct imsg *);
+int    control_imsg_relay(struct imsg *, struct peer *);
 
 /* config.c */
 struct bgpd_config     *new_config(void);
Index: control.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/control.c,v
retrieving revision 1.108
diff -u -p -r1.108 control.c
--- control.c   17 Aug 2022 15:15:26 -0000      1.108
+++ control.c   8 Feb 2023 17:36:19 -0000
@@ -219,7 +219,7 @@ int
 control_close(struct ctl_conn *c)
 {
        if (c->terminate && c->ibuf.pid)
-               imsg_ctl_rde(IMSG_CTL_TERMINATE, c->ibuf.pid, NULL, 0);
+               imsg_ctl_rde(IMSG_CTL_TERMINATE, c->ibuf.pid, 0, NULL, 0);
 
        msgbuf_clear(&c->ibuf.w);
        TAILQ_REMOVE(&ctl_conns, c, entry);
@@ -250,7 +250,8 @@ control_dispatch_msg(struct pollfd *pfd,
                if (msgbuf_write(&c->ibuf.w) <= 0 && errno != EAGAIN)
                        return control_close(c);
                if (c->throttled && c->ibuf.w.queued < CTL_MSG_LOW_MARK) {
-                       if (imsg_ctl_rde(IMSG_XON, c->ibuf.pid, NULL, 0) != -1)
+                       if (imsg_ctl_rde(IMSG_XON, c->ibuf.pid, 0, NULL, 0) !=
+                           -1)
                                c->throttled = 0;
                }
        }
@@ -324,8 +325,7 @@ control_dispatch_msg(struct pollfd *pfd,
                                matched = 1;
                                if (!neighbor || !neighbor->show_timers) {
                                        imsg_ctl_rde(imsg.hdr.type,
-                                           imsg.hdr.pid,
-                                           p, sizeof(struct peer));
+                                           imsg.hdr.pid, p->conf.id, NULL, 0);
                                } else {
                                        u_int                    i;
                                        time_t                   d;
@@ -349,7 +349,7 @@ control_dispatch_msg(struct pollfd *pfd,
                        if (!matched && RB_EMPTY(peers)) {
                                control_result(c, CTL_RES_NOSUCHPEER);
                        } else if (!neighbor || !neighbor->show_timers) {
-                               imsg_ctl_rde(IMSG_CTL_END, imsg.hdr.pid,
+                               imsg_ctl_rde(IMSG_CTL_END, imsg.hdr.pid, 0,
                                    NULL, 0);
                        } else {
                                imsg_compose(&c->ibuf, IMSG_CTL_END, 0, 0, -1,
@@ -494,7 +494,7 @@ control_dispatch_msg(struct pollfd *pfd,
                        c->ibuf.pid = imsg.hdr.pid;
                        c->terminate = 1;
 
-                       imsg_ctl_rde(imsg.hdr.type, imsg.hdr.pid,
+                       imsg_ctl_rde(imsg.hdr.type, imsg.hdr.pid, 0,
                            imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE);
                        break;
                case IMSG_CTL_SHOW_NETWORK:
@@ -503,7 +503,7 @@ control_dispatch_msg(struct pollfd *pfd,
                case IMSG_CTL_SHOW_RIB_MEM:
                case IMSG_CTL_SHOW_SET:
                        c->ibuf.pid = imsg.hdr.pid;
-                       imsg_ctl_rde(imsg.hdr.type, imsg.hdr.pid,
+                       imsg_ctl_rde(imsg.hdr.type, imsg.hdr.pid, 0,
                            imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE);
                        break;
                case IMSG_NETWORK_ADD:
@@ -513,7 +513,7 @@ control_dispatch_msg(struct pollfd *pfd,
                case IMSG_NETWORK_FLUSH:
                case IMSG_NETWORK_DONE:
                case IMSG_FILTER_SET:
-                       imsg_ctl_rde(imsg.hdr.type, 0,
+                       imsg_ctl_rde(imsg.hdr.type, 0, 0,
                            imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE);
                        break;
                case IMSG_CTL_LOG_VERBOSE:
@@ -524,7 +524,7 @@ control_dispatch_msg(struct pollfd *pfd,
                        /* forward to other processes */
                        imsg_ctl_parent(imsg.hdr.type, 0, imsg.hdr.pid,
                            imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE);
-                       imsg_ctl_rde(imsg.hdr.type, 0,
+                       imsg_ctl_rde(imsg.hdr.type, 0, 0,
                            imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE);
 
                        memcpy(&verbose, imsg.data, sizeof(verbose));
@@ -540,19 +540,47 @@ control_dispatch_msg(struct pollfd *pfd,
 }
 
 int
-control_imsg_relay(struct imsg *imsg)
+control_imsg_relay(struct imsg *imsg, struct peer *p)
 {
        struct ctl_conn *c;
 
        if ((c = control_connbypid(imsg->hdr.pid)) == NULL)
                return (0);
 
+       /* special handling for peers since only the stats are sent from RDE */
+       if (imsg->hdr.type == IMSG_CTL_SHOW_NEIGHBOR) {
+               struct rde_peer_stats stats;
+
+               if (imsg->hdr.len > IMSG_HEADER_SIZE + sizeof(stats)) {
+                       log_warnx("wrong imsg len");
+                       return (0);
+               }
+               if (p == NULL) {
+                       log_warnx("no such peer: id=%u", imsg->hdr.peerid);
+                       return (0);
+               }
+               memcpy(&stats, imsg->data, sizeof(stats));
+               p->stats.prefix_cnt = stats.prefix_cnt;
+               p->stats.prefix_out_cnt = stats.prefix_out_cnt;
+               p->stats.prefix_rcvd_update = stats.prefix_rcvd_update;
+               p->stats.prefix_rcvd_withdraw = stats.prefix_rcvd_withdraw;
+               p->stats.prefix_rcvd_eor = stats.prefix_rcvd_eor;
+               p->stats.prefix_sent_update = stats.prefix_sent_update;
+               p->stats.prefix_sent_withdraw = stats.prefix_sent_withdraw;
+               p->stats.prefix_sent_eor = stats.prefix_sent_eor;
+               p->stats.pending_update = stats.pending_update;
+               p->stats.pending_withdraw = stats.pending_withdraw;
+
+               return (imsg_compose(&c->ibuf, imsg->hdr.type, 0,
+                   imsg->hdr.pid, -1, p, sizeof(*p)));
+       }
+
        /* if command finished no need to send exit message */
        if (imsg->hdr.type == IMSG_CTL_END || imsg->hdr.type == IMSG_CTL_RESULT)
                c->terminate = 0;
 
        if (!c->throttled && c->ibuf.w.queued > CTL_MSG_HIGH_MARK) {
-               if (imsg_ctl_rde(IMSG_XOFF, imsg->hdr.pid, NULL, 0) != -1)
+               if (imsg_ctl_rde(IMSG_XOFF, imsg->hdr.pid, 0, NULL, 0) != -1)
                        c->throttled = 1;
        }
 
Index: rde.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v
retrieving revision 1.591
diff -u -p -r1.591 rde.c
--- rde.c       24 Jan 2023 14:13:12 -0000      1.591
+++ rde.c       8 Feb 2023 17:40:32 -0000
@@ -34,8 +34,8 @@
 #include <unistd.h>
 
 #include "bgpd.h"
-#include "rde.h"
 #include "session.h"
+#include "rde.h"
 #include "log.h"
 
 #define PFD_PIPE_MAIN          0
@@ -359,7 +359,7 @@ void
 rde_dispatch_imsg_session(struct imsgbuf *ibuf)
 {
        struct imsg              imsg;
-       struct peer              p;
+       struct rde_peer_stats    stats;
        struct ctl_show_set      cset;
        struct ctl_show_rib      csr;
        struct ctl_show_rib_request     req;
@@ -601,33 +601,18 @@ badnetdel:
                        rde_dump_ctx_new(&req, imsg.hdr.pid, imsg.hdr.type);
                        break;
                case IMSG_CTL_SHOW_NEIGHBOR:
-                       if (imsg.hdr.len - IMSG_HEADER_SIZE !=
-                           sizeof(struct peer)) {
+                       if (imsg.hdr.len - IMSG_HEADER_SIZE != 0) {
                                log_warnx("rde_dispatch: wrong imsg len");
                                break;
                        }
-                       memcpy(&p, imsg.data, sizeof(struct peer));
-                       peer = peer_get(p.conf.id);
-                       if (peer != NULL) {
-                               p.stats.prefix_cnt = peer->prefix_cnt;
-                               p.stats.prefix_out_cnt = peer->prefix_out_cnt;
-                               p.stats.prefix_rcvd_update =
-                                   peer->prefix_rcvd_update;
-                               p.stats.prefix_rcvd_withdraw =
-                                   peer->prefix_rcvd_withdraw;
-                               p.stats.prefix_rcvd_eor =
-                                   peer->prefix_rcvd_eor;
-                               p.stats.prefix_sent_update =
-                                   peer->prefix_sent_update;
-                               p.stats.prefix_sent_withdraw =
-                                   peer->prefix_sent_withdraw;
-                               p.stats.prefix_sent_eor =
-                                   peer->prefix_sent_eor;
-                               p.stats.pending_update = peer->up_nlricnt;
-                               p.stats.pending_withdraw = peer->up_wcnt;
-                       }
-                       imsg_compose(ibuf_se_ctl, IMSG_CTL_SHOW_NEIGHBOR, 0,
-                           imsg.hdr.pid, -1, &p, sizeof(struct peer));
+                       peer = peer_get(imsg.hdr.peerid);
+                       if (peer != NULL)
+                               memcpy(&stats, &peer->stats, sizeof(stats));
+                       else
+                               memset(&stats, 0, sizeof(stats));
+                       imsg_compose(ibuf_se_ctl, IMSG_CTL_SHOW_NEIGHBOR,
+                           imsg.hdr.peerid, imsg.hdr.pid, -1,
+                           &stats, sizeof(stats));
                        break;
                case IMSG_CTL_SHOW_RIB_MEM:
                        imsg_compose(ibuf_se_ctl, IMSG_CTL_SHOW_RIB_MEM, 0,
@@ -1739,7 +1724,7 @@ rde_update_update(struct rde_peer *peer,
        uint8_t                  roa_state, aspa_state;
        const char              *wmsg = "filtered, withdraw";
 
-       peer->prefix_rcvd_update++;
+       peer->stats.prefix_rcvd_update++;
 
        roa_state = rde_roa_validity(&rde_roa, prefix, prefixlen,
            aspath_origin(in->aspath.aspath));
@@ -1750,12 +1735,13 @@ rde_update_update(struct rde_peer *peer,
        /* add original path to the Adj-RIB-In */
        if (prefix_update(rib_byid(RIB_ADJ_IN), peer, path_id, path_id_tx,
            in, prefix, prefixlen) == 1)
-               peer->prefix_cnt++;
+               peer->stats.prefix_cnt++;
 
        /* max prefix checker */
-       if (peer->conf.max_prefix && peer->prefix_cnt > peer->conf.max_prefix) {
+       if (peer->conf.max_prefix &&
+           peer->stats.prefix_cnt > peer->conf.max_prefix) {
                log_peer_warnx(&peer->conf, "prefix limit reached (>%u/%u)",
-                   peer->prefix_cnt, peer->conf.max_prefix);
+                   peer->stats.prefix_cnt, peer->conf.max_prefix);
                rde_update_err(peer, ERR_CEASE, ERR_CEASE_MAX_PREFIX, NULL, 0);
                return (-1);
        }
@@ -1807,9 +1793,9 @@ rde_update_withdraw(struct rde_peer *pee
        /* remove original path form the Adj-RIB-In */
        if (prefix_withdraw(rib_byid(RIB_ADJ_IN), peer, path_id,
            prefix, prefixlen))
-               peer->prefix_cnt--;
+               peer->stats.prefix_cnt--;
 
-       peer->prefix_rcvd_withdraw++;
+       peer->stats.prefix_rcvd_withdraw++;
 }
 
 /*
@@ -4151,7 +4137,7 @@ rde_decisionflags(void)
 static void
 rde_peer_recv_eor(struct rde_peer *peer, uint8_t aid)
 {
-       peer->prefix_rcvd_eor++;
+       peer->stats.prefix_rcvd_eor++;
        peer->recv_eor |= 1 << aid;
 
        /*
@@ -4176,7 +4162,7 @@ rde_peer_send_eor(struct rde_peer *peer,
        uint16_t        afi;
        uint8_t         safi;
 
-       peer->prefix_sent_eor++;
+       peer->stats.prefix_sent_eor++;
        peer->sent_eor |= 1 << aid;
 
        if (aid == AID_INET) {
@@ -4320,7 +4306,7 @@ network_add(struct network_config *nc, s
        path_id_tx = pathid_assign(peerself, 0, &nc->prefix, nc->prefixlen);
        if (prefix_update(rib_byid(RIB_ADJ_IN), peerself, 0, path_id_tx,
            state, &nc->prefix, nc->prefixlen) == 1)
-               peerself->prefix_cnt++;
+               peerself->stats.prefix_cnt++;
        for (i = RIB_LOC_START; i < rib_size; i++) {
                struct rib *rib = rib_byid(i);
                if (rib == NULL)
@@ -4395,7 +4381,7 @@ network_delete(struct network_config *nc
        }
        if (prefix_withdraw(rib_byid(RIB_ADJ_IN), peerself, 0, &nc->prefix,
            nc->prefixlen))
-               peerself->prefix_cnt--;
+               peerself->stats.prefix_cnt--;
 }
 
 static void
@@ -4457,7 +4443,7 @@ network_flush_upcall(struct rib_entry *r
 
        if (prefix_withdraw(rib_byid(RIB_ADJ_IN), peerself, 0, &addr,
            prefixlen) == 1)
-               peerself->prefix_cnt--;
+               peerself->stats.prefix_cnt--;
 }
 
 /* clean up */
Index: rde.h
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde.h,v
retrieving revision 1.281
diff -u -p -r1.281 rde.h
--- rde.h       24 Jan 2023 11:28:41 -0000      1.281
+++ rde.h       7 Feb 2023 10:00:56 -0000
@@ -79,6 +79,7 @@ struct rde_peer {
        RB_ENTRY(rde_peer)               entry;
        SIMPLEQ_HEAD(, iq)               imsg_queue;
        struct peer_config               conf;
+       struct rde_peer_stats            stats;
        struct bgpd_addr                 remote_addr;
        struct bgpd_addr                 local_v4_addr;
        struct bgpd_addr                 local_v6_addr;
@@ -88,17 +89,7 @@ struct rde_peer {
        struct prefix_tree               updates[AID_MAX];
        struct prefix_tree               withdraws[AID_MAX];
        time_t                           staletime[AID_MAX];
-       uint64_t                         prefix_rcvd_update;
-       uint64_t                         prefix_rcvd_withdraw;
-       uint64_t                         prefix_rcvd_eor;
-       uint64_t                         prefix_sent_update;
-       uint64_t                         prefix_sent_withdraw;
-       uint64_t                         prefix_sent_eor;
-       uint32_t                         prefix_cnt;
-       uint32_t                         prefix_out_cnt;
        uint32_t                         remote_bgpid; /* host byte order! */
-       uint32_t                         up_nlricnt;
-       uint32_t                         up_wcnt;
        uint32_t                         path_id_tx;
        enum peer_state                  state;
        enum export_type                 export_type;
Index: rde_peer.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde_peer.c,v
retrieving revision 1.27
diff -u -p -r1.27 rde_peer.c
--- rde_peer.c  24 Jan 2023 11:28:41 -0000      1.27
+++ rde_peer.c  8 Feb 2023 17:41:24 -0000
@@ -348,7 +348,7 @@ peer_flush_upcall(struct rib_entry *re, 
                }
 
                prefix_destroy(p);
-               peer->prefix_cnt--;
+               peer->stats.prefix_cnt--;
        }
 }
 
@@ -422,8 +422,8 @@ peer_up(struct rde_peer *peer, struct se
                    peer_adjout_clear_upcall, NULL, NULL) == -1)
                        fatal("%s: prefix_dump_new", __func__);
                peer_flush(peer, AID_UNSPEC, 0);
-               peer->prefix_cnt = 0;
-               peer->prefix_out_cnt = 0;
+               peer->stats.prefix_cnt = 0;
+               peer->stats.prefix_out_cnt = 0;
                peer->state = PEER_DOWN;
        }
        peer->remote_bgpid = ntohl(sup->remote_bgpid);
@@ -473,8 +473,8 @@ peer_down(struct rde_peer *peer, void *b
 
        /* flush Adj-RIB-In */
        peer_flush(peer, AID_UNSPEC, 0);
-       peer->prefix_cnt = 0;
-       peer->prefix_out_cnt = 0;
+       peer->stats.prefix_cnt = 0;
+       peer->stats.prefix_out_cnt = 0;
 
        RB_REMOVE(peer_tree, &peertable, peer);
        free(peer);
Index: rde_rib.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde_rib.c,v
retrieving revision 1.254
diff -u -p -r1.254 rde_rib.c
--- rde_rib.c   24 Jan 2023 11:28:41 -0000      1.254
+++ rde_rib.c   7 Feb 2023 10:09:03 -0000
@@ -1171,16 +1171,16 @@ prefix_adjout_update(struct prefix *p, s
                /* if pending update unhook it before it is unlinked */
                if (p->flags & PREFIX_FLAG_UPDATE) {
                        RB_REMOVE(prefix_tree, &peer->updates[prefix->aid], p);
-                       peer->up_nlricnt--;
+                       peer->stats.pending_update--;
                }
 
                /* unlink prefix so it can be relinked below */
                prefix_unlink(p);
-               peer->prefix_out_cnt--;
+               peer->stats.prefix_out_cnt--;
        }
        if (p->flags & PREFIX_FLAG_WITHDRAW) {
                RB_REMOVE(prefix_tree, &peer->withdraws[prefix->aid], p);
-               peer->up_wcnt--;
+               peer->stats.pending_withdraw--;
        }
 
        /* nothing needs to be done for PREFIX_FLAG_DEAD and STALE */
@@ -1208,14 +1208,14 @@ prefix_adjout_update(struct prefix *p, s
 
        prefix_link(p, NULL, p->pt, peer, 0, p->path_id_tx, asp, comm,
            state->nexthop, state->nhflags, state->vstate);
-       peer->prefix_out_cnt++;
+       peer->stats.prefix_out_cnt++;
 
        if (p->flags & PREFIX_FLAG_MASK)
                fatalx("%s: bad flags %x", __func__, p->flags);
        p->flags |= PREFIX_FLAG_UPDATE;
        if (RB_INSERT(prefix_tree, &peer->updates[prefix->aid], p) != NULL)
                fatalx("%s: RB tree invariant violated", __func__);
-       peer->up_nlricnt++;
+       peer->stats.pending_update++;
 }
 
 /*
@@ -1239,12 +1239,12 @@ prefix_adjout_withdraw(struct prefix *p)
        /* pending update just got withdrawn */
        if (p->flags & PREFIX_FLAG_UPDATE) {
                RB_REMOVE(prefix_tree, &peer->updates[p->pt->aid], p);
-               peer->up_nlricnt--;
+               peer->stats.pending_update--;
        }
        /* unlink prefix if it was linked (not a withdraw or dead) */
        if ((p->flags & (PREFIX_FLAG_WITHDRAW | PREFIX_FLAG_DEAD)) == 0) {
                prefix_unlink(p);
-               peer->prefix_out_cnt--;
+               peer->stats.prefix_out_cnt--;
        }
 
        /* nothing needs to be done for PREFIX_FLAG_DEAD and STALE */
@@ -1254,7 +1254,7 @@ prefix_adjout_withdraw(struct prefix *p)
        p->flags |= PREFIX_FLAG_WITHDRAW;
        if (RB_INSERT(prefix_tree, &peer->withdraws[p->pt->aid], p) != NULL)
                fatalx("%s: RB tree invariant violated", __func__);
-       peer->up_wcnt++;
+       peer->stats.pending_withdraw++;
 }
 
 void
@@ -1273,16 +1273,16 @@ prefix_adjout_destroy(struct prefix *p)
 
        if (p->flags & PREFIX_FLAG_WITHDRAW) {
                RB_REMOVE(prefix_tree, &peer->withdraws[p->pt->aid], p);
-               peer->up_wcnt--;
+               peer->stats.pending_withdraw--;
        }
        if (p->flags & PREFIX_FLAG_UPDATE) {
                RB_REMOVE(prefix_tree, &peer->updates[p->pt->aid], p);
-               peer->up_nlricnt--;
+               peer->stats.pending_update--;
        }
        /* unlink prefix if it was linked (not a withdraw or dead) */
        if ((p->flags & (PREFIX_FLAG_WITHDRAW | PREFIX_FLAG_DEAD)) == 0) {
                prefix_unlink(p);
-               peer->prefix_out_cnt--;
+               peer->stats.prefix_out_cnt--;
        }
 
        /* nothing needs to be done for PREFIX_FLAG_DEAD and STALE */
Index: rde_update.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde_update.c,v
retrieving revision 1.153
diff -u -p -r1.153 rde_update.c
--- rde_update.c        24 Jan 2023 11:28:41 -0000      1.153
+++ rde_update.c        7 Feb 2023 10:29:59 -0000
@@ -213,10 +213,11 @@ up_generate_updates(struct filter_head *
 
                /* max prefix checker outbound */
                if (peer->conf.max_out_prefix &&
-                   peer->prefix_out_cnt > peer->conf.max_out_prefix) {
+                   peer->stats.prefix_out_cnt > peer->conf.max_out_prefix) {
                        log_peer_warnx(&peer->conf,
                            "outbound prefix limit reached (>%u/%u)",
-                           peer->prefix_out_cnt, peer->conf.max_out_prefix);
+                           peer->stats.prefix_out_cnt,
+                           peer->conf.max_out_prefix);
                        rde_update_err(peer, ERR_CEASE,
                            ERR_CEASE_MAX_SENT_PREFIX, NULL, 0);
                }
@@ -343,10 +344,11 @@ up_generate_addpath(struct filter_head *
 
                /* max prefix checker outbound */
                if (peer->conf.max_out_prefix &&
-                   peer->prefix_out_cnt > peer->conf.max_out_prefix) {
+                   peer->stats.prefix_out_cnt > peer->conf.max_out_prefix) {
                        log_peer_warnx(&peer->conf,
                            "outbound prefix limit reached (>%u/%u)",
-                           peer->prefix_out_cnt, peer->conf.max_out_prefix);
+                           peer->stats.prefix_out_cnt,
+                           peer->conf.max_out_prefix);
                        rde_update_err(peer, ERR_CEASE,
                            ERR_CEASE_MAX_SENT_PREFIX, NULL, 0);
                }
@@ -446,10 +448,11 @@ up_generate_addpath_all(struct filter_he
 
                /* max prefix checker outbound */
                if (peer->conf.max_out_prefix &&
-                   peer->prefix_out_cnt > peer->conf.max_out_prefix) {
+                   peer->stats.prefix_out_cnt > peer->conf.max_out_prefix) {
                        log_peer_warnx(&peer->conf,
                            "outbound prefix limit reached (>%u/%u)",
-                           peer->prefix_out_cnt, peer->conf.max_out_prefix);
+                           peer->stats.prefix_out_cnt,
+                           peer->conf.max_out_prefix);
                        rde_update_err(peer, ERR_CEASE,
                            ERR_CEASE_MAX_SENT_PREFIX, NULL, 0);
                }
@@ -512,10 +515,10 @@ up_generate_default(struct filter_head *
 
        /* max prefix checker outbound */
        if (peer->conf.max_out_prefix &&
-           peer->prefix_out_cnt > peer->conf.max_out_prefix) {
+           peer->stats.prefix_out_cnt > peer->conf.max_out_prefix) {
                log_peer_warnx(&peer->conf,
                    "outbound prefix limit reached (>%u/%u)",
-                   peer->prefix_out_cnt, peer->conf.max_out_prefix);
+                   peer->stats.prefix_out_cnt, peer->conf.max_out_prefix);
                rde_update_err(peer, ERR_CEASE,
                    ERR_CEASE_MAX_SENT_PREFIX, NULL, 0);
        }
@@ -929,13 +932,13 @@ up_dump_prefix(u_char *buf, int len, str
                if (withdraw) {
                        /* prefix no longer needed, remove it */
                        prefix_adjout_destroy(p);
-                       peer->prefix_sent_withdraw++;
+                       peer->stats.prefix_sent_withdraw++;
                } else {
                        /* prefix still in Adj-RIB-Out, keep it */
                        RB_REMOVE(prefix_tree, prefix_head, p);
                        p->flags &= ~PREFIX_FLAG_UPDATE;
-                       peer->up_nlricnt--;
-                       peer->prefix_sent_update++;
+                       peer->stats.pending_update--;
+                       peer->stats.prefix_sent_update++;
                }
 
                if (done)
Index: session.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/session.c,v
retrieving revision 1.439
diff -u -p -r1.439 session.c
--- session.c   4 Jan 2023 14:33:30 -0000       1.439
+++ session.c   8 Feb 2023 17:36:54 -0000
@@ -3189,7 +3189,13 @@ session_dispatch_imsg(struct imsgbuf *ib
                case IMSG_CTL_SHOW_TIMER:
                        if (idx != PFD_PIPE_MAIN)
                                fatalx("ctl kroute request not from parent");
-                       control_imsg_relay(&imsg);
+                       control_imsg_relay(&imsg, NULL);
+                       break;
+               case IMSG_CTL_SHOW_NEIGHBOR:
+                       if (idx != PFD_PIPE_ROUTE_CTL)
+                               fatalx("ctl rib request not from RDE");
+                       p = getpeerbyid(conf, imsg.hdr.peerid);
+                       control_imsg_relay(&imsg, p);
                        break;
                case IMSG_CTL_SHOW_RIB:
                case IMSG_CTL_SHOW_RIB_PREFIX:
@@ -3197,15 +3203,14 @@ session_dispatch_imsg(struct imsgbuf *ib
                case IMSG_CTL_SHOW_RIB_ATTR:
                case IMSG_CTL_SHOW_RIB_MEM:
                case IMSG_CTL_SHOW_NETWORK:
-               case IMSG_CTL_SHOW_NEIGHBOR:
                case IMSG_CTL_SHOW_SET:
                        if (idx != PFD_PIPE_ROUTE_CTL)
                                fatalx("ctl rib request not from RDE");
-                       control_imsg_relay(&imsg);
+                       control_imsg_relay(&imsg, NULL);
                        break;
                case IMSG_CTL_END:
                case IMSG_CTL_RESULT:
-                       control_imsg_relay(&imsg);
+                       control_imsg_relay(&imsg, NULL);
                        break;
                case IMSG_UPDATE:
                        if (idx != PFD_PIPE_ROUTE)
@@ -3554,11 +3559,11 @@ int
 imsg_ctl_parent(int type, uint32_t peerid, pid_t pid, void *data,
     uint16_t datalen)
 {
-       return (imsg_compose(ibuf_main, type, peerid, pid, -1, data, datalen));
+       return imsg_compose(ibuf_main, type, peerid, pid, -1, data, datalen);
 }
 
 int
-imsg_ctl_rde(int type, pid_t pid, void *data, uint16_t datalen)
+imsg_ctl_rde(int type, pid_t pid, uint32_t peerid, void *data, uint16_t 
datalen)
 {
        if (ibuf_rde_ctl == NULL)
                return (0);
@@ -3567,7 +3572,7 @@ imsg_ctl_rde(int type, pid_t pid, void *
         * Use control socket to talk to RDE to bypass the queue of the
         * regular imsg socket.
         */
-       return (imsg_compose(ibuf_rde_ctl, type, 0, pid, -1, data, datalen));
+       return imsg_compose(ibuf_rde_ctl, type, peerid, pid, -1, data, datalen);
 }
 
 int
@@ -3576,7 +3581,7 @@ imsg_rde(int type, uint32_t peerid, void
        if (ibuf_rde == NULL)
                return (0);
 
-       return (imsg_compose(ibuf_rde, type, peerid, 0, -1, data, datalen));
+       return imsg_compose(ibuf_rde, type, peerid, 0, -1, data, datalen);
 }
 
 void
Index: session.h
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/session.h,v
retrieving revision 1.158
diff -u -p -r1.158 session.h
--- session.h   29 Aug 2022 14:57:27 -0000      1.158
+++ session.h   7 Feb 2023 10:06:34 -0000
@@ -348,7 +348,7 @@ struct peer *getpeerbyip(struct bgpd_con
 struct peer    *getpeerbyid(struct bgpd_config *, uint32_t);
 int             peer_matched(struct peer *, struct ctl_neighbor *);
 int             imsg_ctl_parent(int, uint32_t, pid_t, void *, uint16_t);
-int             imsg_ctl_rde(int, pid_t, void *, uint16_t);
+int             imsg_ctl_rde(int, pid_t, uint32_t, void *, uint16_t);
 void            session_stop(struct peer *, uint8_t);
 
 /* timer.c */

Reply via email to