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
This commit is contained in:
parent
7766e0a26b
commit
27d7e8be08
@ -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; \
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user