diff -Nurb linux-2.6.22-510/net/netfilter/xt_MARK.c linux-2.6.22-520/net/netfilter/xt_MARK.c
--- linux-2.6.22-510/net/netfilter/xt_MARK.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-520/net/netfilter/xt_MARK.c 2008-05-09 14:09:29.000000000 -0400
++++ linux-2.6.22-520/net/netfilter/xt_MARK.c 2008-05-09 16:59:26.000000000 -0400
@@ -5,13 +5,18 @@
* 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
static unsigned int
target_v0(struct sk_buff **pskb,
const struct net_device *in,
-@@ -44,7 +91,16 @@
+@@ -44,7 +91,19 @@
const void *targinfo)
{
const struct xt_mark_target_info_v1 *markinfo = targinfo;
- int mark = 0;
-+ struct nf_conn *ct;
-+ int mark = -1;
-+ extern struct inet_hashinfo tcp_hashinfo;
-+ enum ip_conntrack_dir dir;
-+ u_int32_t src_ip;
-+ u_int16_t src_port;
-+ u_int16_t proto;
++ enum ip_conntrack_info ctinfo;
++ struct sock *connection_sk;
++ int dif;
++ struct nf_conn *ct;
++ extern struct inet_hashinfo tcp_hashinfo;
++ enum ip_conntrack_dir dir;
++ u_int32_t src_ip;
++ u_int32_t dst_ip;
++ u_int16_t proto, src_port;
++ u_int32_t ip;
++ u_int16_t port;
+
-+ u_int32_t ip;
-+ u_int16_t port;
++ int mark = -1;
switch (markinfo->mode) {
case XT_MARK_SET:
-@@ -58,8 +114,58 @@
+@@ -58,8 +117,63 @@
case XT_MARK_OR:
mark = (*pskb)->mark | markinfo->mark;
break;
+
-+ case XT_MARK_COPYXID: {
-+ enum ip_conntrack_info ctinfo;
-+ struct sock *connection_sk;
-+ int dif;
-+
++ case XT_MARK_COPYXID:
++
+ ct = nf_ct_get((*pskb), &ctinfo);
+ if (!ct)
+ break;
+
+ dir = CTINFO2DIR(ctinfo);
+ src_ip = ct->tuplehash[dir].tuple.src.u3.ip;
++ dst_ip = ct->tuplehash[dir].tuple.dst.u3.ip;
+ src_port = get_src_port(&ct->tuplehash[dir].tuple);
+ proto = ct->tuplehash[dir].tuple.dst.protonum;
+
+ ip = ct->tuplehash[dir].tuple.dst.u3.ip;
+ port = get_dst_port(&ct->tuplehash[dir].tuple);
+
++
++
+ if (proto == 1 || proto == 17) {
-+ if (((*pskb)->mark!=-1) && (*pskb)->mark)
++ /* Temporary hack for robustness against wrong xid values */
++ if (((*pskb)->mark!=-1) && (*pskb)->mark && ct->xid[0]==-1 && (hooknum != NF_IP_LOCAL_IN))
+ ct->xid[0]=(*pskb)->mark;
+ if (ct->xid[0])
+ mark = ct->xid[0];
+
-+ }
+ }
+ else if (proto == 6) {
+ if ((*pskb)->sk) {
+ connection_sk = (*pskb)->sk;
+ else
+ connection_sk = inet_lookup_established(&tcp_hashinfo, src_ip, src_port, ip, port, dif);
+
-+
+
+ if (connection_sk) {
+ if (connection_sk->sk_state == TCP_TIME_WAIT) {
+ inet_twsk_put(inet_twsk(connection_sk));
+ ct->xid[!dir]=connection_sk->sk_xid;
+ if (connection_sk->sk_xid != 0)
+ mark = connection_sk->sk_xid;
++ else if (hooknum == NF_IP_LOCAL_IN) {
++ /* Neutralize packets in incognito */
++ mark = -1;
++ }
+ sock_put(connection_sk);
+ }
++ else
++ mark = -1 ;
+ }
+ break;
-+ }
- }
-
++ }
+ if (mark != -1)
(*pskb)->mark = mark;
return XT_CONTINUE;
}
-@@ -92,7 +198,8 @@
+@@ -92,7 +206,8 @@
if (markinfo->mode != XT_MARK_SET
&& markinfo->mode != XT_MARK_AND