Messages in this thread Patch in this message | | | Date | Fri, 18 Apr 2003 15:22:51 +0400 (MSD) | From | Arcady Stepanov <> | Subject | [PATCH] net/ipv4/route.c, kernel 2.4.20 |
| |
Hello, all.
After upgrading a kernel from 2.4.19 to 2.4.20, I notice a bug in ip_rt_acct_read() @ net/ipv4/route.c causing incorrect results when reading route accounting information from /proc/net/rt_acct pseudofile. Look at this example output from rtacct utility:
[penguin@hq2 penguin]$ rtacct Realm BytesTo PktsTo BytesFrom PktsFrom unknown 2525573046 17491813 2696204488 15870526 macom.rus 2287217919 13724644 1092230247 14569843 macom.def 1670916923 15376790 3028924585 16093284 mol.arbat 476286103 884267 380803784 827802 mol.core 758578958 5083436 428582889 5382495 mol.dip 1953973432 3800121 279550530 3437570
-- [skipped] --
192 2525573046 17491813 2696204488 15870526 194 2287217919 13724644 1092230247 14569843 195 1670916923 15376790 3028924585 16093284 199 476286103 884267 380803784 827802 200 758578958 5083436 428582889 5382495 201 1953973432 3800121 279550530 3437570
-- [skipped] --
As you can see, all realms with numbers < 192 has a "twins" with >= 192 with exactly same statistics data. Statistics for _real_ realms with numbers >= 192 becomes inaccessible. These results caused by ip_rt_acct_read function, which has been completely owerwritten in 2.4.20: New code completely ignores offset argument when copying stats data in buffer.
The patch is trivial:
--- net/ipv4/route.c.orig Sun Jan 5 15:29:10 2003 +++ net/ipv4/route.c Fri Apr 18 10:11:23 2003 @@ -2422,7 +2422,7 @@ /* This code sucks. But you should have seen it before! --RR */ /* IP route accounting ptr for this logical cpu number. */ -#define IP_RT_ACCT_CPU(i) (ip_rt_acct + cpu_logical_map(i) * 256) +#define IP_RT_ACCT_CPU(i) ((u8*)ip_rt_acct + cpu_logical_map(i) * 256) static int ip_rt_acct_read(char *buffer, char **start, off_t offset, int length, int *eof, void *data) @@ -2442,17 +2442,22 @@ *eof = 1; } - /* Copy first cpu. */ *start = buffer; - memcpy(buffer, IP_RT_ACCT_CPU(0), length); - /* Add the other cpus in, one int at a time */ - for (i = 1; i < smp_num_cpus; i++) { - unsigned int j; - for (j = 0; j < length/4; j++) - ((u32*)buffer)[j] += ((u32*)IP_RT_ACCT_CPU(i))[j]; + if (length > 0) + { + /* Copy first cpu. */ + memcpy(buffer, IP_RT_ACCT_CPU(0) + offset, length); + + /* Add the other cpus in, one int at a time */ + for (i = 1; i < smp_num_cpus; i++) { + unsigned int j; + for (j = 0; j < length/4; j++) + ((u32*)buffer)[j] += ((u32*)(IP_RT_ACCT_CPU(i) + offset))[j]; + } + return length; } - return length; + return 0; } #endif It also cures a bug in pointer aritmetics in IP_RT_ACCT_CPU macro, which will cause incorrect statistics output on SMP systems. -- BW, Arcady Stepanov (AS713-RIPE, AS28-RIPN).
Micronic on-line Network Operating Center. email:noc@mol.ru; phone: +7 095 2320012
========================================== All that we can do is just survive All that we can do to help ourselves Is stay alive... Rush, "Red Sector A" ========================================== - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |