aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/netinet/in_var.h17
-rw-r--r--sys/netinet/ip_output.c17
2 files changed, 26 insertions, 8 deletions
diff --git a/sys/netinet/in_var.h b/sys/netinet/in_var.h
index 319b0dc5519b..9669a1b8993f 100644
--- a/sys/netinet/in_var.h
+++ b/sys/netinet/in_var.h
@@ -94,6 +94,19 @@ extern u_long in_ifaddrhmask; /* mask for hash table */
#define INADDR_HASH(x) \
(&in_ifaddrhashtbl[INADDR_HASHVAL(x) & in_ifaddrhmask])
+/*
+ * Macro for finding the internet address structure (in_ifaddr) corresponding
+ * corresponding to one of our IP addresses (in_addr).
+ */
+#define INADDR_TO_IFADDR(addr, ia) \
+ /* struct in_addr addr; */ \
+ /* struct in_ifaddr *ia; */ \
+do { \
+\
+ LIST_FOREACH(ia, INADDR_HASH((addr).s_addr), ia_hash) \
+ if (IA_SIN(ia)->sin_addr.s_addr == (addr).s_addr) \
+ break; \
+} while (0)
/*
* Macro for finding the interface (ifnet structure) corresponding to one
@@ -105,9 +118,7 @@ extern u_long in_ifaddrhmask; /* mask for hash table */
{ \
struct in_ifaddr *ia; \
\
- LIST_FOREACH(ia, INADDR_HASH((addr).s_addr), ia_hash) \
- if (IA_SIN(ia)->sin_addr.s_addr == (addr).s_addr) \
- break; \
+ INADDR_TO_IFADDR(addr, ia); \
(ifp) = (ia == NULL) ? NULL : ia->ia_ifp; \
}
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index 267538507a6b..33fa3256b4ca 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -116,6 +116,7 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro,
int len, error = 0;
struct sockaddr_in *dst = NULL; /* keep compiler happy */
struct in_ifaddr *ia = NULL;
+ struct in_ifaddr *sia = NULL;
int isbroadcast, sw_csum;
struct route iproute;
struct in_addr odst;
@@ -532,12 +533,15 @@ passout:
* once instead of for every generated packet.
*/
if (!(flags & IP_FORWARDING) && ia) {
+ INADDR_TO_IFADDR(ip->ip_src, sia);
+ if (sia == NULL)
+ sia = ia;
if (m->m_pkthdr.csum_flags & CSUM_TSO)
- ia->ia_ifa.if_opackets +=
+ sia->ia_ifa.if_opackets +=
m->m_pkthdr.len / m->m_pkthdr.tso_segsz;
else
- ia->ia_ifa.if_opackets++;
- ia->ia_ifa.if_obytes += m->m_pkthdr.len;
+ sia->ia_ifa.if_opackets++;
+ sia->ia_ifa.if_obytes += m->m_pkthdr.len;
}
#ifdef IPSEC
/* clean ipsec history once it goes out of the node */
@@ -582,8 +586,11 @@ passout:
if (error == 0) {
/* Record statistics for this interface address. */
if (ia != NULL) {
- ia->ia_ifa.if_opackets++;
- ia->ia_ifa.if_obytes += m->m_pkthdr.len;
+ INADDR_TO_IFADDR(ip->ip_src, sia);
+ if (sia == NULL)
+ sia = ia;
+ sia->ia_ifa.if_opackets++;
+ sia->ia_ifa.if_obytes += m->m_pkthdr.len;
}
/*
* Reset layer specific mbuf flags