Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

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