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