summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2015-01-26 11:36:39 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2015-01-26 11:36:39 +0000
commit2bdc6311b18ab319f7eb0a32ee1a512372c10d19 (patch)
treef452405feacd6ff99ccdc83c4828830872c30df3 /sys
parent95c40f9dcde3f9af00877121538b6dc4dcccb688 (diff)
Do not always try to rtfree(9) route entries inside rtdeletemsg(9).
Instead check the error code returned by this function and let the caller free the route entry when appropriate. ok bluhm@
Diffstat (limited to 'sys')
-rw-r--r--sys/net/route.c32
-rw-r--r--sys/netinet/if_ether.c11
2 files changed, 31 insertions, 12 deletions
diff --git a/sys/net/route.c b/sys/net/route.c
index 640e523c290..6fd74df809b 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: route.c,v 1.201 2015/01/21 21:32:42 bluhm Exp $ */
+/* $OpenBSD: route.c,v 1.202 2015/01/26 11:36:38 mpi Exp $ */
/* $NetBSD: route.c,v 1.14 1996/02/13 22:00:46 christos Exp $ */
/*
@@ -544,11 +544,6 @@ rtdeletemsg(struct rtentry *rt, u_int tableid)
rt_missmsg(RTM_DELETE, &info, info.rti_flags, ifp, error, tableid);
- /* Adjust the refcount */
- if (error == 0 && rt->rt_refcnt <= 0) {
- rt->rt_refcnt++;
- rtfree(rt);
- }
return (error);
}
@@ -556,11 +551,19 @@ int
rtflushclone1(struct radix_node *rn, void *arg, u_int id)
{
struct rtentry *rt, *parent;
+ int error;
rt = (struct rtentry *)rn;
parent = (struct rtentry *)arg;
- if ((rt->rt_flags & RTF_CLONED) != 0 && rt->rt_parent == parent)
- rtdeletemsg(rt, id);
+ if ((rt->rt_flags & RTF_CLONED) != 0 && rt->rt_parent == parent) {
+ error = rtdeletemsg(rt, id);
+
+ /* Adjust the refcount */
+ if (error == 0 && rt->rt_refcnt <= 0) {
+ rt->rt_refcnt++;
+ rtfree(rt);
+ }
+ }
return 0;
}
@@ -1631,8 +1634,17 @@ rt_if_remove_rtdelete(struct radix_node *rn, void *vifp, u_int id)
if (rt->rt_ifp == ifp) {
int cloning = (rt->rt_flags & RTF_CLONING);
- if (rtdeletemsg(rt, id) == 0 && cloning)
- return (EAGAIN);
+ if (rtdeletemsg(rt, id) == 0) {
+
+ /* Adjust the refcount */
+ if (rt->rt_refcnt <= 0) {
+ rt->rt_refcnt++;
+ rtfree(rt);
+ }
+
+ if (cloning)
+ return (EAGAIN);
+ }
}
/*
diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c
index 01458833ac9..6ff4877f1cc 100644
--- a/sys/netinet/if_ether.c
+++ b/sys/netinet/if_ether.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ether.c,v 1.141 2015/01/13 12:16:18 mpi Exp $ */
+/* $OpenBSD: if_ether.c,v 1.142 2015/01/26 11:36:38 mpi Exp $ */
/* $NetBSD: if_ether.c,v 1.31 1996/05/11 12:59:58 mycroft Exp $ */
/*
@@ -789,6 +789,7 @@ arptfree(struct llinfo_arp *la)
struct rtentry *rt = la->la_rt;
struct sockaddr_dl *sdl;
u_int tid = 0;
+ int error;
if (rt == NULL)
panic("arptfree");
@@ -803,7 +804,13 @@ arptfree(struct llinfo_arp *la)
if (rt->rt_ifp)
tid = rt->rt_ifp->if_rdomain;
- rtdeletemsg(rt, tid);
+ error = rtdeletemsg(rt, tid);
+
+ /* Adjust the refcount */
+ if (error == 0 && rt->rt_refcnt <= 0) {
+ rt->rt_refcnt++;
+ rtfree(rt);
+ }
}
/*