On Fri, Nov 16, 2018 at 08:56:52PM +0100, Reyk Floeter wrote:
> > the following diff allows rad(8) to watch interface groups. This
> > allows to automatically add/remove interfaces in a given group.
> >
> > For example, I put "interface tap" into rad.conf and it automatically
> > serves my VM interfaces. You could also configure a custom group in
> > vm.conf and rad.conf. I'm working on IPv6 for vmd that needs it.
Nice idea/work, I like it.
> > For reasons that I don't remember, I always missed this feature in
> > rtadvd(8)[RIP]. It was amazingly simple to add it to rad(8) as it
> > already reinitializes itself on interface changes.
> >
> > This diff includes the previous ENXIO fix to prevent it from crashing
> > when a cloner interface such as tap is destroyed.
> >
>
> Updated diff after committing the ENXIO fix.
>
> Two explanations:
>
> - merge_ra_interfaces() calls merge_ra_interface() for each configured
> interface (explicit config) and for each member that is found in an
> interface group. It is basically just some code shuffling.
>
> - ra_iface->name is split into ra_iface->name and ra_iface->conf as
> "name" indicates and actual (found) interface name ("tap0") and "conf"
> is used to lookup the config where it was derived from ("tap" or
> "tap0", depending on the configuration).
This begs the question about priority in rad.conf(5). It's always been
possible to define duplicate `interface' blocks although it didn't make
any sense.
Now it does since you could define a default config for the entire group
and add further interface specific blocks.
As it currently is, the first matching block wins, so vether0 would
always get RDNS ::11 whether a more specific block exists or not:
interface vether { dns { nameserver ::11 } }
interface vether0 { dns { nameserver ::22 } }
Maybe we should clarify behaviour in rad.conf(5) regardless of your
changes?
> void
> +merge_ra_interface(struct ra_iface_conf *ra_iface_conf, char *name)
> +{
> + struct ra_iface *ra_iface;
> + uint32_t if_index;
> +
> + ra_iface = find_ra_iface_by_name(name);
> + if (ra_iface == NULL) {
> + log_debug("new interface %s", name);
> + if ((if_index = if_nametoindex(name)) == 0)
> + return;
> + log_debug("adding interface %s", name);
> + if ((ra_iface = calloc(1, sizeof(*ra_iface))) == NULL)
> + fatal("%s", __func__);
> +
> + strlcpy(ra_iface->name, name, sizeof(ra_iface->name));
> + strlcpy(ra_iface->conf, ra_iface_conf->name,
> + sizeof(ra_iface->conf));
> +
> + ra_iface->if_index = if_index;
> + SIMPLEQ_INIT(&ra_iface->prefixes);
> + TAILQ_INSERT_TAIL(&ra_interfaces, ra_iface, entry);
> + join_all_routers_mcast_group(ra_iface);
> + } else {
> + log_debug("keeping interface %s", name);
> + ra_iface->removed = 0;
> + }
> +}
How about flipping the check to reduce indentation?
if (ra_iface) {
log_debug("keeping interface %s", name);
...
return;
}
log_debug("new interface %s", name);
...