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.
there should be no user visible changes from this. Index: sbin/ifconfig/ifconfig.c =================================================================== RCS file: /cvs/src/sbin/ifconfig/ifconfig.c,v retrieving revision 1.287 diff -u -p -r1.287 ifconfig.c --- sbin/ifconfig/ifconfig.c 12 Jul 2014 19:58:17 -0000 1.287 +++ sbin/ifconfig/ifconfig.c 13 Jul 2014 13:05:15 -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; @@ -1258,18 +1259,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 @@ -1331,7 +1339,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.297 diff -u -p -r1.297 if.c --- sys/net/if.c 12 Jul 2014 18:44:22 -0000 1.297 +++ sys/net/if.c 13 Jul 2014 13:15:09 -0000 @@ -428,10 +428,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); } @@ -1133,11 +1129,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 @@ -1237,6 +1228,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; @@ -1271,6 +1263,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); @@ -1327,25 +1339,6 @@ ifioctl(struct socket *so, u_long cmd, c if ((error = suser(p, 0)) != 0) 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); - } - } -#endif - #ifdef MPLS if (ISSET(ifr->ifr_flags, IFXF_MPLS) && !ISSET(ifp->if_xflags, IFXF_MPLS)) { @@ -1365,6 +1358,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) && @@ -1679,17 +1678,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(); @@ -2348,7 +2339,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.156 diff -u -p -r1.156 if.h --- sys/net/if.h 11 Jul 2014 16:39:06 -0000 1.156 +++ sys/net/if.h 13 Jul 2014 12:01:57 -0000 @@ -217,7 +217,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 */ @@ -438,6 +437,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/sys/sockio.h =================================================================== RCS file: /cvs/src/sys/sys/sockio.h,v retrieving revision 1.54 diff -u -p -r1.54 sockio.h --- sys/sys/sockio.h 8 Jul 2014 04:02:14 -0000 1.54 +++ sys/sys/sockio.h 13 Jul 2014 12:58:36 -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_ */