On 26.11.2019 20:43, Ilya Maximets wrote:
> On 26.11.2019 9:59, 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
>>
>> Co-authored-by: Rohith Basavaraja <rohith.basavar...@gmail.com>
>> Co-authored-by: Keshav Gupta <keshugup...@gmail.com>
>> Signed-off-by: Anju Thomas <anju.tho...@ericsson.com>
>> Signed-off-by: Rohith Basavaraja <rohith.basavar...@gmail.com>
>> Signed-off-by: Keshav Gupta <keshugup...@gmail.com>
>> Acked-by: Eelco Chaudron <echau...@redhat.com
> 
> Please, limit the line length in a commit message to 72 characters.
> 
>> ---
>> v16 (Ilya and Eelco comments)
>>  1. remove old declaration of xlate_error in v15
>>  2. kernel file formatting in openvswitch.h for xlate_error
>>  3. remove drop_action from odp_actions_from_string
>>
>> v15(Ilya's comments)
>>  1. Description in openvswitch.h
>>  2. Move xlate_error to openvswitch.h to not include ofproto heeader in dp
>>  3. Return u32 for instead of size of enum
>>  4. Formatting
>>  5. Add drop-stats in testsuite.at
>>  6. Use coverage-read-counter
>>  7. Use flow instead of raw packet data wherever possible
>>  8. Change sleep to warp
>>
>> v14 (Eelco's comments)
>>  1. Remove definition of dpif_show_drop_stats_support
>>  2. Remove extra check for drop reason in odp_execute_actions
>>
>>  v13(Eelco and Illya's comments)
>>  1. packet_dropped changed to packets_dropped
>>  2. Uses dp_packet_batch_size instead of packet->size
>>  3. Add version history
>>
>>  v12(Ben's comments)
>>  1. new dp action in kernel block in openvswitch.h
>>  2. change xlate_error enum to be used as u32 3. resetting xlate error in 
>> case of congestion drop
>>      and forwarding disabled
>> ---
>>  datapath/linux/compat/include/linux/openvswitch.h |  18 ++
>>  lib/dpif-netdev.c                                 |  47 +++++-
>>  lib/dpif.c                                        |   7 +
>>  lib/dpif.h                                        |   2 +
>>  lib/odp-execute.c                                 |  77 +++++++++
>>  lib/odp-util.c                                    |   5 +
>>  ofproto/ofproto-dpif-ipfix.c                      |   1 +
>>  ofproto/ofproto-dpif-sflow.c                      |   1 +
>>  ofproto/ofproto-dpif-xlate.c                      |  38 ++++-
>>  ofproto/ofproto-dpif-xlate.h                      |  13 --
>>  ofproto/ofproto-dpif.c                            |   8 +
>>  ofproto/ofproto-dpif.h                            |   8 +-
>>  tests/automake.mk                                 |   3 +-
>>  tests/dpif-netdev.at                              |   8 +
>>  tests/drop-stats.at                               | 190 
>> ++++++++++++++++++++++
>>  tests/ofproto-dpif.at                             |   2 +-
>>  tests/testsuite.at                                |   1 +
>>  tests/tunnel-push-pop.at                          |  28 +++-
>>  tests/tunnel.at                                   |  16 +-
>>  19 files changed, 449 insertions(+), 24 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 778827f..e974d2c 100644
>> --- a/datapath/linux/compat/include/linux/openvswitch.h
>> +++ b/datapath/linux/compat/include/linux/openvswitch.h
>> @@ -404,6 +404,22 @@ enum ovs_tunnel_key_attr {
>>      __OVS_TUNNEL_KEY_ATTR_MAX
>>  };
>>
> 
> 1. Brief explanation of the purpose of this enum is required.
> Look at other enums as a reference.  You may avoid describing
> enum members though.
> 
> 2. This should be under '#ifndef __KERNEL__'.
> 
> 3. Please move the declaration after 'OVS_TUNNEL_KEY_ATTR_MAX'.
>    Don't split it from 'enum ovs_tunnel_key_attr'.
>   
>> +enum xlate_error {
>> +    XLATE_OK = 0,
>> +    XLATE_BRIDGE_NOT_FOUND,
>> +    XLATE_RECURSION_TOO_DEEP,
>> +    XLATE_TOO_MANY_RESUBMITS,
>> +    XLATE_STACK_TOO_DEEP,
>> +    XLATE_NO_RECIRCULATION_CONTEXT,
>> +    XLATE_RECIRCULATION_CONFLICT,
>> +    XLATE_TOO_MANY_MPLS_LABELS,
>> +    XLATE_INVALID_TUNNEL_METADATA,
>> +    XLATE_UNSUPPORTED_PACKET_TYPE,
>> +    XLATE_CONGESTION_DROP,
>> +    XLATE_FORWARDING_DISABLED,
>> +    XLATE_MAX,
>> +};
>> +
>>  #define OVS_TUNNEL_KEY_ATTR_MAX (__OVS_TUNNEL_KEY_ATTR_MAX - 1)
>>  
>>  /**
>> @@ -962,6 +978,7 @@ struct check_pkt_len_arg {
>>   * @OVS_ACTION_ATTR_CHECK_PKT_LEN: Check the packet length and execute a set
>>   * of actions if greater than the specified packet length, else execute
>>   * another set of actions.
>> + * @OVS_ACTION_ATTR_DROP: Explicit drop action.
>>   */
>>  
>>  enum ovs_action_attr {
>> @@ -994,6 +1011,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,          /* explicit drop action. */
> 
> Comment is not correct.  It should describe the type of the argument.
> Say that it's u32 and point to the enum.
> 
>>  #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 5142bad..8adeac5 100644
>> --- a/lib/dpif-netdev.c
>> +++ b/lib/dpif-netdev.c
>> @@ -102,6 +102,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;
>>  
>> @@ -5753,7 +5764,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. */
>> @@ -6503,6 +6514,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;
>>          }
>>  
>> @@ -6623,6 +6635,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;
>>      }
>>  
>> @@ -6753,6 +6766,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++;
>>              }
>>          }
>> @@ -7022,6 +7036,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);
>>      }
>>  }
>>  
>> @@ -7036,6 +7051,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, packets_dropped;
>>  
>>      switch ((enum ovs_action_attr)type) {
>>      case OVS_ACTION_ATTR_OUTPUT:
>> @@ -7077,6 +7093,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;
>>  
>> @@ -7086,10 +7105,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:
>> @@ -7109,7 +7134,14 @@ 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_);
>> +                packets_dropped =
>> +                   packet_count - dp_packet_batch_size(packets_);
>> +                if (packets_dropped) {
>> +                    COVERAGE_ADD(datapath_drop_tunnel_pop_error,
>> +                                 packets_dropped);
>> +                }
>>                  if (dp_packet_batch_is_empty(packets_)) {
>>                      return;
>>                  }
>> @@ -7124,6 +7156,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;
>>  
>> @@ -7168,6 +7205,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:
>> @@ -7191,6 +7231,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;
>>  
>> @@ -7348,6 +7390,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 c98513e..7cc2220 100644
>> --- a/lib/dpif.h
>> +++ b/lib/dpif.h
>> @@ -892,6 +892,8 @@ 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 *);
>> +
>>  
>>  /* Log functions. */
>>  struct vlog_module;
>> diff --git a/lib/odp-execute.c b/lib/odp-execute.c
>> index 563ad1d..3d4ad9e 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,72 @@
>>  #include "util.h"
>>  #include "csum.h"
>>  #include "conntrack.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 +688,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_INC(datapath_drop_sample_error);
>>                      dp_packet_delete(packet);
>>                  }
>>                  return;
>> @@ -749,6 +817,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 +1034,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 +1059,13 @@ 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);
>> +
>> +            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 b9600b4..9bda91f 100644
>> --- a/lib/odp-util.c
>> +++ b/lib/odp-util.c
>> @@ -141,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(uint32_t);
>>  
>>      case OVS_ACTION_ATTR_UNSPEC:
>>      case __OVS_ACTION_ATTR_MAX:
>> @@ -1238,6 +1239,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:
>> @@ -2575,6 +2579,7 @@ odp_actions_from_string(const char *s, const struct 
>> simap *port_names,
>>      size_t old_size;
>>  
>>      if (!strcasecmp(s, "drop")) {
>> +        nl_msg_put_u32(actions, OVS_ACTION_ATTR_DROP, XLATE_OK);
>>          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 9abaab6..f9ea47a 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 cebae7a..18dfebe 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";
>>  }
>> @@ -6002,6 +6008,12 @@ 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)
>>  {
>> @@ -7638,8 +7650,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;
>> @@ -7671,6 +7684,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) {
>> @@ -7679,6 +7693,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. */
>> @@ -7784,6 +7800,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.
> 
> Some spaces are missing above.
> Probably, better to rephrase:
> 
>        /* Install explicit drop action containing the drop reason if
>         * datapath supports it. */
> 
>> +     */
>> +    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..3426a27 100644
>> --- a/ofproto/ofproto-dpif-xlate.h
>> +++ b/ofproto/ofproto-dpif-xlate.h
>> @@ -206,19 +206,6 @@ int xlate_lookup(const struct dpif_backer *, const 
>> struct flow *,
>>                   struct dpif_sflow **, struct netflow **,
>>                   ofp_port_t *ofp_in_port);
>>  
>> -enum xlate_error {
>> -    XLATE_OK = 0,
>> -    XLATE_BRIDGE_NOT_FOUND,
>> -    XLATE_RECURSION_TOO_DEEP,
>> -    XLATE_TOO_MANY_RESUBMITS,
>> -    XLATE_STACK_TOO_DEEP,
>> -    XLATE_NO_RECIRCULATION_CONTEXT,
>> -    XLATE_RECIRCULATION_CONFLICT,
>> -    XLATE_TOO_MANY_MPLS_LABELS,
>> -    XLATE_INVALID_TUNNEL_METADATA,
>> -    XLATE_UNSUPPORTED_PACKET_TYPE,
>> -};
>> -
>>  const char *xlate_strerror(enum xlate_error error);
>>  
>>  enum xlate_error xlate_actions(struct xlate_in *, struct xlate_out *);
>> diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
>> index 2cd786a..c948aba 100644
>> --- a/ofproto/ofproto-dpif.c
>> +++ b/ofproto/ofproto-dpif.c
>> @@ -860,6 +860,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.
>> @@ -1584,6 +1590,8 @@ check_support(struct dpif_backer *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.ct_timeout = check_ct_timeout_policy(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 cd45363..bcaacef 100644
>> --- a/ofproto/ofproto-dpif.h
>> +++ b/ofproto/ofproto-dpif.h
>> @@ -199,7 +199,11 @@ struct group_dpif *group_dpif_lookup(struct 
>> ofproto_dpif *,
>>                                                                              
>> \
>>      /* True if the datapath supports OVS_CT_ATTR_TIMEOUT in                 
>> \
>>       * OVS_ACTION_ATTR_CT action. */                                        
>> \
>> -    DPIF_SUPPORT_FIELD(bool, ct_timeout, "Conntrack timeout policy")
>> +    DPIF_SUPPORT_FIELD(bool, ct_timeout, "Conntrack timeout policy")        
>> \
>> +                                                                            
>> \
>> +    /* True if the datapath supports explicit drop action. */               
>> \
>> +    DPIF_SUPPORT_FIELD(bool, explicit_drop_action, "Explicit Drop action")
> 
> There is a new functionality to report datapath supported features.
> You need to add this new field there.  See get_datapath_cap() callback.


This also needs to be documented in vswitchd/vswitch.xml.

See commit 27501802d09f ("ofproto-dpif: Expose datapath capability to ovsdb.")
for details.

Best regards, Ilya Maximets.
_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to