On Wed, 18 Apr 2018, Dominique Martinet wrote: > Dominique Martinet wrote on Wed, Apr 18, 2018: > > Jozsef Kadlecsik wrote on Wed, Apr 18, 2018: > > > Yes, the state transition is wrong for simultaneous open, because the > > > tcp_conntracks table is not (cannot be) smart enough. Could you verify > > > the > > > next untested patch? > > > > Thanks for the patch; I'll give it a try (probably won't make it today > > so will report tomorrow) > > Actually had time; I can confirm (added printks) we did get in that if > that was pointed at, and we no longer get there now. The connection no > longer gets in invalid state, so that looks like it nailed it. > > I'm now confused what this has to do with tcp_timestamp though, since > setting that off also seemed to work around the issue, but if we get > something like that in I'll be happy anyway.
Thanks for the testing! One more line is required, however: we have to get the assured bit set for the connection, see the new patch below. The tcp_conntracks state table could be fixed with introducing a new state, but that part is exposed to userspace (ctnetlink) and ugly compatibility code would be required for backward compatibility. diff --git a/include/uapi/linux/netfilter/nf_conntrack_tcp.h b/include/uapi/linux/netfilter/nf_conntrack_tcp.h index 74b9115..bcba72d 100644 --- a/include/uapi/linux/netfilter/nf_conntrack_tcp.h +++ b/include/uapi/linux/netfilter/nf_conntrack_tcp.h @@ -46,6 +46,9 @@ enum tcp_conntrack { /* Marks possibility for expected RFC5961 challenge ACK */ #define IP_CT_EXP_CHALLENGE_ACK 0x40 +/* Simultaneous open initialized */ +#define IP_CT_TCP_SIMULTANEOUS_OPEN 0x80 + struct nf_ct_tcp_flags { __u8 flags; __u8 mask; diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c index e97cdc1..2c1fc7e 100644 --- a/net/netfilter/nf_conntrack_proto_tcp.c +++ b/net/netfilter/nf_conntrack_proto_tcp.c @@ -981,6 +981,20 @@ static int tcp_packet(struct nf_conn *ct, return NF_ACCEPT; /* Don't change state */ } break; + case TCP_CONNTRACK_SYN_SENT2: + /* tcp_conntracks table is not smart enough to handle + * simultaneous open. + */ + ct->proto.tcp.last_flags |= IP_CT_TCP_SIMULTANEOUS_OPEN; + break; + case TCP_CONNTRACK_SYN_RECV: + if (dir == IP_CT_DIR_REPLY && index == TCP_ACK_SET && + ct->proto.tcp.last_flags & IP_CT_TCP_SIMULTANEOUS_OPEN) { + /* We want to set the assured bit */ + old_state = TCP_CONNTRACK_SYN_RECV; + new_state = TCP_CONNTRACK_ESTABLISHED; + } + break; case TCP_CONNTRACK_CLOSE: if (index == TCP_RST_SET && (ct->proto.tcp.seen[!dir].flags & IP_CT_TCP_FLAG_MAXACK_SET) Best regards, Jozsef - E-mail : kad...@blackhole.kfki.hu, kadlecsik.joz...@wigner.mta.hu PGP key : http://www.kfki.hu/~kadlec/pgp_public_key.txt Address : Wigner Research Centre for Physics, Hungarian Academy of Sciences H-1525 Budapest 114, POB. 49, Hungary