-/* $OpenBSD: ifconfig.c,v 1.292 2015/01/04 12:30:39 mpi Exp $ */
+/* $OpenBSD: ifconfig.c,v 1.293 2015/01/06 21:26:46 stsp Exp $ */
/* $NetBSD: ifconfig.c,v 1.40 1997/10/01 02:19:43 enami Exp $ */
/*
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);
}
#ifdef INET6
if (argc != 0 && af == AF_INET6)
- setifxflags("inet6", -IFXF_NOINET6);
+ addaf(name, AF_INET6);
#endif
while (argc > 0) {
const struct cmd *p;
warn("SIOCSIFXFLAGS");
}
+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
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");
-/* $OpenBSD: if.c,v 1.309 2014/12/19 17:14:39 tedu Exp $ */
+/* $OpenBSD: if.c,v 1.310 2015/01/06 21:26:46 stsp Exp $ */
/* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */
/*
#else
TAILQ_INSERT_TAIL(&ifnet, ifp, if_list);
#endif
-#ifdef INET6
- ifp->if_xflags |= IFXF_NOINET6;
-#endif
-
if_attachsetup(ifp);
}
#endif
rt_ifmsg(ifp);
#ifdef INET6
- if (!(ifp->if_xflags & IFXF_NOINET6))
+ if (ifp == lo0ifp) /* lo0 is special - needs ::1 */
in6_if_up(ifp);
#endif
-
#ifndef SMALL_KERNEL
rt_if_track(ifp);
#endif
struct ifreq *ifr;
struct sockaddr_dl *sdl;
struct ifgroupreq *ifgr;
+ struct if_afreq *ifar;
char ifdescrbuf[IFDESCRSIZE];
char ifrtlabelbuf[RTLABEL_LEN];
int s, error = 0;
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 = splsoftnet();
+ 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);
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 */
+ if (ISSET(ifr->ifr_flags, IFXF_AUTOCONF6)) {
+ if (in6ifa_ifpforlinklocal(ifp, 0) == NULL) {
s = splnet();
in6_if_up(ifp);
splx(s);
if (!timeout_pending(&nd6_rs_output_timer))
nd6_rs_output_set_timo(nd6_rs_output_timeout);
}
+
if ((ifp->if_xflags & IFXF_AUTOCONF6) &&
!(ifr->ifr_flags & IFXF_AUTOCONF6)) {
hook_disestablish(ifp->if_linkstatehooks,
if (nd6_rs_timeout_count == 0)
timeout_del(&nd6_rs_output_timer);
}
-#endif
+#endif /* INET6 */
#ifdef MPLS
if (ISSET(ifr->ifr_flags, IFXF_MPLS) &&
ifp->if_ll_output = NULL;
splx(s);
}
-#endif
+#endif /* MPLS */
#ifndef SMALL_KERNEL
if (ifp->if_capabilities & IFCAP_WOL) {
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();
#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);
-/* $OpenBSD: if.h,v 1.158 2014/12/05 15:50:04 mpi Exp $ */
+/* $OpenBSD: if.h,v 1.159 2015/01/06 21:26:46 stsp Exp $ */
/* $NetBSD: if.h,v 1.23 1996/05/07 02:40:27 thorpej Exp $ */
/*
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 */
struct sockaddr_storage dstaddr; /* out */
};
+/* SIOCIFAFDETACH */
+struct if_afreq {
+ char ifar_name[IFNAMSIZ];
+ sa_family_t ifar_af;
+};
+
#include <net/if_arp.h>
#ifdef _KERNEL
-/* $OpenBSD: in6.c,v 1.147 2014/12/08 10:38:48 mpi Exp $ */
+/* $OpenBSD: in6.c,v 1.148 2015/01/06 21:26:46 stsp Exp $ */
/* $KAME: in6.c,v 1.372 2004/06/14 08:14:21 itojun Exp $ */
/*
}
/*
* 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)
ifra->ifra_dstaddr.sin6_family != AF_UNSPEC)
return (EAFNOSUPPORT);
- /* must have link-local */
- if (ifp->if_xflags & IFXF_NOINET6)
- return (EAFNOSUPPORT);
-
/*
* validate ifra_prefixmask. don't check sin6_family, netmask
* does not carry fields other than sin6_len.
-/* $OpenBSD: in6_ifattach.c,v 1.78 2014/12/04 00:02:15 tedu Exp $ */
+/* $OpenBSD: in6_ifattach.c,v 1.79 2015/01/06 21:26:46 stsp Exp $ */
/* $KAME: in6_ifattach.c,v 1.124 2001/07/18 08:32:51 jinmei Exp $ */
/*
struct rtentry *rt;
struct sockaddr_in6 sin6;
+ ifp->if_xflags &= ~IFXF_AUTOCONF6;
+
#ifdef MROUTING
/* remove ip6_mrouter stuff */
ip6_mrouter_detach(ifp);
-/* $OpenBSD: sockio.h,v 1.55 2014/07/13 13:41:46 henning Exp $ */
+/* $OpenBSD: sockio.h,v 1.56 2015/01/06 21:26:46 stsp Exp $ */
/* $NetBSD: sockio.h,v 1.5 1995/08/23 00:40:47 thorpej Exp $ */
/*-
#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_ */