First attempt at fixing the if_detach code.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6153 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Waldemar Kornewald
2004-01-19 21:41:45 +00:00
parent ac4bd49716
commit 6c54c57f07
3 changed files with 85 additions and 3 deletions
@@ -2,6 +2,11 @@
#define _CORE_PRIVATE__H
struct ifnet;
void in_if_detach(struct ifnet *ifp);
// this removes all IP related references for this interface (route, address)
extern struct pool_ctl *mbpool;
extern struct pool_ctl *clpool;
+23
View File
@@ -10,6 +10,7 @@
#define printf dprintf
#endif
#include "core_private.h"
#include "netinet/in.h"
#include "sys/socketvar.h"
#include "net/if.h"
@@ -399,6 +400,8 @@ void if_attach(struct ifnet *ifp)
void if_detach(struct ifnet *ifp)
{
struct ifnet *p = devices, *q = NULL;
int32 index;
bool found = false;
for(; p && p != ifp; p = p->if_next)
q = p;
@@ -406,6 +409,26 @@ void if_detach(struct ifnet *ifp)
if(!p)
return;
// XXX: this is a hack, but we don't want to invest too much work into this stack
in_if_detach(ifp);
// this should also remove all remaining routes
// remove the ifa entry from ifnet_addrs and reduce all following ifnet indices
for(index = 0; index < if_index; index++) {
if(found) {
--ifnet_addrs[index]->ifa_ifp->if_index;
ifnet_addrs[index - 1] = ifnet_addrs[index];
}
if(ifnet_addrs[index]->ifa_ifp == ifp) {
found = true;
free(ifnet_addrs[index]);
}
}
if(found)
--if_index;
if(q)
q->if_next = p->if_next;
else
+57 -3
View File
@@ -9,6 +9,8 @@
#include <sys/sockio.h>
#include <net/route.h>
#include "core_private.h"
#ifdef _KERNEL_MODE
#include <KernelExport.h>
#define printf dprintf
@@ -23,6 +25,7 @@ struct in_ifaddr *get_primary_addr(void)
return in_ifaddr;
}
/*
* Trim a mask in a sockaddr
*/
@@ -39,9 +42,60 @@ void in_socktrim(struct sockaddr_in *ap)
}
}
#define rtinitflags(x) \
((((x)->ia_ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) != 0) \
? RTF_HOST : 0)
void
in_if_detach(struct ifnet *ifp)
{
// remove all references to this ifnet
struct in_ifaddr *ia = NULL, *previous = NULL;
struct ifaddr *ifa;
if(!ifp || !in_ifaddr)
return;
if(in_ifaddr->ia_ifp == ifp)
ia = in_ifaddr;
else {
for(previous = in_ifaddr; previous && previous->ia_next;
previous = previous->ia_next)
if(previous->ia_next->ia_ifp == ifp) {
ia = previous->ia_next;
break;
}
}
if(!ia)
return;
if(rtinit(&(ia->ia_ifa), RTM_DELETE, rtinitflags(ia)))
printf("core.c.: in_if_detach(): Could not delete route!\n");
if(ifp->if_addrlist) {
ifa = ifp->if_addrlist;
if(ifa->ifa_addr->sa_family == AF_INET)
ifp->if_addrlist = ifa->ifa_next;
else
for(; ifa; ifa = ifa->ifa_next)
if(ifa->ifa_next && ifa->ifa_next->ifa_addr->sa_family == AF_INET) {
struct ifaddr *tmp = ifa;
ifa = ifa->ifa_next;
tmp->ifa_next = ifa->ifa_next;
}
if(ifa)
free(ifa);
}
if(previous)
previous->ia_next = ia->ia_next;
else
in_ifaddr = ia->ia_next;
}
/*
* remove a route to prefix ("connected route" in cisco terminology).
* re-installs the route by using another interface address, if there's one
@@ -193,12 +247,12 @@ int in_control(struct socket *so, int cmd, caddr_t data, struct ifnet *ifp)
struct sockaddr_in oldaddr;
int error = 0, hostIsNew, maskIsNew;
long i;
if (ifp) /* we need to find the in_ifaddr */
for (ia = in_ifaddr;ia; ia = ia->ia_next)
for (ia = in_ifaddr; ia; ia = ia->ia_next)
if (ia->ia_ifp == ifp)
break;
switch (cmd) {
case SIOCAIFADDR:
printf("SIOCAIFADDR\n");