aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter
diff options
context:
space:
mode:
Diffstat (limited to 'net/netfilter')
-rw-r--r--net/netfilter/Kconfig63
-rw-r--r--net/netfilter/core.c21
-rw-r--r--net/netfilter/nf_conntrack_core.c58
-rw-r--r--net/netfilter/nf_conntrack_ecache.c23
-rw-r--r--net/netfilter/nf_conntrack_expect.c4
-rw-r--r--net/netfilter/nf_conntrack_ftp.c6
-rw-r--r--net/netfilter/nf_conntrack_netbios_ns.c2
-rw-r--r--net/netfilter/nf_conntrack_netlink.c66
-rw-r--r--net/netfilter/nf_conntrack_proto.c144
-rw-r--r--net/netfilter/nf_conntrack_proto_generic.c5
-rw-r--r--net/netfilter/nf_conntrack_proto_sctp.c9
-rw-r--r--net/netfilter/nf_conntrack_proto_tcp.c88
-rw-r--r--net/netfilter/nf_conntrack_proto_udp.c5
-rw-r--r--net/netfilter/nf_conntrack_standalone.c11
-rw-r--r--net/netfilter/nfnetlink.c197
-rw-r--r--net/netfilter/nfnetlink_log.c108
-rw-r--r--net/netfilter/nfnetlink_queue.c20
-rw-r--r--net/netfilter/x_tables.c26
-rw-r--r--net/netfilter/xt_CONNMARK.c32
-rw-r--r--net/netfilter/xt_CONNSECMARK.c18
-rw-r--r--net/netfilter/xt_DSCP.c10
-rw-r--r--net/netfilter/xt_NOTRACK.c4
-rw-r--r--net/netfilter/xt_TCPMSS.c12
-rw-r--r--net/netfilter/xt_connbytes.c35
-rw-r--r--net/netfilter/xt_connmark.c17
-rw-r--r--net/netfilter/xt_conntrack.c110
-rw-r--r--net/netfilter/xt_dscp.c6
-rw-r--r--net/netfilter/xt_hashlimit.c14
-rw-r--r--net/netfilter/xt_helper.c60
-rw-r--r--net/netfilter/xt_length.c5
-rw-r--r--net/netfilter/xt_limit.c7
-rw-r--r--net/netfilter/xt_mac.c4
-rw-r--r--net/netfilter/xt_pkttype.c2
-rw-r--r--net/netfilter/xt_realm.c2
-rw-r--r--net/netfilter/xt_state.c4
35 files changed, 371 insertions, 827 deletions
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 54698af6d0af..c558f3214255 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -25,6 +25,7 @@ config NETFILTER_NETLINK_LOG
and is also scheduled to replace the old syslog-based ipt_LOG
and ip6t_LOG modules.
+# Rename this to NF_CONNTRACK in a 2.6.25
config NF_CONNTRACK_ENABLED
tristate "Netfilter connection tracking support"
help
@@ -39,42 +40,9 @@ config NF_CONNTRACK_ENABLED
To compile it as a module, choose M here. If unsure, say N.
-choice
- prompt "Netfilter connection tracking support"
- depends on NF_CONNTRACK_ENABLED
-
-config NF_CONNTRACK_SUPPORT
- bool "Layer 3 Independent Connection tracking"
- help
- Layer 3 independent connection tracking is experimental scheme
- which generalize ip_conntrack to support other layer 3 protocols.
-
- This is required to do Masquerading or other kinds of Network
- Address Translation (except for Fast NAT). It can also be used to
- enhance packet filtering (see `Connection state match support'
- below).
-
-config IP_NF_CONNTRACK_SUPPORT
- bool "Layer 3 Dependent Connection tracking (OBSOLETE)"
- help
- The old, Layer 3 dependent ip_conntrack subsystem of netfilter.
-
- This is required to do Masquerading or other kinds of Network
- Address Translation (except for Fast NAT). It can also be used to
- enhance packet filtering (see `Connection state match support'
- below).
-
-endchoice
-
config NF_CONNTRACK
tristate
- default m if NF_CONNTRACK_SUPPORT && NF_CONNTRACK_ENABLED=m
- default y if NF_CONNTRACK_SUPPORT && NF_CONNTRACK_ENABLED=y
-
-config IP_NF_CONNTRACK
- tristate
- default m if IP_NF_CONNTRACK_SUPPORT && NF_CONNTRACK_ENABLED=m
- default y if IP_NF_CONNTRACK_SUPPORT && NF_CONNTRACK_ENABLED=y
+ default NF_CONNTRACK_ENABLED
config NF_CT_ACCT
bool "Connection tracking flow accounting"
@@ -303,9 +271,8 @@ config NETFILTER_XT_TARGET_CONNMARK
tristate '"CONNMARK" target support'
depends on NETFILTER_XTABLES
depends on IP_NF_MANGLE || IP6_NF_MANGLE
- depends on IP_NF_CONNTRACK || NF_CONNTRACK
- select IP_NF_CONNTRACK_MARK if IP_NF_CONNTRACK
- select NF_CONNTRACK_MARK if NF_CONNTRACK
+ depends on NF_CONNTRACK
+ select NF_CONNTRACK_MARK
help
This option adds a `CONNMARK' target, which allows one to manipulate
the connection mark value. Similar to the MARK target, but
@@ -366,7 +333,7 @@ config NETFILTER_XT_TARGET_NOTRACK
tristate '"NOTRACK" target support'
depends on NETFILTER_XTABLES
depends on IP_NF_RAW || IP6_NF_RAW
- depends on IP_NF_CONNTRACK || NF_CONNTRACK
+ depends on NF_CONNTRACK
help
The NOTRACK target allows a select rule to specify
which packets *not* to enter the conntrack/NAT
@@ -387,9 +354,7 @@ config NETFILTER_XT_TARGET_SECMARK
config NETFILTER_XT_TARGET_CONNSECMARK
tristate '"CONNSECMARK" target support'
- depends on NETFILTER_XTABLES && \
- ((NF_CONNTRACK && NF_CONNTRACK_SECMARK) || \
- (IP_NF_CONNTRACK && IP_NF_CONNTRACK_SECMARK))
+ depends on NETFILTER_XTABLES && NF_CONNTRACK && NF_CONNTRACK_SECMARK
help
The CONNSECMARK target copies security markings from packets
to connections, and restores security markings from connections
@@ -437,9 +402,8 @@ config NETFILTER_XT_MATCH_COMMENT
config NETFILTER_XT_MATCH_CONNBYTES
tristate '"connbytes" per-connection counter match support'
depends on NETFILTER_XTABLES
- depends on IP_NF_CONNTRACK || NF_CONNTRACK
- select IP_NF_CT_ACCT if IP_NF_CONNTRACK
- select NF_CT_ACCT if NF_CONNTRACK
+ depends on NF_CONNTRACK
+ select NF_CT_ACCT
help
This option adds a `connbytes' match, which allows you to match the
number of bytes and/or packets for each direction within a connection.
@@ -450,9 +414,8 @@ config NETFILTER_XT_MATCH_CONNBYTES
config NETFILTER_XT_MATCH_CONNMARK
tristate '"connmark" connection mark match support'
depends on NETFILTER_XTABLES
- depends on IP_NF_CONNTRACK || NF_CONNTRACK
- select IP_NF_CONNTRACK_MARK if IP_NF_CONNTRACK
- select NF_CONNTRACK_MARK if NF_CONNTRACK
+ depends on NF_CONNTRACK
+ select NF_CONNTRACK_MARK
help
This option adds a `connmark' match, which allows you to match the
connection mark value previously set for the session by `CONNMARK'.
@@ -464,7 +427,7 @@ config NETFILTER_XT_MATCH_CONNMARK
config NETFILTER_XT_MATCH_CONNTRACK
tristate '"conntrack" connection tracking match support'
depends on NETFILTER_XTABLES
- depends on IP_NF_CONNTRACK || NF_CONNTRACK
+ depends on NF_CONNTRACK
help
This is a general conntrack match module, a superset of the state match.
@@ -508,7 +471,7 @@ config NETFILTER_XT_MATCH_ESP
config NETFILTER_XT_MATCH_HELPER
tristate '"helper" match support'
depends on NETFILTER_XTABLES
- depends on IP_NF_CONNTRACK || NF_CONNTRACK
+ depends on NF_CONNTRACK
help
Helper matching allows you to match packets in dynamic connections
tracked by a conntrack-helper, ie. ip_conntrack_ftp
@@ -632,7 +595,7 @@ config NETFILTER_XT_MATCH_SCTP
config NETFILTER_XT_MATCH_STATE
tristate '"state" match support'
depends on NETFILTER_XTABLES
- depends on IP_NF_CONNTRACK || NF_CONNTRACK
+ depends on NF_CONNTRACK
help
Connection state matching allows you to match packets based on their
relationship to a tracked connection (ie. previous packets). This
diff --git a/net/netfilter/core.c b/net/netfilter/core.c
index c3ebdbd917e9..a84478ee2ded 100644
--- a/net/netfilter/core.c
+++ b/net/netfilter/core.c
@@ -5,10 +5,6 @@
* way.
*
* Rusty Russell (C)2000 -- This code is GPL.
- *
- * February 2000: Modified by James Morris to have 1 queue per protocol.
- * 15-Mar-2000: Added NF_REPEAT --RR.
- * 08-May-2003: Internal logging interface added by Jozsef Kadlecsik.
*/
#include <linux/kernel.h>
#include <linux/netfilter.h>
@@ -244,6 +240,7 @@ void nf_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb,
}
EXPORT_SYMBOL(nf_proto_csum_replace4);
+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
/* This does not belong here, but locally generated errors need it if connection
tracking in use: without this, connection may not be in hash table, and hence
manufactured ICMP or RST packets will not be associated with it. */
@@ -264,6 +261,22 @@ void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb)
}
EXPORT_SYMBOL(nf_ct_attach);
+void (*nf_ct_destroy)(struct nf_conntrack *);
+EXPORT_SYMBOL(nf_ct_destroy);
+
+void nf_conntrack_destroy(struct nf_conntrack *nfct)
+{
+ void (*destroy)(struct nf_conntrack *);
+
+ rcu_read_lock();
+ destroy = rcu_dereference(nf_ct_destroy);
+ BUG_ON(destroy == NULL);
+ destroy(nfct);
+ rcu_read_unlock();
+}
+EXPORT_SYMBOL(nf_conntrack_destroy);
+#endif /* CONFIG_NF_CONNTRACK */
+
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *proc_net_netfilter;
EXPORT_SYMBOL(proc_net_netfilter);
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index b3a70eb6d42a..e132c8ae8784 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -9,24 +9,6 @@
* 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.
- *
- * 23 Apr 2001: Harald Welte <laforge@gnumonks.org>
- * - new API and handling of conntrack/nat helpers
- * - now capable of multiple expectations for one master
- * 16 Jul 2002: Harald Welte <laforge@gnumonks.org>
- * - add usage/reference counts to ip_conntrack_expect
- * - export ip_conntrack[_expect]_{find_get,put} functions
- * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
- * - generalize L3 protocol denendent part.
- * 23 Mar 2004: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
- * - add support various size of conntrack structures.
- * 26 Jan 2006: Harald Welte <laforge@netfilter.org>
- * - restructure nf_conn (introduce nf_conn_help)
- * - redesign 'features' how they were originally intended
- * 26 Feb 2006: Pablo Neira Ayuso <pablo@eurodev.net>
- * - add support for L3 protocol module load on demand.
- *
- * Derived from net/ipv4/netfilter/ip_conntrack_core.c
*/
#include <linux/types.h>
@@ -128,10 +110,11 @@ static u_int32_t __hash_conntrack(const struct nf_conntrack_tuple *tuple,
unsigned int size, unsigned int rnd)
{
unsigned int a, b;
- a = jhash((void *)tuple->src.u3.all, sizeof(tuple->src.u3.all),
- ((tuple->src.l3num) << 16) | tuple->dst.protonum);
- b = jhash((void *)tuple->dst.u3.all, sizeof(tuple->dst.u3.all),
- (tuple->src.u.all << 16) | tuple->dst.u.all);
+
+ a = jhash2(tuple->src.u3.all, ARRAY_SIZE(tuple->src.u3.all),
+ (tuple->src.l3num << 16) | tuple->dst.protonum);
+ b = jhash2(tuple->dst.u3.all, ARRAY_SIZE(tuple->dst.u3.all),
+ (tuple->src.u.all << 16) | tuple->dst.u.all);
return jhash_2words(a, b, rnd) % size;
}
@@ -633,13 +616,11 @@ __nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
memset(conntrack, 0, nf_ct_cache[features].size);
conntrack->features = features;
atomic_set(&conntrack->ct_general.use, 1);
- conntrack->ct_general.destroy = destroy_conntrack;
conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple = *orig;
conntrack->tuplehash[IP_CT_DIR_REPLY].tuple = *repl;
/* Don't set timer yet: wait for confirmation */
- init_timer(&conntrack->timeout);
- conntrack->timeout.data = (unsigned long)conntrack;
- conntrack->timeout.function = death_by_timeout;
+ setup_timer(&conntrack->timeout, death_by_timeout,
+ (unsigned long)conntrack);
read_unlock_bh(&nf_ct_cache_lock);
return conntrack;
@@ -768,7 +749,7 @@ resolve_normal_ct(struct sk_buff *skb,
struct nf_conntrack_tuple_hash *h;
struct nf_conn *ct;
- if (!nf_ct_get_tuple(skb, (unsigned int)(skb->nh.raw - skb->data),
+ if (!nf_ct_get_tuple(skb, skb_network_offset(skb),
dataoff, l3num, protonum, &tuple, l3proto,
l4proto)) {
DEBUGP("resolve_normal_ct: Can't get tuple\n");
@@ -960,7 +941,7 @@ void __nf_ct_refresh_acct(struct nf_conn *ct,
if (do_acct) {
ct->counters[CTINFO2DIR(ctinfo)].packets++;
ct->counters[CTINFO2DIR(ctinfo)].bytes +=
- skb->len - (unsigned int)(skb->nh.raw - skb->data);
+ skb->len - skb_network_offset(skb);
if ((ct->counters[CTINFO2DIR(ctinfo)].packets & 0x80000000)
|| (ct->counters[CTINFO2DIR(ctinfo)].bytes & 0x80000000))
@@ -1140,6 +1121,8 @@ void nf_conntrack_cleanup(void)
while (atomic_read(&nf_conntrack_untracked.ct_general.use) > 1)
schedule();
+ rcu_assign_pointer(nf_ct_destroy, NULL);
+
for (i = 0; i < NF_CT_F_NUM; i++) {
if (nf_ct_cache[i].use == 0)
continue;
@@ -1152,14 +1135,7 @@ void nf_conntrack_cleanup(void)
free_conntrack_hash(nf_conntrack_hash, nf_conntrack_vmalloc,
nf_conntrack_htable_size);
- nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_generic);
-
- /* free l3proto protocol tables */
- for (i = 0; i < PF_MAX; i++)
- if (nf_ct_protos[i]) {
- kfree(nf_ct_protos[i]);
- nf_ct_protos[i] = NULL;
- }
+ nf_conntrack_proto_fini();
}
static struct list_head *alloc_hashtable(int size, int *vmalloced)
@@ -1237,7 +1213,6 @@ module_param_call(hashsize, set_hashsize, param_get_uint,
int __init nf_conntrack_init(void)
{
- unsigned int i;
int ret;
/* Idea from tcp.c: use 1/16384 of memory. On i386: 32MB
@@ -1279,18 +1254,13 @@ int __init nf_conntrack_init(void)
goto err_free_conntrack_slab;
}
- ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_generic);
+ ret = nf_conntrack_proto_init();
if (ret < 0)
goto out_free_expect_slab;
- /* Don't NEED lock here, but good form anyway. */
- write_lock_bh(&nf_conntrack_lock);
- for (i = 0; i < AF_MAX; i++)
- nf_ct_l3protos[i] = &nf_conntrack_l3proto_generic;
- write_unlock_bh(&nf_conntrack_lock);
-
/* For use by REJECT target */
rcu_assign_pointer(ip_ct_attach, __nf_conntrack_attach);
+ rcu_assign_pointer(nf_ct_destroy, destroy_conntrack);
/* Set up fake conntrack:
- to never be deleted, not in any hashes */
diff --git a/net/netfilter/nf_conntrack_ecache.c b/net/netfilter/nf_conntrack_ecache.c
index 1a223e0c0856..6bd421df2dbc 100644
--- a/net/netfilter/nf_conntrack_ecache.c
+++ b/net/netfilter/nf_conntrack_ecache.c
@@ -91,3 +91,26 @@ void nf_ct_event_cache_flush(void)
}
}
+int nf_conntrack_register_notifier(struct notifier_block *nb)
+{
+ return atomic_notifier_chain_register(&nf_conntrack_chain, nb);
+}
+EXPORT_SYMBOL_GPL(nf_conntrack_register_notifier);
+
+int nf_conntrack_unregister_notifier(struct notifier_block *nb)
+{
+ return atomic_notifier_chain_unregister(&nf_conntrack_chain, nb);
+}
+EXPORT_SYMBOL_GPL(nf_conntrack_unregister_notifier);
+
+int nf_conntrack_expect_register_notifier(struct notifier_block *nb)
+{
+ return atomic_notifier_chain_register(&nf_conntrack_expect_chain, nb);
+}
+EXPORT_SYMBOL_GPL(nf_conntrack_expect_register_notifier);
+
+int nf_conntrack_expect_unregister_notifier(struct notifier_block *nb)
+{
+ return atomic_notifier_chain_unregister(&nf_conntrack_expect_chain, nb);
+}
+EXPORT_SYMBOL_GPL(nf_conntrack_expect_unregister_notifier);
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c
index ce70a6fc6bda..c31af29a4439 100644
--- a/net/netfilter/nf_conntrack_expect.c
+++ b/net/netfilter/nf_conntrack_expect.c
@@ -290,9 +290,7 @@ static void nf_conntrack_expect_insert(struct nf_conntrack_expect *exp)
master_help->expecting++;
list_add(&exp->list, &nf_conntrack_expect_list);
- init_timer(&exp->timeout);
- exp->timeout.data = (unsigned long)exp;
- exp->timeout.function = expectation_timed_out;
+ setup_timer(&exp->timeout, expectation_timed_out, (unsigned long)exp);
exp->timeout.expires = jiffies + master_help->helper->timeout * HZ;
add_timer(&exp->timeout);
diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c
index 3089dfc40c88..a186799f6542 100644
--- a/net/netfilter/nf_conntrack_ftp.c
+++ b/net/netfilter/nf_conntrack_ftp.c
@@ -7,12 +7,6 @@
* 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>
- * - enable working with Layer 3 protocol independent connection tracking.
- * - track EPRT and EPSV commands with IPv6 address.
- *
- * Derived from net/ipv4/netfilter/ip_conntrack_ftp.c
*/
#include <linux/module.h>
diff --git a/net/netfilter/nf_conntrack_netbios_ns.c b/net/netfilter/nf_conntrack_netbios_ns.c
index bb26a658cc1c..1093478cc007 100644
--- a/net/netfilter/nf_conntrack_netbios_ns.c
+++ b/net/netfilter/nf_conntrack_netbios_ns.c
@@ -46,7 +46,7 @@ static int help(struct sk_buff **pskb, unsigned int protoff,
struct nf_conn *ct, enum ip_conntrack_info ctinfo)
{
struct nf_conntrack_expect *exp;
- struct iphdr *iph = (*pskb)->nh.iph;
+ struct iphdr *iph = ip_hdr(*pskb);
struct rtable *rt = (struct rtable *)(*pskb)->dst;
struct in_device *in_dev;
__be32 mask = 0;
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 48f05314ebf7..aa1a97ee514b 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -6,9 +6,6 @@
* (C) 2003 by Patrick Mchardy <kaber@trash.net>
* (C) 2005-2006 by Pablo Neira Ayuso <pablo@eurodev.net>
*
- * I've reworked this stuff to use attributes instead of conntrack
- * structures. 5.44 am. I need more tea. --pablo 05/07/11.
- *
* Initial connection tracking via netlink development funded and
* generally made possible by Network Robots, Inc. (www.networkrobots.com)
*
@@ -16,8 +13,6 @@
*
* This software may be used and distributed according to the terms
* of the GNU General Public License, incorporated herein by reference.
- *
- * Derived from ip_conntrack_netlink.c: Port by Pablo Neira Ayuso (05/11/14)
*/
#include <linux/init.h>
@@ -33,6 +28,7 @@
#include <linux/notifier.h>
#include <linux/netfilter.h>
+#include <net/netlink.h>
#include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nf_conntrack_core.h>
#include <net/netfilter/nf_conntrack_expect.h>
@@ -268,9 +264,7 @@ ctnetlink_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
struct nlmsghdr *nlh;
struct nfgenmsg *nfmsg;
struct nfattr *nest_parms;
- unsigned char *b;
-
- b = skb->tail;
+ unsigned char *b = skb_tail_pointer(skb);
event |= NFNL_SUBSYS_CTNETLINK << 8;
nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(struct nfgenmsg));
@@ -303,12 +297,12 @@ ctnetlink_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
ctnetlink_dump_use(skb, ct) < 0)
goto nfattr_failure;
- nlh->nlmsg_len = skb->tail - b;
+ nlh->nlmsg_len = skb_tail_pointer(skb) - b;
return skb->len;
nlmsg_failure:
nfattr_failure:
- skb_trim(skb, b - skb->data);
+ nlmsg_trim(skb, b);
return -1;
}
@@ -322,7 +316,7 @@ static int ctnetlink_conntrack_event(struct notifier_block *this,
struct nf_conn *ct = (struct nf_conn *)ptr;
struct sk_buff *skb;
unsigned int type;
- unsigned char *b;
+ sk_buff_data_t b;
unsigned int flags = 0, group;
/* ignore our fake conntrack entry */
@@ -662,7 +656,7 @@ static const size_t cta_min[CTA_MAX] = {
static int
ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
- struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
+ struct nlmsghdr *nlh, struct nfattr *cda[])
{
struct nf_conntrack_tuple_hash *h;
struct nf_conntrack_tuple tuple;
@@ -710,7 +704,7 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
static int
ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
- struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
+ struct nlmsghdr *nlh, struct nfattr *cda[])
{
struct nf_conntrack_tuple_hash *h;
struct nf_conntrack_tuple tuple;
@@ -721,22 +715,12 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
int err = 0;
if (nlh->nlmsg_flags & NLM_F_DUMP) {
- u32 rlen;
-
#ifndef CONFIG_NF_CT_ACCT
if (NFNL_MSG_TYPE(nlh->nlmsg_type) == IPCTNL_MSG_CT_GET_CTRZERO)
return -ENOTSUPP;
#endif
- if ((*errp = netlink_dump_start(ctnl, skb, nlh,
- ctnetlink_dump_table,
- ctnetlink_done)) != 0)
- return -EINVAL;
-
- rlen = NLMSG_ALIGN(nlh->nlmsg_len);
- if (rlen > skb->len)
- rlen = skb->len;
- skb_pull(skb, rlen);
- return 0;
+ return netlink_dump_start(ctnl, skb, nlh, ctnetlink_dump_table,
+ ctnetlink_done);
}
if (nfattr_bad_size(cda, CTA_MAX, cta_min))
@@ -1010,7 +994,7 @@ err:
static int
ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
- struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
+ struct nlmsghdr *nlh, struct nfattr *cda[])
{
struct nf_conntrack_tuple otuple, rtuple;
struct nf_conntrack_tuple_hash *h = NULL;
@@ -1152,9 +1136,7 @@ ctnetlink_exp_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
{
struct nlmsghdr *nlh;
struct nfgenmsg *nfmsg;
- unsigned char *b;
-
- b = skb->tail;
+ unsigned char *b = skb_tail_pointer(skb);
event |= NFNL_SUBSYS_CTNETLINK_EXP << 8;
nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(struct nfgenmsg));
@@ -1168,12 +1150,12 @@ ctnetlink_exp_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
if (ctnetlink_exp_dump_expect(skb, exp) < 0)
goto nfattr_failure;
- nlh->nlmsg_len = skb->tail - b;
+ nlh->nlmsg_len = skb_tail_pointer(skb) - b;
return skb->len;
nlmsg_failure:
nfattr_failure:
- skb_trim(skb, b - skb->data);
+ nlmsg_trim(skb, b);
return -1;
}
@@ -1186,7 +1168,7 @@ static int ctnetlink_expect_event(struct notifier_block *this,
struct nf_conntrack_expect *exp = (struct nf_conntrack_expect *)ptr;
struct sk_buff *skb;
unsigned int type;
- unsigned char *b;
+ sk_buff_data_t b;
int flags = 0;
if (events & IPEXP_NEW) {
@@ -1263,7 +1245,7 @@ static const size_t cta_min_exp[CTA_EXPECT_MAX] = {
static int
ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
- struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
+ struct nlmsghdr *nlh, struct nfattr *cda[])
{
struct nf_conntrack_tuple tuple;
struct nf_conntrack_expect *exp;
@@ -1276,17 +1258,9 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
return -EINVAL;
if (nlh->nlmsg_flags & NLM_F_DUMP) {
- u32 rlen;
-
- if ((*errp = netlink_dump_start(ctnl, skb, nlh,
- ctnetlink_exp_dump_table,
- ctnetlink_done)) != 0)
- return -EINVAL;
- rlen = NLMSG_ALIGN(nlh->nlmsg_len);
- if (rlen > skb->len)
- rlen = skb->len;
- skb_pull(skb, rlen);
- return 0;
+ return netlink_dump_start(ctnl, skb, nlh,
+ ctnetlink_exp_dump_table,
+ ctnetlink_done);
}
if (cda[CTA_EXPECT_MASTER-1])
@@ -1333,7 +1307,7 @@ out:
static int
ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
- struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
+ struct nlmsghdr *nlh, struct nfattr *cda[])
{
struct nf_conntrack_expect *exp, *tmp;
struct nf_conntrack_tuple tuple;
@@ -1467,7 +1441,7 @@ out:
static int
ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
- struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
+ struct nlmsghdr *nlh, struct nfattr *cda[])
{
struct nf_conntrack_tuple tuple;
struct nf_conntrack_expect *exp;
diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c
index 456155f05c75..6d947068c58f 100644
--- a/net/netfilter/nf_conntrack_proto.c
+++ b/net/netfilter/nf_conntrack_proto.c
@@ -28,13 +28,13 @@
#include <net/netfilter/nf_conntrack_l4proto.h>
#include <net/netfilter/nf_conntrack_core.h>
-struct nf_conntrack_l4proto **nf_ct_protos[PF_MAX] __read_mostly;
+static struct nf_conntrack_l4proto **nf_ct_protos[PF_MAX] __read_mostly;
struct nf_conntrack_l3proto *nf_ct_l3protos[AF_MAX] __read_mostly;
EXPORT_SYMBOL_GPL(nf_ct_l3protos);
-#ifdef CONFIG_SYSCTL
-static DEFINE_MUTEX(nf_ct_proto_sysctl_mutex);
+static DEFINE_MUTEX(nf_ct_proto_mutex);
+#ifdef CONFIG_SYSCTL
static int
nf_ct_register_sysctl(struct ctl_table_header **header, struct ctl_table *path,
struct ctl_table *table, unsigned int *users)
@@ -164,13 +164,11 @@ static int nf_ct_l3proto_register_sysctl(struct nf_conntrack_l3proto *l3proto)
int err = 0;
#ifdef CONFIG_SYSCTL
- mutex_lock(&nf_ct_proto_sysctl_mutex);
if (l3proto->ctl_table != NULL) {
err = nf_ct_register_sysctl(&l3proto->ctl_table_header,
l3proto->ctl_table_path,
l3proto->ctl_table, NULL);
}
- mutex_unlock(&nf_ct_proto_sysctl_mutex);
#endif
return err;
}
@@ -178,11 +176,9 @@ static int nf_ct_l3proto_register_sysctl(struct nf_conntrack_l3proto *l3proto)
static void nf_ct_l3proto_unregister_sysctl(struct nf_conntrack_l3proto *l3proto)
{
#ifdef CONFIG_SYSCTL
- mutex_lock(&nf_ct_proto_sysctl_mutex);
if (l3proto->ctl_table_header != NULL)
nf_ct_unregister_sysctl(&l3proto->ctl_table_header,
l3proto->ctl_table, NULL);
- mutex_unlock(&nf_ct_proto_sysctl_mutex);
#endif
}
@@ -190,27 +186,23 @@ int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto)
{
int ret = 0;
- if (proto->l3proto >= AF_MAX) {
- ret = -EBUSY;
- goto out;
- }
+ if (proto->l3proto >= AF_MAX)
+ return -EBUSY;
- write_lock_bh(&nf_conntrack_lock);
+ mutex_lock(&nf_ct_proto_mutex);
if (nf_ct_l3protos[proto->l3proto] != &nf_conntrack_l3proto_generic) {
ret = -EBUSY;
goto out_unlock;
}
- rcu_assign_pointer(nf_ct_l3protos[proto->l3proto], proto);
- write_unlock_bh(&nf_conntrack_lock);
ret = nf_ct_l3proto_register_sysctl(proto);
if (ret < 0)
- nf_conntrack_l3proto_unregister(proto);
- return ret;
+ goto out_unlock;
+
+ rcu_assign_pointer(nf_ct_l3protos[proto->l3proto], proto);
out_unlock:
- write_unlock_bh(&nf_conntrack_lock);
-out:
+ mutex_unlock(&nf_ct_proto_mutex);
return ret;
}
EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_register);
@@ -219,14 +211,14 @@ void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto)
{
BUG_ON(proto->l3proto >= AF_MAX);
- write_lock_bh(&nf_conntrack_lock);
+ mutex_lock(&nf_ct_proto_mutex);
BUG_ON(nf_ct_l3protos[proto->l3proto] != proto);
rcu_assign_pointer(nf_ct_l3protos[proto->l3proto],
&nf_conntrack_l3proto_generic);
- write_unlock_bh(&nf_conntrack_lock);
- synchronize_rcu();
-
nf_ct_l3proto_unregister_sysctl(proto);
+ mutex_unlock(&nf_ct_proto_mutex);
+
+ synchronize_rcu();
/* Remove all contrack entries for this protocol */
nf_ct_iterate_cleanup(kill_l3proto, proto);
@@ -238,7 +230,6 @@ static int nf_ct_l4proto_register_sysctl(struct nf_conntrack_l4proto *l4proto)
int err = 0;
#ifdef CONFIG_SYSCTL
- mutex_lock(&nf_ct_proto_sysctl_mutex);
if (l4proto->ctl_table != NULL) {
err = nf_ct_register_sysctl(l4proto->ctl_table_header,
nf_net_netfilter_sysctl_path,
@@ -260,7 +251,6 @@ static int nf_ct_l4proto_register_sysctl(struct nf_conntrack_l4proto *l4proto)
}
#endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
out:
- mutex_unlock(&nf_ct_proto_sysctl_mutex);
#endif /* CONFIG_SYSCTL */
return err;
}
@@ -268,7 +258,6 @@ out:
static void nf_ct_l4proto_unregister_sysctl(struct nf_conntrack_l4proto *l4proto)
{
#ifdef CONFIG_SYSCTL
- mutex_lock(&nf_ct_proto_sysctl_mutex);
if (l4proto->ctl_table_header != NULL &&
*l4proto->ctl_table_header != NULL)
nf_ct_unregister_sysctl(l4proto->ctl_table_header,
@@ -279,7 +268,6 @@ static void nf_ct_l4proto_unregister_sysctl(struct nf_conntrack_l4proto *l4proto
nf_ct_unregister_sysctl(&l4proto->ctl_compat_table_header,
l4proto->ctl_compat_table, NULL);
#endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
- mutex_unlock(&nf_ct_proto_sysctl_mutex);
#endif /* CONFIG_SYSCTL */
}
@@ -289,68 +277,41 @@ int nf_conntrack_l4proto_register(struct nf_conntrack_l4proto *l4proto)
{
int ret = 0;
- if (l4proto->l3proto >= PF_MAX) {
- ret = -EBUSY;
- goto out;
- }
-
- if (l4proto == &nf_conntrack_l4proto_generic)
- return nf_ct_l4proto_register_sysctl(l4proto);
+ if (l4proto->l3proto >= PF_MAX)
+ return -EBUSY;
-retry:
- write_lock_bh(&nf_conntrack_lock);
- if (nf_ct_protos[l4proto->l3proto]) {
- if (nf_ct_protos[l4proto->l3proto][l4proto->l4proto]
- != &nf_conntrack_l4proto_generic) {
- ret = -EBUSY;
- goto out_unlock;
- }
- } else {
+ mutex_lock(&nf_ct_proto_mutex);
+ if (!nf_ct_protos[l4proto->l3proto]) {
/* l3proto may be loaded latter. */
struct nf_conntrack_l4proto **proto_array;
int i;
- write_unlock_bh(&nf_conntrack_lock);
-
- proto_array = (struct nf_conntrack_l4proto **)
- kmalloc(MAX_NF_CT_PROTO *
- sizeof(struct nf_conntrack_l4proto *),
- GFP_KERNEL);
+ proto_array = kmalloc(MAX_NF_CT_PROTO *
+ sizeof(struct nf_conntrack_l4proto *),
+ GFP_KERNEL);
if (proto_array == NULL) {
ret = -ENOMEM;
- goto out;
+ goto out_unlock;
}
+
for (i = 0; i < MAX_NF_CT_PROTO; i++)
proto_array[i] = &nf_conntrack_l4proto_generic;
-
- write_lock_bh(&nf_conntrack_lock);
- if (nf_ct_protos[l4proto->l3proto]) {
- /* bad timing, but no problem */
- write_unlock_bh(&nf_conntrack_lock);
- kfree(proto_array);
- } else {
- nf_ct_protos[l4proto->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[l4proto->l3proto] = proto_array;
+ } else if (nf_ct_protos[l4proto->l3proto][l4proto->l4proto] !=
+ &nf_conntrack_l4proto_generic) {
+ ret = -EBUSY;
+ goto out_unlock;
}
- rcu_assign_pointer(nf_ct_protos[l4proto->l3proto][l4proto->l4proto], l4proto);
- write_unlock_bh(&nf_conntrack_lock);
-
ret = nf_ct_l4proto_register_sysctl(l4proto);
if (ret < 0)
- nf_conntrack_l4proto_unregister(l4proto);
- return ret;
+ goto out_unlock;
+
+ rcu_assign_pointer(nf_ct_protos[l4proto->l3proto][l4proto->l4proto],
+ l4proto);
out_unlock:
- write_unlock_bh(&nf_conntrack_lock);
-out:
+ mutex_unlock(&nf_ct_proto_mutex);
return ret;
}
EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_register);
@@ -359,21 +320,42 @@ void nf_conntrack_l4proto_unregister(struct nf_conntrack_l4proto *l4proto)
{
BUG_ON(l4proto->l3proto >= PF_MAX);
- if (l4proto == &nf_conntrack_l4proto_generic) {
- nf_ct_l4proto_unregister_sysctl(l4proto);
- return;
- }
-
- write_lock_bh(&nf_conntrack_lock);
+ mutex_lock(&nf_ct_proto_mutex);
BUG_ON(nf_ct_protos[l4proto->l3proto][l4proto->l4proto] != l4proto);
rcu_assign_pointer(nf_ct_protos[l4proto->l3proto][l4proto->l4proto],
&nf_conntrack_l4proto_generic);
- write_unlock_bh(&nf_conntrack_lock);
- synchronize_rcu();
-
nf_ct_l4proto_unregister_sysctl(l4proto);
+ mutex_unlock(&nf_ct_proto_mutex);
+
+ synchronize_rcu();
/* Remove all contrack entries for this protocol */
nf_ct_iterate_cleanup(kill_l4proto, l4proto);
}
EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_unregister);
+
+int nf_conntrack_proto_init(void)
+{
+ unsigned int i;
+ int err;
+
+ err = nf_ct_l4proto_register_sysctl(&nf_conntrack_l4proto_generic);
+ if (err < 0)
+ return err;
+
+ for (i = 0; i < AF_MAX; i++)
+ rcu_assign_pointer(nf_ct_l3protos[i],
+ &nf_conntrack_l3proto_generic);
+ return 0;
+}
+
+void nf_conntrack_proto_fini(void)
+{
+ unsigned int i;
+
+ nf_ct_l4proto_unregister_sysctl(&nf_conntrack_l4proto_generic);
+
+ /* free l3proto protocol tables */
+ for (i = 0; i < PF_MAX; i++)
+ kfree(nf_ct_protos[i]);
+}
diff --git a/net/netfilter/nf_conntrack_proto_generic.c b/net/netfilter/nf_conntrack_proto_generic.c
index 7c069939695a..6faf1bed7224 100644
--- a/net/netfilter/nf_conntrack_proto_generic.c
+++ b/net/netfilter/nf_conntrack_proto_generic.c
@@ -4,11 +4,6 @@
* 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>
- * - enable working with L3 protocol independent connection tracking.
- *
- * Derived from net/ipv4/netfilter/ip_conntrack_proto_generic.c
*/
#include <linux/types.h>
diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c
index 3c80558716a0..0d3254b974c5 100644
--- a/net/netfilter/nf_conntrack_proto_sctp.c
+++ b/net/netfilter/nf_conntrack_proto_sctp.c
@@ -7,15 +7,6 @@
* 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.
- *
- * 17 Oct 2004: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
- * - enable working with L3 protocol independent connection tracking.
- *
- * Derived from net/ipv4/ip_conntrack_sctp.c
- */
-
-/*
- * Added support for proc manipulation of timeouts.
*/
#include <linux/types.h>
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index 153d6619993a..ccdd5d231e0d 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -4,24 +4,6 @@
* 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.
- *
- * Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>:
- * - Real stateful connection tracking
- * - Modified state transitions table
- * - Window scaling support added
- * - SACK support added
- *
- * Willy Tarreau:
- * - State table bugfixes
- * - More robust state changes
- * - Tuning timer parameters
- *
- * 27 Oct 2004: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
- * - genelized Layer 3 protocol part.
- *
- * Derived from net/ipv4/netfilter/ip_conntrack_proto_tcp.c
- *
- * version 2.2
*/
#include <linux/types.h>
@@ -470,11 +452,10 @@ static void tcp_sack(const struct sk_buff *skb, unsigned int dataoff,
/* Fast path for timestamp-only option */
if (length == TCPOLEN_TSTAMP_ALIGNED*4
- && *(__be32 *)ptr ==
- __constant_htonl((TCPOPT_NOP << 24)
- | (TCPOPT_NOP << 16)
- | (TCPOPT_TIMESTAMP << 8)
- | TCPOLEN_TIMESTAMP))
+ && *(__be32 *)ptr == htonl((TCPOPT_NOP << 24)
+ | (TCPOPT_NOP << 16)
+ | (TCPOPT_TIMESTAMP << 8)
+ | TCPOLEN_TIMESTAMP))
return;
while (length > 0) {
@@ -765,26 +746,18 @@ EXPORT_SYMBOL_GPL(nf_conntrack_tcp_update);
#define TH_ECE 0x40
#define TH_CWR 0x80
-/* table of valid flag combinations - ECE and CWR are always valid */
-static u8 tcp_valid_flags[(TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG) + 1] =
+/* table of valid flag combinations - PUSH, ECE and CWR are always valid */
+static u8 tcp_valid_flags[(TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG) + 1] =
{
[TH_SYN] = 1,
- [TH_SYN|TH_PUSH] = 1,
[TH_SYN|TH_URG] = 1,
- [TH_SYN|TH_PUSH|TH_URG] = 1,
[TH_SYN|TH_ACK] = 1,
- [TH_SYN|TH_ACK|TH_PUSH] = 1,
[TH_RST] = 1,
[TH_RST|TH_ACK] = 1,
- [TH_RST|TH_ACK|TH_PUSH] = 1,
[TH_FIN|TH_ACK] = 1,
+ [TH_FIN|TH_ACK|TH_URG] = 1,
[TH_ACK] = 1,
- [TH_ACK|TH_PUSH] = 1,
[TH_ACK|TH_URG] = 1,
- [TH_ACK|TH_URG|TH_PUSH] = 1,
- [TH_FIN|TH_ACK|TH_PUSH] = 1,
- [TH_FIN|TH_ACK|TH_URG] = 1,
- [TH_FIN|TH_ACK|TH_URG|TH_PUSH] = 1,
};
/* Protect conntrack agaist broken packets. Code taken from ipt_unclean.c. */
@@ -831,7 +804,7 @@ static int tcp_error(struct sk_buff *skb,
}
/* Check TCP flags. */
- tcpflags = (((u_int8_t *)th)[13] & ~(TH_ECE|TH_CWR));
+ tcpflags = (((u_int8_t *)th)[13] & ~(TH_ECE|TH_CWR|TH_PUSH));
if (!tcp_valid_flags[tcpflags]) {
if (LOG_INVALID(IPPROTO_TCP))
nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
@@ -1110,11 +1083,26 @@ static int tcp_to_nfattr(struct sk_buff *skb, struct nfattr *nfa,
const struct nf_conn *ct)
{
struct nfattr *nest_parms;
+ struct nf_ct_tcp_flags tmp = {};
read_lock_bh(&tcp_lock);
nest_parms = NFA_NEST(skb, CTA_PROTOINFO_TCP);
NFA_PUT(skb, CTA_PROTOINFO_TCP_STATE, sizeof(u_int8_t),
&ct->proto.tcp.state);
+
+ NFA_PUT(skb, CTA_PROTOINFO_TCP_WSCALE_ORIGINAL, sizeof(u_int8_t),
+ &ct->proto.tcp.seen[0].td_scale);
+
+ NFA_PUT(skb, CTA_PROTOINFO_TCP_WSCALE_REPLY, sizeof(u_int8_t),
+ &ct->proto.tcp.seen[1].td_scale);
+
+ tmp.flags = ct->proto.tcp.seen[0].flags;
+ NFA_PUT(skb, CTA_PROTOINFO_TCP_FLAGS_ORIGINAL,
+ sizeof(struct nf_ct_tcp_flags), &tmp);
+
+ tmp.flags = ct->proto.tcp.seen[1].flags;
+ NFA_PUT(skb, CTA_PROTOINFO_TCP_FLAGS_REPLY,
+ sizeof(struct nf_ct_tcp_flags), &tmp);
read_unlock_bh(&tcp_lock);
NFA_NEST_END(skb, nest_parms);
@@ -1127,7 +1115,11 @@ nfattr_failure:
}
static const size_t cta_min_tcp[CTA_PROTOINFO_TCP_MAX] = {
- [CTA_PROTOINFO_TCP_STATE-1] = sizeof(u_int8_t),
+ [CTA_PROTOINFO_TCP_STATE-1] = sizeof(u_int8_t),
+ [CTA_PROTOINFO_TCP_WSCALE_ORIGINAL-1] = sizeof(u_int8_t),
+ [CTA_PROTOINFO_TCP_WSCALE_REPLY-1] = sizeof(u_int8_t),
+ [CTA_PROTOINFO_TCP_FLAGS_ORIGINAL-1] = sizeof(struct nf_ct_tcp_flags),
+ [CTA_PROTOINFO_TCP_FLAGS_REPLY-1] = sizeof(struct nf_ct_tcp_flags)
};
static int nfattr_to_tcp(struct nfattr *cda[], struct nf_conn *ct)
@@ -1151,6 +1143,30 @@ static int nfattr_to_tcp(struct nfattr *cda[], struct nf_conn *ct)
write_lock_bh(&tcp_lock);
ct->proto.tcp.state =
*(u_int8_t *)NFA_DATA(tb[CTA_PROTOINFO_TCP_STATE-1]);
+
+ if (tb[CTA_PROTOINFO_TCP_FLAGS_ORIGINAL-1]) {
+ struct nf_ct_tcp_flags *attr =
+ NFA_DATA(tb[CTA_PROTOINFO_TCP_FLAGS_ORIGINAL-1]);
+ ct->proto.tcp.seen[0].flags &= ~attr->mask;
+ ct->proto.tcp.seen[0].flags |= attr->flags & attr->mask;
+ }
+
+ if (tb[CTA_PROTOINFO_TCP_FLAGS_REPLY-1]) {
+ struct nf_ct_tcp_flags *attr =
+ NFA_DATA(tb[CTA_PROTOINFO_TCP_FLAGS_REPLY-1]);
+ ct->proto.tcp.seen[1].flags &= ~attr->mask;
+ ct->proto.tcp.seen[1].flags |= attr->flags & attr->mask;
+ }
+
+ if (tb[CTA_PROTOINFO_TCP_WSCALE_ORIGINAL-1] &&
+ tb[CTA_PROTOINFO_TCP_WSCALE_REPLY-1] &&
+ ct->proto.tcp.seen[0].flags & IP_CT_TCP_FLAG_WINDOW_SCALE &&
+ ct->proto.tcp.seen[1].flags & IP_CT_TCP_FLAG_WINDOW_SCALE) {
+ ct->proto.tcp.seen[0].td_scale = *(u_int8_t *)
+ NFA_DATA(tb[CTA_PROTOINFO_TCP_WSCALE_ORIGINAL-1]);
+ ct->proto.tcp.seen[1].td_scale = *(u_int8_t *)
+ NFA_DATA(tb[CTA_PROTOINFO_TCP_WSCALE_REPLY-1]);
+ }
write_unlock_bh(&tcp_lock);
return 0;
diff --git a/net/netfilter/nf_conntrack_proto_udp.c b/net/netfilter/nf_conntrack_proto_udp.c
index a5e5726ec0c7..3620ecc095fd 100644
--- a/net/netfilter/nf_conntrack_proto_udp.c
+++ b/net/netfilter/nf_conntrack_proto_udp.c
@@ -4,11 +4,6 @@
* 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>
- * - enable working with Layer 3 protocol independent connection tracking.
- *
- * Derived from net/ipv4/netfilter/ip_conntrack_proto_udp.c
*/
#include <linux/types.h>
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
index b8586360e519..45baeb0e30f9 100644
--- a/net/netfilter/nf_conntrack_standalone.c
+++ b/net/netfilter/nf_conntrack_standalone.c
@@ -1,20 +1,9 @@
-/* This file contains all the functions required for the standalone
- nf_conntrack module.
-
- These are not required by the compatibility layer.
-*/
-
/* (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.
- *
- * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
- * - generalize L3 protocol dependent part.
- *
- * Derived from net/ipv4/netfilter/ip_conntrack_standalone.c
*/
#include <linux/types.h>
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
index bf23e489e4cd..8797e6953ef2 100644
--- a/net/netfilter/nfnetlink.c
+++ b/net/netfilter/nfnetlink.c
@@ -3,7 +3,7 @@
*
* (C) 2001 by Jay Schulist <jschlst@samba.org>,
* (C) 2002-2005 by Harald Welte <laforge@gnumonks.org>
- * (C) 2005 by Pablo Neira Ayuso <pablo@eurodev.net>
+ * (C) 2005,2007 by Pablo Neira Ayuso <pablo@netfilter.org>
*
* Initial netfilter messages via netlink development funded and
* generally made possible by Network Robots, Inc. (www.networkrobots.com)
@@ -28,10 +28,9 @@
#include <asm/uaccess.h>
#include <asm/system.h>
#include <net/sock.h>
+#include <net/netlink.h>
#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/netfilter.h>
#include <linux/netlink.h>
#include <linux/netfilter/nfnetlink.h>
@@ -41,32 +40,34 @@ MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_NETFILTER);
static char __initdata nfversion[] = "0.30";
-#if 0
-#define DEBUGP(format, args...) \
- printk(KERN_DEBUG "%s(%d):%s(): " format, __FILE__, \
- __LINE__, __FUNCTION__, ## args)
-#else
-#define DEBUGP(format, args...)
-#endif
-
static struct sock *nfnl = NULL;
static struct nfnetlink_subsystem *subsys_table[NFNL_SUBSYS_COUNT];
-DECLARE_MUTEX(nfnl_sem);
+static DEFINE_MUTEX(nfnl_mutex);
-void nfnl_lock(void)
+static void nfnl_lock(void)
{
- nfnl_shlock();
+ mutex_lock(&nfnl_mutex);
}
-void nfnl_unlock(void)
+static int nfnl_trylock(void)
{
- nfnl_shunlock();
+ return !mutex_trylock(&nfnl_mutex);
}
-int nfnetlink_subsys_register(struct nfnetlink_subsystem *n)
+static void __nfnl_unlock(void)
{
- DEBUGP("registering subsystem ID %u\n", n->subsys_id);
+ mutex_unlock(&nfnl_mutex);
+}
+
+static void nfnl_unlock(void)
+{
+ mutex_unlock(&nfnl_mutex);
+ if (nfnl->sk_receive_queue.qlen)
+ nfnl->sk_data_ready(nfnl, 0);
+}
+int nfnetlink_subsys_register(struct nfnetlink_subsystem *n)
+{
nfnl_lock();
if (subsys_table[n->subsys_id]) {
nfnl_unlock();
@@ -77,24 +78,23 @@ int nfnetlink_subsys_register(struct nfnetlink_subsystem *n)
return 0;
}
+EXPORT_SYMBOL_GPL(nfnetlink_subsys_register);
int nfnetlink_subsys_unregister(struct nfnetlink_subsystem *n)
{
- DEBUGP("unregistering subsystem ID %u\n", n->subsys_id);
-
nfnl_lock();
subsys_table[n->subsys_id] = NULL;
nfnl_unlock();
return 0;
}
+EXPORT_SYMBOL_GPL(nfnetlink_subsys_unregister);
static inline struct nfnetlink_subsystem *nfnetlink_get_subsys(u_int16_t type)
{
u_int8_t subsys_id = NFNL_SUBSYS_ID(type);
- if (subsys_id >= NFNL_SUBSYS_COUNT
- || subsys_table[subsys_id] == NULL)
+ if (subsys_id >= NFNL_SUBSYS_COUNT)
return NULL;
return subsys_table[subsys_id];
@@ -105,10 +105,8 @@ nfnetlink_find_client(u_int16_t type, struct nfnetlink_subsystem *ss)
{
u_int8_t cb_id = NFNL_MSG_TYPE(type);
- if (cb_id >= ss->cb_count) {
- DEBUGP("msgtype %u >= %u, returning\n", type, ss->cb_count);
+ if (cb_id >= ss->cb_count)
return NULL;
- }
return &ss->cb[cb_id];
}
@@ -125,6 +123,7 @@ void __nfa_fill(struct sk_buff *skb, int attrtype, int attrlen,
memcpy(NFA_DATA(nfa), data, attrlen);
memset(NFA_DATA(nfa) + attrlen, 0, NFA_ALIGN(size) - size);
}
+EXPORT_SYMBOL_GPL(__nfa_fill);
void nfattr_parse(struct nfattr *tb[], int maxattr, struct nfattr *nfa, int len)
{
@@ -137,6 +136,7 @@ void nfattr_parse(struct nfattr *tb[], int maxattr, struct nfattr *nfa, int len)
nfa = NFA_NEXT(nfa, len);
}
}
+EXPORT_SYMBOL_GPL(nfattr_parse);
/**
* nfnetlink_check_attributes - check and parse nfnetlink attributes
@@ -150,37 +150,15 @@ static int
nfnetlink_check_attributes(struct nfnetlink_subsystem *subsys,
struct nlmsghdr *nlh, struct nfattr *cda[])
{
- int min_len;
- u_int16_t attr_count;
+ int min_len = NLMSG_SPACE(sizeof(struct nfgenmsg));
u_int8_t cb_id = NFNL_MSG_TYPE(nlh->nlmsg_type);
-
- if (unlikely(cb_id >= subsys->cb_count)) {
- DEBUGP("msgtype %u >= %u, returning\n",
- cb_id, subsys->cb_count);
- return -EINVAL;
- }
-
- min_len = NLMSG_SPACE(sizeof(struct nfgenmsg));
- if (unlikely(nlh->nlmsg_len < min_len))
- return -EINVAL;
-
- attr_count = subsys->cb[cb_id].attr_count;
- memset(cda, 0, sizeof(struct nfattr *) * attr_count);
+ u_int16_t attr_count = subsys->cb[cb_id].attr_count;
/* check attribute lengths. */
if (likely(nlh->nlmsg_len > min_len)) {
struct nfattr *attr = NFM_NFA(NLMSG_DATA(nlh));
int attrlen = nlh->nlmsg_len - NLMSG_ALIGN(min_len);
-
- while (NFA_OK(attr, attrlen)) {
- unsigned flavor = NFA_TYPE(attr);
- if (flavor) {
- if (flavor > attr_count)
- return -EINVAL;
- cda[flavor - 1] = attr;
- }
- attr = NFA_NEXT(attr, attrlen);
- }
+ nfattr_parse(cda, attr_count, attr, attrlen);
}
/* implicit: if nlmsg_len == min_len, we return 0, and an empty
@@ -208,62 +186,46 @@ int nfnetlink_send(struct sk_buff *skb, u32 pid, unsigned group, int echo)
return err;
}
+EXPORT_SYMBOL_GPL(nfnetlink_send);
int nfnetlink_unicast(struct sk_buff *skb, u_int32_t pid, int flags)
{
return netlink_unicast(nfnl, skb, pid, flags);
}
+EXPORT_SYMBOL_GPL(nfnetlink_unicast);
/* Process one complete nfnetlink message. */
-static int nfnetlink_rcv_msg(struct sk_buff *skb,
- struct nlmsghdr *nlh, int *errp)
+static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
{
struct nfnl_callback *nc;
struct nfnetlink_subsystem *ss;
- int type, err = 0;
-
- DEBUGP("entered; subsys=%u, msgtype=%u\n",
- NFNL_SUBSYS_ID(nlh->nlmsg_type),
- NFNL_MSG_TYPE(nlh->nlmsg_type));
-
- if (security_netlink_recv(skb, CAP_NET_ADMIN)) {
- DEBUGP("missing CAP_NET_ADMIN\n");
- *errp = -EPERM;
- return -1;
- }
+ int type, err;
- /* Only requests are handled by kernel now. */
- if (!(nlh->nlmsg_flags & NLM_F_REQUEST)) {
- DEBUGP("received non-request message\n");
- return 0;
- }
+ if (security_netlink_recv(skb, CAP_NET_ADMIN))
+ return -EPERM;
/* All the messages must at least contain nfgenmsg */
- if (nlh->nlmsg_len < NLMSG_SPACE(sizeof(struct nfgenmsg))) {
- DEBUGP("received message was too short\n");
+ if (nlh->nlmsg_len < NLMSG_SPACE(sizeof(struct nfgenmsg)))
return 0;
- }
type = nlh->nlmsg_type;
ss = nfnetlink_get_subsys(type);
if (!ss) {
#ifdef CONFIG_KMOD
- /* don't call nfnl_shunlock, since it would reenter
+ /* don't call nfnl_unlock, since it would reenter
* with further packet processing */
- up(&nfnl_sem);
+ __nfnl_unlock();
request_module("nfnetlink-subsys-%d", NFNL_SUBSYS_ID(type));
- nfnl_shlock();
+ nfnl_lock();
ss = nfnetlink_get_subsys(type);
if (!ss)
#endif
- goto err_inval;
+ return -EINVAL;
}
nc = nfnetlink_find_client(type, ss);
- if (!nc) {
- DEBUGP("unable to find client for type %d\n", type);
- goto err_inval;
- }
+ if (!nc)
+ return -EINVAL;
{
u_int16_t attr_count =
@@ -274,73 +236,21 @@ static int nfnetlink_rcv_msg(struct sk_buff *skb,
err = nfnetlink_check_attributes(ss, nlh, cda);
if (err < 0)
- goto err_inval;
-
- DEBUGP("calling handler\n");
- err = nc->call(nfnl, skb, nlh, cda, errp);
- *errp = err;
- return err;
- }
-
-err_inval:
- DEBUGP("returning -EINVAL\n");
- *errp = -EINVAL;
- return -1;
-}
-
-/* Process one packet of messages. */
-static inline int nfnetlink_rcv_skb(struct sk_buff *skb)
-{
- int err;
- struct nlmsghdr *nlh;
-
- while (skb->len >= NLMSG_SPACE(0)) {
- u32 rlen;
-
- nlh = (struct nlmsghdr *)skb->data;
- if (nlh->nlmsg_len < sizeof(struct nlmsghdr)
- || skb->len < nlh->nlmsg_len)
- return 0;
- rlen = NLMSG_ALIGN(nlh->nlmsg_len);
- if (rlen > skb->len)
- rlen = skb->len;
- if (nfnetlink_rcv_msg(skb, nlh, &err)) {
- if (!err)
- return -1;
- netlink_ack(skb, nlh, err);
- } else
- if (nlh->nlmsg_flags & NLM_F_ACK)
- netlink_ack(skb, nlh, 0);
- skb_pull(skb, rlen);
+ return err;
+ return nc->call(nfnl, skb, nlh, cda);
}
-
- return 0;
}
static void nfnetlink_rcv(struct sock *sk, int len)
{
- do {
- struct sk_buff *skb;
+ unsigned int qlen = 0;
- if (nfnl_shlock_nowait())
+ do {
+ if (nfnl_trylock())
return;
-
- while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
- if (nfnetlink_rcv_skb(skb)) {
- if (skb->len)
- skb_queue_head(&sk->sk_receive_queue,
- skb);
- else
- kfree_skb(skb);
- break;
- }
- kfree_skb(skb);
- }
-
- /* don't call nfnl_shunlock, since it would reenter
- * with further packet processing */
- up(&nfnl_sem);
- } while(nfnl && nfnl->sk_receive_queue.qlen);
+ netlink_run_queue(sk, &qlen, nfnetlink_rcv_msg);
+ __nfnl_unlock();
+ } while (qlen);
}
static void __exit nfnetlink_exit(void)
@@ -355,7 +265,7 @@ static int __init nfnetlink_init(void)
printk("Netfilter messages via NETLINK v%s.\n", nfversion);
nfnl = netlink_kernel_create(NETLINK_NETFILTER, NFNLGRP_MAX,
- nfnetlink_rcv, THIS_MODULE);
+ nfnetlink_rcv, NULL, THIS_MODULE);
if (!nfnl) {
printk(KERN_ERR "cannot initialize nfnetlink!\n");
return -1;
@@ -366,10 +276,3 @@ static int __init nfnetlink_init(void)
module_init(nfnetlink_init);
module_exit(nfnetlink_exit);
-
-EXPORT_SYMBOL_GPL(nfnetlink_subsys_register);
-EXPORT_SYMBOL_GPL(nfnetlink_subsys_unregister);
-EXPORT_SYMBOL_GPL(nfnetlink_send);
-EXPORT_SYMBOL_GPL(nfnetlink_unicast);
-EXPORT_SYMBOL_GPL(nfattr_parse);
-EXPORT_SYMBOL_GPL(__nfa_fill);
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index 5cb30ebba0f4..e32e30e7a17c 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -10,11 +10,6 @@
* 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.
- *
- * 2006-01-26 Harald Welte <laforge@netfilter.org>
- * - Add optional local and global sequence number to detect lost
- * events from userspace
- *
*/
#include <linux/module.h>
#include <linux/skbuff.h>
@@ -163,10 +158,7 @@ instance_create(u_int16_t group_num, int pid)
/* needs to be two, since we _put() after creation */
atomic_set(&inst->use, 2);
- init_timer(&inst->timer);
- inst->timer.function = nfulnl_timer;
- inst->timer.data = (unsigned long)inst;
- /* don't start timer yet. (re)start it with every packet */
+ setup_timer(&inst->timer, nfulnl_timer, (unsigned long)inst);
inst->peer_pid = pid;
inst->group_num = group_num;
@@ -200,20 +192,14 @@ out_unlock:
static int __nfulnl_send(struct nfulnl_instance *inst);
static void
-_instance_destroy2(struct nfulnl_instance *inst, int lock)
+__instance_destroy(struct nfulnl_instance *inst)
{
/* first pull it out of the global list */
- if (lock)
- write_lock_bh(&instances_lock);
-
UDEBUG("removing instance %p (queuenum=%u) from hash\n",
inst, inst->group_num);
hlist_del(&inst->hlist);
- if (lock)
- write_unlock_bh(&instances_lock);
-
/* then flush all pending packets from skb */
spin_lock_bh(&inst->lock);
@@ -235,15 +221,11 @@ _instance_destroy2(struct nfulnl_instance *inst, int lock)
}
static inline void
-__instance_destroy(struct nfulnl_instance *inst)
-{
- _instance_destroy2(inst, 0);
-}
-
-static inline void
instance_destroy(struct nfulnl_instance *inst)
{
- _instance_destroy2(inst, 1);
+ write_lock_bh(&instances_lock);
+ __instance_destroy(inst);
+ write_unlock_bh(&instances_lock);
}
static int
@@ -365,9 +347,6 @@ __nfulnl_send(struct nfulnl_instance *inst)
{
int status;
- if (!inst->skb)
- return 0;
-
if (inst->qlen > 1)
inst->lastnlh->nlmsg_type = NLMSG_DONE;
@@ -391,7 +370,8 @@ static void nfulnl_timer(unsigned long data)
UDEBUG("timer function called, flushing buffer\n");
spin_lock_bh(&inst->lock);
- __nfulnl_send(inst);
+ if (inst->skb)
+ __nfulnl_send(inst);
spin_unlock_bh(&inst->lock);
instance_put(inst);
}
@@ -409,15 +389,14 @@ __build_packet_message(struct nfulnl_instance *inst,
const struct nf_loginfo *li,
const char *prefix, unsigned int plen)
{
- unsigned char *old_tail;
struct nfulnl_msg_packet_hdr pmsg;
struct nlmsghdr *nlh;
struct nfgenmsg *nfmsg;
__be32 tmp_uint;
+ sk_buff_data_t old_tail = inst->skb->tail;
UDEBUG("entered\n");
- old_tail = inst->skb->tail;
nlh = NLMSG_PUT(inst->skb, 0, 0,
NFNL_SUBSYS_ULOG << 8 | NFULNL_MSG_PACKET,
sizeof(struct nfgenmsg));
@@ -509,11 +488,11 @@ __build_packet_message(struct nfulnl_instance *inst,
NFA_PUT(inst->skb, NFULA_HWADDR, sizeof(phw), &phw);
}
- if (skb->tstamp.off_sec) {
+ if (skb->tstamp.tv64) {
struct nfulnl_msg_packet_timestamp ts;
-
- ts.sec = cpu_to_be64(skb->tstamp.off_sec);
- ts.usec = cpu_to_be64(skb->tstamp.off_usec);
+ struct timeval tv = ktime_to_timeval(skb->tstamp);
+ ts.sec = cpu_to_be64(tv.tv_sec);
+ ts.usec = cpu_to_be64(tv.tv_usec);
NFA_PUT(inst->skb, NFULA_TIMESTAMP, sizeof(ts), &ts);
}
@@ -596,7 +575,6 @@ nfulnl_log_packet(unsigned int pf,
struct nfulnl_instance *inst;
const struct nf_loginfo *li;
unsigned int qthreshold;
- unsigned int nlbufsiz;
unsigned int plen;
if (li_user && li_user->type == NF_LOG_TYPE_ULOG)
@@ -606,12 +584,7 @@ nfulnl_log_packet(unsigned int pf,
inst = instance_lookup_get(li->u.ulog.group);
if (!inst)
- inst = instance_lookup_get(0);
- if (!inst) {
- PRINTR("nfnetlink_log: trying to log packet, "
- "but no instance for group %u\n", li->u.ulog.group);
return;
- }
plen = 0;
if (prefix)
@@ -667,24 +640,11 @@ nfulnl_log_packet(unsigned int pf,
break;
default:
- spin_unlock_bh(&inst->lock);
- instance_put(inst);
- return;
+ goto unlock_and_release;
}
- if (size > inst->nlbufsiz)
- nlbufsiz = size;
- else
- nlbufsiz = inst->nlbufsiz;
-
- if (!inst->skb) {
- if (!(inst->skb = nfulnl_alloc_skb(nlbufsiz, size))) {
- UDEBUG("error in nfulnl_alloc_skb(%u, %u)\n",
- inst->nlbufsiz, size);
- goto alloc_failure;
- }
- } else if (inst->qlen >= qthreshold ||
- size > skb_tailroom(inst->skb)) {
+ if (inst->qlen >= qthreshold ||
+ (inst->skb && size > skb_tailroom(inst->skb))) {
/* either the queue len is too high or we don't have
* enough room in the skb left. flush to userspace. */
UDEBUG("flushing old skb\n");
@@ -693,12 +653,12 @@ nfulnl_log_packet(unsigned int pf,
if (del_timer(&inst->timer))
instance_put(inst);
__nfulnl_send(inst);
+ }
- if (!(inst->skb = nfulnl_alloc_skb(nlbufsiz, size))) {
- UDEBUG("error in nfulnl_alloc_skb(%u, %u)\n",
- inst->nlbufsiz, size);
+ if (!inst->skb) {
+ inst->skb = nfulnl_alloc_skb(inst->nlbufsiz, size);
+ if (!inst->skb)
goto alloc_failure;
- }
}
UDEBUG("qlen %d, qthreshold %d\n", inst->qlen, qthreshold);
@@ -760,7 +720,7 @@ static struct notifier_block nfulnl_rtnl_notifier = {
static int
nfulnl_recv_unsupp(struct sock *ctnl, struct sk_buff *skb,
- struct nlmsghdr *nlh, struct nfattr *nfqa[], int *errp)
+ struct nlmsghdr *nlh, struct nfattr *nfqa[])
{
return -ENOTSUPP;
}
@@ -798,7 +758,7 @@ static const int nfula_cfg_min[NFULA_CFG_MAX] = {
static int
nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
- struct nlmsghdr *nlh, struct nfattr *nfula[], int *errp)
+ struct nlmsghdr *nlh, struct nfattr *nfula[])
{
struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
u_int16_t group_num = ntohs(nfmsg->res_id);
@@ -830,13 +790,13 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
NETLINK_CB(skb).pid);
if (!inst) {
ret = -EINVAL;
- goto out_put;
+ goto out;
}
break;
case NFULNL_CFG_CMD_UNBIND:
if (!inst) {
ret = -ENODEV;
- goto out_put;
+ goto out;
}
if (inst->peer_pid != NETLINK_CB(skb).pid) {
@@ -845,7 +805,7 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
}
instance_destroy(inst);
- break;
+ goto out;
case NFULNL_CFG_CMD_PF_BIND:
UDEBUG("registering log handler for pf=%u\n", pf);
ret = nf_log_register(pf, &nfulnl_logger);
@@ -869,7 +829,7 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
"group=%u pid=%u =>ENOENT\n",
group_num, NETLINK_CB(skb).pid);
ret = -ENOENT;
- goto out_put;
+ goto out;
}
if (inst->peer_pid != NETLINK_CB(skb).pid) {
@@ -939,10 +899,8 @@ struct iter_state {
unsigned int bucket;
};
-static struct hlist_node *get_first(struct seq_file *seq)
+static struct hlist_node *get_first(struct iter_state *st)
{
- struct iter_state *st = seq->private;
-
if (!st)
return NULL;
@@ -953,10 +911,8 @@ static struct hlist_node *get_first(struct seq_file *seq)
return NULL;
}
-static struct hlist_node *get_next(struct seq_file *seq, struct hlist_node *h)
+static struct hlist_node *get_next(struct iter_state *st, struct hlist_node *h)
{
- struct iter_state *st = seq->private;
-
h = h->next;
while (!h) {
if (++st->bucket >= INSTANCE_BUCKETS)
@@ -967,13 +923,13 @@ static struct hlist_node *get_next(struct seq_file *seq, struct hlist_node *h)
return h;
}
-static struct hlist_node *get_idx(struct seq_file *seq, loff_t pos)
+static struct hlist_node *get_idx(struct iter_state *st, loff_t pos)
{
struct hlist_node *head;
- head = get_first(seq);
+ head = get_first(st);
if (head)
- while (pos && (head = get_next(seq, head)))
+ while (pos && (head = get_next(st, head)))
pos--;
return pos ? NULL : head;
}
@@ -981,13 +937,13 @@ static struct hlist_node *get_idx(struct seq_file *seq, loff_t pos)
static void *seq_start(struct seq_file *seq, loff_t *pos)
{
read_lock_bh(&instances_lock);
- return get_idx(seq, *pos);
+ return get_idx(seq->private, *pos);
}
static void *seq_next(struct seq_file *s, void *v, loff_t *pos)
{
(*pos)++;
- return get_next(s, v);
+ return get_next(s->private, v);
}
static void seq_stop(struct seq_file *s, void *v)
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index d9ce4a71d0f3..7a97bec67729 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -338,7 +338,7 @@ static struct sk_buff *
nfqnl_build_packet_message(struct nfqnl_instance *queue,
struct nfqnl_queue_entry *entry, int *errp)
{
- unsigned char *old_tail;
+ sk_buff_data_t old_tail;
size_t size;
size_t data_len = 0;
struct sk_buff *skb;
@@ -404,7 +404,7 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
if (!skb)
goto nlmsg_failure;
- old_tail= skb->tail;
+ old_tail = skb->tail;
nlh = NLMSG_PUT(skb, 0, 0,
NFNL_SUBSYS_QUEUE << 8 | NFQNL_MSG_PACKET,
sizeof(struct nfgenmsg));
@@ -495,11 +495,11 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
NFA_PUT(skb, NFQA_HWADDR, sizeof(phw), &phw);
}
- if (entskb->tstamp.off_sec) {
+ if (entskb->tstamp.tv64) {
struct nfqnl_msg_packet_timestamp ts;
-
- ts.sec = cpu_to_be64(entskb->tstamp.off_sec);
- ts.usec = cpu_to_be64(entskb->tstamp.off_usec);
+ struct timeval tv = ktime_to_timeval(entskb->tstamp);
+ ts.sec = cpu_to_be64(tv.tv_sec);
+ ts.usec = cpu_to_be64(tv.tv_usec);
NFA_PUT(skb, NFQA_TIMESTAMP, sizeof(ts), &ts);
}
@@ -648,7 +648,7 @@ nfqnl_mangle(void *data, int data_len, struct nfqnl_queue_entry *e)
}
if (!skb_make_writable(&e->skb, data_len))
return -ENOMEM;
- memcpy(e->skb->data, data, data_len);
+ skb_copy_to_linear_data(e->skb, data, data_len);
e->skb->ip_summed = CHECKSUM_NONE;
return 0;
}
@@ -783,7 +783,7 @@ static const int nfqa_verdict_min[NFQA_MAX] = {
static int
nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb,
- struct nlmsghdr *nlh, struct nfattr *nfqa[], int *errp)
+ struct nlmsghdr *nlh, struct nfattr *nfqa[])
{
struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
u_int16_t queue_num = ntohs(nfmsg->res_id);
@@ -848,7 +848,7 @@ err_out_put:
static int
nfqnl_recv_unsupp(struct sock *ctnl, struct sk_buff *skb,
- struct nlmsghdr *nlh, struct nfattr *nfqa[], int *errp)
+ struct nlmsghdr *nlh, struct nfattr *nfqa[])
{
return -ENOTSUPP;
}
@@ -865,7 +865,7 @@ static struct nf_queue_handler nfqh = {
static int
nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
- struct nlmsghdr *nlh, struct nfattr *nfqa[], int *errp)
+ struct nlmsghdr *nlh, struct nfattr *nfqa[])
{
struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
u_int16_t queue_num = ntohs(nfmsg->res_id);
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index ec607a421a5a..0eb2504b89b5 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -56,8 +56,8 @@ enum {
};
static const char *xt_prefix[NPROTO] = {
- [AF_INET] = "ip",
- [AF_INET6] = "ip6",
+ [AF_INET] = "ip",
+ [AF_INET6] = "ip6",
[NF_ARP] = "arp",
};
@@ -651,12 +651,6 @@ void *xt_unregister_table(struct xt_table *table)
EXPORT_SYMBOL_GPL(xt_unregister_table);
#ifdef CONFIG_PROC_FS
-static char *xt_proto_prefix[NPROTO] = {
- [AF_INET] = "ip",
- [AF_INET6] = "ip6",
- [NF_ARP] = "arp",
-};
-
static struct list_head *xt_get_idx(struct list_head *list, struct seq_file *seq, loff_t pos)
{
struct list_head *head = list->next;
@@ -798,7 +792,7 @@ int xt_proto_init(int af)
#ifdef CONFIG_PROC_FS
- strlcpy(buf, xt_proto_prefix[af], sizeof(buf));
+ strlcpy(buf, xt_prefix[af], sizeof(buf));
strlcat(buf, FORMAT_TABLES, sizeof(buf));
proc = proc_net_fops_create(buf, 0440, &xt_file_ops);
if (!proc)
@@ -806,14 +800,14 @@ int xt_proto_init(int af)
proc->data = (void *) ((unsigned long) af | (TABLE << 16));
- strlcpy(buf, xt_proto_prefix[af], sizeof(buf));
+ strlcpy(buf, xt_prefix[af], sizeof(buf));
strlcat(buf, FORMAT_MATCHES, sizeof(buf));
proc = proc_net_fops_create(buf, 0440, &xt_file_ops);
if (!proc)
goto out_remove_tables;
proc->data = (void *) ((unsigned long) af | (MATCH << 16));
- strlcpy(buf, xt_proto_prefix[af], sizeof(buf));
+ strlcpy(buf, xt_prefix[af], sizeof(buf));
strlcat(buf, FORMAT_TARGETS, sizeof(buf));
proc = proc_net_fops_create(buf, 0440, &xt_file_ops);
if (!proc)
@@ -825,12 +819,12 @@ int xt_proto_init(int af)
#ifdef CONFIG_PROC_FS
out_remove_matches:
- strlcpy(buf, xt_proto_prefix[af], sizeof(buf));
+ strlcpy(buf, xt_prefix[af], sizeof(buf));
strlcat(buf, FORMAT_MATCHES, sizeof(buf));
proc_net_remove(buf);
out_remove_tables:
- strlcpy(buf, xt_proto_prefix[af], sizeof(buf));
+ strlcpy(buf, xt_prefix[af], sizeof(buf));
strlcat(buf, FORMAT_TABLES, sizeof(buf));
proc_net_remove(buf);
out:
@@ -844,15 +838,15 @@ void xt_proto_fini(int af)
#ifdef CONFIG_PROC_FS
char buf[XT_FUNCTION_MAXNAMELEN];
- strlcpy(buf, xt_proto_prefix[af], sizeof(buf));
+ strlcpy(buf, xt_prefix[af], sizeof(buf));
strlcat(buf, FORMAT_TABLES, sizeof(buf));
proc_net_remove(buf);
- strlcpy(buf, xt_proto_prefix[af], sizeof(buf));
+ strlcpy(buf, xt_prefix[af], sizeof(buf));
strlcat(buf, FORMAT_TARGETS, sizeof(buf));
proc_net_remove(buf);
- strlcpy(buf, xt_proto_prefix[af], sizeof(buf));
+ strlcpy(buf, xt_prefix[af], sizeof(buf));
strlcat(buf, FORMAT_MATCHES, sizeof(buf));
proc_net_remove(buf);
#endif /*CONFIG_PROC_FS*/
diff --git a/net/netfilter/xt_CONNMARK.c b/net/netfilter/xt_CONNMARK.c
index 795c058b16a5..b03ce009d0bf 100644
--- a/net/netfilter/xt_CONNMARK.c
+++ b/net/netfilter/xt_CONNMARK.c
@@ -30,10 +30,7 @@ MODULE_ALIAS("ipt_CONNMARK");
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter/xt_CONNMARK.h>
-#include <net/netfilter/nf_conntrack_compat.h>
-#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
#include <net/netfilter/nf_conntrack_ecache.h>
-#endif
static unsigned int
target(struct sk_buff **pskb,
@@ -44,40 +41,33 @@ target(struct sk_buff **pskb,
const void *targinfo)
{
const struct xt_connmark_target_info *markinfo = targinfo;
+ struct nf_conn *ct;
+ enum ip_conntrack_info ctinfo;
u_int32_t diff;
u_int32_t mark;
u_int32_t newmark;
- u_int32_t ctinfo;
- u_int32_t *ctmark = nf_ct_get_mark(*pskb, &ctinfo);
- if (ctmark) {
+ ct = nf_ct_get(*pskb, &ctinfo);
+ if (ct) {
switch(markinfo->mode) {
case XT_CONNMARK_SET:
- newmark = (*ctmark & ~markinfo->mask) | markinfo->mark;
- if (newmark != *ctmark) {
- *ctmark = newmark;
-#if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE)
- ip_conntrack_event_cache(IPCT_MARK, *pskb);
-#else
+ newmark = (ct->mark & ~markinfo->mask) | markinfo->mark;
+ if (newmark != ct->mark) {
+ ct->mark = newmark;
nf_conntrack_event_cache(IPCT_MARK, *pskb);
-#endif
}
break;
case XT_CONNMARK_SAVE:
- newmark = (*ctmark & ~markinfo->mask) |
+ newmark = (ct->mark & ~markinfo->mask) |
((*pskb)->mark & markinfo->mask);
- if (*ctmark != newmark) {
- *ctmark = newmark;
-#if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE)
- ip_conntrack_event_cache(IPCT_MARK, *pskb);
-#else
+ if (ct->mark != newmark) {
+ ct->mark = newmark;
nf_conntrack_event_cache(IPCT_MARK, *pskb);
-#endif
}
break;
case XT_CONNMARK_RESTORE:
mark = (*pskb)->mark;
- diff = (*ctmark ^ mark) & markinfo->mask;
+ diff = (ct->mark ^ mark) & markinfo->mask;
(*pskb)->mark = mark ^ diff;
break;
}
diff --git a/net/netfilter/xt_CONNSECMARK.c b/net/netfilter/xt_CONNSECMARK.c
index 1ab0db641f96..81c0c58bab47 100644
--- a/net/netfilter/xt_CONNSECMARK.c
+++ b/net/netfilter/xt_CONNSECMARK.c
@@ -19,7 +19,7 @@
#include <linux/skbuff.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter/xt_CONNSECMARK.h>
-#include <net/netfilter/nf_conntrack_compat.h>
+#include <net/netfilter/nf_conntrack.h>
#define PFX "CONNSECMARK: "
@@ -36,12 +36,12 @@ MODULE_ALIAS("ip6t_CONNSECMARK");
static void secmark_save(struct sk_buff *skb)
{
if (skb->secmark) {
- u32 *connsecmark;
+ struct nf_conn *ct;
enum ip_conntrack_info ctinfo;
- connsecmark = nf_ct_get_secmark(skb, &ctinfo);
- if (connsecmark && !*connsecmark)
- *connsecmark = skb->secmark;
+ ct = nf_ct_get(skb, &ctinfo);
+ if (ct && !ct->secmark)
+ ct->secmark = skb->secmark;
}
}
@@ -52,12 +52,12 @@ static void secmark_save(struct sk_buff *skb)
static void secmark_restore(struct sk_buff *skb)
{
if (!skb->secmark) {
- u32 *connsecmark;
+ struct nf_conn *ct;
enum ip_conntrack_info ctinfo;
- connsecmark = nf_ct_get_secmark(skb, &ctinfo);
- if (connsecmark && *connsecmark)
- skb->secmark = *connsecmark;
+ ct = nf_ct_get(skb, &ctinfo);
+ if (ct && ct->secmark)
+ skb->secmark = ct->secmark;
}
}
diff --git a/net/netfilter/xt_DSCP.c b/net/netfilter/xt_DSCP.c
index a7cc75aeb38d..9f2f2201f6ae 100644
--- a/net/netfilter/xt_DSCP.c
+++ b/net/netfilter/xt_DSCP.c
@@ -8,8 +8,6 @@
* published by the Free Software Foundation.
*
* See RFC2474 for a description of the DSCP field within the IP Header.
- *
- * xt_DSCP.c,v 1.8 2002/08/06 18:41:57 laforge Exp
*/
#include <linux/module.h>
@@ -35,13 +33,13 @@ static unsigned int target(struct sk_buff **pskb,
const void *targinfo)
{
const struct xt_DSCP_info *dinfo = targinfo;
- u_int8_t dscp = ipv4_get_dsfield((*pskb)->nh.iph) >> XT_DSCP_SHIFT;
+ u_int8_t dscp = ipv4_get_dsfield(ip_hdr(*pskb)) >> XT_DSCP_SHIFT;
if (dscp != dinfo->dscp) {
if (!skb_make_writable(pskb, sizeof(struct iphdr)))
return NF_DROP;
- ipv4_change_dsfield((*pskb)->nh.iph, (__u8)(~XT_DSCP_MASK),
+ ipv4_change_dsfield(ip_hdr(*pskb), (__u8)(~XT_DSCP_MASK),
dinfo->dscp << XT_DSCP_SHIFT);
}
@@ -56,13 +54,13 @@ static unsigned int target6(struct sk_buff **pskb,
const void *targinfo)
{
const struct xt_DSCP_info *dinfo = targinfo;
- u_int8_t dscp = ipv6_get_dsfield((*pskb)->nh.ipv6h) >> XT_DSCP_SHIFT;
+ u_int8_t dscp = ipv6_get_dsfield(ipv6_hdr(*pskb)) >> XT_DSCP_SHIFT;
if (dscp != dinfo->dscp) {
if (!skb_make_writable(pskb, sizeof(struct ipv6hdr)))
return NF_DROP;
- ipv6_change_dsfield((*pskb)->nh.ipv6h, (__u8)(~XT_DSCP_MASK),
+ ipv6_change_dsfield(ipv6_hdr(*pskb), (__u8)(~XT_DSCP_MASK),
dinfo->dscp << XT_DSCP_SHIFT);
}
return XT_CONTINUE;
diff --git a/net/netfilter/xt_NOTRACK.c b/net/netfilter/xt_NOTRACK.c
index b874a2008b2b..5085fb3d1e2d 100644
--- a/net/netfilter/xt_NOTRACK.c
+++ b/net/netfilter/xt_NOTRACK.c
@@ -5,7 +5,7 @@
#include <linux/skbuff.h>
#include <linux/netfilter/x_tables.h>
-#include <net/netfilter/nf_conntrack_compat.h>
+#include <net/netfilter/nf_conntrack.h>
MODULE_LICENSE("GPL");
MODULE_ALIAS("ipt_NOTRACK");
@@ -26,7 +26,7 @@ target(struct sk_buff **pskb,
If there is a real ct entry correspondig to this packet,
it'll hang aroun till timing out. We don't deal with it
for performance reasons. JK */
- nf_ct_untrack(*pskb);
+ (*pskb)->nfct = &nf_conntrack_untracked.ct_general;
(*pskb)->nfctinfo = IP_CT_NEW;
nf_conntrack_get((*pskb)->nfct);
diff --git a/net/netfilter/xt_TCPMSS.c b/net/netfilter/xt_TCPMSS.c
index db7e38c08de2..15fe8f649510 100644
--- a/net/netfilter/xt_TCPMSS.c
+++ b/net/netfilter/xt_TCPMSS.c
@@ -54,7 +54,7 @@ tcpmss_mangle_packet(struct sk_buff **pskb,
return -1;
tcplen = (*pskb)->len - tcphoff;
- tcph = (struct tcphdr *)((*pskb)->nh.raw + tcphoff);
+ tcph = (struct tcphdr *)(skb_network_header(*pskb) + tcphoff);
/* Since it passed flags test in tcp match, we know it is is
not a fragment, and has data >= tcp header length. SYN
@@ -113,7 +113,7 @@ tcpmss_mangle_packet(struct sk_buff **pskb,
return -1;
kfree_skb(*pskb);
*pskb = newskb;
- tcph = (struct tcphdr *)((*pskb)->nh.raw + tcphoff);
+ tcph = (struct tcphdr *)(skb_network_header(*pskb) + tcphoff);
}
skb_put((*pskb), TCPOLEN_MSS);
@@ -145,7 +145,7 @@ xt_tcpmss_target4(struct sk_buff **pskb,
const struct xt_target *target,
const void *targinfo)
{
- struct iphdr *iph = (*pskb)->nh.iph;
+ struct iphdr *iph = ip_hdr(*pskb);
__be16 newlen;
int ret;
@@ -154,7 +154,7 @@ xt_tcpmss_target4(struct sk_buff **pskb,
if (ret < 0)
return NF_DROP;
if (ret > 0) {
- iph = (*pskb)->nh.iph;
+ iph = ip_hdr(*pskb);
newlen = htons(ntohs(iph->tot_len) + ret);
nf_csum_replace2(&iph->check, iph->tot_len, newlen);
iph->tot_len = newlen;
@@ -171,7 +171,7 @@ xt_tcpmss_target6(struct sk_buff **pskb,
const struct xt_target *target,
const void *targinfo)
{
- struct ipv6hdr *ipv6h = (*pskb)->nh.ipv6h;
+ struct ipv6hdr *ipv6h = ipv6_hdr(*pskb);
u8 nexthdr;
int tcphoff;
int ret;
@@ -187,7 +187,7 @@ xt_tcpmss_target6(struct sk_buff **pskb,
if (ret < 0)
return NF_DROP;
if (ret > 0) {
- ipv6h = (*pskb)->nh.ipv6h;
+ ipv6h = ipv6_hdr(*pskb);
ipv6h->payload_len = htons(ntohs(ipv6h->payload_len) + ret);
}
return XT_CONTINUE;
diff --git a/net/netfilter/xt_connbytes.c b/net/netfilter/xt_connbytes.c
index 5e32dfa2668b..804afe55e141 100644
--- a/net/netfilter/xt_connbytes.c
+++ b/net/netfilter/xt_connbytes.c
@@ -1,20 +1,11 @@
/* Kernel module to match connection tracking byte counter.
* GPL (C) 2002 Martin Devera (devik@cdi.cz).
- *
- * 2004-07-20 Harald Welte <laforge@netfilter.org>
- * - reimplemented to use per-connection accounting counters
- * - add functionality to match number of packets
- * - add functionality to match average packet size
- * - add support to match directions seperately
- * 2005-10-16 Harald Welte <laforge@netfilter.org>
- * - Port to x_tables
- *
*/
#include <linux/module.h>
#include <linux/skbuff.h>
-#include <net/netfilter/nf_conntrack_compat.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter/xt_connbytes.h>
+#include <net/netfilter/nf_conntrack.h>
#include <asm/div64.h>
#include <asm/bitops.h>
@@ -24,22 +15,6 @@ MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
MODULE_DESCRIPTION("iptables match for matching number of pkts/bytes per connection");
MODULE_ALIAS("ipt_connbytes");
-/* 64bit divisor, dividend and result. dynamic precision */
-static u_int64_t div64_64(u_int64_t dividend, u_int64_t divisor)
-{
- u_int32_t d = divisor;
-
- if (divisor > 0xffffffffULL) {
- unsigned int shift = fls(divisor >> 32);
-
- d = divisor >> shift;
- dividend >>= shift;
- }
-
- do_div(dividend, d);
- return dividend;
-}
-
static int
match(const struct sk_buff *skb,
const struct net_device *in,
@@ -51,13 +26,17 @@ match(const struct sk_buff *skb,
int *hotdrop)
{
const struct xt_connbytes_info *sinfo = matchinfo;
+ struct nf_conn *ct;
+ enum ip_conntrack_info ctinfo;
u_int64_t what = 0; /* initialize to make gcc happy */
u_int64_t bytes = 0;
u_int64_t pkts = 0;
const struct ip_conntrack_counter *counters;
- if (!(counters = nf_ct_get_counters(skb)))
- return 0; /* no match */
+ ct = nf_ct_get(skb, &ctinfo);
+ if (!ct)
+ return 0;
+ counters = ct->counters;
switch (sinfo->what) {
case XT_CONNBYTES_PKTS:
diff --git a/net/netfilter/xt_connmark.c b/net/netfilter/xt_connmark.c
index 36c2defff238..e1803256c792 100644
--- a/net/netfilter/xt_connmark.c
+++ b/net/netfilter/xt_connmark.c
@@ -21,16 +21,15 @@
#include <linux/module.h>
#include <linux/skbuff.h>
+#include <net/netfilter/nf_conntrack.h>
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter/xt_connmark.h>
MODULE_AUTHOR("Henrik Nordstrom <hno@marasytems.com>");
MODULE_DESCRIPTION("IP tables connmark match module");
MODULE_LICENSE("GPL");
MODULE_ALIAS("ipt_connmark");
-#include <linux/netfilter/x_tables.h>
-#include <linux/netfilter/xt_connmark.h>
-#include <net/netfilter/nf_conntrack_compat.h>
-
static int
match(const struct sk_buff *skb,
const struct net_device *in,
@@ -42,12 +41,14 @@ match(const struct sk_buff *skb,
int *hotdrop)
{
const struct xt_connmark_info *info = matchinfo;
- u_int32_t ctinfo;
- const u_int32_t *ctmark = nf_ct_get_mark(skb, &ctinfo);
- if (!ctmark)
+ struct nf_conn *ct;
+ enum ip_conntrack_info ctinfo;
+
+ ct = nf_ct_get(skb, &ctinfo);
+ if (!ct)
return 0;
- return (((*ctmark) & info->mask) == info->mark) ^ info->invert;
+ return (((ct->mark) & info->mask) == info->mark) ^ info->invert;
}
static int
diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c
index 2885c378288e..f4ea8fe07a53 100644
--- a/net/netfilter/xt_conntrack.c
+++ b/net/netfilter/xt_conntrack.c
@@ -10,121 +10,15 @@
#include <linux/module.h>
#include <linux/skbuff.h>
-
-#if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE)
-#include <linux/netfilter_ipv4/ip_conntrack.h>
-#include <linux/netfilter_ipv4/ip_conntrack_tuple.h>
-#else
-#include <net/netfilter/nf_conntrack.h>
-#endif
-
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter/xt_conntrack.h>
-#include <net/netfilter/nf_conntrack_compat.h>
+#include <net/netfilter/nf_conntrack.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
MODULE_DESCRIPTION("iptables connection tracking match module");
MODULE_ALIAS("ipt_conntrack");
-#if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE)
-
-static int
-match(const struct sk_buff *skb,
- const struct net_device *in,
- const struct net_device *out,
- const struct xt_match *match,
- const void *matchinfo,
- int offset,
- unsigned int protoff,
- int *hotdrop)
-{
- const struct xt_conntrack_info *sinfo = matchinfo;
- struct ip_conntrack *ct;
- enum ip_conntrack_info ctinfo;
- unsigned int statebit;
-
- ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo);
-
-#define FWINV(bool, invflg) ((bool) ^ !!(sinfo->invflags & invflg))
-
- if (ct == &ip_conntrack_untracked)
- statebit = XT_CONNTRACK_STATE_UNTRACKED;
- else if (ct)
- statebit = XT_CONNTRACK_STATE_BIT(ctinfo);
- else
- statebit = XT_CONNTRACK_STATE_INVALID;
-
- if (sinfo->flags & XT_CONNTRACK_STATE) {
- if (ct) {
- if (test_bit(IPS_SRC_NAT_BIT, &ct->status))
- statebit |= XT_CONNTRACK_STATE_SNAT;
- if (test_bit(IPS_DST_NAT_BIT, &ct->status))
- statebit |= XT_CONNTRACK_STATE_DNAT;
- }
- if (FWINV((statebit & sinfo->statemask) == 0,
- XT_CONNTRACK_STATE))
- return 0;
- }
-
- if (ct == NULL) {
- if (sinfo->flags & ~XT_CONNTRACK_STATE)
- return 0;
- return 1;
- }
-
- if (sinfo->flags & XT_CONNTRACK_PROTO &&
- FWINV(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum !=
- sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum,
- XT_CONNTRACK_PROTO))
- return 0;
-
- if (sinfo->flags & XT_CONNTRACK_ORIGSRC &&
- FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip &
- sinfo->sipmsk[IP_CT_DIR_ORIGINAL].s_addr) !=
- sinfo->tuple[IP_CT_DIR_ORIGINAL].src.ip,
- XT_CONNTRACK_ORIGSRC))
- return 0;
-
- if (sinfo->flags & XT_CONNTRACK_ORIGDST &&
- FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip &
- sinfo->dipmsk[IP_CT_DIR_ORIGINAL].s_addr) !=
- sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.ip,
- XT_CONNTRACK_ORIGDST))
- return 0;
-
- if (sinfo->flags & XT_CONNTRACK_REPLSRC &&
- FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip &
- sinfo->sipmsk[IP_CT_DIR_REPLY].s_addr) !=
- sinfo->tuple[IP_CT_DIR_REPLY].src.ip,
- XT_CONNTRACK_REPLSRC))
- return 0;
-
- if (sinfo->flags & XT_CONNTRACK_REPLDST &&
- FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip &
- sinfo->dipmsk[IP_CT_DIR_REPLY].s_addr) !=
- sinfo->tuple[IP_CT_DIR_REPLY].dst.ip,
- XT_CONNTRACK_REPLDST))
- return 0;
-
- if (sinfo->flags & XT_CONNTRACK_STATUS &&
- FWINV((ct->status & sinfo->statusmask) == 0,
- XT_CONNTRACK_STATUS))
- return 0;
-
- if (sinfo->flags & XT_CONNTRACK_EXPIRES) {
- unsigned long expires = timer_pending(&ct->timeout) ?
- (ct->timeout.expires - jiffies)/HZ : 0;
-
- if (FWINV(!(expires >= sinfo->expires_min &&
- expires <= sinfo->expires_max),
- XT_CONNTRACK_EXPIRES))
- return 0;
- }
- return 1;
-}
-
-#else /* CONFIG_IP_NF_CONNTRACK */
static int
match(const struct sk_buff *skb,
const struct net_device *in,
@@ -220,8 +114,6 @@ match(const struct sk_buff *skb,
return 1;
}
-#endif /* CONFIG_NF_IP_CONNTRACK */
-
static int
checkentry(const char *tablename,
const void *ip,
diff --git a/net/netfilter/xt_dscp.c b/net/netfilter/xt_dscp.c
index 26c7f4ad102a..56b247ecc283 100644
--- a/net/netfilter/xt_dscp.c
+++ b/net/netfilter/xt_dscp.c
@@ -1,7 +1,5 @@
/* IP tables module for matching the value of the IPv4/IPv6 DSCP field
*
- * xt_dscp.c,v 1.3 2002/08/05 19:00:21 laforge Exp
- *
* (C) 2002 by Harald Welte <laforge@netfilter.org>
*
* This program is free software; you can redistribute it and/or modify
@@ -34,7 +32,7 @@ static int match(const struct sk_buff *skb,
int *hotdrop)
{
const struct xt_dscp_info *info = matchinfo;
- u_int8_t dscp = ipv4_get_dsfield(skb->nh.iph) >> XT_DSCP_SHIFT;
+ u_int8_t dscp = ipv4_get_dsfield(ip_hdr(skb)) >> XT_DSCP_SHIFT;
return (dscp == info->dscp) ^ !!info->invert;
}
@@ -49,7 +47,7 @@ static int match6(const struct sk_buff *skb,
int *hotdrop)
{
const struct xt_dscp_info *info = matchinfo;
- u_int8_t dscp = ipv6_get_dsfield(skb->nh.ipv6h) >> XT_DSCP_SHIFT;
+ u_int8_t dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> XT_DSCP_SHIFT;
return (dscp == info->dscp) ^ !!info->invert;
}
diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c
index 9f37d593ca38..d3043fa32ebc 100644
--- a/net/netfilter/xt_hashlimit.c
+++ b/net/netfilter/xt_hashlimit.c
@@ -216,10 +216,8 @@ static int htable_create(struct xt_hashlimit_info *minfo, int family)
hinfo->pde->proc_fops = &dl_file_ops;
hinfo->pde->data = hinfo;
- init_timer(&hinfo->timer);
+ setup_timer(&hinfo->timer, htable_gc, (unsigned long )hinfo);
hinfo->timer.expires = jiffies + msecs_to_jiffies(hinfo->cfg.gc_interval);
- hinfo->timer.data = (unsigned long )hinfo;
- hinfo->timer.function = htable_gc;
add_timer(&hinfo->timer);
spin_lock_bh(&hashlimit_lock);
@@ -380,22 +378,22 @@ hashlimit_init_dst(struct xt_hashlimit_htable *hinfo, struct dsthash_dst *dst,
switch (hinfo->family) {
case AF_INET:
if (hinfo->cfg.mode & XT_HASHLIMIT_HASH_DIP)
- dst->addr.ip.dst = skb->nh.iph->daddr;
+ dst->addr.ip.dst = ip_hdr(skb)->daddr;
if (hinfo->cfg.mode & XT_HASHLIMIT_HASH_SIP)
- dst->addr.ip.src = skb->nh.iph->saddr;
+ dst->addr.ip.src = ip_hdr(skb)->saddr;
if (!(hinfo->cfg.mode &
(XT_HASHLIMIT_HASH_DPT | XT_HASHLIMIT_HASH_SPT)))
return 0;
- nexthdr = skb->nh.iph->protocol;
+ nexthdr = ip_hdr(skb)->protocol;
break;
#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
case AF_INET6:
if (hinfo->cfg.mode & XT_HASHLIMIT_HASH_DIP)
- memcpy(&dst->addr.ip6.dst, &skb->nh.ipv6h->daddr,
+ memcpy(&dst->addr.ip6.dst, &ipv6_hdr(skb)->daddr,
sizeof(dst->addr.ip6.dst));
if (hinfo->cfg.mode & XT_HASHLIMIT_HASH_SIP)
- memcpy(&dst->addr.ip6.src, &skb->nh.ipv6h->saddr,
+ memcpy(&dst->addr.ip6.src, &ipv6_hdr(skb)->saddr,
sizeof(dst->addr.ip6.src));
if (!(hinfo->cfg.mode &
diff --git a/net/netfilter/xt_helper.c b/net/netfilter/xt_helper.c
index 407d1d5da8a1..c139b2f43a10 100644
--- a/net/netfilter/xt_helper.c
+++ b/net/netfilter/xt_helper.c
@@ -5,26 +5,16 @@
* 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.
- *
- * 19 Mar 2002 Harald Welte <laforge@gnumonks.org>:
- * - Port to newnat infrastructure
*/
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/netfilter.h>
-#if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE)
-#include <linux/netfilter_ipv4/ip_conntrack.h>
-#include <linux/netfilter_ipv4/ip_conntrack_core.h>
-#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
-#else
#include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nf_conntrack_core.h>
#include <net/netfilter/nf_conntrack_helper.h>
-#endif
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter/xt_helper.h>
-#include <net/netfilter/nf_conntrack_compat.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Martin Josefsson <gandalf@netfilter.org>");
@@ -38,55 +28,6 @@ MODULE_ALIAS("ip6t_helper");
#define DEBUGP(format, args...)
#endif
-#if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE)
-static int
-match(const struct sk_buff *skb,
- const struct net_device *in,
- const struct net_device *out,
- const struct xt_match *match,
- const void *matchinfo,
- int offset,
- unsigned int protoff,
- int *hotdrop)
-{
- const struct xt_helper_info *info = matchinfo;
- struct ip_conntrack *ct;
- enum ip_conntrack_info ctinfo;
- int ret = info->invert;
-
- ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo);
- if (!ct) {
- DEBUGP("xt_helper: Eek! invalid conntrack?\n");
- return ret;
- }
-
- if (!ct->master) {
- DEBUGP("xt_helper: conntrack %p has no master\n", ct);
- return ret;
- }
-
- read_lock_bh(&ip_conntrack_lock);
- if (!ct->master->helper) {
- DEBUGP("xt_helper: master ct %p has no helper\n",
- exp->expectant);
- goto out_unlock;
- }
-
- DEBUGP("master's name = %s , info->name = %s\n",
- ct->master->helper->name, info->name);
-
- if (info->name[0] == '\0')
- ret ^= 1;
- else
- ret ^= !strncmp(ct->master->helper->name, info->name,
- strlen(ct->master->helper->name));
-out_unlock:
- read_unlock_bh(&ip_conntrack_lock);
- return ret;
-}
-
-#else /* CONFIG_IP_NF_CONNTRACK */
-
static int
match(const struct sk_buff *skb,
const struct net_device *in,
@@ -134,7 +75,6 @@ out_unlock:
read_unlock_bh(&nf_conntrack_lock);
return ret;
}
-#endif
static int check(const char *tablename,
const void *inf,
diff --git a/net/netfilter/xt_length.c b/net/netfilter/xt_length.c
index 32fb998d9bac..77288c5ada78 100644
--- a/net/netfilter/xt_length.c
+++ b/net/netfilter/xt_length.c
@@ -31,7 +31,7 @@ match(const struct sk_buff *skb,
int *hotdrop)
{
const struct xt_length_info *info = matchinfo;
- u_int16_t pktlen = ntohs(skb->nh.iph->tot_len);
+ u_int16_t pktlen = ntohs(ip_hdr(skb)->tot_len);
return (pktlen >= info->min && pktlen <= info->max) ^ info->invert;
}
@@ -47,7 +47,8 @@ match6(const struct sk_buff *skb,
int *hotdrop)
{
const struct xt_length_info *info = matchinfo;
- u_int16_t pktlen = ntohs(skb->nh.ipv6h->payload_len) + sizeof(struct ipv6hdr);
+ const u_int16_t pktlen = (ntohs(ipv6_hdr(skb)->payload_len) +
+ sizeof(struct ipv6hdr));
return (pktlen >= info->min && pktlen <= info->max) ^ info->invert;
}
diff --git a/net/netfilter/xt_limit.c b/net/netfilter/xt_limit.c
index 6fd8347c0058..571a72ab89ad 100644
--- a/net/netfilter/xt_limit.c
+++ b/net/netfilter/xt_limit.c
@@ -1,10 +1,3 @@
-/* Kernel module to control the rate
- *
- * 2 September 1999: Changed from the target RATE to the match
- * `limit', removed logging. Did I mention that
- * Alexey is a fucking genius?
- * Rusty Russell (rusty@rustcorp.com.au). */
-
/* (C) 1999 Jérôme de Vivie <devivie@info.enserb.u-bordeaux.fr>
* (C) 1999 Hervé Eychenne <eychenne@info.enserb.u-bordeaux.fr>
*
diff --git a/net/netfilter/xt_mac.c b/net/netfilter/xt_mac.c
index d430d90d7b26..1d3a1d98b885 100644
--- a/net/netfilter/xt_mac.c
+++ b/net/netfilter/xt_mac.c
@@ -37,8 +37,8 @@ match(const struct sk_buff *skb,
const struct xt_mac_info *info = matchinfo;
/* Is mac pointer valid? */
- return (skb->mac.raw >= skb->head
- && (skb->mac.raw + ETH_HLEN) <= skb->data
+ return (skb_mac_header(skb) >= skb->head &&
+ (skb_mac_header(skb) + ETH_HLEN) <= skb->data
/* If so, compare... */
&& ((!compare_ether_addr(eth_hdr(skb)->h_source, info->srcaddr))
^ info->invert));
diff --git a/net/netfilter/xt_pkttype.c b/net/netfilter/xt_pkttype.c
index 16e7b0804287..e1409fc5c288 100644
--- a/net/netfilter/xt_pkttype.c
+++ b/net/netfilter/xt_pkttype.c
@@ -34,7 +34,7 @@ static int match(const struct sk_buff *skb,
const struct xt_pkttype_info *info = matchinfo;
if (skb->pkt_type == PACKET_LOOPBACK)
- type = (MULTICAST(skb->nh.iph->daddr)
+ type = (MULTICAST(ip_hdr(skb)->daddr)
? PACKET_MULTICAST
: PACKET_BROADCAST);
else
diff --git a/net/netfilter/xt_realm.c b/net/netfilter/xt_realm.c
index 97ffc2fbc19d..c2017f8af9c4 100644
--- a/net/netfilter/xt_realm.c
+++ b/net/netfilter/xt_realm.c
@@ -1,7 +1,5 @@
/* IP tables module for matching the routing realm
*
- * $Id: ipt_realm.c,v 1.3 2004/03/05 13:25:40 laforge Exp $
- *
* (C) 2003 by Sampsa Ranta <sampsa@netsonic.fi>
*
* This program is free software; you can redistribute it and/or modify
diff --git a/net/netfilter/xt_state.c b/net/netfilter/xt_state.c
index df37b912163a..149294f7df71 100644
--- a/net/netfilter/xt_state.c
+++ b/net/netfilter/xt_state.c
@@ -10,7 +10,7 @@
#include <linux/module.h>
#include <linux/skbuff.h>
-#include <net/netfilter/nf_conntrack_compat.h>
+#include <net/netfilter/nf_conntrack.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter/xt_state.h>
@@ -36,7 +36,7 @@ match(const struct sk_buff *skb,
if (nf_ct_is_untracked(skb))
statebit = XT_STATE_UNTRACKED;
- else if (!nf_ct_get_ctinfo(skb, &ctinfo))
+ else if (!nf_ct_get(skb, &ctinfo))
statebit = XT_STATE_INVALID;
else
statebit = XT_STATE_BIT(ctinfo);