summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/ospfd/area.c9
-rw-r--r--usr.sbin/ospfd/ospfd.c55
-rw-r--r--usr.sbin/ospfd/ospfd.conf.517
-rw-r--r--usr.sbin/ospfd/ospfd.h43
-rw-r--r--usr.sbin/ospfd/ospfe.c9
-rw-r--r--usr.sbin/ospfd/parse.y156
-rw-r--r--usr.sbin/ospfd/printconf.c27
-rw-r--r--usr.sbin/ospfd/rde.c34
-rw-r--r--usr.sbin/ospfd/rde.h6
-rw-r--r--usr.sbin/ospfd/rde_lsdb.c48
-rw-r--r--usr.sbin/ospfd/rde_spf.c7
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;