diff options
-rw-r--r-- | usr.sbin/ospfd/kroute.c | 13 | ||||
-rw-r--r-- | usr.sbin/ospfd/ospf.h | 3 | ||||
-rw-r--r-- | usr.sbin/ospfd/ospfd.c | 16 | ||||
-rw-r--r-- | usr.sbin/ospfd/ospfd.h | 10 | ||||
-rw-r--r-- | usr.sbin/ospfd/parse.y | 60 | ||||
-rw-r--r-- | usr.sbin/ospfd/rde.c | 52 |
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; |