On Sun, Jul 13, 2014 at 03:48:47PM +0200, Henning Brauer 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. > > there should be no user visible changes from this.
I like this direction. It's a lot better than the AF-specific "kill switch". However, since we're heading towards release, I believe we should wait and do this flag removal + ioctl addition later. We've already got the no-link-local-by-default change, and the new autoconf6 flag. I don't see much harm in leaving it at that for this release cycle and moving further in the next one. I'm looking forward to florian's in-kernel rtsol as well, in the next cycle (it's not done yet anyway AFAIK). Perhaps we can also sort out the autoconf vs. ip6forward conundrum then, and ship working IPv6 for SOHO routers in 5.7. I'll be testing this regardless and will let you know if I run into issues. > 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_ */