diff options
author | Hiroki Sato <hrs@FreeBSD.org> | 2010-02-16 19:27:03 +0000 |
---|---|---|
committer | Hiroki Sato <hrs@FreeBSD.org> | 2010-02-16 19:27:03 +0000 |
commit | 7ab9a19af615666cef45e1b4538c8460d19e1ec0 (patch) | |
tree | 301a68c22691daf3b616754a383cd1730c23dae7 /net/openbgpd/files/patch-bgpd_mrt.c | |
parent | Add updating instructions for sysutils/bacula-{server,client}. (diff) |
Update to 4.6.20100215.
Feature safe: yes
Notes
Notes:
svn path=/head/; revision=249966
Diffstat (limited to 'net/openbgpd/files/patch-bgpd_mrt.c')
-rw-r--r-- | net/openbgpd/files/patch-bgpd_mrt.c | 1038 |
1 files changed, 79 insertions, 959 deletions
diff --git a/net/openbgpd/files/patch-bgpd_mrt.c b/net/openbgpd/files/patch-bgpd_mrt.c index e7cad7121912..c35359ac5f39 100644 --- a/net/openbgpd/files/patch-bgpd_mrt.c +++ b/net/openbgpd/files/patch-bgpd_mrt.c @@ -1,1002 +1,122 @@ Index: bgpd/mrt.c =================================================================== RCS file: /home/cvs/private/hrs/openbgpd/bgpd/mrt.c,v -retrieving revision 1.1.1.1 -retrieving revision 1.1.1.3 -diff -u -p -r1.1.1.1 -r1.1.1.3 ---- bgpd/mrt.c 30 Jun 2009 05:46:15 -0000 1.1.1.1 -+++ bgpd/mrt.c 10 Aug 2009 21:09:57 -0000 1.1.1.3 +retrieving revision 1.1.1.7 +retrieving revision 1.1.1.8 +diff -u -p -r1.1.1.7 -r1.1.1.8 +--- bgpd/mrt.c 14 Feb 2010 20:19:57 -0000 1.1.1.7 ++++ bgpd/mrt.c 14 Feb 2010 20:27:06 -0000 1.1.1.8 @@ -1,4 +1,4 @@ --/* $OpenBSD: mrt.c,v 1.53 2007/04/23 13:04:24 claudio Exp $ */ -+/* $OpenBSD: mrt.c,v 1.64 2009/07/12 15:36:41 jsg Exp $ */ +-/* $OpenBSD: mrt.c,v 1.63 2009/06/29 12:22:16 claudio Exp $ */ ++/* $OpenBSD: mrt.c,v 1.66 2009/12/01 14:28:05 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> -@@ -32,24 +32,21 @@ - - #include "mrt.h" - --static u_int16_t mrt_attr_length(struct rde_aspath *, int); --static int mrt_attr_dump(void *, u_int16_t, struct rde_aspath *, -- struct bgpd_addr *); --static int mrt_dump_entry_mp(struct mrt *, struct prefix *, -- u_int16_t, struct rde_peer*); --static int mrt_dump_entry(struct mrt *, struct prefix *, -- u_int16_t, struct rde_peer*); --static int mrt_dump_header(struct buf *, u_int16_t, u_int16_t, -- u_int32_t); --static int mrt_open(struct mrt *, time_t); -+int mrt_attr_dump(struct buf *, struct rde_aspath *, struct bgpd_addr *); -+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, -+ u_int32_t, int); -+int mrt_dump_hdr_rde(struct buf **, 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"); \ -- buf_free((x)); \ -- return (-1); \ -+ goto fail; \ - } \ - } while (0) - -@@ -59,8 +56,7 @@ static int mrt_open(struct mrt *, time_ - t = htons((s)); \ - if (buf_add((x), &t, sizeof(t)) == -1) { \ - log_warnx("mrt_dump2: buf_add error"); \ -- buf_free((x)); \ -- return (-1); \ -+ goto fail; \ - } \ - } while (0) - -@@ -70,8 +66,7 @@ static int mrt_open(struct mrt *, time_ - t = htonl((l)); \ - if (buf_add((x), &t, sizeof(t)) == -1) { \ - log_warnx("mrt_dump3: buf_add error"); \ -- buf_free((x)); \ -- return (-1); \ -+ goto fail; \ - } \ - } while (0) - -@@ -80,327 +75,175 @@ static int mrt_open(struct mrt *, time_ - u_int32_t t = (l); \ - if (buf_add((x), &t, sizeof(t)) == -1) { \ - log_warnx("mrt_dump4: buf_add error"); \ -- buf_free((x)); \ -- return (-1); \ -+ goto fail; \ - } \ - } while (0) - --int -+void - mrt_dump_bgp_msg(struct mrt *mrt, void *pkg, u_int16_t pkglen, -- struct peer *peer, struct bgpd_config *bgp) -+ struct peer *peer) - { - struct buf *buf; -- u_int16_t len; - int incoming = 0; - -- switch (peer->sa_local.ss_family) { -- case AF_INET: -- len = pkglen + MRT_BGP4MP_IPv4_HEADER_SIZE; -- break; -- case AF_INET6: -- len = pkglen + MRT_BGP4MP_IPv6_HEADER_SIZE; -- break; -- default: -- return (-1); -- } -- - /* 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 ((buf = buf_open(len + MRT_HEADER_SIZE)) == NULL) { -- log_warnx("mrt_dump_bgp_msg: buf_open error"); -- return (-1); -- } -- -- if (mrt_dump_header(buf, MSG_PROTOCOL_BGP4MP, BGP4MP_MESSAGE, -- len) == -1) { -- log_warnx("mrt_dump_bgp_msg: buf_add error"); -- return (-1); -- } -- -- if (!incoming) -- DUMP_SHORT(buf, bgp->short_as); -- DUMP_SHORT(buf, peer->short_as); -- if (incoming) -- DUMP_SHORT(buf, bgp->short_as); -- DUMP_SHORT(buf, /* ifindex */ 0); -- switch (peer->sa_local.ss_family) { -- case AF_INET: -- DUMP_SHORT(buf, AFI_IPv4); -- if (!incoming) -- DUMP_NLONG(buf, ((struct sockaddr_in *) -- &peer->sa_local)->sin_addr.s_addr); -- DUMP_NLONG(buf, -- ((struct sockaddr_in *)&peer->sa_remote)->sin_addr.s_addr); -- if (incoming) -- DUMP_NLONG(buf, ((struct sockaddr_in *) -- &peer->sa_local)->sin_addr.s_addr); -- break; -- case AF_INET6: -- DUMP_SHORT(buf, AFI_IPv6); -- if (!incoming) -- if (buf_add(buf, &((struct sockaddr_in6 *) -- &peer->sa_local)->sin6_addr, -- sizeof(struct in6_addr)) == -1) { -- log_warnx("mrt_dump_bgp_msg: buf_add error"); -- buf_free(buf); -- return (-1); -- } -- if (buf_add(buf, -- &((struct sockaddr_in6 *)&peer->sa_remote)->sin6_addr, -- sizeof(struct in6_addr)) == -1) { -- log_warnx("mrt_dump_bgp_msg: buf_add error"); -- buf_free(buf); -- return (-1); -- } -- if (incoming) -- if (buf_add(buf, &((struct sockaddr_in6 *) -- &peer->sa_local)->sin6_addr, -- sizeof(struct in6_addr)) == -1) { -- log_warnx("mrt_dump_bgp_msg: buf_add error"); -- buf_free(buf); -- return (-1); -- } -- break; -- } -+ if (mrt_dump_hdr_se(&buf, peer, MSG_PROTOCOL_BGP4MP, BGP4MP_MESSAGE, -+ pkglen, incoming) == -1) -+ return; - - if (buf_add(buf, pkg, pkglen) == -1) { - log_warnx("mrt_dump_bgp_msg: buf_add error"); - buf_free(buf); -- return (-1); -+ return; - } - -- TAILQ_INSERT_TAIL(&mrt->bufs, buf, entry); -- mrt->queued++; -- -- return (len + MRT_HEADER_SIZE); -+ buf_close(&mrt->wbuf, buf); - } - --int -+void - mrt_dump_state(struct mrt *mrt, u_int16_t old_state, u_int16_t new_state, -- struct peer *peer, struct bgpd_config *bgp) -+ struct peer *peer) - { - struct buf *buf; -- u_int16_t len; -- -- switch (peer->sa_local.ss_family) { -- case AF_INET: -- len = 4 + MRT_BGP4MP_IPv4_HEADER_SIZE; -- break; -- case AF_INET6: -- len = 4 + MRT_BGP4MP_IPv6_HEADER_SIZE; -- break; -- default: -- return (-1); -- } -- -- if ((buf = buf_open(len + MRT_HEADER_SIZE)) == NULL) { -- log_warnx("mrt_dump_bgp_state: buf_open error"); -- return (-1); -- } - -- if (mrt_dump_header(buf, MSG_PROTOCOL_BGP4MP, BGP4MP_STATE_CHANGE, -- len) == -1) { -- log_warnx("mrt_dump_bgp_state: buf_add error"); -- return (-1); -- } -- -- DUMP_SHORT(buf, bgp->short_as); -- DUMP_SHORT(buf, peer->short_as); -- DUMP_SHORT(buf, /* ifindex */ 0); -- switch (peer->sa_local.ss_family) { -- case AF_INET: -- DUMP_SHORT(buf, AFI_IPv4); -- DUMP_NLONG(buf, -- ((struct sockaddr_in *)&peer->sa_local)->sin_addr.s_addr); -- DUMP_NLONG(buf, -- ((struct sockaddr_in *)&peer->sa_remote)->sin_addr.s_addr); -- break; -- case AF_INET6: -- DUMP_SHORT(buf, AFI_IPv6); -- if (buf_add(buf, -- &((struct sockaddr_in6 *)&peer->sa_local)->sin6_addr, -- sizeof(struct in6_addr)) == -1 || -- buf_add(buf, -- &((struct sockaddr_in6 *)&peer->sa_remote)->sin6_addr, -- sizeof(struct in6_addr)) == -1) { -- log_warnx("mrt_dump_bgp_msg: buf_add error"); -- buf_free(buf); -- return (-1); -- } -- break; -- } -+ if (mrt_dump_hdr_se(&buf, peer, MSG_PROTOCOL_BGP4MP, BGP4MP_MESSAGE, -+ 2 * sizeof(short), 0) == -1) -+ return; - - DUMP_SHORT(buf, old_state); - DUMP_SHORT(buf, new_state); - -- TAILQ_INSERT_TAIL(&mrt->bufs, buf, entry); -- mrt->queued++; -- -- return (len + MRT_HEADER_SIZE); --} -- --static u_int16_t --mrt_attr_length(struct rde_aspath *a, int oldform) --{ -- u_int16_t alen, plen; -- u_int8_t l; -+ buf_close(&mrt->wbuf, buf); -+ return; - -- alen = 4 /* origin */ + 7 /* lpref */; -- if (oldform) -- alen += 7 /* nexthop */; -- plen = aspath_length(a->aspath); -- alen += 2 + plen + (plen > 255 ? 2 : 1); -- if (a->med != 0) -- alen += 7; -- -- for (l = 0; l < a->others_len; l++) -- if (a->others[l] != NULL) -- alen += 2 + a->others[l]->len + -- (a->others[l]->len > 255 ? 2 : 1); -- else -- break; -- -- return alen; -+fail: -+ buf_free(buf); - } - --static int --mrt_attr_dump(void *p, u_int16_t len, struct rde_aspath *a, -- struct bgpd_addr *nexthop) -+int -+mrt_attr_dump(struct buf *buf, struct rde_aspath *a, struct bgpd_addr *nexthop) - { - struct attr *oa; -- u_char *buf = p; -- u_int32_t tmp32; -- int r; -- u_int16_t aslen, wlen = 0; -+ u_char *pdata; -+ u_int32_t tmp; -+ int neednewpath = 0; -+ u_int16_t plen; - u_int8_t l; - - /* origin */ -- if ((r = attr_write(buf + wlen, len, ATTR_WELL_KNOWN, ATTR_ORIGIN, -- &a->origin, 1)) == -1) -+ if (attr_writebuf(buf, ATTR_WELL_KNOWN, ATTR_ORIGIN, -+ &a->origin, 1) == -1) - return (-1); -- wlen += r; len -= r; - - /* aspath */ -- aslen = aspath_length(a->aspath); -- if ((r = attr_write(buf + wlen, len, ATTR_WELL_KNOWN, ATTR_ASPATH, -- aspath_dump(a->aspath), aslen)) == -1) -+ 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) - return (-1); -- wlen += r; len -= r; -+ free(pdata); - - if (nexthop) { - /* nexthop, already network byte order */ -- if ((r = attr_write(buf + wlen, len, ATTR_WELL_KNOWN, -- ATTR_NEXTHOP, &nexthop->v4.s_addr, 4)) == -1) -+ if (attr_writebuf(buf, ATTR_WELL_KNOWN, ATTR_NEXTHOP, -+ &nexthop->v4.s_addr, 4) == -1) - return (-1); -- wlen += r; len -= r; - } - - /* MED, non transitive */ - if (a->med != 0) { -- tmp32 = htonl(a->med); -- if ((r = attr_write(buf + wlen, len, ATTR_OPTIONAL, ATTR_MED, -- &tmp32, 4)) == -1) -+ tmp = htonl(a->med); -+ if (attr_writebuf(buf, ATTR_OPTIONAL, ATTR_MED, &tmp, 4) == -1) - return (-1); -- wlen += r; len -= r; - } - - /* local preference, only valid for ibgp */ -- tmp32 = htonl(a->lpref); -- if ((r = attr_write(buf + wlen, len, ATTR_WELL_KNOWN, ATTR_LOCALPREF, -- &tmp32, 4)) == -1) -+ tmp = htonl(a->lpref); -+ if (attr_writebuf(buf, ATTR_WELL_KNOWN, ATTR_LOCALPREF, &tmp, 4) == -1) - return (-1); -- wlen += r; len -= r; - - /* dump all other path attributes without modification */ - for (l = 0; l < a->others_len; l++) { - if ((oa = a->others[l]) == NULL) - break; -- if ((r = attr_write(buf + wlen, len, oa->flags, oa->type, -- oa->data, oa->len)) == -1) -+ if (attr_writebuf(buf, oa->flags, oa->type, -+ oa->data, oa->len) == -1) - return (-1); -- wlen += r; len -= r; - } - -- return (wlen); -+ 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) -+ return (-1); -+ free(pdata); -+ } -+ -+ return (0); - } - --static int -+int - mrt_dump_entry_mp(struct mrt *mrt, struct prefix *p, u_int16_t snum, - struct rde_peer *peer) - { -- struct buf *buf; -+ struct buf *buf, *hbuf = NULL, *h2buf = NULL; - void *bptr; +@@ -194,7 +194,7 @@ mrt_dump_entry_mp(struct mrt *mrt, struc struct bgpd_addr addr, nexthop, *nh; -- u_int16_t len, attr_len; -+ u_int16_t len; + u_int16_t len; u_int8_t p_len; - sa_family_t af; +- sa_family_t af; ++ u_int8_t aid; -- attr_len = mrt_attr_length(p->aspath, 0); -- p_len = PREFIX_SIZE(p->prefix->prefixlen); -- pt_getaddr(p->prefix, &addr); -- -- af = peer->remote_addr.af == 0 ? addr.af : peer->remote_addr.af; + if ((buf = buf_dynamic(0, MAX_PKTSIZE)) == NULL) { + log_warn("mrt_dump_entry_mp: buf_dynamic"); +@@ -219,14 +219,15 @@ 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: -- len = MRT_BGP4MP_IPv4_HEADER_SIZE; -- break; -- case AF_INET6: -- len = MRT_BGP4MP_IPv6_HEADER_SIZE; -- break; -- default: -- return (-1); -- } -- -- switch (addr.af) { -- case AF_INET: -- len += MRT_BGP4MP_IPv4_ENTRY_SIZE + p_len + attr_len; -- break; -- case AF_INET6: -- len += MRT_BGP4MP_IPv4_ENTRY_SIZE + p_len + attr_len; -- break; -- default: -+ if ((buf = buf_dynamic(0, MAX_PKTSIZE)) == NULL) { -+ log_warn("mrt_dump_entry_mp: buf_dynamic"); - return (-1); - } - -- if ((buf = buf_open(len + MRT_HEADER_SIZE)) == NULL) { -- log_warnx("mrt_dump_entry_mp: buf_open error"); -- return (-1); -+ if (mrt_attr_dump(buf, p->aspath, NULL) == -1) { -+ log_warnx("mrt_dump_entry_mp: mrt_attr_dump error"); -+ goto fail; - } -+ len = buf_size(buf); - -- if (mrt_dump_header(buf, MSG_PROTOCOL_BGP4MP, BGP4MP_ENTRY, -- len) == -1) { -- log_warnx("mrt_dump_entry_mp: buf_add error"); -- return (-1); -+ if ((h2buf = buf_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"); -+ goto fail; - } - -- DUMP_SHORT(buf, rde_local_as()); -- DUMP_SHORT(buf, peer->short_as); -- DUMP_SHORT(buf, /* ifindex */ 0); -+ DUMP_SHORT(h2buf, rde_local_as()); -+ DUMP_SHORT(h2buf, peer->short_as); -+ 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: -- DUMP_SHORT(buf, AFI_IPv4); -- DUMP_NLONG(buf, peer->local_v4_addr.v4.s_addr); -- DUMP_NLONG(buf, peer->remote_addr.v4.s_addr); -+ DUMP_SHORT(h2buf, AFI_IPv4); -+ DUMP_NLONG(h2buf, peer->local_v4_addr.v4.s_addr); -+ DUMP_NLONG(h2buf, peer->remote_addr.v4.s_addr); ++ 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: -- DUMP_SHORT(buf, AFI_IPv6); -- if (buf_add(buf, &peer->local_v6_addr.v6, -+ DUMP_SHORT(h2buf, AFI_IPv6); -+ if (buf_add(h2buf, &peer->local_v6_addr.v6, +- case AF_INET6: ++ case AID_INET6: + DUMP_SHORT(h2buf, AFI_IPv6); + if (buf_add(h2buf, &peer->local_v6_addr.v6, sizeof(struct in6_addr)) == -1 || -- buf_add(buf, &peer->remote_addr.v6, -+ buf_add(h2buf, &peer->remote_addr.v6, - sizeof(struct in6_addr)) == -1) { - log_warnx("mrt_dump_entry_mp: buf_add error"); -- buf_free(buf); -- return (-1); -+ goto fail; +@@ -237,7 +238,7 @@ mrt_dump_entry_mp(struct mrt *mrt, struc } break; -+ default: -+ log_warnx("king bula found new AF %d in mrt_dump_entry_mp", af); -+ goto fail; + 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; } -- DUMP_SHORT(buf, 0); /* view */ -- DUMP_SHORT(buf, 1); /* status */ -- DUMP_LONG(buf, p->lastchange); /* originated */ -+ DUMP_SHORT(h2buf, 0); /* view */ -+ DUMP_SHORT(h2buf, 1); /* status */ -+ DUMP_LONG(h2buf, p->lastchange); /* originated */ +@@ -247,20 +248,20 @@ mrt_dump_entry_mp(struct mrt *mrt, struc if (p->aspath->nexthop == NULL) { bzero(&nexthop, sizeof(struct bgpd_addr)); -@@ -409,95 +252,74 @@ mrt_dump_entry_mp(struct mrt *mrt, struc +- 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: -- DUMP_SHORT(buf, AFI_IPv4); /* afi */ -- DUMP_BYTE(buf, SAFI_UNICAST); /* safi */ -- DUMP_BYTE(buf, 4); /* nhlen */ -- DUMP_NLONG(buf, nh->v4.s_addr); /* nexthop */ -+ 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: -- DUMP_SHORT(buf, AFI_IPv6); /* afi */ -- DUMP_BYTE(buf, SAFI_UNICAST); /* safi */ -- DUMP_BYTE(buf, 16); /* nhlen */ -- if (buf_add(buf, &nh->v6, sizeof(struct in6_addr)) == -1) { -+ 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"); -- buf_free(buf); -- return (-1); -+ goto fail; - } + 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; -+ default: -+ log_warnx("king bula found new AF in mrt_dump_entry_mp"); -+ goto fail; - } - -- if ((bptr = buf_reserve(buf, p_len)) == NULL) { -+ p_len = PREFIX_SIZE(p->prefix->prefixlen); -+ if ((bptr = buf_reserve(h2buf, p_len)) == NULL) { - log_warnx("mrt_dump_entry_mp: buf_reserve error"); -- buf_free(buf); -- return (-1); -+ goto fail; - } - if (prefix_write(bptr, p_len, &addr, p->prefix->prefixlen) == -1) { - log_warnx("mrt_dump_entry_mp: prefix_write error"); -- buf_free(buf); -- return (-1); -+ goto fail; - } - -- DUMP_SHORT(buf, attr_len); -- if ((bptr = buf_reserve(buf, attr_len)) == NULL) { -- log_warnx("mrt_dump_entry_mp: buf_reserve error"); -- buf_free(buf); -- return (-1); -- } -+ DUMP_SHORT(h2buf, len); -+ len += buf_size(h2buf); - -- if (mrt_attr_dump(bptr, attr_len, p->aspath, NULL) == -1) { -- log_warnx("mrt_dump_entry_mp: mrt_attr_dump error"); -- buf_free(buf); -- return (-1); -- } -+ if (mrt_dump_hdr_rde(&hbuf, MSG_PROTOCOL_BGP4MP, BGP4MP_ENTRY, -+ len) == -1) -+ goto fail; - -- TAILQ_INSERT_TAIL(&mrt->bufs, buf, entry); -- mrt->queued++; -+ buf_close(&mrt->wbuf, hbuf); -+ buf_close(&mrt->wbuf, h2buf); -+ buf_close(&mrt->wbuf, buf); - - return (len + MRT_HEADER_SIZE); -+ -+fail: -+ if (hbuf) -+ buf_free(hbuf); +- case AF_INET6: ++ case AID_INET6: + DUMP_SHORT(h2buf, AFI_IPv6); /* afi */ + DUMP_BYTE(h2buf, SAFI_UNICAST); /* safi */ + DUMP_BYTE(h2buf, 16); /* nhlen */ +@@ -300,7 +301,7 @@ mrt_dump_entry_mp(struct mrt *mrt, struc + fail: + if (hbuf) + buf_free(hbuf); +- if (h2buf); + if (h2buf) -+ buf_free(h2buf); -+ buf_free(buf); -+ return (-1); - } - --static int -+int - mrt_dump_entry(struct mrt *mrt, struct prefix *p, u_int16_t snum, - struct rde_peer *peer) - { -- struct buf *buf; -- void *bptr; -+ struct buf *buf, *hbuf; + buf_free(h2buf); + buf_free(buf); + return (-1); +@@ -314,7 +315,8 @@ mrt_dump_entry(struct mrt *mrt, struct p struct bgpd_addr addr, *nh; -- u_int16_t len, attr_len; -+ size_t len; + size_t len; - if (p->prefix->af != AF_INET && peer->remote_addr.af == AF_INET) -- /* only for true IPv4 */ -+ /* only able to dump IPv4 */ +- if (p->prefix->af != AF_INET && peer->remote_addr.af == AF_INET) ++ if (p->prefix->aid != AID_INET && ++ peer->remote_addr.aid == AID_INET) + /* only able to dump IPv4 */ return (0); -- attr_len = mrt_attr_length(p->aspath, 1); -- len = MRT_DUMP_HEADER_SIZE + attr_len; -- pt_getaddr(p->prefix, &addr); -- -- if ((buf = buf_open(len + MRT_HEADER_SIZE)) == NULL) { -- log_warnx("mrt_dump_entry: buf_open error"); -- return (-1); -- } -- -- if (mrt_dump_header(buf, MSG_TABLE_DUMP, AFI_IPv4, len) == -1) { -- log_warnx("mrt_dump_entry: buf_add error"); -- return (-1); -- } -- -- DUMP_SHORT(buf, 0); -- DUMP_SHORT(buf, snum); -- DUMP_NLONG(buf, addr.v4.s_addr); -- DUMP_BYTE(buf, p->prefix->prefixlen); -- DUMP_BYTE(buf, 1); /* state */ -- DUMP_LONG(buf, p->lastchange); /* originated */ -- DUMP_NLONG(buf, peer->remote_addr.v4.s_addr); -- DUMP_SHORT(buf, peer->short_as); -- -- DUMP_SHORT(buf, attr_len); -- if ((bptr = buf_reserve(buf, attr_len)) == NULL) { -- log_warnx("mrt_dump_entry: buf_reserve error"); -- buf_free(buf); -+ if ((buf = buf_dynamic(0, MAX_PKTSIZE)) == NULL) { -+ log_warnx("mrt_dump_entry: buf_dynamic"); - return (-1); - } +@@ -325,7 +327,7 @@ mrt_dump_entry(struct mrt *mrt, struct p -@@ -507,28 +329,44 @@ mrt_dump_entry(struct mrt *mrt, struct p + if (p->aspath->nexthop == NULL) { + bzero(&addr, sizeof(struct bgpd_addr)); +- addr.af = AF_INET; ++ addr.aid = AID_INET; nh = &addr; } else nh = &p->aspath->nexthop->exit_nexthop; -- if (mrt_attr_dump(bptr, attr_len, p->aspath, nh) == -1) { -+ if (mrt_attr_dump(buf, p->aspath, nh) == -1) { - log_warnx("mrt_dump_entry: mrt_attr_dump error"); - buf_free(buf); - return (-1); - } -+ len = buf_size(buf); - -- TAILQ_INSERT_TAIL(&mrt->bufs, buf, entry); -- mrt->queued++; -+ if (mrt_dump_hdr_rde(&hbuf, MSG_TABLE_DUMP, AFI_IPv4, len) == -1) { -+ buf_free(buf); -+ return (-1); -+ } - -- return (len + MRT_HEADER_SIZE); --} -+ DUMP_SHORT(hbuf, 0); -+ DUMP_SHORT(hbuf, snum); - --static u_int16_t sequencenum = 0; -+ pt_getaddr(p->prefix, &addr); -+ DUMP_NLONG(hbuf, addr.v4.s_addr); -+ DUMP_BYTE(hbuf, p->prefix->prefixlen); - --void --mrt_clear_seq(void) --{ -- sequencenum = 0; -+ DUMP_BYTE(hbuf, 1); /* state */ -+ DUMP_LONG(hbuf, p->lastchange); /* originated */ -+ DUMP_NLONG(hbuf, peer->remote_addr.v4.s_addr); -+ DUMP_SHORT(hbuf, peer->short_as); -+ DUMP_SHORT(hbuf, len); -+ -+ buf_close(&mrt->wbuf, hbuf); -+ buf_close(&mrt->wbuf, buf); -+ -+ return (len + MRT_HEADER_SIZE); -+ -+fail: -+ buf_free(hbuf); -+ buf_free(buf); -+ return (-1); +@@ -387,7 +389,7 @@ mrt_dump_upcall(struct rib_entry *re, vo } void --mrt_dump_upcall(struct pt_entry *pt, void *ptr) -+mrt_dump_upcall(struct rib_entry *re, void *ptr) +-mrt_dump_done(void *ptr) ++mrt_done(void *ptr) { struct mrt *mrtbuf = ptr; - struct prefix *p; -@@ -538,53 +376,172 @@ mrt_dump_upcall(struct pt_entry *pt, voi - * dumps the table so we do the same. If only the active route should - * be dumped p should be set to p = pt->active. - */ -- LIST_FOREACH(p, &pt->prefix_h, prefix_l) { -- /* for now dump only stuff from the local-RIB */ -- if (!(p->flags & F_LOCAL)) -- continue; -+ LIST_FOREACH(p, &re->prefix_h, rib_l) { - if (mrtbuf->type == MRT_TABLE_DUMP) -- mrt_dump_entry(mrtbuf, p, sequencenum++, -+ mrt_dump_entry(mrtbuf, p, mrtbuf->seqnum++, - p->aspath->peer); - else -- mrt_dump_entry_mp(mrtbuf, p, sequencenum++, -+ mrt_dump_entry_mp(mrtbuf, p, mrtbuf->seqnum++, - p->aspath->peer); - } - } - --static int --mrt_dump_header(struct buf *buf, u_int16_t type, u_int16_t subtype, -- u_int32_t len) -+void -+mrt_dump_done(void *ptr) -+{ -+ struct mrt *mrtbuf = ptr; -+ -+ mrtbuf->state = MRT_STATE_REMOVE; -+} -+ -+int -+mrt_dump_hdr_se(struct buf ** bp, struct peer *peer, u_int16_t type, -+ u_int16_t subtype, u_int32_t len, int swap) - { -- time_t now; -+ time_t now; -+ -+ if ((*bp = buf_dynamic(MRT_HEADER_SIZE, MRT_HEADER_SIZE + -+ MRT_BGP4MP_AS4_IPv6_HEADER_SIZE + len)) == NULL) { -+ log_warnx("mrt_dump_hdr_se: buf_open error"); -+ return (-1); -+ } - - now = time(NULL); -- DUMP_LONG(buf, now); -- DUMP_SHORT(buf, type); -- DUMP_SHORT(buf, subtype); -- DUMP_LONG(buf, len); -+ DUMP_LONG(*bp, now); -+ DUMP_SHORT(*bp, type); -+ DUMP_SHORT(*bp, subtype); -+ -+ switch (peer->sa_local.ss_family) { -+ case AF_INET: -+ if (subtype == BGP4MP_STATE_CHANGE_AS4 || -+ subtype == BGP4MP_MESSAGE_AS4) -+ len += MRT_BGP4MP_AS4_IPv4_HEADER_SIZE; -+ else -+ len += MRT_BGP4MP_IPv4_HEADER_SIZE; -+ break; -+ case AF_INET6: -+ if (subtype == BGP4MP_STATE_CHANGE_AS4 || -+ subtype == BGP4MP_MESSAGE_AS4) -+ len += MRT_BGP4MP_AS4_IPv6_HEADER_SIZE; -+ else -+ len += MRT_BGP4MP_IPv6_HEADER_SIZE; -+ break; -+ case 0: -+ goto fail; -+ default: -+ log_warnx("king bula found new AF in mrt_dump_hdr_se"); -+ goto fail; -+ } -+ -+ DUMP_LONG(*bp, len); -+ -+ if (subtype == BGP4MP_STATE_CHANGE_AS4 || -+ subtype == BGP4MP_MESSAGE_AS4) { -+ if (!swap) -+ DUMP_LONG(*bp, peer->conf.local_as); -+ DUMP_LONG(*bp, peer->conf.remote_as); -+ if (swap) -+ DUMP_LONG(*bp, peer->conf.local_as); -+ } else { -+ if (!swap) -+ DUMP_SHORT(*bp, peer->conf.local_short_as); -+ DUMP_SHORT(*bp, peer->short_as); -+ if (swap) -+ DUMP_SHORT(*bp, peer->conf.local_short_as); -+ } -+ -+ DUMP_SHORT(*bp, /* ifindex */ 0); -+ -+ switch (peer->sa_local.ss_family) { -+ case AF_INET: -+ DUMP_SHORT(*bp, AFI_IPv4); -+ if (!swap) -+ DUMP_NLONG(*bp, ((struct sockaddr_in *) -+ &peer->sa_local)->sin_addr.s_addr); -+ DUMP_NLONG(*bp, -+ ((struct sockaddr_in *)&peer->sa_remote)->sin_addr.s_addr); -+ if (swap) -+ DUMP_NLONG(*bp, ((struct sockaddr_in *) -+ &peer->sa_local)->sin_addr.s_addr); -+ break; -+ case AF_INET6: -+ DUMP_SHORT(*bp, AFI_IPv6); -+ if (!swap) -+ if (buf_add(*bp, &((struct sockaddr_in6 *) -+ &peer->sa_local)->sin6_addr, -+ sizeof(struct in6_addr)) == -1) { -+ log_warnx("mrt_dump_hdr_se: buf_add error"); -+ goto fail; -+ } -+ if (buf_add(*bp, -+ &((struct sockaddr_in6 *)&peer->sa_remote)->sin6_addr, -+ sizeof(struct in6_addr)) == -1) { -+ log_warnx("mrt_dump_hdr_se: buf_add error"); -+ goto fail; -+ } -+ if (swap) -+ if (buf_add(*bp, &((struct sockaddr_in6 *) -+ &peer->sa_local)->sin6_addr, -+ sizeof(struct in6_addr)) == -1) { -+ log_warnx("mrt_dump_hdr_se: buf_add error"); -+ goto fail; -+ } -+ break; -+ } - - return (0); -+ -+fail: -+ buf_free(*bp); -+ return (-1); - } - - int --mrt_write(struct mrt *mrt) -+mrt_dump_hdr_rde(struct buf **bp, u_int16_t type, u_int16_t subtype, -+ u_int32_t len) - { -- struct buf *b; -- int r = 0; -+ time_t now; - -- while ((b = TAILQ_FIRST(&mrt->bufs)) && -- (r = buf_write(mrt->fd, b)) == 1) { -- TAILQ_REMOVE(&mrt->bufs, b, entry); -- mrt->queued--; -- buf_free(b); -- } -- if (r <= -1) { -- log_warn("mrt dump write"); -- mrt_clean(mrt); -+ if ((*bp = buf_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"); - return (-1); +@@ -541,6 +543,7 @@ mrt_write(struct mrt *mrt) + if ((r = buf_write(&mrt->wbuf)) < 0) { + log_warn("mrt dump aborted, mrt_write"); + mrt_clean(mrt); ++ mrt_done(mrt); } -+ -+ now = time(NULL); -+ DUMP_LONG(*bp, now); -+ DUMP_SHORT(*bp, type); -+ DUMP_SHORT(*bp, subtype); -+ -+ switch (type) { -+ case MSG_TABLE_DUMP: -+ DUMP_LONG(*bp, MRT_DUMP_HEADER_SIZE + len); -+ break; -+ case MSG_PROTOCOL_BGP4MP: -+ DUMP_LONG(*bp, len); -+ break; -+ default: -+ log_warnx("mrt_dump_hdr_rde: unsupported type"); -+ goto fail; -+ } - return (0); -+ -+fail: -+ buf_free(*bp); -+ return (-1); -+} -+ -+void -+mrt_write(struct mrt *mrt) -+{ -+ int r; -+ -+ if ((r = buf_write(&mrt->wbuf)) < 0) { -+ log_warn("mrt dump aborted, mrt_write"); -+ mrt_clean(mrt); -+ } } - void -@@ -592,12 +549,12 @@ mrt_clean(struct mrt *mrt) - { - struct buf *b; - -- close(mrt->fd); -- while ((b = TAILQ_FIRST(&mrt->bufs))) { -- TAILQ_REMOVE(&mrt->bufs, b, entry); -+ close(mrt->wbuf.fd); -+ while ((b = TAILQ_FIRST(&mrt->wbuf.bufs))) { -+ TAILQ_REMOVE(&mrt->wbuf.bufs, b, entry); - buf_free(b); - } -- mrt->queued = 0; -+ mrt->wbuf.queued = 0; - } - - static struct imsgbuf *mrt_imsgbuf[2]; -@@ -613,30 +570,30 @@ int - mrt_open(struct mrt *mrt, time_t now) - { - enum imsg_type type; -- int i; -+ int i = 1, fd; - - if (strftime(MRT2MC(mrt)->file, sizeof(MRT2MC(mrt)->file), - MRT2MC(mrt)->name, localtime(&now)) == 0) { - log_warnx("mrt_open: strftime conversion failed"); -- mrt->fd = -1; - return (-1); - } - -- mrt->fd = open(MRT2MC(mrt)->file, -+ fd = open(MRT2MC(mrt)->file, - O_WRONLY|O_NONBLOCK|O_CREAT|O_TRUNC, 0644); -- if (mrt->fd == -1) { -+ if (fd == -1) { - log_warn("mrt_open %s", MRT2MC(mrt)->file); - return (1); - } - -- if (MRT2MC(mrt)->state == MRT_STATE_OPEN) -+ if (mrt->state == MRT_STATE_OPEN) - type = IMSG_MRT_OPEN; - else - type = IMSG_MRT_REOPEN; - -- i = mrt->type == MRT_TABLE_DUMP ? 0 : 1; -+ if (mrt->type == MRT_TABLE_DUMP || mrt->type == MRT_TABLE_DUMP_MP) -+ i = 0; - -- if (imsg_compose(mrt_imsgbuf[i], type, 0, 0, mrt->fd, -+ if (imsg_compose(mrt_imsgbuf[i], type, 0, 0, fd, - mrt, sizeof(struct mrt)) == -1) - log_warn("mrt_open"); - -@@ -652,7 +609,7 @@ mrt_timeout(struct mrt_head *mrt) - - now = time(NULL); - LIST_FOREACH(m, mrt, entry) { -- if (MRT2MC(m)->state == MRT_STATE_RUNNING && -+ if (m->state == MRT_STATE_RUNNING && - MRT2MC(m)->ReopenTimerInterval != 0) { - if (MRT2MC(m)->ReopenTimer <= now) { - mrt_open(m, now); -@@ -675,16 +632,16 @@ mrt_reconfigure(struct mrt_head *mrt) - now = time(NULL); - for (m = LIST_FIRST(mrt); m != NULL; m = xm) { - xm = LIST_NEXT(m, entry); -- if (MRT2MC(m)->state == MRT_STATE_OPEN || -- MRT2MC(m)->state == MRT_STATE_REOPEN) { -+ if (m->state == MRT_STATE_OPEN || -+ m->state == MRT_STATE_REOPEN) { - if (mrt_open(m, now) == -1) - continue; - if (MRT2MC(m)->ReopenTimerInterval != 0) - MRT2MC(m)->ReopenTimer = - now + MRT2MC(m)->ReopenTimerInterval; -- MRT2MC(m)->state = MRT_STATE_RUNNING; -+ m->state = MRT_STATE_RUNNING; - } -- if (MRT2MC(m)->state == MRT_STATE_REMOVE) { -+ if (m->state == MRT_STATE_REMOVE) { - LIST_REMOVE(m, entry); - free(m); - continue; -@@ -700,7 +657,7 @@ mrt_handler(struct mrt_head *mrt) - - now = time(NULL); - LIST_FOREACH(m, mrt, entry) { -- if (MRT2MC(m)->state == MRT_STATE_RUNNING && -+ if (m->state == MRT_STATE_RUNNING && - (MRT2MC(m)->ReopenTimerInterval != 0 || - m->type == MRT_TABLE_DUMP)) { - if (mrt_open(m, now) == -1) -@@ -719,8 +676,8 @@ mrt_get(struct mrt_head *c, struct mrt * - LIST_FOREACH(t, c, entry) { - if (t->type != m->type) - continue; -- if (t->type == MRT_TABLE_DUMP) -- return (t); -+ if (strcmp(t->rib, m->rib)) -+ continue; - if (t->peer_id == m->peer_id && - t->group_id == m->group_id) - return (t); -@@ -739,8 +696,7 @@ mrt_mergeconfig(struct mrt_head *xconf, - if ((xm = calloc(1, sizeof(struct mrt_config))) == NULL) - fatal("mrt_mergeconfig"); - memcpy(xm, m, sizeof(struct mrt_config)); -- xm->fd = -1; -- MRT2MC(xm)->state = MRT_STATE_OPEN; -+ xm->state = MRT_STATE_OPEN; - LIST_INSERT_HEAD(xconf, xm, entry); - } else { - /* MERGE */ -@@ -750,14 +706,14 @@ mrt_mergeconfig(struct mrt_head *xconf, - fatalx("mrt_mergeconfig: strlcpy"); - MRT2MC(xm)->ReopenTimerInterval = - MRT2MC(m)->ReopenTimerInterval; -- MRT2MC(xm)->state = MRT_STATE_REOPEN; -+ xm->state = MRT_STATE_REOPEN; - } - } - - LIST_FOREACH(xm, xconf, entry) - if (mrt_get(nconf, xm) == NULL) - /* REMOVE */ -- MRT2MC(xm)->state = MRT_STATE_REMOVE; -+ xm->state = MRT_STATE_REMOVE; - - /* free config */ - while ((m = LIST_FIRST(nconf)) != NULL) { -@@ -767,4 +723,3 @@ mrt_mergeconfig(struct mrt_head *xconf, - - return (0); - } -- |