[netfilter-cvslog] r4073 - in trunk/patch-o-matic-ng/patchlets:
nf-log tcp-window-tracking
kadlec at netfilter.org
kadlec at netfilter.org
Tue Jun 28 12:12:55 CEST 2005
Author: kadlec at netfilter.org
Date: 2005-06-28 12:12:55 +0200 (Tue, 28 Jun 2005)
New Revision: 4073
Modified:
trunk/patch-o-matic-ng/patchlets/nf-log/linux-2.4.patch
trunk/patch-o-matic-ng/patchlets/tcp-window-tracking/linux-2.4.patch
Log:
nf-log patch updated to reflect changes in the 2.4 tree
TCP window tracking patch backported from the 2.6 tree
Modified: trunk/patch-o-matic-ng/patchlets/nf-log/linux-2.4.patch
===================================================================
--- trunk/patch-o-matic-ng/patchlets/nf-log/linux-2.4.patch 2005-06-28 09:37:27 UTC (rev 4072)
+++ trunk/patch-o-matic-ng/patchlets/nf-log/linux-2.4.patch 2005-06-28 10:12:55 UTC (rev 4073)
@@ -1,6 +1,6 @@
-diff -urN --exclude-from=diff.exclude linux-2.4.20-base/include/linux/netfilter_ipv4/ipt_ULOG.h linux-2.4.20-log/include/linux/netfilter_ipv4/ipt_ULOG.h
---- linux-2.4.20-base/include/linux/netfilter_ipv4/ipt_ULOG.h 2002-02-25 20:38:13.000000000 +0100
-+++ linux-2.4.20-log/include/linux/netfilter_ipv4/ipt_ULOG.h 2003-05-09 08:05:11.000000000 +0200
+diff -urN --exclude-from=/usr/src/diff.exclude linux-2.4.31-orig/include/linux/netfilter_ipv4/ipt_ULOG.h linux-2.4.31-nf-log/include/linux/netfilter_ipv4/ipt_ULOG.h
+--- linux-2.4.31-orig/include/linux/netfilter_ipv4/ipt_ULOG.h 2002-02-25 20:38:13.000000000 +0100
++++ linux-2.4.31-nf-log/include/linux/netfilter_ipv4/ipt_ULOG.h 2005-06-27 17:42:29.000000000 +0200
@@ -11,6 +11,9 @@
#define NETLINK_NFLOG 5
#endif
@@ -11,9 +11,9 @@
#define ULOG_MAC_LEN 80
#define ULOG_PREFIX_LEN 32
-diff -urN --exclude-from=diff.exclude linux-2.4.20-base/net/core/netfilter.c linux-2.4.20-log/net/core/netfilter.c
---- linux-2.4.20-base/net/core/netfilter.c 2002-08-03 02:39:46.000000000 +0200
-+++ linux-2.4.20-log/net/core/netfilter.c 2003-05-13 19:23:34.000000000 +0200
+diff -urN --exclude-from=/usr/src/diff.exclude linux-2.4.31-orig/net/core/netfilter.c linux-2.4.31-nf-log/net/core/netfilter.c
+--- linux-2.4.31-orig/net/core/netfilter.c 2005-01-19 15:10:13.000000000 +0100
++++ linux-2.4.31-nf-log/net/core/netfilter.c 2005-06-27 17:42:30.000000000 +0200
@@ -8,9 +8,12 @@
*
* February 2000: Modified by James Morris to have 1 queue per protocol.
@@ -27,7 +27,7 @@
#include <net/protocol.h>
#include <linux/init.h>
#include <linux/skbuff.h>
-@@ -624,6 +627,75 @@
+@@ -622,6 +625,75 @@
}
#endif /*CONFIG_INET*/
@@ -103,22 +103,25 @@
/* This does not belong here, but locally generated errors need it if connection
tracking in use: without this, connection may not be in hash table, and hence
manufactured ICMP or RST packets will not be associated with it. */
-diff -urN --exclude-from=diff.exclude linux-2.4.20-base/net/ipv4/netfilter/ipt_LOG.c linux-2.4.20-log/net/ipv4/netfilter/ipt_LOG.c
---- linux-2.4.20-base/net/ipv4/netfilter/ipt_LOG.c 2002-02-25 20:38:14.000000000 +0100
-+++ linux-2.4.20-log/net/ipv4/netfilter/ipt_LOG.c 2003-05-13 19:30:26.000000000 +0200
-@@ -12,6 +12,11 @@
+diff -urN --exclude-from=/usr/src/diff.exclude linux-2.4.31-orig/net/ipv4/netfilter/ipt_LOG.c linux-2.4.31-nf-log/net/ipv4/netfilter/ipt_LOG.c
+--- linux-2.4.31-orig/net/ipv4/netfilter/ipt_LOG.c 2005-04-04 03:42:20.000000000 +0200
++++ linux-2.4.31-nf-log/net/ipv4/netfilter/ipt_LOG.c 2005-06-28 11:43:48.000000000 +0200
+@@ -10,9 +10,14 @@
+ #include <net/tcp.h>
+ #include <net/route.h>
++#include <linux/netfilter_logging.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv4/ipt_LOG.h>
-+#include <linux/netfilter_ipv4/ip_logging.h>
-+
+
+static unsigned int nflog = 1;
+MODULE_PARM(nflog, "i");
+MODULE_PARM_DESC(nflog, "register as internal netfilter logging module");
-
++
#if 0
#define DEBUGP printk
-@@ -270,23 +275,21 @@
+ #else
+@@ -298,23 +303,21 @@
/* maxlen = 230+ 91 + 230 + 252 = 803 */
}
@@ -148,7 +151,7 @@
in ? in->name : "",
out ? out->name : "");
if (in && !out) {
-@@ -306,10 +309,59 @@
+@@ -334,10 +337,59 @@
dump_packet(loginfo, iph, (*pskb)->len, 1);
printk("\n");
spin_unlock_bh(&log_lock);
@@ -208,7 +211,7 @@
static int ipt_log_checkentry(const char *tablename,
const struct ipt_entry *e,
void *targinfo,
-@@ -341,17 +393,23 @@
+@@ -369,17 +421,23 @@
static struct ipt_target ipt_log_reg
= { { NULL, NULL }, "LOG", ipt_log_target, ipt_log_checkentry, NULL,
THIS_MODULE };
@@ -221,7 +224,7 @@
return -EINVAL;
-
+ if (nflog)
-+ nf_ip_log_register(&ip_logging_fn);
++ nf_log_register(PF_INET, &ip_logging_fn);
+
return 0;
}
@@ -229,22 +232,22 @@
static void __exit fini(void)
{
+ if (nflog)
-+ nf_ip_log_unregister(&ip_logging_fn);
++ nf_log_unregister(PF_INET, &ip_logging_fn);
ipt_unregister_target(&ipt_log_reg);
}
-diff -urN --exclude-from=diff.exclude linux-2.4.20-base/net/ipv4/netfilter/ipt_ULOG.c linux-2.4.20-log/net/ipv4/netfilter/ipt_ULOG.c
---- linux-2.4.20-base/net/ipv4/netfilter/ipt_ULOG.c 2003-03-24 17:22:51.000000000 +0100
-+++ linux-2.4.20-log/net/ipv4/netfilter/ipt_ULOG.c 2003-05-13 19:30:40.000000000 +0200
-@@ -48,6 +48,7 @@
+diff -urN --exclude-from=/usr/src/diff.exclude linux-2.4.31-orig/net/ipv4/netfilter/ipt_ULOG.c linux-2.4.31-nf-log/net/ipv4/netfilter/ipt_ULOG.c
+--- linux-2.4.31-orig/net/ipv4/netfilter/ipt_ULOG.c 2004-11-17 12:54:22.000000000 +0100
++++ linux-2.4.31-nf-log/net/ipv4/netfilter/ipt_ULOG.c 2005-06-28 11:43:59.000000000 +0200
+@@ -49,6 +49,7 @@
+ #include <linux/netdevice.h>
#include <linux/mm.h>
#include <linux/socket.h>
++#include <linux/netfilter_logging.h>
#include <linux/netfilter_ipv4/ip_tables.h>
-+#include <linux/netfilter_ipv4/ip_logging.h>
#include <linux/netfilter_ipv4/ipt_ULOG.h>
#include <linux/netfilter_ipv4/lockhelp.h>
- #include <net/sock.h>
-@@ -77,6 +78,10 @@
+@@ -79,6 +80,10 @@
MODULE_PARM(flushtimeout, "i");
MODULE_PARM_DESC(flushtimeout, "buffer flush timeout");
@@ -255,7 +258,7 @@
/* global data structures */
typedef struct {
-@@ -154,17 +159,17 @@
+@@ -155,17 +160,17 @@
return skb;
}
@@ -279,7 +282,7 @@
/* ffs == find first bit set, necessary because userspace
* is already shifting groupnumber, but we need unshifted.
-@@ -215,7 +220,9 @@
+@@ -216,7 +221,9 @@
pm->timestamp_usec = (*pskb)->stamp.tv_usec;
pm->mark = (*pskb)->nfmark;
pm->hook = hooknum;
@@ -290,7 +293,7 @@
strncpy(pm->prefix, loginfo->prefix, sizeof(pm->prefix));
else
*(pm->prefix) = '\0';
-@@ -262,8 +269,7 @@
+@@ -264,8 +271,7 @@
UNLOCK_BH(&ulog_lock);
@@ -300,7 +303,7 @@
nlmsg_failure:
PRINTR("ipt_ULOG: error during NLMSG_PUT\n");
-@@ -272,8 +278,128 @@
+@@ -274,8 +280,128 @@
PRINTR("ipt_ULOG: Error building netlink message\n");
UNLOCK_BH(&ulog_lock);
@@ -313,7 +316,8 @@
+ const void *targinfo, void *userinfo)
+{
+ struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) targinfo;
-+
+
+- return IPT_CONTINUE;
+ ipt_ulog_packet(pskb, hooknum, in, out, loginfo, NULL);
+
+ return IPT_CONTINUE;
@@ -421,8 +425,7 @@
+
+nlmsg_failure:
+ PRINTR("ipt_ULOG: error during NLMSG_PUT\n");
-
-- return IPT_CONTINUE;
++
+alloc_failure:
+ PRINTR("ipt_ULOG: Error building netlink message\n");
+
@@ -430,7 +433,7 @@
}
static int ipt_ulog_checkentry(const char *tablename,
-@@ -308,6 +434,8 @@
+@@ -310,6 +436,8 @@
{ {NULL, NULL}, "ULOG", ipt_ulog_target, ipt_ulog_checkentry, NULL,
THIS_MODULE
};
@@ -439,61 +442,38 @@
static int __init init(void)
{
-@@ -336,7 +464,9 @@
+@@ -337,7 +465,9 @@
sock_release(nflognl->socket);
return -EINVAL;
}
-
+ if (nflog)
-+ nf_ip_log_register(&ip_logging_fn);
++ nf_log_register(PF_INET, &ip_logging_fn);
+
return 0;
}
-@@ -347,6 +477,8 @@
+@@ -348,6 +478,8 @@
DEBUGP("ipt_ULOG: cleanup_module\n");
+ if (nflog)
-+ nf_ip_log_unregister(&ip_logging_fn);
++ nf_log_unregister(PF_INET, &ip_logging_fn);
ipt_unregister_target(&ipt_ulog_reg);
sock_release(nflognl->socket);
-diff -urN --exclude-from=diff.exclude linux-2.4.20-base/net/netsyms.c linux-2.4.20-log/net/netsyms.c
---- linux-2.4.20-base/net/netsyms.c 2003-05-09 17:34:23.000000000 +0200
-+++ linux-2.4.20-log/net/netsyms.c 2003-05-09 17:36:32.000000000 +0200
-@@ -572,6 +572,7 @@
- #endif
- #ifdef CONFIG_NETFILTER
- #include <linux/netfilter.h>
-+#include <linux/netfilter_logging.h>
- EXPORT_SYMBOL(nf_register_hook);
- EXPORT_SYMBOL(nf_unregister_hook);
- EXPORT_SYMBOL(nf_register_sockopt);
-@@ -584,6 +585,10 @@
- EXPORT_SYMBOL(nf_setsockopt);
- EXPORT_SYMBOL(nf_getsockopt);
- EXPORT_SYMBOL(ip_ct_attach);
- EXPORT_SYMBOL(nf_ct_attach);
-+EXPORT_SYMBOL(nf_log_register);
-+EXPORT_SYMBOL(nf_log_unregister);
-+EXPORT_SYMBOL(nf_log_packet);
-+EXPORT_SYMBOL(nf_log);
- #ifdef CONFIG_INET
- #include <linux/netfilter_ipv4.h>
- EXPORT_SYMBOL(ip_route_me_harder);
-diff -urN --exclude-from=diff.exclude linux-2.4.20-base/net/ipv6/netfilter/ip6t_LOG.c linux-2.4.20-log/net/ipv6/netfilter/ip6t_LOG.c
---- linux-2.4.20-base/net/ipv6/netfilter/ip6t_LOG.c 2002-11-29 00:53:15.000000000 +0100
-+++ linux-2.4.20-log/net/ipv6/netfilter/ip6t_LOG.c 2003-05-13 19:31:03.000000000 +0200
-@@ -10,6 +10,7 @@
+diff -urN --exclude-from=/usr/src/diff.exclude linux-2.4.31-orig/net/ipv6/netfilter/ip6t_LOG.c linux-2.4.31-nf-log/net/ipv6/netfilter/ip6t_LOG.c
+--- linux-2.4.31-orig/net/ipv6/netfilter/ip6t_LOG.c 2005-01-19 15:10:14.000000000 +0100
++++ linux-2.4.31-nf-log/net/ipv6/netfilter/ip6t_LOG.c 2005-06-28 11:51:21.000000000 +0200
+@@ -9,6 +9,7 @@
+ #include <net/udp.h>
#include <net/tcp.h>
#include <net/ipv6.h>
++#include <linux/netfilter_logging.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
-+#include <linux/netfilter_ipv6/ip6_logging.h>
MODULE_AUTHOR("Jan Rekorajski <baggins at pld.org.pl>");
- MODULE_DESCRIPTION("IP6 tables LOG target module");
-@@ -266,23 +267,21 @@
+@@ -355,23 +356,21 @@
}
}
@@ -523,8 +503,8 @@
in ? in->name : "",
out ? out->name : "");
if (in && !out) {
-@@ -329,10 +328,59 @@
- dump_packet(loginfo, ipv6h, 1);
+@@ -419,10 +418,41 @@
+ 1);
printk("\n");
spin_unlock_bh(&log_lock);
+}
@@ -562,46 +542,28 @@
+ ip6t_log_packet(pskb, hooknum, in, out, &loginfo, KERN_WARNING, prefix);
+}
+
-+static void
-+ip6_log_fn(char *pfh, size_t len,
-+ const char *prefix)
-+{
-+ struct ipv6hdr *ipv6h = (struct ipv6hdr *)pfh;
-+ struct ip6t_log_info loginfo = {
-+ .level = 0,
-+ .logflags = IP6T_LOG_MASK,
-+ .prefix = ""
-+ };
-+
-+ spin_lock_bh(&log_lock);
-+ printk(KERN_WARNING "%s", prefix);
-+ dump_packet(&loginfo, ipv6h, 1);
-+ printk("\n");
-+ spin_unlock_bh(&log_lock);
-+}
-+
static int ip6t_log_checkentry(const char *tablename,
const struct ip6t_entry *e,
void *targinfo,
-@@ -364,17 +412,21 @@
+@@ -454,17 +484,21 @@
static struct ip6t_target ip6t_log_reg
= { { NULL, NULL }, "LOG", ip6t_log_target, ip6t_log_checkentry, NULL,
THIS_MODULE };
+static struct nf_logging_t ip6_logging_fn
-+= { ip6_log_packet_fn, ip6_log_fn };
++= { ip6_log_packet_fn };
static int __init init(void)
{
if (ip6t_register_target(&ip6t_log_reg))
return -EINVAL;
-+ nf_ip6_log_register(&ip6_logging_fn);
++ nf_log_register(PF_INET6, &ip6_logging_fn);
return 0;
}
static void __exit fini(void)
{
-+ nf_ip6_log_unregister(&ip6_logging_fn);
++ nf_log_unregister(PF_INET6, &ip6_logging_fn);
ip6t_unregister_target(&ip6t_log_reg);
}
Modified: trunk/patch-o-matic-ng/patchlets/tcp-window-tracking/linux-2.4.patch
===================================================================
--- trunk/patch-o-matic-ng/patchlets/tcp-window-tracking/linux-2.4.patch 2005-06-28 09:37:27 UTC (rev 4072)
+++ trunk/patch-o-matic-ng/patchlets/tcp-window-tracking/linux-2.4.patch 2005-06-28 10:12:55 UTC (rev 4073)
@@ -1,22 +1,22 @@
-diff -urN --exclude-from=/usr/src/diff.exclude linux-2.4.23-pending/include/linux/netfilter_ipv4/ip_conntrack.h linux-2.4.23-tcp-win/include/linux/netfilter_ipv4/ip_conntrack.h
---- linux-2.4.23-pending/include/linux/netfilter_ipv4/ip_conntrack.h 2003-12-04 17:02:36.000000000 +0100
-+++ linux-2.4.23-tcp-win/include/linux/netfilter_ipv4/ip_conntrack.h 2004-05-19 15:49:51.000000000 +0200
-@@ -256,6 +256,11 @@
+diff -urN --exclude-from=/usr/src/diff.exclude linux-2.4.31-nf-log/include/linux/netfilter_ipv4/ip_conntrack.h linux-2.4.31-tcp-win/include/linux/netfilter_ipv4/ip_conntrack.h
+--- linux-2.4.31-nf-log/include/linux/netfilter_ipv4/ip_conntrack.h 2005-04-04 03:42:20.000000000 +0200
++++ linux-2.4.31-tcp-win/include/linux/netfilter_ipv4/ip_conntrack.h 2005-06-28 11:00:54.000000000 +0200
+@@ -246,6 +246,11 @@
unsigned long extra_jiffies);
/* These are for NAT. Icky. */
-+/* Update TCP window tracking data when NAT mangles the packet */
-+extern void ip_conntrack_tcp_update(struct sk_buff *skb,
-+ struct ip_conntrack *conntrack,
-+ int dir);
++/* Update TCP window tracking data after NAT successfully mangled the packet */
++extern int ip_conntrack_tcp_update(struct sk_buff *skb,
++ struct ip_conntrack *conntrack,
++ int dir);
+
/* Call me when a conntrack is destroyed. */
extern void (*ip_conntrack_destroyed)(struct ip_conntrack *conntrack);
-diff -urN --exclude-from=/usr/src/diff.exclude linux-2.4.23-pending/include/linux/netfilter_ipv4/ip_conntrack_tcp.h linux-2.4.23-tcp-win/include/linux/netfilter_ipv4/ip_conntrack_tcp.h
---- linux-2.4.23-pending/include/linux/netfilter_ipv4/ip_conntrack_tcp.h 2002-11-29 00:53:15.000000000 +0100
-+++ linux-2.4.23-tcp-win/include/linux/netfilter_ipv4/ip_conntrack_tcp.h 2004-05-19 14:56:42.000000000 +0200
-@@ -4,25 +4,44 @@
+diff -urN --exclude-from=/usr/src/diff.exclude linux-2.4.31-nf-log/include/linux/netfilter_ipv4/ip_conntrack_tcp.h linux-2.4.31-tcp-win/include/linux/netfilter_ipv4/ip_conntrack_tcp.h
+--- linux-2.4.31-nf-log/include/linux/netfilter_ipv4/ip_conntrack_tcp.h 2002-11-29 00:53:15.000000000 +0100
++++ linux-2.4.31-tcp-win/include/linux/netfilter_ipv4/ip_conntrack_tcp.h 2005-06-27 15:32:43.000000000 +0200
+@@ -4,25 +4,47 @@
enum tcp_conntrack {
TCP_CONNTRACK_NONE,
@@ -38,18 +38,21 @@
+};
+
+/* Window scaling is advertised by the sender */
-+#define IP_CT_TCP_STATE_FLAG_WINDOW_SCALE 0x01
++#define IP_CT_TCP_FLAG_WINDOW_SCALE 0x01
+
+/* SACK is permitted by the sender */
+#define IP_CT_TCP_FLAG_SACK_PERM 0x02
+
++/* This sender sent FIN first */
++#define IP_CT_TCP_FLAG_CLOSE_INIT 0x03
++
+struct ip_ct_tcp_state {
+ u_int32_t td_end; /* max of seq + len */
+ u_int32_t td_maxend; /* max of ack + max(win, 1) */
+ u_int32_t td_maxwin; /* max(win) */
+ u_int8_t td_scale; /* window scale factor */
+ u_int8_t loose; /* used when connection picked up from the middle */
-+ u_int8_t flags; /* per direction state flags */
++ u_int8_t flags; /* per direction options */
};
struct ip_ct_tcp
@@ -64,31 +67,31 @@
+ /* For detecting stale connections */
+ u_int8_t last_dir; /* Direction of the last packet (enum ip_conntrack_dir) */
+ u_int8_t retrans; /* Number of retransmitted packets */
-+ u_int8_t stored_seq; /* What is stored in last_seq */
++ u_int8_t last_index; /* Index of the last packet */
+ u_int32_t last_seq; /* Last sequence number seen in dir */
+ u_int32_t last_end; /* Last seq + len */
};
#endif /* _IP_CONNTRACK_TCP_H */
-diff -urN --exclude-from=/usr/src/diff.exclude linux-2.4.23-pending/include/linux/sysctl.h linux-2.4.23-tcp-win/include/linux/sysctl.h
---- linux-2.4.23-pending/include/linux/sysctl.h 2003-12-04 16:45:18.000000000 +0100
-+++ linux-2.4.23-tcp-win/include/linux/sysctl.h 2003-12-09 09:42:57.000000000 +0100
-@@ -377,6 +377,11 @@
+diff -urN --exclude-from=/usr/src/diff.exclude linux-2.4.31-nf-log/include/linux/sysctl.h linux-2.4.31-tcp-win/include/linux/sysctl.h
+--- linux-2.4.31-nf-log/include/linux/sysctl.h 2005-04-04 03:42:20.000000000 +0200
++++ linux-2.4.31-tcp-win/include/linux/sysctl.h 2005-06-28 10:56:32.000000000 +0200
+@@ -396,6 +396,11 @@
NET_IPV4_NF_CONNTRACK_ICMP_TIMEOUT=12,
NET_IPV4_NF_CONNTRACK_GENERIC_TIMEOUT=13,
NET_IPV4_NF_CONNTRACK_BUCKETS=14,
-+ NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS=15,
-+ NET_IPV4_NF_CONNTRACK_TCP_LOG_INVALID=16,
-+ NET_IPV4_NF_CONNTRACK_TCP_LOOSE=17,
-+ NET_IPV4_NF_CONNTRACK_TCP_BE_LIBERAL=18,
-+ NET_IPV4_NF_CONNTRACK_TCP_MAX_RETRANS=19,
++ NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS=15,
++ NET_IPV4_NF_CONNTRACK_TCP_LOG_INVALID=16,
++ NET_IPV4_NF_CONNTRACK_TCP_LOOSE=17,
++ NET_IPV4_NF_CONNTRACK_TCP_BE_LIBERAL=18,
++ NET_IPV4_NF_CONNTRACK_TCP_MAX_RETRANS=19,
};
/* /proc/sys/net/ipv6 */
-diff -urN --exclude-from=/usr/src/diff.exclude linux-2.4.23-pending/net/ipv4/netfilter/ip_conntrack_core.c linux-2.4.23-tcp-win/net/ipv4/netfilter/ip_conntrack_core.c
---- linux-2.4.23-pending/net/ipv4/netfilter/ip_conntrack_core.c 2003-12-04 16:56:14.000000000 +0100
-+++ linux-2.4.23-tcp-win/net/ipv4/netfilter/ip_conntrack_core.c 2003-12-09 09:30:21.000000000 +0100
-@@ -864,11 +864,12 @@
+diff -urN --exclude-from=/usr/src/diff.exclude linux-2.4.31-nf-log/net/ipv4/netfilter/ip_conntrack_core.c linux-2.4.31-tcp-win/net/ipv4/netfilter/ip_conntrack_core.c
+--- linux-2.4.31-nf-log/net/ipv4/netfilter/ip_conntrack_core.c 2005-04-04 03:42:20.000000000 +0200
++++ linux-2.4.31-tcp-win/net/ipv4/netfilter/ip_conntrack_core.c 2005-06-27 17:29:09.000000000 +0200
+@@ -874,11 +874,12 @@
IP_NF_ASSERT((*pskb)->nfct);
ret = proto->packet(ct, (*pskb)->nh.iph, (*pskb)->len, ctinfo);
@@ -104,9 +107,9 @@
}
if (ret != NF_DROP && ct->helper) {
-diff -urN --exclude-from=/usr/src/diff.exclude linux-2.4.23-pending/net/ipv4/netfilter/ip_conntrack_ftp.c linux-2.4.23-tcp-win/net/ipv4/netfilter/ip_conntrack_ftp.c
---- linux-2.4.23-pending/net/ipv4/netfilter/ip_conntrack_ftp.c 2003-08-25 13:44:44.000000000 +0200
-+++ linux-2.4.23-tcp-win/net/ipv4/netfilter/ip_conntrack_ftp.c 2003-12-09 09:30:21.000000000 +0100
+diff -urN --exclude-from=/usr/src/diff.exclude linux-2.4.31-nf-log/net/ipv4/netfilter/ip_conntrack_ftp.c linux-2.4.31-tcp-win/net/ipv4/netfilter/ip_conntrack_ftp.c
+--- linux-2.4.31-nf-log/net/ipv4/netfilter/ip_conntrack_ftp.c 2004-11-17 12:54:22.000000000 +0100
++++ linux-2.4.31-tcp-win/net/ipv4/netfilter/ip_conntrack_ftp.c 2005-06-27 17:31:07.000000000 +0200
@@ -4,7 +4,6 @@
#include <linux/netfilter.h>
#include <linux/ip.h>
@@ -152,9 +155,9 @@
LOCK_BH(&ip_ftp_lock);
old_seq_aft_nl_set = ct_ftp_info->seq_aft_nl_set[dir];
old_seq_aft_nl = ct_ftp_info->seq_aft_nl[dir];
-diff -urN --exclude-from=/usr/src/diff.exclude linux-2.4.23-pending/net/ipv4/netfilter/ip_conntrack_irc.c linux-2.4.23-tcp-win/net/ipv4/netfilter/ip_conntrack_irc.c
---- linux-2.4.23-pending/net/ipv4/netfilter/ip_conntrack_irc.c 2003-11-28 19:26:21.000000000 +0100
-+++ linux-2.4.23-tcp-win/net/ipv4/netfilter/ip_conntrack_irc.c 2003-12-09 09:30:21.000000000 +0100
+diff -urN --exclude-from=/usr/src/diff.exclude linux-2.4.31-nf-log/net/ipv4/netfilter/ip_conntrack_irc.c linux-2.4.31-tcp-win/net/ipv4/netfilter/ip_conntrack_irc.c
+--- linux-2.4.31-nf-log/net/ipv4/netfilter/ip_conntrack_irc.c 2004-11-17 12:54:22.000000000 +0100
++++ linux-2.4.31-tcp-win/net/ipv4/netfilter/ip_conntrack_irc.c 2005-06-27 17:32:26.000000000 +0200
@@ -26,7 +26,6 @@
#include <linux/module.h>
#include <linux/netfilter.h>
@@ -162,8 +165,8 @@
-#include <net/checksum.h>
#include <net/tcp.h>
- #include <linux/netfilter_ipv4/lockhelp.h>
-@@ -109,13 +108,12 @@
+ #include <linux/netfilter_ipv4/ip_conntrack_helper.h>
+@@ -107,13 +106,12 @@
static int help(const struct iphdr *iph, size_t len,
struct ip_conntrack *ct, enum ip_conntrack_info ctinfo)
{
@@ -179,7 +182,7 @@
int dir = CTINFO2DIR(ctinfo);
struct ip_conntrack_expect expect, *exp = &expect;
struct ip_ct_irc_expect *exp_irc_info = &exp->help.exp_irc_info;
-@@ -138,22 +136,6 @@
+@@ -136,22 +134,6 @@
return NF_ACCEPT;
}
@@ -202,17 +205,17 @@
data_limit = (char *) data + datalen;
/* strlen("\1DCC SEND t AAAAAAAA P\1\n")=24
-diff -urN --exclude-from=/usr/src/diff.exclude linux-2.4.23-pending/net/ipv4/netfilter/ip_conntrack_proto_tcp.c linux-2.4.23-tcp-win/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
---- linux-2.4.23-pending/net/ipv4/netfilter/ip_conntrack_proto_tcp.c 2003-11-28 19:26:21.000000000 +0100
-+++ linux-2.4.23-tcp-win/net/ipv4/netfilter/ip_conntrack_proto_tcp.c 2004-05-21 14:57:01.000000000 +0200
-@@ -1,3 +1,26 @@
-+/*
-+ * TCP connection tracking
-+ */
-+
-+/* (c) 1999 Paul `Rusty' Russell. Licenced under the GNU General
-+ * Public Licence.
+diff -urN --exclude-from=/usr/src/diff.exclude linux-2.4.31-nf-log/net/ipv4/netfilter/ip_conntrack_proto_tcp.c linux-2.4.31-tcp-win/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
+--- linux-2.4.31-nf-log/net/ipv4/netfilter/ip_conntrack_proto_tcp.c 2003-11-28 19:26:21.000000000 +0100
++++ linux-2.4.31-tcp-win/net/ipv4/netfilter/ip_conntrack_proto_tcp.c 2005-06-27 18:00:13.000000000 +0200
+@@ -1,3 +1,25 @@
++/* (C) 1999-2001 Paul `Rusty' Russell
++ * (C) 2002-2004 Netfilter Core Team <coreteam at netfilter.org>
+ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
+ * Jozsef Kadlecsik <kadlec at blackhole.kfki.hu>:
+ * - Real stateful connection tracking
+ * - Modified state transitions table
@@ -227,12 +230,11 @@
+ * version 2.2
+ */
+
-+#define __NO_VERSION__
+#include <linux/config.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/timer.h>
-@@ -6,101 +29,268 @@
+@@ -6,45 +28,66 @@
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/tcp.h>
@@ -241,9 +243,11 @@
#include <net/tcp.h>
++#include <linux/netfilter.h>
++#include <linux/netfilter_logging.h>
++#include <linux/netfilter_ipv4.h>
#include <linux/netfilter_ipv4/ip_conntrack.h>
#include <linux/netfilter_ipv4/ip_conntrack_protocol.h>
-+#include <linux/netfilter_ipv4/ip_logging.h>
#include <linux/netfilter_ipv4/lockhelp.h>
#if 0
@@ -258,8 +262,10 @@
/* Protects conntrack->proto.tcp */
static DECLARE_RWLOCK(tcp_lock);
+-/* FIXME: Examine ipfilter's timeouts and conntrack transitions more
+- closely. They're more complex. --RR */
+/* Log invalid/ignored packets */
-+int ip_ct_tcp_log_invalid = 1;
++int ip_ct_tcp_log_invalid = 0;
+
+/* "Be conservative in what you do,
+ be liberal in what you accept from others."
@@ -269,22 +275,22 @@
+/* When connection is picked up from the middle, how many packets are required
+ to pass in each direction when we assume we are in sync - if any side uses
+ window scaling, we lost the game.
-+ If it is set to zero, we disable picking up already established connections. */
++ If it is set to zero, we disable picking up already established
++ connections. */
+int ip_ct_tcp_loose = 3;
+
+/* Max number of the retransmitted packets without receiving an (acceptable)
+ ACK from the destination. If this number is reached, a shorter timer
+ will be started. */
+int ip_ct_tcp_max_retrans = 3;
-+
- /* FIXME: Examine ipfilter's timeouts and conntrack transitions more
- closely. They're more complex. --RR */
-/* Actually, I believe that neither ipmasq (where this code is stolen
- from) nor ipfilter do it exactly right. A new conntrack machine taking
- into account packet loss (which creates uncertainty as to exactly
- the conntrack of the connection) is required. RSN. --RR */
--
++ /* FIXME: Examine ipfilter's timeouts and conntrack transitions more
++ closely. They're more complex. --RR */
+
static const char *tcp_conntrack_names[] = {
"NONE",
- "ESTABLISHED",
@@ -300,60 +306,40 @@
+ "CLOSE",
"LISTEN"
};
-
+-
-#define SECS *HZ
++
+#define SECS * HZ
#define MINS * 60 SECS
#define HOURS * 60 MINS
#define DAYS * 24 HOURS
+@@ -58,50 +101,199 @@
+ unsigned long ip_ct_tcp_timeout_time_wait = 2 MINS;
+ unsigned long ip_ct_tcp_timeout_close = 10 SECS;
--unsigned long ip_ct_tcp_timeout_syn_sent = 2 MINS;
--unsigned long ip_ct_tcp_timeout_syn_recv = 60 SECS;
--unsigned long ip_ct_tcp_timeout_established = 5 DAYS;
--unsigned long ip_ct_tcp_timeout_fin_wait = 2 MINS;
--unsigned long ip_ct_tcp_timeout_close_wait = 60 SECS;
--unsigned long ip_ct_tcp_timeout_last_ack = 30 SECS;
--unsigned long ip_ct_tcp_timeout_time_wait = 2 MINS;
--unsigned long ip_ct_tcp_timeout_close = 10 SECS;
-+unsigned long ip_ct_tcp_timeout_syn_sent = 2 MINS;
-+unsigned long ip_ct_tcp_timeout_syn_recv = 60 SECS;
-+unsigned long ip_ct_tcp_timeout_established = 5 DAYS;
-+unsigned long ip_ct_tcp_timeout_fin_wait = 2 MINS;
-+unsigned long ip_ct_tcp_timeout_close_wait = 10 MINS;
-+unsigned long ip_ct_tcp_timeout_last_ack = 90 SECS;
-+unsigned long ip_ct_tcp_timeout_time_wait = 2 MINS;
-+unsigned long ip_ct_tcp_timeout_close = 90 SECS;
-+
+/* RFC1122 says the R2 limit should be at least 100 seconds.
+ Linux uses 15 packets as limit, which corresponds
+ to ~13-30min depending on RTO. */
+unsigned long ip_ct_tcp_timeout_max_retrans = 5 MINS;
-
++
static unsigned long * tcp_timeouts[]
-= { 0, /* TCP_CONNTRACK_NONE */
- &ip_ct_tcp_timeout_established, /* TCP_CONNTRACK_ESTABLISHED, */
-- &ip_ct_tcp_timeout_syn_sent, /* TCP_CONNTRACK_SYN_SENT, */
-- &ip_ct_tcp_timeout_syn_recv, /* TCP_CONNTRACK_SYN_RECV, */
-- &ip_ct_tcp_timeout_fin_wait, /* TCP_CONNTRACK_FIN_WAIT, */
++= { NULL, /* TCP_CONNTRACK_NONE */
+ &ip_ct_tcp_timeout_syn_sent, /* TCP_CONNTRACK_SYN_SENT, */
+ &ip_ct_tcp_timeout_syn_recv, /* TCP_CONNTRACK_SYN_RECV, */
++ &ip_ct_tcp_timeout_established, /* TCP_CONNTRACK_ESTABLISHED, */
+ &ip_ct_tcp_timeout_fin_wait, /* TCP_CONNTRACK_FIN_WAIT, */
- &ip_ct_tcp_timeout_time_wait, /* TCP_CONNTRACK_TIME_WAIT, */
- &ip_ct_tcp_timeout_close, /* TCP_CONNTRACK_CLOSE, */
-- &ip_ct_tcp_timeout_close_wait, /* TCP_CONNTRACK_CLOSE_WAIT, */
-- &ip_ct_tcp_timeout_last_ack, /* TCP_CONNTRACK_LAST_ACK, */
+ &ip_ct_tcp_timeout_close_wait, /* TCP_CONNTRACK_CLOSE_WAIT, */
+ &ip_ct_tcp_timeout_last_ack, /* TCP_CONNTRACK_LAST_ACK, */
- 0, /* TCP_CONNTRACK_LISTEN */
-- };
--
-+= { 0, /* TCP_CONNTRACK_NONE */
-+ &ip_ct_tcp_timeout_syn_sent, /* TCP_CONNTRACK_SYN_SENT, */
-+ &ip_ct_tcp_timeout_syn_recv, /* TCP_CONNTRACK_SYN_RECV, */
-+ &ip_ct_tcp_timeout_established, /* TCP_CONNTRACK_ESTABLISHED, */
-+ &ip_ct_tcp_timeout_fin_wait, /* TCP_CONNTRACK_FIN_WAIT, */
-+ &ip_ct_tcp_timeout_close_wait, /* TCP_CONNTRACK_CLOSE_WAIT, */
-+ &ip_ct_tcp_timeout_last_ack, /* TCP_CONNTRACK_LAST_ACK, */
-+ &ip_ct_tcp_timeout_time_wait, /* TCP_CONNTRACK_TIME_WAIT, */
-+ &ip_ct_tcp_timeout_close, /* TCP_CONNTRACK_CLOSE, */
-+ 0, /* TCP_CONNTRACK_LISTEN */
-+};
-+
++ &ip_ct_tcp_timeout_time_wait, /* TCP_CONNTRACK_TIME_WAIT, */
++ &ip_ct_tcp_timeout_close, /* TCP_CONNTRACK_CLOSE, */
++ NULL, /* TCP_CONNTRACK_LISTEN */
+ };
+
#define sNO TCP_CONNTRACK_NONE
-#define sES TCP_CONNTRACK_ESTABLISHED
#define sSS TCP_CONNTRACK_SYN_SENT
@@ -380,7 +366,7 @@
+ TCP_RST_SET,
+ TCP_NONE_SET,
+};
-+
++
+/*
+ * The TCP state transition table needs a few words...
+ *
@@ -493,6 +479,7 @@
-/*ack*/ {sCL, sES, sSS, sSR, sFW, sTW, sCL, sCW, sCL, sLI },
-/*rst*/ {sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sLA, sLI },
-/*none*/{sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV }
+- }
+/* REPLY */
+/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */
+/*syn*/ { sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV },
@@ -513,7 +500,7 @@
+ * sSS -> sSR Standard open.
+ * sSR -> sSR Retransmitted SYN/ACK.
+ * sES -> sIG Late retransmitted SYN/ACK?
-+ * sFW -> sIG
++ * sFW -> sIG Might be SYN/ACK answering ignored SYN
+ * sCW -> sIG
+ * sLA -> sIG
+ * sTW -> sIG
@@ -532,10 +519,10 @@
+ * sCL -> sCL
+ */
+/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */
-+/*ack*/ { sIV, sIV, sIV, sES, sCW, sCW, sTW, sTW, sCL, sIV },
++/*ack*/ { sIV, sIV, sSR, sES, sCW, sCW, sTW, sTW, sCL, sIV },
+/*
-+ * sSS -> sIV ACK is invalid: we haven't seen a SYN/ACK yet.
-+ * sSR -> sIV Simultaneous open.
++ * sSS -> sIV Might be a half-open connection.
++ * sSR -> sSR Might answer late resent SYN.
+ * sES -> sES :-)
+ * sFW -> sCW Normal close request answered by ACK.
+ * sCW -> sCW
@@ -546,16 +533,19 @@
+/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */
+/*rst*/ { sIV, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sIV },
+/*none*/ { sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV }
- }
++ }
};
-@@ -145,13 +335,433 @@
- return sprintf(buffer, "%s ", tcp_conntrack_names[state]);
- }
+ static int tcp_pkt_to_tuple(const void *datah, size_t datalen,
+@@ -147,11 +339,484 @@
--static unsigned int get_conntrack_index(const struct tcphdr *tcph)
-+static inline unsigned int get_conntrack_index(const struct tcphdr *tcph)
-+{
+ static unsigned int get_conntrack_index(const struct tcphdr *tcph)
+ {
+- if (tcph->rst) return 3;
+- else if (tcph->syn) return 0;
+- else if (tcph->fin) return 1;
+- else if (tcph->ack) return 2;
+- else return 4;
+ if (tcph->rst) return TCP_RST_SET;
+ else if (tcph->syn) return (tcph->ack ? TCP_SYNACK_SET : TCP_SYN_SET);
+ else if (tcph->fin) return TCP_FIN_SET;
@@ -569,51 +559,57 @@
+ http://www.nluug.nl/events/sane2000/papers.html
+ http://www.iae.nl/users/guido/papers/tcp_filtering.ps.gz
+
-+ The boundaries and the conditions are slightly changed:
-+
++ The boundaries and the conditions are changed according to RFC793:
++ the packet must intersect the window (i.e. segments may be
++ after the right or before the left edge) and thus receivers may ACK
++ segments after the right edge of the window.
++
+ td_maxend = max(sack + max(win,1)) seen in reply packets
+ td_maxwin = max(max(win, 1)) + (sack - ack) seen in sent packets
++ td_maxwin += seq + len - sender.td_maxend
++ if seq + len > sender.td_maxend
+ td_end = max(seq + len) seen in sent packets
+
-+ I. Upper bound for valid data: seq + len <= sender.td_maxend
-+ II. Lower bound for valid data: seq >= sender.td_end - receiver.td_maxwin
++ I. Upper bound for valid data: seq <= sender.td_maxend
++ II. Lower bound for valid data: seq + len >= sender.td_end - receiver.td_maxwin
+ III. Upper bound for valid ack: sack <= receiver.td_end
+ IV. Lower bound for valid ack: ack >= receiver.td_end - MAXACKWINDOW
-+
++
+ where sack is the highest right edge of sack block found in the packet.
+
+ The upper bound limit for a valid ack is not ignored -
+ we doesn't have to deal with fragments.
+*/
+
-+static inline __u32 segment_seq_plus_len(__u32 seq, size_t len, struct iphdr *iph,
++static inline __u32 segment_seq_plus_len(__u32 seq,
++ size_t len,
++ struct iphdr *iph,
+ struct tcphdr *tcph)
+{
+ return (seq + len - (iph->ihl + tcph->doff)*4
+ + (tcph->syn ? 1 : 0) + (tcph->fin ? 1 : 0));
+}
-+
++
+/* Fixme: what about big packets? */
+#define MAXACKWINCONST 66000
-+#define MAXACKWINDOW(sender) \
-+ ((sender)->td_maxwin > MAXACKWINCONST ? (sender)->td_maxwin : MAXACKWINCONST)
-+
++#define MAXACKWINDOW(sender) \
++ ((sender)->td_maxwin > MAXACKWINCONST ? (sender)->td_maxwin \
++ : MAXACKWINCONST)
++
+/*
+ * Simplified tcp_parse_options routine from tcp_input.c
+ */
-+static void tcp_options(struct iphdr *iph, size_t len,
-+ struct tcphdr *tcph,
++static void tcp_options(struct tcphdr *tcph,
+ struct ip_ct_tcp_state *state)
- {
-- if (tcph->rst) return 3;
-- else if (tcph->syn) return 0;
-- else if (tcph->fin) return 1;
-- else if (tcph->ack) return 2;
-- else return 4;
++{
+ unsigned char *ptr;
+ int length = (tcph->doff*4) - sizeof(struct tcphdr);
+
++ if (!length)
++ return;
++
+ ptr = (unsigned char *)(tcph + 1);
++
+ state->td_scale =
+ state->flags = 0;
+
@@ -638,14 +634,15 @@
+ && opsize == TCPOLEN_SACK_PERM)
+ state->flags |= IP_CT_TCP_FLAG_SACK_PERM;
+ else if (opcode == TCPOPT_WINDOW
-+ && opsize == TCPOLEN_WINDOW) {
++ && opsize == TCPOLEN_WINDOW) {
+ state->td_scale = *(u_int8_t *)ptr;
+
+ if (state->td_scale > 14) {
-+ /* See RFC1323 for an explanation of the limit to 14 */
++ /* See RFC1323 */
+ state->td_scale = 14;
+ }
-+ state->flags |= IP_CT_TCP_STATE_FLAG_WINDOW_SCALE;
++ state->flags |=
++ IP_CT_TCP_FLAG_WINDOW_SCALE;
+ }
+ ptr += opsize - 2;
+ length -= opsize;
@@ -653,20 +650,26 @@
+ }
+}
+
-+static void tcp_sack(struct tcphdr *tcph, __u32 *sack)
++static void tcp_sack(struct tcphdr *tcph,
++ __u32 *sack)
+{
-+ __u32 tmp;
+ unsigned char *ptr;
+ int length = (tcph->doff*4) - sizeof(struct tcphdr);
-+
++ __u32 tmp;
++
++ if (!length)
++ return;
++
++ ptr = (unsigned char *)(tcph + 1);
+ /* Fast path for timestamp-only option */
+ if (length == TCPOLEN_TSTAMP_ALIGNED*4
-+ && *(__u32 *)(tcph + 1) ==
-+ __constant_ntohl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16)
-+ | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP))
++ && *(__u32 *)ptr ==
++ __constant_ntohl((TCPOPT_NOP << 24)
++ | (TCPOPT_NOP << 16)
++ | (TCPOPT_TIMESTAMP << 8)
++ | TCPOLEN_TIMESTAMP))
+ return;
+
-+ ptr = (unsigned char *)(tcph + 1);
+ while (length > 0) {
+ int opcode=*ptr++;
+ int opsize, i;
@@ -685,12 +688,14 @@
+ break; /* don't parse partial options */
+
+ if (opcode == TCPOPT_SACK
-+ && opsize >= (TCPOLEN_SACK_BASE + TCPOLEN_SACK_PERBLOCK)
-+ && !((opsize - TCPOLEN_SACK_BASE) % TCPOLEN_SACK_PERBLOCK)) {
++ && opsize >= (TCPOLEN_SACK_BASE
++ + TCPOLEN_SACK_PERBLOCK)
++ && !((opsize - TCPOLEN_SACK_BASE)
++ % TCPOLEN_SACK_PERBLOCK)) {
+ for (i = 0;
+ i < (opsize - TCPOLEN_SACK_BASE);
+ i += TCPOLEN_SACK_PERBLOCK) {
-+ tmp = ntohl(*((u_int32_t *)(ptr+i) + 1));
++ tmp = ntohl(*((u_int32_t *)(ptr+i)+1));
+
+ if (after(tmp, *sack))
+ *sack = tmp;
@@ -705,6 +710,7 @@
+
+static int tcp_in_window(struct ip_ct_tcp *state,
+ enum ip_conntrack_dir dir,
++ unsigned int index,
+ struct iphdr *iph, size_t len,
+ struct tcphdr *tcph)
+{
@@ -720,17 +726,22 @@
+ ack = sack = ntohl(tcph->ack_seq);
+ win = ntohs(tcph->window);
+ end = segment_seq_plus_len(seq, len, iph, tcph);
-+
++
+ if (receiver->flags & IP_CT_TCP_FLAG_SACK_PERM)
+ tcp_sack(tcph, &sack);
+
+ DEBUGP("tcp_in_window: START\n");
-+ DEBUGP("tcp_in_window: src=%u.%u.%u.%u:%hu dst=%u.%u.%u.%u:%hu seq=%u ack=%u sack=%u win=%u end=%u\n",
-+ NIPQUAD(iph->saddr), ntohs(tcph->source), NIPQUAD(iph->daddr), ntohs(tcph->dest),
++ DEBUGP("tcp_in_window: src=%u.%u.%u.%u:%hu dst=%u.%u.%u.%u:%hu "
++ "seq=%u ack=%u sack=%u win=%u end=%u\n",
++ NIPQUAD(iph->saddr), ntohs(tcph->source),
++ NIPQUAD(iph->daddr), ntohs(tcph->dest),
+ seq, ack, sack, win, end);
-+ DEBUGP("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i receiver end=%u maxend=%u maxwin=%u scale=%i\n",
-+ sender->td_end, sender->td_maxend, sender->td_maxwin, sender->td_scale,
-+ receiver->td_end, receiver->td_maxend, receiver->td_maxwin, receiver->td_scale);
++ DEBUGP("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i "
++ "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
++ sender->td_end, sender->td_maxend, sender->td_maxwin,
++ sender->td_scale,
++ receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
++ receiver->td_scale);
+
+ if (sender->td_end == 0) {
+ /*
@@ -744,14 +755,14 @@
+ sender->td_maxend = end;
+ sender->td_maxwin = (win == 0 ? 1 : win);
+
-+ tcp_options(iph, len, tcph, sender);
++ tcp_options(tcph, sender);
+ /*
+ * RFC 1323:
+ * Both sides must send the Window Scale option
+ * to enable window scaling in either direction.
+ */
-+ if (!(sender->flags & IP_CT_TCP_STATE_FLAG_WINDOW_SCALE
-+ && receiver->flags & IP_CT_TCP_STATE_FLAG_WINDOW_SCALE))
++ if (!(sender->flags & IP_CT_TCP_FLAG_WINDOW_SCALE
++ && receiver->flags & IP_CT_TCP_FLAG_WINDOW_SCALE))
+ sender->td_scale =
+ receiver->td_scale = 0;
+ } else {
@@ -764,9 +775,11 @@
+ sender->td_maxwin = (win == 0 ? 1 : win);
+ sender->td_maxend = end + sender->td_maxwin;
+ }
-+ } else if (state->state == TCP_CONNTRACK_SYN_SENT
-+ && dir == IP_CT_DIR_ORIGINAL
-+ && after(end, sender->td_end)) {
++ } else if (((state->state == TCP_CONNTRACK_SYN_SENT
++ && dir == IP_CT_DIR_ORIGINAL)
++ || (state->state == TCP_CONNTRACK_SYN_RECV
++ && dir == IP_CT_DIR_REPLY))
++ && after(end, sender->td_end)) {
+ /*
+ * RFC 793: "if a TCP is reinitialized ... then it need
+ * not wait at all; it must only be sure to use sequence
@@ -776,7 +789,7 @@
+ sender->td_maxend = end;
+ sender->td_maxwin = (win == 0 ? 1 : win);
+
-+ tcp_options(iph, len, tcph, sender);
++ tcp_options(tcph, sender);
+ }
+
+ if (!(tcph->ack)) {
@@ -784,7 +797,8 @@
+ * If there is no ACK, just pretend it was set and OK.
+ */
+ ack = sack = receiver->td_end;
-+ } else if (((tcp_flag_word(tcph) & (TCP_FLAG_ACK|TCP_FLAG_RST)) == (TCP_FLAG_ACK|TCP_FLAG_RST))
++ } else if (((tcp_flag_word(tcph) & (TCP_FLAG_ACK|TCP_FLAG_RST)) ==
++ (TCP_FLAG_ACK|TCP_FLAG_RST))
+ && (ack == 0)) {
+ /*
+ * Broken TCP stacks, that set ACK in RST packets as well
@@ -793,39 +807,39 @@
+ ack = sack = receiver->td_end;
+ }
+
-+ if (seq == end)
++ if (seq == end
++ && (!tcph->rst
++ || (seq == 0 && state->state == TCP_CONNTRACK_SYN_SENT)))
+ /*
+ * Packets contains no data: we assume it is valid
+ * and check the ack value only.
++ * However RST segments are always validated by their
++ * SEQ number, except when seq == 0 (reset sent answering
++ * SYN.
+ */
+ seq = end = sender->td_end;
+
-+ DEBUGP("tcp_in_window: src=%u.%u.%u.%u:%hu dst=%u.%u.%u.%u:%hu seq=%u ack=%u sack=%u win=%u end=%u trim=%u\n",
-+ NIPQUAD(iph->saddr), ntohs(tcph->source), NIPQUAD(iph->daddr), ntohs(tcph->dest),
-+ seq, ack, sack, win, end,
-+ after(end, sender->td_maxend) && before(seq, sender->td_maxend) ? sender->td_maxend : end);
-+ DEBUGP("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i receiver end=%u maxend=%u maxwin=%u scale=%i\n",
-+ sender->td_end, sender->td_maxend, sender->td_maxwin, sender->td_scale,
-+ receiver->td_end, receiver->td_maxend, receiver->td_maxwin, receiver->td_scale);
++ DEBUGP("tcp_in_window: src=%u.%u.%u.%u:%hu dst=%u.%u.%u.%u:%hu "
++ "seq=%u ack=%u sack =%u win=%u end=%u\n",
++ NIPQUAD(iph->saddr), ntohs(tcph->source),
++ NIPQUAD(iph->daddr), ntohs(tcph->dest),
++ seq, ack, sack, win, end);
++ DEBUGP("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i "
++ "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
++ sender->td_end, sender->td_maxend, sender->td_maxwin,
++ sender->td_scale,
++ receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
++ receiver->td_scale);
+
-+ /* Ignore data over the right edge of the receiver's window. */
-+ if (after(end, sender->td_maxend) &&
-+ before(seq, sender->td_maxend)) {
-+ end = sender->td_maxend;
-+ if (state->stored_seq == TCP_FIN_SET)
-+ state->stored_seq = TCP_ACK_SET;
-+ }
+ DEBUGP("tcp_in_window: I=%i II=%i III=%i IV=%i\n",
-+ before(end, sender->td_maxend + 1)
-+ || before(seq, sender->td_maxend + 1),
-+ after(seq, sender->td_end - receiver->td_maxwin - 1)
-+ || after(end, sender->td_end - receiver->td_maxwin - 1),
++ before(seq, sender->td_maxend + 1),
++ after(end, sender->td_end - receiver->td_maxwin - 1),
+ before(sack, receiver->td_end + 1),
+ after(ack, receiver->td_end - MAXACKWINDOW(sender)));
+
+ if (sender->loose || receiver->loose ||
-+ (before(end, sender->td_maxend + 1) &&
-+ after(seq, sender->td_end - receiver->td_maxwin - 1) &&
++ (before(seq, sender->td_maxend + 1) &&
++ after(end, sender->td_end - receiver->td_maxwin - 1) &&
+ before(sack, receiver->td_end + 1) &&
+ after(ack, receiver->td_end - MAXACKWINDOW(sender)))) {
+ /*
@@ -842,6 +856,11 @@
+ sender->td_maxwin = swin;
+ if (after(end, sender->td_end))
+ sender->td_end = end;
++ /*
++ * Update receiver data.
++ */
++ if (after(end, sender->td_maxend))
++ receiver->td_maxwin += end - sender->td_maxend;
+ if (after(sack + win, receiver->td_maxend - 1)) {
+ receiver->td_maxend = sack + win;
+ if (win == 0)
@@ -851,7 +870,7 @@
+ /*
+ * Check retransmissions.
+ */
-+ if (state->stored_seq == TCP_ACK_SET) {
++ if (index == TCP_ACK_SET) {
+ if (state->last_dir == dir
+ && state->last_seq == seq
+ && state->last_end == end)
@@ -872,21 +891,22 @@
+ res = 1;
+ } else {
+ if (NET_RATELIMIT(ip_ct_tcp_log_invalid))
-+ nf_log_ip((char *)iph, len,
-+ "ip_conntrack_tcp: IGNORED: Out of window data; %s\n",
-+ before(end, sender->td_maxend + 1) ?
-+ after(seq, sender->td_end - receiver->td_maxwin - 1) ?
-+ before(ack, receiver->td_end + 1) ?
-+ after(ack, receiver->td_end - MAXACKWINDOW(sender)) ? "BUG"
-+ : "ACK is under the lower bound (possibly overly delayed ACK)"
-+ : "ACK is over the upper bound (ACKed data has never seen yet)"
-+ : "SEQ is under the lower bound (retransmitted already ACKed data)"
-+ : "SEQ is over the upper bound (over the window of the receiver)");
++ nf_log(PF_INET, (char *)iph, len,
++ "ip_ct_tcp: %s ",
++ before(seq, sender->td_maxend + 1) ?
++ after(end, sender->td_end - receiver->td_maxwin - 1) ?
++ before(sack, receiver->td_end + 1) ?
++ after(ack, receiver->td_end - MAXACKWINDOW(sender)) ? "BUG"
++ : "ACK is under the lower bound (possible overly delayed ACK)"
++ : "ACK is over the upper bound (ACKed data not seen yet)"
++ : "SEQ is under the lower bound (already ACKed data retransmitted)"
++ : "SEQ is over the upper bound (over the window of the receiver)");
+
-+ res = ip_ct_tcp_be_liberal && !tcph->rst;
-+ }
-+
-+ DEBUGP("tcp_in_window: res=%i sender end=%u maxend=%u maxwin=%u receiver end=%u maxend=%u maxwin=%u\n",
++ res = ip_ct_tcp_be_liberal;
++ }
++
++ DEBUGP("tcp_in_window: res=%i sender end=%u maxend=%u maxwin=%u "
++ "receiver end=%u maxend=%u maxwin=%u\n",
+ res, sender->td_end, sender->td_maxend, sender->td_maxwin,
+ receiver->td_end, receiver->td_maxend, receiver->td_maxwin);
+
@@ -895,9 +915,9 @@
+
+#ifdef CONFIG_IP_NF_NAT_NEEDED
+/* Update sender->td_end after NAT successfully mangled the packet */
-+void ip_conntrack_tcp_update(struct sk_buff *skb,
-+ struct ip_conntrack *conntrack,
-+ int dir)
++int ip_conntrack_tcp_update(struct sk_buff *skb,
++ struct ip_conntrack *conntrack,
++ int dir)
+{
+ struct iphdr *iph = skb->nh.iph;
+ struct tcphdr *tcph = (void *)skb->nh.iph + skb->nh.iph->ihl*4;
@@ -915,12 +935,18 @@
+ */
+ if (after(end, conntrack->proto.tcp.seen[dir].td_end))
+ conntrack->proto.tcp.seen[dir].td_end = end;
++ conntrack->proto.tcp.last_end = end;
+ WRITE_UNLOCK(&tcp_lock);
-+ DEBUGP("tcp_update: sender end=%u maxend=%u maxwin=%u scale=%i receiver end=%u maxend=%u maxwin=%u scale=%i\n",
-+ sender->td_end, sender->td_maxend, sender->td_maxwin, sender->td_scale,
-+ receiver->td_end, receiver->td_maxend, receiver->td_maxwin, receiver->td_scale);
++ DEBUGP("tcp_update: sender end=%u maxend=%u maxwin=%u scale=%i "
++ "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
++ sender->td_end, sender->td_maxend, sender->td_maxwin,
++ sender->td_scale,
++ receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
++ receiver->td_scale);
++
++ return 1;
+}
-+
++
+EXPORT_SYMBOL(ip_conntrack_tcp_update);
+#endif
+
@@ -952,44 +978,56 @@
+};
+
+/* Protect conntrack agaist broken packets. Code taken from ipt_unclean.c. */
-+static int unclean(struct iphdr *iph, size_t len)
++static int tcp_error(struct iphdr *iph, size_t len)
+{
+ struct tcphdr *tcph = (struct tcphdr *)((u_int32_t *)iph + iph->ihl);
+ unsigned int tcplen = len - iph->ihl * 4;
+ u_int8_t tcpflags;
+
++ /* Smaller that minimal TCP header? Should be always false. */
++ if (len < iph->ihl * 4 + sizeof(struct tcphdr)) {
++ if (NET_RATELIMIT(ip_ct_tcp_log_invalid))
++ nf_log(PF_INET, (char *)iph, len,
++ "ip_ct_tcp: short packet ");
++ return -NF_ACCEPT;
++ }
++
+ /* Not whole TCP header or malformed packet */
+ if (tcph->doff*4 < sizeof(struct tcphdr) || tcplen < tcph->doff*4) {
+ if (NET_RATELIMIT(ip_ct_tcp_log_invalid))
-+ nf_log_ip((char *)iph, len,
-+ "ip_conntrack_tcp: INVALID: truncated/malformed packet ");
-+ return 1;
++ nf_log(PF_INET, (char *)iph, len,
++ "ip_ct_tcp: truncated/malformed packet ");
++ return -NF_ACCEPT;
+ }
++
++ /* Checksum invalid? Ignore.
++ * We skip checking packets on the outgoing path
++ * because the semantic of CHECKSUM_HW is different there
++ * and moreover root might send raw packets.
++ */
++ /* FIXME: Source route IP option packets --RR */
++ if (tcp_v4_check(tcph, tcplen, iph->saddr, iph->daddr,
++ csum_partial((char *)tcph, tcplen, 0))) {
++ if (NET_RATELIMIT(ip_ct_tcp_log_invalid))
++ nf_log(PF_INET, (char *)iph, len,
++ "ip_ct_tcp: bad TCP checksum ");
++ return -NF_ACCEPT;
++ }
+
+ /* Check TCP flags. */
+ tcpflags = (((u_int8_t *)tcph)[13] & ~(TH_ECE|TH_CWR));
+ if (!tcp_valid_flags[tcpflags]) {
+ if (NET_RATELIMIT(ip_ct_tcp_log_invalid))
-+ nf_log_ip((char *)iph, len,
-+ "ip_conntrack_tcp: INVALID: invalid TCP flag combination ");
-+ return 1;
++ nf_log(PF_INET, (char *)iph, len,
++ "ip_ct_tcp: invalid TCP flag combination ");
++ return -NF_ACCEPT;
+ }
+
-+ /* Checksum invalid? Ignore. */
-+ /* FIXME: Source route IP option packets --RR */
-+ if (tcp_v4_check(tcph, tcplen, iph->saddr, iph->daddr,
-+ csum_partial((char *)tcph, tcplen, 0))) {
-+ if (NET_RATELIMIT(ip_ct_tcp_log_invalid))
-+ nf_log_ip((char *)iph, len,
-+ "ip_conntrack_tcp: INVALID: bad TCP checksum ");
-+ return 1;
-+ }
-+
-+ return 0;
++ return NF_ACCEPT;
}
/* Returns verdict for packet, or -1 for invalid. */
-@@ -159,60 +769,132 @@
+@@ -159,90 +824,248 @@
struct iphdr *iph, size_t len,
enum ip_conntrack_info ctinfo)
{
@@ -1006,10 +1044,10 @@
- }
-
+ unsigned long timeout;
-+ unsigned int index, old_index;
++ unsigned int index;
+
-+ /* Do not handle unclean packets, which could cause false alarms */
-+ if (unclean(iph, len))
++ /* Do not handle unclean packets, which could cause false alarms. */
++ if (tcp_error(iph, len) != NF_ACCEPT)
+ return -NF_ACCEPT;
+
WRITE_LOCK(&tcp_lock);
@@ -1021,6 +1059,9 @@
-
- /* Invalid */
- if (newconntrack == TCP_CONNTRACK_MAX) {
+- DEBUGP("ip_conntrack_tcp: Invalid dir=%i index=%u conntrack=%u\n",
+- CTINFO2DIR(ctinfo), get_conntrack_index(tcph),
+- conntrack->proto.tcp.state);
+ old_state = conntrack->proto.tcp.state;
+ dir = CTINFO2DIR(ctinfo);
+ index = get_conntrack_index(tcph);
@@ -1028,73 +1069,86 @@
+
+ switch (new_state) {
+ case TCP_CONNTRACK_IGNORE:
-+ /* Either SYN in ORIGINAL, or SYN/ACK in REPLY direction. */
++ /* Either SYN in ORIGINAL
++ * or SYN/ACK in REPLY. */
+ if (index == TCP_SYNACK_SET
-+ && conntrack->proto.tcp.stored_seq == TCP_SYN_SET
++ && conntrack->proto.tcp.last_index == TCP_SYN_SET
+ && conntrack->proto.tcp.last_dir != dir
-+ && after(ntohl(tcph->ack_seq), conntrack->proto.tcp.last_seq)) {
-+ /* This SYN/ACK acknowledges a SYN that we earlier ignored
-+ * as invalid. This means that the client and the server
-+ * are both in sync, while the firewall is not. We kill
-+ * this session and block the SYN/ACK so that the client
-+ * cannot but retransmit its SYN and thus initiate a
-+ * clean new session.
++ && ntohl(tcph->ack_seq) ==
++ conntrack->proto.tcp.last_end) {
++ /* This SYN/ACK acknowledges a SYN that we earlier
++ * ignored as invalid. This means that the client and
++ * the server are both in sync, while the firewall is
++ * not. We kill this session and block the SYN/ACK so
++ * that the client cannot but retransmit its SYN and
++ * thus initiate a clean new session.
+ */
+ WRITE_UNLOCK(&tcp_lock);
+ if (NET_RATELIMIT(ip_ct_tcp_log_invalid))
-+ nf_log_ip((char *)iph, len,
-+ "ip_conntrack_tcp: INVALID: killing out of sync session ");
++ nf_log(PF_INET, (char *)iph, len,
++ "ip_ct_tcp: killing out of sync session ");
+ if (del_timer(&conntrack->timeout))
-+ conntrack->timeout.function((unsigned long)conntrack);
++ conntrack->timeout.function((unsigned long)
++ conntrack);
+ return -NF_DROP;
+ }
-+ conntrack->proto.tcp.stored_seq = index;
++ conntrack->proto.tcp.last_index = index;
+ conntrack->proto.tcp.last_dir = dir;
+ conntrack->proto.tcp.last_seq = ntohl(tcph->seq);
++ conntrack->proto.tcp.last_end =
++ segment_seq_plus_len(ntohl(tcph->seq), len, iph, tcph);
+
+ WRITE_UNLOCK(&tcp_lock);
+ if (NET_RATELIMIT(ip_ct_tcp_log_invalid))
-+ nf_log_ip((char *)iph, len,
-+ "ip_conntrack_tcp: INVALID: invalid SYN (ignored) ");
++ nf_log(PF_INET, (char *)iph, len,
++ "ip_ct_tcp: invalid packet ignored ");
+ return NF_ACCEPT;
+ case TCP_CONNTRACK_MAX:
+ /* Invalid packet */
- DEBUGP("ip_conntrack_tcp: Invalid dir=%i index=%u conntrack=%u\n",
-- CTINFO2DIR(ctinfo), get_conntrack_index(tcph),
-- conntrack->proto.tcp.state);
++ DEBUGP("ip_ct_tcp: Invalid dir=%i index=%u ostate=%u\n",
+ dir, get_conntrack_index(tcph),
+ old_state);
WRITE_UNLOCK(&tcp_lock);
- return -1;
+ if (NET_RATELIMIT(ip_ct_tcp_log_invalid))
-+ nf_log_ip((char *)iph, len,
-+ "ip_conntrack_tcp: INVALID: invalid state ");
++ nf_log(PF_INET, (char *)iph, len,
++ "ip_ct_tcp: invalid state ");
+ return -NF_ACCEPT;
+ case TCP_CONNTRACK_SYN_SENT:
-+ if (old_state >= TCP_CONNTRACK_TIME_WAIT) {
++ if (old_state < TCP_CONNTRACK_TIME_WAIT)
++ break;
++ if ((conntrack->proto.tcp.seen[dir].flags &
++ IP_CT_TCP_FLAG_CLOSE_INIT)
++ || after(ntohl(tcph->seq),
++ conntrack->proto.tcp.seen[dir].td_end)) {
+ /* Attempt to reopen a closed connection.
+ * Delete this connection and look up again. */
+ WRITE_UNLOCK(&tcp_lock);
+ if (del_timer(&conntrack->timeout))
-+ conntrack->timeout.function((unsigned long)conntrack);
++ conntrack->timeout.function((unsigned long)
++ conntrack);
+ return -NF_REPEAT;
++ } else {
++ WRITE_UNLOCK(&tcp_lock);
++ if (NET_RATELIMIT(ip_ct_tcp_log_invalid))
++ nf_log(PF_INET, (char *)iph, len,
++ "ip_ct_tcp: invalid SYN ");
++ return -NF_ACCEPT;
+ }
-+ break;
+ case TCP_CONNTRACK_CLOSE:
+ if (index == TCP_RST_SET
-+ && conntrack->proto.tcp.stored_seq <= TCP_SYNACK_SET
-+ && conntrack->proto.tcp.last_dir != dir
-+ && after(ntohl(tcph->ack_seq), conntrack->proto.tcp.last_seq)) {
-+ /* Ignore RST closing down invalid SYN we had let trough. */
-+ WRITE_UNLOCK(&tcp_lock);
-+ if (NET_RATELIMIT(ip_ct_tcp_log_invalid))
-+ nf_log_ip((char *)iph, len,
-+ "ip_conntrack_tcp: INVALID: invalid RST (ignored) ");
-+ return NF_ACCEPT;
++ && test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)
++ && conntrack->proto.tcp.last_index == TCP_SYN_SET
++ && ntohl(tcph->ack_seq) == conntrack->proto.tcp.last_end) {
++ /* RST sent to invalid SYN we had let trough
++ * SYN was in window then, tear down connection.
++ * We skip window checking, because packet might ACK
++ * segments we ignored in the SYN. */
++ goto in_window;
+ }
+ /* Just fall trough */
+ default:
-+ /* Keep compilers happy */
++ /* Keep compilers happy. */
+ break;
}
@@ -1112,11 +1166,8 @@
- problem case, so we can delete the conntrack
- immediately. --RR */
- if (!test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status) && tcph->rst) {
-+ old_index = conntrack->proto.tcp.stored_seq;
-+ conntrack->proto.tcp.stored_seq = index;
-+ if (!tcp_in_window(&conntrack->proto.tcp, dir, iph, len, tcph)) {
-+ /* Invalid packet, restore previous state */
-+ conntrack->proto.tcp.stored_seq = old_index;
++ if (!tcp_in_window(&conntrack->proto.tcp, dir, index,
++ iph, len, tcph)) {
WRITE_UNLOCK(&tcp_lock);
- if (del_timer(&conntrack->timeout))
- conntrack->timeout.function((unsigned long)conntrack);
@@ -1126,23 +1177,28 @@
- && CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL
- && tcph->ack && !tcph->syn
- && tcph->ack_seq == conntrack->proto.tcp.handshake_ack)
-- set_bit(IPS_ASSURED_BIT, &conntrack->status);
+ return -NF_ACCEPT;
+ }
-+ /* If FIN was trimmed off, don't change state. */
-+ new_state = tcp_conntracks[dir][conntrack->proto.tcp.stored_seq][old_state];
-
-- WRITE_UNLOCK(&tcp_lock);
-- ip_ct_refresh(conntrack, *tcp_timeouts[newconntrack]);
-+ DEBUGP("tcp_conntracks: src=%u.%u.%u.%u:%hu dst=%u.%u.%u.%u:%hu syn=%i ack=%i fin=%i rst=%i old=%i new=%i\n",
-+ NIPQUAD(iph->saddr), ntohs(tcph->source), NIPQUAD(iph->daddr), ntohs(tcph->dest),
-+ (tcph->syn ? 1 : 0), (tcph->ack ? 1 : 0), (tcph->fin ? 1 : 0), (tcph->rst ? 1 : 0),
++ in_window:
++ /* From now on we have got in-window packets */
++ conntrack->proto.tcp.last_index = index;
++
++ DEBUGP("tcp_conntracks: src=%u.%u.%u.%u:%hu dst=%u.%u.%u.%u:%hu "
++ "syn=%i ack=%i fin=%i rst=%i old=%i new=%i\n",
++ NIPQUAD(iph->saddr), ntohs(tcph->source),
++ NIPQUAD(iph->daddr), ntohs(tcph->dest),
++ (tcph->syn ? 1 : 0), (tcph->ack ? 1 : 0),
++ (tcph->fin ? 1 : 0), (tcph->rst ? 1 : 0),
+ old_state, new_state);
+
+ conntrack->proto.tcp.state = new_state;
++ if (old_state != new_state
++ && (new_state == TCP_CONNTRACK_FIN_WAIT
++ || new_state == TCP_CONNTRACK_CLOSE))
++ conntrack->proto.tcp.seen[dir].flags |= IP_CT_TCP_FLAG_CLOSE_INIT;
+ timeout = conntrack->proto.tcp.retrans >= ip_ct_tcp_max_retrans
-+ && *tcp_timeouts[new_state] > ip_ct_tcp_timeout_max_retrans ?
-+ ip_ct_tcp_timeout_max_retrans : *tcp_timeouts[new_state];
++ && *tcp_timeouts[new_state] > ip_ct_tcp_timeout_max_retrans
++ ? ip_ct_tcp_timeout_max_retrans : *tcp_timeouts[new_state];
+ WRITE_UNLOCK(&tcp_lock);
+
+ if (!test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)) {
@@ -1152,22 +1208,29 @@
+ immediately. --RR */
+ if (tcph->rst) {
+ if (del_timer(&conntrack->timeout))
-+ conntrack->timeout.function((unsigned long)conntrack);
++ conntrack->timeout.function((unsigned long)
++ conntrack);
+ return NF_ACCEPT;
+ }
+ } else if (!test_bit(IPS_ASSURED_BIT, &conntrack->status)
+ && (old_state == TCP_CONNTRACK_SYN_RECV
+ || old_state == TCP_CONNTRACK_ESTABLISHED)
+ && new_state == TCP_CONNTRACK_ESTABLISHED) {
-+ /* Set ASSURED if we see see valid ack in ESTABLISHED after SYN_RECV
-+ or a valid answer for a picked up connection. */
-+ set_bit(IPS_ASSURED_BIT, &conntrack->status);
++ /* Set ASSURED if we see see valid ack in ESTABLISHED
++ after SYN_RECV or a valid answer for a picked up
++ connection. */
+ set_bit(IPS_ASSURED_BIT, &conntrack->status);
+-
+- WRITE_UNLOCK(&tcp_lock);
+- ip_ct_refresh(conntrack, *tcp_timeouts[newconntrack]);
}
+ ip_ct_refresh(conntrack, timeout);
return NF_ACCEPT;
}
-@@ -221,21 +903,80 @@
+-
++
+ /* Called when a new connection for this protocol found. */
static int tcp_new(struct ip_conntrack *conntrack,
struct iphdr *iph, size_t len)
{
@@ -1178,11 +1241,11 @@
+ struct ip_ct_tcp_state *sender = &conntrack->proto.tcp.seen[0];
+ struct ip_ct_tcp_state *receiver = &conntrack->proto.tcp.seen[1];
+#endif
-+
+
+ /* Skip unclean packets */
-+ if (unclean(iph, len))
++ if (tcp_error(iph, len) != NF_ACCEPT)
+ return 0;
-
++
/* Don't need lock here: this conntrack not in circulation yet */
- newconntrack
+ new_state
@@ -1191,8 +1254,9 @@
/* Invalid: delete conntrack */
- if (newconntrack == TCP_CONNTRACK_MAX) {
+- DEBUGP("ip_conntrack_tcp: invalid new deleting.\n");
+ if (new_state >= TCP_CONNTRACK_MAX) {
- DEBUGP("ip_conntrack_tcp: invalid new deleting.\n");
++ DEBUGP("ip_ct_tcp: invalid new deleting.\n");
return 0;
}
@@ -1200,14 +1264,15 @@
+ if (new_state == TCP_CONNTRACK_SYN_SENT) {
+ /* SYN packet */
+ conntrack->proto.tcp.seen[0].td_end =
-+ segment_seq_plus_len(ntohl(tcph->seq), len, iph, tcph);
++ segment_seq_plus_len(ntohl(tcph->seq), len,
++ iph, tcph);
+ conntrack->proto.tcp.seen[0].td_maxwin = ntohs(tcph->window);
+ if (conntrack->proto.tcp.seen[0].td_maxwin == 0)
+ conntrack->proto.tcp.seen[0].td_maxwin = 1;
+ conntrack->proto.tcp.seen[0].td_maxend =
+ conntrack->proto.tcp.seen[0].td_end;
+
-+ tcp_options(iph, len, tcph, &conntrack->proto.tcp.seen[0]);
++ tcp_options(tcph, &conntrack->proto.tcp.seen[0]);
+ conntrack->proto.tcp.seen[1].flags = 0;
+ conntrack->proto.tcp.seen[0].loose =
+ conntrack->proto.tcp.seen[1].loose = 0;
@@ -1221,7 +1286,8 @@
+ * Let's try to use the data from the packet.
+ */
+ conntrack->proto.tcp.seen[0].td_end =
-+ segment_seq_plus_len(ntohl(tcph->seq), len, iph, tcph);
++ segment_seq_plus_len(ntohl(tcph->seq), len,
++ iph, tcph);
+ conntrack->proto.tcp.seen[0].td_maxwin = ntohs(tcph->window);
+ if (conntrack->proto.tcp.seen[0].td_maxwin == 0)
+ conntrack->proto.tcp.seen[0].td_maxwin = 1;
@@ -1230,7 +1296,7 @@
+ conntrack->proto.tcp.seen[0].td_maxwin;
+ conntrack->proto.tcp.seen[0].td_scale = 0;
+
-+ /* We assume SACK. Should we assume window scaling? */
++ /* We assume SACK. Should we assume window scaling too? */
+ conntrack->proto.tcp.seen[0].flags =
+ conntrack->proto.tcp.seen[1].flags = IP_CT_TCP_FLAG_SACK_PERM;
+ conntrack->proto.tcp.seen[0].loose =
@@ -1244,18 +1310,50 @@
+
+ /* tcp_packet will set them */
+ conntrack->proto.tcp.state = TCP_CONNTRACK_NONE;
-+ conntrack->proto.tcp.stored_seq = TCP_NONE_SET;
-+
-+ DEBUGP("tcp_new: sender end=%u maxend=%u maxwin=%u scale=%i receiver end=%u maxend=%u maxwin=%u scale=%i\n",
-+ sender->td_end, sender->td_maxend, sender->td_maxwin, sender->td_scale,
-+ receiver->td_end, receiver->td_maxend, receiver->td_maxwin, receiver->td_scale);
++ conntrack->proto.tcp.last_index = TCP_NONE_SET;
++
++ DEBUGP("tcp_new: sender end=%u maxend=%u maxwin=%u scale=%i "
++ "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
++ sender->td_end, sender->td_maxend, sender->td_maxwin,
++ sender->td_scale,
++ receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
++ receiver->td_scale);
return 1;
}
+-
++
+ static int tcp_exp_matches_pkt(struct ip_conntrack_expect *exp,
+ struct sk_buff **pskb)
+ {
+- struct iphdr *iph = (*pskb)->nh.iph;
++ const struct iphdr *iph = (*pskb)->nh.iph;
+ struct tcphdr *tcph = (struct tcphdr *)((u_int32_t *)iph + iph->ihl);
+ unsigned int datalen;
-diff -urN --exclude-from=/usr/src/diff.exclude linux-2.4.23-pending/net/ipv4/netfilter/ip_conntrack_standalone.c linux-2.4.23-tcp-win/net/ipv4/netfilter/ip_conntrack_standalone.c
---- linux-2.4.23-pending/net/ipv4/netfilter/ip_conntrack_standalone.c 2003-12-04 16:56:14.000000000 +0100
-+++ linux-2.4.23-tcp-win/net/ipv4/netfilter/ip_conntrack_standalone.c 2003-12-09 09:30:21.000000000 +0100
-@@ -289,6 +289,11 @@
+@@ -251,7 +1074,15 @@
+ return between(exp->seq, ntohl(tcph->seq), ntohl(tcph->seq) + datalen);
+ }
+
+-struct ip_conntrack_protocol ip_conntrack_protocol_tcp
+-= { { NULL, NULL }, IPPROTO_TCP, "tcp",
+- tcp_pkt_to_tuple, tcp_invert_tuple, tcp_print_tuple, tcp_print_conntrack,
+- tcp_packet, tcp_new, NULL, tcp_exp_matches_pkt, NULL };
++struct ip_conntrack_protocol ip_conntrack_protocol_tcp =
++{
++ .proto = IPPROTO_TCP,
++ .name = "tcp",
++ .pkt_to_tuple = tcp_pkt_to_tuple,
++ .invert_tuple = tcp_invert_tuple,
++ .print_tuple = tcp_print_tuple,
++ .print_conntrack = tcp_print_conntrack,
++ .packet = tcp_packet,
++ .new = tcp_new,
++ .exp_matches_pkt = tcp_exp_matches_pkt,
++};
+diff -urN --exclude-from=/usr/src/diff.exclude linux-2.4.31-nf-log/net/ipv4/netfilter/ip_conntrack_standalone.c linux-2.4.31-tcp-win/net/ipv4/netfilter/ip_conntrack_standalone.c
+--- linux-2.4.31-nf-log/net/ipv4/netfilter/ip_conntrack_standalone.c 2005-04-04 03:42:20.000000000 +0200
++++ linux-2.4.31-tcp-win/net/ipv4/netfilter/ip_conntrack_standalone.c 2005-06-27 17:34:52.000000000 +0200
+@@ -259,6 +259,11 @@
extern unsigned long ip_ct_tcp_timeout_last_ack;
extern unsigned long ip_ct_tcp_timeout_time_wait;
extern unsigned long ip_ct_tcp_timeout_close;
@@ -1267,7 +1365,7 @@
/* From ip_conntrack_proto_udp.c */
extern unsigned long ip_ct_udp_timeout;
-@@ -345,6 +350,21 @@
+@@ -315,6 +320,21 @@
{NET_IPV4_NF_CONNTRACK_GENERIC_TIMEOUT, "ip_conntrack_generic_timeout",
&ip_ct_generic_timeout, sizeof(unsigned int), 0644, NULL,
&proc_dointvec_jiffies},
@@ -1289,15 +1387,15 @@
{0}
};
-diff -urN --exclude-from=/usr/src/diff.exclude linux-2.4.23-pending/net/ipv4/netfilter/ip_nat_helper.c linux-2.4.23-tcp-win/net/ipv4/netfilter/ip_nat_helper.c
---- linux-2.4.23-pending/net/ipv4/netfilter/ip_nat_helper.c 2003-11-28 19:26:21.000000000 +0100
-+++ linux-2.4.23-tcp-win/net/ipv4/netfilter/ip_nat_helper.c 2003-12-09 09:30:21.000000000 +0100
-@@ -452,6 +452,8 @@
+diff -urN --exclude-from=/usr/src/diff.exclude linux-2.4.31-nf-log/net/ipv4/netfilter/ip_nat_helper.c linux-2.4.31-tcp-win/net/ipv4/netfilter/ip_nat_helper.c
+--- linux-2.4.31-nf-log/net/ipv4/netfilter/ip_nat_helper.c 2005-04-04 03:42:20.000000000 +0200
++++ linux-2.4.31-tcp-win/net/ipv4/netfilter/ip_nat_helper.c 2005-06-27 17:35:40.000000000 +0200
+@@ -451,6 +451,8 @@
+ tcph->ack_seq = newack;
ip_nat_sack_adjust(skb, ct, ctinfo);
++
++ ip_conntrack_tcp_update(skb, ct, dir);
-+ ip_conntrack_tcp_update(skb, ct, dir);
-+
return 0;
}
-
More information about the netfilter-cvslog
mailing list