Commit d5228a4f authored by Bart De Schuymer's avatar Bart De Schuymer Committed by David S. Miller

[NETFILTER] ebtables: Support nf_log API from ebt_log and ebt_ulog

This makes ebt_log and ebt_ulog use the new nf_log api.  This enables
the bridging packet filter to log packets e.g. via nfnetlink_log.
Signed-off-by: default avatarBart De Schuymer <bdschuym@pandora.be>
Signed-off-by: default avatarHarald Welte <laforge@netfilter.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 31836064
...@@ -196,9 +196,13 @@ config BRIDGE_EBT_LOG ...@@ -196,9 +196,13 @@ config BRIDGE_EBT_LOG
To compile it as a module, choose M here. If unsure, say N. To compile it as a module, choose M here. If unsure, say N.
config BRIDGE_EBT_ULOG config BRIDGE_EBT_ULOG
tristate "ebt: ulog support" tristate "ebt: ulog support (OBSOLETE)"
depends on BRIDGE_NF_EBTABLES depends on BRIDGE_NF_EBTABLES
help help
This option enables the old bridge-specific "ebt_ulog" implementation
which has been obsoleted by the new "nfnetlink_log" code (see
CONFIG_NETFILTER_NETLINK_LOG).
This option adds the ulog watcher, that you can use in any rule This option adds the ulog watcher, that you can use in any rule
in any ebtables table. The packet is passed to a userspace in any ebtables table. The packet is passed to a userspace
logging daemon using netlink multicast sockets. This differs logging daemon using netlink multicast sockets. This differs
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
* *
* Authors: * Authors:
* Bart De Schuymer <bdschuym@pandora.be> * Bart De Schuymer <bdschuym@pandora.be>
* Harald Welte <laforge@netfilter.org>
* *
* April, 2002 * April, 2002
* *
...@@ -10,6 +11,7 @@ ...@@ -10,6 +11,7 @@
#include <linux/netfilter_bridge/ebtables.h> #include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_log.h> #include <linux/netfilter_bridge/ebt_log.h>
#include <linux/netfilter.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/ip.h> #include <linux/ip.h>
#include <linux/if_arp.h> #include <linux/if_arp.h>
...@@ -55,27 +57,30 @@ static void print_MAC(unsigned char *p) ...@@ -55,27 +57,30 @@ static void print_MAC(unsigned char *p)
} }
#define myNIPQUAD(a) a[0], a[1], a[2], a[3] #define myNIPQUAD(a) a[0], a[1], a[2], a[3]
static void ebt_log(const struct sk_buff *skb, unsigned int hooknr, static void
const struct net_device *in, const struct net_device *out, ebt_log_packet(unsigned int pf, unsigned int hooknum,
const void *data, unsigned int datalen) const struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, const struct nf_loginfo *loginfo,
const char *prefix)
{ {
struct ebt_log_info *info = (struct ebt_log_info *)data; unsigned int bitmask;
char level_string[4] = "< >";
level_string[1] = '0' + info->loglevel;
spin_lock_bh(&ebt_log_lock); spin_lock_bh(&ebt_log_lock);
printk(level_string); printk("<%c>%s IN=%s OUT=%s MAC source = ", '0' + loginfo->u.log.level,
printk("%s IN=%s OUT=%s ", info->prefix, in ? in->name : "", prefix, in ? in->name : "", out ? out->name : "");
out ? out->name : "");
printk("MAC source = ");
print_MAC(eth_hdr(skb)->h_source); print_MAC(eth_hdr(skb)->h_source);
printk("MAC dest = "); printk("MAC dest = ");
print_MAC(eth_hdr(skb)->h_dest); print_MAC(eth_hdr(skb)->h_dest);
printk("proto = 0x%04x", ntohs(eth_hdr(skb)->h_proto)); printk("proto = 0x%04x", ntohs(eth_hdr(skb)->h_proto));
if ((info->bitmask & EBT_LOG_IP) && eth_hdr(skb)->h_proto == if (loginfo->type == NF_LOG_TYPE_LOG)
bitmask = loginfo->u.log.logflags;
else
bitmask = NF_LOG_MASK;
if ((bitmask & EBT_LOG_IP) && eth_hdr(skb)->h_proto ==
htons(ETH_P_IP)){ htons(ETH_P_IP)){
struct iphdr _iph, *ih; struct iphdr _iph, *ih;
...@@ -84,10 +89,9 @@ static void ebt_log(const struct sk_buff *skb, unsigned int hooknr, ...@@ -84,10 +89,9 @@ static void ebt_log(const struct sk_buff *skb, unsigned int hooknr,
printk(" INCOMPLETE IP header"); printk(" INCOMPLETE IP header");
goto out; goto out;
} }
printk(" IP SRC=%u.%u.%u.%u IP DST=%u.%u.%u.%u,", printk(" IP SRC=%u.%u.%u.%u IP DST=%u.%u.%u.%u, IP "
NIPQUAD(ih->saddr), NIPQUAD(ih->daddr)); "tos=0x%02X, IP proto=%d", NIPQUAD(ih->saddr),
printk(" IP tos=0x%02X, IP proto=%d", ih->tos, NIPQUAD(ih->daddr), ih->tos, ih->protocol);
ih->protocol);
if (ih->protocol == IPPROTO_TCP || if (ih->protocol == IPPROTO_TCP ||
ih->protocol == IPPROTO_UDP) { ih->protocol == IPPROTO_UDP) {
struct tcpudphdr _ports, *pptr; struct tcpudphdr _ports, *pptr;
...@@ -104,7 +108,7 @@ static void ebt_log(const struct sk_buff *skb, unsigned int hooknr, ...@@ -104,7 +108,7 @@ static void ebt_log(const struct sk_buff *skb, unsigned int hooknr,
goto out; goto out;
} }
if ((info->bitmask & EBT_LOG_ARP) && if ((bitmask & EBT_LOG_ARP) &&
((eth_hdr(skb)->h_proto == htons(ETH_P_ARP)) || ((eth_hdr(skb)->h_proto == htons(ETH_P_ARP)) ||
(eth_hdr(skb)->h_proto == htons(ETH_P_RARP)))) { (eth_hdr(skb)->h_proto == htons(ETH_P_RARP)))) {
struct arphdr _arph, *ah; struct arphdr _arph, *ah;
...@@ -144,6 +148,21 @@ static void ebt_log(const struct sk_buff *skb, unsigned int hooknr, ...@@ -144,6 +148,21 @@ static void ebt_log(const struct sk_buff *skb, unsigned int hooknr,
out: out:
printk("\n"); printk("\n");
spin_unlock_bh(&ebt_log_lock); spin_unlock_bh(&ebt_log_lock);
}
static void ebt_log(const struct sk_buff *skb, unsigned int hooknr,
const struct net_device *in, const struct net_device *out,
const void *data, unsigned int datalen)
{
struct ebt_log_info *info = (struct ebt_log_info *)data;
struct nf_loginfo li;
li.type = NF_LOG_TYPE_LOG;
li.u.log.level = info->loglevel;
li.u.log.logflags = info->bitmask;
nf_log_packet(PF_BRIDGE, hooknr, skb, in, out, &li, info->prefix);
} }
static struct ebt_watcher log = static struct ebt_watcher log =
...@@ -154,13 +173,32 @@ static struct ebt_watcher log = ...@@ -154,13 +173,32 @@ static struct ebt_watcher log =
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
static struct nf_logger ebt_log_logger = {
.name = "ebt_log",
.logfn = &ebt_log_packet,
.me = THIS_MODULE,
};
static int __init init(void) static int __init init(void)
{ {
return ebt_register_watcher(&log); int ret;
ret = ebt_register_watcher(&log);
if (ret < 0)
return ret;
if (nf_log_register(PF_BRIDGE, &ebt_log_logger) < 0) {
printk(KERN_WARNING "ebt_log: not logging via system console "
"since somebody else already registered for PF_INET\n");
/* we cannot make module load fail here, since otherwise
* ebtables userspace would abort */
}
return 0;
} }
static void __exit fini(void) static void __exit fini(void)
{ {
nf_log_unregister_logger(&ebt_log_logger);
ebt_unregister_watcher(&log); ebt_unregister_watcher(&log);
} }
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
* *
* Authors: * Authors:
* Bart De Schuymer <bdschuym@pandora.be> * Bart De Schuymer <bdschuym@pandora.be>
* Harald Welte <laforge@netfilter.org>
* *
* November, 2004 * November, 2004
* *
...@@ -115,14 +116,13 @@ static struct sk_buff *ulog_alloc_skb(unsigned int size) ...@@ -115,14 +116,13 @@ static struct sk_buff *ulog_alloc_skb(unsigned int size)
return skb; return skb;
} }
static void ebt_ulog(const struct sk_buff *skb, unsigned int hooknr, static void ebt_ulog_packet(unsigned int hooknr, const struct sk_buff *skb,
const struct net_device *in, const struct net_device *out, const struct net_device *in, const struct net_device *out,
const void *data, unsigned int datalen) const struct ebt_ulog_info *uloginfo, const char *prefix)
{ {
ebt_ulog_packet_msg_t *pm; ebt_ulog_packet_msg_t *pm;
size_t size, copy_len; size_t size, copy_len;
struct nlmsghdr *nlh; struct nlmsghdr *nlh;
struct ebt_ulog_info *uloginfo = (struct ebt_ulog_info *)data;
unsigned int group = uloginfo->nlgroup; unsigned int group = uloginfo->nlgroup;
ebt_ulog_buff_t *ub = &ulog_buffers[group]; ebt_ulog_buff_t *ub = &ulog_buffers[group];
spinlock_t *lock = &ub->lock; spinlock_t *lock = &ub->lock;
...@@ -216,6 +216,39 @@ static void ebt_ulog(const struct sk_buff *skb, unsigned int hooknr, ...@@ -216,6 +216,39 @@ static void ebt_ulog(const struct sk_buff *skb, unsigned int hooknr,
goto unlock; goto unlock;
} }
/* this function is registered with the netfilter core */
static void ebt_log_packet(unsigned int pf, unsigned int hooknum,
const struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, const struct nf_loginfo *li,
const char *prefix)
{
struct ebt_ulog_info loginfo;
if (!li || li->type != NF_LOG_TYPE_ULOG) {
loginfo.nlgroup = EBT_ULOG_DEFAULT_NLGROUP;
loginfo.cprange = 0;
loginfo.qthreshold = EBT_ULOG_DEFAULT_QTHRESHOLD;
loginfo.prefix[0] = '\0';
} else {
loginfo.nlgroup = li->u.ulog.group;
loginfo.cprange = li->u.ulog.copy_len;
loginfo.qthreshold = li->u.ulog.qthreshold;
strlcpy(loginfo.prefix, prefix, sizeof(loginfo.prefix));
}
ebt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix);
}
static void ebt_ulog(const struct sk_buff *skb, unsigned int hooknr,
const struct net_device *in, const struct net_device *out,
const void *data, unsigned int datalen)
{
struct ebt_ulog_info *uloginfo = (struct ebt_ulog_info *)data;
ebt_ulog_packet(hooknr, skb, in, out, uloginfo, NULL);
}
static int ebt_ulog_check(const char *tablename, unsigned int hookmask, static int ebt_ulog_check(const char *tablename, unsigned int hookmask,
const struct ebt_entry *e, void *data, unsigned int datalen) const struct ebt_entry *e, void *data, unsigned int datalen)
{ {
...@@ -240,6 +273,12 @@ static struct ebt_watcher ulog = { ...@@ -240,6 +273,12 @@ static struct ebt_watcher ulog = {
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
static struct nf_logger ebt_ulog_logger = {
.name = EBT_ULOG_WATCHER,
.logfn = &ebt_log_packet,
.me = THIS_MODULE,
};
static int __init init(void) static int __init init(void)
{ {
int i, ret = 0; int i, ret = 0;
...@@ -265,6 +304,13 @@ static int __init init(void) ...@@ -265,6 +304,13 @@ static int __init init(void)
else if ((ret = ebt_register_watcher(&ulog))) else if ((ret = ebt_register_watcher(&ulog)))
sock_release(ebtulognl->sk_socket); sock_release(ebtulognl->sk_socket);
if (nf_log_register(PF_BRIDGE, &ebt_ulog_logger) < 0) {
printk(KERN_WARNING "ebt_ulog: not logging via ulog "
"since somebody else already registered for PF_BRIDGE\n");
/* we cannot make module load fail here, since otherwise
* ebtables userspace would abort */
}
return ret; return ret;
} }
...@@ -273,6 +319,7 @@ static void __exit fini(void) ...@@ -273,6 +319,7 @@ static void __exit fini(void)
ebt_ulog_buff_t *ub; ebt_ulog_buff_t *ub;
int i; int i;
nf_log_unregister_logger(&ebt_ulog_logger);
ebt_unregister_watcher(&ulog); ebt_unregister_watcher(&ulog);
for (i = 0; i < EBT_ULOG_MAXNLGROUPS; i++) { for (i = 0; i < EBT_ULOG_MAXNLGROUPS; i++) {
ub = &ulog_buffers[i]; ub = &ulog_buffers[i];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment