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

Reply via email to