summaryrefslogtreecommitdiffstats
path: root/sys/netinet
diff options
context:
space:
mode:
authorru <ru@FreeBSD.org>2001-05-11 14:37:34 +0000
committerru <ru@FreeBSD.org>2001-05-11 14:37:34 +0000
commit82e492f616bd4d837f50dc27c05b98bf391e7ccc (patch)
tree69976ffd77c0159e1052052d3d2f80480a9065c1 /sys/netinet
parentdac4a1cd8732ee47d280e8f9f97dff4ddfab3870 (diff)
downloadFreeBSD-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>
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/in.c2
-rw-r--r--sys/netinet/in_rmx.c20
-rw-r--r--sys/netinet/in_var.h2
-rw-r--r--sys/netinet/raw_ip.c2
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;
}
}
OpenPOWER on IntegriCloud