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:
parent
dac4a1cd87
commit
82e492f616
@ -421,7 +421,7 @@ in_control(so, cmd, data, ifp, p)
|
||||
* thing to do, but at least if we are running
|
||||
* a routing process they will come back.
|
||||
*/
|
||||
in_ifadown(&ia->ia_ifa);
|
||||
in_ifadown(&ia->ia_ifa, 1);
|
||||
|
||||
/*
|
||||
* Protect from ipintr() traversing address list
|
||||
|
@ -369,16 +369,18 @@ in_inithead(void **head, int off)
|
||||
|
||||
|
||||
/*
|
||||
* This zaps old routes (including ARP entries) when the interface
|
||||
* address is deleted. Previously it didn't delete static routes,
|
||||
* and this caused some weird things to happen. In particular, if
|
||||
* you changed the address on an interface, and the default route
|
||||
* was using this interface and address, outgoing datagrams still
|
||||
* used the old address.
|
||||
* This zaps old routes when the interface goes down or interface
|
||||
* address is deleted. In the latter case, it deletes static routes
|
||||
* that point to this address. If we don't do this, we may end up
|
||||
* using the old address in the future. The ones we always want to
|
||||
* get rid of are things like ARP entries, since the user might down
|
||||
* the interface, walk over to a completely different network, and
|
||||
* plug back in.
|
||||
*/
|
||||
struct in_ifadown_arg {
|
||||
struct radix_node_head *rnh;
|
||||
struct ifaddr *ifa;
|
||||
int del;
|
||||
};
|
||||
|
||||
static int
|
||||
@ -388,7 +390,8 @@ in_ifadownkill(struct radix_node *rn, void *xap)
|
||||
struct rtentry *rt = (struct rtentry *)rn;
|
||||
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
|
||||
* in this case in rtrequest() because it will blow
|
||||
@ -408,7 +411,7 @@ in_ifadownkill(struct radix_node *rn, void *xap)
|
||||
}
|
||||
|
||||
int
|
||||
in_ifadown(struct ifaddr *ifa)
|
||||
in_ifadown(struct ifaddr *ifa, int delete)
|
||||
{
|
||||
struct in_ifadown_arg arg;
|
||||
struct radix_node_head *rnh;
|
||||
@ -418,6 +421,7 @@ in_ifadown(struct ifaddr *ifa)
|
||||
|
||||
arg.rnh = rnh = rt_tables[AF_INET];
|
||||
arg.ifa = ifa;
|
||||
arg.del = delete;
|
||||
rnh->rnh_walktree(rnh, in_ifadownkill, &arg);
|
||||
ifa->ifa_flags &= ~IFA_ROUTE;
|
||||
return 0;
|
||||
|
@ -221,7 +221,7 @@ int in_control __P((struct socket *, u_long, caddr_t, struct ifnet *,
|
||||
struct proc *));
|
||||
void in_rtqdrain __P((void));
|
||||
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 *));
|
||||
int ipflow_fastforward __P((struct mbuf *));
|
||||
void ipflow_create __P((const struct route *, struct mbuf *));
|
||||
|
@ -398,7 +398,7 @@ rip_ctlinput(cmd, sa, vip)
|
||||
* thing to do, but at least if we are running
|
||||
* a routing process they will come back.
|
||||
*/
|
||||
in_ifadown(&ia->ia_ifa);
|
||||
in_ifadown(&ia->ia_ifa, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user