aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2013-02-18 23:42:09 -0500
committerDavid S. Miller <davem@davemloft.net>2013-02-18 23:42:09 -0500
commit2ccba5433ba567046e49643eb21502d5ea91dc83 (patch)
tree7297a374160c7785ebc39534d86a175b9c760c8c /net
parent6338a53a2bd02d5878ab449371323364b7cc7694 (diff)
parentb20ab9cc63ca4605aec154cf54faa8455749f3f6 (diff)
Merge branch 'master' of git://1984.lsi.us.es/nf-next
Pablo Neira Ayuso says: ==================== The following patchset contain updates for your net-next tree, they are: * Fix (for just added) connlabel dependencies, from Florian Westphal. * Add aliasing support for conntrack, thus users can either use -m state or -m conntrack from iptables while using the same kernel module, from Jozsef Kadlecsik. * Some code refactoring for the CT target to merge common code in revision 0 and 1, from myself. * Add aliasing support for CT, based on patch from Jozsef Kadlecsik. * Add one mutex per nfnetlink subsystem, from myself. * Improved logging for packets that are dropped by helpers, from myself. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c10
-rw-r--r--net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c8
-rw-r--r--net/netfilter/Kconfig1
-rw-r--r--net/netfilter/ipset/ip_set_core.c26
-rw-r--r--net/netfilter/nf_conntrack_amanda.c5
-rw-r--r--net/netfilter/nf_conntrack_ftp.c10
-rw-r--r--net/netfilter/nf_conntrack_h323_main.c6
-rw-r--r--net/netfilter/nf_conntrack_helper.c19
-rw-r--r--net/netfilter/nf_conntrack_irc.c7
-rw-r--r--net/netfilter/nf_conntrack_netlink.c12
-rw-r--r--net/netfilter/nf_conntrack_pptp.c2
-rw-r--r--net/netfilter/nf_conntrack_sane.c5
-rw-r--r--net/netfilter/nf_conntrack_sip.c73
-rw-r--r--net/netfilter/nf_conntrack_tftp.c8
-rw-r--r--net/netfilter/nf_nat_amanda.c8
-rw-r--r--net/netfilter/nf_nat_ftp.c5
-rw-r--r--net/netfilter/nf_nat_irc.c8
-rw-r--r--net/netfilter/nf_nat_sip.c49
-rw-r--r--net/netfilter/nf_nat_tftp.c4
-rw-r--r--net/netfilter/nfnetlink.c52
-rw-r--r--net/netfilter/xt_CT.c177
21 files changed, 298 insertions, 197 deletions
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index 48990ada0e1e..2820aa18b542 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -100,7 +100,6 @@ static unsigned int ipv4_helper(unsigned int hooknum,
100 enum ip_conntrack_info ctinfo; 100 enum ip_conntrack_info ctinfo;
101 const struct nf_conn_help *help; 101 const struct nf_conn_help *help;
102 const struct nf_conntrack_helper *helper; 102 const struct nf_conntrack_helper *helper;
103 unsigned int ret;
104 103
105 /* This is where we call the helper: as the packet goes out. */ 104 /* This is where we call the helper: as the packet goes out. */
106 ct = nf_ct_get(skb, &ctinfo); 105 ct = nf_ct_get(skb, &ctinfo);
@@ -116,13 +115,8 @@ static unsigned int ipv4_helper(unsigned int hooknum,
116 if (!helper) 115 if (!helper)
117 return NF_ACCEPT; 116 return NF_ACCEPT;
118 117
119 ret = helper->help(skb, skb_network_offset(skb) + ip_hdrlen(skb), 118 return helper->help(skb, skb_network_offset(skb) + ip_hdrlen(skb),
120 ct, ctinfo); 119 ct, ctinfo);
121 if (ret != NF_ACCEPT && (ret & NF_VERDICT_MASK) != NF_QUEUE) {
122 nf_log_packet(NFPROTO_IPV4, hooknum, skb, in, out, NULL,
123 "nf_ct_%s: dropping packet", helper->name);
124 }
125 return ret;
126} 120}
127 121
128static unsigned int ipv4_confirm(unsigned int hooknum, 122static unsigned int ipv4_confirm(unsigned int hooknum,
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index 8a45bb20bedb..2b6c226f5198 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -104,7 +104,6 @@ static unsigned int ipv6_helper(unsigned int hooknum,
104 const struct nf_conn_help *help; 104 const struct nf_conn_help *help;
105 const struct nf_conntrack_helper *helper; 105 const struct nf_conntrack_helper *helper;
106 enum ip_conntrack_info ctinfo; 106 enum ip_conntrack_info ctinfo;
107 unsigned int ret;
108 __be16 frag_off; 107 __be16 frag_off;
109 int protoff; 108 int protoff;
110 u8 nexthdr; 109 u8 nexthdr;
@@ -130,12 +129,7 @@ static unsigned int ipv6_helper(unsigned int hooknum,
130 return NF_ACCEPT; 129 return NF_ACCEPT;
131 } 130 }
132 131
133 ret = helper->help(skb, protoff, ct, ctinfo); 132 return helper->help(skb, protoff, ct, ctinfo);
134 if (ret != NF_ACCEPT && (ret & NF_VERDICT_MASK) != NF_QUEUE) {
135 nf_log_packet(NFPROTO_IPV6, hooknum, skb, in, out, NULL,
136 "nf_ct_%s: dropping packet", helper->name);
137 }
138 return ret;
139} 133}
140 134
141static unsigned int ipv6_confirm(unsigned int hooknum, 135static unsigned int ipv6_confirm(unsigned int hooknum,
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index eb2c8ebf6d99..d4dd702574e4 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -860,6 +860,7 @@ config NETFILTER_XT_MATCH_CONNBYTES
860config NETFILTER_XT_MATCH_CONNLABEL 860config NETFILTER_XT_MATCH_CONNLABEL
861 tristate '"connlabel" match support' 861 tristate '"connlabel" match support'
862 select NF_CONNTRACK_LABELS 862 select NF_CONNTRACK_LABELS
863 depends on NF_CONNTRACK
863 depends on NETFILTER_ADVANCED 864 depends on NETFILTER_ADVANCED
864 ---help--- 865 ---help---
865 This match allows you to test and assign userspace-defined labels names 866 This match allows you to test and assign userspace-defined labels names
diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c
index 6d6d8f2b033e..f82b2e606cfd 100644
--- a/net/netfilter/ipset/ip_set_core.c
+++ b/net/netfilter/ipset/ip_set_core.c
@@ -88,14 +88,14 @@ find_set_type(const char *name, u8 family, u8 revision)
88static bool 88static bool
89load_settype(const char *name) 89load_settype(const char *name)
90{ 90{
91 nfnl_unlock(); 91 nfnl_unlock(NFNL_SUBSYS_IPSET);
92 pr_debug("try to load ip_set_%s\n", name); 92 pr_debug("try to load ip_set_%s\n", name);
93 if (request_module("ip_set_%s", name) < 0) { 93 if (request_module("ip_set_%s", name) < 0) {
94 pr_warning("Can't find ip_set type %s\n", name); 94 pr_warning("Can't find ip_set type %s\n", name);
95 nfnl_lock(); 95 nfnl_lock(NFNL_SUBSYS_IPSET);
96 return false; 96 return false;
97 } 97 }
98 nfnl_lock(); 98 nfnl_lock(NFNL_SUBSYS_IPSET);
99 return true; 99 return true;
100} 100}
101 101
@@ -532,7 +532,7 @@ ip_set_nfnl_get(const char *name)
532 ip_set_id_t i, index = IPSET_INVALID_ID; 532 ip_set_id_t i, index = IPSET_INVALID_ID;
533 struct ip_set *s; 533 struct ip_set *s;
534 534
535 nfnl_lock(); 535 nfnl_lock(NFNL_SUBSYS_IPSET);
536 for (i = 0; i < ip_set_max; i++) { 536 for (i = 0; i < ip_set_max; i++) {
537 s = nfnl_set(i); 537 s = nfnl_set(i);
538 if (s != NULL && STREQ(s->name, name)) { 538 if (s != NULL && STREQ(s->name, name)) {
@@ -541,7 +541,7 @@ ip_set_nfnl_get(const char *name)
541 break; 541 break;
542 } 542 }
543 } 543 }
544 nfnl_unlock(); 544 nfnl_unlock(NFNL_SUBSYS_IPSET);
545 545
546 return index; 546 return index;
547} 547}
@@ -561,13 +561,13 @@ ip_set_nfnl_get_byindex(ip_set_id_t index)
561 if (index > ip_set_max) 561 if (index > ip_set_max)
562 return IPSET_INVALID_ID; 562 return IPSET_INVALID_ID;
563 563
564 nfnl_lock(); 564 nfnl_lock(NFNL_SUBSYS_IPSET);
565 set = nfnl_set(index); 565 set = nfnl_set(index);
566 if (set) 566 if (set)
567 __ip_set_get(set); 567 __ip_set_get(set);
568 else 568 else
569 index = IPSET_INVALID_ID; 569 index = IPSET_INVALID_ID;
570 nfnl_unlock(); 570 nfnl_unlock(NFNL_SUBSYS_IPSET);
571 571
572 return index; 572 return index;
573} 573}
@@ -584,11 +584,11 @@ void
584ip_set_nfnl_put(ip_set_id_t index) 584ip_set_nfnl_put(ip_set_id_t index)
585{ 585{
586 struct ip_set *set; 586 struct ip_set *set;
587 nfnl_lock(); 587 nfnl_lock(NFNL_SUBSYS_IPSET);
588 set = nfnl_set(index); 588 set = nfnl_set(index);
589 if (set != NULL) 589 if (set != NULL)
590 __ip_set_put(set); 590 __ip_set_put(set);
591 nfnl_unlock(); 591 nfnl_unlock(NFNL_SUBSYS_IPSET);
592} 592}
593EXPORT_SYMBOL_GPL(ip_set_nfnl_put); 593EXPORT_SYMBOL_GPL(ip_set_nfnl_put);
594 594
@@ -1763,10 +1763,10 @@ ip_set_sockfn_get(struct sock *sk, int optval, void __user *user, int *len)
1763 goto done; 1763 goto done;
1764 } 1764 }
1765 req_get->set.name[IPSET_MAXNAMELEN - 1] = '\0'; 1765 req_get->set.name[IPSET_MAXNAMELEN - 1] = '\0';
1766 nfnl_lock(); 1766 nfnl_lock(NFNL_SUBSYS_IPSET);
1767 find_set_and_id(req_get->set.name, &id); 1767 find_set_and_id(req_get->set.name, &id);
1768 req_get->set.index = id; 1768 req_get->set.index = id;
1769 nfnl_unlock(); 1769 nfnl_unlock(NFNL_SUBSYS_IPSET);
1770 goto copy; 1770 goto copy;
1771 } 1771 }
1772 case IP_SET_OP_GET_BYINDEX: { 1772 case IP_SET_OP_GET_BYINDEX: {
@@ -1778,11 +1778,11 @@ ip_set_sockfn_get(struct sock *sk, int optval, void __user *user, int *len)
1778 ret = -EINVAL; 1778 ret = -EINVAL;
1779 goto done; 1779 goto done;
1780 } 1780 }
1781 nfnl_lock(); 1781 nfnl_lock(NFNL_SUBSYS_IPSET);
1782 set = nfnl_set(req_get->set.index); 1782 set = nfnl_set(req_get->set.index);
1783 strncpy(req_get->set.name, set ? set->name : "", 1783 strncpy(req_get->set.name, set ? set->name : "",
1784 IPSET_MAXNAMELEN); 1784 IPSET_MAXNAMELEN);
1785 nfnl_unlock(); 1785 nfnl_unlock(NFNL_SUBSYS_IPSET);
1786 goto copy; 1786 goto copy;
1787 } 1787 }
1788 default: 1788 default:
diff --git a/net/netfilter/nf_conntrack_amanda.c b/net/netfilter/nf_conntrack_amanda.c
index c514fe6033d2..dbdaa1149260 100644
--- a/net/netfilter/nf_conntrack_amanda.c
+++ b/net/netfilter/nf_conntrack_amanda.c
@@ -145,6 +145,7 @@ static int amanda_help(struct sk_buff *skb,
145 145
146 exp = nf_ct_expect_alloc(ct); 146 exp = nf_ct_expect_alloc(ct);
147 if (exp == NULL) { 147 if (exp == NULL) {
148 nf_ct_helper_log(skb, ct, "cannot alloc expectation");
148 ret = NF_DROP; 149 ret = NF_DROP;
149 goto out; 150 goto out;
150 } 151 }
@@ -158,8 +159,10 @@ static int amanda_help(struct sk_buff *skb,
158 if (nf_nat_amanda && ct->status & IPS_NAT_MASK) 159 if (nf_nat_amanda && ct->status & IPS_NAT_MASK)
159 ret = nf_nat_amanda(skb, ctinfo, protoff, 160 ret = nf_nat_amanda(skb, ctinfo, protoff,
160 off - dataoff, len, exp); 161 off - dataoff, len, exp);
161 else if (nf_ct_expect_related(exp) != 0) 162 else if (nf_ct_expect_related(exp) != 0) {
163 nf_ct_helper_log(skb, ct, "cannot add expectation");
162 ret = NF_DROP; 164 ret = NF_DROP;
165 }
163 nf_ct_expect_put(exp); 166 nf_ct_expect_put(exp);
164 } 167 }
165 168
diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c
index 1ce3befb7c8a..62fb8faedb80 100644
--- a/net/netfilter/nf_conntrack_ftp.c
+++ b/net/netfilter/nf_conntrack_ftp.c
@@ -435,8 +435,8 @@ skip_nl_seq:
435 connection tracking, not packet filtering. 435 connection tracking, not packet filtering.
436 However, it is necessary for accurate tracking in 436 However, it is necessary for accurate tracking in
437 this case. */ 437 this case. */
438 pr_debug("conntrack_ftp: partial %s %u+%u\n", 438 nf_ct_helper_log(skb, ct, "partial matching of `%s'",
439 search[dir][i].pattern, ntohl(th->seq), datalen); 439 search[dir][i].pattern);
440 ret = NF_DROP; 440 ret = NF_DROP;
441 goto out; 441 goto out;
442 } else if (found == 0) { /* No match */ 442 } else if (found == 0) { /* No match */
@@ -450,6 +450,7 @@ skip_nl_seq:
450 450
451 exp = nf_ct_expect_alloc(ct); 451 exp = nf_ct_expect_alloc(ct);
452 if (exp == NULL) { 452 if (exp == NULL) {
453 nf_ct_helper_log(skb, ct, "cannot alloc expectation");
453 ret = NF_DROP; 454 ret = NF_DROP;
454 goto out; 455 goto out;
455 } 456 }
@@ -500,9 +501,10 @@ skip_nl_seq:
500 protoff, matchoff, matchlen, exp); 501 protoff, matchoff, matchlen, exp);
501 else { 502 else {
502 /* Can't expect this? Best to drop packet now. */ 503 /* Can't expect this? Best to drop packet now. */
503 if (nf_ct_expect_related(exp) != 0) 504 if (nf_ct_expect_related(exp) != 0) {
505 nf_ct_helper_log(skb, ct, "cannot add expectation");
504 ret = NF_DROP; 506 ret = NF_DROP;
505 else 507 } else
506 ret = NF_ACCEPT; 508 ret = NF_ACCEPT;
507 } 509 }
508 510
diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c
index 962795e839ab..7df7b36d2e24 100644
--- a/net/netfilter/nf_conntrack_h323_main.c
+++ b/net/netfilter/nf_conntrack_h323_main.c
@@ -623,7 +623,7 @@ static int h245_help(struct sk_buff *skb, unsigned int protoff,
623 623
624 drop: 624 drop:
625 spin_unlock_bh(&nf_h323_lock); 625 spin_unlock_bh(&nf_h323_lock);
626 net_info_ratelimited("nf_ct_h245: packet dropped\n"); 626 nf_ct_helper_log(skb, ct, "cannot process H.245 message");
627 return NF_DROP; 627 return NF_DROP;
628} 628}
629 629
@@ -1197,7 +1197,7 @@ static int q931_help(struct sk_buff *skb, unsigned int protoff,
1197 1197
1198 drop: 1198 drop:
1199 spin_unlock_bh(&nf_h323_lock); 1199 spin_unlock_bh(&nf_h323_lock);
1200 net_info_ratelimited("nf_ct_q931: packet dropped\n"); 1200 nf_ct_helper_log(skb, ct, "cannot process Q.931 message");
1201 return NF_DROP; 1201 return NF_DROP;
1202} 1202}
1203 1203
@@ -1795,7 +1795,7 @@ static int ras_help(struct sk_buff *skb, unsigned int protoff,
1795 1795
1796 drop: 1796 drop:
1797 spin_unlock_bh(&nf_h323_lock); 1797 spin_unlock_bh(&nf_h323_lock);
1798 net_info_ratelimited("nf_ct_ras: packet dropped\n"); 1798 nf_ct_helper_log(skb, ct, "cannot process RAS message");
1799 return NF_DROP; 1799 return NF_DROP;
1800} 1800}
1801 1801
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c
index 1343a4bb4031..013cdf69fe29 100644
--- a/net/netfilter/nf_conntrack_helper.c
+++ b/net/netfilter/nf_conntrack_helper.c
@@ -28,6 +28,7 @@
28#include <net/netfilter/nf_conntrack_helper.h> 28#include <net/netfilter/nf_conntrack_helper.h>
29#include <net/netfilter/nf_conntrack_core.h> 29#include <net/netfilter/nf_conntrack_core.h>
30#include <net/netfilter/nf_conntrack_extend.h> 30#include <net/netfilter/nf_conntrack_extend.h>
31#include <net/netfilter/nf_log.h>
31 32
32static DEFINE_MUTEX(nf_ct_helper_mutex); 33static DEFINE_MUTEX(nf_ct_helper_mutex);
33struct hlist_head *nf_ct_helper_hash __read_mostly; 34struct hlist_head *nf_ct_helper_hash __read_mostly;
@@ -334,6 +335,24 @@ nf_ct_helper_expectfn_find_by_symbol(const void *symbol)
334} 335}
335EXPORT_SYMBOL_GPL(nf_ct_helper_expectfn_find_by_symbol); 336EXPORT_SYMBOL_GPL(nf_ct_helper_expectfn_find_by_symbol);
336 337
338__printf(3, 4)
339void nf_ct_helper_log(struct sk_buff *skb, const struct nf_conn *ct,
340 const char *fmt, ...)
341{
342 const struct nf_conn_help *help;
343 const struct nf_conntrack_helper *helper;
344
345 /* Called from the helper function, this call never fails */
346 help = nfct_help(ct);
347
348 /* rcu_read_lock()ed by nf_hook_slow */
349 helper = rcu_dereference(help->helper);
350
351 nf_log_packet(nf_ct_l3num(ct), 0, skb, NULL, NULL, NULL,
352 "nf_ct_%s: dropping packet: %s ", helper->name, fmt);
353}
354EXPORT_SYMBOL_GPL(nf_ct_helper_log);
355
337int nf_conntrack_helper_register(struct nf_conntrack_helper *me) 356int nf_conntrack_helper_register(struct nf_conntrack_helper *me)
338{ 357{
339 int ret = 0; 358 int ret = 0;
diff --git a/net/netfilter/nf_conntrack_irc.c b/net/netfilter/nf_conntrack_irc.c
index 3b20aa77cfc8..70985c5d0ffa 100644
--- a/net/netfilter/nf_conntrack_irc.c
+++ b/net/netfilter/nf_conntrack_irc.c
@@ -194,6 +194,8 @@ static int help(struct sk_buff *skb, unsigned int protoff,
194 194
195 exp = nf_ct_expect_alloc(ct); 195 exp = nf_ct_expect_alloc(ct);
196 if (exp == NULL) { 196 if (exp == NULL) {
197 nf_ct_helper_log(skb, ct,
198 "cannot alloc expectation");
197 ret = NF_DROP; 199 ret = NF_DROP;
198 goto out; 200 goto out;
199 } 201 }
@@ -210,8 +212,11 @@ static int help(struct sk_buff *skb, unsigned int protoff,
210 addr_beg_p - ib_ptr, 212 addr_beg_p - ib_ptr,
211 addr_end_p - addr_beg_p, 213 addr_end_p - addr_beg_p,
212 exp); 214 exp);
213 else if (nf_ct_expect_related(exp) != 0) 215 else if (nf_ct_expect_related(exp) != 0) {
216 nf_ct_helper_log(skb, ct,
217 "cannot add expectation");
214 ret = NF_DROP; 218 ret = NF_DROP;
219 }
215 nf_ct_expect_put(exp); 220 nf_ct_expect_put(exp);
216 goto out; 221 goto out;
217 } 222 }
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 79c2d507ac49..5d60e04f9679 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -1256,13 +1256,13 @@ ctnetlink_parse_nat_setup(struct nf_conn *ct,
1256 if (!parse_nat_setup) { 1256 if (!parse_nat_setup) {
1257#ifdef CONFIG_MODULES 1257#ifdef CONFIG_MODULES
1258 rcu_read_unlock(); 1258 rcu_read_unlock();
1259 nfnl_unlock(); 1259 nfnl_unlock(NFNL_SUBSYS_CTNETLINK);
1260 if (request_module("nf-nat") < 0) { 1260 if (request_module("nf-nat") < 0) {
1261 nfnl_lock(); 1261 nfnl_lock(NFNL_SUBSYS_CTNETLINK);
1262 rcu_read_lock(); 1262 rcu_read_lock();
1263 return -EOPNOTSUPP; 1263 return -EOPNOTSUPP;
1264 } 1264 }
1265 nfnl_lock(); 1265 nfnl_lock(NFNL_SUBSYS_CTNETLINK);
1266 rcu_read_lock(); 1266 rcu_read_lock();
1267 if (nfnetlink_parse_nat_setup_hook) 1267 if (nfnetlink_parse_nat_setup_hook)
1268 return -EAGAIN; 1268 return -EAGAIN;
@@ -1274,13 +1274,13 @@ ctnetlink_parse_nat_setup(struct nf_conn *ct,
1274 if (err == -EAGAIN) { 1274 if (err == -EAGAIN) {
1275#ifdef CONFIG_MODULES 1275#ifdef CONFIG_MODULES
1276 rcu_read_unlock(); 1276 rcu_read_unlock();
1277 nfnl_unlock(); 1277 nfnl_unlock(NFNL_SUBSYS_CTNETLINK);
1278 if (request_module("nf-nat-%u", nf_ct_l3num(ct)) < 0) { 1278 if (request_module("nf-nat-%u", nf_ct_l3num(ct)) < 0) {
1279 nfnl_lock(); 1279 nfnl_lock(NFNL_SUBSYS_CTNETLINK);
1280 rcu_read_lock(); 1280 rcu_read_lock();
1281 return -EOPNOTSUPP; 1281 return -EOPNOTSUPP;
1282 } 1282 }
1283 nfnl_lock(); 1283 nfnl_lock(NFNL_SUBSYS_CTNETLINK);
1284 rcu_read_lock(); 1284 rcu_read_lock();
1285#else 1285#else
1286 err = -EOPNOTSUPP; 1286 err = -EOPNOTSUPP;
diff --git a/net/netfilter/nf_conntrack_pptp.c b/net/netfilter/nf_conntrack_pptp.c
index cc7669ef0b95..e6678d2b624e 100644
--- a/net/netfilter/nf_conntrack_pptp.c
+++ b/net/netfilter/nf_conntrack_pptp.c
@@ -14,7 +14,7 @@
14 * Limitations: 14 * Limitations:
15 * - We blindly assume that control connections are always 15 * - We blindly assume that control connections are always
16 * established in PNS->PAC direction. This is a violation 16 * established in PNS->PAC direction. This is a violation
17 * of RFFC2673 17 * of RFC 2637
18 * - We can only support one single call within each session 18 * - We can only support one single call within each session
19 * TODO: 19 * TODO:
20 * - testing of incoming PPTP calls 20 * - testing of incoming PPTP calls
diff --git a/net/netfilter/nf_conntrack_sane.c b/net/netfilter/nf_conntrack_sane.c
index 295429f39088..4a2134fd3fcb 100644
--- a/net/netfilter/nf_conntrack_sane.c
+++ b/net/netfilter/nf_conntrack_sane.c
@@ -138,6 +138,7 @@ static int help(struct sk_buff *skb,
138 138
139 exp = nf_ct_expect_alloc(ct); 139 exp = nf_ct_expect_alloc(ct);
140 if (exp == NULL) { 140 if (exp == NULL) {
141 nf_ct_helper_log(skb, ct, "cannot alloc expectation");
141 ret = NF_DROP; 142 ret = NF_DROP;
142 goto out; 143 goto out;
143 } 144 }
@@ -151,8 +152,10 @@ static int help(struct sk_buff *skb,
151 nf_ct_dump_tuple(&exp->tuple); 152 nf_ct_dump_tuple(&exp->tuple);
152 153
153 /* Can't expect this? Best to drop packet now. */ 154 /* Can't expect this? Best to drop packet now. */
154 if (nf_ct_expect_related(exp) != 0) 155 if (nf_ct_expect_related(exp) != 0) {
156 nf_ct_helper_log(skb, ct, "cannot add expectation");
155 ret = NF_DROP; 157 ret = NF_DROP;
158 }
156 159
157 nf_ct_expect_put(exp); 160 nf_ct_expect_put(exp);
158 161
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c
index 72a67bbe3518..069229d919b6 100644
--- a/net/netfilter/nf_conntrack_sip.c
+++ b/net/netfilter/nf_conntrack_sip.c
@@ -1095,8 +1095,10 @@ static int process_sdp(struct sk_buff *skb, unsigned int protoff,
1095 port = simple_strtoul(*dptr + mediaoff, NULL, 10); 1095 port = simple_strtoul(*dptr + mediaoff, NULL, 10);
1096 if (port == 0) 1096 if (port == 0)
1097 continue; 1097 continue;
1098 if (port < 1024 || port > 65535) 1098 if (port < 1024 || port > 65535) {
1099 nf_ct_helper_log(skb, ct, "wrong port %u", port);
1099 return NF_DROP; 1100 return NF_DROP;
1101 }
1100 1102
1101 /* The media description overrides the session description. */ 1103 /* The media description overrides the session description. */
1102 maddr_len = 0; 1104 maddr_len = 0;
@@ -1107,15 +1109,20 @@ static int process_sdp(struct sk_buff *skb, unsigned int protoff,
1107 memcpy(&rtp_addr, &maddr, sizeof(rtp_addr)); 1109 memcpy(&rtp_addr, &maddr, sizeof(rtp_addr));
1108 } else if (caddr_len) 1110 } else if (caddr_len)
1109 memcpy(&rtp_addr, &caddr, sizeof(rtp_addr)); 1111 memcpy(&rtp_addr, &caddr, sizeof(rtp_addr));
1110 else 1112 else {
1113 nf_ct_helper_log(skb, ct, "cannot parse SDP message");
1111 return NF_DROP; 1114 return NF_DROP;
1115 }
1112 1116
1113 ret = set_expected_rtp_rtcp(skb, protoff, dataoff, 1117 ret = set_expected_rtp_rtcp(skb, protoff, dataoff,
1114 dptr, datalen, 1118 dptr, datalen,
1115 &rtp_addr, htons(port), t->class, 1119 &rtp_addr, htons(port), t->class,
1116 mediaoff, medialen); 1120 mediaoff, medialen);
1117 if (ret != NF_ACCEPT) 1121 if (ret != NF_ACCEPT) {
1122 nf_ct_helper_log(skb, ct,
1123 "cannot add expectation for voice");
1118 return ret; 1124 return ret;
1125 }
1119 1126
1120 /* Update media connection address if present */ 1127 /* Update media connection address if present */
1121 if (maddr_len && nf_nat_sdp_addr && ct->status & IPS_NAT_MASK) { 1128 if (maddr_len && nf_nat_sdp_addr && ct->status & IPS_NAT_MASK) {
@@ -1123,8 +1130,10 @@ static int process_sdp(struct sk_buff *skb, unsigned int protoff,
1123 dptr, datalen, mediaoff, 1130 dptr, datalen, mediaoff,
1124 SDP_HDR_CONNECTION, SDP_HDR_MEDIA, 1131 SDP_HDR_CONNECTION, SDP_HDR_MEDIA,
1125 &rtp_addr); 1132 &rtp_addr);
1126 if (ret != NF_ACCEPT) 1133 if (ret != NF_ACCEPT) {
1134 nf_ct_helper_log(skb, ct, "cannot mangle SDP");
1127 return ret; 1135 return ret;
1136 }
1128 } 1137 }
1129 i++; 1138 i++;
1130 } 1139 }
@@ -1258,9 +1267,10 @@ static int process_register_request(struct sk_buff *skb, unsigned int protoff,
1258 ret = ct_sip_parse_header_uri(ct, *dptr, NULL, *datalen, 1267 ret = ct_sip_parse_header_uri(ct, *dptr, NULL, *datalen,
1259 SIP_HDR_CONTACT, NULL, 1268 SIP_HDR_CONTACT, NULL,
1260 &matchoff, &matchlen, &daddr, &port); 1269 &matchoff, &matchlen, &daddr, &port);
1261 if (ret < 0) 1270 if (ret < 0) {
1271 nf_ct_helper_log(skb, ct, "cannot parse contact");
1262 return NF_DROP; 1272 return NF_DROP;
1263 else if (ret == 0) 1273 } else if (ret == 0)
1264 return NF_ACCEPT; 1274 return NF_ACCEPT;
1265 1275
1266 /* We don't support third-party registrations */ 1276 /* We don't support third-party registrations */
@@ -1273,8 +1283,10 @@ static int process_register_request(struct sk_buff *skb, unsigned int protoff,
1273 1283
1274 if (ct_sip_parse_numerical_param(ct, *dptr, 1284 if (ct_sip_parse_numerical_param(ct, *dptr,
1275 matchoff + matchlen, *datalen, 1285 matchoff + matchlen, *datalen,
1276 "expires=", NULL, NULL, &expires) < 0) 1286 "expires=", NULL, NULL, &expires) < 0) {
1287 nf_ct_helper_log(skb, ct, "cannot parse expires");
1277 return NF_DROP; 1288 return NF_DROP;
1289 }
1278 1290
1279 if (expires == 0) { 1291 if (expires == 0) {
1280 ret = NF_ACCEPT; 1292 ret = NF_ACCEPT;
@@ -1282,8 +1294,10 @@ static int process_register_request(struct sk_buff *skb, unsigned int protoff,
1282 } 1294 }
1283 1295
1284 exp = nf_ct_expect_alloc(ct); 1296 exp = nf_ct_expect_alloc(ct);
1285 if (!exp) 1297 if (!exp) {
1298 nf_ct_helper_log(skb, ct, "cannot alloc expectation");
1286 return NF_DROP; 1299 return NF_DROP;
1300 }
1287 1301
1288 saddr = NULL; 1302 saddr = NULL;
1289 if (sip_direct_signalling) 1303 if (sip_direct_signalling)
@@ -1300,9 +1314,10 @@ static int process_register_request(struct sk_buff *skb, unsigned int protoff,
1300 ret = nf_nat_sip_expect(skb, protoff, dataoff, dptr, datalen, 1314 ret = nf_nat_sip_expect(skb, protoff, dataoff, dptr, datalen,
1301 exp, matchoff, matchlen); 1315 exp, matchoff, matchlen);
1302 else { 1316 else {
1303 if (nf_ct_expect_related(exp) != 0) 1317 if (nf_ct_expect_related(exp) != 0) {
1318 nf_ct_helper_log(skb, ct, "cannot add expectation");
1304 ret = NF_DROP; 1319 ret = NF_DROP;
1305 else 1320 } else
1306 ret = NF_ACCEPT; 1321 ret = NF_ACCEPT;
1307 } 1322 }
1308 nf_ct_expect_put(exp); 1323 nf_ct_expect_put(exp);
@@ -1356,9 +1371,10 @@ static int process_register_response(struct sk_buff *skb, unsigned int protoff,
1356 SIP_HDR_CONTACT, &in_contact, 1371 SIP_HDR_CONTACT, &in_contact,
1357 &matchoff, &matchlen, 1372 &matchoff, &matchlen,
1358 &addr, &port); 1373 &addr, &port);
1359 if (ret < 0) 1374 if (ret < 0) {
1375 nf_ct_helper_log(skb, ct, "cannot parse contact");
1360 return NF_DROP; 1376 return NF_DROP;
1361 else if (ret == 0) 1377 } else if (ret == 0)
1362 break; 1378 break;
1363 1379
1364 /* We don't support third-party registrations */ 1380 /* We don't support third-party registrations */
@@ -1373,8 +1389,10 @@ static int process_register_response(struct sk_buff *skb, unsigned int protoff,
1373 matchoff + matchlen, 1389 matchoff + matchlen,
1374 *datalen, "expires=", 1390 *datalen, "expires=",
1375 NULL, NULL, &c_expires); 1391 NULL, NULL, &c_expires);
1376 if (ret < 0) 1392 if (ret < 0) {
1393 nf_ct_helper_log(skb, ct, "cannot parse expires");
1377 return NF_DROP; 1394 return NF_DROP;
1395 }
1378 if (c_expires == 0) 1396 if (c_expires == 0)
1379 break; 1397 break;
1380 if (refresh_signalling_expectation(ct, &addr, proto, port, 1398 if (refresh_signalling_expectation(ct, &addr, proto, port,
@@ -1408,15 +1426,21 @@ static int process_sip_response(struct sk_buff *skb, unsigned int protoff,
1408 if (*datalen < strlen("SIP/2.0 200")) 1426 if (*datalen < strlen("SIP/2.0 200"))
1409 return NF_ACCEPT; 1427 return NF_ACCEPT;
1410 code = simple_strtoul(*dptr + strlen("SIP/2.0 "), NULL, 10); 1428 code = simple_strtoul(*dptr + strlen("SIP/2.0 "), NULL, 10);
1411 if (!code) 1429 if (!code) {
1430 nf_ct_helper_log(skb, ct, "cannot get code");
1412 return NF_DROP; 1431 return NF_DROP;
1432 }
1413 1433
1414 if (ct_sip_get_header(ct, *dptr, 0, *datalen, SIP_HDR_CSEQ, 1434 if (ct_sip_get_header(ct, *dptr, 0, *datalen, SIP_HDR_CSEQ,
1415 &matchoff, &matchlen) <= 0) 1435 &matchoff, &matchlen) <= 0) {
1436 nf_ct_helper_log(skb, ct, "cannot parse cseq");
1416 return NF_DROP; 1437 return NF_DROP;
1438 }
1417 cseq = simple_strtoul(*dptr + matchoff, NULL, 10); 1439 cseq = simple_strtoul(*dptr + matchoff, NULL, 10);
1418 if (!cseq) 1440 if (!cseq) {
1441 nf_ct_helper_log(skb, ct, "cannot get cseq");
1419 return NF_DROP; 1442 return NF_DROP;
1443 }
1420 matchend = matchoff + matchlen + 1; 1444 matchend = matchoff + matchlen + 1;
1421 1445
1422 for (i = 0; i < ARRAY_SIZE(sip_handlers); i++) { 1446 for (i = 0; i < ARRAY_SIZE(sip_handlers); i++) {
@@ -1471,11 +1495,15 @@ static int process_sip_request(struct sk_buff *skb, unsigned int protoff,
1471 continue; 1495 continue;
1472 1496
1473 if (ct_sip_get_header(ct, *dptr, 0, *datalen, SIP_HDR_CSEQ, 1497 if (ct_sip_get_header(ct, *dptr, 0, *datalen, SIP_HDR_CSEQ,
1474 &matchoff, &matchlen) <= 0) 1498 &matchoff, &matchlen) <= 0) {
1499 nf_ct_helper_log(skb, ct, "cannot parse cseq");
1475 return NF_DROP; 1500 return NF_DROP;
1501 }
1476 cseq = simple_strtoul(*dptr + matchoff, NULL, 10); 1502 cseq = simple_strtoul(*dptr + matchoff, NULL, 10);
1477 if (!cseq) 1503 if (!cseq) {
1504 nf_ct_helper_log(skb, ct, "cannot get cseq");
1478 return NF_DROP; 1505 return NF_DROP;
1506 }
1479 1507
1480 return handler->request(skb, protoff, dataoff, dptr, datalen, 1508 return handler->request(skb, protoff, dataoff, dptr, datalen,
1481 cseq); 1509 cseq);
@@ -1498,8 +1526,10 @@ static int process_sip_msg(struct sk_buff *skb, struct nf_conn *ct,
1498 if (ret == NF_ACCEPT && ct->status & IPS_NAT_MASK) { 1526 if (ret == NF_ACCEPT && ct->status & IPS_NAT_MASK) {
1499 nf_nat_sip = rcu_dereference(nf_nat_sip_hook); 1527 nf_nat_sip = rcu_dereference(nf_nat_sip_hook);
1500 if (nf_nat_sip && !nf_nat_sip(skb, protoff, dataoff, 1528 if (nf_nat_sip && !nf_nat_sip(skb, protoff, dataoff,
1501 dptr, datalen)) 1529 dptr, datalen)) {
1530 nf_ct_helper_log(skb, ct, "cannot NAT SIP message");
1502 ret = NF_DROP; 1531 ret = NF_DROP;
1532 }
1503 } 1533 }
1504 1534
1505 return ret; 1535 return ret;
@@ -1563,11 +1593,14 @@ static int sip_help_tcp(struct sk_buff *skb, unsigned int protoff,
1563 end += strlen("\r\n\r\n") + clen; 1593 end += strlen("\r\n\r\n") + clen;
1564 1594
1565 msglen = origlen = end - dptr; 1595 msglen = origlen = end - dptr;
1566 if (msglen > datalen) 1596 if (msglen > datalen) {
1597 nf_ct_helper_log(skb, ct, "incomplete/bad SIP message");
1567 return NF_DROP; 1598 return NF_DROP;
1599 }
1568 1600
1569 ret = process_sip_msg(skb, ct, protoff, dataoff, 1601 ret = process_sip_msg(skb, ct, protoff, dataoff,
1570 &dptr, &msglen); 1602 &dptr, &msglen);
1603 /* process_sip_* functions report why this packet is dropped */
1571 if (ret != NF_ACCEPT) 1604 if (ret != NF_ACCEPT)
1572 break; 1605 break;
1573 diff = msglen - origlen; 1606 diff = msglen - origlen;
diff --git a/net/netfilter/nf_conntrack_tftp.c b/net/netfilter/nf_conntrack_tftp.c
index 81fc61c05263..e9936c830208 100644
--- a/net/netfilter/nf_conntrack_tftp.c
+++ b/net/netfilter/nf_conntrack_tftp.c
@@ -60,8 +60,10 @@ static int tftp_help(struct sk_buff *skb,
60 nf_ct_dump_tuple(&ct->tuplehash[IP_CT_DIR_REPLY].tuple); 60 nf_ct_dump_tuple(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
61 61
62 exp = nf_ct_expect_alloc(ct); 62 exp = nf_ct_expect_alloc(ct);
63 if (exp == NULL) 63 if (exp == NULL) {
64 nf_ct_helper_log(skb, ct, "cannot alloc expectation");
64 return NF_DROP; 65 return NF_DROP;
66 }
65 tuple = &ct->tuplehash[IP_CT_DIR_REPLY].tuple; 67 tuple = &ct->tuplehash[IP_CT_DIR_REPLY].tuple;
66 nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, 68 nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT,
67 nf_ct_l3num(ct), 69 nf_ct_l3num(ct),
@@ -74,8 +76,10 @@ static int tftp_help(struct sk_buff *skb,
74 nf_nat_tftp = rcu_dereference(nf_nat_tftp_hook); 76 nf_nat_tftp = rcu_dereference(nf_nat_tftp_hook);
75 if (nf_nat_tftp && ct->status & IPS_NAT_MASK) 77 if (nf_nat_tftp && ct->status & IPS_NAT_MASK)
76 ret = nf_nat_tftp(skb, ctinfo, exp); 78 ret = nf_nat_tftp(skb, ctinfo, exp);
77 else if (nf_ct_expect_related(exp) != 0) 79 else if (nf_ct_expect_related(exp) != 0) {
80 nf_ct_helper_log(skb, ct, "cannot add expectation");
78 ret = NF_DROP; 81 ret = NF_DROP;
82 }
79 nf_ct_expect_put(exp); 83 nf_ct_expect_put(exp);
80 break; 84 break;
81 case TFTP_OPCODE_DATA: 85 case TFTP_OPCODE_DATA:
diff --git a/net/netfilter/nf_nat_amanda.c b/net/netfilter/nf_nat_amanda.c
index 42d337881171..3b67c9d11273 100644
--- a/net/netfilter/nf_nat_amanda.c
+++ b/net/netfilter/nf_nat_amanda.c
@@ -56,15 +56,19 @@ static unsigned int help(struct sk_buff *skb,
56 } 56 }
57 } 57 }
58 58
59 if (port == 0) 59 if (port == 0) {
60 nf_ct_helper_log(skb, exp->master, "all ports in use");
60 return NF_DROP; 61 return NF_DROP;
62 }
61 63
62 sprintf(buffer, "%u", port); 64 sprintf(buffer, "%u", port);
63 ret = nf_nat_mangle_udp_packet(skb, exp->master, ctinfo, 65 ret = nf_nat_mangle_udp_packet(skb, exp->master, ctinfo,
64 protoff, matchoff, matchlen, 66 protoff, matchoff, matchlen,
65 buffer, strlen(buffer)); 67 buffer, strlen(buffer));
66 if (ret != NF_ACCEPT) 68 if (ret != NF_ACCEPT) {
69 nf_ct_helper_log(skb, exp->master, "cannot mangle packet");
67 nf_ct_unexpect_related(exp); 70 nf_ct_unexpect_related(exp);
71 }
68 return ret; 72 return ret;
69} 73}
70 74
diff --git a/net/netfilter/nf_nat_ftp.c b/net/netfilter/nf_nat_ftp.c
index e839b97b2863..e84a578dbe35 100644
--- a/net/netfilter/nf_nat_ftp.c
+++ b/net/netfilter/nf_nat_ftp.c
@@ -96,8 +96,10 @@ static unsigned int nf_nat_ftp(struct sk_buff *skb,
96 } 96 }
97 } 97 }
98 98
99 if (port == 0) 99 if (port == 0) {
100 nf_ct_helper_log(skb, ct, "all ports in use");
100 return NF_DROP; 101 return NF_DROP;
102 }
101 103
102 buflen = nf_nat_ftp_fmt_cmd(ct, type, buffer, sizeof(buffer), 104 buflen = nf_nat_ftp_fmt_cmd(ct, type, buffer, sizeof(buffer),
103 &newaddr, port); 105 &newaddr, port);
@@ -113,6 +115,7 @@ static unsigned int nf_nat_ftp(struct sk_buff *skb,
113 return NF_ACCEPT; 115 return NF_ACCEPT;
114 116
115out: 117out:
118 nf_ct_helper_log(skb, ct, "cannot mangle packet");
116 nf_ct_unexpect_related(exp); 119 nf_ct_unexpect_related(exp);
117 return NF_DROP; 120 return NF_DROP;
118} 121}
diff --git a/net/netfilter/nf_nat_irc.c b/net/netfilter/nf_nat_irc.c
index 1fedee6e7fb6..f02b3605823e 100644
--- a/net/netfilter/nf_nat_irc.c
+++ b/net/netfilter/nf_nat_irc.c
@@ -56,14 +56,18 @@ static unsigned int help(struct sk_buff *skb,
56 } 56 }
57 } 57 }
58 58
59 if (port == 0) 59 if (port == 0) {
60 nf_ct_helper_log(skb, exp->master, "all ports in use");
60 return NF_DROP; 61 return NF_DROP;
62 }
61 63
62 ret = nf_nat_mangle_tcp_packet(skb, exp->master, ctinfo, 64 ret = nf_nat_mangle_tcp_packet(skb, exp->master, ctinfo,
63 protoff, matchoff, matchlen, buffer, 65 protoff, matchoff, matchlen, buffer,
64 strlen(buffer)); 66 strlen(buffer));
65 if (ret != NF_ACCEPT) 67 if (ret != NF_ACCEPT) {
68 nf_ct_helper_log(skb, exp->master, "cannot mangle packet");
66 nf_ct_unexpect_related(exp); 69 nf_ct_unexpect_related(exp);
70 }
67 return ret; 71 return ret;
68} 72}
69 73
diff --git a/net/netfilter/nf_nat_sip.c b/net/netfilter/nf_nat_sip.c
index 5951146e7688..96ccdf78a29f 100644
--- a/net/netfilter/nf_nat_sip.c
+++ b/net/netfilter/nf_nat_sip.c
@@ -159,8 +159,10 @@ static unsigned int nf_nat_sip(struct sk_buff *skb, unsigned int protoff,
159 &matchoff, &matchlen, 159 &matchoff, &matchlen,
160 &addr, &port) > 0 && 160 &addr, &port) > 0 &&
161 !map_addr(skb, protoff, dataoff, dptr, datalen, 161 !map_addr(skb, protoff, dataoff, dptr, datalen,
162 matchoff, matchlen, &addr, port)) 162 matchoff, matchlen, &addr, port)) {
163 nf_ct_helper_log(skb, ct, "cannot mangle SIP message");
163 return NF_DROP; 164 return NF_DROP;
165 }
164 request = 1; 166 request = 1;
165 } else 167 } else
166 request = 0; 168 request = 0;
@@ -193,8 +195,10 @@ static unsigned int nf_nat_sip(struct sk_buff *skb, unsigned int protoff,
193 195
194 olen = *datalen; 196 olen = *datalen;
195 if (!map_addr(skb, protoff, dataoff, dptr, datalen, 197 if (!map_addr(skb, protoff, dataoff, dptr, datalen,
196 matchoff, matchlen, &addr, port)) 198 matchoff, matchlen, &addr, port)) {
199 nf_ct_helper_log(skb, ct, "cannot mangle Via header");
197 return NF_DROP; 200 return NF_DROP;
201 }
198 202
199 matchend = matchoff + matchlen + *datalen - olen; 203 matchend = matchoff + matchlen + *datalen - olen;
200 204
@@ -209,8 +213,10 @@ static unsigned int nf_nat_sip(struct sk_buff *skb, unsigned int protoff,
209 &ct->tuplehash[!dir].tuple.dst.u3, 213 &ct->tuplehash[!dir].tuple.dst.u3,
210 true); 214 true);
211 if (!mangle_packet(skb, protoff, dataoff, dptr, datalen, 215 if (!mangle_packet(skb, protoff, dataoff, dptr, datalen,
212 poff, plen, buffer, buflen)) 216 poff, plen, buffer, buflen)) {
217 nf_ct_helper_log(skb, ct, "cannot mangle maddr");
213 return NF_DROP; 218 return NF_DROP;
219 }
214 } 220 }
215 221
216 /* The received= parameter (RFC 2361) contains the address 222 /* The received= parameter (RFC 2361) contains the address
@@ -225,6 +231,7 @@ static unsigned int nf_nat_sip(struct sk_buff *skb, unsigned int protoff,
225 false); 231 false);
226 if (!mangle_packet(skb, protoff, dataoff, dptr, datalen, 232 if (!mangle_packet(skb, protoff, dataoff, dptr, datalen,
227 poff, plen, buffer, buflen)) 233 poff, plen, buffer, buflen))
234 nf_ct_helper_log(skb, ct, "cannot mangle received");
228 return NF_DROP; 235 return NF_DROP;
229 } 236 }
230 237
@@ -238,8 +245,10 @@ static unsigned int nf_nat_sip(struct sk_buff *skb, unsigned int protoff,
238 __be16 p = ct->tuplehash[!dir].tuple.src.u.udp.port; 245 __be16 p = ct->tuplehash[!dir].tuple.src.u.udp.port;
239 buflen = sprintf(buffer, "%u", ntohs(p)); 246 buflen = sprintf(buffer, "%u", ntohs(p));
240 if (!mangle_packet(skb, protoff, dataoff, dptr, datalen, 247 if (!mangle_packet(skb, protoff, dataoff, dptr, datalen,
241 poff, plen, buffer, buflen)) 248 poff, plen, buffer, buflen)) {
249 nf_ct_helper_log(skb, ct, "cannot mangle rport");
242 return NF_DROP; 250 return NF_DROP;
251 }
243 } 252 }
244 } 253 }
245 254
@@ -253,27 +262,35 @@ next:
253 &addr, &port) > 0) { 262 &addr, &port) > 0) {
254 if (!map_addr(skb, protoff, dataoff, dptr, datalen, 263 if (!map_addr(skb, protoff, dataoff, dptr, datalen,
255 matchoff, matchlen, 264 matchoff, matchlen,
256 &addr, port)) 265 &addr, port)) {
266 nf_ct_helper_log(skb, ct, "cannot mangle contact");
257 return NF_DROP; 267 return NF_DROP;
268 }
258 } 269 }
259 270
260 if (!map_sip_addr(skb, protoff, dataoff, dptr, datalen, SIP_HDR_FROM) || 271 if (!map_sip_addr(skb, protoff, dataoff, dptr, datalen, SIP_HDR_FROM) ||
261 !map_sip_addr(skb, protoff, dataoff, dptr, datalen, SIP_HDR_TO)) 272 !map_sip_addr(skb, protoff, dataoff, dptr, datalen, SIP_HDR_TO)) {
273 nf_ct_helper_log(skb, ct, "cannot mangle SIP from/to");
262 return NF_DROP; 274 return NF_DROP;
275 }
263 276
264 /* Mangle destination port for Cisco phones, then fix up checksums */ 277 /* Mangle destination port for Cisco phones, then fix up checksums */
265 if (dir == IP_CT_DIR_REPLY && ct_sip_info->forced_dport) { 278 if (dir == IP_CT_DIR_REPLY && ct_sip_info->forced_dport) {
266 struct udphdr *uh; 279 struct udphdr *uh;
267 280
268 if (!skb_make_writable(skb, skb->len)) 281 if (!skb_make_writable(skb, skb->len)) {
282 nf_ct_helper_log(skb, ct, "cannot mangle packet");
269 return NF_DROP; 283 return NF_DROP;
284 }
270 285
271 uh = (void *)skb->data + protoff; 286 uh = (void *)skb->data + protoff;
272 uh->dest = ct_sip_info->forced_dport; 287 uh->dest = ct_sip_info->forced_dport;
273 288
274 if (!nf_nat_mangle_udp_packet(skb, ct, ctinfo, protoff, 289 if (!nf_nat_mangle_udp_packet(skb, ct, ctinfo, protoff,
275 0, 0, NULL, 0)) 290 0, 0, NULL, 0)) {
291 nf_ct_helper_log(skb, ct, "cannot mangle packet");
276 return NF_DROP; 292 return NF_DROP;
293 }
277 } 294 }
278 295
279 return NF_ACCEPT; 296 return NF_ACCEPT;
@@ -372,15 +389,19 @@ static unsigned int nf_nat_sip_expect(struct sk_buff *skb, unsigned int protoff,
372 } 389 }
373 } 390 }
374 391
375 if (port == 0) 392 if (port == 0) {
393 nf_ct_helper_log(skb, ct, "all ports in use for SIP");
376 return NF_DROP; 394 return NF_DROP;
395 }
377 396
378 if (!nf_inet_addr_cmp(&exp->tuple.dst.u3, &exp->saved_addr) || 397 if (!nf_inet_addr_cmp(&exp->tuple.dst.u3, &exp->saved_addr) ||
379 exp->tuple.dst.u.udp.port != exp->saved_proto.udp.port) { 398 exp->tuple.dst.u.udp.port != exp->saved_proto.udp.port) {
380 buflen = sip_sprintf_addr_port(ct, buffer, &newaddr, port); 399 buflen = sip_sprintf_addr_port(ct, buffer, &newaddr, port);
381 if (!mangle_packet(skb, protoff, dataoff, dptr, datalen, 400 if (!mangle_packet(skb, protoff, dataoff, dptr, datalen,
382 matchoff, matchlen, buffer, buflen)) 401 matchoff, matchlen, buffer, buflen)) {
402 nf_ct_helper_log(skb, ct, "cannot mangle packet");
383 goto err; 403 goto err;
404 }
384 } 405 }
385 return NF_ACCEPT; 406 return NF_ACCEPT;
386 407
@@ -573,14 +594,18 @@ static unsigned int nf_nat_sdp_media(struct sk_buff *skb, unsigned int protoff,
573 } 594 }
574 } 595 }
575 596
576 if (port == 0) 597 if (port == 0) {
598 nf_ct_helper_log(skb, ct, "all ports in use for SDP media");
577 goto err1; 599 goto err1;
600 }
578 601
579 /* Update media port. */ 602 /* Update media port. */
580 if (rtp_exp->tuple.dst.u.udp.port != rtp_exp->saved_proto.udp.port && 603 if (rtp_exp->tuple.dst.u.udp.port != rtp_exp->saved_proto.udp.port &&
581 !nf_nat_sdp_port(skb, protoff, dataoff, dptr, datalen, 604 !nf_nat_sdp_port(skb, protoff, dataoff, dptr, datalen,
582 mediaoff, medialen, port)) 605 mediaoff, medialen, port)) {
606 nf_ct_helper_log(skb, ct, "cannot mangle SDP message");
583 goto err2; 607 goto err2;
608 }
584 609
585 return NF_ACCEPT; 610 return NF_ACCEPT;
586 611
diff --git a/net/netfilter/nf_nat_tftp.c b/net/netfilter/nf_nat_tftp.c
index ccabbda71a3e..7f67e1d5310d 100644
--- a/net/netfilter/nf_nat_tftp.c
+++ b/net/netfilter/nf_nat_tftp.c
@@ -28,8 +28,10 @@ static unsigned int help(struct sk_buff *skb,
28 = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.udp.port; 28 = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.udp.port;
29 exp->dir = IP_CT_DIR_REPLY; 29 exp->dir = IP_CT_DIR_REPLY;
30 exp->expectfn = nf_nat_follow_master; 30 exp->expectfn = nf_nat_follow_master;
31 if (nf_ct_expect_related(exp) != 0) 31 if (nf_ct_expect_related(exp) != 0) {
32 nf_ct_helper_log(skb, exp->master, "cannot add expectation");
32 return NF_DROP; 33 return NF_DROP;
34 }
33 return NF_ACCEPT; 35 return NF_ACCEPT;
34} 36}
35 37
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
index 58a09b7c3f6d..d578ec251712 100644
--- a/net/netfilter/nfnetlink.c
+++ b/net/netfilter/nfnetlink.c
@@ -36,8 +36,10 @@ MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_NETFILTER);
36 36
37static char __initdata nfversion[] = "0.30"; 37static char __initdata nfversion[] = "0.30";
38 38
39static const struct nfnetlink_subsystem __rcu *subsys_table[NFNL_SUBSYS_COUNT]; 39static struct {
40static DEFINE_MUTEX(nfnl_mutex); 40 struct mutex mutex;
41 const struct nfnetlink_subsystem __rcu *subsys;
42} table[NFNL_SUBSYS_COUNT];
41 43
42static const int nfnl_group2type[NFNLGRP_MAX+1] = { 44static const int nfnl_group2type[NFNLGRP_MAX+1] = {
43 [NFNLGRP_CONNTRACK_NEW] = NFNL_SUBSYS_CTNETLINK, 45 [NFNLGRP_CONNTRACK_NEW] = NFNL_SUBSYS_CTNETLINK,
@@ -48,27 +50,32 @@ static const int nfnl_group2type[NFNLGRP_MAX+1] = {
48 [NFNLGRP_CONNTRACK_EXP_DESTROY] = NFNL_SUBSYS_CTNETLINK_EXP, 50 [NFNLGRP_CONNTRACK_EXP_DESTROY] = NFNL_SUBSYS_CTNETLINK_EXP,
49}; 51};
50 52
51void nfnl_lock(void) 53void nfnl_lock(__u8 subsys_id)
52{ 54{
53 mutex_lock(&nfnl_mutex); 55 mutex_lock(&table[subsys_id].mutex);
54} 56}
55EXPORT_SYMBOL_GPL(nfnl_lock); 57EXPORT_SYMBOL_GPL(nfnl_lock);
56 58
57void nfnl_unlock(void) 59void nfnl_unlock(__u8 subsys_id)
58{ 60{
59 mutex_unlock(&nfnl_mutex); 61 mutex_unlock(&table[subsys_id].mutex);
60} 62}
61EXPORT_SYMBOL_GPL(nfnl_unlock); 63EXPORT_SYMBOL_GPL(nfnl_unlock);
62 64
65static struct mutex *nfnl_get_lock(__u8 subsys_id)
66{
67 return &table[subsys_id].mutex;
68}
69
63int nfnetlink_subsys_register(const struct nfnetlink_subsystem *n) 70int nfnetlink_subsys_register(const struct nfnetlink_subsystem *n)
64{ 71{
65 nfnl_lock(); 72 nfnl_lock(n->subsys_id);
66 if (subsys_table[n->subsys_id]) { 73 if (table[n->subsys_id].subsys) {
67 nfnl_unlock(); 74 nfnl_unlock(n->subsys_id);
68 return -EBUSY; 75 return -EBUSY;
69 } 76 }
70 rcu_assign_pointer(subsys_table[n->subsys_id], n); 77 rcu_assign_pointer(table[n->subsys_id].subsys, n);
71 nfnl_unlock(); 78 nfnl_unlock(n->subsys_id);
72 79
73 return 0; 80 return 0;
74} 81}
@@ -76,9 +83,9 @@ EXPORT_SYMBOL_GPL(nfnetlink_subsys_register);
76 83
77int nfnetlink_subsys_unregister(const struct nfnetlink_subsystem *n) 84int nfnetlink_subsys_unregister(const struct nfnetlink_subsystem *n)
78{ 85{
79 nfnl_lock(); 86 nfnl_lock(n->subsys_id);
80 subsys_table[n->subsys_id] = NULL; 87 table[n->subsys_id].subsys = NULL;
81 nfnl_unlock(); 88 nfnl_unlock(n->subsys_id);
82 synchronize_rcu(); 89 synchronize_rcu();
83 return 0; 90 return 0;
84} 91}
@@ -91,7 +98,7 @@ static inline const struct nfnetlink_subsystem *nfnetlink_get_subsys(u_int16_t t
91 if (subsys_id >= NFNL_SUBSYS_COUNT) 98 if (subsys_id >= NFNL_SUBSYS_COUNT)
92 return NULL; 99 return NULL;
93 100
94 return rcu_dereference(subsys_table[subsys_id]); 101 return rcu_dereference(table[subsys_id].subsys);
95} 102}
96 103
97static inline const struct nfnl_callback * 104static inline const struct nfnl_callback *
@@ -175,6 +182,7 @@ replay:
175 struct nlattr *cda[ss->cb[cb_id].attr_count + 1]; 182 struct nlattr *cda[ss->cb[cb_id].attr_count + 1];
176 struct nlattr *attr = (void *)nlh + min_len; 183 struct nlattr *attr = (void *)nlh + min_len;
177 int attrlen = nlh->nlmsg_len - min_len; 184 int attrlen = nlh->nlmsg_len - min_len;
185 __u8 subsys_id = NFNL_SUBSYS_ID(type);
178 186
179 err = nla_parse(cda, ss->cb[cb_id].attr_count, 187 err = nla_parse(cda, ss->cb[cb_id].attr_count,
180 attr, attrlen, ss->cb[cb_id].policy); 188 attr, attrlen, ss->cb[cb_id].policy);
@@ -189,10 +197,9 @@ replay:
189 rcu_read_unlock(); 197 rcu_read_unlock();
190 } else { 198 } else {
191 rcu_read_unlock(); 199 rcu_read_unlock();
192 nfnl_lock(); 200 nfnl_lock(subsys_id);
193 if (rcu_dereference_protected( 201 if (rcu_dereference_protected(table[subsys_id].subsys,
194 subsys_table[NFNL_SUBSYS_ID(type)], 202 lockdep_is_held(nfnl_get_lock(subsys_id))) != ss ||
195 lockdep_is_held(&nfnl_mutex)) != ss ||
196 nfnetlink_find_client(type, ss) != nc) 203 nfnetlink_find_client(type, ss) != nc)
197 err = -EAGAIN; 204 err = -EAGAIN;
198 else if (nc->call) 205 else if (nc->call)
@@ -200,7 +207,7 @@ replay:
200 (const struct nlattr **)cda); 207 (const struct nlattr **)cda);
201 else 208 else
202 err = -EINVAL; 209 err = -EINVAL;
203 nfnl_unlock(); 210 nfnl_unlock(subsys_id);
204 } 211 }
205 if (err == -EAGAIN) 212 if (err == -EAGAIN)
206 goto replay; 213 goto replay;
@@ -267,6 +274,11 @@ static struct pernet_operations nfnetlink_net_ops = {
267 274
268static int __init nfnetlink_init(void) 275static int __init nfnetlink_init(void)
269{ 276{
277 int i;
278
279 for (i=0; i<NFNL_SUBSYS_COUNT; i++)
280 mutex_init(&table[i].mutex);
281
270 pr_info("Netfilter messages via NETLINK v%s.\n", nfversion); 282 pr_info("Netfilter messages via NETLINK v%s.\n", nfversion);
271 return register_pernet_subsys(&nfnetlink_net_ops); 283 return register_pernet_subsys(&nfnetlink_net_ops);
272} 284}
diff --git a/net/netfilter/xt_CT.c b/net/netfilter/xt_CT.c
index bde009ed8d3b..a60261cb0e80 100644
--- a/net/netfilter/xt_CT.c
+++ b/net/netfilter/xt_CT.c
@@ -20,12 +20,8 @@
20#include <net/netfilter/nf_conntrack_timeout.h> 20#include <net/netfilter/nf_conntrack_timeout.h>
21#include <net/netfilter/nf_conntrack_zones.h> 21#include <net/netfilter/nf_conntrack_zones.h>
22 22
23static unsigned int xt_ct_target_v0(struct sk_buff *skb, 23static inline int xt_ct_target(struct sk_buff *skb, struct nf_conn *ct)
24 const struct xt_action_param *par)
25{ 24{
26 const struct xt_ct_target_info *info = par->targinfo;
27 struct nf_conn *ct = info->ct;
28
29 /* Previously seen (loopback)? Ignore. */ 25 /* Previously seen (loopback)? Ignore. */
30 if (skb->nfct != NULL) 26 if (skb->nfct != NULL)
31 return XT_CONTINUE; 27 return XT_CONTINUE;
@@ -37,21 +33,22 @@ static unsigned int xt_ct_target_v0(struct sk_buff *skb,
37 return XT_CONTINUE; 33 return XT_CONTINUE;
38} 34}
39 35
40static unsigned int xt_ct_target_v1(struct sk_buff *skb, 36static unsigned int xt_ct_target_v0(struct sk_buff *skb,
41 const struct xt_action_param *par) 37 const struct xt_action_param *par)
42{ 38{
43 const struct xt_ct_target_info_v1 *info = par->targinfo; 39 const struct xt_ct_target_info *info = par->targinfo;
44 struct nf_conn *ct = info->ct; 40 struct nf_conn *ct = info->ct;
45 41
46 /* Previously seen (loopback)? Ignore. */ 42 return xt_ct_target(skb, ct);
47 if (skb->nfct != NULL) 43}
48 return XT_CONTINUE;
49 44
50 atomic_inc(&ct->ct_general.use); 45static unsigned int xt_ct_target_v1(struct sk_buff *skb,
51 skb->nfct = &ct->ct_general; 46 const struct xt_action_param *par)
52 skb->nfctinfo = IP_CT_NEW; 47{
48 const struct xt_ct_target_info_v1 *info = par->targinfo;
49 struct nf_conn *ct = info->ct;
53 50
54 return XT_CONTINUE; 51 return xt_ct_target(skb, ct);
55} 52}
56 53
57static u8 xt_ct_find_proto(const struct xt_tgchk_param *par) 54static u8 xt_ct_find_proto(const struct xt_tgchk_param *par)
@@ -104,67 +101,6 @@ xt_ct_set_helper(struct nf_conn *ct, const char *helper_name,
104 return 0; 101 return 0;
105} 102}
106 103
107static int xt_ct_tg_check_v0(const struct xt_tgchk_param *par)
108{
109 struct xt_ct_target_info *info = par->targinfo;
110 struct nf_conntrack_tuple t;
111 struct nf_conn *ct;
112 int ret = -EOPNOTSUPP;
113
114 if (info->flags & ~XT_CT_NOTRACK)
115 return -EINVAL;
116
117 if (info->flags & XT_CT_NOTRACK) {
118 ct = nf_ct_untracked_get();
119 atomic_inc(&ct->ct_general.use);
120 goto out;
121 }
122
123#ifndef CONFIG_NF_CONNTRACK_ZONES
124 if (info->zone)
125 goto err1;
126#endif
127
128 ret = nf_ct_l3proto_try_module_get(par->family);
129 if (ret < 0)
130 goto err1;
131
132 memset(&t, 0, sizeof(t));
133 ct = nf_conntrack_alloc(par->net, info->zone, &t, &t, GFP_KERNEL);
134 ret = PTR_ERR(ct);
135 if (IS_ERR(ct))
136 goto err2;
137
138 ret = 0;
139 if ((info->ct_events || info->exp_events) &&
140 !nf_ct_ecache_ext_add(ct, info->ct_events, info->exp_events,
141 GFP_KERNEL))
142 goto err3;
143
144 if (info->helper[0]) {
145 ret = xt_ct_set_helper(ct, info->helper, par);
146 if (ret < 0)
147 goto err3;
148 }
149
150 __set_bit(IPS_TEMPLATE_BIT, &ct->status);
151 __set_bit(IPS_CONFIRMED_BIT, &ct->status);
152
153 /* Overload tuple linked list to put us in template list. */
154 hlist_nulls_add_head_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode,
155 &par->net->ct.tmpl);
156out:
157 info->ct = ct;
158 return 0;
159
160err3:
161 nf_conntrack_free(ct);
162err2:
163 nf_ct_l3proto_module_put(par->family);
164err1:
165 return ret;
166}
167
168#ifdef CONFIG_NF_CONNTRACK_TIMEOUT 104#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
169static void __xt_ct_tg_timeout_put(struct ctnl_timeout *timeout) 105static void __xt_ct_tg_timeout_put(struct ctnl_timeout *timeout)
170{ 106{
@@ -242,16 +178,13 @@ out:
242#endif 178#endif
243} 179}
244 180
245static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par) 181static int xt_ct_tg_check(const struct xt_tgchk_param *par,
182 struct xt_ct_target_info_v1 *info)
246{ 183{
247 struct xt_ct_target_info_v1 *info = par->targinfo;
248 struct nf_conntrack_tuple t; 184 struct nf_conntrack_tuple t;
249 struct nf_conn *ct; 185 struct nf_conn *ct;
250 int ret = -EOPNOTSUPP; 186 int ret = -EOPNOTSUPP;
251 187
252 if (info->flags & ~XT_CT_NOTRACK)
253 return -EINVAL;
254
255 if (info->flags & XT_CT_NOTRACK) { 188 if (info->flags & XT_CT_NOTRACK) {
256 ct = nf_ct_untracked_get(); 189 ct = nf_ct_untracked_get();
257 atomic_inc(&ct->ct_general.use); 190 atomic_inc(&ct->ct_general.use);
@@ -309,20 +242,49 @@ err1:
309 return ret; 242 return ret;
310} 243}
311 244
312static void xt_ct_tg_destroy_v0(const struct xt_tgdtor_param *par) 245static int xt_ct_tg_check_v0(const struct xt_tgchk_param *par)
313{ 246{
314 struct xt_ct_target_info *info = par->targinfo; 247 struct xt_ct_target_info *info = par->targinfo;
315 struct nf_conn *ct = info->ct; 248 struct xt_ct_target_info_v1 info_v1 = {
316 struct nf_conn_help *help; 249 .flags = info->flags,
250 .zone = info->zone,
251 .ct_events = info->ct_events,
252 .exp_events = info->exp_events,
253 };
254 int ret;
317 255
318 if (!nf_ct_is_untracked(ct)) { 256 if (info->flags & ~XT_CT_NOTRACK)
319 help = nfct_help(ct); 257 return -EINVAL;
320 if (help)
321 module_put(help->helper->me);
322 258
323 nf_ct_l3proto_module_put(par->family); 259 memcpy(info_v1.helper, info->helper, sizeof(info->helper));
324 } 260
325 nf_ct_put(info->ct); 261 ret = xt_ct_tg_check(par, &info_v1);
262 if (ret < 0)
263 return ret;
264
265 info->ct = info_v1.ct;
266
267 return ret;
268}
269
270static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par)
271{
272 struct xt_ct_target_info_v1 *info = par->targinfo;
273
274 if (info->flags & ~XT_CT_NOTRACK)
275 return -EINVAL;
276
277 return xt_ct_tg_check(par, par->targinfo);
278}
279
280static int xt_ct_tg_check_v2(const struct xt_tgchk_param *par)
281{
282 struct xt_ct_target_info_v1 *info = par->targinfo;
283
284 if (info->flags & ~XT_CT_MASK)
285 return -EINVAL;
286
287 return xt_ct_tg_check(par, par->targinfo);
326} 288}
327 289
328static void xt_ct_destroy_timeout(struct nf_conn *ct) 290static void xt_ct_destroy_timeout(struct nf_conn *ct)
@@ -343,9 +305,9 @@ static void xt_ct_destroy_timeout(struct nf_conn *ct)
343#endif 305#endif
344} 306}
345 307
346static void xt_ct_tg_destroy_v1(const struct xt_tgdtor_param *par) 308static void xt_ct_tg_destroy(const struct xt_tgdtor_param *par,
309 struct xt_ct_target_info_v1 *info)
347{ 310{
348 struct xt_ct_target_info_v1 *info = par->targinfo;
349 struct nf_conn *ct = info->ct; 311 struct nf_conn *ct = info->ct;
350 struct nf_conn_help *help; 312 struct nf_conn_help *help;
351 313
@@ -361,6 +323,26 @@ static void xt_ct_tg_destroy_v1(const struct xt_tgdtor_param *par)
361 nf_ct_put(info->ct); 323 nf_ct_put(info->ct);
362} 324}
363 325
326static void xt_ct_tg_destroy_v0(const struct xt_tgdtor_param *par)
327{
328 struct xt_ct_target_info *info = par->targinfo;
329 struct xt_ct_target_info_v1 info_v1 = {
330 .flags = info->flags,
331 .zone = info->zone,
332 .ct_events = info->ct_events,
333 .exp_events = info->exp_events,
334 .ct = info->ct,
335 };
336 memcpy(info_v1.helper, info->helper, sizeof(info->helper));
337
338 xt_ct_tg_destroy(par, &info_v1);
339}
340
341static void xt_ct_tg_destroy_v1(const struct xt_tgdtor_param *par)
342{
343 xt_ct_tg_destroy(par, par->targinfo);
344}
345
364static struct xt_target xt_ct_tg_reg[] __read_mostly = { 346static struct xt_target xt_ct_tg_reg[] __read_mostly = {
365 { 347 {
366 .name = "CT", 348 .name = "CT",
@@ -383,6 +365,17 @@ static struct xt_target xt_ct_tg_reg[] __read_mostly = {
383 .table = "raw", 365 .table = "raw",
384 .me = THIS_MODULE, 366 .me = THIS_MODULE,
385 }, 367 },
368 {
369 .name = "CT",
370 .family = NFPROTO_UNSPEC,
371 .revision = 2,
372 .targetsize = sizeof(struct xt_ct_target_info_v1),
373 .checkentry = xt_ct_tg_check_v2,
374 .destroy = xt_ct_tg_destroy_v1,
375 .target = xt_ct_target_v1,
376 .table = "raw",
377 .me = THIS_MODULE,
378 },
386}; 379};
387 380
388static unsigned int 381static unsigned int