Skip to content

Commit

Permalink
avoided duplicate free after in[6]_clsroute when rtexpire is set to 0.
Browse files Browse the repository at this point in the history
  • Loading branch information
jinmei committed Sep 30, 2004
1 parent 422eeb8 commit f484e88
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 15 deletions.
46 changes: 32 additions & 14 deletions freebsd4/sys/netinet/in_rmx.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 $
*/

/*
Expand Down Expand Up @@ -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));

Expand Down Expand Up @@ -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
}
}

Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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) {
Expand All @@ -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;
Expand All @@ -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;
Expand Down
8 changes: 7 additions & 1 deletion kame/sys/netinet6/in6_rmx.c
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -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),
Expand Down

0 comments on commit f484e88

Please sign in to comment.