diff options
author | ru <ru@FreeBSD.org> | 2001-05-11 14:37:34 +0000 |
---|---|---|
committer | ru <ru@FreeBSD.org> | 2001-05-11 14:37:34 +0000 |
commit | 82e492f616bd4d837f50dc27c05b98bf391e7ccc (patch) | |
tree | 69976ffd77c0159e1052052d3d2f80480a9065c1 | |
parent | dac4a1cd8732ee47d280e8f9f97dff4ddfab3870 (diff) | |
download | FreeBSD-src-82e492f616bd4d837f50dc27c05b98bf391e7ccc.zip FreeBSD-src-82e492f616bd4d837f50dc27c05b98bf391e7ccc.tar.gz |
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>
-rw-r--r-- | sys/netinet/in.c | 2 | ||||
-rw-r--r-- | sys/netinet/in_rmx.c | 20 | ||||
-rw-r--r-- | sys/netinet/in_var.h | 2 | ||||
-rw-r--r-- | sys/netinet/raw_ip.c | 2 |
4 files changed, 15 insertions, 11 deletions
diff --git a/sys/netinet/in.c b/sys/netinet/in.c index 256e006..95abe3f 100644 --- a/sys/netinet/in.c +++ b/sys/netinet/in.c @@ -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 diff --git a/sys/netinet/in_rmx.c b/sys/netinet/in_rmx.c index 16ea5be..bfd65e6 100644 --- a/sys/netinet/in_rmx.c +++ b/sys/netinet/in_rmx.c @@ -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; diff --git a/sys/netinet/in_var.h b/sys/netinet/in_var.h index e89c501..f5c1464 100644 --- a/sys/netinet/in_var.h +++ b/sys/netinet/in_var.h @@ -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 *)); diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c index 1fa0ee8..50bbf32 100644 --- a/sys/netinet/raw_ip.c +++ b/sys/netinet/raw_ip.c @@ -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; } } |