aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-11-28 05:19:15 -0500
committerDavid S. Miller <davem@davemloft.net>2008-11-28 05:19:15 -0500
commited77a89c30fa03dcb234a84ddea710b3fb7b62da (patch)
tree69f3e2c2bbf2fdd4f742e891441f01307d1d1f49 /net/netfilter
parent475ad8e2172d7f8b73af5532a8dad265b51339c2 (diff)
parentd6e8cc6cc7ac77b0f9118f78c453a2e834e62709 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-next-2.6
Conflicts: net/netfilter/nf_conntrack_netlink.c
Diffstat (limited to 'net/netfilter')
-rw-r--r--net/netfilter/nf_conntrack_amanda.c1
-rw-r--r--net/netfilter/nf_conntrack_core.c61
-rw-r--r--net/netfilter/nf_conntrack_ecache.c14
-rw-r--r--net/netfilter/nf_conntrack_expect.c43
-rw-r--r--net/netfilter/nf_conntrack_ftp.c9
-rw-r--r--net/netfilter/nf_conntrack_h323_main.c1
-rw-r--r--net/netfilter/nf_conntrack_helper.c32
-rw-r--r--net/netfilter/nf_conntrack_irc.c1
-rw-r--r--net/netfilter/nf_conntrack_netbios_ns.c1
-rw-r--r--net/netfilter/nf_conntrack_netlink.c201
-rw-r--r--net/netfilter/nf_conntrack_pptp.c1
-rw-r--r--net/netfilter/nf_conntrack_proto_gre.c2
-rw-r--r--net/netfilter/nf_conntrack_proto_sctp.c2
-rw-r--r--net/netfilter/nf_conntrack_sane.c1
-rw-r--r--net/netfilter/nf_conntrack_sip.c1
-rw-r--r--net/netfilter/nf_conntrack_tftp.c1
-rw-r--r--net/netfilter/nfnetlink_log.c4
-rw-r--r--net/netfilter/xt_NFLOG.c5
-rw-r--r--net/netfilter/xt_recent.c22
19 files changed, 289 insertions, 114 deletions
diff --git a/net/netfilter/nf_conntrack_amanda.c b/net/netfilter/nf_conntrack_amanda.c
index 38aedeeaf4e..4f8fcf49854 100644
--- a/net/netfilter/nf_conntrack_amanda.c
+++ b/net/netfilter/nf_conntrack_amanda.c
@@ -30,6 +30,7 @@ MODULE_AUTHOR("Brian J. Murrell <netfilter@interlinx.bc.ca>");
30MODULE_DESCRIPTION("Amanda connection tracking module"); 30MODULE_DESCRIPTION("Amanda connection tracking module");
31MODULE_LICENSE("GPL"); 31MODULE_LICENSE("GPL");
32MODULE_ALIAS("ip_conntrack_amanda"); 32MODULE_ALIAS("ip_conntrack_amanda");
33MODULE_ALIAS_NFCT_HELPER("amanda");
33 34
34module_param(master_timeout, uint, 0600); 35module_param(master_timeout, uint, 0600);
35MODULE_PARM_DESC(master_timeout, "timeout for the master connection"); 36MODULE_PARM_DESC(master_timeout, "timeout for the master connection");
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 233fdd2d7d2..7e83f74cd5d 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -39,13 +39,13 @@
39#include <net/netfilter/nf_conntrack_extend.h> 39#include <net/netfilter/nf_conntrack_extend.h>
40#include <net/netfilter/nf_conntrack_acct.h> 40#include <net/netfilter/nf_conntrack_acct.h>
41#include <net/netfilter/nf_nat.h> 41#include <net/netfilter/nf_nat.h>
42#include <net/netfilter/nf_nat_core.h>
42 43
43#define NF_CONNTRACK_VERSION "0.5.0" 44#define NF_CONNTRACK_VERSION "0.5.0"
44 45
45unsigned int 46int (*nfnetlink_parse_nat_setup_hook)(struct nf_conn *ct,
46(*nfnetlink_parse_nat_setup_hook)(struct nf_conn *ct, 47 enum nf_nat_manip_type manip,
47 enum nf_nat_manip_type manip, 48 struct nlattr *attr) __read_mostly;
48 struct nlattr *attr) __read_mostly;
49EXPORT_SYMBOL_GPL(nfnetlink_parse_nat_setup_hook); 49EXPORT_SYMBOL_GPL(nfnetlink_parse_nat_setup_hook);
50 50
51DEFINE_SPINLOCK(nf_conntrack_lock); 51DEFINE_SPINLOCK(nf_conntrack_lock);
@@ -181,7 +181,8 @@ destroy_conntrack(struct nf_conntrack *nfct)
181 NF_CT_ASSERT(atomic_read(&nfct->use) == 0); 181 NF_CT_ASSERT(atomic_read(&nfct->use) == 0);
182 NF_CT_ASSERT(!timer_pending(&ct->timeout)); 182 NF_CT_ASSERT(!timer_pending(&ct->timeout));
183 183
184 nf_conntrack_event(IPCT_DESTROY, ct); 184 if (!test_bit(IPS_DYING_BIT, &ct->status))
185 nf_conntrack_event(IPCT_DESTROY, ct);
185 set_bit(IPS_DYING_BIT, &ct->status); 186 set_bit(IPS_DYING_BIT, &ct->status);
186 187
187 /* To make sure we don't get any weird locking issues here: 188 /* To make sure we don't get any weird locking issues here:
@@ -586,14 +587,7 @@ init_conntrack(struct net *net,
586 nf_conntrack_get(&ct->master->ct_general); 587 nf_conntrack_get(&ct->master->ct_general);
587 NF_CT_STAT_INC(net, expect_new); 588 NF_CT_STAT_INC(net, expect_new);
588 } else { 589 } else {
589 struct nf_conntrack_helper *helper; 590 __nf_ct_try_assign_helper(ct, GFP_ATOMIC);
590
591 helper = __nf_ct_helper_find(&repl_tuple);
592 if (helper) {
593 help = nf_ct_helper_ext_add(ct, GFP_ATOMIC);
594 if (help)
595 rcu_assign_pointer(help->helper, helper);
596 }
597 NF_CT_STAT_INC(net, new); 591 NF_CT_STAT_INC(net, new);
598 } 592 }
599 593
@@ -770,7 +764,6 @@ void nf_conntrack_alter_reply(struct nf_conn *ct,
770 const struct nf_conntrack_tuple *newreply) 764 const struct nf_conntrack_tuple *newreply)
771{ 765{
772 struct nf_conn_help *help = nfct_help(ct); 766 struct nf_conn_help *help = nfct_help(ct);
773 struct nf_conntrack_helper *helper;
774 767
775 /* Should be unconfirmed, so not in hash table yet */ 768 /* Should be unconfirmed, so not in hash table yet */
776 NF_CT_ASSERT(!nf_ct_is_confirmed(ct)); 769 NF_CT_ASSERT(!nf_ct_is_confirmed(ct));
@@ -783,23 +776,7 @@ void nf_conntrack_alter_reply(struct nf_conn *ct,
783 return; 776 return;
784 777
785 rcu_read_lock(); 778 rcu_read_lock();
786 helper = __nf_ct_helper_find(newreply); 779 __nf_ct_try_assign_helper(ct, GFP_ATOMIC);
787 if (helper == NULL) {
788 if (help)
789 rcu_assign_pointer(help->helper, NULL);
790 goto out;
791 }
792
793 if (help == NULL) {
794 help = nf_ct_helper_ext_add(ct, GFP_ATOMIC);
795 if (help == NULL)
796 goto out;
797 } else {
798 memset(&help->help, 0, sizeof(help->help));
799 }
800
801 rcu_assign_pointer(help->helper, helper);
802out:
803 rcu_read_unlock(); 780 rcu_read_unlock();
804} 781}
805EXPORT_SYMBOL_GPL(nf_conntrack_alter_reply); 782EXPORT_SYMBOL_GPL(nf_conntrack_alter_reply);
@@ -994,8 +971,20 @@ void nf_ct_iterate_cleanup(struct net *net,
994} 971}
995EXPORT_SYMBOL_GPL(nf_ct_iterate_cleanup); 972EXPORT_SYMBOL_GPL(nf_ct_iterate_cleanup);
996 973
974struct __nf_ct_flush_report {
975 u32 pid;
976 int report;
977};
978
997static int kill_all(struct nf_conn *i, void *data) 979static int kill_all(struct nf_conn *i, void *data)
998{ 980{
981 struct __nf_ct_flush_report *fr = (struct __nf_ct_flush_report *)data;
982
983 /* get_next_corpse sets the dying bit for us */
984 nf_conntrack_event_report(IPCT_DESTROY,
985 i,
986 fr->pid,
987 fr->report);
999 return 1; 988 return 1;
1000} 989}
1001 990
@@ -1009,9 +998,13 @@ void nf_ct_free_hashtable(struct hlist_head *hash, int vmalloced, unsigned int s
1009} 998}
1010EXPORT_SYMBOL_GPL(nf_ct_free_hashtable); 999EXPORT_SYMBOL_GPL(nf_ct_free_hashtable);
1011 1000
1012void nf_conntrack_flush(struct net *net) 1001void nf_conntrack_flush(struct net *net, u32 pid, int report)
1013{ 1002{
1014 nf_ct_iterate_cleanup(net, kill_all, NULL); 1003 struct __nf_ct_flush_report fr = {
1004 .pid = pid,
1005 .report = report,
1006 };
1007 nf_ct_iterate_cleanup(net, kill_all, &fr);
1015} 1008}
1016EXPORT_SYMBOL_GPL(nf_conntrack_flush); 1009EXPORT_SYMBOL_GPL(nf_conntrack_flush);
1017 1010
@@ -1027,7 +1020,7 @@ static void nf_conntrack_cleanup_net(struct net *net)
1027 nf_ct_event_cache_flush(net); 1020 nf_ct_event_cache_flush(net);
1028 nf_conntrack_ecache_fini(net); 1021 nf_conntrack_ecache_fini(net);
1029 i_see_dead_people: 1022 i_see_dead_people:
1030 nf_conntrack_flush(net); 1023 nf_conntrack_flush(net, 0, 0);
1031 if (atomic_read(&net->ct.count) != 0) { 1024 if (atomic_read(&net->ct.count) != 0) {
1032 schedule(); 1025 schedule();
1033 goto i_see_dead_people; 1026 goto i_see_dead_people;
diff --git a/net/netfilter/nf_conntrack_ecache.c b/net/netfilter/nf_conntrack_ecache.c
index a5f5e2e65d1..dee4190209c 100644
--- a/net/netfilter/nf_conntrack_ecache.c
+++ b/net/netfilter/nf_conntrack_ecache.c
@@ -35,9 +35,17 @@ static inline void
35__nf_ct_deliver_cached_events(struct nf_conntrack_ecache *ecache) 35__nf_ct_deliver_cached_events(struct nf_conntrack_ecache *ecache)
36{ 36{
37 if (nf_ct_is_confirmed(ecache->ct) && !nf_ct_is_dying(ecache->ct) 37 if (nf_ct_is_confirmed(ecache->ct) && !nf_ct_is_dying(ecache->ct)
38 && ecache->events) 38 && ecache->events) {
39 atomic_notifier_call_chain(&nf_conntrack_chain, ecache->events, 39 struct nf_ct_event item = {
40 ecache->ct); 40 .ct = ecache->ct,
41 .pid = 0,
42 .report = 0
43 };
44
45 atomic_notifier_call_chain(&nf_conntrack_chain,
46 ecache->events,
47 &item);
48 }
41 49
42 ecache->events = 0; 50 ecache->events = 0;
43 nf_ct_put(ecache->ct); 51 nf_ct_put(ecache->ct);
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c
index 37a703bc3b8..3a8a34a6d37 100644
--- a/net/netfilter/nf_conntrack_expect.c
+++ b/net/netfilter/nf_conntrack_expect.c
@@ -362,7 +362,7 @@ static inline int refresh_timer(struct nf_conntrack_expect *i)
362 return 1; 362 return 1;
363} 363}
364 364
365int nf_ct_expect_related(struct nf_conntrack_expect *expect) 365static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect)
366{ 366{
367 const struct nf_conntrack_expect_policy *p; 367 const struct nf_conntrack_expect_policy *p;
368 struct nf_conntrack_expect *i; 368 struct nf_conntrack_expect *i;
@@ -371,11 +371,8 @@ int nf_ct_expect_related(struct nf_conntrack_expect *expect)
371 struct net *net = nf_ct_exp_net(expect); 371 struct net *net = nf_ct_exp_net(expect);
372 struct hlist_node *n; 372 struct hlist_node *n;
373 unsigned int h; 373 unsigned int h;
374 int ret; 374 int ret = 0;
375
376 NF_CT_ASSERT(master_help);
377 375
378 spin_lock_bh(&nf_conntrack_lock);
379 if (!master_help->helper) { 376 if (!master_help->helper) {
380 ret = -ESHUTDOWN; 377 ret = -ESHUTDOWN;
381 goto out; 378 goto out;
@@ -409,18 +406,50 @@ int nf_ct_expect_related(struct nf_conntrack_expect *expect)
409 printk(KERN_WARNING 406 printk(KERN_WARNING
410 "nf_conntrack: expectation table full\n"); 407 "nf_conntrack: expectation table full\n");
411 ret = -EMFILE; 408 ret = -EMFILE;
412 goto out;
413 } 409 }
410out:
411 return ret;
412}
413
414int nf_ct_expect_related(struct nf_conntrack_expect *expect)
415{
416 int ret;
417
418 spin_lock_bh(&nf_conntrack_lock);
419 ret = __nf_ct_expect_check(expect);
420 if (ret < 0)
421 goto out;
414 422
415 nf_ct_expect_insert(expect); 423 nf_ct_expect_insert(expect);
424 atomic_inc(&expect->use);
425 spin_unlock_bh(&nf_conntrack_lock);
416 nf_ct_expect_event(IPEXP_NEW, expect); 426 nf_ct_expect_event(IPEXP_NEW, expect);
417 ret = 0; 427 nf_ct_expect_put(expect);
428 return ret;
418out: 429out:
419 spin_unlock_bh(&nf_conntrack_lock); 430 spin_unlock_bh(&nf_conntrack_lock);
420 return ret; 431 return ret;
421} 432}
422EXPORT_SYMBOL_GPL(nf_ct_expect_related); 433EXPORT_SYMBOL_GPL(nf_ct_expect_related);
423 434
435int nf_ct_expect_related_report(struct nf_conntrack_expect *expect,
436 u32 pid, int report)
437{
438 int ret;
439
440 spin_lock_bh(&nf_conntrack_lock);
441 ret = __nf_ct_expect_check(expect);
442 if (ret < 0)
443 goto out;
444 nf_ct_expect_insert(expect);
445out:
446 spin_unlock_bh(&nf_conntrack_lock);
447 if (ret == 0)
448 nf_ct_expect_event_report(IPEXP_NEW, expect, pid, report);
449 return ret;
450}
451EXPORT_SYMBOL_GPL(nf_ct_expect_related_report);
452
424#ifdef CONFIG_PROC_FS 453#ifdef CONFIG_PROC_FS
425struct ct_expect_iter_state { 454struct ct_expect_iter_state {
426 struct seq_net_private p; 455 struct seq_net_private p;
diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c
index 629500901bd..00fecc385f9 100644
--- a/net/netfilter/nf_conntrack_ftp.c
+++ b/net/netfilter/nf_conntrack_ftp.c
@@ -29,6 +29,7 @@ MODULE_LICENSE("GPL");
29MODULE_AUTHOR("Rusty Russell <rusty@rustcorp.com.au>"); 29MODULE_AUTHOR("Rusty Russell <rusty@rustcorp.com.au>");
30MODULE_DESCRIPTION("ftp connection tracking helper"); 30MODULE_DESCRIPTION("ftp connection tracking helper");
31MODULE_ALIAS("ip_conntrack_ftp"); 31MODULE_ALIAS("ip_conntrack_ftp");
32MODULE_ALIAS_NFCT_HELPER("ftp");
32 33
33/* This is slow, but it's simple. --RR */ 34/* This is slow, but it's simple. --RR */
34static char *ftp_buffer; 35static char *ftp_buffer;
@@ -357,7 +358,7 @@ static int help(struct sk_buff *skb,
357 int ret; 358 int ret;
358 u32 seq; 359 u32 seq;
359 int dir = CTINFO2DIR(ctinfo); 360 int dir = CTINFO2DIR(ctinfo);
360 unsigned int matchlen, matchoff; 361 unsigned int uninitialized_var(matchlen), uninitialized_var(matchoff);
361 struct nf_ct_ftp_master *ct_ftp_info = &nfct_help(ct)->help.ct_ftp_info; 362 struct nf_ct_ftp_master *ct_ftp_info = &nfct_help(ct)->help.ct_ftp_info;
362 struct nf_conntrack_expect *exp; 363 struct nf_conntrack_expect *exp;
363 union nf_inet_addr *daddr; 364 union nf_inet_addr *daddr;
@@ -427,10 +428,8 @@ static int help(struct sk_buff *skb,
427 connection tracking, not packet filtering. 428 connection tracking, not packet filtering.
428 However, it is necessary for accurate tracking in 429 However, it is necessary for accurate tracking in
429 this case. */ 430 this case. */
430 if (net_ratelimit()) 431 pr_debug("conntrack_ftp: partial %s %u+%u\n",
431 printk("conntrack_ftp: partial %s %u+%u\n", 432 search[dir][i].pattern, ntohl(th->seq), datalen);
432 search[dir][i].pattern,
433 ntohl(th->seq), datalen);
434 ret = NF_DROP; 433 ret = NF_DROP;
435 goto out; 434 goto out;
436 } else if (found == 0) { /* No match */ 435 } else if (found == 0) { /* No match */
diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c
index 99bc803d1dd..687bd633c3d 100644
--- a/net/netfilter/nf_conntrack_h323_main.c
+++ b/net/netfilter/nf_conntrack_h323_main.c
@@ -1827,3 +1827,4 @@ MODULE_AUTHOR("Jing Min Zhao <zhaojingmin@users.sourceforge.net>");
1827MODULE_DESCRIPTION("H.323 connection tracking helper"); 1827MODULE_DESCRIPTION("H.323 connection tracking helper");
1828MODULE_LICENSE("GPL"); 1828MODULE_LICENSE("GPL");
1829MODULE_ALIAS("ip_conntrack_h323"); 1829MODULE_ALIAS("ip_conntrack_h323");
1830MODULE_ALIAS_NFCT_HELPER("h323");
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c
index c39b6a99413..a51bdac9f3a 100644
--- a/net/netfilter/nf_conntrack_helper.c
+++ b/net/netfilter/nf_conntrack_helper.c
@@ -45,7 +45,7 @@ static unsigned int helper_hash(const struct nf_conntrack_tuple *tuple)
45 (__force __u16)tuple->src.u.all) % nf_ct_helper_hsize; 45 (__force __u16)tuple->src.u.all) % nf_ct_helper_hsize;
46} 46}
47 47
48struct nf_conntrack_helper * 48static struct nf_conntrack_helper *
49__nf_ct_helper_find(const struct nf_conntrack_tuple *tuple) 49__nf_ct_helper_find(const struct nf_conntrack_tuple *tuple)
50{ 50{
51 struct nf_conntrack_helper *helper; 51 struct nf_conntrack_helper *helper;
@@ -63,7 +63,6 @@ __nf_ct_helper_find(const struct nf_conntrack_tuple *tuple)
63 } 63 }
64 return NULL; 64 return NULL;
65} 65}
66EXPORT_SYMBOL_GPL(__nf_ct_helper_find);
67 66
68struct nf_conntrack_helper * 67struct nf_conntrack_helper *
69__nf_conntrack_helper_find_byname(const char *name) 68__nf_conntrack_helper_find_byname(const char *name)
@@ -95,6 +94,35 @@ struct nf_conn_help *nf_ct_helper_ext_add(struct nf_conn *ct, gfp_t gfp)
95} 94}
96EXPORT_SYMBOL_GPL(nf_ct_helper_ext_add); 95EXPORT_SYMBOL_GPL(nf_ct_helper_ext_add);
97 96
97int __nf_ct_try_assign_helper(struct nf_conn *ct, gfp_t flags)
98{
99 int ret = 0;
100 struct nf_conntrack_helper *helper;
101 struct nf_conn_help *help = nfct_help(ct);
102
103 helper = __nf_ct_helper_find(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
104 if (helper == NULL) {
105 if (help)
106 rcu_assign_pointer(help->helper, NULL);
107 goto out;
108 }
109
110 if (help == NULL) {
111 help = nf_ct_helper_ext_add(ct, flags);
112 if (help == NULL) {
113 ret = -ENOMEM;
114 goto out;
115 }
116 } else {
117 memset(&help->help, 0, sizeof(help->help));
118 }
119
120 rcu_assign_pointer(help->helper, helper);
121out:
122 return ret;
123}
124EXPORT_SYMBOL_GPL(__nf_ct_try_assign_helper);
125
98static inline int unhelp(struct nf_conntrack_tuple_hash *i, 126static inline int unhelp(struct nf_conntrack_tuple_hash *i,
99 const struct nf_conntrack_helper *me) 127 const struct nf_conntrack_helper *me)
100{ 128{
diff --git a/net/netfilter/nf_conntrack_irc.c b/net/netfilter/nf_conntrack_irc.c
index 4d681a04447..409c8be58e7 100644
--- a/net/netfilter/nf_conntrack_irc.c
+++ b/net/netfilter/nf_conntrack_irc.c
@@ -41,6 +41,7 @@ MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
41MODULE_DESCRIPTION("IRC (DCC) connection tracking helper"); 41MODULE_DESCRIPTION("IRC (DCC) connection tracking helper");
42MODULE_LICENSE("GPL"); 42MODULE_LICENSE("GPL");
43MODULE_ALIAS("ip_conntrack_irc"); 43MODULE_ALIAS("ip_conntrack_irc");
44MODULE_ALIAS_NFCT_HELPER("irc");
44 45
45module_param_array(ports, ushort, &ports_c, 0400); 46module_param_array(ports, ushort, &ports_c, 0400);
46MODULE_PARM_DESC(ports, "port numbers of IRC servers"); 47MODULE_PARM_DESC(ports, "port numbers of IRC servers");
diff --git a/net/netfilter/nf_conntrack_netbios_ns.c b/net/netfilter/nf_conntrack_netbios_ns.c
index 08404e6755f..5af4273b466 100644
--- a/net/netfilter/nf_conntrack_netbios_ns.c
+++ b/net/netfilter/nf_conntrack_netbios_ns.c
@@ -37,6 +37,7 @@ MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
37MODULE_DESCRIPTION("NetBIOS name service broadcast connection tracking helper"); 37MODULE_DESCRIPTION("NetBIOS name service broadcast connection tracking helper");
38MODULE_LICENSE("GPL"); 38MODULE_LICENSE("GPL");
39MODULE_ALIAS("ip_conntrack_netbios_ns"); 39MODULE_ALIAS("ip_conntrack_netbios_ns");
40MODULE_ALIAS_NFCT_HELPER("netbios_ns");
40 41
41static unsigned int timeout __read_mostly = 3; 42static unsigned int timeout __read_mostly = 3;
42module_param(timeout, uint, 0400); 43module_param(timeout, uint, 0400);
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 5f4a6516b3b..00e8c27130f 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -105,16 +105,14 @@ ctnetlink_dump_tuples(struct sk_buff *skb,
105 struct nf_conntrack_l3proto *l3proto; 105 struct nf_conntrack_l3proto *l3proto;
106 struct nf_conntrack_l4proto *l4proto; 106 struct nf_conntrack_l4proto *l4proto;
107 107
108 l3proto = nf_ct_l3proto_find_get(tuple->src.l3num); 108 l3proto = __nf_ct_l3proto_find(tuple->src.l3num);
109 ret = ctnetlink_dump_tuples_ip(skb, tuple, l3proto); 109 ret = ctnetlink_dump_tuples_ip(skb, tuple, l3proto);
110 nf_ct_l3proto_put(l3proto);
111 110
112 if (unlikely(ret < 0)) 111 if (unlikely(ret < 0))
113 return ret; 112 return ret;
114 113
115 l4proto = nf_ct_l4proto_find_get(tuple->src.l3num, tuple->dst.protonum); 114 l4proto = __nf_ct_l4proto_find(tuple->src.l3num, tuple->dst.protonum);
116 ret = ctnetlink_dump_tuples_proto(skb, tuple, l4proto); 115 ret = ctnetlink_dump_tuples_proto(skb, tuple, l4proto);
117 nf_ct_l4proto_put(l4proto);
118 116
119 return ret; 117 return ret;
120} 118}
@@ -151,11 +149,9 @@ ctnetlink_dump_protoinfo(struct sk_buff *skb, const struct nf_conn *ct)
151 struct nlattr *nest_proto; 149 struct nlattr *nest_proto;
152 int ret; 150 int ret;
153 151
154 l4proto = nf_ct_l4proto_find_get(nf_ct_l3num(ct), nf_ct_protonum(ct)); 152 l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct));
155 if (!l4proto->to_nlattr) { 153 if (!l4proto->to_nlattr)
156 nf_ct_l4proto_put(l4proto);
157 return 0; 154 return 0;
158 }
159 155
160 nest_proto = nla_nest_start(skb, CTA_PROTOINFO | NLA_F_NESTED); 156 nest_proto = nla_nest_start(skb, CTA_PROTOINFO | NLA_F_NESTED);
161 if (!nest_proto) 157 if (!nest_proto)
@@ -163,14 +159,11 @@ ctnetlink_dump_protoinfo(struct sk_buff *skb, const struct nf_conn *ct)
163 159
164 ret = l4proto->to_nlattr(skb, nest_proto, ct); 160 ret = l4proto->to_nlattr(skb, nest_proto, ct);
165 161
166 nf_ct_l4proto_put(l4proto);
167
168 nla_nest_end(skb, nest_proto); 162 nla_nest_end(skb, nest_proto);
169 163
170 return ret; 164 return ret;
171 165
172nla_put_failure: 166nla_put_failure:
173 nf_ct_l4proto_put(l4proto);
174 return -1; 167 return -1;
175} 168}
176 169
@@ -184,7 +177,6 @@ ctnetlink_dump_helpinfo(struct sk_buff *skb, const struct nf_conn *ct)
184 if (!help) 177 if (!help)
185 return 0; 178 return 0;
186 179
187 rcu_read_lock();
188 helper = rcu_dereference(help->helper); 180 helper = rcu_dereference(help->helper);
189 if (!helper) 181 if (!helper)
190 goto out; 182 goto out;
@@ -199,11 +191,9 @@ ctnetlink_dump_helpinfo(struct sk_buff *skb, const struct nf_conn *ct)
199 191
200 nla_nest_end(skb, nest_helper); 192 nla_nest_end(skb, nest_helper);
201out: 193out:
202 rcu_read_unlock();
203 return 0; 194 return 0;
204 195
205nla_put_failure: 196nla_put_failure:
206 rcu_read_unlock();
207 return -1; 197 return -1;
208} 198}
209 199
@@ -420,7 +410,8 @@ static int ctnetlink_conntrack_event(struct notifier_block *this,
420 struct nlmsghdr *nlh; 410 struct nlmsghdr *nlh;
421 struct nfgenmsg *nfmsg; 411 struct nfgenmsg *nfmsg;
422 struct nlattr *nest_parms; 412 struct nlattr *nest_parms;
423 struct nf_conn *ct = (struct nf_conn *)ptr; 413 struct nf_ct_event *item = (struct nf_ct_event *)ptr;
414 struct nf_conn *ct = item->ct;
424 struct sk_buff *skb; 415 struct sk_buff *skb;
425 unsigned int type; 416 unsigned int type;
426 sk_buff_data_t b; 417 sk_buff_data_t b;
@@ -453,7 +444,7 @@ static int ctnetlink_conntrack_event(struct notifier_block *this,
453 b = skb->tail; 444 b = skb->tail;
454 445
455 type |= NFNL_SUBSYS_CTNETLINK << 8; 446 type |= NFNL_SUBSYS_CTNETLINK << 8;
456 nlh = NLMSG_PUT(skb, 0, 0, type, sizeof(struct nfgenmsg)); 447 nlh = NLMSG_PUT(skb, item->pid, 0, type, sizeof(struct nfgenmsg));
457 nfmsg = NLMSG_DATA(nlh); 448 nfmsg = NLMSG_DATA(nlh);
458 449
459 nlh->nlmsg_flags = flags; 450 nlh->nlmsg_flags = flags;
@@ -461,6 +452,7 @@ static int ctnetlink_conntrack_event(struct notifier_block *this,
461 nfmsg->version = NFNETLINK_V0; 452 nfmsg->version = NFNETLINK_V0;
462 nfmsg->res_id = 0; 453 nfmsg->res_id = 0;
463 454
455 rcu_read_lock();
464 nest_parms = nla_nest_start(skb, CTA_TUPLE_ORIG | NLA_F_NESTED); 456 nest_parms = nla_nest_start(skb, CTA_TUPLE_ORIG | NLA_F_NESTED);
465 if (!nest_parms) 457 if (!nest_parms)
466 goto nla_put_failure; 458 goto nla_put_failure;
@@ -517,13 +509,15 @@ static int ctnetlink_conntrack_event(struct notifier_block *this,
517 && ctnetlink_dump_mark(skb, ct) < 0) 509 && ctnetlink_dump_mark(skb, ct) < 0)
518 goto nla_put_failure; 510 goto nla_put_failure;
519#endif 511#endif
512 rcu_read_unlock();
520 513
521 nlh->nlmsg_len = skb->tail - b; 514 nlh->nlmsg_len = skb->tail - b;
522 nfnetlink_send(skb, 0, group, 0); 515 nfnetlink_send(skb, item->pid, group, item->report);
523 return NOTIFY_DONE; 516 return NOTIFY_DONE;
524 517
525nlmsg_failure:
526nla_put_failure: 518nla_put_failure:
519 rcu_read_unlock();
520nlmsg_failure:
527 kfree_skb(skb); 521 kfree_skb(skb);
528 return NOTIFY_DONE; 522 return NOTIFY_DONE;
529} 523}
@@ -729,7 +723,9 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
729 err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_REPLY, u3); 723 err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_REPLY, u3);
730 else { 724 else {
731 /* Flush the whole table */ 725 /* Flush the whole table */
732 nf_conntrack_flush(&init_net); 726 nf_conntrack_flush(&init_net,
727 NETLINK_CB(skb).pid,
728 nlmsg_report(nlh));
733 return 0; 729 return 0;
734 } 730 }
735 731
@@ -750,6 +746,14 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
750 } 746 }
751 } 747 }
752 748
749 nf_conntrack_event_report(IPCT_DESTROY,
750 ct,
751 NETLINK_CB(skb).pid,
752 nlmsg_report(nlh));
753
754 /* death_by_timeout would report the event again */
755 set_bit(IPS_DYING_BIT, &ct->status);
756
753 nf_ct_kill(ct); 757 nf_ct_kill(ct);
754 nf_ct_put(ct); 758 nf_ct_put(ct);
755 759
@@ -795,8 +799,10 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
795 return -ENOMEM; 799 return -ENOMEM;
796 } 800 }
797 801
802 rcu_read_lock();
798 err = ctnetlink_fill_info(skb2, NETLINK_CB(skb).pid, nlh->nlmsg_seq, 803 err = ctnetlink_fill_info(skb2, NETLINK_CB(skb).pid, nlh->nlmsg_seq,
799 IPCTNL_MSG_CT_NEW, 1, ct); 804 IPCTNL_MSG_CT_NEW, 1, ct);
805 rcu_read_unlock();
800 nf_ct_put(ct); 806 nf_ct_put(ct);
801 if (err <= 0) 807 if (err <= 0)
802 goto free; 808 goto free;
@@ -922,8 +928,22 @@ ctnetlink_change_helper(struct nf_conn *ct, struct nlattr *cda[])
922 } 928 }
923 929
924 helper = __nf_conntrack_helper_find_byname(helpname); 930 helper = __nf_conntrack_helper_find_byname(helpname);
925 if (helper == NULL) 931 if (helper == NULL) {
932#ifdef CONFIG_MODULES
933 spin_unlock_bh(&nf_conntrack_lock);
934
935 if (request_module("nfct-helper-%s", helpname) < 0) {
936 spin_lock_bh(&nf_conntrack_lock);
937 return -EOPNOTSUPP;
938 }
939
940 spin_lock_bh(&nf_conntrack_lock);
941 helper = __nf_conntrack_helper_find_byname(helpname);
942 if (helper)
943 return -EAGAIN;
944#endif
926 return -EOPNOTSUPP; 945 return -EOPNOTSUPP;
946 }
927 947
928 if (help) { 948 if (help) {
929 if (help->helper == helper) 949 if (help->helper == helper)
@@ -1079,15 +1099,38 @@ ctnetlink_change_conntrack(struct nf_conn *ct, struct nlattr *cda[])
1079 return 0; 1099 return 0;
1080} 1100}
1081 1101
1102static inline void
1103ctnetlink_event_report(struct nf_conn *ct, u32 pid, int report)
1104{
1105 unsigned int events = 0;
1106
1107 if (test_bit(IPS_EXPECTED_BIT, &ct->status))
1108 events |= IPCT_RELATED;
1109 else
1110 events |= IPCT_NEW;
1111
1112 nf_conntrack_event_report(IPCT_STATUS |
1113 IPCT_HELPER |
1114 IPCT_REFRESH |
1115 IPCT_PROTOINFO |
1116 IPCT_NATSEQADJ |
1117 IPCT_MARK |
1118 events,
1119 ct,
1120 pid,
1121 report);
1122}
1123
1082static int 1124static int
1083ctnetlink_create_conntrack(struct nlattr *cda[], 1125ctnetlink_create_conntrack(struct nlattr *cda[],
1084 struct nf_conntrack_tuple *otuple, 1126 struct nf_conntrack_tuple *otuple,
1085 struct nf_conntrack_tuple *rtuple, 1127 struct nf_conntrack_tuple *rtuple,
1086 struct nf_conn *master_ct) 1128 struct nf_conn *master_ct,
1129 u32 pid,
1130 int report)
1087{ 1131{
1088 struct nf_conn *ct; 1132 struct nf_conn *ct;
1089 int err = -EINVAL; 1133 int err = -EINVAL;
1090 struct nf_conn_help *help;
1091 struct nf_conntrack_helper *helper; 1134 struct nf_conntrack_helper *helper;
1092 1135
1093 ct = nf_conntrack_alloc(&init_net, otuple, rtuple, GFP_ATOMIC); 1136 ct = nf_conntrack_alloc(&init_net, otuple, rtuple, GFP_ATOMIC);
@@ -1102,16 +1145,55 @@ ctnetlink_create_conntrack(struct nlattr *cda[],
1102 ct->status |= IPS_CONFIRMED; 1145 ct->status |= IPS_CONFIRMED;
1103 1146
1104 rcu_read_lock(); 1147 rcu_read_lock();
1105 helper = __nf_ct_helper_find(rtuple); 1148 if (cda[CTA_HELP]) {
1106 if (helper) { 1149 char *helpname;
1107 help = nf_ct_helper_ext_add(ct, GFP_ATOMIC); 1150
1108 if (help == NULL) { 1151 err = ctnetlink_parse_help(cda[CTA_HELP], &helpname);
1152 if (err < 0) {
1153 rcu_read_unlock();
1154 goto err;
1155 }
1156
1157 helper = __nf_conntrack_helper_find_byname(helpname);
1158 if (helper == NULL) {
1159 rcu_read_unlock();
1160#ifdef CONFIG_MODULES
1161 if (request_module("nfct-helper-%s", helpname) < 0) {
1162 err = -EOPNOTSUPP;
1163 goto err;
1164 }
1165
1166 rcu_read_lock();
1167 helper = __nf_conntrack_helper_find_byname(helpname);
1168 if (helper) {
1169 rcu_read_unlock();
1170 err = -EAGAIN;
1171 goto err;
1172 }
1173 rcu_read_unlock();
1174#endif
1175 err = -EOPNOTSUPP;
1176 goto err;
1177 } else {
1178 struct nf_conn_help *help;
1179
1180 help = nf_ct_helper_ext_add(ct, GFP_ATOMIC);
1181 if (help == NULL) {
1182 rcu_read_unlock();
1183 err = -ENOMEM;
1184 goto err;
1185 }
1186
1187 /* not in hash table yet so not strictly necessary */
1188 rcu_assign_pointer(help->helper, helper);
1189 }
1190 } else {
1191 /* try an implicit helper assignation */
1192 err = __nf_ct_try_assign_helper(ct, GFP_ATOMIC);
1193 if (err < 0) {
1109 rcu_read_unlock(); 1194 rcu_read_unlock();
1110 err = -ENOMEM;
1111 goto err; 1195 goto err;
1112 } 1196 }
1113 /* not in hash table yet so not strictly necessary */
1114 rcu_assign_pointer(help->helper, helper);
1115 } 1197 }
1116 1198
1117 if (cda[CTA_STATUS]) { 1199 if (cda[CTA_STATUS]) {
@@ -1151,9 +1233,12 @@ ctnetlink_create_conntrack(struct nlattr *cda[],
1151 ct->master = master_ct; 1233 ct->master = master_ct;
1152 } 1234 }
1153 1235
1236 nf_conntrack_get(&ct->ct_general);
1154 add_timer(&ct->timeout); 1237 add_timer(&ct->timeout);
1155 nf_conntrack_hash_insert(ct); 1238 nf_conntrack_hash_insert(ct);
1156 rcu_read_unlock(); 1239 rcu_read_unlock();
1240 ctnetlink_event_report(ct, pid, report);
1241 nf_ct_put(ct);
1157 1242
1158 return 0; 1243 return 0;
1159 1244
@@ -1209,7 +1294,7 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
1209 goto out_unlock; 1294 goto out_unlock;
1210 } 1295 }
1211 master_ct = nf_ct_tuplehash_to_ctrack(master_h); 1296 master_ct = nf_ct_tuplehash_to_ctrack(master_h);
1212 atomic_inc(&master_ct->ct_general.use); 1297 nf_conntrack_get(&master_ct->ct_general);
1213 } 1298 }
1214 1299
1215 err = -ENOENT; 1300 err = -ENOENT;
@@ -1217,9 +1302,10 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
1217 err = ctnetlink_create_conntrack(cda, 1302 err = ctnetlink_create_conntrack(cda,
1218 &otuple, 1303 &otuple,
1219 &rtuple, 1304 &rtuple,
1220 master_ct); 1305 master_ct,
1306 NETLINK_CB(skb).pid,
1307 nlmsg_report(nlh));
1221 spin_unlock_bh(&nf_conntrack_lock); 1308 spin_unlock_bh(&nf_conntrack_lock);
1222
1223 if (err < 0 && master_ct) 1309 if (err < 0 && master_ct)
1224 nf_ct_put(master_ct); 1310 nf_ct_put(master_ct);
1225 1311
@@ -1231,6 +1317,8 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
1231 * so there's no need to increase the refcount */ 1317 * so there's no need to increase the refcount */
1232 err = -EEXIST; 1318 err = -EEXIST;
1233 if (!(nlh->nlmsg_flags & NLM_F_EXCL)) { 1319 if (!(nlh->nlmsg_flags & NLM_F_EXCL)) {
1320 struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h);
1321
1234 /* we only allow nat config for new conntracks */ 1322 /* we only allow nat config for new conntracks */
1235 if (cda[CTA_NAT_SRC] || cda[CTA_NAT_DST]) { 1323 if (cda[CTA_NAT_SRC] || cda[CTA_NAT_DST]) {
1236 err = -EOPNOTSUPP; 1324 err = -EOPNOTSUPP;
@@ -1241,8 +1329,19 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
1241 err = -EOPNOTSUPP; 1329 err = -EOPNOTSUPP;
1242 goto out_unlock; 1330 goto out_unlock;
1243 } 1331 }
1244 err = ctnetlink_change_conntrack(nf_ct_tuplehash_to_ctrack(h), 1332
1245 cda); 1333 err = ctnetlink_change_conntrack(ct, cda);
1334 if (err == 0) {
1335 nf_conntrack_get(&ct->ct_general);
1336 spin_unlock_bh(&nf_conntrack_lock);
1337 ctnetlink_event_report(ct,
1338 NETLINK_CB(skb).pid,
1339 nlmsg_report(nlh));
1340 nf_ct_put(ct);
1341 } else
1342 spin_unlock_bh(&nf_conntrack_lock);
1343
1344 return err;
1246 } 1345 }
1247 1346
1248out_unlock: 1347out_unlock:
@@ -1293,16 +1392,14 @@ ctnetlink_exp_dump_mask(struct sk_buff *skb,
1293 if (!nest_parms) 1392 if (!nest_parms)
1294 goto nla_put_failure; 1393 goto nla_put_failure;
1295 1394
1296 l3proto = nf_ct_l3proto_find_get(tuple->src.l3num); 1395 l3proto = __nf_ct_l3proto_find(tuple->src.l3num);
1297 ret = ctnetlink_dump_tuples_ip(skb, &m, l3proto); 1396 ret = ctnetlink_dump_tuples_ip(skb, &m, l3proto);
1298 nf_ct_l3proto_put(l3proto);
1299 1397
1300 if (unlikely(ret < 0)) 1398 if (unlikely(ret < 0))
1301 goto nla_put_failure; 1399 goto nla_put_failure;
1302 1400
1303 l4proto = nf_ct_l4proto_find_get(tuple->src.l3num, tuple->dst.protonum); 1401 l4proto = __nf_ct_l4proto_find(tuple->src.l3num, tuple->dst.protonum);
1304 ret = ctnetlink_dump_tuples_proto(skb, &m, l4proto); 1402 ret = ctnetlink_dump_tuples_proto(skb, &m, l4proto);
1305 nf_ct_l4proto_put(l4proto);
1306 if (unlikely(ret < 0)) 1403 if (unlikely(ret < 0))
1307 goto nla_put_failure; 1404 goto nla_put_failure;
1308 1405
@@ -1379,7 +1476,8 @@ static int ctnetlink_expect_event(struct notifier_block *this,
1379{ 1476{
1380 struct nlmsghdr *nlh; 1477 struct nlmsghdr *nlh;
1381 struct nfgenmsg *nfmsg; 1478 struct nfgenmsg *nfmsg;
1382 struct nf_conntrack_expect *exp = (struct nf_conntrack_expect *)ptr; 1479 struct nf_exp_event *item = (struct nf_exp_event *)ptr;
1480 struct nf_conntrack_expect *exp = item->exp;
1383 struct sk_buff *skb; 1481 struct sk_buff *skb;
1384 unsigned int type; 1482 unsigned int type;
1385 sk_buff_data_t b; 1483 sk_buff_data_t b;
@@ -1401,7 +1499,7 @@ static int ctnetlink_expect_event(struct notifier_block *this,
1401 b = skb->tail; 1499 b = skb->tail;
1402 1500
1403 type |= NFNL_SUBSYS_CTNETLINK_EXP << 8; 1501 type |= NFNL_SUBSYS_CTNETLINK_EXP << 8;
1404 nlh = NLMSG_PUT(skb, 0, 0, type, sizeof(struct nfgenmsg)); 1502 nlh = NLMSG_PUT(skb, item->pid, 0, type, sizeof(struct nfgenmsg));
1405 nfmsg = NLMSG_DATA(nlh); 1503 nfmsg = NLMSG_DATA(nlh);
1406 1504
1407 nlh->nlmsg_flags = flags; 1505 nlh->nlmsg_flags = flags;
@@ -1409,15 +1507,18 @@ static int ctnetlink_expect_event(struct notifier_block *this,
1409 nfmsg->version = NFNETLINK_V0; 1507 nfmsg->version = NFNETLINK_V0;
1410 nfmsg->res_id = 0; 1508 nfmsg->res_id = 0;
1411 1509
1510 rcu_read_lock();
1412 if (ctnetlink_exp_dump_expect(skb, exp) < 0) 1511 if (ctnetlink_exp_dump_expect(skb, exp) < 0)
1413 goto nla_put_failure; 1512 goto nla_put_failure;
1513 rcu_read_unlock();
1414 1514
1415 nlh->nlmsg_len = skb->tail - b; 1515 nlh->nlmsg_len = skb->tail - b;
1416 nfnetlink_send(skb, 0, NFNLGRP_CONNTRACK_EXP_NEW, 0); 1516 nfnetlink_send(skb, item->pid, NFNLGRP_CONNTRACK_EXP_NEW, item->report);
1417 return NOTIFY_DONE; 1517 return NOTIFY_DONE;
1418 1518
1419nlmsg_failure:
1420nla_put_failure: 1519nla_put_failure:
1520 rcu_read_unlock();
1521nlmsg_failure:
1421 kfree_skb(skb); 1522 kfree_skb(skb);
1422 return NOTIFY_DONE; 1523 return NOTIFY_DONE;
1423} 1524}
@@ -1521,9 +1622,11 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
1521 if (!skb2) 1622 if (!skb2)
1522 goto out; 1623 goto out;
1523 1624
1625 rcu_read_lock();
1524 err = ctnetlink_exp_fill_info(skb2, NETLINK_CB(skb).pid, 1626 err = ctnetlink_exp_fill_info(skb2, NETLINK_CB(skb).pid,
1525 nlh->nlmsg_seq, IPCTNL_MSG_EXP_NEW, 1627 nlh->nlmsg_seq, IPCTNL_MSG_EXP_NEW,
1526 1, exp); 1628 1, exp);
1629 rcu_read_unlock();
1527 if (err <= 0) 1630 if (err <= 0)
1528 goto free; 1631 goto free;
1529 1632
@@ -1624,7 +1727,7 @@ ctnetlink_change_expect(struct nf_conntrack_expect *x, struct nlattr *cda[])
1624} 1727}
1625 1728
1626static int 1729static int
1627ctnetlink_create_expect(struct nlattr *cda[], u_int8_t u3) 1730ctnetlink_create_expect(struct nlattr *cda[], u_int8_t u3, u32 pid, int report)
1628{ 1731{
1629 struct nf_conntrack_tuple tuple, mask, master_tuple; 1732 struct nf_conntrack_tuple tuple, mask, master_tuple;
1630 struct nf_conntrack_tuple_hash *h = NULL; 1733 struct nf_conntrack_tuple_hash *h = NULL;
@@ -1653,7 +1756,7 @@ ctnetlink_create_expect(struct nlattr *cda[], u_int8_t u3)
1653 1756
1654 if (!help || !help->helper) { 1757 if (!help || !help->helper) {
1655 /* such conntrack hasn't got any helper, abort */ 1758 /* such conntrack hasn't got any helper, abort */
1656 err = -EINVAL; 1759 err = -EOPNOTSUPP;
1657 goto out; 1760 goto out;
1658 } 1761 }
1659 1762
@@ -1671,7 +1774,7 @@ ctnetlink_create_expect(struct nlattr *cda[], u_int8_t u3)
1671 memcpy(&exp->mask.src.u3, &mask.src.u3, sizeof(exp->mask.src.u3)); 1774 memcpy(&exp->mask.src.u3, &mask.src.u3, sizeof(exp->mask.src.u3));
1672 exp->mask.src.u.all = mask.src.u.all; 1775 exp->mask.src.u.all = mask.src.u.all;
1673 1776
1674 err = nf_ct_expect_related(exp); 1777 err = nf_ct_expect_related_report(exp, pid, report);
1675 nf_ct_expect_put(exp); 1778 nf_ct_expect_put(exp);
1676 1779
1677out: 1780out:
@@ -1704,8 +1807,12 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
1704 if (!exp) { 1807 if (!exp) {
1705 spin_unlock_bh(&nf_conntrack_lock); 1808 spin_unlock_bh(&nf_conntrack_lock);
1706 err = -ENOENT; 1809 err = -ENOENT;
1707 if (nlh->nlmsg_flags & NLM_F_CREATE) 1810 if (nlh->nlmsg_flags & NLM_F_CREATE) {
1708 err = ctnetlink_create_expect(cda, u3); 1811 err = ctnetlink_create_expect(cda,
1812 u3,
1813 NETLINK_CB(skb).pid,
1814 nlmsg_report(nlh));
1815 }
1709 return err; 1816 return err;
1710 } 1817 }
1711 1818
diff --git a/net/netfilter/nf_conntrack_pptp.c b/net/netfilter/nf_conntrack_pptp.c
index 1bc3001d182..9e169ef2e85 100644
--- a/net/netfilter/nf_conntrack_pptp.c
+++ b/net/netfilter/nf_conntrack_pptp.c
@@ -37,6 +37,7 @@ MODULE_LICENSE("GPL");
37MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>"); 37MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
38MODULE_DESCRIPTION("Netfilter connection tracking helper module for PPTP"); 38MODULE_DESCRIPTION("Netfilter connection tracking helper module for PPTP");
39MODULE_ALIAS("ip_conntrack_pptp"); 39MODULE_ALIAS("ip_conntrack_pptp");
40MODULE_ALIAS_NFCT_HELPER("pptp");
40 41
41static DEFINE_SPINLOCK(nf_pptp_lock); 42static DEFINE_SPINLOCK(nf_pptp_lock);
42 43
diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c
index 4ab62ad85dd..1b279f9d6bf 100644
--- a/net/netfilter/nf_conntrack_proto_gre.c
+++ b/net/netfilter/nf_conntrack_proto_gre.c
@@ -341,7 +341,7 @@ static int __init nf_ct_proto_gre_init(void)
341 return rv; 341 return rv;
342} 342}
343 343
344static void nf_ct_proto_gre_fini(void) 344static void __exit nf_ct_proto_gre_fini(void)
345{ 345{
346 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_gre4); 346 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_gre4);
347 unregister_pernet_gen_subsys(proto_gre_net_id, &proto_gre_net_ops); 347 unregister_pernet_gen_subsys(proto_gre_net_id, &proto_gre_net_ops);
diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c
index c2bd457bc2f..74e03790119 100644
--- a/net/netfilter/nf_conntrack_proto_sctp.c
+++ b/net/netfilter/nf_conntrack_proto_sctp.c
@@ -317,7 +317,7 @@ static int sctp_packet(struct nf_conn *ct,
317 goto out; 317 goto out;
318 } 318 }
319 319
320 old_state = new_state = SCTP_CONNTRACK_MAX; 320 old_state = new_state = SCTP_CONNTRACK_NONE;
321 write_lock_bh(&sctp_lock); 321 write_lock_bh(&sctp_lock);
322 for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) { 322 for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
323 /* Special cases of Verification tag check (Sec 8.5.1) */ 323 /* Special cases of Verification tag check (Sec 8.5.1) */
diff --git a/net/netfilter/nf_conntrack_sane.c b/net/netfilter/nf_conntrack_sane.c
index a94294b2b23..dcfecbb81c4 100644
--- a/net/netfilter/nf_conntrack_sane.c
+++ b/net/netfilter/nf_conntrack_sane.c
@@ -30,6 +30,7 @@
30MODULE_LICENSE("GPL"); 30MODULE_LICENSE("GPL");
31MODULE_AUTHOR("Michal Schmidt <mschmidt@redhat.com>"); 31MODULE_AUTHOR("Michal Schmidt <mschmidt@redhat.com>");
32MODULE_DESCRIPTION("SANE connection tracking helper"); 32MODULE_DESCRIPTION("SANE connection tracking helper");
33MODULE_ALIAS_NFCT_HELPER("sane");
33 34
34static char *sane_buffer; 35static char *sane_buffer;
35 36
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c
index 6813f1c8863..4b572163784 100644
--- a/net/netfilter/nf_conntrack_sip.c
+++ b/net/netfilter/nf_conntrack_sip.c
@@ -28,6 +28,7 @@ MODULE_LICENSE("GPL");
28MODULE_AUTHOR("Christian Hentschel <chentschel@arnet.com.ar>"); 28MODULE_AUTHOR("Christian Hentschel <chentschel@arnet.com.ar>");
29MODULE_DESCRIPTION("SIP connection tracking helper"); 29MODULE_DESCRIPTION("SIP connection tracking helper");
30MODULE_ALIAS("ip_conntrack_sip"); 30MODULE_ALIAS("ip_conntrack_sip");
31MODULE_ALIAS_NFCT_HELPER("sip");
31 32
32#define MAX_PORTS 8 33#define MAX_PORTS 8
33static unsigned short ports[MAX_PORTS]; 34static unsigned short ports[MAX_PORTS];
diff --git a/net/netfilter/nf_conntrack_tftp.c b/net/netfilter/nf_conntrack_tftp.c
index f57f6e7a71e..46e646b2e9b 100644
--- a/net/netfilter/nf_conntrack_tftp.c
+++ b/net/netfilter/nf_conntrack_tftp.c
@@ -22,6 +22,7 @@ MODULE_AUTHOR("Magnus Boden <mb@ozaba.mine.nu>");
22MODULE_DESCRIPTION("TFTP connection tracking helper"); 22MODULE_DESCRIPTION("TFTP connection tracking helper");
23MODULE_LICENSE("GPL"); 23MODULE_LICENSE("GPL");
24MODULE_ALIAS("ip_conntrack_tftp"); 24MODULE_ALIAS("ip_conntrack_tftp");
25MODULE_ALIAS_NFCT_HELPER("tftp");
25 26
26#define MAX_PORTS 8 27#define MAX_PORTS 8
27static unsigned short ports[MAX_PORTS]; 28static unsigned short ports[MAX_PORTS];
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index 41e0105d382..2770b4e57ea 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -30,6 +30,7 @@
30#include <linux/random.h> 30#include <linux/random.h>
31#include <net/sock.h> 31#include <net/sock.h>
32#include <net/netfilter/nf_log.h> 32#include <net/netfilter/nf_log.h>
33#include <net/netfilter/nfnetlink_log.h>
33 34
34#include <asm/atomic.h> 35#include <asm/atomic.h>
35 36
@@ -533,7 +534,7 @@ static struct nf_loginfo default_loginfo = {
533}; 534};
534 535
535/* log handler for internal netfilter logging api */ 536/* log handler for internal netfilter logging api */
536static void 537void
537nfulnl_log_packet(u_int8_t pf, 538nfulnl_log_packet(u_int8_t pf,
538 unsigned int hooknum, 539 unsigned int hooknum,
539 const struct sk_buff *skb, 540 const struct sk_buff *skb,
@@ -648,6 +649,7 @@ alloc_failure:
648 /* FIXME: statistics */ 649 /* FIXME: statistics */
649 goto unlock_and_release; 650 goto unlock_and_release;
650} 651}
652EXPORT_SYMBOL_GPL(nfulnl_log_packet);
651 653
652static int 654static int
653nfulnl_rcv_nl_event(struct notifier_block *this, 655nfulnl_rcv_nl_event(struct notifier_block *this,
diff --git a/net/netfilter/xt_NFLOG.c b/net/netfilter/xt_NFLOG.c
index 50e3a52d3b3..a57c5cf018e 100644
--- a/net/netfilter/xt_NFLOG.c
+++ b/net/netfilter/xt_NFLOG.c
@@ -13,6 +13,7 @@
13#include <linux/netfilter/x_tables.h> 13#include <linux/netfilter/x_tables.h>
14#include <linux/netfilter/xt_NFLOG.h> 14#include <linux/netfilter/xt_NFLOG.h>
15#include <net/netfilter/nf_log.h> 15#include <net/netfilter/nf_log.h>
16#include <net/netfilter/nfnetlink_log.h>
16 17
17MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); 18MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
18MODULE_DESCRIPTION("Xtables: packet logging to netlink using NFLOG"); 19MODULE_DESCRIPTION("Xtables: packet logging to netlink using NFLOG");
@@ -31,8 +32,8 @@ nflog_tg(struct sk_buff *skb, const struct xt_target_param *par)
31 li.u.ulog.group = info->group; 32 li.u.ulog.group = info->group;
32 li.u.ulog.qthreshold = info->threshold; 33 li.u.ulog.qthreshold = info->threshold;
33 34
34 nf_log_packet(par->family, par->hooknum, skb, par->in, 35 nfulnl_log_packet(par->family, par->hooknum, skb, par->in,
35 par->out, &li, "%s", info->prefix); 36 par->out, &li, info->prefix);
36 return XT_CONTINUE; 37 return XT_CONTINUE;
37} 38}
38 39
diff --git a/net/netfilter/xt_recent.c b/net/netfilter/xt_recent.c
index 3c3dd22b1d0..fe80b614a40 100644
--- a/net/netfilter/xt_recent.c
+++ b/net/netfilter/xt_recent.c
@@ -72,9 +72,6 @@ struct recent_entry {
72struct recent_table { 72struct recent_table {
73 struct list_head list; 73 struct list_head list;
74 char name[XT_RECENT_NAME_LEN]; 74 char name[XT_RECENT_NAME_LEN];
75#ifdef CONFIG_PROC_FS
76 struct proc_dir_entry *proc_old, *proc;
77#endif
78 unsigned int refcnt; 75 unsigned int refcnt;
79 unsigned int entries; 76 unsigned int entries;
80 struct list_head lru_list; 77 struct list_head lru_list;
@@ -284,6 +281,9 @@ static bool recent_mt_check(const struct xt_mtchk_param *par)
284{ 281{
285 const struct xt_recent_mtinfo *info = par->matchinfo; 282 const struct xt_recent_mtinfo *info = par->matchinfo;
286 struct recent_table *t; 283 struct recent_table *t;
284#ifdef CONFIG_PROC_FS
285 struct proc_dir_entry *pde;
286#endif
287 unsigned i; 287 unsigned i;
288 bool ret = false; 288 bool ret = false;
289 289
@@ -318,25 +318,25 @@ static bool recent_mt_check(const struct xt_mtchk_param *par)
318 for (i = 0; i < ip_list_hash_size; i++) 318 for (i = 0; i < ip_list_hash_size; i++)
319 INIT_LIST_HEAD(&t->iphash[i]); 319 INIT_LIST_HEAD(&t->iphash[i]);
320#ifdef CONFIG_PROC_FS 320#ifdef CONFIG_PROC_FS
321 t->proc = proc_create_data(t->name, ip_list_perms, recent_proc_dir, 321 pde = proc_create_data(t->name, ip_list_perms, recent_proc_dir,
322 &recent_mt_fops, t); 322 &recent_mt_fops, t);
323 if (t->proc == NULL) { 323 if (pde == NULL) {
324 kfree(t); 324 kfree(t);
325 goto out; 325 goto out;
326 } 326 }
327 pde->uid = ip_list_uid;
328 pde->gid = ip_list_gid;
327#ifdef CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT 329#ifdef CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT
328 t->proc_old = proc_create_data(t->name, ip_list_perms, proc_old_dir, 330 pde = proc_create_data(t->name, ip_list_perms, proc_old_dir,
329 &recent_old_fops, t); 331 &recent_old_fops, t);
330 if (t->proc_old == NULL) { 332 if (pde == NULL) {
331 remove_proc_entry(t->name, proc_old_dir); 333 remove_proc_entry(t->name, proc_old_dir);
332 kfree(t); 334 kfree(t);
333 goto out; 335 goto out;
334 } 336 }
335 t->proc_old->uid = ip_list_uid; 337 pde->uid = ip_list_uid;
336 t->proc_old->gid = ip_list_gid; 338 pde->gid = ip_list_gid;
337#endif 339#endif
338 t->proc->uid = ip_list_uid;
339 t->proc->gid = ip_list_gid;
340#endif 340#endif
341 spin_lock_bh(&recent_lock); 341 spin_lock_bh(&recent_lock);
342 list_add_tail(&t->list, &tables); 342 list_add_tail(&t->list, &tables);