Plug a reference leak: before doing 'goto again' we need to unref

ia->ia_ifa if there is any.

Submitted by:	Andrey Zonov <andrey zonov.org>
This commit is contained in:
Gleb Smirnoff 2012-07-18 08:58:30 +00:00
parent b9abeb9d99
commit 3c73180f55

View File

@ -124,7 +124,7 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags,
int n; /* scratchpad */
int error = 0;
struct sockaddr_in *dst;
struct in_ifaddr *ia = NULL;
struct in_ifaddr *ia;
int isbroadcast, sw_csum;
struct route iproute;
struct rtentry *rte; /* cache for ro->ro_rt */
@ -198,6 +198,7 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags,
dst = (struct sockaddr_in *)&ro->ro_dst;
again:
ia = NULL;
/*
* If there is a cached route,
* check that it is to the same destination
@ -533,8 +534,11 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags,
#endif
error = netisr_queue(NETISR_IP, m);
goto done;
} else
} else {
if (ia != NULL)
ifa_free(&ia->ia_ifa);
goto again; /* Redo the routing table lookup. */
}
}
#ifdef IPFIREWALL_FORWARD
@ -564,6 +568,8 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags,
bcopy((fwd_tag+1), dst, sizeof(struct sockaddr_in));
m->m_flags |= M_SKIP_FIREWALL;
m_tag_delete(m, fwd_tag);
if (ia != NULL)
ifa_free(&ia->ia_ifa);
goto again;
}
#endif /* IPFIREWALL_FORWARD */