Thanks, I’ve CC’ed Ben so he can look at the comments regarding his earlier comment :)

Looking forward for the next version…

//Eelco


On 4 Sep 2019, at 11:24, Anju Thomas wrote:

Hi Eelco,
Since I have not received any more comments, let me respond to your comments:



-----Original Message-----
From: Eelco Chaudron <[email protected]>
Sent: Tuesday, September 3, 2019 7:27 PM
To: Anju Thomas <[email protected]>
Cc: [email protected]; Keshav Gupta <[email protected]>
Subject: Re: [ovs-dev] [PATCH v12] Improved Packet Drop Statistics in OVS



On 20 Aug 2019, at 11:57, Anju Thomas wrote:

Thanks for the comments Eelco. I will address them in the next patch.

On a similar note, are these the final set of comments for this patch
?

Did you get any update, and are you planning on sending out an update?

Thanks,

Eelco

Regards
Anju

-----Original Message-----
From: Eelco Chaudron <[email protected]>
Sent: Monday, August 12, 2019 5:48 PM
To: Anju Thomas <[email protected]>
Cc: [email protected]; Keshav Gupta <[email protected]>
Subject: Re: [ovs-dev] [PATCH v12] Improved Packet Drop Statistics in
OVS

Hi Anju,

See comments inline…

//Eelco


On 25 Jul 2019, at 14:16, 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

v11->v12 Addresses comments from Ben Pfaff

Co-authored-by: Rohith Basavaraja <[email protected]>
Co-authored-by: Keshav Gupta <[email protected]>
Signed-off-by: Anju Thomas <[email protected]>
Signed-off-by: Rohith Basavaraja <[email protected]>
Signed-off-by: Keshav Gupta <[email protected]>
---
 datapath/linux/compat/include/linux/openvswitch.h |   1 +
 lib/dpif-netdev.c                                 |  46 ++++-
 lib/dpif.c                                        |   7 +
 lib/dpif.h                                        |   4 +
 lib/odp-execute.c                                 |  79 ++++++++
 lib/odp-util.c                                    |   9 +
 ofproto/ofproto-dpif-ipfix.c                      |   1 +
 ofproto/ofproto-dpif-sflow.c                      |   1 +
 ofproto/ofproto-dpif-xlate.c                      |  40 ++++-
 ofproto/ofproto-dpif-xlate.h                      |   3 +
 ofproto/ofproto-dpif.c                            |   8 +
 ofproto/ofproto-dpif.h                            |   8 +-
 tests/automake.mk                                 |   3 +-
 tests/dpif-netdev.at                              |   8 +
 tests/drop-stats.at                               | 210
++++++++++++++++++++++
 tests/ofproto-dpif.at                             |   2 +-
 tests/tunnel-push-pop.at                          |  29 ++-
 tests/tunnel.at                                   |  16 +-
 18 files changed, 464 insertions(+), 11 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 65a003a..415c053 100644
--- a/datapath/linux/compat/include/linux/openvswitch.h
+++ b/datapath/linux/compat/include/linux/openvswitch.h
@@ -989,6 +989,7 @@ enum ovs_action_attr {  #ifndef __KERNEL__
        OVS_ACTION_ATTR_TUNNEL_PUSH,   /* struct ovs_action_push_tnl*/
        OVS_ACTION_ATTR_TUNNEL_POP,    /* u32 port number. */
+       OVS_ACTION_ATTR_DROP,
 #endif
        __OVS_ACTION_ATTR_MAX,        /* Nothing past this will be accepted
                                       * from userspace. */
diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index
6b99a3c..3878b8d 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;

@@ -5762,7 +5773,7 @@ dp_netdev_run_meter(struct dp_netdev *dp,
struct dp_packet_batch *packets_,
             band = &meter->bands[exceeded_band[j]];
             band->packet_count += 1;
             band->byte_count += dp_packet_size(packet);
-
+            COVERAGE_INC(datapath_drop_meter);
             dp_packet_delete(packet);
         } else {
             /* Meter accepts packet. */ @@ -6512,6 +6523,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;
         }

@@ -6631,6 +6643,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;
     }

@@ -6761,6 +6774,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++;
             }
         }
@@ -7030,6 +7044,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);
     }
 }

@@ -7044,6 +7059,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;

nit, but maybe packetS_dropped make more sense…

Will change to packets_dropped


     switch ((enum ovs_action_attr)type) {
     case OVS_ACTION_ATTR_OUTPUT:
@@ -7085,6 +7101,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;

@@ -7094,10 +7113,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:
@@ -7117,7 +7142,13 @@ dp_execute_cb(void *aux_, struct
dp_packet_batch *packets_,

                 dp_packet_batch_apply_cutlen(packets_);

+                packet_count = dp_packet_batch_size(packets_);
                 netdev_pop_header(p->port->netdev, packets_);
+                packet_dropped = packet_count - packets_->count;

Here you need to use the dp_packet_batch_size(packets_) macro also, so

packetsCOVERAGE_INC_dropped = packet_count -
dp_packet_batch_size(packets_);

Will use dp_packet_batch_size here as well

+                if (packet_dropped) {
+                    COVERAGE_ADD(datapath_drop_tunnel_pop_error,
+                                 packet_dropped);
+                }
                 if (dp_packet_batch_is_empty(packets_)) {
                     return;
                 }
@@ -7132,6 +7163,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;

@@ -7176,6 +7212,9 @@ 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:
@@ -7199,6 +7238,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;

@@ -7352,6 +7393,7 @@ dp_execute_cb(void *aux_, struct
dp_packet_batch *packets_,
     case OVS_ACTION_ATTR_POP_NSH:
     case OVS_ACTION_ATTR_CT_CLEAR:
     case OVS_ACTION_ATTR_CHECK_PKT_LEN:
+    case OVS_ACTION_ATTR_DROP:
     case __OVS_ACTION_ATTR_MAX:
         OVS_NOT_REACHED();
     }
diff --git a/lib/dpif.c b/lib/dpif.c
index c88b210..5a9ff46 100644
--- a/lib/dpif.c
+++ b/lib/dpif.c
@@ -1274,6 +1274,7 @@ dpif_execute_helper_cb(void *aux_, struct
dp_packet_batch *packets_,
     case OVS_ACTION_ATTR_CT_CLEAR:
     case OVS_ACTION_ATTR_UNSPEC:
     case OVS_ACTION_ATTR_CHECK_PKT_LEN:
+    case OVS_ACTION_ATTR_DROP:
     case __OVS_ACTION_ATTR_MAX:
         OVS_NOT_REACHED();
     }
@@ -1879,6 +1880,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 289d574..3ac5a5a 100644
--- a/lib/dpif.h
+++ b/lib/dpif.h
@@ -890,6 +890,10 @@ 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
563ad1d..a4837a6 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,73 @@
 #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(datapath_drop_sample_error);
+COVERAGE_DEFINE(datapath_drop_nsh_decap_error);
+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 +689,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(datapath_drop_sample_error, 1);

Use COVERAGE_INC() here


Will use COVERGAE_INC here
                     dp_packet_delete(packet);
                 }
                 return;
@@ -749,6 +818,7 @@ requires_datapath_assistance(const struct nlattr
*a)
     case OVS_ACTION_ATTR_POP_NSH:
     case OVS_ACTION_ATTR_CT_CLEAR:
     case OVS_ACTION_ATTR_CHECK_PKT_LEN:
+    case OVS_ACTION_ATTR_DROP:
         return false;

     case OVS_ACTION_ATTR_UNSPEC:
@@ -965,6 +1035,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(datapath_drop_nsh_decap_error);
                     dp_packet_delete(packet);
                 }
             }
@@ -989,6 +1060,14 @@ odp_execute_actions(void *dp, struct
dp_packet_batch *batch, bool steal,
             }
             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 84ea4c1..5dc5bbf
100644
--- a/lib/odp-util.c
+++ b/lib/odp-util.c
@@ -44,6 +44,7 @@
 #include "openvswitch/vlog.h"
 #include "openvswitch/match.h"
 #include "odp-netlink-macros.h"
+#include "ofproto/ofproto-dpif-xlate.h"

 VLOG_DEFINE_THIS_MODULE(odp_util);

@@ -140,6 +141,7 @@ odp_action_len(uint16_t type)
     case OVS_ACTION_ATTR_PUSH_NSH: return ATTR_LEN_VARIABLE;
     case OVS_ACTION_ATTR_POP_NSH: return 0;
     case OVS_ACTION_ATTR_CHECK_PKT_LEN: return ATTR_LEN_VARIABLE;
+    case OVS_ACTION_ATTR_DROP: return sizeof(enum xlate_error);

     case OVS_ACTION_ATTR_UNSPEC:
     case __OVS_ACTION_ATTR_MAX:
@@ -1230,6 +1232,9 @@ format_odp_action(struct ds *ds, const struct
nlattr *a,
     case OVS_ACTION_ATTR_CHECK_PKT_LEN:
         format_odp_check_pkt_len_action(ds, a, portno_names);
         break;
+    case OVS_ACTION_ATTR_DROP:
+        ds_put_cstr(ds, "drop");
+        break;
     case OVS_ACTION_ATTR_UNSPEC:
     case __OVS_ACTION_ATTR_MAX:
     default:
@@ -2547,8 +2552,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_u32(actions, OVS_ACTION_ATTR_DROP,
+                          drop_action);
         return 0;
     }

diff --git a/ofproto/ofproto-dpif-ipfix.c
b/ofproto/ofproto-dpif-ipfix.c index b8bd1b8..b413768 100644
--- a/ofproto/ofproto-dpif-ipfix.c
+++ b/ofproto/ofproto-dpif-ipfix.c
@@ -3016,6 +3016,7 @@ dpif_ipfix_read_actions(const struct flow
*flow,
         case OVS_ACTION_ATTR_POP_NSH:
         case OVS_ACTION_ATTR_CHECK_PKT_LEN:
         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 03bd763..387e9b5 100644
--- a/ofproto/ofproto-dpif-sflow.c
+++ b/ofproto/ofproto-dpif-sflow.c
@@ -1224,6 +1224,7 @@ dpif_sflow_read_actions(const struct flow
*flow,
         case OVS_ACTION_ATTR_POP_NSH:
         case OVS_ACTION_ATTR_UNSPEC:
         case OVS_ACTION_ATTR_CHECK_PKT_LEN:
+        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 73966a4..2b583e2 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -445,6 +445,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";
 }
@@ -5955,6 +5961,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_u32(odp_actions, OVS_ACTION_ATTR_DROP,
+                      error);
+
+}
+
+static void
 put_ct_helper(struct xlate_ctx *ctx,
               struct ofpbuf *odp_actions, struct ofpact_conntrack
*ofc)
 {
@@ -7544,8 +7558,9 @@ xlate_actions(struct xlate_in *xin, struct
xlate_out *xout)
             compose_ipfix_action(&ctx, ODPP_NONE);
         }
         size_t sample_actions_len = ctx.odp_actions->size;
+        bool ecn_drop = !tnl_process_ecn(flow);

-        if (tnl_process_ecn(flow)
+        if (!ecn_drop
             && (!in_port || may_receive(in_port, &ctx))) {
             const struct ofpact *ofpacts;
             size_t ofpacts_len;
@@ -7577,6 +7592,7 @@ xlate_actions(struct xlate_in *xin, struct
xlate_out *xout)
                 ctx.odp_actions->size = sample_actions_len;
                 ctx_cancel_freeze(&ctx);
                 ofpbuf_clear(&ctx.action_set);
+                ctx.error = XLATE_FORWARDING_DISABLED;
             }

             if (!ctx.freezing) {
@@ -7585,6 +7601,8 @@ xlate_actions(struct xlate_in *xin, struct
xlate_out *xout)
             if (ctx.freezing) {
                 finish_freezing(&ctx);
             }
+        } else if (ecn_drop) {
+            ctx.error = XLATE_CONGESTION_DROP;
         }

         /* Output only fully processed packets. */ @@ -7690,6
+7708,26 @@ 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);
+    }
+
+    /* Since congestion drop and forwarding drop are not exactly
+     * translation error, we are resetting the translation error.
+     */
+    if (ctx.error == XLATE_CONGESTION_DROP ||
+        ctx.error == XLATE_FORWARDING_DISABLED) {
+       ctx.error = XLATE_OK;
+    }
+
     return ctx.error;
 }

diff --git a/ofproto/ofproto-dpif-xlate.h
b/ofproto/ofproto-dpif-xlate.h index f97c7c0..3105a44 100644
--- a/ofproto/ofproto-dpif-xlate.h
+++ b/ofproto/ofproto-dpif-xlate.h
@@ -217,6 +217,9 @@ enum xlate_error {
     XLATE_TOO_MANY_MPLS_LABELS,
     XLATE_INVALID_TUNNEL_METADATA,
     XLATE_UNSUPPORTED_PACKET_TYPE,
+    XLATE_CONGESTION_DROP,
+    XLATE_FORWARDING_DISABLED,

There was a comment from Benn you did not reply to, so I leave this
open:

“I'm uncomfortable with the two new errors XLATE_CONGESTION_DROP and
XLATE_FORWARDING_DISABLED as translation errors, since they aren't
translation errors and don't prevent translation from completing.”

Yes. Basically Ben wanted to not propagate ctx.error as error to the datapath. Hence I have reset it to XLATE_OK after setting it as drop reason above.

+    XLATE_MAX,

Why did you at XLATE_MAX as it’s not used?


I have used XLATE_MAX because I am using this value for comparison in datapath. In future if more errors are introduced we don’t need to change this in comparison in future. (Ref func: odp_execute_actions condition if (*drop_reason < XLATE_MAX) )


 };

 const char *xlate_strerror(enum xlate_error error); diff --git
a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index
7515352..358b9b8 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -828,6 +828,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.
@@ -1441,6 +1447,8 @@ check_support(struct dpif_backer *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.check_pkt_len = check_check_pkt_len(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
cd5321e..f2f0f20 100644
--- a/ofproto/ofproto-dpif.h
+++ b/ofproto/ofproto-dpif.h
@@ -195,7 +195,11 @@ struct group_dpif *group_dpif_lookup(struct
ofproto_dpif *,
     DPIF_SUPPORT_FIELD(size_t, max_hash_alg, "Max dp_hash
algorithm")
      \
                                                                             \
     /* True if the datapath supports OVS_ACTION_ATTR_CHECK_PKT_LEN.
*/   \
-    DPIF_SUPPORT_FIELD(bool, check_pkt_len, "Check pkt length
action")
+    DPIF_SUPPORT_FIELD(bool, check_pkt_len, "Check pkt length
action")     \
+
      \
+    /* True if the datapath supports explicit drop action. */
      \
+    DPIF_SUPPORT_FIELD(bool, explicit_drop_action, "Explicit Drop
action")
+

Please fix alignment of trailing \, while you are at it also for the
line above “PIF_SUPPORT_FIELD(size_t, max_hash_alg, "Max dp_hash
algorithm”)”


 /* Stores the various features which the corresponding backer
supports. */  struct dpif_backer_support { @@ -364,4 +368,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
2956e68..04e67c2 100644
--- a/tests/automake.mk
+++ b/tests/automake.mk
@@ -111,7 +111,8 @@ TESTSUITE_AT = \
        tests/mcast-snooping.at \
        tests/packet-type-aware.at \
        tests/nsh.at \
-       tests/ovn-performance.at
+       tests/ovn-performance.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
af8a29e..b8b6296 100644
--- a/tests/dpif-netdev.at
+++ b/tests/dpif-netdev.at
@@ -349,6 +349,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),ipv4(
frag=no),
actions:meter(0),7

recirc_id(0),in_port(2),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(
frag=no),
actions:8
diff --git a/tests/drop-stats.at b/tests/drop-stats.at new file mode
100644 index 0000000..c7f8cb7
--- /dev/null
+++ b/tests/drop-stats.at
@@ -0,0 +1,210 @@
+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
1e2ce92a669e3a6dd2099cab0800450000548a53400040011addc0a80a0ac0a80a1e0
8006f200a4d0001fc509a58000000002715020000000000101112131415161718191a
1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+    ovs-appctl netdev-dummy/receive p1
1e2ce92a669e3a6dd2099cab0800450000548a53400040011addc0a80a0ac0a80a1e0
8006f200a4d0001fc509a58000000002715020000000000101112131415161718191a
1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+    ovs-appctl netdev-dummy/receive p1
+1e2ce92a669e3a6dd2099cab0800450000548a53400040011addc0a80a0ac0a80a1e
+080
+06f200a4d0001fc509a58000000002715020000000000101112131415161718191a1
+b1c
+1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+], [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),ipv4
+(fr ag=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
+1e2ce92a669e3a6dd2099cab0800450000548a53400040011addc0a80a0ac0a80a1e
+080
+06f200a4d0001fc509a58000000002715020000000000101112131415161718191a1
+b1c
+1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+], [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
+1e2ce92a669e3a6dd2099cab0800450000548a53400040011addc0a80a0ac0a80a1e
+080
+06f200a4d0001fc509a58000000002715020000000000101112131415161718191a1
+b1c
+1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+], [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
+1e2ce92a669e3a6dd2099cab0800450000548a53400040011addc0a80a0ac0a80a1e
+080
+06f200a4d0001fc509a58000000002715020000000000101112131415161718191a1
+b1c
+1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+], [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
dc21c88..e42c490 100644
--- a/tests/ofproto-dpif.at
+++ b/tests/ofproto-dpif.at
@@ -9425,7 +9425,7 @@
recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x8100),vlan(
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@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(ns=
0,id=0),eth(src=50:54:00:00:00:09/00:00:00:00:00:00,dst=50:54:00:00:0
0:0a/00:00:00:00:00:00),eth_type(0x1234)
+dpif|DBG|dummy@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(ns=
0,id=0),eth(src=50:54:00:00:00:09/00:00:00:00:00:00,dst=50:54:00:00:0
0:0a/00:00:00:00:00:00),eth_type(0x1234),
actions:drop
 dpif|DBG|dummy@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(ns=
0,id=0),eth(src=50:54:00:00:00:09/00:00:00:00:00:00,dst=50:54:00:00:0
0: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),vlan(
vid=99,pcp=7/0x0),encap(eth_type(0x1234)),
actions:drop
 ])
diff --git a/tests/tunnel-push-pop.at b/tests/tunnel-push-pop.at
index f717243..532c44e 100644
--- a/tests/tunnel-push-pop.at
+++ b/tests/tunnel-push-pop.at
@@ -447,6 +447,28 @@ 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
'aa55aa550000001b213cab6408004500007079464000402fba600101025c01010258
20000800000001c845000054ba200000400184861e0000011e00000200004227e7540
0030af3195500000000f265010000000000101112131415161718191a1b1c1d1e1f20
2122232425262728292a2b2c2d2e2f3031323334353637'])
+
+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
'aa55aa550000001b213cab6408004503007079464000402fba600101025c01010258
20000800000001c845000054ba200000400184861e0000011e00000200004227e7540
0030af3195500000000f265010000000000101112131415161718191a1b1c1d1e1f20
2122232425262728292a2b2c2d2e2f3031323334353637'])
+
+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
'aa55aa550000001b213cab6408004500007e79464000402fba550101025c01010258
20000800000001c8fe71d883724fbeb6f4e1494a080045000054ba200000400184861
e0000011e00000200004227e75400030af3195500000000f265010000000000101112
131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f30313233343
53637'])

@@ -455,7 +477,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
+500,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,ty
pe=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(0x0800)
,ipv4(frag=no),
packets:0, bytes:0, used:never,
actions:userspace(pid=0,controller(reason=1,dont_send=0,continuation=
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,ty
+pe=0x80,len=4,0xa/0xf}{class=0xffff,type=0,len=4}),flags(-df-csum+ke
+y)),recirc_id(0),in_port(6081),packet_type(ns=0,id=0),eth_type(0x080
+0),ipv4(frag=no),
packets:0, bytes:0, used:never,
actions:userspace(pid=0,controller(reason=1,dont_send=0,continuation=
0,recirc_id=2,rule_cookie=0,controller_id=0,max_len=65535))
 ])

 ovs-appctl time/warp 10000
@@ -510,7 +532,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 035c54f..b0a80d5 100644
--- a/tests/tunnel.at
+++ b/tests/tunnel.at
@@ -102,8 +102,9 @@ 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),et
h(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(
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],
-  [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
+AT_CHECK([tail -3 stdout], [0],
+  [Final flow: unchanged
+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
 ])
OVS_VSWITCHD_STOP(["/dropping tunnel packet marked ECN CE but is not
ECN capable/d"]) @@ -193,6 +194,17 @@ 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
'aa55aa550001f8bc124434b6080045000054ba200000400184860101035801010370
01004227e75400030af3195500000000f265010000000000101112131415161718191
a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637'])
+
+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
[email protected]
https://protect2.fireeye.com/url?k=58a57294-04717fe6-58a5320f-86859b2
931b3-8b0fe0ffb85e8b17&q=1&u=https%3A%2F%2Fmail.openvswitch.org%2Fmai
lman%2Flistinfo%2Fovs-dev
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to