Hi,
Oh.. You are right I did send the wrong version. Let me send the latest version.

Regards
Anju

-----Original Message-----
From: Ilya Maximets <i.maxim...@samsung.com> 
Sent: Thursday, June 6, 2019 8:18 PM
To: Anju Thomas <anju.tho...@ericsson.com>; ovs-dev@openvswitch.org
Cc: Eelco Chaudron <echau...@redhat.com>
Subject: Re: [ovs-dev] [PATCH v9] Improved Packet Drop Statistics in OVS

On 06.06.2019 17:28, Anju Thomas wrote:
> Hi Ilya,
> Yes, I have addressed those comments in v9.

That is really strange. Maybe you've sent the wrong version?

That is what I (and everyone else) received:
  https://mail.openvswitch.org/pipermail/ovs-dev/2019-February/356743.html
It's the same code as down below.

You may simply grep for following lines:

COVERAGE_DEFINE(dp_sample_error_drop);   <-- I asked to rename this.

if (tnl_process_ecn(flow)                <-- Here started a big diff that
                                             that I suggested to replace with
                                             a smaller one.

packet_count = packets_->count;          <-- Here I suggested to use
                                             dp_packet_batch_size().

Please, re-check.
Here is my review for v8, just in case:
https://mail.openvswitch.org/pipermail/ovs-dev/2019-February/356153.html

Best regards, Ilya Maximets.


> 
> Regards  & Thanks
> Anju
> 
> -----Original Message-----
> From: Ilya Maximets <i.maxim...@samsung.com>
> Sent: Tuesday, June 4, 2019 12:33 PM
> To: ovs-dev@openvswitch.org; Anju Thomas <anju.tho...@ericsson.com>
> Cc: Eelco Chaudron <echau...@redhat.com>
> Subject: Re: Re: [ovs-dev] [PATCH v9] Improved Packet Drop Statistics 
> in OVS
> 
>> Hi Eelco,
>> Apart from Ilya's comments I have not received any comments for v8. I have 
>> addressed those comment in v9.
> 
> Hi Anju.
> I wrote about my comments to v8 just because you didn't reply or address a 
> bunch of them in v9. There was comments about using dp_packet_batch_size(), 
> renaming suggestion for sample and nsh drop counters, suggested ecn handling 
> code snippet, maybe something else.
> 
> Best regards, Ilya Maximets.
> 
>>
>> Regards
>> Anju
>>
>> -----Original Message-----
>> From: Eelco Chaudron <echaudro at redhat.com>
>> Sent: Monday, June 3, 2019 6:23 PM
>> To: Anju Thomas <anju.thomas at ericsson.com>
>> Cc: dev at openvswitch.org
>> Subject: Re: [ovs-dev] [PATCH v9] Improved Packet Drop Statistics in 
>> OVS
>>
>> Hi Anju,
>>
>> Wondering if you got the email below…
>>
>> Cheers,
>>
>> Eelco
>>
>>
>> On 24 May 2019, at 11:46, Eelco Chaudron wrote:
>>
>>> Hi Anju,
>>>
>>> Was there ever a follow up on this patch? I only see one response 
>>> from Ilya on this asking about his v8 comments.
>>>
>>> Thanks,
>>>
>>> Eelco
>>>
>>>
>>> On 27 Feb 2019, at 10:22, Anju Thomas wrote:
>>>
>>>> Currently OVS maintains explicit packet drop/error counters only on 
>>>> port level. Packets that are dropped as part of normal OpenFlow 
>>>> processing are counted in flow stats of “drop” flows or as table 
>>>> misses in table stats.
>>>> These can only be interpreted by controllers that know the 
>>>> semantics of the configured OpenFlow pipeline. Without that 
>>>> knowledge, it is impossible for an OVS user to obtain e.g. the 
>>>> total number of packets dropped due to OpenFlow rules.
>>>>
>>>> Furthermore, there are numerous other reasons for which packets can 
>>>> be dropped by OVS slow path that are not related to the OpenFlow 
>>>> pipeline.
>>>> The generated datapath flow entries include a drop action to avoid 
>>>> further expensive upcalls to the slow path, but subsequent packets 
>>>> dropped by the datapath are not accounted anywhere.
>>>>
>>>> Finally, the datapath itself drops packets in certain error 
>>>> situations.
>>>> Also, these drops are today not accounted for.
>>>>
>>>> This makes it difficult for OVS users to monitor packet drop in an 
>>>> OVS instance and to alert a management system in case of a 
>>>> unexpected increase of such drops. Also OVS trouble-shooters face 
>>>> difficulties in analysing packet drops.
>>>>
>>>> With this patch we implement following changes to address the 
>>>> issues mentioned above.
>>>>
>>>> 1. Identify and account all the silent packet drop scenarios
>>>>
>>>> 2. Display these drops in ovs-appctl coverage/show
>>>>
>>>> A detailed presentation on this was presented at OvS conference 
>>>> 2017 and link for the corresponding presentation is available at:
>>>>
>>>> https://www.slideshare.net/LF_OpenvSwitch/lfovs17troubleshooting-th
>>>> e
>>>> -
>>>> data-plane-in-ovs-82280329
>>>>
>>>> Co-authored-by: Rohith Basavaraja <rohith.basavaraja at gmail.com>
>>>> Co-authored-by: Keshav Gupta <keshugupta1 at gmail.com>
>>>> Signed-off-by: Anju Thomas <anju.thomas at ericsson.com>
>>>> Signed-off-by: Rohith Basavaraja <rohith.basavaraja at gmail.com>
>>>> Signed-off-by: Keshav Gupta <keshugupta1 at gmail.com>
>>>> ---
>>>>  datapath/linux/compat/include/linux/openvswitch.h |   1 +
>>>>  lib/dpif-netdev.c                                 |  44 ++++-
>>>>  lib/dpif.c                                        |   7 +
>>>>  lib/dpif.h                                        |   3 +
>>>>  lib/odp-execute.c                                 |  81 ++++++++-
>>>>  lib/odp-util.c                                    |   9 +
>>>>  ofproto/ofproto-dpif-ipfix.c                      |   1 +
>>>>  ofproto/ofproto-dpif-sflow.c                      |   1 +
>>>>  ofproto/ofproto-dpif-xlate.c                      | 103 +++++++----
>>>>  ofproto/ofproto-dpif-xlate.h                      |   3 +
>>>>  ofproto/ofproto-dpif.c                            |   8 +
>>>>  ofproto/ofproto-dpif.h                            |   7 +-
>>>>  tests/automake.mk                                 |   3 +-
>>>>  tests/dpif-netdev.at                              |   8 +
>>>>  tests/drop-stats.at                               | 197 
>>>> ++++++++++++++++++++++
>>>>  tests/ofproto-dpif.at                             |   2 +-
>>>>  tests/testsuite.at                                |   1 +
>>>>  tests/tunnel-push-pop.at                          |  28 ++-
>>>>  tests/tunnel.at                                   |  14 +-
>>>>  19 files changed, 475 insertions(+), 46 deletions(-)  create mode
>>>> 100644 tests/drop-stats.at
>>>>
>>>> diff --git a/datapath/linux/compat/include/linux/openvswitch.h
>>>> b/datapath/linux/compat/include/linux/openvswitch.h
>>>> index d5aa09d..e77e9c8 100644
>>>> --- a/datapath/linux/compat/include/linux/openvswitch.h
>>>> +++ b/datapath/linux/compat/include/linux/openvswitch.h
>>>> @@ -946,6 +946,7 @@ enum ovs_action_attr {
>>>>    OVS_ACTION_ATTR_POP_NSH,      /* No argument. */
>>>>    OVS_ACTION_ATTR_METER,        /* u32 meter number. */
>>>>    OVS_ACTION_ATTR_CLONE,        /* Nested OVS_CLONE_ATTR_*.  */
>>>> +  OVS_ACTION_ATTR_DROP,         /* Drop action. */
>>>>
>>>>  #ifndef __KERNEL__
>>>>    OVS_ACTION_ATTR_TUNNEL_PUSH,   /* struct ovs_action_push_tnl*/
>>>> diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index
>>>> 77ac1d2..acc7913 100644
>>>> --- a/lib/dpif-netdev.c
>>>> +++ b/lib/dpif-netdev.c
>>>> @@ -101,6 +101,17 @@ enum { MAX_METERS = 65536 };    /* Maximum 
>>>> number of meters. */
>>>>  enum { MAX_BANDS = 8 };         /* Maximum number of bands / meter. 
>>>> */
>>>>  enum { N_METER_LOCKS = 64 };    /* Maximum number of meters. */
>>>>
>>>> +COVERAGE_DEFINE(datapath_drop_meter);
>>>> +COVERAGE_DEFINE(datapath_drop_upcall_error);
>>>> +COVERAGE_DEFINE(datapath_drop_lock_error);
>>>> +COVERAGE_DEFINE(datapath_drop_userspace_action_error);
>>>> +COVERAGE_DEFINE(datapath_drop_tunnel_push_error);
>>>> +COVERAGE_DEFINE(datapath_drop_tunnel_pop_error);
>>>> +COVERAGE_DEFINE(datapath_drop_recirc_error);
>>>> +COVERAGE_DEFINE(datapath_drop_invalid_port);
>>>> +COVERAGE_DEFINE(datapath_drop_invalid_tnl_port);
>>>> +COVERAGE_DEFINE(datapath_drop_rx_invalid_packet);
>>>> +
>>>>  /* Protects against changes to 'dp_netdevs'. */  static struct 
>>>> ovs_mutex dp_netdev_mutex = OVS_MUTEX_INITIALIZER;
>>>>
>>>> @@ -5647,6 +5658,7 @@ dp_netdev_run_meter(struct dp_netdev *dp, 
>>>> struct dp_packet_batch *packets_,
>>>>              band->packet_count += 1;
>>>>              band->byte_count += dp_packet_size(packet);
>>>>
>>>> +            COVERAGE_INC(datapath_drop_meter);
>>>>              dp_packet_delete(packet);
>>>>          } else {
>>>>              /* Meter accepts packet. */ @@ -6402,6 +6414,7 @@ 
>>>> dfc_processing(struct dp_netdev_pmd_thread *pmd,
>>>>
>>>>          if (OVS_UNLIKELY(dp_packet_size(packet) < ETH_HEADER_LEN)) {
>>>>              dp_packet_delete(packet);
>>>> +            COVERAGE_INC(datapath_drop_rx_invalid_packet);
>>>>              continue;
>>>>          }
>>>>
>>>> @@ -6528,6 +6541,7 @@ handle_packet_upcall(struct 
>>>> dp_netdev_pmd_thread *pmd,
>>>>                               put_actions);
>>>>      if (OVS_UNLIKELY(error && error != ENOSPC)) {
>>>>          dp_packet_delete(packet);
>>>> +        COVERAGE_INC(datapath_drop_upcall_error);
>>>>          return error;
>>>>      }
>>>>
>>>> @@ -6659,6 +6673,7 @@ fast_path_processing(struct 
>>>> dp_netdev_pmd_thread *pmd,
>>>>          DP_PACKET_BATCH_FOR_EACH (i, packet, packets_) {
>>>>              if (OVS_UNLIKELY(!rules[i])) {
>>>>                  dp_packet_delete(packet);
>>>> +                COVERAGE_INC(datapath_drop_lock_error);
>>>>                  upcall_fail_cnt++;
>>>>              }
>>>>          }
>>>> @@ -6928,6 +6943,7 @@ dp_execute_userspace_action(struct
>>>> dp_netdev_pmd_thread *pmd,
>>>>                                    actions->data, actions->size);
>>>>      } else if (should_steal) {
>>>>          dp_packet_delete(packet);
>>>> +        COVERAGE_INC(datapath_drop_userspace_action_error);
>>>>      }
>>>>  }
>>>>
>>>> @@ -6942,6 +6958,7 @@ dp_execute_cb(void *aux_, struct 
>>>> dp_packet_batch *packets_,
>>>>      struct dp_netdev *dp = pmd->dp;
>>>>      int type = nl_attr_type(a);
>>>>      struct tx_port *p;
>>>> +    uint32_t packet_count, packet_dropped;
>>>>
>>>>      switch ((enum ovs_action_attr)type) {
>>>>      case OVS_ACTION_ATTR_OUTPUT:
>>>> @@ -6983,6 +7000,9 @@ dp_execute_cb(void *aux_, struct 
>>>> dp_packet_batch *packets_,
>>>>                  dp_packet_batch_add(&p->output_pkts, packet);
>>>>              }
>>>>              return;
>>>> +        } else {
>>>> +            COVERAGE_ADD(datapath_drop_invalid_port,
>>>> +                            dp_packet_batch_size(packets_));
>>>>          }
>>>>          break;
>>>>
>>>> @@ -6992,10 +7012,16 @@ dp_execute_cb(void *aux_, struct 
>>>> dp_packet_batch *packets_,
>>>>               * the ownership of these packets. Thus, we can avoid 
>>>> performing
>>>>               * the action, because the caller will not use the 
>>>> result anyway.
>>>>               * Just break to free the batch. */
>>>> +            COVERAGE_ADD(datapath_drop_tunnel_push_error,
>>>> +                            dp_packet_batch_size(packets_));
>>>>              break;
>>>>          }
>>>>          dp_packet_batch_apply_cutlen(packets_);
>>>> -        push_tnl_action(pmd, a, packets_);
>>>> +        packet_count = dp_packet_batch_size(packets_);
>>>> +        if (push_tnl_action(pmd, a, packets_)) {
>>>> +            COVERAGE_ADD(datapath_drop_tunnel_push_error,
>>>> +                            packet_count);
>>>> +        }
>>>>          return;
>>>>
>>>>      case OVS_ACTION_ATTR_TUNNEL_POP:
>>>> @@ -7015,7 +7041,13 @@ dp_execute_cb(void *aux_, struct 
>>>> dp_packet_batch *packets_,
>>>>
>>>>                  dp_packet_batch_apply_cutlen(packets_);
>>>>
>>>> +                packet_count = packets_->count;
>>>>                  netdev_pop_header(p->port->netdev, packets_);
>>>> +                packet_dropped = packet_count - packets_->count;
>>>> +                if (packet_dropped) {
>>>> +                    COVERAGE_ADD(datapath_drop_tunnel_pop_error,
>>>> +                                     packet_dropped);
>>>> +                }
>>>>                  if (dp_packet_batch_is_empty(packets_)) {
>>>>                      return;
>>>>                  }
>>>> @@ -7030,6 +7062,11 @@ dp_execute_cb(void *aux_, struct 
>>>> dp_packet_batch *packets_,
>>>>                  (*depth)--;
>>>>                  return;
>>>>              }
>>>> +            COVERAGE_ADD(datapath_drop_invalid_tnl_port,
>>>> +                            dp_packet_batch_size(packets_));
>>>> +        } else {
>>>> +            COVERAGE_ADD(datapath_drop_recirc_error,
>>>> +                            dp_packet_batch_size(packets_));
>>>>          }
>>>>          break;
>>>>
>>>> @@ -7074,6 +7111,8 @@ dp_execute_cb(void *aux_, struct 
>>>> dp_packet_batch *packets_,
>>>>
>>>>              return;
>>>>          }
>>>> +        COVERAGE_ADD(datapath_drop_lock_error,
>>>> +                        dp_packet_batch_size(packets_));
>>>>          break;
>>>>
>>>>      case OVS_ACTION_ATTR_RECIRC:
>>>> @@ -7097,6 +7136,8 @@ dp_execute_cb(void *aux_, struct 
>>>> dp_packet_batch *packets_,
>>>>              return;
>>>>          }
>>>>
>>>> +        COVERAGE_ADD(datapath_drop_recirc_error,
>>>> +                        dp_packet_batch_size(packets_));
>>>>          VLOG_WARN("Packet dropped. Max recirculation depth 
>>>> exceeded.");
>>>>          break;
>>>>
>>>> @@ -7249,6 +7290,7 @@ dp_execute_cb(void *aux_, struct 
>>>> dp_packet_batch *packets_,
>>>>      case OVS_ACTION_ATTR_PUSH_NSH:
>>>>      case OVS_ACTION_ATTR_POP_NSH:
>>>>      case OVS_ACTION_ATTR_CT_CLEAR:
>>>> +    case OVS_ACTION_ATTR_DROP:
>>>>      case __OVS_ACTION_ATTR_MAX:
>>>>          OVS_NOT_REACHED();
>>>>      }
>>>> diff --git a/lib/dpif.c b/lib/dpif.c index 457c9bf..d75a012 100644
>>>> --- a/lib/dpif.c
>>>> +++ b/lib/dpif.c
>>>> @@ -1269,6 +1269,7 @@ dpif_execute_helper_cb(void *aux_, struct 
>>>> dp_packet_batch *packets_,
>>>>      case OVS_ACTION_ATTR_POP_NSH:
>>>>      case OVS_ACTION_ATTR_CT_CLEAR:
>>>>      case OVS_ACTION_ATTR_UNSPEC:
>>>> +    case OVS_ACTION_ATTR_DROP:
>>>>      case __OVS_ACTION_ATTR_MAX:
>>>>          OVS_NOT_REACHED();
>>>>      }
>>>> @@ -1874,6 +1875,12 @@ dpif_supports_tnl_push_pop(const struct dpif
>>>> *dpif)
>>>>      return dpif_is_netdev(dpif);
>>>>  }
>>>>
>>>> +bool
>>>> +dpif_supports_explicit_drop_action(const struct dpif *dpif) {
>>>> +    return dpif_is_netdev(dpif);
>>>> +}
>>>> +
>>>>  /* Meters */
>>>>  void
>>>>  dpif_meter_get_features(const struct dpif *dpif, diff --git 
>>>> a/lib/dpif.h b/lib/dpif.h index 475d5a6..e799da8 100644
>>>> --- a/lib/dpif.h
>>>> +++ b/lib/dpif.h
>>>> @@ -888,6 +888,9 @@ int dpif_get_pmds_for_port(const struct dpif * 
>>>> dpif, odp_port_t port_no,
>>>>
>>>>  char *dpif_get_dp_version(const struct dpif *);  bool 
>>>> dpif_supports_tnl_push_pop(const struct dpif *);
>>>> +bool dpif_supports_explicit_drop_action(const struct dpif *); int 
>>>> +dpif_show_drop_stats_support(struct dpif *dpif, bool detail,
>>>> +                                 struct ds *reply);
>>>>
>>>>  /* Log functions. */
>>>>  struct vlog_module;
>>>> diff --git a/lib/odp-execute.c b/lib/odp-execute.c index 
>>>> 5d07133..c8ff16b 100644
>>>> --- a/lib/odp-execute.c
>>>> +++ b/lib/odp-execute.c
>>>> @@ -25,6 +25,7 @@
>>>>  #include <stdlib.h>
>>>>  #include <string.h>
>>>>
>>>> +#include "coverage.h"
>>>>  #include "dp-packet.h"
>>>>  #include "dpif.h"
>>>>  #include "netlink.h"
>>>> @@ -36,6 +37,74 @@
>>>>  #include "util.h"
>>>>  #include "csum.h"
>>>>  #include "conntrack.h"
>>>> +#include "ofproto/ofproto-dpif-xlate.h"
>>>> +#include "openvswitch/vlog.h"
>>>> +
>>>> +VLOG_DEFINE_THIS_MODULE(odp_execute)
>>>> +COVERAGE_DEFINE(dp_sample_error_drop);
>>>> +COVERAGE_DEFINE(dp_nsh_decap_error_drop);
>>>> +COVERAGE_DEFINE(drop_action_of_pipeline);
>>>> +COVERAGE_DEFINE(drop_action_bridge_not_found);
>>>> +COVERAGE_DEFINE(drop_action_recursion_too_deep);
>>>> +COVERAGE_DEFINE(drop_action_too_many_resubmit);
>>>> +COVERAGE_DEFINE(drop_action_stack_too_deep);
>>>> +COVERAGE_DEFINE(drop_action_no_recirculation_context);
>>>> +COVERAGE_DEFINE(drop_action_recirculation_conflict);
>>>> +COVERAGE_DEFINE(drop_action_too_many_mpls_labels);
>>>> +COVERAGE_DEFINE(drop_action_invalid_tunnel_metadata);
>>>> +COVERAGE_DEFINE(drop_action_unsupported_packet_type);
>>>> +COVERAGE_DEFINE(drop_action_congestion);
>>>> +COVERAGE_DEFINE(drop_action_forwarding_disabled);
>>>> +
>>>> +static void
>>>> +dp_update_drop_action_counter(enum xlate_error drop_reason,
>>>> +                                 int delta) {
>>>> +   static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
>>>> +
>>>> +   switch (drop_reason) {
>>>> +   case XLATE_OK:
>>>> +        COVERAGE_ADD(drop_action_of_pipeline, delta);
>>>> +        break;
>>>> +   case XLATE_BRIDGE_NOT_FOUND:
>>>> +        COVERAGE_ADD(drop_action_bridge_not_found, delta);
>>>> +        break;
>>>> +   case XLATE_RECURSION_TOO_DEEP:
>>>> +        COVERAGE_ADD(drop_action_recursion_too_deep, delta);
>>>> +        break;
>>>> +   case XLATE_TOO_MANY_RESUBMITS:
>>>> +        COVERAGE_ADD(drop_action_too_many_resubmit, delta);
>>>> +        break;
>>>> +   case XLATE_STACK_TOO_DEEP:
>>>> +        COVERAGE_ADD(drop_action_stack_too_deep, delta);
>>>> +        break;
>>>> +   case XLATE_NO_RECIRCULATION_CONTEXT:
>>>> +        COVERAGE_ADD(drop_action_no_recirculation_context, delta);
>>>> +        break;
>>>> +   case XLATE_RECIRCULATION_CONFLICT:
>>>> +        COVERAGE_ADD(drop_action_recirculation_conflict, delta);
>>>> +        break;
>>>> +   case XLATE_TOO_MANY_MPLS_LABELS:
>>>> +        COVERAGE_ADD(drop_action_too_many_mpls_labels, delta);
>>>> +        break;
>>>> +   case XLATE_INVALID_TUNNEL_METADATA:
>>>> +        COVERAGE_ADD(drop_action_invalid_tunnel_metadata, delta);
>>>> +        break;
>>>> +   case XLATE_UNSUPPORTED_PACKET_TYPE:
>>>> +        COVERAGE_ADD(drop_action_unsupported_packet_type, delta);
>>>> +        break;
>>>> +   case XLATE_CONGESTION_DROP:
>>>> +        COVERAGE_ADD(drop_action_congestion, delta);
>>>> +        break;
>>>> +   case XLATE_FORWARDING_DISABLED:
>>>> +        COVERAGE_ADD(drop_action_forwarding_disabled, delta);
>>>> +        break;
>>>> +   case XLATE_MAX:
>>>> +   default:
>>>> +        VLOG_ERR_RL(&rl, "Invalid Drop reason type:%d",
>>>> drop_reason);
>>>> +   }
>>>> +}
>>>> +
>>>>
>>>>  /* Masked copy of an ethernet address. 'src' is already properly 
>>>> masked. */  static void @@ -621,6 +690,7 @@ odp_execute_sample(void 
>>>> *dp, struct dp_packet *packet, bool steal,
>>>>          case OVS_SAMPLE_ATTR_PROBABILITY:
>>>>              if (random_uint32() >= nl_attr_get_u32(a)) {
>>>>                  if (steal) {
>>>> +                    COVERAGE_ADD(dp_sample_error_drop, 1);
>>>>                      dp_packet_delete(packet);
>>>>                  }
>>>>                  return;
>>>> @@ -705,6 +775,7 @@ requires_datapath_assistance(const struct 
>>>> nlattr
>>>> *a)
>>>>      case OVS_ACTION_ATTR_PUSH_NSH:
>>>>      case OVS_ACTION_ATTR_POP_NSH:
>>>>      case OVS_ACTION_ATTR_CT_CLEAR:
>>>> +    case OVS_ACTION_ATTR_DROP:
>>>>          return false;
>>>>
>>>>      case OVS_ACTION_ATTR_UNSPEC:
>>>> @@ -921,6 +992,7 @@ odp_execute_actions(void *dp, struct 
>>>> dp_packet_batch *batch, bool steal,
>>>>                  if (pop_nsh(packet)) {
>>>>                      dp_packet_batch_refill(batch, packet, i);
>>>>                  } else {
>>>> +                    COVERAGE_INC(dp_nsh_decap_error_drop);
>>>>                      dp_packet_delete(packet);
>>>>                  }
>>>>              }
>>>> @@ -931,7 +1003,14 @@ odp_execute_actions(void *dp, struct 
>>>> dp_packet_batch *batch, bool steal,
>>>>                  conntrack_clear(packet);
>>>>              }
>>>>              break;
>>>> -
>>>> +        case OVS_ACTION_ATTR_DROP: {
>>>> +            const enum xlate_error *drop_reason = nl_attr_get(a);
>>>> +            if (*drop_reason < XLATE_MAX) {
>>>> +                 dp_update_drop_action_counter(*drop_reason,
>>>> batch->count);
>>>> +            }
>>>> +            dp_packet_delete_batch(batch, steal);
>>>> +            return;
>>>> +        }
>>>>          case OVS_ACTION_ATTR_OUTPUT:
>>>>          case OVS_ACTION_ATTR_TUNNEL_PUSH:
>>>>          case OVS_ACTION_ATTR_TUNNEL_POP:
>>>> diff --git a/lib/odp-util.c b/lib/odp-util.c index e893f46..9c3acc1
>>>> 100644
>>>> --- a/lib/odp-util.c
>>>> +++ b/lib/odp-util.c
>>>> @@ -43,6 +43,7 @@
>>>>  #include "uuid.h"
>>>>  #include "openvswitch/vlog.h"
>>>>  #include "openvswitch/match.h"
>>>> +#include "ofproto/ofproto-dpif-xlate.h"
>>>>
>>>>  VLOG_DEFINE_THIS_MODULE(odp_util);
>>>>
>>>> @@ -131,6 +132,7 @@ odp_action_len(uint16_t type)
>>>>      case OVS_ACTION_ATTR_CLONE: return ATTR_LEN_VARIABLE;
>>>>      case OVS_ACTION_ATTR_PUSH_NSH: return ATTR_LEN_VARIABLE;
>>>>      case OVS_ACTION_ATTR_POP_NSH: return 0;
>>>> +    case OVS_ACTION_ATTR_DROP: return sizeof(enum xlate_error);
>>>>
>>>>      case OVS_ACTION_ATTR_UNSPEC:
>>>>      case __OVS_ACTION_ATTR_MAX:
>>>> @@ -1182,6 +1184,9 @@ format_odp_action(struct ds *ds, const struct 
>>>> nlattr *a,
>>>>      case OVS_ACTION_ATTR_POP_NSH:
>>>>          ds_put_cstr(ds, "pop_nsh()");
>>>>          break;
>>>> +    case OVS_ACTION_ATTR_DROP:
>>>> +        ds_put_cstr(ds, "drop");
>>>> +        break;
>>>>      case OVS_ACTION_ATTR_UNSPEC:
>>>>      case __OVS_ACTION_ATTR_MAX:
>>>>      default:
>>>> @@ -2428,8 +2433,12 @@ odp_actions_from_string(const char *s, const 
>>>> struct simap *port_names,
>>>>                          struct ofpbuf *actions)  {
>>>>      size_t old_size;
>>>> +    enum xlate_error drop_action;
>>>>
>>>>      if (!strcasecmp(s, "drop")) {
>>>> +        drop_action = XLATE_OK;
>>>> +        nl_msg_put_unspec(actions, OVS_ACTION_ATTR_DROP,
>>>> +                          &drop_action, sizeof drop_action);
>>>>          return 0;
>>>>      }
>>>>
>>>> diff --git a/ofproto/ofproto-dpif-ipfix.c 
>>>> b/ofproto/ofproto-dpif-ipfix.c index 5ea1097..52b328d 100644
>>>> --- a/ofproto/ofproto-dpif-ipfix.c
>>>> +++ b/ofproto/ofproto-dpif-ipfix.c
>>>> @@ -3015,6 +3015,7 @@ dpif_ipfix_read_actions(const struct flow 
>>>> *flow,
>>>>          case OVS_ACTION_ATTR_PUSH_NSH:
>>>>          case OVS_ACTION_ATTR_POP_NSH:
>>>>          case OVS_ACTION_ATTR_UNSPEC:
>>>> +        case OVS_ACTION_ATTR_DROP:
>>>>          case __OVS_ACTION_ATTR_MAX:
>>>>          default:
>>>>              break;
>>>> diff --git a/ofproto/ofproto-dpif-sflow.c 
>>>> b/ofproto/ofproto-dpif-sflow.c index bc4ffee..0d0a27d 100644
>>>> --- a/ofproto/ofproto-dpif-sflow.c
>>>> +++ b/ofproto/ofproto-dpif-sflow.c
>>>> @@ -1223,6 +1223,7 @@ dpif_sflow_read_actions(const struct flow 
>>>> *flow,
>>>>          case OVS_ACTION_ATTR_PUSH_NSH:
>>>>          case OVS_ACTION_ATTR_POP_NSH:
>>>>          case OVS_ACTION_ATTR_UNSPEC:
>>>> +        case OVS_ACTION_ATTR_DROP:
>>>>          case __OVS_ACTION_ATTR_MAX:
>>>>          default:
>>>>              break;
>>>> diff --git a/ofproto/ofproto-dpif-xlate.c 
>>>> b/ofproto/ofproto-dpif-xlate.c index acd4817..95e2f25 100644
>>>> --- a/ofproto/ofproto-dpif-xlate.c
>>>> +++ b/ofproto/ofproto-dpif-xlate.c
>>>> @@ -444,6 +444,12 @@ const char *xlate_strerror(enum xlate_error
>>>> error)
>>>>          return "Invalid tunnel metadata";
>>>>      case XLATE_UNSUPPORTED_PACKET_TYPE:
>>>>          return "Unsupported packet type";
>>>> +    case XLATE_CONGESTION_DROP:
>>>> +        return "Congestion Drop";
>>>> +    case XLATE_FORWARDING_DISABLED:
>>>> +        return "Forwarding is disabled";
>>>> +    case XLATE_MAX:
>>>> +        break;
>>>>      }
>>>>      return "Unknown error";
>>>>  }
>>>> @@ -5921,6 +5927,14 @@ put_ct_label(const struct flow *flow, struct 
>>>> ofpbuf *odp_actions,  }
>>>>
>>>>  static void
>>>> +put_drop_action(struct ofpbuf *odp_actions, enum xlate_error 
>>>> +error) {
>>>> +    nl_msg_put_unspec(odp_actions, OVS_ACTION_ATTR_DROP,
>>>> +                      &error, sizeof error);
>>>> +
>>>> +}
>>>> +
>>>> +static void
>>>>  put_ct_helper(struct xlate_ctx *ctx,
>>>>                struct ofpbuf *odp_actions, struct ofpact_conntrack
>>>> *ofc)
>>>>  {
>>>> @@ -7383,48 +7397,51 @@ xlate_actions(struct xlate_in *xin, struct 
>>>> xlate_out *xout)
>>>>          }
>>>>          size_t sample_actions_len = ctx.odp_actions->size;
>>>>
>>>> -        if (tnl_process_ecn(flow)
>>>> -            && (!in_port || may_receive(in_port, &ctx))) {
>>>> -            const struct ofpact *ofpacts;
>>>> -            size_t ofpacts_len;
>>>> -
>>>> -            if (xin->ofpacts) {
>>>> -                ofpacts = xin->ofpacts;
>>>> -                ofpacts_len = xin->ofpacts_len;
>>>> -            } else if (ctx.rule) {
>>>> -                const struct rule_actions *actions
>>>> -                    = rule_get_actions(&ctx.rule->up);
>>>> -                ofpacts = actions->ofpacts;
>>>> -                ofpacts_len = actions->ofpacts_len;
>>>> -                ctx.rule_cookie = ctx.rule->up.flow_cookie;
>>>> -            } else {
>>>> -                OVS_NOT_REACHED();
>>>> -            }
>>>> +        if (!tnl_process_ecn(flow)) {
>>>> +            ctx.error = XLATE_CONGESTION_DROP;
>>>> +        } else {
>>>> +            if (!in_port || may_receive(in_port, &ctx)) {
>>>> +                const struct ofpact *ofpacts;
>>>> +                size_t ofpacts_len;
>>>> +
>>>> +                if (xin->ofpacts) {
>>>> +                    ofpacts = xin->ofpacts;
>>>> +                    ofpacts_len = xin->ofpacts_len;
>>>> +                } else if (ctx.rule) {
>>>> +                    const struct rule_actions *actions
>>>> +                         = rule_get_actions(&ctx.rule->up);
>>>> +                    ofpacts = actions->ofpacts;
>>>> +                    ofpacts_len = actions->ofpacts_len;
>>>> +                    ctx.rule_cookie = ctx.rule->up.flow_cookie;
>>>> +                } else {
>>>> +                    OVS_NOT_REACHED();
>>>> +                }
>>>>
>>>> -            mirror_ingress_packet(&ctx);
>>>> -            do_xlate_actions(ofpacts, ofpacts_len, &ctx, true, 
>>>> false);
>>>> -            if (ctx.error) {
>>>> -                goto exit;
>>>> -            }
>>>> +                mirror_ingress_packet(&ctx);
>>>> +                do_xlate_actions(ofpacts, ofpacts_len, &ctx, true,
>>>> false);
>>>> +                if (ctx.error) {
>>>> +                    goto exit;
>>>> +                }
>>>>
>>>> -            /* We've let OFPP_NORMAL and the learning action look at 
>>>> the
>>>> -             * packet, so cancel all actions and freezing if 
>>>> forwarding is
>>>> -             * disabled. */
>>>> -            if (in_port && (!xport_stp_forward_state(in_port) ||
>>>> -                            !xport_rstp_forward_state(in_port))) {
>>>> -                ctx.odp_actions->size = sample_actions_len;
>>>> -                ctx_cancel_freeze(&ctx);
>>>> -                ofpbuf_clear(&ctx.action_set);
>>>> -            }
>>>> +                /* We've let OFPP_NORMAL and the learning action
>>>> look at the
>>>> +                * packet, so cancel all actions and freezing if
>>>> forwarding is
>>>> +                * disabled. */
>>>> +                if (in_port && (!xport_stp_forward_state(in_port) 
>>>> + ||
>>>> +                                
>>>> + !xport_rstp_forward_state(in_port)))
>>>> {
>>>> +                    ctx.odp_actions->size = sample_actions_len;
>>>> +                    ctx_cancel_freeze(&ctx);
>>>> +                    ofpbuf_clear(&ctx.action_set);
>>>> +                    ctx.error = XLATE_FORWARDING_DISABLED;
>>>> +                }
>>>>
>>>> -            if (!ctx.freezing) {
>>>> -                xlate_action_set(&ctx);
>>>> -            }
>>>> -            if (ctx.freezing) {
>>>> -                finish_freezing(&ctx);
>>>> +                if (!ctx.freezing) {
>>>> +                    xlate_action_set(&ctx);
>>>> +                }
>>>> +                if (ctx.freezing) {
>>>> +                    finish_freezing(&ctx);
>>>> +                }
>>>>              }
>>>>          }
>>>> -
>>>>          /* Output only fully processed packets. */
>>>>          if (!ctx.freezing
>>>>              && xbridge->has_in_band @@ -7522,6 +7539,18 @@ exit:
>>>>              ofpbuf_clear(xin->odp_actions);
>>>>          }
>>>>      }
>>>> +
>>>> +    /*
>>>> +     * If we are going to install "drop" action, check whether
>>>> +     * datapath supports explicit "drop"action. If datapath
>>>> +     * supports explicit "drop"action then install the "drop"
>>>> +     * action containing the drop reason.
>>>> +     */
>>>> +    if (xin->odp_actions && !xin->odp_actions->size &&
>>>> +         ovs_explicit_drop_action_supported(ctx.xbridge->ofproto)) {
>>>> +        put_drop_action(xin->odp_actions, ctx.error);
>>>> +    }
>>>> +
>>>>      return ctx.error;
>>>>  }
>>>>
>>>> diff --git a/ofproto/ofproto-dpif-xlate.h 
>>>> b/ofproto/ofproto-dpif-xlate.h index 0a5a528..496bdbf 100644
>>>> --- a/ofproto/ofproto-dpif-xlate.h
>>>> +++ b/ofproto/ofproto-dpif-xlate.h
>>>> @@ -216,6 +216,9 @@ enum xlate_error {
>>>>      XLATE_TOO_MANY_MPLS_LABELS,
>>>>      XLATE_INVALID_TUNNEL_METADATA,
>>>>      XLATE_UNSUPPORTED_PACKET_TYPE,
>>>> +    XLATE_CONGESTION_DROP,
>>>> +    XLATE_FORWARDING_DISABLED,
>>>> +    XLATE_MAX,
>>>>  };
>>>>
>>>>  const char *xlate_strerror(enum xlate_error error); diff --git 
>>>> a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index
>>>> 50c959b..91df1b3 100644
>>>> --- a/ofproto/ofproto-dpif.c
>>>> +++ b/ofproto/ofproto-dpif.c
>>>> @@ -827,6 +827,12 @@ ovs_native_tunneling_is_on(struct ofproto_dpif
>>>> *ofproto)
>>>>          && atomic_count_get(&ofproto->backer->tnl_count);
>>>>  }
>>>>
>>>> +bool
>>>> +ovs_explicit_drop_action_supported(struct ofproto_dpif *ofproto) {
>>>> +    return ofproto->backer->rt_support.explicit_drop_action;
>>>> +}
>>>> +
>>>>  /* Tests whether 'backer''s datapath supports recirculation.  Only 
>>>> newer
>>>>   * datapaths support OVS_KEY_ATTR_RECIRC_ID in keys.  We need to 
>>>> disable some
>>>>   * features on older datapaths that don't support this feature.
>>>> @@ -1397,6 +1403,8 @@ check_support(struct dpif_backer *backer)
>>>>      backer->rt_support.ct_eventmask = check_ct_eventmask(backer);
>>>>      backer->rt_support.ct_clear = check_ct_clear(backer);
>>>>      backer->rt_support.max_hash_alg = 
>>>> check_max_dp_hash_alg(backer);
>>>> +    backer->rt_support.explicit_drop_action =
>>>> +        dpif_supports_explicit_drop_action(backer->dpif);
>>>>
>>>>      /* Flow fields. */
>>>>      backer->rt_support.odp.ct_state = check_ct_state(backer); diff 
>>>> --git a/ofproto/ofproto-dpif.h b/ofproto/ofproto-dpif.h index 
>>>> 1a404c8..8d8edca 100644
>>>> --- a/ofproto/ofproto-dpif.h
>>>> +++ b/ofproto/ofproto-dpif.h
>>>> @@ -192,7 +192,10 @@ struct group_dpif *group_dpif_lookup(struct 
>>>> ofproto_dpif *,
>>>>      DPIF_SUPPORT_FIELD(bool, ct_clear, "Conntrack clear")            
>>>>        \
>>>>                                                                            
>>>>   \
>>>>      /* Highest supported dp_hash algorithm. */                       
>>>>        \
>>>> -    DPIF_SUPPORT_FIELD(size_t, max_hash_alg, "Max dp_hash 
>>>> algorithm")
>>>> +    DPIF_SUPPORT_FIELD(size_t, max_hash_alg, "Max dp_hash
>>>> algorithm")       \
>>>> +                                                                     
>>>>        \
>>>> +    /* True if the datapath supports explicit drop action. */        
>>>>        \
>>>> +    DPIF_SUPPORT_FIELD(bool, explicit_drop_action, "Explicit Drop
>>>> action")
>>>>
>>>>  /* Stores the various features which the corresponding backer 
>>>> supports. */  struct dpif_backer_support { @@ -361,4 +364,6 @@ int 
>>>> ofproto_dpif_delete_internal_flow(struct
>>>> ofproto_dpif *, struct match *,
>>>>
>>>>  bool ovs_native_tunneling_is_on(struct ofproto_dpif *);
>>>>
>>>> +bool ovs_explicit_drop_action_supported(struct ofproto_dpif *);
>>>> +
>>>>  #endif /* ofproto-dpif.h */
>>>> diff --git a/tests/automake.mk b/tests/automake.mk index 
>>>> 92d56b2..a4da75e 100644
>>>> --- a/tests/automake.mk
>>>> +++ b/tests/automake.mk
>>>> @@ -108,7 +108,8 @@ TESTSUITE_AT = \
>>>>    tests/ovn-controller-vtep.at \
>>>>    tests/mcast-snooping.at \
>>>>    tests/packet-type-aware.at \
>>>> -  tests/nsh.at
>>>> +  tests/nsh.at \
>>>> +  tests/drop-stats.at
>>>>
>>>>  EXTRA_DIST += $(FUZZ_REGRESSION_TESTS)  FUZZ_REGRESSION_TESTS = \ 
>>>> diff --git a/tests/dpif-netdev.at b/tests/dpif-netdev.at index
>>>> 6915d43..5221c10 100644
>>>> --- a/tests/dpif-netdev.at
>>>> +++ b/tests/dpif-netdev.at
>>>> @@ -337,6 +337,14 @@ meter:2 flow_count:1 packet_in_count:10
>>>> byte_in_count:600 duration:0.0s bands:
>>>>  0: packet_count:5 byte_count:300
>>>>  ])
>>>>
>>>> +ovs-appctl time/warp 5000
>>>> +
>>>> +AT_CHECK([
>>>> +ovs-appctl coverage/show | grep "datapath_drop_meter" | cut -d':' 
>>>> -f2|sed 's/ //'
>>>> +], [0], [dnl
>>>> +14
>>>> +])
>>>> +
>>>>  AT_CHECK([cat ovs-vswitchd.log | filter_flow_install | 
>>>> strip_xout_keep_actions], [0], [dnl
>>>> recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv
>>>> 4
>>>> (frag=no),
>>>> actions:meter(0),7
>>>>  
>>>> recirc_id(0),in_port(2),packet_type(ns=0,id=0),eth_type(0x0800),ipv
>>>> 4
>>>> (frag=no),
>>>> actions:8
>>>> diff --git a/tests/drop-stats.at b/tests/drop-stats.at new file 
>>>> mode
>>>> 100644 index 0000000..318bc02
>>>> --- /dev/null
>>>> +++ b/tests/drop-stats.at
>>>> @@ -0,0 +1,197 @@
>>>> +AT_BANNER([drop-stats])
>>>> +
>>>> +AT_SETUP([drop-stats - cli tests])
>>>> +
>>>> +OVS_VSWITCHD_START([dnl
>>>> +    set bridge br0 datapath_type=dummy \
>>>> +        protocols=OpenFlow10,OpenFlow13,OpenFlow14,OpenFlow15 -- \
>>>> +    add-port br0 p1 -- set Interface p1 type=dummy
>>>> ofport_request=1])
>>>> +
>>>> +AT_DATA([flows.txt], [dnl
>>>> +table=0,in_port=1,actions=drop
>>>> +])
>>>> +
>>>> +AT_CHECK([
>>>> +    ovs-ofctl del-flows br0
>>>> +    ovs-ofctl -Oopenflow13 add-flows br0 flows.txt
>>>> +    ovs-ofctl -Oopenflow13 dump-flows br0 | ofctl_strip | sort |
>>>> grep actions
>>>> +], [0], [dnl
>>>> + in_port=1 actions=drop
>>>> +])
>>>> +
>>>> +AT_CHECK([
>>>> +    ovs-appctl netdev-dummy/receive p1
>>>> 1e2ce92a669e3a6dd2099cab0800450000548a53400040011addc0a80a0ac0a80a1
>>>> e
>>>> 08006f200a4d0001fc509a580000000027150200000000001011121314151617181
>>>> 9
>>>> 1a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
>>>> +    ovs-appctl netdev-dummy/receive p1
>>>> 1e2ce92a669e3a6dd2099cab0800450000548a53400040011addc0a80a0ac0a80a1
>>>> e
>>>> 08006f200a4d0001fc509a580000000027150200000000001011121314151617181
>>>> 9
>>>> 1a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
>>>> +    ovs-appctl netdev-dummy/receive p1
>>>> 1e2ce92a669e3a6dd2099cab0800450000548a53400040011addc0a80a0ac0a80a1
>>>> e
>>>> 08006f200a4d0001fc509a580000000027150200000000001011121314151617181
>>>> 9
>>>> 1a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
>>>> +], [0], [ignore])
>>>> +
>>>> +AT_CHECK([ovs-appctl dpctl/dump-flows | sed
>>>> 's/used:[[0-9]].[[0-9]]*s/used:0.0/' | sort], [0],
>>>> +[flow-dump from non-dpdk interfaces:
>>>> +recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ip
>>>> +v
>>>> +4(frag=no),
>>>> packets:2, bytes:196, used:0.0, actions:drop
>>>> +])
>>>> +
>>>> +sleep 1
>>>> +
>>>> +
>>>> +AT_CHECK([
>>>> +ovs-appctl coverage/show | grep "drop_action_of_pipeline" | cut
>>>> -d':' -f2|sed 's/ //'
>>>> +], [0], [dnl
>>>> +3
>>>> +])
>>>> +
>>>> +
>>>> +OVS_VSWITCHD_STOP
>>>> +AT_CLEANUP
>>>> +
>>>> +AT_SETUP([drop-stats - pipeline and recurssion drops])
>>>> +
>>>> +OVS_VSWITCHD_START([dnl
>>>> +    set bridge br0 datapath_type=dummy \
>>>> +        protocols=OpenFlow10,OpenFlow13,OpenFlow14,OpenFlow15 -- \
>>>> +    add-port br0 p1 -- set Interface p1 type=dummy 
>>>> +ofport_request=1
>>>> -- \
>>>> +    add-port br0 p2 -- set Interface p2 type=dummy
>>>> ofport_request=2])
>>>> +
>>>> +AT_DATA([flows.txt], [dnl
>>>> +table=0,in_port=1,actions=drop
>>>> +])
>>>> +
>>>> +AT_CHECK([
>>>> +    ovs-ofctl del-flows br0
>>>> +    ovs-ofctl -Oopenflow13 add-flows br0 flows.txt
>>>> +    ovs-ofctl -Oopenflow13 dump-flows br0 | ofctl_strip | sort |
>>>> grep actions
>>>> +], [0], [dnl
>>>> + in_port=1 actions=drop
>>>> +])
>>>> +
>>>> +AT_CHECK([
>>>> +    ovs-appctl netdev-dummy/receive p1
>>>> 1e2ce92a669e3a6dd2099cab0800450000548a53400040011addc0a80a0ac0a80a1
>>>> e
>>>> 08006f200a4d0001fc509a580000000027150200000000001011121314151617181
>>>> 9
>>>> 1a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
>>>> +], [0], [ignore])
>>>> +
>>>> +sleep 1
>>>> +
>>>> +
>>>> +AT_CHECK([
>>>> +ovs-appctl coverage/show | grep "drop_action_of_pipeline" | cut
>>>> -d':' -f2|sed 's/ //'
>>>> +], [0], [dnl
>>>> +1
>>>> +])
>>>> +
>>>> +
>>>> +AT_DATA([flows.txt], [dnl
>>>> +table=0, in_port=1, actions=goto_table:1 table=1, in_port=1,
>>>> +actions=goto_table:2 table=2, in_port=1, actions=resubmit(,1)
>>>> +])
>>>> +
>>>> +AT_CHECK([
>>>> +    ovs-ofctl del-flows br0
>>>> +    ovs-ofctl -Oopenflow13 add-flows br0 flows.txt
>>>> +    ovs-ofctl -Oopenflow13 dump-flows br0 | ofctl_strip | sort |
>>>> grep actions
>>>> +], [0], [ignore])
>>>> +
>>>> +AT_CHECK([
>>>> +    ovs-appctl netdev-dummy/receive p1
>>>> 1e2ce92a669e3a6dd2099cab0800450000548a53400040011addc0a80a0ac0a80a1
>>>> e
>>>> 08006f200a4d0001fc509a580000000027150200000000001011121314151617181
>>>> 9
>>>> 1a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
>>>> +], [0], [ignore])
>>>> +
>>>> +sleep 1
>>>> +
>>>> +AT_CHECK([
>>>> +ovs-appctl coverage/show | grep "drop_action_recursion_too_deep" |
>>>> cut -d':' -f2|sed 's/ //'
>>>> +], [0], [dnl
>>>> +1
>>>> +])
>>>> +
>>>> +
>>>> +OVS_VSWITCHD_STOP(["/|WARN|/d"])
>>>> +AT_CLEANUP
>>>> +
>>>> +AT_SETUP([drop-stats - too many resubmit])
>>>> +
>>>> +OVS_VSWITCHD_START
>>>> +add_of_ports br0 1
>>>> +(for i in `seq 1 64`; do
>>>> +     j=`expr $i + 1`
>>>> +     echo "in_port=$i, actions=resubmit:$j, resubmit:$j, local"
>>>> + done
>>>> + echo "in_port=65, actions=local") > flows.txt
>>>> +
>>>> +AT_CHECK([
>>>> +    ovs-ofctl del-flows br0
>>>> +    ovs-ofctl -Oopenflow13 add-flows br0 flows.txt ], [0],
>>>> +[ignore])
>>>> +
>>>> +ovs-appctl netdev-dummy/receive p1
>>>> 'in_port(1),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x1234)'
>>>> +
>>>> +sleep 1
>>>> +
>>>> +AT_CHECK([
>>>> +ovs-appctl coverage/show | grep "drop_action_too_many_resubmit" |
>>>> cut -d':' -f2|sed 's/ //'
>>>> +], [0], [dnl
>>>> +1
>>>> +])
>>>> +
>>>> +OVS_VSWITCHD_STOP(["/|WARN|/d"])
>>>> +AT_CLEANUP
>>>> +
>>>> +
>>>> +AT_SETUP([drop-stats - stack too deep]) OVS_VSWITCHD_START 
>>>> +add_of_ports br0 1 (for i in `seq 1 12`; do
>>>> +     j=`expr $i + 1`
>>>> +     echo "in_port=$i, actions=resubmit:$j, resubmit:$j, local"
>>>> + done
>>>> + push="push:NXM_NX_REG0[[]]"
>>>> + echo "in_port=13,
>>>> actions=$push,$push,$push,$push,$push,$push,$push,$push") > flows
>>>> + AT_CHECK([ovs-ofctl add-flows br0 flows])
>>>> +
>>>> +ovs-appctl netdev-dummy/receive p1
>>>> 'in_port(1),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x1234)'
>>>> +
>>>> +sleep 1
>>>> +
>>>> +AT_CHECK([
>>>> +ovs-appctl coverage/show | grep "drop_action_stack_too_deep" | cut
>>>> -d':' -f2|sed 's/ //'
>>>> +], [0], [dnl
>>>> +1
>>>> +])
>>>> +
>>>> +
>>>> +OVS_VSWITCHD_STOP(["/resubmits yielded over 64 kB of stack/d"]) 
>>>> +AT_CLEANUP
>>>> +
>>>> +AT_SETUP([drop-stats - too many mpls labels])
>>>> +
>>>> +OVS_VSWITCHD_START([dnl
>>>> +    set bridge br0 datapath_type=dummy \
>>>> +        protocols=OpenFlow10,OpenFlow13,OpenFlow14,OpenFlow15 -- \
>>>> +    add-port br0 p1 -- set Interface p1 type=dummy 
>>>> +ofport_request=1
>>>> -- \
>>>> +    add-port br0 p2 -- set Interface p2 type=dummy
>>>> ofport_request=2])
>>>> +
>>>> +AT_DATA([flows.txt], [dnl
>>>> +table=0, in_port=1, actions=push_mpls:0x8847, resubmit:3 table=0, 
>>>> +in_port=3, actions=push_mpls:0x8847,
>>>> set_field:10->mpls_label, set_field:15->mpls_label,  resubmit:4
>>>> +table=0, in_port=4, actions=push_mpls:0x8847,
>>>> set_field:11->mpls_label, resubmit:5
>>>> +table=0, in_port=5, actions=push_mpls:0x8847,
>>>> set_field:12->mpls_label, resubmit:6
>>>> +table=0, in_port=6, actions=push_mpls:0x8847,
>>>> set_field:13->mpls_label, output:2
>>>> +])
>>>> +
>>>> +AT_CHECK([
>>>> +    ovs-ofctl del-flows br0
>>>> +    ovs-ofctl -Oopenflow13 add-flows br0 flows.txt
>>>> +])
>>>> +
>>>> +AT_CHECK([
>>>> +    ovs-appctl netdev-dummy/receive p1
>>>> 1e2ce92a669e3a6dd2099cab0800450000548a53400040011addc0a80a0ac0a80a1
>>>> e
>>>> 08006f200a4d0001fc509a580000000027150200000000001011121314151617181
>>>> 9
>>>> 1a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
>>>> +], [0], [ignore])
>>>> +
>>>> +sleep 1
>>>> +
>>>> +AT_CHECK([
>>>> +ovs-appctl coverage/show | grep "drop_action_too_many_mpls_labels" 
>>>> +|
>>>> cut -d':' -f2|sed 's/ //'
>>>> +], [0], [dnl
>>>> +1
>>>> +])
>>>> +
>>>> +
>>>> +OVS_VSWITCHD_STOP(["/|WARN|/d"])
>>>> +AT_CLEANUP
>>>> diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at index 
>>>> ded2ef0..2c8cdce 100644
>>>> --- a/tests/ofproto-dpif.at
>>>> +++ b/tests/ofproto-dpif.at
>>>> @@ -9384,7 +9384,7 @@
>>>> recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x8100),vla
>>>> n
>>>> (vid=99,pcp=
>>>>  # are wildcarded.
>>>>  AT_CHECK([grep '\(modify\)\|\(flow_add\)' ovs-vswitchd.log | 
>>>> strip_ufid ], [0], [dnl
>>>>  dpif_netdev|DBG|flow_add: 
>>>> recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x1234),
>>>> actions:100
>>>> -dpif|DBG|dummy at ovs-dummy: put[[modify]]
>>>> skb_priority(0/0),skb_mark(0/0),ct_state(0/0),ct_zone(0/0),ct_mark(
>>>> 0 
>>>> /0),ct_label(0/0),recirc_id(0),dp_hash(0/0),in_port(1),packet_type(
>>>> n
>>>> s=0,id=0),eth(src=50:54:00:00:00:09/00:00:00:00:00:00,dst=50:54:00:
>>>> 0
>>>> 0:00:0a/00:00:00:00:00:00),eth_type(0x1234)
>>>> +dpif|DBG|dummy at ovs-dummy: put[[modify]]
>>>> skb_priority(0/0),skb_mark(0/0),ct_state(0/0),ct_zone(0/0),ct_mark(
>>>> 0 
>>>> /0),ct_label(0/0),recirc_id(0),dp_hash(0/0),in_port(1),packet_type(
>>>> n
>>>> s=0,id=0),eth(src=50:54:00:00:00:09/00:00:00:00:00:00,dst=50:54:00:
>>>> 0 0:00:0a/00:00:00:00:00:00),eth_type(0x1234),
>>>> actions:drop
>>>>  dpif|DBG|dummy at ovs-dummy: put[[modify]]
>>>> skb_priority(0/0),skb_mark(0/0),ct_state(0/0),ct_zone(0/0),ct_mark(
>>>> 0 
>>>> /0),ct_label(0/0),recirc_id(0),dp_hash(0/0),in_port(1),packet_type(
>>>> n
>>>> s=0,id=0),eth(src=50:54:00:00:00:09/00:00:00:00:00:00,dst=50:54:00:
>>>> 0 0:00:0a/00:00:00:00:00:00),eth_type(0x1234),
>>>> actions:100
>>>>  dpif_netdev|DBG|flow_add: 
>>>> recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x8100),vla
>>>> n (vid=99,pcp=7/0x0),encap(eth_type(0x1234)),
>>>> actions:drop
>>>>  ])
>>>> diff --git a/tests/testsuite.at b/tests/testsuite.at index
>>>> b840dbf..922ba48 100644
>>>> --- a/tests/testsuite.at
>>>> +++ b/tests/testsuite.at
>>>> @@ -82,3 +82,4 @@ m4_include([tests/ovn-controller-vtep.at])
>>>>  m4_include([tests/mcast-snooping.at])
>>>>  m4_include([tests/packet-type-aware.at])
>>>>  m4_include([tests/nsh.at])
>>>> +m4_include([tests/drop-stats.at])
>>>> diff --git a/tests/tunnel-push-pop.at b/tests/tunnel-push-pop.at 
>>>> index f717243..045b1a7 100644
>>>> --- a/tests/tunnel-push-pop.at
>>>> +++ b/tests/tunnel-push-pop.at
>>>> @@ -447,6 +447,27 @@ AT_CHECK([ovs-ofctl dump-ports int-br | grep 
>>>> 'port  7'], [0], [dnl
>>>>    port  7: rx pkts=3, bytes=252, drop=?, errs=?, frame=?, over=?, 
>>>> crc=?
>>>>  ])
>>>>
>>>> +AT_CHECK([ovs-appctl netdev-dummy/receive p0
>>>> 'aa55aa550000001b213cab6408004500007079464000402fba600101025c010102
>>>> 5
>>>> 820000800000001c845000054ba200000400184861e0000011e00000200004227e7
>>>> 5
>>>> 400030af3195500000000f265010000000000101112131415161718191a1b1c1d1e
>>>> 1
>>>> f202122232425262728292a2b2c2d2e2f3031323334353637'])
>>>> +
>>>> +ovs-appctl time/warp 5000
>>>> +
>>>> +AT_CHECK([
>>>> +ovs-appctl coverage/show | grep "datapath_drop_tunnel_pop_error" |
>>>> cut -d':' -f2|sed 's/ //'
>>>> +], [0], [dnl
>>>> +1
>>>> +])
>>>> +
>>>> +sleep 1
>>>> +AT_CHECK([ovs-appctl netdev-dummy/receive p0
>>>> 'aa55aa550000001b213cab6408004503007079464000402fba600101025c010102
>>>> 5
>>>> 820000800000001c845000054ba200000400184861e0000011e00000200004227e7
>>>> 5
>>>> 400030af3195500000000f265010000000000101112131415161718191a1b1c1d1e
>>>> 1
>>>> f202122232425262728292a2b2c2d2e2f3031323334353637'])
>>>> +
>>>> +ovs-appctl time/warp 5000
>>>> +
>>>> +AT_CHECK([
>>>> +ovs-appctl coverage/show | grep "drop_action_congestion" | cut -d':' 
>>>> -f2|sed 's/ //'
>>>> +], [0], [dnl
>>>> +1
>>>> +])
>>>> +
>>>>  dnl Check GREL3 only accepts non-fragmented packets?
>>>>  AT_CHECK([ovs-appctl netdev-dummy/receive p0
>>>> 'aa55aa550000001b213cab6408004500007e79464000402fba550101025c010102
>>>> 5
>>>> 820000800000001c8fe71d883724fbeb6f4e1494a080045000054ba200000400184
>>>> 8
>>>> 61e0000011e00000200004227e75400030af3195500000000f26501000000000010
>>>> 1
>>>> 112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132
>>>> 3
>>>> 334353637'])
>>>>
>>>> @@ -455,7 +476,7 @@ ovs-appctl time/warp 1000
>>>>
>>>>  AT_CHECK([ovs-ofctl dump-ports int-br | grep 'port  [[37]]' | 
>>>> sort], [0], [dnl
>>>>    port  3: rx pkts=3, bytes=294, drop=?, errs=?, frame=?, over=?, 
>>>> crc=?
>>>> -  port  7: rx pkts=4, bytes=350, drop=?, errs=?, frame=?, over=?, 
>>>> crc=?
>>>> +  port  7: rx pkts=5, bytes=434, drop=?, errs=?, frame=?, over=?,
>>>> crc=?
>>>>  ])
>>>>
>>>>  dnl Check decapsulation of Geneve packet with options @@ -478,7
>>>> +499,7 @@ AT_CHECK([ovs-ofctl dump-ports int-br | grep 'port  5'],
>>>> [0], [dnl
>>>>    port  5: rx pkts=1, bytes=98, drop=?, errs=?, frame=?, over=?, 
>>>> crc=?
>>>>  ])
>>>>  AT_CHECK([ovs-appctl dpif/dump-flows int-br | grep 
>>>> 'in_port(6081)'], [0], [dnl 
>>>> -tunnel(tun_id=0x7b,src=1.1.2.92,dst=1.1.2.88,geneve({class=0xffff,
>>>> t 
>>>> ype=0x80,len=4,0xa/0xf}{class=0xffff,type=0,len=4}),flags(-df-csum+
>>>> k
>>>> ey)),recirc_id(0),in_port(6081),packet_type(ns=0,id=0),eth_type(0x0
>>>> 8
>>>> 00),ipv4(frag=no),
>>>> packets:0, bytes:0, used:never,
>>>> actions:userspace(pid=0,controller(reason=1,dont_send=0,continuatio
>>>> n
>>>> =0,recirc_id=3,rule_cookie=0,controller_id=0,max_len=65535))
>>>> +tunnel(tun_id=0x7b,src=1.1.2.92,dst=1.1.2.88,geneve({class=0xffff,
>>>> +t 
>>>> +ype=0x80,len=4,0xa/0xf}{class=0xffff,type=0,len=4}),flags(-df-csum
>>>> ++ 
>>>> +key)),recirc_id(0),in_port(6081),packet_type(ns=0,id=0),eth_type(0
>>>> +x
>>>> +0800),ipv4(frag=no),
>>>> packets:0, bytes:0, used:never,
>>>> actions:userspace(pid=0,controller(reason=1,dont_send=0,continuatio
>>>> n
>>>> =0,recirc_id=2,rule_cookie=0,controller_id=0,max_len=65535))
>>>>  ])
>>>>
>>>>  ovs-appctl time/warp 10000
>>>> @@ -510,7 +531,8 @@ AT_CHECK([ovs-appctl tnl/ports/show |sort], 
>>>> [0], [dnl  Listening ports:
>>>>  ])
>>>>
>>>> -OVS_VSWITCHD_STOP
>>>> +OVS_VSWITCHD_STOP(["/dropping tunnel packet marked ECN CE but is 
>>>> +not
>>>> ECN capable/d
>>>> +/ip packet has invalid checksum/d"])
>>>>  AT_CLEANUP
>>>>
>>>>  AT_SETUP([tunnel_push_pop - packet_out]) diff --git 
>>>> a/tests/tunnel.at b/tests/tunnel.at index 55fb1d3..7bd5b48 100644
>>>> --- a/tests/tunnel.at
>>>> +++ b/tests/tunnel.at
>>>> @@ -102,10 +102,12 @@ Datapath actions: set(ipv4(tos=0x3/0x3)),2
>>>>
>>>>  dnl Tunnel CE and encapsulated packet Non-ECT  
>>>> AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 
>>>> 'tunnel(src=1.1.1.1,dst=2.2.2.2,tos=0x3,ttl=64,flags()),in_port(1),
>>>> e 
>>>> th(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ip
>>>> v 
>>>> 4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=0,ttl=64,frag=no),tcp
>>>> (
>>>> src=8,dst=9)'],
>>>> [0], [stdout])
>>>> -AT_CHECK([tail -2 stdout], [0],
>>>> +AT_CHECK([tail -3 stdout], [0],
>>>>    [Megaflow: 
>>>> recirc_id=0,eth,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=2.2.2.2,tun_tos
>>>> = 3,tun_flags=-df-csum-key,in_port=1,nw_ecn=0,nw_frag=no
>>>>  Datapath actions: drop
>>>> +Translation failed (Congestion Drop), packet is dropped.
>>>>  ])
>>>> +
>>>>  OVS_VSWITCHD_STOP(["/dropping tunnel packet marked ECN CE but is 
>>>> not ECN capable/d"])  AT_CLEANUP
>>>>
>>>> @@ -193,6 +195,16 @@ AT_CHECK([ovs-appctl ofproto/trace ovs-dummy
>>>> 'in_port(2),eth(src=50:54:00:00:00:
>>>>  AT_CHECK([tail -1 stdout], [0],
>>>>    [Datapath actions: 
>>>> set(tunnel(tun_id=0x5,src=2.2.2.2,dst=1.1.1.1,ttl=64,flags(df|key))
>>>> )
>>>> ,set(skb_mark(0x2)),1
>>>>  ])
>>>> +
>>>> +AT_CHECK([ovs-appctl netdev-dummy/receive p2
>>>> 'aa55aa550001f8bc124434b6080045000054ba2000004001848601010358010103
>>>> 7
>>>> 001004227e75400030af3195500000000f265010000000000101112131415161718
>>>> 1
>>>> 91a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637'])
>>>> +
>>>> +sleep 2
>>>> +
>>>> +AT_CHECK([
>>>> +ovs-appctl coverage/show | grep "datapath_drop_invalid_port" | cut
>>>> -d':' -f2|sed 's/ //'
>>>> +], [0], [dnl
>>>> +1
>>>> +])
>>>>  OVS_VSWITCHD_STOP
>>>>  AT_CLEANUP
>>>>
>>>> --
>>>> 1.9.1
>>>>
>>>> _______________________________________________
>>>> dev mailing list
>>>> dev at openvswitch.org
>>>> https://protect2.fireeye.com/url?k=b1bddc0f-ed69d7a4-b1bd9c94-864b0
>>>> d 
>>>> 136b87-d394ae6811e94bab&q=1&u=https%3A%2F%2Fmail.openvswitch.org%2F
>>>> m
>>>> ailman%2Flistinfo%2Fovs-dev
_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to