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>