In in_ifadown(), differentiate between whether the interface goes

down or interface address is deleted.  Only delete static routes
in the latter case.

Reported by:	Alexander Leidinger <Alexander@leidinger.net>
This commit is contained in:
Ruslan Ermilov
2001-05-11 14:37:34 +00:00
parent bf6ff2766c
commit 9185426827
4 changed files with 15 additions and 11 deletions
+1 -1
View File
@@ -421,7 +421,7 @@ in_control(so, cmd, data, ifp, p)
* thing to do, but at least if we are running * thing to do, but at least if we are running
* a routing process they will come back. * a routing process they will come back.
*/ */
in_ifadown(&ia->ia_ifa); in_ifadown(&ia->ia_ifa, 1);
/* /*
* Protect from ipintr() traversing address list * Protect from ipintr() traversing address list
+12 -8
View File
@@ -369,16 +369,18 @@ in_inithead(void **head, int off)
/* /*
* This zaps old routes (including ARP entries) when the interface * This zaps old routes when the interface goes down or interface
* address is deleted. Previously it didn't delete static routes, * address is deleted. In the latter case, it deletes static routes
* and this caused some weird things to happen. In particular, if * that point to this address. If we don't do this, we may end up
* you changed the address on an interface, and the default route * using the old address in the future. The ones we always want to
* was using this interface and address, outgoing datagrams still * get rid of are things like ARP entries, since the user might down
* used the old address. * the interface, walk over to a completely different network, and
* plug back in.
*/ */
struct in_ifadown_arg { struct in_ifadown_arg {
struct radix_node_head *rnh; struct radix_node_head *rnh;
struct ifaddr *ifa; struct ifaddr *ifa;
int del;
}; };
static int static int
@@ -388,7 +390,8 @@ in_ifadownkill(struct radix_node *rn, void *xap)
struct rtentry *rt = (struct rtentry *)rn; struct rtentry *rt = (struct rtentry *)rn;
int err; int err;
if (rt->rt_ifa == ap->ifa) { if (rt->rt_ifa == ap->ifa &&
(ap->del || !(rt->rt_flags & RTF_STATIC))) {
/* /*
* We need to disable the automatic prune that happens * We need to disable the automatic prune that happens
* in this case in rtrequest() because it will blow * in this case in rtrequest() because it will blow
@@ -408,7 +411,7 @@ in_ifadownkill(struct radix_node *rn, void *xap)
} }
int int
in_ifadown(struct ifaddr *ifa) in_ifadown(struct ifaddr *ifa, int delete)
{ {
struct in_ifadown_arg arg; struct in_ifadown_arg arg;
struct radix_node_head *rnh; struct radix_node_head *rnh;
@@ -418,6 +421,7 @@ in_ifadown(struct ifaddr *ifa)
arg.rnh = rnh = rt_tables[AF_INET]; arg.rnh = rnh = rt_tables[AF_INET];
arg.ifa = ifa; arg.ifa = ifa;
arg.del = delete;
rnh->rnh_walktree(rnh, in_ifadownkill, &arg); rnh->rnh_walktree(rnh, in_ifadownkill, &arg);
ifa->ifa_flags &= ~IFA_ROUTE; ifa->ifa_flags &= ~IFA_ROUTE;
return 0; return 0;
+1 -1
View File
@@ -221,7 +221,7 @@ int in_control __P((struct socket *, u_long, caddr_t, struct ifnet *,
struct proc *)); struct proc *));
void in_rtqdrain __P((void)); void in_rtqdrain __P((void));
void ip_input __P((struct mbuf *)); void ip_input __P((struct mbuf *));
int in_ifadown __P((struct ifaddr *ifa)); int in_ifadown __P((struct ifaddr *ifa, int));
void in_ifscrub __P((struct ifnet *, struct in_ifaddr *)); void in_ifscrub __P((struct ifnet *, struct in_ifaddr *));
int ipflow_fastforward __P((struct mbuf *)); int ipflow_fastforward __P((struct mbuf *));
void ipflow_create __P((const struct route *, struct mbuf *)); void ipflow_create __P((const struct route *, struct mbuf *));
+1 -1
View File
@@ -398,7 +398,7 @@ rip_ctlinput(cmd, sa, vip)
* thing to do, but at least if we are running * thing to do, but at least if we are running
* a routing process they will come back. * a routing process they will come back.
*/ */
in_ifadown(&ia->ia_ifa); in_ifadown(&ia->ia_ifa, 0);
break; break;
} }
} }