fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / net / netfilter / nfnetlink_queue.c
index 2cf5fb8..a88a017 100644 (file)
@@ -349,21 +349,22 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
        struct sk_buff *entskb = entry->skb;
        struct net_device *indev;
        struct net_device *outdev;
-       unsigned int tmp_uint;
+       __be32 tmp_uint;
 
        QDEBUG("entered\n");
 
        /* all macros expand to constant values at compile time */
-       size =    NLMSG_SPACE(sizeof(struct nfqnl_msg_packet_hdr))
-               + NLMSG_SPACE(sizeof(u_int32_t))        /* ifindex */
-               + NLMSG_SPACE(sizeof(u_int32_t))        /* ifindex */
+       size =    NLMSG_SPACE(sizeof(struct nfgenmsg)) +
+               + NFA_SPACE(sizeof(struct nfqnl_msg_packet_hdr))
+               + NFA_SPACE(sizeof(u_int32_t))  /* ifindex */
+               + NFA_SPACE(sizeof(u_int32_t))  /* ifindex */
 #ifdef CONFIG_BRIDGE_NETFILTER
-               + NLMSG_SPACE(sizeof(u_int32_t))        /* ifindex */
-               + NLMSG_SPACE(sizeof(u_int32_t))        /* ifindex */
+               + NFA_SPACE(sizeof(u_int32_t))  /* ifindex */
+               + NFA_SPACE(sizeof(u_int32_t))  /* ifindex */
 #endif
-               + NLMSG_SPACE(sizeof(u_int32_t))        /* mark */
-               + NLMSG_SPACE(sizeof(struct nfqnl_msg_packet_hw))
-               + NLMSG_SPACE(sizeof(struct nfqnl_msg_packet_timestamp));
+               + NFA_SPACE(sizeof(u_int32_t))  /* mark */
+               + NFA_SPACE(sizeof(struct nfqnl_msg_packet_hw))
+               + NFA_SPACE(sizeof(struct nfqnl_msg_packet_timestamp));
 
        outdev = entinf->outdev;
 
@@ -376,9 +377,9 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
                break;
        
        case NFQNL_COPY_PACKET:
-               if (entskb->ip_summed == CHECKSUM_HW &&
-                   (*errp = skb_checksum_help(entskb,
-                                              outdev == NULL))) {
+               if ((entskb->ip_summed == CHECKSUM_PARTIAL ||
+                    entskb->ip_summed == CHECKSUM_COMPLETE) &&
+                   (*errp = skb_checksum_help(entskb))) {
                        spin_unlock_bh(&queue->lock);
                        return NULL;
                }
@@ -388,7 +389,7 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
                else
                        data_len = queue->copy_range;
                
-               size += NLMSG_SPACE(data_len);
+               size += NFA_SPACE(data_len);
                break;
        
        default:
@@ -413,7 +414,7 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
        nfmsg->res_id = htons(queue->queue_num);
 
        pmsg.packet_id          = htonl(entry->id);
-       pmsg.hw_protocol        = htons(entskb->protocol);
+       pmsg.hw_protocol        = entskb->protocol;
        pmsg.hook               = entinf->hook;
 
        NFA_PUT(skb, NFQA_PACKET_HDR, sizeof(pmsg), &pmsg);
@@ -479,8 +480,8 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
 #endif
        }
 
-       if (entskb->nfmark) {
-               tmp_uint = htonl(entskb->nfmark);
+       if (entskb->mark) {
+               tmp_uint = htonl(entskb->mark);
                NFA_PUT(skb, NFQA_MARK, sizeof(u_int32_t), &tmp_uint);
        }
 
@@ -488,10 +489,9 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
            && entskb->dev->hard_header_parse) {
                struct nfqnl_msg_packet_hw phw;
 
-               phw.hw_addrlen =
-                       entskb->dev->hard_header_parse(entskb,
+               int len = entskb->dev->hard_header_parse(entskb,
                                                           phw.hw_addr);
-               phw.hw_addrlen = htons(phw.hw_addrlen);
+               phw.hw_addrlen = htons(len);
                NFA_PUT(skb, NFQA_HWADDR, sizeof(phw), &phw);
        }
 
@@ -583,7 +583,7 @@ nfqnl_enqueue_packet(struct sk_buff *skb, struct nf_info *info,
                 queue->queue_dropped++;
                status = -ENOSPC;
                if (net_ratelimit())
-                         printk(KERN_WARNING "ip_queue: full at %d entries, "
+                         printk(KERN_WARNING "nf_queue: full at %d entries, "
                                 "dropping packets(s). Dropped: %d\n", 
                                 queue->queue_total, queue->queue_dropped);
                goto err_out_free_nskb;
@@ -621,9 +621,10 @@ nfqnl_mangle(void *data, int data_len, struct nfqnl_queue_entry *e)
        int diff;
 
        diff = data_len - e->skb->len;
-       if (diff < 0)
-               skb_trim(e->skb, data_len);
-       else if (diff > 0) {
+       if (diff < 0) {
+               if (pskb_trim(e->skb, data_len))
+                       return -ENOMEM;
+       } else if (diff > 0) {
                if (data_len > 0xFFFF)
                        return -EINVAL;
                if (diff > skb_tailroom(e->skb)) {
@@ -634,7 +635,7 @@ nfqnl_mangle(void *data, int data_len, struct nfqnl_queue_entry *e)
                                                 diff,
                                                 GFP_ATOMIC);
                        if (newskb == NULL) {
-                               printk(KERN_WARNING "ip_queue: OOM "
+                               printk(KERN_WARNING "nf_queue: OOM "
                                      "in mangle, dropping packet\n");
                                return -ENOMEM;
                        }
@@ -679,11 +680,19 @@ dev_cmp(struct nfqnl_queue_entry *entry, unsigned long ifindex)
        if (entinf->indev)
                if (entinf->indev->ifindex == ifindex)
                        return 1;
-                       
        if (entinf->outdev)
                if (entinf->outdev->ifindex == ifindex)
                        return 1;
-
+#ifdef CONFIG_BRIDGE_NETFILTER
+       if (entry->skb->nf_bridge) {
+               if (entry->skb->nf_bridge->physindev &&
+                   entry->skb->nf_bridge->physindev->ifindex == ifindex)
+                       return 1;
+               if (entry->skb->nf_bridge->physoutdev &&
+                   entry->skb->nf_bridge->physoutdev->ifindex == ifindex)
+                       return 1;
+       }
+#endif
        return 0;
 }
 
@@ -825,8 +834,8 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb,
        }
 
        if (nfqa[NFQA_MARK-1])
-               entry->skb->nfmark = ntohl(*(u_int32_t *)
-                                          NFA_DATA(nfqa[NFQA_MARK-1]));
+               entry->skb->mark = ntohl(*(__be32 *)
+                                        NFA_DATA(nfqa[NFQA_MARK-1]));
                
        issue_verdict(entry, verdict);
        instance_put(queue);
@@ -938,6 +947,14 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
                                ntohl(params->copy_range));
        }
 
+       if (nfqa[NFQA_CFG_QUEUE_MAXLEN-1]) {
+               __be32 *queue_maxlen;
+               queue_maxlen = NFA_DATA(nfqa[NFQA_CFG_QUEUE_MAXLEN-1]);
+               spin_lock_bh(&queue->lock);
+               queue->queue_maxlen = ntohl(*queue_maxlen);
+               spin_unlock_bh(&queue->lock);
+       }
+
 out_put:
        instance_put(queue);
        return ret;
@@ -1070,17 +1087,13 @@ static struct file_operations nfqnl_file_ops = {
 
 #endif /* PROC_FS */
 
-static int
-init_or_cleanup(int init)
+static int __init nfnetlink_queue_init(void)
 {
        int i, status = -ENOMEM;
 #ifdef CONFIG_PROC_FS
        struct proc_dir_entry *proc_nfqueue;
 #endif
        
-       if (!init)
-               goto cleanup;
-
        for (i = 0; i < INSTANCE_BUCKETS; i++)
                INIT_HLIST_HEAD(&instance_table[i]);
 
@@ -1100,31 +1113,26 @@ init_or_cleanup(int init)
 #endif
 
        register_netdevice_notifier(&nfqnl_dev_notifier);
-
        return status;
 
-cleanup:
-       nf_unregister_queue_handlers(&nfqh);
-       unregister_netdevice_notifier(&nfqnl_dev_notifier);
 #ifdef CONFIG_PROC_FS
-       remove_proc_entry("nfnetlink_queue", proc_net_netfilter);
 cleanup_subsys:
-#endif 
        nfnetlink_subsys_unregister(&nfqnl_subsys);
+#endif
 cleanup_netlink_notifier:
        netlink_unregister_notifier(&nfqnl_rtnl_notifier);
        return status;
 }
 
-static int __init init(void)
-{
-       
-       return init_or_cleanup(1);
-}
-
-static void __exit fini(void)
+static void __exit nfnetlink_queue_fini(void)
 {
-       init_or_cleanup(0);
+       nf_unregister_queue_handlers(&nfqh);
+       unregister_netdevice_notifier(&nfqnl_dev_notifier);
+#ifdef CONFIG_PROC_FS
+       remove_proc_entry("nfnetlink_queue", proc_net_netfilter);
+#endif
+       nfnetlink_subsys_unregister(&nfqnl_subsys);
+       netlink_unregister_notifier(&nfqnl_rtnl_notifier);
 }
 
 MODULE_DESCRIPTION("netfilter packet queue handler");
@@ -1132,5 +1140,5 @@ MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_QUEUE);
 
-module_init(init);
-module_exit(fini);
+module_init(nfnetlink_queue_init);
+module_exit(nfnetlink_queue_fini);