On Fri, Aug 04, 2017 at 06:04:26PM +0200, Alexander Bluhm wrote:
> On Fri, Aug 04, 2017 at 03:38:40PM +0000, Florian Obser wrote:
> > When we disable INET6 on an interface that also removes the autoconf6
> > flag.  Notify userland about this via the route socket, otherwise
> > slaacd gets confused about the state the interface is in.
> 
> The other rtm_ifchg() calls are in net/if.c.  Should this one
> not also be there in the SIOCIFAFDETACH case?
> 
> bluhm

Yes, I was thinking about that, too. it's a bit more complex. I think
it's worth it, especially if we ever have a autoconf4 flag.  The
trouble with the SIOCIFAFDETACH that have to track if a flag changes.
this applies the heavy hammer of just checking if if_flags or
if_xflags changed.
Am I overengineering this?

diff --git if.c if.c
index ed95b15b8c9..3d9af2acf6e 100644
--- if.c
+++ if.c
@@ -1828,7 +1828,7 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, 
struct proc *p)
        struct if_afreq *ifar;
        char ifdescrbuf[IFDESCRSIZE];
        char ifrtlabelbuf[RTLABEL_LEN];
-       int s, error = 0;
+       int s, error = 0, oif_xflags;
        size_t bytesdone;
        short oif_flags;
        const char *label;
@@ -1865,23 +1865,29 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, 
struct proc *p)
                ifar = (struct if_afreq *)data;
                if ((ifp = ifunit(ifar->ifar_name)) == NULL)
                        return (ENXIO);
+               oif_flags = ifp->if_flags;
+               oif_xflags = ifp->if_xflags;
+               error = 0;
                switch (ifar->ifar_af) {
                case AF_INET:
                        /* attach is a noop for AF_INET */
                        if (cmd == SIOCIFAFDETACH)
                                in_ifdetach(ifp);
-                       return (0);
+                       break;
 #ifdef INET6
                case AF_INET6:
                        if (cmd == SIOCIFAFATTACH)
                                error = in6_ifattach(ifp);
                        else
                                in6_ifdetach(ifp);
-                       return (error);
+                       break;
 #endif /* INET6 */
                default:
                        return (EAFNOSUPPORT);
                }
+               if (oif_flags != ifp->if_flags || oif_xflags != ifp->if_xflags)
+                       rtm_ifchg(ifp);
+               return (error);
        }
 
        ifp = ifunit(ifr->ifr_name);


-- 
I'm not entirely sure you are real.

Reply via email to