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:
@@ -2,6 +2,11 @@
|
|||||||
#define _CORE_PRIVATE__H
|
#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 *mbpool;
|
||||||
extern struct pool_ctl *clpool;
|
extern struct pool_ctl *clpool;
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#define printf dprintf
|
#define printf dprintf
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "core_private.h"
|
||||||
#include "netinet/in.h"
|
#include "netinet/in.h"
|
||||||
#include "sys/socketvar.h"
|
#include "sys/socketvar.h"
|
||||||
#include "net/if.h"
|
#include "net/if.h"
|
||||||
@@ -399,6 +400,8 @@ void if_attach(struct ifnet *ifp)
|
|||||||
void if_detach(struct ifnet *ifp)
|
void if_detach(struct ifnet *ifp)
|
||||||
{
|
{
|
||||||
struct ifnet *p = devices, *q = NULL;
|
struct ifnet *p = devices, *q = NULL;
|
||||||
|
int32 index;
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
for(; p && p != ifp; p = p->if_next)
|
for(; p && p != ifp; p = p->if_next)
|
||||||
q = p;
|
q = p;
|
||||||
@@ -406,6 +409,26 @@ void if_detach(struct ifnet *ifp)
|
|||||||
if(!p)
|
if(!p)
|
||||||
return;
|
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)
|
if(q)
|
||||||
q->if_next = p->if_next;
|
q->if_next = p->if_next;
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -9,6 +9,8 @@
|
|||||||
#include <sys/sockio.h>
|
#include <sys/sockio.h>
|
||||||
#include <net/route.h>
|
#include <net/route.h>
|
||||||
|
|
||||||
|
#include "core_private.h"
|
||||||
|
|
||||||
#ifdef _KERNEL_MODE
|
#ifdef _KERNEL_MODE
|
||||||
#include <KernelExport.h>
|
#include <KernelExport.h>
|
||||||
#define printf dprintf
|
#define printf dprintf
|
||||||
@@ -23,6 +25,7 @@ struct in_ifaddr *get_primary_addr(void)
|
|||||||
return in_ifaddr;
|
return in_ifaddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Trim a mask in a sockaddr
|
* Trim a mask in a sockaddr
|
||||||
*/
|
*/
|
||||||
@@ -39,9 +42,60 @@ void in_socktrim(struct sockaddr_in *ap)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define rtinitflags(x) \
|
#define rtinitflags(x) \
|
||||||
((((x)->ia_ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) != 0) \
|
((((x)->ia_ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) != 0) \
|
||||||
? RTF_HOST : 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).
|
* remove a route to prefix ("connected route" in cisco terminology).
|
||||||
* re-installs the route by using another interface address, if there's one
|
* 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;
|
struct sockaddr_in oldaddr;
|
||||||
int error = 0, hostIsNew, maskIsNew;
|
int error = 0, hostIsNew, maskIsNew;
|
||||||
long i;
|
long i;
|
||||||
|
|
||||||
if (ifp) /* we need to find the in_ifaddr */
|
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)
|
if (ia->ia_ifp == ifp)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case SIOCAIFADDR:
|
case SIOCAIFADDR:
|
||||||
printf("SIOCAIFADDR\n");
|
printf("SIOCAIFADDR\n");
|
||||||
|
|||||||
Reference in New Issue
Block a user