version 1.217, 2008/02/07 08:48:16 |
version 1.217.6.2, 2008/06/02 13:24:21 |
|
|
/* $NetBSD$ */ |
/* $NetBSD$ */ |
|
|
/*- |
/*- |
* Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc. |
* Copyright (c) 1999, 2000, 2001, 2008 The NetBSD Foundation, Inc. |
* All rights reserved. |
* All rights reserved. |
* |
* |
* This code is derived from software contributed to The NetBSD Foundation |
* This code is derived from software contributed to The NetBSD Foundation |
|
|
* 2. Redistributions in binary form must reproduce the above copyright |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
|
* must display the following acknowledgement: |
|
* This product includes software developed by the NetBSD |
|
* Foundation, Inc. and its contributors. |
|
* 4. Neither the name of The NetBSD Foundation nor the names of its |
|
* contributors may be used to endorse or promote products derived |
|
* from this software without specific prior written permission. |
|
* |
* |
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
Line 273 if_set_sadl(struct ifnet *ifp, const voi |
|
Line 266 if_set_sadl(struct ifnet *ifp, const voi |
|
sdl = satosdl(ifa->ifa_addr); |
sdl = satosdl(ifa->ifa_addr); |
|
|
(void)sockaddr_dl_setaddr(sdl, sdl->sdl_len, lla, ifp->if_addrlen); |
(void)sockaddr_dl_setaddr(sdl, sdl->sdl_len, lla, ifp->if_addrlen); |
|
/* TBD routing socket */ |
} |
} |
|
|
struct ifaddr * |
struct ifaddr * |
Line 305 if_dl_create(const struct ifnet *ifp, co |
|
Line 299 if_dl_create(const struct ifnet *ifp, co |
|
return ifa; |
return ifa; |
} |
} |
|
|
|
static void |
|
if_sadl_setrefs(struct ifnet *ifp, struct ifaddr *ifa) |
|
{ |
|
const struct sockaddr_dl *sdl; |
|
ifnet_addrs[ifp->if_index] = ifa; |
|
IFAREF(ifa); |
|
ifp->if_dl = ifa; |
|
IFAREF(ifa); |
|
sdl = satosdl(ifa->ifa_addr); |
|
ifp->if_sadl = sdl; |
|
} |
|
|
/* |
/* |
* Allocate the link level name for the specified interface. This |
* Allocate the link level name for the specified interface. This |
* is an attachment helper. It must be called after ifp->if_addrlen |
* is an attachment helper. It must be called after ifp->if_addrlen |
Line 327 if_alloc_sadl(struct ifnet *ifp) |
|
Line 333 if_alloc_sadl(struct ifnet *ifp) |
|
|
|
ifa = if_dl_create(ifp, &sdl); |
ifa = if_dl_create(ifp, &sdl); |
|
|
ifnet_addrs[ifp->if_index] = ifa; |
|
IFAREF(ifa); |
|
ifa_insert(ifp, ifa); |
ifa_insert(ifp, ifa); |
ifp->if_dl = ifa; |
if_sadl_setrefs(ifp, ifa); |
IFAREF(ifa); |
} |
ifp->if_sadl = sdl; |
|
|
static void |
|
if_deactivate_sadl(struct ifnet *ifp) |
|
{ |
|
struct ifaddr *ifa; |
|
|
|
KASSERT(ifp->if_dl != NULL); |
|
|
|
ifa = ifp->if_dl; |
|
|
|
ifp->if_sadl = NULL; |
|
|
|
ifnet_addrs[ifp->if_index] = NULL; |
|
IFAFREE(ifa); |
|
ifp->if_dl = NULL; |
|
IFAFREE(ifa); |
|
} |
|
|
|
void |
|
if_activate_sadl(struct ifnet *ifp, struct ifaddr *ifa, |
|
const struct sockaddr_dl *sdl) |
|
{ |
|
int s; |
|
|
|
s = splnet(); |
|
|
|
if_deactivate_sadl(ifp); |
|
|
|
if_sadl_setrefs(ifp, ifa); |
|
splx(s); |
|
rt_ifmsg(ifp); |
} |
} |
|
|
/* |
/* |
Line 360 if_free_sadl(struct ifnet *ifp) |
|
Line 394 if_free_sadl(struct ifnet *ifp) |
|
rtinit(ifa, RTM_DELETE, 0); |
rtinit(ifa, RTM_DELETE, 0); |
ifa_remove(ifp, ifa); |
ifa_remove(ifp, ifa); |
|
|
ifp->if_sadl = NULL; |
if_deactivate_sadl(ifp); |
|
|
ifnet_addrs[ifp->if_index] = NULL; |
|
IFAFREE(ifa); |
|
ifp->if_dl = NULL; |
|
IFAFREE(ifa); |
|
splx(s); |
splx(s); |
} |
} |
|
|
Line 552 if_deactivate(struct ifnet *ifp) |
|
Line 581 if_deactivate(struct ifnet *ifp) |
|
} |
} |
|
|
void |
void |
if_purgeaddrs(struct ifnet *ifp, int family, |
if_purgeaddrs(struct ifnet *ifp, int family, void (*purgeaddr)(struct ifaddr *)) |
void (*purgeaddr)(struct ifaddr *)) |
|
{ |
{ |
struct ifaddr *ifa, *nifa; |
struct ifaddr *ifa, *nifa; |
|
|
Line 1169 link_rtrequest(int cmd, struct rtentry * |
|
Line 1197 link_rtrequest(int cmd, struct rtentry * |
|
const struct sockaddr *dst; |
const struct sockaddr *dst; |
struct ifnet *ifp; |
struct ifnet *ifp; |
|
|
if (cmd != RTM_ADD || ((ifa = rt->rt_ifa) == NULL) || |
if (cmd != RTM_ADD || (ifa = rt->rt_ifa) == NULL || |
((ifp = ifa->ifa_ifp) == NULL) || ((dst = rt_getkey(rt)) == NULL)) |
(ifp = ifa->ifa_ifp) == NULL || (dst = rt_getkey(rt)) == NULL) |
return; |
return; |
if ((ifa = ifaof_ifpforaddr(dst, ifp)) != NULL) { |
if ((ifa = ifaof_ifpforaddr(dst, ifp)) != NULL) { |
rt_replace_ifa(rt, ifa); |
rt_replace_ifa(rt, ifa); |
Line 1492 ifioctl_common(struct ifnet *ifp, u_long |
|
Line 1520 ifioctl_common(struct ifnet *ifp, u_long |
|
#endif |
#endif |
return ENETRESET; |
return ENETRESET; |
default: |
default: |
return EOPNOTSUPP; |
return ENOTTY; |
} |
} |
return 0; |
return 0; |
} |
} |
Line 1634 ifioctl(struct socket *so, u_long cmd, v |
|
Line 1662 ifioctl(struct socket *so, u_long cmd, v |
|
|
|
default: |
default: |
error = ifioctl_common(ifp, cmd, data); |
error = ifioctl_common(ifp, cmd, data); |
if (error != EOPNOTSUPP) |
if (error != ENOTTY) |
break; |
break; |
if (so->so_proto == NULL) |
if (so->so_proto == NULL) |
return EOPNOTSUPP; |
return EOPNOTSUPP; |
#ifdef COMPAT_OSOCK |
#ifdef COMPAT_OSOCK |
error = compat_ifioctl(so, ocmd, cmd, data, l); |
error = compat_ifioctl(so, ocmd, cmd, data, l); |
#else |
#else |
error = ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL, |
error = (*so->so_proto->pr_usrreq)(so, PRU_CONTROL, |
(struct mbuf *)cmd, (struct mbuf *)data, |
(struct mbuf *)cmd, (struct mbuf *)data, |
(struct mbuf *)ifp, l)); |
(struct mbuf *)ifp, l); |
#endif |
#endif |
break; |
break; |
} |
} |
Line 1716 ifconf(u_long cmd, void *data) |
|
Line 1744 ifconf(u_long cmd, void *data) |
|
if (IFADDR_EMPTY(ifp)) { |
if (IFADDR_EMPTY(ifp)) { |
/* Interface with no addresses - send zero sockaddr. */ |
/* Interface with no addresses - send zero sockaddr. */ |
memset(&ifr.ifr_addr, 0, sizeof(ifr.ifr_addr)); |
memset(&ifr.ifr_addr, 0, sizeof(ifr.ifr_addr)); |
if (ifrp != NULL) |
if (ifrp == NULL) { |
{ |
|
if (space >= sz) { |
|
error = copyout(&ifr, ifrp, sz); |
|
if (error != 0) |
|
return (error); |
|
ifrp++; space -= sz; |
|
} |
|
} |
|
else |
|
space += sz; |
space += sz; |
continue; |
continue; |
|
} |
|
if (space >= sz) { |
|
error = copyout(&ifr, ifrp, sz); |
|
if (error != 0) |
|
return error; |
|
ifrp++; |
|
space -= sz; |
|
} |
} |
} |
|
|
IFADDR_FOREACH(ifa, ifp) { |
IFADDR_FOREACH(ifa, ifp) { |
Line 1735 ifconf(u_long cmd, void *data) |
|
Line 1762 ifconf(u_long cmd, void *data) |
|
/* all sockaddrs must fit in sockaddr_storage */ |
/* all sockaddrs must fit in sockaddr_storage */ |
KASSERT(sa->sa_len <= sizeof(ifr.ifr_ifru)); |
KASSERT(sa->sa_len <= sizeof(ifr.ifr_ifru)); |
|
|
if (ifrp != NULL) |
if (ifrp == NULL) { |
{ |
|
memcpy(&ifr.ifr_space, sa, sa->sa_len); |
|
if (space >= sz) { |
|
error = copyout(&ifr, ifrp, sz); |
|
if (error != 0) |
|
return (error); |
|
ifrp++; space -= sz; |
|
} |
|
} |
|
else |
|
space += sz; |
space += sz; |
|
continue; |
|
} |
|
memcpy(&ifr.ifr_space, sa, sa->sa_len); |
|
if (space >= sz) { |
|
error = copyout(&ifr, ifrp, sz); |
|
if (error != 0) |
|
return (error); |
|
ifrp++; space -= sz; |
|
} |
} |
} |
} |
} |
if (ifrp != NULL) |
if (ifrp != NULL) { |
{ |
|
KASSERT(0 <= space && space <= ifc->ifc_len); |
KASSERT(0 <= space && space <= ifc->ifc_len); |
ifc->ifc_len -= space; |
ifc->ifc_len -= space; |
} |
} else { |
else |
|
{ |
|
KASSERT(space >= 0); |
KASSERT(space >= 0); |
ifc->ifc_len = space; |
ifc->ifc_len = space; |
} |
} |