]> err.no Git - linux-2.6/blobdiff - net/bridge/netfilter/ebt_ulog.c
Merge with /pub/scm/linux/kernel/git/torvalds/linux-2.6.git
[linux-2.6] / net / bridge / netfilter / ebt_ulog.c
index 561d75c8ed5a414337011d6038defd36b8a0ce99..ce617b3dbbb8dbb4c9a77cfcfe70c25c5748f304 100644 (file)
@@ -3,6 +3,7 @@
  *
  *     Authors:
  *     Bart De Schuymer <bdschuym@pandora.be>
+ *     Harald Welte <laforge@netfilter.org>
  *
  *  November, 2004
  *
@@ -78,8 +79,8 @@ static void ulog_send(unsigned int nlgroup)
        if (ub->qlen > 1)
                ub->lastnlh->nlmsg_type = NLMSG_DONE;
 
-       NETLINK_CB(ub->skb).dst_groups = 1 << nlgroup;
-       netlink_broadcast(ebtulognl, ub->skb, 0, 1 << nlgroup, GFP_ATOMIC);
+       NETLINK_CB(ub->skb).dst_group = nlgroup + 1;
+       netlink_broadcast(ebtulognl, ub->skb, 0, nlgroup + 1, GFP_ATOMIC);
 
        ub->qlen = 0;
        ub->skb = NULL;
@@ -115,14 +116,13 @@ static struct sk_buff *ulog_alloc_skb(unsigned int size)
        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 void *data, unsigned int datalen)
+   const struct ebt_ulog_info *uloginfo, const char *prefix)
 {
        ebt_ulog_packet_msg_t *pm;
        size_t size, copy_len;
        struct nlmsghdr *nlh;
-       struct ebt_ulog_info *uloginfo = (struct ebt_ulog_info *)data;
        unsigned int group = uloginfo->nlgroup;
        ebt_ulog_buff_t *ub = &ulog_buffers[group];
        spinlock_t *lock = &ub->lock;
@@ -162,7 +162,7 @@ static void ebt_ulog(const struct sk_buff *skb, unsigned int hooknr,
        pm->version = EBT_ULOG_VERSION;
        do_gettimeofday(&pm->stamp);
        if (ub->qlen == 1)
-               ub->skb->stamp = pm->stamp;
+               skb_set_timestamp(ub->skb, &pm->stamp);
        pm->data_len = copy_len;
        pm->mark = skb->nfmark;
        pm->hook = hooknr;
@@ -216,6 +216,39 @@ alloc_failure:
        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,
    const struct ebt_entry *e, void *data, unsigned int datalen)
 {
@@ -240,6 +273,12 @@ static struct ebt_watcher ulog = {
        .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)
 {
        int i, ret = 0;
@@ -258,12 +297,20 @@ static int __init init(void)
                spin_lock_init(&ulog_buffers[i].lock);
        }
 
-       ebtulognl = netlink_kernel_create(NETLINK_NFLOG, NULL, THIS_MODULE);
+       ebtulognl = netlink_kernel_create(NETLINK_NFLOG, EBT_ULOG_MAXNLGROUPS,
+                                         NULL, THIS_MODULE);
        if (!ebtulognl)
                ret = -ENOMEM;
        else if ((ret = ebt_register_watcher(&ulog)))
                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;
 }
 
@@ -272,6 +319,7 @@ static void __exit fini(void)
        ebt_ulog_buff_t *ub;
        int i;
 
+       nf_log_unregister_logger(&ebt_ulog_logger);
        ebt_unregister_watcher(&ulog);
        for (i = 0; i < EBT_ULOG_MAXNLGROUPS; i++) {
                ub = &ulog_buffers[i];