svn commit: r238713 - stable/9/sys/netinet
Gleb Smirnoff
glebius at FreeBSD.org
Mon Jul 23 09:19:15 UTC 2012
Author: glebius
Date: Mon Jul 23 09:19:14 2012
New Revision: 238713
URL: http://svn.freebsd.org/changeset/base/238713
Log:
Merge from head r238572, r238573:
------------------------------------------------------------------------
r238572 | glebius | 2012-07-18 12:41:00 +0400 (ср, 18 июл 2012) | 3 lines
When traversing global in_ifaddr list in the IFP_TO_IA() macro, we need
to obtain IN_IFADDR_RLOCK().
------------------------------------------------------------------------
r238573 | glebius | 2012-07-18 12:58:30 +0400 (ср, 18 июл 2012) | 5 lines
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>
Approved by: re (kib)
Modified:
stable/9/sys/netinet/in_var.h
stable/9/sys/netinet/ip_output.c
Directory Properties:
stable/9/sys/ (props changed)
Modified: stable/9/sys/netinet/in_var.h
==============================================================================
--- stable/9/sys/netinet/in_var.h Mon Jul 23 04:48:58 2012 (r238712)
+++ stable/9/sys/netinet/in_var.h Mon Jul 23 09:19:14 2012 (r238713)
@@ -159,14 +159,16 @@ do { \
#define IFP_TO_IA(ifp, ia) \
/* struct ifnet *ifp; */ \
/* struct in_ifaddr *ia; */ \
-{ \
+do { \
+ IN_IFADDR_RLOCK(); \
for ((ia) = TAILQ_FIRST(&V_in_ifaddrhead); \
(ia) != NULL && (ia)->ia_ifp != (ifp); \
(ia) = TAILQ_NEXT((ia), ia_link)) \
continue; \
if ((ia) != NULL) \
ifa_ref(&(ia)->ia_ifa); \
-}
+ IN_IFADDR_RUNLOCK(); \
+} while (0)
#endif
/*
Modified: stable/9/sys/netinet/ip_output.c
==============================================================================
--- stable/9/sys/netinet/ip_output.c Mon Jul 23 04:48:58 2012 (r238712)
+++ stable/9/sys/netinet/ip_output.c Mon Jul 23 09:19:14 2012 (r238713)
@@ -121,7 +121,7 @@ ip_output(struct mbuf *m, struct mbuf *o
int error = 0;
int nortfree = 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 */
@@ -196,6 +196,7 @@ ip_output(struct mbuf *m, struct mbuf *o
dst = (struct sockaddr_in *)&ro->ro_dst;
again:
+ ia = NULL;
/*
* If there is a cached route,
* check that it is to the same destination
@@ -532,8 +533,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
@@ -563,6 +567,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 */
More information about the svn-src-stable-9
mailing list