From 27d7e8be08d5080b783ef437149fc4f7fc3adfde Mon Sep 17 00:00:00 2001 From: bms Date: Mon, 25 Sep 2006 10:11:16 +0000 Subject: [PATCH] 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 --- sys/netinet/in_var.h | 17 ++++++++++++++--- sys/netinet/ip_output.c | 17 ++++++++++++----- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/sys/netinet/in_var.h b/sys/netinet/in_var.h index 319b0dc5519..9669a1b8993 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 267538507a6..33fa3256b4c 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 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, * 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 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, 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 -- 2.45.0