alistair23-linux/net/bridge/netfilter/nf_log_bridge.c
Pablo Neira Ayuso 960649d192 netfilter: bridge: add generic packet logger
This adds the generic plain text packet loggger for bridged packets.
It routes the logging message to the real protocol packet logger.
I decided not to refactor the ebt_log code for two reasons:

1) The ebt_log output is not consistent with the IPv4 and IPv6
   Netfilter packet loggers. The output is different for no good
   reason and it adds redundant code to handle packet logging.

2) To avoid breaking backward compatibility for applications
   outthere that are parsing the specific ebt_log output, the ebt_log
   output has been left as is. So only nftables will use the new
   consistent logging format for logged bridged packets.

More decisions coming in this patch:

1) This also removes ebt_log as default logger for bridged packets.
   Thus, nf_log_packet() routes packet to this new packet logger
   instead. This doesn't break backward compatibility since
   nf_log_packet() is not used to log packets in plain text format
   from anywhere in the ebtables/netfilter bridge code.

2) The new bridge packet logger also performs a lazy request to
   register the real IPv4, ARP and IPv6 netfilter packet loggers.
   If the real protocol logger is no available (not compiled or the
   module is not available in the system, not packet logging happens.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2014-06-27 13:20:47 +02:00

97 lines
2.5 KiB
C

/*
* (C) 2014 by Pablo Neira Ayuso <pablo@netfilter.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/skbuff.h>
#include <linux/if_bridge.h>
#include <linux/ip.h>
#include <net/route.h>
#include <linux/netfilter.h>
#include <net/netfilter/nf_log.h>
static void nf_log_bridge_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)
{
switch (eth_hdr(skb)->h_proto) {
case htons(ETH_P_IP):
nf_log_packet(net, NFPROTO_IPV4, hooknum, skb, in, out,
loginfo, "%s", prefix);
break;
case htons(ETH_P_IPV6):
nf_log_packet(net, NFPROTO_IPV6, hooknum, skb, in, out,
loginfo, "%s", prefix);
break;
case htons(ETH_P_ARP):
case htons(ETH_P_RARP):
nf_log_packet(net, NFPROTO_ARP, hooknum, skb, in, out,
loginfo, "%s", prefix);
break;
}
}
static struct nf_logger nf_bridge_logger __read_mostly = {
.name = "nf_log_bridge",
.type = NF_LOG_TYPE_LOG,
.logfn = nf_log_bridge_packet,
.me = THIS_MODULE,
};
static int __net_init nf_log_bridge_net_init(struct net *net)
{
nf_log_set(net, NFPROTO_BRIDGE, &nf_bridge_logger);
return 0;
}
static void __net_exit nf_log_bridge_net_exit(struct net *net)
{
nf_log_unset(net, &nf_bridge_logger);
}
static struct pernet_operations nf_log_bridge_net_ops = {
.init = nf_log_bridge_net_init,
.exit = nf_log_bridge_net_exit,
};
static int __init nf_log_bridge_init(void)
{
int ret;
/* Request to load the real packet loggers. */
nf_logger_request_module(NFPROTO_IPV4, NF_LOG_TYPE_LOG);
nf_logger_request_module(NFPROTO_IPV6, NF_LOG_TYPE_LOG);
nf_logger_request_module(NFPROTO_ARP, NF_LOG_TYPE_LOG);
ret = register_pernet_subsys(&nf_log_bridge_net_ops);
if (ret < 0)
return ret;
nf_log_register(NFPROTO_BRIDGE, &nf_bridge_logger);
return 0;
}
static void __exit nf_log_bridge_exit(void)
{
unregister_pernet_subsys(&nf_log_bridge_net_ops);
nf_log_unregister(&nf_bridge_logger);
}
module_init(nf_log_bridge_init);
module_exit(nf_log_bridge_exit);
MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>");
MODULE_DESCRIPTION("Netfilter bridge packet logging");
MODULE_LICENSE("GPL");
MODULE_ALIAS_NF_LOGGER(AF_BRIDGE, 0);