-/* $OpenBSD: mrt.c,v 1.112 2023/03/28 09:52:08 claudio Exp $ */
+/* $OpenBSD: mrt.c,v 1.113 2023/03/28 15:17:34 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
{
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;
/* 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 */
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;
}
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;
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;
}
-/* $OpenBSD: rde.h,v 1.287 2023/03/28 13:30:31 claudio Exp $ */
+/* $OpenBSD: rde.h,v 1.288 2023/03/28 15:17:34 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> and
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)
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 *);
-/* $OpenBSD: rde_prefix.c,v 1.44 2023/03/28 13:30:31 claudio Exp $ */
+/* $OpenBSD: rde_prefix.c,v 1.45 2023/03/28 15:17:34 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
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);
+}
-/* $OpenBSD: rde_rib.c,v 1.255 2023/02/09 13:43:23 claudio Exp $ */
+/* $OpenBSD: rde_rib.c,v 1.256 2023/03/28 15:17:34 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
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.
-/* $OpenBSD: rde_update.c,v 1.159 2023/03/13 16:52:42 claudio Exp $ */
+/* $OpenBSD: rde_update.c,v 1.160 2023/03/28 15:17:34 claudio Exp $ */
/*
* Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
struct rde_peer *peer, int withdraw)
{
struct prefix *p, *np;
- struct bgpd_addr addr;
uint32_t pathid;
int r, wpos = 0, done = 0;
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;