First-draft if_detach() implementation, originally from Bill Studnemund,
although this version has been changed somewhat: - reference counting on ifaddrs isn't as complete as Bill's original work was. This is hard to get right, and we should attack one protocol at a time. - This doesn't do reference counting or dynamic allocation of ifnets yet. - This version introduces a new PRU -- PRU_PURGEADDR, which is used to purge an ifaddr from a protocol. The old method Bill used didn't work on all protocols, and it only worked on some because it was Very Lucky. This mostly works ... i.e. works for my USB Ethernet, except for a dangling ifaddr reference left by the IPv6 code; have not yet tracked this down.
This commit is contained in:
parent
d8e72e215d
commit
d844a3ac41
419
sys/net/if.c
419
sys/net/if.c
@ -1,4 +1,40 @@
|
||||
/* $NetBSD: if.c,v 1.52 1999/09/29 22:42:02 thorpej Exp $ */
|
||||
/* $NetBSD: if.c,v 1.53 2000/02/01 22:52:04 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by William Studnemund and Jason R. Thorpe.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* 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
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
@ -85,6 +121,7 @@
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/radix.h>
|
||||
#include <net/route.h>
|
||||
#ifdef NETATALK
|
||||
#include <netatalk/at_extern.h>
|
||||
#include <netatalk/at.h>
|
||||
@ -106,6 +143,8 @@ void if_slowtimo __P((void *arg));
|
||||
extern void nd6_setmtu __P((struct ifnet *));
|
||||
#endif
|
||||
|
||||
int if_rt_walktree __P((struct radix_node *, void *));
|
||||
|
||||
/*
|
||||
* Network interface utility routines.
|
||||
*
|
||||
@ -119,6 +158,81 @@ ifinit()
|
||||
if_slowtimo(NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Null routines used while an interface is going away. These routines
|
||||
* just return an error.
|
||||
*/
|
||||
int if_nulloutput __P((struct ifnet *, struct mbuf *,
|
||||
struct sockaddr *, struct rtentry *));
|
||||
void if_nullinput __P((struct ifnet *, struct mbuf *));
|
||||
void if_nullstart __P((struct ifnet *));
|
||||
int if_nullioctl __P((struct ifnet *, u_long, caddr_t));
|
||||
int if_nullreset __P((struct ifnet *));
|
||||
void if_nullwatchdog __P((struct ifnet *));
|
||||
void if_nulldrain __P((struct ifnet *));
|
||||
|
||||
int
|
||||
if_nulloutput(ifp, m, so, rt)
|
||||
struct ifnet *ifp;
|
||||
struct mbuf *m;
|
||||
struct sockaddr *so;
|
||||
struct rtentry *rt;
|
||||
{
|
||||
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
void
|
||||
if_nullinput(ifp, m)
|
||||
struct ifnet *ifp;
|
||||
struct mbuf *m;
|
||||
{
|
||||
|
||||
/* Nothing. */
|
||||
}
|
||||
|
||||
void
|
||||
if_nullstart(ifp)
|
||||
struct ifnet *ifp;
|
||||
{
|
||||
|
||||
/* Nothing. */
|
||||
}
|
||||
|
||||
int
|
||||
if_nullioctl(ifp, cmd, data)
|
||||
struct ifnet *ifp;
|
||||
u_long cmd;
|
||||
caddr_t data;
|
||||
{
|
||||
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
int
|
||||
if_nullreset(ifp)
|
||||
struct ifnet *ifp;
|
||||
{
|
||||
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
void
|
||||
if_nullwatchdog(ifp)
|
||||
struct ifnet *ifp;
|
||||
{
|
||||
|
||||
/* Nothing. */
|
||||
}
|
||||
|
||||
void
|
||||
if_nulldrain(ifp)
|
||||
struct ifnet *ifp;
|
||||
{
|
||||
|
||||
/* Nothing. */
|
||||
}
|
||||
|
||||
int if_index = 0;
|
||||
struct ifaddr **ifnet_addrs = NULL;
|
||||
struct ifnet **ifindex2ifnet = NULL;
|
||||
@ -149,11 +263,12 @@ if_attach(ifp)
|
||||
* struct ifadd **ifnet_addrs
|
||||
* struct ifnet **ifindex2ifnet
|
||||
*/
|
||||
if (ifnet_addrs == 0 || ifindex2ifnet == 0 || if_index >= if_indexlim) {
|
||||
if (ifnet_addrs == 0 || ifindex2ifnet == 0 ||
|
||||
ifp->if_index >= if_indexlim) {
|
||||
size_t n;
|
||||
caddr_t q;
|
||||
|
||||
while (if_index >= if_indexlim)
|
||||
while (ifp->if_index >= if_indexlim)
|
||||
if_indexlim <<= 1;
|
||||
|
||||
/* grow ifnet_addrs */
|
||||
@ -177,7 +292,7 @@ if_attach(ifp)
|
||||
ifindex2ifnet = (struct ifnet **)q;
|
||||
}
|
||||
|
||||
ifindex2ifnet[if_index] = ifp;
|
||||
ifindex2ifnet[ifp->if_index] = ifp;
|
||||
|
||||
/*
|
||||
* create a Link Level name for this device
|
||||
@ -199,10 +314,12 @@ if_attach(ifp)
|
||||
sdl->sdl_nlen = namelen;
|
||||
sdl->sdl_index = ifp->if_index;
|
||||
sdl->sdl_type = ifp->if_type;
|
||||
ifnet_addrs[if_index] = ifa;
|
||||
ifnet_addrs[ifp->if_index] = ifa;
|
||||
IFAREF(ifa);
|
||||
ifa->ifa_ifp = ifp;
|
||||
ifa->ifa_rtrequest = link_rtrequest;
|
||||
TAILQ_INSERT_HEAD(&ifp->if_addrlist, ifa, ifa_list);
|
||||
IFAREF(ifa);
|
||||
ifa->ifa_addr = (struct sockaddr *)sdl;
|
||||
ifp->if_sadl = sdl;
|
||||
sdl = (struct sockaddr_dl *)(socksize + (caddr_t)sdl);
|
||||
@ -214,6 +331,144 @@ if_attach(ifp)
|
||||
ifp->if_snd.ifq_maxlen = ifqmaxlen;
|
||||
ifp->if_broadcastaddr = 0; /* reliably crash if used uninitialized */
|
||||
}
|
||||
|
||||
/*
|
||||
* Deactivate an interface. This points all of the procedure
|
||||
* handles at error stubs. May be called from interrupt context.
|
||||
*/
|
||||
void
|
||||
if_deactivate(ifp)
|
||||
struct ifnet *ifp;
|
||||
{
|
||||
int s;
|
||||
|
||||
s = splimp();
|
||||
|
||||
ifp->if_output = if_nulloutput;
|
||||
ifp->if_input = if_nullinput;
|
||||
ifp->if_start = if_nullstart;
|
||||
ifp->if_ioctl = if_nullioctl;
|
||||
ifp->if_reset = if_nullreset;
|
||||
ifp->if_watchdog = if_nullwatchdog;
|
||||
ifp->if_drain = if_nulldrain;
|
||||
|
||||
/* No more packets may be enqueued. */
|
||||
ifp->if_snd.ifq_maxlen = 0;
|
||||
|
||||
splx(s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Detach an interface from the list of "active" interfaces,
|
||||
* freeing any resources as we go along.
|
||||
*
|
||||
* NOTE: This routine must be called with a valid thread context,
|
||||
* as it may block.
|
||||
*/
|
||||
void
|
||||
if_detach(ifp)
|
||||
struct ifnet *ifp;
|
||||
{
|
||||
struct ifaddr *ifa;
|
||||
#ifdef IFAREF_DEBUG
|
||||
struct ifaddr *last_ifa = NULL;
|
||||
#endif
|
||||
struct protosw *pr;
|
||||
struct socket so;
|
||||
struct radix_node_head *rnh;
|
||||
int s, i;
|
||||
|
||||
/* XXX Rethink this part. */
|
||||
so.so_type = SOCK_DGRAM;
|
||||
so.so_options = 0;
|
||||
so.so_linger = 0;
|
||||
so.so_state = SS_NOFDREF | SS_CANTSENDMORE | SS_CANTRCVMORE;
|
||||
so.so_pcb = 0;
|
||||
so.so_head = 0;
|
||||
TAILQ_INIT(&so.so_q0);
|
||||
TAILQ_INIT(&so.so_q);
|
||||
|
||||
so.so_q0len = so.so_qlen = so.so_qlimit = 0;
|
||||
so.so_timeo = so.so_oobmark = 0;
|
||||
|
||||
s = splimp();
|
||||
|
||||
/*
|
||||
* Do an if_down() to give protocols a chance to do something.
|
||||
*/
|
||||
if_down(ifp);
|
||||
|
||||
/*
|
||||
* Rip all the addresses off the interface. This should make
|
||||
* all of the routes go away.
|
||||
*/
|
||||
while ((ifa = TAILQ_FIRST(&ifp->if_addrlist)) != NULL) {
|
||||
#ifdef IFAREF_DEBUG
|
||||
printf("if_detach: ifaddr %p, family %d, refcnt %d\n",
|
||||
ifa, ifa->ifa_addr->sa_family, ifa->ifa_refcnt);
|
||||
if (last_ifa != NULL && ifa == last_ifa)
|
||||
panic("loop detected");
|
||||
last_ifa = ifa;
|
||||
#endif
|
||||
if (ifa->ifa_addr->sa_family == AF_LINK) {
|
||||
rtinit(ifa, RTM_DELETE, 0);
|
||||
TAILQ_REMOVE(&ifp->if_addrlist, ifa, ifa_list);
|
||||
IFAFREE(ifa);
|
||||
} else {
|
||||
pr = pffindtype(ifa->ifa_addr->sa_family, SOCK_DGRAM);
|
||||
so.so_proto = pr;
|
||||
if (pr->pr_usrreq) {
|
||||
(void) (*pr->pr_usrreq)(&so, PRU_PURGEADDR,
|
||||
NULL,
|
||||
(struct mbuf *) ifa,
|
||||
(struct mbuf *) ifp, curproc);
|
||||
} else {
|
||||
rtinit(ifa, RTM_DELETE, 0);
|
||||
TAILQ_REMOVE(&ifp->if_addrlist, ifa, ifa_list);
|
||||
IFAFREE(ifa);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Walk the routing table looking for straglers. */
|
||||
for (i = 1; i <= AF_MAX; i++) {
|
||||
if ((rnh = rt_tables[i]) != NULL &&
|
||||
(*rnh->rnh_walktree)(rnh, if_rt_walktree, ifp) != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
IFAFREE(ifnet_addrs[ifp->if_index]);
|
||||
ifnet_addrs[ifp->if_index] = NULL;
|
||||
|
||||
TAILQ_REMOVE(&ifnet, ifp, if_list);
|
||||
|
||||
splx(s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Callback for a radix tree walk to delete all references to an
|
||||
* ifnet.
|
||||
*/
|
||||
int
|
||||
if_rt_walktree(rn, v)
|
||||
struct radix_node *rn;
|
||||
void *v;
|
||||
{
|
||||
struct ifnet *ifp;
|
||||
struct rtentry *rt = (struct rtentry *)rn;
|
||||
int error;
|
||||
|
||||
if (rt->rt_ifp == ifp) {
|
||||
/* Delete the entry. */
|
||||
error = rtrequest(RTM_DELETE, rt_key(rt), rt->rt_gateway,
|
||||
rt_mask(rt), rt->rt_flags, NULL);
|
||||
if (error)
|
||||
printf("%s: warning: unable to delete rtentry @ %p, "
|
||||
"error = %d\n", ifp->if_xname, rt, error);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Locate an interface based on a complete address.
|
||||
*/
|
||||
@ -227,19 +482,26 @@ ifa_ifwithaddr(addr)
|
||||
|
||||
#define equal(a1, a2) \
|
||||
(bcmp((caddr_t)(a1), (caddr_t)(a2), ((struct sockaddr *)(a1))->sa_len) == 0)
|
||||
for (ifp = ifnet.tqh_first; ifp != 0; ifp = ifp->if_list.tqe_next)
|
||||
for (ifa = ifp->if_addrlist.tqh_first; ifa != 0; ifa = ifa->ifa_list.tqe_next) {
|
||||
if (ifa->ifa_addr->sa_family != addr->sa_family)
|
||||
|
||||
for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL;
|
||||
ifp = TAILQ_NEXT(ifp, if_list)) {
|
||||
if (ifp->if_output == if_nulloutput)
|
||||
continue;
|
||||
if (equal(addr, ifa->ifa_addr))
|
||||
return (ifa);
|
||||
if ((ifp->if_flags & IFF_BROADCAST) && ifa->ifa_broadaddr &&
|
||||
/* IP6 doesn't have broadcast */
|
||||
ifa->ifa_broadaddr->sa_len != 0 &&
|
||||
equal(ifa->ifa_broadaddr, addr))
|
||||
return (ifa);
|
||||
for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL;
|
||||
ifa = TAILQ_NEXT(ifa, ifa_list)) {
|
||||
if (ifa->ifa_addr->sa_family != addr->sa_family)
|
||||
continue;
|
||||
if (equal(addr, ifa->ifa_addr))
|
||||
return (ifa);
|
||||
if ((ifp->if_flags & IFF_BROADCAST) &&
|
||||
ifa->ifa_broadaddr &&
|
||||
/* IP6 doesn't have broadcast */
|
||||
ifa->ifa_broadaddr->sa_len != 0 &&
|
||||
equal(ifa->ifa_broadaddr, addr))
|
||||
return (ifa);
|
||||
}
|
||||
}
|
||||
return ((struct ifaddr *)0);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -253,16 +515,23 @@ ifa_ifwithdstaddr(addr)
|
||||
register struct ifnet *ifp;
|
||||
register struct ifaddr *ifa;
|
||||
|
||||
for (ifp = ifnet.tqh_first; ifp != 0; ifp = ifp->if_list.tqe_next)
|
||||
if (ifp->if_flags & IFF_POINTOPOINT)
|
||||
for (ifa = ifp->if_addrlist.tqh_first; ifa != 0; ifa = ifa->ifa_list.tqe_next) {
|
||||
if (ifa->ifa_addr->sa_family != addr->sa_family ||
|
||||
ifa->ifa_dstaddr == NULL)
|
||||
continue;
|
||||
if (equal(addr, ifa->ifa_dstaddr))
|
||||
return (ifa);
|
||||
for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL;
|
||||
ifp = TAILQ_NEXT(ifp, if_list)) {
|
||||
if (ifp->if_output == if_nulloutput)
|
||||
continue;
|
||||
if (ifp->if_flags & IFF_POINTOPOINT) {
|
||||
for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL;
|
||||
ifa = TAILQ_NEXT(ifa, ifa_list)) {
|
||||
if (ifa->ifa_addr->sa_family !=
|
||||
addr->sa_family ||
|
||||
ifa->ifa_dstaddr == NULL)
|
||||
continue;
|
||||
if (equal(addr, ifa->ifa_dstaddr))
|
||||
return (ifa);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ((struct ifaddr *)0);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -275,49 +544,61 @@ ifa_ifwithnet(addr)
|
||||
{
|
||||
register struct ifnet *ifp;
|
||||
register struct ifaddr *ifa;
|
||||
register struct sockaddr_dl *sdl;
|
||||
struct ifaddr *ifa_maybe = 0;
|
||||
u_int af = addr->sa_family;
|
||||
char *addr_data = addr->sa_data, *cplim;
|
||||
|
||||
if (af == AF_LINK) {
|
||||
register struct sockaddr_dl *sdl = (struct sockaddr_dl *)addr;
|
||||
if (sdl->sdl_index && sdl->sdl_index <= if_index)
|
||||
return (ifnet_addrs[sdl->sdl_index]);
|
||||
sdl = (struct sockaddr_dl *)addr;
|
||||
if (sdl->sdl_index && sdl->sdl_index <= if_index &&
|
||||
ifindex2ifnet[sdl->sdl_index]->if_output != if_nulloutput)
|
||||
return (ifnet_addrs[sdl->sdl_index]);
|
||||
}
|
||||
#ifdef NETATALK
|
||||
if (af == AF_APPLETALK) {
|
||||
for (ifp = ifnet.tqh_first; ifp != 0;
|
||||
ifp = ifp->if_list.tqe_next) {
|
||||
for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL;
|
||||
ifp = TAILQ_NEXT(ifp, if_list)) {
|
||||
if (ifp->if_output == if_nulloutput)
|
||||
continue;
|
||||
ifa = at_ifawithnet((struct sockaddr_at *)addr, ifp);
|
||||
if (ifa)
|
||||
return ifa;
|
||||
return (ifa);
|
||||
}
|
||||
return NULL;
|
||||
return (NULL);
|
||||
}
|
||||
#endif
|
||||
for (ifp = ifnet.tqh_first; ifp != 0; ifp = ifp->if_list.tqe_next)
|
||||
for (ifa = ifp->if_addrlist.tqh_first; ifa != 0; ifa = ifa->ifa_list.tqe_next) {
|
||||
for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL;
|
||||
ifp = TAILQ_NEXT(ifp, if_list)) {
|
||||
if (ifp->if_output == if_nulloutput)
|
||||
continue;
|
||||
for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL;
|
||||
ifa = TAILQ_NEXT(ifa, ifa_list)) {
|
||||
register char *cp, *cp2, *cp3;
|
||||
|
||||
if (ifa->ifa_addr->sa_family != af ||
|
||||
ifa->ifa_netmask == 0)
|
||||
next: continue;
|
||||
next: continue;
|
||||
cp = addr_data;
|
||||
cp2 = ifa->ifa_addr->sa_data;
|
||||
cp3 = ifa->ifa_netmask->sa_data;
|
||||
cplim = (char *)ifa->ifa_netmask +
|
||||
ifa->ifa_netmask->sa_len;
|
||||
while (cp3 < cplim)
|
||||
if ((*cp++ ^ *cp2++) & *cp3++)
|
||||
/* want to continue for() loop */
|
||||
ifa->ifa_netmask->sa_len;
|
||||
while (cp3 < cplim) {
|
||||
if ((*cp++ ^ *cp2++) & *cp3++) {
|
||||
/* want to continue for() loop */
|
||||
goto next;
|
||||
}
|
||||
}
|
||||
if (ifa_maybe == 0 ||
|
||||
rn_refines((caddr_t)ifa->ifa_netmask,
|
||||
(caddr_t)ifa_maybe->ifa_netmask))
|
||||
ifa_maybe = ifa;
|
||||
}
|
||||
}
|
||||
return (ifa_maybe);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the interface of the addresss.
|
||||
*/
|
||||
@ -327,8 +608,8 @@ ifa_ifwithladdr(addr)
|
||||
{
|
||||
struct ifaddr *ia;
|
||||
|
||||
if ((ia = ifa_ifwithaddr(addr)) || (ia = ifa_ifwithdstaddr(addr))
|
||||
|| (ia = ifa_ifwithnet(addr)))
|
||||
if ((ia = ifa_ifwithaddr(addr)) || (ia = ifa_ifwithdstaddr(addr)) ||
|
||||
(ia = ifa_ifwithnet(addr)))
|
||||
return (ia);
|
||||
return (NULL);
|
||||
}
|
||||
@ -343,11 +624,17 @@ ifa_ifwithaf(af)
|
||||
register struct ifnet *ifp;
|
||||
register struct ifaddr *ifa;
|
||||
|
||||
for (ifp = ifnet.tqh_first; ifp != 0; ifp = ifp->if_list.tqe_next)
|
||||
for (ifa = ifp->if_addrlist.tqh_first; ifa != 0; ifa = ifa->ifa_list.tqe_next)
|
||||
for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL;
|
||||
ifp = TAILQ_NEXT(ifp, if_list)) {
|
||||
if (ifp->if_output == if_nulloutput)
|
||||
continue;
|
||||
for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL;
|
||||
ifa = TAILQ_NEXT(ifa, ifa_list)) {
|
||||
if (ifa->ifa_addr->sa_family == af)
|
||||
return (ifa);
|
||||
return ((struct ifaddr *)0);
|
||||
}
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -365,15 +652,21 @@ ifaof_ifpforaddr(addr, ifp)
|
||||
struct ifaddr *ifa_maybe = 0;
|
||||
u_int af = addr->sa_family;
|
||||
|
||||
if (ifp->if_output == if_nulloutput)
|
||||
return (NULL);
|
||||
|
||||
if (af >= AF_MAX)
|
||||
return (0);
|
||||
for (ifa = ifp->if_addrlist.tqh_first; ifa != 0; ifa = ifa->ifa_list.tqe_next) {
|
||||
return (NULL);
|
||||
|
||||
for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL;
|
||||
ifa = TAILQ_NEXT(ifa, ifa_list)) {
|
||||
if (ifa->ifa_addr->sa_family != af)
|
||||
continue;
|
||||
ifa_maybe = ifa;
|
||||
if (ifa->ifa_netmask == 0) {
|
||||
if (equal(addr, ifa->ifa_addr) ||
|
||||
(ifa->ifa_dstaddr && equal(addr, ifa->ifa_dstaddr)))
|
||||
(ifa->ifa_dstaddr &&
|
||||
equal(addr, ifa->ifa_dstaddr)))
|
||||
return (ifa);
|
||||
continue;
|
||||
}
|
||||
@ -381,17 +674,16 @@ ifaof_ifpforaddr(addr, ifp)
|
||||
cp2 = ifa->ifa_addr->sa_data;
|
||||
cp3 = ifa->ifa_netmask->sa_data;
|
||||
cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask;
|
||||
for (; cp3 < cplim; cp3++)
|
||||
for (; cp3 < cplim; cp3++) {
|
||||
if ((*cp++ ^ *cp2++) & *cp3)
|
||||
break;
|
||||
}
|
||||
if (cp3 == cplim)
|
||||
return (ifa);
|
||||
}
|
||||
return (ifa_maybe);
|
||||
}
|
||||
|
||||
#include <net/route.h>
|
||||
|
||||
/*
|
||||
* Default action when installing a route with a Link Level gateway.
|
||||
* Lookup an appropriate real ifa to point to.
|
||||
@ -413,7 +705,7 @@ link_rtrequest(cmd, rt, sa)
|
||||
if ((ifa = ifaof_ifpforaddr(dst, ifp)) != NULL) {
|
||||
IFAFREE(rt->rt_ifa);
|
||||
rt->rt_ifa = ifa;
|
||||
ifa->ifa_refcnt++;
|
||||
IFAREF(ifa);
|
||||
if (ifa->ifa_rtrequest && ifa->ifa_rtrequest != link_rtrequest)
|
||||
ifa->ifa_rtrequest(cmd, rt, sa);
|
||||
}
|
||||
@ -431,7 +723,8 @@ if_down(ifp)
|
||||
register struct ifaddr *ifa;
|
||||
|
||||
ifp->if_flags &= ~IFF_UP;
|
||||
for (ifa = ifp->if_addrlist.tqh_first; ifa != 0; ifa = ifa->ifa_list.tqe_next)
|
||||
for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL;
|
||||
ifa = TAILQ_NEXT(ifa, ifa_list))
|
||||
pfctlinput(PRC_IFDOWN, ifa->ifa_addr);
|
||||
if_qflush(&ifp->if_snd);
|
||||
rt_ifmsg(ifp);
|
||||
@ -453,8 +746,8 @@ if_up(ifp)
|
||||
ifp->if_flags |= IFF_UP;
|
||||
#ifdef notyet
|
||||
/* this has no effect on IP, and will kill all ISO connections XXX */
|
||||
for (ifa = ifp->if_addrlist.tqh_first; ifa != 0;
|
||||
ifa = ifa->ifa_list.tqe_next)
|
||||
for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL;
|
||||
ifa = TAILQ_NEXT(ifa, ifa_list))
|
||||
pfctlinput(PRC_IFUP, ifa->ifa_addr);
|
||||
#endif
|
||||
rt_ifmsg(ifp);
|
||||
@ -494,7 +787,8 @@ if_slowtimo(arg)
|
||||
register struct ifnet *ifp;
|
||||
int s = splimp();
|
||||
|
||||
for (ifp = ifnet.tqh_first; ifp != 0; ifp = ifp->if_list.tqe_next) {
|
||||
for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL;
|
||||
ifp = TAILQ_NEXT(ifp, if_list)) {
|
||||
if (ifp->if_timer == 0 || --ifp->if_timer)
|
||||
continue;
|
||||
if (ifp->if_watchdog)
|
||||
@ -514,10 +808,13 @@ ifunit(name)
|
||||
{
|
||||
register struct ifnet *ifp;
|
||||
|
||||
for (ifp = ifnet.tqh_first; ifp != 0; ifp = ifp->if_list.tqe_next)
|
||||
if (strcmp(ifp->if_xname, name) == 0)
|
||||
for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL;
|
||||
ifp = TAILQ_NEXT(ifp, if_list)) {
|
||||
if (ifp->if_output == if_nulloutput)
|
||||
continue;
|
||||
if (strcmp(ifp->if_xname, name) == 0)
|
||||
return (ifp);
|
||||
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
@ -533,9 +830,9 @@ if_withname(sa)
|
||||
char ifname[IFNAMSIZ+1];
|
||||
struct sockaddr_dl *sdl = (struct sockaddr_dl *)sa;
|
||||
|
||||
if ( (sa->sa_family != AF_LINK) || (sdl->sdl_nlen == 0) ||
|
||||
(sdl->sdl_nlen > IFNAMSIZ) )
|
||||
return NULL;
|
||||
if ((sa->sa_family != AF_LINK) || (sdl->sdl_nlen == 0) ||
|
||||
(sdl->sdl_nlen > IFNAMSIZ))
|
||||
return (NULL);
|
||||
|
||||
/*
|
||||
* ifunit wants a null-terminated name. It may not be null-terminated
|
||||
|
101
sys/net/if.h
101
sys/net/if.h
@ -1,4 +1,40 @@
|
||||
/* $NetBSD: if.h,v 1.43 1999/12/13 15:17:19 itojun Exp $ */
|
||||
/* $NetBSD: if.h,v 1.44 2000/02/01 22:52:05 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by William Studnemund and Jason R. Thorpe.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* 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
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1989, 1993
|
||||
@ -158,7 +194,10 @@ struct ifnet { /* and the entries */
|
||||
short if_flags; /* up/down, broadcast, etc. */
|
||||
short if__pad1; /* be nice to m68k ports */
|
||||
struct if_data if_data; /* statistics and other data about if */
|
||||
/* procedure handles */
|
||||
/*
|
||||
* Procedure handles. If you add more of these, don't forget the
|
||||
* corresponding NULL stub in if.c.
|
||||
*/
|
||||
int (*if_output) /* output routine (enqueue) */
|
||||
__P((struct ifnet *, struct mbuf *, struct sockaddr *,
|
||||
struct rtentry *));
|
||||
@ -438,11 +477,43 @@ struct if_laddrreq {
|
||||
#endif /* !_XOPEN_SOURCE */
|
||||
|
||||
#ifdef _KERNEL
|
||||
#define IFAFREE(ifa) \
|
||||
if ((ifa)->ifa_refcnt <= 0) \
|
||||
ifafree(ifa); \
|
||||
else \
|
||||
(ifa)->ifa_refcnt--;
|
||||
#ifdef IFAREF_DEBUG
|
||||
#define IFAREF(ifa) \
|
||||
do { \
|
||||
printf("IFAREF: %s:%d %p -> %d\n", __FILE__, __LINE__, \
|
||||
(ifa), ++(ifa)->ifa_refcnt); \
|
||||
} while (0)
|
||||
|
||||
#define IFAFREE(ifa) \
|
||||
do { \
|
||||
if ((ifa)->ifa_refcnt <= 0) \
|
||||
panic("%s:%d: %p ifa_refcnt <= 0", __FILE__, \
|
||||
__LINE__, (ifa)); \
|
||||
printf("IFAFREE: %s:%d %p -> %d\n", __FILE__, __LINE__, \
|
||||
(ifa), --(ifa)->ifa_refcnt); \
|
||||
if ((ifa)->ifa_refcnt == 0) \
|
||||
ifafree(ifa); \
|
||||
} while (0)
|
||||
#else
|
||||
#define IFAREF(ifa) (ifa)->ifa_refcnt++
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
#define IFAFREE(ifa) \
|
||||
do { \
|
||||
if ((ifa)->ifa_refcnt <= 0) \
|
||||
panic("%s:%d: %p ifa_refcnt <= 0", __FILE__, \
|
||||
__LINE__, (ifa)); \
|
||||
if (--(ifa)->ifa_refcnt == 0) \
|
||||
ifafree(ifa); \
|
||||
} while (0)
|
||||
#else
|
||||
#define IFAFREE(ifa) \
|
||||
do { \
|
||||
if (--(ifa)->ifa_refcnt == 0) \
|
||||
ifafree(ifa); \
|
||||
} while (0)
|
||||
#endif /* DIAGNOSTIC */
|
||||
#endif /* IFAREF_DEBUG */
|
||||
|
||||
struct ifnet_head ifnet;
|
||||
struct ifnet **ifindex2ifnet;
|
||||
@ -452,9 +523,12 @@ struct ifnet loif[];
|
||||
int if_index;
|
||||
|
||||
void ether_ifattach __P((struct ifnet *, const u_int8_t *));
|
||||
void ether_ifdetach __P((struct ifnet *));
|
||||
char *ether_sprintf __P((const u_char *));
|
||||
|
||||
void if_attach __P((struct ifnet *));
|
||||
void if_deactivate __P((struct ifnet *));
|
||||
void if_detach __P((struct ifnet *));
|
||||
void if_down __P((struct ifnet *));
|
||||
void if_qflush __P((struct ifqueue *));
|
||||
void if_slowtimo __P((void *));
|
||||
@ -482,6 +556,19 @@ void loopattach __P((int));
|
||||
int looutput __P((struct ifnet *,
|
||||
struct mbuf *, struct sockaddr *, struct rtentry *));
|
||||
void lortrequest __P((int, struct rtentry *, struct sockaddr *));
|
||||
|
||||
/*
|
||||
* These are exported because they're an easy way to tell if
|
||||
* an interface is going away without having to burn a flag.
|
||||
*/
|
||||
int if_nulloutput __P((struct ifnet *, struct mbuf *,
|
||||
struct sockaddr *, struct rtentry *));
|
||||
void if_nullinput __P((struct ifnet *, struct mbuf *));
|
||||
void if_nullstart __P((struct ifnet *));
|
||||
int if_nullioctl __P((struct ifnet *, u_long, caddr_t));
|
||||
int if_nullreset __P((struct ifnet *));
|
||||
void if_nullwatchdog __P((struct ifnet *));
|
||||
void if_nulldrain __P((struct ifnet *));
|
||||
#else
|
||||
struct if_nameindex {
|
||||
unsigned int if_index; /* 1, 2, ... */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: if_ethersubr.c,v 1.51 1999/12/13 15:17:19 itojun Exp $ */
|
||||
/* $NetBSD: if_ethersubr.c,v 1.52 2000/02/01 22:52:05 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
@ -783,6 +783,14 @@ ether_ifattach(ifp, lla)
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
ether_ifdetach(ifp)
|
||||
struct ifnet *ifp;
|
||||
{
|
||||
|
||||
/* Nothing. */
|
||||
}
|
||||
|
||||
#ifdef INET
|
||||
u_char ether_ipmulticast_min[6] = { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 };
|
||||
u_char ether_ipmulticast_max[6] = { 0x01, 0x00, 0x5e, 0x7f, 0xff, 0xff };
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: route.c,v 1.29 1999/10/09 18:55:30 sommerfeld Exp $ */
|
||||
/* $NetBSD: route.c,v 1.30 2000/02/01 22:52:05 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
@ -238,12 +238,15 @@ void
|
||||
ifafree(ifa)
|
||||
register struct ifaddr *ifa;
|
||||
{
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
if (ifa == NULL)
|
||||
panic("ifafree");
|
||||
if (ifa->ifa_refcnt == 0)
|
||||
free(ifa, M_IFADDR);
|
||||
else
|
||||
ifa->ifa_refcnt--;
|
||||
panic("ifafree: null ifa");
|
||||
if (ifa->ifa_refcnt != 0)
|
||||
panic("ifafree: ifa_refcnt != 0 (%d)", ifa->ifa_refcnt);
|
||||
#endif
|
||||
printf("ifafree: freeing ifaddr %p\n", ifa);
|
||||
free(ifa, M_IFADDR);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -486,7 +489,7 @@ rtrequest(req, dst, gateway, netmask, flags, ret_nrt)
|
||||
pool_put(&rtentry_pool, rt);
|
||||
senderr(EEXIST);
|
||||
}
|
||||
ifa->ifa_refcnt++;
|
||||
IFAREF(ifa);
|
||||
rt->rt_ifa = ifa;
|
||||
rt->rt_ifp = ifa->ifa_ifp;
|
||||
if (req == RTM_RESOLVE) {
|
||||
@ -627,7 +630,7 @@ rtinit(ifa, cmd, flags)
|
||||
rt->rt_ifa = ifa;
|
||||
rt->rt_ifp = ifa->ifa_ifp;
|
||||
rt->rt_rmx.rmx_mtu = ifa->ifa_ifp->if_mtu; /*XXX*/
|
||||
ifa->ifa_refcnt++;
|
||||
IFAREF(ifa);
|
||||
if (ifa->ifa_rtrequest)
|
||||
ifa->ifa_rtrequest(RTM_ADD, rt, SA(0));
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: rtsock.c,v 1.32 1999/11/19 10:41:42 bouyer Exp $ */
|
||||
/* $NetBSD: rtsock.c,v 1.33 2000/02/01 22:52:05 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
@ -466,32 +466,31 @@ rt_setif(rt, Ifpaddr, Ifaaddr, Gate)
|
||||
(ifp = ifa->ifa_ifp) && (Ifaaddr || Gate))
|
||||
ifa = ifaof_ifpforaddr(Ifaaddr ? Ifaaddr : Gate,
|
||||
ifp);
|
||||
else if (Ifpaddr && (ifp = if_withname(Ifpaddr)) ) {
|
||||
else if (Ifpaddr && (ifp = if_withname(Ifpaddr))) {
|
||||
ifa = Gate ? ifaof_ifpforaddr(Gate, ifp) :
|
||||
TAILQ_FIRST(&ifp->if_addrlist);
|
||||
}
|
||||
else if ((Ifaaddr && (ifa = ifa_ifwithaddr(Ifaaddr))) ||
|
||||
} else if ((Ifaaddr && (ifa = ifa_ifwithaddr(Ifaaddr))) ||
|
||||
(Gate && (ifa = ifa_ifwithroute(rt->rt_flags,
|
||||
rt_key(rt), Gate))))
|
||||
ifp = ifa->ifa_ifp;
|
||||
if (ifa) {
|
||||
register struct ifaddr *oifa = rt->rt_ifa;
|
||||
if (oifa != ifa) {
|
||||
if (oifa && oifa->ifa_rtrequest)
|
||||
oifa->ifa_rtrequest(RTM_DELETE,
|
||||
rt, Gate);
|
||||
IFAFREE(rt->rt_ifa);
|
||||
rt->rt_ifa = ifa;
|
||||
ifa->ifa_refcnt++;
|
||||
rt->rt_ifp = ifp;
|
||||
rt->rt_rmx.rmx_mtu = ifp->if_mtu;
|
||||
if (rt->rt_ifa && rt->rt_ifa->ifa_rtrequest)
|
||||
rt->rt_ifa->ifa_rtrequest(RTM_ADD, rt, Gate);
|
||||
} else
|
||||
|
||||
if (oifa == ifa)
|
||||
goto call_ifareq;
|
||||
|
||||
if (oifa && oifa->ifa_rtrequest)
|
||||
oifa->ifa_rtrequest(RTM_DELETE, rt, Gate);
|
||||
IFAFREE(rt->rt_ifa);
|
||||
rt->rt_ifa = ifa;
|
||||
IFAREF(rt->rt_ifa);
|
||||
rt->rt_ifp = ifp;
|
||||
rt->rt_rmx.rmx_mtu = ifp->if_mtu;
|
||||
if (rt->rt_ifa && rt->rt_ifa->ifa_rtrequest)
|
||||
rt->rt_ifa->ifa_rtrequest(RTM_ADD, rt, Gate);
|
||||
return;
|
||||
}
|
||||
call_ifareq:
|
||||
call_ifareq:
|
||||
/* XXX: to reset gateway to correct value, at RTM_CHANGE */
|
||||
if (rt->rt_ifa && rt->rt_ifa->ifa_rtrequest)
|
||||
rt->rt_ifa->ifa_rtrequest(RTM_ADD, rt, Gate);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: at_control.c,v 1.1 1997/04/02 21:31:04 christos Exp $ */
|
||||
/* $NetBSD: at_control.c,v 1.2 2000/02/01 22:52:06 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1990,1994 Regents of The University of Michigan.
|
||||
@ -190,6 +190,7 @@ at_control(cmd, data, ifp, p)
|
||||
} else {
|
||||
TAILQ_INSERT_TAIL(&at_ifaddr, aa, aa_list);
|
||||
}
|
||||
IFAREF(&aa->aa_ifa);
|
||||
|
||||
/*
|
||||
* Find the end of the interface's addresses
|
||||
@ -197,6 +198,7 @@ at_control(cmd, data, ifp, p)
|
||||
*/
|
||||
TAILQ_INSERT_TAIL(&ifp->if_addrlist,
|
||||
(struct ifaddr *) aa, ifa_list);
|
||||
IFAREF(&aa->aa_ifa);
|
||||
|
||||
/*
|
||||
* As the at_ifaddr contains the actual sockaddrs,
|
||||
@ -295,17 +297,7 @@ at_control(cmd, data, ifp, p)
|
||||
(struct sockaddr_at *) &ifr->ifr_addr));
|
||||
|
||||
case SIOCDIFADDR:
|
||||
/*
|
||||
* scrub all routes.. didn't we just DO this? XXX yes, del it
|
||||
*/
|
||||
at_scrub(ifp, aa);
|
||||
|
||||
/*
|
||||
* remove the ifaddr from the interface
|
||||
*/
|
||||
TAILQ_REMOVE(&ifp->if_addrlist, (struct ifaddr *) aa, ifa_list);
|
||||
TAILQ_REMOVE(&at_ifaddr, aa, aa_list);
|
||||
IFAFREE((struct ifaddr *) aa);
|
||||
at_purgeaddr((struct ifaddr *) aa, ifp);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -316,6 +308,28 @@ at_control(cmd, data, ifp, p)
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
at_purgeaddr(ifa, ifp)
|
||||
struct ifaddr *ifa;
|
||||
struct ifnet *ifp;
|
||||
{
|
||||
struct at_ifaddr *aa = (void *) ifa;
|
||||
|
||||
/*
|
||||
* scrub all routes.. didn't we just DO this? XXX yes, del it
|
||||
* XXX above XXX not necessarily true anymore
|
||||
*/
|
||||
at_scrub(ifp, aa);
|
||||
|
||||
/*
|
||||
* remove the ifaddr from the interface
|
||||
*/
|
||||
TAILQ_REMOVE(&ifp->if_addrlist, (struct ifaddr *) aa, ifa_list);
|
||||
IFAFREE(&aa->aa_ifa);
|
||||
TAILQ_REMOVE(&at_ifaddr, aa, aa_list);
|
||||
IFAFREE(&aa->aa_ifa);
|
||||
}
|
||||
|
||||
/*
|
||||
* Given an interface and an at_ifaddr (supposedly on that interface) remove
|
||||
* any routes that depend on this. Why ifp is needed I'm not sure, as
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: at_extern.h,v 1.3 1997/04/03 18:38:23 christos Exp $ */
|
||||
/* $NetBSD: at_extern.h,v 1.4 2000/02/01 22:52:06 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1990,1994 Regents of The University of Michigan.
|
||||
@ -33,6 +33,7 @@ struct ifnet;
|
||||
struct mbuf;
|
||||
struct sockaddr_at;
|
||||
struct proc;
|
||||
struct ifaddr;
|
||||
struct at_ifaddr;
|
||||
struct route;
|
||||
struct socket;
|
||||
@ -45,6 +46,7 @@ void aarpinput __P((struct ifnet *, struct mbuf *));
|
||||
int at_broadcast __P((struct sockaddr_at *));
|
||||
void aarp_clean __P((void));
|
||||
int at_control __P((u_long, caddr_t, struct ifnet *, struct proc *));
|
||||
void at_purgeaddr __P((struct ifaddr *, struct ifnet *));
|
||||
u_int16_t
|
||||
at_cksum __P((struct mbuf *, int));
|
||||
int ddp_usrreq __P((struct socket *, int, struct mbuf *, struct mbuf *,
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ddp_usrreq.c,v 1.2 1997/04/29 13:44:47 christos Exp $ */
|
||||
/* $NetBSD: ddp_usrreq.c,v 1.3 2000/02/01 22:52:06 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1990,1991 Regents of The University of Michigan.
|
||||
@ -79,6 +79,10 @@ ddp_usrreq(so, req, m, addr, rights, p)
|
||||
return (at_control((long) m, (caddr_t) addr,
|
||||
(struct ifnet *) rights, (struct proc *) p));
|
||||
}
|
||||
if (req == PRU_PURGEADDR) {
|
||||
at_purgeaddr((struct ifaddr *) addr, (struct ifnet *) rights);
|
||||
return (0);
|
||||
}
|
||||
if (rights && rights->m_len) {
|
||||
error = EINVAL;
|
||||
goto release;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: hd_subr.c,v 1.10 1998/09/13 16:21:17 christos Exp $ */
|
||||
/* $NetBSD: hd_subr.c,v 1.11 2000/02/01 22:52:07 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1984 University of British Columbia.
|
||||
@ -106,6 +106,7 @@ hd_ctlinput(prc, addr, ext)
|
||||
return (void *) (ENOBUFS);
|
||||
}
|
||||
hdp->hd_ifp = ifp;
|
||||
IFAREF(ifa);
|
||||
hdp->hd_ifa = ifa;
|
||||
hdp->hd_xcp = xcp;
|
||||
hdp->hd_state = INIT;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: pk_input.c,v 1.13 1998/09/13 16:21:19 christos Exp $ */
|
||||
/* $NetBSD: pk_input.c,v 1.14 2000/02/01 22:52:07 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1984 University of British Columbia.
|
||||
@ -128,6 +128,7 @@ pk_newlink(ia, llnext)
|
||||
pkp->pk_lloutput = pp->pr_output;
|
||||
pkp->pk_llctlinput = pp->pr_ctlinput;
|
||||
pkp->pk_xcp = xcp;
|
||||
IFAREF(&ia->ia_ifa);
|
||||
pkp->pk_ia = ia;
|
||||
pkp->pk_state = DTE_WAITING;
|
||||
pkp->pk_llnext = llnext;
|
||||
@ -204,6 +205,9 @@ pk_dellink(pkp)
|
||||
(struct sockaddr *)pkp->pk_xcp,
|
||||
&ctlinfo);
|
||||
}
|
||||
if (pkp->pk_ia != NULL)
|
||||
IFAFREE(&pkp->pk_ia->ia_ifa);
|
||||
|
||||
free((caddr_t) pkp->pk_chan, M_IFADDR);
|
||||
free((caddr_t) pkp, M_PCB);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: pk_usrreq.c,v 1.16 1998/09/13 16:21:19 christos Exp $ */
|
||||
/* $NetBSD: pk_usrreq.c,v 1.17 2000/02/01 22:52:07 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1984 University of British Columbia.
|
||||
@ -387,6 +387,7 @@ pk_control(so, cmd, data, ifp, p)
|
||||
TAILQ_INSERT_TAIL(&ifp->if_addrlist, &ia->ia_ifa,
|
||||
ifa_list);
|
||||
ifa = &ia->ia_ifa;
|
||||
IFAREF(ifa);
|
||||
ifa->ifa_netmask = (struct sockaddr *) & pk_sockmask;
|
||||
ifa->ifa_addr = (struct sockaddr *) & ia->ia_xc.xc_addr;
|
||||
ifa->ifa_dstaddr = (struct sockaddr *) & ia->ia_dstaddr; /* XXX */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: in.c,v 1.49 1999/12/12 15:57:07 itojun Exp $ */
|
||||
/* $NetBSD: in.c,v 1.50 2000/02/01 22:52:07 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
@ -383,8 +383,10 @@ in_control(so, cmd, data, ifp, p)
|
||||
return (ENOBUFS);
|
||||
bzero((caddr_t)ia, sizeof *ia);
|
||||
TAILQ_INSERT_TAIL(&in_ifaddr, ia, ia_list);
|
||||
TAILQ_INSERT_TAIL(&ifp->if_addrlist, (struct ifaddr *)ia,
|
||||
IFAREF(&ia->ia_ifa);
|
||||
TAILQ_INSERT_TAIL(&ifp->if_addrlist, &ia->ia_ifa,
|
||||
ifa_list);
|
||||
IFAREF(&ia->ia_ifa);
|
||||
ia->ia_ifa.ifa_addr = sintosa(&ia->ia_addr);
|
||||
ia->ia_ifa.ifa_dstaddr = sintosa(&ia->ia_dstaddr);
|
||||
ia->ia_ifa.ifa_netmask = sintosa(&ia->ia_sockmask);
|
||||
@ -512,12 +514,7 @@ in_control(so, cmd, data, ifp, p)
|
||||
return 0;
|
||||
|
||||
case SIOCDIFADDR:
|
||||
in_ifscrub(ifp, ia);
|
||||
LIST_REMOVE(ia, ia_hash);
|
||||
TAILQ_REMOVE(&ifp->if_addrlist, (struct ifaddr *)ia, ifa_list);
|
||||
TAILQ_REMOVE(&in_ifaddr, ia, ia_list);
|
||||
IFAFREE((&ia->ia_ifa));
|
||||
in_setmaxmtu();
|
||||
in_purgeaddr(&ia->ia_ifa, ifp);
|
||||
break;
|
||||
|
||||
#ifdef MROUTING
|
||||
@ -536,6 +533,22 @@ in_control(so, cmd, data, ifp, p)
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
in_purgeaddr(ifa, ifp)
|
||||
struct ifaddr *ifa;
|
||||
struct ifnet *ifp;
|
||||
{
|
||||
struct in_ifaddr *ia = (void *) ifa;
|
||||
|
||||
in_ifscrub(ifp, ia);
|
||||
LIST_REMOVE(ia, ia_hash);
|
||||
TAILQ_REMOVE(&ifp->if_addrlist, &ia->ia_ifa, ifa_list);
|
||||
IFAFREE(&ia->ia_ifa);
|
||||
TAILQ_REMOVE(&in_ifaddr, ia, ia_list);
|
||||
IFAFREE(&ia->ia_ifa);
|
||||
in_setmaxmtu();
|
||||
}
|
||||
|
||||
/*
|
||||
* SIOC[GAD]LIFADDR.
|
||||
* SIOCGLIFADDR: get first address. (???)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: in_var.h,v 1.35 1999/07/01 08:12:50 itojun Exp $ */
|
||||
/* $NetBSD: in_var.h,v 1.36 2000/02/01 22:52:08 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
@ -301,6 +301,8 @@ struct in_multistep {
|
||||
IN_NEXT_MULTI((step), (inm)); \
|
||||
}
|
||||
|
||||
struct ifaddr;
|
||||
|
||||
int in_ifinit __P((struct ifnet *,
|
||||
struct in_ifaddr *, struct sockaddr_in *, int));
|
||||
struct in_multi *in_addmulti __P((struct in_addr *, struct ifnet *));
|
||||
@ -310,6 +312,7 @@ void in_setmaxmtu __P((void));
|
||||
const char *in_fmtaddr __P((struct in_addr));
|
||||
int in_control __P((struct socket *, u_long, caddr_t, struct ifnet *,
|
||||
struct proc *));
|
||||
void in_purgeaddr __P((struct ifaddr *, struct ifnet *));
|
||||
void ip_input __P((struct mbuf *));
|
||||
int ipflow_fastforward __P((struct mbuf *));
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: raw_ip.c,v 1.48 2000/01/31 14:18:55 itojun Exp $ */
|
||||
/* $NetBSD: raw_ip.c,v 1.49 2000/02/01 22:52:08 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
@ -431,6 +431,11 @@ rip_usrreq(so, req, m, nam, control, p)
|
||||
return (in_control(so, (long)m, (caddr_t)nam,
|
||||
(struct ifnet *)control, p));
|
||||
|
||||
if (req == PRU_PURGEADDR) {
|
||||
in_purgeaddr((struct ifaddr *)nam, (struct ifnet *)control);
|
||||
return (0);
|
||||
}
|
||||
|
||||
s = splsoftnet();
|
||||
inp = sotoinpcb(so);
|
||||
#ifdef DIAGNOSTIC
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: tcp_usrreq.c,v 1.44 2000/01/31 14:18:58 itojun Exp $ */
|
||||
/* $NetBSD: tcp_usrreq.c,v 1.45 2000/02/01 22:52:10 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
@ -200,6 +200,11 @@ tcp_usrreq(so, req, m, nam, control, p)
|
||||
}
|
||||
}
|
||||
|
||||
if (req == PRU_PURGEADDR) {
|
||||
in_purgeaddr((struct ifaddr *)nam, (struct ifnet *)control);
|
||||
return (0);
|
||||
}
|
||||
|
||||
s = splsoftnet();
|
||||
switch (family) {
|
||||
case PF_INET:
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: udp_usrreq.c,v 1.58 2000/01/31 14:18:58 itojun Exp $ */
|
||||
/* $NetBSD: udp_usrreq.c,v 1.59 2000/02/01 22:52:10 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
@ -1309,6 +1309,11 @@ udp_usrreq(so, req, m, nam, control, p)
|
||||
return (in_control(so, (long)m, (caddr_t)nam,
|
||||
(struct ifnet *)control, p));
|
||||
|
||||
if (req == PRU_PURGEADDR) {
|
||||
in_purgeaddr((struct ifaddr *)nam, (struct ifnet *)control);
|
||||
return (0);
|
||||
}
|
||||
|
||||
s = splsoftnet();
|
||||
inp = sotoinpcb(so);
|
||||
#ifdef DIAGNOSTIC
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: in6.c,v 1.9 2000/01/06 15:46:09 itojun Exp $ */
|
||||
/* $NetBSD: in6.c,v 1.10 2000/02/01 22:52:10 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
@ -210,8 +210,8 @@ in6_ifloop_request(int cmd, struct ifaddr *ifa)
|
||||
* loopback address.
|
||||
*/
|
||||
if (cmd == RTM_ADD && nrt && ifa != nrt->rt_ifa) {
|
||||
nrt->rt_ifa->ifa_refcnt--;
|
||||
ifa->ifa_refcnt++;
|
||||
IFAFREE(nrt->rt_ifa);
|
||||
IFAREF(ifa);
|
||||
nrt->rt_ifa = ifa;
|
||||
}
|
||||
if (nrt)
|
||||
@ -559,8 +559,12 @@ in6_control(so, cmd, data, ifp, p)
|
||||
oia->ia_next = ia;
|
||||
} else
|
||||
in6_ifaddr = ia;
|
||||
IFAREF(&ia->ia_ifa);
|
||||
|
||||
TAILQ_INSERT_TAIL(&ifp->if_addrlist,
|
||||
(struct ifaddr *)ia, ifa_list);
|
||||
IFAREF(&ia->ia_ifa);
|
||||
|
||||
if ((ifp->if_flags & IFF_LOOPBACK) == 0)
|
||||
in6_interfaces++; /*XXX*/
|
||||
}
|
||||
@ -862,58 +866,7 @@ in6_control(so, cmd, data, ifp, p)
|
||||
return(error);
|
||||
|
||||
case SIOCDIFADDR_IN6:
|
||||
in6_ifscrub(ifp, ia);
|
||||
|
||||
if (ifp->if_flags & IFF_MULTICAST) {
|
||||
/*
|
||||
* delete solicited multicast addr for deleting host id
|
||||
*/
|
||||
struct in6_multi *in6m;
|
||||
struct in6_addr llsol;
|
||||
bzero(&llsol, sizeof(struct in6_addr));
|
||||
llsol.s6_addr16[0] = htons(0xff02);
|
||||
llsol.s6_addr16[1] = htons(ifp->if_index);
|
||||
llsol.s6_addr32[1] = 0;
|
||||
llsol.s6_addr32[2] = htonl(1);
|
||||
llsol.s6_addr32[3] =
|
||||
ia->ia_addr.sin6_addr.s6_addr32[3];
|
||||
llsol.s6_addr8[12] = 0xff;
|
||||
|
||||
IN6_LOOKUP_MULTI(llsol, ifp, in6m);
|
||||
if (in6m)
|
||||
in6_delmulti(in6m);
|
||||
}
|
||||
/* Leave dstaddr's solicited multicast if necessary. */
|
||||
if (nd6_proxyall)
|
||||
in6_ifremproxy(ia);
|
||||
|
||||
TAILQ_REMOVE(&ifp->if_addrlist, (struct ifaddr *)ia, ifa_list);
|
||||
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");
|
||||
}
|
||||
{
|
||||
int iilen;
|
||||
|
||||
iilen = (sizeof(oia->ia_prefixmask.sin6_addr) << 3) -
|
||||
in6_mask2len(&oia->ia_prefixmask.sin6_addr);
|
||||
in6_prefix_remove_ifid(iilen, oia);
|
||||
}
|
||||
if (oia->ia6_multiaddrs.lh_first == NULL) {
|
||||
IFAFREE(&oia->ia_ifa);
|
||||
break;
|
||||
}
|
||||
else
|
||||
in6_savemkludge(oia);
|
||||
|
||||
IFAFREE((&oia->ia_ifa));
|
||||
in6_purgeaddr(&ia->ia_ifa, ifp);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -924,6 +877,77 @@ in6_control(so, cmd, data, ifp, p)
|
||||
return(0);
|
||||
}
|
||||
|
||||
void
|
||||
in6_purgeaddr(ifa, ifp)
|
||||
struct ifaddr *ifa;
|
||||
struct ifnet *ifp;
|
||||
{
|
||||
struct in6_ifaddr *oia, *ia = (void *) ifa;
|
||||
|
||||
in6_ifscrub(ifp, ia);
|
||||
|
||||
if (ifp->if_flags & IFF_MULTICAST) {
|
||||
/*
|
||||
* delete solicited multicast addr for deleting host id
|
||||
*/
|
||||
struct in6_multi *in6m;
|
||||
struct in6_addr llsol;
|
||||
bzero(&llsol, sizeof(struct in6_addr));
|
||||
llsol.s6_addr16[0] = htons(0xff02);
|
||||
llsol.s6_addr16[1] = htons(ifp->if_index);
|
||||
llsol.s6_addr32[1] = 0;
|
||||
llsol.s6_addr32[2] = htonl(1);
|
||||
llsol.s6_addr32[3] =
|
||||
ia->ia_addr.sin6_addr.s6_addr32[3];
|
||||
llsol.s6_addr8[12] = 0xff;
|
||||
|
||||
IN6_LOOKUP_MULTI(llsol, ifp, in6m);
|
||||
if (in6m)
|
||||
in6_delmulti(in6m);
|
||||
}
|
||||
/* Leave dstaddr's solicited multicast if necessary. */
|
||||
if (nd6_proxyall)
|
||||
in6_ifremproxy(ia);
|
||||
|
||||
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");
|
||||
}
|
||||
{
|
||||
int iilen;
|
||||
|
||||
iilen = (sizeof(oia->ia_prefixmask.sin6_addr) << 3) -
|
||||
in6_mask2len(&oia->ia_prefixmask.sin6_addr);
|
||||
in6_prefix_remove_ifid(iilen, oia);
|
||||
}
|
||||
if (oia->ia6_multiaddrs.lh_first != NULL) {
|
||||
/*
|
||||
* XXX thorpej@netbsd.org -- if the interface is going
|
||||
* XXX away, don't save the multicast entries, delete them!
|
||||
*/
|
||||
if (oia->ia_ifa.ifa_ifp->if_output == if_nulloutput) {
|
||||
struct in6_multi *in6m;
|
||||
|
||||
while ((in6m =
|
||||
LIST_FIRST(&oia->ia6_multiaddrs)) != NULL)
|
||||
in6_delmulti(in6m);
|
||||
} else
|
||||
in6_savemkludge(oia);
|
||||
}
|
||||
|
||||
IFAFREE(&oia->ia_ifa);
|
||||
}
|
||||
|
||||
/*
|
||||
* SIOC[GAD]LIFADDR.
|
||||
* SIOCGLIFADDR: get first address. (???)
|
||||
@ -1279,7 +1303,7 @@ in6_savemkludge(oia)
|
||||
for (in6m = oia->ia6_multiaddrs.lh_first; in6m; in6m = next){
|
||||
next = in6m->in6m_entry.le_next;
|
||||
IFAFREE(&in6m->in6m_ia->ia_ifa);
|
||||
ia->ia_ifa.ifa_refcnt++;
|
||||
IFAREF(&ia->ia_ifa);
|
||||
in6m->in6m_ia = ia;
|
||||
LIST_INSERT_HEAD(&ia->ia6_multiaddrs, in6m, in6m_entry);
|
||||
}
|
||||
@ -1381,7 +1405,7 @@ in6_addmulti(maddr6, ifp, errorp)
|
||||
return(NULL);
|
||||
}
|
||||
in6m->in6m_ia = ia;
|
||||
ia->ia_ifa.ifa_refcnt++; /* gain a reference */
|
||||
IFAREF(&ia->ia_ifa); /* gain a reference */
|
||||
LIST_INSERT_HEAD(&ia->ia6_multiaddrs, in6m, in6m_entry);
|
||||
|
||||
/*
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: in6_ifattach.c,v 1.14 2000/01/06 15:46:09 itojun Exp $ */
|
||||
/* $NetBSD: in6_ifattach.c,v 1.15 2000/02/01 22:52:11 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
@ -339,6 +339,8 @@ in6_ifattach(ifp, type, laddr, noloop)
|
||||
ia->ia_ifa.ifa_netmask = (struct sockaddr *)&ia->ia_prefixmask;
|
||||
ia->ia_ifp = ifp;
|
||||
TAILQ_INSERT_TAIL(&ifp->if_addrlist, (struct ifaddr *)ia, ifa_list);
|
||||
IFAREF((struct ifaddr *)ia);
|
||||
|
||||
/*
|
||||
* Also link into the IPv6 address chain beginning with in6_ifaddr.
|
||||
* kazu opposed it, but itojun & jinmei wanted.
|
||||
@ -349,6 +351,7 @@ in6_ifattach(ifp, type, laddr, noloop)
|
||||
oia->ia_next = ia;
|
||||
} else
|
||||
in6_ifaddr = ia;
|
||||
IFAREF((struct ifaddr *)ia);
|
||||
|
||||
ia->ia_prefixmask.sin6_len = sizeof(struct sockaddr_in6);
|
||||
ia->ia_prefixmask.sin6_family = AF_INET6;
|
||||
@ -435,11 +438,12 @@ in6_ifattach(ifp, type, laddr, noloop)
|
||||
|
||||
/* undo changes */
|
||||
TAILQ_REMOVE(&ifp->if_addrlist, (struct ifaddr *)ia, ifa_list);
|
||||
IFAFREE((struct ifaddr *)ia);
|
||||
if (oia)
|
||||
oia->ia_next = ia->ia_next;
|
||||
else
|
||||
in6_ifaddr = ia->ia_next;
|
||||
free(ia, M_IFADDR);
|
||||
IFAFREE((struct ifaddr *)ia);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: in6_var.h,v 1.6 2000/01/06 15:46:09 itojun Exp $ */
|
||||
/* $NetBSD: in6_var.h,v 1.7 2000/02/01 22:52:11 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
@ -550,6 +550,7 @@ extern int in6_mask2len __P((struct in6_addr *));
|
||||
extern void in6_len2mask __P((struct in6_addr *, int));
|
||||
int in6_control __P((struct socket *,
|
||||
u_long, caddr_t, struct ifnet *, struct proc *));
|
||||
void in6_purgeaddr __P((struct ifaddr *, struct ifnet *));
|
||||
void in6_savemkludge __P((struct in6_ifaddr *));
|
||||
void in6_setmaxmtu __P((void));
|
||||
void in6_restoremkludge __P((struct in6_ifaddr *, struct ifnet *));
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: nd6.c,v 1.13 2000/01/06 15:46:10 itojun Exp $ */
|
||||
/* $NetBSD: nd6.c,v 1.14 2000/02/01 22:52:11 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
@ -1011,8 +1011,8 @@ nd6_rtrequest(req, rt, sa)
|
||||
* of the loopback address.
|
||||
*/
|
||||
if (ifa != rt->rt_ifa) {
|
||||
rt->rt_ifa->ifa_refcnt--;
|
||||
ifa->ifa_refcnt++;
|
||||
IFAFREE(rt->rt_ifa);
|
||||
IFAREF(ifa);
|
||||
rt->rt_ifa = ifa;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: nd6_nbr.c,v 1.12 2000/01/28 07:21:29 itojun Exp $ */
|
||||
/* $NetBSD: nd6_nbr.c,v 1.13 2000/02/01 22:52:11 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
@ -927,7 +927,7 @@ nd6_dad_start(ifa, tick)
|
||||
* (re)initialization.
|
||||
*/
|
||||
dp->dad_ifa = ifa;
|
||||
ifa->ifa_refcnt++; /*just for safety*/
|
||||
IFAREF(ifa); /* just for safety */
|
||||
dp->dad_count = ip6_dad_count;
|
||||
dp->dad_ns_icount = dp->dad_na_icount = 0;
|
||||
dp->dad_ns_ocount = dp->dad_ns_tcount = 0;
|
||||
@ -991,7 +991,7 @@ nd6_dad_timer(ifa)
|
||||
TAILQ_REMOVE(&dadq, (struct dadq *)dp, dad_list);
|
||||
free(dp, M_IP6NDP);
|
||||
dp = NULL;
|
||||
ifa->ifa_refcnt--;
|
||||
IFAFREE(ifa);
|
||||
goto done;
|
||||
}
|
||||
|
||||
@ -1068,7 +1068,7 @@ nd6_dad_timer(ifa)
|
||||
TAILQ_REMOVE(&dadq, (struct dadq *)dp, dad_list);
|
||||
free(dp, M_IP6NDP);
|
||||
dp = NULL;
|
||||
ifa->ifa_refcnt--;
|
||||
IFAFREE(ifa);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1107,7 +1107,7 @@ nd6_dad_duplicated(ifa)
|
||||
TAILQ_REMOVE(&dadq, (struct dadq *)dp, dad_list);
|
||||
free(dp, M_IP6NDP);
|
||||
dp = NULL;
|
||||
ifa->ifa_refcnt--;
|
||||
IFAFREE(ifa);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: nd6_rtr.c,v 1.8 2000/01/06 15:46:11 itojun Exp $ */
|
||||
/* $NetBSD: nd6_rtr.c,v 1.9 2000/02/01 22:52:12 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
@ -430,7 +430,7 @@ defrouter_addreq(new)
|
||||
Free(rt);
|
||||
goto bad;
|
||||
}
|
||||
ifa->ifa_refcnt++;
|
||||
IFAREF(ifa);
|
||||
rt->rt_ifa = ifa;
|
||||
rt->rt_ifp = ifp;
|
||||
rt->rt_rmx.rmx_mtu = ifa->ifa_ifp->if_mtu;
|
||||
@ -1250,11 +1250,13 @@ in6_ifadd(ifp, in6, addr, prefixlen)
|
||||
oia->ia_next = ia;
|
||||
} else
|
||||
in6_ifaddr = ia;
|
||||
IFAREF((struct ifaddr *)ia);
|
||||
|
||||
/* link to if_addrlist */
|
||||
if (ifp->if_addrlist.tqh_first != NULL) {
|
||||
TAILQ_INSERT_TAIL(&ifp->if_addrlist, (struct ifaddr *)ia,
|
||||
ifa_list);
|
||||
IFAREF((struct ifaddr *)ia);
|
||||
}
|
||||
#if 0
|
||||
else {
|
||||
@ -1386,6 +1388,7 @@ in6_ifdel(ifp, in6)
|
||||
}
|
||||
|
||||
TAILQ_REMOVE(&ifp->if_addrlist, (struct ifaddr *)ia, ifa_list);
|
||||
IFAFREE((struct ifaddr *)ia);
|
||||
|
||||
/* lladdr is never deleted */
|
||||
oia = ia;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: raw_ip6.c,v 1.16 2000/01/31 14:19:06 itojun Exp $ */
|
||||
/* $NetBSD: raw_ip6.c,v 1.17 2000/02/01 22:52:12 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
@ -494,6 +494,11 @@ rip6_usrreq(so, req, m, nam, control, p)
|
||||
return (in6_control(so, (u_long)m, (caddr_t)nam,
|
||||
(struct ifnet *)control, p));
|
||||
|
||||
if (req == PRU_PURGEADDR) {
|
||||
in6_purgeaddr((struct ifaddr *)nam, (struct ifnet *)control);
|
||||
return (0);
|
||||
}
|
||||
|
||||
switch (req) {
|
||||
case PRU_ATTACH:
|
||||
if (in6p)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: udp6_usrreq.c,v 1.19 2000/01/31 14:19:07 itojun Exp $ */
|
||||
/* $NetBSD: udp6_usrreq.c,v 1.20 2000/02/01 22:52:12 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
@ -798,6 +798,11 @@ udp6_usrreq(so, req, m, addr6, control, p)
|
||||
return(in6_control(so, (u_long)m, (caddr_t)addr6,
|
||||
(struct ifnet *)control, p));
|
||||
|
||||
if (req == PRU_PURGEADDR) {
|
||||
in6_purgeaddr((struct ifaddr *)addr6, (struct ifnet *)control);
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (in6p == NULL && req != PRU_ATTACH) {
|
||||
error = EINVAL;
|
||||
goto release;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: cltp_usrreq.c,v 1.14 1997/06/24 02:26:09 thorpej Exp $ */
|
||||
/* $NetBSD: cltp_usrreq.c,v 1.15 2000/02/01 22:52:12 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
@ -307,6 +307,11 @@ cltp_usrreq(so, req, m, nam, control, p)
|
||||
return (iso_control(so, (long)m, (caddr_t)nam,
|
||||
(struct ifnet *)control, p));
|
||||
|
||||
if (req == PRU_PURGEADDR) {
|
||||
iso_purgeaddr((struct ifaddr *)nam, (struct ifnet *)control);
|
||||
return (0);
|
||||
}
|
||||
|
||||
s = splsoftnet();
|
||||
isop = sotoisopcb(so);
|
||||
#ifdef DIAGNOSTIC
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: iso.c,v 1.25 1999/07/12 18:15:09 thorpej Exp $ */
|
||||
/* $NetBSD: iso.c,v 1.26 2000/02/01 22:52:12 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993
|
||||
@ -494,8 +494,10 @@ iso_control(so, cmd, data, ifp, p)
|
||||
return (ENOBUFS);
|
||||
bzero((caddr_t)ia, sizeof(*ia));
|
||||
TAILQ_INSERT_TAIL(&iso_ifaddr, ia, ia_list);
|
||||
IFAREF((struct ifaddr *)ia);
|
||||
TAILQ_INSERT_TAIL(&ifp->if_addrlist, (struct ifaddr *)ia,
|
||||
ifa_list);
|
||||
IFAREF((struct ifaddr *)ia);
|
||||
ia->ia_ifa.ifa_addr = sisotosa(&ia->ia_addr);
|
||||
ia->ia_ifa.ifa_dstaddr = sisotosa(&ia->ia_dstaddr);
|
||||
ia->ia_ifa.ifa_netmask = sisotosa(&ia->ia_sockmask);
|
||||
@ -558,10 +560,7 @@ iso_control(so, cmd, data, ifp, p)
|
||||
return (error);
|
||||
|
||||
case SIOCDIFADDR_ISO:
|
||||
iso_ifscrub(ifp, ia);
|
||||
TAILQ_REMOVE(&ifp->if_addrlist, (struct ifaddr *)ia, ifa_list);
|
||||
TAILQ_REMOVE(&iso_ifaddr, ia, ia_list);
|
||||
IFAFREE((&ia->ia_ifa));
|
||||
iso_purgeaddr(&ia->ia_ifa, ifp);
|
||||
break;
|
||||
|
||||
#define cmdbyte(x) (((x) >> 8) & 0xff)
|
||||
@ -575,6 +574,20 @@ iso_control(so, cmd, data, ifp, p)
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
iso_purgeaddr(ifa, ifp)
|
||||
struct ifaddr *ifa;
|
||||
struct ifnet *ifp;
|
||||
{
|
||||
struct iso_ifaddr *ia = (void *) ifa;
|
||||
|
||||
iso_ifscrub(ifp, ia);
|
||||
TAILQ_REMOVE(&ifp->if_addrlist, (struct ifaddr *)ia, ifa_list);
|
||||
IFAFREE(&ia->ia_ifa);
|
||||
TAILQ_REMOVE(&iso_ifaddr, ia, ia_list);
|
||||
IFAFREE((&ia->ia_ifa));
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete any existing route for an interface.
|
||||
*/
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: iso_var.h,v 1.11 1999/04/01 06:51:48 chopps Exp $ */
|
||||
/* $NetBSD: iso_var.h,v 1.12 2000/02/01 22:52:13 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1988, 1991, 1993
|
||||
@ -143,6 +143,7 @@ int iso_hash __P((struct sockaddr_iso *, struct afhash *));
|
||||
int iso_netof __P((struct iso_addr *, caddr_t));
|
||||
int iso_control __P((struct socket *, u_long, caddr_t, struct ifnet *,
|
||||
struct proc *));
|
||||
void iso_purgeaddr __P((struct ifaddr *, struct ifnet *));
|
||||
void iso_ifscrub __P((struct ifnet *, struct iso_ifaddr *));
|
||||
int iso_ifinit __P((struct ifnet *, struct iso_ifaddr *, struct sockaddr_iso *,
|
||||
int ));
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: idp_usrreq.c,v 1.15 1998/07/05 06:49:17 jonathan Exp $ */
|
||||
/* $NetBSD: idp_usrreq.c,v 1.16 2000/02/01 22:52:13 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1984, 1985, 1986, 1987, 1993
|
||||
@ -371,6 +371,11 @@ idp_usrreq(so, req, m, nam, control, p)
|
||||
return (ns_control(so, (u_long)m, (caddr_t)nam,
|
||||
(struct ifnet *)control, p));
|
||||
|
||||
if (req == PRU_PURGEADDR) {
|
||||
ns_purgeaddr((struct ifaddr *)nam, (struct ifnet *)control);
|
||||
return (0);
|
||||
}
|
||||
|
||||
s = splsoftnet();
|
||||
nsp = sotonspcb(so);
|
||||
if (nsp == 0 && req != PRU_ATTACH) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ns.c,v 1.17 1999/10/25 19:18:11 drochner Exp $ */
|
||||
/* $NetBSD: ns.c,v 1.18 2000/02/01 22:52:13 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1984, 1985, 1986, 1987, 1993
|
||||
@ -109,8 +109,10 @@ ns_control(so, cmd, data, ifp, p)
|
||||
return (ENOBUFS);
|
||||
bzero((caddr_t)ia, sizeof(*ia));
|
||||
TAILQ_INSERT_TAIL(&ns_ifaddr, ia, ia_list);
|
||||
IFAREF((struct ifaddr *)ia);
|
||||
TAILQ_INSERT_TAIL(&ifp->if_addrlist, (struct ifaddr *)ia,
|
||||
ifa_list);
|
||||
IFAREF((struct ifaddr *)ia);
|
||||
ia->ia_ifa.ifa_addr = snstosa(&ia->ia_addr);
|
||||
ia->ia_ifa.ifa_netmask = snstosa(&ns_netmask);
|
||||
ia->ia_ifa.ifa_dstaddr = snstosa(&ia->ia_dstaddr);
|
||||
@ -193,16 +195,7 @@ ns_control(so, cmd, data, ifp, p)
|
||||
return (error);
|
||||
|
||||
case SIOCDIFADDR:
|
||||
ns_ifscrub(ifp, ia);
|
||||
TAILQ_REMOVE(&ifp->if_addrlist, (struct ifaddr *)ia, ifa_list);
|
||||
TAILQ_REMOVE(&ns_ifaddr, ia, ia_list);
|
||||
IFAFREE((&ia->ia_ifa));
|
||||
if (0 == --ns_interfaces) {
|
||||
/*
|
||||
* We reset to virginity and start all over again
|
||||
*/
|
||||
ns_thishost = ns_zerohost;
|
||||
}
|
||||
ns_purgeaddr(&ia->ia_ifa, ifp);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -213,6 +206,26 @@ ns_control(so, cmd, data, ifp, p)
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
ns_purgeaddr(ifa, ifp)
|
||||
struct ifaddr *ifa;
|
||||
struct ifnet *ifp;
|
||||
{
|
||||
struct ns_ifaddr *ia = (void *) ifa;
|
||||
|
||||
ns_ifscrub(ifp, ia);
|
||||
TAILQ_REMOVE(&ifp->if_addrlist, (struct ifaddr *)ia, ifa_list);
|
||||
IFAFREE(&ia->ia_ifa);
|
||||
TAILQ_REMOVE(&ns_ifaddr, ia, ia_list);
|
||||
IFAFREE((&ia->ia_ifa));
|
||||
if (0 == --ns_interfaces) {
|
||||
/*
|
||||
* We reset to virginity and start all over again
|
||||
*/
|
||||
ns_thishost = ns_zerohost;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete any previous route for an old address.
|
||||
*/
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: spp_usrreq.c,v 1.21 1999/09/10 03:24:15 simonb Exp $ */
|
||||
/* $NetBSD: spp_usrreq.c,v 1.22 2000/02/01 22:52:13 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1984, 1985, 1986, 1987, 1993
|
||||
@ -1339,6 +1339,11 @@ spp_usrreq(so, req, m, nam, control, p)
|
||||
return (ns_control(so, (u_long)m, (caddr_t)nam,
|
||||
(struct ifnet *)control, p));
|
||||
|
||||
if (req == PRU_PURGEADDR) {
|
||||
ns_purgeaddr((struct ifaddr *)nam, (struct ifnet *)control);
|
||||
return (0);
|
||||
}
|
||||
|
||||
s = splsoftnet();
|
||||
nsp = sotonspcb(so);
|
||||
if (nsp == 0 && req != PRU_ATTACH) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: protosw.h,v 1.18 1999/07/01 05:56:53 darrenr Exp $ */
|
||||
/* $NetBSD: protosw.h,v 1.19 2000/02/01 22:52:14 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1982, 1986, 1993
|
||||
@ -153,8 +153,9 @@ struct protosw {
|
||||
#define PRU_SLOWTIMO 19 /* 500ms timeout */
|
||||
#define PRU_PROTORCV 20 /* receive from below */
|
||||
#define PRU_PROTOSEND 21 /* send to below */
|
||||
#define PRU_PURGEADDR 22 /* purge specified ifaddr */
|
||||
|
||||
#define PRU_NREQ 22
|
||||
#define PRU_NREQ 23
|
||||
|
||||
#ifdef PRUREQUESTS
|
||||
char *prurequests[] = {
|
||||
@ -163,7 +164,7 @@ char *prurequests[] = {
|
||||
"RCVD", "SEND", "ABORT", "CONTROL",
|
||||
"SENSE", "RCVOOB", "SENDOOB", "SOCKADDR",
|
||||
"PEERADDR", "CONNECT2", "FASTTIMO", "SLOWTIMO",
|
||||
"PROTORCV", "PROTOSEND",
|
||||
"PROTORCV", "PROTOSEND", "PURGEADDR",
|
||||
};
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user