From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:52153) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bJuN9-0005Nb-AI for qemu-devel@nongnu.org; Sun, 03 Jul 2016 23:16:36 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bJuN5-0002ey-1L for qemu-devel@nongnu.org; Sun, 03 Jul 2016 23:16:34 -0400 Received: from mx1.redhat.com ([209.132.183.28]:52485) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bJuN4-0002et-P4 for qemu-devel@nongnu.org; Sun, 03 Jul 2016 23:16:30 -0400 References: <1467440540-6630-1-git-send-email-zhangchen.fnst@cn.fujitsu.com> <1467440540-6630-4-git-send-email-zhangchen.fnst@cn.fujitsu.com> From: Jason Wang Message-ID: <5779D505.2060602@redhat.com> Date: Mon, 4 Jul 2016 11:16:21 +0800 MIME-Version: 1.0 In-Reply-To: <1467440540-6630-4-git-send-email-zhangchen.fnst@cn.fujitsu.com> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: quoted-printable Subject: Re: [Qemu-devel] [RFC PATCH V2 3/3] filter-rewriter: rewrite tcp packet to keep secondary connection List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Zhang Chen , qemu devel Cc: Li Zhijian , "eddie . dong" , "Dr . David Alan Gilbert" , zhanghailiang On 2016=E5=B9=B407=E6=9C=8802=E6=97=A5 14:22, Zhang Chen wrote: > We will rewrite tcp packet secondary received and sent. > When colo guest is a tcp server. > > Firstly, client start a tcp handshake. the packet's seq=3Dclient_seq, > ack=3D0,flag=3DSYN. COLO primary guest get this pkt and mirror(filter-m= irror) > to secondary guest, secondary get it use filter-redirector. > Then,primary guest response pkt > (seq=3Dprimary_seq,ack=3Dclient_seq+1,flag=3DACK|SYN). > secondary guest response pkt > (seq=3Dsecondary_seq,ack=3Dclient_seq+1,flag=3DACK|SYN). > In here,we use filter-rewriter save the secondary_seq to it's tcp conne= ction. > Finally handshake,client send pkt > (seq=3Dclient_seq+1,ack=3Dprimary_seq+1,flag=3DACK). > Here,filter-rewriter can get primary_seq, and rewrite ack from primary_= seq+1 > to secondary_seq+1, recalculate checksum. So the secondary tcp connecti= on > kept good. > > When we send/recv packet. > client send pkt(seq=3Dclient_seq+1+data_len,ack=3Dprimary_seq+1,flag=3D= ACK|PSH). > filter-rewriter rewrite ack and send to secondary guest. > > primary guest response pkt > (seq=3Dprimary_seq+1,ack=3Dclient_seq+1+data_len,flag=3DACK) > secondary guest response pkt > (seq=3Dsecondary_seq+1,ack=3Dclient_seq+1+data_len,flag=3DACK) > we rewrite secondary guest seq from secondary_seq+1 to primary_seq+1. > So tcp connection kept good. > > In code We use offset( =3D secondary_seq - primary_seq ) > to rewrite seq or ack. > handle_primary_tcp_pkt: tcp_pkt->th_ack +=3D offset; > handle_secondary_tcp_pkt: tcp_pkt->th_seq -=3D offset; > > Signed-off-by: Zhang Chen > Signed-off-by: Li Zhijian > Signed-off-by: Wen Congyang > --- > net/colo-base.h | 2 + > net/filter-rewriter.c | 110 +++++++++++++++++++++++++++++++++++++++++= ++++++++- > trace-events | 5 +++ > 3 files changed, 115 insertions(+), 2 deletions(-) > > diff --git a/net/colo-base.h b/net/colo-base.h > index 62460c5..7b32648 100644 > --- a/net/colo-base.h > +++ b/net/colo-base.h > @@ -71,6 +71,8 @@ typedef struct Connection { > uint8_t ip_proto; > /* be used by filter-rewriter */ > colo_conn_state state; > + /* offset =3D secondary_seq - primary_seq */ > + tcp_seq offset; Fail to find the definition of 'tcp_seq'. > } Connection; > =20 > uint32_t connection_key_hash(const void *opaque); > diff --git a/net/filter-rewriter.c b/net/filter-rewriter.c > index c38ab24..9f63c75 100644 > --- a/net/filter-rewriter.c > +++ b/net/filter-rewriter.c > @@ -21,6 +21,7 @@ > #include "qemu/main-loop.h" > #include "qemu/iov.h" > #include "net/checksum.h" > +#include "trace.h" > =20 > #define FILTER_COLO_REWRITER(obj) \ > OBJECT_CHECK(RewriterState, (obj), TYPE_FILTER_REWRITER) > @@ -64,6 +65,91 @@ static int is_tcp_packet(Packet *pkt) > } > } > =20 > +/* handle tcp packet from primary guest */ > +static int handle_primary_tcp_pkt(NetFilterState *nf, > + Connection *conn, > + Packet *pkt) > +{ > + struct tcphdr *tcp_pkt; > + static int syn_flag; > + > + tcp_pkt =3D (struct tcphdr *)pkt->transport_layer; > + if (trace_event_get_state(TRACE_COLO_FILTER_REWRITER_DEBUG)) { > + char *sdebug, *ddebug; > + sdebug =3D strdup(inet_ntoa(pkt->ip->ip_src)); > + ddebug =3D strdup(inet_ntoa(pkt->ip->ip_dst)); > + trace_colo_filter_rewriter_pkt_info(__func__, sdebug, ddebug, > + ntohl(tcp_pkt->th_seq), ntohl(tcp_pkt->th_ack), > + tcp_pkt->th_flags); > + trace_colo_filter_rewriter_conn_offset(conn->offset); > + g_free(sdebug); > + g_free(ddebug); > + } > + > + if (((tcp_pkt->th_flags & (TH_ACK | TH_SYN)) =3D=3D TH_SYN)) { > + /* > + * this flag update offset func run oncs typo? > + * in independent tcp connection > + */ > + syn_flag =3D 1; Does this really work if you have more than one tcp connections? You=20 probably need a conn->syn_flag. > + } > + > + if (((tcp_pkt->th_flags & (TH_ACK | TH_SYN)) =3D=3D TH_ACK)) { > + if (syn_flag) { > + /* offset =3D secondary_seq - primary seq */ > + conn->offset -=3D (ntohl(tcp_pkt->th_ack)); > + syn_flag =3D 0; > + > + } > + /* handle packets to the secondary from the primary */ > + tcp_pkt->th_ack =3D htonl(ntohl(tcp_pkt->th_ack) + conn->offse= t + 1); Maybe I miss something, but why +1 here?