diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2004-02-26 16:19:59 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2004-02-26 16:19:59 +0000 |
commit | 36f9dd8f56855a96f12bfe0c6e6f206d6af8b986 (patch) | |
tree | d995beb8244c50de18b5e3684bea607467f1f7d2 /usr.sbin | |
parent | 892286cd9843a11eba4c3219b764664e7129d166 (diff) |
Implement "show rib" and "show rib <astype> <AS>" commands to dump the
RIB. OK henning@
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/bgpctl/Makefile | 6 | ||||
-rw-r--r-- | usr.sbin/bgpctl/bgpctl.c | 133 | ||||
-rw-r--r-- | usr.sbin/bgpctl/parser.c | 80 | ||||
-rw-r--r-- | usr.sbin/bgpctl/parser.h | 4 |
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 *[]); |