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. OK? 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); }