[Bug 9106] ip neigh flush dev eth0 is hanging
bugzilla-daemon at bugzilla.ubuntu.com
bugzilla-daemon at bugzilla.ubuntu.com
Tue Aug 2 08:58:16 UTC 2005
Please do not reply to this email. You can add comments at
http://bugzilla.ubuntu.com/show_bug.cgi?id=9106
Ubuntu | linux
------- Additional Comments From herbert at linuxhacker.at 2005-08-02 09:58 UTC -------
If this bug is not a kernel problem, then this could be a iproute problem. I
found this workaround.
**Patch for iproute**
Another possible solution is a change of iproute, to avoid the loop situation.
The source code for flush looks like::
for (;;) {
if (rtnl_wilddump_request(&rth, filter.family,
RTM_GETNEIGH) < 0) {
perror("Cannot send dump request");
exit(1);
}
filter.flushed = 0;
if (rtnl_dump_filter(&rth, print_neigh, stdout, NULL,
NULL) < 0) {
fprintf(stderr, "Flush terminated\n");
exit(1);
}
if (filter.flushed == 0) {
if (round == 0) {
fprintf(stderr, "Nothing to flush.\n");
} else if (show_stats)
printf("*** Flush is complete after %d
round%s ***\n", round, round>1?"s":"");
fflush(stdout);
return 0;
}
round++;
if (flush_update() < 0)
exit(1);
if (show_stats) {
printf("\n*** Round %d, deleting %d entries
***\n", round, filter.flushed);
fflush(stdout);
}
}
}
There is no way out of the loop, if the arp entry cannot be flushed. The 'for
(;;)' construction can be found in other .c files. In iproute.c there is a exit
construction like the following patch::
--- ip/ipneigh.c.orig 2005-07-26 16:10:40.850647298 +0200
+++ ip/ipneigh.c 2005-07-26 16:11:09.302486025 +0200
@@ -410,6 +410,7 @@
filter.flushe = sizeof(flushb);
filter.rth = &rth;
filter.state &= ~NUD_FAILED;
+ time_t start = time(0);
for (;;) {
if (rtnl_wilddump_request(&rth, filter.family,
RTM_GETNEIGH) < 0) {
@@ -432,6 +433,12 @@
round++;
if (flush_update() < 0)
exit(1);
+ if (time(0) - start > 30) {
+ printf("\n*** Flush not completed after %ld
seconds, %d entries remain ***\n",
+ time(0) - start, filter.flushed);
+ exit(1);
+ }
+
if (show_stats) {
printf("\n*** Round %d, deleting %d entries
***\n", round, filter.flushed);
fflush(stdout);
This is not ideal, but avoid a endless loop. The output of 'ip -s -4 neigh
flush dev eth1' looks like::
...
*** Round 57934, deleting 1 entries ***
*** Round 57935, deleting 1 entries ***
*** Round 57936, deleting 1 entries ***
*** Flush not completed after 31 seconds, 1 entries remain ***
The disadvantage of this solution is the 100% CPU consum for 30 seconds.
--
Configure bugmail: http://bugzilla.ubuntu.com/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug, or are watching the QA contact.
More information about the kernel-bugs
mailing list