Blame view

net/netfilter/nfnetlink_queue_ct.c 2.46 KB
7c6223454   Pablo Neira Ayuso   netfilter: nfnetl...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  /*
   * (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.org>
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License version 2 as
   * published by the Free Software Foundation.
   *
   */
  
  #include <linux/skbuff.h>
  #include <linux/netfilter.h>
  #include <linux/netfilter/nfnetlink.h>
  #include <linux/netfilter/nfnetlink_queue.h>
  #include <net/netfilter/nf_conntrack.h>
ab5e8b77d   Pablo Neira Ayuso   netfilter: nfnetl...
15
  #include <net/netfilter/nfnetlink_queue.h>
7c6223454   Pablo Neira Ayuso   netfilter: nfnetl...
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
  
  struct nf_conn *nfqnl_ct_get(struct sk_buff *entskb, size_t *size,
  			     enum ip_conntrack_info *ctinfo)
  {
  	struct nfq_ct_hook *nfq_ct;
  	struct nf_conn *ct;
  
  	/* rcu_read_lock()ed by __nf_queue already. */
  	nfq_ct = rcu_dereference(nfq_ct_hook);
  	if (nfq_ct == NULL)
  		return NULL;
  
  	ct = nf_ct_get(entskb, ctinfo);
  	if (ct) {
  		if (!nf_ct_is_untracked(ct))
  			*size += nfq_ct->build_size(ct);
  		else
  			ct = NULL;
  	}
  	return ct;
  }
  
  struct nf_conn *
  nfqnl_ct_parse(const struct sk_buff *skb, const struct nlattr *attr,
  	       enum ip_conntrack_info *ctinfo)
  {
  	struct nfq_ct_hook *nfq_ct;
  	struct nf_conn *ct;
  
  	/* rcu_read_lock()ed by __nf_queue already. */
  	nfq_ct = rcu_dereference(nfq_ct_hook);
  	if (nfq_ct == NULL)
  		return NULL;
  
  	ct = nf_ct_get(skb, ctinfo);
  	if (ct && !nf_ct_is_untracked(ct))
  		nfq_ct->parse(attr, ct);
  
  	return ct;
  }
  
  int nfqnl_ct_put(struct sk_buff *skb, struct nf_conn *ct,
  		 enum ip_conntrack_info ctinfo)
  {
  	struct nfq_ct_hook *nfq_ct;
  	struct nlattr *nest_parms;
  	u_int32_t tmp;
  
  	nfq_ct = rcu_dereference(nfq_ct_hook);
  	if (nfq_ct == NULL)
  		return 0;
  
  	nest_parms = nla_nest_start(skb, NFQA_CT | NLA_F_NESTED);
  	if (!nest_parms)
  		goto nla_put_failure;
  
  	if (nfq_ct->build(skb, ct) < 0)
  		goto nla_put_failure;
  
  	nla_nest_end(skb, nest_parms);
  
  	tmp = ctinfo;
  	if (nla_put_be32(skb, NFQA_CT_INFO, htonl(tmp)))
  		goto nla_put_failure;
  
  	return 0;
  
  nla_put_failure:
  	return -1;
  }
  
  void nfqnl_ct_seq_adjust(struct sk_buff *skb, struct nf_conn *ct,
  			 enum ip_conntrack_info ctinfo, int diff)
  {
41d73ec05   Patrick McHardy   netfilter: nf_con...
90
  	struct nfq_ct_hook *nfq_ct;
7c6223454   Pablo Neira Ayuso   netfilter: nfnetl...
91

41d73ec05   Patrick McHardy   netfilter: nf_con...
92
93
  	nfq_ct = rcu_dereference(nfq_ct_hook);
  	if (nfq_ct == NULL)
7c6223454   Pablo Neira Ayuso   netfilter: nfnetl...
94
95
96
  		return;
  
  	if ((ct->status & IPS_NAT_MASK) && diff)
41d73ec05   Patrick McHardy   netfilter: nf_con...
97
  		nfq_ct->seq_adjust(skb, ct, ctinfo, diff);
7c6223454   Pablo Neira Ayuso   netfilter: nfnetl...
98
  }
bd0779370   Pablo Neira Ayuso   netfilter: nfnetl...
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
  
  int nfqnl_attach_expect(struct nf_conn *ct, const struct nlattr *attr,
  			u32 portid, u32 report)
  {
  	struct nfq_ct_hook *nfq_ct;
  
  	if (nf_ct_is_untracked(ct))
  		return 0;
  
  	nfq_ct = rcu_dereference(nfq_ct_hook);
  	if (nfq_ct == NULL)
  		return -EOPNOTSUPP;
  
  	return nfq_ct->attach_expect(attr, ct, portid, report);
  }