* Chris Cappuccio <ch...@nmedia.net> [2014-10-22 01:11]: > Stuart Henderson [st...@openbsd.org] wrote: > > Any comments on the diff in this? > > > > > +#ifdef INET6 > > > + sc->sc_sppp.pp_if.if_xflags &= ~IFXF_NOINET6; > > > +#endif > Aside from what Stefan said, isn't this flag going to be removed > in favor of a flag that explicitly enables INET6 for interfaces?
remove yes, no need for a new one. 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 3 Oct 2014 12:58:22 -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.301 diff -u -p -r1.301 if.c --- sys/net/if.c 30 Sep 2014 08:27:57 -0000 1.301 +++ sys/net/if.c 3 Oct 2014 12:59:29 -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); } @@ -1142,11 +1138,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 @@ -1246,6 +1237,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; @@ -1280,6 +1272,28 @@ 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) { +#ifdef INET6 + 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); +#endif /* INET6 */ + default: + return (EAFNOSUPPORT); + } } ifp = ifunit(ifr->ifr_name); @@ -1335,25 +1349,26 @@ ifioctl(struct socket *so, u_long cmd, c case SIOCSIFXFLAGS: if ((error = suser(p, 0)) != 0) return (error); - -#ifdef INET6 - if (ifr->ifr_flags & IFXF_NOINET6 && - !(ifp->if_xflags & IFXF_NOINET6)) { +#ifdef MPLS + if (ISSET(ifr->ifr_flags, IFXF_MPLS) && + !ISSET(ifp->if_xflags, IFXF_MPLS)) { s = splnet(); - in6_ifdetach(ifp); + ifp->if_xflags |= IFXF_MPLS; + ifp->if_ll_output = ifp->if_output; + ifp->if_output = mpls_output; 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 (ISSET(ifp->if_xflags, IFXF_MPLS) && + !ISSET(ifr->ifr_flags, IFXF_MPLS)) { + s = splnet(); + ifp->if_xflags &= ~IFXF_MPLS; + ifp->if_output = ifp->if_ll_output; + ifp->if_ll_output = NULL; + splx(s); } +#endif +#ifdef INET6 if (ifr->ifr_flags & IFXF_AUTOCONF6) nd6_rs_output_set_timo(ND6_RS_OUTPUT_QUICK_INTERVAL); @@ -1373,25 +1388,9 @@ ifioctl(struct socket *so, u_long cmd, c if (nd6_rs_timeout_count == 0) timeout_del(&nd6_rs_output_timer); } -#endif - -#ifdef MPLS - if (ISSET(ifr->ifr_flags, IFXF_MPLS) && - !ISSET(ifp->if_xflags, IFXF_MPLS)) { - s = splnet(); - ifp->if_xflags |= IFXF_MPLS; - ifp->if_ll_output = ifp->if_output; - ifp->if_output = mpls_output; - splx(s); - } - if (ISSET(ifp->if_xflags, IFXF_MPLS) && - !ISSET(ifr->ifr_flags, IFXF_MPLS)) { - s = splnet(); - ifp->if_xflags &= ~IFXF_MPLS; - ifp->if_output = ifp->if_ll_output; - ifp->if_ll_output = NULL; - splx(s); - } + if (ISSET(ifr->ifr_flags, IFXF_AUTOCONF6)) + if (in6ifa_ifpforlinklocal(ifp, 0) == NULL) + in6_if_up(ifp); #endif #ifndef SMALL_KERNEL @@ -1708,17 +1707,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(); @@ -2377,7 +2368,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 14 Jul 2014 10:57:47 -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 */ +}; + +/* SIOCIFAFDETACH */ +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.140 diff -u -p -r1.140 in6.c --- sys/netinet6/in6.c 26 Aug 2014 21:44:29 -0000 1.140 +++ sys/netinet6/in6.c 3 Oct 2014 13:31:52 -0000 @@ -474,9 +474,12 @@ in6_control(struct socket *so, u_long cm } /* * first, make or update the interface address structure, - * and link it to the list. + * and link it to the list. try to enable inet6 if there + * is no link-local yet. */ s = splsoftnet(); + if (in6ifa_ifpforlinklocal(ifp, 0) == NULL) + in6_if_up(ifp); error = in6_update_ifa(ifp, ifra, ia6); splx(s); if (error != 0) @@ -603,10 +606,6 @@ in6_update_ifa(struct ifnet *ifp, struct if ((ifp->if_flags & IFF_POINTOPOINT) != 0 && ifra->ifra_dstaddr.sin6_family != AF_INET6 && ifra->ifra_dstaddr.sin6_family != AF_UNSPEC) - return (EAFNOSUPPORT); - - /* must have link-local */ - if (ifp->if_xflags & IFXF_NOINET6) return (EAFNOSUPPORT); /* Index: sys/netinet6/in6_ifattach.c =================================================================== RCS file: /cvs/src/sys/netinet6/in6_ifattach.c,v retrieving revision 1.73 diff -u -p -r1.73 in6_ifattach.c --- sys/netinet6/in6_ifattach.c 25 Aug 2014 14:00:34 -0000 1.73 +++ sys/netinet6/in6_ifattach.c 3 Oct 2014 12:39:58 -0000 @@ -624,6 +624,8 @@ in6_ifdetach(struct ifnet *ifp) struct rtentry *rt; struct sockaddr_in6 sin6; + ifp->if_xflags &= ~IFXF_AUTOCONF6; + #ifdef MROUTING /* remove ip6_mrouter stuff */ ip6_mrouter_detach(ifp); 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 14 Jul 2014 11:03:44 -0000 @@ -199,6 +199,8 @@ #define SIOCSETPFLOW _IOW('i', 253, struct ifreq) #define SIOCGETPFLOW _IOWR('i', 254, struct ifreq) -#define SIOCGIFRXR _IOW('i', 170, 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_ */ Index: usr.sbin/rtsold/if.c =================================================================== RCS file: /cvs/src/usr.sbin/rtsold/if.c,v retrieving revision 1.27 diff -u -p -r1.27 if.c --- usr.sbin/rtsold/if.c 11 Jul 2014 16:44:13 -0000 1.27 +++ usr.sbin/rtsold/if.c 13 Jul 2014 13:05:59 -0000 @@ -104,7 +104,6 @@ interface_up(char *name) strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); if (ioctl(ifsock, SIOCGIFXFLAGS, (caddr_t)&ifr) < 0) warn("SIOCGIFXFLAGS"); - ifr.ifr_flags &= ~IFXF_NOINET6; ifr.ifr_flags |= IFXF_AUTOCONF6; if (ioctl(ifsock, SIOCSIFXFLAGS, (caddr_t)&ifr) < 0) warn("SIOCSIFXFLAGS");