diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2012-08-13 19:49:58 +0200 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2012-08-13 19:50:09 +0200 |
commit | 8b15e485c0d5f4a1e56b2148a34995ed1fa9e95b (patch) | |
tree | 5512712e5fbe21eef57ab46f644e71f05c48fe5f /src | |
parent | 830fcfda1900444ecfc9102415fa46fe637ddbb3 (diff) |
iftable: fix incomplete list of interfaces via nlif_query
RTM_GETLINK with NLM_F_DUMP returns a multi-part netlink message.
The existing code only handled the first message of it, thus,
ignoring the remaining interfaces.
This is the cause of the following bug in conntrackd:
[Thu Aug 9 14:14:23 2012] (pid=3819) [notice] -- starting in daemon mode --
[Thu Aug 9 14:14:23 2012] (pid=3819) [ERROR] no dedicated links available!
[Thu Aug 9 14:14:23 2012] (pid=3819) [ERROR] no dedicated links available!
[Thu Aug 9 14:14:23 2012] (pid=3819) [ERROR] no dedicated links available!
[Thu Aug 9 14:19:54 2012] (pid=3819) [notice] ---- shutdown received ----
Thanks to Jan Engelhardt for providing useful pointer to address the
problem.
Reported-by: Arturo Borrero <aborrero@cica.es>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/iftable.c | 12 | ||||
-rw-r--r-- | src/rtnl.c | 9 | ||||
-rw-r--r-- | src/rtnl.h | 1 |
3 files changed, 21 insertions, 1 deletions
diff --git a/src/iftable.c b/src/iftable.c index 959249a..0325335 100644 --- a/src/iftable.c +++ b/src/iftable.c @@ -295,6 +295,16 @@ int nlif_catch(struct nlif_handle *h) return -1; } +static int nlif_catch_multi(struct nlif_handle *h) +{ + assert(h != NULL); + + if (h->rtnl_handle) + return rtnl_receive_multi(h->rtnl_handle); + + return -1; +} + /** * nlif_query - request a dump of interfaces available in the system * @h: pointer to a valid nlif_handler @@ -306,7 +316,7 @@ int nlif_query(struct nlif_handle *h) if (rtnl_dump_type(h->rtnl_handle, RTM_GETLINK) < 0) return -1; - return nlif_catch(h); + return nlif_catch_multi(h); } /** Returns socket descriptor for the netlink socket @@ -193,6 +193,15 @@ int rtnl_receive(struct rtnl_handle *rtnl_handle) return 1; } +int rtnl_receive_multi(struct rtnl_handle *rtnl_handle) +{ + while (1) { + if (rtnl_receive(rtnl_handle) <= 0) + break; + } + return 1; +} + /* rtnl_open - constructor of rtnetlink module */ struct rtnl_handle *rtnl_open(void) { @@ -32,5 +32,6 @@ int rtnl_dump_type(struct rtnl_handle *rtnl_handle, unsigned int type); struct rtnl_handle *rtnl_open(void); void rtnl_close(struct rtnl_handle *rtnl_handle); int rtnl_receive(struct rtnl_handle *rtnl_handle); +int rtnl_receive_multi(struct rtnl_handle *rtnl_handle); #endif |