All of lore.kernel.org
 help / color / mirror / Atom feed
From: Wei Xu <wexu@redhat.com>
To: Jason Wang <jasowang@redhat.com>, qemu-devel@nongnu.org
Cc: Wei Xu <wei@redhat.com>,
	victork@redhat.com, mst@redhat.com, yvugenfi@redhat.com,
	marcel@redhat.com, dfleytma@redhat.com
Subject: Re: [Qemu-devel] [RFC Patch v2 09/10] virtio-net rsc: Add IPv6 support
Date: Mon, 01 Feb 2016 16:49:42 +0800	[thread overview]
Message-ID: <56AF1C26.9010901@redhat.com> (raw)
In-Reply-To: <56AF05F1.4090902@redhat.com>



On 02/01/2016 03:14 PM, Jason Wang wrote:
>
> On 02/01/2016 02:13 AM, wexu@redhat.com wrote:
>> From: Wei Xu <wei@wei-thinkpad.nay.redhat.com>
>>
>> A few more stuffs should be included to support this
>> 1. Corresponding chain lookup
>> 2. Coalescing callback for the protocol chain
>> 3. Filter & Sanity Check.
>>
>> Signed-off-by: Wei Xu <wexu@redhat.com>
>> ---
>>   hw/net/virtio-net.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++-
>>   1 file changed, 102 insertions(+), 2 deletions(-)
>>
>> diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
>> index 9b44762..c9f6bfc 100644
>> --- a/hw/net/virtio-net.c
>> +++ b/hw/net/virtio-net.c
>> @@ -46,12 +46,19 @@
>>   #define TCP4_OFFSET (IP_OFFSET + sizeof(struct ip_header)) /* tcp4 header */
>>   #define TCP4_PORT_OFFSET TCP4_OFFSET        /* tcp4 port offset */
>>   #define IP4_ADDR_SIZE   8                   /* ipv4 saddr + daddr */
>> +
>> +#define IP6_ADDR_OFFSET (IP_OFFSET + 8)     /* ipv6 address start */
>> +#define TCP6_OFFSET (IP_OFFSET + sizeof(struct ip6_header)) /* tcp6 header */
>> +#define TCP6_PORT_OFFSET TCP6_OFFSET        /* tcp6 port offset */
>> +#define IP6_ADDR_SIZE   32                  /* ipv6 saddr + daddr */
>>   #define TCP_PORT_SIZE   4                   /* sport + dport */
>>   #define TCP_WINDOW      65535
>>   
>>   /* IPv4 max payload, 16 bits in the header */
>>   #define MAX_IP4_PAYLOAD  (65535 - sizeof(struct ip_header))
>>   
>> +/* ip6 max payload, payload in ipv6 don't include the  header */
>> +#define MAX_IP6_PAYLOAD  65535
>>   #define MAX_VIRTIO_IP_PAYLOAD  (65535 + IP_OFFSET)
>>   
>>   /* Purge coalesced packets timer interval */
>> @@ -1856,6 +1863,42 @@ static int32_t virtio_net_rsc_try_coalesce4(NetRscChain *chain,
>>                                       o_data, &o_ip->ip_len, MAX_IP4_PAYLOAD);
>>   }
>>   
>> +static int32_t virtio_net_rsc_try_coalesce6(NetRscChain *chain,
>> +                        NetRscSeg *seg, const uint8_t *buf, size_t size)
>> +{
>> +    uint16_t o_ip_len, n_ip_len;    /* len in ip header field */
>> +    uint16_t n_tcp_len, o_tcp_len;  /* tcp header len */
>> +    uint16_t o_data, n_data;        /* payload without virtio/eth/ip/tcp */
>> +    struct ip6_header *n_ip, *o_ip;
>> +    struct tcp_header *n_tcp, *o_tcp;
>> +
>> +    n_ip = (struct ip6_header *)(buf + IP_OFFSET);
>> +    n_ip_len = htons(n_ip->ip6_ctlun.ip6_un1.ip6_un1_plen);
>> +    n_tcp = (struct tcp_header *)(((uint8_t *)n_ip)\
>> +                                    + sizeof(struct ip6_header));
>> +    n_tcp_len = (htons(n_tcp->th_offset_flags) & 0xF000) >> 10;
>> +    n_data = n_ip_len - n_tcp_len;
>> +
>> +    o_ip = (struct ip6_header *)(seg->buf + IP_OFFSET);
>> +    o_ip_len = htons(o_ip->ip6_ctlun.ip6_un1.ip6_un1_plen);
>> +    o_tcp = (struct tcp_header *)(((uint8_t *)o_ip)\
>> +                                    + sizeof(struct ip6_header));
>> +    o_tcp_len = (htons(o_tcp->th_offset_flags) & 0xF000) >> 10;
>> +    o_data = o_ip_len - o_tcp_len;
> Like I've replied in previous mails, need a helper or just store
> pointers to both ip and tcp in seg.
OK.
>
>> +
>> +    if (memcmp(&n_ip->ip6_src, &o_ip->ip6_src, sizeof(struct in6_address))
>> +        || memcmp(&n_ip->ip6_dst, &o_ip->ip6_dst, sizeof(struct in6_address))
>> +        || (n_tcp->th_sport ^ o_tcp->th_sport)
>> +        || (n_tcp->th_dport ^ o_tcp->th_dport)) {
>> +            return RSC_NO_MATCH;
>> +    }
> And if you still want to handle coalescing in a layer style, better
> delay the check of ports to tcp function.
OK.
>
>> +
>> +    /* There is a difference between payload lenght in ipv4 and v6,
>> +       ip header is excluded in ipv6 */
>> +    return virtio_net_rsc_coalesce_tcp(chain, seg, buf,
>> +                       n_tcp, n_tcp_len, n_data, o_tcp, o_tcp_len, o_data,
>> +                       &o_ip->ip6_ctlun.ip6_un1.ip6_un1_plen, MAX_IP6_PAYLOAD);
>> +}
>>   
>>   /* Pakcets with 'SYN' should bypass, other flag should be sent after drain
>>    * to prevent out of order */
>> @@ -2015,6 +2058,59 @@ static size_t virtio_net_rsc_receive4(void *opq, NetClientState* nc,
>>                                      virtio_net_rsc_try_coalesce4);
>>   }
>>   
>> +static int32_t virtio_net_rsc_filter6(NetRscChain *chain, struct ip6_header *ip,
>> +                                      const uint8_t *buf, size_t size)
>> +{
>> +    uint16_t ip_len;
>> +
>> +    if (size < (TCP6_OFFSET + sizeof(tcp_header))) {
>> +        return RSC_BYPASS;
>> +    }
>> +
>> +    if (0x6 != (0xF & ip->ip6_ctlun.ip6_un1.ip6_un1_flow)) {
>> +        return RSC_BYPASS;
>> +    }
>> +
>> +    /* Both option and protocol is checked in this */
>> +    if (ip->ip6_ctlun.ip6_un1.ip6_un1_nxt != IPPROTO_TCP) {
>> +        return RSC_BYPASS;
>> +    }
>> +
>> +    /* Sanity check */
>> +    ip_len = htons(ip->ip6_ctlun.ip6_un1.ip6_un1_plen);
>> +    if (ip_len < sizeof(struct tcp_header)
>> +        || ip_len > (size - TCP6_OFFSET)) {
>> +        return RSC_BYPASS;
>> +    }
>> +
>> +    return 0;
> RSC_WANT?
Yes, the is new code and not tested.
>
>> +}
>> +
>> +static size_t virtio_net_rsc_receive6(void *opq, NetClientState* nc,
>> +                                      const uint8_t *buf, size_t size)
>> +{
>> +    int32_t ret;
>> +    NetRscChain *chain;
>> +    struct ip6_header *ip;
>> +
>> +    chain = (NetRscChain *)opq;
>> +    ip = (struct ip6_header *)(buf + IP_OFFSET);
>> +    if (RSC_WANT != virtio_net_rsc_filter6(chain, ip, buf, size)) {
>> +        return virtio_net_do_receive(nc, buf, size);
>> +    }
>> +
>> +    ret = virtio_net_rsc_parse_tcp_ctrl((uint8_t *)ip, sizeof(*ip));
> Same as IPv4, looks like a layer violation.
OK.
>
>> +    if (RSC_BYPASS == ret) {
>> +        return virtio_net_do_receive(nc, buf, size);
>> +    } else if (RSC_FINAL == ret) {
>> +        return virtio_net_rsc_drain_one(chain, nc, buf, size, IP6_ADDR_OFFSET,
>> +                        IP6_ADDR_SIZE, TCP6_PORT_OFFSET, TCP_PORT_SIZE);
>> +    }
>> +
>> +    return virtio_net_rsc_callback(chain, nc, buf, size,
>> +                                   virtio_net_rsc_try_coalesce6);
>> +}
>> +
>>   static NetRscChain *virtio_net_rsc_lookup_chain(NetClientState *nc,
>>                                                   uint16_t proto)
>>   {
>> @@ -2023,7 +2119,7 @@ static NetRscChain *virtio_net_rsc_lookup_chain(NetClientState *nc,
>>       NICState *nic;
>>   
>>       /* Only handle IPv4/6 */
>> -    if (proto != (uint16_t)ETH_P_IP) {
>> +    if ((proto != (uint16_t)ETH_P_IP) && (proto != (uint16_t)ETH_P_IPV6)) {
>>           return NULL;
>>       }
>>   
>> @@ -2044,7 +2140,11 @@ static NetRscChain *virtio_net_rsc_lookup_chain(NetClientState *nc,
>>       chain->proto = proto;
>>       chain->drain_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
>>                                         virtio_net_rsc_purge, chain);
>> -    chain->do_receive = virtio_net_rsc_receive4;
>> +    if (ETH_P_IP == proto) {
>> +        chain->do_receive = virtio_net_rsc_receive4;
>> +    } else {
>> +        chain->do_receive = virtio_net_rsc_receive6;
>> +    }
>>   
>>       QTAILQ_INIT(&chain->buffers);
>>       QTAILQ_INSERT_TAIL(&n->rsc_chains, chain, next);
>

  reply	other threads:[~2016-02-01  8:50 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-01-31 18:13 [Qemu-devel] [RFC v2 0/10] Support Receive-Segment-Offload(RSC) for WHQL test of Window guest wexu
2016-01-31 18:13 ` [Qemu-devel] [RFC Patch v2 01/10] virtio-net rsc: Data structure, 'Segment', 'Chain' and 'Status' wexu
2016-01-31 18:13 ` [Qemu-devel] [RFC Patch v2 02/10] virtio-net rsc: Initilize & Cleanup wexu
2016-01-31 18:47   ` Michael S. Tsirkin
2016-02-01  3:56     ` Wei Xu
2016-02-01  3:32   ` Jason Wang
2016-02-01  7:46     ` Wei Xu
2016-01-31 18:13 ` [Qemu-devel] [RFC Patch v2 03/10] virtio-net rsc: Chain Lookup, Packet Caching and Framework of IPv4 wexu
2016-01-31 18:50   ` Michael S. Tsirkin
2016-02-01  3:40     ` Wei Xu
2016-02-01  5:55   ` Jason Wang
2016-02-01  8:02     ` Wei Xu
2016-02-01  9:22       ` Jason Wang
2016-01-31 18:13 ` [Qemu-devel] [RFC Patch v2 04/10] virtio-net rsc: Detailed IPv4 and General TCP data coalescing wexu
2016-02-01  6:21   ` Jason Wang
2016-02-01  8:29     ` Wei Xu
2016-02-01  9:29       ` Jason Wang
2016-01-31 18:13 ` [Qemu-devel] [RFC Patch v2 05/10] virtio-net rsc: Create timer to drain the packets from the cache pool wexu
2016-02-01  6:28   ` Jason Wang
2016-02-01  8:39     ` Wei Xu
2016-02-01  9:31       ` Jason Wang
2016-02-01 13:31         ` Wei Xu
2016-01-31 18:13 ` [Qemu-devel] [RFC Patch v2 06/10] virtio-net rsc: IPv4 checksum wexu
2016-02-01  6:31   ` Jason Wang
2016-02-01  8:40     ` Wei Xu
2016-01-31 18:13 ` [Qemu-devel] [RFC Patch v2 07/10] virtio-net rsc: Checking TCP flag and drain specific connection packets wexu
2016-02-01  6:44   ` Jason Wang
2016-02-01  8:44     ` Wei Xu
2016-01-31 18:13 ` [Qemu-devel] [RFC Patch v2 08/10] virtio-net rsc: Sanity check & More bypass cases check wexu
2016-02-01  6:58   ` Jason Wang
2016-02-01  8:46     ` Wei Xu
2016-01-31 18:13 ` [Qemu-devel] [RFC Patch v2 09/10] virtio-net rsc: Add IPv6 support wexu
2016-02-01  7:14   ` Jason Wang
2016-02-01  8:49     ` Wei Xu [this message]
2016-01-31 18:13 ` [Qemu-devel] [RFC Patch v2 10/10] virtio-net rsc: Add Receive Segment Coalesce statistics wexu
2016-02-01  7:16   ` Jason Wang
2016-02-01  8:50     ` Wei Xu
2016-01-31 19:03 ` [Qemu-devel] [RFC v2 0/10] Support Receive-Segment-Offload(RSC) for WHQL test of Window guest Michael S. Tsirkin
2016-02-01  3:23 ` Jason Wang
2016-02-01  3:42   ` Wei Xu

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=56AF1C26.9010901@redhat.com \
    --to=wexu@redhat.com \
    --cc=dfleytma@redhat.com \
    --cc=jasowang@redhat.com \
    --cc=marcel@redhat.com \
    --cc=mst@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=victork@redhat.com \
    --cc=wei@redhat.com \
    --cc=yvugenfi@redhat.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.