Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

avoided duplicate free after in[6]_clsroute when rtexpire is set to 0.

  • Loading branch information...
commit f484e88034cf15ec74287fc5617e5541839b3dbb 1 parent 422eeb8
jinmei authored
Showing with 39 additions and 15 deletions.
  1. +32 −14 freebsd4/sys/netinet/in_rmx.c
  2. +7 −1 kame/sys/netinet6/in6_rmx.c
46 freebsd4/sys/netinet/in_rmx.c
View
@@ -26,7 +26,7 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: src/sys/netinet/in_rmx.c,v 1.37 1999/08/28 00:49:18 peter Exp $
+ * $FreeBSD: src/sys/netinet/in_rmx.c,v 1.37.2.3 2002/08/09 14:49:23 ru Exp $
*/
/*
@@ -54,6 +54,7 @@
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/in_var.h>
+#include <netinet/ip_var.h>
extern int in_inithead __P((void **head, int off));
@@ -100,11 +101,9 @@ in_addroute(void *v_arg, void *n_arg, struct radix_node_head *head,
if (in_broadcast(sin->sin_addr, rt->rt_ifp)) {
rt->rt_flags |= RTF_BROADCAST;
} else {
-#define satosin(sa) ((struct sockaddr_in *)sa)
if (satosin(rt->rt_ifa->ifa_addr)->sin_addr.s_addr
== sin->sin_addr.s_addr)
rt->rt_flags |= RTF_LOCAL;
-#undef satosin
}
}
@@ -137,6 +136,17 @@ in_addroute(void *v_arg, void *n_arg, struct radix_node_head *head,
RTFREE(rt2);
}
}
+
+ /*
+ * If the new route created successfully, and we are forwarding,
+ * and there is a cached route, free it. Otherwise, we may end
+ * up using the wrong route.
+ */
+ if (ret != NULL && ipforwarding && ipforward_rt.ro_rt) {
+ RTFREE(ipforward_rt.ro_rt);
+ ipforward_rt.ro_rt = 0;
+ }
+
return ret;
}
@@ -205,6 +215,12 @@ in_clsroute(struct radix_node *rn, struct radix_node_head *head)
rt->rt_flags |= RTPRF_OURS;
rt->rt_rmx.rmx_expire = time_second + rtq_reallyold;
} else {
+ struct rtentry *dummy;
+
+ /*
+ * rtrequest() would recursively call rtfree() without the
+ * dummy entry argument, causing duplicated free.
+ */
rtrequest(RTM_DELETE,
(struct sockaddr *)rt_key(rt),
rt->rt_gateway, rt_mask(rt),
@@ -357,18 +373,18 @@ in_inithead(void **head, int off)
/*
- * This zaps old routes when the interface goes down.
- * Currently it doesn't delete static routes; there are
- * arguments one could make for both behaviors. For the moment,
- * we will adopt the Principle of Least Surprise and leave them
- * alone (with the knowledge that this will not be enough for some
- * people). The ones we really 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.
+ * 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
@@ -378,7 +394,8 @@ in_ifadownkill(struct radix_node *rn, void *xap)
struct rtentry *rt = (struct rtentry *)rn;
int err;
- if (rt->rt_ifa == ap->ifa && !(rt->rt_flags & RTF_STATIC)) {
+ 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
@@ -387,7 +404,7 @@ in_ifadownkill(struct radix_node *rn, void *xap)
* the routes that rtrequest() would have in any case,
* so that behavior is not needed there.
*/
- rt->rt_flags &= ~RTF_PRCLONING;
+ rt->rt_flags &= ~(RTF_CLONING | RTF_PRCLONING);
err = rtrequest(RTM_DELETE, (struct sockaddr *)rt_key(rt),
rt->rt_gateway, rt_mask(rt), rt->rt_flags, 0);
if (err) {
@@ -398,7 +415,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;
@@ -408,6 +425,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;
8 kame/sys/netinet6/in6_rmx.c
View
@@ -1,4 +1,4 @@
-/* $KAME: in6_rmx.c,v 1.21 2004/06/02 05:53:15 itojun Exp $ */
+/* $KAME: in6_rmx.c,v 1.22 2004/09/30 21:52:16 jinmei Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -319,6 +319,12 @@ in6_clsroute(struct radix_node *rn, struct radix_node_head *head)
rt->rt_flags |= RTPRF_OURS;
rt->rt_rmx.rmx_expire = time_second + rtq_reallyold;
} else {
+ struct rtentry *dummy;
+
+ /*
+ * rtrequest() would recursively call rtfree() without the
+ * dummy entry argument, causing duplicated free.
+ */
rtrequest(RTM_DELETE,
(struct sockaddr *)rt_key(rt),
rt->rt_gateway, rt_mask(rt),
Please sign in to comment.
Something went wrong with that request. Please try again.