From d3d663ed24d568c9974faed86764cfb1682887e9 Mon Sep 17 00:00:00 2001 From: mpi Date: Mon, 26 Jan 2015 11:36:38 +0000 Subject: [PATCH] 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@ --- sys/net/route.c | 32 ++++++++++++++++++++++---------- sys/netinet/if_ether.c | 11 +++++++++-- 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); + } } /* -- 2.20.1