diff options
author | bms <bms@FreeBSD.org> | 2006-09-25 10:11:16 +0000 |
---|---|---|
committer | bms <bms@FreeBSD.org> | 2006-09-25 10:11:16 +0000 |
commit | 27d7e8be08d5080b783ef437149fc4f7fc3adfde (patch) | |
tree | 32da2515bec6367ff396b9b72c433ec025da3189 /sys/netinet/ip_output.c | |
parent | 7766e0a26b4a6088ea3cd0c32d8450ce1e25535b (diff) | |
download | FreeBSD-src-27d7e8be08d5080b783ef437149fc4f7fc3adfde.zip FreeBSD-src-27d7e8be08d5080b783ef437149fc4f7fc3adfde.tar.gz |
Account for output IP datagrams on the ifaddr where they originated from,
*not* the first ifaddr on the ifp. This is similar to what NetBSD does.
PR: kern/72936
Submitted by: alfred
Reviewed by: andre
Diffstat (limited to 'sys/netinet/ip_output.c')
-rw-r--r-- | sys/netinet/ip_output.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index 2675385..33fa325 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 |