Remi Locherer(remi.loche...@relo.ch) on 2019.04.28 11:43:41 +0200: > Hi, > > the parser in ospf(6)d accepts depend on interfaces that are in a > different rdomain. This works on startup of the daemon. But since it > filters route messages based on it's rdomain it will not get notified > if the depend on interface changes link state. > > Below diff extends the existing conf_check_rdomain to also check the > depend on interfaces.
I can think of examples where you could (ab)use this to redistribute a route based on the availablility of some service running in a different rdomain (but reachable through pf rtable tricks). But then, not getting overwhelmed by route messages is more important. If someone really needs it, we could make the filter configurable. > OK? ok benno@ > > Remi > > > Index: ospfd/parse.y > =================================================================== > RCS file: /cvs/src/usr.sbin/ospfd/parse.y,v > retrieving revision 1.95 > diff -u -p -r1.95 parse.y > --- ospfd/parse.y 13 Feb 2019 22:57:08 -0000 1.95 > +++ ospfd/parse.y 28 Apr 2019 09:29:00 -0000 > @@ -1371,18 +1371,45 @@ conf_get_if(struct kif *kif, struct kif_ > int > conf_check_rdomain(unsigned int rdomain) > { > - struct area *a; > - struct iface *i; > - int errs = 0; > + struct area *a; > + struct iface *i; > + struct in_addr addr; > + struct kif *kif; > + struct redistribute *r; > + int errs = 0; > + > + SIMPLEQ_FOREACH(r, &conf->redist_list, entry) > + if (r->dependon[0] != '\0') { > + bzero(&addr, sizeof(addr)); > + kif = kif_findname(r->dependon, addr, NULL); > + if (kif->rdomain != rdomain) { > + logit(LOG_CRIT, > + "depend on %s: interface not in rdomain %u", > + kif->ifname, rdomain); > + errs++; > + } > + } > > LIST_FOREACH(a, &conf->area_list, entry) > - LIST_FOREACH(i, &a->iface_list, entry) > + LIST_FOREACH(i, &a->iface_list, entry) { > if (i->rdomain != rdomain) { > logit(LOG_CRIT, > "interface %s not in rdomain %u", > i->name, rdomain); > errs++; > } > + if (i->dependon[0] != '\0') { > + bzero(&addr, sizeof(addr)); > + kif = kif_findname(i->dependon, addr, NULL); > + if (kif->rdomain != rdomain) { > + logit(LOG_CRIT, > + "depend on %s: interface not in " > + "rdomain %u", > + kif->ifname, rdomain); > + errs++; > + } > + } > + } > > return (errs); > } > Index: ospf6d/parse.y > =================================================================== > RCS file: /cvs/src/usr.sbin/ospf6d/parse.y,v > retrieving revision 1.42 > diff -u -p -r1.42 parse.y > --- ospf6d/parse.y 13 Feb 2019 22:57:08 -0000 1.42 > +++ ospf6d/parse.y 28 Apr 2019 09:28:33 -0000 > @@ -1151,18 +1151,41 @@ conf_get_area(struct in_addr id) > int > conf_check_rdomain(u_int rdomain) > { > - struct area *a; > - struct iface *i; > - int errs = 0; > + struct area *a; > + struct iface *i, *idep; > + struct redistribute *r; > + int errs = 0; > + > + SIMPLEQ_FOREACH(r, &conf->redist_list, entry) > + if (r->dependon[0] != '\0') { > + idep = if_findname(r->dependon); > + if (idep->rdomain != rdomain) { > + logit(LOG_CRIT, > + "depend on %s: interface not in rdomain %u", > + idep->name, rdomain); > + errs++; > + } > + } > > LIST_FOREACH(a, &conf->area_list, entry) > - LIST_FOREACH(i, &a->iface_list, entry) > + LIST_FOREACH(i, &a->iface_list, entry) { > if (i->rdomain != rdomain) { > logit(LOG_CRIT, > "interface %s not in rdomain %u", > i->name, rdomain); > errs++; > } > + if (i->dependon[0] != '\0') { > + idep = if_findname(i->dependon); > + if (idep->rdomain != rdomain) { > + logit(LOG_CRIT, > + "depend on %s: interface not in " > + "rdomain %u", > + idep->name, rdomain); > + errs++; > + } > + } > + } > > return (errs); > } >