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);
 }

Reply via email to