summaryrefslogtreecommitdiffstats
path: root/sys/netinet
diff options
context:
space:
mode:
authorglebius <glebius@FreeBSD.org>2012-07-18 08:58:30 +0000
committerglebius <glebius@FreeBSD.org>2012-07-18 08:58:30 +0000
commit3b4ff3bafbbc7b96119d505dbddfd3d69f62bf51 (patch)
tree64762c692a4d985e3709a1cfc69f17b48c2b80b3 /sys/netinet
parent636d3aa68f5379759a09f7b4f36f38e1aeee3a45 (diff)
downloadFreeBSD-src-3b4ff3bafbbc7b96119d505dbddfd3d69f62bf51.zip
FreeBSD-src-3b4ff3bafbbc7b96119d505dbddfd3d69f62bf51.tar.gz
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>
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/ip_output.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index cc38dcf..eeea58c 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -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 @@ sendit:
#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 @@ sendit:
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 */
OpenPOWER on IntegriCloud