On 05/06/13 01:16, Claudio Jeker wrote: > On Mon, Jun 03, 2013 at 03:43:21PM +0300, Kapetanakis Giannis wrote: >> >On 01/06/13 18:44, Claudio Jeker wrote: >>> > >Can you give this diff a spin? Not much tested but the current way we >>> > >define an area as active (having at least one active neighbor) is wrong. >>> > >This changes the decision to have at least one active interface >>> > >(not IF_STA_DOWN). Not sure if that will cause troubles with passive >>> > >interfaces since those are not considered active. At least it seems that >>> > >RFC 3509 uses this to define active areas. >>> > > >>> > >Thanks >> > >> >Just tested this diff and it does not work in my case for passive >> >interfaces (either carp or loopback). >> > >> >area 0.0.0.7 { >> > stub >> > interface carp8 {passive} >> > interface lo1 {passive} >> >} >> > >> >If I add carp8 or lo1 in area 0.0.0.0 then the routes are announced. >> > > Yeah, while the diff fixed the B flag it did not solve the problem that we > skipped our own networks. This version should solve that (at least it does > in my quick test). > > Needs lots of testing since this changes core parts of the route calculation. > -- :wq Claudio Index: area.c > =================================================================== > RCS file: /cvs/src/usr.sbin/ospfd/area.c,v retrieving revision 1.9 > diff -u -p -r1.9 area.c --- area.c 7 Jan 2009 21:16:36 -0000 1.9 +++ > area.c 4 Jun 2013 20:58:05 -0000 @@ -94,19 +94,24 @@ area_find(struct > ospfd_conf *conf, struc } void -area_track(struct area *area, int > state) +area_track(struct area *area) { - int old = area->active; + > int old = area->active; + struct iface *iface; - if (state & > NBR_STA_FULL) - area->active++; - else if (area->active == 0) - > fatalx("area_track: area already inactive"); - else - area->active--; > + area->active = 0; + LIST_FOREACH(iface, &area->iface_list, entry) { > + if (iface->state & IF_STA_DOWN) + continue; + area->active = 1; + > break; + } - if (area->active == 0 || old == 0) + if (area->active != > old) { + ospfe_imsg_compose_rde(IMSG_AREA_CHANGE, area->id.s_addr, 0, > + &area->active, sizeof(area->active)); ospfe_demote_area(area, old == > 0); + } } int @@ -116,7 +121,7 @@ area_border_router(struct ospfd_conf > *co int active = 0; LIST_FOREACH(area, &conf->area_list, entry) - if > (area->active > 0) + if (area->active) active++; return (active > 1); > Index: interface.c > =================================================================== > RCS file: /cvs/src/usr.sbin/ospfd/interface.c,v retrieving revision > 1.75 diff -u -p -r1.75 interface.c --- interface.c 14 May 2012 > 10:17:21 -0000 1.75 +++ interface.c 4 Jun 2013 20:58:05 -0000 @@ > -136,8 +136,10 @@ if_fsm(struct iface *iface, enum iface_e if > (new_state != 0) iface->state = new_state; - if (iface->state != > old_state) + if (iface->state != old_state) { + > area_track(iface->area); orig_rtr_lsa(iface->area); + } if (old_state > & (IF_STA_MULTI | IF_STA_POINTTOPOINT) && (iface->state & > (IF_STA_MULTI | IF_STA_POINTTOPOINT)) == 0) Index: neighbor.c > =================================================================== > RCS file: /cvs/src/usr.sbin/ospfd/neighbor.c,v retrieving revision > 1.46 diff -u -p -r1.46 neighbor.c --- neighbor.c 17 Jan 2013 10:07:56 > -0000 1.46 +++ neighbor.c 4 Jun 2013 20:58:05 -0000 @@ -204,7 +204,6 > @@ nbr_fsm(struct nbr *nbr, enum nbr_event * neighbor changed from/to > FULL * originate new rtr and net LSA */ - area_track(nbr->iface->area, > nbr->state); orig_rtr_lsa(nbr->iface->area); if (nbr->iface->state & > IF_STA_DR) orig_net_lsa(nbr->iface); Index: ospfd.h > =================================================================== > RCS file: /cvs/src/usr.sbin/ospfd/ospfd.h,v retrieving revision 1.91 > diff -u -p -r1.91 ospfd.h --- ospfd.h 17 Jan 2013 10:07:56 -0000 1.91 > +++ ospfd.h 4 Jun 2013 20:58:05 -0000 @@ -104,6 +104,7 @@ enum > imsg_type { IMSG_NEIGHBOR_CAPA, IMSG_NETWORK_ADD, IMSG_NETWORK_DEL, + > IMSG_AREA_CHANGE, IMSG_DD, IMSG_DD_END, IMSG_DD_BADLSA, @@ -530,7 > +531,7 @@ struct demote_msg { struct area *area_new(void); int > area_del(struct area *); struct area *area_find(struct ospfd_conf *, > struct in_addr); -void area_track(struct area *, int); +void > area_track(struct area *); int area_border_router(struct ospfd_conf > *); u_int8_t area_ospf_options(struct area *); Index: ospfe.c > =================================================================== > RCS file: /cvs/src/usr.sbin/ospfd/ospfe.c,v retrieving revision 1.86 > diff -u -p -r1.86 ospfe.c --- ospfe.c 22 Mar 2013 08:42:55 -0000 1.86 > +++ ospfe.c 4 Jun 2013 20:58:05 -0000 @@ -992,9 +992,9 @@ > orig_rtr_lsa(struct area *area) oeconf->border = border; > orig_rtr_lsa_all(area); } - if (oeconf->border) lsa_rtr.flags |= > OSPF_RTR_B; + /* TODO set V flag if a active virtual link ends here > and the * area is the transit area for this link. */ if (virtual) > Index: rde.c > =================================================================== > RCS file: /cvs/src/usr.sbin/ospfd/rde.c,v retrieving revision 1.94 > diff -u -p -r1.94 rde.c --- rde.c 9 May 2011 12:24:41 -0000 1.94 +++ > rde.c 4 Jun 2013 21:57:47 -0000 @@ -296,11 +296,6 @@ > rde_dispatch_imsg(int fd, short event, v if (nbr == NULL) break; - if > (state != nbr->state && - (nbr->state & NBR_STA_FULL || - state & > NBR_STA_FULL)) - area_track(nbr->area, state); - nbr->state = state; > if (nbr->state & NBR_STA_FULL) rde_req_list_free(nbr); @@ -313,6 > +308,19 @@ rde_dispatch_imsg(int fd, short event, v break; > nbr->capa_options = *(u_int8_t *)imsg.data; break; + case > IMSG_AREA_CHANGE: + if (imsg.hdr.len - IMSG_HEADER_SIZE != > sizeof(state)) + fatalx("invalid size of OE request"); + + > LIST_FOREACH(area, &rdeconf->area_list, entry) { + if (area->id.s_addr > == imsg.hdr.peerid) + break; + } + if (area == NULL) + break; + > memcpy(&state, imsg.data, sizeof(state)); + area->active = state; + > break; case IMSG_DB_SNAPSHOT: nbr = rde_nbr_find(imsg.hdr.peerid); if > (nbr == NULL) @@ -776,8 +784,11 @@ rde_send_change_kroute(struct > rt_node *r kr.ext_tag = r->ext_tag; imsg_add(wbuf, &kr, sizeof(kr)); } > - if (krcount == 0) - fatalx("rde_send_change_kroute: no valid nexthop > found"); + if (krcount == 0) { + /* ignore self originated networks */ > + ibuf_free(wbuf); + return; + } imsg_close(&iev_main->ibuf, wbuf); > imsg_event_add(iev_main); } @@ -1341,14 +1352,18 @@ > rde_summary_update(struct rt_node *rte, /* no need to originate > inter-area routes to the backbone */ if (rte->p_type == PT_INTER_AREA > && area->id.s_addr == INADDR_ANY) return; - /* nexthop check, nexthop > part of area -> no summary */ + /* + * nexthop check, nexthop part of > area -> no summary + * but exclude self originated networks (empty > nexthop list) + */ 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 */ + if (rn == NULL && > !TAILQ_EMPTY(&rte->nexthop)) + /* all nexthops belong to this area */ > return; if (rte->cost >= LS_INFINITY) Index: rde_spf.c > =================================================================== > RCS file: /cvs/src/usr.sbin/ospfd/rde_spf.c,v retrieving revision 1.75 > diff -u -p -r1.75 rde_spf.c --- rde_spf.c 18 Sep 2012 18:58:56 -0000 > 1.75 +++ rde_spf.c 4 Jun 2013 22:01:23 -0000 @@ -22,6 +22,7 @@ > #include <arpa/inet.h> #include <err.h> #include <stdlib.h> +#include > <string.h> #include "ospfd.h" #include "ospf.h" @@ -182,7 +183,7 @@ > rt_calc(struct vertex *v, struct area *a switch (v->type) { case > LSA_TYPE_ROUTER: /* stub networks */ - if (v->cost >= LS_INFINITY || > TAILQ_EMPTY(&v->nexthop)) + if (v->cost >= LS_INFINITY) return; for (i > = 0; i < lsa_num_links(v); i++) { @@ -211,7 +212,7 @@ rt_calc(struct > vertex *v, struct area *a adv_rtr, PT_INTRA_AREA, DT_RTR, > v->lsa->data.rtr.flags, 0); break; case LSA_TYPE_NETWORK: - if > (v->cost >= LS_INFINITY || TAILQ_EMPTY(&v->nexthop)) + if (v->cost >= > LS_INFINITY) return; addr.s_addr = htonl(v->ls_id) & > v->lsa->data.net.mask; @@ -245,7 +246,7 @@ rt_calc(struct vertex *v, > struct area *a v->cost = w->cost + (ntohl(v->lsa->data.sum.metric) & > LSA_METRIC_MASK); - if (v->cost >= LS_INFINITY || > TAILQ_EMPTY(&v->nexthop)) + if (v->cost >= LS_INFINITY) return; > adv_rtr.s_addr = htonl(v->adv_rtr); @@ -823,20 +824,26 @@ > rt_dump(struct in_addr area, pid_t pid, fatalx("rt_dump: invalid RIB > type"); } + bzero(&rtctl, sizeof(rtctl)); + rtctl.prefix.s_addr = > r->prefix.s_addr; + rtctl.area.s_addr = r->area.s_addr; + rtctl.cost = > r->cost; + rtctl.cost2 = r->cost2; + rtctl.p_type = r->p_type; + > rtctl.d_type = r->d_type; + rtctl.flags = r->flags; + rtctl.prefixlen > = r->prefixlen; + + if (TAILQ_EMPTY(&r->nexthop)) { + > rde_imsg_compose_ospfe(IMSG_CTL_SHOW_RIB, 0, pid, + &rtctl, > sizeof(rtctl)); + } TAILQ_FOREACH(rn, &r->nexthop, entry) { if > (rn->invalid) continue; - rtctl.prefix.s_addr = r->prefix.s_addr; > rtctl.nexthop.s_addr = rn->nexthop.s_addr; - rtctl.area.s_addr = > r->area.s_addr; rtctl.adv_rtr.s_addr = rn->adv_rtr.s_addr; - > rtctl.cost = r->cost; - rtctl.cost2 = r->cost2; - rtctl.p_type = > r->p_type; - rtctl.d_type = r->d_type; - rtctl.flags = r->flags; - > rtctl.prefixlen = r->prefixlen; rtctl.uptime = now.tv_sec - > rn->uptime; rde_imsg_compose_ospfe(IMSG_CTL_SHOW_RIB, 0, pid, @@ > -854,9 +861,6 @@ rt_update(struct in_addr prefix, u_int8_ struct > rt_node *rte; struct rt_nexthop *rn; int better = 0, equal = 0; - - if > (vnh == NULL || TAILQ_EMPTY(vnh)) /* XXX remove */ - > fatalx("rt_update: invalid nexthop"); if ((rte = > rt_find(prefix.s_addr, prefixlen, d_type)) == NULL) { if ((rte = > calloc(1, sizeof(struct rt_node))) == NULL)
Hi, Are there any updates on this? I've seen it hasn't been committed in cvs (nor any other change). This patch seems to work for me. My initial problem was that networks of interfaces defined in areas != 0.0.0.0 where not announced if there was no remote router on those interfaces. area 0.0.0.0 { interface bge0 {...} interface lo1 {passive} } area 0.0.0.7 { stub interface lo2 {passive} inteface carpX {passive} } Without this patch, routes to (lo2) and carpX:network where not distributed. regards, G