Date: Tue, 5 Nov 2013 16:02:40 +0400 From: Gleb Smirnoff <glebius@FreeBSD.org> To: current@FreeBSD.org Cc: net@FreeBSD.org Subject: Re: axing KAME interface ioctls Message-ID: <20131105120240.GA7577@FreeBSD.org> In-Reply-To: <20131105110114.GQ1467@FreeBSD.org> References: <20131105110114.GQ1467@FreeBSD.org>
next in thread | previous in thread | raw e-mail | index | archive | help
--ikeVEW9yuYc//A+q Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Tue, Nov 05, 2013 at 03:01:14PM +0400, Gleb Smirnoff wrote: T> Hello. T> T> Since 1999 we have got some dead code from KAME, namely support for these T> ioctls: T> T> SIOCALIFADDR T> SIOCGLIFADDR T> SIOCDLIFADDR T> SIOCSLIFPHYADDR T> SIOCGLIFPHYADDR T> T> We don not have any software in base that use (or used) them. The ports T> exp-run with SIOC.LIFADDR undefined didn't reveal any port that use them. T> I forgot to add SIOC.LIFPHYADDR to exp-run, but pretty sure these are unused, T> too. T> T> What did this ioctls do? They are KAME version of SIOCAIFADDR, and T> SIOCSIFPHYADDR respectively. Some operating systems (at least HPUX) T> have adopted them, and some software may use them on these systems. T> Anyway, in FreeBSD all software always used our native ioctls. T> T> I hope there is no objections against axing these in head/. Patch attached. -- Totus tuus, Glebius. --ikeVEW9yuYc//A+q Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="axe-KAME-ioctls.diff" Index: sys/net/if.c =================================================================== --- sys/net/if.c (revision 257696) +++ sys/net/if.c (working copy) @@ -2414,7 +2414,6 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t d #ifdef INET6 case SIOCSIFPHYADDR_IN6: #endif - case SIOCSLIFPHYADDR: case SIOCSIFMEDIA: case SIOCSIFGENERIC: error = priv_check(td, PRIV_NET_HWIOCTL); @@ -2433,7 +2432,6 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t d case SIOCGIFPSRCADDR: case SIOCGIFPDSTADDR: - case SIOCGLIFPHYADDR: case SIOCGIFMEDIA: case SIOCGIFGENERIC: if (ifp->if_ioctl == NULL) Index: sys/net/if.h =================================================================== --- sys/net/if.h (revision 257696) +++ sys/net/if.h (working copy) @@ -489,18 +489,6 @@ struct ifgroupreq { #define ifgr_groups ifgr_ifgru.ifgru_groups }; -/* - * Structure for SIOC[AGD]LIFADDR - */ -struct if_laddrreq { - char iflr_name[IFNAMSIZ]; - u_int flags; -#define IFLR_PREFIX 0x8000 /* in: prefix given out: kernel fills id */ - u_int prefixlen; /* in/out */ - struct sockaddr_storage addr; /* in/out */ - struct sockaddr_storage dstaddr; /* out */ -}; - #endif /* __BSD_VISIBLE */ #ifdef _KERNEL Index: sys/net/if_gif.c =================================================================== --- sys/net/if_gif.c (revision 257694) +++ sys/net/if_gif.c (working copy) @@ -710,7 +710,6 @@ gif_ioctl(ifp, cmd, data) #ifdef INET6 case SIOCSIFPHYADDR_IN6: #endif /* INET6 */ - case SIOCSLIFPHYADDR: switch (cmd) { #ifdef INET case SIOCSIFPHYADDR: @@ -728,12 +727,6 @@ gif_ioctl(ifp, cmd, data) &(((struct in6_aliasreq *)data)->ifra_dstaddr); break; #endif - case SIOCSLIFPHYADDR: - src = (struct sockaddr *) - &(((struct if_laddrreq *)data)->addr); - dst = (struct sockaddr *) - &(((struct if_laddrreq *)data)->dstaddr); - break; default: return EINVAL; } @@ -788,9 +781,6 @@ gif_ioctl(ifp, cmd, data) break; return EAFNOSUPPORT; #endif /* INET6 */ - case SIOCSLIFPHYADDR: - /* checks done in the above */ - break; } error = gif_set_tunnel(GIF2IFP(sc), src, dst); @@ -886,31 +876,6 @@ gif_ioctl(ifp, cmd, data) #endif break; - case SIOCGLIFPHYADDR: - if (sc->gif_psrc == NULL || sc->gif_pdst == NULL) { - error = EADDRNOTAVAIL; - goto bad; - } - - /* copy src */ - src = sc->gif_psrc; - dst = (struct sockaddr *) - &(((struct if_laddrreq *)data)->addr); - size = sizeof(((struct if_laddrreq *)data)->addr); - if (src->sa_len > size) - return EINVAL; - bcopy((caddr_t)src, (caddr_t)dst, src->sa_len); - - /* copy dst */ - src = sc->gif_pdst; - dst = (struct sockaddr *) - &(((struct if_laddrreq *)data)->dstaddr); - size = sizeof(((struct if_laddrreq *)data)->dstaddr); - if (src->sa_len > size) - return EINVAL; - bcopy((caddr_t)src, (caddr_t)dst, src->sa_len); - break; - case SIOCSIFFLAGS: /* if_ioctl() takes care of it */ break; Index: sys/net/if_gre.c =================================================================== --- sys/net/if_gre.c (revision 257694) +++ sys/net/if_gre.c (working copy) @@ -519,7 +519,6 @@ static int gre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) { struct ifreq *ifr = (struct ifreq *)data; - struct if_laddrreq *lifr = (struct if_laddrreq *)data; struct in_aliasreq *aifr = (struct in_aliasreq *)data; struct gre_softc *sc = ifp->if_softc; struct sockaddr_in si; @@ -734,27 +733,6 @@ gre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t d sc->g_src = aifr->ifra_addr.sin_addr; sc->g_dst = aifr->ifra_dstaddr.sin_addr; goto recompute; - case SIOCSLIFPHYADDR: - /* - * XXXRW: Isn't this priv_check() redundant to the ifnet - * layer check? - */ - if ((error = priv_check(curthread, PRIV_NET_SETIFPHYS)) != 0) - break; - if (lifr->addr.ss_family != AF_INET || - lifr->dstaddr.ss_family != AF_INET) { - error = EAFNOSUPPORT; - break; - } - if (lifr->addr.ss_len != sizeof(si) || - lifr->dstaddr.ss_len != sizeof(si)) { - error = EINVAL; - break; - } - sc->g_src = (satosin(&lifr->addr))->sin_addr; - sc->g_dst = - (satosin(&lifr->dstaddr))->sin_addr; - goto recompute; case SIOCDIFPHYADDR: /* * XXXRW: Isn't this priv_check() redundant to the ifnet @@ -765,26 +743,6 @@ gre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t d sc->g_src.s_addr = INADDR_ANY; sc->g_dst.s_addr = INADDR_ANY; goto recompute; - case SIOCGLIFPHYADDR: - if (sc->g_src.s_addr == INADDR_ANY || - sc->g_dst.s_addr == INADDR_ANY) { - error = EADDRNOTAVAIL; - break; - } - memset(&si, 0, sizeof(si)); - si.sin_family = AF_INET; - si.sin_len = sizeof(struct sockaddr_in); - si.sin_addr.s_addr = sc->g_src.s_addr; - error = prison_if(curthread->td_ucred, (struct sockaddr *)&si); - if (error != 0) - break; - memcpy(&lifr->addr, &si, sizeof(si)); - si.sin_addr.s_addr = sc->g_dst.s_addr; - error = prison_if(curthread->td_ucred, (struct sockaddr *)&si); - if (error != 0) - break; - memcpy(&lifr->dstaddr, &si, sizeof(si)); - break; case SIOCGIFPSRCADDR: #ifdef INET6 case SIOCGIFPSRCADDR_IN6: Index: sys/netinet/in.c =================================================================== --- sys/netinet/in.c (revision 257694) +++ sys/netinet/in.c (working copy) @@ -68,10 +68,6 @@ __FBSDID("$FreeBSD$"); #include <netinet/udp.h> #include <netinet/udp_var.h> -static int in_mask2len(struct in_addr *); -static void in_len2mask(struct in_addr *, int); -static int in_lifaddr_ioctl(struct socket *, u_long, caddr_t, - struct ifnet *, struct thread *); static int in_aifaddr_ioctl(caddr_t, struct ifnet *, struct thread *); static int in_difaddr_ioctl(caddr_t, struct ifnet *, struct thread *); @@ -192,42 +188,6 @@ in_socktrim(struct sockaddr_in *ap) } } -static int -in_mask2len(mask) - struct in_addr *mask; -{ - int x, y; - u_char *p; - - p = (u_char *)mask; - for (x = 0; x < sizeof(*mask); x++) { - if (p[x] != 0xff) - break; - } - y = 0; - if (x < sizeof(*mask)) { - for (y = 0; y < 8; y++) { - if ((p[x] & (0x80 >> y)) == 0) - break; - } - } - return (x * 8 + y); -} - -static void -in_len2mask(struct in_addr *mask, int len) -{ - int i; - u_char *p; - - p = (u_char *)mask; - bzero(mask, sizeof(*mask)); - for (i = 0; i < len / 8; i++) - p[i] = 0xff; - if (len % 8) - p[i] = (0xff00 >> (len % 8)) & 0xff; -} - /* * Generic internet control operations (ioctl's). */ @@ -263,10 +223,6 @@ in_control(struct socket *so, u_long cmd, caddr_t error = in_aifaddr_ioctl(data, ifp, td); sx_xunlock(&in_control_sx); return (error); - case SIOCALIFADDR: - case SIOCDLIFADDR: - case SIOCGLIFADDR: - return (in_lifaddr_ioctl(so, cmd, data, ifp, td)); case SIOCSIFADDR: case SIOCSIFBRDADDR: case SIOCSIFDSTADDR: @@ -634,194 +590,6 @@ in_difaddr_ioctl(caddr_t data, struct ifnet *ifp, return (0); } -/* - * SIOC[GAD]LIFADDR. - * SIOCGLIFADDR: get first address. (?!?) - * SIOCGLIFADDR with IFLR_PREFIX: - * get first address that matches the specified prefix. - * SIOCALIFADDR: add the specified address. - * SIOCALIFADDR with IFLR_PREFIX: - * EINVAL since we can't deduce hostid part of the address. - * SIOCDLIFADDR: delete the specified address. - * SIOCDLIFADDR with IFLR_PREFIX: - * delete the first address that matches the specified prefix. - * return values: - * EINVAL on invalid parameters - * EADDRNOTAVAIL on prefix match failed/specified address not found - * other values may be returned from in_ioctl() - */ -static int -in_lifaddr_ioctl(struct socket *so, u_long cmd, caddr_t data, - struct ifnet *ifp, struct thread *td) -{ - struct if_laddrreq *iflr = (struct if_laddrreq *)data; - struct ifaddr *ifa; - int error; - - switch (cmd) { - case SIOCALIFADDR: - if (td != NULL) { - error = priv_check(td, PRIV_NET_ADDIFADDR); - if (error) - return (error); - } - break; - case SIOCDLIFADDR: - if (td != NULL) { - error = priv_check(td, PRIV_NET_DELIFADDR); - if (error) - return (error); - } - break; - } - - switch (cmd) { - case SIOCGLIFADDR: - /* address must be specified on GET with IFLR_PREFIX */ - if ((iflr->flags & IFLR_PREFIX) == 0) - break; - /*FALLTHROUGH*/ - case SIOCALIFADDR: - case SIOCDLIFADDR: - /* address must be specified on ADD and DELETE */ - if (iflr->addr.ss_family != AF_INET) - return (EINVAL); - if (iflr->addr.ss_len != sizeof(struct sockaddr_in)) - return (EINVAL); - /* XXX need improvement */ - if (iflr->dstaddr.ss_family - && iflr->dstaddr.ss_family != AF_INET) - return (EINVAL); - if (iflr->dstaddr.ss_family - && iflr->dstaddr.ss_len != sizeof(struct sockaddr_in)) - return (EINVAL); - break; - default: /*shouldn't happen*/ - return (EOPNOTSUPP); - } - if (sizeof(struct in_addr) * 8 < iflr->prefixlen) - return (EINVAL); - - switch (cmd) { - case SIOCALIFADDR: - { - struct in_aliasreq ifra; - - if (iflr->flags & IFLR_PREFIX) - return (EINVAL); - - /* copy args to in_aliasreq, perform ioctl(SIOCAIFADDR). */ - bzero(&ifra, sizeof(ifra)); - bcopy(iflr->iflr_name, ifra.ifra_name, - sizeof(ifra.ifra_name)); - - bcopy(&iflr->addr, &ifra.ifra_addr, iflr->addr.ss_len); - - if (iflr->dstaddr.ss_family) { /*XXX*/ - bcopy(&iflr->dstaddr, &ifra.ifra_dstaddr, - iflr->dstaddr.ss_len); - } - - ifra.ifra_mask.sin_family = AF_INET; - ifra.ifra_mask.sin_len = sizeof(struct sockaddr_in); - in_len2mask(&ifra.ifra_mask.sin_addr, iflr->prefixlen); - - return (in_control(so, SIOCAIFADDR, (caddr_t)&ifra, ifp, td)); - } - case SIOCGLIFADDR: - case SIOCDLIFADDR: - { - struct in_ifaddr *ia; - struct in_addr mask, candidate, match; - struct sockaddr_in *sin; - - bzero(&mask, sizeof(mask)); - bzero(&match, sizeof(match)); - if (iflr->flags & IFLR_PREFIX) { - /* lookup a prefix rather than address. */ - in_len2mask(&mask, iflr->prefixlen); - - sin = (struct sockaddr_in *)&iflr->addr; - match.s_addr = sin->sin_addr.s_addr; - match.s_addr &= mask.s_addr; - - /* if you set extra bits, that's wrong */ - if (match.s_addr != sin->sin_addr.s_addr) - return (EINVAL); - - } else { - /* on getting an address, take the 1st match */ - /* on deleting an address, do exact match */ - if (cmd != SIOCGLIFADDR) { - in_len2mask(&mask, 32); - sin = (struct sockaddr_in *)&iflr->addr; - match.s_addr = sin->sin_addr.s_addr; - } - } - - IF_ADDR_RLOCK(ifp); - TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { - if (ifa->ifa_addr->sa_family != AF_INET) - continue; - if (match.s_addr == 0) - break; - sin = (struct sockaddr_in *)&ifa->ifa_addr; - candidate.s_addr = sin->sin_addr.s_addr; - candidate.s_addr &= mask.s_addr; - if (candidate.s_addr == match.s_addr) - break; - } - if (ifa != NULL) - ifa_ref(ifa); - IF_ADDR_RUNLOCK(ifp); - if (ifa == NULL) - return (EADDRNOTAVAIL); - ia = (struct in_ifaddr *)ifa; - - if (cmd == SIOCGLIFADDR) { - /* fill in the if_laddrreq structure */ - bcopy(&ia->ia_addr, &iflr->addr, ia->ia_addr.sin_len); - - if ((ifp->if_flags & IFF_POINTOPOINT) != 0) { - bcopy(&ia->ia_dstaddr, &iflr->dstaddr, - ia->ia_dstaddr.sin_len); - } else - bzero(&iflr->dstaddr, sizeof(iflr->dstaddr)); - - iflr->prefixlen = - in_mask2len(&ia->ia_sockmask.sin_addr); - - iflr->flags = 0; /*XXX*/ - ifa_free(ifa); - - return (0); - } else { - struct in_aliasreq ifra; - - /* fill in_aliasreq and do ioctl(SIOCDIFADDR) */ - bzero(&ifra, sizeof(ifra)); - bcopy(iflr->iflr_name, ifra.ifra_name, - sizeof(ifra.ifra_name)); - - bcopy(&ia->ia_addr, &ifra.ifra_addr, - ia->ia_addr.sin_len); - if ((ifp->if_flags & IFF_POINTOPOINT) != 0) { - bcopy(&ia->ia_dstaddr, &ifra.ifra_dstaddr, - ia->ia_dstaddr.sin_len); - } - bcopy(&ia->ia_sockmask, &ifra.ifra_dstaddr, - ia->ia_sockmask.sin_len); - ifa_free(ifa); - - return (in_control(so, SIOCDIFADDR, (caddr_t)&ifra, - ifp, td)); - } - } - } - - return (EOPNOTSUPP); /*just for safety*/ -} - #define rtinitflags(x) \ ((((x)->ia_ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) != 0) \ ? RTF_HOST : 0) Index: sys/netinet6/in6.c =================================================================== --- sys/netinet6/in6.c (revision 257694) +++ sys/netinet6/in6.c (working copy) @@ -133,8 +133,6 @@ const struct in6_addr in6mask128 = IN6MASK128; const struct sockaddr_in6 sa6_any = { sizeof(sa6_any), AF_INET6, 0, 0, IN6ADDR_ANY_INIT, 0 }; -static int in6_lifaddr_ioctl(struct socket *, u_long, caddr_t, - struct ifnet *, struct thread *); static int in6_ifinit(struct ifnet *, struct in6_ifaddr *, struct sockaddr_in6 *, int); static void in6_unlink_ifa(struct in6_ifaddr *, struct ifnet *); @@ -376,26 +374,6 @@ in6_control(struct socket *so, u_long cmd, caddr_t ifr->ifr_ifru.ifru_scope_id)); } - switch (cmd) { - case SIOCALIFADDR: - if (td != NULL) { - error = priv_check(td, PRIV_NET_ADDIFADDR); - if (error) - return (error); - } - return in6_lifaddr_ioctl(so, cmd, data, ifp, td); - - case SIOCDLIFADDR: - if (td != NULL) { - error = priv_check(td, PRIV_NET_DELIFADDR); - if (error) - return (error); - } - /* FALLTHROUGH */ - case SIOCGLIFADDR: - return in6_lifaddr_ioctl(so, cmd, data, ifp, td); - } - /* * Find address for this interface, if it exists. * @@ -1601,277 +1579,6 @@ in6_purgeif(struct ifnet *ifp) } /* - * SIOC[GAD]LIFADDR. - * SIOCGLIFADDR: get first address. (?) - * SIOCGLIFADDR with IFLR_PREFIX: - * get first address that matches the specified prefix. - * SIOCALIFADDR: add the specified address. - * SIOCALIFADDR with IFLR_PREFIX: - * add the specified prefix, filling hostid part from - * the first link-local address. prefixlen must be <= 64. - * SIOCDLIFADDR: delete the specified address. - * SIOCDLIFADDR with IFLR_PREFIX: - * delete the first address that matches the specified prefix. - * return values: - * EINVAL on invalid parameters - * EADDRNOTAVAIL on prefix match failed/specified address not found - * other values may be returned from in6_ioctl() - * - * NOTE: SIOCALIFADDR(with IFLR_PREFIX set) allows prefixlen less than 64. - * this is to accomodate address naming scheme other than RFC2374, - * in the future. - * RFC2373 defines interface id to be 64bit, but it allows non-RFC2374 - * address encoding scheme. (see figure on page 8) - */ -static int -in6_lifaddr_ioctl(struct socket *so, u_long cmd, caddr_t data, - struct ifnet *ifp, struct thread *td) -{ - struct if_laddrreq *iflr = (struct if_laddrreq *)data; - struct ifaddr *ifa; - struct sockaddr *sa; - - /* sanity checks */ - if (!data || !ifp) { - panic("invalid argument to in6_lifaddr_ioctl"); - /* NOTREACHED */ - } - - switch (cmd) { - case SIOCGLIFADDR: - /* address must be specified on GET with IFLR_PREFIX */ - if ((iflr->flags & IFLR_PREFIX) == 0) - break; - /* FALLTHROUGH */ - case SIOCALIFADDR: - case SIOCDLIFADDR: - /* address must be specified on ADD and DELETE */ - sa = (struct sockaddr *)&iflr->addr; - if (sa->sa_family != AF_INET6) - return EINVAL; - if (sa->sa_len != sizeof(struct sockaddr_in6)) - return EINVAL; - /* XXX need improvement */ - sa = (struct sockaddr *)&iflr->dstaddr; - if (sa->sa_family && sa->sa_family != AF_INET6) - return EINVAL; - if (sa->sa_len && sa->sa_len != sizeof(struct sockaddr_in6)) - return EINVAL; - break; - default: /* shouldn't happen */ -#if 0 - panic("invalid cmd to in6_lifaddr_ioctl"); - /* NOTREACHED */ -#else - return EOPNOTSUPP; -#endif - } - if (sizeof(struct in6_addr) * 8 < iflr->prefixlen) - return EINVAL; - - switch (cmd) { - case SIOCALIFADDR: - { - struct in6_aliasreq ifra; - struct in6_addr *hostid = NULL; - int prefixlen; - - ifa = NULL; - if ((iflr->flags & IFLR_PREFIX) != 0) { - struct sockaddr_in6 *sin6; - - /* - * hostid is to fill in the hostid part of the - * address. hostid points to the first link-local - * address attached to the interface. - */ - ifa = (struct ifaddr *)in6ifa_ifpforlinklocal(ifp, 0); - if (!ifa) - return EADDRNOTAVAIL; - hostid = IFA_IN6(ifa); - - /* prefixlen must be <= 64. */ - if (64 < iflr->prefixlen) { - if (ifa != NULL) - ifa_free(ifa); - return EINVAL; - } - prefixlen = iflr->prefixlen; - - /* hostid part must be zero. */ - sin6 = (struct sockaddr_in6 *)&iflr->addr; - if (sin6->sin6_addr.s6_addr32[2] != 0 || - sin6->sin6_addr.s6_addr32[3] != 0) { - if (ifa != NULL) - ifa_free(ifa); - return EINVAL; - } - } else - prefixlen = iflr->prefixlen; - - /* copy args to in6_aliasreq, perform ioctl(SIOCAIFADDR_IN6). */ - bzero(&ifra, sizeof(ifra)); - bcopy(iflr->iflr_name, ifra.ifra_name, sizeof(ifra.ifra_name)); - - bcopy(&iflr->addr, &ifra.ifra_addr, - ((struct sockaddr *)&iflr->addr)->sa_len); - if (hostid) { - /* fill in hostid part */ - ifra.ifra_addr.sin6_addr.s6_addr32[2] = - hostid->s6_addr32[2]; - ifra.ifra_addr.sin6_addr.s6_addr32[3] = - hostid->s6_addr32[3]; - } - - if (((struct sockaddr *)&iflr->dstaddr)->sa_family) { /* XXX */ - bcopy(&iflr->dstaddr, &ifra.ifra_dstaddr, - ((struct sockaddr *)&iflr->dstaddr)->sa_len); - if (hostid) { - ifra.ifra_dstaddr.sin6_addr.s6_addr32[2] = - hostid->s6_addr32[2]; - ifra.ifra_dstaddr.sin6_addr.s6_addr32[3] = - hostid->s6_addr32[3]; - } - } - if (ifa != NULL) - ifa_free(ifa); - - ifra.ifra_prefixmask.sin6_len = sizeof(struct sockaddr_in6); - in6_prefixlen2mask(&ifra.ifra_prefixmask.sin6_addr, prefixlen); - - ifra.ifra_flags = iflr->flags & ~IFLR_PREFIX; - return in6_control(so, SIOCAIFADDR_IN6, (caddr_t)&ifra, ifp, td); - } - case SIOCGLIFADDR: - case SIOCDLIFADDR: - { - struct in6_ifaddr *ia; - struct in6_addr mask, candidate, match; - struct sockaddr_in6 *sin6; - int cmp; - - bzero(&mask, sizeof(mask)); - if (iflr->flags & IFLR_PREFIX) { - /* lookup a prefix rather than address. */ - in6_prefixlen2mask(&mask, iflr->prefixlen); - - sin6 = (struct sockaddr_in6 *)&iflr->addr; - bcopy(&sin6->sin6_addr, &match, sizeof(match)); - match.s6_addr32[0] &= mask.s6_addr32[0]; - match.s6_addr32[1] &= mask.s6_addr32[1]; - match.s6_addr32[2] &= mask.s6_addr32[2]; - match.s6_addr32[3] &= mask.s6_addr32[3]; - - /* if you set extra bits, that's wrong */ - if (bcmp(&match, &sin6->sin6_addr, sizeof(match))) - return EINVAL; - - cmp = 1; - } else { - if (cmd == SIOCGLIFADDR) { - /* on getting an address, take the 1st match */ - cmp = 0; /* XXX */ - } else { - /* on deleting an address, do exact match */ - in6_prefixlen2mask(&mask, 128); - sin6 = (struct sockaddr_in6 *)&iflr->addr; - bcopy(&sin6->sin6_addr, &match, sizeof(match)); - - cmp = 1; - } - } - - IF_ADDR_RLOCK(ifp); - TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { - if (ifa->ifa_addr->sa_family != AF_INET6) - continue; - if (!cmp) - break; - - /* - * XXX: this is adhoc, but is necessary to allow - * a user to specify fe80::/64 (not /10) for a - * link-local address. - */ - bcopy(IFA_IN6(ifa), &candidate, sizeof(candidate)); - in6_clearscope(&candidate); - candidate.s6_addr32[0] &= mask.s6_addr32[0]; - candidate.s6_addr32[1] &= mask.s6_addr32[1]; - candidate.s6_addr32[2] &= mask.s6_addr32[2]; - candidate.s6_addr32[3] &= mask.s6_addr32[3]; - if (IN6_ARE_ADDR_EQUAL(&candidate, &match)) - break; - } - if (ifa != NULL) - ifa_ref(ifa); - IF_ADDR_RUNLOCK(ifp); - if (!ifa) - return EADDRNOTAVAIL; - ia = ifa2ia6(ifa); - - if (cmd == SIOCGLIFADDR) { - int error; - - /* fill in the if_laddrreq structure */ - bcopy(&ia->ia_addr, &iflr->addr, ia->ia_addr.sin6_len); - error = sa6_recoverscope( - (struct sockaddr_in6 *)&iflr->addr); - if (error != 0) { - ifa_free(ifa); - return (error); - } - - if ((ifp->if_flags & IFF_POINTOPOINT) != 0) { - bcopy(&ia->ia_dstaddr, &iflr->dstaddr, - ia->ia_dstaddr.sin6_len); - error = sa6_recoverscope( - (struct sockaddr_in6 *)&iflr->dstaddr); - if (error != 0) { - ifa_free(ifa); - return (error); - } - } else - bzero(&iflr->dstaddr, sizeof(iflr->dstaddr)); - - iflr->prefixlen = - in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL); - - iflr->flags = ia->ia6_flags; /* XXX */ - ifa_free(ifa); - - return 0; - } else { - struct in6_aliasreq ifra; - - /* fill in6_aliasreq and do ioctl(SIOCDIFADDR_IN6) */ - bzero(&ifra, sizeof(ifra)); - bcopy(iflr->iflr_name, ifra.ifra_name, - sizeof(ifra.ifra_name)); - - bcopy(&ia->ia_addr, &ifra.ifra_addr, - ia->ia_addr.sin6_len); - if ((ifp->if_flags & IFF_POINTOPOINT) != 0) { - bcopy(&ia->ia_dstaddr, &ifra.ifra_dstaddr, - ia->ia_dstaddr.sin6_len); - } else { - bzero(&ifra.ifra_dstaddr, - sizeof(ifra.ifra_dstaddr)); - } - bcopy(&ia->ia_prefixmask, &ifra.ifra_dstaddr, - ia->ia_prefixmask.sin6_len); - - ifra.ifra_flags = ia->ia6_flags; - ifa_free(ifa); - return in6_control(so, SIOCDIFADDR_IN6, (caddr_t)&ifra, - ifp, td); - } - } - } - - return EOPNOTSUPP; /* just for safety */ -} - -/* * Initialize an interface's IPv6 address and routing table entry. */ static int Index: sys/sys/sockio.h =================================================================== --- sys/sys/sockio.h (revision 257696) +++ sys/sys/sockio.h (working copy) @@ -69,9 +69,9 @@ #define SIOCSIFMETRIC _IOW('i', 24, struct ifreq) /* set IF metric */ #define SIOCDIFADDR _IOW('i', 25, struct ifreq) /* delete IF addr */ /* OSIOCAIFADDR _IOW('i', 26, struct oifaliasreq) FreeBSD 9.x */ -#define SIOCALIFADDR _IOW('i', 27, struct if_laddrreq) /* add IF addr */ -#define SIOCGLIFADDR _IOWR('i', 28, struct if_laddrreq) /* get IF addr */ -#define SIOCDLIFADDR _IOW('i', 29, struct if_laddrreq) /* delete IF addr */ +/* SIOCALIFADDR _IOW('i', 27, struct if_laddrreq) KAME */ +/* SIOCGLIFADDR _IOWR('i', 28, struct if_laddrreq) KAME */ +/* SIOCDLIFADDR _IOW('i', 29, struct if_laddrreq) KAME */ #define SIOCSIFCAP _IOW('i', 30, struct ifreq) /* set IF features */ #define SIOCGIFCAP _IOWR('i', 31, struct ifreq) /* get IF features */ #define SIOCGIFINDEX _IOWR('i', 32, struct ifreq) /* get IF index */ @@ -101,8 +101,8 @@ #define SIOCGIFPSRCADDR _IOWR('i', 71, struct ifreq) /* get gif psrc addr */ #define SIOCGIFPDSTADDR _IOWR('i', 72, struct ifreq) /* get gif pdst addr */ #define SIOCDIFPHYADDR _IOW('i', 73, struct ifreq) /* delete gif addrs */ -#define SIOCSLIFPHYADDR _IOW('i', 74, struct if_laddrreq) /* set gif addrs */ -#define SIOCGLIFPHYADDR _IOWR('i', 75, struct if_laddrreq) /* get gif addrs */ +/* SIOCSLIFPHYADDR _IOW('i', 74, struct if_laddrreq) KAME */ +/* SIOCGLIFPHYADDR _IOWR('i', 75, struct if_laddrreq) KAME */ #define SIOCGPRIVATE_0 _IOWR('i', 80, struct ifreq) /* device private 0 */ #define SIOCGPRIVATE_1 _IOWR('i', 81, struct ifreq) /* device private 1 */ --ikeVEW9yuYc//A+q--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20131105120240.GA7577>