diff options
author | Ondrej Zajicek <santiago@crfreenet.org> | 2011-04-07 11:31:56 +0200 |
---|---|---|
committer | Ondrej Zajicek <santiago@crfreenet.org> | 2011-04-07 11:42:13 +0200 |
commit | 4aef102be1e29d3450e53a20a6b2f96d50527139 (patch) | |
tree | f10dac200be3b6dce21829a3d21ac0d9941584da /sysdep | |
parent | 489c308a75b121f286cc8637ead8b2bf7bf896ec (diff) | |
download | bird-4aef102be1e29d3450e53a20a6b2f96d50527139.tar bird-4aef102be1e29d3450e53a20a6b2f96d50527139.zip |
Fixes KRT sync in BSD.
When buffer is too small (because of change between sysctls()),
needed is *not* changed.
Diffstat (limited to 'sysdep')
-rw-r--r-- | sysdep/bsd/krt-sock.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/sysdep/bsd/krt-sock.c b/sysdep/bsd/krt-sock.c index a4df52e..81f0013 100644 --- a/sysdep/bsd/krt-sock.c +++ b/sysdep/bsd/krt-sock.c @@ -620,9 +620,10 @@ static void krt_sysctl_scan(struct proto *p, pool *pool, byte **buf, size_t *bl, int cmd) { byte *next; - int mib[6], on; + int mib[6]; size_t obl, needed; struct ks_msg *m; + int retries = 3; mib[0] = CTL_NET; 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[5] = 0; + try: if (sysctl(mib, 6 , NULL , &needed, NULL, 0) < 0) - { - die("RT scan..."); - } + die("krt_sysctl_scan 1: %m"); 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"); } - on = needed; - if (sysctl(mib, 6 , *buf, &needed, NULL, 0) < 0) { - if (on != needed) return; /* The buffer size changed since last sysctl */ - die("RT scan 2"); + if (errno == ENOMEM) + { + /* 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) |