diff options
-rw-r--r-- | usr.sbin/ospfd/area.c | 9 | ||||
-rw-r--r-- | usr.sbin/ospfd/ospfd.c | 55 | ||||
-rw-r--r-- | usr.sbin/ospfd/ospfd.conf.5 | 17 | ||||
-rw-r--r-- | usr.sbin/ospfd/ospfd.h | 43 | ||||
-rw-r--r-- | usr.sbin/ospfd/ospfe.c | 9 | ||||
-rw-r--r-- | usr.sbin/ospfd/parse.y | 156 | ||||
-rw-r--r-- | usr.sbin/ospfd/printconf.c | 27 | ||||
-rw-r--r-- | usr.sbin/ospfd/rde.c | 34 | ||||
-rw-r--r-- | usr.sbin/ospfd/rde.h | 6 | ||||
-rw-r--r-- | usr.sbin/ospfd/rde_lsdb.c | 48 | ||||
-rw-r--r-- | usr.sbin/ospfd/rde_spf.c | 7 |
11 files changed, 282 insertions, 129 deletions
diff --git a/usr.sbin/ospfd/area.c b/usr.sbin/ospfd/area.c index 2d3522094dc..f5f4acf7091 100644 --- a/usr.sbin/ospfd/area.c +++ b/usr.sbin/ospfd/area.c @@ -1,4 +1,4 @@ -/* $OpenBSD: area.c,v 1.8 2007/10/11 12:19:31 claudio Exp $ */ +/* $OpenBSD: area.c,v 1.9 2009/01/07 21:16:36 claudio Exp $ */ /* * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org> @@ -38,6 +38,7 @@ area_new(void) LIST_INIT(&area->iface_list); LIST_INIT(&area->nbr_list); RB_INIT(&area->lsa_tree); + SIMPLEQ_INIT(&area->redist_list); return (area); } @@ -48,6 +49,7 @@ area_del(struct area *area) struct iface *iface = NULL; struct vertex *v, *nv; struct rde_nbr *n; + struct redistribute *r; /* area is removed so neutralize the demotion done by the area */ if (area->active == 0) @@ -67,6 +69,11 @@ area_del(struct area *area) vertex_free(v); } + while ((r = SIMPLEQ_FIRST(&area->redist_list)) != NULL) { + SIMPLEQ_REMOVE_HEAD(&area->redist_list, entry); + free(r); + } + free(area); return (0); diff --git a/usr.sbin/ospfd/ospfd.c b/usr.sbin/ospfd/ospfd.c index 2607e229ac5..622bdccf745 100644 --- a/usr.sbin/ospfd/ospfd.c +++ b/usr.sbin/ospfd/ospfd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ospfd.c,v 1.59 2009/01/01 20:44:06 claudio Exp $ */ +/* $OpenBSD: ospfd.c,v 1.60 2009/01/07 21:16:36 claudio Exp $ */ /* * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org> @@ -567,6 +567,9 @@ ospf_redistribute(struct kroute *kr, u_int32_t *metric) return (r->type & REDIST_NO ? 0 : 1); } break; + case REDIST_DEFAULT: + /* nothing to be done here */ + break; } } @@ -576,14 +579,20 @@ ospf_redistribute(struct kroute *kr, u_int32_t *metric) void ospf_redistribute_default(int type) { - struct rroute rr; + struct rroute rr; + struct redistribute *r; - if (!(ospfd_conf->redistribute & REDISTRIBUTE_DEFAULT)) - return; + SIMPLEQ_FOREACH(r, &ospfd_conf->redist_list, entry) { + if (r->type != REDIST_DEFAULT) + continue; + if (r->type == (REDIST_DEFAULT | REDIST_NO)) + return; - bzero(&rr, sizeof(rr)); - rr.metric = ospfd_conf->defaultmetric; - main_imsg_compose_rde(type, 0, &rr, sizeof(struct rroute)); + bzero(&rr, sizeof(rr)); + rr.metric = r->metric; + main_imsg_compose_rde(type, 0, &rr, sizeof(struct rroute)); + return; + } } int @@ -592,6 +601,7 @@ ospf_reload(void) struct area *area; struct iface *iface; struct ospfd_conf *xconf; + struct redistribute *r; if ((xconf = parse_config(conffile, ospfd_conf->opts)) == NULL) return (-1); @@ -605,6 +615,10 @@ ospf_reload(void) if (ospf_sendboth(IMSG_RECONF_AREA, area, sizeof(*area)) == -1) return (-1); + SIMPLEQ_FOREACH(r, &area->redist_list, entry) { + main_imsg_compose_rde(IMSG_RECONF_REDIST, 0, r, + sizeof(*r)); + } LIST_FOREACH(iface, &area->iface_list, entry) { if (ospf_sendboth(IMSG_RECONF_IFACE, iface, sizeof(*iface)) == -1) @@ -647,10 +661,9 @@ merge_config(struct ospfd_conf *conf, struct ospfd_conf *xconf) conf->flags = xconf->flags; conf->spf_delay = xconf->spf_delay; conf->spf_hold_time = xconf->spf_hold_time; - if ((conf->redistribute & REDISTRIBUTE_ON) != - (xconf->redistribute & REDISTRIBUTE_ON)) + if (SIMPLEQ_EMPTY(&conf->redist_list) != + SIMPLEQ_EMPTY(&xconf->redist_list)) rchange = 1; - conf->redistribute = xconf->redistribute; conf->rfc1583compat = xconf->rfc1583compat; if (ospfd_process == PROC_MAIN) { @@ -704,9 +717,19 @@ merge_config(struct ospfd_conf *conf, struct ospfd_conf *xconf) * stub is not yet used but switching between stub and normal * will be another painful job. */ - if (a->stub != xa->stub && - ospfd_process == PROC_OSPF_ENGINE) + if (a->stub != xa->stub && ospfd_process == PROC_OSPF_ENGINE) a->dirty = 1; /* force rtr LSA update */ + if (xa->stub && ospfd_process == PROC_RDE_ENGINE) { + while ((r = SIMPLEQ_FIRST(&a->redist_list)) != NULL) { + SIMPLEQ_REMOVE_HEAD(&a->redist_list, entry); + free(r); + } + + while ((r = SIMPLEQ_FIRST(&xa->redist_list)) != NULL) { + SIMPLEQ_REMOVE_HEAD(&xa->redist_list, entry); + SIMPLEQ_INSERT_TAIL(&a->redist_list, r, entry); + } + } a->stub = xa->stub; a->stub_default_cost = xa->stub_default_cost; @@ -738,6 +761,14 @@ merge_config(struct ospfd_conf *conf, struct ospfd_conf *xconf) } } } + if (ospfd_process == PROC_RDE_ENGINE) { + LIST_FOREACH(a, &conf->area_list, entry) { + if (a->dirty) { + start_spf_timer(); + break; + } + } + } done: while ((a = LIST_FIRST(&xconf->area_list)) != NULL) { diff --git a/usr.sbin/ospfd/ospfd.conf.5 b/usr.sbin/ospfd/ospfd.conf.5 index f18189ac62d..7fcfce6d43e 100644 --- a/usr.sbin/ospfd/ospfd.conf.5 +++ b/usr.sbin/ospfd/ospfd.conf.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ospfd.conf.5,v 1.31 2008/06/10 07:22:45 jsing Exp $ +.\" $OpenBSD: ospfd.conf.5,v 1.32 2009/01/07 21:16:36 claudio Exp $ .\" .\" Copyright (c) 2005 Esben Norby <norby@openbsd.org> .\" Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org> @@ -17,7 +17,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: June 10 2008 $ +.Dd $Mdocdate: January 7 2009 $ .Dt OSPFD.CONF 5 .Os .Sh NAME @@ -241,6 +241,19 @@ see the .Ic group keyword in .Xr ifconfig 8 . +.It Xo +.Ic stub +.Op Ic no +.Ic redistribute default Op Ic set ...\& +.Xc +Mark the area as +.Ar stub . +Stub areas will not be flooded by as-ext LSA which results in smaller routing +tables. +Area border router should redistribute a default network LSA this can be +enabled by specifying the default redistribute option. +A default summary LSA will only be redistributed if the router has an active +connection to the backbone area 0.0.0.0. .El .Sh INTERFACES Each interface can have several parameters configured individually, otherwise diff --git a/usr.sbin/ospfd/ospfd.h b/usr.sbin/ospfd/ospfd.h index 8e20005846a..2b63edb9e21 100644 --- a/usr.sbin/ospfd/ospfd.h +++ b/usr.sbin/ospfd/ospfd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ospfd.h,v 1.73 2008/12/12 22:43:17 claudio Exp $ */ +/* $OpenBSD: ospfd.h,v 1.74 2009/01/07 21:16:36 claudio Exp $ */ /* * Copyright (c) 2004 Esben Norby <norby@openbsd.org> @@ -57,9 +57,6 @@ #define F_DYNAMIC 0x0040 #define F_REDISTRIBUTED 0x0100 -#define REDISTRIBUTE_ON 0x01 -#define REDISTRIBUTE_DEFAULT 0x02 - /* buffer */ struct buf { TAILQ_ENTRY(buf) entry; @@ -143,6 +140,7 @@ enum imsg_type { IMSG_RECONF_AREA, IMSG_RECONF_IFACE, IMSG_RECONF_AUTHMD, + IMSG_RECONF_REDIST, IMSG_RECONF_END, IMSG_DEMOTE }; @@ -159,7 +157,23 @@ struct imsg { void *data; }; -/* area */ +#define REDIST_CONNECTED 0x01 +#define REDIST_STATIC 0x02 +#define REDIST_LABEL 0x04 +#define REDIST_ADDR 0x08 +#define REDIST_NO 0x10 +#define REDIST_DEFAULT 0x20 + +struct redistribute { + SIMPLEQ_ENTRY(redistribute) entry; + struct in_addr addr; + struct in_addr mask; + u_int32_t metric; + u_int16_t label; + u_int16_t type; +}; +SIMPLEQ_HEAD(redist_list, redistribute); + struct vertex; struct rde_nbr; RB_HEAD(lsa_tree, vertex); @@ -171,6 +185,7 @@ struct area { LIST_HEAD(, iface) iface_list; LIST_HEAD(, rde_nbr) nbr_list; + struct redist_list redist_list; /* list addr_range_list; */ char demote_group[IFNAMSIZ]; u_int32_t stub_default_cost; @@ -371,29 +386,13 @@ enum { PROC_RDE_ENGINE } ospfd_process; -#define REDIST_CONNECTED 0x01 -#define REDIST_STATIC 0x02 -#define REDIST_LABEL 0x04 -#define REDIST_ADDR 0x08 -#define REDIST_NO 0x10 - -struct redistribute { - SIMPLEQ_ENTRY(redistribute) entry; - struct in_addr addr; - struct in_addr mask; - u_int32_t metric; - u_int16_t label; - u_int16_t type; -}; - struct ospfd_conf { struct event ev; struct in_addr rtr_id; LIST_HEAD(, area) area_list; LIST_HEAD(, vertex) cand_list; - SIMPLEQ_HEAD(, redistribute) redist_list; + struct redist_list redist_list; - u_int32_t defaultmetric; u_int32_t opts; #define OSPFD_OPT_VERBOSE 0x00000001 #define OSPFD_OPT_VERBOSE2 0x00000002 diff --git a/usr.sbin/ospfd/ospfe.c b/usr.sbin/ospfd/ospfe.c index 05134e12329..05ce44f2679 100644 --- a/usr.sbin/ospfd/ospfe.c +++ b/usr.sbin/ospfd/ospfe.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ospfe.c,v 1.61 2008/11/24 18:28:02 claudio Exp $ */ +/* $OpenBSD: ospfe.c,v 1.62 2009/01/07 21:16:36 claudio Exp $ */ /* * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org> @@ -170,6 +170,12 @@ ospfe(struct ospfd_conf *xconf, int pipe_parent2ospfe[2], int pipe_ospfe2rde[2], SIMPLEQ_REMOVE_HEAD(&oeconf->redist_list, entry); free(r); } + LIST_FOREACH(area, &oeconf->area_list, entry) { + while ((r = SIMPLEQ_FIRST(&area->redist_list)) != NULL) { + SIMPLEQ_REMOVE_HEAD(&area->redist_list, entry); + free(r); + } + } /* listen on ospfd control socket */ TAILQ_INIT(&ctl_conns); @@ -335,6 +341,7 @@ ospfe_dispatch_main(int fd, short event, void *bula) LIST_INIT(&narea->iface_list); LIST_INIT(&narea->nbr_list); RB_INIT(&narea->lsa_tree); + SIMPLEQ_INIT(&narea->redist_list); LIST_INSERT_HEAD(&nconf->area_list, narea, entry); break; diff --git a/usr.sbin/ospfd/parse.y b/usr.sbin/ospfd/parse.y index d441d9cee2e..4c9e688c0f1 100644 --- a/usr.sbin/ospfd/parse.y +++ b/usr.sbin/ospfd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.63 2008/11/24 18:28:02 claudio Exp $ */ +/* $OpenBSD: parse.y,v 1.64 2009/01/07 21:16:36 claudio Exp $ */ /* * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org> @@ -108,6 +108,7 @@ typedef struct { union { int64_t number; char *string; + struct redistribute *redist; } v; int lineno; } YYSTYPE; @@ -128,6 +129,7 @@ typedef struct { %token <v.number> NUMBER %type <v.number> yesno no optlist optlist_l option demotecount %type <v.string> string +%type <v.redist> redistribute %% @@ -184,78 +186,9 @@ conf_main : ROUTERID STRING { else conf->flags &= ~OSPFD_FLAG_NO_FIB_UPDATE; } - | no REDISTRIBUTE NUMBER '/' NUMBER optlist { - struct redistribute *r; - - if ((r = calloc(1, sizeof(*r))) == NULL) - fatal(NULL); - r->type = REDIST_ADDR; - if ($3 < 0 || $3 > 255 || $5 < 1 || $5 > 32) { - yyerror("bad network: %llu/%llu", $3, $5); - free(r); - YYERROR; - } - r->addr.s_addr = htonl($3 << IN_CLASSA_NSHIFT); - r->mask.s_addr = prefixlen2mask($5); - - if ($1) - r->type |= REDIST_NO; - r->metric = $6; - - SIMPLEQ_INSERT_TAIL(&conf->redist_list, r, entry); - conf->redistribute |= REDISTRIBUTE_ON; - } - | no REDISTRIBUTE STRING optlist { - struct redistribute *r; - - if (!strcmp($3, "default")) { - if (!$1) - conf->redistribute |= - REDISTRIBUTE_DEFAULT; - else - conf->redistribute &= - ~REDISTRIBUTE_DEFAULT; - conf->defaultmetric = $4; - } else { - if ((r = calloc(1, sizeof(*r))) == NULL) - fatal(NULL); - if (!strcmp($3, "static")) - r->type = REDIST_STATIC; - else if (!strcmp($3, "connected")) - r->type = REDIST_CONNECTED; - else if (host($3, &r->addr, &r->mask)) - r->type = REDIST_ADDR; - else { - yyerror("unknown redistribute type"); - free($3); - free(r); - YYERROR; - } - - if ($1) - r->type |= REDIST_NO; - r->metric = $4; - - SIMPLEQ_INSERT_TAIL(&conf->redist_list, r, - entry); - } - conf->redistribute |= REDISTRIBUTE_ON; - free($3); - } - | no REDISTRIBUTE RTLABEL STRING optlist { - struct redistribute *r; - - if ((r = calloc(1, sizeof(*r))) == NULL) - fatal(NULL); - r->type = REDIST_LABEL; - r->label = rtlabel_name2id($4); - if ($1) - r->type |= REDIST_NO; - r->metric = $5; - free($4); - - SIMPLEQ_INSERT_TAIL(&conf->redist_list, r, entry); - conf->redistribute |= REDISTRIBUTE_ON; + | redistribute { + SIMPLEQ_INSERT_TAIL(&conf->redist_list, $1, entry); + conf->redistribute = 1; } | RTLABEL STRING EXTTAG NUMBER { if ($4 < 0 || $4 > UINT_MAX) { @@ -297,6 +230,68 @@ conf_main : ROUTERID STRING { | defaults ; + +redistribute : no REDISTRIBUTE NUMBER '/' NUMBER optlist { + struct redistribute *r; + + if ((r = calloc(1, sizeof(*r))) == NULL) + fatal(NULL); + r->type = REDIST_ADDR; + if ($3 < 0 || $3 > 255 || $5 < 1 || $5 > 32) { + yyerror("bad network: %llu/%llu", $3, $5); + free(r); + YYERROR; + } + r->addr.s_addr = htonl($3 << IN_CLASSA_NSHIFT); + r->mask.s_addr = prefixlen2mask($5); + + if ($1) + r->type |= REDIST_NO; + r->metric = $6; + $$ = r; + } + | no REDISTRIBUTE STRING optlist { + struct redistribute *r; + + if ((r = calloc(1, sizeof(*r))) == NULL) + fatal(NULL); + if (!strcmp($3, "default")) + r->type = REDIST_DEFAULT; + else if (!strcmp($3, "static")) + r->type = REDIST_STATIC; + else if (!strcmp($3, "connected")) + r->type = REDIST_CONNECTED; + else if (host($3, &r->addr, &r->mask)) + r->type = REDIST_ADDR; + else { + yyerror("unknown redistribute type"); + free($3); + free(r); + YYERROR; + } + + if ($1) + r->type |= REDIST_NO; + r->metric = $4; + free($3); + $$ = r; + } + | no REDISTRIBUTE RTLABEL STRING optlist { + struct redistribute *r; + + if ((r = calloc(1, sizeof(*r))) == NULL) + fatal(NULL); + r->type = REDIST_LABEL; + r->label = rtlabel_name2id($4); + if ($1) + r->type |= REDIST_NO; + r->metric = $5; + free($4); + + $$ = r; + } + ; + optlist : /* empty */ { $$ = DEFAULT_REDIST_METRIC; } | SET option { $$ = $2; @@ -525,7 +520,20 @@ areaoptsl : interface } } | defaults - | STUB { area->stub = 1; } + | STUB { area->stub = 1; } + | STUB redistribute { + area->stub = 1; + if ($2->type != REDIST_DEFAULT) { + yyerror("bad redistribute option"); + YYERROR; + } + if (!SIMPLEQ_EMPTY(&area->redist_list)) { + yyerror("area redistribute option only " + "allowed once"); + YYERROR; + } + SIMPLEQ_INSERT_TAIL(&area->redist_list, $2, entry); + } ; interface : INTERFACE STRING { diff --git a/usr.sbin/ospfd/printconf.c b/usr.sbin/ospfd/printconf.c index d1ee875aefe..4c001aaf1a1 100644 --- a/usr.sbin/ospfd/printconf.c +++ b/usr.sbin/ospfd/printconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: printconf.c,v 1.12 2008/11/24 18:28:02 claudio Exp $ */ +/* $OpenBSD: printconf.c,v 1.13 2009/01/07 21:16:36 claudio Exp $ */ /* * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org> @@ -30,7 +30,7 @@ void print_mainconf(struct ospfd_conf *); const char *print_no(u_int16_t); -void print_redistribute(struct ospfd_conf *); +void print_redistribute(struct redist_list *); void print_rtlabel(struct ospfd_conf *); void print_iface(struct iface *); @@ -52,7 +52,7 @@ print_mainconf(struct ospfd_conf *conf) if (conf->flags & OSPFD_FLAG_STUB_ROUTER) printf("stub router yes\n"); - print_redistribute(conf); + print_redistribute(&conf->redist_list); print_rtlabel(conf); printf("spf-delay %u\n", conf->spf_delay); @@ -69,14 +69,11 @@ print_no(u_int16_t type) } void -print_redistribute(struct ospfd_conf *conf) +print_redistribute(struct redist_list *rlh) { struct redistribute *r; - if (conf->redistribute & REDISTRIBUTE_DEFAULT) - printf("redistribute default\n"); - - SIMPLEQ_FOREACH(r, &conf->redist_list, entry) { + SIMPLEQ_FOREACH(r, rlh, entry) { switch (r->type & ~REDIST_NO) { case REDIST_STATIC: printf("%sredistribute static\n", print_no(r->type)); @@ -93,6 +90,9 @@ print_redistribute(struct ospfd_conf *conf) print_no(r->type), inet_ntoa(r->addr), mask2prefixlen(r->mask.s_addr)); break; + case REDIST_DEFAULT: + printf("%sredistribute default\n", print_no(r->type)); + break; } } } @@ -160,8 +160,15 @@ print_config(struct ospfd_conf *conf) LIST_FOREACH(area, &conf->area_list, entry) { printf("area %s {\n", inet_ntoa(area->id)); - if (area->stub) - printf("\tstub\n"); + if (area->stub) { + printf("\tstub"); + if (SIMPLEQ_EMPTY(&area->redist_list)) + printf("\n"); + else { + printf(" "); + print_redistribute(&area->redist_list); + } + } if (*area->demote_group) printf("\tdemote %s %d\n", area->demote_group, area->demote_level); diff --git a/usr.sbin/ospfd/rde.c b/usr.sbin/ospfd/rde.c index 5e63c5d3225..11d782c1d64 100644 --- a/usr.sbin/ospfd/rde.c +++ b/usr.sbin/ospfd/rde.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.c,v 1.75 2008/12/12 22:43:17 claudio Exp $ */ +/* $OpenBSD: rde.c,v 1.76 2009/01/07 21:16:36 claudio Exp $ */ /* * Copyright (c) 2004, 2005 Claudio Jeker <claudio@openbsd.org> @@ -589,6 +589,7 @@ rde_dispatch_parent(int fd, short event, void *bula) struct imsgbuf *ibuf = bula; struct lsa *lsa; struct vertex *v; + struct redistribute *nred; ssize_t n; int shut = 0; @@ -667,9 +668,17 @@ rde_dispatch_parent(int fd, short event, void *bula) LIST_INIT(&narea->iface_list); LIST_INIT(&narea->nbr_list); RB_INIT(&narea->lsa_tree); + SIMPLEQ_INIT(&narea->redist_list); LIST_INSERT_HEAD(&nconf->area_list, narea, entry); break; + case IMSG_RECONF_REDIST: + if ((nred= malloc(sizeof(struct redistribute))) == NULL) + fatal(NULL); + memcpy(nred, imsg.data, sizeof(struct redistribute)); + + SIMPLEQ_INSERT_TAIL(&narea->redist_list, nred, entry); + break; case IMSG_RECONF_IFACE: if ((niface = malloc(sizeof(struct iface))) == NULL) fatal(NULL); @@ -709,6 +718,16 @@ rde_router_id(void) return (rdeconf->rtr_id.s_addr); } +struct area * +rde_backbone_area(void) +{ + struct in_addr id; + + id.s_addr = INADDR_ANY; + + return (area_find(rdeconf, id)); +} + void rde_send_change_kroute(struct rt_node *r) { @@ -1056,6 +1075,8 @@ rde_asext_put(struct rroute *rr) void rde_summary_update(struct rt_node *rte, struct area *area) { + struct rt_nexthop *rn; + struct rt_node *nr; struct vertex *v = NULL; struct lsa *lsa; u_int8_t type = 0; @@ -1072,7 +1093,16 @@ rde_summary_update(struct rt_node *rte, struct area *area) /* no need to originate inter-area routes to the backbone */ if (rte->p_type == PT_INTER_AREA && area->id.s_addr == INADDR_ANY) return; - /* TODO nexthop check, nexthop part of area -> no summary */ + /* nexthop check, nexthop part of area -> no summary */ + TAILQ_FOREACH(rn, &rte->nexthop, entry) { + nr = rt_lookup(DT_NET, rn->nexthop.s_addr); + if (nr && nr->area.s_addr == area->id.s_addr) + continue; + break; + } + if (rn == NULL) /* all nexthops belong to this area */ + return; + if (rte->cost >= LS_INFINITY) return; /* TODO AS border router specific checks */ diff --git a/usr.sbin/ospfd/rde.h b/usr.sbin/ospfd/rde.h index dbec72cb14d..c0baebc2049 100644 --- a/usr.sbin/ospfd/rde.h +++ b/usr.sbin/ospfd/rde.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.h,v 1.34 2007/06/19 16:45:15 reyk Exp $ */ +/* $OpenBSD: rde.h,v 1.35 2009/01/07 21:16:36 claudio Exp $ */ /* * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org> @@ -111,12 +111,14 @@ pid_t rde(struct ospfd_conf *, int [2], int [2], int [2]); int rde_imsg_compose_ospfe(int, u_int32_t, pid_t, void *, u_int16_t); u_int32_t rde_router_id(void); +struct area *rde_backbone_area(void); void rde_send_change_kroute(struct rt_node *); void rde_send_delete_kroute(struct rt_node *); void rde_nbr_del(struct rde_nbr *); int rde_nbr_loading(struct area *); struct rde_nbr *rde_nbr_self(struct area *); void rde_summary_update(struct rt_node *, struct area *); +struct lsa *orig_sum_lsa(struct rt_node *, struct area *, u_int8_t, int); /* rde_lsdb.c */ void lsa_init(struct lsa_tree *); @@ -135,6 +137,7 @@ void lsa_snap(struct area *, u_int32_t); void lsa_dump(struct lsa_tree *, int, pid_t); void lsa_merge(struct rde_nbr *, struct lsa *, struct vertex *); void lsa_remove_invalid_sums(struct area *); +void lsa_generate_stub_sums(struct area *); /* rde_spf.c */ void spf_calc(struct area *); @@ -160,6 +163,7 @@ 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 rt_node *rt_lookup(enum dst_type, in_addr_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_lsdb.c b/usr.sbin/ospfd/rde_lsdb.c index 82e6d78f859..d860c260ce1 100644 --- a/usr.sbin/ospfd/rde_lsdb.c +++ b/usr.sbin/ospfd/rde_lsdb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde_lsdb.c,v 1.41 2008/11/24 18:28:02 claudio Exp $ */ +/* $OpenBSD: rde_lsdb.c,v 1.42 2009/01/07 21:16:36 claudio Exp $ */ /* * Copyright (c) 2004, 2005 Claudio Jeker <claudio@openbsd.org> @@ -713,6 +713,52 @@ lsa_remove_invalid_sums(struct area *area) } } +void +lsa_generate_stub_sums(struct area *area) +{ + struct rt_node rn; + struct redistribute *r; + struct vertex *v; + struct lsa *lsa; + struct area *back; + + if (!area->stub) + return; + + back = rde_backbone_area(); + if (!back || !back->active) + return; + + SIMPLEQ_FOREACH(r, &area->redist_list, entry) { + bzero(&rn, sizeof(rn)); + if (r->type == REDIST_DEFAULT) { + /* setup fake rt_node */ + rn.prefixlen = 0; + rn.prefix.s_addr = INADDR_ANY; + rn.cost = r->metric & LSA_METRIC_MASK; + + /* update lsa but only if it was changed */ + v = lsa_find(area, LSA_TYPE_SUM_NETWORK, + rn.prefix.s_addr, rde_router_id()); + lsa = orig_sum_lsa(&rn, area, LSA_TYPE_SUM_NETWORK, 0); + lsa_merge(rde_nbr_self(area), lsa, v); + + if (v == NULL) + v = lsa_find(area, LSA_TYPE_SUM_NETWORK, + rn.prefix.s_addr, rde_router_id()); + + /* + * suppressed/deleted routes are not found in the + * second lsa_find + */ + if (v) + v->cost = rn.cost; + return; + } else if (r->type == (REDIST_DEFAULT | REDIST_NO)) + return; + } +} + int lsa_equal(struct lsa *a, struct lsa *b) { diff --git a/usr.sbin/ospfd/rde_spf.c b/usr.sbin/ospfd/rde_spf.c index 3901838ee4b..94c74487009 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.66 2008/02/11 12:37:37 norby Exp $ */ +/* $OpenBSD: rde_spf.c,v 1.67 2009/01/07 21:16:36 claudio Exp $ */ /* * Copyright (c) 2005 Esben Norby <norby@openbsd.org> @@ -45,7 +45,6 @@ void rt_nexthop_add(struct rt_node *, struct v_nexthead *, void rt_update(struct in_addr, u_int8_t, struct v_nexthead *, u_int32_t, u_int32_t, struct in_addr, struct in_addr, enum path_type, enum dst_type, u_int8_t, u_int32_t); -struct rt_node *rt_lookup(enum dst_type, in_addr_t); void rt_invalidate(struct area *); int linked(struct vertex *, struct vertex *); @@ -573,8 +572,10 @@ spf_timer(int fd, short event, void *arg) rde_send_change_kroute(r); } - LIST_FOREACH(area, &conf->area_list, entry) + LIST_FOREACH(area, &conf->area_list, entry) { + lsa_generate_stub_sums(area); lsa_remove_invalid_sums(area); + } start_spf_holdtimer(conf); break; |