aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGao feng <gaofeng@cn.fujitsu.com>2012-05-28 17:04:12 -0400
committerPablo Neira Ayuso <pablo@netfilter.org>2012-06-07 08:58:39 -0400
commitd2ba1fde42af44fbce361202e9af13daff9e4381 (patch)
treeff268b9e00824abbcbf2bd2234cd338c34045180
parent15f585bd76b6bd2974b23c9e69ff038a0826a0be (diff)
netfilter: nf_ct_tcp: add namespace support
This patch adds namespace support for TCP protocol tracker. Acked-by: Eric W. Biederman <ebiederm@xmission.com> Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--include/net/netns/conntrack.h10
-rw-r--r--net/netfilter/nf_conntrack_proto.c2
-rw-r--r--net/netfilter/nf_conntrack_proto_tcp.c162
3 files changed, 145 insertions, 29 deletions
diff --git a/include/net/netns/conntrack.h b/include/net/netns/conntrack.h
index 0ef8592d48bf..680d799ece8b 100644
--- a/include/net/netns/conntrack.h
+++ b/include/net/netns/conntrack.h
@@ -4,6 +4,7 @@
4#include <linux/list.h> 4#include <linux/list.h>
5#include <linux/list_nulls.h> 5#include <linux/list_nulls.h>
6#include <linux/atomic.h> 6#include <linux/atomic.h>
7#include <linux/netfilter/nf_conntrack_tcp.h>
7 8
8struct ctl_table_header; 9struct ctl_table_header;
9struct nf_conntrack_ecache; 10struct nf_conntrack_ecache;
@@ -25,8 +26,17 @@ struct nf_generic_net {
25 unsigned int timeout; 26 unsigned int timeout;
26}; 27};
27 28
29struct nf_tcp_net {
30 struct nf_proto_net pn;
31 unsigned int timeouts[TCP_CONNTRACK_TIMEOUT_MAX];
32 unsigned int tcp_loose;
33 unsigned int tcp_be_liberal;
34 unsigned int tcp_max_retrans;
35};
36
28struct nf_ip_net { 37struct nf_ip_net {
29 struct nf_generic_net generic; 38 struct nf_generic_net generic;
39 struct nf_tcp_net tcp;
30#if defined(CONFIG_SYSCTL) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT) 40#if defined(CONFIG_SYSCTL) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
31 struct ctl_table_header *ctl_table_header; 41 struct ctl_table_header *ctl_table_header;
32 struct ctl_table *ctl_table; 42 struct ctl_table *ctl_table;
diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c
index b095b4aefd7c..8a71e8bb0d6c 100644
--- a/net/netfilter/nf_conntrack_proto.c
+++ b/net/netfilter/nf_conntrack_proto.c
@@ -303,6 +303,8 @@ static struct nf_proto_net *nf_ct_l4proto_net(struct net *net,
303 struct nf_conntrack_l4proto *l4proto) 303 struct nf_conntrack_l4proto *l4proto)
304{ 304{
305 switch (l4proto->l4proto) { 305 switch (l4proto->l4proto) {
306 case IPPROTO_TCP:
307 return (struct nf_proto_net *)&net->ct.nf_ct_proto.tcp;
306 case 255: /* l4proto_generic */ 308 case 255: /* l4proto_generic */
307 return (struct nf_proto_net *)&net->ct.nf_ct_proto.generic; 309 return (struct nf_proto_net *)&net->ct.nf_ct_proto.generic;
308 default: 310 default:
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index 21ff1a99f534..a053f6786b3c 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -270,6 +270,11 @@ static const u8 tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = {
270 } 270 }
271}; 271};
272 272
273static inline struct nf_tcp_net *tcp_pernet(struct net *net)
274{
275 return &net->ct.nf_ct_proto.tcp;
276}
277
273static bool tcp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff, 278static bool tcp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,
274 struct nf_conntrack_tuple *tuple) 279 struct nf_conntrack_tuple *tuple)
275{ 280{
@@ -516,6 +521,7 @@ static bool tcp_in_window(const struct nf_conn *ct,
516 u_int8_t pf) 521 u_int8_t pf)
517{ 522{
518 struct net *net = nf_ct_net(ct); 523 struct net *net = nf_ct_net(ct);
524 struct nf_tcp_net *tn = tcp_pernet(net);
519 struct ip_ct_tcp_state *sender = &state->seen[dir]; 525 struct ip_ct_tcp_state *sender = &state->seen[dir];
520 struct ip_ct_tcp_state *receiver = &state->seen[!dir]; 526 struct ip_ct_tcp_state *receiver = &state->seen[!dir];
521 const struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple; 527 const struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple;
@@ -720,7 +726,7 @@ static bool tcp_in_window(const struct nf_conn *ct,
720 } else { 726 } else {
721 res = false; 727 res = false;
722 if (sender->flags & IP_CT_TCP_FLAG_BE_LIBERAL || 728 if (sender->flags & IP_CT_TCP_FLAG_BE_LIBERAL ||
723 nf_ct_tcp_be_liberal) 729 tn->tcp_be_liberal)
724 res = true; 730 res = true;
725 if (!res && LOG_INVALID(net, IPPROTO_TCP)) 731 if (!res && LOG_INVALID(net, IPPROTO_TCP))
726 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 732 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
@@ -828,6 +834,7 @@ static int tcp_packet(struct nf_conn *ct,
828 unsigned int *timeouts) 834 unsigned int *timeouts)
829{ 835{
830 struct net *net = nf_ct_net(ct); 836 struct net *net = nf_ct_net(ct);
837 struct nf_tcp_net *tn = tcp_pernet(net);
831 struct nf_conntrack_tuple *tuple; 838 struct nf_conntrack_tuple *tuple;
832 enum tcp_conntrack new_state, old_state; 839 enum tcp_conntrack new_state, old_state;
833 enum ip_conntrack_dir dir; 840 enum ip_conntrack_dir dir;
@@ -1020,7 +1027,7 @@ static int tcp_packet(struct nf_conn *ct,
1020 && new_state == TCP_CONNTRACK_FIN_WAIT) 1027 && new_state == TCP_CONNTRACK_FIN_WAIT)
1021 ct->proto.tcp.seen[dir].flags |= IP_CT_TCP_FLAG_CLOSE_INIT; 1028 ct->proto.tcp.seen[dir].flags |= IP_CT_TCP_FLAG_CLOSE_INIT;
1022 1029
1023 if (ct->proto.tcp.retrans >= nf_ct_tcp_max_retrans && 1030 if (ct->proto.tcp.retrans >= tn->tcp_max_retrans &&
1024 timeouts[new_state] > timeouts[TCP_CONNTRACK_RETRANS]) 1031 timeouts[new_state] > timeouts[TCP_CONNTRACK_RETRANS])
1025 timeout = timeouts[TCP_CONNTRACK_RETRANS]; 1032 timeout = timeouts[TCP_CONNTRACK_RETRANS];
1026 else if ((ct->proto.tcp.seen[0].flags | ct->proto.tcp.seen[1].flags) & 1033 else if ((ct->proto.tcp.seen[0].flags | ct->proto.tcp.seen[1].flags) &
@@ -1065,6 +1072,8 @@ static bool tcp_new(struct nf_conn *ct, const struct sk_buff *skb,
1065 enum tcp_conntrack new_state; 1072 enum tcp_conntrack new_state;
1066 const struct tcphdr *th; 1073 const struct tcphdr *th;
1067 struct tcphdr _tcph; 1074 struct tcphdr _tcph;
1075 struct net *net = nf_ct_net(ct);
1076 struct nf_tcp_net *tn = tcp_pernet(net);
1068 const struct ip_ct_tcp_state *sender = &ct->proto.tcp.seen[0]; 1077 const struct ip_ct_tcp_state *sender = &ct->proto.tcp.seen[0];
1069 const struct ip_ct_tcp_state *receiver = &ct->proto.tcp.seen[1]; 1078 const struct ip_ct_tcp_state *receiver = &ct->proto.tcp.seen[1];
1070 1079
@@ -1093,7 +1102,7 @@ static bool tcp_new(struct nf_conn *ct, const struct sk_buff *skb,
1093 ct->proto.tcp.seen[0].td_end; 1102 ct->proto.tcp.seen[0].td_end;
1094 1103
1095 tcp_options(skb, dataoff, th, &ct->proto.tcp.seen[0]); 1104 tcp_options(skb, dataoff, th, &ct->proto.tcp.seen[0]);
1096 } else if (nf_ct_tcp_loose == 0) { 1105 } else if (tn->tcp_loose == 0) {
1097 /* Don't try to pick up connections. */ 1106 /* Don't try to pick up connections. */
1098 return false; 1107 return false;
1099 } else { 1108 } else {
@@ -1360,91 +1369,78 @@ static struct ctl_table_header *tcp_sysctl_header;
1360static struct ctl_table tcp_sysctl_table[] = { 1369static struct ctl_table tcp_sysctl_table[] = {
1361 { 1370 {
1362 .procname = "nf_conntrack_tcp_timeout_syn_sent", 1371 .procname = "nf_conntrack_tcp_timeout_syn_sent",
1363 .data = &tcp_timeouts[TCP_CONNTRACK_SYN_SENT],
1364 .maxlen = sizeof(unsigned int), 1372 .maxlen = sizeof(unsigned int),
1365 .mode = 0644, 1373 .mode = 0644,
1366 .proc_handler = proc_dointvec_jiffies, 1374 .proc_handler = proc_dointvec_jiffies,
1367 }, 1375 },
1368 { 1376 {
1369 .procname = "nf_conntrack_tcp_timeout_syn_recv", 1377 .procname = "nf_conntrack_tcp_timeout_syn_recv",
1370 .data = &tcp_timeouts[TCP_CONNTRACK_SYN_RECV],
1371 .maxlen = sizeof(unsigned int), 1378 .maxlen = sizeof(unsigned int),
1372 .mode = 0644, 1379 .mode = 0644,
1373 .proc_handler = proc_dointvec_jiffies, 1380 .proc_handler = proc_dointvec_jiffies,
1374 }, 1381 },
1375 { 1382 {
1376 .procname = "nf_conntrack_tcp_timeout_established", 1383 .procname = "nf_conntrack_tcp_timeout_established",
1377 .data = &tcp_timeouts[TCP_CONNTRACK_ESTABLISHED],
1378 .maxlen = sizeof(unsigned int), 1384 .maxlen = sizeof(unsigned int),
1379 .mode = 0644, 1385 .mode = 0644,
1380 .proc_handler = proc_dointvec_jiffies, 1386 .proc_handler = proc_dointvec_jiffies,
1381 }, 1387 },
1382 { 1388 {
1383 .procname = "nf_conntrack_tcp_timeout_fin_wait", 1389 .procname = "nf_conntrack_tcp_timeout_fin_wait",
1384 .data = &tcp_timeouts[TCP_CONNTRACK_FIN_WAIT],
1385 .maxlen = sizeof(unsigned int), 1390 .maxlen = sizeof(unsigned int),
1386 .mode = 0644, 1391 .mode = 0644,
1387 .proc_handler = proc_dointvec_jiffies, 1392 .proc_handler = proc_dointvec_jiffies,
1388 }, 1393 },
1389 { 1394 {
1390 .procname = "nf_conntrack_tcp_timeout_close_wait", 1395 .procname = "nf_conntrack_tcp_timeout_close_wait",
1391 .data = &tcp_timeouts[TCP_CONNTRACK_CLOSE_WAIT],
1392 .maxlen = sizeof(unsigned int), 1396 .maxlen = sizeof(unsigned int),
1393 .mode = 0644, 1397 .mode = 0644,
1394 .proc_handler = proc_dointvec_jiffies, 1398 .proc_handler = proc_dointvec_jiffies,
1395 }, 1399 },
1396 { 1400 {
1397 .procname = "nf_conntrack_tcp_timeout_last_ack", 1401 .procname = "nf_conntrack_tcp_timeout_last_ack",
1398 .data = &tcp_timeouts[TCP_CONNTRACK_LAST_ACK],
1399 .maxlen = sizeof(unsigned int), 1402 .maxlen = sizeof(unsigned int),
1400 .mode = 0644, 1403 .mode = 0644,
1401 .proc_handler = proc_dointvec_jiffies, 1404 .proc_handler = proc_dointvec_jiffies,
1402 }, 1405 },
1403 { 1406 {
1404 .procname = "nf_conntrack_tcp_timeout_time_wait", 1407 .procname = "nf_conntrack_tcp_timeout_time_wait",
1405 .data = &tcp_timeouts[TCP_CONNTRACK_TIME_WAIT],
1406 .maxlen = sizeof(unsigned int), 1408 .maxlen = sizeof(unsigned int),
1407 .mode = 0644, 1409 .mode = 0644,
1408 .proc_handler = proc_dointvec_jiffies, 1410 .proc_handler = proc_dointvec_jiffies,
1409 }, 1411 },
1410 { 1412 {
1411 .procname = "nf_conntrack_tcp_timeout_close", 1413 .procname = "nf_conntrack_tcp_timeout_close",
1412 .data = &tcp_timeouts[TCP_CONNTRACK_CLOSE],
1413 .maxlen = sizeof(unsigned int), 1414 .maxlen = sizeof(unsigned int),
1414 .mode = 0644, 1415 .mode = 0644,
1415 .proc_handler = proc_dointvec_jiffies, 1416 .proc_handler = proc_dointvec_jiffies,
1416 }, 1417 },
1417 { 1418 {
1418 .procname = "nf_conntrack_tcp_timeout_max_retrans", 1419 .procname = "nf_conntrack_tcp_timeout_max_retrans",
1419 .data = &tcp_timeouts[TCP_CONNTRACK_RETRANS],
1420 .maxlen = sizeof(unsigned int), 1420 .maxlen = sizeof(unsigned int),
1421 .mode = 0644, 1421 .mode = 0644,
1422 .proc_handler = proc_dointvec_jiffies, 1422 .proc_handler = proc_dointvec_jiffies,
1423 }, 1423 },
1424 { 1424 {
1425 .procname = "nf_conntrack_tcp_timeout_unacknowledged", 1425 .procname = "nf_conntrack_tcp_timeout_unacknowledged",
1426 .data = &tcp_timeouts[TCP_CONNTRACK_UNACK],
1427 .maxlen = sizeof(unsigned int), 1426 .maxlen = sizeof(unsigned int),
1428 .mode = 0644, 1427 .mode = 0644,
1429 .proc_handler = proc_dointvec_jiffies, 1428 .proc_handler = proc_dointvec_jiffies,
1430 }, 1429 },
1431 { 1430 {
1432 .procname = "nf_conntrack_tcp_loose", 1431 .procname = "nf_conntrack_tcp_loose",
1433 .data = &nf_ct_tcp_loose,
1434 .maxlen = sizeof(unsigned int), 1432 .maxlen = sizeof(unsigned int),
1435 .mode = 0644, 1433 .mode = 0644,
1436 .proc_handler = proc_dointvec, 1434 .proc_handler = proc_dointvec,
1437 }, 1435 },
1438 { 1436 {
1439 .procname = "nf_conntrack_tcp_be_liberal", 1437 .procname = "nf_conntrack_tcp_be_liberal",
1440 .data = &nf_ct_tcp_be_liberal,
1441 .maxlen = sizeof(unsigned int), 1438 .maxlen = sizeof(unsigned int),
1442 .mode = 0644, 1439 .mode = 0644,
1443 .proc_handler = proc_dointvec, 1440 .proc_handler = proc_dointvec,
1444 }, 1441 },
1445 { 1442 {
1446 .procname = "nf_conntrack_tcp_max_retrans", 1443 .procname = "nf_conntrack_tcp_max_retrans",
1447 .data = &nf_ct_tcp_max_retrans,
1448 .maxlen = sizeof(unsigned int), 1444 .maxlen = sizeof(unsigned int),
1449 .mode = 0644, 1445 .mode = 0644,
1450 .proc_handler = proc_dointvec, 1446 .proc_handler = proc_dointvec,
@@ -1456,91 +1452,78 @@ static struct ctl_table tcp_sysctl_table[] = {
1456static struct ctl_table tcp_compat_sysctl_table[] = { 1452static struct ctl_table tcp_compat_sysctl_table[] = {
1457 { 1453 {
1458 .procname = "ip_conntrack_tcp_timeout_syn_sent", 1454 .procname = "ip_conntrack_tcp_timeout_syn_sent",
1459 .data = &tcp_timeouts[TCP_CONNTRACK_SYN_SENT],
1460 .maxlen = sizeof(unsigned int), 1455 .maxlen = sizeof(unsigned int),
1461 .mode = 0644, 1456 .mode = 0644,
1462 .proc_handler = proc_dointvec_jiffies, 1457 .proc_handler = proc_dointvec_jiffies,
1463 }, 1458 },
1464 { 1459 {
1465 .procname = "ip_conntrack_tcp_timeout_syn_sent2", 1460 .procname = "ip_conntrack_tcp_timeout_syn_sent2",
1466 .data = &tcp_timeouts[TCP_CONNTRACK_SYN_SENT2],
1467 .maxlen = sizeof(unsigned int), 1461 .maxlen = sizeof(unsigned int),
1468 .mode = 0644, 1462 .mode = 0644,
1469 .proc_handler = proc_dointvec_jiffies, 1463 .proc_handler = proc_dointvec_jiffies,
1470 }, 1464 },
1471 { 1465 {
1472 .procname = "ip_conntrack_tcp_timeout_syn_recv", 1466 .procname = "ip_conntrack_tcp_timeout_syn_recv",
1473 .data = &tcp_timeouts[TCP_CONNTRACK_SYN_RECV],
1474 .maxlen = sizeof(unsigned int), 1467 .maxlen = sizeof(unsigned int),
1475 .mode = 0644, 1468 .mode = 0644,
1476 .proc_handler = proc_dointvec_jiffies, 1469 .proc_handler = proc_dointvec_jiffies,
1477 }, 1470 },
1478 { 1471 {
1479 .procname = "ip_conntrack_tcp_timeout_established", 1472 .procname = "ip_conntrack_tcp_timeout_established",
1480 .data = &tcp_timeouts[TCP_CONNTRACK_ESTABLISHED],
1481 .maxlen = sizeof(unsigned int), 1473 .maxlen = sizeof(unsigned int),
1482 .mode = 0644, 1474 .mode = 0644,
1483 .proc_handler = proc_dointvec_jiffies, 1475 .proc_handler = proc_dointvec_jiffies,
1484 }, 1476 },
1485 { 1477 {
1486 .procname = "ip_conntrack_tcp_timeout_fin_wait", 1478 .procname = "ip_conntrack_tcp_timeout_fin_wait",
1487 .data = &tcp_timeouts[TCP_CONNTRACK_FIN_WAIT],
1488 .maxlen = sizeof(unsigned int), 1479 .maxlen = sizeof(unsigned int),
1489 .mode = 0644, 1480 .mode = 0644,
1490 .proc_handler = proc_dointvec_jiffies, 1481 .proc_handler = proc_dointvec_jiffies,
1491 }, 1482 },
1492 { 1483 {
1493 .procname = "ip_conntrack_tcp_timeout_close_wait", 1484 .procname = "ip_conntrack_tcp_timeout_close_wait",
1494 .data = &tcp_timeouts[TCP_CONNTRACK_CLOSE_WAIT],
1495 .maxlen = sizeof(unsigned int), 1485 .maxlen = sizeof(unsigned int),
1496 .mode = 0644, 1486 .mode = 0644,
1497 .proc_handler = proc_dointvec_jiffies, 1487 .proc_handler = proc_dointvec_jiffies,
1498 }, 1488 },
1499 { 1489 {
1500 .procname = "ip_conntrack_tcp_timeout_last_ack", 1490 .procname = "ip_conntrack_tcp_timeout_last_ack",
1501 .data = &tcp_timeouts[TCP_CONNTRACK_LAST_ACK],
1502 .maxlen = sizeof(unsigned int), 1491 .maxlen = sizeof(unsigned int),
1503 .mode = 0644, 1492 .mode = 0644,
1504 .proc_handler = proc_dointvec_jiffies, 1493 .proc_handler = proc_dointvec_jiffies,
1505 }, 1494 },
1506 { 1495 {
1507 .procname = "ip_conntrack_tcp_timeout_time_wait", 1496 .procname = "ip_conntrack_tcp_timeout_time_wait",
1508 .data = &tcp_timeouts[TCP_CONNTRACK_TIME_WAIT],
1509 .maxlen = sizeof(unsigned int), 1497 .maxlen = sizeof(unsigned int),
1510 .mode = 0644, 1498 .mode = 0644,
1511 .proc_handler = proc_dointvec_jiffies, 1499 .proc_handler = proc_dointvec_jiffies,
1512 }, 1500 },
1513 { 1501 {
1514 .procname = "ip_conntrack_tcp_timeout_close", 1502 .procname = "ip_conntrack_tcp_timeout_close",
1515 .data = &tcp_timeouts[TCP_CONNTRACK_CLOSE],
1516 .maxlen = sizeof(unsigned int), 1503 .maxlen = sizeof(unsigned int),
1517 .mode = 0644, 1504 .mode = 0644,
1518 .proc_handler = proc_dointvec_jiffies, 1505 .proc_handler = proc_dointvec_jiffies,
1519 }, 1506 },
1520 { 1507 {
1521 .procname = "ip_conntrack_tcp_timeout_max_retrans", 1508 .procname = "ip_conntrack_tcp_timeout_max_retrans",
1522 .data = &tcp_timeouts[TCP_CONNTRACK_RETRANS],
1523 .maxlen = sizeof(unsigned int), 1509 .maxlen = sizeof(unsigned int),
1524 .mode = 0644, 1510 .mode = 0644,
1525 .proc_handler = proc_dointvec_jiffies, 1511 .proc_handler = proc_dointvec_jiffies,
1526 }, 1512 },
1527 { 1513 {
1528 .procname = "ip_conntrack_tcp_loose", 1514 .procname = "ip_conntrack_tcp_loose",
1529 .data = &nf_ct_tcp_loose,
1530 .maxlen = sizeof(unsigned int), 1515 .maxlen = sizeof(unsigned int),
1531 .mode = 0644, 1516 .mode = 0644,
1532 .proc_handler = proc_dointvec, 1517 .proc_handler = proc_dointvec,
1533 }, 1518 },
1534 { 1519 {
1535 .procname = "ip_conntrack_tcp_be_liberal", 1520 .procname = "ip_conntrack_tcp_be_liberal",
1536 .data = &nf_ct_tcp_be_liberal,
1537 .maxlen = sizeof(unsigned int), 1521 .maxlen = sizeof(unsigned int),
1538 .mode = 0644, 1522 .mode = 0644,
1539 .proc_handler = proc_dointvec, 1523 .proc_handler = proc_dointvec,
1540 }, 1524 },
1541 { 1525 {
1542 .procname = "ip_conntrack_tcp_max_retrans", 1526 .procname = "ip_conntrack_tcp_max_retrans",
1543 .data = &nf_ct_tcp_max_retrans,
1544 .maxlen = sizeof(unsigned int), 1527 .maxlen = sizeof(unsigned int),
1545 .mode = 0644, 1528 .mode = 0644,
1546 .proc_handler = proc_dointvec, 1529 .proc_handler = proc_dointvec,
@@ -1550,6 +1533,125 @@ static struct ctl_table tcp_compat_sysctl_table[] = {
1550#endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */ 1533#endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
1551#endif /* CONFIG_SYSCTL */ 1534#endif /* CONFIG_SYSCTL */
1552 1535
1536static int tcp_kmemdup_sysctl_table(struct nf_proto_net *pn)
1537{
1538#ifdef CONFIG_SYSCTL
1539 struct nf_tcp_net *tn = (struct nf_tcp_net *)pn;
1540
1541 if (pn->ctl_table)
1542 return 0;
1543
1544 pn->ctl_table = kmemdup(tcp_sysctl_table,
1545 sizeof(tcp_sysctl_table),
1546 GFP_KERNEL);
1547 if (!pn->ctl_table)
1548 return -ENOMEM;
1549
1550 pn->ctl_table[0].data = &tn->timeouts[TCP_CONNTRACK_SYN_SENT];
1551 pn->ctl_table[1].data = &tn->timeouts[TCP_CONNTRACK_SYN_RECV];
1552 pn->ctl_table[2].data = &tn->timeouts[TCP_CONNTRACK_ESTABLISHED];
1553 pn->ctl_table[3].data = &tn->timeouts[TCP_CONNTRACK_FIN_WAIT];
1554 pn->ctl_table[4].data = &tn->timeouts[TCP_CONNTRACK_CLOSE_WAIT];
1555 pn->ctl_table[5].data = &tn->timeouts[TCP_CONNTRACK_LAST_ACK];
1556 pn->ctl_table[6].data = &tn->timeouts[TCP_CONNTRACK_TIME_WAIT];
1557 pn->ctl_table[7].data = &tn->timeouts[TCP_CONNTRACK_CLOSE];
1558 pn->ctl_table[8].data = &tn->timeouts[TCP_CONNTRACK_RETRANS];
1559 pn->ctl_table[9].data = &tn->timeouts[TCP_CONNTRACK_UNACK];
1560 pn->ctl_table[10].data = &tn->tcp_loose;
1561 pn->ctl_table[11].data = &tn->tcp_be_liberal;
1562 pn->ctl_table[12].data = &tn->tcp_max_retrans;
1563#endif
1564 return 0;
1565}
1566
1567static int tcp_kmemdup_compat_sysctl_table(struct nf_proto_net *pn)
1568{
1569#ifdef CONFIG_SYSCTL
1570#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
1571 struct nf_tcp_net *tn = (struct nf_tcp_net *)pn;
1572 pn->ctl_compat_table = kmemdup(tcp_compat_sysctl_table,
1573 sizeof(tcp_compat_sysctl_table),
1574 GFP_KERNEL);
1575 if (!pn->ctl_compat_table)
1576 return -ENOMEM;
1577
1578 pn->ctl_compat_table[0].data = &tn->timeouts[TCP_CONNTRACK_SYN_SENT];
1579 pn->ctl_compat_table[1].data = &tn->timeouts[TCP_CONNTRACK_SYN_SENT2];
1580 pn->ctl_compat_table[2].data = &tn->timeouts[TCP_CONNTRACK_SYN_RECV];
1581 pn->ctl_compat_table[3].data = &tn->timeouts[TCP_CONNTRACK_ESTABLISHED];
1582 pn->ctl_compat_table[4].data = &tn->timeouts[TCP_CONNTRACK_FIN_WAIT];
1583 pn->ctl_compat_table[5].data = &tn->timeouts[TCP_CONNTRACK_CLOSE_WAIT];
1584 pn->ctl_compat_table[6].data = &tn->timeouts[TCP_CONNTRACK_LAST_ACK];
1585 pn->ctl_compat_table[7].data = &tn->timeouts[TCP_CONNTRACK_TIME_WAIT];
1586 pn->ctl_compat_table[8].data = &tn->timeouts[TCP_CONNTRACK_CLOSE];
1587 pn->ctl_compat_table[9].data = &tn->timeouts[TCP_CONNTRACK_RETRANS];
1588 pn->ctl_compat_table[10].data = &tn->tcp_loose;
1589 pn->ctl_compat_table[11].data = &tn->tcp_be_liberal;
1590 pn->ctl_compat_table[12].data = &tn->tcp_max_retrans;
1591#endif
1592#endif
1593 return 0;
1594}
1595
1596static int tcpv4_init_net(struct net *net)
1597{
1598 int i;
1599 int ret = 0;
1600 struct nf_tcp_net *tn = tcp_pernet(net);
1601 struct nf_proto_net *pn = (struct nf_proto_net *)tn;
1602
1603#ifdef CONFIG_SYSCTL
1604 if (!pn->ctl_table) {
1605#else
1606 if (!pn->user++) {
1607#endif
1608 for (i = 0; i < TCP_CONNTRACK_TIMEOUT_MAX; i++)
1609 tn->timeouts[i] = tcp_timeouts[i];
1610
1611 tn->tcp_loose = nf_ct_tcp_loose;
1612 tn->tcp_be_liberal = nf_ct_tcp_be_liberal;
1613 tn->tcp_max_retrans = nf_ct_tcp_max_retrans;
1614 }
1615
1616 ret = tcp_kmemdup_compat_sysctl_table(pn);
1617
1618 if (ret < 0)
1619 return ret;
1620
1621 ret = tcp_kmemdup_sysctl_table(pn);
1622
1623#ifdef CONFIG_SYSCTL
1624#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
1625 if (ret < 0) {
1626 kfree(pn->ctl_compat_table);
1627 pn->ctl_compat_table = NULL;
1628 }
1629#endif
1630#endif
1631 return ret;
1632}
1633
1634static int tcpv6_init_net(struct net *net)
1635{
1636 int i;
1637 struct nf_tcp_net *tn = tcp_pernet(net);
1638 struct nf_proto_net *pn = (struct nf_proto_net *)tn;
1639
1640#ifdef CONFIG_SYSCTL
1641 if (!pn->ctl_table) {
1642#else
1643 if (!pn->user++) {
1644#endif
1645 for (i = 0; i < TCP_CONNTRACK_TIMEOUT_MAX; i++)
1646 tn->timeouts[i] = tcp_timeouts[i];
1647 tn->tcp_loose = nf_ct_tcp_loose;
1648 tn->tcp_be_liberal = nf_ct_tcp_be_liberal;
1649 tn->tcp_max_retrans = nf_ct_tcp_max_retrans;
1650 }
1651
1652 return tcp_kmemdup_sysctl_table(pn);
1653}
1654
1553struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4 __read_mostly = 1655struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4 __read_mostly =
1554{ 1656{
1555 .l3proto = PF_INET, 1657 .l3proto = PF_INET,
@@ -1590,6 +1692,7 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4 __read_mostly =
1590 .ctl_compat_table = tcp_compat_sysctl_table, 1692 .ctl_compat_table = tcp_compat_sysctl_table,
1591#endif 1693#endif
1592#endif 1694#endif
1695 .init_net = tcpv4_init_net,
1593}; 1696};
1594EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_tcp4); 1697EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_tcp4);
1595 1698
@@ -1630,5 +1733,6 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp6 __read_mostly =
1630 .ctl_table_header = &tcp_sysctl_header, 1733 .ctl_table_header = &tcp_sysctl_header,
1631 .ctl_table = tcp_sysctl_table, 1734 .ctl_table = tcp_sysctl_table,
1632#endif 1735#endif
1736 .init_net = tcpv6_init_net,
1633}; 1737};
1634EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_tcp6); 1738EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_tcp6);