kern/72396: Incorrect network accounting with aliases.
Alfred Perlstein
alfred at FreeBSD.org
Wed Oct 6 10:50:39 PDT 2004
>Number: 72396
>Category: kern
>Synopsis: Incorrect network accounting with aliases.
>Confidential: no
>Severity: serious
>Priority: high
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Wed Oct 06 17:50:29 GMT 2004
>Closed-Date:
>Last-Modified:
>Originator: Alfred Perlstein
>Release: FreeBSD 4.10-STABLE i386
>Organization:
RED Inc
>Environment:
System: FreeBSD freefall.freebsd.org 4.10-STABLE FreeBSD 4.10-STABLE #13: Fri May 28 21:29:54 PDT 2004 kensmith at freefall.freebsd.org:/c/src/sys/compile/FREEFALL i386
This bug appears to be in all versions of FreeBSD.
>Description:
When an interface has aliases we incorrectly charge the main IP on the
for outbound data.
>How-To-Repeat:
Assign IP aliases to a machine:
ifconfig xl0 inet 192.168.0.55 netmask 0xffffffff alias
Ping the alias from a _different_ machine:
ping 192.168.0.55
Now on the machine with the alias run:
netstat -if inet -rnb
You will see that the alias is being charged for input of the icmp,
but not output icmp.
>Fix:
This fix could probably be improved, but it works for me.
Index: in_var.h
===================================================================
RCS file: /home/ncvs/src/sys/netinet/in_var.h,v
retrieving revision 1.51
diff -u -r1.51 in_var.h
--- in_var.h 16 Aug 2004 18:32:07 -0000 1.51
+++ in_var.h 6 Oct 2004 17:16:27 -0000
@@ -95,6 +95,16 @@
(&in_ifaddrhashtbl[INADDR_HASHVAL(x) & in_ifaddrhmask])
+#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
* of our IP addresses.
@@ -105,9 +115,7 @@
{ \
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; \
}
Index: ip_output.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/ip_output.c,v
retrieving revision 1.232
diff -u -r1.232 ip_output.c
--- ip_output.c 29 Sep 2004 04:54:33 -0000 1.232
+++ ip_output.c 6 Oct 2004 17:26:11 -0000
@@ -755,8 +755,14 @@
/* Record statistics for this interface address. */
if (!(flags & IP_FORWARDING) && ia) {
- ia->ia_ifa.if_opackets++;
- ia->ia_ifa.if_obytes += m->m_pkthdr.len;
+ struct in_ifaddr *uia;
+
+ INADDR_TO_IFADDR(ip->ip_src, uia);
+ if (uia == NULL) {
+ uia = ia;
+ }
+ uia->ia_ifa.if_opackets++;
+ uia->ia_ifa.if_obytes += m->m_pkthdr.len;
}
#ifdef IPSEC
@@ -807,8 +813,14 @@
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;
+ struct in_ifaddr *uia;
+
+ INADDR_TO_IFADDR(ip->ip_src, uia);
+ if (uia == NULL) {
+ uia = ia;
+ }
+ uia->ia_ifa.if_opackets++;
+ uia->ia_ifa.if_obytes += m->m_pkthdr.len;
}
error = (*ifp->if_output)(ifp, m,
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list