dm thin: wake worker when discard is prepared
[linux-2.6.git] / net / netfilter / nfnetlink_queue_ct.c
blobab61d66bc0b9e53fb5c0b657d0d954f8ea16cf3b
1 /*
2 * (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.org>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
8 */
10 #include <linux/skbuff.h>
11 #include <linux/netfilter.h>
12 #include <linux/netfilter/nfnetlink.h>
13 #include <linux/netfilter/nfnetlink_queue.h>
14 #include <net/netfilter/nf_conntrack.h>
15 #include <net/netfilter/nfnetlink_queue.h>
17 struct nf_conn *nfqnl_ct_get(struct sk_buff *entskb, size_t *size,
18 enum ip_conntrack_info *ctinfo)
20 struct nfq_ct_hook *nfq_ct;
21 struct nf_conn *ct;
23 /* rcu_read_lock()ed by __nf_queue already. */
24 nfq_ct = rcu_dereference(nfq_ct_hook);
25 if (nfq_ct == NULL)
26 return NULL;
28 ct = nf_ct_get(entskb, ctinfo);
29 if (ct) {
30 if (!nf_ct_is_untracked(ct))
31 *size += nfq_ct->build_size(ct);
32 else
33 ct = NULL;
35 return ct;
38 struct nf_conn *
39 nfqnl_ct_parse(const struct sk_buff *skb, const struct nlattr *attr,
40 enum ip_conntrack_info *ctinfo)
42 struct nfq_ct_hook *nfq_ct;
43 struct nf_conn *ct;
45 /* rcu_read_lock()ed by __nf_queue already. */
46 nfq_ct = rcu_dereference(nfq_ct_hook);
47 if (nfq_ct == NULL)
48 return NULL;
50 ct = nf_ct_get(skb, ctinfo);
51 if (ct && !nf_ct_is_untracked(ct))
52 nfq_ct->parse(attr, ct);
54 return ct;
57 int nfqnl_ct_put(struct sk_buff *skb, struct nf_conn *ct,
58 enum ip_conntrack_info ctinfo)
60 struct nfq_ct_hook *nfq_ct;
61 struct nlattr *nest_parms;
62 u_int32_t tmp;
64 nfq_ct = rcu_dereference(nfq_ct_hook);
65 if (nfq_ct == NULL)
66 return 0;
68 nest_parms = nla_nest_start(skb, NFQA_CT | NLA_F_NESTED);
69 if (!nest_parms)
70 goto nla_put_failure;
72 if (nfq_ct->build(skb, ct) < 0)
73 goto nla_put_failure;
75 nla_nest_end(skb, nest_parms);
77 tmp = ctinfo;
78 if (nla_put_be32(skb, NFQA_CT_INFO, htonl(tmp)))
79 goto nla_put_failure;
81 return 0;
83 nla_put_failure:
84 return -1;
87 void nfqnl_ct_seq_adjust(struct sk_buff *skb, struct nf_conn *ct,
88 enum ip_conntrack_info ctinfo, int diff)
90 struct nfq_ct_nat_hook *nfq_nat_ct;
92 nfq_nat_ct = rcu_dereference(nfq_ct_nat_hook);
93 if (nfq_nat_ct == NULL)
94 return;
96 if ((ct->status & IPS_NAT_MASK) && diff)
97 nfq_nat_ct->seq_adjust(skb, ct, ctinfo, diff);