#include <linux/proc_fs.h>
#include <linux/skbuff.h>
#include <linux/netfilter.h>
+#include <linux/seq_file.h>
#include <net/protocol.h>
#include "nf_internals.h"
static struct nf_logger *nf_logging[NPROTO]; /* = NULL */
static DEFINE_SPINLOCK(nf_log_lock);
+/* return EBUSY if somebody else is registered, EEXIST if the same logger
+ * is registred, 0 on success. */
int nf_log_register(int pf, struct nf_logger *logger)
{
int ret = -EBUSY;
+ if (pf >= NPROTO)
+ return -EINVAL;
+
/* Any setup of logging members must be done before
* substituting pointer. */
spin_lock(&nf_log_lock);
if (!nf_logging[pf]) {
rcu_assign_pointer(nf_logging[pf], logger);
ret = 0;
- }
+ } else if (nf_logging[pf] == logger)
+ ret = -EEXIST;
+
spin_unlock(&nf_log_lock);
return ret;
}
EXPORT_SYMBOL(nf_log_register);
-void nf_log_unregister_pf(int pf)
+int nf_log_unregister_pf(int pf)
{
+ if (pf >= NPROTO)
+ return -EINVAL;
+
spin_lock(&nf_log_lock);
nf_logging[pf] = NULL;
spin_unlock(&nf_log_lock);
/* Give time to concurrent readers. */
synchronize_net();
+
+ return 0;
}
EXPORT_SYMBOL(nf_log_unregister_pf);
{
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *pde;
+
pde = create_proc_entry("nf_log", S_IRUGO, proc_net_netfilter);
-#endif
if (!pde)
return -1;
pde->proc_fops = &nflog_file_ops;
-
+#endif
return 0;
}