summaryrefslogtreecommitdiff
path: root/net/openbgpd/files/patch-bgpctl_bgpctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/openbgpd/files/patch-bgpctl_bgpctl.c')
-rw-r--r--net/openbgpd/files/patch-bgpctl_bgpctl.c1529
1 files changed, 0 insertions, 1529 deletions
diff --git a/net/openbgpd/files/patch-bgpctl_bgpctl.c b/net/openbgpd/files/patch-bgpctl_bgpctl.c
deleted file mode 100644
index 1553efc83281..000000000000
--- a/net/openbgpd/files/patch-bgpctl_bgpctl.c
+++ /dev/null
@@ -1,1529 +0,0 @@
-Index: bgpctl/bgpctl.c
-===================================================================
-RCS file: /home/cvs/private/hrs/openbgpd/bgpctl/bgpctl.c,v
-retrieving revision 1.1.1.7
-retrieving revision 1.10
-diff -u -p -r1.1.1.7 -r1.10
---- bgpctl/bgpctl.c 14 Feb 2010 20:20:14 -0000 1.1.1.7
-+++ bgpctl/bgpctl.c 8 Dec 2012 20:17:55 -0000 1.10
-@@ -1,4 +1,4 @@
--/* $OpenBSD: bgpctl.c,v 1.142 2009/06/06 06:33:15 eric Exp $ */
-+/* $OpenBSD: bgpctl.c,v 1.167 2012/11/15 19:55:08 sthen Exp $ */
-
- /*
- * Copyright (c) 2003 Henning Brauer <henning@openbsd.org>
-@@ -16,11 +16,19 @@
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-+#if defined(__FreeBSD__) /* compat */
-+#include "openbsd-compat.h"
-+#endif /* defined(__FreeBSD__) */
-+
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <sys/un.h>
- #include <net/if.h>
-+#if defined(__FreeBSD__) /* net/if_media.h */
-+#include "if_media.h"
-+#else
- #include <net/if_media.h>
-+#endif /* defined(__FreeBSD__) */
- #include <net/if_types.h>
-
- #include <err.h>
-@@ -29,7 +37,11 @@
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
-+#if defined(__FreeBSD__) /* util.h */
-+#include "util.h"
-+#else
- #include <util.h>
-+#endif /* defined(__FreeBSD__) */
-
- #include "bgpd.h"
- #include "session.h"
-@@ -37,6 +49,11 @@
- #include "log.h"
- #include "parser.h"
- #include "irrfilter.h"
-+#include "mrtparser.h"
-+
-+#if defined(__FreeBSD__) /* FreeBSD has no LINK_STATE_IS_UP macro. */
-+#define LINK_STATE_IS_UP(_s) ((_s) >= LINK_STATE_UP)
-+#endif /* defined(__FreeBSD__) */
-
- enum neighbor_views {
- NV_DEFAULT,
-@@ -50,12 +67,14 @@ int show_summary_msg(struct imsg *, in
- int show_summary_terse_msg(struct imsg *, int);
- int show_neighbor_terse(struct imsg *);
- int show_neighbor_msg(struct imsg *, enum neighbor_views);
--void print_neighbor_capa_mp_safi(u_int8_t);
-+void print_neighbor_capa_mp(struct peer *);
-+void print_neighbor_capa_restart(struct peer *);
- void print_neighbor_msgstats(struct peer *);
- void print_timer(const char *, time_t);
- static char *fmt_timeframe(time_t t);
- static char *fmt_timeframe_core(time_t t);
- void show_fib_head(void);
-+void show_fib_tables_head(void);
- void show_network_head(void);
- void show_fib_flags(u_int16_t);
- int show_fib_msg(struct imsg *);
-@@ -65,7 +84,7 @@ void show_interface_head(void);
- int ift2ifm(int);
- const char * get_media_descr(int);
- const char * get_linkstate(int, int);
--void print_baudrate(u_int64_t);
-+const char * get_baudrate(u_int64_t, char *);
- int show_interface_msg(struct imsg *);
- void show_rib_summary_head(void);
- void print_prefix(struct bgpd_addr *, u_int8_t, u_int8_t);
-@@ -73,16 +92,25 @@ const char * print_origin(u_int8_t, int
- void print_flags(u_int8_t, int);
- int show_rib_summary_msg(struct imsg *);
- int show_rib_detail_msg(struct imsg *, int);
-+void show_rib_brief(struct ctl_show_rib *, u_char *);
-+void show_rib_detail(struct ctl_show_rib *, u_char *, int);
-+void show_attr(void *, u_int16_t);
- void show_community(u_char *, u_int16_t);
--const char *get_ext_subtype(u_int8_t);
- void show_ext_community(u_char *, u_int16_t);
- char *fmt_mem(int64_t);
- int show_rib_memory_msg(struct imsg *);
- void send_filterset(struct imsgbuf *, struct filter_set_head *);
- static const char *get_errstr(u_int8_t, u_int8_t);
- int show_result(struct imsg *);
-+void show_mrt_dump(struct mrt_rib *, struct mrt_peer *, void *);
-+void network_mrt_dump(struct mrt_rib *, struct mrt_peer *, void *);
-+void show_mrt_state(struct mrt_bgp_state *, void *);
-+void show_mrt_msg(struct mrt_bgp_msg *, void *);
-+void mrt_to_bgpd_addr(union mrt_addr *, struct bgpd_addr *);
-
- struct imsgbuf *ibuf;
-+struct mrt_parser show_mrt = { show_mrt_dump, show_mrt_state, show_mrt_msg };
-+struct mrt_parser net_mrt = { network_mrt_dump, NULL, NULL };
-
- __dead void
- usage(void)
-@@ -98,7 +126,7 @@ int
- main(int argc, char *argv[])
- {
- struct sockaddr_un sun;
-- int fd, n, done, ch, nodescr = 0;
-+ int fd, n, done, ch, nodescr = 0, verbose = 0;
- struct imsg imsg;
- struct network_config net;
- struct parse_result *res;
-@@ -128,8 +156,11 @@ main(int argc, char *argv[])
- if ((res = parse(argc, argv)) == NULL)
- exit(1);
-
-- if (res->action == IRRFILTER)
-+ if (res->action == IRRFILTER) {
-+ if (!(res->flags & (F_IPV4|F_IPV6)))
-+ res->flags |= (F_IPV4|F_IPV6);
- irr_main(res->as.as, res->flags, res->irr_outdir);
-+ }
-
- memcpy(&neighbor.addr, &res->peeraddr, sizeof(neighbor.addr));
- strlcpy(neighbor.descr, res->peerdesc, sizeof(neighbor.descr));
-@@ -154,7 +185,7 @@ main(int argc, char *argv[])
- case NONE:
- case IRRFILTER:
- usage();
-- /* not reached */
-+ /* NOTREACHED */
- case SHOW:
- case SHOW_SUMMARY:
- imsg_compose(ibuf, IMSG_CTL_SHOW_NEIGHBOR, 0, 0, -1, NULL, 0);
-@@ -164,24 +195,32 @@ main(int argc, char *argv[])
- imsg_compose(ibuf, IMSG_CTL_SHOW_TERSE, 0, 0, -1, NULL, 0);
- break;
- case SHOW_FIB:
-- if (!res->addr.af) {
-- struct buf *msg;
--
-- if ((msg = imsg_create(ibuf, IMSG_CTL_KROUTE, 0, 0,
-- sizeof(res->flags) + sizeof(res->af))) == NULL)
-+ if (!res->addr.aid) {
-+ struct ibuf *msg;
-+ sa_family_t af;
-+
-+ af = aid2af(res->aid);
-+ if ((msg = imsg_create(ibuf, IMSG_CTL_KROUTE,
-+ res->rtableid, 0, sizeof(res->flags) +
-+ sizeof(af))) == NULL)
- errx(1, "imsg_create failure");
- if (imsg_add(msg, &res->flags, sizeof(res->flags)) ==
- -1 ||
-- imsg_add(msg, &res->af, sizeof(res->af)) == -1)
-+ imsg_add(msg, &af, sizeof(af)) == -1)
- errx(1, "imsg_add failure");
- imsg_close(ibuf, msg);
- } else
-- imsg_compose(ibuf, IMSG_CTL_KROUTE_ADDR, 0, 0, -1,
-- &res->addr, sizeof(res->addr));
-+ imsg_compose(ibuf, IMSG_CTL_KROUTE_ADDR, res->rtableid,
-+ 0, -1, &res->addr, sizeof(res->addr));
- show_fib_head();
- break;
-+ case SHOW_FIB_TABLES:
-+ imsg_compose(ibuf, IMSG_CTL_SHOW_FIB_TABLES, 0, 0, -1, NULL, 0);
-+ show_fib_tables_head();
-+ break;
- case SHOW_NEXTHOP:
-- imsg_compose(ibuf, IMSG_CTL_SHOW_NEXTHOP, 0, 0, -1, NULL, 0);
-+ imsg_compose(ibuf, IMSG_CTL_SHOW_NEXTHOP, res->rtableid, 0, -1,
-+ NULL, 0);
- show_nexthop_head();
- break;
- case SHOW_INTERFACE:
-@@ -192,7 +231,7 @@ main(int argc, char *argv[])
- case SHOW_NEIGHBOR_TIMERS:
- case SHOW_NEIGHBOR_TERSE:
- neighbor.show_timers = (res->action == SHOW_NEIGHBOR_TIMERS);
-- if (res->peeraddr.af || res->peerdesc[0])
-+ if (res->peeraddr.aid || res->peerdesc[0])
- imsg_compose(ibuf, IMSG_CTL_SHOW_NEIGHBOR, 0, 0, -1,
- &neighbor, sizeof(neighbor));
- else
-@@ -206,7 +245,7 @@ main(int argc, char *argv[])
- memcpy(&ribreq.as, &res->as, sizeof(res->as));
- type = IMSG_CTL_SHOW_RIB_AS;
- }
-- if (res->addr.af) {
-+ if (res->addr.aid) {
- memcpy(&ribreq.prefix, &res->addr, sizeof(res->addr));
- ribreq.prefixlen = res->prefixlen;
- type = IMSG_CTL_SHOW_RIB_PREFIX;
-@@ -217,15 +256,35 @@ main(int argc, char *argv[])
- sizeof(res->community));
- type = IMSG_CTL_SHOW_RIB_COMMUNITY;
- }
-- memcpy(&ribreq.neighbor, &neighbor,
-- sizeof(ribreq.neighbor));
-+ memcpy(&ribreq.neighbor, &neighbor, sizeof(ribreq.neighbor));
- strlcpy(ribreq.rib, res->rib, sizeof(ribreq.rib));
-- ribreq.af = res->af;
-+ ribreq.aid = res->aid;
- ribreq.flags = res->flags;
- imsg_compose(ibuf, type, 0, 0, -1, &ribreq, sizeof(ribreq));
- if (!(res->flags & F_CTL_DETAIL))
- show_rib_summary_head();
- break;
-+ case SHOW_MRT:
-+ close(fd);
-+ bzero(&ribreq, sizeof(ribreq));
-+ if (res->as.type != AS_NONE)
-+ memcpy(&ribreq.as, &res->as, sizeof(res->as));
-+ if (res->addr.aid) {
-+ memcpy(&ribreq.prefix, &res->addr, sizeof(res->addr));
-+ ribreq.prefixlen = res->prefixlen;
-+ }
-+ if (res->community.as != COMMUNITY_UNSET &&
-+ res->community.type != COMMUNITY_UNSET)
-+ memcpy(&ribreq.community, &res->community,
-+ sizeof(res->community));
-+ memcpy(&ribreq.neighbor, &neighbor, sizeof(ribreq.neighbor));
-+ ribreq.aid = res->aid;
-+ ribreq.flags = res->flags;
-+ show_mrt.arg = &ribreq;
-+ if (!(res->flags & F_CTL_DETAIL))
-+ show_rib_summary_head();
-+ mrt_parse(res->mrtfd, &show_mrt, 1);
-+ exit(0);
- case SHOW_RIB_MEM:
- imsg_compose(ibuf, IMSG_CTL_SHOW_RIB_MEM, 0, 0, -1, NULL, 0);
- break;
-@@ -237,12 +296,14 @@ main(int argc, char *argv[])
- errx(1, "action==FIB");
- break;
- case FIB_COUPLE:
-- imsg_compose(ibuf, IMSG_CTL_FIB_COUPLE, 0, 0, -1, NULL, 0);
-+ imsg_compose(ibuf, IMSG_CTL_FIB_COUPLE, res->rtableid, 0, -1,
-+ NULL, 0);
- printf("couple request sent.\n");
- done = 1;
- break;
- case FIB_DECOUPLE:
-- imsg_compose(ibuf, IMSG_CTL_FIB_DECOUPLE, 0, 0, -1, NULL, 0);
-+ imsg_compose(ibuf, IMSG_CTL_FIB_DECOUPLE, res->rtableid, 0, -1,
-+ NULL, 0);
- printf("decouple request sent.\n");
- done = 1;
- break;
-@@ -290,12 +351,40 @@ main(int argc, char *argv[])
- break;
- case NETWORK_SHOW:
- bzero(&ribreq, sizeof(ribreq));
-- ribreq.af = res->af;
-+ ribreq.aid = res->aid;
- strlcpy(ribreq.rib, res->rib, sizeof(ribreq.rib));
- imsg_compose(ibuf, IMSG_CTL_SHOW_NETWORK, 0, 0, -1,
- &ribreq, sizeof(ribreq));
- show_network_head();
- break;
-+ case NETWORK_MRT:
-+ bzero(&ribreq, sizeof(ribreq));
-+ if (res->as.type != AS_NONE)
-+ memcpy(&ribreq.as, &res->as, sizeof(res->as));
-+ if (res->addr.aid) {
-+ memcpy(&ribreq.prefix, &res->addr, sizeof(res->addr));
-+ ribreq.prefixlen = res->prefixlen;
-+ }
-+ if (res->community.as != COMMUNITY_UNSET &&
-+ res->community.type != COMMUNITY_UNSET)
-+ memcpy(&ribreq.community, &res->community,
-+ sizeof(res->community));
-+ memcpy(&ribreq.neighbor, &neighbor, sizeof(ribreq.neighbor));
-+ ribreq.aid = res->aid;
-+ ribreq.flags = res->flags;
-+ net_mrt.arg = &ribreq;
-+ mrt_parse(res->mrtfd, &net_mrt, 1);
-+ done = 1;
-+ break;
-+ case LOG_VERBOSE:
-+ verbose = 1;
-+ /* FALLTHROUGH */
-+ case LOG_BRIEF:
-+ imsg_compose(ibuf, IMSG_CTL_LOG_VERBOSE, 0, 0, -1,
-+ &verbose, sizeof(verbose));
-+ printf("logging request sent.\n");
-+ done = 1;
-+ break;
- }
-
- while (ibuf->w.queued)
-@@ -304,13 +393,13 @@ main(int argc, char *argv[])
-
- while (!done) {
- if ((n = imsg_read(ibuf)) == -1)
-- errx(1, "imsg_read error");
-+ err(1, "imsg_read error");
- if (n == 0)
- errx(1, "pipe closed");
-
- while (!done) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
-- errx(1, "imsg_get error");
-+ err(1, "imsg_get error");
- if (n == 0)
- break;
-
-@@ -329,6 +418,8 @@ main(int argc, char *argv[])
- done = show_summary_terse_msg(&imsg, nodescr);
- break;
- case SHOW_FIB:
-+ case SHOW_FIB_TABLES:
-+ case NETWORK_SHOW:
- done = show_fib_msg(&imsg);
- break;
- case SHOW_NEXTHOP:
-@@ -356,9 +447,6 @@ main(int argc, char *argv[])
- case SHOW_RIB_MEM:
- done = show_rib_memory_msg(&imsg);
- break;
-- case NETWORK_SHOW:
-- done = show_fib_msg(&imsg);
-- break;
- case NEIGHBOR:
- case NEIGHBOR_UP:
- case NEIGHBOR_DOWN:
-@@ -373,6 +461,10 @@ main(int argc, char *argv[])
- case NETWORK_REMOVE:
- case NETWORK_FLUSH:
- case IRRFILTER:
-+ case LOG_VERBOSE:
-+ case LOG_BRIEF:
-+ case SHOW_MRT:
-+ case NETWORK_MRT:
- break;
- }
- imsg_free(&imsg);
-@@ -398,8 +490,8 @@ fmt_peer(const char *descr, const struct
- }
-
- ip = log_addr(remote_addr);
-- if (masklen != -1 && ((remote_addr->af == AF_INET && masklen != 32) ||
-- (remote_addr->af == AF_INET6 && masklen != 128))) {
-+ if (masklen != -1 && ((remote_addr->aid == AID_INET && masklen != 32) ||
-+ (remote_addr->aid == AID_INET6 && masklen != 128))) {
- if (asprintf(&p, "%s/%u", ip, masklen) == -1)
- err(1, NULL);
- } else {
-@@ -430,7 +522,7 @@ show_summary_msg(struct imsg *imsg, int
- p->conf.remote_masklen, nodescr);
- if (strlen(s) >= 20)
- s[20] = 0;
-- printf("%-20s %8s %10llu %10llu %5u %-8s ",
-+ printf("%-20s %8s %10" PRIu64 " %10" PRIu64 " %5u %-8s ",
- s, log_as(p->conf.remote_as),
- p->stats.msg_rcvd_open + p->stats.msg_rcvd_notification +
- p->stats.msg_rcvd_update + p->stats.msg_rcvd_keepalive +
-@@ -492,8 +584,8 @@ show_neighbor_terse(struct imsg *imsg)
- switch (imsg->hdr.type) {
- case IMSG_CTL_SHOW_NEIGHBOR:
- p = imsg->data;
-- printf("%llu %llu %llu %llu %llu %llu %llu "
-- "%llu %llu %llu %u %u %llu %llu %llu %llu\n",
-+ printf("%" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 " "
-+ "%" PRIu64 " %" PRIu64 " %" PRIu64 " %u %u %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 "\n",
- p->stats.msg_sent_open, p->stats.msg_rcvd_open,
- p->stats.msg_sent_notification,
- p->stats.msg_rcvd_notification,
-@@ -521,13 +613,15 @@ show_neighbor_msg(struct imsg *imsg, enu
- struct ctl_timer *t;
- struct in_addr ina;
- char buf[NI_MAXHOST], pbuf[NI_MAXSERV], *s;
-+ int hascapamp = 0;
-+ u_int8_t i;
-
- switch (imsg->hdr.type) {
- case IMSG_CTL_SHOW_NEIGHBOR:
- p = imsg->data;
-- if ((p->conf.remote_addr.af == AF_INET &&
-+ if ((p->conf.remote_addr.aid == AID_INET &&
- p->conf.remote_masklen != 32) ||
-- (p->conf.remote_addr.af == AF_INET6 &&
-+ (p->conf.remote_addr.aid == AID_INET6 &&
- p->conf.remote_masklen != 128)) {
- if (asprintf(&s, "%s/%u",
- log_addr(&p->conf.remote_addr),
-@@ -549,9 +643,20 @@ show_neighbor_msg(struct imsg *imsg, enu
- printf(", Template");
- if (p->conf.cloned)
- printf(", Cloned");
-+ if (p->conf.passive)
-+ printf(", Passive");
-+ if (p->conf.ebgp && p->conf.distance > 1)
-+ printf(", Multihop (%u)", (int)p->conf.distance);
- printf("\n");
- if (p->conf.descr[0])
- printf(" Description: %s\n", p->conf.descr);
-+ if (p->conf.max_prefix) {
-+ printf(" Max-prefix: %u", p->conf.max_prefix);
-+ if (p->conf.max_prefix_restart)
-+ printf(" (restart %u)",
-+ p->conf.max_prefix_restart);
-+ printf("\n");
-+ }
- printf(" BGP version 4, remote router-id %s\n",
- inet_ntoa(ina));
- printf(" BGP state = %s", statenames[p->state]);
-@@ -563,22 +668,24 @@ show_neighbor_msg(struct imsg *imsg, enu
- printf(" Last read %s, holdtime %us, keepalive interval %us\n",
- fmt_timeframe(p->stats.last_read),
- p->holdtime, p->holdtime/3);
-- if (p->capa.peer.mp_v4 || p->capa.peer.mp_v6 ||
-- p->capa.peer.refresh || p->capa.peer.restart ||
-- p->capa.peer.as4byte) {
-+ for (i = 0; i < AID_MAX; i++)
-+ if (p->capa.peer.mp[i])
-+ hascapamp = 1;
-+ if (hascapamp || p->capa.peer.refresh ||
-+ p->capa.peer.grestart.restart || p->capa.peer.as4byte) {
- printf(" Neighbor capabilities:\n");
-- if (p->capa.peer.mp_v4) {
-- printf(" Multiprotocol extensions: IPv4");
-- print_neighbor_capa_mp_safi(p->capa.peer.mp_v4);
-- }
-- if (p->capa.peer.mp_v6) {
-- printf(" Multiprotocol extensions: IPv6");
-- print_neighbor_capa_mp_safi(p->capa.peer.mp_v6);
-+ if (hascapamp) {
-+ printf(" Multiprotocol extensions: ");
-+ print_neighbor_capa_mp(p);
-+ printf("\n");
- }
- if (p->capa.peer.refresh)
- printf(" Route Refresh\n");
-- if (p->capa.peer.restart)
-- printf(" Graceful Restart\n");
-+ if (p->capa.peer.grestart.restart) {
-+ printf(" Graceful Restart");
-+ print_neighbor_capa_restart(p);
-+ printf("\n");
-+ }
- if (p->capa.peer.as4byte)
- printf(" 4-byte AS numbers\n");
- }
-@@ -633,20 +740,38 @@ show_neighbor_msg(struct imsg *imsg, enu
- }
-
- void
--print_neighbor_capa_mp_safi(u_int8_t safi)
-+print_neighbor_capa_mp(struct peer *p)
- {
-- switch (safi) {
-- case SAFI_UNICAST:
-- printf(" Unicast");
-- break;
-- case SAFI_MULTICAST:
-- printf(" Multicast");
-- break;
-- default:
-- printf(" unknown (%u)", safi);
-- break;
-- }
-- printf("\n");
-+ int comma;
-+ u_int8_t i;
-+
-+ for (i = 0, comma = 0; i < AID_MAX; i++)
-+ if (p->capa.peer.mp[i]) {
-+ printf("%s%s", comma ? ", " : "", aid2str(i));
-+ comma = 1;
-+ }
-+}
-+
-+void
-+print_neighbor_capa_restart(struct peer *p)
-+{
-+ int comma;
-+ u_int8_t i;
-+
-+ if (p->capa.peer.grestart.timeout)
-+ printf(": Timeout: %d, ", p->capa.peer.grestart.timeout);
-+ for (i = 0, comma = 0; i < AID_MAX; i++)
-+ if (p->capa.peer.grestart.flags[i] & CAPA_GR_PRESENT) {
-+ if (!comma &&
-+ p->capa.peer.grestart.flags[i] & CAPA_GR_RESTART)
-+ printf("restarted, ");
-+ if (comma)
-+ printf(", ");
-+ printf("%s", aid2str(i));
-+ if (p->capa.peer.grestart.flags[i] & CAPA_GR_FORWARD)
-+ printf(" (preserved)");
-+ comma = 1;
-+ }
- }
-
- void
-@@ -654,17 +779,17 @@ print_neighbor_msgstats(struct peer *p)
- {
- printf(" Message statistics:\n");
- printf(" %-15s %-10s %-10s\n", "", "Sent", "Received");
-- printf(" %-15s %10llu %10llu\n", "Opens",
-+ printf(" %-15s %10" PRIu64 " %10" PRIu64 "\n", "Opens",
- p->stats.msg_sent_open, p->stats.msg_rcvd_open);
-- printf(" %-15s %10llu %10llu\n", "Notifications",
-+ printf(" %-15s %10" PRIu64 " %10" PRIu64 "\n", "Notifications",
- p->stats.msg_sent_notification, p->stats.msg_rcvd_notification);
-- printf(" %-15s %10llu %10llu\n", "Updates",
-+ printf(" %-15s %10" PRIu64 " %10" PRIu64 "\n", "Updates",
- p->stats.msg_sent_update, p->stats.msg_rcvd_update);
-- printf(" %-15s %10llu %10llu\n", "Keepalives",
-+ printf(" %-15s %10" PRIu64 " %10" PRIu64 "\n", "Keepalives",
- p->stats.msg_sent_keepalive, p->stats.msg_rcvd_keepalive);
-- printf(" %-15s %10llu %10llu\n", "Route Refresh",
-+ printf(" %-15s %10" PRIu64 " %10" PRIu64 "\n", "Route Refresh",
- p->stats.msg_sent_rrefresh, p->stats.msg_rcvd_rrefresh);
-- printf(" %-15s %10llu %10llu\n\n", "Total",
-+ printf(" %-15s %10" PRIu64 " %10" PRIu64 "\n\n", "Total",
- p->stats.msg_sent_open + p->stats.msg_sent_notification +
- p->stats.msg_sent_update + p->stats.msg_sent_keepalive +
- p->stats.msg_sent_rrefresh,
-@@ -673,14 +798,16 @@ print_neighbor_msgstats(struct peer *p)
- p->stats.msg_rcvd_rrefresh);
- printf(" Update statistics:\n");
- printf(" %-15s %-10s %-10s\n", "", "Sent", "Received");
-- printf(" %-15s %10llu %10llu\n", "Updates",
-+ printf(" %-15s %10" PRIu64 " %10" PRIu64 "\n", "Updates",
- p->stats.prefix_sent_update, p->stats.prefix_rcvd_update);
-- printf(" %-15s %10llu %10llu\n", "Withdraws",
-+ printf(" %-15s %10" PRIu64 " %10" PRIu64 "\n", "Withdraws",
- p->stats.prefix_sent_withdraw, p->stats.prefix_rcvd_withdraw);
-+ printf(" %-15s %10" PRIu64 " %10" PRIu64 "\n", "End-of-Rib",
-+ p->stats.prefix_sent_eor, p->stats.prefix_rcvd_eor);
- }
-
- void
--print_timer(const char *name, timer_t d)
-+print_timer(const char *name, time_t d)
- {
- printf(" %-20s ", name);
-
-@@ -745,6 +872,12 @@ show_fib_head(void)
- }
-
- void
-+show_fib_tables_head(void)
-+{
-+ printf("%-5s %-20s %-8s\n", "Table", "Description", "State");
-+}
-+
-+void
- show_network_head(void)
- {
- printf("flags: S = Static\n");
-@@ -788,56 +921,44 @@ show_fib_flags(u_int16_t flags)
- int
- show_fib_msg(struct imsg *imsg)
- {
-- struct kroute *k;
-- struct kroute6 *k6;
-+ struct kroute_full *kf;
-+ struct ktable *kt;
- char *p;
-
- switch (imsg->hdr.type) {
- case IMSG_CTL_KROUTE:
- case IMSG_CTL_SHOW_NETWORK:
-- if (imsg->hdr.len < IMSG_HEADER_SIZE + sizeof(struct kroute))
-+ if (imsg->hdr.len < IMSG_HEADER_SIZE + sizeof(*kf))
- errx(1, "wrong imsg len");
-- k = imsg->data;
-+ kf = imsg->data;
-
-- show_fib_flags(k->flags);
-+ show_fib_flags(kf->flags);
-
-- if (asprintf(&p, "%s/%u", inet_ntoa(k->prefix), k->prefixlen) ==
-- -1)
-+ if (asprintf(&p, "%s/%u", log_addr(&kf->prefix),
-+ kf->prefixlen) == -1)
- err(1, NULL);
-- printf("%4i %-20s ", k->priority, p);
-+ printf("%4i %-20s ", kf->priority, p);
- free(p);
-
-- if (k->nexthop.s_addr)
-- printf("%s", inet_ntoa(k->nexthop));
-- else if (k->flags & F_CONNECTED)
-- printf("link#%u", k->ifindex);
-+ if (kf->flags & F_CONNECTED)
-+ printf("link#%u", kf->ifindex);
-+ else
-+ printf("%s", log_addr(&kf->nexthop));
- printf("\n");
-
- break;
-- case IMSG_CTL_KROUTE6:
-- case IMSG_CTL_SHOW_NETWORK6:
-- if (imsg->hdr.len < IMSG_HEADER_SIZE + sizeof(struct kroute6))
-+ case IMSG_CTL_SHOW_FIB_TABLES:
-+ if (imsg->hdr.len < IMSG_HEADER_SIZE + sizeof(*kt))
- errx(1, "wrong imsg len");
-- k6 = imsg->data;
--
-- show_fib_flags(k6->flags);
-+ kt = imsg->data;
-
-- if (asprintf(&p, "%s/%u", log_in6addr(&k6->prefix),
-- k6->prefixlen) == -1)
-- err(1, NULL);
-- printf("%4i %-20s ", k6->priority, p);
-- free(p);
--
-- if (!IN6_IS_ADDR_UNSPECIFIED(&k6->nexthop))
-- printf("%s", log_in6addr(&k6->nexthop));
-- else if (k6->flags & F_CONNECTED)
-- printf("link#%u", k6->ifindex);
-- printf("\n");
-+ printf("%5i %-20s %-8s%s\n", kt->rtableid, kt->descr,
-+ kt->fib_sync ? "coupled" : "decoupled",
-+ kt->fib_sync != kt->fib_conf ? "*" : "");
-
- break;
- case IMSG_CTL_END:
- return (1);
-- break;
- default:
- break;
- }
-@@ -848,35 +969,70 @@ show_fib_msg(struct imsg *imsg)
- void
- show_nexthop_head(void)
- {
-- printf("%-20s %-10s\n", "Nexthop", "State");
-+ printf("Flags: * = nexthop valid\n");
-+ printf("\n %-15s %-19s%-4s %-15s %-20s\n", "Nexthop", "Route",
-+ "Prio", "Gateway", "Iface");
- }
-
- int
- show_nexthop_msg(struct imsg *imsg)
- {
- struct ctl_show_nexthop *p;
-- int ifms_type;
-+ struct kroute *k;
-+ struct kroute6 *k6;
-+ char *s;
-
- switch (imsg->hdr.type) {
- case IMSG_CTL_SHOW_NEXTHOP:
- p = imsg->data;
-- printf("%-20s %-10s", log_addr(&p->addr),
-- p->valid ? "valid" : "invalid");
-+ printf("%s %-15s ", p->valid ? "*" : " ", log_addr(&p->addr));
-+ if (!p->krvalid) {
-+ printf("\n");
-+ return (0);
-+ }
-+ switch (p->addr.aid) {
-+ case AID_INET:
-+ k = &p->kr.kr4;
-+ if (asprintf(&s, "%s/%u", inet_ntoa(k->prefix),
-+ k->prefixlen) == -1)
-+ err(1, NULL);
-+ printf("%-20s", s);
-+ free(s);
-+ printf("%3i %-15s ", k->priority,
-+ k->flags & F_CONNECTED ? "connected" :
-+ inet_ntoa(k->nexthop));
-+ break;
-+ case AID_INET6:
-+ k6 = &p->kr.kr6;
-+ if (asprintf(&s, "%s/%u", log_in6addr(&k6->prefix),
-+ k6->prefixlen) == -1)
-+ err(1, NULL);
-+ printf("%-20s", s);
-+ free(s);
-+ printf("%3i %-15s ", k6->priority,
-+ k6->flags & F_CONNECTED ? "connected" :
-+ log_in6addr(&k6->nexthop));
-+ break;
-+ default:
-+ printf("unknown address family\n");
-+ return (0);
-+ }
- if (p->kif.ifname[0]) {
-- printf("%-8s", p->kif.ifname);
-- if (p->kif.flags & IFF_UP) {
-- printf("UP");
-- ifms_type = ift2ifm(p->kif.media_type);
-- if (ifms_type != 0)
-- printf(", %s, %s",
-- get_media_descr(ifms_type),
-- get_linkstate(ifms_type,
-- p->kif.link_state));
-- if (p->kif.baudrate) {
-- printf(", ");
-- print_baudrate(p->kif.baudrate);
-- }
-- }
-+ char *s1;
-+ if (p->kif.baudrate) {
-+ if (asprintf(&s1, ", %s",
-+ get_baudrate(p->kif.baudrate,
-+ "bps")) == -1)
-+ err(1, NULL);
-+ } else if (asprintf(&s1, ", %s", get_linkstate(
-+ p->kif.media_type, p->kif.link_state)) == -1)
-+ err(1, NULL);
-+ if (asprintf(&s, "%s (%s%s)", p->kif.ifname,
-+ p->kif.flags & IFF_UP ? "UP" : "DOWN", s1) == -1)
-+ err(1, NULL);
-+ printf("%-15s", s);
-+ free(s1);
-+ free(s);
- }
- printf("\n");
- break;
-@@ -898,9 +1054,8 @@ show_interface_head(void)
- "Link state");
- }
-
--const int ifm_status_valid_list[] = IFM_STATUS_VALID_LIST;
--const struct ifmedia_status_description
-- ifm_status_descriptions[] = IFM_STATUS_DESCRIPTIONS;
-+const struct if_status_description
-+ if_status_descriptions[] = LINK_STATE_DESCRIPTIONS;
- const struct ifmedia_description
- ifm_type_descriptions[] = IFM_TYPE_DESCRIPTIONS;
-
-@@ -936,36 +1091,36 @@ get_media_descr(int media_type)
- const char *
- get_linkstate(int media_type, int link_state)
- {
-- const struct ifmedia_status_description *p;
-- int i;
--
-- if (link_state == LINK_STATE_UNKNOWN)
-- return ("unknown");
--
-- for (i = 0; ifm_status_valid_list[i] != 0; i++)
-- for (p = ifm_status_descriptions; p->ifms_valid != 0; p++) {
-- if (p->ifms_type != media_type ||
-- p->ifms_valid != ifm_status_valid_list[i])
-- continue;
-- if (LINK_STATE_IS_UP(link_state))
-- return (p->ifms_string[1]);
-- return (p->ifms_string[0]);
-- }
-+ const struct if_status_description *p;
-+ static char buf[8];
-
-- return ("unknown link state");
-+ for (p = if_status_descriptions; p->ifs_string != NULL; p++) {
-+ if (LINK_STATE_DESC_MATCH(p, media_type, link_state))
-+ return (p->ifs_string);
-+ }
-+ snprintf(buf, sizeof(buf), "[#%d]", link_state);
-+ return (buf);
- }
-
--void
--print_baudrate(u_int64_t baudrate)
-+const char *
-+get_baudrate(u_int64_t baudrate, char *unit)
- {
-+ static char bbuf[16];
-+
- if (baudrate > IF_Gbps(1))
-- printf("%llu GBit/s", baudrate / IF_Gbps(1));
-+ snprintf(bbuf, sizeof(bbuf), "%" PRIu64 " G%s",
-+ baudrate / IF_Gbps(1), unit);
- else if (baudrate > IF_Mbps(1))
-- printf("%llu MBit/s", baudrate / IF_Mbps(1));
-+ snprintf(bbuf, sizeof(bbuf), "%" PRIu64 " M%s",
-+ baudrate / IF_Mbps(1), unit);
- else if (baudrate > IF_Kbps(1))
-- printf("%llu KBit/s", baudrate / IF_Kbps(1));
-+ snprintf(bbuf, sizeof(bbuf), "%" PRIu64 " K%s",
-+ baudrate / IF_Kbps(1), unit);
- else
-- printf("%llu Bit/s", baudrate);
-+ snprintf(bbuf, sizeof(bbuf), "%" PRIu64 " %s",
-+ baudrate, unit);
-+
-+ return (bbuf);
- }
-
- int
-@@ -982,17 +1137,12 @@ show_interface_msg(struct imsg *imsg)
- printf("%-15s", k->flags & IFF_UP ? "UP" : "");
-
- if ((ifms_type = ift2ifm(k->media_type)) != 0)
-- printf("%s, %s", get_media_descr(ifms_type),
-- get_linkstate(ifms_type, k->link_state));
-- else if (k->link_state == LINK_STATE_UNKNOWN)
-- printf("unknown");
-- else
-- printf("link state %u", k->link_state);
-+ printf("%s, ", get_media_descr(ifms_type));
-
-- if (k->link_state != LINK_STATE_DOWN && k->baudrate > 0) {
-- printf(", ");
-- print_baudrate(k->baudrate);
-- }
-+ printf("%s", get_linkstate(k->media_type, k->link_state));
-+
-+ if (k->link_state != LINK_STATE_DOWN && k->baudrate > 0)
-+ printf(", %s", get_baudrate(k->baudrate, "Bit/s"));
- printf("\n");
- break;
- case IMSG_CTL_END:
-@@ -1008,10 +1158,10 @@ show_interface_msg(struct imsg *imsg)
- void
- show_rib_summary_head(void)
- {
-- printf(
-- "flags: * = Valid, > = Selected, I = via IBGP, A = Announced\n");
-+ printf("flags: * = Valid, > = Selected, I = via IBGP, A = Announced, "
-+ "S = Stale\n");
- printf("origin: i = IGP, e = EGP, ? = Incomplete\n\n");
-- printf("%-5s %-20s%-15s %5s %5s %s\n", "flags", "destination",
-+ printf("%-5s %-20s %-15s %5s %5s %s\n", "flags", "destination",
- "gateway", "lpref", "med", "aspath origin");
- }
-
-@@ -1049,26 +1199,30 @@ print_flags(u_int8_t flags, int sum)
- char *p = flagstr;
-
- if (sum) {
-- if (flags & F_RIB_ANNOUNCE)
-+ if (flags & F_PREF_ANNOUNCE)
- *p++ = 'A';
-- if (flags & F_RIB_INTERNAL)
-+ if (flags & F_PREF_INTERNAL)
- *p++ = 'I';
-- if (flags & F_RIB_ELIGIBLE)
-+ if (flags & F_PREF_STALE)
-+ *p++ = 'S';
-+ if (flags & F_PREF_ELIGIBLE)
- *p++ = '*';
-- if (flags & F_RIB_ACTIVE)
-+ if (flags & F_PREF_ACTIVE)
- *p++ = '>';
- *p = '\0';
- printf("%-5s ", flagstr);
- } else {
-- if (flags & F_RIB_INTERNAL)
-+ if (flags & F_PREF_INTERNAL)
- printf("internal");
- else
- printf("external");
-- if (flags & F_RIB_ELIGIBLE)
-+ if (flags & F_PREF_STALE)
-+ printf(", stale");
-+ if (flags & F_PREF_ELIGIBLE)
- printf(", valid");
-- if (flags & F_RIB_ACTIVE)
-+ if (flags & F_PREF_ACTIVE)
- printf(", best");
-- if (flags & F_RIB_ANNOUNCE)
-+ if (flags & F_PREF_ANNOUNCE)
- printf(", announced");
- }
- }
-@@ -1077,27 +1231,14 @@ int
- show_rib_summary_msg(struct imsg *imsg)
- {
- struct ctl_show_rib rib;
-- char *aspath;
- u_char *asdata;
-
- switch (imsg->hdr.type) {
- case IMSG_CTL_SHOW_RIB:
- memcpy(&rib, imsg->data, sizeof(rib));
--
-- print_prefix(&rib.prefix, rib.prefixlen, rib.flags);
-- printf("%-15s ", log_addr(&rib.exit_nexthop));
--
-- printf(" %5u %5u ", rib.local_pref, rib.med);
--
- asdata = imsg->data;
- asdata += sizeof(struct ctl_show_rib);
-- if (aspath_asprint(&aspath, asdata, rib.aspath_len) == -1)
-- err(1, NULL);
-- if (strlen(aspath) > 0)
-- printf("%s ", aspath);
-- free(aspath);
--
-- printf("%s\n", print_origin(rib.origin, 1));
-+ show_rib_brief(&rib, asdata);
- break;
- case IMSG_CTL_END:
- return (1);
-@@ -1112,108 +1253,21 @@ int
- show_rib_detail_msg(struct imsg *imsg, int nodescr)
- {
- struct ctl_show_rib rib;
-- struct in_addr id;
-- char *aspath, *s;
-- u_char *data;
-- u_int32_t as;
-- u_int16_t ilen, alen, ioff;
-- u_int8_t flags, type;
-- time_t now;
-+ u_char *asdata;
-+ u_int16_t ilen;
-
- switch (imsg->hdr.type) {
- case IMSG_CTL_SHOW_RIB:
- memcpy(&rib, imsg->data, sizeof(rib));
--
-- printf("\nBGP routing table entry for %s/%u\n",
-- log_addr(&rib.prefix), rib.prefixlen);
--
-- data = imsg->data;
-- data += sizeof(struct ctl_show_rib);
-- if (aspath_asprint(&aspath, data, rib.aspath_len) == -1)
-- err(1, NULL);
-- if (strlen(aspath) > 0)
-- printf(" %s\n", aspath);
-- free(aspath);
--
-- s = fmt_peer(rib.descr, &rib.remote_addr, -1, nodescr);
-- printf(" Nexthop %s ", log_addr(&rib.exit_nexthop));
-- printf("(via %s) from %s (", log_addr(&rib.true_nexthop), s);
-- free(s);
-- id.s_addr = htonl(rib.remote_id);
-- printf("%s)\n", inet_ntoa(id));
--
-- printf(" Origin %s, metric %u, localpref %u, ",
-- print_origin(rib.origin, 0), rib.med, rib.local_pref);
-- print_flags(rib.flags, 0);
--
-- now = time(NULL);
-- if (now > rib.lastchange)
-- now -= rib.lastchange;
-- else
-- now = 0;
--
-- printf("\n Last update: %s ago\n",
-- fmt_timeframe_core(now));
-+ asdata = imsg->data;
-+ asdata += sizeof(struct ctl_show_rib);
-+ show_rib_detail(&rib, asdata, nodescr);
- break;
- case IMSG_CTL_SHOW_RIB_ATTR:
- ilen = imsg->hdr.len - IMSG_HEADER_SIZE;
- if (ilen < 3)
- errx(1, "bad IMSG_CTL_SHOW_RIB_ATTR received");
-- data = imsg->data;
-- flags = data[0];
-- type = data[1];
--
-- /* get the attribute length */
-- if (flags & ATTR_EXTLEN) {
-- if (ilen < 4)
-- errx(1, "bad IMSG_CTL_SHOW_RIB_ATTR received");
-- memcpy(&alen, data+2, sizeof(u_int16_t));
-- alen = ntohs(alen);
-- data += 4;
-- ilen -= 4;
-- } else {
-- alen = data[2];
-- data += 3;
-- ilen -= 3;
-- }
-- /* bad imsg len how can that happen!? */
-- if (alen != ilen)
-- errx(1, "bad IMSG_CTL_SHOW_RIB_ATTR received");
--
-- switch (type) {
-- case ATTR_COMMUNITIES:
-- printf(" Communities: ");
-- show_community(data, alen);
-- printf("\n");
-- break;
-- case ATTR_AGGREGATOR:
-- memcpy(&as, data, sizeof(as));
-- memcpy(&id, data + sizeof(as), sizeof(id));
-- printf(" Aggregator: %s [%s]\n",
-- log_as(htonl(as)), inet_ntoa(id));
-- break;
-- case ATTR_ORIGINATOR_ID:
-- memcpy(&id, data, sizeof(id));
-- printf(" Originator Id: %s\n", inet_ntoa(id));
-- break;
-- case ATTR_CLUSTER_LIST:
-- printf(" Cluster ID List:");
-- for (ioff = 0; ioff + sizeof(id) <= ilen;
-- ioff += sizeof(id)) {
-- memcpy(&id, data + ioff, sizeof(id));
-- printf(" %s", inet_ntoa(id));
-- }
-- printf("\n");
-- break;
-- case ATTR_EXT_COMMUNITIES:
-- printf(" Ext. communities: ");
-- show_ext_community(data, alen);
-- printf("\n");
-- break;
-- default:
-- /* ignore unknown attributes */
-- break;
-- }
-+ show_attr(imsg->data, ilen);
- break;
- case IMSG_CTL_END:
- printf("\n");
-@@ -1225,67 +1279,128 @@ show_rib_detail_msg(struct imsg *imsg, i
- return (0);
- }
-
--char *
--fmt_mem(int64_t num)
-+void
-+show_rib_brief(struct ctl_show_rib *r, u_char *asdata)
- {
-- static char buf[16];
-+ char *aspath;
-
-- if (fmt_scaled(num, buf) == -1)
-- snprintf(buf, sizeof(buf), "%lldB", (long long)num);
-+ print_prefix(&r->prefix, r->prefixlen, r->flags);
-+ printf(" %-15s ", log_addr(&r->exit_nexthop));
-+ printf(" %5u %5u ", r->local_pref, r->med);
-
-- return (buf);
-+ if (aspath_asprint(&aspath, asdata, r->aspath_len) == -1)
-+ err(1, NULL);
-+ if (strlen(aspath) > 0)
-+ printf("%s ", aspath);
-+ free(aspath);
-+
-+ printf("%s\n", print_origin(r->origin, 1));
- }
-
--int
--show_rib_memory_msg(struct imsg *imsg)
-+void
-+show_rib_detail(struct ctl_show_rib *r, u_char *asdata, int nodescr)
- {
-- struct rde_memstats stats;
-+ struct in_addr id;
-+ char *aspath, *s;
-+ time_t now;
-
-- switch (imsg->hdr.type) {
-- case IMSG_CTL_SHOW_RIB_MEM:
-- memcpy(&stats, imsg->data, sizeof(stats));
-- printf("RDE memory statistics\n");
-- printf("%10lld IPv4 network entries using %s of memory\n",
-- (long long)stats.pt4_cnt, fmt_mem(stats.pt4_cnt *
-- sizeof(struct pt_entry4)));
-- if (stats.pt6_cnt != 0)
-- printf("%10lld IPv6 network entries using "
-- "%s of memory\n", (long long)stats.pt6_cnt,
-- fmt_mem(stats.pt6_cnt * sizeof(struct pt_entry6)));
-- printf("%10lld rib entries using %s of memory\n",
-- (long long)stats.rib_cnt, fmt_mem(stats.rib_cnt *
-- sizeof(struct rib_entry)));
-- printf("%10lld prefix entries using %s of memory\n",
-- (long long)stats.prefix_cnt, fmt_mem(stats.prefix_cnt *
-- sizeof(struct prefix)));
-- printf("%10lld BGP path attribute entries using %s of memory\n",
-- (long long)stats.path_cnt, fmt_mem(stats.path_cnt *
-- sizeof(struct rde_aspath)));
-- printf("%10lld BGP AS-PATH attribute entries using "
-- "%s of memory,\n\t and holding %lld references\n",
-- (long long)stats.aspath_cnt, fmt_mem(stats.aspath_size),
-- (long long)stats.aspath_refs);
-- printf("%10lld BGP attributes entries using %s of memory\n",
-- (long long)stats.attr_cnt, fmt_mem(stats.attr_cnt *
-- sizeof(struct attr)));
-- printf("\t and holding %lld references\n",
-- (long long)stats.attr_refs);
-- printf("%10lld BGP attributes using %s of memory\n",
-- (long long)stats.attr_dcnt, fmt_mem(stats.attr_data));
-- printf("RIB using %s of memory\n", fmt_mem(
-- stats.pt4_cnt * sizeof(struct pt_entry4) +
-- stats.pt6_cnt * sizeof(struct pt_entry6) +
-- stats.prefix_cnt * sizeof(struct prefix) +
-- stats.rib_cnt * sizeof(struct rib_entry) +
-- stats.path_cnt * sizeof(struct rde_aspath) +
-- stats.aspath_size + stats.attr_cnt * sizeof(struct attr) +
-- stats.attr_data));
-+ printf("\nBGP routing table entry for %s/%u\n",
-+ log_addr(&r->prefix), r->prefixlen);
-+
-+ if (aspath_asprint(&aspath, asdata, r->aspath_len) == -1)
-+ err(1, NULL);
-+ if (strlen(aspath) > 0)
-+ printf(" %s\n", aspath);
-+ free(aspath);
-+
-+ s = fmt_peer(r->descr, &r->remote_addr, -1, nodescr);
-+ printf(" Nexthop %s ", log_addr(&r->exit_nexthop));
-+ printf("(via %s) from %s (", log_addr(&r->true_nexthop), s);
-+ free(s);
-+ id.s_addr = htonl(r->remote_id);
-+ printf("%s)\n", inet_ntoa(id));
-+
-+ printf(" Origin %s, metric %u, localpref %u, weight %u, ",
-+ print_origin(r->origin, 0), r->med, r->local_pref, r->weight);
-+ print_flags(r->flags, 0);
-+
-+ now = time(NULL);
-+ if (now > r->lastchange)
-+ now -= r->lastchange;
-+ else
-+ now = 0;
-+
-+ printf("\n Last update: %s ago\n", fmt_timeframe_core(now));
-+}
-+
-+void
-+show_attr(void *b, u_int16_t len)
-+{
-+ char *data = b;
-+ struct in_addr id;
-+ u_int32_t as;
-+ u_int16_t alen, ioff;
-+ u_int8_t flags, type;
-+
-+ data = b;
-+ if (len < 3)
-+ errx(1, "show_attr: too short bgp attr");
-+
-+ flags = data[0];
-+ type = data[1];
-+
-+ /* get the attribute length */
-+ if (flags & ATTR_EXTLEN) {
-+ if (len < 4)
-+ errx(1, "show_attr: too short bgp attr");
-+ memcpy(&alen, data+2, sizeof(u_int16_t));
-+ alen = ntohs(alen);
-+ data += 4;
-+ len -= 4;
-+ } else {
-+ alen = data[2];
-+ data += 3;
-+ len -= 3;
-+ }
-+
-+ /* bad imsg len how can that happen!? */
-+ if (alen > len)
-+ errx(1, "show_attr: bad length");
-+
-+ switch (type) {
-+ case ATTR_COMMUNITIES:
-+ printf(" Communities: ");
-+ show_community(data, alen);
-+ printf("\n");
-+ break;
-+ case ATTR_AGGREGATOR:
-+ memcpy(&as, data, sizeof(as));
-+ memcpy(&id, data + sizeof(as), sizeof(id));
-+ printf(" Aggregator: %s [%s]\n",
-+ log_as(ntohl(as)), inet_ntoa(id));
-+ break;
-+ case ATTR_ORIGINATOR_ID:
-+ memcpy(&id, data, sizeof(id));
-+ printf(" Originator Id: %s\n", inet_ntoa(id));
-+ break;
-+ case ATTR_CLUSTER_LIST:
-+ printf(" Cluster ID List:");
-+ for (ioff = 0; ioff + sizeof(id) <= alen;
-+ ioff += sizeof(id)) {
-+ memcpy(&id, data + ioff, sizeof(id));
-+ printf(" %s", inet_ntoa(id));
-+ }
-+ printf("\n");
-+ break;
-+ case ATTR_EXT_COMMUNITIES:
-+ printf(" Ext. communities: ");
-+ show_ext_community(data, alen);
-+ printf("\n");
- break;
- default:
-+ /* ignore unknown attributes */
- break;
- }
--
-- return (1);
- }
-
- void
-@@ -1328,30 +1443,6 @@ show_community(u_char *data, u_int16_t l
- }
- }
-
--const char *
--get_ext_subtype(u_int8_t type)
--{
-- static char etype[6];
--
-- switch (type) {
-- case EXT_COMMUNITY_ROUTE_TGT:
-- return "rt"; /* route target */
-- case EXT_CUMMUNITY_ROUTE_ORIG:
-- return "soo"; /* source of origin */
-- case EXT_COMMUNITY_OSPF_DOM_ID:
-- return "odi"; /* ospf domain id */
-- case EXT_COMMUNITY_OSPF_RTR_TYPE:
-- return "ort"; /* ospf route type */
-- case EXT_COMMUNITY_OSPF_RTR_ID:
-- return "ori"; /* ospf router id */
-- case EXT_COMMUNITY_BGP_COLLECT:
-- return "bdc"; /* bgp data collection */
-- default:
-- snprintf(etype, sizeof(etype), "[%i]", (int)type);
-- return etype;
-- }
--}
--
- void
- show_ext_community(u_char *data, u_int16_t len)
- {
-@@ -1372,34 +1463,101 @@ show_ext_community(u_char *data, u_int16
- case EXT_COMMUNITY_TWO_AS:
- memcpy(&as2, data + i + 2, sizeof(as2));
- memcpy(&u32, data + i + 4, sizeof(u32));
-- printf("%s %hu:%u", get_ext_subtype(subtype), as2, u32);
-+ printf("%s %s:%u", log_ext_subtype(subtype),
-+ log_as(ntohs(as2)), ntohl(u32));
- break;
- case EXT_COMMUNITY_IPV4:
- memcpy(&ip, data + i + 2, sizeof(ip));
- memcpy(&u16, data + i + 6, sizeof(u16));
-- printf("%s %s:%hu", get_ext_subtype(subtype),
-- inet_ntoa(ip), u16);
-+ printf("%s %s:%hu", log_ext_subtype(subtype),
-+ inet_ntoa(ip), ntohs(u16));
- break;
- case EXT_COMMUNITY_FOUR_AS:
- memcpy(&as4, data + i + 2, sizeof(as4));
- memcpy(&u16, data + i + 6, sizeof(u16));
-- printf("%s %s:%hu", get_ext_subtype(subtype),
-- log_as(as4), u16);
-+ printf("%s %s:%hu", log_ext_subtype(subtype),
-+ log_as(ntohl(as4)), ntohs(u16));
- break;
- case EXT_COMMUNITY_OPAQUE:
- memcpy(&ext, data + i, sizeof(ext));
- ext = betoh64(ext) & 0xffffffffffffLL;
-- printf("%s 0x%llx", get_ext_subtype(subtype), ext);
-+ printf("%s 0x%" PRIx64, log_ext_subtype(subtype), ext);
- break;
- default:
- memcpy(&ext, data + i, sizeof(ext));
-- printf("0x%llx", betoh64(ext));
-+ printf("0x%" PRIx64, betoh64(ext));
- }
- if (i + 8 < len)
- printf(", ");
- }
- }
-
-+char *
-+fmt_mem(int64_t num)
-+{
-+ static char buf[16];
-+
-+ if (fmt_scaled(num, buf) == -1)
-+ snprintf(buf, sizeof(buf), "%lldB", (long long)num);
-+
-+ return (buf);
-+}
-+
-+size_t pt_sizes[AID_MAX] = AID_PTSIZE;
-+
-+int
-+show_rib_memory_msg(struct imsg *imsg)
-+{
-+ struct rde_memstats stats;
-+ size_t pts = 0;
-+ int i;
-+
-+ switch (imsg->hdr.type) {
-+ case IMSG_CTL_SHOW_RIB_MEM:
-+ memcpy(&stats, imsg->data, sizeof(stats));
-+ printf("RDE memory statistics\n");
-+ for (i = 0; i < AID_MAX; i++) {
-+ if (stats.pt_cnt[i] == 0)
-+ continue;
-+ pts += stats.pt_cnt[i] * pt_sizes[i];
-+ printf("%10lld %s network entries using %s of memory\n",
-+ (long long)stats.pt_cnt[i], aid_vals[i].name,
-+ fmt_mem(stats.pt_cnt[i] * pt_sizes[i]));
-+ }
-+ printf("%10lld rib entries using %s of memory\n",
-+ (long long)stats.rib_cnt, fmt_mem(stats.rib_cnt *
-+ sizeof(struct rib_entry)));
-+ printf("%10lld prefix entries using %s of memory\n",
-+ (long long)stats.prefix_cnt, fmt_mem(stats.prefix_cnt *
-+ sizeof(struct prefix)));
-+ printf("%10lld BGP path attribute entries using %s of memory\n",
-+ (long long)stats.path_cnt, fmt_mem(stats.path_cnt *
-+ sizeof(struct rde_aspath)));
-+ printf("%10lld BGP AS-PATH attribute entries using "
-+ "%s of memory,\n\t and holding %lld references\n",
-+ (long long)stats.aspath_cnt, fmt_mem(stats.aspath_size),
-+ (long long)stats.aspath_refs);
-+ printf("%10lld BGP attributes entries using %s of memory\n",
-+ (long long)stats.attr_cnt, fmt_mem(stats.attr_cnt *
-+ sizeof(struct attr)));
-+ printf("\t and holding %lld references\n",
-+ (long long)stats.attr_refs);
-+ printf("%10lld BGP attributes using %s of memory\n",
-+ (long long)stats.attr_dcnt, fmt_mem(stats.attr_data));
-+ printf("RIB using %s of memory\n", fmt_mem(pts +
-+ stats.prefix_cnt * sizeof(struct prefix) +
-+ stats.rib_cnt * sizeof(struct rib_entry) +
-+ stats.path_cnt * sizeof(struct rde_aspath) +
-+ stats.aspath_size + stats.attr_cnt * sizeof(struct attr) +
-+ stats.attr_data));
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ return (1);
-+}
-+
- void
- send_filterset(struct imsgbuf *i, struct filter_set_head *set)
- {
-@@ -1469,6 +1627,183 @@ show_result(struct imsg *imsg)
- return (1);
- }
-
-+void
-+show_mrt_dump(struct mrt_rib *mr, struct mrt_peer *mp, void *arg)
-+{
-+ struct ctl_show_rib ctl;
-+ struct ctl_show_rib_request *req = arg;
-+ struct mrt_rib_entry *mre;
-+ u_int16_t i, j;
-+
-+ for (i = 0; i < mr->nentries; i++) {
-+ mre = &mr->entries[i];
-+ bzero(&ctl, sizeof(ctl));
-+ mrt_to_bgpd_addr(&mr->prefix, &ctl.prefix);
-+ ctl.prefixlen = mr->prefixlen;
-+ ctl.lastchange = mre->originated;
-+ mrt_to_bgpd_addr(&mre->nexthop, &ctl.true_nexthop);
-+ mrt_to_bgpd_addr(&mre->nexthop, &ctl.exit_nexthop);
-+ ctl.origin = mre->origin;
-+ ctl.local_pref = mre->local_pref;
-+ ctl.med = mre->med;
-+ /* weight is not part of the mrt dump so it can't be set */
-+ ctl.aspath_len = mre->aspath_len;
-+
-+ if (mre->peer_idx < mp->npeers) {
-+ mrt_to_bgpd_addr(&mp->peers[mre->peer_idx].addr,
-+ &ctl.remote_addr);
-+ ctl.remote_id = mp->peers[mre->peer_idx].bgp_id;
-+ }
-+
-+ /* filter by neighbor */
-+ if (req->neighbor.addr.aid != AID_UNSPEC &&
-+ memcmp(&req->neighbor.addr, &ctl.remote_addr,
-+ sizeof(ctl.remote_addr)) != 0)
-+ continue;
-+ /* filter by AF */
-+ if (req->aid && req->aid != ctl.prefix.aid)
-+ return;
-+ /* filter by prefix */
-+ if (req->prefix.aid != AID_UNSPEC) {
-+ if (!prefix_compare(&req->prefix, &ctl.prefix,
-+ req->prefixlen)) {
-+ if (req->flags & F_LONGER) {
-+ if (req->prefixlen > ctl.prefixlen)
-+ return;
-+ } else if (req->prefixlen != ctl.prefixlen)
-+ return;
-+ } else
-+ return;
-+ }
-+ /* filter by AS */
-+ if (req->as.type != AS_NONE &&
-+ !aspath_match(mre->aspath, mre->aspath_len,
-+ req->as.type, req->as.as))
-+ continue;
-+
-+ if (req->flags & F_CTL_DETAIL) {
-+ show_rib_detail(&ctl, mre->aspath, 1);
-+ for (j = 0; j < mre->nattrs; j++)
-+ show_attr(mre->attrs[j].attr,
-+ mre->attrs[j].attr_len);
-+ } else
-+ show_rib_brief(&ctl, mre->aspath);
-+ }
-+}
-+
-+void
-+network_mrt_dump(struct mrt_rib *mr, struct mrt_peer *mp, void *arg)
-+{
-+ struct ctl_show_rib ctl;
-+ struct network_config net;
-+ struct ctl_show_rib_request *req = arg;
-+ struct mrt_rib_entry *mre;
-+ struct ibuf *msg;
-+ u_int16_t i, j;
-+
-+ for (i = 0; i < mr->nentries; i++) {
-+ mre = &mr->entries[i];
-+ bzero(&ctl, sizeof(ctl));
-+ mrt_to_bgpd_addr(&mr->prefix, &ctl.prefix);
-+ ctl.prefixlen = mr->prefixlen;
-+ ctl.lastchange = mre->originated;
-+ mrt_to_bgpd_addr(&mre->nexthop, &ctl.true_nexthop);
-+ mrt_to_bgpd_addr(&mre->nexthop, &ctl.exit_nexthop);
-+ ctl.origin = mre->origin;
-+ ctl.local_pref = mre->local_pref;
-+ ctl.med = mre->med;
-+ ctl.aspath_len = mre->aspath_len;
-+
-+ if (mre->peer_idx < mp->npeers) {
-+ mrt_to_bgpd_addr(&mp->peers[mre->peer_idx].addr,
-+ &ctl.remote_addr);
-+ ctl.remote_id = mp->peers[mre->peer_idx].bgp_id;
-+ }
-+
-+ /* filter by neighbor */
-+ if (req->neighbor.addr.aid != AID_UNSPEC &&
-+ memcmp(&req->neighbor.addr, &ctl.remote_addr,
-+ sizeof(ctl.remote_addr)) != 0)
-+ continue;
-+ /* filter by AF */
-+ if (req->aid && req->aid != ctl.prefix.aid)
-+ return;
-+ /* filter by prefix */
-+ if (req->prefix.aid != AID_UNSPEC) {
-+ if (!prefix_compare(&req->prefix, &ctl.prefix,
-+ req->prefixlen)) {
-+ if (req->flags & F_LONGER) {
-+ if (req->prefixlen > ctl.prefixlen)
-+ return;
-+ } else if (req->prefixlen != ctl.prefixlen)
-+ return;
-+ } else
-+ return;
-+ }
-+ /* filter by AS */
-+ if (req->as.type != AS_NONE &&
-+ !aspath_match(mre->aspath, mre->aspath_len,
-+ req->as.type, req->as.as))
-+ continue;
-+
-+ bzero(&net, sizeof(net));
-+ memcpy(&net.prefix, &ctl.prefix, sizeof(net.prefix));
-+ net.prefixlen = ctl.prefixlen;
-+ net.type = NETWORK_MRTCLONE;
-+ /* XXX rtableid */
-+
-+ imsg_compose(ibuf, IMSG_NETWORK_ADD, 0, 0, -1,
-+ &net, sizeof(net));
-+ if ((msg = imsg_create(ibuf, IMSG_NETWORK_ASPATH,
-+ 0, 0, sizeof(ctl) + mre->aspath_len)) == NULL)
-+ errx(1, "imsg_create failure");
-+ if (imsg_add(msg, &ctl, sizeof(ctl)) == -1 ||
-+ imsg_add(msg, mre->aspath, mre->aspath_len) == -1)
-+ errx(1, "imsg_add failure");
-+ imsg_close(ibuf, msg);
-+ for (j = 0; j < mre->nattrs; j++)
-+ imsg_compose(ibuf, IMSG_NETWORK_ATTR, 0, 0, -1,
-+ mre->attrs[j].attr, mre->attrs[j].attr_len);
-+ imsg_compose(ibuf, IMSG_NETWORK_DONE, 0, 0, -1, NULL, 0);
-+
-+ while (ibuf->w.queued) {
-+ if (msgbuf_write(&ibuf->w) < 0)
-+ err(1, "write error");
-+ }
-+ }
-+}
-+
-+void
-+show_mrt_state(struct mrt_bgp_state *ms, void *arg)
-+{
-+ printf("show_mrt_state\n");
-+}
-+
-+void
-+show_mrt_msg(struct mrt_bgp_msg *mm, void *arg)
-+{
-+ printf("show_mrt_msg\n");
-+}
-+
-+void
-+mrt_to_bgpd_addr(union mrt_addr *ma, struct bgpd_addr *ba)
-+{
-+ switch (ma->sa.sa_family) {
-+ case AF_INET:
-+ case AF_INET6:
-+ sa2addr(&ma->sa, ba);
-+ break;
-+ case AF_VPNv4:
-+ bzero(ba, sizeof(*ba));
-+ ba->aid = AID_VPN_IPv4;
-+ ba->vpn4.rd = ma->svpn4.sv_rd;
-+ ba->vpn4.addr.s_addr = ma->svpn4.sv_addr.s_addr;
-+ memcpy(ba->vpn4.labelstack, ma->svpn4.sv_label,
-+ sizeof(ba->vpn4.labelstack));
-+ break;
-+ }
-+}
-+
- /* following functions are necessary for imsg framework */
- void
- log_warnx(const char *emsg, ...)
-@@ -1495,3 +1830,9 @@ fatal(const char *emsg)
- {
- err(1, emsg);
- }
-+
-+void
-+fatalx(const char *emsg)
-+{
-+ errx(1, emsg);
-+}