summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/ospfd/kroute.c13
-rw-r--r--usr.sbin/ospfd/ospf.h3
-rw-r--r--usr.sbin/ospfd/ospfd.c16
-rw-r--r--usr.sbin/ospfd/ospfd.h10
-rw-r--r--usr.sbin/ospfd/parse.y60
-rw-r--r--usr.sbin/ospfd/rde.c52
6 files changed, 109 insertions, 45 deletions
diff --git a/usr.sbin/ospfd/kroute.c b/usr.sbin/ospfd/kroute.c
index ee0ae0d9a9d..6080c6aa249 100644
--- a/usr.sbin/ospfd/kroute.c
+++ b/usr.sbin/ospfd/kroute.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kroute.c,v 1.37 2006/11/28 19:21:15 reyk Exp $ */
+/* $OpenBSD: kroute.c,v 1.38 2006/12/07 19:14:27 claudio Exp $ */
/*
* Copyright (c) 2004 Esben Norby <norby@openbsd.org>
@@ -343,8 +343,8 @@ kr_ifinfo(char *ifname, pid_t pid)
void
kr_redistribute(int type, struct kroute *kr)
{
- u_int32_t a;
-
+ u_int32_t a, metric = 0;
+ struct rroute rr;
if (type == IMSG_NETWORK_DEL) {
dont_redistribute:
@@ -385,12 +385,15 @@ dont_redistribute:
goto dont_redistribute;
/* Should we redistrubute this route? */
- if (!ospf_redistribute(kr))
+ if (!ospf_redistribute(kr, &metric))
goto dont_redistribute;
/* Does not matter if we resend the kr, the RDE will cope. */
kr->flags |= F_REDISTRIBUTED;
- main_imsg_compose_rde(type, 0, kr, sizeof(struct kroute));
+
+ rr.kr = *kr;
+ rr.metric = metric;
+ main_imsg_compose_rde(type, 0, &rr, sizeof(struct rroute));
}
/* rb-tree compare */
diff --git a/usr.sbin/ospfd/ospf.h b/usr.sbin/ospfd/ospf.h
index 8d46b6b63ef..5b65d7758b8 100644
--- a/usr.sbin/ospfd/ospf.h
+++ b/usr.sbin/ospfd/ospf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ospf.h,v 1.15 2006/03/09 16:52:43 norby Exp $ */
+/* $OpenBSD: ospf.h,v 1.16 2006/12/07 19:14:27 claudio Exp $ */
/*
* Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org>
@@ -32,6 +32,7 @@
#define PACKET_HDR 100 /* XXX used to calculate the IP payload */
#define DEFAULT_METRIC 10
+#define DEFAULT_REDIST_METRIC 100
#define MIN_METRIC 1
#define MAX_METRIC 65535 /* sum & as-ext lsa use 24bit metrics */
diff --git a/usr.sbin/ospfd/ospfd.c b/usr.sbin/ospfd/ospfd.c
index 7af4b2515c4..88687d33a7f 100644
--- a/usr.sbin/ospfd/ospfd.c
+++ b/usr.sbin/ospfd/ospfd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ospfd.c,v 1.36 2006/11/01 13:20:18 claudio Exp $ */
+/* $OpenBSD: ospfd.c,v 1.37 2006/12/07 19:14:27 claudio Exp $ */
/*
* Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org>
@@ -485,7 +485,7 @@ imsg_event_add(struct imsgbuf *ibuf)
}
int
-ospf_redistribute(struct kroute *kr)
+ospf_redistribute(struct kroute *kr, u_int32_t *metric)
{
struct redistribute *r;
@@ -511,22 +511,28 @@ ospf_redistribute(struct kroute *kr)
*/
if (kr->flags & F_DYNAMIC)
continue;
- if (kr->flags & F_STATIC)
+ if (kr->flags & F_STATIC) {
+ *metric = r->metric;
return (r->type & REDIST_NO ? 0 : 1);
+ }
break;
case REDIST_CONNECTED:
if (kr->flags & F_DYNAMIC)
continue;
- if (kr->flags & F_CONNECTED)
+ if (kr->flags & F_CONNECTED) {
+ *metric = r->metric;
return (r->type & REDIST_NO ? 0 : 1);
+ }
break;
case REDIST_ADDR:
if (kr->flags & F_DYNAMIC)
continue;
if ((kr->prefix.s_addr & r->mask.s_addr) ==
(r->addr.s_addr & r->mask.s_addr) &&
- kr->prefixlen >= mask2prefixlen(r->mask.s_addr))
+ kr->prefixlen >= mask2prefixlen(r->mask.s_addr)) {
+ *metric = r->metric;
return (r->type & REDIST_NO? 0 : 1);
+ }
break;
}
}
diff --git a/usr.sbin/ospfd/ospfd.h b/usr.sbin/ospfd/ospfd.h
index 6121643ee9c..1c036f35ace 100644
--- a/usr.sbin/ospfd/ospfd.h
+++ b/usr.sbin/ospfd/ospfd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ospfd.h,v 1.61 2006/11/17 08:55:31 claudio Exp $ */
+/* $OpenBSD: ospfd.h,v 1.62 2006/12/07 19:14:27 claudio Exp $ */
/*
* Copyright (c) 2004 Esben Norby <norby@openbsd.org>
@@ -371,6 +371,7 @@ 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;
};
@@ -408,6 +409,11 @@ struct kroute {
u_int8_t prefixlen;
};
+struct rroute {
+ struct kroute kr;
+ u_int32_t metric;
+};
+
struct kif_addr {
TAILQ_ENTRY(kif_addr) entry;
struct in_addr addr;
@@ -585,7 +591,7 @@ void rtlabel_unref(u_int16_t);
/* ospfd.c */
void main_imsg_compose_ospfe(int, pid_t, void *, u_int16_t);
void main_imsg_compose_rde(int, pid_t, void *, u_int16_t);
-int ospf_redistribute(struct kroute *kr);
+int ospf_redistribute(struct kroute *, u_int32_t *);
/* printconf.c */
void print_config(struct ospfd_conf *);
diff --git a/usr.sbin/ospfd/parse.y b/usr.sbin/ospfd/parse.y
index 857df2c0a0e..a114b10aef4 100644
--- a/usr.sbin/ospfd/parse.y
+++ b/usr.sbin/ospfd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.38 2006/11/17 08:55:31 claudio Exp $ */
+/* $OpenBSD: parse.y,v 1.39 2006/12/07 19:14:27 claudio Exp $ */
/*
* Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org>
@@ -111,10 +111,11 @@ typedef struct {
%token METRIC PASSIVE
%token HELLOINTERVAL TRANSMITDELAY
%token RETRANSMITINTERVAL ROUTERDEADTIME ROUTERPRIORITY
+%token SET TYPE
%token YES NO
%token ERROR
%token <v.string> STRING
-%type <v.number> number yesno no
+%type <v.number> number yesno no optlist, optlist_l option
%type <v.string> string
%%
@@ -186,7 +187,7 @@ conf_main : ROUTERID STRING {
else
conf->flags &= ~OSPFD_FLAG_NO_FIB_UPDATE;
}
- | no REDISTRIBUTE STRING {
+ | no REDISTRIBUTE STRING optlist {
struct redistribute *r;
if (!strcmp($3, "default")) {
@@ -215,15 +216,15 @@ conf_main : ROUTERID STRING {
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 {
+ | no REDISTRIBUTE RTLABEL STRING optlist {
struct redistribute *r;
if ((r = calloc(1, sizeof(*r))) == NULL)
@@ -232,6 +233,7 @@ conf_main : ROUTERID STRING {
r->label = rtlabel_name2id($4);
if ($1)
r->type |= REDIST_NO;
+ r->metric = $5;
free($4);
SIMPLEQ_INSERT_TAIL(&conf->redist_list, r, entry);
@@ -261,6 +263,47 @@ conf_main : ROUTERID STRING {
| defaults
;
+optlist : /* empty */ { $$ = DEFAULT_REDIST_METRIC; }
+ | SET option { $$ = $2; }
+ | SET optnl '{' optnl optlist_l optnl '}' { $$ = $5; }
+ ;
+
+optlist_l : optlist_l comma option {
+ if ($1 & LSA_ASEXT_E_FLAG && $3 & LSA_ASEXT_E_FLAG) {
+ yyerror("redistribute type already defined");
+ YYERROR;
+ }
+ if ($1 & LSA_METRIC_MASK && $3 & LSA_METRIC_MASK) {
+ yyerror("redistribute metricr already defined");
+ YYERROR;
+ }
+ $$ = $1 | $3;
+ }
+ | option { $$ = $1; }
+ ;
+
+option : METRIC number {
+ if ($2 == 0 || $2 > MAX_METRIC) {
+ yyerror("invalid redistribute metric");
+ YYERROR;
+ }
+ $$ = $2;
+ }
+ | TYPE number {
+ switch ($2) {
+ case 1:
+ $$ = 0;
+ break;
+ case 2:
+ $$ = LSA_ASEXT_E_FLAG;
+ break;
+ default:
+ yyerror("illegal external type %u", $2);
+ YYERROR;
+ }
+ }
+ ;
+
authmd : AUTHMD number STRING {
if ($2 < MIN_MD_ID || $2 > MAX_MD_ID) {
yyerror("auth-md key-id out of range "
@@ -384,6 +427,10 @@ optnl : '\n' optnl
nl : '\n' optnl /* one newline or more */
;
+comma : ','
+ | /*empty*/
+ ;
+
area : AREA STRING {
struct in_addr id;
if (inet_aton($2, &id) == 0) {
@@ -538,9 +585,11 @@ lookup(char *s)
{"router-id", ROUTERID},
{"router-priority", ROUTERPRIORITY},
{"rtlabel", RTLABEL},
+ {"set", SET},
{"spf-delay", SPFDELAY},
{"spf-holdtime", SPFHOLDTIME},
{"transmit-delay", TRANSMITDELAY},
+ {"type", TYPE},
{"yes", YES}
};
const struct keywords *p;
@@ -985,4 +1034,3 @@ host(const char *s, struct in_addr *addr, struct in_addr *mask)
return (1);
}
-
diff --git a/usr.sbin/ospfd/rde.c b/usr.sbin/ospfd/rde.c
index 06d8a1bebb5..d7af2b0d19a 100644
--- a/usr.sbin/ospfd/rde.c
+++ b/usr.sbin/ospfd/rde.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.c,v 1.47 2006/06/28 10:53:39 norby Exp $ */
+/* $OpenBSD: rde.c,v 1.48 2006/12/07 19:14:27 claudio Exp $ */
/*
* Copyright (c) 2004, 2005 Claudio Jeker <claudio@openbsd.org>
@@ -56,10 +56,10 @@ int rde_req_list_exists(struct rde_nbr *, struct lsa_hdr *);
void rde_req_list_del(struct rde_nbr *, struct lsa_hdr *);
void rde_req_list_free(struct rde_nbr *);
-struct lsa *rde_asext_get(struct kroute *);
-struct lsa *rde_asext_put(struct kroute *);
+struct lsa *rde_asext_get(struct rroute *);
+struct lsa *rde_asext_put(struct rroute *);
-struct lsa *orig_asext_lsa(struct kroute *, u_int16_t);
+struct lsa *orig_asext_lsa(struct rroute *, u_int16_t);
struct lsa *orig_sum_lsa(struct rt_node *, u_int8_t);
struct ospfd_conf *rdeconf = NULL;
@@ -580,6 +580,7 @@ rde_dispatch_parent(int fd, short event, void *bula)
{
struct imsg imsg;
struct kroute kr;
+ struct rroute rr;
struct imsgbuf *ibuf = bula;
struct lsa *lsa;
struct vertex *v;
@@ -610,13 +611,13 @@ rde_dispatch_parent(int fd, short event, void *bula)
switch (imsg.hdr.type) {
case IMSG_NETWORK_ADD:
- if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(kr)) {
+ if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(rr)) {
log_warnx("rde_dispatch: wrong imsg len");
break;
}
- memcpy(&kr, imsg.data, sizeof(kr));
+ memcpy(&rr, imsg.data, sizeof(rr));
- if ((lsa = rde_asext_get(&kr)) != NULL) {
+ if ((lsa = rde_asext_get(&rr)) != NULL) {
v = lsa_find(NULL, lsa->hdr.type,
lsa->hdr.ls_id, lsa->hdr.adv_rtr);
@@ -624,13 +625,13 @@ rde_dispatch_parent(int fd, short event, void *bula)
}
break;
case IMSG_NETWORK_DEL:
- if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(kr)) {
+ if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(rr)) {
log_warnx("rde_dispatch: wrong imsg len");
break;
}
- memcpy(&kr, imsg.data, sizeof(kr));
+ memcpy(&rr, imsg.data, sizeof(rr));
- if ((lsa = rde_asext_put(&kr)) != NULL) {
+ if ((lsa = rde_asext_put(&rr)) != NULL) {
v = lsa_find(NULL, lsa->hdr.type,
lsa->hdr.ls_id, lsa->hdr.adv_rtr);
@@ -949,7 +950,7 @@ rde_req_list_free(struct rde_nbr *nbr)
* as-external LSA handling
*/
struct lsa *
-rde_asext_get(struct kroute *kr)
+rde_asext_get(struct rroute *rr)
{
struct area *area;
struct iface *iface;
@@ -957,21 +958,21 @@ rde_asext_get(struct kroute *kr)
LIST_FOREACH(area, &rdeconf->area_list, entry)
LIST_FOREACH(iface, &area->iface_list, entry) {
if ((iface->addr.s_addr & iface->mask.s_addr) ==
- kr->prefix.s_addr && iface->mask.s_addr ==
- prefixlen2mask(kr->prefixlen)) {
+ rr->kr.prefix.s_addr && iface->mask.s_addr ==
+ prefixlen2mask(rr->kr.prefixlen)) {
/* already announced as (stub) net LSA */
log_debug("rde_asext_get: %s/%d is net LSA",
- inet_ntoa(kr->prefix), kr->prefixlen);
+ inet_ntoa(rr->kr.prefix), rr->kr.prefixlen);
return (NULL);
}
}
/* update of seqnum is done by lsa_merge */
- return (orig_asext_lsa(kr, DEFAULT_AGE));
+ return (orig_asext_lsa(rr, DEFAULT_AGE));
}
struct lsa *
-rde_asext_put(struct kroute *kr)
+rde_asext_put(struct rroute *rr)
{
struct area *area;
struct iface *iface;
@@ -979,17 +980,17 @@ rde_asext_put(struct kroute *kr)
LIST_FOREACH(area, &rdeconf->area_list, entry)
LIST_FOREACH(iface, &area->iface_list, entry) {
if ((iface->addr.s_addr & iface->mask.s_addr) ==
- kr->prefix.s_addr && iface->mask.s_addr ==
- prefixlen2mask(kr->prefixlen)) {
+ rr->kr.prefix.s_addr && iface->mask.s_addr ==
+ prefixlen2mask(rr->kr.prefixlen)) {
/* already announced as (stub) net LSA */
log_debug("rde_asext_put: %s/%d is net LSA",
- inet_ntoa(kr->prefix), kr->prefixlen);
+ inet_ntoa(rr->kr.prefix), rr->kr.prefixlen);
return (NULL);
}
}
/* remove by reflooding with MAX_AGE */
- return (orig_asext_lsa(kr, MAX_AGE));
+ return (orig_asext_lsa(rr, MAX_AGE));
}
/*
@@ -1047,7 +1048,7 @@ rde_summary_update(struct rt_node *rte, struct area *area)
* functions for self-originated LSA
*/
struct lsa *
-orig_asext_lsa(struct kroute *kr, u_int16_t age)
+orig_asext_lsa(struct rroute *rr, u_int16_t age)
{
struct lsa *lsa;
u_int16_t len;
@@ -1057,7 +1058,7 @@ orig_asext_lsa(struct kroute *kr, u_int16_t age)
fatal("orig_asext_lsa");
log_debug("orig_asext_lsa: %s/%d age %d",
- inet_ntoa(kr->prefix), kr->prefixlen, age);
+ inet_ntoa(rr->kr.prefix), rr->kr.prefixlen, age);
/* LSA header */
lsa->hdr.age = htons(age);
@@ -1073,8 +1074,8 @@ orig_asext_lsa(struct kroute *kr, u_int16_t age)
* not be true. In this case a hack needs to be done to
* make the ls_id unique.
*/
- lsa->hdr.ls_id = kr->prefix.s_addr;
- lsa->data.asext.mask = prefixlen2mask(kr->prefixlen);
+ lsa->hdr.ls_id = rr->kr.prefix.s_addr;
+ lsa->data.asext.mask = prefixlen2mask(rr->kr.prefixlen);
/*
* nexthop -- on connected routes we are the nexthop,
@@ -1085,8 +1086,7 @@ orig_asext_lsa(struct kroute *kr, u_int16_t age)
*/
lsa->data.asext.fw_addr = 0;
- lsa->data.asext.metric = htonl(/* LSA_ASEXT_E_FLAG | */ 100);
- /* XXX until now there is no metric */
+ lsa->data.asext.metric = htonl(rr->metric);
lsa->data.asext.ext_tag = 0;
lsa->hdr.ls_chksum = 0;