From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
To: Jason Wang <jasowang@redhat.com>, qemu devel <qemu-devel@nongnu.org>
Cc: Li Zhijian <lizhijian@cn.fujitsu.com>,
"eddie . dong" <eddie.dong@intel.com>,
"Dr . David Alan Gilbert" <dgilbert@redhat.com>,
zhanghailiang <zhang.zhanghailiang@huawei.com>
Subject: Re: [Qemu-devel] [RFC PATCH V2 3/3] filter-rewriter: rewrite tcp packet to keep secondary connection
Date: Mon, 4 Jul 2016 16:59:43 +0800 [thread overview]
Message-ID: <577A257F.4040207@cn.fujitsu.com> (raw)
In-Reply-To: <5779D505.2060602@redhat.com>
On 07/04/2016 11:16 AM, Jason Wang wrote:
>
>
> On 2016年07月02日 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=client_seq,
>> ack=0,flag=SYN. COLO primary guest get this pkt and
>> mirror(filter-mirror)
>> to secondary guest, secondary get it use filter-redirector.
>> Then,primary guest response pkt
>> (seq=primary_seq,ack=client_seq+1,flag=ACK|SYN).
>> secondary guest response pkt
>> (seq=secondary_seq,ack=client_seq+1,flag=ACK|SYN).
>> In here,we use filter-rewriter save the secondary_seq to it's tcp
>> connection.
>> Finally handshake,client send pkt
>> (seq=client_seq+1,ack=primary_seq+1,flag=ACK).
>> Here,filter-rewriter can get primary_seq, and rewrite ack from
>> primary_seq+1
>> to secondary_seq+1, recalculate checksum. So the secondary tcp
>> connection
>> kept good.
>>
>> When we send/recv packet.
>> client send
>> pkt(seq=client_seq+1+data_len,ack=primary_seq+1,flag=ACK|PSH).
>> filter-rewriter rewrite ack and send to secondary guest.
>>
>> primary guest response pkt
>> (seq=primary_seq+1,ack=client_seq+1+data_len,flag=ACK)
>> secondary guest response pkt
>> (seq=secondary_seq+1,ack=client_seq+1+data_len,flag=ACK)
>> we rewrite secondary guest seq from secondary_seq+1 to primary_seq+1.
>> So tcp connection kept good.
>>
>> In code We use offset( = secondary_seq - primary_seq )
>> to rewrite seq or ack.
>> handle_primary_tcp_pkt: tcp_pkt->th_ack += offset;
>> handle_secondary_tcp_pkt: tcp_pkt->th_seq -= offset;
>>
>> Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
>> Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
>> Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
>> ---
>> 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 = secondary_seq - primary_seq */
>> + tcp_seq offset;
>
> Fail to find the definition of 'tcp_seq'.
>
In slirp/tcp.h
typedef uint32_t tcp_seq;
we add this .h in colo-base.h
>> } Connection;
>> 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"
>> #define FILTER_COLO_REWRITER(obj) \
>> OBJECT_CHECK(RewriterState, (obj), TYPE_FILTER_REWRITER)
>> @@ -64,6 +65,91 @@ static int is_tcp_packet(Packet *pkt)
>> }
>> }
>> +/* 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 = (struct tcphdr *)pkt->transport_layer;
>> + if (trace_event_get_state(TRACE_COLO_FILTER_REWRITER_DEBUG)) {
>> + char *sdebug, *ddebug;
>> + sdebug = strdup(inet_ntoa(pkt->ip->ip_src));
>> + ddebug = 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)) == TH_SYN)) {
>> + /*
>> + * this flag update offset func run oncs
>
> typo?
S/oncs/once
>
>> + * in independent tcp connection
>> + */
>> + syn_flag = 1;
>
> Does this really work if you have more than one tcp connections? You
> probably need a conn->syn_flag.
Good catch...
I will fix it in next.
>
>> + }
>> +
>> + if (((tcp_pkt->th_flags & (TH_ACK | TH_SYN)) == TH_ACK)) {
>> + if (syn_flag) {
>> + /* offset = secondary_seq - primary seq */
>> + conn->offset -= (ntohl(tcp_pkt->th_ack));
>> + syn_flag = 0;
>> +
>> + }
>> + /* handle packets to the secondary from the primary */
>> + tcp_pkt->th_ack = htonl(ntohl(tcp_pkt->th_ack) +
>> conn->offset + 1);
>
> Maybe I miss something, but why +1 here?
>
>
No,I miss something.
+ /* offset = secondary_seq - primary seq */
+ conn->offset -= (ntohl(tcp_pkt->th_ack));
should be
+ conn->offset -= (ntohl(tcp_pkt->th_ack) - 1);
(ntohl(tcp_pkt->th_ack) - 1) is the primary seq
+ tcp_pkt->th_ack = htonl(ntohl(tcp_pkt->th_ack) + conn->offset);
I will fix it.
Thanks
Zhang Chen
>
> .
>
--
Thanks
zhangchen
prev parent reply other threads:[~2016-07-04 8:59 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-07-02 6:22 [Qemu-devel] [RFC PATCH V2 0/3] filter-rewriter: introduce filter-rewriter Zhang Chen
2016-07-02 6:22 ` [Qemu-devel] [RFC PATCH V2 1/3] filter-rewriter: introduce filter-rewriter initialization Zhang Chen
2016-07-04 2:49 ` Jason Wang
2016-07-04 7:42 ` Zhang Chen
2016-07-04 8:28 ` Jason Wang
2016-07-02 6:22 ` [Qemu-devel] [RFC PATCH V2 2/3] filter-rewriter: track connection and parse packet Zhang Chen
2016-07-04 3:04 ` Jason Wang
2016-07-04 7:47 ` Zhang Chen
2016-07-04 8:29 ` Jason Wang
2016-07-02 6:22 ` [Qemu-devel] [RFC PATCH V2 3/3] filter-rewriter: rewrite tcp packet to keep secondary connection Zhang Chen
2016-07-04 3:16 ` Jason Wang
2016-07-04 8:59 ` Zhang Chen [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=577A257F.4040207@cn.fujitsu.com \
--to=zhangchen.fnst@cn.fujitsu.com \
--cc=dgilbert@redhat.com \
--cc=eddie.dong@intel.com \
--cc=jasowang@redhat.com \
--cc=lizhijian@cn.fujitsu.com \
--cc=qemu-devel@nongnu.org \
--cc=zhang.zhanghailiang@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.