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_ */