diff --git a/SOURCES/openvswitch-2.17.0.patch b/SOURCES/openvswitch-2.17.0.patch
index 4a6c88b..d98f087 100644
--- a/SOURCES/openvswitch-2.17.0.patch
+++ b/SOURCES/openvswitch-2.17.0.patch
@@ -59040,7 +59040,7 @@ index 78a54c715d..109940ad2a 100644
              oftrace_node_destroy(node);
          }
 diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c
-index 57f94df544..308876d38c 100644
+index 57f94df544..53b47073ad 100644
 --- a/ofproto/ofproto-dpif-upcall.c
 +++ b/ofproto/ofproto-dpif-upcall.c
 @@ -47,17 +47,20 @@
@@ -59130,7 +59130,46 @@ index 57f94df544..308876d38c 100644
              ovsrcu_postpone(ukey_delete__, old_ukey);
              transition_ukey(old_ukey, UKEY_DELETED);
              transition_ukey(new_ukey, UKEY_VISIBLE);
-@@ -2321,6 +2346,13 @@ revalidate_ukey(struct udpif *udpif, struct udpif_key *ukey,
+@@ -2074,10 +2099,12 @@ ukey_delete(struct umap *umap, struct udpif_key *ukey)
+ }
+ 
+ static bool
+-should_revalidate(const struct udpif *udpif, uint64_t packets,
+-                  long long int used)
++should_revalidate(const struct udpif *udpif, const struct udpif_key *ukey,
++                  uint64_t packets)
++    OVS_REQUIRES(ukey->mutex)
+ {
+     long long int metric, now, duration;
++    long long int used = ukey->stats.used;
+ 
+     if (!used) {
+         /* Always revalidate the first time a flow is dumped. */
+@@ -2104,8 +2131,12 @@ should_revalidate(const struct udpif *udpif, uint64_t packets,
+     duration = now - used;
+     metric = duration / packets;
+ 
+-    if (metric < 1000 / ofproto_min_revalidate_pps) {
+-        /* The flow is receiving more than min-revalidate-pps, so keep it. */
++    if (metric < 1000 / ofproto_min_revalidate_pps ||
++        (ukey->offloaded && duration < ofproto_offloaded_stats_delay)) {
++        /* The flow is receiving more than min-revalidate-pps, so keep it.
++         * Or it's a hardware offloaded flow that might take up to X seconds
++         * to update its statistics. Until we are sure the statistics had a
++         * chance to be updated, also keep it. */
+         return true;
+     }
+     return false;
+@@ -2303,7 +2334,7 @@ static enum reval_result
+ revalidate_ukey(struct udpif *udpif, struct udpif_key *ukey,
+                 const struct dpif_flow_stats *stats,
+                 struct ofpbuf *odp_actions, uint64_t reval_seq,
+-                struct recirc_refs *recircs, bool offloaded)
++                struct recirc_refs *recircs)
+     OVS_REQUIRES(ukey->mutex)
+ {
+     bool need_revalidate = ukey->reval_seq != reval_seq;
+@@ -2321,8 +2352,15 @@ revalidate_ukey(struct udpif *udpif, struct udpif_key *ukey,
                      ? stats->n_bytes - ukey->stats.n_bytes
                      : 0);
  
@@ -59142,9 +59181,21 @@ index 57f94df544..308876d38c 100644
 +    }
 +
      if (need_revalidate) {
-         if (should_revalidate(udpif, push.n_packets, ukey->stats.used)) {
+-        if (should_revalidate(udpif, push.n_packets, ukey->stats.used)) {
++        if (should_revalidate(udpif, ukey, push.n_packets)) {
              if (!ukey->xcache) {
-@@ -2434,6 +2466,15 @@ push_dp_ops(struct udpif *udpif, struct ukey_op *ops, size_t n_ops)
+                 ukey->xcache = xlate_cache_new();
+             } else {
+@@ -2338,7 +2376,7 @@ revalidate_ukey(struct udpif *udpif, struct udpif_key *ukey,
+ 
+     /* Stats for deleted flows will be attributed upon flow deletion. Skip. */
+     if (result != UKEY_DELETE) {
+-        xlate_push_stats(ukey->xcache, &push, offloaded);
++        xlate_push_stats(ukey->xcache, &push, ukey->offloaded);
+         ukey->stats = *stats;
+         ukey->reval_seq = reval_seq;
+     }
+@@ -2434,6 +2472,15 @@ push_dp_ops(struct udpif *udpif, struct ukey_op *ops, size_t n_ops)
              push->tcp_flags = stats->tcp_flags | op->ukey->stats.tcp_flags;
              push->n_packets = stats->n_packets - op->ukey->stats.n_packets;
              push->n_bytes = stats->n_bytes - op->ukey->stats.n_bytes;
@@ -59160,7 +59211,7 @@ index 57f94df544..308876d38c 100644
              ovs_mutex_unlock(&op->ukey->mutex);
          } else {
              push = stats;
-@@ -2738,6 +2779,22 @@ revalidate(struct revalidator *revalidator)
+@@ -2738,6 +2785,22 @@ revalidate(struct revalidator *revalidator)
                  continue;
              }
  
@@ -59183,16 +59234,29 @@ index 57f94df544..308876d38c 100644
              already_dumped = ukey->dump_seq == dump_seq;
              if (already_dumped) {
                  /* The flow has already been handled during this flow dump
-@@ -2853,7 +2910,7 @@ revalidator_sweep__(struct revalidator *revalidator, bool purge)
+@@ -2769,8 +2832,7 @@ revalidate(struct revalidator *revalidator)
+                 result = UKEY_DELETE;
+             } else {
+                 result = revalidate_ukey(udpif, ukey, &stats, &odp_actions,
+-                                         reval_seq, &recircs,
+-                                         f->attrs.offloaded);
++                                         reval_seq, &recircs);
+             }
+             ukey->dump_seq = dump_seq;
+ 
+@@ -2853,9 +2915,9 @@ revalidator_sweep__(struct revalidator *revalidator, bool purge)
                  } else {
                      struct dpif_flow_stats stats;
                      COVERAGE_INC(revalidate_missed_dp_flow);
 -                    memset(&stats, 0, sizeof stats);
 +                    memcpy(&stats, &ukey->stats, sizeof stats);
                      result = revalidate_ukey(udpif, ukey, &stats, &odp_actions,
-                                              reval_seq, &recircs, false);
+-                                             reval_seq, &recircs, false);
++                                             reval_seq, &recircs);
                  }
-@@ -3099,6 +3156,31 @@ upcall_unixctl_purge(struct unixctl_conn *conn, int argc OVS_UNUSED,
+                 if (result != UKEY_KEEP) {
+                     /* Clears 'recircs' if filled by revalidate_ukey(). */
+@@ -3099,6 +3161,31 @@ upcall_unixctl_purge(struct unixctl_conn *conn, int argc OVS_UNUSED,
      unixctl_command_reply(conn, "");
  }
  
@@ -60015,7 +60079,7 @@ index 8143dd965f..b3e575bcd0 100644
  
  static void
 diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h
-index 14b909973d..47e96e62e1 100644
+index 14b909973d..e64ca5b805 100644
 --- a/ofproto/ofproto-provider.h
 +++ b/ofproto/ofproto-provider.h
 @@ -143,6 +143,8 @@ struct ofproto {
@@ -60027,11 +60091,31 @@ index 14b909973d..47e96e62e1 100644
  };
  
  void ofproto_init_tables(struct ofproto *, int n_tables);
+@@ -536,6 +538,11 @@ extern unsigned ofproto_max_revalidator;
+  * duration exceeds half of max-revalidator config variable. */
+ extern unsigned ofproto_min_revalidate_pps;
+ 
++/* Worst case delay (in ms) it might take before statistics of offloaded flows
++ * are updated. Offloaded flows younger than this delay will always be
++ * revalidated regardless of ofproto_min_revalidate_pps. */
++extern unsigned ofproto_offloaded_stats_delay;
++
+ /* Number of upcall handler and revalidator threads. Only affects the
+  * ofproto-dpif implementation. */
+ extern uint32_t n_handlers, n_revalidators;
 diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
-index 56aeac7209..933f7de2dc 100644
+index 56aeac7209..8569ce94cb 100644
 --- a/ofproto/ofproto.c
 +++ b/ofproto/ofproto.c
-@@ -549,6 +549,7 @@ ofproto_create(const char *datapath_name, const char *datapath_type,
+@@ -310,6 +310,7 @@ unsigned ofproto_flow_limit = OFPROTO_FLOW_LIMIT_DEFAULT;
+ unsigned ofproto_max_idle = OFPROTO_MAX_IDLE_DEFAULT;
+ unsigned ofproto_max_revalidator = OFPROTO_MAX_REVALIDATOR_DEFAULT;
+ unsigned ofproto_min_revalidate_pps = OFPROTO_MIN_REVALIDATE_PPS_DEFAULT;
++unsigned ofproto_offloaded_stats_delay = OFPROTO_OFFLOADED_STATS_DELAY;
+ 
+ uint32_t n_handlers, n_revalidators;
+ 
+@@ -549,6 +550,7 @@ ofproto_create(const char *datapath_name, const char *datapath_type,
  
      ovs_mutex_init(&ofproto->vl_mff_map.mutex);
      cmap_init(&ofproto->vl_mff_map.cmap);
@@ -60039,7 +60123,23 @@ index 56aeac7209..933f7de2dc 100644
  
      error = ofproto->ofproto_class->construct(ofproto);
      if (error) {
-@@ -1695,9 +1696,33 @@ ofproto_destroy__(struct ofproto *ofproto)
+@@ -725,6 +727,15 @@ ofproto_set_min_revalidate_pps(unsigned min_revalidate_pps)
+     ofproto_min_revalidate_pps = min_revalidate_pps ? min_revalidate_pps : 1;
+ }
+ 
++/* Set worst case delay (in ms) it might take before statistics of offloaded
++ * flows are updated. Offloaded flows younger than this delay will always be
++ * revalidated regardless of ofproto_min_revalidate_pps. */
++void
++ofproto_set_offloaded_stats_delay(unsigned offloaded_stats_delay)
++{
++    ofproto_offloaded_stats_delay = offloaded_stats_delay;
++}
++
+ /* If forward_bpdu is true, the NORMAL action will forward frames with
+  * reserved (e.g. STP) destination Ethernet addresses. if forward_bpdu is false,
+  * the NORMAL action will drop these frames. */
+@@ -1695,9 +1706,33 @@ ofproto_destroy__(struct ofproto *ofproto)
      ofproto->ofproto_class->dealloc(ofproto);
  }
  
@@ -60076,7 +60176,7 @@ index 56aeac7209..933f7de2dc 100644
  static void
  ofproto_destroy_defer__(struct ofproto *ofproto)
      OVS_EXCLUDED(ofproto_mutex)
-@@ -1705,11 +1730,31 @@ ofproto_destroy_defer__(struct ofproto *ofproto)
+@@ -1705,11 +1740,31 @@ ofproto_destroy_defer__(struct ofproto *ofproto)
      ovsrcu_postpone(ofproto_destroy__, ofproto);
  }
  
@@ -60109,7 +60209,7 @@ index 56aeac7209..933f7de2dc 100644
      struct ofport_usage *usage;
  
      if (!p) {
-@@ -1717,7 +1762,7 @@ ofproto_destroy(struct ofproto *p, bool del)
+@@ -1717,7 +1772,7 @@ ofproto_destroy(struct ofproto *p, bool del)
      }
  
      ofproto_flush__(p, del);
@@ -60118,7 +60218,7 @@ index 56aeac7209..933f7de2dc 100644
          ofport_destroy(ofport, del);
      }
  
-@@ -1736,8 +1781,7 @@ ofproto_destroy(struct ofproto *p, bool del)
+@@ -1736,8 +1791,7 @@ ofproto_destroy(struct ofproto *p, bool del)
      p->connmgr = NULL;
      ovs_mutex_unlock(&ofproto_mutex);
  
@@ -60128,7 +60228,7 @@ index 56aeac7209..933f7de2dc 100644
  }
  
  /* Destroys the datapath with the respective 'name' and 'type'.  With the Linux
-@@ -2782,7 +2826,7 @@ init_ports(struct ofproto *p)
+@@ -2782,7 +2836,7 @@ init_ports(struct ofproto *p)
  {
      struct ofproto_port_dump dump;
      struct ofproto_port ofproto_port;
@@ -60137,7 +60237,7 @@ index 56aeac7209..933f7de2dc 100644
  
      OFPROTO_PORT_FOR_EACH (&ofproto_port, &dump, p) {
          const char *name = ofproto_port.name;
-@@ -2813,7 +2857,7 @@ init_ports(struct ofproto *p)
+@@ -2813,7 +2867,7 @@ init_ports(struct ofproto *p)
          }
      }
  
@@ -60146,7 +60246,7 @@ index 56aeac7209..933f7de2dc 100644
          struct iface_hint *iface_hint = node->data;
  
          if (!strcmp(iface_hint->br_name, p->name)) {
-@@ -2929,6 +2973,9 @@ ofproto_rule_destroy__(struct rule *rule)
+@@ -2929,6 +2983,9 @@ ofproto_rule_destroy__(struct rule *rule)
      cls_rule_destroy(CONST_CAST(struct cls_rule *, &rule->cr));
      rule_actions_destroy(rule_get_actions(rule));
      ovs_mutex_destroy(&rule->mutex);
@@ -60156,7 +60256,7 @@ index 56aeac7209..933f7de2dc 100644
      rule->ofproto->ofproto_class->rule_dealloc(rule);
  }
  
-@@ -3069,6 +3116,9 @@ group_destroy_cb(struct ofgroup *group)
+@@ -3069,6 +3126,9 @@ group_destroy_cb(struct ofgroup *group)
                                                  &group->props));
      ofputil_bucket_list_destroy(CONST_CAST(struct ovs_list *,
                                             &group->buckets));
@@ -60166,7 +60266,7 @@ index 56aeac7209..933f7de2dc 100644
      group->ofproto->ofproto_class->group_dealloc(group);
  }
  
-@@ -5271,10 +5321,15 @@ ofproto_rule_create(struct ofproto *ofproto, struct cls_rule *cr,
+@@ -5271,10 +5331,15 @@ ofproto_rule_create(struct ofproto *ofproto, struct cls_rule *cr,
      struct rule *rule;
      enum ofperr error;
  
@@ -60182,7 +60282,7 @@ index 56aeac7209..933f7de2dc 100644
          VLOG_WARN_RL(&rl, "%s: failed to allocate a rule.", ofproto->name);
          return OFPERR_OFPFMFC_UNKNOWN;
      }
-@@ -6797,9 +6852,9 @@ static void
+@@ -6797,9 +6862,9 @@ static void
  meter_delete_all(struct ofproto *ofproto)
      OVS_REQUIRES(ofproto_mutex)
  {
@@ -60194,7 +60294,7 @@ index 56aeac7209..933f7de2dc 100644
          hmap_remove(&ofproto->meters, &meter->node);
          meter_destroy(ofproto, meter);
      }
-@@ -7339,8 +7394,13 @@ init_group(struct ofproto *ofproto, const struct ofputil_group_mod *gm,
+@@ -7339,8 +7404,13 @@ init_group(struct ofproto *ofproto, const struct ofputil_group_mod *gm,
          return OFPERR_OFPGMFC_BAD_TYPE;
      }
  
@@ -60208,7 +60308,7 @@ index 56aeac7209..933f7de2dc 100644
          VLOG_WARN_RL(&rl, "%s: failed to allocate group", ofproto->name);
          return OFPERR_OFPGMFC_OUT_OF_GROUPS;
      }
-@@ -7377,6 +7437,7 @@ init_group(struct ofproto *ofproto, const struct ofputil_group_mod *gm,
+@@ -7377,6 +7447,7 @@ init_group(struct ofproto *ofproto, const struct ofputil_group_mod *gm,
                                                      &(*ofgroup)->props));
          ofputil_bucket_list_destroy(CONST_CAST(struct ovs_list *,
                                                 &(*ofgroup)->buckets));
@@ -60216,7 +60316,7 @@ index 56aeac7209..933f7de2dc 100644
          ofproto->ofproto_class->group_dealloc(*ofgroup);
      }
      return error;
-@@ -8902,7 +8963,7 @@ eviction_group_hash_rule(struct rule *rule)
+@@ -8902,7 +8973,7 @@ eviction_group_hash_rule(struct rule *rule)
      hash = table->eviction_group_id_basis;
      miniflow_expand(rule->cr.match.flow, &flow);
      for (sf = table->eviction_fields;
@@ -60225,7 +60325,7 @@ index 56aeac7209..933f7de2dc 100644
           sf++)
      {
          if (mf_are_prereqs_ok(sf->field, &flow, NULL)) {
-@@ -9138,8 +9199,8 @@ oftable_configure_eviction(struct oftable *table, unsigned int eviction,
+@@ -9138,8 +9209,8 @@ oftable_configure_eviction(struct oftable *table, unsigned int eviction,
  
      /* Destroy existing eviction groups, then destroy and recreate data
       * structures to recover memory. */
@@ -60237,10 +60337,26 @@ index 56aeac7209..933f7de2dc 100644
      }
      hmap_destroy(&table->eviction_groups_by_id);
 diff --git a/ofproto/ofproto.h b/ofproto/ofproto.h
-index b0262da2df..4e15167ab7 100644
+index b0262da2df..fa7973ac72 100644
 --- a/ofproto/ofproto.h
 +++ b/ofproto/ofproto.h
-@@ -563,6 +563,10 @@ int ofproto_port_get_cfm_status(const struct ofproto *,
+@@ -311,6 +311,7 @@ int ofproto_port_dump_done(struct ofproto_port_dump *);
+ #define OFPROTO_MAX_IDLE_DEFAULT 10000 /* ms */
+ #define OFPROTO_MAX_REVALIDATOR_DEFAULT 500 /* ms */
+ #define OFPROTO_MIN_REVALIDATE_PPS_DEFAULT 5
++#define OFPROTO_OFFLOADED_STATS_DELAY 2000 /* ms */
+ 
+ const char *ofproto_port_open_type(const struct ofproto *,
+                                    const char *port_type);
+@@ -340,6 +341,7 @@ void ofproto_set_flow_limit(unsigned limit);
+ void ofproto_set_max_idle(unsigned max_idle);
+ void ofproto_set_max_revalidator(unsigned max_revalidator);
+ void ofproto_set_min_revalidate_pps(unsigned min_revalidate_pps);
++void ofproto_set_offloaded_stats_delay(unsigned offloaded_stats_delay);
+ void ofproto_set_forward_bpdu(struct ofproto *, bool forward_bpdu);
+ void ofproto_set_mac_table_config(struct ofproto *, unsigned idle_time,
+                                   size_t max_entries);
+@@ -563,6 +565,10 @@ int ofproto_port_get_cfm_status(const struct ofproto *,
  enum ofputil_table_miss ofproto_table_get_miss_config(const struct ofproto *,
                                                        uint8_t table_id);
  
@@ -70157,7 +70273,7 @@ index 37cc72d401..1032089fc2 100644
          if (fscset->bridge == br->br_cfg) {
              ovsrec_flow_sample_collector_set_delete(fscset);
 diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c
-index 5223aa8970..793bad1243 100644
+index 5223aa8970..81f073b1cf 100644
 --- a/vswitchd/bridge.c
 +++ b/vswitchd/bridge.c
 @@ -543,13 +543,13 @@ bridge_exit(bool delete_datapath)
@@ -70234,7 +70350,17 @@ index 5223aa8970..793bad1243 100644
      int sflow_bridge_number;
      size_t n_managers;
  
-@@ -875,7 +875,7 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg)
+@@ -832,6 +832,9 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg)
+     ofproto_set_min_revalidate_pps(
+         smap_get_uint(&ovs_cfg->other_config, "min-revalidate-pps",
+                      OFPROTO_MIN_REVALIDATE_PPS_DEFAULT));
++    ofproto_set_offloaded_stats_delay(
++        smap_get_uint(&ovs_cfg->other_config, "offloaded-stats-delay",
++                      OFPROTO_OFFLOADED_STATS_DELAY));
+     ofproto_set_vlan_limit(smap_get_int(&ovs_cfg->other_config, "vlan-limit",
+                                        LEGACY_MAX_VLAN_HEADERS));
+     ofproto_set_bundle_idle_timeout(smap_get_uint(&ovs_cfg->other_config,
+@@ -875,7 +878,7 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg)
       *     - Create ofprotos that are missing.
       *
       *     - Add ports that are missing. */
@@ -70243,7 +70369,7 @@ index 5223aa8970..793bad1243 100644
          if (!br->ofproto) {
              int error;
  
-@@ -1020,7 +1020,7 @@ bridge_delete_or_reconfigure_ports(struct bridge *br)
+@@ -1020,7 +1023,7 @@ bridge_delete_or_reconfigure_ports(struct bridge *br)
      struct ofproto_port_dump dump;
  
      struct sset ofproto_ports;
@@ -70252,7 +70378,7 @@ index 5223aa8970..793bad1243 100644
  
      /* List of "ofp_port"s to delete.  We make a list instead of deleting them
       * right away because ofproto implementations aren't necessarily able to
-@@ -1132,10 +1132,10 @@ bridge_delete_or_reconfigure_ports(struct bridge *br)
+@@ -1132,10 +1135,10 @@ bridge_delete_or_reconfigure_ports(struct bridge *br)
       *       device destroyed via "tunctl -d", a physical Ethernet device
       *       whose module was just unloaded via "rmmod", or a virtual NIC for a
       *       VM whose VM was just terminated. */
@@ -70266,7 +70392,7 @@ index 5223aa8970..793bad1243 100644
              if (!sset_contains(&ofproto_ports, iface->name)) {
                  iface_destroy__(iface);
              }
-@@ -1967,7 +1967,7 @@ port_is_bond_fake_iface(const struct port *port)
+@@ -1967,7 +1970,7 @@ port_is_bond_fake_iface(const struct port *port)
  static void
  add_del_bridges(const struct ovsrec_open_vswitch *cfg)
  {
@@ -70275,7 +70401,7 @@ index 5223aa8970..793bad1243 100644
      struct shash_node *node;
      struct shash new_br;
      size_t i;
-@@ -1993,7 +1993,7 @@ add_del_bridges(const struct ovsrec_open_vswitch *cfg)
+@@ -1993,7 +1996,7 @@ add_del_bridges(const struct ovsrec_open_vswitch *cfg)
  
      /* Get rid of deleted bridges or those whose types have changed.
       * Update 'cfg' of bridges that still exist. */
@@ -70284,7 +70410,7 @@ index 5223aa8970..793bad1243 100644
          br->cfg = shash_find_data(&new_br, br->name);
          if (!br->cfg || strcmp(br->type, ofproto_normalize_type(
                                     br->cfg->datapath_type))) {
-@@ -2660,6 +2660,7 @@ iface_refresh_stats(struct iface *iface)
+@@ -2660,6 +2663,7 @@ iface_refresh_stats(struct iface *iface)
      IFACE_STAT(tx_512_to_1023_packets,  "tx_512_to_1023_packets")   \
      IFACE_STAT(tx_1024_to_1522_packets, "tx_1024_to_1522_packets")  \
      IFACE_STAT(tx_1523_to_max_packets,  "tx_1523_to_max_packets")   \
@@ -70292,7 +70418,7 @@ index 5223aa8970..793bad1243 100644
      IFACE_STAT(tx_multicast_packets,    "tx_multicast_packets")     \
      IFACE_STAT(rx_broadcast_packets,    "rx_broadcast_packets")     \
      IFACE_STAT(tx_broadcast_packets,    "tx_broadcast_packets")     \
-@@ -3266,13 +3267,13 @@ bridge_run(void)
+@@ -3266,13 +3270,13 @@ bridge_run(void)
  
      if (ovsdb_idl_is_lock_contended(idl)) {
          static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
@@ -70308,7 +70434,7 @@ index 5223aa8970..793bad1243 100644
              bridge_destroy(br, false);
          }
          /* Since we will not be running system_stats_run() in this process
-@@ -3594,13 +3595,13 @@ static void
+@@ -3594,13 +3598,13 @@ static void
  bridge_destroy(struct bridge *br, bool del)
  {
      if (br) {
@@ -70326,7 +70452,7 @@ index 5223aa8970..793bad1243 100644
              mirror_destroy(mirror);
          }
  
-@@ -3746,11 +3747,11 @@ static void
+@@ -3746,11 +3750,11 @@ static void
  bridge_del_ports(struct bridge *br, const struct shash *wanted_ports)
  {
      struct shash_node *port_node;
@@ -70340,7 +70466,7 @@ index 5223aa8970..793bad1243 100644
          port->cfg = shash_find_data(wanted_ports, port->name);
          if (!port->cfg) {
              port_destroy(port);
-@@ -4211,7 +4212,7 @@ bridge_configure_aa(struct bridge *br)
+@@ -4211,7 +4215,7 @@ bridge_configure_aa(struct bridge *br)
      const struct ovsdb_datum *mc;
      struct ovsrec_autoattach *auto_attach = br->cfg->auto_attach;
      struct aa_settings aa_s;
@@ -70349,7 +70475,7 @@ index 5223aa8970..793bad1243 100644
      size_t i;
  
      if (!auto_attach) {
-@@ -4227,7 +4228,7 @@ bridge_configure_aa(struct bridge *br)
+@@ -4227,7 +4231,7 @@ bridge_configure_aa(struct bridge *br)
      mc = ovsrec_autoattach_get_mappings(auto_attach,
                                          OVSDB_TYPE_INTEGER,
                                          OVSDB_TYPE_INTEGER);
@@ -70358,7 +70484,7 @@ index 5223aa8970..793bad1243 100644
          union ovsdb_atom atom;
  
          atom.integer = m->isid;
-@@ -4341,12 +4342,12 @@ static void
+@@ -4341,12 +4345,12 @@ static void
  bridge_aa_refresh_queued(struct bridge *br)
  {
      struct ovs_list *list = xmalloc(sizeof *list);
@@ -70373,7 +70499,7 @@ index 5223aa8970..793bad1243 100644
          struct port *port;
  
          VLOG_INFO("ifname=%s, vlan=%u, oper=%u", node->port_name, node->vlan,
-@@ -4387,7 +4388,7 @@ port_create(struct bridge *br, const struct ovsrec_port *cfg)
+@@ -4387,7 +4391,7 @@ port_create(struct bridge *br, const struct ovsrec_port *cfg)
  static void
  port_del_ifaces(struct port *port)
  {
@@ -70382,7 +70508,7 @@ index 5223aa8970..793bad1243 100644
      struct sset new_ifaces;
      size_t i;
  
-@@ -4398,7 +4399,7 @@ port_del_ifaces(struct port *port)
+@@ -4398,7 +4402,7 @@ port_del_ifaces(struct port *port)
      }
  
      /* Get rid of deleted interfaces. */
@@ -70391,7 +70517,7 @@ index 5223aa8970..793bad1243 100644
          if (!sset_contains(&new_ifaces, iface->name)) {
              iface_destroy(iface);
          }
-@@ -4412,13 +4413,13 @@ port_destroy(struct port *port)
+@@ -4412,13 +4416,13 @@ port_destroy(struct port *port)
  {
      if (port) {
          struct bridge *br = port->bridge;
@@ -70407,7 +70533,7 @@ index 5223aa8970..793bad1243 100644
              iface_destroy__(iface);
          }
  
-@@ -5013,12 +5014,12 @@ bridge_configure_mirrors(struct bridge *br)
+@@ -5013,12 +5017,12 @@ bridge_configure_mirrors(struct bridge *br)
  {
      const struct ovsdb_datum *mc;
      unsigned long *flood_vlans;
@@ -70423,10 +70549,30 @@ index 5223aa8970..793bad1243 100644
  
          atom.uuid = m->uuid;
 diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml
-index 0c66326171..87d8f3e67a 100644
+index 0c66326171..0c8534f142 100644
 --- a/vswitchd/vswitch.xml
 +++ b/vswitchd/vswitch.xml
-@@ -2312,7 +2312,7 @@
+@@ -222,6 +222,19 @@
+         </p>
+       </column>
+ 
++      <column name="other_config" key="offloaded-stats-delay"
++              type='{"type": "integer", "minInteger": 0}'>
++        <p>
++          Set worst case delay (in ms) it might take before statistics of
++          offloaded flows are updated. Offloaded flows younger than this
++          delay will always be revalidated regardless of
++          <ref column="other_config" key="min-revalidate-pps"/>.
++        </p>
++        <p>
++          The default is 2000.
++        </p>
++      </column>
++
+       <column name="other_config" key="hw-offload"
+               type='{"type": "boolean"}'>
+         <p>
+@@ -2312,7 +2325,7 @@
            lowest port-id is elected as the root.
          </column>
  
diff --git a/SPECS/openvswitch2.17.spec b/SPECS/openvswitch2.17.spec
index 34683ca..c9d07cd 100644
--- a/SPECS/openvswitch2.17.spec
+++ b/SPECS/openvswitch2.17.spec
@@ -63,7 +63,7 @@ Summary: Open vSwitch
 Group: System Environment/Daemons daemon/database/utilities
 URL: http://www.openvswitch.org/
 Version: 2.17.0
-Release: 81%{?dist}
+Release: 82%{?dist}
 
 # Nearly all of openvswitch is ASL 2.0.  The bugtool is LGPLv2+, and the
 # lib/sflow*.[ch] files are SISSL
@@ -749,6 +749,12 @@ exit 0
 %endif
 
 %changelog
+* Wed Mar 15 2023 Open vSwitch CI <ovs-ci@redhat.com> - 2.17.0-82
+- Merging upstream branch-2.17 [RH git: bf382f68d4]
+    Commit list:
+    09e6e1de7a ofproto-dpif-upcall: Wait for valid hw flow stats before applying min-revalidate-pps.
+
+
 * Mon Mar 13 2023 Open vSwitch CI <ovs-ci@redhat.com> - 2.17.0-81
 - Merging upstream branch-2.17 [RH git: 04b7f28f9f]
     Commit list: