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) {
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;
.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
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;
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 = {
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;
[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 = {
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 = {