Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 6 Oct 2004 17:46:36 GMT
From:      Alfred Perlstein <alfred@FreeBSD.org>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   kern/72396: Incorrect network accounting with aliases.
Message-ID:  <200410061746.i96HkaGX082699@freefall.freebsd.org>
Resent-Message-ID: <200410061750.i96HoT0P082787@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>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@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:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200410061746.i96HkaGX082699>