summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorclaudio <claudio@openbsd.org>2007-05-29 22:08:25 +0000
committerclaudio <claudio@openbsd.org>2007-05-29 22:08:25 +0000
commitfba2d3d0ed78659b3eaed86dbc20ef17780ed1fb (patch)
tree14226c6f664488715ff3772b1e8146981d5a07c0
parentI suck. Forgot splx() in the early return path. (diff)
downloadwireguard-openbsd-fba2d3d0ed78659b3eaed86dbc20ef17780ed1fb.tar.xz
wireguard-openbsd-fba2d3d0ed78659b3eaed86dbc20ef17780ed1fb.zip
Demote support for ospfd. It is possible to specify a demote group on
interfaces and areas. With this carp setups using ospfd are more reliable because we can fail over if the OSPF connectivity is (partially) lost. OK norby@
-rw-r--r--usr.sbin/ospfd/Makefile4
-rw-r--r--usr.sbin/ospfd/area.c11
-rw-r--r--usr.sbin/ospfd/carp.c181
-rw-r--r--usr.sbin/ospfd/interface.c15
-rw-r--r--usr.sbin/ospfd/ospfd.c18
-rw-r--r--usr.sbin/ospfd/ospfd.h20
-rw-r--r--usr.sbin/ospfd/ospfe.c42
-rw-r--r--usr.sbin/ospfd/ospfe.h4
-rw-r--r--usr.sbin/ospfd/parse.y42
-rw-r--r--usr.sbin/ospfd/printconf.c7
10 files changed, 331 insertions, 13 deletions
diff --git a/usr.sbin/ospfd/Makefile b/usr.sbin/ospfd/Makefile
index 20b20bb1149..2e13a46dce0 100644
--- a/usr.sbin/ospfd/Makefile
+++ b/usr.sbin/ospfd/Makefile
@@ -1,8 +1,8 @@
-# $OpenBSD: Makefile,v 1.6 2006/11/26 11:31:13 deraadt Exp $
+# $OpenBSD: Makefile,v 1.7 2007/05/29 22:08:25 claudio Exp $
PROG= ospfd
-SRCS= area.c auth.c buffer.c control.c database.c hello.c \
+SRCS= area.c auth.c buffer.c carp.c control.c database.c hello.c \
imsg.c in_cksum.c interface.c iso_cksum.c kroute.c lsack.c \
lsreq.c lsupdate.c log.c neighbor.c ospfd.c ospfe.c packet.c \
parse.y printconf.c rde.c rde_lsdb.c rde_spf.c name2id.c
diff --git a/usr.sbin/ospfd/area.c b/usr.sbin/ospfd/area.c
index 7b37ea9f040..169e791e054 100644
--- a/usr.sbin/ospfd/area.c
+++ b/usr.sbin/ospfd/area.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: area.c,v 1.4 2005/05/26 18:59:14 norby Exp $ */
+/* $OpenBSD: area.c,v 1.5 2007/05/29 22:08:25 claudio Exp $ */
/*
* Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org>
@@ -53,6 +53,10 @@ area_del(struct area *area)
struct vertex *v, *nv;
struct rde_nbr *n;
+ /* area is removed so neutralize the demotion done by the area */
+ if (area->active == 0)
+ ospfe_demote_area(area, 1);
+
/* clean lists */
while ((iface = LIST_FIRST(&area->iface_list)) != NULL) {
LIST_REMOVE(iface, entry);
@@ -90,12 +94,17 @@ area_find(struct ospfd_conf *conf, struct in_addr area_id)
void
area_track(struct area *area, int state)
{
+ int old = area->active;
+
if (state & NBR_STA_FULL)
area->active++;
else if (area->active == 0)
fatalx("king bula sez: area already inactive");
else
area->active--;
+
+ if (area->active == 0 || old == 0)
+ ospfe_demote_area(area, old == 0);
}
int
diff --git a/usr.sbin/ospfd/carp.c b/usr.sbin/ospfd/carp.c
new file mode 100644
index 00000000000..b633ba01708
--- /dev/null
+++ b/usr.sbin/ospfd/carp.c
@@ -0,0 +1,181 @@
+/* $OpenBSD: carp.c,v 1.1 2007/05/29 22:08:25 claudio Exp $ */
+
+/*
+ * Copyright (c) 2006 Henning Brauer <henning@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "ospfd.h"
+#include "log.h"
+
+struct carpgroup {
+ TAILQ_ENTRY(carpgroup) entry;
+ char *group;
+ int do_demote;
+ int changed_by;
+};
+
+TAILQ_HEAD(carpgroups, carpgroup) carpgroups =
+ TAILQ_HEAD_INITIALIZER(carpgroups);
+
+struct carpgroup *carp_group_find(char *group);
+int carp_demote_ioctl(char *, int);
+
+struct carpgroup *
+carp_group_find(char *group)
+{
+ struct carpgroup *c;
+
+ TAILQ_FOREACH(c, &carpgroups, entry)
+ if (!strcmp(c->group, group))
+ return (c);
+
+ return (NULL);
+}
+
+int
+carp_demote_init(char *group, int force)
+{
+ struct carpgroup *c;
+ int level;
+
+ if ((c = carp_group_find(group)) == NULL) {
+ if ((c = calloc(1, sizeof(struct carpgroup))) == NULL) {
+ log_warn("carp_demote_init calloc");
+ return (-1);
+ }
+ if ((c->group = strdup(group)) == NULL) {
+ log_warn("carp_demote_init strdup");
+ free(c);
+ return (-1);
+ }
+
+ /* only demote if this group already is demoted */
+ if ((level = carp_demote_get(group)) == -1)
+ return (-1);
+ if (level > 0 || force)
+ c->do_demote = 1;
+
+ TAILQ_INSERT_TAIL(&carpgroups, c, entry);
+ }
+
+ return (0);
+}
+
+void
+carp_demote_shutdown(void)
+{
+ struct carpgroup *c;
+
+ while ((c = TAILQ_FIRST(&carpgroups)) != NULL) {
+ TAILQ_REMOVE(&carpgroups, c, entry);
+ for (; c->changed_by > 0; c->changed_by--)
+ if (c->do_demote)
+ carp_demote_ioctl(c->group, -1);
+
+ free(c->group);
+ free(c);
+ }
+}
+
+int
+carp_demote_get(char *group)
+{
+ int s;
+ struct ifgroupreq ifgr;
+
+ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
+ log_warn("carp_demote_get: socket");
+ return (-1);
+ }
+
+ bzero(&ifgr, sizeof(ifgr));
+ strlcpy(ifgr.ifgr_name, group, sizeof(ifgr.ifgr_name));
+
+ if (ioctl(s, SIOCGIFGATTR, (caddr_t)&ifgr) == -1) {
+ if (errno == ENOENT)
+ log_warnx("group \"%s\" does not exist", group);
+ else
+ log_warn("carp_demote_get: ioctl");
+ close(s);
+ return (-1);
+ }
+
+ close(s);
+ return ((int)ifgr.ifgr_attrib.ifg_carp_demoted);
+}
+
+int
+carp_demote_set(char *group, int demote)
+{
+ struct carpgroup *c;
+
+ if ((c = carp_group_find(group)) == NULL) {
+ log_warnx("carp_group_find for %s returned NULL?!", group);
+ return (-1);
+ }
+
+ if (c->changed_by + demote < 0) {
+ log_warnx("carp_demote_set: changed_by + demote < 0");
+ return (-1);
+ }
+
+ if (c->do_demote && carp_demote_ioctl(group, demote) == -1)
+ return (-1);
+
+ c->changed_by += demote;
+
+ /* enable demotion when we return to 0, i. e. all sessions up */
+ if (demote < 0 && c->changed_by == 0)
+ c->do_demote = 1;
+
+ return (0);
+}
+
+int
+carp_demote_ioctl(char *group, int demote)
+{
+ int s, res;
+ struct ifgroupreq ifgr;
+
+ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
+ log_warn("carp_demote_get: socket");
+ return (-1);
+ }
+
+ bzero(&ifgr, sizeof(ifgr));
+ strlcpy(ifgr.ifgr_name, group, sizeof(ifgr.ifgr_name));
+ ifgr.ifgr_attrib.ifg_carp_demoted = demote;
+
+ if ((res = ioctl(s, SIOCSIFGATTR, (caddr_t)&ifgr)) == -1)
+ log_warn("unable to %s the demote state "
+ "of group '%s'", (demote > 0) ? "increment" : "decrement",
+ group);
+ else
+ log_info("%s the demote state of group '%s'",
+ (demote > 0) ? "incremented" : "decremented", group);
+
+ close(s);
+ return (res);
+}
diff --git a/usr.sbin/ospfd/interface.c b/usr.sbin/ospfd/interface.c
index 8d6f2f7e940..393d277ab96 100644
--- a/usr.sbin/ospfd/interface.c
+++ b/usr.sbin/ospfd/interface.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: interface.c,v 1.58 2007/02/01 13:25:28 claudio Exp $ */
+/* $OpenBSD: interface.c,v 1.59 2007/05/29 22:08:25 claudio Exp $ */
/*
* Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org>
@@ -139,6 +139,13 @@ if_fsm(struct iface *iface, enum iface_event event)
if (iface->state != old_state)
orig_rtr_lsa(iface->area);
+ if (old_state & (IF_STA_MULTI | IF_STA_POINTTOPOINT) &&
+ (iface->state & (IF_STA_MULTI | IF_STA_POINTTOPOINT)) == 0)
+ ospfe_demote_iface(iface, 0);
+ if ((old_state & (IF_STA_MULTI | IF_STA_POINTTOPOINT)) == 0 &&
+ iface->state & (IF_STA_MULTI | IF_STA_POINTTOPOINT))
+ ospfe_demote_iface(iface, 1);
+
log_debug("if_fsm: event %s resulted in action %s and changing "
"state for interface %s from %s to %s",
if_event_names[event], if_action_names[iface_fsm[i].action],
@@ -209,6 +216,10 @@ if_del(struct iface *iface)
log_debug("if_del: interface %s", iface->name);
+ /* revert the demotion when the interface is deleted */
+ if ((iface->state & (IF_STA_MULTI | IF_STA_POINTTOPOINT)) == 0)
+ ospfe_demote_iface(iface, 1);
+
/* clear lists etc */
while ((nbr = LIST_FIRST(&iface->nbr_list)) != NULL)
nbr_del(nbr);
@@ -237,6 +248,8 @@ if_init(struct ospfd_conf *xconf, struct iface *iface)
evtimer_set(&iface->wait_timer, if_wait_timer, iface);
iface->fd = xconf->ospf_socket;
+
+ ospfe_demote_iface(iface, 0);
}
/* timers */
diff --git a/usr.sbin/ospfd/ospfd.c b/usr.sbin/ospfd/ospfd.c
index d27330b1094..e71744f1119 100644
--- a/usr.sbin/ospfd/ospfd.c
+++ b/usr.sbin/ospfd/ospfd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ospfd.c,v 1.45 2007/03/25 15:48:54 claudio Exp $ */
+/* $OpenBSD: ospfd.c,v 1.46 2007/05/29 22:08:25 claudio Exp $ */
/*
* Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org>
@@ -117,7 +117,7 @@ usage(void)
{
extern char *__progname;
- fprintf(stderr, "usage: %s [-dnv] [-f file]\n", __progname);
+ fprintf(stderr, "usage: %s [-cdnv] [-f file]\n", __progname);
exit(1);
}
@@ -135,8 +135,11 @@ main(int argc, char *argv[])
conffile = CONF_FILE;
ospfd_process = PROC_MAIN;
- while ((ch = getopt(argc, argv, "df:nv")) != -1) {
+ while ((ch = getopt(argc, argv, "cdf:nv")) != -1) {
switch (ch) {
+ case 'c':
+ opts |= OSPFD_OPT_FORCE_DEMOTE;
+ break;
case 'd':
debug = 1;
break;
@@ -295,6 +298,7 @@ ospfd_shutdown(void)
control_cleanup();
kr_shutdown();
+ carp_demote_shutdown();
do {
if ((pid = wait(NULL)) == -1 &&
@@ -339,6 +343,7 @@ main_dispatch_ospfe(int fd, short event, void *bula)
{
struct imsgbuf *ibuf = bula;
struct imsg imsg;
+ struct demote_msg dmsg;
ssize_t n;
switch (event) {
@@ -389,6 +394,12 @@ main_dispatch_ospfe(int fd, short event, void *bula)
else
log_warnx("IFINFO request with wrong len");
break;
+ case IMSG_DEMOTE:
+ if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(dmsg))
+ fatalx("invalid size of OE request");
+ memcpy(&dmsg, imsg.data, sizeof(dmsg));
+ carp_demote_set(dmsg.demote_group, dmsg.level);
+ break;
default:
log_debug("main_dispatch_ospfe: error handling imsg %d",
imsg.hdr.type);
@@ -667,6 +678,7 @@ merge_config(struct ospfd_conf *conf, struct ospfd_conf *xconf)
LIST_INSERT_HEAD(&conf->area_list, xa, entry);
if (ospfd_process == PROC_OSPF_ENGINE) {
/* start interfaces */
+ ospfe_demote_area(xa, 0);
LIST_FOREACH(iface, &xa->iface_list, entry) {
if_init(conf, iface);
if (if_fsm(iface, IF_EVT_UP)) {
diff --git a/usr.sbin/ospfd/ospfd.h b/usr.sbin/ospfd/ospfd.h
index ece2f416e89..7da4116f7b2 100644
--- a/usr.sbin/ospfd/ospfd.h
+++ b/usr.sbin/ospfd/ospfd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ospfd.h,v 1.66 2007/03/21 10:54:30 claudio Exp $ */
+/* $OpenBSD: ospfd.h,v 1.67 2007/05/29 22:08:25 claudio Exp $ */
/*
* Copyright (c) 2004 Esben Norby <norby@openbsd.org>
@@ -144,7 +144,8 @@ enum imsg_type {
IMSG_RECONF_AREA,
IMSG_RECONF_IFACE,
IMSG_RECONF_AUTHMD,
- IMSG_RECONF_END
+ IMSG_RECONF_END,
+ IMSG_DEMOTE
};
struct imsg_hdr {
@@ -172,12 +173,14 @@ struct area {
LIST_HEAD(, iface) iface_list;
LIST_HEAD(, rde_nbr) nbr_list;
/* list addr_range_list; */
+ char demote_group[IFNAMSIZ];
u_int32_t stub_default_cost;
u_int32_t num_spf_calc;
int active;
u_int8_t transit;
u_int8_t stub;
u_int8_t dirty;
+ u_int8_t demote_level;
};
/* interface states */
@@ -328,6 +331,7 @@ struct iface {
struct lsa_head ls_ack_list;
char name[IF_NAMESIZE];
+ char demote_group[IFNAMSIZ];
char auth_key[MAX_SIMPLE_AUTH_LEN];
struct in_addr addr;
struct in_addr dst;
@@ -396,6 +400,7 @@ struct ospfd_conf {
#define OSPFD_OPT_VERBOSE2 0x00000002
#define OSPFD_OPT_NOACTION 0x00000004
#define OSPFD_OPT_STUB_ROUTER 0x00000008
+#define OSPFD_OPT_FORCE_DEMOTE 0x00000010
u_int32_t spf_delay;
u_int32_t spf_hold_time;
time_t uptime;
@@ -526,6 +531,11 @@ struct ctl_sum_area {
u_int32_t num_lsa;
};
+struct demote_msg {
+ char demote_group[IF_NAMESIZE];
+ int level;
+};
+
/* area.c */
struct area *area_new(void);
int area_del(struct area *);
@@ -545,6 +555,12 @@ void msgbuf_init(struct msgbuf *);
void msgbuf_clear(struct msgbuf *);
int msgbuf_write(struct msgbuf *);
+/* carp.c */
+int carp_demote_init(char *, int);
+void carp_demote_shutdown(void);
+int carp_demote_get(char *);
+int carp_demote_set(char *, int);
+
/* parse.y */
struct ospfd_conf *parse_config(char *, int);
int cmdline_symset(char *);
diff --git a/usr.sbin/ospfd/ospfe.c b/usr.sbin/ospfd/ospfe.c
index f97fd09d02b..90c30d427d4 100644
--- a/usr.sbin/ospfd/ospfe.c
+++ b/usr.sbin/ospfd/ospfe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ospfe.c,v 1.54 2007/03/21 10:54:30 claudio Exp $ */
+/* $OpenBSD: ospfe.c,v 1.55 2007/05/29 22:08:25 claudio Exp $ */
/*
* Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org>
@@ -179,6 +179,7 @@ ospfe(struct ospfd_conf *xconf, int pipe_parent2ospfe[2], int pipe_ospfe2rde[2],
/* start interfaces */
LIST_FOREACH(area, &oeconf->area_list, entry) {
+ ospfe_demote_area(area, 0);
LIST_FOREACH(iface, &area->iface_list, entry) {
if_init(xconf, iface);
if (if_fsm(iface, IF_EVT_UP)) {
@@ -1043,3 +1044,42 @@ ospfe_nbr_ctl(struct ctl_conn *c)
imsg_compose(&c->ibuf, IMSG_CTL_END, 0, 0, NULL, 0);
}
+
+void
+ospfe_demote_area(struct area *area, int active)
+{
+ struct demote_msg dmsg;
+
+ if (ospfd_process != PROC_OSPF_ENGINE ||
+ area->demote_group[0] == '\0')
+ return;
+
+ bzero(&dmsg, sizeof(dmsg));
+ strlcpy(dmsg.demote_group, area->demote_group,
+ sizeof(dmsg.demote_group));
+ dmsg.level = area->demote_level;
+ if (active)
+ dmsg.level = -dmsg.level;
+
+ ospfe_imsg_compose_parent(IMSG_DEMOTE, 0, &dmsg, sizeof(dmsg));
+}
+
+void
+ospfe_demote_iface(struct iface *iface, int active)
+{
+ struct demote_msg dmsg;
+
+ if (ospfd_process != PROC_OSPF_ENGINE ||
+ iface->demote_group[0] == '\0')
+ return;
+
+ bzero(&dmsg, sizeof(dmsg));
+ strlcpy(dmsg.demote_group, iface->demote_group,
+ sizeof(dmsg.demote_group));
+ if (active)
+ dmsg.level = -1;
+ else
+ dmsg.level = 1;
+
+ ospfe_imsg_compose_parent(IMSG_DEMOTE, 0, &dmsg, sizeof(dmsg));
+}
diff --git a/usr.sbin/ospfd/ospfe.h b/usr.sbin/ospfd/ospfe.h
index fa27628090c..e828fe6465d 100644
--- a/usr.sbin/ospfd/ospfe.h
+++ b/usr.sbin/ospfd/ospfe.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ospfe.h,v 1.35 2007/03/21 10:54:30 claudio Exp $ */
+/* $OpenBSD: ospfe.h,v 1.36 2007/05/29 22:08:25 claudio Exp $ */
/*
* Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org>
@@ -130,6 +130,8 @@ void ospfe_iface_ctl(struct ctl_conn *, unsigned int);
void ospfe_nbr_ctl(struct ctl_conn *);
void orig_rtr_lsa(struct area *);
void orig_net_lsa(struct iface *);
+void ospfe_demote_area(struct area *, int);
+void ospfe_demote_iface(struct iface *, int);
/* interface.c */
int if_fsm(struct iface *, enum iface_event);
diff --git a/usr.sbin/ospfd/parse.y b/usr.sbin/ospfd/parse.y
index 564928298c7..9d96f6641b1 100644
--- a/usr.sbin/ospfd/parse.y
+++ b/usr.sbin/ospfd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.47 2007/03/28 14:17:13 claudio Exp $ */
+/* $OpenBSD: parse.y,v 1.48 2007/05/29 22:08:25 claudio Exp $ */
/*
* Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org>
@@ -112,6 +112,7 @@ typedef struct {
%token RETRANSMITINTERVAL ROUTERDEADTIME ROUTERPRIORITY
%token SET TYPE
%token YES NO
+%token DEMOTE
%token ERROR
%token <v.string> STRING
%type <v.number> number yesno no optlist, optlist_l option
@@ -470,6 +471,28 @@ areaopts_l : areaopts_l areaoptsl nl
;
areaoptsl : interface
+ | DEMOTE STRING number {
+ if ($3 > 255) {
+ yyerror("demote count too big: max 255");
+ free($2);
+ YYERROR;
+ }
+ area->demote_level = $3;
+ if (strlcpy(area->demote_group, $2,
+ sizeof(area->demote_group)) >=
+ sizeof(area->demote_group)) {
+ yyerror("demote group name \"%s\" too long");
+ free($2);
+ YYERROR;
+ }
+ free($2);
+ if (carp_demote_init(area->demote_group,
+ conf->opts & OSPFD_OPT_FORCE_DEMOTE) == -1) {
+ yyerror("error initializing group \"%s\"",
+ area->demote_group);
+ YYERROR;
+ }
+ }
| defaults
;
@@ -544,6 +567,22 @@ interfaceopts_l : interfaceopts_l interfaceoptsl nl
;
interfaceoptsl : PASSIVE { iface->passive = 1; }
+ | DEMOTE STRING {
+ if (strlcpy(iface->demote_group, $2,
+ sizeof(iface->demote_group)) >=
+ sizeof(iface->demote_group)) {
+ yyerror("demote group name \"%s\" too long");
+ free($2);
+ YYERROR;
+ }
+ free($2);
+ if (carp_demote_init(iface->demote_group,
+ conf->opts & OSPFD_OPT_FORCE_DEMOTE) == -1) {
+ yyerror("error initializing group \"%s\"",
+ iface->demote_group);
+ YYERROR;
+ }
+ }
| defaults
;
@@ -585,6 +624,7 @@ lookup(char *s)
{"auth-md", AUTHMD},
{"auth-md-keyid", AUTHMDKEYID},
{"auth-type", AUTHTYPE},
+ {"demote", DEMOTE},
{"fib-update", FIBUPDATE},
{"hello-interval", HELLOINTERVAL},
{"interface", INTERFACE},
diff --git a/usr.sbin/ospfd/printconf.c b/usr.sbin/ospfd/printconf.c
index b7f2445e22d..510a7ae87a6 100644
--- a/usr.sbin/ospfd/printconf.c
+++ b/usr.sbin/ospfd/printconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: printconf.c,v 1.8 2007/03/22 16:00:46 claudio Exp $ */
+/* $OpenBSD: printconf.c,v 1.9 2007/05/29 22:08:25 claudio Exp $ */
/*
* Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org>
@@ -107,6 +107,8 @@ print_iface(struct iface *iface)
if (iface->passive)
printf("\t\tpassive\n");
+ if (*iface->demote_group)
+ printf("\t\tdemote %s\n", iface->demote_group);
printf("\t\tretransmit-interval %d\n", iface->rxmt_interval);
printf("\t\trouter-dead-time %d\n", iface->dead_interval);
@@ -145,6 +147,9 @@ print_config(struct ospfd_conf *conf)
LIST_FOREACH(area, &conf->area_list, entry) {
printf("area %s {\n", inet_ntoa(area->id));
+ if (*area->demote_group)
+ printf("\tdemote %s %d\n", area->demote_group,
+ area->demote_level);
LIST_FOREACH(iface, &area->iface_list, entry) {
print_iface(iface);
}