remove support for deprecated ioctls (EINVAL). sync w/kame
This commit is contained in:
parent
3acf6ed1d8
commit
83aff37a0f
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: in6.c,v 1.59 2002/05/29 07:53:40 itojun Exp $ */
|
||||
/* $NetBSD: in6.c,v 1.60 2002/06/07 04:03:53 itojun Exp $ */
|
||||
/* $KAME: in6.c,v 1.198 2001/07/18 09:12:38 itojun Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -66,7 +66,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.59 2002/05/29 07:53:40 itojun Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.60 2002/06/07 04:03:53 itojun Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
|
||||
|
@ -335,10 +335,8 @@ in6_control(so, cmd, data, ifp, p)
|
|||
struct in6_ifreq *ifr = (struct in6_ifreq *)data;
|
||||
struct in6_ifaddr *ia, *oia;
|
||||
struct in6_aliasreq *ifra = (struct in6_aliasreq *)data;
|
||||
struct sockaddr_in6 *sa6;
|
||||
struct sockaddr_in6 oldaddr;
|
||||
#ifdef COMPAT_IN6IFIOCTL
|
||||
struct sockaddr_in6 net;
|
||||
#endif
|
||||
int error = 0, hostIsNew, prefixIsNew;
|
||||
int newifaddr;
|
||||
time_t time_second = (time_t)time.tv_sec;
|
||||
|
@ -381,11 +379,11 @@ in6_control(so, cmd, data, ifp, p)
|
|||
case SIOCAIFPREFIX_IN6:
|
||||
case SIOCCIFPREFIX_IN6:
|
||||
case SIOCSGIFPREFIX_IN6:
|
||||
if (!privileged)
|
||||
return(EPERM);
|
||||
/* fall through */
|
||||
case SIOCGIFPREFIX_IN6:
|
||||
return(in6_prefix_ioctl(so, cmd, data, ifp));
|
||||
log(LOG_NOTICE,
|
||||
"prefix ioctls are now invalidated. "
|
||||
"please use ifconfig.\n");
|
||||
return(EOPNOTSUPP);
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
|
@ -400,18 +398,52 @@ in6_control(so, cmd, data, ifp, p)
|
|||
|
||||
/*
|
||||
* Find address for this interface, if it exists.
|
||||
*
|
||||
* In netinet code, we have checked ifra_addr in SIOCSIF*ADDR operation
|
||||
* only, and used the first interface address as the target of other
|
||||
* operations (without checking ifra_addr). This was because netinet
|
||||
* code/API assumed at most 1 interface address per interface.
|
||||
* Since IPv6 allows a node to assign multiple addresses
|
||||
* on a single interface, we almost always look and check the
|
||||
* presence of ifra_addr, and reject invalid ones here.
|
||||
* It also decreases duplicated code among SIOC*_IN6 operations.
|
||||
*/
|
||||
if (ifra->ifra_addr.sin6_family == AF_INET6) { /* XXX */
|
||||
struct sockaddr_in6 *sa6 =
|
||||
(struct sockaddr_in6 *)&ifra->ifra_addr;
|
||||
|
||||
switch (cmd) {
|
||||
case SIOCAIFADDR_IN6:
|
||||
case SIOCSIFPHYADDR_IN6:
|
||||
sa6 = &ifra->ifra_addr;
|
||||
break;
|
||||
case SIOCSIFADDR_IN6:
|
||||
case SIOCGIFADDR_IN6:
|
||||
case SIOCSIFDSTADDR_IN6:
|
||||
case SIOCSIFNETMASK_IN6:
|
||||
case SIOCGIFDSTADDR_IN6:
|
||||
case SIOCGIFNETMASK_IN6:
|
||||
case SIOCDIFADDR_IN6:
|
||||
case SIOCGIFPSRCADDR_IN6:
|
||||
case SIOCGIFPDSTADDR_IN6:
|
||||
case SIOCGIFAFLAG_IN6:
|
||||
case SIOCSNDFLUSH_IN6:
|
||||
case SIOCSPFXFLUSH_IN6:
|
||||
case SIOCSRTRFLUSH_IN6:
|
||||
case SIOCGIFALIFETIME_IN6:
|
||||
case SIOCSIFALIFETIME_IN6:
|
||||
case SIOCGIFSTAT_IN6:
|
||||
case SIOCGIFSTAT_ICMP6:
|
||||
sa6 = &ifr->ifr_addr;
|
||||
break;
|
||||
default:
|
||||
sa6 = NULL;
|
||||
break;
|
||||
}
|
||||
if (sa6 && sa6->sin6_family == AF_INET6) {
|
||||
if (IN6_IS_ADDR_LINKLOCAL(&sa6->sin6_addr)) {
|
||||
if (sa6->sin6_addr.s6_addr16[1] == 0) {
|
||||
/* interface ID is not embedded by the user */
|
||||
/* link ID is not embedded by the user */
|
||||
sa6->sin6_addr.s6_addr16[1] =
|
||||
htons(ifp->if_index);
|
||||
htons(ifp->if_index);
|
||||
} else if (sa6->sin6_addr.s6_addr16[1] !=
|
||||
htons(ifp->if_index)) {
|
||||
htons(ifp->if_index)) {
|
||||
return(EINVAL); /* link ID contradicts */
|
||||
}
|
||||
if (sa6->sin6_scope_id) {
|
||||
|
@ -421,11 +453,19 @@ in6_control(so, cmd, data, ifp, p)
|
|||
sa6->sin6_scope_id = 0; /* XXX: good way? */
|
||||
}
|
||||
}
|
||||
ia = in6ifa_ifpwithaddr(ifp, &ifra->ifra_addr.sin6_addr);
|
||||
ia = in6ifa_ifpwithaddr(ifp, &sa6->sin6_addr);
|
||||
} else
|
||||
ia = NULL;
|
||||
|
||||
switch (cmd) {
|
||||
case SIOCSIFADDR_IN6:
|
||||
case SIOCSIFDSTADDR_IN6:
|
||||
case SIOCSIFNETMASK_IN6:
|
||||
/*
|
||||
* Since IPv6 allows a node to assign multiple addresses
|
||||
* on a single interface, SIOCSIFxxx ioctls are deprecated.
|
||||
*/
|
||||
return(EINVAL);
|
||||
|
||||
case SIOCDIFADDR_IN6:
|
||||
/*
|
||||
|
@ -439,16 +479,6 @@ in6_control(so, cmd, data, ifp, p)
|
|||
return(EADDRNOTAVAIL);
|
||||
/* FALLTHROUGH */
|
||||
case SIOCAIFADDR_IN6:
|
||||
case SIOCSIFADDR_IN6:
|
||||
#ifdef COMPAT_IN6IFIOCTL
|
||||
case SIOCSIFDSTADDR_IN6:
|
||||
case SIOCSIFNETMASK_IN6:
|
||||
/*
|
||||
* Since IPv6 allows a node to assign multiple addresses
|
||||
* on a single interface, SIOCSIFxxx ioctls are not suitable
|
||||
* and should be unused.
|
||||
*/
|
||||
#endif
|
||||
if (ifra->ifra_addr.sin6_family != AF_INET6)
|
||||
return(EAFNOSUPPORT);
|
||||
if (!privileged)
|
||||
|
@ -582,41 +612,6 @@ in6_control(so, cmd, data, ifp, p)
|
|||
*((struct in6_ifextra *)ifp->if_afdata[AF_INET6])->icmp6_ifstat;
|
||||
break;
|
||||
|
||||
#ifdef COMPAT_IN6IFIOCTL /* should be unused */
|
||||
case SIOCSIFDSTADDR_IN6:
|
||||
if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
|
||||
return(EINVAL);
|
||||
oldaddr = ia->ia_dstaddr;
|
||||
ia->ia_dstaddr = ifr->ifr_dstaddr;
|
||||
|
||||
/* link-local index check */
|
||||
if (IN6_IS_ADDR_LINKLOCAL(&ia->ia_dstaddr.sin6_addr)) {
|
||||
if (ia->ia_dstaddr.sin6_addr.s6_addr16[1] == 0) {
|
||||
/* interface ID is not embedded by the user */
|
||||
ia->ia_dstaddr.sin6_addr.s6_addr16[1]
|
||||
= htons(ifp->if_index);
|
||||
} else if (ia->ia_dstaddr.sin6_addr.s6_addr16[1] !=
|
||||
htons(ifp->if_index)) {
|
||||
ia->ia_dstaddr = oldaddr;
|
||||
return(EINVAL); /* ifid contradicts */
|
||||
}
|
||||
}
|
||||
|
||||
if (ifp->if_ioctl && (error = (ifp->if_ioctl)
|
||||
(ifp, SIOCSIFDSTADDR, (caddr_t)ia))) {
|
||||
ia->ia_dstaddr = oldaddr;
|
||||
return(error);
|
||||
}
|
||||
if (ia->ia_flags & IFA_ROUTE) {
|
||||
ia->ia_ifa.ifa_dstaddr = (struct sockaddr *)&oldaddr;
|
||||
rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
|
||||
ia->ia_ifa.ifa_dstaddr =
|
||||
(struct sockaddr *)&ia->ia_dstaddr;
|
||||
rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP);
|
||||
}
|
||||
break;
|
||||
|
||||
#endif
|
||||
case SIOCGIFALIFETIME_IN6:
|
||||
ifr->ifr_ifru.ifru_lifetime = ia->ia6_lifetime;
|
||||
break;
|
||||
|
@ -636,63 +631,6 @@ in6_control(so, cmd, data, ifp, p)
|
|||
ia->ia6_lifetime.ia6t_preferred = 0;
|
||||
break;
|
||||
|
||||
case SIOCSIFADDR_IN6:
|
||||
error = in6_ifinit(ifp, ia, &ifr->ifr_addr, 1);
|
||||
#if 0
|
||||
/*
|
||||
* the code chokes if we are to assign multiple addresses with
|
||||
* the same address prefix (rtinit() will return EEXIST, which
|
||||
* is not fatal actually). we will get memory leak if we
|
||||
* don't do it.
|
||||
* -> we may want to hide EEXIST from rtinit().
|
||||
*/
|
||||
undo:
|
||||
if (error && newifaddr) {
|
||||
TAILQ_REMOVE(&ifp->if_addrlist, &ia->ia_ifa, ifa_list);
|
||||
IFAFREE(&ia->ia_ifa);
|
||||
|
||||
oia = ia;
|
||||
if (oia == (ia = in6_ifaddr))
|
||||
in6_ifaddr = ia->ia_next;
|
||||
else {
|
||||
while (ia->ia_next && (ia->ia_next != oia))
|
||||
ia = ia->ia_next;
|
||||
if (ia->ia_next)
|
||||
ia->ia_next = oia->ia_next;
|
||||
else {
|
||||
printf("Didn't unlink in6_ifaddr "
|
||||
"from list\n");
|
||||
}
|
||||
}
|
||||
IFAFREE(&oia->ia_ifa);
|
||||
}
|
||||
#endif
|
||||
return error;
|
||||
|
||||
#ifdef COMPAT_IN6IFIOCTL /* XXX should be unused */
|
||||
case SIOCSIFNETMASK_IN6:
|
||||
ia->ia_prefixmask = ifr->ifr_addr;
|
||||
bzero(&net, sizeof(net));
|
||||
net.sin6_len = sizeof(struct sockaddr_in6);
|
||||
net.sin6_family = AF_INET6;
|
||||
net.sin6_port = htons(0);
|
||||
net.sin6_flowinfo = htonl(0);
|
||||
net.sin6_addr.s6_addr32[0]
|
||||
= ia->ia_addr.sin6_addr.s6_addr32[0] &
|
||||
ia->ia_prefixmask.sin6_addr.s6_addr32[0];
|
||||
net.sin6_addr.s6_addr32[1]
|
||||
= ia->ia_addr.sin6_addr.s6_addr32[1] &
|
||||
ia->ia_prefixmask.sin6_addr.s6_addr32[1];
|
||||
net.sin6_addr.s6_addr32[2]
|
||||
= ia->ia_addr.sin6_addr.s6_addr32[2] &
|
||||
ia->ia_prefixmask.sin6_addr.s6_addr32[2];
|
||||
net.sin6_addr.s6_addr32[3]
|
||||
= ia->ia_addr.sin6_addr.s6_addr32[3] &
|
||||
ia->ia_prefixmask.sin6_addr.s6_addr32[3];
|
||||
ia->ia_net = net;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case SIOCAIFADDR_IN6:
|
||||
prefixIsNew = 0;
|
||||
hostIsNew = 1;
|
||||
|
|
Loading…
Reference in New Issue