Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
nfnetlink_queue_ct.c
Go to the documentation of this file.
1 /*
2  * (C) 2012 by Pablo Neira Ayuso <[email protected]>
3  *
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.
7  *
8  */
9 
10 #include <linux/skbuff.h>
11 #include <linux/netfilter.h>
12 #include <linux/netfilter/nfnetlink.h>
16 
17 struct nf_conn *nfqnl_ct_get(struct sk_buff *entskb, size_t *size,
18  enum ip_conntrack_info *ctinfo)
19 {
20  struct nfq_ct_hook *nfq_ct;
21  struct nf_conn *ct;
22 
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;
27 
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;
34  }
35  return ct;
36 }
37 
38 struct nf_conn *
39 nfqnl_ct_parse(const struct sk_buff *skb, const struct nlattr *attr,
40  enum ip_conntrack_info *ctinfo)
41 {
42  struct nfq_ct_hook *nfq_ct;
43  struct nf_conn *ct;
44 
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;
49 
50  ct = nf_ct_get(skb, ctinfo);
51  if (ct && !nf_ct_is_untracked(ct))
52  nfq_ct->parse(attr, ct);
53 
54  return ct;
55 }
56 
57 int nfqnl_ct_put(struct sk_buff *skb, struct nf_conn *ct,
58  enum ip_conntrack_info ctinfo)
59 {
60  struct nfq_ct_hook *nfq_ct;
61  struct nlattr *nest_parms;
62  u_int32_t tmp;
63 
64  nfq_ct = rcu_dereference(nfq_ct_hook);
65  if (nfq_ct == NULL)
66  return 0;
67 
68  nest_parms = nla_nest_start(skb, NFQA_CT | NLA_F_NESTED);
69  if (!nest_parms)
70  goto nla_put_failure;
71 
72  if (nfq_ct->build(skb, ct) < 0)
73  goto nla_put_failure;
74 
75  nla_nest_end(skb, nest_parms);
76 
77  tmp = ctinfo;
78  if (nla_put_be32(skb, NFQA_CT_INFO, htonl(tmp)))
79  goto nla_put_failure;
80 
81  return 0;
82 
83 nla_put_failure:
84  return -1;
85 }
86 
87 void nfqnl_ct_seq_adjust(struct sk_buff *skb, struct nf_conn *ct,
88  enum ip_conntrack_info ctinfo, int diff)
89 {
90  struct nfq_ct_nat_hook *nfq_nat_ct;
91 
92  nfq_nat_ct = rcu_dereference(nfq_ct_nat_hook);
93  if (nfq_nat_ct == NULL)
94  return;
95 
96  if ((ct->status & IPS_NAT_MASK) && diff)
97  nfq_nat_ct->seq_adjust(skb, ct, ctinfo, diff);
98 }