2 < /* (C) 1999-2001 Paul `Rusty' Russell
3 < * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
5 < * This program is free software; you can redistribute it and/or modify
6 < * it under the terms of the GNU General Public License version 2 as
7 < * published by the Free Software Foundation.
10 > /* (c) 1999 Paul `Rusty' Russell. Licenced under the GNU General
13 < #include <linux/config.h>
15 < #ifdef CONFIG_SYSCTL
16 < #include <linux/sysctl.h>
19 > #include <linux/version.h>
23 > struct module *ip_conntrack_module = THIS_MODULE;
25 < static int kill_proto(const struct ip_conntrack *i, void *data)
27 < return (i->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum ==
28 < *((u_int8_t *) data));
31 < if (expect->expectant->helper->timeout)
32 < len = sprintf(buffer, "EXPECTING: %lu ",
33 < timer_pending(&expect->timeout)
34 < ? (expect->timeout.expires - jiffies)/HZ : 0);
36 < len = sprintf(buffer, "EXPECTING: - ");
37 < len += sprintf(buffer + len, "use=%u proto=%u ",
38 < atomic_read(&expect->use), expect->tuple.dst.protonum);
40 > len = sprintf(buffer, "EXPECTING: proto=%u ",
41 > expect->tuple.dst.protonum);
43 < __ip_ct_find_proto(expect->tuple.dst.protonum));
45 > __find_proto(expect->tuple.dst.protonum));
47 < print_conntrack(char *buffer, struct ip_conntrack *conntrack)
49 > print_conntrack(char *buffer, const struct ip_conntrack *conntrack)
51 < = __ip_ct_find_proto(conntrack->tuplehash[IP_CT_DIR_ORIGINAL]
53 > = __find_proto(conntrack->tuplehash[IP_CT_DIR_ORIGINAL]
55 < if (!(test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)))
57 > if (!(conntrack->status & IPS_SEEN_REPLY))
59 < if (test_bit(IPS_ASSURED_BIT, &conntrack->status))
61 > if (conntrack->status & IPS_ASSURED)
63 < READ_LOCK(&ip_conntrack_expect_tuple_lock);
64 < list_for_each(e, &ip_conntrack_expect_list) {
66 > for (e = expect_list.next; e != &expect_list; e = e->next) {
68 < goto finished_expects;
73 < READ_UNLOCK(&ip_conntrack_expect_tuple_lock);
75 < static unsigned int ip_conntrack_defrag(unsigned int hooknum,
76 < struct sk_buff **pskb,
77 < const struct net_device *in,
78 < const struct net_device *out,
79 < int (*okfn)(struct sk_buff *))
81 < /* Previously seen (loopback)? Ignore. Do this before
86 < /* Gather fragments. */
87 < if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
88 < *pskb = ip_ct_gather_frags(*pskb);
96 < if ((*pskb)->len > dst_pmtu(&rt->u.dst) &&
97 < !skb_shinfo(*pskb)->tso_size) {
99 > if ((*pskb)->len > rt->u.dst.pmtu) {
101 < static struct nf_hook_ops ip_conntrack_defrag_ops = {
102 < .hook = ip_conntrack_defrag,
103 < .owner = THIS_MODULE,
105 < .hooknum = NF_IP_PRE_ROUTING,
106 < .priority = NF_IP_PRI_CONNTRACK_DEFRAG,
109 < static struct nf_hook_ops ip_conntrack_in_ops = {
110 < .hook = ip_conntrack_in,
111 < .owner = THIS_MODULE,
113 < .hooknum = NF_IP_PRE_ROUTING,
114 < .priority = NF_IP_PRI_CONNTRACK,
117 < static struct nf_hook_ops ip_conntrack_defrag_local_out_ops = {
118 < .hook = ip_conntrack_defrag,
119 < .owner = THIS_MODULE,
121 < .hooknum = NF_IP_LOCAL_OUT,
122 < .priority = NF_IP_PRI_CONNTRACK_DEFRAG,
125 < static struct nf_hook_ops ip_conntrack_local_out_ops = {
126 < .hook = ip_conntrack_local,
127 < .owner = THIS_MODULE,
129 < .hooknum = NF_IP_LOCAL_OUT,
130 < .priority = NF_IP_PRI_CONNTRACK,
134 > static struct nf_hook_ops ip_conntrack_in_ops
135 > = { { NULL, NULL }, ip_conntrack_in, PF_INET, NF_IP_PRE_ROUTING,
136 > NF_IP_PRI_CONNTRACK };
137 > static struct nf_hook_ops ip_conntrack_local_out_ops
138 > = { { NULL, NULL }, ip_conntrack_local, PF_INET, NF_IP_LOCAL_OUT,
139 > NF_IP_PRI_CONNTRACK };
141 < static struct nf_hook_ops ip_conntrack_out_ops = {
143 < .owner = THIS_MODULE,
145 < .hooknum = NF_IP_POST_ROUTING,
146 < .priority = NF_IP_PRI_LAST,
149 < static struct nf_hook_ops ip_conntrack_local_in_ops = {
150 < .hook = ip_confirm,
151 < .owner = THIS_MODULE,
153 < .hooknum = NF_IP_LOCAL_IN,
154 < .priority = NF_IP_PRI_LAST-1,
157 < /* Sysctl support */
159 < #ifdef CONFIG_SYSCTL
161 < /* From ip_conntrack_core.c */
162 < extern int ip_conntrack_max;
163 < extern unsigned int ip_conntrack_htable_size;
165 < /* From ip_conntrack_proto_tcp.c */
166 < extern unsigned long ip_ct_tcp_timeout_syn_sent;
167 < extern unsigned long ip_ct_tcp_timeout_syn_recv;
168 < extern unsigned long ip_ct_tcp_timeout_established;
169 < extern unsigned long ip_ct_tcp_timeout_fin_wait;
170 < extern unsigned long ip_ct_tcp_timeout_close_wait;
171 < extern unsigned long ip_ct_tcp_timeout_last_ack;
172 < extern unsigned long ip_ct_tcp_timeout_time_wait;
173 < extern unsigned long ip_ct_tcp_timeout_close;
175 < /* From ip_conntrack_proto_udp.c */
176 < extern unsigned long ip_ct_udp_timeout;
177 < extern unsigned long ip_ct_udp_timeout_stream;
179 < /* From ip_conntrack_proto_icmp.c */
180 < extern unsigned long ip_ct_icmp_timeout;
182 < /* From ip_conntrack_proto_icmp.c */
183 < extern unsigned long ip_ct_generic_timeout;
185 < static struct ctl_table_header *ip_ct_sysctl_header;
187 < static ctl_table ip_ct_sysctl_table[] = {
189 < .ctl_name = NET_IPV4_NF_CONNTRACK_MAX,
190 < .procname = "ip_conntrack_max",
191 < .data = &ip_conntrack_max,
192 < .maxlen = sizeof(int),
194 < .proc_handler = &proc_dointvec,
197 < .ctl_name = NET_IPV4_NF_CONNTRACK_BUCKETS,
198 < .procname = "ip_conntrack_buckets",
199 < .data = &ip_conntrack_htable_size,
200 < .maxlen = sizeof(unsigned int),
202 < .proc_handler = &proc_dointvec,
205 < .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT,
206 < .procname = "ip_conntrack_tcp_timeout_syn_sent",
207 < .data = &ip_ct_tcp_timeout_syn_sent,
208 < .maxlen = sizeof(unsigned int),
210 < .proc_handler = &proc_dointvec_jiffies,
213 < .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV,
214 < .procname = "ip_conntrack_tcp_timeout_syn_recv",
215 < .data = &ip_ct_tcp_timeout_syn_recv,
216 < .maxlen = sizeof(unsigned int),
218 < .proc_handler = &proc_dointvec_jiffies,
221 < .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED,
222 < .procname = "ip_conntrack_tcp_timeout_established",
223 < .data = &ip_ct_tcp_timeout_established,
224 < .maxlen = sizeof(unsigned int),
226 < .proc_handler = &proc_dointvec_jiffies,
229 < .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT,
230 < .procname = "ip_conntrack_tcp_timeout_fin_wait",
231 < .data = &ip_ct_tcp_timeout_fin_wait,
232 < .maxlen = sizeof(unsigned int),
234 < .proc_handler = &proc_dointvec_jiffies,
237 < .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT,
238 < .procname = "ip_conntrack_tcp_timeout_close_wait",
239 < .data = &ip_ct_tcp_timeout_close_wait,
240 < .maxlen = sizeof(unsigned int),
242 < .proc_handler = &proc_dointvec_jiffies,
245 < .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK,
246 < .procname = "ip_conntrack_tcp_timeout_last_ack",
247 < .data = &ip_ct_tcp_timeout_last_ack,
248 < .maxlen = sizeof(unsigned int),
250 < .proc_handler = &proc_dointvec_jiffies,
253 < .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT,
254 < .procname = "ip_conntrack_tcp_timeout_time_wait",
255 < .data = &ip_ct_tcp_timeout_time_wait,
256 < .maxlen = sizeof(unsigned int),
258 < .proc_handler = &proc_dointvec_jiffies,
261 < .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE,
262 < .procname = "ip_conntrack_tcp_timeout_close",
263 < .data = &ip_ct_tcp_timeout_close,
264 < .maxlen = sizeof(unsigned int),
266 < .proc_handler = &proc_dointvec_jiffies,
269 < .ctl_name = NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT,
270 < .procname = "ip_conntrack_udp_timeout",
271 < .data = &ip_ct_udp_timeout,
272 < .maxlen = sizeof(unsigned int),
274 < .proc_handler = &proc_dointvec_jiffies,
277 < .ctl_name = NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT_STREAM,
278 < .procname = "ip_conntrack_udp_timeout_stream",
279 < .data = &ip_ct_udp_timeout_stream,
280 < .maxlen = sizeof(unsigned int),
282 < .proc_handler = &proc_dointvec_jiffies,
285 < .ctl_name = NET_IPV4_NF_CONNTRACK_ICMP_TIMEOUT,
286 < .procname = "ip_conntrack_icmp_timeout",
287 < .data = &ip_ct_icmp_timeout,
288 < .maxlen = sizeof(unsigned int),
290 < .proc_handler = &proc_dointvec_jiffies,
293 < .ctl_name = NET_IPV4_NF_CONNTRACK_GENERIC_TIMEOUT,
294 < .procname = "ip_conntrack_generic_timeout",
295 < .data = &ip_ct_generic_timeout,
296 < .maxlen = sizeof(unsigned int),
298 < .proc_handler = &proc_dointvec_jiffies,
303 < #define NET_IP_CONNTRACK_MAX 2089
305 < static ctl_table ip_ct_netfilter_table[] = {
307 < .ctl_name = NET_IPV4_NETFILTER,
308 < .procname = "netfilter",
310 < .child = ip_ct_sysctl_table,
313 < .ctl_name = NET_IP_CONNTRACK_MAX,
314 < .procname = "ip_conntrack_max",
315 < .data = &ip_conntrack_max,
316 < .maxlen = sizeof(int),
318 < .proc_handler = &proc_dointvec
323 < static ctl_table ip_ct_ipv4_table[] = {
325 < .ctl_name = NET_IPV4,
326 < .procname = "ipv4",
328 < .child = ip_ct_netfilter_table,
333 < static ctl_table ip_ct_net_table[] = {
335 < .ctl_name = CTL_NET,
338 < .child = ip_ct_ipv4_table,
344 > static struct nf_hook_ops ip_conntrack_out_ops
345 > = { { NULL, NULL }, ip_refrag, PF_INET, NF_IP_POST_ROUTING, NF_IP_PRI_LAST };
346 > static struct nf_hook_ops ip_conntrack_local_in_ops
347 > = { { NULL, NULL }, ip_confirm, PF_INET, NF_IP_LOCAL_IN, NF_IP_PRI_LAST-1 };
350 < proc = proc_net_create("ip_conntrack", 0440, list_conntracks);
352 > proc = proc_net_create("ip_conntrack",0,list_conntracks);
354 < ret = nf_register_hook(&ip_conntrack_defrag_ops);
356 < printk("ip_conntrack: can't register pre-routing defrag hook.\n");
359 < ret = nf_register_hook(&ip_conntrack_defrag_local_out_ops);
361 < printk("ip_conntrack: can't register local_out defrag hook.\n");
362 < goto cleanup_defragops;
365 < printk("ip_conntrack: can't register pre-routing hook.\n");
366 < goto cleanup_defraglocalops;
368 > printk("ip_conntrack: can't register in hook.\n");
371 < #ifdef CONFIG_SYSCTL
372 < ip_ct_sysctl_header = register_sysctl_table(ip_ct_net_table, 0);
373 < if (ip_ct_sysctl_header == NULL) {
374 < printk("ip_conntrack: can't register to sysctl.\n");
379 < #ifdef CONFIG_SYSCTL
380 < unregister_sysctl_table(ip_ct_sysctl_header);
383 < cleanup_defraglocalops:
384 < nf_unregister_hook(&ip_conntrack_defrag_local_out_ops);
386 < nf_unregister_hook(&ip_conntrack_defrag_ops);
388 < list_for_each(i, &protocol_list) {
390 > for (i = protocol_list.next; i != &protocol_list; i = i->next) {
394 > /* FIXME: Implement this --RR */
397 < WRITE_LOCK(&ip_conntrack_lock);
399 < /* ip_ct_find_proto() returns proto_generic in case there is no protocol
400 < * helper. So this should be enough - HW */
401 < LIST_DELETE(&protocol_list, proto);
402 < WRITE_UNLOCK(&ip_conntrack_lock);
404 < /* Somebody could be still looking at the proto in bh. */
407 < /* Remove all contrack entries for this protocol */
408 < ip_ct_selective_cleanup(kill_proto, &proto->proto);
412 < /* Some modules need us, but don't depend directly on any symbol.
413 < They should call this. */
414 < void need_ip_conntrack(void)
419 < EXPORT_SYMBOL(ip_conntrack_protocol_unregister);
421 < EXPORT_SYMBOL(need_ip_conntrack);
423 > EXPORT_SYMBOL(ip_conntrack_module);
425 < EXPORT_SYMBOL(ip_ct_find_proto);
426 < EXPORT_SYMBOL(__ip_ct_find_proto);
427 < EXPORT_SYMBOL(ip_ct_find_helper);
428 < EXPORT_SYMBOL(ip_conntrack_expect_alloc);
430 < EXPORT_SYMBOL_GPL(ip_conntrack_expect_find_get);
431 < EXPORT_SYMBOL_GPL(ip_conntrack_expect_put);
433 < EXPORT_SYMBOL(ip_conntrack_expect_list);
435 < EXPORT_SYMBOL(ip_conntrack_hash);
436 < EXPORT_SYMBOL(ip_conntrack_untracked);
437 < EXPORT_SYMBOL_GPL(ip_conntrack_find_get);
438 < EXPORT_SYMBOL_GPL(ip_conntrack_put);