diff options
-rw-r--r-- | usr.sbin/ospfctl/ospfctl.c | 165 | ||||
-rw-r--r-- | usr.sbin/ospfctl/parser.c | 10 | ||||
-rw-r--r-- | usr.sbin/ospfctl/parser.h | 4 | ||||
-rw-r--r-- | usr.sbin/ospfd/control.c | 7 | ||||
-rw-r--r-- | usr.sbin/ospfd/ospfd.h | 20 | ||||
-rw-r--r-- | usr.sbin/ospfd/ospfe.c | 3 | ||||
-rw-r--r-- | usr.sbin/ospfd/parse.y | 2 | ||||
-rw-r--r-- | usr.sbin/ospfd/rde.c | 15 | ||||
-rw-r--r-- | usr.sbin/ospfd/rde.h | 4 | ||||
-rw-r--r-- | usr.sbin/ospfd/rde_spf.c | 101 |
10 files changed, 301 insertions, 30 deletions
diff --git a/usr.sbin/ospfctl/ospfctl.c b/usr.sbin/ospfctl/ospfctl.c index 3ca17aa6288..4dcfbc44976 100644 --- a/usr.sbin/ospfctl/ospfctl.c +++ b/usr.sbin/ospfctl/ospfctl.c @@ -1,8 +1,8 @@ -/* $OpenBSD: ospfctl.c,v 1.5 2005/03/12 10:49:12 norby Exp $ */ +/* $OpenBSD: ospfctl.c,v 1.6 2005/03/12 11:03:05 norby Exp $ */ /* * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org> - * Copyright (c) 2004 Esben Norby <norby@openbsd.org> + * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org> * Copyright (c) 2003 Henning Brauer <henning@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any @@ -54,6 +54,9 @@ int show_database_msg(struct imsg *); int show_nbr_msg(struct imsg *); const char *print_ospf_options(u_int8_t); int show_nbr_detail_msg(struct imsg *); +int show_rib_msg(struct imsg *); +void show_rib_head(struct in_addr, u_int8_t, u_int8_t); +int show_rib_detail_msg(struct imsg *); struct imsgbuf *ibuf; @@ -132,6 +135,12 @@ main(int argc, char *argv[]) imsg_compose(ibuf, IMSG_CTL_SHOW_DATABASE, 0, 0, -1, &res->addr, sizeof(res->addr)); break; + case SHOW_RIB: + printf("%-20s %-17s %-12s %-9s %-7s\n", "Destination", + "Nexthop", "Path Type", "Type", "Cost"); + case SHOW_RIB_DTAIL: + imsg_compose(ibuf, IMSG_CTL_SHOW_RIB, 0, 0, -1, NULL, 0); + break; case RELOAD: imsg_compose(ibuf, IMSG_CTL_RELOAD, 0, 0, -1, NULL, 0); printf("reload request sent.\n"); @@ -172,6 +181,12 @@ main(int argc, char *argv[]) case SHOW_DBBYAREA: done = show_database_msg(&imsg); break; + case SHOW_RIB: + done = show_rib_msg(&imsg); + break; + case SHOW_RIB_DTAIL: + done = show_rib_detail_msg(&imsg); + break; case NONE: case RELOAD: break; @@ -551,3 +566,149 @@ show_nbr_detail_msg(struct imsg *imsg) return (0); } + +int +show_rib_msg(struct imsg *imsg) +{ + struct ctl_rt *rt; + char *dstnet; + + switch (imsg->hdr.type) { + case IMSG_CTL_SHOW_RIB: + rt = imsg->data; + switch (rt->d_type) { + case DT_NET: + if (asprintf(&dstnet, "%s/%d", inet_ntoa(rt->prefix), + rt->prefixlen) == -1) + err(1, NULL); + break; + case DT_RTR: + if (asprintf(&dstnet, "%s", + inet_ntoa(rt->prefix)) == -1) + err(1, NULL); + break; + default: + errx(1, "Invalid route type"); + } + + printf("%-20s %-17s %-12s %-9s %-7d\n", dstnet, + inet_ntoa(rt->nexthop), path_type_names[rt->p_type], + dst_type_names[rt->d_type], rt->cost); + free(dstnet); + break; + case IMSG_CTL_END: + printf("\n"); + return (1); + default: + break; + } + + return (0); +} + +void +show_rib_head(struct in_addr aid, u_int8_t d_type, u_int8_t p_type) +{ + char *header, *format; + + switch (p_type) { + case PT_INTRA_AREA: + case PT_INTER_AREA: + switch (d_type) { + case DT_NET: + format = "Network Routing Table"; + break; + case DT_RTR: + format = "Router Routing Table"; + break; + default: + errx(1, "unknown route type"); + } + break; + case PT_TYPE1_EXT: + case PT_TYPE2_EXT: + format = NULL; + if ((header = strdup("External Routing Table")) == NULL) + err(1, NULL); + break; + default: + errx(1, "unknown route type"); + } + + if (p_type != PT_TYPE1_EXT && p_type != PT_TYPE2_EXT) + if (asprintf(&header, "%s (Area %s)", format, + inet_ntoa(aid)) == -1) + err(1, NULL); + + printf("\n%-15s %s\n", "", header); + free(header); + + printf("\n%-20s %-17s %-17s %-12s %-8s\n", + "Destination", "Nexthop", "Adv Router", "Path type", "Cost"); + +} + +int +show_rib_detail_msg(struct imsg *imsg) +{ + static struct in_addr area_id; + struct ctl_rt *rt; + struct area *area; + char *dstnet; + static u_int8_t lasttype; + + switch (imsg->hdr.type) { + case IMSG_CTL_SHOW_RIB: + rt = imsg->data; + + switch (rt->p_type) { + case PT_INTRA_AREA: + case PT_INTER_AREA: + switch (rt->d_type) { + case DT_NET: + if (lasttype != RIB_NET) + show_rib_head(rt->area, rt->d_type, + rt->p_type); + if (asprintf(&dstnet, "%s/%d", + inet_ntoa(rt->prefix), rt->prefixlen) == -1) + err(1, NULL); + lasttype = RIB_NET; + break; + case DT_RTR: + if (lasttype != RIB_RTR) + show_rib_head(rt->area, rt->d_type, + rt->p_type); + if (asprintf(&dstnet, "%s", + inet_ntoa(rt->prefix)) == -1) + err(1, NULL); + lasttype = RIB_RTR; + break; + default: + errx(1, "unknown route type"); + } + printf("%-20s %-17s ", dstnet, inet_ntoa(rt->nexthop)); + printf("%-17s %-12s %-7d\n", inet_ntoa(rt->adv_rtr), + path_type_names[rt->p_type], rt->cost); + free(dstnet); + break; + case PT_TYPE1_EXT: + case PT_TYPE2_EXT: + /* XXX TODO */ + break; + default: + errx(1, "unknown route type"); + } + break; + case IMSG_CTL_AREA: + area = imsg->data; + area_id = area->id; + break; + case IMSG_CTL_END: + printf("\n"); + return (1); + default: + break; + } + + return (0); +} diff --git a/usr.sbin/ospfctl/parser.c b/usr.sbin/ospfctl/parser.c index 02c9d8762bf..1ab0e16a81b 100644 --- a/usr.sbin/ospfctl/parser.c +++ b/usr.sbin/ospfctl/parser.c @@ -1,4 +1,4 @@ -/* $OpenBSD: parser.c,v 1.3 2005/02/02 19:08:42 henning Exp $ */ +/* $OpenBSD: parser.c,v 1.4 2005/03/12 11:03:05 norby Exp $ */ /* * Copyright (c) 2004 Esben Norby <norby@openbsd.org> @@ -53,6 +53,7 @@ static const struct token t_show_iface[]; static const struct token t_show_db[]; static const struct token t_show_area[]; static const struct token t_show_nbr[]; +static const struct token t_show_rib[]; static const struct token t_main[] = { /* {KEYWORD, "reload", RELOAD, NULL}, */ @@ -66,6 +67,7 @@ static const struct token t_show[] = { {KEYWORD, "database", SHOW_DB, t_show_db}, {KEYWORD, "neighbor", SHOW_NBR, t_show_nbr}, /* {KEYWORD, "summary", SHOW_SUMMARY, NULL}, */ + {KEYWORD, "rib", SHOW_RIB, t_show_rib}, {ENDTOKEN, "", NONE, NULL} }; @@ -94,6 +96,12 @@ static const struct token t_show_nbr[] = { {ENDTOKEN, "", NONE, NULL} }; +static const struct token t_show_rib[] = { + {NOTOKEN, "", NONE, NULL}, + {KEYWORD, "detail", SHOW_RIB_DTAIL, NULL}, + {ENDTOKEN, "", NONE, NULL} +}; + static struct parse_result res; struct parse_result * diff --git a/usr.sbin/ospfctl/parser.h b/usr.sbin/ospfctl/parser.h index a1dc361ee0e..3ecf6e7c33f 100644 --- a/usr.sbin/ospfctl/parser.h +++ b/usr.sbin/ospfctl/parser.h @@ -1,4 +1,4 @@ -/* $OpenBSD: parser.h,v 1.2 2005/01/28 17:26:05 norby Exp $ */ +/* $OpenBSD: parser.h,v 1.3 2005/03/12 11:03:05 norby Exp $ */ /* * Copyright (c) 2004 Esben Norby <norby@openbsd.org> @@ -33,6 +33,8 @@ enum actions { SHOW_NBR_DTAIL, SHOW_DB, SHOW_DBBYAREA, + SHOW_RIB, + SHOW_RIB_DTAIL, RELOAD }; diff --git a/usr.sbin/ospfd/control.c b/usr.sbin/ospfd/control.c index e22b1ce13a6..6e4ddea3e71 100644 --- a/usr.sbin/ospfd/control.c +++ b/usr.sbin/ospfd/control.c @@ -1,4 +1,4 @@ -/* $OpenBSD: control.c,v 1.3 2005/03/12 10:49:12 norby Exp $ */ +/* $OpenBSD: control.c,v 1.4 2005/03/12 11:03:05 norby Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -242,6 +242,11 @@ control_dispatch_imsg(int fd, short event, void *bula) case IMSG_CTL_SHOW_NBR: ospfe_nbr_ctl(c); break; + case IMSG_CTL_SHOW_RIB: + c->ibuf.pid = imsg.hdr.pid; + ospfe_imsg_compose_rde(imsg.hdr.type, 0, imsg.hdr.pid, + imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE); + break; default: log_debug("control_dispatch_imsg: " "error handling imsg %d", imsg.hdr.type); diff --git a/usr.sbin/ospfd/ospfd.h b/usr.sbin/ospfd/ospfd.h index 3496c29bdc8..5cadc3b4048 100644 --- a/usr.sbin/ospfd/ospfd.h +++ b/usr.sbin/ospfd/ospfd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ospfd.h,v 1.13 2005/03/08 20:12:18 norby Exp $ */ +/* $OpenBSD: ospfd.h,v 1.14 2005/03/12 11:03:05 norby Exp $ */ /* * Copyright (c) 2004 Esben Norby <norby@openbsd.org> @@ -91,6 +91,7 @@ enum imsg_type { IMSG_CTL_SHOW_INTERFACE, IMSG_CTL_SHOW_DATABASE, IMSG_CTL_SHOW_NBR, + IMSG_CTL_SHOW_RIB, IMSG_CTL_FIB_COUPLE, IMSG_CTL_FIB_DECOUPLE, IMSG_CTL_AREA, @@ -240,6 +241,12 @@ enum path_type { PT_TYPE2_EXT }; +enum rib_type { + RIB_NET = 1, + RIB_RTR, + RIB_EXT +}; + static const char * const path_type_names[] = { "Intra-Area", "Inter-Area", @@ -385,6 +392,17 @@ struct ctl_nbr { u_int8_t options; }; +struct ctl_rt { + struct in_addr prefix; + struct in_addr nexthop; + struct in_addr area; + struct in_addr adv_rtr; + u_int32_t cost; + enum path_type p_type; + enum dst_type d_type; + u_int8_t prefixlen; +}; + void show_config(struct ospfd_conf *xconf); /* area.c */ diff --git a/usr.sbin/ospfd/ospfe.c b/usr.sbin/ospfd/ospfe.c index fb4dff5441e..617d7caebf6 100644 --- a/usr.sbin/ospfd/ospfe.c +++ b/usr.sbin/ospfd/ospfe.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ospfe.c,v 1.10 2005/03/12 10:49:12 norby Exp $ */ +/* $OpenBSD: ospfe.c,v 1.11 2005/03/12 11:03:05 norby Exp $ */ /* * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org> @@ -523,6 +523,7 @@ ospfe_dispatch_rde(int fd, short event, void *bula) nbr_fsm(nbr, NBR_EVT_BAD_LS_REQ); break; case IMSG_CTL_SHOW_DATABASE: + case IMSG_CTL_SHOW_RIB: case IMSG_CTL_AREA: case IMSG_CTL_END: control_imsg_relay(&imsg); diff --git a/usr.sbin/ospfd/parse.y b/usr.sbin/ospfd/parse.y index e65438810b6..afb4d61b08b 100644 --- a/usr.sbin/ospfd/parse.y +++ b/usr.sbin/ospfd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.7 2005/03/12 10:49:12 norby Exp $ */ +/* $OpenBSD: parse.y,v 1.8 2005/03/12 11:03:05 norby Exp $ */ /* * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org> diff --git a/usr.sbin/ospfd/rde.c b/usr.sbin/ospfd/rde.c index 5ff81983993..da05d90aba1 100644 --- a/usr.sbin/ospfd/rde.c +++ b/usr.sbin/ospfd/rde.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.c,v 1.8 2005/03/08 20:12:18 norby Exp $ */ +/* $OpenBSD: rde.c,v 1.9 2005/03/12 11:03:05 norby Exp $ */ /* * Copyright (c) 2004, 2005 Claudio Jeker <claudio@openbsd.org> @@ -457,6 +457,19 @@ rde_dispatch_imsg(int fd, short event, void *bula) imsg_compose(ibuf_ospfe, IMSG_CTL_END, 0, imsg.hdr.pid, -1, NULL, 0); break; + case IMSG_CTL_SHOW_RIB: + LIST_FOREACH(area, &rdeconf->area_list, entry) { + imsg_compose(ibuf_ospfe, IMSG_CTL_AREA, + 0, imsg.hdr.pid, -1, area, + sizeof(*area)); + + rt_dump(area->id, imsg.hdr.pid, RIB_RTR); + rt_dump(area->id, imsg.hdr.pid, RIB_NET); + rt_dump(area->id, imsg.hdr.pid, RIB_EXT); + } + imsg_compose(ibuf_ospfe, IMSG_CTL_END, 0, imsg.hdr.pid, + -1, NULL, 0); + break; default: log_debug("rde_dispatch_msg: unexpected imsg %d", imsg.hdr.type); diff --git a/usr.sbin/ospfd/rde.h b/usr.sbin/ospfd/rde.h index 0500862180c..0b938913118 100644 --- a/usr.sbin/ospfd/rde.h +++ b/usr.sbin/ospfd/rde.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.h,v 1.6 2005/03/08 20:12:18 norby Exp $ */ +/* $OpenBSD: rde.h,v 1.7 2005/03/12 11:03:05 norby Exp $ */ /* * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org> @@ -60,6 +60,7 @@ struct rt_node { struct in_addr prefix; struct in_addr nexthop; struct in_addr area; + struct in_addr adv_rtr; u_int32_t cost; enum path_type p_type; enum dst_type d_type; @@ -117,6 +118,7 @@ struct rt_node *rt_find(in_addr_t, u_int8_t); int rt_insert(struct rt_node *); int rt_remove(struct rt_node *); void rt_clear(void); +void rt_dump(struct in_addr, pid_t, u_int8_t); struct lsa_rtr_link *get_rtr_link(struct vertex *, int); struct lsa_net_link *get_net_link(struct vertex *, int); diff --git a/usr.sbin/ospfd/rde_spf.c b/usr.sbin/ospfd/rde_spf.c index 62246d704d0..3e4b949e61c 100644 --- a/usr.sbin/ospfd/rde_spf.c +++ b/usr.sbin/ospfd/rde_spf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde_spf.c,v 1.4 2005/03/12 10:49:12 norby Exp $ */ +/* $OpenBSD: rde_spf.c,v 1.5 2005/03/12 11:03:05 norby Exp $ */ /* * Copyright (c) 2005 Esben Norby <norby@openbsd.org> @@ -35,15 +35,15 @@ RB_PROTOTYPE(rt_tree, rt_node, entry, rt_compare) RB_GENERATE(rt_tree, rt_node, entry, rt_compare) struct vertex *spf_root = NULL; -void spf_dump(struct area *); /* XXX */ -void rt_dump(void); /* XXX */ -void cand_list_dump(void); /* XXX */ -void calc_next_hop(struct vertex *, struct vertex *); -void rt_update(struct in_addr, u_int8_t, struct in_addr, u_int32_t, - struct in_addr, u_int8_t, u_int8_t); -void rt_invalidate(void); -bool linked(struct vertex *, struct vertex *); -u_int8_t mask2prefixlen(in_addr_t); +void spf_dump(struct area *); /* XXX */ +void rt_dump_debug(void); /* XXX */ +void cand_list_dump(void); /* XXX */ +void calc_next_hop(struct vertex *, struct vertex *); +void rt_update(struct in_addr, u_int8_t, struct in_addr, u_int32_t, + struct in_addr, struct in_addr, u_int8_t, u_int8_t); +void rt_invalidate(void); +bool linked(struct vertex *, struct vertex *); +u_int8_t mask2prefixlen(in_addr_t); void spf_dump(struct area *area) @@ -77,12 +77,12 @@ spf_dump(struct area *area) } void -rt_dump(void) +rt_dump_debug(void) { struct rt_node *r; int i = 0; - log_debug("rt_dump:"); + log_debug("rt_dump_debug:"); RB_FOREACH(r, rt_tree, &rt) { log_debug("net: %s/%d", inet_ntoa(r->prefix), r->prefixlen); @@ -105,7 +105,7 @@ spf_calc(struct area *area) struct lsa_net_link *net_link = NULL; u_int32_t d; int i; - struct in_addr addr; + struct in_addr addr, adv_rtr; log_debug("spf_calc: calculation started, area ID %s", inet_ntoa(area->id)); @@ -235,12 +235,20 @@ spf_calc(struct area *area) continue; addr.s_addr = rtr_link->id; + adv_rtr.s_addr = htonl(v->adv_rtr); rt_update(addr, mask2prefixlen(rtr_link->data), v->nexthop, v->cost + - ntohs(rtr_link->metric), area->id, + ntohs(rtr_link->metric), area->id, adv_rtr, PT_INTRA_AREA, DT_NET); } + + /* routers */ + addr.s_addr = htonl(v->ls_id); + adv_rtr.s_addr = htonl(v->adv_rtr); + + rt_update(addr, 0, v->nexthop, v->cost, area->id, + adv_rtr, PT_INTRA_AREA, DT_RTR); break; case LSA_TYPE_NETWORK: if ((v->cost == LS_INFINITY) || @@ -248,9 +256,10 @@ spf_calc(struct area *area) continue; addr.s_addr = htonl(v->ls_id) & v->lsa->data.net.mask; + adv_rtr.s_addr = htonl(v->adv_rtr); rt_update(addr, mask2prefixlen(v->lsa->data.net.mask), - v->nexthop, v->cost, area->id, PT_INTRA_AREA, - DT_NET); + v->nexthop, v->cost, area->id, adv_rtr, + PT_INTRA_AREA, DT_NET); break; case LSA_TYPE_SUM_NETWORK: if (rdeconf->flags & OSPF_RTR_B) @@ -269,9 +278,10 @@ spf_calc(struct area *area) continue; addr.s_addr = htonl(v->ls_id) & v->lsa->data.sum.mask; + adv_rtr.s_addr = htonl(v->adv_rtr); rt_update(addr, mask2prefixlen(v->lsa->data.sum.mask), - v->nexthop, v->cost, area->id, PT_INTER_AREA, - DT_NET); + v->nexthop, v->cost, area->id, adv_rtr, + PT_INTER_AREA, DT_NET); break; case LSA_TYPE_SUM_ROUTER: /* XXX */ @@ -285,7 +295,7 @@ spf_calc(struct area *area) } spf_dump(area); - rt_dump(); + rt_dump_debug(); log_debug("spf_calc: calculation ended, area ID %s", inet_ntoa(area->id)); @@ -477,6 +487,9 @@ spf_timer(int fd, short event, void *arg) } RB_FOREACH(r, rt_tree, &rt) { + if (r->d_type != DT_NET) + continue; + if (r->invalid) rde_send_delete_kroute(r); else @@ -516,6 +529,7 @@ start_spf_timer(struct ospfd_conf *conf) conf->spf_state = SPF_HOLDQUEUE; break; case SPF_HOLDQUEUE: + /* ignore */ break; default: fatalx("start_spf_timer: invalid spf_state"); @@ -633,8 +647,52 @@ rt_clear(void) } void +rt_dump(struct in_addr area, pid_t pid, u_int8_t r_type) +{ + static struct ctl_rt rtctl; + struct rt_node *r; + + RB_FOREACH(r, rt_tree, &rt) { + if (r->area.s_addr != area.s_addr) + continue; + + switch (r_type) { + case RIB_RTR: + if (r->d_type != DT_RTR) + continue; + break; + case RIB_NET: + if (r->d_type != DT_NET) + continue; + break; + case RIB_EXT: + if (r->p_type != PT_TYPE1_EXT || + r->p_type != PT_TYPE2_EXT) + continue; + break; + default: + fatalx("rt_dump: invalid RIB type"); + } + + rtctl.prefix.s_addr = r->prefix.s_addr; + rtctl.nexthop.s_addr = r->nexthop.s_addr; + rtctl.area.s_addr = r->area.s_addr; + rtctl.adv_rtr.s_addr = r->adv_rtr.s_addr; + rtctl.cost = r->cost; + rtctl.p_type = r->p_type; + rtctl.d_type = r->d_type; + rtctl.prefixlen = r->prefixlen; + + rde_imsg_compose_ospfe(IMSG_CTL_SHOW_RIB, 0, pid, &rtctl, + sizeof(rtctl)); + } +} + + +void rt_update(struct in_addr prefix, u_int8_t prefixlen, struct in_addr nexthop, - u_int32_t cost, struct in_addr area, u_int8_t p_type, u_int8_t d_type) + u_int32_t cost, struct in_addr area, struct in_addr adv_rtr, + u_int8_t p_type, u_int8_t d_type) { struct rt_node *rte; @@ -649,6 +707,7 @@ rt_update(struct in_addr prefix, u_int8_t prefixlen, struct in_addr nexthop, rte->prefix.s_addr = prefix.s_addr; rte->prefixlen = prefixlen; rte->nexthop.s_addr = nexthop.s_addr; + rte->adv_rtr.s_addr = adv_rtr.s_addr; rte->cost = cost; rte->area = area; rte->p_type = p_type; @@ -663,6 +722,7 @@ rt_update(struct in_addr prefix, u_int8_t prefixlen, struct in_addr nexthop, if (rte->invalid) { /* invalidated entry - just update */ rte->nexthop.s_addr = nexthop.s_addr; + rte->adv_rtr.s_addr = adv_rtr.s_addr; rte->cost = cost; rte->area = area; rte->p_type = p_type; @@ -672,6 +732,7 @@ rt_update(struct in_addr prefix, u_int8_t prefixlen, struct in_addr nexthop, /* consider intra vs. inter */ if (cost < rte->cost) { rte->nexthop.s_addr = nexthop.s_addr; + rte->adv_rtr.s_addr = adv_rtr.s_addr; rte->cost = cost; rte->area = area; rte->p_type = p_type; |