On Mon, Nov 24, 2014 at 02:43:39PM -0800, Chris Cappuccio wrote:
> Henning Brauer [[email protected]] 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_ */