Yes. Thank you. I'll review it tomorrow.
On Fri, Jan 18, 2019 at 04:54:51AM +0000, Anju Thomas wrote: > Hi Ben, > Were you able to apply this patch successfully? > Regards > Anju > > -----Original Message----- > From: Anju Thomas [mailto:anju.tho...@ericsson.com] > Sent: Thursday, January 17, 2019 10:19 AM > To: d...@openvswitch.org > Cc: Anju Thomas <anju.tho...@ericsson.com>; Rohith Basavaraja > <rohith.basavar...@gmail.com>; Keshav Gupta <keshugup...@gmail.com> > Subject: [PATCH v6] Improved Packet Drop Statistics in OVS > > 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. Account and categorize all the packet drops in OVS. > 2. Account & classify “drop” action packet drops according to the drop > reason. > 3. Identify and account all the silent packet drop scenarios. > 4. Display these drops in ovs-appctl coverage/show > 5. Modified ovs-appctl dpcls/dump-flows and ovs-appctl dpif/dump-flows > to print drop reason along with drop action > > 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-the-data-plane-in-ovs-82280329 > > Sample ovs-appctl dpcls/dump-flows & ovs-appctl dpif/dump-flows > displaying drop reason along with drop action. > > The idea is to use the coverage infrastructure to maintain the drops > > $ ovs-appctl dpctl/dump-flows netdev at ovs-netdev > flow-dump from pmd on cpu core: 0 > > recirc_id(0),in_port(5),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=no), > packets:12, bytes:1176, used:0.884s, actions:drop:recursion too deep > > $ ovs-appctl dpif/dump-flows br-int > > recirc_id(0),in_port(5),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=no), > packets:25, bytes:2450, used:5.008s, actions:drop:recursion too deep > recirc_id(0),in_port(5),packet_type(ns=0,id=0),eth_type(0x0806), > packets:7, bytes:294, used:0.009s, actions:drop:recursion too deep > > In subsequent commits, we are planning to see if we can use this > infrastructure to create a > wrapper to clear and display counters as well. > > 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> > --- > datapath/linux/compat/include/linux/openvswitch.h | 51 ++++++ > lib/coverage.c | 6 +- > lib/coverage.h | 3 +- > lib/dpif-netdev.c | 105 +++++++++++- > lib/dpif.c | 10 +- > lib/dpif.h | 3 + > lib/netdev-dpdk.c | 4 + > lib/odp-execute.c | 50 ++++-- > lib/odp-execute.h | 10 +- > lib/odp-util.c | 54 +++++- > ofproto/ofproto-dpif-ipfix.c | 1 + > ofproto/ofproto-dpif-sflow.c | 1 + > ofproto/ofproto-dpif-upcall.c | 3 +- > ofproto/ofproto-dpif-xlate.c | 64 +++++++ > ofproto/ofproto-dpif-xlate.h | 4 + > ofproto/ofproto-dpif.c | 11 +- > ofproto/ofproto-dpif.h | 8 +- > tests/automake.mk | 3 +- > tests/bundle.at | 2 +- > tests/classifier.at | 10 +- > tests/dpif-netdev.at | 17 +- > tests/drop-stats.at | 197 > ++++++++++++++++++++++ > tests/ofproto-dpif.at | 118 ++++++------- > tests/ovs-ofctl.at | 2 +- > tests/packet-type-aware.at | 17 +- > tests/testsuite.at | 1 + > tests/tunnel-push-pop.at | 26 ++- > tests/tunnel.at | 21 ++- > 28 files changed, 695 insertions(+), 107 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 9b087f1..b66b46f 100644 > --- a/datapath/linux/compat/include/linux/openvswitch.h > +++ b/datapath/linux/compat/include/linux/openvswitch.h > @@ -819,6 +819,56 @@ struct ovs_action_push_eth { > }; > > /** > + * enum ovs_drop_reason - Reasons for installing %OVS_ACTION_ATTR_DROP. > + * @OVS_DROP_REASON_OF_PIPELINE: Explicit drop action in the pipeline. > + * @OVS_DROP_REASON_BRIDGE_NOT_FOUND: Xlation error generated due to > + * unable to determine bridge. > + * @OVS_DROP_REASON_RECURSION_TOO_DEEP: Xlation error generated due to > + * recursion reached maximum depth. > + * @OVS_DROP_REASON_TOO_MANY_RESUBMITS: Xlation error generated due to > + * too many resubmits. > + * @OVS_DROP_REASON_STACK_TOO_DEEP: Xlation error generated due to stack > + * too deep. > + * @OVS_DROP_REASON_NO_RECIRCULATION_CONTEXT: Xlation error generated > + * due to no recirculation context. > + * @OVS_DROP_REASON_RECIRCULATION_CONFLICT: Xlation error generated due to > + * conflict in recirculation context. > + * @OVS_DROP_REASON_TOO_MANY_MPLS_LABELS: Xlation error generated due to > + * too many mpls labels. > + * @OVS_DROP_REASON_INVALID_TUNNEL_METADATA: Xlation error generated due to > + * invalid tunnel metadata. > + * @OVS_DROP_REASON_UNSUPPORTED_PACKET_TYPE: Xlation error generated due to > + * unsupported packet type. > + * @OVS_DROP_REASON_CONGESTION: Xlation error generated due to ecn mismatch > + * during tunnel decapsulation. > + * @OVS_DROP_REASON_FORWARDING_DISABLED: Xlation error generated due to > + * forwarding is disabled. > + */ > +enum ovs_drop_reason { > + OVS_DROP_REASON_OF_PIPELINE = 0, > + OVS_DROP_REASON_BRIDGE_NOT_FOUND, > + OVS_DROP_REASON_RECURSION_TOO_DEEP, > + OVS_DROP_REASON_TOO_MANY_RESUBMITS, > + OVS_DROP_REASON_STACK_TOO_DEEP, > + OVS_DROP_REASON_NO_RECIRCULATION_CONTEXT, > + OVS_DROP_REASON_RECIRCULATION_CONFLICT, > + OVS_DROP_REASON_TOO_MANY_MPLS_LABELS, > + OVS_DROP_REASON_INVALID_TUNNEL_METADATA, > + OVS_DROP_REASON_UNSUPPORTED_PACKET_TYPE, > + OVS_DROP_REASON_CONGESTION, > + OVS_DROP_REASON_FORWARDING_DISABLED, > + OVS_DROP_REASON_MAX, > +}; > + > +/* > + * struct ovs_action_drop - %OVS_ACTION_ATTR_DROP action argument. > + * @drop_reason: Reason for installing drop action. > + */ > +struct ovs_action_drop { > + enum ovs_drop_reason drop_reason; > +}; > + > +/** > * enum ovs_nat_attr - Attributes for %OVS_CT_ATTR_NAT. > * > * @OVS_NAT_ATTR_SRC: Flag for Source NAT (mangle source address/port). > @@ -938,6 +988,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, /* explicit drop action. */ > > #ifndef __KERNEL__ > OVS_ACTION_ATTR_TUNNEL_PUSH, /* struct ovs_action_push_tnl*/ > diff --git a/lib/coverage.c b/lib/coverage.c > index 6cef826..c9acc37 100644 > --- a/lib/coverage.c > +++ b/lib/coverage.c > @@ -32,9 +32,7 @@ VLOG_DEFINE_THIS_MODULE(coverage); > static struct coverage_counter **coverage_counters = NULL; > static size_t n_coverage_counters = 0; > static size_t allocated_coverage_counters = 0; > - > -static struct ovs_mutex coverage_mutex = OVS_MUTEX_INITIALIZER; > - > +struct ovs_mutex coverage_mutex = OVS_MUTEX_INITIALIZER; > DEFINE_STATIC_PER_THREAD_DATA(long long int, coverage_clear_time, LLONG_MIN); > static long long int coverage_run_time = LLONG_MIN; > > @@ -52,7 +50,7 @@ coverage_counter_register(struct coverage_counter* counter) > if (n_coverage_counters >= allocated_coverage_counters) { > coverage_counters = x2nrealloc(coverage_counters, > &allocated_coverage_counters, > - sizeof(struct coverage_counter*)); > + sizeof(struct coverage_counter *)); > } > coverage_counters[n_coverage_counters++] = counter; > } > diff --git a/lib/coverage.h b/lib/coverage.h > index dea990e..45b1dbd 100644 > --- a/lib/coverage.h > +++ b/lib/coverage.h > @@ -54,7 +54,8 @@ struct coverage_counter { > unsigned int hr[HR_AVG_LEN]; > }; > > -void coverage_counter_register(struct coverage_counter*); > +extern struct ovs_mutex coverage_mutex; > +void coverage_counter_register(struct coverage_counter *); > > /* Defines COUNTER. There must be exactly one such definition at file scope > * within a program. */ > diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c > index be529b6..8749cba 100644 > --- a/lib/dpif-netdev.c > +++ b/lib/dpif-netdev.c > @@ -100,6 +100,30 @@ 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(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); > +COVERAGE_DEFINE(dp_meter_drop); > +COVERAGE_DEFINE(dp_upcall_error_drop); > +COVERAGE_DEFINE(dp_lock_error_drop); > +COVERAGE_DEFINE(dp_userspace_action_error_drop); > +COVERAGE_DEFINE(dp_tunnel_push_error_drop); > +COVERAGE_DEFINE(dp_tunnel_pop_error_drop); > +COVERAGE_DEFINE(dp_recirc_error_drop); > +COVERAGE_DEFINE(dp_invalid_port_drop); > +COVERAGE_DEFINE(dp_invalid_tnl_port_drop); > +COVERAGE_DEFINE(rx_invalid_packet_drop); > + > /* Protects against changes to 'dp_netdevs'. */ > static struct ovs_mutex dp_netdev_mutex = OVS_MUTEX_INITIALIZER; > > @@ -829,7 +853,6 @@ static inline bool > pmd_perf_metrics_enabled(const struct dp_netdev_pmd_thread *pmd); > static void queue_netdev_flow_del(struct dp_netdev_pmd_thread *pmd, > struct dp_netdev_flow *flow); > - > static void > emc_cache_init(struct emc_cache *flow_cache) > { > @@ -1388,6 +1411,7 @@ dpif_netdev_init(void) > return 0; > } > > + > static int > dpif_netdev_enumerate(struct sset *all_dps, > const struct dpif_class *dpif_class) > @@ -5563,7 +5587,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(dp_meter_drop); > dp_packet_delete(packet); > } else { > /* Meter accepts packet. */ > @@ -6320,6 +6344,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(rx_invalid_packet_drop); > continue; > } > > @@ -6446,6 +6471,7 @@ handle_packet_upcall(struct dp_netdev_pmd_thread *pmd, > put_actions); > if (OVS_UNLIKELY(error && error != ENOSPC)) { > dp_packet_delete(packet); > + COVERAGE_INC(dp_upcall_error_drop); > return error; > } > > @@ -6577,6 +6603,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(dp_lock_error_drop); > upcall_fail_cnt++; > } > } > @@ -6846,10 +6873,59 @@ dp_execute_userspace_action(struct > dp_netdev_pmd_thread *pmd, > actions->data, actions->size); > } else if (should_steal) { > dp_packet_delete(packet); > + COVERAGE_INC(dp_userspace_action_error_drop); > } > } > > static void > +dp_update_drop_action_counter_cb(enum ovs_drop_reason drop_reason, > + int delta) > + OVS_NO_THREAD_SAFETY_ANALYSIS > +{ > + switch (drop_reason) { > + case OVS_DROP_REASON_OF_PIPELINE: > + COVERAGE_ADD(drop_action_of_pipeline, delta); > + break; > + case OVS_DROP_REASON_BRIDGE_NOT_FOUND: > + COVERAGE_ADD(drop_action_bridge_not_found, delta); > + break; > + case OVS_DROP_REASON_RECURSION_TOO_DEEP: > + COVERAGE_ADD(drop_action_recursion_too_deep, delta); > + break; > + case OVS_DROP_REASON_TOO_MANY_RESUBMITS: > + COVERAGE_ADD(drop_action_too_many_resubmit, delta); > + break; > + case OVS_DROP_REASON_STACK_TOO_DEEP: > + COVERAGE_ADD(drop_action_stack_too_deep, delta); > + break; > + case OVS_DROP_REASON_NO_RECIRCULATION_CONTEXT: > + COVERAGE_ADD(drop_action_no_recirculation_context, delta); > + break; > + case OVS_DROP_REASON_RECIRCULATION_CONFLICT: > + COVERAGE_ADD(drop_action_recirculation_conflict, delta); > + break; > + case OVS_DROP_REASON_TOO_MANY_MPLS_LABELS: > + COVERAGE_ADD(drop_action_too_many_mpls_labels, delta); > + break; > + case OVS_DROP_REASON_INVALID_TUNNEL_METADATA: > + COVERAGE_ADD(drop_action_invalid_tunnel_metadata, delta); > + break; > + case OVS_DROP_REASON_UNSUPPORTED_PACKET_TYPE: > + COVERAGE_ADD(drop_action_unsupported_packet_type, delta); > + break; > + case OVS_DROP_REASON_CONGESTION: > + COVERAGE_ADD(drop_action_congestion, delta); > + break; > + case OVS_DROP_REASON_FORWARDING_DISABLED: > + COVERAGE_ADD(drop_action_forwarding_disabled, delta); > + break; > + case OVS_DROP_REASON_MAX: > + default: > + VLOG_ERR("Invalid Drop reason type:%d",drop_reason); > + } > +} > + > +static void > dp_execute_cb(void *aux_, struct dp_packet_batch *packets_, > const struct nlattr *a, bool should_steal) > OVS_NO_THREAD_SAFETY_ANALYSIS > @@ -6860,6 +6936,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: > @@ -6901,6 +6978,8 @@ dp_execute_cb(void *aux_, struct dp_packet_batch > *packets_, > dp_packet_batch_add(&p->output_pkts, packet); > } > return; > + } else { > + COVERAGE_ADD(dp_invalid_port_drop, packets_->count); > } > break; > > @@ -6910,10 +6989,13 @@ 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(dp_tunnel_push_error_drop, packets_->count); > break; > } > dp_packet_batch_apply_cutlen(packets_); > - push_tnl_action(pmd, a, packets_); > + if (push_tnl_action(pmd, a, packets_)) { > + COVERAGE_ADD(dp_tunnel_push_error_drop, packets_->count); > + } > return; > > case OVS_ACTION_ATTR_TUNNEL_POP: > @@ -6933,7 +7015,12 @@ 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(dp_tunnel_pop_error_drop, packet_dropped); > + } > if (dp_packet_batch_is_empty(packets_)) { > return; > } > @@ -6947,7 +7034,11 @@ dp_execute_cb(void *aux_, struct dp_packet_batch > *packets_, > dp_netdev_recirculate(pmd, packets_); > (*depth)--; > return; > + } else { > + COVERAGE_ADD(dp_invalid_tnl_port_drop, packets_->count); > } > + } else { > + COVERAGE_ADD(dp_recirc_error_drop, packets_->count); > } > break; > > @@ -6991,6 +7082,8 @@ dp_execute_cb(void *aux_, struct dp_packet_batch > *packets_, > fat_rwlock_unlock(&dp->upcall_rwlock); > > return; > + } else { > + COVERAGE_ADD(dp_lock_error_drop, packets_->count); > } > break; > > @@ -7013,6 +7106,8 @@ dp_execute_cb(void *aux_, struct dp_packet_batch > *packets_, > (*depth)--; > > return; > + } else { > + COVERAGE_ADD(dp_recirc_error_drop, packets_->count); > } > > VLOG_WARN("Packet dropped. Max recirculation depth exceeded."); > @@ -7167,6 +7262,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(); > } > @@ -7183,7 +7279,8 @@ dp_netdev_execute_actions(struct dp_netdev_pmd_thread > *pmd, > struct dp_netdev_execute_aux aux = { pmd, flow }; > > odp_execute_actions(&aux, packets, should_steal, actions, > - actions_len, dp_execute_cb); > + actions_len, dp_execute_cb, > + dp_update_drop_action_counter_cb); > } > > struct dp_netdev_ct_dump { > diff --git a/lib/dpif.c b/lib/dpif.c > index e35f111..21f9f54 100644 > --- a/lib/dpif.c > +++ b/lib/dpif.c > @@ -1273,6 +1273,7 @@ dpif_execute_helper_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_UNSPEC: > case __OVS_ACTION_ATTR_MAX: > OVS_NOT_REACHED(); > @@ -1295,7 +1296,7 @@ dpif_execute_with_help(struct dpif *dpif, struct > dpif_execute *execute) > > dp_packet_batch_init_packet(&pb, execute->packet); > odp_execute_actions(&aux, &pb, false, execute->actions, > - execute->actions_len, dpif_execute_helper_cb); > + execute->actions_len, dpif_execute_helper_cb, NULL); > return aux.error; > } > > @@ -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, > @@ -1976,3 +1983,4 @@ dpif_meter_del(struct dpif *dpif, ofproto_meter_id > meter_id, > } > return error; > } > + > 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/netdev-dpdk.c b/lib/netdev-dpdk.c > index 320422b..0c3bc9c 100644 > --- a/lib/netdev-dpdk.c > +++ b/lib/netdev-dpdk.c > @@ -2395,6 +2395,10 @@ netdev_dpdk_send__(struct netdev_dpdk *dev, int qid, > bool concurrent_txq) > { > if (OVS_UNLIKELY(!(dev->flags & NETDEV_UP))) { > + int batch_cnt = dp_packet_batch_size(batch); > + rte_spinlock_lock(&dev->stats_lock); > + dev->stats.tx_dropped += batch_cnt; > + rte_spinlock_unlock(&dev->stats_lock); > dp_packet_delete_batch(batch, true); > return; > } > diff --git a/lib/odp-execute.c b/lib/odp-execute.c > index 3b6890e..c0db93f 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" > @@ -37,6 +38,10 @@ > #include "csum.h" > #include "conntrack.h" > > +COVERAGE_DEFINE(dp_sample_error_drop); > +COVERAGE_DEFINE(dp_nsh_decap_error_drop); > + > + > /* Masked copy of an ethernet address. 'src' is already properly masked. */ > static void > ether_addr_copy_masked(struct eth_addr *dst, const struct eth_addr src, > @@ -575,7 +580,9 @@ odp_execute_masked_set_action(struct dp_packet *packet, > static void > odp_execute_sample(void *dp, struct dp_packet *packet, bool steal, > const struct nlattr *action, > - odp_execute_cb dp_execute_action) > + odp_execute_cb dp_execute_action, > + odp_update_drop_action_counter_cb > + dp_update_drop_action_counter) > { > const struct nlattr *subactions = NULL; > const struct nlattr *a; > @@ -589,6 +596,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; > @@ -616,13 +624,16 @@ odp_execute_sample(void *dp, struct dp_packet *packet, > bool steal, > } > dp_packet_batch_init_packet(&pb, packet); > odp_execute_actions(dp, &pb, true, nl_attr_get(subactions), > - nl_attr_get_size(subactions), dp_execute_action); > + nl_attr_get_size(subactions), dp_execute_action, > + dp_update_drop_action_counter); > } > > static void > odp_execute_clone(void *dp, struct dp_packet_batch *batch, bool steal, > const struct nlattr *actions, > - odp_execute_cb dp_execute_action) > + odp_execute_cb dp_execute_action, > + odp_update_drop_action_counter_cb > + dp_update_drop_action_counter) > { > if (!steal) { > /* The 'actions' may modify the packet, but the modification > @@ -634,11 +645,12 @@ odp_execute_clone(void *dp, struct dp_packet_batch > *batch, bool steal, > dp_packet_batch_clone(&clone_pkt_batch, batch); > dp_packet_batch_reset_cutlen(batch); > odp_execute_actions(dp, &clone_pkt_batch, true, nl_attr_get(actions), > - nl_attr_get_size(actions), dp_execute_action); > - } > - else { > + nl_attr_get_size(actions), dp_execute_action, > + dp_update_drop_action_counter); > + } else { > odp_execute_actions(dp, batch, true, nl_attr_get(actions), > - nl_attr_get_size(actions), dp_execute_action); > + nl_attr_get_size(actions), dp_execute_action, > + dp_update_drop_action_counter); > } > } > > @@ -673,6 +685,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: > @@ -699,12 +712,15 @@ requires_datapath_assistance(const struct nlattr *a) > void > odp_execute_actions(void *dp, struct dp_packet_batch *batch, bool steal, > const struct nlattr *actions, size_t actions_len, > - odp_execute_cb dp_execute_action) > + odp_execute_cb dp_execute_action, > + odp_update_drop_action_counter_cb > + dp_update_drop_action_counter) > { > struct dp_packet *packet; > const struct nlattr *a; > unsigned int left; > > + > NL_ATTR_FOR_EACH_UNSAFE (a, left, actions, actions_len) { > int type = nl_attr_type(a); > bool last_action = (left <= NLA_ALIGN(a->nla_len)); > @@ -822,7 +838,8 @@ odp_execute_actions(void *dp, struct dp_packet_batch > *batch, bool steal, > case OVS_ACTION_ATTR_SAMPLE: > DP_PACKET_BATCH_FOR_EACH (i, packet, batch) { > odp_execute_sample(dp, packet, steal && last_action, a, > - dp_execute_action); > + dp_execute_action, > + dp_update_drop_action_counter); > } > > if (last_action) { > @@ -845,7 +862,8 @@ odp_execute_actions(void *dp, struct dp_packet_batch > *batch, bool steal, > > case OVS_ACTION_ATTR_CLONE: > odp_execute_clone(dp, batch, steal && last_action, a, > - dp_execute_action); > + dp_execute_action, > + dp_update_drop_action_counter); > if (last_action) { > /* We do not need to free the packets. odp_execute_clone() > has > * stolen them. */ > @@ -889,6 +907,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); > } > } > @@ -900,6 +919,17 @@ odp_execute_actions(void *dp, struct dp_packet_batch > *batch, bool steal, > } > break; > > + case OVS_ACTION_ATTR_DROP: { > + const struct ovs_action_drop *drop_action = nl_attr_get(a); > + enum ovs_drop_reason drop_reason = drop_action->drop_reason; > + if ((drop_reason < OVS_DROP_REASON_MAX) && > + dp_update_drop_action_counter) { > + 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-execute.h b/lib/odp-execute.h > index a3578a5..a84ecbb 100644 > --- a/lib/odp-execute.h > +++ b/lib/odp-execute.h > @@ -22,6 +22,8 @@ > #include <stddef.h> > #include <stdint.h> > #include "openvswitch/types.h" > +#include "ovs-atomic.h" > +#include "dpif.h" > > struct nlattr; > struct dp_packet; > @@ -31,6 +33,10 @@ struct dp_packet_batch; > typedef void (*odp_execute_cb)(void *dp, struct dp_packet_batch *batch, > const struct nlattr *action, bool > should_steal); > > +typedef void (*odp_update_drop_action_counter_cb) ( > + enum ovs_drop_reason drop_reason, > + int delta); > + > /* Actions that need to be executed in the context of a datapath are handed > * to 'dp_execute_action', if non-NULL. Currently this is called only for > * actions OVS_ACTION_ATTR_OUTPUT and OVS_ACTION_ATTR_USERSPACE so > @@ -38,5 +44,7 @@ typedef void (*odp_execute_cb)(void *dp, struct > dp_packet_batch *batch, > void odp_execute_actions(void *dp, struct dp_packet_batch *batch, > bool steal, > const struct nlattr *actions, size_t actions_len, > - odp_execute_cb dp_execute_action); > + odp_execute_cb dp_execute_action, > + odp_update_drop_action_counter_cb > + dp_update_drop_action_counter_cb); > #endif > diff --git a/lib/odp-util.c b/lib/odp-util.c > index 0491bed..9754fd5 100644 > --- a/lib/odp-util.c > +++ b/lib/odp-util.c > @@ -131,6 +131,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(struct ovs_action_drop); > > case OVS_ACTION_ATTR_UNSPEC: > case __OVS_ACTION_ATTR_MAX: > @@ -345,6 +346,49 @@ format_nsh_key_mask(struct ds *ds, const struct > ovs_key_nsh *key, > } > } > > +static const char * > +dropreason_str(enum ovs_drop_reason reason) > +{ > + switch (reason) { > + case OVS_DROP_REASON_OF_PIPELINE: > + return "pipeline-drop"; > + case OVS_DROP_REASON_BRIDGE_NOT_FOUND: > + return "bridge not found"; > + case OVS_DROP_REASON_RECURSION_TOO_DEEP: > + return "recursion too deep"; > + case OVS_DROP_REASON_TOO_MANY_RESUBMITS: > + return "too many resubmits"; > + case OVS_DROP_REASON_STACK_TOO_DEEP: > + return "stack too deep"; > + case OVS_DROP_REASON_NO_RECIRCULATION_CONTEXT: > + return "no recirculation context"; > + case OVS_DROP_REASON_RECIRCULATION_CONFLICT: > + return "recirculation conflict"; > + case OVS_DROP_REASON_TOO_MANY_MPLS_LABELS: > + return "too many mpls labels"; > + case OVS_DROP_REASON_INVALID_TUNNEL_METADATA: > + return "invalid tunnel metadata"; > + case OVS_DROP_REASON_UNSUPPORTED_PACKET_TYPE: > + return "unsupported packet type"; > + case OVS_DROP_REASON_CONGESTION: > + return "ecn mismatch at tunnel decapsulation"; > + case OVS_DROP_REASON_FORWARDING_DISABLED: > + return "forwarding disabled (stp/rstp)"; > + case OVS_DROP_REASON_MAX: > + default: > + return "unknown reason"; > + } > + return "unknown reason"; > +} > + > +static void > +format_odp_drop_action(struct ds *ds, > + const struct ovs_action_drop *drop_action) > +{ > + ds_put_format(ds, "drop:%s", > + dropreason_str(drop_action->drop_reason)); > +} > + > static void > format_odp_push_nsh_action(struct ds *ds, > const struct nsh_hdr *nsh_hdr) > @@ -1181,6 +1225,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: > + format_odp_drop_action(ds, nl_attr_get(a)); > + break; > case OVS_ACTION_ATTR_UNSPEC: > case __OVS_ACTION_ATTR_MAX: > default: > @@ -2427,8 +2474,13 @@ odp_actions_from_string(const char *s, const struct > simap *port_names, > struct ofpbuf *actions) > { > size_t old_size; > + struct ovs_action_drop drop_action; > > - if (!strcasecmp(s, "drop")) { > + if ((!strcasecmp(s, "drop") || > + !strcasecmp(s, "drop:pipeline-drop"))) { > + drop_action.drop_reason = OVS_DROP_REASON_OF_PIPELINE; > + 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 4029806..1d23a5a 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 7da3175..69ed7b8 100644 > --- a/ofproto/ofproto-dpif-sflow.c > +++ b/ofproto/ofproto-dpif-sflow.c > @@ -1222,6 +1222,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-upcall.c b/ofproto/ofproto-dpif-upcall.c > index dc30824..b1ce2ec 100644 > --- a/ofproto/ofproto-dpif-upcall.c > +++ b/ofproto/ofproto-dpif-upcall.c > @@ -1154,7 +1154,7 @@ upcall_receive(struct upcall *upcall, const struct > dpif_backer *backer, > return 0; > } > > -static void > +static enum xlate_error > upcall_xlate(struct udpif *udpif, struct upcall *upcall, > struct ofpbuf *odp_actions, struct flow_wildcards *wc) > { > @@ -1244,6 +1244,7 @@ upcall_xlate(struct udpif *udpif, struct upcall *upcall, > if (upcall->type == MISS_UPCALL) { > upcall->ukey = ukey_create_from_upcall(upcall, wc); > } > + return xerr; > } > > static void > diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c > index 839fddd..32c4edf 100644 > --- a/ofproto/ofproto-dpif-xlate.c > +++ b/ofproto/ofproto-dpif-xlate.c > @@ -444,10 +444,46 @@ 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"; > + > } > return "Unknown error"; > } > > +enum ovs_drop_reason xlate_error_to_drop_reason(enum xlate_error error) > +{ > + switch (error) { > + case XLATE_OK: > + return OVS_DROP_REASON_OF_PIPELINE; > + case XLATE_BRIDGE_NOT_FOUND: > + return OVS_DROP_REASON_BRIDGE_NOT_FOUND; > + case XLATE_RECURSION_TOO_DEEP: > + return OVS_DROP_REASON_RECURSION_TOO_DEEP; > + case XLATE_TOO_MANY_RESUBMITS: > + return OVS_DROP_REASON_TOO_MANY_RESUBMITS; > + case XLATE_STACK_TOO_DEEP: > + return OVS_DROP_REASON_STACK_TOO_DEEP; > + case XLATE_NO_RECIRCULATION_CONTEXT: > + return OVS_DROP_REASON_NO_RECIRCULATION_CONTEXT; > + case XLATE_RECIRCULATION_CONFLICT: > + return OVS_DROP_REASON_RECIRCULATION_CONFLICT; > + case XLATE_TOO_MANY_MPLS_LABELS: > + return OVS_DROP_REASON_TOO_MANY_MPLS_LABELS; > + case XLATE_INVALID_TUNNEL_METADATA: > + return OVS_DROP_REASON_INVALID_TUNNEL_METADATA; > + case XLATE_UNSUPPORTED_PACKET_TYPE: > + return OVS_DROP_REASON_UNSUPPORTED_PACKET_TYPE; > + case XLATE_CONGESTION_DROP: > + return OVS_DROP_REASON_CONGESTION; > + case XLATE_FORWARDING_DISABLED: > + return OVS_DROP_REASON_MAX; > + } > + return OVS_DROP_REASON_OF_PIPELINE; > +} > + > static void xlate_action_set(struct xlate_ctx *ctx); > static void xlate_commit_actions(struct xlate_ctx *ctx); > > @@ -5921,6 +5957,17 @@ put_ct_label(const struct flow *flow, struct ofpbuf > *odp_actions, > } > > static void > +put_drop_action(struct ofpbuf *odp_actions, enum xlate_error error) > +{ > + struct ovs_action_drop drop_action; > + > + drop_action.drop_reason = xlate_error_to_drop_reason(error); > + nl_msg_put_unspec(odp_actions, OVS_ACTION_ATTR_DROP, > + &drop_action, sizeof drop_action); > + > +} > + > +static void > put_ct_helper(struct xlate_ctx *ctx, > struct ofpbuf *odp_actions, struct ofpact_conntrack *ofc) > { > @@ -7383,6 +7430,10 @@ xlate_actions(struct xlate_in *xin, struct xlate_out > *xout) > } > size_t sample_actions_len = ctx.odp_actions->size; > > + if (!tnl_process_ecn(flow)) { > + ctx.error = XLATE_CONGESTION_DROP; > + } > + > if (tnl_process_ecn(flow) > && (!in_port || may_receive(in_port, &ctx))) { > const struct ofpact *ofpacts; > @@ -7415,6 +7466,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) { > @@ -7522,6 +7574,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..bb3f9ff 100644 > --- a/ofproto/ofproto-dpif-xlate.h > +++ b/ofproto/ofproto-dpif-xlate.h > @@ -216,12 +216,16 @@ enum xlate_error { > XLATE_TOO_MANY_MPLS_LABELS, > XLATE_INVALID_TUNNEL_METADATA, > XLATE_UNSUPPORTED_PACKET_TYPE, > + XLATE_CONGESTION_DROP, > + XLATE_FORWARDING_DISABLED, > }; > > const char *xlate_strerror(enum xlate_error error); > > enum xlate_error xlate_actions(struct xlate_in *, struct xlate_out *); > > +enum ovs_drop_reason xlate_error_to_drop_reason(enum xlate_error error); > + > void xlate_in_init(struct xlate_in *, struct ofproto_dpif *, ovs_version_t, > const struct flow *, ofp_port_t in_port, struct rule_dpif > *, > uint16_t tcp_flags, const struct dp_packet *packet, > diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c > index 14fe6fc..609226a 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); > @@ -5776,6 +5784,7 @@ ofproto_unixctl_dpif_set_dp_features(struct > unixctl_conn *conn, > ds_destroy(&ds); > } > > + > static void > ofproto_unixctl_init(void) > { > @@ -5809,7 +5818,7 @@ ofproto_unixctl_init(void) > unixctl_command_register("dpif/set-dp-features", "bridge", 1, 3 , > ofproto_unixctl_dpif_set_dp_features, NULL); > } > - > > + > static odp_port_t > ofp_port_to_odp_port(const struct ofproto_dpif *ofproto, ofp_port_t ofp_port) > { > diff --git a/ofproto/ofproto-dpif.h b/ofproto/ofproto-dpif.h > index 1a404c8..9162ba0 100644 > --- a/ofproto/ofproto-dpif.h > +++ b/ofproto/ofproto-dpif.h > @@ -106,6 +106,7 @@ struct rule_dpif *rule_dpif_lookup_from_table(struct > ofproto_dpif *, > bool honor_table_miss, > struct xlate_cache *); > > + > void rule_dpif_credit_stats(struct rule_dpif *, > const struct dpif_flow_stats *); > > @@ -192,7 +193,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 +365,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..22b4722 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/bundle.at b/tests/bundle.at > index 0a4eadc..33fe249 100644 > --- a/tests/bundle.at > +++ b/tests/bundle.at > @@ -241,7 +241,7 @@ AT_CHECK([tail -1 stdout], [0], > AT_CHECK([ovs-ofctl mod-port br0 p2 down]) > AT_CHECK([ovs-appctl ofproto/trace br0 > 'in_port=LOCAL,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:06'], [0], > [stdout]) > AT_CHECK([tail -1 stdout], [0], > - [Datapath actions: drop > + [Datapath actions: drop:pipeline-drop > ]) > AT_CHECK([ovs-ofctl mod-port br0 p1 up]) > AT_CHECK([ovs-appctl ofproto/trace br0 > 'in_port=LOCAL,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:06'], [0], > [stdout]) > diff --git a/tests/classifier.at b/tests/classifier.at > index 86f872d..a7378a7 100644 > --- a/tests/classifier.at > +++ b/tests/classifier.at > @@ -50,12 +50,12 @@ Datapath actions: 1 > AT_CHECK([ovs-appctl ofproto/trace br0 > 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=11.1.2.15,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=80'], > [0], [stdout]) > AT_CHECK([tail -2 stdout], [0], > [Megaflow: recirc_id=0,eth,ip,in_port=1,nw_dst=11.0.0.0/8,nw_frag=no > -Datapath actions: drop > +Datapath actions: drop:pipeline-drop > ]) > AT_CHECK([ovs-appctl ofproto/trace br0 > 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=10.1.2.15,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=80'], > [0], [stdout]) > AT_CHECK([tail -2 stdout], [0], > [Megaflow: > recirc_id=0,eth,tcp,in_port=1,nw_dst=10.1.2.15,nw_frag=no,tp_dst=80 > -Datapath actions: drop > +Datapath actions: drop:pipeline-drop > ]) > AT_CHECK([ovs-appctl ofproto/trace br0 > 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=10.1.2.15,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=79'], > [0], [stdout]) > AT_CHECK([tail -2 stdout], [0], > @@ -88,7 +88,7 @@ AT_CHECK([ovs-ofctl add-flows br0 flows.txt]) > AT_CHECK([ovs-appctl ofproto/trace br0 > 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=80'], > [0], [stdout]) > AT_CHECK([tail -2 stdout], [0], > [Megaflow: recirc_id=0,eth,tcp,in_port=1,nw_dst=192.168.0.0/16,nw_frag=no > -Datapath actions: drop > +Datapath actions: drop:pipeline-drop > ]) > > AT_CHECK([ovs-vsctl set Flow_Table t0 prefixes=ipv6_label], [0]) > @@ -103,7 +103,7 @@ AT_CHECK([ovs-vsctl set Flow_Table t0 prefixes=nw_dst], > [0]) > AT_CHECK([ovs-appctl ofproto/trace br0 > 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=80'], > [0], [stdout]) > AT_CHECK([tail -2 stdout], [0], > [Megaflow: recirc_id=0,eth,tcp,in_port=1,nw_dst=192.168.0.0/16,nw_frag=no > -Datapath actions: drop > +Datapath actions: drop:pipeline-drop > ]) > AT_CHECK([ovs-appctl ofproto/trace br0 > 'in_port=2,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=80'], > [0], [stdout]) > AT_CHECK([tail -2 stdout], [0], > @@ -113,7 +113,7 @@ Datapath actions: 1 > AT_CHECK([ovs-appctl ofproto/trace br0 > 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=10.1.2.15,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=80'], > [0], [stdout]) > AT_CHECK([tail -2 stdout], [0], > [Megaflow: > recirc_id=0,eth,tcp,in_port=1,nw_dst=10.1.2.15,nw_frag=no,tp_dst=80 > -Datapath actions: drop > +Datapath actions: drop:pipeline-drop > ]) > AT_CHECK([ovs-appctl ofproto/trace br0 > 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=10.1.2.15,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=79'], > [0], [stdout]) > AT_CHECK([tail -2 stdout], [0], > diff --git a/tests/dpif-netdev.at b/tests/dpif-netdev.at > index 6915d43..08349f6 100644 > --- a/tests/dpif-netdev.at > +++ b/tests/dpif-netdev.at > @@ -1,4 +1,4 @@ > -AT_BANNER([dpif-netdev]) > +T_BANNER([dpif-netdev]) > > m4_divert_push([PREPARE_TESTS]) > [ > @@ -281,6 +281,7 @@ type=drop rate=1 burst_size=2 > ]) > > ovs-appctl time/warp 5000 > +sleep 10 > AT_CHECK([ovs-appctl netdev-dummy/receive p7 > 'in_port(7),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' > --len 60]) > AT_CHECK([ovs-appctl netdev-dummy/receive p7 > 'in_port(7),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' > --len 60]) > AT_CHECK([ovs-appctl netdev-dummy/receive p7 > 'in_port(7),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' > --len 60]) > @@ -291,7 +292,7 @@ AT_CHECK([ovs-appctl netdev-dummy/receive p8 > 'in_port(8),packet_type(ns=0,id=0), > AT_CHECK([ovs-appctl netdev-dummy/receive p8 > 'in_port(8),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.3,dst=10.0.0.4,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' > --len 60]) > AT_CHECK([ovs-appctl netdev-dummy/receive p8 > 'in_port(8),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.3,dst=10.0.0.4,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' > --len 60]) > AT_CHECK([ovs-appctl netdev-dummy/receive p8 > 'in_port(8),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.3,dst=10.0.0.4,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' > --len 60]) > -sleep 1 # wait for forwarders process packets > +# wait for forwarders process packets > > # Meter 1 is measuring packets, allowing one packet per second with > # bursts of one packet, so 4 out of 5 packets should hit the drop > @@ -320,7 +321,8 @@ AT_CHECK([ovs-appctl netdev-dummy/receive p8 > 'in_port(8),packet_type(ns=0,id=0), > AT_CHECK([ovs-appctl netdev-dummy/receive p8 > 'in_port(8),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.3,dst=10.0.0.4,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' > --len 60]) > AT_CHECK([ovs-appctl netdev-dummy/receive p8 > 'in_port(8),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.3,dst=10.0.0.4,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' > --len 60]) > AT_CHECK([ovs-appctl netdev-dummy/receive p8 > 'in_port(8),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.3,dst=10.0.0.4,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' > --len 60]) > -sleep 1 # wait for forwarders process packets > + > +sleep 10 # wait for forwarders process packets > > # Meter 1 is measuring packets, allowing one packet per second with > # bursts of one packet, so all 5 of the new packets should hit the drop > @@ -337,6 +339,15 @@ 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 > +sleep 10 > + > +AT_CHECK([ > +ovs-appctl coverage/show | grep "dp_meter_drop" | 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..be8b8ae > --- /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 > 1e2ce92a669e3a6dd2099cab0800450000548a53400040011addc0a80a0ac0a80a1e08006f200a4d0001fc509a58000000002715020000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637 > + ovs-appctl netdev-dummy/receive p1 > 1e2ce92a669e3a6dd2099cab0800450000548a53400040011addc0a80a0ac0a80a1e08006f200a4d0001fc509a58000000002715020000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637 > + ovs-appctl netdev-dummy/receive p1 > 1e2ce92a669e3a6dd2099cab0800450000548a53400040011addc0a80a0ac0a80a1e08006f200a4d0001fc509a58000000002715020000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637 > +], [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(frag=no), > packets:2, bytes:196, used:0.0, actions:drop:pipeline-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 > 1e2ce92a669e3a6dd2099cab0800450000548a53400040011addc0a80a0ac0a80a1e08006f200a4d0001fc509a58000000002715020000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637 > +], [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 > 1e2ce92a669e3a6dd2099cab0800450000548a53400040011addc0a80a0ac0a80a1e08006f200a4d0001fc509a58000000002715020000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637 > +], [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 > 1e2ce92a669e3a6dd2099cab0800450000548a53400040011addc0a80a0ac0a80a1e08006f200a4d0001fc509a58000000002715020000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637 > +], [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..298aa9a 100644 > --- a/tests/ofproto-dpif.at > +++ b/tests/ofproto-dpif.at > @@ -3496,51 +3496,51 @@ dnl Each of these specifies an in_port by number, a > VLAN VID (or "none"), > dnl a VLAN PCP (used if the VID isn't "none") and the expected set of > datapath > dnl actions. > for tuple in \ > - "100 none 0 drop" \ > - "100 0 0 drop" \ > - "100 0 1 drop" \ > + "100 none 0 drop:pipeline-drop" \ > + "100 0 0 drop:pipeline-drop" \ > + "100 0 1 drop:pipeline-drop" \ > "100 10 0 1,5,6,7,8,pop_vlan,2,9" \ > "100 10 1 1,5,6,7,8,pop_vlan,2,9" \ > "100 11 0 5,7" \ > "100 11 1 5,7" \ > "100 12 0 1,5,6,pop_vlan,3,4,7,8,11,12" \ > "100 12 1 1,5,6,pop_vlan,4,7,11,push_vlan(vid=0,pcp=1),3,8,12" \ > - "1 none 0 drop" \ > - "1 0 0 drop" \ > - "1 0 1 drop" \ > + "1 none 0 drop:pipeline-drop" \ > + "1 0 0 drop:pipeline-drop" \ > + "1 0 1 drop:pipeline-drop" \ > "1 10 0 5,6,7,8,100,pop_vlan,2,9" \ > "1 10 1 5,6,7,8,100,pop_vlan,2,9" \ > - "1 11 0 drop" \ > - "1 11 1 drop" \ > + "1 11 0 drop:pipeline-drop" \ > + "1 11 1 drop:pipeline-drop" \ > "1 12 0 5,6,100,pop_vlan,3,4,7,8,11,12" \ > "1 12 1 5,6,100,pop_vlan,4,7,11,push_vlan(vid=0,pcp=1),3,8,12" \ > "2 none 0 9,push_vlan(vid=10,pcp=0),1,5,6,7,8,100" \ > "2 0 0 pop_vlan,9,push_vlan(vid=10,pcp=0),1,5,6,7,8,100" \ > "2 0 1 pop_vlan,9,push_vlan(vid=10,pcp=1),1,5,6,7,8,100" \ > - "2 10 0 drop" \ > - "2 10 1 drop" \ > - "2 11 0 drop" \ > - "2 11 1 drop" \ > - "2 12 0 drop" \ > - "2 12 1 drop" \ > + "2 10 0 drop:pipeline-drop" \ > + "2 10 1 drop:pipeline-drop" \ > + "2 11 0 drop:pipeline-drop" \ > + "2 11 1 drop:pipeline-drop" \ > + "2 12 0 drop:pipeline-drop" \ > + "2 12 1 drop:pipeline-drop" \ > "3 none 0 4,7,8,11,12,push_vlan(vid=12,pcp=0),1,5,6,100" \ > "3 0 0 pop_vlan,4,7,8,11,12,push_vlan(vid=12,pcp=0),1,5,6,100" \ > "3 0 1 8,12,pop_vlan,4,7,11,push_vlan(vid=12,pcp=1),1,5,6,100" \ > - "3 10 0 drop" \ > - "3 10 1 drop" \ > - "3 11 0 drop" \ > - "3 11 1 drop" \ > - "3 12 0 drop" \ > - "3 12 1 drop" \ > + "3 10 0 drop:pipeline-drop" \ > + "3 10 1 drop:pipeline-drop" \ > + "3 11 0 drop:pipeline-drop" \ > + "3 11 1 drop:pipeline-drop" \ > + "3 12 0 drop:pipeline-drop" \ > + "3 12 1 drop:pipeline-drop" \ > "4 none 0 3,7,8,11,12,push_vlan(vid=12,pcp=0),1,5,6,100" \ > "4 0 0 pop_vlan,3,7,8,11,12,push_vlan(vid=12,pcp=0),1,5,6,100" \ > "4 0 1 3,8,12,pop_vlan,7,11,push_vlan(vid=12,pcp=1),1,5,6,100" \ > - "4 10 0 drop" \ > - "4 10 1 drop" \ > - "4 11 0 drop" \ > - "4 11 1 drop" \ > - "4 12 0 drop" \ > - "4 12 1 drop" \ > + "4 10 0 drop:pipeline-drop" \ > + "4 10 1 drop:pipeline-drop" \ > + "4 11 0 drop:pipeline-drop" \ > + "4 11 1 drop:pipeline-drop" \ > + "4 12 0 drop:pipeline-drop" \ > + "4 12 1 drop:pipeline-drop" \ > "5 none 0 2,9,push_vlan(vid=10,pcp=0),1,6,7,8,100" \ > "5 0 0 pop_vlan,2,9,push_vlan(vid=10,pcp=0),1,6,7,8,100" \ > "5 0 1 pop_vlan,2,9,push_vlan(vid=10,pcp=1),1,6,7,8,100" \ > @@ -3555,8 +3555,8 @@ for tuple in \ > "6 0 1 pop_vlan,2,9,push_vlan(vid=10,pcp=1),1,5,7,8,100" \ > "6 10 0 1,5,7,8,100,pop_vlan,2,9" \ > "6 10 1 1,5,7,8,100,pop_vlan,2,9" \ > - "6 11 0 drop" \ > - "6 11 1 drop" \ > + "6 11 0 drop:pipeline-drop" \ > + "6 11 1 drop:pipeline-drop" \ > "6 12 0 1,5,100,pop_vlan,3,4,7,8,11,12" \ > "6 12 1 1,5,100,pop_vlan,4,7,11,push_vlan(vid=0,pcp=1),3,8,12" \ > "7 none 0 3,4,8,11,12,push_vlan(vid=12,pcp=0),1,5,6,100" \ > @@ -3573,16 +3573,16 @@ for tuple in \ > "8 0 1 3,12,pop_vlan,4,7,11,push_vlan(vid=12,pcp=1),1,5,6,100" \ > "8 10 0 1,5,6,7,100,pop_vlan,2,9" \ > "8 10 1 1,5,6,7,100,pop_vlan,2,9" \ > - "8 11 0 drop" \ > - "8 11 1 drop" \ > + "8 11 0 drop:pipeline-drop" \ > + "8 11 1 drop:pipeline-drop" \ > "8 12 0 1,5,6,100,pop_vlan,3,4,7,11,12" \ > "8 12 1 1,5,6,100,pop_vlan,4,7,11,push_vlan(vid=0,pcp=1),3,12" \ > "9 none 0 2,push_vlan(vid=10,pcp=0),1,5,6,7,8,100" \ > "9 10 0 10,push_vlan(vid=10,pcp=0),1,5,6,7,8,100" \ > "9 11 0 push_vlan(vid=10,pcp=0),1,5,6,7,8,100" \ > - "10 none 0 drop" \ > - "10 0 0 drop" \ > - "10 11 0 drop" \ > + "10 none 0 drop:pipeline-drop" \ > + "10 0 0 drop:pipeline-drop" \ > + "10 11 0 drop:pipeline-drop" \ > "10 12 0 9,push_vlan(vid=10,pcp=0),1,5,6,7,8,100" \ > "11 10 0 7,8,12,push_vlan(vid=12,pcp=0),1,5,6,100" \ > "11 10 1 7,8,12,push_vlan(vid=12,pcp=0),1,5,6,100" > @@ -4322,11 +4322,11 @@ no_flow="$base_flow,frag=no),tcp(src=12345,dst=80)" > first_flow="$base_flow,frag=first),tcp(src=12345,dst=80)" > later_flow="$base_flow,frag=later)" > > - # mode no first later > + # mode no first later > for tuple in \ > - 'normal 1 5 6' \ > - 'drop 1 drop drop' \ > - 'nx-match 1 2 6' > + 'normal 1 5 6' \ > + 'drop 1 drop:pipeline-drop drop:pipeline-drop' \ > + 'nx-match 1 2 6' > do > set $tuple > mode=$1 > @@ -4404,8 +4404,8 @@ done > AT_CHECK([ovs-appctl dpctl/dump-flows], [0], [dnl > flow-dump from non-dpdk interfaces: > > recirc_id(0),in_port(90),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(proto=6,frag=no),tcp(dst=80), > packets:0, bytes:0, used:never, actions:set(tcp(dst=81)),1 > -recirc_id(0),in_port(90),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=first), > packets:0, bytes:0, used:never, actions:drop > -recirc_id(0),in_port(90),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=later), > packets:0, bytes:0, used:never, actions:drop > +recirc_id(0),in_port(90),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=first), > packets:0, bytes:0, used:never, actions:drop:pipeline-drop > +recirc_id(0),in_port(90),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=later), > packets:0, bytes:0, used:never, actions:drop:pipeline-drop > ]) > > mode=nx-match > @@ -5751,7 +5751,7 @@ bridge("br0") > > Final flow: <cleared> > Megaflow: <cleared> > -Datapath actions: drop > +Datapath actions: drop:pipeline-drop > ]) > > dnl Now, try again without megaflows: > @@ -5772,7 +5772,7 @@ bridge("br0") > > Final flow: <cleared> > Megaflow: <cleared> > -Datapath actions: drop > +Datapath actions: drop:pipeline-drop > ]) > > OVS_VSWITCHD_STOP > @@ -7066,7 +7066,7 @@ for i in `seq 1 3`; do > done > AT_CHECK([ovs-appctl dpctl/dump-flows | sed 's/.*\(packets:\)/\1/' | sed > 's/used:[[0-9]].[[0-9]]*s/used:0.001s/'], [0], [dnl > flow-dump from non-dpdk interfaces: > -packets:2, bytes:68, used:0.001s, actions:drop > +packets:2, bytes:68, used:0.001s, actions:drop:pipeline-drop > ]) > > OVS_VSWITCHD_STOP(["/sending to collector failed/d"]) > @@ -7158,7 +7158,7 @@ for i in `seq 1 3`; do > done > AT_CHECK([ovs-appctl dpctl/dump-flows | sed 's/.*\(packets:\)/\1/' | sed > 's/used:[[0-9]].[[0-9]]*s/used:0.001s/'], [0], [dnl > flow-dump from non-dpdk interfaces: > -packets:2, bytes:68, used:0.001s, actions:drop > +packets:2, bytes:68, used:0.001s, actions:drop:pipeline-drop > ]) > > OVS_VSWITCHD_STOP(["/sending to collector failed/d > @@ -7832,21 +7832,21 @@ AT_CHECK([ovs-appctl netdev-dummy/receive p2 > 'in_port(2),eth(src=50:54:00:00:00: > AT_CHECK([ovs-appctl netdev-dummy/receive p3 > 'in_port(3),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)']) > ovs-appctl revalidator/wait > AT_CHECK([ovs-appctl dpif/dump-flows br0 | strip_ufid | strip_used | sort], > [0], [dnl > -recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=no), > packets:0, bytes:0, used:never, actions:drop > -recirc_id(0),in_port(2),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=no), > packets:0, bytes:0, used:never, actions:drop > +recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=no), > packets:0, bytes:0, used:never, actions:drop:pipeline-drop > +recirc_id(0),in_port(2),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=no), > packets:0, bytes:0, used:never, actions:drop:pipeline-drop > ]) > > AT_CHECK([ovs-appctl dpif/dump-flows br1 | strip_ufid | strip_used | sort], > [0], [dnl > -recirc_id(0),in_port(3),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=no), > packets:0, bytes:0, used:never, actions:drop > +recirc_id(0),in_port(3),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=no), > packets:0, bytes:0, used:never, actions:drop:pipeline-drop > ]) > > AT_CHECK([ovs-appctl dpif/dump-flows -m br0 | strip_ufid | strip_used | > sort], [0], [dnl > -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(p1),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:05/00:00:00:00:00:00,dst=50:54:00:00:00:07/00:00:00:00:00:00),eth_type(0x0800),ipv4(src=192.168.0.1/0.0.0.0,dst=192.168.0.2/0.0.0.0,proto=1/0,tos=0/0,ttl=64/0,frag=no),icmp(type=8/0,code=0/0), > packets:0, bytes:0, used:never, actions:drop > -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(p2),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:07/00:00:00:00:00:00,dst=50:54:00:00:00:05/00:00:00:00:00:00),eth_type(0x0800),ipv4(src=192.168.0.2/0.0.0.0,dst=192.168.0.1/0.0.0.0,proto=1/0,tos=0/0,ttl=64/0,frag=no),icmp(type=0/0,code=0/0), > packets:0, bytes:0, used:never, actions:drop > +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(p1),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:05/00:00:00:00:00:00,dst=50:54:00:00:00:07/00:00:00:00:00:00),eth_type(0x0800),ipv4(src=192.168.0.1/0.0.0.0,dst=192.168.0.2/0.0.0.0,proto=1/0,tos=0/0,ttl=64/0,frag=no),icmp(type=8/0,code=0/0), > packets:0, bytes:0, used:never, actions:drop:pipeline-drop > +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(p2),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:07/00:00:00:00:00:00,dst=50:54:00:00:00:05/00:00:00:00:00:00),eth_type(0x0800),ipv4(src=192.168.0.2/0.0.0.0,dst=192.168.0.1/0.0.0.0,proto=1/0,tos=0/0,ttl=64/0,frag=no),icmp(type=0/0,code=0/0), > packets:0, bytes:0, used:never, actions:drop:pipeline-drop > ]) > > AT_CHECK([ovs-appctl dpif/dump-flows -m br1 | strip_ufid | strip_used | > sort], [0], [dnl > -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(p3),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:00:0a/00:00:00:00:00:00),eth_type(0x0800),ipv4(src=10.0.0.2/0.0.0.0,dst=10.0.0.1/0.0.0.0,proto=1/0,tos=0/0,ttl=64/0,frag=no),icmp(type=8/0,code=0/0), > packets:0, bytes:0, used:never, actions:drop > +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(p3),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:00:0a/00:00:00:00:00:00),eth_type(0x0800),ipv4(src=10.0.0.2/0.0.0.0,dst=10.0.0.1/0.0.0.0,proto=1/0,tos=0/0,ttl=64/0,frag=no),icmp(type=8/0,code=0/0), > packets:0, bytes:0, used:never, actions:drop:pipeline-drop > ]) > > OVS_VSWITCHD_STOP > @@ -7869,7 +7869,7 @@ m4_define([OFPROTO_DPIF_GET_FLOW], > > UFID=`sed -n 's/\(ufid:[[-0-9a-fA-F]]*\).*/\1/p' stdout` > AT_CHECK([ovs-appctl dpctl/get-flow $UFID], [0], [dnl > -recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=no), > packets:0, bytes:0, used:never, actions:drop > +recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=no), > packets:0, bytes:0, used:never, actions:drop:pipeline-drop > ]) > > OVS_VSWITCHD_STOP > @@ -8617,11 +8617,11 @@ table=0 in_port=1,ip,nw_dst=10.0.0.3 actions=drop > sleep 1 > AT_CHECK([strip_ufid < ovs-vswitchd.log | filter_flow_install | > strip_used], [0], [dnl > > skb_priority(0),skb_mark(0),ct_state(-new-est-rel-rpl-inv-trk-snat-dnat),ct_zone(0),ct_mark(0),ct_label(0),recirc_id(0),dp_hash(0),in_port(1),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0), > actions:2 > -skb_priority(0),skb_mark(0),ct_state(-new-est-rel-rpl-inv-trk-snat-dnat),ct_zone(0),ct_mark(0),ct_label(0),recirc_id(0),dp_hash(0),in_port(1),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.4,dst=10.0.0.3,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0), > actions:drop > +skb_priority(0),skb_mark(0),ct_state(-new-est-rel-rpl-inv-trk-snat-dnat),ct_zone(0),ct_mark(0),ct_label(0),recirc_id(0),dp_hash(0),in_port(1),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.4,dst=10.0.0.3,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0), > actions:drop:pipeline-drop > ]) > AT_CHECK([strip_ufid < ovs-vswitchd.log | filter_flow_dump | grep > 'packets:3'], [0], [dnl > > skb_priority(0),skb_mark(0),ct_state(0/0xff),ct_zone(0),ct_mark(0),ct_label(0),recirc_id(0),dp_hash(0),in_port(1),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0), > packets:3, bytes:318, used:0.0s, actions:2 > -skb_priority(0),skb_mark(0),ct_state(0/0xff),ct_zone(0),ct_mark(0),ct_label(0),recirc_id(0),dp_hash(0),in_port(1),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.4,dst=10.0.0.3,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0), > packets:3, bytes:318, used:0.0s, actions:drop > +skb_priority(0),skb_mark(0),ct_state(0/0xff),ct_zone(0),ct_mark(0),ct_label(0),recirc_id(0),dp_hash(0),in_port(1),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.4,dst=10.0.0.3,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0), > packets:3, bytes:318, used:0.0s, actions:drop:pipeline-drop > ]) > OVS_VSWITCHD_STOP > AT_CLEANUP]) > @@ -9348,7 +9348,7 @@ for i in 1 2 3; do > done > > AT_CHECK([ovs-appctl dpif/dump-flows br0 | strip_ufid | strip_used | sort], > [0], [dnl > -recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x1234), packets:5, > bytes:70, used:0.0s, actions:drop > +recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x1234), packets:5, > bytes:70, used:0.0s, actions:drop:pipeline-drop > ]) > > # Add a flow that matches the non-presence of a vlan tag, and check > @@ -9377,16 +9377,16 @@ done > > AT_CHECK([ovs-appctl dpif/dump-flows br0 | strip_ufid | strip_used | sort], > [0], [dnl > recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x1234), packets:8, > bytes:112, used:0.0s, actions:100 > -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)), > packets:2, bytes:36, used:0.0s, actions:drop > +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)), > packets:2, bytes:36, used:0.0s, actions:drop:pipeline-drop > ]) > > # Check that the new flow matches the CFI bit, while both vid and 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:00: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:00:0a/00:00:00:00:00:00),eth_type(0x1234), > actions:drop:pipeline-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: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),vlan(vid=99,pcp=7/0x0),encap(eth_type(0x1234)), > actions:drop > +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:pipeline-drop > ]) > OVS_VSWITCHD_STOP > AT_CLEANUP > @@ -9711,7 +9711,7 @@ AT_CHECK([ovs-appctl netdev-dummy/receive p2 > 'in_port(2),eth(src=50:54:00:00:00: > > > AT_CHECK([cat ovs-vswitchd.log | strip_ufid | filter_flow_install], [0], [dnl > -ct_state(+new-est+trk),recirc_id(0x1),in_port(2),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=no), > actions:drop > +ct_state(+new-est+trk),recirc_id(0x1),in_port(2),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=no), > actions:drop:pipeline-drop > > ct_state(-new+est+trk),recirc_id(0x1),in_port(2),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(proto=17,frag=no), > actions:1 > > recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(proto=17,frag=no), > actions:ct(commit),2 > > recirc_id(0),in_port(2),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(proto=17,frag=no), > actions:ct,recirc(0x1) > @@ -10398,7 +10398,7 @@ AT_CHECK([ovs-ofctl add-flows br0 flows.txt]) > > AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=2,udp'], [0], [stdout]) > AT_CHECK([tail -1 stdout], [0], > - [Datapath actions: drop > + [Datapath actions: drop:pipeline-drop > ]) > > AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,udp'], [0], [stdout]) > @@ -10490,7 +10490,7 @@ AT_CHECK([ovs-appctl netdev-dummy/receive p1 > 'recirc_id(0),in_port(1),eth_type(0 > ovs-appctl time/warp 5000 > > AT_CHECK([strip_ufid < ovs-vswitchd.log | filter_flow_install | strip_used], > [0], [dnl > -recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(proto=17,frag=later), > actions:drop > +recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(proto=17,frag=later), > actions:drop:pipeline-drop > ]) > > dnl Change the flow table. This will trigger revalidation of all the flows. > diff --git a/tests/ovs-ofctl.at b/tests/ovs-ofctl.at > index 6ae3470..cd19d41 100644 > --- a/tests/ovs-ofctl.at > +++ b/tests/ovs-ofctl.at > @@ -2999,7 +2999,7 @@ AT_CHECK([tail -1 stdout], [0], > dnl Inbound web traffic with SYN bit without ACK or RST bits > AT_CHECK([ovs-appctl ofproto/trace ovs-dummy > 'in_port(2),eth(src=50:54:00:00:00:07,dst=50:54:00:00:00:05),eth_type(0x0800),ipv4(src=192.168.0.2,dst=192.168.0.1,proto=6,tos=0,ttl=64,frag=no),tcp(src=80,dst=8),tcp_flags(0xfeb)'], > [0], [stdout]) > AT_CHECK([tail -1 stdout], [0], > - [Datapath actions: drop > + [Datapath actions: drop:pipeline-drop > ]) > > OVS_VSWITCHD_STOP > diff --git a/tests/packet-type-aware.at b/tests/packet-type-aware.at > index bfb47b4..7c1b551 100644 > --- a/tests/packet-type-aware.at > +++ b/tests/packet-type-aware.at > @@ -505,7 +505,7 @@ AT_CHECK([ > ovs-appctl dpctl/dump-flows --names dummy@ovs-dummy | strip_used | grep > -v ipv6 | sort > ], [0], [flow-dump from non-dpdk interfaces: > > recirc_id(0),in_port(n3),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(dst=192.168.10.20,tos=0/0x3,frag=no), > packets:1, bytes:98, used:0.0s, > actions:pop_eth,clone(tnl_push(tnl_port(gre_sys),header(size=38,type=3,eth(dst=aa:55:00:00:00:02,src=aa:55:00:00:00:03,dl_type=0x0800),ipv4(src=30.0.0.3,dst=30.0.0.2,proto=47,tos=0,ttl=64,frag=0x4000),gre((flags=0x0,proto=0x800))),out_port(br-p3)),set(ipv4(src=20.0.0.3,dst=20.0.0.2)),tnl_pop(gre_sys)) > -tunnel(src=20.0.0.3,dst=20.0.0.2,flags(-df-csum)),recirc_id(0),in_port(gre_sys),packet_type(ns=1,id=0x800),ipv4(dst=192.168.10.20,frag=no), > packets:1, bytes:84, used:0.0s, actions:drop > +tunnel(src=20.0.0.3,dst=20.0.0.2,flags(-df-csum)),recirc_id(0),in_port(gre_sys),packet_type(ns=1,id=0x800),ipv4(dst=192.168.10.20,frag=no), > packets:1, bytes:84, used:0.0s, actions:drop:pipeline-drop > ]) > > OVS_VSWITCHD_STOP(["/The Open vSwitch kernel module is probably not > loaded/d"]) > @@ -565,7 +565,14 @@ ovs-appctl time/warp 1000 > AT_CHECK([ > ovs-appctl dpctl/dump-flows | strip_used | grep -v ipv6 | sort > ], [0], [flow-dump from non-dpdk interfaces: > -recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=no), > packets:1, bytes:98, used:0.0s, actions:drop > +recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=no), > packets:1, bytes:98, used:0.0s, actions:drop:unsupported packet type > +]) > + > + > +AT_CHECK([ > +ovs-appctl coverage/show | grep "drop_action_unsupported_packet_type" | cut > -d':' -f2|sed 's/ //' > +], [0], [dnl > +2 > ]) > > # Encap(ethernet) on Ethernet frame -> should be droped > @@ -587,7 +594,7 @@ ovs-appctl time/warp 1000 > AT_CHECK([ > ovs-appctl dpctl/dump-flows | strip_used | grep -v ipv6 | sort > ], [0], [flow-dump from non-dpdk interfaces: > -recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=no), > packets:1, bytes:98, used:0.0s, actions:drop > +recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=no), > packets:1, bytes:98, used:0.0s, actions:drop:pipeline-drop > ]) > > # Encap(ethernet) on VLAN tagged Ethernet frame -> should be droped > @@ -609,7 +616,7 @@ ovs-appctl time/warp 1000 > AT_CHECK([ > ovs-appctl dpctl/dump-flows | strip_used | grep -v ipv6 | sort > ], [0], [flow-dump from non-dpdk interfaces: > -recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=no), > packets:1, bytes:98, used:0.0s, actions:drop > +recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=no), > packets:1, bytes:98, used:0.0s, actions:drop:unsupported packet type > ]) > > OVS_VSWITCHD_STOP > @@ -770,7 +777,7 @@ ovs-appctl time/warp 1000 > AT_CHECK([ > ovs-appctl dpctl/dump-flows --names dummy@ovs-dummy | strip_used | grep > -v ipv6 | sort > ], [0], [flow-dump from non-dpdk interfaces: > -recirc_id(0),in_port(n0),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=no), > packets:1, bytes:98, used:0.0s, actions:drop > +recirc_id(0),in_port(n0),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=no), > packets:1, bytes:98, used:0.0s, actions:drop:pipeline-drop > ]) > > AT_CHECK([ > 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..385c114 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 > 'aa55aa550000001b213cab6408004500007079464000402fba600101025c0101025820000800000001c845000054ba200000400184861e0000011e00000200004227e75400030af3195500000000f265010000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637']) > + > +ovs-appctl time/warp 1200 > + > + > +AT_CHECK([ > +ovs-appctl coverage/show | grep "dp_tunnel_pop_error_drop" | cut -d':' > -f2|sed 's/ //' > +], [0], [dnl > +1 > +]) > + > + > +AT_CHECK([ovs-appctl netdev-dummy/receive p0 > 'aa55aa550000001b213cab6408004503007079464000402fba600101025c0101025820000800000001c845000054ba200000400184861e0000011e00000200004227e75400030af3195500000000f265010000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637']) > +ovs-appctl time/warp 1200 > + > +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 > 'aa55aa550000001b213cab6408004500007e79464000402fba550101025c0101025820000800000001c8fe71d883724fbeb6f4e1494a080045000054ba200000400184861e0000011e00000200004227e75400030af3195500000000f265010000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637']) > > @@ -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 > @@ -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..3646c06 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),eth(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], > +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 > +Datapath actions: drop:ecn mismatch at tunnel decapsulation > +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,15 @@ 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 > 'aa55aa550001f8bc124434b6080045000054ba20000040018486010103580101037001004227e75400030af3195500000000f265010000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637']) > +sleep 2 > + > +AT_CHECK([ > +ovs-appctl coverage/show | grep "dp_invalid_port_drop" | cut -d':' -f2|sed > 's/ //' > +], [0], [dnl > +1 > +]) > OVS_VSWITCHD_STOP > AT_CLEANUP > > @@ -364,7 +375,7 @@ Datapath actions: 4,3,5 > > AT_CHECK([ovs-appctl ofproto/trace ovs-dummy > 'tunnel(tun_id=0x0,src=1.1.1.1,dst=2.2.2.2,ttl=64,flags(key)),in_port(1),eth(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 -1 stdout], [0], [dnl > -Datapath actions: drop > +Datapath actions: drop:pipeline-drop > ]) > > OVS_VSWITCHD_STOP > @@ -571,7 +582,7 @@ dnl receive packet from ERSPAN port with wrong v1 metadata > AT_CHECK([ovs-appctl ofproto/trace ovs-dummy > 'recirc_id(0),tunnel(tun_id=0x1,src=1.1.1.1,dst=2.2.2.2,ttl=64,erspan(ver=1,idx=0xabcd),flags(df|key)),in_port(3),skb_mark(0),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(frag=no)'], > [0], [stdout]) > AT_CHECK([tail -2 stdout], [0], > [Megaflow: > recirc_id=0,eth,ip,tun_id=0x1,tun_src=1.1.1.1,tun_dst=2.2.2.2,tun_tos=0,tun_erspan_ver=1,tun_erspan_idx=0xabcd,tun_flags=+df-csum+key,in_port=3,nw_frag=no > -Datapath actions: drop > +Datapath actions: drop:pipeline-drop > ]) > > dnl receive packet from ERSPAN port with v2 metadata > @@ -585,7 +596,7 @@ dnl receive packet from ERSPAN port with wrong v2 metadata > AT_CHECK([ovs-appctl ofproto/trace ovs-dummy > 'recirc_id(0),tunnel(tun_id=0x2,src=1.1.1.2,dst=2.2.2.2,ttl=64,erspan(ver=2,dir=0,hwid=0x17),flags(df|key)),in_port(3),skb_mark(0),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(frag=no)'], > [0], [stdout]) > AT_CHECK([tail -2 stdout], [0], > [Megaflow: > recirc_id=0,eth,ip,tun_id=0x2,tun_src=1.1.1.2,tun_dst=2.2.2.2,tun_tos=0,tun_erspan_ver=2,tun_erspan_dir=0,tun_erspan_hwid=0x1,tun_flags=+df-csum+key,in_port=4,nw_frag=no > -Datapath actions: drop > +Datapath actions: drop:pipeline-drop > ]) > > dnl test wildcard mask: recevie all v2 regardless of its metadata > -- > 1.9.1 > _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev