]> err.no Git - linux-2.6/blobdiff - net/netfilter/nfnetlink_queue.c
Merge branch 'linux-2.6'
[linux-2.6] / net / netfilter / nfnetlink_queue.c
index 1c34668588f172c9c1b874394cce51789e1434f8..3ceeffcf6f9de65cd5386d0a7e9d73d11cdacdc6 100644 (file)
@@ -617,6 +617,7 @@ static int
 nfqnl_mangle(void *data, int data_len, struct nfqnl_queue_entry *e)
 {
        int diff;
+       int err;
 
        diff = data_len - e->skb->len;
        if (diff < 0) {
@@ -626,25 +627,18 @@ nfqnl_mangle(void *data, int data_len, struct nfqnl_queue_entry *e)
                if (data_len > 0xFFFF)
                        return -EINVAL;
                if (diff > skb_tailroom(e->skb)) {
-                       struct sk_buff *newskb;
-
-                       newskb = skb_copy_expand(e->skb,
-                                                skb_headroom(e->skb),
-                                                diff,
-                                                GFP_ATOMIC);
-                       if (newskb == NULL) {
+                       err = pskb_expand_head(e->skb, 0,
+                                              diff - skb_tailroom(e->skb),
+                                              GFP_ATOMIC);
+                       if (err) {
                                printk(KERN_WARNING "nf_queue: OOM "
                                      "in mangle, dropping packet\n");
-                               return -ENOMEM;
+                               return err;
                        }
-                       if (e->skb->sk)
-                               skb_set_owner_w(newskb, e->skb->sk);
-                       kfree_skb(e->skb);
-                       e->skb = newskb;
                }
                skb_put(e->skb, diff);
        }
-       if (!skb_make_writable(&e->skb, data_len))
+       if (!skb_make_writable(e->skb, data_len))
                return -ENOMEM;
        skb_copy_to_linear_data(e->skb, data, data_len);
        e->skb->ip_summed = CHECKSUM_NONE;
@@ -777,10 +771,10 @@ static struct notifier_block nfqnl_rtnl_notifier = {
        .notifier_call  = nfqnl_rcv_nl_event,
 };
 
-static const int nfqa_verdict_min[NFQA_MAX+1] = {
-       [NFQA_VERDICT_HDR]      = sizeof(struct nfqnl_msg_verdict_hdr),
-       [NFQA_MARK]             = sizeof(u_int32_t),
-       [NFQA_PAYLOAD]          = 0,
+static const struct nla_policy nfqa_verdict_policy[NFQA_MAX+1] = {
+       [NFQA_VERDICT_HDR]      = { .len = sizeof(struct nfqnl_msg_verdict_hdr) },
+       [NFQA_MARK]             = { .type = NLA_U32 },
+       [NFQA_PAYLOAD]          = { .type = NLA_UNSPEC },
 };
 
 static int
@@ -796,11 +790,6 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb,
        struct nfqnl_queue_entry *entry;
        int err;
 
-       if (nlattr_bad_size(nfqa, NFQA_MAX, nfqa_verdict_min)) {
-               QDEBUG("bad attribute size\n");
-               return -EINVAL;
-       }
-
        queue = instance_lookup_get(queue_num);
        if (!queue)
                return -ENODEV;
@@ -855,9 +844,9 @@ nfqnl_recv_unsupp(struct sock *ctnl, struct sk_buff *skb,
        return -ENOTSUPP;
 }
 
-static const int nfqa_cfg_min[NFQA_CFG_MAX+1] = {
-       [NFQA_CFG_CMD]          = sizeof(struct nfqnl_msg_config_cmd),
-       [NFQA_CFG_PARAMS]       = sizeof(struct nfqnl_msg_config_params),
+static const struct nla_policy nfqa_cfg_policy[NFQA_CFG_MAX+1] = {
+       [NFQA_CFG_CMD]          = { .len = sizeof(struct nfqnl_msg_config_cmd) },
+       [NFQA_CFG_PARAMS]       = { .len = sizeof(struct nfqnl_msg_config_params) },
 };
 
 static struct nf_queue_handler nfqh = {
@@ -876,11 +865,6 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
 
        QDEBUG("entering for msg %u\n", NFNL_MSG_TYPE(nlh->nlmsg_type));
 
-       if (nlattr_bad_size(nfqa, NFQA_CFG_MAX, nfqa_cfg_min)) {
-               QDEBUG("bad attribute size\n");
-               return -EINVAL;
-       }
-
        queue = instance_lookup_get(queue_num);
        if (nfqa[NFQA_CFG_CMD]) {
                struct nfqnl_msg_config_cmd *cmd;
@@ -964,9 +948,11 @@ static const struct nfnl_callback nfqnl_cb[NFQNL_MSG_MAX] = {
        [NFQNL_MSG_PACKET]      = { .call = nfqnl_recv_unsupp,
                                    .attr_count = NFQA_MAX, },
        [NFQNL_MSG_VERDICT]     = { .call = nfqnl_recv_verdict,
-                                   .attr_count = NFQA_MAX, },
+                                   .attr_count = NFQA_MAX,
+                                   .policy = nfqa_verdict_policy },
        [NFQNL_MSG_CONFIG]      = { .call = nfqnl_recv_config,
-                                   .attr_count = NFQA_CFG_MAX, },
+                                   .attr_count = NFQA_CFG_MAX,
+                                   .policy = nfqa_cfg_policy },
 };
 
 static const struct nfnetlink_subsystem nfqnl_subsys = {
@@ -1059,22 +1045,8 @@ static const struct seq_operations nfqnl_seq_ops = {
 
 static int nfqnl_open(struct inode *inode, struct file *file)
 {
-       struct seq_file *seq;
-       struct iter_state *is;
-       int ret;
-
-       is = kzalloc(sizeof(*is), GFP_KERNEL);
-       if (!is)
-               return -ENOMEM;
-       ret = seq_open(file, &nfqnl_seq_ops);
-       if (ret < 0)
-               goto out_free;
-       seq = file->private_data;
-       seq->private = is;
-       return ret;
-out_free:
-       kfree(is);
-       return ret;
+       return seq_open_private(file, &nfqnl_seq_ops,
+                       sizeof(struct iter_state));
 }
 
 static const struct file_operations nfqnl_file_ops = {