summaryrefslogtreecommitdiffstats
path: root/sbin/ipfw
diff options
context:
space:
mode:
authorluigi <luigi@FreeBSD.org>2010-03-04 16:56:36 +0000
committerluigi <luigi@FreeBSD.org>2010-03-04 16:56:36 +0000
commit7053937fa6b7489260f32ab5250e908f6b721c6c (patch)
treed80e9fcfcaa025df57ed1c13a72ae2f0017a0177 /sbin/ipfw
parentb486493f31704510ea9ba1a97eb1f59f7b828fd1 (diff)
downloadFreeBSD-src-7053937fa6b7489260f32ab5250e908f6b721c6c.zip
FreeBSD-src-7053937fa6b7489260f32ab5250e908f6b721c6c.tar.gz
make the listing of queues/pipes/schedulers handle the case of
data size increasing while we fetch the info.
Diffstat (limited to 'sbin/ipfw')
-rw-r--r--sbin/ipfw/dummynet.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/sbin/ipfw/dummynet.c b/sbin/ipfw/dummynet.c
index dbbf011..1cc6832 100644
--- a/sbin/ipfw/dummynet.c
+++ b/sbin/ipfw/dummynet.c
@@ -1241,8 +1241,8 @@ dummynet_flush(void)
void
dummynet_list(int ac, char *av[], int show_counters)
{
- struct dn_id oid, *x;
- int ret, l = sizeof(oid);
+ struct dn_id oid, *x = NULL;
+ int ret, i, l = sizeof(oid);
oid_fill(&oid, l, DN_CMD_GET, DN_API_VERSION);
switch (co.do_pipe) {
@@ -1256,14 +1256,29 @@ dummynet_list(int ac, char *av[], int show_counters)
oid.subtype = DN_SCH; /* list sched */
break;
}
+
+ /* Request the buffer size (in oid.id)*/
ret = do_cmd(-IP_DUMMYNET3, &oid, (uintptr_t)&l);
// printf("%s returns %d need %d\n", __FUNCTION__, ret, oid.id);
if (ret != 0 || oid.id <= sizeof(oid))
return;
- l = oid.id;
- x = safe_calloc(1, l);
+
+ /* Try max 10 times
+ * Buffer is correct if l != 0.
+ * If l == 0 no buffer is sent, maybe because kernel requires
+ * a greater buffer, so try with the new size in x->id.
+ */
+ for (i = 0, l = oid.id; i < 10; i++, l = x->id) {
+ x = safe_realloc(x, l);
*x = oid;
ret = do_cmd(-IP_DUMMYNET3, x, (uintptr_t)&l);
+
+ if (ret != 0 || x->id <= sizeof(oid))
+ return;
+
+ if (l != 0)
+ break; /* ok */
+ }
// printf("%s returns %d need %d\n", __FUNCTION__, ret, oid.id);
// XXX filter on ac, av
list_pipes(x, O_NEXT(x, l));
OpenPOWER on IntegriCloud