[email protected] writes:

> From: Lin Huang <[email protected]>
>
> 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 <[email protected]>
> ---
>  Documentation/topics/dpdk/qos.rst |  21 ++
>  NEWS                              |   2 +
>  lib/netdev-dpdk.c                 |  91 +++++++-
>  tests/system-dpdk.at              | 339 ++++++++++++++++++++++++++++++
>  4 files changed, 445 insertions(+), 8 deletions(-)
>
> diff --git a/Documentation/topics/dpdk/qos.rst 
> b/Documentation/topics/dpdk/qos.rst
> index 6a4408127..db66dcecf 100644
> --- a/Documentation/topics/dpdk/qos.rst
> +++ b/Documentation/topics/dpdk/qos.rst
> @@ -120,6 +120,9 @@ Refer to ``vswitch.xml`` for more details on egress 
> policer.
>  Rate Limiting (Ingress Policing)
>  --------------------------------
>  
> +Bytes Per Second Policer
> +~~~~~~~~~~~~~~~~~~~~
> +
>  Assuming you have a :doc:`vhost-user port <vhost-user>` receiving traffic
>  consisting of packets of size 64 bytes, the following command would limit the
>  reception rate of the port to ~1,000,000 packets per second::
> @@ -135,6 +138,24 @@ To clear the ingress policer configuration from the 
> port::
>  
>      $ ovs-vsctl set interface vhost-user0 ingress_policing_rate=0
>  
> +Packets Per Second Policer
> +~~~~~~~~~~~~~~~~~~~~
> +
> +Assuming you have a :doc:`vhost-user port <vhost-user>` receiving traffic,
> +the following command would limit the reception rate of the port to 
> ~1,000,000
> +packets per second::
> +
> +    $ ovs-vsctl set interface dpdk0 ingress_policing_kpkts_rate=1000 \
> +        ingress_policing_kpkts_burst=1000`
> +
> +To examine the ingress policer configuration of the port::
> +
> +    $ ovs-vsctl list interface vhost-user0
> +
> +To clear the ingress policer configuration from the port::
> +
> +    $ ovs-vsctl set interface vhost-user0 ingress_policing_rate=0
> +
>  Refer to ``vswitch.xml`` for more details on ingress policer.
>  
>  Flow Control
> diff --git a/NEWS b/NEWS
> index 3d1ab282e..47330e644 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -64,6 +64,8 @@ v3.2.0 - xx xxx xxxx
>         max sleep configuration of PMD thread cores.
>       * Removed experimental tag from PMD load based sleeping.
>       * Added new Qos type 'pkts-policer' to support kilo packet-per-second 
> policing.
> +     * Added support for ingress kilo packet-per-second policing configured 
> by
> +       ingress_policing_kpkts_rate/burst options.
>     - Linux TC offload:
>       * Add support for offloading VXLAN tunnels with the GBP extensions.
>     - Python
> diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c
> index e6b8922aa..8c252022a 100644
> --- a/lib/netdev-dpdk.c
> +++ b/lib/netdev-dpdk.c
> @@ -406,10 +406,17 @@ struct dpdk_tx_queue {
>      );
>  };
>  
> +enum policer_type {
> +    POLICER_BPS   = 1 << 0,   /* Rate value in bytes/sec. */
> +    POLICER_PKTPS = 1 << 1,   /* Rate value in packet/sec. */
> +};
> +
>  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;
>  };
>  
> @@ -516,6 +523,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;
>  
> @@ -615,6 +625,14 @@ is_dpdk_class(const struct netdev_class *class)
>             || class->destruct == netdev_dpdk_vhost_destruct;
>  }
>  
> +static int
> +kpkts_policer_run_single_packet(struct token_bucket *tb, struct rte_mbuf 
> **pkts,
> +                                int pkt_cnt, bool should_steal);
> +
> +static int
> +kpkts_policer_profile_config(struct token_bucket *tb,
> +                             uint32_t kpkts_rate, uint32_t kpkts_burst);
> +
>  /* DPDK NIC drivers allocate RX buffers at a particular granularity, 
> typically
>   * aligned at 1k or less. If a declared mbuf size is not a multiple of this
>   * value, insufficient buffers are allocated to accomodate the packet in its
> @@ -1462,6 +1480,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;
> @@ -2582,9 +2602,17 @@ 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);
> +    }
> +
> +    /* bps nd pps rate limits not allowed to configure at the same time. */
> +    if (policer->type & POLICER_PKTPS) {
> +        cnt = kpkts_policer_run_single_packet(&policer->tb, pkts, pkt_cnt,
> +                                              should_steal);
> +    }
>      rte_spinlock_unlock(&policer->policer_lock);
>  
>      return cnt;
> @@ -3810,7 +3838,7 @@ netdev_dpdk_policer_construct(uint32_t rate, uint32_t 
> burst)
>      uint64_t burst_bytes;
>      int err = 0;
>  
> -    policer = xmalloc(sizeof *policer);
> +    policer = xzalloc(sizeof *policer);
>      rte_spinlock_init(&policer->policer_lock);
>  
>      /* rte_meter requires bytes so convert kbits rate and burst to bytes. */
> @@ -3832,18 +3860,48 @@ netdev_dpdk_policer_construct(uint32_t rate, uint32_t 
> burst)
>          return NULL;
>      }
>  
> +    policer->type |= POLICER_BPS;
> +
> +    return policer;
> +}
> +
> +static struct ingress_policer *
> +netdev_dpdk_kpkts_policer_construct(uint32_t kpkts_rate, uint32_t 
> kpkts_burst)
> +{
> +    struct ingress_policer *policer = NULL;
> +    int err = 0;
> +
> +    policer = xzalloc(sizeof *policer);
> +    rte_spinlock_init(&policer->policer_lock);
> +
> +    err = kpkts_policer_profile_config(&policer->tb, kpkts_rate, 
> kpkts_burst);
> +    if (err) {
> +        VLOG_ERR("Could not create tocken bucket for ingress policer");
> +        free(policer);
> +        return NULL;
> +    }
> +
> +    policer->type |= POLICER_PKTPS;
> +
>      return policer;
>  }
>  
>  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;
>  
> +    if (policer_rate && policer_kpkts_rate) {
> +        VLOG_WARN("packet-per-second and byte-per-second rate limits not"
> +                  " allowed to configure at the same time.");
> +
> +        return -1;

I think we should return EINVAL here

> +    }
> +
>      /* Force to 0 if no rate specified,
>       * default to 8000 kbits if burst is 0,
>       * else stick with user-specified value.
> @@ -3852,13 +3910,24 @@ 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);

Why this whitespace change?

>  
>      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;
> @@ -3871,12 +3940,18 @@ netdev_dpdk_set_policing(struct netdev* netdev, 
> uint32_t policer_rate,
>  
>      if (policer_rate != 0) {
>          policer = netdev_dpdk_policer_construct(policer_rate, policer_burst);
> +    } else if (policer_kpkts_rate != 0) {
> +        policer = netdev_dpdk_kpkts_policer_construct(policer_kpkts_rate,
> +                                                      policer_kpkts_burst);
>      } else {
>          policer = NULL;
>      }
> +
>      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 8b80a31e6..9f209604e 100644
> --- a/tests/system-dpdk.at
> +++ b/tests/system-dpdk.at
> @@ -426,6 +426,345 @@ 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-appctl vlog/set netdev_dpdk:dbg], [], [stdout])
> +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 token 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-appctl vlog/set netdev_dpdk:dbg], [], [stdout])
> +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 token 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-appctl vlog/set netdev_dpdk:dbg], [], [stdout])
> +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 token 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-appctl vlog/set netdev_dpdk:dbg], [], [stdout])
> +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 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 token 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-appctl vlog/set netdev_dpdk:dbg], [], [stdout])
> +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 token 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 token 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) set both bps and pps policing configurations
> +AT_SETUP([OVS-DPDK - Ingress policing (kpkts) both policing configurations])
> +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-appctl vlog/set netdev_dpdk:dbg], [], [stdout])
> +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_rate=1234 ingress_policing_burst=1234 
> ingress_policing_kpkts_rate=1234 ingress_policing_kpkts_burst=1234])
> +AT_CHECK([ovs-vsctl show], [], [stdout])
> +sleep 2
> +
> +dnl check ingress policer not be created
> +AT_CHECK([grep "packet-per-second and byte-per-second" ovs-vswitchd.log | 
> sed 's/^.*|WARN|//'], [0], [stdout])
> +
> +dnl Check ingress policer was created correctly
> +AT_CHECK([ovs-vsctl list interface dpdkvhostuserclient0], [], [stdout])
> +AT_CHECK([grep -E 'ingress_policing_kpkts_burst: 1234' stdout], [], [stdout])
> +
> +AT_CHECK([ovs-vsctl list interface dpdkvhostuserclient0], [], [stdout])
> +AT_CHECK([grep -E 'ingress_policing_kpkts_rate: 1234' stdout], [], [stdout])
> +
> +AT_CHECK([ovs-vsctl list interface dpdkvhostuserclient0], [], [stdout])
> +AT_CHECK([grep -E 'ingress_policing_rate: 1234' stdout], [], [stdout])
> +
> +AT_CHECK([ovs-vsctl list interface dpdkvhostuserclient0], [], [stdout])
> +AT_CHECK([grep -E 'ingress_policing_burst: 1234' stdout], [], [stdout])
> +
> +dnl check ingress policer not be created
> +AT_CHECK([ovs-vsctl set interface dpdkvhostuserclient0 
> ingress_policing_rate=0 ingress_policing_burst=1234 
> ingress_policing_kpkts_rate=1234 ingress_policing_kpkts_burst=1234])
> +AT_FAIL_IF([grep "Could not create token bucket for ingress policer" 
> ovs-vswitchd.log], [], [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 token 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
> +\@packet-per-second and byte-per-second@d
> +])")
> +AT_CLEANUP
> +dnl 
> --------------------------------------------------------------------------
> +
> +
> +
> +dnl 
> --------------------------------------------------------------------------
> +dnl Ingress policing (kpkts) police
> +AT_SETUP([OVS-DPDK - Ingress policing (kpkts) police])
> +AT_KEYWORDS([dpdk])
> +
> +OVS_DPDK_PRE_CHECK()
> +AT_SKIP_IF([! which dpdk-testpmd >/dev/null 2>/dev/null])
> +OVS_DPDK_START([--no-pci])
> +
> +dnl Find number of sockets
> +AT_CHECK([lscpu], [], [stdout])
> +AT_CHECK([cat stdout | grep "NUMA node(s)" | awk '{c=1; while (c++<$(3)) 
> {printf "512,"}; print "512"}' > NUMA_NODE])
> +
> +dnl Add userspace bridge and attach it to OVS
> +AT_CHECK([ovs-vsctl add-br br10 -- set bridge br10 datapath_type=netdev])
> +
> +dnl Parse log file
> +AT_CHECK([ovs-vsctl add-port br10 dpdkvhostuser0 -- set Interface 
> dpdkvhostuser0 type=dpdkvhostuser], [], [stdout], [stderr])
> +AT_CHECK([ovs-vsctl add-port br10 dpdkvhostuser1 -- set Interface 
> dpdkvhostuser1 type=dpdkvhostuser], [], [stdout], [stderr])
> +AT_CHECK([ovs-vsctl show], [], [stdout])
> +
> +dnl Parse log file
> +AT_CHECK([grep "VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostuser0) vhost-user 
> server: socket created" ovs-vswitchd.log], [], [stdout])
> +AT_CHECK([grep "Socket $OVS_RUNDIR/dpdkvhostuser0 created for vhost-user 
> port dpdkvhostuser0" ovs-vswitchd.log], [], [stdout])
> +AT_CHECK([grep "VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostuser0) binding 
> succeeded" ovs-vswitchd.log], [], [stdout])
> +
> +dnl Parse log file
> +AT_CHECK([grep "VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostuser1) vhost-user 
> server: socket created" ovs-vswitchd.log], [], [stdout])
> +AT_CHECK([grep "Socket $OVS_RUNDIR/dpdkvhostuser1 created for vhost-user 
> port dpdkvhostuser1" ovs-vswitchd.log], [], [stdout])
> +AT_CHECK([grep "VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostuser1) binding 
> succeeded" ovs-vswitchd.log], [], [stdout])
> +
> +dnl Configure the police for interface.
> +AT_CHECK([ovs-vsctl set interface dpdkvhostuser1 
> ingress_policing_kpkts_rate=1 ingress_policing_kpkts_burst=1])
> +
> +dnl add flows, only send packets from dpdkvhostuser1 to dpdkvhostuser0.
> +AT_DATA([flows.txt], [dnl
> +priority=100,in_port=dpdkvhostuser1,ip,actions=dpdkvhostuser0
> +])
> +
> +AT_CHECK([ovs-ofctl del-flows br10])
> +AT_CHECK([ovs-ofctl add-flows br10 flows.txt])
> +
> +dnl Execute testpmd in background
> +on_exit "pkill -f -x -9 'tail -f /dev/null'"
> +tail -f /dev/null | dpdk-testpmd --socket-mem="$(cat NUMA_NODE)" --no-pci\
> +           --vdev="net_virtio_user0,path=$OVS_RUNDIR/dpdkvhostuser0" \
> +           --vdev="net_virtio_user1,path=$OVS_RUNDIR/dpdkvhostuser1" \
> +           --single-file-segments -- --forward-mode=flowgen -a > 
> $OVS_RUNDIR/testpmd-dpdkvhostuser.log 2>&1 &
> +
> +dnl sent packet 10 second.
> +AT_CHECK([sleep 10])
> +
> +dnl Clean up the testpmd now
> +pkill -f -x -9 'tail -f /dev/null'
> +
> +dnl ---------------------- Forward statistics for port 0  
> ----------------------
> +dnl RX-packets: 9911           RX-dropped: 0             RX-total: 9911
> +dnl TX-packets: 15937632       TX-dropped: 226661984     TX-total: 242599616
> +dnl 
> ----------------------------------------------------------------------------
> +port0_rx_packets=`cat testpmd-dpdkvhostuser.log | grep "Forward statistics 
> for port 0" -A 1 | grep "RX-packets:" | awk '{print $2}'`
> +echo "port0_rx_packets=$port0_rx_packets"
> +
> +AT_CHECK([test $port0_rx_packets -lt 10500])
> +AT_CHECK([test $port0_rx_packets -gt 9500])
> +
> +OVS_VSWITCHD_STOP("m4_join([], [SYSTEM_DPDK_ALLOWED_LOGS], [
> +\@dpdkvhostuser ports are considered deprecated;  please migrate to 
> dpdkvhostuserclient ports.@d
> +])")
> +AT_CLEANUP
> +dnl 
> --------------------------------------------------------------------------
> +
> +
> +
>  dnl 
> --------------------------------------------------------------------------
>  dnl QoS create delete phy port
>  AT_SETUP([OVS-DPDK - QoS create delete phy port])

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to