On Mon, Nov 24, 2014 at 02:43:39PM -0800, Chris Cappuccio wrote:
> Henning Brauer [hb-openbsdt...@ml.bsws.de] wrote:
> > now that we have an uncontaminated, err, inet6-free system by default,
> > IFXF_NOINET6 just doesn't make sense any more.
> > fully go for no inet6 by default, get rid of the IFXF_NOINET6 guarded
> > attachments etc.
> > introduce IFAFATTACH and IFAFDETACH ioctls. note that they are NOT
> > inet6 specific; the kernel only has code for inet6 so far and will
> > properly return EAFNOSUPPORT for all others.
> > 
> 
> It's time to revisit this one before we are too close to 5.7.
> 
> IFXF_NOINET6 is backwards.

I agree. However it looks like this diff isn't ready yet.
I've tried porting the diff on -current but can't make it work as-is.

During netstart I see:

ifconfig: SIOCAIFADDR: Address family not supported by protocol family
IPv6 autoconf: re0
get_llflag() failed, anyway I'll try
sendmsg on re0: Can't assign requested address
sendmsg on re0: Can't assign requested address
sendmsg on re0: Can't assign requested address

I did:
 - apply the patch, fix one reject and a new kernel build failure in in6.c
 - rebuild kernel and reboot
 - run make includes in /usr/src to ensure new ioctls are declared
 - re-compiled and reinstalled ifconfig

My hostname.re0 effectively looks like this:
dhcp
rtsol
inet6 2001:db8::1 64
wol

Seems like rtsol and/or setting an IPv6 address doesn't activate AF_INET6
even though it should.

This is the diff I tried:

Index: sbin/ifconfig/ifconfig.c
===================================================================
RCS file: /cvs/src/sbin/ifconfig/ifconfig.c,v
retrieving revision 1.289
diff -u -p -r1.289 ifconfig.c
--- sbin/ifconfig/ifconfig.c    14 Nov 2014 15:09:29 -0000      1.289
+++ sbin/ifconfig/ifconfig.c    27 Nov 2014 09:18:51 -0000
@@ -148,6 +148,7 @@ void        setiflladdr(const char *, int);
 void   setifdstaddr(const char *, int);
 void   setifflags(const char *, int);
 void   setifxflags(const char *, int);
+void   addaf(const char *, int);
 void   removeaf(const char *, int);
 void   setifbroadaddr(const char *, int);
 void   setifmtu(const char *, int);
@@ -682,7 +683,7 @@ main(int argc, char *argv[])
        }
 #ifdef INET6
        if (argc != 0 && af == AF_INET6)
-               setifxflags("inet6", -IFXF_NOINET6);
+               addaf(name, AF_INET6);
 #endif
        while (argc > 0) {
                const struct cmd *p;
@@ -1261,18 +1262,25 @@ setifxflags(const char *vname, int value
 }
 
 void
+addaf(const char *vname, int value)
+{
+       struct if_afreq ifar;
+
+       strlcpy(ifar.ifar_name, name, sizeof(ifar.ifar_name));
+       ifar.ifar_af = value;
+       if (ioctl(s, SIOCIFAFATTACH, (caddr_t)&ifar) < 0)
+               warn("SIOCIFAFATTACH");
+}
+
+void
 removeaf(const char *vname, int value)
 {
-       switch (value) {
-#ifdef INET6
-       case AF_INET6:
-               setifxflags(vname, IFXF_NOINET6);
-               setifxflags(vname, -IFXF_AUTOCONF6);
-               break;
-#endif
-       default:
-               errx(1, "removeaf not implemented for this AF");
-       }
+       struct if_afreq ifar;
+
+       strlcpy(ifar.ifar_name, name, sizeof(ifar.ifar_name));
+       ifar.ifar_af = value;
+       if (ioctl(s, SIOCIFAFDETACH, (caddr_t)&ifar) < 0)
+               warn("SIOCIFAFDETACH");
 }
 
 #ifdef INET6
@@ -1334,7 +1342,9 @@ setia6eui64(const char *cmd, int val)
 
        if (afp->af_af != AF_INET6)
                errx(1, "%s not allowed for the AF", cmd);
-       setifxflags("inet6", -IFXF_NOINET6);
+#ifdef INET6
+       addaf(name, AF_INET6);
+#endif
        in6 = (struct in6_addr *)&in6_addreq.ifra_addr.sin6_addr;
        if (memcmp(&in6addr_any.s6_addr[8], &in6->s6_addr[8], 8) != 0)
                errx(1, "interface index is already filled");
Index: sys/net/if.c
===================================================================
RCS file: /cvs/src/sys/net/if.c,v
retrieving revision 1.304
diff -u -p -r1.304 if.c
--- sys/net/if.c        23 Nov 2014 07:39:02 -0000      1.304
+++ sys/net/if.c        27 Nov 2014 09:20:01 -0000
@@ -406,10 +406,6 @@ if_attach(struct ifnet *ifp)
 #else
        TAILQ_INSERT_TAIL(&ifnet, ifp, if_list);
 #endif
-#ifdef INET6
-       ifp->if_xflags |= IFXF_NOINET6;
-#endif
-
        if_attachsetup(ifp);
 }
 
@@ -1119,11 +1115,6 @@ if_up(struct ifnet *ifp)
                bstp_ifstate(ifp);
 #endif
        rt_ifmsg(ifp);
-#ifdef INET6
-       if (!(ifp->if_xflags & IFXF_NOINET6))
-               in6_if_up(ifp);
-#endif
-
 #ifndef SMALL_KERNEL
        rt_if_track(ifp);
 #endif
@@ -1223,6 +1214,7 @@ ifioctl(struct socket *so, u_long cmd, c
        struct ifaddr *ifa;
        struct sockaddr_dl *sdl;
        struct ifgroupreq *ifgr;
+       struct if_afreq *ifar;
        char ifdescrbuf[IFDESCRSIZE];
        char ifrtlabelbuf[RTLABEL_LEN];
        int s, error = 0;
@@ -1257,6 +1249,26 @@ ifioctl(struct socket *so, u_long cmd, c
                if ((error = suser(p, 0)) != 0)
                        return (error);
                return (if_setgroupattribs(data));
+       case SIOCIFAFATTACH:
+       case SIOCIFAFDETACH:
+               if ((error = suser(p, 0)) != 0)
+                       return (error);
+               ifar = (struct if_afreq *)data;
+               if ((ifp = ifunit(ifar->ifar_name)) == NULL)
+                       return (ENXIO);
+               switch (ifar->ifar_af) {
+               case AF_INET6:
+                       s = splnet();
+                       if (cmd == SIOCIFAFATTACH) {
+                               if (in6ifa_ifpforlinklocal(ifp, 0) == NULL)
+                                       in6_if_up(ifp);
+                       } else
+                               in6_ifdetach(ifp);
+                       splx(s);
+                       return (0);
+               default:
+                       return (EAFNOSUPPORT);
+               }
        }
 
        ifp = ifunit(ifr->ifr_name);
@@ -1314,23 +1326,6 @@ ifioctl(struct socket *so, u_long cmd, c
                        return (error);
 
 #ifdef INET6
-               if (ifr->ifr_flags & IFXF_NOINET6 &&
-                   !(ifp->if_xflags & IFXF_NOINET6)) {
-                       s = splnet();
-                       in6_ifdetach(ifp);
-                       splx(s);
-               }
-               if (ifp->if_xflags & IFXF_NOINET6 &&
-                   !(ifr->ifr_flags & IFXF_NOINET6)) {
-                       ifp->if_xflags &= ~IFXF_NOINET6;
-                       if (ifp->if_flags & IFF_UP) {
-                               /* configure link-local address */
-                               s = splnet();
-                               in6_if_up(ifp);
-                               splx(s);
-                       }
-               }
-
                if (ifr->ifr_flags & IFXF_AUTOCONF6)
                        nd6_rs_output_set_timo(ND6_RS_OUTPUT_QUICK_INTERVAL);
 
@@ -1371,6 +1366,12 @@ ifioctl(struct socket *so, u_long cmd, c
                }
 #endif
 
+#ifdef INET6
+               if (ISSET(ifr->ifr_flags, IFXF_AUTOCONF6))
+                       if (in6ifa_ifpforlinklocal(ifp, 0) == NULL)
+                               in6_if_up(ifp);
+#endif
+
 #ifndef SMALL_KERNEL
                if (ifp->if_capabilities & IFCAP_WOL) {
                        if (ISSET(ifr->ifr_flags, IFXF_WOL) &&
@@ -1685,17 +1686,9 @@ ifioctl(struct socket *so, u_long cmd, c
                break;
        }
 
-       if (((oif_flags ^ ifp->if_flags) & IFF_UP) != 0) {
+       if (((oif_flags ^ ifp->if_flags) & IFF_UP) != 0)
                microtime(&ifp->if_lastchange);
-#ifdef INET6
-               if (!(ifp->if_xflags & IFXF_NOINET6) &&
-                   (ifp->if_flags & IFF_UP) != 0) {
-                       s = splnet();
-                       in6_if_up(ifp);
-                       splx(s);
-               }
-#endif
-       }
+
        /* If we took down the IF, bring it back */
        if (up) {
                s = splnet();
@@ -2291,7 +2284,7 @@ ifnewlladdr(struct ifnet *ifp)
 #ifdef INET6
        /* Update the link-local address. Don't do it if we're
         * a router to avoid confusing hosts on the network. */
-       if (!(ifp->if_xflags & IFXF_NOINET6) && !ip6_forwarding) {
+       if (!ip6_forwarding) {
                ifa = &in6ifa_ifpforlinklocal(ifp, 0)->ia_ifa;
                if (ifa) {
                        in6_purgeaddr(ifa);
Index: sys/net/if.h
===================================================================
RCS file: /cvs/src/sys/net/if.h,v
retrieving revision 1.157
diff -u -p -r1.157 if.h
--- sys/net/if.h        14 Jul 2014 03:45:43 -0000      1.157
+++ sys/net/if.h        27 Nov 2014 09:18:51 -0000
@@ -206,7 +206,6 @@ struct if_status_description {
            IFF_SIMPLEX|IFF_MULTICAST|IFF_ALLMULTI)
 
 #define IFXF_TXREADY           0x1             /* interface is ready to tx */
-#define        IFXF_NOINET6            0x2             /* don't do inet6 */
 #define        IFXF_INET6_NOPRIVACY    0x4             /* don't autoconf 
privacy */
 #define        IFXF_MPLS               0x8             /* supports MPLS */
 #define        IFXF_WOL                0x10            /* wake on lan enabled 
*/
@@ -427,6 +426,12 @@ struct if_laddrreq {
        unsigned int prefixlen;         /* in/out */
        struct sockaddr_storage addr;   /* in/out */
        struct sockaddr_storage dstaddr; /* out */
+};
+
+/* SIOCIFAFATTACH + DETACH */
+struct if_afreq {
+       char            ifar_name[IFNAMSIZ];
+       sa_family_t     ifar_af;
 };
 
 #include <net/if_arp.h>
Index: sys/netinet6/in6.c
===================================================================
RCS file: /cvs/src/sys/netinet6/in6.c,v
retrieving revision 1.146
diff -u -p -r1.146 in6.c
--- sys/netinet6/in6.c  24 Nov 2014 12:43:54 -0000      1.146
+++ sys/netinet6/in6.c  27 Nov 2014 10:40:42 -0000
@@ -607,7 +607,7 @@ in6_update_ifa(struct ifnet *ifp, struct
                return (EAFNOSUPPORT);
 
        /* must have link-local */
-       if (ifp->if_xflags & IFXF_NOINET6)
+       if (in6ifa_ifpforlinklocal(ifp, 0) == NULL)
                return (EAFNOSUPPORT);
 
        /*
Index: sys/sys/sockio.h
===================================================================
RCS file: /cvs/src/sys/sys/sockio.h,v
retrieving revision 1.55
diff -u -p -r1.55 sockio.h
--- sys/sys/sockio.h    13 Jul 2014 13:41:46 -0000      1.55
+++ sys/sys/sockio.h    27 Nov 2014 09:18:51 -0000
@@ -200,5 +200,7 @@
 #define        SIOCGETPFLOW    _IOWR('i', 254, struct ifreq)
 
 #define        SIOCGIFRXR      _IOW('i', 170, struct ifreq)
+#define        SIOCIFAFATTACH  _IOW('i', 171, struct if_afreq) /* attach given 
af */
+#define        SIOCIFAFDETACH  _IOW('i', 172, struct if_afreq) /* detach given 
af */
 
 #endif /* !_SYS_SOCKIO_H_ */

Reply via email to