diff options
Diffstat (limited to 'net/openbgpd/files/patch-bgpd_mrt.c')
-rw-r--r-- | net/openbgpd/files/patch-bgpd_mrt.c | 864 |
1 files changed, 0 insertions, 864 deletions
diff --git a/net/openbgpd/files/patch-bgpd_mrt.c b/net/openbgpd/files/patch-bgpd_mrt.c deleted file mode 100644 index 31546fcf96d0..000000000000 --- a/net/openbgpd/files/patch-bgpd_mrt.c +++ /dev/null @@ -1,864 +0,0 @@ -Index: bgpd/mrt.c -=================================================================== -RCS file: /home/cvs/private/hrs/openbgpd/bgpd/mrt.c,v -retrieving revision 1.1.1.7 -retrieving revision 1.1.1.11 -diff -u -p -r1.1.1.7 -r1.1.1.11 ---- bgpd/mrt.c 14 Feb 2010 20:19:57 -0000 1.1.1.7 -+++ bgpd/mrt.c 8 Dec 2012 10:37:09 -0000 1.1.1.11 -@@ -1,4 +1,4 @@ --/* $OpenBSD: mrt.c,v 1.63 2009/06/29 12:22:16 claudio Exp $ */ -+/* $OpenBSD: mrt.c,v 1.72 2011/11/06 10:29:05 guenther Exp $ */ - - /* - * Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> -@@ -21,6 +21,7 @@ - - #include <errno.h> - #include <fcntl.h> -+#include <limits.h> - #include <stdlib.h> - #include <string.h> - #include <time.h> -@@ -32,20 +33,22 @@ - - #include "mrt.h" - --int mrt_attr_dump(struct buf *, struct rde_aspath *, struct bgpd_addr *); -+int mrt_attr_dump(struct ibuf *, struct rde_aspath *, struct bgpd_addr *, int); - int mrt_dump_entry_mp(struct mrt *, struct prefix *, u_int16_t, - struct rde_peer*); - int mrt_dump_entry(struct mrt *, struct prefix *, u_int16_t, struct rde_peer*); --int mrt_dump_hdr_se(struct buf **, struct peer *, u_int16_t, u_int16_t, -+int mrt_dump_entry_v2(struct mrt *, struct rib_entry *, u_int32_t); -+int mrt_dump_peer(struct ibuf *, struct rde_peer *); -+int mrt_dump_hdr_se(struct ibuf **, struct peer *, u_int16_t, u_int16_t, - u_int32_t, int); --int mrt_dump_hdr_rde(struct buf **, u_int16_t type, u_int16_t, u_int32_t); -+int mrt_dump_hdr_rde(struct ibuf **, u_int16_t type, u_int16_t, u_int32_t); - int mrt_open(struct mrt *, time_t); - - #define DUMP_BYTE(x, b) \ - do { \ - u_char t = (b); \ -- if (buf_add((x), &t, sizeof(t)) == -1) { \ -- log_warnx("mrt_dump1: buf_add error"); \ -+ if (ibuf_add((x), &t, sizeof(t)) == -1) { \ -+ log_warn("mrt_dump1: ibuf_add error"); \ - goto fail; \ - } \ - } while (0) -@@ -54,8 +57,8 @@ int mrt_open(struct mrt *, time_t); - do { \ - u_int16_t t; \ - t = htons((s)); \ -- if (buf_add((x), &t, sizeof(t)) == -1) { \ -- log_warnx("mrt_dump2: buf_add error"); \ -+ if (ibuf_add((x), &t, sizeof(t)) == -1) { \ -+ log_warn("mrt_dump2: ibuf_add error"); \ - goto fail; \ - } \ - } while (0) -@@ -64,8 +67,8 @@ int mrt_open(struct mrt *, time_t); - do { \ - u_int32_t t; \ - t = htonl((l)); \ -- if (buf_add((x), &t, sizeof(t)) == -1) { \ -- log_warnx("mrt_dump3: buf_add error"); \ -+ if (ibuf_add((x), &t, sizeof(t)) == -1) { \ -+ log_warn("mrt_dump3: ibuf_add error"); \ - goto fail; \ - } \ - } while (0) -@@ -73,8 +76,8 @@ int mrt_open(struct mrt *, time_t); - #define DUMP_NLONG(x, l) \ - do { \ - u_int32_t t = (l); \ -- if (buf_add((x), &t, sizeof(t)) == -1) { \ -- log_warnx("mrt_dump4: buf_add error"); \ -+ if (ibuf_add((x), &t, sizeof(t)) == -1) { \ -+ log_warn("mrt_dump4: ibuf_add error"); \ - goto fail; \ - } \ - } while (0) -@@ -83,55 +86,64 @@ void - mrt_dump_bgp_msg(struct mrt *mrt, void *pkg, u_int16_t pkglen, - struct peer *peer) - { -- struct buf *buf; -+ struct ibuf *buf; - int incoming = 0; -+ u_int16_t subtype = BGP4MP_MESSAGE; -+ -+ if (peer->capa.neg.as4byte) -+ subtype = BGP4MP_MESSAGE_AS4; - - /* get the direction of the message to swap address and AS fields */ - if (mrt->type == MRT_ALL_IN || mrt->type == MRT_UPDATE_IN) - incoming = 1; - -- if (mrt_dump_hdr_se(&buf, peer, MSG_PROTOCOL_BGP4MP, BGP4MP_MESSAGE, -+ if (mrt_dump_hdr_se(&buf, peer, MSG_PROTOCOL_BGP4MP, subtype, - pkglen, incoming) == -1) - return; - -- if (buf_add(buf, pkg, pkglen) == -1) { -- log_warnx("mrt_dump_bgp_msg: buf_add error"); -- buf_free(buf); -+ if (ibuf_add(buf, pkg, pkglen) == -1) { -+ log_warn("mrt_dump_bgp_msg: ibuf_add error"); -+ ibuf_free(buf); - return; - } - -- buf_close(&mrt->wbuf, buf); -+ ibuf_close(&mrt->wbuf, buf); - } - - void - mrt_dump_state(struct mrt *mrt, u_int16_t old_state, u_int16_t new_state, - struct peer *peer) - { -- struct buf *buf; -+ struct ibuf *buf; -+ u_int16_t subtype = BGP4MP_STATE_CHANGE; -+ -+ if (peer->capa.neg.as4byte) -+ subtype = BGP4MP_STATE_CHANGE_AS4; - -- if (mrt_dump_hdr_se(&buf, peer, MSG_PROTOCOL_BGP4MP, BGP4MP_MESSAGE, -+ if (mrt_dump_hdr_se(&buf, peer, MSG_PROTOCOL_BGP4MP, subtype, - 2 * sizeof(short), 0) == -1) - return; - - DUMP_SHORT(buf, old_state); - DUMP_SHORT(buf, new_state); - -- buf_close(&mrt->wbuf, buf); -+ ibuf_close(&mrt->wbuf, buf); - return; - - fail: -- buf_free(buf); -+ ibuf_free(buf); - } - - int --mrt_attr_dump(struct buf *buf, struct rde_aspath *a, struct bgpd_addr *nexthop) -+mrt_attr_dump(struct ibuf *buf, struct rde_aspath *a, struct bgpd_addr *nexthop, -+ int v2) - { - struct attr *oa; - u_char *pdata; - u_int32_t tmp; - int neednewpath = 0; -- u_int16_t plen; -- u_int8_t l; -+ u_int16_t plen, afi; -+ u_int8_t l, safi; - - /* origin */ - if (attr_writebuf(buf, ATTR_WELL_KNOWN, ATTR_ORIGIN, -@@ -140,12 +152,16 @@ mrt_attr_dump(struct buf *buf, struct rd - - /* aspath */ - pdata = aspath_prepend(a->aspath, rde_local_as(), 0, &plen); -- pdata = aspath_deflate(pdata, &plen, &neednewpath); -- if (attr_writebuf(buf, ATTR_WELL_KNOWN, ATTR_ASPATH, pdata, plen) == -1) -+ if (!v2) -+ pdata = aspath_deflate(pdata, &plen, &neednewpath); -+ if (attr_writebuf(buf, ATTR_WELL_KNOWN, ATTR_ASPATH, pdata, -+ plen) == -1) { -+ free(pdata); - return (-1); -+ } - free(pdata); - -- if (nexthop) { -+ if (nexthop && nexthop->aid == AID_INET) { - /* nexthop, already network byte order */ - if (attr_writebuf(buf, ATTR_WELL_KNOWN, ATTR_NEXTHOP, - &nexthop->v4.s_addr, 4) == -1) -@@ -159,7 +175,7 @@ mrt_attr_dump(struct buf *buf, struct rd - return (-1); - } - -- /* local preference, only valid for ibgp */ -+ /* local preference */ - tmp = htonl(a->lpref); - if (attr_writebuf(buf, ATTR_WELL_KNOWN, ATTR_LOCALPREF, &tmp, 4) == -1) - return (-1); -@@ -173,12 +189,51 @@ mrt_attr_dump(struct buf *buf, struct rd - return (-1); - } - -+ if (nexthop && nexthop->aid != AID_INET) { -+ struct ibuf *nhbuf; -+ -+ if ((nhbuf = ibuf_dynamic(0, UCHAR_MAX)) == NULL) -+ return (-1); -+ if (!v2) { -+ if (aid2afi(nexthop->aid, &afi, &safi)) -+ return (-1); -+ DUMP_SHORT(nhbuf, afi); -+ DUMP_BYTE(nhbuf, safi); -+ } -+ switch (nexthop->aid) { -+ case AID_INET6: -+ DUMP_BYTE(nhbuf, sizeof(struct in6_addr)); -+ if (ibuf_add(nhbuf, &nexthop->v6, -+ sizeof(struct in6_addr)) == -1) { -+ } -+ break; -+ case AID_VPN_IPv4: -+ DUMP_BYTE(nhbuf, sizeof(u_int64_t) + -+ sizeof(struct in_addr)); -+ DUMP_NLONG(nhbuf, 0); /* set RD to 0 */ -+ DUMP_NLONG(nhbuf, 0); -+ DUMP_NLONG(nhbuf, nexthop->v4.s_addr); -+ break; -+ } -+ if (!v2) -+ DUMP_BYTE(nhbuf, 0); -+ if (attr_writebuf(buf, ATTR_OPTIONAL, ATTR_MP_REACH_NLRI, -+ nhbuf->buf, ibuf_size(nhbuf)) == -1) { -+fail: -+ ibuf_free(nhbuf); -+ return (-1); -+ } -+ ibuf_free(nhbuf); -+ } -+ - if (neednewpath) { - pdata = aspath_prepend(a->aspath, rde_local_as(), 0, &plen); - if (plen != 0) - if (attr_writebuf(buf, ATTR_OPTIONAL|ATTR_TRANSITIVE, -- ATTR_AS4_PATH, pdata, plen) == -1) -+ ATTR_AS4_PATH, pdata, plen) == -1) { -+ free(pdata); - return (-1); -+ } - free(pdata); - } - -@@ -189,28 +244,26 @@ int - mrt_dump_entry_mp(struct mrt *mrt, struct prefix *p, u_int16_t snum, - struct rde_peer *peer) - { -- struct buf *buf, *hbuf = NULL, *h2buf = NULL; -- void *bptr; -+ struct ibuf *buf, *hbuf = NULL, *h2buf = NULL; - struct bgpd_addr addr, nexthop, *nh; - u_int16_t len; -- u_int8_t p_len; -- sa_family_t af; -+ u_int8_t aid; - -- if ((buf = buf_dynamic(0, MAX_PKTSIZE)) == NULL) { -- log_warn("mrt_dump_entry_mp: buf_dynamic"); -+ if ((buf = ibuf_dynamic(0, MAX_PKTSIZE)) == NULL) { -+ log_warn("mrt_dump_entry_mp: ibuf_dynamic"); - return (-1); - } - -- if (mrt_attr_dump(buf, p->aspath, NULL) == -1) { -+ if (mrt_attr_dump(buf, p->aspath, NULL, 0) == -1) { - log_warnx("mrt_dump_entry_mp: mrt_attr_dump error"); - goto fail; - } -- len = buf_size(buf); -+ len = ibuf_size(buf); - -- if ((h2buf = buf_dynamic(MRT_BGP4MP_IPv4_HEADER_SIZE + -+ if ((h2buf = ibuf_dynamic(MRT_BGP4MP_IPv4_HEADER_SIZE + - MRT_BGP4MP_IPv4_ENTRY_SIZE, MRT_BGP4MP_IPv6_HEADER_SIZE + - MRT_BGP4MP_IPv6_ENTRY_SIZE + MRT_BGP4MP_MAX_PREFIXLEN)) == NULL) { -- log_warn("mrt_dump_entry_mp: buf_dynamic"); -+ log_warn("mrt_dump_entry_mp: ibuf_dynamic"); - goto fail; - } - -@@ -219,25 +272,26 @@ mrt_dump_entry_mp(struct mrt *mrt, struc - DUMP_SHORT(h2buf, /* ifindex */ 0); - - /* XXX is this for peer self? */ -- af = peer->remote_addr.af == 0 ? p->prefix->af : peer->remote_addr.af; -- switch (af) { -- case AF_INET: -+ aid = peer->remote_addr.aid == AID_UNSPEC ? p->prefix->aid : -+ peer->remote_addr.aid; -+ switch (aid) { -+ case AID_INET: - DUMP_SHORT(h2buf, AFI_IPv4); - DUMP_NLONG(h2buf, peer->local_v4_addr.v4.s_addr); - DUMP_NLONG(h2buf, peer->remote_addr.v4.s_addr); - break; -- case AF_INET6: -+ case AID_INET6: - DUMP_SHORT(h2buf, AFI_IPv6); -- if (buf_add(h2buf, &peer->local_v6_addr.v6, -+ if (ibuf_add(h2buf, &peer->local_v6_addr.v6, - sizeof(struct in6_addr)) == -1 || -- buf_add(h2buf, &peer->remote_addr.v6, -+ ibuf_add(h2buf, &peer->remote_addr.v6, - sizeof(struct in6_addr)) == -1) { -- log_warnx("mrt_dump_entry_mp: buf_add error"); -+ log_warn("mrt_dump_entry_mp: ibuf_add error"); - goto fail; - } - break; - default: -- log_warnx("king bula found new AF %d in mrt_dump_entry_mp", af); -+ log_warnx("king bula found new AF in mrt_dump_entry_mp"); - goto fail; - } - -@@ -247,25 +301,25 @@ mrt_dump_entry_mp(struct mrt *mrt, struc - - if (p->aspath->nexthop == NULL) { - bzero(&nexthop, sizeof(struct bgpd_addr)); -- nexthop.af = addr.af; -+ nexthop.aid = addr.aid; - nh = &nexthop; - } else - nh = &p->aspath->nexthop->exit_nexthop; - - pt_getaddr(p->prefix, &addr); -- switch (addr.af) { -- case AF_INET: -+ switch (addr.aid) { -+ case AID_INET: - DUMP_SHORT(h2buf, AFI_IPv4); /* afi */ - DUMP_BYTE(h2buf, SAFI_UNICAST); /* safi */ - DUMP_BYTE(h2buf, 4); /* nhlen */ - DUMP_NLONG(h2buf, nh->v4.s_addr); /* nexthop */ - break; -- case AF_INET6: -+ case AID_INET6: - DUMP_SHORT(h2buf, AFI_IPv6); /* afi */ - DUMP_BYTE(h2buf, SAFI_UNICAST); /* safi */ - DUMP_BYTE(h2buf, 16); /* nhlen */ -- if (buf_add(h2buf, &nh->v6, sizeof(struct in6_addr)) == -1) { -- log_warnx("mrt_dump_entry_mp: buf_add error"); -+ if (ibuf_add(h2buf, &nh->v6, sizeof(struct in6_addr)) == -1) { -+ log_warn("mrt_dump_entry_mp: ibuf_add error"); - goto fail; - } - break; -@@ -274,35 +328,30 @@ mrt_dump_entry_mp(struct mrt *mrt, struc - goto fail; - } - -- p_len = PREFIX_SIZE(p->prefix->prefixlen); -- if ((bptr = buf_reserve(h2buf, p_len)) == NULL) { -- log_warnx("mrt_dump_entry_mp: buf_reserve error"); -- goto fail; -- } -- if (prefix_write(bptr, p_len, &addr, p->prefix->prefixlen) == -1) { -- log_warnx("mrt_dump_entry_mp: prefix_write error"); -+ if (prefix_writebuf(h2buf, &addr, p->prefix->prefixlen) == -1) { -+ log_warn("mrt_dump_entry_mp: prefix_writebuf error"); - goto fail; - } - - DUMP_SHORT(h2buf, len); -- len += buf_size(h2buf); -+ len += ibuf_size(h2buf); - - if (mrt_dump_hdr_rde(&hbuf, MSG_PROTOCOL_BGP4MP, BGP4MP_ENTRY, - len) == -1) - goto fail; - -- buf_close(&mrt->wbuf, hbuf); -- buf_close(&mrt->wbuf, h2buf); -- buf_close(&mrt->wbuf, buf); -+ ibuf_close(&mrt->wbuf, hbuf); -+ ibuf_close(&mrt->wbuf, h2buf); -+ ibuf_close(&mrt->wbuf, buf); - - return (len + MRT_HEADER_SIZE); - - fail: - if (hbuf) -- buf_free(hbuf); -- if (h2buf); -- buf_free(h2buf); -- buf_free(buf); -+ ibuf_free(hbuf); -+ if (h2buf) -+ ibuf_free(h2buf); -+ ibuf_free(buf); - return (-1); - } - -@@ -310,34 +359,37 @@ int - mrt_dump_entry(struct mrt *mrt, struct prefix *p, u_int16_t snum, - struct rde_peer *peer) - { -- struct buf *buf, *hbuf; -+ struct ibuf *buf, *hbuf; - struct bgpd_addr addr, *nh; - size_t len; -+ u_int16_t subtype; -+ u_int8_t dummy; - -- if (p->prefix->af != AF_INET && peer->remote_addr.af == AF_INET) -- /* only able to dump IPv4 */ -+ if (p->prefix->aid != peer->remote_addr.aid && -+ p->prefix->aid != AID_INET && p->prefix->aid != AID_INET6) -+ /* only able to dump pure IPv4/IPv6 */ - return (0); - -- if ((buf = buf_dynamic(0, MAX_PKTSIZE)) == NULL) { -- log_warnx("mrt_dump_entry: buf_dynamic"); -+ if ((buf = ibuf_dynamic(0, MAX_PKTSIZE)) == NULL) { -+ log_warn("mrt_dump_entry: ibuf_dynamic"); - return (-1); - } - - if (p->aspath->nexthop == NULL) { - bzero(&addr, sizeof(struct bgpd_addr)); -- addr.af = AF_INET; -+ addr.aid = p->prefix->aid; - nh = &addr; - } else - nh = &p->aspath->nexthop->exit_nexthop; -- if (mrt_attr_dump(buf, p->aspath, nh) == -1) { -+ if (mrt_attr_dump(buf, p->aspath, nh, 0) == -1) { - log_warnx("mrt_dump_entry: mrt_attr_dump error"); -- buf_free(buf); -+ ibuf_free(buf); - return (-1); - } -- len = buf_size(buf); -- -- if (mrt_dump_hdr_rde(&hbuf, MSG_TABLE_DUMP, AFI_IPv4, len) == -1) { -- buf_free(buf); -+ len = ibuf_size(buf); -+ aid2afi(p->prefix->aid, &subtype, &dummy); -+ if (mrt_dump_hdr_rde(&hbuf, MSG_TABLE_DUMP, subtype, len) == -1) { -+ ibuf_free(buf); - return (-1); - } - -@@ -345,23 +397,241 @@ mrt_dump_entry(struct mrt *mrt, struct p - DUMP_SHORT(hbuf, snum); - - pt_getaddr(p->prefix, &addr); -- DUMP_NLONG(hbuf, addr.v4.s_addr); -+ switch (p->prefix->aid) { -+ case AID_INET: -+ DUMP_NLONG(hbuf, addr.v4.s_addr); -+ break; -+ case AID_INET6: -+ if (ibuf_add(hbuf, &addr.v6, sizeof(struct in6_addr)) == -1) { -+ log_warn("mrt_dump_entry: ibuf_add error"); -+ goto fail; -+ } -+ break; -+ } - DUMP_BYTE(hbuf, p->prefix->prefixlen); - - DUMP_BYTE(hbuf, 1); /* state */ - DUMP_LONG(hbuf, p->lastchange); /* originated */ -- DUMP_NLONG(hbuf, peer->remote_addr.v4.s_addr); -+ switch (p->prefix->aid) { -+ case AID_INET: -+ DUMP_NLONG(hbuf, peer->remote_addr.v4.s_addr); -+ break; -+ case AID_INET6: -+ if (ibuf_add(hbuf, &peer->remote_addr.v6, -+ sizeof(struct in6_addr)) == -1) { -+ log_warn("mrt_dump_entry: ibuf_add error"); -+ goto fail; -+ } -+ break; -+ } - DUMP_SHORT(hbuf, peer->short_as); - DUMP_SHORT(hbuf, len); - -- buf_close(&mrt->wbuf, hbuf); -- buf_close(&mrt->wbuf, buf); -+ ibuf_close(&mrt->wbuf, hbuf); -+ ibuf_close(&mrt->wbuf, buf); - - return (len + MRT_HEADER_SIZE); - - fail: -- buf_free(hbuf); -- buf_free(buf); -+ ibuf_free(hbuf); -+ ibuf_free(buf); -+ return (-1); -+} -+ -+int -+mrt_dump_entry_v2(struct mrt *mrt, struct rib_entry *re, u_int32_t snum) -+{ -+ struct ibuf *buf, *hbuf = NULL; -+ struct prefix *p; -+ struct bgpd_addr addr; -+ size_t len, off; -+ u_int16_t subtype, nump; -+ -+ switch (re->prefix->aid) { -+ case AID_INET: -+ subtype = MRT_DUMP_V2_RIB_IPV4_UNICAST; -+ break; -+ case AID_INET6: -+ subtype = MRT_DUMP_V2_RIB_IPV6_UNICAST; -+ break; -+ default: -+ subtype = MRT_DUMP_V2_RIB_GENERIC; -+ break; -+ } -+ -+ if ((buf = ibuf_dynamic(0, UINT_MAX)) == NULL) { -+ log_warn("mrt_dump_entry: ibuf_dynamic"); -+ return (-1); -+ } -+ -+ DUMP_LONG(buf, snum); -+ pt_getaddr(re->prefix, &addr); -+ if (subtype == MRT_DUMP_V2_RIB_GENERIC) { -+ u_int16_t afi; -+ u_int8_t safi; -+ -+ aid2afi(re->prefix->aid, &afi, &safi); -+ DUMP_SHORT(buf, afi); -+ DUMP_BYTE(buf, safi); -+ } -+ if (prefix_writebuf(buf, &addr, re->prefix->prefixlen) == -1) { -+ log_warn("mrt_dump_entry_mp: prefix_writebuf error"); -+ goto fail; -+ } -+ -+ off = ibuf_size(buf); -+ if (ibuf_reserve(buf, sizeof(nump)) == NULL) { -+ log_warn("mrt_dump_v2_hdr: ibuf_reserve error"); -+ goto fail; -+ } -+ nump = 0; -+ LIST_FOREACH(p, &re->prefix_h, rib_l) { -+ struct bgpd_addr *nh; -+ struct ibuf *tbuf; -+ -+ if (p->aspath->nexthop == NULL) { -+ bzero(&addr, sizeof(struct bgpd_addr)); -+ addr.aid = p->prefix->aid; -+ nh = &addr; -+ } else -+ nh = &p->aspath->nexthop->exit_nexthop; -+ -+ DUMP_SHORT(buf, p->aspath->peer->mrt_idx); -+ DUMP_LONG(buf, p->lastchange); /* originated */ -+ -+ if ((tbuf = ibuf_dynamic(0, MAX_PKTSIZE)) == NULL) { -+ log_warn("mrt_dump_entry_v2: ibuf_dynamic"); -+ return (-1); -+ } -+ if (mrt_attr_dump(tbuf, p->aspath, nh, 1) == -1) { -+ log_warnx("mrt_dump_entry_v2: mrt_attr_dump error"); -+ ibuf_free(buf); -+ return (-1); -+ } -+ len = ibuf_size(tbuf); -+ DUMP_SHORT(buf, (u_int16_t)len); -+ if (ibuf_add(buf, tbuf->buf, ibuf_size(tbuf)) == -1) { -+ log_warn("mrt_dump_entry_v2: ibuf_add error"); -+ ibuf_free(tbuf); -+ return (-1); -+ } -+ ibuf_free(tbuf); -+ nump++; -+ } -+ nump = htons(nump); -+ memcpy(ibuf_seek(buf, off, sizeof(nump)), &nump, sizeof(nump)); -+ -+ len = ibuf_size(buf); -+ if (mrt_dump_hdr_rde(&hbuf, MSG_TABLE_DUMP_V2, subtype, len) == -1) { -+ ibuf_free(buf); -+ return (-1); -+ } -+ -+ ibuf_close(&mrt->wbuf, hbuf); -+ ibuf_close(&mrt->wbuf, buf); -+ -+ return (0); -+fail: -+ if (hbuf) -+ ibuf_free(hbuf); -+ ibuf_free(buf); -+ return (-1); -+} -+ -+int -+mrt_dump_v2_hdr(struct mrt *mrt, struct bgpd_config *conf, -+ struct rde_peer_head *ph) -+{ -+ struct rde_peer *peer; -+ struct ibuf *buf, *hbuf = NULL; -+ size_t len, off; -+ u_int16_t nlen, nump; -+ -+ if ((buf = ibuf_dynamic(0, UINT_MAX)) == NULL) { -+ log_warn("mrt_dump_v2_hdr: ibuf_dynamic"); -+ return (-1); -+ } -+ -+ DUMP_NLONG(buf, conf->bgpid); -+ nlen = strlen(mrt->rib); -+ if (nlen > 0) -+ nlen += 1; -+ DUMP_SHORT(buf, nlen); -+ if (ibuf_add(buf, mrt->rib, nlen) == -1) { -+ log_warn("mrt_dump_v2_hdr: ibuf_add error"); -+ goto fail; -+ } -+ -+ off = ibuf_size(buf); -+ if (ibuf_reserve(buf, sizeof(nump)) == NULL) { -+ log_warn("mrt_dump_v2_hdr: ibuf_reserve error"); -+ goto fail; -+ } -+ nump = 0; -+ LIST_FOREACH(peer, ph, peer_l) { -+ peer->mrt_idx = nump; -+ if (mrt_dump_peer(buf, peer) == -1) -+ goto fail; -+ nump++; -+ } -+ nump = htons(nump); -+ memcpy(ibuf_seek(buf, off, sizeof(nump)), &nump, sizeof(nump)); -+ -+ len = ibuf_size(buf); -+ if (mrt_dump_hdr_rde(&hbuf, MSG_TABLE_DUMP_V2, -+ MRT_DUMP_V2_PEER_INDEX_TABLE, len) == -1) -+ goto fail; -+ -+ ibuf_close(&mrt->wbuf, hbuf); -+ ibuf_close(&mrt->wbuf, buf); -+ -+ return (0); -+fail: -+ if (hbuf) -+ ibuf_free(hbuf); -+ ibuf_free(buf); -+ return (-1); -+} -+ -+int -+mrt_dump_peer(struct ibuf *buf, struct rde_peer *peer) -+{ -+ u_int8_t type = 0; -+ -+ if (peer->capa.as4byte) -+ type |= MRT_DUMP_V2_PEER_BIT_A; -+ if (peer->remote_addr.aid == AID_INET6) -+ type |= MRT_DUMP_V2_PEER_BIT_I; -+ -+ DUMP_BYTE(buf, type); -+ DUMP_LONG(buf, peer->remote_bgpid); -+ -+ switch (peer->remote_addr.aid) { -+ case AID_INET: -+ DUMP_NLONG(buf, peer->remote_addr.v4.s_addr); -+ break; -+ case AID_INET6: -+ if (ibuf_add(buf, &peer->remote_addr.v6, -+ sizeof(struct in6_addr)) == -1) { -+ log_warn("mrt_dump_peer: ibuf_add error"); -+ goto fail; -+ } -+ break; -+ case AID_UNSPEC: /* XXX special handling for peer_self? */ -+ DUMP_NLONG(buf, 0); -+ break; -+ default: -+ log_warnx("king bula found new AF in mrt_dump_entry_mp"); -+ goto fail; -+ } -+ -+ if (peer->capa.as4byte) -+ DUMP_LONG(buf, peer->conf.remote_as); -+ else -+ DUMP_SHORT(buf, peer->short_as); -+ -+ return (0); -+fail: - return (-1); - } - -@@ -371,6 +641,11 @@ mrt_dump_upcall(struct rib_entry *re, vo - struct mrt *mrtbuf = ptr; - struct prefix *p; - -+ if (mrtbuf->type == MRT_TABLE_DUMP_V2) { -+ mrt_dump_entry_v2(mrtbuf, re, mrtbuf->seqnum++); -+ return; -+ } -+ - /* - * dump all prefixes even the inactive ones. That is the way zebra - * dumps the table so we do the same. If only the active route should -@@ -387,7 +662,7 @@ mrt_dump_upcall(struct rib_entry *re, vo - } - - void --mrt_dump_done(void *ptr) -+mrt_done(void *ptr) - { - struct mrt *mrtbuf = ptr; - -@@ -395,14 +670,14 @@ mrt_dump_done(void *ptr) - } - - int --mrt_dump_hdr_se(struct buf ** bp, struct peer *peer, u_int16_t type, -+mrt_dump_hdr_se(struct ibuf ** bp, struct peer *peer, u_int16_t type, - u_int16_t subtype, u_int32_t len, int swap) - { - time_t now; - -- if ((*bp = buf_dynamic(MRT_HEADER_SIZE, MRT_HEADER_SIZE + -+ if ((*bp = ibuf_dynamic(MRT_HEADER_SIZE, MRT_HEADER_SIZE + - MRT_BGP4MP_AS4_IPv6_HEADER_SIZE + len)) == NULL) { -- log_warnx("mrt_dump_hdr_se: buf_open error"); -+ log_warn("mrt_dump_hdr_se: ibuf_dynamic error"); - return (-1); - } - -@@ -468,23 +743,23 @@ mrt_dump_hdr_se(struct buf ** bp, struct - case AF_INET6: - DUMP_SHORT(*bp, AFI_IPv6); - if (!swap) -- if (buf_add(*bp, &((struct sockaddr_in6 *) -+ if (ibuf_add(*bp, &((struct sockaddr_in6 *) - &peer->sa_local)->sin6_addr, - sizeof(struct in6_addr)) == -1) { -- log_warnx("mrt_dump_hdr_se: buf_add error"); -+ log_warn("mrt_dump_hdr_se: ibuf_add error"); - goto fail; - } -- if (buf_add(*bp, -+ if (ibuf_add(*bp, - &((struct sockaddr_in6 *)&peer->sa_remote)->sin6_addr, - sizeof(struct in6_addr)) == -1) { -- log_warnx("mrt_dump_hdr_se: buf_add error"); -+ log_warn("mrt_dump_hdr_se: ibuf_add error"); - goto fail; - } - if (swap) -- if (buf_add(*bp, &((struct sockaddr_in6 *) -+ if (ibuf_add(*bp, &((struct sockaddr_in6 *) - &peer->sa_local)->sin6_addr, - sizeof(struct in6_addr)) == -1) { -- log_warnx("mrt_dump_hdr_se: buf_add error"); -+ log_warn("mrt_dump_hdr_se: ibuf_add error"); - goto fail; - } - break; -@@ -493,20 +768,20 @@ mrt_dump_hdr_se(struct buf ** bp, struct - return (0); - - fail: -- buf_free(*bp); -+ ibuf_free(*bp); - return (-1); - } - - int --mrt_dump_hdr_rde(struct buf **bp, u_int16_t type, u_int16_t subtype, -+mrt_dump_hdr_rde(struct ibuf **bp, u_int16_t type, u_int16_t subtype, - u_int32_t len) - { - time_t now; - -- if ((*bp = buf_dynamic(MRT_HEADER_SIZE, MRT_HEADER_SIZE + -+ if ((*bp = ibuf_dynamic(MRT_HEADER_SIZE, MRT_HEADER_SIZE + - MRT_BGP4MP_AS4_IPv6_HEADER_SIZE + MRT_BGP4MP_IPv6_ENTRY_SIZE)) == - NULL) { -- log_warnx("mrt_dump_hdr_rde: buf_dynamic error"); -+ log_warn("mrt_dump_hdr_rde: ibuf_dynamic error"); - return (-1); - } - -@@ -517,19 +792,28 @@ mrt_dump_hdr_rde(struct buf **bp, u_int1 - - switch (type) { - case MSG_TABLE_DUMP: -- DUMP_LONG(*bp, MRT_DUMP_HEADER_SIZE + len); -+ switch (subtype) { -+ case AFI_IPv4: -+ len += MRT_DUMP_HEADER_SIZE; -+ break; -+ case AFI_IPv6: -+ len += MRT_DUMP_HEADER_SIZE_V6; -+ break; -+ } -+ DUMP_LONG(*bp, len); - break; - case MSG_PROTOCOL_BGP4MP: -+ case MSG_TABLE_DUMP_V2: - DUMP_LONG(*bp, len); - break; - default: - log_warnx("mrt_dump_hdr_rde: unsupported type"); - goto fail; -- } -+ } - return (0); - - fail: -- buf_free(*bp); -+ ibuf_free(*bp); - return (-1); - } - -@@ -538,21 +822,22 @@ mrt_write(struct mrt *mrt) - { - int r; - -- if ((r = buf_write(&mrt->wbuf)) < 0) { -+ if ((r = ibuf_write(&mrt->wbuf)) < 0) { - log_warn("mrt dump aborted, mrt_write"); - mrt_clean(mrt); -+ mrt_done(mrt); - } - } - - void - mrt_clean(struct mrt *mrt) - { -- struct buf *b; -+ struct ibuf *b; - - close(mrt->wbuf.fd); - while ((b = TAILQ_FIRST(&mrt->wbuf.bufs))) { - TAILQ_REMOVE(&mrt->wbuf.bufs, b, entry); -- buf_free(b); -+ ibuf_free(b); - } - mrt->wbuf.queued = 0; - } -@@ -590,7 +875,8 @@ mrt_open(struct mrt *mrt, time_t now) - else - type = IMSG_MRT_REOPEN; - -- if (mrt->type == MRT_TABLE_DUMP || mrt->type == MRT_TABLE_DUMP_MP) -+ if (mrt->type == MRT_TABLE_DUMP || mrt->type == MRT_TABLE_DUMP_MP || -+ mrt->type == MRT_TABLE_DUMP_V2) - i = 0; - - if (imsg_compose(mrt_imsgbuf[i], type, 0, 0, fd, -@@ -659,7 +945,9 @@ mrt_handler(struct mrt_head *mrt) - LIST_FOREACH(m, mrt, entry) { - if (m->state == MRT_STATE_RUNNING && - (MRT2MC(m)->ReopenTimerInterval != 0 || -- m->type == MRT_TABLE_DUMP)) { -+ m->type == MRT_TABLE_DUMP || -+ m->type == MRT_TABLE_DUMP_MP || -+ m->type == MRT_TABLE_DUMP_V2)) { - if (mrt_open(m, now) == -1) - continue; - MRT2MC(m)->ReopenTimer = |