From alfred@FreeBSD.org  Wed Oct  6 17:46:37 2004
Return-Path: <alfred@FreeBSD.org>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 2A15516A4CE
	for <FreeBSD-gnats-submit@freebsd.org>; Wed,  6 Oct 2004 17:46:37 +0000 (GMT)
Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21])
	by mx1.FreeBSD.org (Postfix) with ESMTP id F41C943D45
	for <FreeBSD-gnats-submit@freebsd.org>; Wed,  6 Oct 2004 17:46:36 +0000 (GMT)
	(envelope-from alfred@FreeBSD.org)
Received: from freefall.freebsd.org (alfred@localhost [127.0.0.1])
	by freefall.freebsd.org (8.12.11/8.12.11) with ESMTP id i96HkaWQ082700
	for <FreeBSD-gnats-submit@freebsd.org>; Wed, 6 Oct 2004 17:46:36 GMT
	(envelope-from alfred@freefall.freebsd.org)
Received: (from alfred@localhost)
	by freefall.freebsd.org (8.12.11/8.12.11/Submit) id i96HkaGX082699;
	Wed, 6 Oct 2004 17:46:36 GMT
	(envelope-from alfred)
Message-Id: <200410061746.i96HkaGX082699@freefall.freebsd.org>
Date: Wed, 6 Oct 2004 17:46:36 GMT
From: Alfred Perlstein <alfred@FreeBSD.org>
Reply-To: Alfred Perlstein <alfred@FreeBSD.org>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: Incorrect network accounting with aliases.
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         72396
>Category:       kern
>Synopsis:       [netinet] [patch] Incorrect network accounting with aliases.
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    bms
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Oct 06 17:50:29 GMT 2004
>Closed-Date:    Mon Sep 25 13:03:27 GMT 2006
>Last-Modified:  Mon Sep 25 13:03:27 GMT 2006
>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:
Responsible-Changed-From-To: freebsd-bugs->bms 
Responsible-Changed-By: bms 
Responsible-Changed-When: Mon Sep 25 09:11:28 UTC 2006 
Responsible-Changed-Why:  
Takez-vous. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=72396 
State-Changed-From-To: open->analyzed 
State-Changed-By: bms 
State-Changed-When: Mon Sep 25 09:15:14 UTC 2006 
State-Changed-Why:  
Reproduced on 7.0-CURRENT. 
NetBSD does something very similar to Alfred's patch. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=72396 
State-Changed-From-To: analyzed->patched 
State-Changed-By: bms 
State-Changed-When: Mon Sep 25 10:12:12 UTC 2006 
State-Changed-Why:  
Committed on current. MFC pending re@ launch clearance 

http://www.freebsd.org/cgi/query-pr.cgi?pr=72396 
State-Changed-From-To: patched->closed 
State-Changed-By: bms 
State-Changed-When: Mon Sep 25 13:03:14 UTC 2006 
State-Changed-Why:  
mfc approved by re 

http://www.freebsd.org/cgi/query-pr.cgi?pr=72396 
>Unformatted:
