summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2010-08-22 21:15:26 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2010-08-22 21:15:26 +0000
commite332c640366dec097cd0fce713647877e049f841 (patch)
tree09faa050f385c2eb717bde1c9b86a499fbd5c1d6
parent8b0fe1f05a24ae94c4d8e02325e8956d04164f11 (diff)
Redistributing the default route with ospf6d did not work correctly.
- kroute.c may not ignore the default route. - Use the ROUNDUP macro from route/show.c as this one is also correct for netmask with prefixlen 0. - Implement ospf_redistribute and the redistribute parser like ospfd. ok claudio@
-rw-r--r--usr.sbin/ospf6d/kroute.c11
-rw-r--r--usr.sbin/ospf6d/ospf6d.c47
-rw-r--r--usr.sbin/ospf6d/ospf6d.h7
-rw-r--r--usr.sbin/ospf6d/parse.y99
-rw-r--r--usr.sbin/ospf6d/printconf.c8
5 files changed, 83 insertions, 89 deletions
diff --git a/usr.sbin/ospf6d/kroute.c b/usr.sbin/ospf6d/kroute.c
index e8738e36764..cbbb5310591 100644
--- a/usr.sbin/ospf6d/kroute.c
+++ b/usr.sbin/ospf6d/kroute.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kroute.c,v 1.27 2010/07/14 17:09:13 claudio Exp $ */
+/* $OpenBSD: kroute.c,v 1.28 2010/08/22 21:15:25 bluhm Exp $ */
/*
* Copyright (c) 2004 Esben Norby <norby@openbsd.org>
@@ -382,11 +382,10 @@ kr_redist_eval(struct kroute *kr, struct rroute *rr)
goto dont_redistribute;
/*
- * We consider unspecified, loopback, multicast, link- and site-local,
+ * We consider loopback, multicast, link- and site-local,
* IPv4 mapped and IPv4 compatible addresses as not redistributable.
*/
- if (IN6_IS_ADDR_UNSPECIFIED(&kr->prefix) ||
- IN6_IS_ADDR_LOOPBACK(&kr->prefix) ||
+ if (IN6_IS_ADDR_LOOPBACK(&kr->prefix) ||
IN6_IS_ADDR_MULTICAST(&kr->prefix) ||
IN6_IS_ADDR_LINKLOCAL(&kr->prefix) ||
IN6_IS_ADDR_SITELOCAL(&kr->prefix) ||
@@ -774,8 +773,8 @@ inet6applymask(struct in6_addr *dest, const struct in6_addr *src, int prefixlen)
dest->s6_addr[i] = src->s6_addr[i] & mask.s6_addr[i];
}
-#define ROUNDUP(a) \
- (((a) & (sizeof(long) - 1)) ? (1 + ((a) | (sizeof(long) - 1))) : (a))
+#define ROUNDUP(a) \
+ ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
void
get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info)
diff --git a/usr.sbin/ospf6d/ospf6d.c b/usr.sbin/ospf6d/ospf6d.c
index 4e01a7d789c..68187ef26eb 100644
--- a/usr.sbin/ospf6d/ospf6d.c
+++ b/usr.sbin/ospf6d/ospf6d.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ospf6d.c,v 1.20 2010/07/06 13:24:35 bluhm Exp $ */
+/* $OpenBSD: ospf6d.c,v 1.21 2010/08/22 21:15:25 bluhm Exp $ */
/*
* Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org>
@@ -55,8 +55,6 @@ int check_child(pid_t, const char *);
void main_dispatch_ospfe(int, short, void *);
void main_dispatch_rde(int, short, void *);
-void ospf_redistribute_default(int);
-
int ospf_reload(void);
int ospf_sendboth(enum imsg_type, void *, u_int16_t);
int merge_interfaces(struct area *, struct area *);
@@ -282,9 +280,6 @@ main(int argc, char *argv[])
if (kr_init(!(ospfd_conf->flags & OSPFD_FLAG_NO_FIB_UPDATE)) == -1)
fatalx("kr_init failed");
- /* redistribute default */
- ospf_redistribute_default(IMSG_NETWORK_ADD);
-
event_dispatch();
ospfd_shutdown();
@@ -517,10 +512,11 @@ ospf_redistribute(struct kroute *kr, u_int32_t *metric)
{
struct redistribute *r;
struct in6_addr ina, inb;
+ u_int8_t is_default = 0;
- /* only allow 0.0.0.0/0 via REDISTRIBUTE_DEFAULT */
+ /* only allow ::/0 via REDIST_DEFAULT */
if (IN6_IS_ADDR_UNSPECIFIED(&kr->prefix) && kr->prefixlen == 0)
- return (0);
+ is_default = 1;
SIMPLEQ_FOREACH(r, &ospfd_conf->redist_list, entry) {
switch (r->type & ~REDIST_NO) {
@@ -536,6 +532,8 @@ ospf_redistribute(struct kroute *kr, u_int32_t *metric)
* so that link local addresses can be redistributed
* via a rtlabel.
*/
+ if (is_default)
+ continue;
if (kr->flags & F_DYNAMIC)
continue;
if (kr->flags & F_STATIC) {
@@ -544,6 +542,8 @@ ospf_redistribute(struct kroute *kr, u_int32_t *metric)
}
break;
case REDIST_CONNECTED:
+ if (is_default)
+ continue;
if (kr->flags & F_DYNAMIC)
continue;
if (kr->flags & F_CONNECTED) {
@@ -554,7 +554,17 @@ ospf_redistribute(struct kroute *kr, u_int32_t *metric)
case REDIST_ADDR:
if (kr->flags & F_DYNAMIC)
continue;
- inet6applymask(&ina, &kr->prefix, kr->prefixlen);
+
+ if (IN6_IS_ADDR_UNSPECIFIED(&r->addr) &&
+ r->prefixlen == 0) {
+ if (is_default) {
+ *metric = r->metric;
+ return (r->type & REDIST_NO ? 0 : 1);
+ } else
+ return (0);
+ }
+
+ inet6applymask(&ina, &kr->prefix, r->prefixlen);
inet6applymask(&inb, &r->addr, r->prefixlen);
if (IN6_ARE_ADDR_EQUAL(&ina, &inb) &&
kr->prefixlen >= r->prefixlen) {
@@ -562,25 +572,18 @@ ospf_redistribute(struct kroute *kr, u_int32_t *metric)
return (r->type & REDIST_NO ? 0 : 1);
}
break;
+ case REDIST_DEFAULT:
+ if (is_default) {
+ *metric = r->metric;
+ return (r->type & REDIST_NO ? 0 : 1);
+ }
+ break;
}
}
return (0);
}
-void
-ospf_redistribute_default(int type)
-{
- struct rroute rr;
-
- if (!(ospfd_conf->redistribute & REDISTRIBUTE_DEFAULT))
- return;
-
- bzero(&rr, sizeof(rr));
- rr.metric = ospfd_conf->defaultmetric;
- main_imsg_compose_rde(type, 0, &rr, sizeof(struct rroute));
-}
-
int
ospf_reload(void)
{
diff --git a/usr.sbin/ospf6d/ospf6d.h b/usr.sbin/ospf6d/ospf6d.h
index 6b6937a2357..6c117c67a8a 100644
--- a/usr.sbin/ospf6d/ospf6d.h
+++ b/usr.sbin/ospf6d/ospf6d.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ospf6d.h,v 1.21 2010/07/01 18:57:21 bluhm Exp $ */
+/* $OpenBSD: ospf6d.h,v 1.22 2010/08/22 21:15:25 bluhm Exp $ */
/*
* Copyright (c) 2004, 2007 Esben Norby <norby@openbsd.org>
@@ -58,9 +58,6 @@
#define F_DYNAMIC 0x0040
#define F_REDISTRIBUTED 0x0100
-#define REDISTRIBUTE_ON 0x01
-#define REDISTRIBUTE_DEFAULT 0x02
-
struct imsgev {
struct imsgbuf ibuf;
void (*handler)(int, short, void *);
@@ -345,6 +342,7 @@ enum {
#define REDIST_LABEL 0x04
#define REDIST_ADDR 0x08
#define REDIST_NO 0x10
+#define REDIST_DEFAULT 0x20
struct redistribute {
SIMPLEQ_ENTRY(redistribute) entry;
@@ -362,7 +360,6 @@ struct ospfd_conf {
LIST_HEAD(, vertex) cand_list;
SIMPLEQ_HEAD(, redistribute) 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/ospf6d/parse.y b/usr.sbin/ospf6d/parse.y
index ec85caf7abd..f1cca75a3db 100644
--- a/usr.sbin/ospf6d/parse.y
+++ b/usr.sbin/ospf6d/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.18 2010/08/03 18:42:41 henning Exp $ */
+/* $OpenBSD: parse.y,v 1.19 2010/08/22 21:15:25 bluhm Exp $ */
/*
* Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org>
@@ -106,6 +106,7 @@ typedef struct {
union {
int64_t number;
char *string;
+ struct redistribute *redist;
} v;
int lineno;
} YYSTYPE;
@@ -125,6 +126,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
%%
@@ -180,57 +182,9 @@ conf_main : ROUTERID STRING {
else
conf->flags &= ~OSPFD_FLAG_NO_FIB_UPDATE;
}
- | 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 (prefix($3, &r->addr, &r->prefixlen))
- 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) {
@@ -269,6 +223,47 @@ conf_main : ROUTERID STRING {
| defaults
;
+redistribute : 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 (prefix($3, &r->addr, &r->prefixlen))
+ 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;
diff --git a/usr.sbin/ospf6d/printconf.c b/usr.sbin/ospf6d/printconf.c
index 26a9f3500d9..9f8f5f29fb4 100644
--- a/usr.sbin/ospf6d/printconf.c
+++ b/usr.sbin/ospf6d/printconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: printconf.c,v 1.3 2007/12/13 08:54:05 claudio Exp $ */
+/* $OpenBSD: printconf.c,v 1.4 2010/08/22 21:15:25 bluhm Exp $ */
/*
* Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org>
@@ -69,9 +69,6 @@ print_redistribute(struct ospfd_conf *conf)
{
struct redistribute *r;
- if (conf->redistribute & REDISTRIBUTE_DEFAULT)
- printf("redistribute default\n");
-
SIMPLEQ_FOREACH(r, &conf->redist_list, entry) {
switch (r->type & ~REDIST_NO) {
case REDIST_STATIC:
@@ -89,6 +86,9 @@ print_redistribute(struct ospfd_conf *conf)
print_no(r->type), log_in6addr(&r->addr),
r->prefixlen);
break;
+ case REDIST_DEFAULT:
+ printf("%sredistribute default\n", print_no(r->type));
+ break;
}
}
}