diff mbox series

[ovs-dev,v3,2/2] netdev-dpdk: Add support for userspace port-based ingress packet-per-second policing.

Message ID SY4PR01MB84389C82E64B353971C8C230CD6E9@SY4PR01MB8438.ausprd01.prod.outlook.com
State Changes Requested
Headers show
Series netdev-dpdk: Add support for userspace port-based packet-per-second policing. | expand

Checks

Context Check Description
ovsrobot/apply-robot success apply and check: success
ovsrobot/github-robot-_Build_and_Test fail github build: failed

Commit Message

miter May 1, 2023, 11:33 a.m. UTC
From: Lin Huang <linhuang@ruijie.com.cn>

OvS has supported packet-per-second policer which can be set at ingress
and egress side in kernel datapath. But the userspace datapath dosen't
support for ingress and egress packet-per-second policing now.

So, this patch add support for userspace ingress pps policing by using
native ovs token bucket library. Token bucket is accumulated by 'rate'
tokens per millisecond and store maxiumim tokens at 'burst' bucket size.
One token in the bucket means one packet (1 kpkts * millisecond) which
will drop or pass by policer.

This patch reuse 'ingress_policing_kpkts_rate' and
'ingress_policing_kpkts_burst' options at interface table. Now userspace
ingress policer supports setting packet-per-second limits in addition to
the previously configurable byte rate settings.

Examples:
$ ovs-vsctl set interface dpdk0 ingress_policing_rate=12300
$ ovs-vsctl set interface dpdk0 ingress_policing_burst=12300
$ ovs-vsctl set interface dpdk0 ingress_policing_kpkts_rate=123
$ ovs-vsctl set interface dpdk0 ingress_policing_kpkts_burst=123

Add some unit tests for ingress packet-per-second policing.

Signed-off-by: Lin Huang <linhuang@ruijie.com.cn>
---
 NEWS                 |   4 +
 lib/netdev-dpdk.c    |  78 +++++++++++++---
 tests/system-dpdk.at | 216 ++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 285 insertions(+), 13 deletions(-)

Comments

Ilya Maximets May 10, 2023, 6:42 p.m. UTC | #1
On 5/1/23 13:33, miterv@outlook.com wrote:
> From: Lin Huang <linhuang@ruijie.com.cn>
> 
> OvS has supported packet-per-second policer which can be set at ingress
> and egress side in kernel datapath. But the userspace datapath dosen't
> support for ingress and egress packet-per-second policing now.
> 
> So, this patch add support for userspace ingress pps policing by using
> native ovs token bucket library. Token bucket is accumulated by 'rate'
> tokens per millisecond and store maxiumim tokens at 'burst' bucket size.
> One token in the bucket means one packet (1 kpkts * millisecond) which
> will drop or pass by policer.
> 
> This patch reuse 'ingress_policing_kpkts_rate' and
> 'ingress_policing_kpkts_burst' options at interface table. Now userspace
> ingress policer supports setting packet-per-second limits in addition to
> the previously configurable byte rate settings.
> 
> Examples:
> $ ovs-vsctl set interface dpdk0 ingress_policing_rate=12300
> $ ovs-vsctl set interface dpdk0 ingress_policing_burst=12300
> $ ovs-vsctl set interface dpdk0 ingress_policing_kpkts_rate=123
> $ ovs-vsctl set interface dpdk0 ingress_policing_kpkts_burst=123
> 
> Add some unit tests for ingress packet-per-second policing.
> 
> Signed-off-by: Lin Huang <linhuang@ruijie.com.cn>

Thanks for the new version.  Not a full review but a few comments inline.

Also, you may drop the 'userspace port-based' part from patch names.
'netdev-dpdk' area already means that it is userpsace and that it is
for ports.

> ---
>  NEWS                 |   4 +
>  lib/netdev-dpdk.c    |  78 +++++++++++++---
>  tests/system-dpdk.at | 216 ++++++++++++++++++++++++++++++++++++++++++-
>  3 files changed, 285 insertions(+), 13 deletions(-)
> 
> diff --git a/NEWS b/NEWS
> index c41c6adf6..53adbed82 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -30,6 +30,10 @@ Post-v3.1.0
>         ovs-vsctl set port vhost-user0 qos=@newqos -- \
>            --id=@newqos create qos type=egress-policer \
>            other-config:kpkts_rate=123 other-config:kpkts_burst=123
> +     * Added support for ingress packet-per-second policing.
> +       Examples:
> +       $ ovs-vsctl set interface dpdk0 ingress_policing_kpkts_rate=123
> +       $ ovs-vsctl set interface dpdk0 ingress_policing_kpkts_burst=123

Examples are not really necessary in the NEWS file in most cases.
You may just say that the feature can be configured via
ingress_policing_kpkts_rate/burst columns in the Interface table.

>  
>  
>  v3.1.0 - 16 Feb 2023
> diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c
> index bcd13c116..a717edc5e 100644
> --- a/lib/netdev-dpdk.c
> +++ b/lib/netdev-dpdk.c
> @@ -413,6 +413,8 @@ struct ingress_policer {
>      struct rte_meter_srtcm_params app_srtcm_params;
>      struct rte_meter_srtcm in_policer;
>      struct rte_meter_srtcm_profile in_prof;
> +    struct token_bucket tb;
> +    enum policer_type type;
>      rte_spinlock_t policer_lock;
>  };
>  
> @@ -496,6 +498,9 @@ struct netdev_dpdk {
>          uint32_t policer_rate;
>          uint32_t policer_burst;
>  
> +        uint32_t policer_kpkts_rate;
> +        uint32_t policer_kpkts_burst;
> +
>          /* Array of vhost rxq states, see vring_state_changed. */
>          bool *vhost_rxq_enabled;
>      );
> @@ -1315,6 +1320,8 @@ common_construct(struct netdev *netdev, dpdk_port_t port_no,
>      ovsrcu_init(&dev->ingress_policer, NULL);
>      dev->policer_rate = 0;
>      dev->policer_burst = 0;
> +    dev->policer_kpkts_rate = 0;
> +    dev->policer_kpkts_burst = 0;
>  
>      netdev->n_rxq = 0;
>      netdev->n_txq = 0;
> @@ -2367,9 +2374,16 @@ ingress_policer_run(struct ingress_policer *policer, struct rte_mbuf **pkts,
>      int cnt = 0;
>  
>      rte_spinlock_lock(&policer->policer_lock);
> -    cnt = srtcm_policer_run_single_packet(&policer->in_policer,
> -                                          &policer->in_prof,
> -                                          pkts, pkt_cnt, should_steal);
> +    if (policer->type & POLICER_BPS) {
> +        cnt = srtcm_policer_run_single_packet(&policer->in_policer,
> +                                              &policer->in_prof,
> +                                              pkts, pkt_cnt, should_steal);
> +    }
> +
> +    if (policer->type & POLICER_PKTPS) {
> +        cnt = pkts_policer_run_single_packet(&policer->tb, pkts, pkt_cnt,
> +                                             should_steal);
> +    }

We're running 2 policers here.  If the POLICER_BPS drops some packets,
we can't use pkt_cnt as an argument for the POLICER_PKTPS, otherwise
we may get use-after-free.

>      rte_spinlock_unlock(&policer->policer_lock);
>  
>      return cnt;

And if both policers drop some packets, this return value will also
be incorrect.

Best regards, Ilya Maximets.
Eelco Chaudron May 11, 2023, 7:26 a.m. UTC | #2
On 1 May 2023, at 13:33, miterv@outlook.com wrote:

> From: Lin Huang <linhuang@ruijie.com.cn>
>
> OvS has supported packet-per-second policer which can be set at ingress
> and egress side in kernel datapath. But the userspace datapath dosen't
> support for ingress and egress packet-per-second policing now.
>
> So, this patch add support for userspace ingress pps policing by using
> native ovs token bucket library. Token bucket is accumulated by 'rate'
> tokens per millisecond and store maxiumim tokens at 'burst' bucket size.
> One token in the bucket means one packet (1 kpkts * millisecond) which
> will drop or pass by policer.
>
> This patch reuse 'ingress_policing_kpkts_rate' and
> 'ingress_policing_kpkts_burst' options at interface table. Now userspace
> ingress policer supports setting packet-per-second limits in addition to
> the previously configurable byte rate settings.
>
> Examples:
> $ ovs-vsctl set interface dpdk0 ingress_policing_rate=12300
> $ ovs-vsctl set interface dpdk0 ingress_policing_burst=12300
> $ ovs-vsctl set interface dpdk0 ingress_policing_kpkts_rate=123
> $ ovs-vsctl set interface dpdk0 ingress_policing_kpkts_burst=123


I did not review this, but I noticed that we are missing documentation for this feature in the “Documentation/topics/dpdk/qos.rst” doc.

//Eelco


> Add some unit tests for ingress packet-per-second policing.
>
> Signed-off-by: Lin Huang <linhuang@ruijie.com.cn>
> ---
>  NEWS                 |   4 +
>  lib/netdev-dpdk.c    |  78 +++++++++++++---
>  tests/system-dpdk.at | 216 ++++++++++++++++++++++++++++++++++++++++++-
>  3 files changed, 285 insertions(+), 13 deletions(-)
>
> diff --git a/NEWS b/NEWS
> index c41c6adf6..53adbed82 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -30,6 +30,10 @@ Post-v3.1.0
>         ovs-vsctl set port vhost-user0 qos=@newqos -- \
>            --id=@newqos create qos type=egress-policer \
>            other-config:kpkts_rate=123 other-config:kpkts_burst=123
> +     * Added support for ingress packet-per-second policing.
> +       Examples:
> +       $ ovs-vsctl set interface dpdk0 ingress_policing_kpkts_rate=123
> +       $ ovs-vsctl set interface dpdk0 ingress_policing_kpkts_burst=123
>
>
>  v3.1.0 - 16 Feb 2023
> diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c
> index bcd13c116..a717edc5e 100644
> --- a/lib/netdev-dpdk.c
> +++ b/lib/netdev-dpdk.c
> @@ -413,6 +413,8 @@ struct ingress_policer {
>      struct rte_meter_srtcm_params app_srtcm_params;
>      struct rte_meter_srtcm in_policer;
>      struct rte_meter_srtcm_profile in_prof;
> +    struct token_bucket tb;
> +    enum policer_type type;
>      rte_spinlock_t policer_lock;
>  };
>
> @@ -496,6 +498,9 @@ struct netdev_dpdk {
>          uint32_t policer_rate;
>          uint32_t policer_burst;
>
> +        uint32_t policer_kpkts_rate;
> +        uint32_t policer_kpkts_burst;
> +
>          /* Array of vhost rxq states, see vring_state_changed. */
>          bool *vhost_rxq_enabled;
>      );
> @@ -1315,6 +1320,8 @@ common_construct(struct netdev *netdev, dpdk_port_t port_no,
>      ovsrcu_init(&dev->ingress_policer, NULL);
>      dev->policer_rate = 0;
>      dev->policer_burst = 0;
> +    dev->policer_kpkts_rate = 0;
> +    dev->policer_kpkts_burst = 0;
>
>      netdev->n_rxq = 0;
>      netdev->n_txq = 0;
> @@ -2367,9 +2374,16 @@ ingress_policer_run(struct ingress_policer *policer, struct rte_mbuf **pkts,
>      int cnt = 0;
>
>      rte_spinlock_lock(&policer->policer_lock);
> -    cnt = srtcm_policer_run_single_packet(&policer->in_policer,
> -                                          &policer->in_prof,
> -                                          pkts, pkt_cnt, should_steal);
> +    if (policer->type & POLICER_BPS) {
> +        cnt = srtcm_policer_run_single_packet(&policer->in_policer,
> +                                              &policer->in_prof,
> +                                              pkts, pkt_cnt, should_steal);
> +    }
> +
> +    if (policer->type & POLICER_PKTPS) {
> +        cnt = pkts_policer_run_single_packet(&policer->tb, pkts, pkt_cnt,
> +                                             should_steal);
> +    }
>      rte_spinlock_unlock(&policer->policer_lock);
>
>      return cnt;
> @@ -3531,7 +3545,8 @@ netdev_dpdk_get_features(const struct netdev *netdev,
>  }
>
>  static struct ingress_policer *
> -netdev_dpdk_policer_construct(uint32_t rate, uint32_t burst)
> +netdev_dpdk_policer_construct(uint32_t rate, uint32_t burst,
> +                              uint32_t kpkts_rate, uint32_t kpkts_burst)
>  {
>      struct ingress_policer *policer = NULL;
>      uint64_t rate_bytes;
> @@ -3539,6 +3554,9 @@ netdev_dpdk_policer_construct(uint32_t rate, uint32_t burst)
>      int err = 0;
>
>      policer = xmalloc(sizeof *policer);
> +    if (!policer) {
> +        return NULL;
> +    }
>      rte_spinlock_init(&policer->policer_lock);
>
>      /* rte_meter requires bytes so convert kbits rate and burst to bytes. */
> @@ -3556,8 +3574,29 @@ netdev_dpdk_policer_construct(uint32_t rate, uint32_t burst)
>      }
>      if (err) {
>          VLOG_ERR("Could not create rte meter for ingress policer");
> +    } else {
> +        policer->type |= POLICER_BPS;
> +    }
> +
> +    if (kpkts_rate > MAX_KPKTS_PARAMETER || kpkts_burst > MAX_KPKTS_PARAMETER
> +        || kpkts_rate == 0 || kpkts_burst == 0) {
> +        /* Paramters between (1 ~ MAX_KPKTS_PARAMETER). */
> +        /* Zero means not to police the flow. */
> +        VLOG_ERR("Could not create tocken bucket for ingress policer");
> +    } else {
> +        /*
> +        * By default token is added per millisecond.
> +        * Rate in kilo-packets/second, bucket 1000 packets.
> +        * msec * kilo-packets/sec = 1 packets.
> +        */
> +        token_bucket_init(&policer->tb, kpkts_rate, kpkts_burst * 1000);
> +        policer->type |= POLICER_PKTPS;
> +    }
> +
> +    if (!policer->type) {
> +        /* Neither kbps nor kpkts policer is configured. */
>          free(policer);
> -        return NULL;
> +        policer = NULL;
>      }
>
>      return policer;
> @@ -3566,8 +3605,8 @@ netdev_dpdk_policer_construct(uint32_t rate, uint32_t burst)
>  static int
>  netdev_dpdk_set_policing(struct netdev* netdev, uint32_t policer_rate,
>                           uint32_t policer_burst,
> -                         uint32_t policer_kpkts_rate OVS_UNUSED,
> -                         uint32_t policer_kpkts_burst OVS_UNUSED)
> +                         uint32_t policer_kpkts_rate,
> +                         uint32_t policer_kpkts_burst)
>  {
>      struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
>      struct ingress_policer *policer;
> @@ -3580,13 +3619,23 @@ netdev_dpdk_set_policing(struct netdev* netdev, uint32_t policer_rate,
>                       : !policer_burst ? 8000
>                       : policer_burst);
>
> +    /*
> +     * Force to 0 if no rate specified,
> +     * default to rate value if burst is 0,
> +     * else stick with user-specified value.
> +     */
> +    policer_kpkts_burst = (!policer_kpkts_rate ? 0
> +                           : !policer_kpkts_burst ? policer_kpkts_rate
> +                           : policer_kpkts_burst);
>      ovs_mutex_lock(&dev->mutex);
>
>      policer = ovsrcu_get_protected(struct ingress_policer *,
> -                                    &dev->ingress_policer);
> +                                   &dev->ingress_policer);
>
>      if (dev->policer_rate == policer_rate &&
> -        dev->policer_burst == policer_burst) {
> +        dev->policer_burst == policer_burst &&
> +        dev->policer_kpkts_rate == policer_kpkts_rate &&
> +        dev->policer_kpkts_burst == policer_kpkts_burst) {
>          /* Assume that settings haven't changed since we last set them. */
>          ovs_mutex_unlock(&dev->mutex);
>          return 0;
> @@ -3597,14 +3646,19 @@ netdev_dpdk_set_policing(struct netdev* netdev, uint32_t policer_rate,
>          ovsrcu_postpone(free, policer);
>      }
>
> -    if (policer_rate != 0) {
> -        policer = netdev_dpdk_policer_construct(policer_rate, policer_burst);
> -    } else {
> +    if (!policer_rate && !policer_kpkts_rate) {
> +        /* both policers are zero. */
>          policer = NULL;
> +    } else {
> +        policer = netdev_dpdk_policer_construct(policer_rate, policer_burst,
> +                                                policer_kpkts_rate,
> +                                                policer_kpkts_burst);
>      }
>      ovsrcu_set(&dev->ingress_policer, policer);
>      dev->policer_rate = policer_rate;
>      dev->policer_burst = policer_burst;
> +    dev->policer_kpkts_rate = policer_kpkts_rate;
> +    dev->policer_kpkts_burst = policer_kpkts_burst;
>      ovs_mutex_unlock(&dev->mutex);
>
>      return 0;
> diff --git a/tests/system-dpdk.at b/tests/system-dpdk.at
> index 75a6ab7f5..492bc2f55 100644
> --- a/tests/system-dpdk.at
> +++ b/tests/system-dpdk.at
> @@ -297,7 +297,9 @@ AT_CHECK([grep -E 'ingress_policing_rate: 0' stdout], [], [stdout])
>
>  dnl Clean up
>  AT_CHECK([ovs-vsctl del-port br10 phy0], [], [stdout], [stderr])
> -OVS_VSWITCHD_STOP("[SYSTEM_DPDK_ALLOWED_LOGS]")
> +OVS_VSWITCHD_STOP("m4_join([], [SYSTEM_DPDK_ALLOWED_LOGS], [
> +\@Could not create tocken bucket for ingress policer@d
> +])")
>  AT_CLEANUP
>  dnl --------------------------------------------------------------------------
>
> @@ -339,6 +341,7 @@ AT_CHECK([grep "VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) reconnecting..." ov
>  dnl Clean up
>  AT_CHECK([ovs-vsctl del-port br10 dpdkvhostuserclient0], [], [stdout], [stderr])
>  OVS_VSWITCHD_STOP("m4_join([], [SYSTEM_DPDK_ALLOWED_LOGS], [
> +\@Could not create tocken bucket for ingress policer@d
>  \@VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) failed to connect: No such file or directory@d
>  ])")
>  AT_CLEANUP
> @@ -420,12 +423,223 @@ AT_CHECK([grep "VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) reconnecting..." ov
>  dnl Clean up
>  AT_CHECK([ovs-vsctl del-port br10 dpdkvhostuserclient0], [], [stdout], [stderr])
>  OVS_VSWITCHD_STOP("m4_join([], [SYSTEM_DPDK_ALLOWED_LOGS], [
> +\@Could not create tocken bucket for ingress policer@d
> +\@VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) failed to connect: No such file or directory@d
> +])")
> +AT_CLEANUP
> +dnl --------------------------------------------------------------------------
> +
> +
> +dnl --------------------------------------------------------------------------
> +dnl Ingress policing (kpkts) create delete vport port
> +AT_SETUP([OVS-DPDK - Ingress policing (kpkts) create delete vport port])
> +AT_KEYWORDS([dpdk])
> +
> +OVS_DPDK_PRE_CHECK()
> +OVS_DPDK_START()
> +
> +dnl Add userspace bridge and attach it to OVS and add ingress policer
> +AT_CHECK([ovs-vsctl add-br br10 -- set bridge br10 datapath_type=netdev])
> +AT_CHECK([ovs-vsctl add-port br10 dpdkvhostuserclient0 -- set Interface dpdkvhostuserclient0 type=dpdkvhostuserclient options:vhost-server-path=$OVS_RUNDIR/dpdkvhostclient0], [], [stdout], [stderr])
> +AT_CHECK([ovs-vsctl set interface dpdkvhostuserclient0 ingress_policing_kpkts_rate=10000 ingress_policing_kpkts_burst=10000])
> +AT_CHECK([ovs-vsctl show], [], [stdout])
> +sleep 2
> +
> +dnl Remove ingress policer
> +AT_CHECK([ovs-vsctl set interface dpdkvhostuserclient0 ingress_policing_kpkts_rate=0 ingress_policing_kpkts_burst=0])
> +
> +dnl Fail if ingress policer could not be created
> +AT_FAIL_IF([grep "Could not create tocken bucket for ingress policer" ovs-vswitchd.log], [], [stdout])
> +
> +dnl Check ingress policer was removed correctly
> +AT_CHECK([ovs-vsctl list interface dpdkvhostuserclient0], [], [stdout])
> +AT_CHECK([grep -E 'ingress_policing_kpkts_burst: 0' stdout], [], [stdout])
> +
> +AT_CHECK([ovs-vsctl list interface dpdkvhostuserclient0], [], [stdout])
> +AT_CHECK([grep -E 'ingress_policing_kpkts_rate: 0' stdout], [], [stdout])
> +
> +dnl Parse log file
> +AT_CHECK([grep "VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) vhost-user client: socket created" ovs-vswitchd.log], [], [stdout])
> +AT_CHECK([grep "vHost User device 'dpdkvhostuserclient0' created in 'client' mode, using client socket" ovs-vswitchd.log], [], [stdout])
> +AT_CHECK([grep "VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) reconnecting..." ovs-vswitchd.log], [], [stdout])
> +
> +dnl Clean up
> +AT_CHECK([ovs-vsctl del-port br10 dpdkvhostuserclient0], [], [stdout], [stderr])
> +OVS_VSWITCHD_STOP("m4_join([], [SYSTEM_DPDK_ALLOWED_LOGS], [
> +\@Could not create rte meter for ingress policer@d
> +\@VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) failed to connect: No such file or directory@d
> +])")
> +AT_CLEANUP
> +dnl --------------------------------------------------------------------------
> +
> +
> +
> +dnl --------------------------------------------------------------------------
> +dnl Ingress policing (kpkts) no policing rate
> +AT_SETUP([OVS-DPDK - Ingress policing (kpkts) no policing rate])
> +AT_KEYWORDS([dpdk])
> +
> +OVS_DPDK_PRE_CHECK()
> +OVS_DPDK_START()
> +
> +dnl Add userspace bridge and attach it to OVS and add ingress policer
> +AT_CHECK([ovs-vsctl add-br br10 -- set bridge br10 datapath_type=netdev])
> +AT_CHECK([ovs-vsctl add-port br10 dpdkvhostuserclient0 -- set Interface dpdkvhostuserclient0 type=dpdkvhostuserclient options:vhost-server-path=$OVS_RUNDIR/dpdkvhostclient0], [], [stdout], [stderr])
> +AT_CHECK([ovs-vsctl set interface dpdkvhostuserclient0 ingress_policing_kpkts_burst=1000])
> +AT_CHECK([ovs-vsctl show], [], [stdout])
> +sleep 2
> +
> +dnl check ingress policer not be created
> +AT_FAIL_IF([grep "Could not create tocken bucket for ingress policer" ovs-vswitchd.log], [], [stdout])
> +
> +dnl Check ingress policer was created correctly
> +AT_CHECK([ovs-vsctl list interface dpdkvhostuserclient0], [], [stdout])
> +AT_CHECK([grep -E 'ingress_policing_kpkts_burst: 1000' stdout], [], [stdout])
> +
> +AT_CHECK([ovs-vsctl list interface dpdkvhostuserclient0], [], [stdout])
> +AT_CHECK([grep -E 'ingress_policing_kpkts_rate: 0' stdout], [], [stdout])
> +
> +
> +dnl Parse log file
> +AT_CHECK([grep "VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) vhost-user client: socket created" ovs-vswitchd.log], [], [stdout])
> +AT_CHECK([grep "vHost User device 'dpdkvhostuserclient0' created in 'client' mode, using client socket" ovs-vswitchd.log], [], [stdout])
> +AT_CHECK([grep "VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) reconnecting..." ovs-vswitchd.log], [], [stdout])
> +
> +dnl Clean up
> +AT_CHECK([ovs-vsctl del-port br10 dpdkvhostuserclient0], [], [stdout], [stderr])
> +OVS_VSWITCHD_STOP("m4_join([], [SYSTEM_DPDK_ALLOWED_LOGS], [
> +\@VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) failed to connect: No such file or directory@d
> +])")
> +AT_CLEANUP
> +dnl --------------------------------------------------------------------------
> +
> +
> +
> +dnl --------------------------------------------------------------------------
> +dnl Ingress policing (kpkts) no policing burst
> +AT_SETUP([OVS-DPDK - Ingress policing (kpkts) no policing burst])
> +AT_KEYWORDS([dpdk])
> +
> +OVS_DPDK_PRE_CHECK()
> +OVS_DPDK_START()
> +
> +dnl Add userspace bridge and attach it to OVS and add ingress policer
> +AT_CHECK([ovs-vsctl add-br br10 -- set bridge br10 datapath_type=netdev])
> +AT_CHECK([ovs-vsctl add-port br10 dpdkvhostuserclient0 -- set Interface dpdkvhostuserclient0 type=dpdkvhostuserclient options:vhost-server-path=$OVS_RUNDIR/dpdkvhostclient0], [], [stdout], [stderr])
> +AT_CHECK([ovs-vsctl set interface dpdkvhostuserclient0 ingress_policing_kpkts_rate=10000])
> +AT_CHECK([ovs-vsctl show], [], [stdout])
> +sleep 2
> +
> +dnl check ingress policer not be created
> +AT_FAIL_IF([grep "Could not create tocken bucket for ingress policer" ovs-vswitchd.log], [], [stdout])
> +
> +dnl Check ingress policer was created correctly
> +AT_CHECK([ovs-vsctl list interface dpdkvhostuserclient0], [], [stdout])
> +AT_CHECK([grep -E 'ingress_policing_kpkts_burst: 0' stdout], [], [stdout])
> +
> +AT_CHECK([ovs-vsctl list interface dpdkvhostuserclient0], [], [stdout])
> +AT_CHECK([grep -E 'ingress_policing_kpkts_rate: 10000' stdout], [], [stdout])
> +
> +dnl Parse log file
> +AT_CHECK([grep "VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) vhost-user client: socket created" ovs-vswitchd.log], [], [stdout])
> +AT_CHECK([grep "vHost User device 'dpdkvhostuserclient0' created in 'client' mode, using client socket" ovs-vswitchd.log], [], [stdout])
> +AT_CHECK([grep "VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) reconnecting..." ovs-vswitchd.log], [], [stdout])
> +
> +dnl Clean up
> +AT_CHECK([ovs-vsctl del-port br10 dpdkvhostuserclient0], [], [stdout], [stderr])
> +OVS_VSWITCHD_STOP("m4_join([], [SYSTEM_DPDK_ALLOWED_LOGS], [
> +\@Could not create rte meter for ingress policer@d
> +\@VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) failed to connect: No such file or directory@d
> +])")
> +AT_CLEANUP
> +dnl --------------------------------------------------------------------------
> +
> +
> +
> +dnl --------------------------------------------------------------------------
> +dnl Ingress policing (kpkts) max policing rate
> +AT_SETUP([OVS-DPDK - Ingress policing (kpkts) max policing rate])
> +AT_KEYWORDS([dpdk])
> +
> +OVS_DPDK_PRE_CHECK()
> +OVS_DPDK_START()
> +
> +dnl Add userspace bridge and attach it to OVS and add ingress policer
> +AT_CHECK([ovs-vsctl add-br br10 -- set bridge br10 datapath_type=netdev])
> +AT_CHECK([ovs-vsctl add-port br10 dpdkvhostuserclient0 -- set Interface dpdkvhostuserclient0 type=dpdkvhostuserclient options:vhost-server-path=$OVS_RUNDIR/dpdkvhostclient0], [], [stdout], [stderr])
> +AT_CHECK([ovs-vsctl set interface dpdkvhostuserclient0 ingress_policing_kpkts_rate=42949671])
> +AT_CHECK([ovs-vsctl show], [], [stdout])
> +sleep 2
> +
> +dnl check ingress policer not be created
> +AT_CHECK([grep "Could not create tocken bucket for ingress policer" ovs-vswitchd.log], [], [stdout])
> +
> +dnl Check ingress policer was created correctly
> +AT_CHECK([ovs-vsctl list interface dpdkvhostuserclient0], [], [stdout])
> +AT_CHECK([grep -E 'ingress_policing_kpkts_burst: 0' stdout], [], [stdout])
> +
> +AT_CHECK([ovs-vsctl list interface dpdkvhostuserclient0], [], [stdout])
> +AT_CHECK([grep -E 'ingress_policing_kpkts_rate: 42949671' stdout], [], [stdout])
> +
> +dnl Parse log file
> +AT_CHECK([grep "VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) vhost-user client: socket created" ovs-vswitchd.log], [], [stdout])
> +AT_CHECK([grep "vHost User device 'dpdkvhostuserclient0' created in 'client' mode, using client socket" ovs-vswitchd.log], [], [stdout])
> +AT_CHECK([grep "VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) reconnecting..." ovs-vswitchd.log], [], [stdout])
> +
> +dnl Clean up
> +AT_CHECK([ovs-vsctl del-port br10 dpdkvhostuserclient0], [], [stdout], [stderr])
> +OVS_VSWITCHD_STOP("m4_join([], [SYSTEM_DPDK_ALLOWED_LOGS], [
> +\@Could not create tocken bucket for ingress policer@d
> +\@Could not create rte meter for ingress policer@d
>  \@VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) failed to connect: No such file or directory@d
>  ])")
>  AT_CLEANUP
>  dnl --------------------------------------------------------------------------
>
>
> +
> +dnl --------------------------------------------------------------------------
> +dnl Ingress policing (kpkts) max policing burst
> +AT_SETUP([OVS-DPDK - Ingress policing (kpkts) max policing burst])
> +AT_KEYWORDS([dpdk])
> +
> +OVS_DPDK_PRE_CHECK()
> +OVS_DPDK_START()
> +
> +dnl Add userspace bridge and attach it to OVS and add ingress policer
> +AT_CHECK([ovs-vsctl add-br br10 -- set bridge br10 datapath_type=netdev])
> +AT_CHECK([ovs-vsctl add-port br10 dpdkvhostuserclient0 -- set Interface dpdkvhostuserclient0 type=dpdkvhostuserclient options:vhost-server-path=$OVS_RUNDIR/dpdkvhostclient0], [], [stdout], [stderr])
> +AT_CHECK([ovs-vsctl set interface dpdkvhostuserclient0 ingress_policing_kpkts_burst=42949671])
> +AT_CHECK([ovs-vsctl show], [], [stdout])
> +sleep 2
> +
> +dnl check ingress policer not be created
> +AT_FAIL_IF([grep "Could not create tocken bucket for ingress policer" ovs-vswitchd.log], [], [stdout])
> +
> +dnl Check ingress policer was created correctly
> +AT_CHECK([ovs-vsctl list interface dpdkvhostuserclient0], [], [stdout])
> +AT_CHECK([grep -E 'ingress_policing_kpkts_burst: 42949671' stdout], [], [stdout])
> +
> +AT_CHECK([ovs-vsctl list interface dpdkvhostuserclient0], [], [stdout])
> +AT_CHECK([grep -E 'ingress_policing_kpkts_rate: 0' stdout], [], [stdout])
> +
> +dnl Parse log file
> +AT_CHECK([grep "VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) vhost-user client: socket created" ovs-vswitchd.log], [], [stdout])
> +AT_CHECK([grep "vHost User device 'dpdkvhostuserclient0' created in 'client' mode, using client socket" ovs-vswitchd.log], [], [stdout])
> +AT_CHECK([grep "VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) reconnecting..." ovs-vswitchd.log], [], [stdout])
> +
> +dnl Clean up
> +AT_CHECK([ovs-vsctl del-port br10 dpdkvhostuserclient0], [], [stdout], [stderr])
> +OVS_VSWITCHD_STOP("m4_join([], [SYSTEM_DPDK_ALLOWED_LOGS], [
> +\@Could not create tocken bucket for ingress policer@d
> +\@Could not create rte meter for ingress policer@d
> +\@VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) failed to connect: No such file or directory@d
> +])")
> +AT_CLEANUP
> +dnl --------------------------------------------------------------------------
> +
> +
> +
>  dnl --------------------------------------------------------------------------
>  dnl QoS create delete phy port
>  AT_SETUP([OVS-DPDK - QoS create delete phy port])
> -- 
> 2.31.1
>
> _______________________________________________
> dev mailing list
> dev@openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
diff mbox series

Patch

diff --git a/NEWS b/NEWS
index c41c6adf6..53adbed82 100644
--- a/NEWS
+++ b/NEWS
@@ -30,6 +30,10 @@  Post-v3.1.0
        ovs-vsctl set port vhost-user0 qos=@newqos -- \
           --id=@newqos create qos type=egress-policer \
           other-config:kpkts_rate=123 other-config:kpkts_burst=123
+     * Added support for ingress packet-per-second policing.
+       Examples:
+       $ ovs-vsctl set interface dpdk0 ingress_policing_kpkts_rate=123
+       $ ovs-vsctl set interface dpdk0 ingress_policing_kpkts_burst=123
 
 
 v3.1.0 - 16 Feb 2023
diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c
index bcd13c116..a717edc5e 100644
--- a/lib/netdev-dpdk.c
+++ b/lib/netdev-dpdk.c
@@ -413,6 +413,8 @@  struct ingress_policer {
     struct rte_meter_srtcm_params app_srtcm_params;
     struct rte_meter_srtcm in_policer;
     struct rte_meter_srtcm_profile in_prof;
+    struct token_bucket tb;
+    enum policer_type type;
     rte_spinlock_t policer_lock;
 };
 
@@ -496,6 +498,9 @@  struct netdev_dpdk {
         uint32_t policer_rate;
         uint32_t policer_burst;
 
+        uint32_t policer_kpkts_rate;
+        uint32_t policer_kpkts_burst;
+
         /* Array of vhost rxq states, see vring_state_changed. */
         bool *vhost_rxq_enabled;
     );
@@ -1315,6 +1320,8 @@  common_construct(struct netdev *netdev, dpdk_port_t port_no,
     ovsrcu_init(&dev->ingress_policer, NULL);
     dev->policer_rate = 0;
     dev->policer_burst = 0;
+    dev->policer_kpkts_rate = 0;
+    dev->policer_kpkts_burst = 0;
 
     netdev->n_rxq = 0;
     netdev->n_txq = 0;
@@ -2367,9 +2374,16 @@  ingress_policer_run(struct ingress_policer *policer, struct rte_mbuf **pkts,
     int cnt = 0;
 
     rte_spinlock_lock(&policer->policer_lock);
-    cnt = srtcm_policer_run_single_packet(&policer->in_policer,
-                                          &policer->in_prof,
-                                          pkts, pkt_cnt, should_steal);
+    if (policer->type & POLICER_BPS) {
+        cnt = srtcm_policer_run_single_packet(&policer->in_policer,
+                                              &policer->in_prof,
+                                              pkts, pkt_cnt, should_steal);
+    }
+
+    if (policer->type & POLICER_PKTPS) {
+        cnt = pkts_policer_run_single_packet(&policer->tb, pkts, pkt_cnt,
+                                             should_steal);
+    }
     rte_spinlock_unlock(&policer->policer_lock);
 
     return cnt;
@@ -3531,7 +3545,8 @@  netdev_dpdk_get_features(const struct netdev *netdev,
 }
 
 static struct ingress_policer *
-netdev_dpdk_policer_construct(uint32_t rate, uint32_t burst)
+netdev_dpdk_policer_construct(uint32_t rate, uint32_t burst,
+                              uint32_t kpkts_rate, uint32_t kpkts_burst)
 {
     struct ingress_policer *policer = NULL;
     uint64_t rate_bytes;
@@ -3539,6 +3554,9 @@  netdev_dpdk_policer_construct(uint32_t rate, uint32_t burst)
     int err = 0;
 
     policer = xmalloc(sizeof *policer);
+    if (!policer) {
+        return NULL;
+    }
     rte_spinlock_init(&policer->policer_lock);
 
     /* rte_meter requires bytes so convert kbits rate and burst to bytes. */
@@ -3556,8 +3574,29 @@  netdev_dpdk_policer_construct(uint32_t rate, uint32_t burst)
     }
     if (err) {
         VLOG_ERR("Could not create rte meter for ingress policer");
+    } else {
+        policer->type |= POLICER_BPS;
+    }
+
+    if (kpkts_rate > MAX_KPKTS_PARAMETER || kpkts_burst > MAX_KPKTS_PARAMETER
+        || kpkts_rate == 0 || kpkts_burst == 0) {
+        /* Paramters between (1 ~ MAX_KPKTS_PARAMETER). */
+        /* Zero means not to police the flow. */
+        VLOG_ERR("Could not create tocken bucket for ingress policer");
+    } else {
+        /*
+        * By default token is added per millisecond.
+        * Rate in kilo-packets/second, bucket 1000 packets.
+        * msec * kilo-packets/sec = 1 packets.
+        */
+        token_bucket_init(&policer->tb, kpkts_rate, kpkts_burst * 1000);
+        policer->type |= POLICER_PKTPS;
+    }
+
+    if (!policer->type) {
+        /* Neither kbps nor kpkts policer is configured. */
         free(policer);
-        return NULL;
+        policer = NULL;
     }
 
     return policer;
@@ -3566,8 +3605,8 @@  netdev_dpdk_policer_construct(uint32_t rate, uint32_t burst)
 static int
 netdev_dpdk_set_policing(struct netdev* netdev, uint32_t policer_rate,
                          uint32_t policer_burst,
-                         uint32_t policer_kpkts_rate OVS_UNUSED,
-                         uint32_t policer_kpkts_burst OVS_UNUSED)
+                         uint32_t policer_kpkts_rate,
+                         uint32_t policer_kpkts_burst)
 {
     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
     struct ingress_policer *policer;
@@ -3580,13 +3619,23 @@  netdev_dpdk_set_policing(struct netdev* netdev, uint32_t policer_rate,
                      : !policer_burst ? 8000
                      : policer_burst);
 
+    /*
+     * Force to 0 if no rate specified,
+     * default to rate value if burst is 0,
+     * else stick with user-specified value.
+     */
+    policer_kpkts_burst = (!policer_kpkts_rate ? 0
+                           : !policer_kpkts_burst ? policer_kpkts_rate
+                           : policer_kpkts_burst);
     ovs_mutex_lock(&dev->mutex);
 
     policer = ovsrcu_get_protected(struct ingress_policer *,
-                                    &dev->ingress_policer);
+                                   &dev->ingress_policer);
 
     if (dev->policer_rate == policer_rate &&
-        dev->policer_burst == policer_burst) {
+        dev->policer_burst == policer_burst &&
+        dev->policer_kpkts_rate == policer_kpkts_rate &&
+        dev->policer_kpkts_burst == policer_kpkts_burst) {
         /* Assume that settings haven't changed since we last set them. */
         ovs_mutex_unlock(&dev->mutex);
         return 0;
@@ -3597,14 +3646,19 @@  netdev_dpdk_set_policing(struct netdev* netdev, uint32_t policer_rate,
         ovsrcu_postpone(free, policer);
     }
 
-    if (policer_rate != 0) {
-        policer = netdev_dpdk_policer_construct(policer_rate, policer_burst);
-    } else {
+    if (!policer_rate && !policer_kpkts_rate) {
+        /* both policers are zero. */
         policer = NULL;
+    } else {
+        policer = netdev_dpdk_policer_construct(policer_rate, policer_burst,
+                                                policer_kpkts_rate,
+                                                policer_kpkts_burst);
     }
     ovsrcu_set(&dev->ingress_policer, policer);
     dev->policer_rate = policer_rate;
     dev->policer_burst = policer_burst;
+    dev->policer_kpkts_rate = policer_kpkts_rate;
+    dev->policer_kpkts_burst = policer_kpkts_burst;
     ovs_mutex_unlock(&dev->mutex);
 
     return 0;
diff --git a/tests/system-dpdk.at b/tests/system-dpdk.at
index 75a6ab7f5..492bc2f55 100644
--- a/tests/system-dpdk.at
+++ b/tests/system-dpdk.at
@@ -297,7 +297,9 @@  AT_CHECK([grep -E 'ingress_policing_rate: 0' stdout], [], [stdout])
 
 dnl Clean up
 AT_CHECK([ovs-vsctl del-port br10 phy0], [], [stdout], [stderr])
-OVS_VSWITCHD_STOP("[SYSTEM_DPDK_ALLOWED_LOGS]")
+OVS_VSWITCHD_STOP("m4_join([], [SYSTEM_DPDK_ALLOWED_LOGS], [
+\@Could not create tocken bucket for ingress policer@d
+])")
 AT_CLEANUP
 dnl --------------------------------------------------------------------------
 
@@ -339,6 +341,7 @@  AT_CHECK([grep "VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) reconnecting..." ov
 dnl Clean up
 AT_CHECK([ovs-vsctl del-port br10 dpdkvhostuserclient0], [], [stdout], [stderr])
 OVS_VSWITCHD_STOP("m4_join([], [SYSTEM_DPDK_ALLOWED_LOGS], [
+\@Could not create tocken bucket for ingress policer@d
 \@VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) failed to connect: No such file or directory@d
 ])")
 AT_CLEANUP
@@ -420,12 +423,223 @@  AT_CHECK([grep "VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) reconnecting..." ov
 dnl Clean up
 AT_CHECK([ovs-vsctl del-port br10 dpdkvhostuserclient0], [], [stdout], [stderr])
 OVS_VSWITCHD_STOP("m4_join([], [SYSTEM_DPDK_ALLOWED_LOGS], [
+\@Could not create tocken bucket for ingress policer@d
+\@VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) failed to connect: No such file or directory@d
+])")
+AT_CLEANUP
+dnl --------------------------------------------------------------------------
+
+
+dnl --------------------------------------------------------------------------
+dnl Ingress policing (kpkts) create delete vport port
+AT_SETUP([OVS-DPDK - Ingress policing (kpkts) create delete vport port])
+AT_KEYWORDS([dpdk])
+
+OVS_DPDK_PRE_CHECK()
+OVS_DPDK_START()
+
+dnl Add userspace bridge and attach it to OVS and add ingress policer
+AT_CHECK([ovs-vsctl add-br br10 -- set bridge br10 datapath_type=netdev])
+AT_CHECK([ovs-vsctl add-port br10 dpdkvhostuserclient0 -- set Interface dpdkvhostuserclient0 type=dpdkvhostuserclient options:vhost-server-path=$OVS_RUNDIR/dpdkvhostclient0], [], [stdout], [stderr])
+AT_CHECK([ovs-vsctl set interface dpdkvhostuserclient0 ingress_policing_kpkts_rate=10000 ingress_policing_kpkts_burst=10000])
+AT_CHECK([ovs-vsctl show], [], [stdout])
+sleep 2
+
+dnl Remove ingress policer
+AT_CHECK([ovs-vsctl set interface dpdkvhostuserclient0 ingress_policing_kpkts_rate=0 ingress_policing_kpkts_burst=0])
+
+dnl Fail if ingress policer could not be created
+AT_FAIL_IF([grep "Could not create tocken bucket for ingress policer" ovs-vswitchd.log], [], [stdout])
+
+dnl Check ingress policer was removed correctly
+AT_CHECK([ovs-vsctl list interface dpdkvhostuserclient0], [], [stdout])
+AT_CHECK([grep -E 'ingress_policing_kpkts_burst: 0' stdout], [], [stdout])
+
+AT_CHECK([ovs-vsctl list interface dpdkvhostuserclient0], [], [stdout])
+AT_CHECK([grep -E 'ingress_policing_kpkts_rate: 0' stdout], [], [stdout])
+
+dnl Parse log file
+AT_CHECK([grep "VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) vhost-user client: socket created" ovs-vswitchd.log], [], [stdout])
+AT_CHECK([grep "vHost User device 'dpdkvhostuserclient0' created in 'client' mode, using client socket" ovs-vswitchd.log], [], [stdout])
+AT_CHECK([grep "VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) reconnecting..." ovs-vswitchd.log], [], [stdout])
+
+dnl Clean up
+AT_CHECK([ovs-vsctl del-port br10 dpdkvhostuserclient0], [], [stdout], [stderr])
+OVS_VSWITCHD_STOP("m4_join([], [SYSTEM_DPDK_ALLOWED_LOGS], [
+\@Could not create rte meter for ingress policer@d
+\@VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) failed to connect: No such file or directory@d
+])")
+AT_CLEANUP
+dnl --------------------------------------------------------------------------
+
+
+
+dnl --------------------------------------------------------------------------
+dnl Ingress policing (kpkts) no policing rate
+AT_SETUP([OVS-DPDK - Ingress policing (kpkts) no policing rate])
+AT_KEYWORDS([dpdk])
+
+OVS_DPDK_PRE_CHECK()
+OVS_DPDK_START()
+
+dnl Add userspace bridge and attach it to OVS and add ingress policer
+AT_CHECK([ovs-vsctl add-br br10 -- set bridge br10 datapath_type=netdev])
+AT_CHECK([ovs-vsctl add-port br10 dpdkvhostuserclient0 -- set Interface dpdkvhostuserclient0 type=dpdkvhostuserclient options:vhost-server-path=$OVS_RUNDIR/dpdkvhostclient0], [], [stdout], [stderr])
+AT_CHECK([ovs-vsctl set interface dpdkvhostuserclient0 ingress_policing_kpkts_burst=1000])
+AT_CHECK([ovs-vsctl show], [], [stdout])
+sleep 2
+
+dnl check ingress policer not be created
+AT_FAIL_IF([grep "Could not create tocken bucket for ingress policer" ovs-vswitchd.log], [], [stdout])
+
+dnl Check ingress policer was created correctly
+AT_CHECK([ovs-vsctl list interface dpdkvhostuserclient0], [], [stdout])
+AT_CHECK([grep -E 'ingress_policing_kpkts_burst: 1000' stdout], [], [stdout])
+
+AT_CHECK([ovs-vsctl list interface dpdkvhostuserclient0], [], [stdout])
+AT_CHECK([grep -E 'ingress_policing_kpkts_rate: 0' stdout], [], [stdout])
+
+
+dnl Parse log file
+AT_CHECK([grep "VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) vhost-user client: socket created" ovs-vswitchd.log], [], [stdout])
+AT_CHECK([grep "vHost User device 'dpdkvhostuserclient0' created in 'client' mode, using client socket" ovs-vswitchd.log], [], [stdout])
+AT_CHECK([grep "VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) reconnecting..." ovs-vswitchd.log], [], [stdout])
+
+dnl Clean up
+AT_CHECK([ovs-vsctl del-port br10 dpdkvhostuserclient0], [], [stdout], [stderr])
+OVS_VSWITCHD_STOP("m4_join([], [SYSTEM_DPDK_ALLOWED_LOGS], [
+\@VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) failed to connect: No such file or directory@d
+])")
+AT_CLEANUP
+dnl --------------------------------------------------------------------------
+
+
+
+dnl --------------------------------------------------------------------------
+dnl Ingress policing (kpkts) no policing burst
+AT_SETUP([OVS-DPDK - Ingress policing (kpkts) no policing burst])
+AT_KEYWORDS([dpdk])
+
+OVS_DPDK_PRE_CHECK()
+OVS_DPDK_START()
+
+dnl Add userspace bridge and attach it to OVS and add ingress policer
+AT_CHECK([ovs-vsctl add-br br10 -- set bridge br10 datapath_type=netdev])
+AT_CHECK([ovs-vsctl add-port br10 dpdkvhostuserclient0 -- set Interface dpdkvhostuserclient0 type=dpdkvhostuserclient options:vhost-server-path=$OVS_RUNDIR/dpdkvhostclient0], [], [stdout], [stderr])
+AT_CHECK([ovs-vsctl set interface dpdkvhostuserclient0 ingress_policing_kpkts_rate=10000])
+AT_CHECK([ovs-vsctl show], [], [stdout])
+sleep 2
+
+dnl check ingress policer not be created
+AT_FAIL_IF([grep "Could not create tocken bucket for ingress policer" ovs-vswitchd.log], [], [stdout])
+
+dnl Check ingress policer was created correctly
+AT_CHECK([ovs-vsctl list interface dpdkvhostuserclient0], [], [stdout])
+AT_CHECK([grep -E 'ingress_policing_kpkts_burst: 0' stdout], [], [stdout])
+
+AT_CHECK([ovs-vsctl list interface dpdkvhostuserclient0], [], [stdout])
+AT_CHECK([grep -E 'ingress_policing_kpkts_rate: 10000' stdout], [], [stdout])
+
+dnl Parse log file
+AT_CHECK([grep "VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) vhost-user client: socket created" ovs-vswitchd.log], [], [stdout])
+AT_CHECK([grep "vHost User device 'dpdkvhostuserclient0' created in 'client' mode, using client socket" ovs-vswitchd.log], [], [stdout])
+AT_CHECK([grep "VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) reconnecting..." ovs-vswitchd.log], [], [stdout])
+
+dnl Clean up
+AT_CHECK([ovs-vsctl del-port br10 dpdkvhostuserclient0], [], [stdout], [stderr])
+OVS_VSWITCHD_STOP("m4_join([], [SYSTEM_DPDK_ALLOWED_LOGS], [
+\@Could not create rte meter for ingress policer@d
+\@VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) failed to connect: No such file or directory@d
+])")
+AT_CLEANUP
+dnl --------------------------------------------------------------------------
+
+
+
+dnl --------------------------------------------------------------------------
+dnl Ingress policing (kpkts) max policing rate
+AT_SETUP([OVS-DPDK - Ingress policing (kpkts) max policing rate])
+AT_KEYWORDS([dpdk])
+
+OVS_DPDK_PRE_CHECK()
+OVS_DPDK_START()
+
+dnl Add userspace bridge and attach it to OVS and add ingress policer
+AT_CHECK([ovs-vsctl add-br br10 -- set bridge br10 datapath_type=netdev])
+AT_CHECK([ovs-vsctl add-port br10 dpdkvhostuserclient0 -- set Interface dpdkvhostuserclient0 type=dpdkvhostuserclient options:vhost-server-path=$OVS_RUNDIR/dpdkvhostclient0], [], [stdout], [stderr])
+AT_CHECK([ovs-vsctl set interface dpdkvhostuserclient0 ingress_policing_kpkts_rate=42949671])
+AT_CHECK([ovs-vsctl show], [], [stdout])
+sleep 2
+
+dnl check ingress policer not be created
+AT_CHECK([grep "Could not create tocken bucket for ingress policer" ovs-vswitchd.log], [], [stdout])
+
+dnl Check ingress policer was created correctly
+AT_CHECK([ovs-vsctl list interface dpdkvhostuserclient0], [], [stdout])
+AT_CHECK([grep -E 'ingress_policing_kpkts_burst: 0' stdout], [], [stdout])
+
+AT_CHECK([ovs-vsctl list interface dpdkvhostuserclient0], [], [stdout])
+AT_CHECK([grep -E 'ingress_policing_kpkts_rate: 42949671' stdout], [], [stdout])
+
+dnl Parse log file
+AT_CHECK([grep "VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) vhost-user client: socket created" ovs-vswitchd.log], [], [stdout])
+AT_CHECK([grep "vHost User device 'dpdkvhostuserclient0' created in 'client' mode, using client socket" ovs-vswitchd.log], [], [stdout])
+AT_CHECK([grep "VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) reconnecting..." ovs-vswitchd.log], [], [stdout])
+
+dnl Clean up
+AT_CHECK([ovs-vsctl del-port br10 dpdkvhostuserclient0], [], [stdout], [stderr])
+OVS_VSWITCHD_STOP("m4_join([], [SYSTEM_DPDK_ALLOWED_LOGS], [
+\@Could not create tocken bucket for ingress policer@d
+\@Could not create rte meter for ingress policer@d
 \@VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) failed to connect: No such file or directory@d
 ])")
 AT_CLEANUP
 dnl --------------------------------------------------------------------------
 
 
+
+dnl --------------------------------------------------------------------------
+dnl Ingress policing (kpkts) max policing burst
+AT_SETUP([OVS-DPDK - Ingress policing (kpkts) max policing burst])
+AT_KEYWORDS([dpdk])
+
+OVS_DPDK_PRE_CHECK()
+OVS_DPDK_START()
+
+dnl Add userspace bridge and attach it to OVS and add ingress policer
+AT_CHECK([ovs-vsctl add-br br10 -- set bridge br10 datapath_type=netdev])
+AT_CHECK([ovs-vsctl add-port br10 dpdkvhostuserclient0 -- set Interface dpdkvhostuserclient0 type=dpdkvhostuserclient options:vhost-server-path=$OVS_RUNDIR/dpdkvhostclient0], [], [stdout], [stderr])
+AT_CHECK([ovs-vsctl set interface dpdkvhostuserclient0 ingress_policing_kpkts_burst=42949671])
+AT_CHECK([ovs-vsctl show], [], [stdout])
+sleep 2
+
+dnl check ingress policer not be created
+AT_FAIL_IF([grep "Could not create tocken bucket for ingress policer" ovs-vswitchd.log], [], [stdout])
+
+dnl Check ingress policer was created correctly
+AT_CHECK([ovs-vsctl list interface dpdkvhostuserclient0], [], [stdout])
+AT_CHECK([grep -E 'ingress_policing_kpkts_burst: 42949671' stdout], [], [stdout])
+
+AT_CHECK([ovs-vsctl list interface dpdkvhostuserclient0], [], [stdout])
+AT_CHECK([grep -E 'ingress_policing_kpkts_rate: 0' stdout], [], [stdout])
+
+dnl Parse log file
+AT_CHECK([grep "VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) vhost-user client: socket created" ovs-vswitchd.log], [], [stdout])
+AT_CHECK([grep "vHost User device 'dpdkvhostuserclient0' created in 'client' mode, using client socket" ovs-vswitchd.log], [], [stdout])
+AT_CHECK([grep "VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) reconnecting..." ovs-vswitchd.log], [], [stdout])
+
+dnl Clean up
+AT_CHECK([ovs-vsctl del-port br10 dpdkvhostuserclient0], [], [stdout], [stderr])
+OVS_VSWITCHD_STOP("m4_join([], [SYSTEM_DPDK_ALLOWED_LOGS], [
+\@Could not create tocken bucket for ingress policer@d
+\@Could not create rte meter for ingress policer@d
+\@VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) failed to connect: No such file or directory@d
+])")
+AT_CLEANUP
+dnl --------------------------------------------------------------------------
+
+
+
 dnl --------------------------------------------------------------------------
 dnl QoS create delete phy port
 AT_SETUP([OVS-DPDK - QoS create delete phy port])