* Chris Cappuccio <[email protected]> [2014-10-22 01:11]:
> Stuart Henderson [[email protected]] 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");