fixed a memory leak when net.inet6.icmp6.nd6_maxqueuelen is greater than 1

Obtained from: KAME
MFC after: 3 days
This commit is contained in:
SUZUKI Shinsuke 2006-03-24 16:20:12 +00:00
parent b8e00b4cf4
commit 31d4137bf3
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=157097

View File

@ -114,6 +114,7 @@ static void nd6_slowtimo __P((void *));
static int regen_tmpaddr __P((struct in6_ifaddr *));
static struct llinfo_nd6 *nd6_free __P((struct rtentry *, int));
static void nd6_llinfo_timer __P((void *));
static void clear_llinfo_pqueue __P((struct llinfo_nd6 *));
struct callout nd6_slowtimo_ch;
struct callout nd6_timer_ch;
@ -460,13 +461,19 @@ nd6_llinfo_timer(arg)
} else {
struct mbuf *m = ln->ln_hold;
if (m) {
struct mbuf *m0;
/*
* assuming every packet in ln_hold has the
* same IP header
*/
ln->ln_hold = NULL;
m0 = m->m_nextpkt;
m->m_nextpkt = NULL;
icmp6_error2(m, ICMP6_DST_UNREACH,
ICMP6_DST_UNREACH_ADDR, 0, rt->rt_ifp);
ln->ln_hold = m0;
clear_llinfo_pqueue(ln);
}
if (rt)
(void)nd6_free(rt, 0);
@ -1403,8 +1410,7 @@ nd6_rtrequest(req, rt, info)
nd6_llinfo_settimer(ln, -1);
rt->rt_llinfo = 0;
rt->rt_flags &= ~RTF_LLINFO;
if (ln->ln_hold)
m_freem(ln->ln_hold);
clear_llinfo_pqueue(ln);
Free((caddr_t)ln);
}
}
@ -2078,7 +2084,7 @@ nd6_output(ifp, origifp, m0, dst, rt0)
while (i >= nd6_maxqueuelen) {
m_hold = ln->ln_hold;
ln->ln_hold = ln->ln_hold->m_nextpkt;
m_free(m_hold);
m_freem(m_hold);
i--;
}
} else {
@ -2236,6 +2242,22 @@ nd6_storelladdr(ifp, rt0, m, dst, desten)
return (0);
}
static void
clear_llinfo_pqueue(ln)
struct llinfo_nd6 *ln;
{
struct mbuf *m_hold, *m_hold_next;
for (m_hold = ln->ln_hold; m_hold; m_hold = m_hold_next) {
m_hold_next = m_hold->m_nextpkt;
m_hold->m_nextpkt = NULL;
m_freem(m_hold);
}
ln->ln_hold = NULL;
return;
}
static int nd6_sysctl_drlist(SYSCTL_HANDLER_ARGS);
static int nd6_sysctl_prlist(SYSCTL_HANDLER_ARGS);
#ifdef SYSCTL_DECL