Remi Locherer([email protected]) 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);
> }
>