netfilter: log: nf_log_packet() as real unified interface
authorPablo Neira Ayuso <pablo@netfilter.org>
Wed, 18 Jun 2014 17:38:25 +0000 (19:38 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Fri, 27 Jun 2014 11:20:13 +0000 (13:20 +0200)
Before this patch, the nf_loginfo parameter specified the logging
configuration in case the specified default logger was loaded. This
patch updates the semantics of the nf_loginfo parameter in
nf_log_packet() which now indicates the logger that you explicitly
want to use.

Thus, nf_log_packet() is exposed as an unified interface which
internally routes the log message to the corresponding logger type
by family.

The module dependencies are expressed by the new nf_logger_find_get()
and nf_logger_put() functions which bump the logger module refcount.
Thus, you can not remove logger modules that are used by rules anymore.

Another important effect of this change is that the family specific
module is only loaded when required. Therefore, xt_LOG and nft_log
will just trigger the autoload of the nf_log_{ip,ip6} modules
according to the family.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/net/netfilter/nf_log.h
net/ipv4/netfilter/nf_log_ipv4.c
net/ipv6/netfilter/nf_log_ipv6.c
net/netfilter/nf_log.c
net/netfilter/nfnetlink_log.c
net/netfilter/xt_LOG.c

index bba354e78f49a3c8d385ad8f67c5f3d8537cd7ea..b82dd19b8f260767721430cc995e8d9dae9d98c0 100644 (file)
@@ -61,6 +61,12 @@ int nf_log_bind_pf(struct net *net, u_int8_t pf,
                   const struct nf_logger *logger);
 void nf_log_unbind_pf(struct net *net, u_int8_t pf);
 
+int nf_logger_find_get(int pf, enum nf_log_type type);
+void nf_logger_put(int pf, enum nf_log_type type);
+
+#define MODULE_ALIAS_NF_LOGGER(family, type) \
+       MODULE_ALIAS("nf-logger-" __stringify(family) "-" __stringify(type))
+
 /* Calls the registered backend logging function */
 __printf(8, 9)
 void nf_log_packet(struct net *net,
@@ -78,20 +84,6 @@ struct nf_log_buf *nf_log_buf_open(void);
 __printf(2, 3) int nf_log_buf_add(struct nf_log_buf *m, const char *f, ...);
 void nf_log_buf_close(struct nf_log_buf *m);
 
-void nf_log_ip_packet(struct net *net, u_int8_t pf,
-                     unsigned int hooknum, const struct sk_buff *skb,
-                     const struct net_device *in,
-                     const struct net_device *out,
-                     const struct nf_loginfo *loginfo,
-                     const char *prefix);
-
-void nf_log_ip6_packet(struct net *net, u_int8_t pf,
-                      unsigned int hooknum, const struct sk_buff *skb,
-                      const struct net_device *in,
-                      const struct net_device *out,
-                      const struct nf_loginfo *loginfo,
-                      const char *prefix);
-
 /* common logging functions */
 int nf_log_dump_udp_header(struct nf_log_buf *m, const struct sk_buff *skb,
                           u8 proto, int fragment, unsigned int offset);
index 7e69a401a29ee67705e53efb01cf6a68e3158aa5..078bdca1b607a167e05e7cf1bdfedccdd5aca92a 100644 (file)
@@ -306,12 +306,12 @@ fallback:
        nf_log_buf_add(m, " ");
 }
 
-void nf_log_ip_packet(struct net *net, u_int8_t pf,
-                     unsigned int hooknum, const struct sk_buff *skb,
-                     const struct net_device *in,
-                     const struct net_device *out,
-                     const struct nf_loginfo *loginfo,
-                     const char *prefix)
+static void nf_log_ip_packet(struct net *net, u_int8_t pf,
+                            unsigned int hooknum, const struct sk_buff *skb,
+                            const struct net_device *in,
+                            const struct net_device *out,
+                            const struct nf_loginfo *loginfo,
+                            const char *prefix)
 {
        struct nf_log_buf *m;
 
@@ -334,7 +334,6 @@ void nf_log_ip_packet(struct net *net, u_int8_t pf,
 
        nf_log_buf_close(m);
 }
-EXPORT_SYMBOL_GPL(nf_log_ip_packet);
 
 static struct nf_logger nf_ip_logger __read_mostly = {
        .name           = "nf_log_ipv4",
@@ -383,3 +382,4 @@ module_exit(nf_log_ipv4_exit);
 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
 MODULE_DESCRIPTION("Netfilter IPv4 packet logging");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS_NF_LOGGER(AF_INET, 0);
index 804060946d2bb6c89f67050d19952e8f95883581..7b17a0be93e7eccb2a26cd3294713d0f1112158d 100644 (file)
@@ -338,12 +338,12 @@ fallback:
        }
 }
 
-void nf_log_ip6_packet(struct net *net, u_int8_t pf,
-                      unsigned int hooknum, const struct sk_buff *skb,
-                      const struct net_device *in,
-                      const struct net_device *out,
-                      const struct nf_loginfo *loginfo,
-                      const char *prefix)
+static void nf_log_ip6_packet(struct net *net, u_int8_t pf,
+                             unsigned int hooknum, const struct sk_buff *skb,
+                             const struct net_device *in,
+                             const struct net_device *out,
+                             const struct nf_loginfo *loginfo,
+                             const char *prefix)
 {
        struct nf_log_buf *m;
 
@@ -366,7 +366,6 @@ void nf_log_ip6_packet(struct net *net, u_int8_t pf,
 
        nf_log_buf_close(m);
 }
-EXPORT_SYMBOL_GPL(nf_log_ip6_packet);
 
 static struct nf_logger nf_ip6_logger __read_mostly = {
        .name           = "nf_log_ipv6",
@@ -415,3 +414,4 @@ module_exit(nf_log_ipv6_exit);
 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
 MODULE_DESCRIPTION("Netfilter IPv4 packet logging");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS_NF_LOGGER(AF_INET6, 0);
index 0b6b2c874199abbac575496331fab22aa4153364..0b2161c689e0d5a267fcb79ed85491f3f90b0f73 100644 (file)
@@ -132,6 +132,41 @@ void nf_log_unbind_pf(struct net *net, u_int8_t pf)
 }
 EXPORT_SYMBOL(nf_log_unbind_pf);
 
+int nf_logger_find_get(int pf, enum nf_log_type type)
+{
+       struct nf_logger *logger;
+       int ret = -ENOENT;
+
+       logger = loggers[pf][type];
+       if (logger == NULL)
+               request_module("nf-logger-%u-%u", pf, type);
+
+       rcu_read_lock();
+       logger = rcu_dereference(loggers[pf][type]);
+       if (logger == NULL)
+               goto out;
+
+       if (logger && try_module_get(logger->me))
+               ret = 0;
+out:
+       rcu_read_unlock();
+       return ret;
+}
+EXPORT_SYMBOL_GPL(nf_logger_find_get);
+
+void nf_logger_put(int pf, enum nf_log_type type)
+{
+       struct nf_logger *logger;
+
+       BUG_ON(loggers[pf][type] == NULL);
+
+       rcu_read_lock();
+       logger = rcu_dereference(loggers[pf][type]);
+       module_put(logger->me);
+       rcu_read_unlock();
+}
+EXPORT_SYMBOL_GPL(nf_logger_put);
+
 void nf_log_packet(struct net *net,
                   u_int8_t pf,
                   unsigned int hooknum,
@@ -146,7 +181,11 @@ void nf_log_packet(struct net *net,
        const struct nf_logger *logger;
 
        rcu_read_lock();
-       logger = rcu_dereference(net->nf.nf_loggers[pf]);
+       if (loginfo != NULL)
+               logger = rcu_dereference(loggers[pf][loginfo->type]);
+       else
+               logger = rcu_dereference(net->nf.nf_loggers[pf]);
+
        if (logger) {
                va_start(args, fmt);
                vsnprintf(prefix, sizeof(prefix), fmt, args);
index 160bb8ea99234b7172e9a8d6fecd44960331ef30..a11c5ff2f720187418e22ed602119651672bb717 100644 (file)
@@ -1106,6 +1106,9 @@ MODULE_DESCRIPTION("netfilter userspace logging");
 MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_ULOG);
+MODULE_ALIAS_NF_LOGGER(AF_INET, 1);
+MODULE_ALIAS_NF_LOGGER(AF_INET6, 1);
+MODULE_ALIAS_NF_LOGGER(AF_BRIDGE, 1);
 
 module_init(nfnetlink_log_init);
 module_exit(nfnetlink_log_fini);
index 5a6bd60e20d668ed1add65ee347ffffe990ef68f..00eb49196e75f799720b140620c18db5e1bb8bdd 100644 (file)
@@ -39,17 +39,8 @@ log_tg(struct sk_buff *skb, const struct xt_action_param *par)
        li.u.log.level = loginfo->level;
        li.u.log.logflags = loginfo->logflags;
 
-       if (par->family == NFPROTO_IPV4)
-               nf_log_ip_packet(net, NFPROTO_IPV4, par->hooknum, skb, par->in,
-                                par->out, &li, loginfo->prefix);
-#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
-       else if (par->family == NFPROTO_IPV6)
-               nf_log_ip6_packet(net, NFPROTO_IPV6, par->hooknum, skb, par->in,
-                                 par->out, &li, loginfo->prefix);
-#endif
-       else
-               WARN_ON_ONCE(1);
-
+       nf_log_packet(net, par->family, par->hooknum, skb, par->in, par->out,
+                     &li, loginfo->prefix);
        return XT_CONTINUE;
 }
 
@@ -70,7 +61,12 @@ static int log_tg_check(const struct xt_tgchk_param *par)
                return -EINVAL;
        }
 
-       return 0;
+       return nf_logger_find_get(par->family, NF_LOG_TYPE_LOG);
+}
+
+static void log_tg_destroy(const struct xt_tgdtor_param *par)
+{
+       nf_logger_put(par->family, NF_LOG_TYPE_LOG);
 }
 
 static struct xt_target log_tg_regs[] __read_mostly = {
@@ -80,6 +76,7 @@ static struct xt_target log_tg_regs[] __read_mostly = {
                .target         = log_tg,
                .targetsize     = sizeof(struct xt_log_info),
                .checkentry     = log_tg_check,
+               .destroy        = log_tg_destroy,
                .me             = THIS_MODULE,
        },
 #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
@@ -89,6 +86,7 @@ static struct xt_target log_tg_regs[] __read_mostly = {
                .target         = log_tg,
                .targetsize     = sizeof(struct xt_log_info),
                .checkentry     = log_tg_check,
+               .destroy        = log_tg_destroy,
                .me             = THIS_MODULE,
        },
 #endif