This diff moves prefix_write to rde_prefix.c and renames it to pt_write. The function now takes a struct pt_entry * as argument and with this the extra indirection via pt_getaddr() falls away.
-- :wq Claudio Index: mrt.c =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/mrt.c,v retrieving revision 1.112 diff -u -p -r1.112 mrt.c --- mrt.c 28 Mar 2023 09:52:08 -0000 1.112 +++ mrt.c 28 Mar 2023 13:33:41 -0000 @@ -387,7 +387,7 @@ mrt_dump_entry_mp(struct mrt *mrt, struc { struct ibuf *buf, *hbuf = NULL, *h2buf = NULL; struct nexthop *n; - struct bgpd_addr addr, nexthop, *nh; + struct bgpd_addr nexthop, *nh; uint16_t len; uint8_t aid; @@ -445,17 +445,15 @@ mrt_dump_entry_mp(struct mrt *mrt, struc /* originated timestamp */ DUMP_LONG(h2buf, time(NULL) - (getmonotime() - p->lastchange)); - pt_getaddr(p->pt, &addr); - n = prefix_nexthop(p); if (n == NULL) { memset(&nexthop, 0, sizeof(struct bgpd_addr)); - nexthop.aid = addr.aid; + nexthop.aid = p->pt->aid; nh = &nexthop; } else nh = &n->exit_nexthop; - switch (addr.aid) { + switch (p->pt->aid) { case AID_INET: DUMP_SHORT(h2buf, AFI_IPv4); /* afi */ DUMP_BYTE(h2buf, SAFI_UNICAST); /* safi */ @@ -495,8 +493,8 @@ mrt_dump_entry_mp(struct mrt *mrt, struc goto fail; } - if (prefix_writebuf(h2buf, &addr, p->pt->prefixlen) == -1) { - log_warnx("%s: prefix_writebuf error", __func__); + if (pt_writebuf(h2buf, p->pt) == -1) { + log_warnx("%s: pt_writebuf error", __func__); goto fail; } @@ -689,7 +687,6 @@ int mrt_dump_entry_v2(struct mrt *mrt, struct rib_entry *re, uint32_t snum) { struct ibuf *hbuf = NULL, *nbuf = NULL, *apbuf = NULL, *pbuf; - struct bgpd_addr addr; size_t hlen, len; uint16_t subtype, apsubtype, nump, apnump, afi; uint8_t safi; @@ -725,9 +722,8 @@ mrt_dump_entry_v2(struct mrt *mrt, struc break; } - pt_getaddr(re->prefix, &addr); - if (prefix_writebuf(pbuf, &addr, re->prefix->prefixlen) == -1) { - log_warnx("%s: prefix_writebuf error", __func__); + if (pt_writebuf(pbuf, re->prefix) == -1) { + log_warnx("%s: pt_writebuf error", __func__); goto fail; } Index: rde.h =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/rde.h,v retrieving revision 1.287 diff -u -p -r1.287 rde.h --- rde.h 28 Mar 2023 13:30:31 -0000 1.287 +++ rde.h 28 Mar 2023 13:33:41 -0000 @@ -517,6 +517,8 @@ struct pt_entry *pt_add(struct bgpd_addr void pt_remove(struct pt_entry *); struct pt_entry *pt_lookup(struct bgpd_addr *); int pt_prefix_cmp(const struct pt_entry *, const struct pt_entry *); +int pt_write(u_char *, int, struct pt_entry *, int); +int pt_writebuf(struct ibuf *, struct pt_entry *); static inline struct pt_entry * pt_ref(struct pt_entry *pt) @@ -602,8 +604,6 @@ int prefix_dump_subtree(struct rde_pee uint8_t, unsigned int, void *, void (*)(struct prefix *, void *), void (*)(void *, uint8_t), int (*)(void *)); -int prefix_write(u_char *, int, struct bgpd_addr *, uint8_t, int); -int prefix_writebuf(struct ibuf *, struct bgpd_addr *, uint8_t); struct prefix *prefix_bypeer(struct rib_entry *, struct rde_peer *, uint32_t); void prefix_destroy(struct prefix *); Index: rde_prefix.c =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/rde_prefix.c,v retrieving revision 1.44 diff -u -p -r1.44 rde_prefix.c --- rde_prefix.c 28 Mar 2023 13:30:31 -0000 1.44 +++ rde_prefix.c 28 Mar 2023 13:33:41 -0000 @@ -371,3 +371,121 @@ pt_free(struct pt_entry *pte) rdemem.pt_size[pte->aid] -= pt_sizes[pte->aid]; free(pte); } + +/* dump a prefix into specified buffer */ +int +pt_write(u_char *buf, int len, struct pt_entry *pte, int withdraw) +{ + struct pt_entry_vpn4 *pvpn4 = (struct pt_entry_vpn4 *)pte; + struct pt_entry_vpn6 *pvpn6 = (struct pt_entry_vpn6 *)pte; + int totlen, psize; + uint8_t plen; + + switch (pte->aid) { + case AID_INET: + case AID_INET6: + plen = pte->prefixlen; + totlen = PREFIX_SIZE(plen); + + if (totlen > len) + return (-1); + *buf++ = plen; + memcpy(buf, pte->data, totlen - 1); + return (totlen); + case AID_VPN_IPv4: + plen = pvpn4->prefixlen; + totlen = PREFIX_SIZE(plen) + sizeof(pvpn4->rd); + psize = PREFIX_SIZE(plen) - 1; + plen += sizeof(pvpn4->rd) * 8; + if (withdraw) { + /* withdraw have one compat label as placeholder */ + totlen += 3; + plen += 3 * 8; + } else { + totlen += pvpn4->labellen; + plen += pvpn4->labellen * 8; + } + + if (totlen > len) + return (-1); + *buf++ = plen; + if (withdraw) { + /* magic compatibility label as per rfc8277 */ + *buf++ = 0x80; + *buf++ = 0x0; + *buf++ = 0x0; + } else { + memcpy(buf, &pvpn4->labelstack, pvpn4->labellen); + buf += pvpn4->labellen; + } + memcpy(buf, &pvpn4->rd, sizeof(pvpn4->rd)); + buf += sizeof(pvpn4->rd); + memcpy(buf, &pvpn4->prefix4, psize); + return (totlen); + case AID_VPN_IPv6: + plen = pvpn6->prefixlen; + totlen = PREFIX_SIZE(plen) + sizeof(pvpn6->rd); + psize = PREFIX_SIZE(plen) - 1; + plen += sizeof(pvpn6->rd) * 8; + if (withdraw) { + /* withdraw have one compat label as placeholder */ + totlen += 3; + plen += 3 * 8; + } else { + totlen += pvpn6->labellen; + plen += pvpn6->labellen * 8; + } + + if (totlen > len) + return (-1); + *buf++ = plen; + if (withdraw) { + /* magic compatibility label as per rfc8277 */ + *buf++ = 0x80; + *buf++ = 0x0; + *buf++ = 0x0; + } else { + memcpy(buf, &pvpn6->labelstack, pvpn6->labellen); + buf += pvpn6->labellen; + } + memcpy(buf, &pvpn6->rd, sizeof(pvpn6->rd)); + buf += sizeof(pvpn6->rd); + memcpy(buf, &pvpn6->prefix6, psize); + return (totlen); + default: + return (-1); + } +} + +/* dump a prefix into specified ibuf, allocating space for it if needed */ +int +pt_writebuf(struct ibuf *buf, struct pt_entry *pte) +{ + struct pt_entry_vpn4 *pvpn4 = (struct pt_entry_vpn4 *)pte; + struct pt_entry_vpn6 *pvpn6 = (struct pt_entry_vpn6 *)pte; + int totlen; + void *bptr; + + switch (pte->aid) { + case AID_INET: + case AID_INET6: + totlen = PREFIX_SIZE(pte->prefixlen); + break; + case AID_VPN_IPv4: + totlen = PREFIX_SIZE(pte->prefixlen) + sizeof(pvpn4->rd) + + pvpn4->labellen; + break; + case AID_VPN_IPv6: + totlen = PREFIX_SIZE(pte->prefixlen) + sizeof(pvpn6->rd) + + pvpn6->labellen; + break; + default: + return (-1); + } + + if ((bptr = ibuf_reserve(buf, totlen)) == NULL) + return (-1); + if (pt_write(bptr, totlen, pte, 0) == -1) + return (-1); + return (0); +} Index: rde_rib.c =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/rde_rib.c,v retrieving revision 1.255 diff -u -p -r1.255 rde_rib.c --- rde_rib.c 9 Feb 2023 13:43:23 -0000 1.255 +++ rde_rib.c 28 Mar 2023 13:33:41 -0000 @@ -1427,86 +1427,6 @@ prefix_dump_subtree(struct rde_peer *pee return 0; } -/* dump a prefix into specified buffer */ -int -prefix_write(u_char *buf, int len, struct bgpd_addr *prefix, uint8_t plen, - int withdraw) -{ - int totlen, psize; - - switch (prefix->aid) { - case AID_INET: - case AID_INET6: - totlen = PREFIX_SIZE(plen); - - if (totlen > len) - return (-1); - *buf++ = plen; - memcpy(buf, &prefix->ba, totlen - 1); - return (totlen); - case AID_VPN_IPv4: - case AID_VPN_IPv6: - totlen = PREFIX_SIZE(plen) + sizeof(prefix->rd); - psize = PREFIX_SIZE(plen) - 1; - plen += sizeof(prefix->rd) * 8; - if (withdraw) { - /* withdraw have one compat label as placeholder */ - totlen += 3; - plen += 3 * 8; - } else { - totlen += prefix->labellen; - plen += prefix->labellen * 8; - } - - if (totlen > len) - return (-1); - *buf++ = plen; - if (withdraw) { - /* magic compatibility label as per rfc8277 */ - *buf++ = 0x80; - *buf++ = 0x0; - *buf++ = 0x0; - } else { - memcpy(buf, &prefix->labelstack, - prefix->labellen); - buf += prefix->labellen; - } - memcpy(buf, &prefix->rd, sizeof(prefix->rd)); - buf += sizeof(prefix->rd); - memcpy(buf, &prefix->ba, psize); - return (totlen); - default: - return (-1); - } -} - -int -prefix_writebuf(struct ibuf *buf, struct bgpd_addr *prefix, uint8_t plen) -{ - int totlen; - void *bptr; - - switch (prefix->aid) { - case AID_INET: - case AID_INET6: - totlen = PREFIX_SIZE(plen); - break; - case AID_VPN_IPv4: - case AID_VPN_IPv6: - totlen = PREFIX_SIZE(plen) + sizeof(prefix->rd) + - prefix->labellen; - break; - default: - return (-1); - } - - if ((bptr = ibuf_reserve(buf, totlen)) == NULL) - return (-1); - if (prefix_write(bptr, totlen, prefix, plen, 0) == -1) - return (-1); - return (0); -} - /* * Searches in the prefix list of specified rib_entry for a prefix entry * belonging to the peer peer. Returns NULL if no match found. Index: rde_update.c =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/rde_update.c,v retrieving revision 1.159 diff -u -p -r1.159 rde_update.c --- rde_update.c 13 Mar 2023 16:52:42 -0000 1.159 +++ rde_update.c 28 Mar 2023 13:33:41 -0000 @@ -836,7 +836,6 @@ up_dump_prefix(u_char *buf, int len, str struct rde_peer *peer, int withdraw) { struct prefix *p, *np; - struct bgpd_addr addr; uint32_t pathid; int r, wpos = 0, done = 0; @@ -848,9 +847,8 @@ up_dump_prefix(u_char *buf, int len, str memcpy(buf + wpos, &pathid, sizeof(pathid)); wpos += sizeof(pathid); } - pt_getaddr(p->pt, &addr); - if ((r = prefix_write(buf + wpos, len - wpos, - &addr, p->pt->prefixlen, withdraw)) == -1) { + if ((r = pt_write(buf + wpos, len - wpos, p->pt, + withdraw)) == -1) { if (peer_has_add_path(peer, p->pt->aid, CAPA_AP_SEND)) wpos -= sizeof(pathid); break;