aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2007-02-07 18:05:33 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2007-02-08 15:39:10 -0500
commita09113c2c8ec59a5cc228efa5869aade2b8f13f7 (patch)
treedf582dfa453cb8e1c6eb397062f60d69508c38fe /net
parent6fecd1985116fb08bdee3b9db6719e159fe5e43d (diff)
[NETFILTER]: tcp conntrack: do liberal tracking for picked up connections
Do liberal tracking (only RSTs need to be in-window) for connections picked up without seeing a SYN to deal with window scaling. Also change logging of invalid packets not to log packets accepted by liberal tracking to avoid spamming the logs. Based on suggestion from James Ralston <ralston@pobox.com> Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/netfilter/ip_conntrack_proto_tcp.c40
-rw-r--r--net/netfilter/nf_conntrack_proto_tcp.c40
2 files changed, 30 insertions, 50 deletions
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
index 06e4e8a6dd9..c34f48fe547 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
@@ -50,12 +50,9 @@ static DEFINE_RWLOCK(tcp_lock);
50 If it's non-zero, we mark only out of window RST segments as INVALID. */ 50 If it's non-zero, we mark only out of window RST segments as INVALID. */
51int ip_ct_tcp_be_liberal __read_mostly = 0; 51int ip_ct_tcp_be_liberal __read_mostly = 0;
52 52
53/* When connection is picked up from the middle, how many packets are required 53/* If it is set to zero, we disable picking up already established
54 to pass in each direction when we assume we are in sync - if any side uses
55 window scaling, we lost the game.
56 If it is set to zero, we disable picking up already established
57 connections. */ 54 connections. */
58int ip_ct_tcp_loose __read_mostly = 3; 55int ip_ct_tcp_loose __read_mostly = 1;
59 56
60/* Max number of the retransmitted packets without receiving an (acceptable) 57/* Max number of the retransmitted packets without receiving an (acceptable)
61 ACK from the destination. If this number is reached, a shorter timer 58 ACK from the destination. If this number is reached, a shorter timer
@@ -694,11 +691,10 @@ static int tcp_in_window(struct ip_ct_tcp *state,
694 before(sack, receiver->td_end + 1), 691 before(sack, receiver->td_end + 1),
695 after(ack, receiver->td_end - MAXACKWINDOW(sender))); 692 after(ack, receiver->td_end - MAXACKWINDOW(sender)));
696 693
697 if (sender->loose || receiver->loose || 694 if (before(seq, sender->td_maxend + 1) &&
698 (before(seq, sender->td_maxend + 1) && 695 after(end, sender->td_end - receiver->td_maxwin - 1) &&
699 after(end, sender->td_end - receiver->td_maxwin - 1) && 696 before(sack, receiver->td_end + 1) &&
700 before(sack, receiver->td_end + 1) && 697 after(ack, receiver->td_end - MAXACKWINDOW(sender))) {
701 after(ack, receiver->td_end - MAXACKWINDOW(sender)))) {
702 /* 698 /*
703 * Take into account window scaling (RFC 1323). 699 * Take into account window scaling (RFC 1323).
704 */ 700 */
@@ -743,15 +739,13 @@ static int tcp_in_window(struct ip_ct_tcp *state,
743 state->retrans = 0; 739 state->retrans = 0;
744 } 740 }
745 } 741 }
746 /*
747 * Close the window of disabled window tracking :-)
748 */
749 if (sender->loose)
750 sender->loose--;
751
752 res = 1; 742 res = 1;
753 } else { 743 } else {
754 if (LOG_INVALID(IPPROTO_TCP)) 744 res = 0;
745 if (sender->flags & IP_CT_TCP_FLAG_BE_LIBERAL ||
746 ip_ct_tcp_be_liberal)
747 res = 1;
748 if (!res && LOG_INVALID(IPPROTO_TCP))
755 nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, 749 nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
756 "ip_ct_tcp: %s ", 750 "ip_ct_tcp: %s ",
757 before(seq, sender->td_maxend + 1) ? 751 before(seq, sender->td_maxend + 1) ?
@@ -762,8 +756,6 @@ static int tcp_in_window(struct ip_ct_tcp *state,
762 : "ACK is over the upper bound (ACKed data not seen yet)" 756 : "ACK is over the upper bound (ACKed data not seen yet)"
763 : "SEQ is under the lower bound (already ACKed data retransmitted)" 757 : "SEQ is under the lower bound (already ACKed data retransmitted)"
764 : "SEQ is over the upper bound (over the window of the receiver)"); 758 : "SEQ is over the upper bound (over the window of the receiver)");
765
766 res = ip_ct_tcp_be_liberal;
767 } 759 }
768 760
769 DEBUGP("tcp_in_window: res=%i sender end=%u maxend=%u maxwin=%u " 761 DEBUGP("tcp_in_window: res=%i sender end=%u maxend=%u maxwin=%u "
@@ -1105,8 +1097,6 @@ static int tcp_new(struct ip_conntrack *conntrack,
1105 1097
1106 tcp_options(skb, iph, th, &conntrack->proto.tcp.seen[0]); 1098 tcp_options(skb, iph, th, &conntrack->proto.tcp.seen[0]);
1107 conntrack->proto.tcp.seen[1].flags = 0; 1099 conntrack->proto.tcp.seen[1].flags = 0;
1108 conntrack->proto.tcp.seen[0].loose =
1109 conntrack->proto.tcp.seen[1].loose = 0;
1110 } else if (ip_ct_tcp_loose == 0) { 1100 } else if (ip_ct_tcp_loose == 0) {
1111 /* Don't try to pick up connections. */ 1101 /* Don't try to pick up connections. */
1112 return 0; 1102 return 0;
@@ -1127,11 +1117,11 @@ static int tcp_new(struct ip_conntrack *conntrack,
1127 conntrack->proto.tcp.seen[0].td_maxwin; 1117 conntrack->proto.tcp.seen[0].td_maxwin;
1128 conntrack->proto.tcp.seen[0].td_scale = 0; 1118 conntrack->proto.tcp.seen[0].td_scale = 0;
1129 1119
1130 /* We assume SACK. Should we assume window scaling too? */ 1120 /* We assume SACK and liberal window checking to handle
1121 * window scaling */
1131 conntrack->proto.tcp.seen[0].flags = 1122 conntrack->proto.tcp.seen[0].flags =
1132 conntrack->proto.tcp.seen[1].flags = IP_CT_TCP_FLAG_SACK_PERM; 1123 conntrack->proto.tcp.seen[1].flags = IP_CT_TCP_FLAG_SACK_PERM |
1133 conntrack->proto.tcp.seen[0].loose = 1124 IP_CT_TCP_FLAG_BE_LIBERAL;
1134 conntrack->proto.tcp.seen[1].loose = ip_ct_tcp_loose;
1135 } 1125 }
1136 1126
1137 conntrack->proto.tcp.seen[1].td_end = 0; 1127 conntrack->proto.tcp.seen[1].td_end = 0;
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index 626b0011dd8..6fccdcf43e0 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -60,12 +60,9 @@ static DEFINE_RWLOCK(tcp_lock);
60 If it's non-zero, we mark only out of window RST segments as INVALID. */ 60 If it's non-zero, we mark only out of window RST segments as INVALID. */
61int nf_ct_tcp_be_liberal __read_mostly = 0; 61int nf_ct_tcp_be_liberal __read_mostly = 0;
62 62
63/* When connection is picked up from the middle, how many packets are required 63/* If it is set to zero, we disable picking up already established
64 to pass in each direction when we assume we are in sync - if any side uses
65 window scaling, we lost the game.
66 If it is set to zero, we disable picking up already established
67 connections. */ 64 connections. */
68int nf_ct_tcp_loose __read_mostly = 3; 65int nf_ct_tcp_loose __read_mostly = 1;
69 66
70/* Max number of the retransmitted packets without receiving an (acceptable) 67/* Max number of the retransmitted packets without receiving an (acceptable)
71 ACK from the destination. If this number is reached, a shorter timer 68 ACK from the destination. If this number is reached, a shorter timer
@@ -650,11 +647,10 @@ static int tcp_in_window(struct ip_ct_tcp *state,
650 before(sack, receiver->td_end + 1), 647 before(sack, receiver->td_end + 1),
651 after(ack, receiver->td_end - MAXACKWINDOW(sender))); 648 after(ack, receiver->td_end - MAXACKWINDOW(sender)));
652 649
653 if (sender->loose || receiver->loose || 650 if (before(seq, sender->td_maxend + 1) &&
654 (before(seq, sender->td_maxend + 1) && 651 after(end, sender->td_end - receiver->td_maxwin - 1) &&
655 after(end, sender->td_end - receiver->td_maxwin - 1) && 652 before(sack, receiver->td_end + 1) &&
656 before(sack, receiver->td_end + 1) && 653 after(ack, receiver->td_end - MAXACKWINDOW(sender))) {
657 after(ack, receiver->td_end - MAXACKWINDOW(sender)))) {
658 /* 654 /*
659 * Take into account window scaling (RFC 1323). 655 * Take into account window scaling (RFC 1323).
660 */ 656 */
@@ -699,15 +695,13 @@ static int tcp_in_window(struct ip_ct_tcp *state,
699 state->retrans = 0; 695 state->retrans = 0;
700 } 696 }
701 } 697 }
702 /*
703 * Close the window of disabled window tracking :-)
704 */
705 if (sender->loose)
706 sender->loose--;
707
708 res = 1; 698 res = 1;
709 } else { 699 } else {
710 if (LOG_INVALID(IPPROTO_TCP)) 700 res = 0;
701 if (sender->flags & IP_CT_TCP_FLAG_BE_LIBERAL ||
702 nf_ct_tcp_be_liberal)
703 res = 1;
704 if (!res && LOG_INVALID(IPPROTO_TCP))
711 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 705 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
712 "nf_ct_tcp: %s ", 706 "nf_ct_tcp: %s ",
713 before(seq, sender->td_maxend + 1) ? 707 before(seq, sender->td_maxend + 1) ?
@@ -718,8 +712,6 @@ static int tcp_in_window(struct ip_ct_tcp *state,
718 : "ACK is over the upper bound (ACKed data not seen yet)" 712 : "ACK is over the upper bound (ACKed data not seen yet)"
719 : "SEQ is under the lower bound (already ACKed data retransmitted)" 713 : "SEQ is under the lower bound (already ACKed data retransmitted)"
720 : "SEQ is over the upper bound (over the window of the receiver)"); 714 : "SEQ is over the upper bound (over the window of the receiver)");
721
722 res = nf_ct_tcp_be_liberal;
723 } 715 }
724 716
725 DEBUGP("tcp_in_window: res=%i sender end=%u maxend=%u maxwin=%u " 717 DEBUGP("tcp_in_window: res=%i sender end=%u maxend=%u maxwin=%u "
@@ -1063,8 +1055,6 @@ static int tcp_new(struct nf_conn *conntrack,
1063 1055
1064 tcp_options(skb, dataoff, th, &conntrack->proto.tcp.seen[0]); 1056 tcp_options(skb, dataoff, th, &conntrack->proto.tcp.seen[0]);
1065 conntrack->proto.tcp.seen[1].flags = 0; 1057 conntrack->proto.tcp.seen[1].flags = 0;
1066 conntrack->proto.tcp.seen[0].loose =
1067 conntrack->proto.tcp.seen[1].loose = 0;
1068 } else if (nf_ct_tcp_loose == 0) { 1058 } else if (nf_ct_tcp_loose == 0) {
1069 /* Don't try to pick up connections. */ 1059 /* Don't try to pick up connections. */
1070 return 0; 1060 return 0;
@@ -1085,11 +1075,11 @@ static int tcp_new(struct nf_conn *conntrack,
1085 conntrack->proto.tcp.seen[0].td_maxwin; 1075 conntrack->proto.tcp.seen[0].td_maxwin;
1086 conntrack->proto.tcp.seen[0].td_scale = 0; 1076 conntrack->proto.tcp.seen[0].td_scale = 0;
1087 1077
1088 /* We assume SACK. Should we assume window scaling too? */ 1078 /* We assume SACK and liberal window checking to handle
1079 * window scaling */
1089 conntrack->proto.tcp.seen[0].flags = 1080 conntrack->proto.tcp.seen[0].flags =
1090 conntrack->proto.tcp.seen[1].flags = IP_CT_TCP_FLAG_SACK_PERM; 1081 conntrack->proto.tcp.seen[1].flags = IP_CT_TCP_FLAG_SACK_PERM |
1091 conntrack->proto.tcp.seen[0].loose = 1082 IP_CT_TCP_FLAG_BE_LIBERAL;
1092 conntrack->proto.tcp.seen[1].loose = nf_ct_tcp_loose;
1093 } 1083 }
1094 1084
1095 conntrack->proto.tcp.seen[1].td_end = 0; 1085 conntrack->proto.tcp.seen[1].td_end = 0;