diff mbox series

net/colo: check vnet_hdr_support flag when using virtio-net

Message ID 20210806060837.62774-1-tao3.xu@intel.com (mailing list archive)
State New, archived
Headers show
Series net/colo: check vnet_hdr_support flag when using virtio-net | expand

Commit Message

Tao Xu Aug. 6, 2021, 6:08 a.m. UTC
When COLO use only one vnet_hdr_support parameter between
COLO network filter(filter-mirror, filter-redirector or
filter-rewriter and colo-compare, packet will not be parsed
correctly. Acquire network driver related to COLO, if it is
nirtio-net, check vnet_hdr_support flag of COLO network filter
and colo-compare.

Signed-off-by: Tao Xu <tao3.xu@intel.com>
Signed-off-by: Zhang Chen <chen.zhang@intel.com>
---
 net/colo-compare.c    | 25 +++++++++++++++++++++++++
 net/colo.c            | 20 ++++++++++++++++++++
 net/colo.h            |  4 ++++
 net/filter-mirror.c   | 17 +++++++++++++++++
 net/filter-rewriter.c |  9 +++++++++
 5 files changed, 75 insertions(+)

Comments

Tao Xu Aug. 13, 2021, 5:13 a.m. UTC | #1
Hi Jason,

Do you have any comments on this patch?

Thank you!

On 8/6/2021 2:08 PM, Xu, Tao3 wrote:
> When COLO use only one vnet_hdr_support parameter between
> COLO network filter(filter-mirror, filter-redirector or
> filter-rewriter and colo-compare, packet will not be parsed
> correctly. Acquire network driver related to COLO, if it is
> nirtio-net, check vnet_hdr_support flag of COLO network filter
> and colo-compare.
> 
> Signed-off-by: Tao Xu <tao3.xu@intel.com>
> Signed-off-by: Zhang Chen <chen.zhang@intel.com>
> ---
>   net/colo-compare.c    | 25 +++++++++++++++++++++++++
>   net/colo.c            | 20 ++++++++++++++++++++
>   net/colo.h            |  4 ++++
>   net/filter-mirror.c   | 17 +++++++++++++++++
>   net/filter-rewriter.c |  9 +++++++++
>   5 files changed, 75 insertions(+)
> 
> diff --git a/net/colo-compare.c b/net/colo-compare.c
> index b100e7b51f..bc1cc951c0 100644
> --- a/net/colo-compare.c
> +++ b/net/colo-compare.c
> @@ -838,6 +838,23 @@ static int compare_chr_can_read(void *opaque)
>       return COMPARE_READ_LEN_MAX;
>   }
>   
> +/* check vnet_hdr_support flag through COLO filter modules */
> +static int colo_vnet_driver_check(void *opaque, QemuOpts *opts, Error **errp)
> +{
> +    const char *colo_obj_type;
> +
> +    colo_obj_type = qemu_opt_get(opts, "qom-type");
> +
> +    if (strcmp(colo_obj_type, "filter-mirror") == 0 ||
> +        strcmp(colo_obj_type, "filter-redirector") == 0 ||
> +        strcmp(colo_obj_type, "filter-rewriter") == 0) {
> +        if (qemu_opt_get(opts, "vnet_hdr_support")) {
> +            return 1;
> +        }
> +    }
> +    return 0;
> +}
> +
>   /*
>    * Called from the main thread on the primary for packets
>    * arriving over the socket from the primary.
> @@ -1289,6 +1306,14 @@ static void colo_compare_complete(UserCreatable *uc, Error **errp)
>           return;
>       }
>   
> +    if (!s->vnet_hdr &&
> +        qemu_opts_foreach(qemu_find_opts("object"),
> +                          colo_vnet_driver_check, NULL, NULL)) {
> +        error_setg(errp, "colo compare needs 'vnet_hdr_support' "
> +                   "when colo filter modules work on virtio-net");
> +        return;
> +    }
> +
>       net_socket_rs_init(&s->pri_rs, compare_pri_rs_finalize, s->vnet_hdr);
>       net_socket_rs_init(&s->sec_rs, compare_sec_rs_finalize, s->vnet_hdr);
>   
> diff --git a/net/colo.c b/net/colo.c
> index 3a3e6e89a0..4a03780f45 100644
> --- a/net/colo.c
> +++ b/net/colo.c
> @@ -243,3 +243,23 @@ bool connection_has_tracked(GHashTable *connection_track_table,
>   
>       return conn ? true : false;
>   }
> +
> +/* check the network driver related to COLO, return 1 if it is virtio-net */
> +int vnet_driver_check(void *opaque, QemuOpts *opts, Error **errp)
> +{
> +    const char *driver_type, *netdev_from_driver;
> +    char *netdev_from_filter = (char *)opaque;
> +
> +    driver_type = qemu_opt_get(opts, "driver");
> +    netdev_from_driver = qemu_opt_get(opts, "netdev");
> +
> +    if (!driver_type || !netdev_from_driver || !netdev_from_filter) {
> +        return 0;
> +    }
> +
> +    if (g_str_has_prefix(driver_type, "virtio-net") &&
> +        strcmp(netdev_from_driver, netdev_from_filter) == 0) {
> +        return 1;
> +    }
> +    return 0;
> +}
> diff --git a/net/colo.h b/net/colo.h
> index d91cd245c4..d401fc76b6 100644
> --- a/net/colo.h
> +++ b/net/colo.h
> @@ -18,6 +18,9 @@
>   #include "qemu/jhash.h"
>   #include "qemu/timer.h"
>   #include "net/eth.h"
> +#include "qemu/option.h"
> +#include "qemu/option_int.h"
> +#include "qemu/config-file.h"
>   
>   #define HASHTABLE_MAX_SIZE 16384
>   
> @@ -104,5 +107,6 @@ Packet *packet_new(const void *data, int size, int vnet_hdr_len);
>   Packet *packet_new_nocopy(void *data, int size, int vnet_hdr_len);
>   void packet_destroy(void *opaque, void *user_data);
>   void packet_destroy_partial(void *opaque, void *user_data);
> +int vnet_driver_check(void *opaque, QemuOpts *opts, Error **errp);
>   
>   #endif /* NET_COLO_H */
> diff --git a/net/filter-mirror.c b/net/filter-mirror.c
> index f20240cc9f..b8b3f2fe1d 100644
> --- a/net/filter-mirror.c
> +++ b/net/filter-mirror.c
> @@ -12,6 +12,7 @@
>   #include "qemu/osdep.h"
>   #include "net/filter.h"
>   #include "net/net.h"
> +#include "net/colo.h"
>   #include "qapi/error.h"
>   #include "qom/object.h"
>   #include "qemu/main-loop.h"
> @@ -224,6 +225,14 @@ static void filter_mirror_setup(NetFilterState *nf, Error **errp)
>           return;
>       }
>   
> +    if (!s->vnet_hdr &&
> +        qemu_opts_foreach(qemu_find_opts("device"),
> +                         vnet_driver_check, nf->netdev_id, NULL)) {
> +        error_setg(errp, "filter mirror needs 'vnet_hdr_support' "
> +                   "when network driver is virtio-net");
> +        return;
> +    }
> +
>       qemu_chr_fe_init(&s->chr_out, chr, errp);
>   }
>   
> @@ -252,6 +261,14 @@ static void filter_redirector_setup(NetFilterState *nf, Error **errp)
>           }
>       }
>   
> +    if (!s->vnet_hdr &&
> +        qemu_opts_foreach(qemu_find_opts("device"),
> +                         vnet_driver_check, nf->netdev_id, NULL)) {
> +        error_setg(errp, "filter redirector needs 'vnet_hdr_support' "
> +                   "when network driver is virtio-net");
> +        return;
> +    }
> +
>       net_socket_rs_init(&s->rs, redirector_rs_finalize, s->vnet_hdr);
>   
>       if (s->indev) {
> diff --git a/net/filter-rewriter.c b/net/filter-rewriter.c
> index cb3a96cde1..0e84eac1f8 100644
> --- a/net/filter-rewriter.c
> +++ b/net/filter-rewriter.c
> @@ -14,6 +14,7 @@
>   #include "colo.h"
>   #include "net/filter.h"
>   #include "net/net.h"
> +#include "qapi/error.h"
>   #include "qemu/error-report.h"
>   #include "qom/object.h"
>   #include "qemu/main-loop.h"
> @@ -388,6 +389,14 @@ static void colo_rewriter_setup(NetFilterState *nf, Error **errp)
>   {
>       RewriterState *s = FILTER_REWRITER(nf);
>   
> +    if (!s->vnet_hdr &&
> +        qemu_opts_foreach(qemu_find_opts("device"),
> +                         vnet_driver_check, nf->netdev_id, NULL)) {
> +        error_setg(errp, "filter rewriter needs 'vnet_hdr_support' "
> +                   "when network driver is virtio-net");
> +        return;
> +    }
> +
>       s->connection_track_table = g_hash_table_new_full(connection_key_hash,
>                                                         connection_key_equal,
>                                                         g_free,
>
Jason Wang Aug. 16, 2021, 2:58 a.m. UTC | #2
在 2021/8/6 下午2:08, Tao Xu 写道:
> When COLO use only one vnet_hdr_support parameter between
> COLO network filter(filter-mirror, filter-redirector or
> filter-rewriter and colo-compare, packet will not be parsed
> correctly. Acquire network driver related to COLO, if it is
> nirtio-net, check vnet_hdr_support flag of COLO network filter
> and colo-compare.
>
> Signed-off-by: Tao Xu <tao3.xu@intel.com>
> Signed-off-by: Zhang Chen <chen.zhang@intel.com>
> ---
>   net/colo-compare.c    | 25 +++++++++++++++++++++++++
>   net/colo.c            | 20 ++++++++++++++++++++
>   net/colo.h            |  4 ++++
>   net/filter-mirror.c   | 17 +++++++++++++++++
>   net/filter-rewriter.c |  9 +++++++++
>   5 files changed, 75 insertions(+)
>
> diff --git a/net/colo-compare.c b/net/colo-compare.c
> index b100e7b51f..bc1cc951c0 100644
> --- a/net/colo-compare.c
> +++ b/net/colo-compare.c
> @@ -838,6 +838,23 @@ static int compare_chr_can_read(void *opaque)
>       return COMPARE_READ_LEN_MAX;
>   }
>   
> +/* check vnet_hdr_support flag through COLO filter modules */
> +static int colo_vnet_driver_check(void *opaque, QemuOpts *opts, Error **errp)
> +{
> +    const char *colo_obj_type;
> +
> +    colo_obj_type = qemu_opt_get(opts, "qom-type");
> +
> +    if (strcmp(colo_obj_type, "filter-mirror") == 0 ||
> +        strcmp(colo_obj_type, "filter-redirector") == 0 ||
> +        strcmp(colo_obj_type, "filter-rewriter") == 0) {
> +        if (qemu_opt_get(opts, "vnet_hdr_support")) {
> +            return 1;
> +        }
> +    }
> +    return 0;
> +}
> +
>   /*
>    * Called from the main thread on the primary for packets
>    * arriving over the socket from the primary.
> @@ -1289,6 +1306,14 @@ static void colo_compare_complete(UserCreatable *uc, Error **errp)
>           return;
>       }
>   
> +    if (!s->vnet_hdr &&
> +        qemu_opts_foreach(qemu_find_opts("object"),
> +                          colo_vnet_driver_check, NULL, NULL)) {
> +        error_setg(errp, "colo compare needs 'vnet_hdr_support' "
> +                   "when colo filter modules work on virtio-net");
> +        return;
> +    }


I wonder if we can detect virtio-net and apply vnet_hdr automatically.

Thanks


> +
>       net_socket_rs_init(&s->pri_rs, compare_pri_rs_finalize, s->vnet_hdr);
>       net_socket_rs_init(&s->sec_rs, compare_sec_rs_finalize, s->vnet_hdr);
>   
> diff --git a/net/colo.c b/net/colo.c
> index 3a3e6e89a0..4a03780f45 100644
> --- a/net/colo.c
> +++ b/net/colo.c
> @@ -243,3 +243,23 @@ bool connection_has_tracked(GHashTable *connection_track_table,
>   
>       return conn ? true : false;
>   }
> +
> +/* check the network driver related to COLO, return 1 if it is virtio-net */
> +int vnet_driver_check(void *opaque, QemuOpts *opts, Error **errp)
> +{
> +    const char *driver_type, *netdev_from_driver;
> +    char *netdev_from_filter = (char *)opaque;
> +
> +    driver_type = qemu_opt_get(opts, "driver");
> +    netdev_from_driver = qemu_opt_get(opts, "netdev");
> +
> +    if (!driver_type || !netdev_from_driver || !netdev_from_filter) {
> +        return 0;
> +    }
> +
> +    if (g_str_has_prefix(driver_type, "virtio-net") &&
> +        strcmp(netdev_from_driver, netdev_from_filter) == 0) {
> +        return 1;
> +    }
> +    return 0;
> +}
> diff --git a/net/colo.h b/net/colo.h
> index d91cd245c4..d401fc76b6 100644
> --- a/net/colo.h
> +++ b/net/colo.h
> @@ -18,6 +18,9 @@
>   #include "qemu/jhash.h"
>   #include "qemu/timer.h"
>   #include "net/eth.h"
> +#include "qemu/option.h"
> +#include "qemu/option_int.h"
> +#include "qemu/config-file.h"
>   
>   #define HASHTABLE_MAX_SIZE 16384
>   
> @@ -104,5 +107,6 @@ Packet *packet_new(const void *data, int size, int vnet_hdr_len);
>   Packet *packet_new_nocopy(void *data, int size, int vnet_hdr_len);
>   void packet_destroy(void *opaque, void *user_data);
>   void packet_destroy_partial(void *opaque, void *user_data);
> +int vnet_driver_check(void *opaque, QemuOpts *opts, Error **errp);
>   
>   #endif /* NET_COLO_H */
> diff --git a/net/filter-mirror.c b/net/filter-mirror.c
> index f20240cc9f..b8b3f2fe1d 100644
> --- a/net/filter-mirror.c
> +++ b/net/filter-mirror.c
> @@ -12,6 +12,7 @@
>   #include "qemu/osdep.h"
>   #include "net/filter.h"
>   #include "net/net.h"
> +#include "net/colo.h"
>   #include "qapi/error.h"
>   #include "qom/object.h"
>   #include "qemu/main-loop.h"
> @@ -224,6 +225,14 @@ static void filter_mirror_setup(NetFilterState *nf, Error **errp)
>           return;
>       }
>   
> +    if (!s->vnet_hdr &&
> +        qemu_opts_foreach(qemu_find_opts("device"),
> +                         vnet_driver_check, nf->netdev_id, NULL)) {
> +        error_setg(errp, "filter mirror needs 'vnet_hdr_support' "
> +                   "when network driver is virtio-net");
> +        return;
> +    }
> +
>       qemu_chr_fe_init(&s->chr_out, chr, errp);
>   }
>   
> @@ -252,6 +261,14 @@ static void filter_redirector_setup(NetFilterState *nf, Error **errp)
>           }
>       }
>   
> +    if (!s->vnet_hdr &&
> +        qemu_opts_foreach(qemu_find_opts("device"),
> +                         vnet_driver_check, nf->netdev_id, NULL)) {
> +        error_setg(errp, "filter redirector needs 'vnet_hdr_support' "
> +                   "when network driver is virtio-net");
> +        return;
> +    }
> +
>       net_socket_rs_init(&s->rs, redirector_rs_finalize, s->vnet_hdr);
>   
>       if (s->indev) {
> diff --git a/net/filter-rewriter.c b/net/filter-rewriter.c
> index cb3a96cde1..0e84eac1f8 100644
> --- a/net/filter-rewriter.c
> +++ b/net/filter-rewriter.c
> @@ -14,6 +14,7 @@
>   #include "colo.h"
>   #include "net/filter.h"
>   #include "net/net.h"
> +#include "qapi/error.h"
>   #include "qemu/error-report.h"
>   #include "qom/object.h"
>   #include "qemu/main-loop.h"
> @@ -388,6 +389,14 @@ static void colo_rewriter_setup(NetFilterState *nf, Error **errp)
>   {
>       RewriterState *s = FILTER_REWRITER(nf);
>   
> +    if (!s->vnet_hdr &&
> +        qemu_opts_foreach(qemu_find_opts("device"),
> +                         vnet_driver_check, nf->netdev_id, NULL)) {
> +        error_setg(errp, "filter rewriter needs 'vnet_hdr_support' "
> +                   "when network driver is virtio-net");
> +        return;
> +    }
> +
>       s->connection_track_table = g_hash_table_new_full(connection_key_hash,
>                                                         connection_key_equal,
>                                                         g_free,
Tao Xu Aug. 17, 2021, 6:01 a.m. UTC | #3
On 8/16/2021 10:58 AM, Jason Wang wrote:
> 
> 在 2021/8/6 下午2:08, Tao Xu 写道:
>> When COLO use only one vnet_hdr_support parameter between
>> COLO network filter(filter-mirror, filter-redirector or
>> filter-rewriter and colo-compare, packet will not be parsed
>> correctly. Acquire network driver related to COLO, if it is
>> nirtio-net, check vnet_hdr_support flag of COLO network filter
>> and colo-compare.
>>
>> Signed-off-by: Tao Xu <tao3.xu@intel.com>
>> Signed-off-by: Zhang Chen <chen.zhang@intel.com>
>> ---
>>    net/colo-compare.c    | 25 +++++++++++++++++++++++++
>>    net/colo.c            | 20 ++++++++++++++++++++
>>    net/colo.h            |  4 ++++
>>    net/filter-mirror.c   | 17 +++++++++++++++++
>>    net/filter-rewriter.c |  9 +++++++++
>>    5 files changed, 75 insertions(+)
>>
>> diff --git a/net/colo-compare.c b/net/colo-compare.c
>> index b100e7b51f..bc1cc951c0 100644
>> --- a/net/colo-compare.c
>> +++ b/net/colo-compare.c
>> @@ -838,6 +838,23 @@ static int compare_chr_can_read(void *opaque)
>>        return COMPARE_READ_LEN_MAX;
>>    }
>>    
>> +/* check vnet_hdr_support flag through COLO filter modules */
>> +static int colo_vnet_driver_check(void *opaque, QemuOpts *opts, Error **errp)
>> +{
>> +    const char *colo_obj_type;
>> +
>> +    colo_obj_type = qemu_opt_get(opts, "qom-type");
>> +
>> +    if (strcmp(colo_obj_type, "filter-mirror") == 0 ||
>> +        strcmp(colo_obj_type, "filter-redirector") == 0 ||
>> +        strcmp(colo_obj_type, "filter-rewriter") == 0) {
>> +        if (qemu_opt_get(opts, "vnet_hdr_support")) {
>> +            return 1;
>> +        }
>> +    }
>> +    return 0;
>> +}
>> +
>>    /*
>>     * Called from the main thread on the primary for packets
>>     * arriving over the socket from the primary.
>> @@ -1289,6 +1306,14 @@ static void colo_compare_complete(UserCreatable *uc, Error **errp)
>>            return;
>>        }
>>    
>> +    if (!s->vnet_hdr &&
>> +        qemu_opts_foreach(qemu_find_opts("object"),
>> +                          colo_vnet_driver_check, NULL, NULL)) {
>> +        error_setg(errp, "colo compare needs 'vnet_hdr_support' "
>> +                   "when colo filter modules work on virtio-net");
>> +        return;
>> +    }
> 
> 
> I wonder if we can detect virtio-net and apply vnet_hdr automatically.
> 
> Thanks
> 
For filter-mirror, filter-redirector and filter-rewriter, we can detect 
and add it automatically, because these netfilter is attached to netdev, 
for example,

     if (!s->vnet_hdr &&
         qemu_opts_foreach(qemu_find_opts("device"),
                          vnet_driver_check, nf->netdev_id, NULL)) {
         s->vnet_hdr = true.
     }


But for colo-compare, it isn't attached to netdev, only can check colo 
netfilter to check vnet_hdr_support. In this situation, if all netfilter 
vnet_hdr_support is missing, colo_vnet_driver_check() will return 0, it 
can't find vnet_hdr_support is missing.

So can we apply vnet_hdr automatically for filter-mirror, 
filter-redirector and filter-rewriter? And keep report error for 
colo-compare?
Tao Xu Aug. 17, 2021, 7:37 a.m. UTC | #4
On 8/17/2021 2:01 PM, Tao Xu wrote:
> 
> On 8/16/2021 10:58 AM, Jason Wang wrote:
>>
>> 在 2021/8/6 下午2:08, Tao Xu 写道:
>>> When COLO use only one vnet_hdr_support parameter between
>>> COLO network filter(filter-mirror, filter-redirector or
>>> filter-rewriter and colo-compare, packet will not be parsed
>>> correctly. Acquire network driver related to COLO, if it is
>>> nirtio-net, check vnet_hdr_support flag of COLO network filter
>>> and colo-compare.
>>>
>>> Signed-off-by: Tao Xu <tao3.xu@intel.com>
>>> Signed-off-by: Zhang Chen <chen.zhang@intel.com>
>>> ---
>>>    net/colo-compare.c    | 25 +++++++++++++++++++++++++
>>>    net/colo.c            | 20 ++++++++++++++++++++
>>>    net/colo.h            |  4 ++++
>>>    net/filter-mirror.c   | 17 +++++++++++++++++
>>>    net/filter-rewriter.c |  9 +++++++++
>>>    5 files changed, 75 insertions(+)
>>>
>>> diff --git a/net/colo-compare.c b/net/colo-compare.c
>>> index b100e7b51f..bc1cc951c0 100644
>>> --- a/net/colo-compare.c
>>> +++ b/net/colo-compare.c
>>> @@ -838,6 +838,23 @@ static int compare_chr_can_read(void *opaque)
>>>        return COMPARE_READ_LEN_MAX;
>>>    }
>>> +/* check vnet_hdr_support flag through COLO filter modules */
>>> +static int colo_vnet_driver_check(void *opaque, QemuOpts *opts, 
>>> Error **errp)
>>> +{
>>> +    const char *colo_obj_type;
>>> +
>>> +    colo_obj_type = qemu_opt_get(opts, "qom-type");
>>> +
>>> +    if (strcmp(colo_obj_type, "filter-mirror") == 0 ||
>>> +        strcmp(colo_obj_type, "filter-redirector") == 0 ||
>>> +        strcmp(colo_obj_type, "filter-rewriter") == 0) {
>>> +        if (qemu_opt_get(opts, "vnet_hdr_support")) {
>>> +            return 1;
>>> +        }
>>> +    }
>>> +    return 0;
>>> +}
>>> +
>>>    /*
>>>     * Called from the main thread on the primary for packets
>>>     * arriving over the socket from the primary.
>>> @@ -1289,6 +1306,14 @@ static void 
>>> colo_compare_complete(UserCreatable *uc, Error **errp)
>>>            return;
>>>        }
>>> +    if (!s->vnet_hdr &&
>>> +        qemu_opts_foreach(qemu_find_opts("object"),
>>> +                          colo_vnet_driver_check, NULL, NULL)) {
>>> +        error_setg(errp, "colo compare needs 'vnet_hdr_support' "
>>> +                   "when colo filter modules work on virtio-net");
>>> +        return;
>>> +    }
>>
>>
>> I wonder if we can detect virtio-net and apply vnet_hdr automatically.
>>
>> Thanks
>>
> For filter-mirror, filter-redirector and filter-rewriter, we can detect 
> and add it automatically, because these netfilter is attached to netdev, 
> for example,
> 
>      if (!s->vnet_hdr &&
>          qemu_opts_foreach(qemu_find_opts("device"),
>                           vnet_driver_check, nf->netdev_id, NULL)) {
>          s->vnet_hdr = true.
>      }
> 
> 
> But for colo-compare, it isn't attached to netdev, only can check colo 
> netfilter to check vnet_hdr_support. In this situation, if all netfilter 
> vnet_hdr_support is missing, colo_vnet_driver_check() will return 0, it 
> can't find vnet_hdr_support is missing.
> 
> So can we apply vnet_hdr automatically for filter-mirror, 
> filter-redirector and filter-rewriter? And keep report error for 
> colo-compare?

Sorry, I find the solution for colo-compare apply vnet_hdr 
automatically, I will submit V2 later.
diff mbox series

Patch

diff --git a/net/colo-compare.c b/net/colo-compare.c
index b100e7b51f..bc1cc951c0 100644
--- a/net/colo-compare.c
+++ b/net/colo-compare.c
@@ -838,6 +838,23 @@  static int compare_chr_can_read(void *opaque)
     return COMPARE_READ_LEN_MAX;
 }
 
+/* check vnet_hdr_support flag through COLO filter modules */
+static int colo_vnet_driver_check(void *opaque, QemuOpts *opts, Error **errp)
+{
+    const char *colo_obj_type;
+
+    colo_obj_type = qemu_opt_get(opts, "qom-type");
+
+    if (strcmp(colo_obj_type, "filter-mirror") == 0 ||
+        strcmp(colo_obj_type, "filter-redirector") == 0 ||
+        strcmp(colo_obj_type, "filter-rewriter") == 0) {
+        if (qemu_opt_get(opts, "vnet_hdr_support")) {
+            return 1;
+        }
+    }
+    return 0;
+}
+
 /*
  * Called from the main thread on the primary for packets
  * arriving over the socket from the primary.
@@ -1289,6 +1306,14 @@  static void colo_compare_complete(UserCreatable *uc, Error **errp)
         return;
     }
 
+    if (!s->vnet_hdr &&
+        qemu_opts_foreach(qemu_find_opts("object"),
+                          colo_vnet_driver_check, NULL, NULL)) {
+        error_setg(errp, "colo compare needs 'vnet_hdr_support' "
+                   "when colo filter modules work on virtio-net");
+        return;
+    }
+
     net_socket_rs_init(&s->pri_rs, compare_pri_rs_finalize, s->vnet_hdr);
     net_socket_rs_init(&s->sec_rs, compare_sec_rs_finalize, s->vnet_hdr);
 
diff --git a/net/colo.c b/net/colo.c
index 3a3e6e89a0..4a03780f45 100644
--- a/net/colo.c
+++ b/net/colo.c
@@ -243,3 +243,23 @@  bool connection_has_tracked(GHashTable *connection_track_table,
 
     return conn ? true : false;
 }
+
+/* check the network driver related to COLO, return 1 if it is virtio-net */
+int vnet_driver_check(void *opaque, QemuOpts *opts, Error **errp)
+{
+    const char *driver_type, *netdev_from_driver;
+    char *netdev_from_filter = (char *)opaque;
+
+    driver_type = qemu_opt_get(opts, "driver");
+    netdev_from_driver = qemu_opt_get(opts, "netdev");
+
+    if (!driver_type || !netdev_from_driver || !netdev_from_filter) {
+        return 0;
+    }
+
+    if (g_str_has_prefix(driver_type, "virtio-net") &&
+        strcmp(netdev_from_driver, netdev_from_filter) == 0) {
+        return 1;
+    }
+    return 0;
+}
diff --git a/net/colo.h b/net/colo.h
index d91cd245c4..d401fc76b6 100644
--- a/net/colo.h
+++ b/net/colo.h
@@ -18,6 +18,9 @@ 
 #include "qemu/jhash.h"
 #include "qemu/timer.h"
 #include "net/eth.h"
+#include "qemu/option.h"
+#include "qemu/option_int.h"
+#include "qemu/config-file.h"
 
 #define HASHTABLE_MAX_SIZE 16384
 
@@ -104,5 +107,6 @@  Packet *packet_new(const void *data, int size, int vnet_hdr_len);
 Packet *packet_new_nocopy(void *data, int size, int vnet_hdr_len);
 void packet_destroy(void *opaque, void *user_data);
 void packet_destroy_partial(void *opaque, void *user_data);
+int vnet_driver_check(void *opaque, QemuOpts *opts, Error **errp);
 
 #endif /* NET_COLO_H */
diff --git a/net/filter-mirror.c b/net/filter-mirror.c
index f20240cc9f..b8b3f2fe1d 100644
--- a/net/filter-mirror.c
+++ b/net/filter-mirror.c
@@ -12,6 +12,7 @@ 
 #include "qemu/osdep.h"
 #include "net/filter.h"
 #include "net/net.h"
+#include "net/colo.h"
 #include "qapi/error.h"
 #include "qom/object.h"
 #include "qemu/main-loop.h"
@@ -224,6 +225,14 @@  static void filter_mirror_setup(NetFilterState *nf, Error **errp)
         return;
     }
 
+    if (!s->vnet_hdr &&
+        qemu_opts_foreach(qemu_find_opts("device"),
+                         vnet_driver_check, nf->netdev_id, NULL)) {
+        error_setg(errp, "filter mirror needs 'vnet_hdr_support' "
+                   "when network driver is virtio-net");
+        return;
+    }
+
     qemu_chr_fe_init(&s->chr_out, chr, errp);
 }
 
@@ -252,6 +261,14 @@  static void filter_redirector_setup(NetFilterState *nf, Error **errp)
         }
     }
 
+    if (!s->vnet_hdr &&
+        qemu_opts_foreach(qemu_find_opts("device"),
+                         vnet_driver_check, nf->netdev_id, NULL)) {
+        error_setg(errp, "filter redirector needs 'vnet_hdr_support' "
+                   "when network driver is virtio-net");
+        return;
+    }
+
     net_socket_rs_init(&s->rs, redirector_rs_finalize, s->vnet_hdr);
 
     if (s->indev) {
diff --git a/net/filter-rewriter.c b/net/filter-rewriter.c
index cb3a96cde1..0e84eac1f8 100644
--- a/net/filter-rewriter.c
+++ b/net/filter-rewriter.c
@@ -14,6 +14,7 @@ 
 #include "colo.h"
 #include "net/filter.h"
 #include "net/net.h"
+#include "qapi/error.h"
 #include "qemu/error-report.h"
 #include "qom/object.h"
 #include "qemu/main-loop.h"
@@ -388,6 +389,14 @@  static void colo_rewriter_setup(NetFilterState *nf, Error **errp)
 {
     RewriterState *s = FILTER_REWRITER(nf);
 
+    if (!s->vnet_hdr &&
+        qemu_opts_foreach(qemu_find_opts("device"),
+                         vnet_driver_check, nf->netdev_id, NULL)) {
+        error_setg(errp, "filter rewriter needs 'vnet_hdr_support' "
+                   "when network driver is virtio-net");
+        return;
+    }
+
     s->connection_track_table = g_hash_table_new_full(connection_key_hash,
                                                       connection_key_equal,
                                                       g_free,