* 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.
- *
- * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
- * - move L3 protocol dependent part to this file.
- * 23 Mar 2004: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
- * - add get_features() to support various size of conntrack
- * structures.
- *
- * Derived from net/ipv4/netfilter/ip_conntrack_standalone.c
*/
#include <linux/types.h>
#include <linux/netfilter_ipv4.h>
#include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nf_conntrack_helper.h>
-#include <net/netfilter/nf_conntrack_protocol.h>
+#include <net/netfilter/nf_conntrack_l4proto.h>
#include <net/netfilter/nf_conntrack_l3proto.h>
#include <net/netfilter/nf_conntrack_core.h>
#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
#define DEBUGP(format, args...)
#endif
-DECLARE_PER_CPU(struct nf_conntrack_stat, nf_conntrack_stat);
-
static int ipv4_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
struct nf_conntrack_tuple *tuple)
{
- u_int32_t _addrs[2], *ap;
+ __be32 _addrs[2], *ap;
ap = skb_header_pointer(skb, nhoff + offsetof(struct iphdr, saddr),
sizeof(u_int32_t) * 2, _addrs);
if (ap == NULL)
const struct nf_conntrack_tuple *tuple)
{
return seq_printf(s, "src=%u.%u.%u.%u dst=%u.%u.%u.%u ",
- NIPQUAD(tuple->src.u3.ip),
+ NIPQUAD(tuple->src.u3.ip),
NIPQUAD(tuple->dst.u3.ip));
}
{
skb_orphan(skb);
- local_bh_disable();
- skb = ip_defrag(skb, user);
- local_bh_enable();
+ local_bh_disable();
+ skb = ip_defrag(skb, user);
+ local_bh_enable();
- if (skb)
- ip_send_check(skb->nh.iph);
+ if (skb)
+ ip_send_check(ip_hdr(skb));
- return skb;
+ return skb;
}
static int
u_int8_t *protonum)
{
/* Never happen */
- if ((*pskb)->nh.iph->frag_off & htons(IP_OFFSET)) {
+ if (ip_hdr(*pskb)->frag_off & htons(IP_OFFSET)) {
if (net_ratelimit()) {
printk(KERN_ERR "ipv4_prepare: Frag of proto %u (hook=%u)\n",
- (*pskb)->nh.iph->protocol, hooknum);
+ ip_hdr(*pskb)->protocol, hooknum);
}
return -NF_DROP;
}
- *dataoff = (*pskb)->nh.raw - (*pskb)->data + (*pskb)->nh.iph->ihl*4;
- *protonum = (*pskb)->nh.iph->protocol;
+ *dataoff = skb_network_offset(*pskb) + ip_hdrlen(*pskb);
+ *protonum = ip_hdr(*pskb)->protocol;
return NF_ACCEPT;
}
-int nat_module_is_loaded = 0;
+int nf_nat_module_is_loaded = 0;
+EXPORT_SYMBOL_GPL(nf_nat_module_is_loaded);
+
static u_int32_t ipv4_get_features(const struct nf_conntrack_tuple *tuple)
{
- if (nat_module_is_loaded)
+ if (nf_nat_module_is_loaded)
return NF_CT_F_NAT;
return NF_CT_F_BASIC;
return NF_ACCEPT;
return help->helper->help(pskb,
- (*pskb)->nh.raw - (*pskb)->data
- + (*pskb)->nh.iph->ihl*4,
- ct, ctinfo);
+ skb_network_offset(*pskb) + ip_hdrlen(*pskb),
+ ct, ctinfo);
}
static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
#endif
/* Gather fragments. */
- if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
+ if (ip_hdr(*pskb)->frag_off & htons(IP_MF | IP_OFFSET)) {
*pskb = nf_ct_ipv4_gather_frags(*pskb,
hooknum == NF_IP_PRE_ROUTING ?
IP_DEFRAG_CONNTRACK_IN :
}
static unsigned int ipv4_conntrack_local(unsigned int hooknum,
- struct sk_buff **pskb,
- const struct net_device *in,
- const struct net_device *out,
- int (*okfn)(struct sk_buff *))
+ struct sk_buff **pskb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
{
/* root is playing with raw sockets. */
if ((*pskb)->len < sizeof(struct iphdr)
- || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr)) {
+ || ip_hdrlen(*pskb) < sizeof(struct iphdr)) {
if (net_ratelimit())
printk("ipt_hook: happy cracking.\n");
return NF_ACCEPT;
},
};
-#ifdef CONFIG_SYSCTL
-/* From nf_conntrack_proto_icmp.c */
-extern unsigned int nf_ct_icmp_timeout;
-static struct ctl_table_header *nf_ct_ipv4_sysctl_header;
+#if defined(CONFIG_SYSCTL) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
+static int log_invalid_proto_min = 0;
+static int log_invalid_proto_max = 255;
-static ctl_table nf_ct_sysctl_table[] = {
+static ctl_table ip_ct_sysctl_table[] = {
{
- .ctl_name = NET_NF_CONNTRACK_ICMP_TIMEOUT,
- .procname = "nf_conntrack_icmp_timeout",
- .data = &nf_ct_icmp_timeout,
- .maxlen = sizeof(unsigned int),
+ .ctl_name = NET_IPV4_NF_CONNTRACK_MAX,
+ .procname = "ip_conntrack_max",
+ .data = &nf_conntrack_max,
+ .maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = &proc_dointvec_jiffies,
+ .proc_handler = &proc_dointvec,
},
- { .ctl_name = 0 }
-};
-
-static ctl_table nf_ct_netfilter_table[] = {
{
- .ctl_name = NET_NETFILTER,
- .procname = "netfilter",
- .mode = 0555,
- .child = nf_ct_sysctl_table,
+ .ctl_name = NET_IPV4_NF_CONNTRACK_COUNT,
+ .procname = "ip_conntrack_count",
+ .data = &nf_conntrack_count,
+ .maxlen = sizeof(int),
+ .mode = 0444,
+ .proc_handler = &proc_dointvec,
+ },
+ {
+ .ctl_name = NET_IPV4_NF_CONNTRACK_BUCKETS,
+ .procname = "ip_conntrack_buckets",
+ .data = &nf_conntrack_htable_size,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0444,
+ .proc_handler = &proc_dointvec,
+ },
+ {
+ .ctl_name = NET_IPV4_NF_CONNTRACK_CHECKSUM,
+ .procname = "ip_conntrack_checksum",
+ .data = &nf_conntrack_checksum,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
},
- { .ctl_name = 0 }
-};
-
-static ctl_table nf_ct_net_table[] = {
{
- .ctl_name = CTL_NET,
- .procname = "net",
- .mode = 0555,
- .child = nf_ct_netfilter_table,
+ .ctl_name = NET_IPV4_NF_CONNTRACK_LOG_INVALID,
+ .procname = "ip_conntrack_log_invalid",
+ .data = &nf_ct_log_invalid,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_minmax,
+ .strategy = &sysctl_intvec,
+ .extra1 = &log_invalid_proto_min,
+ .extra2 = &log_invalid_proto_max,
},
- { .ctl_name = 0 }
+ {
+ .ctl_name = 0
+ }
};
-#endif
+#endif /* CONFIG_SYSCTL && CONFIG_NF_CONNTRACK_PROC_COMPAT */
/* Fast function for those who don't want to parse /proc (and I don't
blame them). */
struct inet_sock *inet = inet_sk(sk);
struct nf_conntrack_tuple_hash *h;
struct nf_conntrack_tuple tuple;
-
+
NF_CT_TUPLE_U_BLANK(&tuple);
tuple.src.u3.ip = inet->rcv_saddr;
tuple.src.u.tcp.port = inet->sport;
return -ENOENT;
}
-#if defined(CONFIG_NF_CT_NETLINK) || \
- defined(CONFIG_NF_CT_NETLINK_MODULE)
+#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nfnetlink_conntrack.h>
if (nfattr_bad_size(tb, CTA_IP_MAX, cta_min_ip))
return -EINVAL;
- t->src.u3.ip =
- *(u_int32_t *)NFA_DATA(tb[CTA_IP_V4_SRC-1]);
- t->dst.u3.ip =
- *(u_int32_t *)NFA_DATA(tb[CTA_IP_V4_DST-1]);
+ t->src.u3.ip = *(__be32 *)NFA_DATA(tb[CTA_IP_V4_SRC-1]);
+ t->dst.u3.ip = *(__be32 *)NFA_DATA(tb[CTA_IP_V4_DST-1]);
return 0;
}
.print_conntrack = ipv4_print_conntrack,
.prepare = ipv4_prepare,
.get_features = ipv4_get_features,
-#if defined(CONFIG_NF_CT_NETLINK) || \
- defined(CONFIG_NF_CT_NETLINK_MODULE)
+#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
.tuple_to_nfattr = ipv4_tuple_to_nfattr,
.nfattr_to_tuple = ipv4_nfattr_to_tuple,
+#endif
+#if defined(CONFIG_SYSCTL) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
+ .ctl_table_path = nf_net_ipv4_netfilter_sysctl_path,
+ .ctl_table = ip_ct_sysctl_table,
#endif
.me = THIS_MODULE,
};
-extern struct nf_conntrack_protocol nf_conntrack_protocol_tcp4;
-extern struct nf_conntrack_protocol nf_conntrack_protocol_udp4;
-extern struct nf_conntrack_protocol nf_conntrack_protocol_icmp;
-
MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET));
+MODULE_ALIAS("ip_conntrack");
MODULE_LICENSE("GPL");
static int __init nf_conntrack_l3proto_ipv4_init(void)
return ret;
}
- ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_tcp4);
+ ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_tcp4);
if (ret < 0) {
printk("nf_conntrack_ipv4: can't register tcp.\n");
goto cleanup_sockopt;
}
- ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_udp4);
+ ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_udp4);
if (ret < 0) {
printk("nf_conntrack_ipv4: can't register udp.\n");
goto cleanup_tcp;
}
- ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_icmp);
+ ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_icmp);
if (ret < 0) {
printk("nf_conntrack_ipv4: can't register icmp.\n");
goto cleanup_udp;
printk("nf_conntrack_ipv4: can't register hooks.\n");
goto cleanup_ipv4;
}
-#ifdef CONFIG_SYSCTL
- nf_ct_ipv4_sysctl_header = register_sysctl_table(nf_ct_net_table, 0);
- if (nf_ct_ipv4_sysctl_header == NULL) {
- printk("nf_conntrack: can't register to sysctl.\n");
- ret = -ENOMEM;
+#if defined(CONFIG_PROC_FS) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
+ ret = nf_conntrack_ipv4_compat_init();
+ if (ret < 0)
goto cleanup_hooks;
- }
#endif
return ret;
-
-#ifdef CONFIG_SYSCTL
+#if defined(CONFIG_PROC_FS) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
cleanup_hooks:
nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops));
#endif
cleanup_ipv4:
nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv4);
cleanup_icmp:
- nf_conntrack_protocol_unregister(&nf_conntrack_protocol_icmp);
+ nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_icmp);
cleanup_udp:
- nf_conntrack_protocol_unregister(&nf_conntrack_protocol_udp4);
+ nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp4);
cleanup_tcp:
- nf_conntrack_protocol_unregister(&nf_conntrack_protocol_tcp4);
+ nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp4);
cleanup_sockopt:
nf_unregister_sockopt(&so_getorigdst);
return ret;
static void __exit nf_conntrack_l3proto_ipv4_fini(void)
{
synchronize_net();
-#ifdef CONFIG_SYSCTL
- unregister_sysctl_table(nf_ct_ipv4_sysctl_header);
+#if defined(CONFIG_PROC_FS) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
+ nf_conntrack_ipv4_compat_fini();
#endif
nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops));
nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv4);
- nf_conntrack_protocol_unregister(&nf_conntrack_protocol_icmp);
- nf_conntrack_protocol_unregister(&nf_conntrack_protocol_udp4);
- nf_conntrack_protocol_unregister(&nf_conntrack_protocol_tcp4);
+ nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_icmp);
+ nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp4);
+ nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp4);
nf_unregister_sockopt(&so_getorigdst);
}
module_init(nf_conntrack_l3proto_ipv4_init);
module_exit(nf_conntrack_l3proto_ipv4_fini);
-
-EXPORT_SYMBOL(nf_ct_ipv4_gather_frags);