summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2004-02-26 16:19:59 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2004-02-26 16:19:59 +0000
commit36f9dd8f56855a96f12bfe0c6e6f206d6af8b986 (patch)
treed995beb8244c50de18b5e3684bea607467f1f7d2
parent892286cd9843a11eba4c3219b764664e7129d166 (diff)
Implement "show rib" and "show rib <astype> <AS>" commands to dump the
RIB. OK henning@
-rw-r--r--usr.sbin/bgpctl/Makefile6
-rw-r--r--usr.sbin/bgpctl/bgpctl.c133
-rw-r--r--usr.sbin/bgpctl/parser.c80
-rw-r--r--usr.sbin/bgpctl/parser.h4
4 files changed, 213 insertions, 10 deletions
diff --git a/usr.sbin/bgpctl/Makefile b/usr.sbin/bgpctl/Makefile
index a9856469cc6..5743def0a7b 100644
--- a/usr.sbin/bgpctl/Makefile
+++ b/usr.sbin/bgpctl/Makefile
@@ -1,9 +1,9 @@
-# $OpenBSD: Makefile,v 1.2 2004/01/21 23:45:18 henning Exp $
+# $OpenBSD: Makefile,v 1.3 2004/02/26 16:19:58 claudio Exp $
-.PATH: ${.CURDIR}/../bgpd/
+.PATH: ${.CURDIR}/../bgpd
PROG= bgpctl
-SRCS= bgpctl.c parser.c buffer.c imsg.c log.c
+SRCS= bgpctl.c parser.c buffer.c imsg.c log.c rde_attr.c
CFLAGS+= -Wall
CFLAGS+= -Wstrict-prototypes -Wmissing-prototypes
CLFAGS+= -Wmissing-declarations -Wredundant-decls
diff --git a/usr.sbin/bgpctl/bgpctl.c b/usr.sbin/bgpctl/bgpctl.c
index fbfcc23d02f..444e28b6159 100644
--- a/usr.sbin/bgpctl/bgpctl.c
+++ b/usr.sbin/bgpctl/bgpctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bgpctl.c,v 1.41 2004/02/24 13:12:24 henning Exp $ */
+/* $OpenBSD: bgpctl.c,v 1.42 2004/02/26 16:19:58 claudio Exp $ */
/*
* Copyright (c) 2003 Henning Brauer <henning@openbsd.org>
@@ -30,6 +30,7 @@
#include "bgpd.h"
#include "session.h"
+#include "rde.h"
#include "log.h"
#include "parser.h"
@@ -58,6 +59,10 @@ const char * get_media_descr(int);
const char * get_linkstate(int, int);
void print_baudrate(u_long);
int show_interface_msg(struct imsg *);
+void show_rib_summary_head(void);
+void print_prefix(struct bgpd_addr *, u_int8_t, u_int8_t);
+const char * print_origin(u_int8_t, int);
+int show_rib_summary_msg(struct imsg *);
struct imsgbuf ibuf;
@@ -127,6 +132,14 @@ main(int argc, char *argv[])
else
imsg_compose(&ibuf, IMSG_CTL_SHOW_NEIGHBOR, 0, NULL, 0);
break;
+ case SHOW_RIB:
+ if (res->as.type == AS_NONE)
+ imsg_compose(&ibuf, IMSG_CTL_SHOW_RIB, 0, NULL, 0);
+ else
+ imsg_compose(&ibuf, IMSG_CTL_SHOW_RIB_AS, 0,
+ &res->as, sizeof(res->as));
+ show_rib_summary_head();
+ break;
case RELOAD:
imsg_compose(&ibuf, IMSG_CTL_RELOAD, 0, NULL, 0);
printf("reload request sent.\n");
@@ -197,6 +210,9 @@ main(int argc, char *argv[])
case SHOW_NEIGHBOR_TIMERS:
done = show_neighbor_msg(&imsg, NV_TIMERS);
break;
+ case SHOW_RIB:
+ done = show_rib_summary_msg(&imsg);
+ break;
case NONE:
case RELOAD:
case FIB:
@@ -605,3 +621,118 @@ show_interface_msg(struct imsg *imsg)
return (0);
}
+
+void
+show_rib_summary_head(void)
+{
+ printf(
+ "flags: * = Valid, > = Selected, I = via IBGP, A = Announced\n");
+ printf("origin: i = IGP, e = EGP, ? = Incomplete\n\n");
+ printf("%-4s %-20s%-15s %5s %5s %s\n", "flags", "destination",
+ "gateway", "lpref", "med", "aspath origin");
+}
+
+void
+print_prefix(struct bgpd_addr *prefix, u_int8_t prefixlen, u_int8_t flags)
+{
+ char flagstr[5];
+ char *p;
+
+ p = flagstr;
+ if (flags & F_RIB_ANNOUNCE)
+ *p++ = 'A';
+ if (flags & F_RIB_INTERNAL)
+ *p++ = 'I';
+ if (flags & F_RIB_ELIGIBLE)
+ *p++ = '*';
+ if (flags & F_RIB_ACTIVE)
+ *p++ = '>';
+ *p = '\0';
+
+ if (asprintf(&p, "%s/%u", inet_ntoa(prefix->v4), prefixlen) == -1)
+ err(1, NULL);
+ printf("%-4s %-20s", flagstr, p);
+ free(p);
+}
+
+const char *
+print_origin(u_int8_t origin, int sum)
+{
+ switch (origin) {
+ case ORIGIN_IGP:
+ return (sum ? "i" : "IGP");
+ case ORIGIN_EGP:
+ return (sum ? "e" : "EGP");
+ case ORIGIN_INCOMPLETE:
+ return (sum ? "?" : "incomplete");
+ default:
+ return (sum ? "X" : "bad origin");
+ }
+}
+
+char *aspath = NULL;
+struct ctl_show_rib *rib = NULL;
+
+int
+show_rib_summary_msg(struct imsg *imsg)
+{
+ struct ctl_show_rib_prefix *p;
+ u_char *asdata;
+
+ switch (imsg->hdr.type) {
+ case IMSG_CTL_SHOW_RIB:
+ if (rib != NULL) {
+ free(rib);
+ rib = NULL;
+ }
+ if (aspath != NULL) {
+ free(aspath);
+ aspath = NULL;
+ }
+
+ rib = malloc(imsg->hdr.len - IMSG_HEADER_SIZE);
+ memcpy(rib, imsg->data, imsg->hdr.len - IMSG_HEADER_SIZE);
+
+ print_prefix(&rib->prefix, rib->prefixlen, rib->flags);
+ printf("%-15s ", inet_ntoa(rib->nexthop.v4));
+
+ printf(" %5u %5u ", rib->local_pref, rib->med);
+
+ asdata = imsg->data;
+ asdata += sizeof(struct ctl_show_rib);
+ aspath = malloc(aspath_strlen(asdata, rib->aspath_len) + 1);
+ if (aspath == NULL)
+ err(1, NULL);
+ aspath_snprint(aspath, aspath_strlen(asdata,
+ rib->aspath_len) + 1, asdata, rib->aspath_len);
+ if (strlen(aspath) > 0)
+ printf("%s ", aspath);
+
+ printf("%s\n", print_origin(rib->origin, 1));
+ break;
+ case IMSG_CTL_SHOW_RIB_PREFIX:
+ p = imsg->data;
+ if (rib == NULL)
+ /* unexpected packet */
+ return (0);
+
+ print_prefix(&p->prefix, p->prefixlen, p->flags);
+ printf("%-15s ", inet_ntoa(rib->nexthop.v4));
+
+ printf(" %5u %5u ", rib->local_pref, rib->med);
+
+ if (strlen(aspath) > 0)
+ printf("%s ", aspath);
+
+ printf("%s\n", print_origin(rib->origin, 1));
+ break;
+ case IMSG_CTL_END:
+ return (1);
+ break;
+ default:
+ break;
+ }
+
+ return (0);
+}
+
diff --git a/usr.sbin/bgpctl/parser.c b/usr.sbin/bgpctl/parser.c
index 18347638a3f..4b186c5202f 100644
--- a/usr.sbin/bgpctl/parser.c
+++ b/usr.sbin/bgpctl/parser.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: parser.c,v 1.2 2004/01/29 12:02:13 henning Exp $ */
+/* $OpenBSD: parser.c,v 1.3 2004/02/26 16:19:58 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -16,7 +16,10 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include <errno.h>
+#include <limits.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include "parser.h"
@@ -26,7 +29,9 @@ enum token_type {
ENDTOKEN,
KEYWORD,
ADDRESS,
- FLAG
+ FLAG,
+ ASNUM,
+ ASTYPE
};
struct token {
@@ -39,11 +44,14 @@ struct token {
static const struct token t_main[];
static const struct token t_show[];
static const struct token t_show_fib[];
+static const struct token t_show_rib[];
static const struct token t_show_neighbor[];
static const struct token t_show_neighbor_modifiers[];
static const struct token t_fib[];
static const struct token t_neighbor[];
static const struct token t_neighbor_modifiers[];
+static const struct token t_show_as[];
+static const struct token t_show_ip[];
static const struct token t_main[] = {
{ KEYWORD, "reload", RELOAD, NULL},
@@ -59,6 +67,8 @@ static const struct token t_show[] = {
{ KEYWORD, "interfaces", SHOW_INTERFACE, NULL},
{ KEYWORD, "neighbor", SHOW_NEIGHBOR, t_show_neighbor},
{ KEYWORD, "nexthop", SHOW_NEXTHOP, NULL},
+ { KEYWORD, "rib", SHOW_RIB, t_show_rib},
+ { KEYWORD, "ip", NONE, t_show_ip},
{ KEYWORD, "summary", SHOW_SUMMARY, NULL},
{ ENDTOKEN, "", NONE, NULL}
};
@@ -73,8 +83,17 @@ static const struct token t_show_fib[] = {
{ ENDTOKEN, "", NONE, NULL}
};
+static const struct token t_show_rib[] = {
+ { NOTOKEN, "", NONE, NULL},
+ { ASTYPE, "as", AS_ALL, t_show_as},
+ { ASTYPE, "source-as", AS_SOURCE, t_show_as},
+ { ASTYPE, "transit-as", AS_TRANSIT, t_show_as},
+ { ASTYPE, "empty-as", AS_EMPTY, NULL},
+ { ENDTOKEN, "", NONE, NULL}
+};
+
static const struct token t_show_neighbor[] = {
- { NOTOKEN, "", NONE, NULL},
+ { NOTOKEN, "", NONE, NULL},
{ ADDRESS, "", NONE, t_show_neighbor_modifiers},
{ ENDTOKEN, "", NONE, NULL}
};
@@ -103,11 +122,22 @@ static const struct token t_neighbor_modifiers[] = {
{ ENDTOKEN, "", NONE, NULL}
};
+static const struct token t_show_as[] = {
+ { ASNUM, "", NONE, NULL},
+ { ENDTOKEN, "", NONE, NULL}
+};
+
+static const struct token t_show_ip[] = {
+ { KEYWORD, "bgp", SHOW_RIB, t_show_rib},
+ { ENDTOKEN, "", NONE, NULL}
+};
+
static struct parse_result res;
const struct token *match_token(const char *, const struct token []);
void show_valid_args(const struct token []);
int parse_addr(const char *, struct bgpd_addr *);
+int parse_asnum(const char *, u_int16_t *);
struct parse_result *
parse(int argc, char *argv[])
@@ -137,7 +167,7 @@ parse(int argc, char *argv[])
if (match->type == NOTOKEN)
break;
-
+
if (match->next == NULL)
break;
@@ -193,6 +223,20 @@ match_token(const char *word, const struct token table[])
res.action = t->value;
}
break;
+ case ASTYPE:
+ if (word != NULL && strncmp(word, table[i].keyword,
+ strlen(word)) == 0) {
+ match++;
+ t = &table[i];
+ res.as.type = t->value;
+ }
+ break;
+ case ASNUM:
+ if (parse_asnum(word, &res.as.as)) {
+ match++;
+ t = &table[i];
+ }
+ break;
case ENDTOKEN:
break;
}
@@ -216,16 +260,20 @@ show_valid_args(const struct token table[])
for (i = 0; table[i].type != ENDTOKEN; i++) {
switch (table[i].type) {
- case NONE:
+ case NOTOKEN:
fprintf(stderr, " (nothing)\n");
break;
case KEYWORD:
case FLAG:
+ case ASTYPE:
fprintf(stderr, " %s\n", table[i].keyword);
break;
case ADDRESS:
fprintf(stderr, " <address>\n");
break;
+ case ASNUM:
+ fprintf(stderr, " <asnum>\n");
+ break;
case ENDTOKEN:
break;
}
@@ -251,3 +299,25 @@ parse_addr(const char *word, struct bgpd_addr *addr)
return (0);
}
+
+int
+parse_asnum(const char *word, u_int16_t *asnum)
+{
+ u_long ulval;
+ char *ep;
+
+ if (word == NULL)
+ return (0);
+
+ errno = 0;
+ ulval = strtoul(word, &ep, 0);
+ if (word[0] == '\0' || *ep != '\0')
+ return (0);
+ if (errno == ERANGE && ulval == ULONG_MAX)
+ return (0);
+ if (ulval > USHRT_MAX)
+ return (0);
+ *asnum = (u_int16_t)ulval;
+ return (1);
+}
+
diff --git a/usr.sbin/bgpctl/parser.h b/usr.sbin/bgpctl/parser.h
index c61310be192..116be69cec4 100644
--- a/usr.sbin/bgpctl/parser.h
+++ b/usr.sbin/bgpctl/parser.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: parser.h,v 1.1 2004/01/21 23:45:18 henning Exp $ */
+/* $OpenBSD: parser.h,v 1.2 2004/02/26 16:19:58 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -27,6 +27,7 @@ enum actions {
SHOW_NEIGHBOR,
SHOW_NEIGHBOR_TIMERS,
SHOW_FIB,
+ SHOW_RIB,
SHOW_NEXTHOP,
SHOW_INTERFACE,
RELOAD,
@@ -42,6 +43,7 @@ struct parse_result {
enum actions action;
int flags;
struct bgpd_addr addr;
+ struct as_filter as;
};
struct parse_result *parse(int, char *[]);