#include <linux/sysctl.h>
#endif
-#define ASSERT_READ_LOCK(x)
-#define ASSERT_WRITE_LOCK(x)
-
#include <net/netfilter/nf_conntrack.h>
-#include <net/netfilter/nf_conntrack_l3proto.h>
-#include <net/netfilter/nf_conntrack_protocol.h>
#include <net/netfilter/nf_conntrack_core.h>
+#include <net/netfilter/nf_conntrack_l3proto.h>
+#include <net/netfilter/nf_conntrack_l4proto.h>
+#include <net/netfilter/nf_conntrack_expect.h>
#include <net/netfilter/nf_conntrack_helper.h>
-#include <linux/netfilter_ipv4/listhelp.h>
#if 0
#define DEBUGP printk
MODULE_LICENSE("GPL");
-extern atomic_t nf_conntrack_count;
-DECLARE_PER_CPU(struct ip_conntrack_stat, nf_conntrack_stat);
-
-static int kill_l3proto(struct nf_conn *i, void *data)
-{
- return (i->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num ==
- ((struct nf_conntrack_l3proto *)data)->l3proto);
-}
-
-static int kill_proto(struct nf_conn *i, void *data)
-{
- struct nf_conntrack_protocol *proto;
- proto = (struct nf_conntrack_protocol *)data;
- return (i->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum ==
- proto->proto) &&
- (i->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num ==
- proto->l3proto);
-}
-
#ifdef CONFIG_PROC_FS
-static int
+int
print_tuple(struct seq_file *s, const struct nf_conntrack_tuple *tuple,
struct nf_conntrack_l3proto *l3proto,
- struct nf_conntrack_protocol *proto)
+ struct nf_conntrack_l4proto *l4proto)
{
- return l3proto->print_tuple(s, tuple) || proto->print_tuple(s, tuple);
+ return l3proto->print_tuple(s, tuple) || l4proto->print_tuple(s, tuple);
}
+EXPORT_SYMBOL_GPL(print_tuple);
#ifdef CONFIG_NF_CT_ACCT
static unsigned int
const struct nf_conntrack_tuple_hash *hash = v;
const struct nf_conn *conntrack = nf_ct_tuplehash_to_ctrack(hash);
struct nf_conntrack_l3proto *l3proto;
- struct nf_conntrack_protocol *proto;
+ struct nf_conntrack_l4proto *l4proto;
- ASSERT_READ_LOCK(&nf_conntrack_lock);
NF_CT_ASSERT(conntrack);
/* we only want to print DIR_ORIGINAL */
.tuple.src.l3num);
NF_CT_ASSERT(l3proto);
- proto = __nf_ct_proto_find(conntrack->tuplehash[IP_CT_DIR_ORIGINAL]
+ l4proto = __nf_ct_l4proto_find(conntrack->tuplehash[IP_CT_DIR_ORIGINAL]
.tuple.src.l3num,
conntrack->tuplehash[IP_CT_DIR_ORIGINAL]
.tuple.dst.protonum);
- NF_CT_ASSERT(proto);
+ NF_CT_ASSERT(l4proto);
if (seq_printf(s, "%-8s %u %-8s %u %ld ",
l3proto->name,
conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num,
- proto->name,
+ l4proto->name,
conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum,
timer_pending(&conntrack->timeout)
? (long)(conntrack->timeout.expires - jiffies)/HZ : 0) != 0)
if (l3proto->print_conntrack(s, conntrack))
return -ENOSPC;
- if (proto->print_conntrack(s, conntrack))
+ if (l4proto->print_conntrack(s, conntrack))
return -ENOSPC;
if (print_tuple(s, &conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
- l3proto, proto))
+ l3proto, l4proto))
return -ENOSPC;
if (seq_print_counters(s, &conntrack->counters[IP_CT_DIR_ORIGINAL]))
return -ENOSPC;
if (print_tuple(s, &conntrack->tuplehash[IP_CT_DIR_REPLY].tuple,
- l3proto, proto))
+ l3proto, l4proto))
return -ENOSPC;
if (seq_print_counters(s, &conntrack->counters[IP_CT_DIR_REPLY]))
.release = seq_release_private,
};
-/* expects */
-static void *exp_seq_start(struct seq_file *s, loff_t *pos)
-{
- struct list_head *e = &nf_conntrack_expect_list;
- loff_t i;
-
- /* strange seq_file api calls stop even if we fail,
- * thus we need to grab lock since stop unlocks */
- read_lock_bh(&nf_conntrack_lock);
-
- if (list_empty(e))
- return NULL;
-
- for (i = 0; i <= *pos; i++) {
- e = e->next;
- if (e == &nf_conntrack_expect_list)
- return NULL;
- }
- return e;
-}
-
-static void *exp_seq_next(struct seq_file *s, void *v, loff_t *pos)
-{
- struct list_head *e = v;
-
- ++*pos;
- e = e->next;
-
- if (e == &nf_conntrack_expect_list)
- return NULL;
-
- return e;
-}
-
-static void exp_seq_stop(struct seq_file *s, void *v)
-{
- read_unlock_bh(&nf_conntrack_lock);
-}
-
-static int exp_seq_show(struct seq_file *s, void *v)
-{
- struct nf_conntrack_expect *expect = v;
-
- if (expect->timeout.function)
- seq_printf(s, "%ld ", timer_pending(&expect->timeout)
- ? (long)(expect->timeout.expires - jiffies)/HZ : 0);
- else
- seq_printf(s, "- ");
- seq_printf(s, "l3proto = %u proto=%u ",
- expect->tuple.src.l3num,
- expect->tuple.dst.protonum);
- print_tuple(s, &expect->tuple,
- __nf_ct_l3proto_find(expect->tuple.src.l3num),
- __nf_ct_proto_find(expect->tuple.src.l3num,
- expect->tuple.dst.protonum));
- return seq_putc(s, '\n');
-}
-
-static struct seq_operations exp_seq_ops = {
- .start = exp_seq_start,
- .next = exp_seq_next,
- .stop = exp_seq_stop,
- .show = exp_seq_show
-};
-
-static int exp_open(struct inode *inode, struct file *file)
-{
- return seq_open(file, &exp_seq_ops);
-}
-
-static struct file_operations exp_file_ops = {
- .owner = THIS_MODULE,
- .open = exp_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = seq_release
-};
-
static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos)
{
int cpu;
/* Sysctl support */
-int nf_conntrack_checksum = 1;
+int nf_conntrack_checksum __read_mostly = 1;
#ifdef CONFIG_SYSCTL
-
-/* From nf_conntrack_core.c */
-extern int nf_conntrack_max;
-extern unsigned int nf_conntrack_htable_size;
-
-/* From nf_conntrack_proto_tcp.c */
-extern unsigned int nf_ct_tcp_timeout_syn_sent;
-extern unsigned int nf_ct_tcp_timeout_syn_recv;
-extern unsigned int nf_ct_tcp_timeout_established;
-extern unsigned int nf_ct_tcp_timeout_fin_wait;
-extern unsigned int nf_ct_tcp_timeout_close_wait;
-extern unsigned int nf_ct_tcp_timeout_last_ack;
-extern unsigned int nf_ct_tcp_timeout_time_wait;
-extern unsigned int nf_ct_tcp_timeout_close;
-extern unsigned int nf_ct_tcp_timeout_max_retrans;
-extern int nf_ct_tcp_loose;
-extern int nf_ct_tcp_be_liberal;
-extern int nf_ct_tcp_max_retrans;
-
-/* From nf_conntrack_proto_udp.c */
-extern unsigned int nf_ct_udp_timeout;
-extern unsigned int nf_ct_udp_timeout_stream;
-
-/* From nf_conntrack_proto_generic.c */
-extern unsigned int nf_ct_generic_timeout;
-
/* Log invalid packets of a given protocol */
static int log_invalid_proto_min = 0;
static int log_invalid_proto_max = 255;
.mode = 0644,
.proc_handler = &proc_dointvec,
},
- {
- .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT,
- .procname = "nf_conntrack_tcp_timeout_syn_sent",
- .data = &nf_ct_tcp_timeout_syn_sent,
- .maxlen = sizeof(unsigned int),
- .mode = 0644,
- .proc_handler = &proc_dointvec_jiffies,
- },
- {
- .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV,
- .procname = "nf_conntrack_tcp_timeout_syn_recv",
- .data = &nf_ct_tcp_timeout_syn_recv,
- .maxlen = sizeof(unsigned int),
- .mode = 0644,
- .proc_handler = &proc_dointvec_jiffies,
- },
- {
- .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED,
- .procname = "nf_conntrack_tcp_timeout_established",
- .data = &nf_ct_tcp_timeout_established,
- .maxlen = sizeof(unsigned int),
- .mode = 0644,
- .proc_handler = &proc_dointvec_jiffies,
- },
- {
- .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT,
- .procname = "nf_conntrack_tcp_timeout_fin_wait",
- .data = &nf_ct_tcp_timeout_fin_wait,
- .maxlen = sizeof(unsigned int),
- .mode = 0644,
- .proc_handler = &proc_dointvec_jiffies,
- },
- {
- .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT,
- .procname = "nf_conntrack_tcp_timeout_close_wait",
- .data = &nf_ct_tcp_timeout_close_wait,
- .maxlen = sizeof(unsigned int),
- .mode = 0644,
- .proc_handler = &proc_dointvec_jiffies,
- },
- {
- .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK,
- .procname = "nf_conntrack_tcp_timeout_last_ack",
- .data = &nf_ct_tcp_timeout_last_ack,
- .maxlen = sizeof(unsigned int),
- .mode = 0644,
- .proc_handler = &proc_dointvec_jiffies,
- },
- {
- .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT,
- .procname = "nf_conntrack_tcp_timeout_time_wait",
- .data = &nf_ct_tcp_timeout_time_wait,
- .maxlen = sizeof(unsigned int),
- .mode = 0644,
- .proc_handler = &proc_dointvec_jiffies,
- },
- {
- .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE,
- .procname = "nf_conntrack_tcp_timeout_close",
- .data = &nf_ct_tcp_timeout_close,
- .maxlen = sizeof(unsigned int),
- .mode = 0644,
- .proc_handler = &proc_dointvec_jiffies,
- },
- {
- .ctl_name = NET_NF_CONNTRACK_UDP_TIMEOUT,
- .procname = "nf_conntrack_udp_timeout",
- .data = &nf_ct_udp_timeout,
- .maxlen = sizeof(unsigned int),
- .mode = 0644,
- .proc_handler = &proc_dointvec_jiffies,
- },
- {
- .ctl_name = NET_NF_CONNTRACK_UDP_TIMEOUT_STREAM,
- .procname = "nf_conntrack_udp_timeout_stream",
- .data = &nf_ct_udp_timeout_stream,
- .maxlen = sizeof(unsigned int),
- .mode = 0644,
- .proc_handler = &proc_dointvec_jiffies,
- },
- {
- .ctl_name = NET_NF_CONNTRACK_GENERIC_TIMEOUT,
- .procname = "nf_conntrack_generic_timeout",
- .data = &nf_ct_generic_timeout,
- .maxlen = sizeof(unsigned int),
- .mode = 0644,
- .proc_handler = &proc_dointvec_jiffies,
- },
{
.ctl_name = NET_NF_CONNTRACK_LOG_INVALID,
.procname = "nf_conntrack_log_invalid",
.extra1 = &log_invalid_proto_min,
.extra2 = &log_invalid_proto_max,
},
- {
- .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS,
- .procname = "nf_conntrack_tcp_timeout_max_retrans",
- .data = &nf_ct_tcp_timeout_max_retrans,
- .maxlen = sizeof(unsigned int),
- .mode = 0644,
- .proc_handler = &proc_dointvec_jiffies,
- },
- {
- .ctl_name = NET_NF_CONNTRACK_TCP_LOOSE,
- .procname = "nf_conntrack_tcp_loose",
- .data = &nf_ct_tcp_loose,
- .maxlen = sizeof(unsigned int),
- .mode = 0644,
- .proc_handler = &proc_dointvec,
- },
- {
- .ctl_name = NET_NF_CONNTRACK_TCP_BE_LIBERAL,
- .procname = "nf_conntrack_tcp_be_liberal",
- .data = &nf_ct_tcp_be_liberal,
- .maxlen = sizeof(unsigned int),
- .mode = 0644,
- .proc_handler = &proc_dointvec,
- },
- {
- .ctl_name = NET_NF_CONNTRACK_TCP_MAX_RETRANS,
- .procname = "nf_conntrack_tcp_max_retrans",
- .data = &nf_ct_tcp_max_retrans,
- .maxlen = sizeof(unsigned int),
- .mode = 0644,
- .proc_handler = &proc_dointvec,
- },
{ .ctl_name = 0 }
};
EXPORT_SYMBOL(nf_ct_log_invalid);
#endif /* CONFIG_SYSCTL */
-int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto)
-{
- int ret = 0;
-
- write_lock_bh(&nf_conntrack_lock);
- if (nf_ct_l3protos[proto->l3proto] != &nf_conntrack_generic_l3proto) {
- ret = -EBUSY;
- goto out;
- }
- nf_ct_l3protos[proto->l3proto] = proto;
-out:
- write_unlock_bh(&nf_conntrack_lock);
-
- return ret;
-}
-
-void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto)
-{
- write_lock_bh(&nf_conntrack_lock);
- nf_ct_l3protos[proto->l3proto] = &nf_conntrack_generic_l3proto;
- write_unlock_bh(&nf_conntrack_lock);
-
- /* Somebody could be still looking at the proto in bh. */
- synchronize_net();
-
- /* Remove all contrack entries for this protocol */
- nf_ct_iterate_cleanup(kill_l3proto, proto);
-}
-
-/* FIXME: Allow NULL functions and sub in pointers to generic for
- them. --RR */
-int nf_conntrack_protocol_register(struct nf_conntrack_protocol *proto)
-{
- int ret = 0;
-
-retry:
- write_lock_bh(&nf_conntrack_lock);
- if (nf_ct_protos[proto->l3proto]) {
- if (nf_ct_protos[proto->l3proto][proto->proto]
- != &nf_conntrack_generic_protocol) {
- ret = -EBUSY;
- goto out_unlock;
- }
- } else {
- /* l3proto may be loaded latter. */
- struct nf_conntrack_protocol **proto_array;
- int i;
-
- write_unlock_bh(&nf_conntrack_lock);
-
- proto_array = (struct nf_conntrack_protocol **)
- kmalloc(MAX_NF_CT_PROTO *
- sizeof(struct nf_conntrack_protocol *),
- GFP_KERNEL);
- if (proto_array == NULL) {
- ret = -ENOMEM;
- goto out;
- }
- for (i = 0; i < MAX_NF_CT_PROTO; i++)
- proto_array[i] = &nf_conntrack_generic_protocol;
-
- write_lock_bh(&nf_conntrack_lock);
- if (nf_ct_protos[proto->l3proto]) {
- /* bad timing, but no problem */
- write_unlock_bh(&nf_conntrack_lock);
- kfree(proto_array);
- } else {
- nf_ct_protos[proto->l3proto] = proto_array;
- write_unlock_bh(&nf_conntrack_lock);
- }
-
- /*
- * Just once because array is never freed until unloading
- * nf_conntrack.ko
- */
- goto retry;
- }
-
- nf_ct_protos[proto->l3proto][proto->proto] = proto;
-
-out_unlock:
- write_unlock_bh(&nf_conntrack_lock);
-out:
- return ret;
-}
-
-void nf_conntrack_protocol_unregister(struct nf_conntrack_protocol *proto)
-{
- write_lock_bh(&nf_conntrack_lock);
- nf_ct_protos[proto->l3proto][proto->proto]
- = &nf_conntrack_generic_protocol;
- write_unlock_bh(&nf_conntrack_lock);
-
- /* Somebody could be still looking at the proto in bh. */
- synchronize_net();
-
- /* Remove all contrack entries for this protocol */
- nf_ct_iterate_cleanup(kill_proto, proto);
-}
-
static int __init nf_conntrack_standalone_init(void)
{
#ifdef CONFIG_PROC_FS
EXPORT_SYMBOL(nf_ct_l3proto_module_put);
EXPORT_SYMBOL(nf_conntrack_l3proto_register);
EXPORT_SYMBOL(nf_conntrack_l3proto_unregister);
-EXPORT_SYMBOL(nf_conntrack_protocol_register);
-EXPORT_SYMBOL(nf_conntrack_protocol_unregister);
+EXPORT_SYMBOL(nf_conntrack_l4proto_register);
+EXPORT_SYMBOL(nf_conntrack_l4proto_unregister);
EXPORT_SYMBOL(nf_ct_invert_tuplepr);
EXPORT_SYMBOL(nf_conntrack_destroyed);
EXPORT_SYMBOL(need_conntrack);
EXPORT_SYMBOL(nf_ct_iterate_cleanup);
EXPORT_SYMBOL(__nf_ct_refresh_acct);
EXPORT_SYMBOL(nf_ct_protos);
-EXPORT_SYMBOL(__nf_ct_proto_find);
-EXPORT_SYMBOL(nf_ct_proto_find_get);
-EXPORT_SYMBOL(nf_ct_proto_put);
+EXPORT_SYMBOL(__nf_ct_l4proto_find);
+EXPORT_SYMBOL(nf_ct_l4proto_find_get);
+EXPORT_SYMBOL(nf_ct_l4proto_put);
EXPORT_SYMBOL(nf_ct_l3proto_find_get);
EXPORT_SYMBOL(nf_ct_l3proto_put);
EXPORT_SYMBOL(nf_ct_l3protos);
EXPORT_SYMBOL(nf_ct_unlink_expect);
EXPORT_SYMBOL(nf_conntrack_hash_insert);
EXPORT_SYMBOL(__nf_conntrack_expect_find);
-EXPORT_SYMBOL(nf_conntrack_expect_find);
+EXPORT_SYMBOL(nf_conntrack_expect_find_get);
EXPORT_SYMBOL(nf_conntrack_expect_list);
#if defined(CONFIG_NF_CT_NETLINK) || \
defined(CONFIG_NF_CT_NETLINK_MODULE)