Fixes KRT sync in BSD.

When buffer is too small (because of change between sysctls()),
needed is *not* changed.
This commit is contained in:
Ondrej Zajicek 2011-04-07 11:31:56 +02:00
parent 489c308a75
commit 4aef102be1

View file

@ -620,9 +620,10 @@ static void
krt_sysctl_scan(struct proto *p, pool *pool, byte **buf, size_t *bl, int cmd) krt_sysctl_scan(struct proto *p, pool *pool, byte **buf, size_t *bl, int cmd)
{ {
byte *next; byte *next;
int mib[6], on; int mib[6];
size_t obl, needed; size_t obl, needed;
struct ks_msg *m; struct ks_msg *m;
int retries = 3;
mib[0] = CTL_NET; mib[0] = CTL_NET;
mib[1] = PF_ROUTE; mib[1] = PF_ROUTE;
@ -631,10 +632,9 @@ krt_sysctl_scan(struct proto *p, pool *pool, byte **buf, size_t *bl, int cmd)
mib[4] = cmd; mib[4] = cmd;
mib[5] = 0; mib[5] = 0;
try:
if (sysctl(mib, 6 , NULL , &needed, NULL, 0) < 0) if (sysctl(mib, 6 , NULL , &needed, NULL, 0) < 0)
{ die("krt_sysctl_scan 1: %m");
die("RT scan...");
}
obl = *bl; obl = *bl;
@ -647,12 +647,18 @@ krt_sysctl_scan(struct proto *p, pool *pool, byte **buf, size_t *bl, int cmd)
if ((*buf = mb_alloc(pool, *bl)) == NULL) die("RT scan buf alloc"); if ((*buf = mb_alloc(pool, *bl)) == NULL) die("RT scan buf alloc");
} }
on = needed;
if (sysctl(mib, 6 , *buf, &needed, NULL, 0) < 0) if (sysctl(mib, 6 , *buf, &needed, NULL, 0) < 0)
{ {
if (on != needed) return; /* The buffer size changed since last sysctl */ if (errno == ENOMEM)
die("RT scan 2"); {
/* The buffer size changed since last sysctl ('needed' is not changed) */
if (retries--)
goto try;
log(L_ERR "KRT: Route scan failed");
return;
}
die("krt_sysctl_scan 2: %m");
} }
for (next = *buf; next < (*buf + needed); next += m->rtm.rtm_msglen) for (next = *buf; next < (*buf + needed); next += m->rtm.rtm_msglen)