diff mbox

[V3,05/10] net/net.c: Add vnet header length to SocketReadState

Message ID 1493372840-24551-6-git-send-email-zhangchen.fnst@cn.fujitsu.com (mailing list archive)
State New, archived
Headers show

Commit Message

Zhang Chen April 28, 2017, 9:47 a.m. UTC
Address Jason Wang's comments add vnet header length to SocketReadState.
So we change net_fill_rstate() to read
struct  {int size; int vnet_hdr_len; const uint8_t buf[];}.

Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
---
 include/net/net.h |  4 +++-
 net/net.c         | 24 ++++++++++++++++++++++--
 2 files changed, 25 insertions(+), 3 deletions(-)

Comments

Jason Wang May 2, 2017, 5:53 a.m. UTC | #1
On 2017年04月28日 17:47, Zhang Chen wrote:
> Address Jason Wang's comments add vnet header length to SocketReadState.

Instead of saying this, you can add "Suggested-by: Jason Wang 
<jasowang@redhat.com>" above your sign-off.

> So we change net_fill_rstate() to read
> struct  {int size; int vnet_hdr_len; const uint8_t buf[];}.

This makes me thinking about the backward compatibility. I think we'd 
better try to keep it as much as possible. E.g how about pack 
vnet_hdr_len into higher bits of size?

Thanks

>
> Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
> ---
>   include/net/net.h |  4 +++-
>   net/net.c         | 24 ++++++++++++++++++++++--
>   2 files changed, 25 insertions(+), 3 deletions(-)
>
> diff --git a/include/net/net.h b/include/net/net.h
> index 402d913..865cb98 100644
> --- a/include/net/net.h
> +++ b/include/net/net.h
> @@ -115,9 +115,11 @@ typedef struct NICState {
>   } NICState;
>   
>   struct SocketReadState {
> -    int state; /* 0 = getting length, 1 = getting data */
> +    /* 0 = getting length, 1 = getting vnet header length, 2 = getting data */
> +    int state;
>       uint32_t index;
>       uint32_t packet_len;
> +    uint32_t vnet_hdr_len;
>       uint8_t buf[NET_BUFSIZE];
>       SocketReadStateFinalize *finalize;
>   };
> diff --git a/net/net.c b/net/net.c
> index f69260f..5a6b5ac 100644
> --- a/net/net.c
> +++ b/net/net.c
> @@ -1639,8 +1639,12 @@ int net_fill_rstate(SocketReadState *rs, const uint8_t *buf, int size)
>       unsigned int l;
>   
>       while (size > 0) {
> -        /* reassemble a packet from the network */
> -        switch (rs->state) { /* 0 = getting length, 1 = getting data */
> +        /* Reassemble a packet from the network.
> +         * 0 = getting length.
> +         * 1 = getting vnet header length.
> +         * 2 = getting data.
> +         */
> +        switch (rs->state) {
>           case 0:
>               l = 4 - rs->index;
>               if (l > size) {
> @@ -1658,6 +1662,22 @@ int net_fill_rstate(SocketReadState *rs, const uint8_t *buf, int size)
>               }
>               break;
>           case 1:
> +            l = 4 - rs->index;
> +            if (l > size) {
> +                l = size;
> +            }
> +            memcpy(rs->buf + rs->index, buf, l);
> +            buf += l;
> +            size -= l;
> +            rs->index += l;
> +            if (rs->index == 4) {
> +                /* got vnet header length */
> +                rs->vnet_hdr_len = ntohl(*(uint32_t *)rs->buf);
> +                rs->index = 0;
> +                rs->state = 2;
> +            }
> +            break;
> +        case 2:
>               l = rs->packet_len - rs->index;
>               if (l > size) {
>                   l = size;
Zhang Chen May 3, 2017, 3:43 a.m. UTC | #2
On 05/02/2017 12:53 PM, Jason Wang wrote:
>
>
> On 2017年04月28日 17:47, Zhang Chen wrote:
>> Address Jason Wang's comments add vnet header length to SocketReadState.
>
> Instead of saying this, you can add "Suggested-by: Jason Wang 
> <jasowang@redhat.com>" above your sign-off.

OK.

>
>> So we change net_fill_rstate() to read
>> struct  {int size; int vnet_hdr_len; const uint8_t buf[];}.
>
> This makes me thinking about the backward compatibility. I think we'd 
> better try to keep it as much as possible. E.g how about pack 
> vnet_hdr_len into higher bits of size?
>

Do you means split uint32_t size to uint16_t size and uint16_t 
vnet_hdr_len ?
If yes, we also can't keep compatibility with old version.
Old code send a uint32_t size, we read it as uint16_t size is always wrong.

Thanks
Zhang Chen


> Thanks
>
>>
>> Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
>> ---
>>   include/net/net.h |  4 +++-
>>   net/net.c         | 24 ++++++++++++++++++++++--
>>   2 files changed, 25 insertions(+), 3 deletions(-)
>>
>> diff --git a/include/net/net.h b/include/net/net.h
>> index 402d913..865cb98 100644
>> --- a/include/net/net.h
>> +++ b/include/net/net.h
>> @@ -115,9 +115,11 @@ typedef struct NICState {
>>   } NICState;
>>     struct SocketReadState {
>> -    int state; /* 0 = getting length, 1 = getting data */
>> +    /* 0 = getting length, 1 = getting vnet header length, 2 = 
>> getting data */
>> +    int state;
>>       uint32_t index;
>>       uint32_t packet_len;
>> +    uint32_t vnet_hdr_len;
>>       uint8_t buf[NET_BUFSIZE];
>>       SocketReadStateFinalize *finalize;
>>   };
>> diff --git a/net/net.c b/net/net.c
>> index f69260f..5a6b5ac 100644
>> --- a/net/net.c
>> +++ b/net/net.c
>> @@ -1639,8 +1639,12 @@ int net_fill_rstate(SocketReadState *rs, const 
>> uint8_t *buf, int size)
>>       unsigned int l;
>>         while (size > 0) {
>> -        /* reassemble a packet from the network */
>> -        switch (rs->state) { /* 0 = getting length, 1 = getting data */
>> +        /* Reassemble a packet from the network.
>> +         * 0 = getting length.
>> +         * 1 = getting vnet header length.
>> +         * 2 = getting data.
>> +         */
>> +        switch (rs->state) {
>>           case 0:
>>               l = 4 - rs->index;
>>               if (l > size) {
>> @@ -1658,6 +1662,22 @@ int net_fill_rstate(SocketReadState *rs, const 
>> uint8_t *buf, int size)
>>               }
>>               break;
>>           case 1:
>> +            l = 4 - rs->index;
>> +            if (l > size) {
>> +                l = size;
>> +            }
>> +            memcpy(rs->buf + rs->index, buf, l);
>> +            buf += l;
>> +            size -= l;
>> +            rs->index += l;
>> +            if (rs->index == 4) {
>> +                /* got vnet header length */
>> +                rs->vnet_hdr_len = ntohl(*(uint32_t *)rs->buf);
>> +                rs->index = 0;
>> +                rs->state = 2;
>> +            }
>> +            break;
>> +        case 2:
>>               l = rs->packet_len - rs->index;
>>               if (l > size) {
>>                   l = size;
>
>
>
> .
>
Jason Wang May 3, 2017, 10:42 a.m. UTC | #3
On 2017年05月03日 11:43, Zhang Chen wrote:
>
>
> On 05/02/2017 12:53 PM, Jason Wang wrote:
>>
>>
>> On 2017年04月28日 17:47, Zhang Chen wrote:
>>> Address Jason Wang's comments add vnet header length to 
>>> SocketReadState.
>>
>> Instead of saying this, you can add "Suggested-by: Jason Wang 
>> <jasowang@redhat.com>" above your sign-off.
>
> OK.
>
>>
>>> So we change net_fill_rstate() to read
>>> struct  {int size; int vnet_hdr_len; const uint8_t buf[];}.
>>
>> This makes me thinking about the backward compatibility. I think we'd 
>> better try to keep it as much as possible. E.g how about pack 
>> vnet_hdr_len into higher bits of size?
>>
>
> Do you means split uint32_t size to uint16_t size and uint16_t 
> vnet_hdr_len ?
> If yes, we also can't keep compatibility with old version.
> Old code send a uint32_t size, we read it as uint16_t size is always 
> wrong.
>
> Thanks
> Zhang Chen

Consider it's unlikely to send or receive packet >= 64K, we can reuse 
higher bits (e.g highest 8 bits). Then we can still read uint32_t and 
then check its highest 8 bits. If it was zero, we know vnet header is 
zero, if not it could be read as vnet header length.

Thanks
Zhang Chen May 8, 2017, 3:47 a.m. UTC | #4
On 05/03/2017 06:42 PM, Jason Wang wrote:
>
>
> On 2017年05月03日 11:43, Zhang Chen wrote:
>>
>>
>> On 05/02/2017 12:53 PM, Jason Wang wrote:
>>>
>>>
>>> On 2017年04月28日 17:47, Zhang Chen wrote:
>>>> Address Jason Wang's comments add vnet header length to 
>>>> SocketReadState.
>>>
>>> Instead of saying this, you can add "Suggested-by: Jason Wang 
>>> <jasowang@redhat.com>" above your sign-off.
>>
>> OK.
>>
>>>
>>>> So we change net_fill_rstate() to read
>>>> struct  {int size; int vnet_hdr_len; const uint8_t buf[];}.
>>>
>>> This makes me thinking about the backward compatibility. I think 
>>> we'd better try to keep it as much as possible. E.g how about pack 
>>> vnet_hdr_len into higher bits of size?
>>>
>>
>> Do you means split uint32_t size to uint16_t size and uint16_t 
>> vnet_hdr_len ?
>> If yes, we also can't keep compatibility with old version.
>> Old code send a uint32_t size, we read it as uint16_t size is always 
>> wrong.
>>
>> Thanks
>> Zhang Chen
>
> Consider it's unlikely to send or receive packet >= 64K, we can reuse 
> higher bits (e.g highest 8 bits). Then we can still read uint32_t and 
> then check its highest 8 bits. If it was zero, we know vnet header is 
> zero, if not it could be read as vnet header length.

I got your point, but in this way, packet size must < 64K, if size >=64K 
we still can't maintain the backward compatibility,
For the packet sender that didn't know the potential packet size limit, 
I think we should make code explicitly declared like
currently code. Otherwise we will make other people confused and make 
code difficult to maintain.

Thanks
Zhang Chen


>
> Thanks
>
>
>
> .
>
Jason Wang May 9, 2017, 2:40 a.m. UTC | #5
On 2017年05月08日 11:47, Zhang Chen wrote:
>
>
> On 05/03/2017 06:42 PM, Jason Wang wrote:
>>
>>
>> On 2017年05月03日 11:43, Zhang Chen wrote:
>>>
>>>
>>> On 05/02/2017 12:53 PM, Jason Wang wrote:
>>>>
>>>>
>>>> On 2017年04月28日 17:47, Zhang Chen wrote:
>>>>> Address Jason Wang's comments add vnet header length to 
>>>>> SocketReadState.
>>>>
>>>> Instead of saying this, you can add "Suggested-by: Jason Wang 
>>>> <jasowang@redhat.com>" above your sign-off.
>>>
>>> OK.
>>>
>>>>
>>>>> So we change net_fill_rstate() to read
>>>>> struct  {int size; int vnet_hdr_len; const uint8_t buf[];}.
>>>>
>>>> This makes me thinking about the backward compatibility. I think 
>>>> we'd better try to keep it as much as possible. E.g how about pack 
>>>> vnet_hdr_len into higher bits of size?
>>>>
>>>
>>> Do you means split uint32_t size to uint16_t size and uint16_t 
>>> vnet_hdr_len ?
>>> If yes, we also can't keep compatibility with old version.
>>> Old code send a uint32_t size, we read it as uint16_t size is always 
>>> wrong.
>>>
>>> Thanks
>>> Zhang Chen
>>
>> Consider it's unlikely to send or receive packet >= 64K, we can reuse 
>> higher bits (e.g highest 8 bits). Then we can still read uint32_t and 
>> then check its highest 8 bits. If it was zero, we know vnet header is 
>> zero, if not it could be read as vnet header length.
>
> I got your point, but in this way, packet size must < 64K, if size 
> >=64K we still can't maintain the backward compatibility,
> For the packet sender that didn't know the potential packet size 
> limit, I think we should make code explicitly declared like
> currently code. Otherwise we will make other people confused and make 
> code difficult to maintain.
>
> Thanks
> Zhang Chen
>

Yes, this is an possible issue in the future. Rethink about this, what 
if we just compare vnet header? Is there any issue of doing this? 
(Sorry, I remember this is a reason, but forget now).

Thanks
Zhang Chen May 9, 2017, 4:03 a.m. UTC | #6
On 05/09/2017 10:40 AM, Jason Wang wrote:
>
>
> On 2017年05月08日 11:47, Zhang Chen wrote:
>>
>>
>> On 05/03/2017 06:42 PM, Jason Wang wrote:
>>>
>>>
>>> On 2017年05月03日 11:43, Zhang Chen wrote:
>>>>
>>>>
>>>> On 05/02/2017 12:53 PM, Jason Wang wrote:
>>>>>
>>>>>
>>>>> On 2017年04月28日 17:47, Zhang Chen wrote:
>>>>>> Address Jason Wang's comments add vnet header length to 
>>>>>> SocketReadState.
>>>>>
>>>>> Instead of saying this, you can add "Suggested-by: Jason Wang 
>>>>> <jasowang@redhat.com>" above your sign-off.
>>>>
>>>> OK.
>>>>
>>>>>
>>>>>> So we change net_fill_rstate() to read
>>>>>> struct  {int size; int vnet_hdr_len; const uint8_t buf[];}.
>>>>>
>>>>> This makes me thinking about the backward compatibility. I think 
>>>>> we'd better try to keep it as much as possible. E.g how about pack 
>>>>> vnet_hdr_len into higher bits of size?
>>>>>
>>>>
>>>> Do you means split uint32_t size to uint16_t size and uint16_t 
>>>> vnet_hdr_len ?
>>>> If yes, we also can't keep compatibility with old version.
>>>> Old code send a uint32_t size, we read it as uint16_t size is 
>>>> always wrong.
>>>>
>>>> Thanks
>>>> Zhang Chen
>>>
>>> Consider it's unlikely to send or receive packet >= 64K, we can 
>>> reuse higher bits (e.g highest 8 bits). Then we can still read 
>>> uint32_t and then check its highest 8 bits. If it was zero, we know 
>>> vnet header is zero, if not it could be read as vnet header length.
>>
>> I got your point, but in this way, packet size must < 64K, if size 
>> >=64K we still can't maintain the backward compatibility,
>> For the packet sender that didn't know the potential packet size 
>> limit, I think we should make code explicitly declared like
>> currently code. Otherwise we will make other people confused and make 
>> code difficult to maintain.
>>
>> Thanks
>> Zhang Chen
>>
>
> Yes, this is an possible issue in the future. Rethink about this, what 
> if we just compare vnet header? Is there any issue of doing this? 
> (Sorry, I remember this is a reason, but forget now).

Yes, we can compare all packet with vnet header, the compare performance 
is very low. but we can't parse raw packet to tcp/udp/icmp packet, 
because we didn't know the vnet_hdr_len as the offset.

Thanks
Zhang Chen

>
> Thanks
>
>
> .
>
Jason Wang May 9, 2017, 5:36 a.m. UTC | #7
On 2017年05月09日 12:03, Zhang Chen wrote:
>
>
> On 05/09/2017 10:40 AM, Jason Wang wrote:
>>
>>
>> On 2017年05月08日 11:47, Zhang Chen wrote:
>>>
>>>
>>> On 05/03/2017 06:42 PM, Jason Wang wrote:
>>>>
>>>>
>>>> On 2017年05月03日 11:43, Zhang Chen wrote:
>>>>>
>>>>>
>>>>> On 05/02/2017 12:53 PM, Jason Wang wrote:
>>>>>>
>>>>>>
>>>>>> On 2017年04月28日 17:47, Zhang Chen wrote:
>>>>>>> Address Jason Wang's comments add vnet header length to 
>>>>>>> SocketReadState.
>>>>>>
>>>>>> Instead of saying this, you can add "Suggested-by: Jason Wang 
>>>>>> <jasowang@redhat.com>" above your sign-off.
>>>>>
>>>>> OK.
>>>>>
>>>>>>
>>>>>>> So we change net_fill_rstate() to read
>>>>>>> struct  {int size; int vnet_hdr_len; const uint8_t buf[];}.
>>>>>>
>>>>>> This makes me thinking about the backward compatibility. I think 
>>>>>> we'd better try to keep it as much as possible. E.g how about 
>>>>>> pack vnet_hdr_len into higher bits of size?
>>>>>>
>>>>>
>>>>> Do you means split uint32_t size to uint16_t size and uint16_t 
>>>>> vnet_hdr_len ?
>>>>> If yes, we also can't keep compatibility with old version.
>>>>> Old code send a uint32_t size, we read it as uint16_t size is 
>>>>> always wrong.
>>>>>
>>>>> Thanks
>>>>> Zhang Chen
>>>>
>>>> Consider it's unlikely to send or receive packet >= 64K, we can 
>>>> reuse higher bits (e.g highest 8 bits). Then we can still read 
>>>> uint32_t and then check its highest 8 bits. If it was zero, we know 
>>>> vnet header is zero, if not it could be read as vnet header length.
>>>
>>> I got your point, but in this way, packet size must < 64K, if size 
>>> >=64K we still can't maintain the backward compatibility,
>>> For the packet sender that didn't know the potential packet size 
>>> limit, I think we should make code explicitly declared like
>>> currently code. Otherwise we will make other people confused and 
>>> make code difficult to maintain.
>>>
>>> Thanks
>>> Zhang Chen
>>>
>>
>> Yes, this is an possible issue in the future. Rethink about this, 
>> what if we just compare vnet header? Is there any issue of doing 
>> this? (Sorry, I remember this is a reason, but forget now).
>
> Yes, we can compare all packet with vnet header, the compare 
> performance is very low. but we can't parse raw packet to tcp/udp/icmp 
> packet, because we didn't know the vnet_hdr_len as the offset.
>
> Thanks
> Zhang Chen

Aha, so I think it's time to use the new format but:

- probably need a new option to enable this support for filter
- let's don't touch socket backend, and make it still can work with 
filters whose vnet_hder is off

Thanks

>
>>
>> Thanks
>>
>>
>> .
>>
>
Zhang Chen May 9, 2017, 6:59 a.m. UTC | #8
On 05/09/2017 01:36 PM, Jason Wang wrote:
>
>
> On 2017年05月09日 12:03, Zhang Chen wrote:
>>
>>
>> On 05/09/2017 10:40 AM, Jason Wang wrote:
>>>
>>>
>>> On 2017年05月08日 11:47, Zhang Chen wrote:
>>>>
>>>>
>>>> On 05/03/2017 06:42 PM, Jason Wang wrote:
>>>>>
>>>>>
>>>>> On 2017年05月03日 11:43, Zhang Chen wrote:
>>>>>>
>>>>>>
>>>>>> On 05/02/2017 12:53 PM, Jason Wang wrote:
>>>>>>>
>>>>>>>
>>>>>>> On 2017年04月28日 17:47, Zhang Chen wrote:
>>>>>>>> Address Jason Wang's comments add vnet header length to 
>>>>>>>> SocketReadState.
>>>>>>>
>>>>>>> Instead of saying this, you can add "Suggested-by: Jason Wang 
>>>>>>> <jasowang@redhat.com>" above your sign-off.
>>>>>>
>>>>>> OK.
>>>>>>
>>>>>>>
>>>>>>>> So we change net_fill_rstate() to read
>>>>>>>> struct  {int size; int vnet_hdr_len; const uint8_t buf[];}.
>>>>>>>
>>>>>>> This makes me thinking about the backward compatibility. I think 
>>>>>>> we'd better try to keep it as much as possible. E.g how about 
>>>>>>> pack vnet_hdr_len into higher bits of size?
>>>>>>>
>>>>>>
>>>>>> Do you means split uint32_t size to uint16_t size and uint16_t 
>>>>>> vnet_hdr_len ?
>>>>>> If yes, we also can't keep compatibility with old version.
>>>>>> Old code send a uint32_t size, we read it as uint16_t size is 
>>>>>> always wrong.
>>>>>>
>>>>>> Thanks
>>>>>> Zhang Chen
>>>>>
>>>>> Consider it's unlikely to send or receive packet >= 64K, we can 
>>>>> reuse higher bits (e.g highest 8 bits). Then we can still read 
>>>>> uint32_t and then check its highest 8 bits. If it was zero, we 
>>>>> know vnet header is zero, if not it could be read as vnet header 
>>>>> length.
>>>>
>>>> I got your point, but in this way, packet size must < 64K, if size 
>>>> >=64K we still can't maintain the backward compatibility,
>>>> For the packet sender that didn't know the potential packet size 
>>>> limit, I think we should make code explicitly declared like
>>>> currently code. Otherwise we will make other people confused and 
>>>> make code difficult to maintain.
>>>>
>>>> Thanks
>>>> Zhang Chen
>>>>
>>>
>>> Yes, this is an possible issue in the future. Rethink about this, 
>>> what if we just compare vnet header? Is there any issue of doing 
>>> this? (Sorry, I remember this is a reason, but forget now).
>>
>> Yes, we can compare all packet with vnet header, the compare 
>> performance is very low. but we can't parse raw packet to 
>> tcp/udp/icmp packet, because we didn't know the vnet_hdr_len as the 
>> offset.
>>
>> Thanks
>> Zhang Chen
>
> Aha, so I think it's time to use the new format but:
>
> - probably need a new option to enable this support for filter

Do you means we should add the new option for every filter object like that:
Now:
-object filter-mirror,id=m0,netdev=hn0,queue=tx,outdev=mirror0
Feature:
-object 
filter-mirror,id=m0,netdev=hn0,queue=tx,outdev=mirror0,has_vnet_hdr_len=on

And colo-compare also need this option to get the vnet_hdr_len.


> - let's don't touch socket backend, and make it still can work with 
> filters whose vnet_hder is off

OK, Maybe we can add a new variable in net_fill_rstate().

Thanks
Zhang Chen

>
> Thanks
>
>>
>>>
>>> Thanks
>>>
>>>
>>> .
>>>
>>
>
>
>
> .
>
Jason Wang May 9, 2017, 7:36 a.m. UTC | #9
On 2017年05月09日 14:59, Zhang Chen wrote:
>
>
> On 05/09/2017 01:36 PM, Jason Wang wrote:
>>
>>
>> On 2017年05月09日 12:03, Zhang Chen wrote:
>>>
>>>
>>> On 05/09/2017 10:40 AM, Jason Wang wrote:
>>>>
>>>>
>>>> On 2017年05月08日 11:47, Zhang Chen wrote:
>>>>>
>>>>>
>>>>> On 05/03/2017 06:42 PM, Jason Wang wrote:
>>>>>>
>>>>>>
>>>>>> On 2017年05月03日 11:43, Zhang Chen wrote:
>>>>>>>
>>>>>>>
>>>>>>> On 05/02/2017 12:53 PM, Jason Wang wrote:
>>>>>>>>
>>>>>>>>
>>>>>>>> On 2017年04月28日 17:47, Zhang Chen wrote:
>>>>>>>>> Address Jason Wang's comments add vnet header length to 
>>>>>>>>> SocketReadState.
>>>>>>>>
>>>>>>>> Instead of saying this, you can add "Suggested-by: Jason Wang 
>>>>>>>> <jasowang@redhat.com>" above your sign-off.
>>>>>>>
>>>>>>> OK.
>>>>>>>
>>>>>>>>
>>>>>>>>> So we change net_fill_rstate() to read
>>>>>>>>> struct  {int size; int vnet_hdr_len; const uint8_t buf[];}.
>>>>>>>>
>>>>>>>> This makes me thinking about the backward compatibility. I 
>>>>>>>> think we'd better try to keep it as much as possible. E.g how 
>>>>>>>> about pack vnet_hdr_len into higher bits of size?
>>>>>>>>
>>>>>>>
>>>>>>> Do you means split uint32_t size to uint16_t size and uint16_t 
>>>>>>> vnet_hdr_len ?
>>>>>>> If yes, we also can't keep compatibility with old version.
>>>>>>> Old code send a uint32_t size, we read it as uint16_t size is 
>>>>>>> always wrong.
>>>>>>>
>>>>>>> Thanks
>>>>>>> Zhang Chen
>>>>>>
>>>>>> Consider it's unlikely to send or receive packet >= 64K, we can 
>>>>>> reuse higher bits (e.g highest 8 bits). Then we can still read 
>>>>>> uint32_t and then check its highest 8 bits. If it was zero, we 
>>>>>> know vnet header is zero, if not it could be read as vnet header 
>>>>>> length.
>>>>>
>>>>> I got your point, but in this way, packet size must < 64K, if size 
>>>>> >=64K we still can't maintain the backward compatibility,
>>>>> For the packet sender that didn't know the potential packet size 
>>>>> limit, I think we should make code explicitly declared like
>>>>> currently code. Otherwise we will make other people confused and 
>>>>> make code difficult to maintain.
>>>>>
>>>>> Thanks
>>>>> Zhang Chen
>>>>>
>>>>
>>>> Yes, this is an possible issue in the future. Rethink about this, 
>>>> what if we just compare vnet header? Is there any issue of doing 
>>>> this? (Sorry, I remember this is a reason, but forget now).
>>>
>>> Yes, we can compare all packet with vnet header, the compare 
>>> performance is very low. but we can't parse raw packet to 
>>> tcp/udp/icmp packet, because we didn't know the vnet_hdr_len as the 
>>> offset.
>>>
>>> Thanks
>>> Zhang Chen
>>
>> Aha, so I think it's time to use the new format but:
>>
>> - probably need a new option to enable this support for filter
>
> Do you means we should add the new option for every filter object like 
> that:
> Now:
> -object filter-mirror,id=m0,netdev=hn0,queue=tx,outdev=mirror0
> Feature:
> -object 
> filter-mirror,id=m0,netdev=hn0,queue=tx,outdev=mirror0,has_vnet_hdr_len=on
>
> And colo-compare also need this option to get the vnet_hdr_len.

Yes, and you can use make it short like "vnet_hdr".

>
>
>> - let's don't touch socket backend, and make it still can work with 
>> filters whose vnet_hder is off
>
> OK, Maybe we can add a new variable in net_fill_rstate().

Right.

Thanks

>
> Thanks
> Zhang Chen
>
>>
>> Thanks
>>
>>>
>>>>
>>>> Thanks
>>>>
>>>>
>>>> .
>>>>
>>>
>>
>>
>>
>> .
>>
>
diff mbox

Patch

diff --git a/include/net/net.h b/include/net/net.h
index 402d913..865cb98 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -115,9 +115,11 @@  typedef struct NICState {
 } NICState;
 
 struct SocketReadState {
-    int state; /* 0 = getting length, 1 = getting data */
+    /* 0 = getting length, 1 = getting vnet header length, 2 = getting data */
+    int state;
     uint32_t index;
     uint32_t packet_len;
+    uint32_t vnet_hdr_len;
     uint8_t buf[NET_BUFSIZE];
     SocketReadStateFinalize *finalize;
 };
diff --git a/net/net.c b/net/net.c
index f69260f..5a6b5ac 100644
--- a/net/net.c
+++ b/net/net.c
@@ -1639,8 +1639,12 @@  int net_fill_rstate(SocketReadState *rs, const uint8_t *buf, int size)
     unsigned int l;
 
     while (size > 0) {
-        /* reassemble a packet from the network */
-        switch (rs->state) { /* 0 = getting length, 1 = getting data */
+        /* Reassemble a packet from the network.
+         * 0 = getting length.
+         * 1 = getting vnet header length.
+         * 2 = getting data.
+         */
+        switch (rs->state) {
         case 0:
             l = 4 - rs->index;
             if (l > size) {
@@ -1658,6 +1662,22 @@  int net_fill_rstate(SocketReadState *rs, const uint8_t *buf, int size)
             }
             break;
         case 1:
+            l = 4 - rs->index;
+            if (l > size) {
+                l = size;
+            }
+            memcpy(rs->buf + rs->index, buf, l);
+            buf += l;
+            size -= l;
+            rs->index += l;
+            if (rs->index == 4) {
+                /* got vnet header length */
+                rs->vnet_hdr_len = ntohl(*(uint32_t *)rs->buf);
+                rs->index = 0;
+                rs->state = 2;
+            }
+            break;
+        case 2:
             l = rs->packet_len - rs->index;
             if (l > size) {
                 l = size;