diff --git a/SOURCES/openvswitch-2.17.0.patch b/SOURCES/openvswitch-2.17.0.patch
index cdebc0b..e01ff54 100644
--- a/SOURCES/openvswitch-2.17.0.patch
+++ b/SOURCES/openvswitch-2.17.0.patch
@@ -52578,10 +52578,34 @@ index a024dc5e58..4bff7b017f 100644
              ovs_list_remove(&chassis->list);
              lldpd_chassis_cleanup(chassis, 1);
 diff --git a/lib/mac-learning.c b/lib/mac-learning.c
-index 3fcd7d9b77..a60794fb26 100644
+index 3fcd7d9b77..5932e2709d 100644
 --- a/lib/mac-learning.c
 +++ b/lib/mac-learning.c
-@@ -244,10 +244,10 @@ void
+@@ -176,12 +176,18 @@ get_lru(struct mac_learning *ml, struct mac_entry **e)
+     OVS_REQ_RDLOCK(ml->rwlock)
+ {
+     if (!ovs_list_is_empty(&ml->lrus)) {
+-        *e = mac_entry_from_lru_node(ml->lrus.next);
+-        return true;
+-    } else {
+-        *e = NULL;
+-        return false;
++        struct mac_entry *entry;
++
++        LIST_FOR_EACH (entry, lru_node, &ml->lrus) {
++            if (entry->expires != MAC_ENTRY_AGE_STATIC_ENTRY) {
++                *e = entry;
++                return true;
++            }
++        }
+     }
++
++    *e = NULL;
++    return false;
+ }
+ 
+ static unsigned int
+@@ -244,10 +250,10 @@ void
  mac_learning_unref(struct mac_learning *ml)
  {
      if (ml && ovs_refcount_unref(&ml->ref_cnt) == 1) {
@@ -52594,6 +52618,35 @@ index 3fcd7d9b77..a60794fb26 100644
              mac_learning_expire(ml, e);
          }
          hmap_destroy(&ml->table);
+@@ -618,25 +624,10 @@ mac_learning_expire(struct mac_learning *ml, struct mac_entry *e)
+ void
+ mac_learning_flush(struct mac_learning *ml)
+ {
+-    struct mac_entry *e, *first_static_mac = NULL;
+-
+-    while (get_lru(ml, &e) && (e != first_static_mac)) {
+-
+-        /* Static mac should not be evicted. */
+-        if (MAC_ENTRY_AGE_STATIC_ENTRY == e->expires) {
+-
+-            /* Make note of first static-mac encountered, so that this while
+-             * loop will break on visting this mac again via get_lru(). */
+-            if (!first_static_mac) {
+-                first_static_mac = e;
+-            }
++    struct mac_entry *e;
+ 
+-            /* Remove from lru head and append it to tail. */
+-            ovs_list_remove(&e->lru_node);
+-            ovs_list_push_back(&ml->lrus, &e->lru_node);
+-        } else {
+-            mac_learning_expire(ml, e);
+-        }
++    while (get_lru(ml, &e)) {
++        mac_learning_expire(ml, e);
+     }
+     hmap_shrink(&ml->table);
+ }
 diff --git a/lib/match.c b/lib/match.c
 index 2ad03e044e..0b9dc4278c 100644
 --- a/lib/match.c
@@ -52703,7 +52756,7 @@ index 482400d8d1..ca3f2431ea 100644
          count = umem_pool_count(&pool->umem_info->mpool);
          ovs_assert(count + pool->lost_in_rings <= NUM_FRAMES);
 diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c
-index b6b29c75e3..e28e397d7e 100644
+index b6b29c75e3..39a1fd388d 100644
 --- a/lib/netdev-dpdk.c
 +++ b/lib/netdev-dpdk.c
 @@ -622,9 +622,9 @@ dpdk_mp_full(const struct rte_mempool *mp) OVS_REQUIRES(dpdk_mp_mutex)
@@ -52919,7 +52972,7 @@ index b6b29c75e3..e28e397d7e 100644
 +        cnt = dpdk_copy_batch_to_mbuf(netdev, batch);
 +        stats->tx_failure_drops += pkt_cnt - cnt;
 +        pkt_cnt = cnt;
-     }
++    }
 +
 +    /* Drop oversized packets. */
 +    cnt = netdev_dpdk_filter_packet_len(dev, pkts, pkt_cnt);
@@ -52931,7 +52984,7 @@ index b6b29c75e3..e28e397d7e 100644
 +        cnt = netdev_dpdk_prep_hwol_batch(dev, pkts, pkt_cnt);
 +        stats->tx_invalid_hwol_drops += pkt_cnt - cnt;
 +        pkt_cnt = cnt;
-+    }
+     }
 +
 +    /* Apply Quality of Service policy. */
 +    cnt = netdev_dpdk_qos_run(dev, pkts, pkt_cnt, true);
@@ -53055,9 +53108,9 @@ index b6b29c75e3..e28e397d7e 100644
 -        dpdk_do_tx_copy(netdev, qid, batch);
 -        dp_packet_delete_batch(batch, true);
 -    } else {
-+    dropped = batch_cnt - cnt;
-+
-+    dropped += netdev_dpdk_eth_tx_burst(dev, qid, pkts, cnt);
++    dropped = netdev_dpdk_eth_tx_burst(dev, qid, pkts, cnt);
++    stats.tx_failure_drops += dropped;
++    dropped += batch_cnt - cnt;
 +    if (OVS_UNLIKELY(dropped)) {
          struct netdev_dpdk_sw_stats *sw_stats = dev->sw_stats;
 -        int dropped;
@@ -53128,7 +53181,7 @@ index b6b29c75e3..e28e397d7e 100644
          free(queue);
      }
 diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c
-index 620a451dec..1b9c2874ac 100644
+index 620a451dec..5aa8a8ca3c 100644
 --- a/lib/netdev-linux.c
 +++ b/lib/netdev-linux.c
 @@ -247,6 +247,14 @@ enum {
@@ -53167,7 +53220,26 @@ index 620a451dec..1b9c2874ac 100644
      nl_msg_end_nested(request, offset);
      nl_msg_end_nested(request, act_offset);
  }
-@@ -5331,11 +5342,11 @@ static void
+@@ -2970,12 +2981,18 @@ netdev_linux_set_qos(struct netdev *netdev_,
+         /* Delete existing qdisc. */
+         error = tc_del_qdisc(netdev_);
+         if (error) {
++            VLOG_WARN_RL(&rl, "%s: Failed to delete existing qdisc: %s",
++                         netdev_get_name(netdev_), ovs_strerror(error));
+             goto exit;
+         }
+         ovs_assert(netdev->tc == NULL);
+ 
+         /* Install new qdisc. */
+         error = new_ops->tc_install(netdev_, details);
++        if (error) {
++            VLOG_WARN_RL(&rl, "%s: Failed to install new qdisc: %s",
++                         netdev_get_name(netdev_), ovs_strerror(error));
++        }
+         ovs_assert((error == 0) == (netdev->tc != NULL));
+     }
+ 
+@@ -5331,11 +5348,11 @@ static void
  hfsc_tc_destroy(struct tc *tc)
  {
      struct hfsc *hfsc;
@@ -53181,7 +53253,24 @@ index 620a451dec..1b9c2874ac 100644
          hmap_remove(&hfsc->tc.queues, &hc->tc_queue.hmap_node);
          free(hc);
      }
-@@ -6295,7 +6306,14 @@ get_stats_via_netlink(const struct netdev *netdev_, struct netdev_stats *stats)
+@@ -5966,13 +5983,12 @@ tc_del_qdisc(struct netdev *netdev_)
+     if (!tcmsg) {
+         return ENODEV;
+     }
+-    tcmsg->tcm_handle = tc_make_handle(1, 0);
+     tcmsg->tcm_parent = TC_H_ROOT;
+ 
+     error = tc_transact(&request, NULL);
+-    if (error == EINVAL) {
+-        /* EINVAL probably means that the default qdisc was in use, in which
+-         * case we've accomplished our purpose. */
++    if (error == EINVAL || error == ENOENT) {
++        /* EINVAL or ENOENT probably means that the default qdisc was in use,
++         * in which case we've accomplished our purpose. */
+         error = 0;
+     }
+     if (!error && netdev->tc) {
+@@ -6295,7 +6311,14 @@ get_stats_via_netlink(const struct netdev *netdev_, struct netdev_stats *stats)
      if (ofpbuf_try_pull(reply, NLMSG_HDRLEN + sizeof(struct ifinfomsg))) {
          const struct nlattr *a = nl_attr_find(reply, 0, IFLA_STATS64);
          if (a && nl_attr_get_size(a) >= sizeof(struct rtnl_link_stats64)) {
@@ -53197,7 +53286,7 @@ index 620a451dec..1b9c2874ac 100644
              error = 0;
          } else {
              a = nl_attr_find(reply, 0, IFLA_STATS);
-@@ -6411,6 +6429,9 @@ netdev_linux_update_via_netlink(struct netdev_linux *netdev)
+@@ -6411,6 +6434,9 @@ netdev_linux_update_via_netlink(struct netdev_linux *netdev)
      if (netdev_linux_netnsid_is_remote(netdev)) {
          nl_msg_put_u32(&request, IFLA_IF_NETNSID, netdev->netnsid);
      }
@@ -53934,9 +54023,18 @@ index 8305f6c427..c797783782 100644
  
                  /* By default enable one tx and rx queue per netdev. */
 diff --git a/lib/odp-util.c b/lib/odp-util.c
-index 9a705cffa3..2d2a6893c6 100644
+index 9a705cffa3..3bbc9a1010 100644
 --- a/lib/odp-util.c
 +++ b/lib/odp-util.c
+@@ -1003,7 +1003,7 @@ format_odp_conntrack_action(struct ds *ds, const struct nlattr *attr)
+             ds_put_format(ds, "helper=%s,", helper);
+         }
+         if (timeout) {
+-            ds_put_format(ds, "timeout=%s", timeout);
++            ds_put_format(ds, "timeout=%s,", timeout);
+         }
+         if (nat) {
+             format_odp_ct_nat(ds, nat);
 @@ -3429,16 +3429,16 @@ format_eth(struct ds *ds, const char *name, const struct eth_addr key,
  
  static void
@@ -55646,7 +55744,7 @@ index fcaddf10ad..71039e24f1 100644
  
  /* Attempts to guess the content type of a stream whose first few bytes were
 diff --git a/lib/tc.c b/lib/tc.c
-index adb2d3182a..276cc54b35 100644
+index adb2d3182a..900a631553 100644
 --- a/lib/tc.c
 +++ b/lib/tc.c
 @@ -395,8 +395,14 @@ static const struct nl_policy tca_flower_policy[] = {
@@ -55803,7 +55901,32 @@ index adb2d3182a..276cc54b35 100644
      size_t keys_ex_size, left;
      int type, i = 0, err;
  
-@@ -1092,7 +1112,6 @@ nl_parse_act_pedit(struct nlattr *options, struct tc_flower *flower)
+@@ -1068,7 +1088,7 @@ nl_parse_act_pedit(struct nlattr *options, struct tc_flower *flower)
+                 int diff = flower_off + (keys->off - mf);
+                 ovs_be32 *dst = (void *) (rewrite_key + diff);
+                 ovs_be32 *dst_m = (void *) (rewrite_mask + diff);
+-                ovs_be32 mask, mask_word, data_word;
++                ovs_be32 mask, mask_word, data_word, val;
+                 uint32_t zero_bits;
+ 
+                 mask_word = htonl(ntohl(keys->mask) << m->boundary_shift);
+@@ -1083,8 +1103,13 @@ nl_parse_act_pedit(struct nlattr *options, struct tc_flower *flower)
+                     mask &= htonl(UINT32_MAX << zero_bits);
+                 }
+ 
+-                *dst_m |= mask;
+-                *dst |= data_word & mask;
++                val = get_unaligned_be32(dst_m);
++                val |= mask;
++                put_unaligned_be32(dst_m, val);
++
++                val = get_unaligned_be32(dst);
++                val |= data_word & mask;
++                put_unaligned_be32(dst, val);
+             }
+         }
+ 
+@@ -1092,7 +1117,6 @@ nl_parse_act_pedit(struct nlattr *options, struct tc_flower *flower)
          i++;
      }
  
@@ -55811,7 +55934,7 @@ index adb2d3182a..276cc54b35 100644
      action->type = TC_ACT_PEDIT;
  
      return 0;
-@@ -1314,8 +1333,8 @@ nl_parse_act_gact(struct nlattr *options, struct tc_flower *flower)
+@@ -1314,8 +1338,8 @@ nl_parse_act_gact(struct nlattr *options, struct tc_flower *flower)
      struct nlattr *gact_attrs[ARRAY_SIZE(gact_policy)];
      const struct tc_gact *p;
      struct nlattr *gact_parms;
@@ -55821,7 +55944,7 @@ index adb2d3182a..276cc54b35 100644
  
      if (!nl_parse_nested(options, gact_policy, gact_attrs,
                           ARRAY_SIZE(gact_policy))) {
-@@ -1335,8 +1354,9 @@ nl_parse_act_gact(struct nlattr *options, struct tc_flower *flower)
+@@ -1335,8 +1359,9 @@ nl_parse_act_gact(struct nlattr *options, struct tc_flower *flower)
          return EINVAL;
      }
  
@@ -55833,7 +55956,7 @@ index adb2d3182a..276cc54b35 100644
  
      return 0;
  }
-@@ -1357,9 +1377,9 @@ nl_parse_act_mirred(struct nlattr *options, struct tc_flower *flower)
+@@ -1357,9 +1382,9 @@ nl_parse_act_mirred(struct nlattr *options, struct tc_flower *flower)
      struct nlattr *mirred_attrs[ARRAY_SIZE(mirred_policy)];
      const struct tc_mirred *m;
      const struct nlattr *mirred_parms;
@@ -55844,7 +55967,7 @@ index adb2d3182a..276cc54b35 100644
  
      if (!nl_parse_nested(options, mirred_policy, mirred_attrs,
                           ARRAY_SIZE(mirred_policy))) {
-@@ -1387,8 +1407,8 @@ nl_parse_act_mirred(struct nlattr *options, struct tc_flower *flower)
+@@ -1387,8 +1412,8 @@ nl_parse_act_mirred(struct nlattr *options, struct tc_flower *flower)
      action->type = TC_ACT_OUTPUT;
  
      mirred_tm = mirred_attrs[TCA_MIRRED_TM];
@@ -55855,7 +55978,7 @@ index adb2d3182a..276cc54b35 100644
  
      return 0;
  }
-@@ -1487,7 +1507,9 @@ nl_parse_act_ct(struct nlattr *options, struct tc_flower *flower)
+@@ -1487,7 +1512,9 @@ nl_parse_act_ct(struct nlattr *options, struct tc_flower *flower)
                  if (ipv4_max) {
                      ovs_be32 addr = nl_attr_get_be32(ipv4_max);
  
@@ -55866,7 +55989,7 @@ index adb2d3182a..276cc54b35 100644
                  }
              } else if (ipv6_min) {
                  action->ct.range.ip_family = AF_INET6;
-@@ -1496,7 +1518,9 @@ nl_parse_act_ct(struct nlattr *options, struct tc_flower *flower)
+@@ -1496,7 +1523,9 @@ nl_parse_act_ct(struct nlattr *options, struct tc_flower *flower)
                  if (ipv6_max) {
                      struct in6_addr addr = nl_attr_get_in6_addr(ipv6_max);
  
@@ -55877,7 +56000,7 @@ index adb2d3182a..276cc54b35 100644
                  }
              }
  
-@@ -1504,6 +1528,10 @@ nl_parse_act_ct(struct nlattr *options, struct tc_flower *flower)
+@@ -1504,6 +1533,10 @@ nl_parse_act_ct(struct nlattr *options, struct tc_flower *flower)
                  action->ct.range.port.min = nl_attr_get_be16(port_min);
                  if (port_max) {
                      action->ct.range.port.max = nl_attr_get_be16(port_max);
@@ -55888,7 +56011,7 @@ index adb2d3182a..276cc54b35 100644
                  }
              }
          }
-@@ -1702,6 +1730,9 @@ static const struct nl_policy stats_policy[] = {
+@@ -1702,6 +1735,9 @@ static const struct nl_policy stats_policy[] = {
      [TCA_STATS_BASIC] = { .type = NL_A_UNSPEC,
                            .min_len = sizeof(struct gnet_stats_basic),
                            .optional = false, },
@@ -55898,7 +56021,7 @@ index adb2d3182a..276cc54b35 100644
  };
  
  static int
-@@ -1714,8 +1745,9 @@ nl_parse_single_action(struct nlattr *action, struct tc_flower *flower,
+@@ -1714,8 +1750,9 @@ nl_parse_single_action(struct nlattr *action, struct tc_flower *flower,
      const char *act_kind;
      struct nlattr *action_attrs[ARRAY_SIZE(act_policy)];
      struct nlattr *stats_attrs[ARRAY_SIZE(stats_policy)];
@@ -55910,7 +56033,7 @@ index adb2d3182a..276cc54b35 100644
      int err = 0;
  
      if (!nl_parse_nested(action, act_policy, action_attrs,
-@@ -1771,10 +1803,30 @@ nl_parse_single_action(struct nlattr *action, struct tc_flower *flower,
+@@ -1771,10 +1808,30 @@ nl_parse_single_action(struct nlattr *action, struct tc_flower *flower,
          return EPROTO;
      }
  
@@ -55945,7 +56068,7 @@ index adb2d3182a..276cc54b35 100644
      }
  
      return 0;
-@@ -2399,14 +2451,14 @@ nl_msg_put_act_flags(struct ofpbuf *request) {
+@@ -2399,14 +2456,14 @@ nl_msg_put_act_flags(struct ofpbuf *request) {
   * first_word_mask/last_word_mask - the mask to use for the first/last read
   * (as we read entire words). */
  static void
@@ -55963,7 +56086,7 @@ index adb2d3182a..276cc54b35 100644
  
      max_offset = m->offset + m->size;
      start_offset = ROUND_DOWN(m->offset, 4);
-@@ -2473,7 +2525,8 @@ csum_update_flag(struct tc_flower *flower,
+@@ -2473,7 +2530,8 @@ csum_update_flag(struct tc_flower *flower,
  
  static int
  nl_msg_put_flower_rewrite_pedits(struct ofpbuf *request,
@@ -55973,7 +56096,7 @@ index adb2d3182a..276cc54b35 100644
  {
      struct {
          struct tc_pedit sel;
-@@ -2497,12 +2550,12 @@ nl_msg_put_flower_rewrite_pedits(struct ofpbuf *request,
+@@ -2497,12 +2555,12 @@ nl_msg_put_flower_rewrite_pedits(struct ofpbuf *request,
              continue;
          }
  
@@ -55989,7 +56112,7 @@ index adb2d3182a..276cc54b35 100644
  
              if (j == 0) {
                  mask_word &= first_word_mask;
-@@ -2556,6 +2609,29 @@ nl_msg_put_flower_acts_release(struct ofpbuf *request, uint16_t act_index)
+@@ -2556,6 +2614,29 @@ nl_msg_put_flower_acts_release(struct ofpbuf *request, uint16_t act_index)
      nl_msg_end_nested(request, act_offset);
  }
  
@@ -56019,7 +56142,7 @@ index adb2d3182a..276cc54b35 100644
  static int
  nl_msg_put_flower_acts(struct ofpbuf *request, struct tc_flower *flower)
  {
-@@ -2572,20 +2648,22 @@ nl_msg_put_flower_acts(struct ofpbuf *request, struct tc_flower *flower)
+@@ -2572,20 +2653,22 @@ nl_msg_put_flower_acts(struct ofpbuf *request, struct tc_flower *flower)
  
          action = flower->actions;
          for (i = 0; i < flower->action_count; i++, action++) {
@@ -56048,7 +56171,7 @@ index adb2d3182a..276cc54b35 100644
                  }
              }
              break;
-@@ -2792,13 +2870,16 @@ nl_msg_put_flower_tunnel(struct ofpbuf *request, struct tc_flower *flower)
+@@ -2792,13 +2875,16 @@ nl_msg_put_flower_tunnel(struct ofpbuf *request, struct tc_flower *flower)
      struct in6_addr *ipv6_dst_mask = &flower->mask.tunnel.ipv6.ipv6_dst;
      struct in6_addr *ipv6_src = &flower->key.tunnel.ipv6.ipv6_src;
      struct in6_addr *ipv6_dst = &flower->key.tunnel.ipv6.ipv6_dst;
@@ -56066,7 +56189,7 @@ index adb2d3182a..276cc54b35 100644
  
      if (ipv4_dst_mask || ipv4_src_mask) {
          nl_msg_put_be32(request, TCA_FLOWER_KEY_ENC_IPV4_DST_MASK,
-@@ -2824,8 +2905,15 @@ nl_msg_put_flower_tunnel(struct ofpbuf *request, struct tc_flower *flower)
+@@ -2824,8 +2910,15 @@ nl_msg_put_flower_tunnel(struct ofpbuf *request, struct tc_flower *flower)
          nl_msg_put_u8(request, TCA_FLOWER_KEY_ENC_IP_TTL, ttl);
          nl_msg_put_u8(request, TCA_FLOWER_KEY_ENC_IP_TTL_MASK, ttl_mask);
      }
@@ -56083,7 +56206,7 @@ index adb2d3182a..276cc54b35 100644
      }
      if (id_mask) {
          nl_msg_put_be32(request, TCA_FLOWER_KEY_ENC_KEY_ID, id);
-@@ -2914,13 +3002,13 @@ nl_msg_put_flower_options(struct ofpbuf *request, struct tc_flower *flower)
+@@ -2914,13 +3007,13 @@ nl_msg_put_flower_options(struct ofpbuf *request, struct tc_flower *flower)
              FLOWER_PUT_MASKED_VALUE(icmp_code, TCA_FLOWER_KEY_ICMPV6_CODE);
              FLOWER_PUT_MASKED_VALUE(icmp_type, TCA_FLOWER_KEY_ICMPV6_TYPE);
          }
@@ -56102,7 +56225,7 @@ index adb2d3182a..276cc54b35 100644
      if (host_eth_type == ETH_P_IP) {
              FLOWER_PUT_MASKED_VALUE(ipv4.ipv4_src, TCA_FLOWER_KEY_IPV4_SRC);
              FLOWER_PUT_MASKED_VALUE(ipv4.ipv4_dst, TCA_FLOWER_KEY_IPV4_DST);
-@@ -2993,12 +3081,79 @@ nl_msg_put_flower_options(struct ofpbuf *request, struct tc_flower *flower)
+@@ -2993,12 +3086,79 @@ nl_msg_put_flower_options(struct ofpbuf *request, struct tc_flower *flower)
      return 0;
  }
  
@@ -56183,7 +56306,7 @@ index adb2d3182a..276cc54b35 100644
          return false;
      }
  
-@@ -3011,8 +3166,8 @@ cmp_tc_flower_match_action(const struct tc_flower *a,
+@@ -3011,8 +3171,8 @@ cmp_tc_flower_match_action(const struct tc_flower *a,
          uint8_t key_b = ((uint8_t *)&b->key)[i] & mask;
  
          if (key_a != key_b) {
@@ -56194,7 +56317,7 @@ index adb2d3182a..276cc54b35 100644
              return false;
          }
      }
-@@ -3022,14 +3177,15 @@ cmp_tc_flower_match_action(const struct tc_flower *a,
+@@ -3022,14 +3182,15 @@ cmp_tc_flower_match_action(const struct tc_flower *a,
      const struct tc_action *action_b = b->actions;
  
      if (a->action_count != b->action_count) {
@@ -56567,7 +56690,7 @@ index 4c3bace6ef..09134feca0 100644
       AC_DEFINE([HAVE_LD_AVX512_GOOD], [1],
                 [Define to 1 if binutils correctly supports AVX512.])
 diff --git a/ofproto/bond.c b/ofproto/bond.c
-index cdfdf0b9d8..6ecd6e1c9f 100644
+index cdfdf0b9d8..a7c859b909 100644
 --- a/ofproto/bond.c
 +++ b/ofproto/bond.c
 @@ -185,10 +185,14 @@ static struct bond_member *choose_output_member(const struct bond *,
@@ -56629,6 +56752,15 @@ index cdfdf0b9d8..6ecd6e1c9f 100644
      revalidate = bond->bond_revalidate;
      bond->bond_revalidate = false;
      ovs_rwlock_unlock(&rwlock);
+@@ -876,7 +892,7 @@ bond_check_admissibility(struct bond *bond, const void *member_,
+         if (!member->enabled && member->may_enable) {
+             VLOG_DBG_RL(&rl, "bond %s: member %s: "
+                         "main thread has not yet enabled member",
+-                        bond->name, bond->active_member->name);
++                        bond->name, member->name);
+         }
+         goto out;
+     case LACP_CONFIGURED:
 @@ -1038,7 +1054,7 @@ bond_may_recirc(const struct bond *bond)
  }
  
@@ -57174,7 +57306,7 @@ index 114aff8ea3..0fc6d2ea60 100644
      enum xc_type type;
      union {
 diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
-index 578cbfe581..ce1d94db34 100644
+index 578cbfe581..8a28b29d4c 100644
 --- a/ofproto/ofproto-dpif-xlate.c
 +++ b/ofproto/ofproto-dpif-xlate.c
 @@ -865,7 +865,7 @@ xlate_xbridge_init(struct xlate_cfg *xcfg, struct xbridge *xbridge)
@@ -57438,7 +57570,35 @@ index 578cbfe581..ce1d94db34 100644
          }
          return err;
      }
-@@ -4176,6 +4230,10 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port,
+@@ -4099,6 +4153,16 @@ xport_has_ip(const struct xport *xport)
+     return n_in6 ? true : false;
+ }
+ 
++static bool check_neighbor_reply(struct xlate_ctx *ctx, struct flow *flow)
++{
++    if (flow->dl_type == htons(ETH_TYPE_ARP) ||
++        flow->nw_proto == IPPROTO_ICMPV6) {
++        return is_neighbor_reply_correct(ctx, flow);
++    }
++
++    return false;
++}
++
+ static bool
+ terminate_native_tunnel(struct xlate_ctx *ctx, const struct xport *xport,
+                         struct flow *flow, struct flow_wildcards *wc,
+@@ -4119,9 +4183,7 @@ terminate_native_tunnel(struct xlate_ctx *ctx, const struct xport *xport,
+         /* If no tunnel port was found and it's about an ARP or ICMPv6 packet,
+          * do tunnel neighbor snooping. */
+         if (*tnl_port == ODPP_NONE &&
+-            (flow->dl_type == htons(ETH_TYPE_ARP) ||
+-             flow->nw_proto == IPPROTO_ICMPV6) &&
+-             is_neighbor_reply_correct(ctx, flow)) {
++            (check_neighbor_reply(ctx, flow) || is_garp(flow, wc))) {
+             tnl_neigh_snoop(flow, wc, ctx->xbridge->name,
+                             ctx->xin->allow_side_effects);
+         } else if (*tnl_port != ODPP_NONE &&
+@@ -4176,6 +4238,10 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port,
          if (xport->pt_mode == NETDEV_PT_LEGACY_L3) {
              flow->packet_type = PACKET_TYPE_BE(OFPHTN_ETHERTYPE,
                                                 ntohs(flow->dl_type));
@@ -57449,7 +57609,7 @@ index 578cbfe581..ce1d94db34 100644
          }
      }
  
-@@ -4678,7 +4736,7 @@ pick_dp_hash_select_group(struct xlate_ctx *ctx, struct group_dpif *group)
+@@ -4678,7 +4744,7 @@ pick_dp_hash_select_group(struct xlate_ctx *ctx, struct group_dpif *group)
          for (int i = 0; i <= hash_mask; i++) {
              struct ofputil_bucket *b =
                      group->hash_map[(dp_hash + i) & hash_mask];
@@ -57458,7 +57618,7 @@ index 578cbfe581..ce1d94db34 100644
                  return b;
              }
          }
-@@ -5622,7 +5680,8 @@ xlate_sample_action(struct xlate_ctx *ctx,
+@@ -5622,7 +5688,8 @@ xlate_sample_action(struct xlate_ctx *ctx,
  
      /* Scale the probability from 16-bit to 32-bit while representing
       * the same percentage. */
@@ -57468,7 +57628,7 @@ index 578cbfe581..ce1d94db34 100644
  
      /* If ofp_port in flow sample action is equel to ofp_port,
       * this sample action is a input port action. */
-@@ -7609,6 +7668,10 @@ xlate_wc_finish(struct xlate_ctx *ctx)
+@@ -7609,6 +7676,10 @@ xlate_wc_finish(struct xlate_ctx *ctx)
              ctx->wc->masks.vlans[i].tci = 0;
          }
      }
@@ -57479,7 +57639,7 @@ index 578cbfe581..ce1d94db34 100644
  }
  
  /* Translates the flow, actions, or rule in 'xin' into datapath actions in
-@@ -7784,6 +7847,12 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout)
+@@ -7784,6 +7855,12 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout)
          goto exit;
      }
  
@@ -60942,6 +61102,20 @@ index 4d49f12017..91ded1445d 100644
  
  bridge("br0")
  -------------
+diff --git a/tests/odp.at b/tests/odp.at
+index 4d08c59ca6..fce6a4f2bc 100644
+--- a/tests/odp.at
++++ b/tests/odp.at
+@@ -348,7 +348,9 @@ ct(commit,helper=tftp)
+ ct(commit,timeout=ovs_tp_1_tcp4)
+ ct(nat)
+ ct(commit,nat(src))
++ct(commit,timeout=ovs_tp_1_tcp4,nat(src))
+ ct(commit,nat(dst))
++ct(commit,timeout=ovs_tp_1_tcp4,nat(dst))
+ ct(commit,nat(src=10.0.0.240,random))
+ ct(commit,nat(src=10.0.0.240:32768-65535,random))
+ ct(commit,nat(dst=10.0.0.128-10.0.0.254,hash))
 diff --git a/tests/ofp-print.at b/tests/ofp-print.at
 index 2c7e163bd6..7be6628c34 100644
 --- a/tests/ofp-print.at
@@ -61046,7 +61220,7 @@ index 2c7e163bd6..7be6628c34 100644
  AT_CLEANUP
  
 diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at
-index 7c2edeb9d4..1a8de7398c 100644
+index 7c2edeb9d4..73a5e8c3d0 100644
 --- a/tests/ofproto-dpif.at
 +++ b/tests/ofproto-dpif.at
 @@ -29,6 +29,39 @@ AT_CHECK([ovs-appctl revalidator/wait])
@@ -62319,7 +62493,37 @@ index 7c2edeb9d4..1a8de7398c 100644
  OVS_VSWITCHD_STOP
  AT_CLEANUP
  
-@@ -7031,7 +7173,7 @@ dnl An 170 byte packet
+@@ -7004,6 +7146,29 @@ AT_CHECK([ovs-appctl coverage/read-counter mac_learning_static_none_move], [0],
+ OVS_VSWITCHD_STOP
+ AT_CLEANUP
+ 
++AT_SETUP([ofproto-dpif - static-mac learned mac age out])
++OVS_VSWITCHD_START([set bridge br0 fail-mode=standalone -- set bridge br0 other_config:mac-aging-time=5])
++add_of_ports br0 1 2
++
++dnl Add some static mac entries.
++AT_CHECK([ovs-appctl fdb/add br0 p1 0 50:54:00:00:01:01])
++AT_CHECK([ovs-appctl fdb/add br0 p2 0 50:54:00:00:02:02])
++
++dnl Generate some dynamic fdb entries on some ports.
++OFPROTO_TRACE([ovs-dummy], [in_port(1),eth(src=60:54:00:00:00:01)], [-generate], [100,2])
++OFPROTO_TRACE([ovs-dummy], [in_port(2),eth(src=60:54:00:00:00:02)], [-generate], [100,1])
++
++dnl Waiting for aging out.
++ovs-appctl time/warp 20000
++
++dnl Count number of static entries remaining.
++AT_CHECK_UNQUOTED([ovs-appctl fdb/stats-show br0 | grep expired], [0], [dnl
++  Total number of expired MAC entries     : 2
++])
++
++OVS_VSWITCHD_STOP
++AT_CLEANUP
++
+ AT_SETUP([ofproto-dpif - basic truncate action])
+ OVS_VSWITCHD_START
+ add_of_ports br0 1 2 3 4 5
+@@ -7031,7 +7196,7 @@ dnl An 170 byte packet
  AT_CHECK([ovs-appctl netdev-dummy/receive p1 '000c29c8a0a4005056c0000808004500009cb4a6000040019003c0a8da01c0a8da640800cb5fa762000556f431ad0009388e08090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f'])
  
  AT_CHECK([ovs-ofctl parse-pcap p1.pcap], [0], [dnl
@@ -62328,7 +62532,7 @@ index 7c2edeb9d4..1a8de7398c 100644
  ])
  
  AT_CHECK([ovs-appctl revalidator/purge], [0])
-@@ -7600,13 +7742,28 @@ dnl configure bridge IPFIX and ensure that sample action generation works at the
+@@ -7600,13 +7765,28 @@ dnl configure bridge IPFIX and ensure that sample action generation works at the
  dnl datapath level.
  AT_SETUP([ofproto-dpif - Bridge IPFIX sanity check])
  OVS_VSWITCHD_START
@@ -62358,7 +62562,7 @@ index 7c2edeb9d4..1a8de7398c 100644
  dnl Send some packets that should be sampled.
  for i in `seq 1 3`; do
      AT_CHECK([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(0x0800)'])
-@@ -8666,7 +8823,7 @@ recirc_id(0),in_port(100),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(src=192.1
+@@ -8666,7 +8846,7 @@ recirc_id(0),in_port(100),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(src=192.1
  ])
  
  AT_CHECK([grep -e '|ofproto_dpif_xlate|WARN|' ovs-vswitchd.log | sed "s/^.*|WARN|//"], [0], [dnl
@@ -62367,7 +62571,7 @@ index 7c2edeb9d4..1a8de7398c 100644
  ])
  
  OVS_VSWITCHD_STOP(["/stack underflow/d"])
-@@ -9855,7 +10012,7 @@ OVS_APP_EXIT_AND_WAIT([ovs-ofctl])
+@@ -9855,7 +10035,7 @@ OVS_APP_EXIT_AND_WAIT([ovs-ofctl])
  
  AT_CHECK([cat ofctl_monitor.log], [0], [dnl
  NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=86 in_port=1 (via no_match) data_len=86 (unbuffered)
@@ -62376,7 +62580,7 @@ index 7c2edeb9d4..1a8de7398c 100644
  ])
  
  OVS_VSWITCHD_STOP
-@@ -9906,7 +10063,7 @@ OVS_APP_EXIT_AND_WAIT([ovs-ofctl])
+@@ -9906,7 +10086,7 @@ OVS_APP_EXIT_AND_WAIT([ovs-ofctl])
  
  AT_CHECK([cat ofctl_monitor.log], [0], [dnl
  NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=86 in_port=1 (via action) data_len=86 (unbuffered)
@@ -62385,7 +62589,7 @@ index 7c2edeb9d4..1a8de7398c 100644
  ])
  
  OVS_VSWITCHD_STOP
-@@ -10166,10 +10323,10 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
+@@ -10166,10 +10346,10 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
  dnl Check this output. We only see the latter two packets, not the first.
  AT_CHECK([cat ofctl_monitor.log], [0], [dnl
  NXT_PACKET_IN (xid=0x0): table_id=6 cookie=0x0 total_len=106 reg0=0x1,reg1=0x4d2,reg2=0x1,reg3=0x1,reg4=0x1,in_port=1 (via action) data_len=106 (unbuffered)
@@ -62398,7 +62602,7 @@ index 7c2edeb9d4..1a8de7398c 100644
  ])
  
  AT_CHECK([ovs-ofctl monitor br0 65534 invalid_ttl -P nxt_packet_in --detach --no-chdir --pidfile 2> ofctl_monitor.log])
-@@ -10187,10 +10344,10 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
+@@ -10187,10 +10367,10 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
  dnl Check this output. We should see both packets
  AT_CHECK([cat ofctl_monitor.log], [0], [dnl
  NXT_PACKET_IN (xid=0x0): table_id=6 cookie=0x0 total_len=106 reg0=0x1,reg1=0x4d2,reg2=0x1,reg3=0x1,reg4=0x1,in_port=1 (via action) data_len=106 (unbuffered)
@@ -62411,7 +62615,7 @@ index 7c2edeb9d4..1a8de7398c 100644
  ])
  
  OVS_VSWITCHD_STOP
-@@ -10239,10 +10396,10 @@ dnl Note that the first packet doesn't have the ct_state bits set. This
+@@ -10239,10 +10419,10 @@ dnl Note that the first packet doesn't have the ct_state bits set. This
  dnl happens because the ct_state field is available only after recirc.
  AT_CHECK([cat ofctl_monitor.log], [0], [dnl
  NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=106 in_port=1 (via action) data_len=106 (unbuffered)
@@ -62424,7 +62628,7 @@ index 7c2edeb9d4..1a8de7398c 100644
  ])
  
  AT_CHECK([ovs-ofctl monitor br0 65534 invalid_ttl -P nxt_packet_in --detach --no-chdir --pidfile 2> ofctl_monitor.log])
-@@ -10261,10 +10418,10 @@ dnl Note that the first packet doesn't have the ct_state bits set. This
+@@ -10261,10 +10441,10 @@ dnl Note that the first packet doesn't have the ct_state bits set. This
  dnl happens because the ct_state field is available only after recirc.
  AT_CHECK([cat ofctl_monitor.log], [0], [dnl
  NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=106 in_port=1 (via action) data_len=106 (unbuffered)
@@ -62437,7 +62641,7 @@ index 7c2edeb9d4..1a8de7398c 100644
  ])
  
  dnl
-@@ -10320,9 +10477,9 @@ dnl Note that the first packet doesn't have the ct_state bits set. This
+@@ -10320,9 +10500,9 @@ dnl Note that the first packet doesn't have the ct_state bits set. This
  dnl happens because the ct_state field is available only after recirc.
  AT_CHECK([cat ofctl_monitor.log], [0], [dnl
  NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=126 in_port=1 (via action) data_len=126 (unbuffered)
@@ -62449,7 +62653,7 @@ index 7c2edeb9d4..1a8de7398c 100644
  ])
  
  OVS_VSWITCHD_STOP
-@@ -10433,7 +10590,7 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
+@@ -10433,7 +10613,7 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
  dnl Check this output. Only one reply must be there
  AT_CHECK([cat ofctl_monitor.log], [0], [dnl
  NXT_PACKET_IN (xid=0x0): table_id=1 cookie=0x0 total_len=106 ct_state=est|rpl|trk,ct_nw_src=10.1.1.1,ct_nw_dst=10.1.1.2,ct_nw_proto=17,ct_tp_src=1,ct_tp_dst=2,ip,in_port=2 (via action) data_len=106 (unbuffered)
@@ -62458,7 +62662,7 @@ index 7c2edeb9d4..1a8de7398c 100644
  dnl
  OFPT_ECHO_REQUEST (xid=0x0): 0 bytes of payload
  ])
-@@ -10467,7 +10624,7 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
+@@ -10467,7 +10647,7 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
  
  AT_CHECK([cat ofctl_monitor.log], [0], [dnl
  NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=86 ct_state=inv|trk,ipv6,in_port=2 (via action) data_len=86 (unbuffered)
@@ -62467,7 +62671,7 @@ index 7c2edeb9d4..1a8de7398c 100644
  ])
  
  OVS_VSWITCHD_STOP
-@@ -10523,16 +10680,16 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
+@@ -10523,16 +10703,16 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
  dnl Check this output. We only see the latter two packets (for each zone), not the first.
  AT_CHECK([cat ofctl_monitor.log], [0], [dnl
  NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=106 in_port=1 (via action) data_len=106 (unbuffered)
@@ -62488,7 +62692,7 @@ index 7c2edeb9d4..1a8de7398c 100644
  ])
  
  OVS_VSWITCHD_STOP
-@@ -10579,10 +10736,10 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
+@@ -10579,10 +10759,10 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
  dnl Check this output. We only see the latter two packets, not the first.
  AT_CHECK([cat ofctl_monitor.log], [0], [dnl
  NXT_PACKET_IN (xid=0x0): table_id=1 cookie=0x0 total_len=106 in_port=1 (via action) data_len=106 (unbuffered)
@@ -62501,7 +62705,7 @@ index 7c2edeb9d4..1a8de7398c 100644
  ])
  
  OVS_VSWITCHD_STOP
-@@ -10629,10 +10786,10 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
+@@ -10629,10 +10809,10 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
  dnl Check this output. We only see the first and the last packet
  AT_CHECK([cat ofctl_monitor.log], [0], [dnl
  NXT_PACKET_IN (xid=0x0): table_id=1 cookie=0x0 total_len=47 ct_state=new|trk,ct_nw_src=172.16.0.1,ct_nw_dst=172.16.0.2,ct_nw_proto=17,ct_tp_src=41614,ct_tp_dst=5555,ip,in_port=1 (via action) data_len=47 (unbuffered)
@@ -62514,7 +62718,7 @@ index 7c2edeb9d4..1a8de7398c 100644
  ])
  
  OVS_VSWITCHD_STOP
-@@ -10681,19 +10838,19 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
+@@ -10681,19 +10861,19 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
  dnl Check this output.
  AT_CHECK([cat ofctl_monitor.log], [0], [dnl
  NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=106 in_port=1 (via action) data_len=106 (unbuffered)
@@ -62539,7 +62743,7 @@ index 7c2edeb9d4..1a8de7398c 100644
  ])
  
  OVS_VSWITCHD_STOP
-@@ -10738,10 +10895,10 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
+@@ -10738,10 +10918,10 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
  dnl Check this output.
  AT_CHECK([cat ofctl_monitor.log], [0], [dnl
  NXT_PACKET_IN (xid=0x0): table_id=1 cookie=0x0 total_len=106 ct_state=est|rpl|trk,ct_label=0x1,ct_nw_src=10.1.1.1,ct_nw_dst=10.1.1.2,ct_nw_proto=17,ct_tp_src=1,ct_tp_dst=2,ip,in_port=2 (via action) data_len=106 (unbuffered)
@@ -62552,7 +62756,7 @@ index 7c2edeb9d4..1a8de7398c 100644
  ])
  
  OVS_VSWITCHD_STOP
-@@ -11152,16 +11309,16 @@ dnl Note that the first packet doesn't have the ct_state bits set. This
+@@ -11152,16 +11332,16 @@ dnl Note that the first packet doesn't have the ct_state bits set. This
  dnl happens because the ct_state field is available only after recirc.
  AT_CHECK([cat ofctl_monitor.log], [0], [dnl
  NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=106 in_port=1 (via action) data_len=106 (unbuffered)
@@ -62573,7 +62777,7 @@ index 7c2edeb9d4..1a8de7398c 100644
  ])
  
  dnl The next test verifies that ct_clear at the datapath only gets executed
-@@ -11235,13 +11392,13 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
+@@ -11235,13 +11415,13 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
  dnl Check this output.
  AT_CHECK([cat ofctl_monitor.log], [0], [dnl
  NXT_PACKET_IN (xid=0x0): table_id=1 cookie=0x0 total_len=106 ct_state=est|rpl|trk,ct_nw_src=10.1.2.100,ct_nw_dst=10.1.2.200,ct_nw_proto=17,ct_tp_src=6,ct_tp_dst=6,ip,in_port=2 (via action) data_len=106 (unbuffered)
@@ -63985,7 +64189,7 @@ index 1714273e35..270956d13f 100644
  dnl Delete ip address.
  AT_CHECK([ip addr del 10.0.0.17/24 dev p1-route], [0], [stdout])
 diff --git a/tests/system-traffic.at b/tests/system-traffic.at
-index f22d86e466..69de604fa0 100644
+index f22d86e466..9d1c96bb43 100644
 --- a/tests/system-traffic.at
 +++ b/tests/system-traffic.at
 @@ -192,6 +192,46 @@ NS_CHECK_EXEC([at_ns0], [ping6 -s 3200 -q -c 3 -i 0.3 -w 2 fc00:1::2 | FORMAT_PI
@@ -64413,7 +64617,7 @@ index f22d86e466..69de604fa0 100644
  
  
  OVS_TRAFFIC_VSWITCHD_STOP
-@@ -1933,13 +2037,13 @@ dnl p1(at_ns1) interface
+@@ -1933,15 +2037,51 @@ dnl p1(at_ns1) interface
  NS_CHECK_EXEC([at_ns0], [$PYTHON3 $srcdir/sendpkt.py p0 00 00 00 00 00 02 00 00 00 00 00 01 88 47 00 00 21 40 36 b1 ee 7c 01 02 36 b1 ee 7c 01 03 08 00 45 00 00 54 03 44 40 00 40 01 21 61 0a 01 01 01 0a 01 01 02 08 00 ef ac 7c e4 00 03 5b 2c 1f 61 00 00 00 00 50 0b 02 00 00 00 00 00 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37  > /dev/null])
  
  dnl Check the expected decapsulated on the egress interface
@@ -64433,8 +64637,46 @@ index f22d86e466..69de604fa0 100644
 +OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0060:  *3637" 2>&1 1>/dev/null])
  
  
++OVS_TRAFFIC_VSWITCHD_STOP
++AT_CLEANUP
++
++AT_BANNER([QoS])
++
++AT_SETUP([QoS - basic configuration])
++AT_SKIP_IF([test $HAVE_TC = no])
++OVS_TRAFFIC_VSWITCHD_START()
++
++ADD_NAMESPACES(at_ns0, at_ns1)
++
++ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24")
++ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24")
++
++dnl Adding a custom qdisc to ovs-p1, ovs-p0 will have the default qdisc.
++AT_CHECK([tc qdisc add dev ovs-p1 root noqueue])
++AT_CHECK([tc qdisc show dev ovs-p1 | grep -q noqueue])
++
++dnl Configure the same QoS for both ports.
++AT_CHECK([ovs-vsctl set port ovs-p0 qos=@qos -- set port ovs-p1 qos=@qos dnl
++            -- --id=@qos create qos dnl
++               type=linux-htb other-config:max-rate=3000000 queues:0=@queue dnl
++            -- --id=@queue create queue dnl
++               other_config:min-rate=2000000 other_config:max-rate=3000000 dnl
++               other_config:burst=3000000],
++         [ignore], [ignore])
++
++dnl Wait for qdiscs to be applied.
++OVS_WAIT_UNTIL([tc qdisc show dev ovs-p0 | grep -q htb])
++OVS_WAIT_UNTIL([tc qdisc show dev ovs-p1 | grep -q htb])
++
++dnl Check the configuration.
++m4_define([HTB_CONF], [rate 2Mbit ceil 3Mbit burst 375000b cburst 375000b])
++AT_CHECK([tc class show dev ovs-p0 | grep -q 'class htb .* HTB_CONF'])
++AT_CHECK([tc class show dev ovs-p1 | grep -q 'class htb .* HTB_CONF'])
++
  OVS_TRAFFIC_VSWITCHD_STOP
-@@ -1985,9 +2089,9 @@ OVS_APP_EXIT_AND_WAIT([ovs-ofctl])
+ AT_CLEANUP
+ 
+@@ -1985,9 +2125,9 @@ OVS_APP_EXIT_AND_WAIT([ovs-ofctl])
  dnl Check this output. We only see the latter two packets, not the first.
  AT_CHECK([cat ofctl_monitor.log], [0], [dnl
  NXT_PACKET_IN2 (xid=0x0): total_len=42 in_port=1 (via action) data_len=42 (unbuffered)
@@ -64446,7 +64688,7 @@ index f22d86e466..69de604fa0 100644
  ])
  
  OVS_TRAFFIC_VSWITCHD_STOP
-@@ -2033,9 +2137,9 @@ OVS_APP_EXIT_AND_WAIT([ovs-ofctl])
+@@ -2033,9 +2173,9 @@ OVS_APP_EXIT_AND_WAIT([ovs-ofctl])
  dnl Check this output. We only see the latter two packets, not the first.
  AT_CHECK([cat ofctl_monitor.log], [0], [dnl
  NXT_PACKET_IN2 (xid=0x0): cookie=0x0 total_len=42 in_port=1 (via action) data_len=42 (unbuffered)
@@ -64458,7 +64700,7 @@ index f22d86e466..69de604fa0 100644
  ])
  
  dnl
-@@ -2980,6 +3084,15 @@ NXST_FLOW reply:
+@@ -2980,6 +3120,15 @@ NXST_FLOW reply:
   table=1, priority=100,ct_state=+est+trk,in_port=1 actions=output:2
  ])
  
@@ -64474,7 +64716,7 @@ index f22d86e466..69de604fa0 100644
  OVS_TRAFFIC_VSWITCHD_STOP
  AT_CLEANUP
  
-@@ -3140,11 +3253,11 @@ OVS_APP_EXIT_AND_WAIT([ovs-ofctl])
+@@ -3140,11 +3289,11 @@ OVS_APP_EXIT_AND_WAIT([ovs-ofctl])
  dnl Check this output. We only see the latter two packets, not the first.
  AT_CHECK([cat ofctl_monitor.log | grep -v ff02 | grep -v fe80 | grep -v no_match], [0], [dnl
  NXT_PACKET_IN2 (xid=0x0): table_id=1 cookie=0x0 total_len=75 ct_state=inv|trk,ip,in_port=2 (via action) data_len=75 (unbuffered)
@@ -64489,7 +64731,7 @@ index f22d86e466..69de604fa0 100644
  ])
  
  AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(172.16.0.1)], [0], [dnl
-@@ -3345,6 +3458,11 @@ AT_CHECK([ovs-ofctl bundle br0 bundle.txt])
+@@ -3345,6 +3494,11 @@ AT_CHECK([ovs-ofctl bundle br0 bundle.txt])
  AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2)], [0], [dnl
  ])
  
@@ -64501,7 +64743,7 @@ index f22d86e466..69de604fa0 100644
  OVS_TRAFFIC_VSWITCHD_STOP
  AT_CLEANUP
  
-@@ -4100,15 +4218,15 @@ action=normal
+@@ -4100,15 +4254,15 @@ action=normal
  
  AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt])
  
@@ -64520,7 +64762,7 @@ index f22d86e466..69de604fa0 100644
  "1616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161610a, actions=ct(table=1)"])
  
  AT_CHECK([ovs-appctl dpctl/dump-flows | head -2 | tail -1 | grep -q -e ["]udp[(]src=5001["]])
-@@ -5384,7 +5502,7 @@ AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2) | sed -e 's/dst=
+@@ -5384,7 +5538,7 @@ AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2) | sed -e 's/dst=
  udp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=<cleared>,dport=<cleared>),reply=(src=10.1.1.2,dst=10.1.1.2XX,sport=<cleared>,dport=<cleared>),mark=1
  ])
  
@@ -64529,7 +64771,7 @@ index f22d86e466..69de604fa0 100644
  
  OVS_TRAFFIC_VSWITCHD_STOP
  AT_CLEANUP
-@@ -6134,7 +6252,7 @@ sleep 1
+@@ -6134,7 +6288,7 @@ sleep 1
  dnl UDP packets from ns0->ns1 should solicit "destination unreachable" response.
  NS_CHECK_EXEC([at_ns0], [bash -c "echo a | nc -6 $NC_EOF_OPT -u fc00::2 1"])
  
@@ -64538,7 +64780,7 @@ index f22d86e466..69de604fa0 100644
  
  AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(fc00::2)], [0], [dnl
  udp,orig=(src=fc00::1,dst=fc00::2,sport=<cleared>,dport=<cleared>),reply=(src=fc00::2,dst=fc00::240,sport=<cleared>,dport=<cleared>)
-@@ -6454,7 +6572,7 @@ on_exit 'ovs-appctl revalidator/purge'
+@@ -6454,7 +6608,7 @@ on_exit 'ovs-appctl revalidator/purge'
  on_exit 'ovs-appctl dpif/dump-flows br0'
  
  dnl Should work with the virtual IP address through NAT
@@ -64547,7 +64789,7 @@ index f22d86e466..69de604fa0 100644
      echo Request $i
      NS_CHECK_EXEC([at_ns1], [wget 10.1.1.64 -t 5 -T 1 --retry-connrefused -v -o wget$i.log])
  done
-@@ -6743,6 +6861,132 @@ AT_CHECK([ovs-ofctl dump-flows br0 | grep table=2, | OFPROTO_CLEAR_DURATION_IDLE
+@@ -6743,6 +6897,132 @@ AT_CHECK([ovs-ofctl dump-flows br0 | grep table=2, | OFPROTO_CLEAR_DURATION_IDLE
  OVS_TRAFFIC_VSWITCHD_STOP
  AT_CLEANUP
  
@@ -64680,7 +64922,7 @@ index f22d86e466..69de604fa0 100644
  AT_BANNER([802.1ad])
  
  AT_SETUP([802.1ad - vlan_limit])
-@@ -7007,12 +7251,12 @@ dnl p1(at_ns1) interface
+@@ -7007,12 +7287,12 @@ dnl p1(at_ns1) interface
  NS_CHECK_EXEC([at_ns0], [$PYTHON3 $srcdir/sendpkt.py p0 f2 00 00 00 00 02 f2 00 00 00 00 01 08 00 45 00 00 28 00 01 00 00 40 06 b0 13 c0 a8 00 0a 0a 00 00 0a 04 00 08 00 00 00 00 c8 00 00 00 00 50 02 20 00 b8 5e 00 00 > /dev/null])
  
  dnl Check the expected nsh encapsulated packet on the egress interface
@@ -64699,7 +64941,7 @@ index f22d86e466..69de604fa0 100644
  
  OVS_TRAFFIC_VSWITCHD_STOP
  AT_CLEANUP
-@@ -7039,10 +7283,10 @@ dnl p1(at_ns1) interface
+@@ -7039,10 +7319,10 @@ dnl p1(at_ns1) interface
  NS_CHECK_EXEC([at_ns0], [$PYTHON3 $srcdir/sendpkt.py p0 f2 ff 00 00 00 02 f2 ff 00 00 00 01 89 4f 02 06 01 03 00 00 64 03 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 f2 00 00 00 00 02 f2 00 00 00 00 01 08 00 45 00 00 28 00 01 00 00 40 06 b0 13 c0 a8 00 0a 0a 00 00 0a 04 00 08 00 00 00 00 c8 00 00 00 00 50 02 20 00 b8 5e 00 00 > /dev/null])
  
  dnl Check the expected de-capsulated TCP packet on the egress interface
@@ -64714,7 +64956,7 @@ index f22d86e466..69de604fa0 100644
  
  OVS_TRAFFIC_VSWITCHD_STOP
  AT_CLEANUP
-@@ -7072,12 +7316,12 @@ dnl p1(at_ns1) interface
+@@ -7072,12 +7352,12 @@ dnl p1(at_ns1) interface
  NS_CHECK_EXEC([at_ns0], [$PYTHON3 $srcdir/sendpkt.py p0 f2 ff 00 00 00 02 f2 ff 00 00 00 01 89 4f 02 06 01 03 00 01 00 03 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 f2 00 00 00 00 02 f2 00 00 00 00 01 08 00 45 00 00 28 00 01 00 00 40 06 b0 13 c0 a8 00 0a 0a 00 00 0a 04 00 08 00 00 00 00 c8 00 00 00 00 50 02 20 00 b8 5e 00 00 > /dev/null])
  
  dnl Check the expected NSH packet with new fields in the header
@@ -64733,7 +64975,7 @@ index f22d86e466..69de604fa0 100644
  
  OVS_TRAFFIC_VSWITCHD_STOP
  AT_CLEANUP
-@@ -7106,23 +7350,23 @@ dnl First send packet from at_ns0 --> OVS with SPI=0x100 and SI=2
+@@ -7106,23 +7386,23 @@ dnl First send packet from at_ns0 --> OVS with SPI=0x100 and SI=2
  NS_CHECK_EXEC([at_ns0], [$PYTHON3 $srcdir/sendpkt.py p0 f2 ff 00 00 00 02 f2 ff 00 00 00 01 89 4f 02 06 01 03 00 01 00 02 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 f2 00 00 00 00 02 f2 00 00 00 00 01 08 00 45 00 00 28 00 01 00 00 40 06 b0 13 c0 a8 00 0a 0a 00 00 0a 04 00 08 00 00 00 00 c8 00 00 00 00 50 02 20 00 b8 5e 00 00 > /dev/null])
  
  dnl Check for the above packet on p1 interface
@@ -65623,10 +65865,37 @@ index 3f58e3e8fd..8c5af459e9 100644
  
  AT_CHECK([ovs-ofctl dump-ports int-br | grep 'port  5'], [0], [dnl
 diff --git a/tests/tunnel-push-pop.at b/tests/tunnel-push-pop.at
-index 57589758f4..c9a04c76bd 100644
+index 57589758f4..50f90815a1 100644
 --- a/tests/tunnel-push-pop.at
 +++ b/tests/tunnel-push-pop.at
-@@ -546,6 +546,28 @@ AT_CHECK([ovs-ofctl dump-ports int-br | grep 'port  [[37]]' | sort], [0], [dnl
+@@ -369,6 +369,26 @@ AT_CHECK([ovs-appctl tnl/neigh/show | grep br | sort], [0], [dnl
+ 1.1.2.92                                      f8:bc:12:44:34:b6   br0
+ ])
+ 
++dnl Receiving Gratuitous ARP request with correct VLAN id should alter tunnel neighbor cache
++AT_CHECK([ovs-appctl netdev-dummy/receive p0 'recirc_id(0),in_port(1),eth(src=f8:bc:12:44:34:c8,dst=ff:ff:ff:ff:ff:ff),eth_type(0x8100),vlan(vid=10,pcp=7),encap(eth_type(0x0806),arp(sip=1.1.2.92,tip=1.1.2.92,op=1,sha=f8:bc:12:44:34:c8,tha=00:00:00:00:00:00))'])
++
++ovs-appctl time/warp 1000
++ovs-appctl time/warp 1000
++
++AT_CHECK([ovs-appctl tnl/neigh/show | grep br | sort], [0], [dnl
++1.1.2.92                                      f8:bc:12:44:34:c8   br0
++])
++
++dnl Receiving Gratuitous ARP reply with correct VLAN id should alter tunnel neighbor cache
++AT_CHECK([ovs-appctl netdev-dummy/receive p0 'recirc_id(0),in_port(1),eth(src=f8:bc:12:44:34:b2,dst=ff:ff:ff:ff:ff:ff),eth_type(0x8100),vlan(vid=10,pcp=7),encap(eth_type(0x0806),arp(sip=1.1.2.92,tip=1.1.2.92,op=2,sha=f8:bc:12:44:34:b2,tha=f8:bc:12:44:34:b2))'])
++
++ovs-appctl time/warp 1000
++ovs-appctl time/warp 1000
++
++AT_CHECK([ovs-appctl tnl/neigh/show | grep br | sort], [0], [dnl
++1.1.2.92                                      f8:bc:12:44:34:b2   br0
++])
++
+ dnl Receive ARP reply without VLAN header
+ AT_CHECK([ovs-vsctl set port br0 tag=0])
+ AT_CHECK([ovs-appctl tnl/neigh/flush], [0], [OK
+@@ -546,6 +566,28 @@ AT_CHECK([ovs-ofctl dump-ports int-br | grep 'port  [[37]]' | sort], [0], [dnl
    port  7: rx pkts=5, bytes=434, drop=?, errs=?, frame=?, over=?, crc=?
  ])
  
@@ -65655,7 +65924,7 @@ index 57589758f4..c9a04c76bd 100644
  dnl Check decapsulation of Geneve packet with options
  AT_CAPTURE_FILE([ofctl_monitor.log])
  AT_CHECK([ovs-ofctl monitor int-br 65534 --detach --no-chdir --pidfile 2> ofctl_monitor.log])
-@@ -559,14 +581,14 @@ OVS_APP_EXIT_AND_WAIT(ovs-ofctl)
+@@ -559,14 +601,14 @@ OVS_APP_EXIT_AND_WAIT(ovs-ofctl)
  
  AT_CHECK([cat ofctl_monitor.log], [0], [dnl
  NXT_PACKET_IN2 (xid=0x0): cookie=0x0 total_len=98 tun_id=0x7b,tun_src=1.1.2.92,tun_dst=1.1.2.88,tun_metadata0=0xa,in_port=5 (via action) data_len=98 (unbuffered)
@@ -65673,7 +65942,7 @@ index 57589758f4..c9a04c76bd 100644
  ])
  
  dnl Receive VXLAN with different MAC and verify that the neigh cache gets updated
-@@ -718,14 +740,14 @@ dnl Output to tunnel from a int-br internal port.
+@@ -718,14 +760,14 @@ dnl Output to tunnel from a int-br internal port.
  dnl Checking that the packet arrived and it was correctly encapsulated.
  AT_CHECK([ovs-ofctl add-flow int-br "in_port=LOCAL,actions=debug_slow,output:2"])
  AT_CHECK([ovs-appctl netdev-dummy/receive int-br "${packet}4"])
@@ -65691,7 +65960,7 @@ index 57589758f4..c9a04c76bd 100644
  
  dnl Datapath actions should not have tunnel push action.
  AT_CHECK([ovs-appctl dpctl/dump-flows | grep -q tnl_push], [1])
-@@ -842,3 +864,54 @@ Datapath actions: 7
+@@ -842,3 +884,54 @@ Datapath actions: 7
  
  OVS_VSWITCHD_STOP
  AT_CLEANUP
@@ -65831,10 +66100,18 @@ index fb2025b765..67092ecf7e 100755
          awk '/^  *0x/ {if (cnt != 0) printf ","; \
               cnt++;printf "{class="$1",type="$2",len="$3"}->"$4}'
 diff --git a/utilities/ovs-tcpdump.in b/utilities/ovs-tcpdump.in
-index 82d1bedfa6..e12bab8895 100755
+index 82d1bedfa6..a49ec9f942 100755
 --- a/utilities/ovs-tcpdump.in
 +++ b/utilities/ovs-tcpdump.in
-@@ -165,6 +165,9 @@ class OVSDB(object):
+@@ -44,6 +44,7 @@ try:
+     from ovs import jsonrpc
+     from ovs.poller import Poller
+     from ovs.stream import Stream
++    from ovs.fatal_signal import add_hook
+ except Exception:
+     print("ERROR: Please install the correct Open vSwitch python support")
+     print("       libraries (version @VERSION@).")
+@@ -165,6 +166,9 @@ class OVSDB(object):
          self._idl_conn = idl.Idl(db_sock, schema)
          OVSDB.wait_for_db_change(self._idl_conn)  # Initial Sync with DB
  
@@ -65844,7 +66121,7 @@ index 82d1bedfa6..e12bab8895 100755
      def _get_schema(self):
          error, strm = Stream.open_block(Stream.open(self._db_sock))
          if error:
-@@ -222,6 +225,13 @@ class OVSDB(object):
+@@ -222,6 +226,13 @@ class OVSDB(object):
      def interface_mtu(self, intf_name):
          try:
              intf = self._find_row_by_name('Interface', intf_name)
@@ -65858,9 +66135,28 @@ index 82d1bedfa6..e12bab8895 100755
              return intf.mtu[0]
          except Exception:
              return None
-@@ -403,7 +413,8 @@ def py_which(executable):
+@@ -402,8 +413,27 @@ def py_which(executable):
+                for path in os.environ["PATH"].split(os.pathsep))
  
  
++def teardown(db_sock, interface, mirror_interface, tap_created):
++    def cleanup_mirror():
++        try:
++            ovsdb = OVSDB(db_sock)
++            ovsdb.destroy_mirror(interface, ovsdb.port_bridge(interface))
++            ovsdb.destroy_port(mirror_interface, ovsdb.port_bridge(interface))
++            if tap_created is True:
++                _del_taps[sys.platform](mirror_interface)
++        except Exception:
++            print("Unable to tear down the ports and mirrors.")
++            print("Please use ovs-vsctl to remove the ports and mirrors"
++                  " created.")
++            print(" ex: ovs-vsctl --db=%s del-port %s" % (db_sock,
++                                                          mirror_interface))
++
++    add_hook(cleanup_mirror, None, True)
++
++
  def main():
 -    db_sock = 'unix:@RUNDIR@/db.sock'
 +    rundir = os.environ.get('OVS_RUNDIR', '@RUNDIR@')
@@ -65868,8 +66164,26 @@ index 82d1bedfa6..e12bab8895 100755
      interface = None
      tcpdargs = []
  
-@@ -500,6 +511,8 @@ def main():
-             pass
+@@ -485,6 +515,9 @@ def main():
+         print("ERROR: Mirror port (%s) exists for port %s." %
+               (mirror_interface, interface))
+         sys.exit(1)
++
++    teardown(db_sock, interface, mirror_interface, tap_created)
++
+     try:
+         ovsdb.make_port(mirror_interface, ovsdb.port_bridge(interface))
+         ovsdb.bridge_mirror(interface, mirror_interface,
+@@ -492,14 +525,10 @@ def main():
+                             mirror_select_all)
+     except OVSDBException as oe:
+         print("ERROR: Unable to properly setup the mirror: %s." % str(oe))
+-        try:
+-            ovsdb.destroy_port(mirror_interface, ovsdb.port_bridge(interface))
+-            if tap_created is True:
+-                _del_taps[sys.platform](mirror_interface)
+-        except Exception:
+-            pass
          sys.exit(1)
  
 +    ovsdb.close_idl()
@@ -65877,14 +66191,24 @@ index 82d1bedfa6..e12bab8895 100755
      pipes = _doexec(*([dump_cmd, '-i', mirror_interface] + tcpdargs))
      try:
          while pipes.poll() is None:
-@@ -512,6 +525,7 @@ def main():
+@@ -512,17 +541,6 @@ def main():
          if pipes.poll() is None:
              pipes.terminate()
  
-+        ovsdb = OVSDB(db_sock)
-         ovsdb.destroy_mirror(interface, ovsdb.port_bridge(interface))
-         ovsdb.destroy_port(mirror_interface, ovsdb.port_bridge(interface))
-         if tap_created is True:
+-        ovsdb.destroy_mirror(interface, ovsdb.port_bridge(interface))
+-        ovsdb.destroy_port(mirror_interface, ovsdb.port_bridge(interface))
+-        if tap_created is True:
+-            _del_taps[sys.platform](mirror_interface)
+-    except Exception:
+-        print("Unable to tear down the ports and mirrors.")
+-        print("Please use ovs-vsctl to remove the ports and mirrors created.")
+-        print(" ex: ovs-vsctl --db=%s del-port %s" % (db_sock,
+-                                                      mirror_interface))
+-        sys.exit(1)
+-
+     sys.exit(0)
+ 
+ 
 diff --git a/utilities/ovs-vsctl-bashcomp.bash b/utilities/ovs-vsctl-bashcomp.bash
 old mode 100755
 new mode 100644
@@ -66259,6 +66583,19 @@ index 5223aa8970..e328d8ead1 100644
          union ovsdb_atom atom;
  
          atom.uuid = m->uuid;
+diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml
+index 0c66326171..87d8f3e67a 100644
+--- a/vswitchd/vswitch.xml
++++ b/vswitchd/vswitch.xml
+@@ -2312,7 +2312,7 @@
+           lowest port-id is elected as the root.
+         </column>
+ 
+-        <column name="other_config" key="rstp-port-path-cost"
++        <column name="other_config" key="rstp-path-cost"
+                 type='{"type": "integer"}'>
+           The port path cost.  The Port's contribution, when it is
+           the Root Port, to the Root Path Cost for the Bridge.  By default the
 diff --git a/vtep/vtep-ctl.c b/vtep/vtep-ctl.c
 index ab552457d9..99c4adcd53 100644
 --- a/vtep/vtep-ctl.c
diff --git a/SPECS/openvswitch2.17.spec b/SPECS/openvswitch2.17.spec
index 4a48628..030aa4f 100644
--- a/SPECS/openvswitch2.17.spec
+++ b/SPECS/openvswitch2.17.spec
@@ -57,7 +57,7 @@ Summary: Open vSwitch
 Group: System Environment/Daemons daemon/database/utilities
 URL: http://www.openvswitch.org/
 Version: 2.17.0
-Release: 52%{?dist}
+Release: 53%{?dist}
 
 # Nearly all of openvswitch is ASL 2.0.  The bugtool is LGPLv2+, and the
 # lib/sflow*.[ch] files are SISSL
@@ -748,6 +748,20 @@ exit 0
 %endif
 
 %changelog
+* Wed Nov 02 2022 Open vSwitch CI <ovs-ci@redhat.com> - 2.17.0-53
+- Merging upstream branch-2.17 [RH git: 5c721e65a7]
+    Commit list:
+    fa95bf9621 ovs-tcpdump: Cleanup mirror port on SIGHUP/SIGTERM.
+    7ebef81f91 netdev-linux: Fix inability to apply QoS on ports with custom qdiscs. (#2138339)
+    037ef6301b tc: Fix misaligned writes while parsing pedit.
+    869e2e1ba0 odp-util: Add missing separator in format_odp_conntrack_action().
+    0aa55709fc vswitch.xml: Fix the name of rstp-path-cost option.
+    af459fa370 mac-learning: Fix learned fdb entries not age out issue.
+    c4336a1f12 ofproto-dpif-xlate: Update tunnel neighbor when receive gratuitous ARP.
+    683508cd4e bond: Fix crash while logging not yet enabled member.
+    41b178d525 netdev-dpdk: Fix tx_dropped counters value.
+
+
 * Wed Oct 26 2022 Open vSwitch CI <ovs-ci@redhat.com> - 2.17.0-52
 - Merging upstream branch-2.17 [RH git: 2e56cd8bfd]
     Commit list: