Path: csiph.com!x330-a1.tempe.blueboxinc.net!usenet.pasdenom.info!news.albasani.net!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail From: Rainer Weikusat Newsgroups: comp.os.linux.development.apps Subject: connection tracking accounting design glitch Date: Tue, 10 Jan 2012 16:16:42 +0000 Lines: 38 Message-ID: <87wr8zzg5x.fsf@sapphire.mobileactivedefense.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: individual.net nYMnoH9F3Hv+seqSj0ly1wVAWvGX3XtaXU8oSh+F90RCufJas= Cancel-Lock: sha1:EP2g1tf7+MPfxcza/k0ig/ylWo8= sha1:g9+IJ17/PVwCZ3nIrhTuqaPV5Fg= User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.2 (gnu/linux) Xref: x330-a1.tempe.blueboxinc.net comp.os.linux.development.apps:384 The kernel loads nfnetlink sub-protocol modules upon reception of the first message for a particular sub-protocol. An application listening for connection tracking accounting events via libnetfilter_conntrack (tested with 0.9.1) usually doesn't ever send anything to the kernel and this implies that such an application won't ever receive connection tracking accounting events except if the nf_conntrack_netlink module either was already loaded or gets loaded as side effect of operations performed by some other application, eg, by manually executing a conntrack -L. It is possible to work around this by sending some nonsense message to the kernel and thus causing the module to be loaded before starting to listen for accounting events. Below is some example (GPL) code which actually does this. ---------------------------- static void force_module_load(struct nfct_handle *h) { /* The kernel loads nfnetlink sub protocol modules upon receipt of a message of the corresponding type. In order to receive CTACCT messages, it is therefore necessary to send something to the kernel which triggers loading of the nf_conntrack_netlink module. */ struct nf_conntrack *nfct; int rc; nfct = nfct_new(); nfct || sys_die(__func__, "nfct_new", errno); nfct_set_attr_u8(nfct, ATTR_L3PROTO, AF_INET); rc = nfct_query(h, NFCT_Q_CREATE, nfct); if (rc == -1 && errno != EINVAL) sys_die(__func__, "nfct_query", errno); /* EINVAL expected */ nfct_destroy(nfct); }