Blame view

net/netfilter/nf_conntrack_proto_generic.c 5.87 KB
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1
2
3
4
5
6
  /* (C) 1999-2001 Paul `Rusty' Russell
   * (C) 2002-2004 Netfilter Core Team <coreteam@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.
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
7
8
9
   */
  
  #include <linux/types.h>
cd354f1ae   Tim Schmielau   [PATCH] remove ma...
10
  #include <linux/jiffies.h>
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
11
12
  #include <linux/timer.h>
  #include <linux/netfilter.h>
605dcad6c   Martin Josefsson   [NETFILTER]: nf_c...
13
  #include <net/netfilter/nf_conntrack_l4proto.h>
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
14

933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
15
  static unsigned int nf_ct_generic_timeout __read_mostly = 600*HZ;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
16

db29a9508   Florian Westphal   netfilter: conntr...
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
  static bool nf_generic_should_process(u8 proto)
  {
  	switch (proto) {
  #ifdef CONFIG_NF_CT_PROTO_SCTP_MODULE
  	case IPPROTO_SCTP:
  		return false;
  #endif
  #ifdef CONFIG_NF_CT_PROTO_DCCP_MODULE
  	case IPPROTO_DCCP:
  		return false;
  #endif
  #ifdef CONFIG_NF_CT_PROTO_GRE_MODULE
  	case IPPROTO_GRE:
  		return false;
  #endif
  #ifdef CONFIG_NF_CT_PROTO_UDPLITE_MODULE
  	case IPPROTO_UDPLITE:
  		return false;
  #endif
  	default:
  		return true;
  	}
  }
15f585bd7   Gao feng   netfilter: nf_ct_...
40
41
42
43
  static inline struct nf_generic_net *generic_pernet(struct net *net)
  {
  	return &net->ct.nf_ct_proto.generic;
  }
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
44
45
  static bool generic_pkt_to_tuple(const struct sk_buff *skb,
  				 unsigned int dataoff,
a31f1adc0   Eric W. Biederman   netfilter: nf_con...
46
  				 struct net *net, struct nf_conntrack_tuple *tuple)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
47
48
49
  {
  	tuple->src.u.all = 0;
  	tuple->dst.u.all = 0;
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
50
  	return true;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
51
  }
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
52
53
  static bool generic_invert_tuple(struct nf_conntrack_tuple *tuple,
  				 const struct nf_conntrack_tuple *orig)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
54
55
56
  {
  	tuple->src.u.all = 0;
  	tuple->dst.u.all = 0;
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
57
  	return true;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
58
59
60
  }
  
  /* Print out the per-protocol part of the tuple. */
824f1fbee   Joe Perches   netfilter: Conver...
61
62
  static void generic_print_tuple(struct seq_file *s,
  				const struct nf_conntrack_tuple *tuple)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
63
  {
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
64
  }
2c8503f55   Pablo Neira Ayuso   netfilter: nf_con...
65
66
  static unsigned int *generic_get_timeouts(struct net *net)
  {
15f585bd7   Gao feng   netfilter: nf_ct_...
67
  	return &(generic_pernet(net)->timeout);
2c8503f55   Pablo Neira Ayuso   netfilter: nf_con...
68
  }
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
69
  /* Returns verdict for packet, or -1 for invalid. */
2c8503f55   Pablo Neira Ayuso   netfilter: nf_con...
70
71
72
73
74
75
76
  static int generic_packet(struct nf_conn *ct,
  			  const struct sk_buff *skb,
  			  unsigned int dataoff,
  			  enum ip_conntrack_info ctinfo,
  			  u_int8_t pf,
  			  unsigned int hooknum,
  			  unsigned int *timeout)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
77
  {
2c8503f55   Pablo Neira Ayuso   netfilter: nf_con...
78
  	nf_ct_refresh_acct(ct, ctinfo, skb, *timeout);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
79
80
81
82
  	return NF_ACCEPT;
  }
  
  /* Called when a new connection for this protocol found. */
2c8503f55   Pablo Neira Ayuso   netfilter: nf_con...
83
84
  static bool generic_new(struct nf_conn *ct, const struct sk_buff *skb,
  			unsigned int dataoff, unsigned int *timeouts)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
85
  {
779668450   Marcelo Ricardo Leitner   netfilter: conntr...
86
87
88
89
90
91
92
93
  	bool ret;
  
  	ret = nf_generic_should_process(nf_ct_protonum(ct));
  	if (!ret)
  		pr_warn_once("conntrack: generic helper won't handle protocol %d. Please consider loading the specific helper module.
  ",
  			     nf_ct_protonum(ct));
  	return ret;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
94
  }
509784623   Pablo Neira Ayuso   netfilter: add ct...
95
96
97
98
  #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
  
  #include <linux/netfilter/nfnetlink.h>
  #include <linux/netfilter/nfnetlink_cttimeout.h>
8264deb81   Gao feng   netfilter: nf_con...
99
100
  static int generic_timeout_nlattr_to_obj(struct nlattr *tb[],
  					 struct net *net, void *data)
509784623   Pablo Neira Ayuso   netfilter: add ct...
101
102
  {
  	unsigned int *timeout = data;
8264deb81   Gao feng   netfilter: nf_con...
103
  	struct nf_generic_net *gn = generic_pernet(net);
509784623   Pablo Neira Ayuso   netfilter: add ct...
104
105
106
107
108
109
  
  	if (tb[CTA_TIMEOUT_GENERIC_TIMEOUT])
  		*timeout =
  		    ntohl(nla_get_be32(tb[CTA_TIMEOUT_GENERIC_TIMEOUT])) * HZ;
  	else {
  		/* Set default generic timeout. */
8264deb81   Gao feng   netfilter: nf_con...
110
  		*timeout = gn->timeout;
509784623   Pablo Neira Ayuso   netfilter: add ct...
111
112
113
114
115
116
117
118
119
  	}
  
  	return 0;
  }
  
  static int
  generic_timeout_obj_to_nlattr(struct sk_buff *skb, const void *data)
  {
  	const unsigned int *timeout = data;
f57769414   David S. Miller   nf_conntrack_prot...
120
121
  	if (nla_put_be32(skb, CTA_TIMEOUT_GENERIC_TIMEOUT, htonl(*timeout / HZ)))
  		goto nla_put_failure;
509784623   Pablo Neira Ayuso   netfilter: add ct...
122
123
124
125
126
127
128
129
130
131
132
133
  
  	return 0;
  
  nla_put_failure:
          return -ENOSPC;
  }
  
  static const struct nla_policy
  generic_timeout_nla_policy[CTA_TIMEOUT_GENERIC_MAX+1] = {
  	[CTA_TIMEOUT_GENERIC_TIMEOUT]	= { .type = NLA_U32 },
  };
  #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
134
  #ifdef CONFIG_SYSCTL
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
135
136
  static struct ctl_table generic_sysctl_table[] = {
  	{
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
137
  		.procname	= "nf_conntrack_generic_timeout",
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
138
139
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
140
  		.proc_handler	= proc_dointvec_jiffies,
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
141
  	},
f8572d8f2   Eric W. Biederman   sysctl net: Remov...
142
  	{ }
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
143
  };
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
144
145
146
  #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
  static struct ctl_table generic_compat_sysctl_table[] = {
  	{
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
147
  		.procname	= "ip_conntrack_generic_timeout",
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
148
149
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
150
  		.proc_handler	= proc_dointvec_jiffies,
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
151
  	},
f8572d8f2   Eric W. Biederman   sysctl net: Remov...
152
  	{ }
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
153
154
  };
  #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
155
  #endif /* CONFIG_SYSCTL */
22ac03772   Gao feng   netfilter: nf_ct_...
156
157
  static int generic_kmemdup_sysctl_table(struct nf_proto_net *pn,
  					struct nf_generic_net *gn)
15f585bd7   Gao feng   netfilter: nf_ct_...
158
  {
15f585bd7   Gao feng   netfilter: nf_ct_...
159
160
161
162
163
164
  #ifdef CONFIG_SYSCTL
  	pn->ctl_table = kmemdup(generic_sysctl_table,
  				sizeof(generic_sysctl_table),
  				GFP_KERNEL);
  	if (!pn->ctl_table)
  		return -ENOMEM;
22ac03772   Gao feng   netfilter: nf_ct_...
165

15f585bd7   Gao feng   netfilter: nf_ct_...
166
  	pn->ctl_table[0].data = &gn->timeout;
22ac03772   Gao feng   netfilter: nf_ct_...
167
168
169
  #endif
  	return 0;
  }
15f585bd7   Gao feng   netfilter: nf_ct_...
170

22ac03772   Gao feng   netfilter: nf_ct_...
171
172
173
174
  static int generic_kmemdup_compat_sysctl_table(struct nf_proto_net *pn,
  					       struct nf_generic_net *gn)
  {
  #ifdef CONFIG_SYSCTL
15f585bd7   Gao feng   netfilter: nf_ct_...
175
176
177
178
  #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
  	pn->ctl_compat_table = kmemdup(generic_compat_sysctl_table,
  				       sizeof(generic_compat_sysctl_table),
  				       GFP_KERNEL);
22ac03772   Gao feng   netfilter: nf_ct_...
179
  	if (!pn->ctl_compat_table)
15f585bd7   Gao feng   netfilter: nf_ct_...
180
  		return -ENOMEM;
22ac03772   Gao feng   netfilter: nf_ct_...
181

15f585bd7   Gao feng   netfilter: nf_ct_...
182
183
184
185
186
  	pn->ctl_compat_table[0].data = &gn->timeout;
  #endif
  #endif
  	return 0;
  }
22ac03772   Gao feng   netfilter: nf_ct_...
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
  static int generic_init_net(struct net *net, u_int16_t proto)
  {
  	int ret;
  	struct nf_generic_net *gn = generic_pernet(net);
  	struct nf_proto_net *pn = &gn->pn;
  
  	gn->timeout = nf_ct_generic_timeout;
  
  	ret = generic_kmemdup_compat_sysctl_table(pn, gn);
  	if (ret < 0)
  		return ret;
  
  	ret = generic_kmemdup_sysctl_table(pn, gn);
  	if (ret < 0)
  		nf_ct_kfree_compat_sysctl_table(pn);
  
  	return ret;
  }
08911475d   Pablo Neira Ayuso   netfilter: nf_con...
205
206
207
208
  static struct nf_proto_net *generic_get_net_proto(struct net *net)
  {
  	return &net->ct.nf_ct_proto.generic.pn;
  }
61075af51   Patrick McHardy   [NETFILTER]: nf_c...
209
  struct nf_conntrack_l4proto nf_conntrack_l4proto_generic __read_mostly =
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
210
211
  {
  	.l3proto		= PF_UNSPEC,
fe2a7ce4d   Christoph Paasch   netfilter: change...
212
  	.l4proto		= 255,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
213
214
215
216
  	.name			= "unknown",
  	.pkt_to_tuple		= generic_pkt_to_tuple,
  	.invert_tuple		= generic_invert_tuple,
  	.print_tuple		= generic_print_tuple,
2c8503f55   Pablo Neira Ayuso   netfilter: nf_con...
217
218
219
  	.packet			= generic_packet,
  	.get_timeouts		= generic_get_timeouts,
  	.new			= generic_new,
509784623   Pablo Neira Ayuso   netfilter: add ct...
220
221
222
223
224
225
226
227
228
  #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
  	.ctnl_timeout		= {
  		.nlattr_to_obj	= generic_timeout_nlattr_to_obj,
  		.obj_to_nlattr	= generic_timeout_obj_to_nlattr,
  		.nlattr_max	= CTA_TIMEOUT_GENERIC_MAX,
  		.obj_size	= sizeof(unsigned int),
  		.nla_policy	= generic_timeout_nla_policy,
  	},
  #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
15f585bd7   Gao feng   netfilter: nf_ct_...
229
  	.init_net		= generic_init_net,
08911475d   Pablo Neira Ayuso   netfilter: nf_con...
230
  	.get_net_proto		= generic_get_net_proto,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
231
  };