From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43926) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bEsgW-0006Sa-WE for qemu-devel@nongnu.org; Mon, 20 Jun 2016 02:27:50 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bEsgS-0005Xq-N1 for qemu-devel@nongnu.org; Mon, 20 Jun 2016 02:27:47 -0400 Received: from mx1.redhat.com ([209.132.183.28]:44204) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bEsgS-0005Xm-Ez for qemu-devel@nongnu.org; Mon, 20 Jun 2016 02:27:44 -0400 References: <1465902912-27527-1-git-send-email-zhangchen.fnst@cn.fujitsu.com> <1465902912-27527-4-git-send-email-zhangchen.fnst@cn.fujitsu.com> From: Jason Wang Message-ID: <57678CDA.7020700@redhat.com> Date: Mon, 20 Jun 2016 14:27:38 +0800 MIME-Version: 1.0 In-Reply-To: <1465902912-27527-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 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" , zhanghailiang , "Dr . David Alan Gilbert" , Yang Hongyang On 2016=E5=B9=B406=E6=9C=8814=E6=97=A5 19:15, Zhang Chen wrote: > We will rewrite tcp packet secondary received and sent. More verbose please. E.g which fields were rewrote and why. > Signed-off-by: Zhang Chen > Signed-off-by: Li Zhijian > Signed-off-by: Wen Congyang > --- > net/filter-rewriter.c | 94 ++++++++++++++++++++++++++++++++++++++++++= +++++++-- > trace-events | 3 ++ > 2 files changed, 95 insertions(+), 2 deletions(-) > > diff --git a/net/filter-rewriter.c b/net/filter-rewriter.c > index 12f88c5..86a2f53 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,75 @@ static int is_tcp_packet(Packet *pkt) > } > } > =20 > +static int handle_primary_tcp_pkt(NetFilterState *nf, > + Connection *conn, > + Packet *pkt) > +{ > + struct tcphdr *tcp_pkt; > + > + tcp_pkt =3D (struct tcphdr *)pkt->transport_layer; > + > + if (trace_event_get_state(TRACE_COLO_FILTER_REWRITER_DEBUG)) { Why not use tracepoints directly? > + char *sdebug, *ddebug; > + sdebug =3D strdup(inet_ntoa(pkt->ip->ip_src)); > + ddebug =3D strdup(inet_ntoa(pkt->ip->ip_dst)); > + fprintf(stderr, "%s: src/dst: %s/%s p: seq/ack=3D%u/%u" > + " flags=3D%x\n", __func__, sdebug, ddebug, > + ntohl(tcp_pkt->th_seq), ntohl(tcp_pkt->th_ack), > + tcp_pkt->th_flags); > + g_free(sdebug); > + g_free(ddebug); > + } > + > + if (((tcp_pkt->th_flags & (TH_ACK | TH_SYN)) =3D=3D TH_ACK)) { > + /* save primary colo tcp packet seq */ > + conn->primary_seq =3D ntohl(tcp_pkt->th_ack) - 1; Looks like primary_seq will only be updated during handshake, I wonder=20 how this works. > + > + /* adjust tcp seq to make secondary guest handle it */ > + tcp_pkt->th_ack =3D htonl(conn->secondary_seq + 1); I'm not sure this can work for all cases. I believe we should also=20 rewrite seq here. And to me, a better approach is to track the offset of=20 seq between pri and sec during handshake and rewrite both ack and seq=20 based on this offset. > + net_checksum_calculate((uint8_t *)pkt->data, pkt->size); > + } > + > + return 0; > +} > + > +static int handle_secondary_tcp_pkt(NetFilterState *nf, > + Connection *conn, > + Packet *pkt) > +{ > + struct tcphdr *tcp_pkt; > + > + 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)); > + printf("handle_secondary_tcp_pkt conn->secondary_seq =3D %u,\n= ", > + conn->secondary_seq); > + printf("handle_secondary_tcp_pkt conn->primary_seq =3D %u,\n", > + conn->primary_seq); > + fprintf(stderr, "%s: src/dst: %s/%s p: seq/ack=3D%u/%u" > + " flags=3D%x\n", __func__, sdebug, ddebug, > + ntohl(tcp_pkt->th_seq), ntohl(tcp_pkt->th_ack), > + tcp_pkt->th_flags); > + g_free(sdebug); > + g_free(ddebug); > + } > + > + if (((tcp_pkt->th_flags & (TH_ACK | TH_SYN)) =3D=3D (TH_ACK | TH_S= YN))) { > + /* save client's seq */ > + conn->secondary_seq =3D ntohl(tcp_pkt->th_seq); > + } > + > + if ((tcp_pkt->th_flags & (TH_ACK | TH_SYN)) =3D=3D TH_ACK) { > + tcp_pkt->th_seq =3D htonl(conn->primary_seq + 1); > + net_checksum_calculate((uint8_t *)pkt->data, pkt->size); > + } > + > + return 0; > +} > + > static ssize_t colo_rewriter_receive_iov(NetFilterState *nf, > NetClientState *sender, > unsigned flags, > @@ -106,10 +176,30 @@ static ssize_t colo_rewriter_receive_iov(NetFilte= rState *nf, > if (sender =3D=3D nf->netdev) { > /* This packet is sent by netdev itself */ > /* NET_FILTER_DIRECTION_TX */ > - /* handle_primary_tcp_pkt */ > + if (!handle_primary_tcp_pkt(nf, conn, pkt)) { > + qemu_net_queue_send(s->incoming_queue, sender, 0, > + (const uint8_t *)pkt->data, pkt->size, NULL); > + packet_destroy(pkt, NULL); > + pkt =3D NULL; > + /* > + * We block the packet here,after rewrite pkt > + * and will send it > + */ > + return 1; > + } > } else { > /* NET_FILTER_DIRECTION_RX */ > - /* handle_secondary_tcp_pkt */ > + if (!handle_secondary_tcp_pkt(nf, conn, pkt)) { > + qemu_net_queue_send(s->incoming_queue, sender, 0, > + (const uint8_t *)pkt->data, pkt->size, NULL); > + packet_destroy(pkt, NULL); > + pkt =3D NULL; > + /* > + * We block the packet here,after rewrite pkt > + * and will send it > + */ > + return 1; > + } > } > } > =20 > diff --git a/trace-events b/trace-events > index 6686cdf..5d798c6 100644 > --- a/trace-events > +++ b/trace-events > @@ -1927,3 +1927,6 @@ colo_compare_icmp_miscompare_mtu(const char *sta,= int size) ": %s %d" > colo_compare_ip_info(int psize, const char *sta, const char *stb, int= ssize, const char *stc, const char *std) "ppkt size =3D %d, ip_src =3D %= s, ip_dst =3D %s, spkt size =3D %d, ip_src =3D %s, ip_dst =3D %s" > colo_old_packet_check_found(int64_t old_time) "%" PRId64 > colo_compare_miscompare(void) "" > + > +# net/filter-rewriter.c > +colo_filter_rewriter_debug(void) ""