diff --git a/.openvswitch.metadata b/.openvswitch.metadata
index aae65b4..53d7d0a 100644
--- a/.openvswitch.metadata
+++ b/.openvswitch.metadata
@@ -1,5 +1,5 @@
 002450621b33c5690060345b0aac25bc2426d675  SOURCES/docutils-0.12.tar.gz
-722b63cd114c21041abda7b38d7f14e46338e3e0  SOURCES/openvswitch-2.17.0.tar.gz
+019c0a80416de57f0820850034e17ce2a4768910  SOURCES/openvswitch-2.17.0.tar.gz
 8509a716f9f936526f64fb23f313c5a9baf2f123  SOURCES/pyelftools-0.27.tar.gz
 d34f96421a86004aa5d26ecf975edefd09f948b1  SOURCES/Pygments-1.4.tar.gz
 3a11f130c63b057532ca37fe49c8967d0cbae1d5  SOURCES/Sphinx-1.2.3.tar.gz
diff --git a/SOURCES/openvswitch-2.17.0.patch b/SOURCES/openvswitch-2.17.0.patch
index 48590fe..d36876f 100644
--- a/SOURCES/openvswitch-2.17.0.patch
+++ b/SOURCES/openvswitch-2.17.0.patch
@@ -53567,7 +53567,7 @@ index b6b29c75e3..39a1fd388d 100644
          free(queue);
      }
 diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c
-index 620a451dec..5aa8a8ca3c 100644
+index 620a451dec..387773e927 100644
 --- a/lib/netdev-linux.c
 +++ b/lib/netdev-linux.c
 @@ -247,6 +247,14 @@ enum {
@@ -53606,6 +53606,15 @@ index 620a451dec..5aa8a8ca3c 100644
      nl_msg_end_nested(request, offset);
      nl_msg_end_nested(request, act_offset);
  }
+@@ -2721,7 +2732,7 @@ tc_del_matchall_policer(struct netdev *netdev)
+     }
+ 
+     id = tc_make_tcf_id(ifindex, block_id, prio, TC_INGRESS);
+-    err = tc_del_filter(&id);
++    err = tc_del_filter(&id, "matchall");
+     if (err) {
+         return err;
+     }
 @@ -2970,12 +2981,18 @@ netdev_linux_set_qos(struct netdev *netdev_,
          /* Delete existing qdisc. */
          error = tc_del_qdisc(netdev_);
@@ -53783,7 +53792,7 @@ index 94dc6a9b74..303b99daf4 100644
              .queue = rss_data->queue,
              .key_len = 0,
 diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c
-index 9845e8d3fe..93321989a9 100644
+index 9845e8d3fe..057fad412a 100644
 --- a/lib/netdev-offload-tc.c
 +++ b/lib/netdev-offload-tc.c
 @@ -44,6 +44,7 @@
@@ -53794,7 +53803,25 @@ index 9845e8d3fe..93321989a9 100644
  
  static struct hmap ufid_to_tc = HMAP_INITIALIZER(&ufid_to_tc);
  static struct hmap tc_to_ufid = HMAP_INITIALIZER(&tc_to_ufid);
-@@ -417,11 +418,11 @@ delete_chains_from_netdev(struct netdev *netdev, struct tcf_id *id)
+@@ -204,7 +205,7 @@ del_filter_and_ufid_mapping(struct tcf_id *id, const ovs_u128 *ufid)
+ {
+     int err;
+ 
+-    err = tc_del_filter(id);
++    err = tc_del_flower_filter(id);
+     if (!err) {
+         del_ufid_tc_mapping(ufid);
+     }
+@@ -405,7 +406,7 @@ delete_chains_from_netdev(struct netdev *netdev, struct tcf_id *id)
+          */
+         HMAP_FOR_EACH_POP (chain_node, node, &map) {
+             id->chain = chain_node->chain;
+-            tc_del_filter(id);
++            tc_del_flower_filter(id);
+             free(chain_node);
+         }
+     }
+@@ -417,16 +418,16 @@ delete_chains_from_netdev(struct netdev *netdev, struct tcf_id *id)
  static int
  netdev_tc_flow_flush(struct netdev *netdev)
  {
@@ -53808,6 +53835,12 @@ index 9845e8d3fe..93321989a9 100644
          if (data->netdev != netdev) {
              continue;
          }
+ 
+-        err = tc_del_filter(&data->id);
++        err = tc_del_flower_filter(&data->id);
+         if (!err) {
+             del_ufid_tc_mapping_unlocked(&data->ufid);
+         }
 @@ -481,10 +482,10 @@ netdev_tc_flow_dump_destroy(struct netdev_flow_dump *dump)
  
  static void
@@ -53934,6 +53967,26 @@ index 9845e8d3fe..93321989a9 100644
              }
              break;
              case TC_ACT_ENCAP: {
+@@ -965,13 +987,13 @@ parse_tc_flower_to_match(struct tc_flower *flower,
+                     struct {
+                         ovs_u128 key;
+                         ovs_u128 mask;
+-                    } *ct_label;
++                    } ct_label = {
++                        .key = action->ct.label,
++                        .mask = action->ct.label_mask,
++                    };
+ 
+-                    ct_label = nl_msg_put_unspec_uninit(buf,
+-                                                        OVS_CT_ATTR_LABELS,
+-                                                        sizeof *ct_label);
+-                    ct_label->key = action->ct.label;
+-                    ct_label->mask = action->ct.label_mask;
++                    nl_msg_put_unspec(buf, OVS_CT_ATTR_LABELS,
++                                      &ct_label, sizeof ct_label);
+                 }
+ 
+                 if (action->ct.nat_type) {
 @@ -1054,8 +1076,8 @@ netdev_tc_flow_dump_next(struct netdev_flow_dump *dump,
              continue;
          }
@@ -53945,7 +53998,26 @@ index 9845e8d3fe..93321989a9 100644
              continue;
          }
  
-@@ -1222,8 +1244,8 @@ parse_put_flow_set_masked_action(struct tc_flower *flower,
+@@ -1194,13 +1216,14 @@ parse_put_flow_ct_action(struct tc_flower *flower,
+                 break;
+                 case OVS_CT_ATTR_LABELS: {
+                     const struct {
+-                        ovs_u128 key;
+-                        ovs_u128 mask;
++                        ovs_32aligned_u128 key;
++                        ovs_32aligned_u128 mask;
+                     } *ct_label;
+ 
+                     ct_label = nl_attr_get_unspec(ct_attr, sizeof *ct_label);
+-                    action->ct.label = ct_label->key;
+-                    action->ct.label_mask = ct_label->mask;
++                    action->ct.label = get_32aligned_u128(&ct_label->key);
++                    action->ct.label_mask =
++                        get_32aligned_u128(&ct_label->mask);
+                 }
+                 break;
+             }
+@@ -1222,8 +1245,8 @@ parse_put_flow_set_masked_action(struct tc_flower *flower,
      uint64_t set_stub[1024 / 8];
      struct ofpbuf set_buf = OFPBUF_STUB_INITIALIZER(set_stub);
      char *set_data, *set_mask;
@@ -53956,7 +54028,7 @@ index 9845e8d3fe..93321989a9 100644
      const struct nlattr *attr;
      int i, j, type;
      size_t size;
-@@ -1265,14 +1287,6 @@ parse_put_flow_set_masked_action(struct tc_flower *flower,
+@@ -1265,14 +1288,6 @@ parse_put_flow_set_masked_action(struct tc_flower *flower,
          }
      }
  
@@ -53971,7 +54043,7 @@ index 9845e8d3fe..93321989a9 100644
      if (hasmask && !is_all_zeros(set_mask, size)) {
          VLOG_DBG_RL(&rl, "unsupported sub attribute of set action type %d",
                      type);
-@@ -1281,6 +1295,8 @@ parse_put_flow_set_masked_action(struct tc_flower *flower,
+@@ -1281,6 +1296,8 @@ parse_put_flow_set_masked_action(struct tc_flower *flower,
      }
  
      ofpbuf_uninit(&set_buf);
@@ -53980,7 +54052,7 @@ index 9845e8d3fe..93321989a9 100644
      return 0;
  }
  
-@@ -1288,6 +1304,7 @@ static int
+@@ -1288,6 +1305,7 @@ static int
  parse_put_flow_set_action(struct tc_flower *flower, struct tc_action *action,
                            const struct nlattr *set, size_t set_len)
  {
@@ -53988,7 +54060,7 @@ index 9845e8d3fe..93321989a9 100644
      const struct nlattr *tunnel;
      const struct nlattr *tun_attr;
      size_t tun_left, tunnel_len;
-@@ -1306,6 +1323,7 @@ parse_put_flow_set_action(struct tc_flower *flower, struct tc_action *action,
+@@ -1306,6 +1324,7 @@ parse_put_flow_set_action(struct tc_flower *flower, struct tc_action *action,
  
      action->type = TC_ACT_ENCAP;
      action->encap.id_present = false;
@@ -53996,7 +54068,7 @@ index 9845e8d3fe..93321989a9 100644
      flower->action_count++;
      NL_ATTR_FOR_EACH_UNSAFE(tun_attr, tun_left, tunnel, tunnel_len) {
          switch (nl_attr_type(tun_attr)) {
-@@ -1330,6 +1348,18 @@ parse_put_flow_set_action(struct tc_flower *flower, struct tc_action *action,
+@@ -1330,6 +1349,18 @@ parse_put_flow_set_action(struct tc_flower *flower, struct tc_action *action,
              action->encap.ttl = nl_attr_get_u8(tun_attr);
          }
          break;
@@ -54015,7 +54087,7 @@ index 9845e8d3fe..93321989a9 100644
          case OVS_TUNNEL_KEY_ATTR_IPV6_SRC: {
              action->encap.ipv6.ipv6_src =
                  nl_attr_get_in6_addr(tun_attr);
-@@ -1354,12 +1384,31 @@ parse_put_flow_set_action(struct tc_flower *flower, struct tc_action *action,
+@@ -1354,12 +1385,31 @@ parse_put_flow_set_action(struct tc_flower *flower, struct tc_action *action,
              action->encap.data.present.len = nl_attr_get_size(tun_attr);
          }
          break;
@@ -54047,7 +54119,7 @@ index 9845e8d3fe..93321989a9 100644
  static int
  test_key_and_mask(struct match *match)
  {
-@@ -1442,8 +1491,23 @@ test_key_and_mask(struct match *match)
+@@ -1442,8 +1492,23 @@ test_key_and_mask(struct match *match)
          return EOPNOTSUPP;
      }
  
@@ -54072,7 +54144,7 @@ index 9845e8d3fe..93321989a9 100644
          return EOPNOTSUPP;
      }
  
-@@ -1452,18 +1516,51 @@ test_key_and_mask(struct match *match)
+@@ -1452,18 +1517,51 @@ test_key_and_mask(struct match *match)
  
  static void
  flower_match_to_tun_opt(struct tc_flower *flower, const struct flow_tnl *tnl,
@@ -54127,7 +54199,7 @@ index 9845e8d3fe..93321989a9 100644
      len = flower->key.tunnel.metadata.present.len;
      while (len) {
          opt = &flower->key.tunnel.metadata.opts.gnv[cnt];
-@@ -1474,8 +1571,6 @@ flower_match_to_tun_opt(struct tc_flower *flower, const struct flow_tnl *tnl,
+@@ -1474,8 +1572,6 @@ flower_match_to_tun_opt(struct tc_flower *flower, const struct flow_tnl *tnl,
          cnt += sizeof(struct geneve_opt) / 4 + opt->length;
          len -= sizeof(struct geneve_opt) + opt->length * 4;
      }
@@ -54136,7 +54208,7 @@ index 9845e8d3fe..93321989a9 100644
  }
  
  static void
-@@ -1541,6 +1636,12 @@ parse_match_ct_state_to_flower(struct tc_flower *flower, struct match *match)
+@@ -1541,6 +1637,12 @@ parse_match_ct_state_to_flower(struct tc_flower *flower, struct match *match)
              flower->key.ct_state &= ~(TCA_FLOWER_KEY_CT_FLAGS_NEW);
              flower->mask.ct_state &= ~(TCA_FLOWER_KEY_CT_FLAGS_NEW);
          }
@@ -54149,7 +54221,7 @@ index 9845e8d3fe..93321989a9 100644
      }
  
      if (mask->ct_zone) {
-@@ -1574,7 +1675,7 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match,
+@@ -1574,7 +1676,7 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match,
      const struct flow *key = &match->flow;
      struct flow *mask = &match->wc.masks;
      const struct flow_tnl *tnl = &match->flow.tunnel;
@@ -54158,7 +54230,7 @@ index 9845e8d3fe..93321989a9 100644
      struct tc_action *action;
      bool recirc_act = false;
      uint32_t block_id = 0;
-@@ -1615,17 +1716,49 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match,
+@@ -1615,17 +1717,49 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match,
          flower.key.tunnel.ttl = tnl->ip_ttl;
          flower.key.tunnel.tp_src = tnl->tp_src;
          flower.key.tunnel.tp_dst = tnl->tp_dst;
@@ -54210,7 +54282,7 @@ index 9845e8d3fe..93321989a9 100644
  
      flower.key.eth_type = key->dl_type;
      flower.mask.eth_type = mask->dl_type;
-@@ -1638,7 +1771,7 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match,
+@@ -1638,7 +1772,7 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match,
  
      if (mask->vlans[0].tpid && eth_type_vlan(key->vlans[0].tpid)) {
          flower.key.encap_eth_type[0] = flower.key.eth_type;
@@ -54219,7 +54291,7 @@ index 9845e8d3fe..93321989a9 100644
          flower.key.eth_type = key->vlans[0].tpid;
          flower.mask.eth_type = mask->vlans[0].tpid;
      }
-@@ -1734,7 +1867,7 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match,
+@@ -1734,7 +1868,7 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match,
              memset(&mask->arp_tha, 0, sizeof mask->arp_tha);
      }
  
@@ -54228,7 +54300,7 @@ index 9845e8d3fe..93321989a9 100644
          flower.key.ip_proto = key->nw_proto;
          flower.mask.ip_proto = mask->nw_proto;
          mask->nw_proto = 0;
-@@ -1841,7 +1974,25 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match,
+@@ -1841,7 +1975,25 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match,
                  VLOG_DBG_RL(&rl, "Can't find netdev for output port %d", port);
                  return ENODEV;
              }
@@ -54254,7 +54326,7 @@ index 9845e8d3fe..93321989a9 100644
              action->out.ingress = is_internal_port(netdev_get_type(outdev));
              action->type = TC_ACT_OUTPUT;
              flower.action_count++;
-@@ -1879,10 +2030,6 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match,
+@@ -1879,10 +2031,6 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match,
              if (err) {
                  return err;
              }
@@ -54265,7 +54337,7 @@ index 9845e8d3fe..93321989a9 100644
          } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_SET_MASKED) {
              const struct nlattr *set = nl_attr_get(nla);
              const size_t set_len = nl_attr_get_size(nla);
-@@ -1989,7 +2136,8 @@ netdev_tc_flow_get(struct netdev *netdev,
+@@ -1989,7 +2137,8 @@ netdev_tc_flow_get(struct netdev *netdev,
      }
  
      in_port = netdev_ifindex_to_odp_port(id.ifindex);
@@ -54275,7 +54347,7 @@ index 9845e8d3fe..93321989a9 100644
  
      match->wc.masks.in_port.odp_port = u32_to_odp(UINT32_MAX);
      match->flow.in_port.odp_port = in_port;
-@@ -2015,9 +2163,7 @@ netdev_tc_flow_del(struct netdev *netdev OVS_UNUSED,
+@@ -2015,9 +2164,7 @@ netdev_tc_flow_del(struct netdev *netdev OVS_UNUSED,
      if (stats) {
          memset(stats, 0, sizeof *stats);
          if (!tc_get_flower(&id, &flower)) {
@@ -54286,6 +54358,67 @@ index 9845e8d3fe..93321989a9 100644
          }
      }
  
+@@ -2077,13 +2224,13 @@ probe_multi_mask_per_prio(int ifindex)
+ 
+     id2 = tc_make_tcf_id(ifindex, block_id, prio, TC_INGRESS);
+     error = tc_replace_flower(&id2, &flower);
+-    tc_del_filter(&id1);
++    tc_del_flower_filter(&id1);
+ 
+     if (error) {
+         goto out;
+     }
+ 
+-    tc_del_filter(&id2);
++    tc_del_flower_filter(&id2);
+ 
+     multi_mask_per_prio = true;
+     VLOG_INFO("probe tc: multiple masks on single tc prio is supported.");
+@@ -2135,7 +2282,7 @@ probe_ct_state_support(int ifindex)
+         goto out_del;
+     }
+ 
+-    tc_del_filter(&id);
++    tc_del_flower_filter(&id);
+     ct_state_support = OVS_CS_F_NEW |
+                        OVS_CS_F_ESTABLISHED |
+                        OVS_CS_F_TRACKED |
+@@ -2149,7 +2296,7 @@ probe_ct_state_support(int ifindex)
+         goto out_del;
+     }
+ 
+-    tc_del_filter(&id);
++    tc_del_flower_filter(&id);
+ 
+     /* Test for ct_state INVALID support */
+     memset(&flower, 0, sizeof flower);
+@@ -2160,7 +2307,7 @@ probe_ct_state_support(int ifindex)
+         goto out;
+     }
+ 
+-    tc_del_filter(&id);
++    tc_del_flower_filter(&id);
+     ct_state_support |= OVS_CS_F_INVALID;
+ 
+     /* Test for ct_state REPLY support */
+@@ -2176,7 +2323,7 @@ probe_ct_state_support(int ifindex)
+     ct_state_support |= OVS_CS_F_REPLY_DIR;
+ 
+ out_del:
+-    tc_del_filter(&id);
++    tc_del_flower_filter(&id);
+ out:
+     tc_add_del_qdisc(ifindex, false, 0, TC_INGRESS);
+     VLOG_INFO("probe tc: supported ovs ct_state bits: 0x%x", ct_state_support);
+@@ -2251,7 +2398,7 @@ netdev_tc_init_flow_api(struct netdev *netdev)
+ 
+     /* fallback here if delete chains fail */
+     if (!get_chain_supported) {
+-        tc_del_filter(&id);
++        tc_del_flower_filter(&id);
+     }
+ 
+     /* make sure there is no ingress/egress qdisc */
 diff --git a/lib/netdev-offload.c b/lib/netdev-offload.c
 index fb108c0d50..eea8fadc0e 100644
 --- a/lib/netdev-offload.c
@@ -56191,7 +56324,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..8bc999ca83 100644
+index adb2d3182a..485e4834f8 100644
 --- a/lib/tc.c
 +++ b/lib/tc.c
 @@ -84,6 +84,11 @@ struct flower_key_to_pedit {
@@ -56593,7 +56726,38 @@ index adb2d3182a..8bc999ca83 100644
  }
  
  #define TCA_ACT_MIN_PRIO 1
-@@ -2399,14 +2489,14 @@ nl_msg_put_act_flags(struct ofpbuf *request) {
+@@ -1964,14 +2054,21 @@ tc_dump_tc_chain_start(struct tcf_id *id, struct nl_dump *dump)
+ }
+ 
+ int
+-tc_del_filter(struct tcf_id *id)
++tc_del_filter(struct tcf_id *id, const char *kind)
+ {
+     struct ofpbuf request;
+ 
+     request_from_tcf_id(id, 0, RTM_DELTFILTER, NLM_F_ACK, &request);
++    nl_msg_put_string(&request, TCA_KIND, kind);
+     return tc_transact(&request, NULL);
+ }
+ 
++int
++tc_del_flower_filter(struct tcf_id *id)
++{
++    return tc_del_filter(id, "flower");
++}
++
+ int
+ tc_get_flower(struct tcf_id *id, struct tc_flower *flower)
+ {
+@@ -1980,6 +2077,7 @@ tc_get_flower(struct tcf_id *id, struct tc_flower *flower)
+     int error;
+ 
+     request_from_tcf_id(id, 0, RTM_GETTFILTER, NLM_F_ECHO, &request);
++    nl_msg_put_string(&request, TCA_KIND, "flower");
+     error = tc_transact(&request, &reply);
+     if (error) {
+         return error;
+@@ -2399,14 +2497,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
@@ -56611,7 +56775,7 @@ index adb2d3182a..8bc999ca83 100644
  
      max_offset = m->offset + m->size;
      start_offset = ROUND_DOWN(m->offset, 4);
-@@ -2473,7 +2563,8 @@ csum_update_flag(struct tc_flower *flower,
+@@ -2473,7 +2571,8 @@ csum_update_flag(struct tc_flower *flower,
  
  static int
  nl_msg_put_flower_rewrite_pedits(struct ofpbuf *request,
@@ -56621,7 +56785,7 @@ index adb2d3182a..8bc999ca83 100644
  {
      struct {
          struct tc_pedit sel;
-@@ -2497,12 +2588,12 @@ nl_msg_put_flower_rewrite_pedits(struct ofpbuf *request,
+@@ -2497,12 +2596,12 @@ nl_msg_put_flower_rewrite_pedits(struct ofpbuf *request,
              continue;
          }
  
@@ -56637,7 +56801,7 @@ index adb2d3182a..8bc999ca83 100644
  
              if (j == 0) {
                  mask_word &= first_word_mask;
-@@ -2556,6 +2647,29 @@ nl_msg_put_flower_acts_release(struct ofpbuf *request, uint16_t act_index)
+@@ -2556,6 +2655,29 @@ nl_msg_put_flower_acts_release(struct ofpbuf *request, uint16_t act_index)
      nl_msg_end_nested(request, act_offset);
  }
  
@@ -56667,7 +56831,7 @@ index adb2d3182a..8bc999ca83 100644
  static int
  nl_msg_put_flower_acts(struct ofpbuf *request, struct tc_flower *flower)
  {
-@@ -2572,20 +2686,22 @@ nl_msg_put_flower_acts(struct ofpbuf *request, struct tc_flower *flower)
+@@ -2572,20 +2694,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++) {
@@ -56696,7 +56860,7 @@ index adb2d3182a..8bc999ca83 100644
                  }
              }
              break;
-@@ -2792,13 +2908,16 @@ nl_msg_put_flower_tunnel(struct ofpbuf *request, struct tc_flower *flower)
+@@ -2792,13 +2916,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;
@@ -56714,7 +56878,7 @@ index adb2d3182a..8bc999ca83 100644
  
      if (ipv4_dst_mask || ipv4_src_mask) {
          nl_msg_put_be32(request, TCA_FLOWER_KEY_ENC_IPV4_DST_MASK,
-@@ -2824,8 +2943,15 @@ nl_msg_put_flower_tunnel(struct ofpbuf *request, struct tc_flower *flower)
+@@ -2824,8 +2951,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);
      }
@@ -56731,7 +56895,7 @@ index adb2d3182a..8bc999ca83 100644
      }
      if (id_mask) {
          nl_msg_put_be32(request, TCA_FLOWER_KEY_ENC_KEY_ID, id);
-@@ -2914,13 +3040,13 @@ nl_msg_put_flower_options(struct ofpbuf *request, struct tc_flower *flower)
+@@ -2914,13 +3048,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);
          }
@@ -56750,7 +56914,7 @@ index adb2d3182a..8bc999ca83 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 +3119,79 @@ nl_msg_put_flower_options(struct ofpbuf *request, struct tc_flower *flower)
+@@ -2993,12 +3127,79 @@ nl_msg_put_flower_options(struct ofpbuf *request, struct tc_flower *flower)
      return 0;
  }
  
@@ -56831,7 +56995,7 @@ index adb2d3182a..8bc999ca83 100644
          return false;
      }
  
-@@ -3011,8 +3204,8 @@ cmp_tc_flower_match_action(const struct tc_flower *a,
+@@ -3011,8 +3212,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) {
@@ -56842,7 +57006,7 @@ index adb2d3182a..8bc999ca83 100644
              return false;
          }
      }
-@@ -3022,14 +3215,15 @@ cmp_tc_flower_match_action(const struct tc_flower *a,
+@@ -3022,14 +3223,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) {
@@ -56862,7 +57026,7 @@ index adb2d3182a..8bc999ca83 100644
          }
      }
 diff --git a/lib/tc.h b/lib/tc.h
-index a147ca461d..d6cdddd169 100644
+index a147ca461d..55bed0853a 100644
 --- a/lib/tc.h
 +++ b/lib/tc.h
 @@ -256,11 +256,23 @@ struct tc_action {
@@ -56907,7 +57071,7 @@ index a147ca461d..d6cdddd169 100644
      uint32_t csum_update_flags;
  
      bool tunnel;
-@@ -352,13 +359,6 @@ struct tc_flower {
+@@ -352,15 +359,9 @@ struct tc_flower {
      enum tc_offload_policy tc_policy;
  };
  
@@ -56919,8 +57083,12 @@ index a147ca461d..d6cdddd169 100644
 -                  + sizeof(uint32_t) - 2 < sizeof(struct tc_flower));
 -
  int tc_replace_flower(struct tcf_id *id, struct tc_flower *flower);
- int tc_del_filter(struct tcf_id *id);
+-int tc_del_filter(struct tcf_id *id);
++int tc_del_filter(struct tcf_id *id, const char *kind);
++int tc_del_flower_filter(struct tcf_id *id);
  int tc_get_flower(struct tcf_id *id, struct tc_flower *flower);
+ int tc_dump_flower_start(struct tcf_id *id, struct nl_dump *dump, bool terse);
+ int tc_dump_tc_chain_start(struct tcf_id *id, struct nl_dump *dump);
 diff --git a/lib/tnl-ports.c b/lib/tnl-ports.c
 index 58269d3b16..050eafa6b8 100644
 --- a/lib/tnl-ports.c
@@ -59514,7 +59682,7 @@ index d4a9e34cc4..df2e373c3c 100644
          free(leader);
      }
 diff --git a/ovsdb/ovsdb.c b/ovsdb/ovsdb.c
-index e6d866182c..91b4a01af8 100644
+index e6d866182c..3eb6ce870a 100644
 --- a/ovsdb/ovsdb.c
 +++ b/ovsdb/ovsdb.c
 @@ -571,8 +571,8 @@ ovsdb_replace(struct ovsdb *dst, struct ovsdb *src)
@@ -59528,6 +59696,15 @@ index e6d866182c..91b4a01af8 100644
          ovsdb_trigger_prereplace_db(trigger);
      }
  
+@@ -587,5 +587,8 @@ ovsdb_replace(struct ovsdb *dst, struct ovsdb *src)
+ 
+     dst->rbac_role = ovsdb_get_table(dst, "RBAC_Role");
+ 
++    /* Get statistics from the new database. */
++    dst->n_atoms = src->n_atoms;
++
+     ovsdb_destroy(src);
+ }
 diff --git a/ovsdb/query.c b/ovsdb/query.c
 index de74519989..eebe564127 100644
 --- a/ovsdb/query.c
@@ -64359,7 +64536,7 @@ index 62e2b63832..092d9f81a2 100644
 +006: done
 +]])
 diff --git a/tests/ovsdb-server.at b/tests/ovsdb-server.at
-index 876cb836cd..d49de0daa4 100644
+index 876cb836cd..4a183bf186 100644
 --- a/tests/ovsdb-server.at
 +++ b/tests/ovsdb-server.at
 @@ -4,7 +4,7 @@ m4_define([OVSDB_SERVER_SHUTDOWN],
@@ -64461,7 +64638,32 @@ index 876cb836cd..d49de0daa4 100644
          n=0
      fi
      echo $n
-@@ -1319,15 +1318,14 @@ m4_define([OVSDB_CHECK_EXECUTION],
+@@ -1293,6 +1292,24 @@ dnl After removing all the bridges, the number of atoms in the database
+ dnl should return to its initial value.
+ AT_CHECK([test $(get_memory_value atoms) -eq $initial_db_atoms])
+ 
++dnl Add a few more resources.
++for i in $(seq 1 10); do
++    cmd=$(add_ports $i $(($i / 4 + 1)))
++    AT_CHECK([ovs-vsctl --no-wait add-br br$i $cmd])
++done
++check_atoms
++
++db_atoms_before_conversion=$(get_memory_value atoms)
++
++dnl Trigger online conversion.
++AT_CHECK([ovsdb-client convert $abs_top_srcdir/vswitchd/vswitch.ovsschema],
++         [0], [ignore], [ignore])
++
++dnl Check that conversion didn't change the number of atoms and the history
++dnl still has a reasonable size.
++check_atoms
++AT_CHECK([test $(get_memory_value atoms) -eq $db_atoms_before_conversion])
++
+ OVS_APP_EXIT_AND_WAIT([ovsdb-server])
+ AT_CLEANUP
+ 
+@@ -1319,15 +1336,14 @@ m4_define([OVSDB_CHECK_EXECUTION],
     $2 > schema
     PKIDIR=$abs_top_builddir/tests
     AT_CHECK([ovsdb-tool create db schema], [0], [stdout], [ignore])
@@ -64480,7 +64682,7 @@ index 876cb836cd..d49de0daa4 100644
     OVSDB_SERVER_SHUTDOWN
     AT_CLEANUP])
  
-@@ -1356,16 +1354,15 @@ m4_define([OVSDB_CHECK_EXECUTION],
+@@ -1356,16 +1372,15 @@ m4_define([OVSDB_CHECK_EXECUTION],
     AT_SKIP_IF([test $HAVE_IPV6 = no])
     $2 > schema
     PKIDIR=$abs_top_builddir/tests
@@ -64500,7 +64702,7 @@ index 876cb836cd..d49de0daa4 100644
     OVSDB_SERVER_SHUTDOWN
     AT_CLEANUP])
  
-@@ -1392,16 +1389,15 @@ m4_define([OVSDB_CHECK_EXECUTION],
+@@ -1392,16 +1407,15 @@ m4_define([OVSDB_CHECK_EXECUTION],
     AT_KEYWORDS([ovsdb server positive tcp $5])
     $2 > schema
     PKIDIR=$abs_top_builddir/tests
@@ -64520,7 +64722,7 @@ index 876cb836cd..d49de0daa4 100644
     OVSDB_SERVER_SHUTDOWN
     AT_CLEANUP])
  
-@@ -1429,16 +1425,15 @@ m4_define([OVSDB_CHECK_EXECUTION],
+@@ -1429,16 +1443,15 @@ m4_define([OVSDB_CHECK_EXECUTION],
     AT_SKIP_IF([test $HAVE_IPV6 = no])
     $2 > schema
     PKIDIR=$abs_top_builddir/tests
@@ -64540,7 +64742,7 @@ index 876cb836cd..d49de0daa4 100644
     OVSDB_SERVER_SHUTDOWN
     AT_CLEANUP])
  
-@@ -1518,9 +1513,9 @@ m4_define([OVSDB_CHECK_EXECUTION],
+@@ -1518,9 +1531,9 @@ m4_define([OVSDB_CHECK_EXECUTION],
     target=4
     $2 > schema
     schema_name=`ovsdb-tool schema-name schema`
@@ -64551,7 +64753,7 @@ index 876cb836cd..d49de0daa4 100644
     AT_CHECK([ovsdb-server --detach --no-chdir --log-file=ovsdb-server1.log dnl
                            --pidfile --remote=punix:db1.sock db1
              ], [0], [ignore], [ignore])
-@@ -1576,12 +1571,11 @@ m4_define([OVSDB_CHECK_EXECUTION],
+@@ -1576,12 +1589,11 @@ m4_define([OVSDB_CHECK_EXECUTION],
     AT_CHECK([ovsdb-tool create db1 schema], [0], [stdout], [ignore])
     AT_CHECK([ovsdb-tool create db2 schema], [0], [stdout], [ignore])
  
@@ -64566,7 +64768,7 @@ index 876cb836cd..d49de0daa4 100644
  
     m4_foreach([txn], [$3],
       [AT_CHECK([ovsdb-client transact 'txn'], [0], [stdout], [ignore])
-@@ -1622,11 +1616,10 @@ m4_define([OVSDB_CHECK_REPLICATION],
+@@ -1622,11 +1634,10 @@ m4_define([OVSDB_CHECK_REPLICATION],
     AT_CHECK([ovsdb-tool create db1 schema], [0], [stdout], [ignore])
     AT_CHECK([ovsdb-tool create db2 schema], [0], [stdout], [ignore])
  
@@ -64580,7 +64782,7 @@ index 876cb836cd..d49de0daa4 100644
  
     m4_foreach([txn], [$3],
       [AT_CHECK([ ovsdb-client transact 'txn' ], [0], [stdout], [ignore])
-@@ -1694,6 +1687,7 @@ AT_CLEANUP
+@@ -1694,6 +1705,7 @@ AT_CLEANUP
  
  #ovsdb-server/set-sync-exclude-tables command
  AT_SETUP([ovsdb-server/set-sync-exclude-tables])
@@ -64588,7 +64790,7 @@ index 876cb836cd..d49de0daa4 100644
  AT_KEYWORDS([ovsdb server replication set-exclude-tables])
  AT_SKIP_IF([test $DIFF_SUPPORTS_NORMAL_FORMAT = no])
  
-@@ -1702,12 +1696,10 @@ AT_CHECK([ovsdb-tool create db1 schema], [0], [stdout], [ignore])
+@@ -1702,12 +1714,10 @@ AT_CHECK([ovsdb-tool create db1 schema], [0], [stdout], [ignore])
  AT_CHECK([ovsdb-tool create db2 schema], [0], [stdout], [ignore])
  
  AT_CHECK([ovsdb-server --detach --no-chdir --log-file=ovsdb-server1.log --pidfile --remote=punix:db.sock db1], [0], [ignore], [ignore])
@@ -64603,7 +64805,7 @@ index 876cb836cd..d49de0daa4 100644
  
  AT_CHECK([ovsdb-client transact unix:db.sock \
   '[["mydb",
-@@ -1716,11 +1708,9 @@ AT_CHECK([ovsdb-client transact unix:db.sock \
+@@ -1716,11 +1726,9 @@ AT_CHECK([ovsdb-client transact unix:db.sock \
        "row": {"number": 0, "name": "zero"}},
      {"op": "insert",
        "table": "b",
@@ -64617,7 +64819,7 @@ index 876cb836cd..d49de0daa4 100644
  cat stdout > dump1
  OVS_WAIT_UNTIL([ ovsdb-client dump unix:db2.sock | grep zero ])
  AT_CHECK([ovsdb-client dump unix:db2.sock], [0], [stdout], [ignore])
-@@ -1744,16 +1734,15 @@ AT_CLEANUP
+@@ -1744,16 +1752,15 @@ AT_CLEANUP
  
  #ovsdb-server/connect-active-ovsdb-server
  AT_SETUP([ovsdb-server/connect-active-server])
@@ -64636,7 +64838,7 @@ index 876cb836cd..d49de0daa4 100644
  
  dnl Try to connect without specifying the active server.
  AT_CHECK([ovs-appctl -t "`pwd`"/unixctl2 ovsdb-server/connect-active-ovsdb-server], [0],
-@@ -1783,6 +1772,7 @@ AT_CLEANUP
+@@ -1783,6 +1790,7 @@ AT_CLEANUP
  
  #ovsdb-server/disconnect-active-server command
  AT_SETUP([ovsdb-server/disconnect-active-server])
@@ -64644,7 +64846,7 @@ index 876cb836cd..d49de0daa4 100644
  AT_KEYWORDS([ovsdb server replication disconnect-active-server])
  AT_SKIP_IF([test $DIFF_SUPPORTS_NORMAL_FORMAT = no])
  
-@@ -1791,10 +1781,8 @@ AT_CHECK([ovsdb-tool create db1 schema], [0], [stdout], [ignore])
+@@ -1791,10 +1799,8 @@ AT_CHECK([ovsdb-tool create db1 schema], [0], [stdout], [ignore])
  AT_CHECK([ovsdb-tool create db2 schema], [0], [stdout], [ignore])
  
  AT_CHECK([ovsdb-server --detach --no-chdir --log-file=ovsdb-server1.log --pidfile --remote=punix:db.sock db1], [0], [ignore], [ignore])
@@ -64656,7 +64858,7 @@ index 876cb836cd..d49de0daa4 100644
  
  AT_CHECK([ovsdb-client transact unix:db.sock \
  '[["mydb",
-@@ -1840,7 +1828,7 @@ AT_CHECK([uuidfilt output], [0], [7,9c7,8
+@@ -1840,7 +1846,7 @@ AT_CHECK([uuidfilt output], [0], [7,9c7,8
  ---
  > _uuid name number
  > ----- ---- ------
@@ -64665,7 +64867,7 @@ index 876cb836cd..d49de0daa4 100644
  
  dnl The backup server now become active, and can accept write transactions.
  AT_CHECK([ovsdb-client transact unix:db2.sock \
-@@ -1891,13 +1879,12 @@ dnl Start both 'db1' and 'db2' in backup mode. Let them backup from each
+@@ -1891,13 +1897,12 @@ dnl Start both 'db1' and 'db2' in backup mode. Let them backup from each
  dnl other. This is not an supported operation state, but to simulate a start
  dnl up condition where an HA manger can select which one to be an active
  dnl server soon after.
@@ -64682,7 +64884,7 @@ index 876cb836cd..d49de0daa4 100644
  
  dnl
  dnl make sure both servers reached the replication state
-@@ -1965,8 +1952,8 @@ AT_CHECK([ovsdb-tool transact db \
+@@ -1965,8 +1970,8 @@ AT_CHECK([ovsdb-tool transact db \
     "row": {"number": 9, "name": "nine"}}]]'], [0], [ignore], [ignore])
  
  dnl Start 'db', then try to be a back up server of itself.
@@ -64693,7 +64895,7 @@ index 876cb836cd..d49de0daa4 100644
  
  dnl Save the current content
  AT_CHECK([ovsdb-client dump unix:db.sock], [0], [stdout])
-@@ -1984,6 +1971,7 @@ AT_CHECK([diff dump1 dump2])
+@@ -1984,6 +1989,7 @@ AT_CHECK([diff dump1 dump2])
  AT_CLEANUP
  
  AT_SETUP([ovsdb-server/read-only db:ptcp connection])
@@ -64701,7 +64903,7 @@ index 876cb836cd..d49de0daa4 100644
  AT_KEYWORDS([ovsdb server read-only])
  AT_DATA([schema],
    [[{"name": "mydb",
-@@ -2072,12 +2060,10 @@ AT_CHECK([ovsdb-tool transact db2 \
+@@ -2072,12 +2078,10 @@ AT_CHECK([ovsdb-tool transact db2 \
     "row": {"number": 10, "name": "ten"}}]]'], [0], [ignore], [ignore])
  
  dnl Start both 'db1' and 'db2'.
@@ -64717,7 +64919,7 @@ index 876cb836cd..d49de0daa4 100644
  
  OVS_WAIT_UNTIL([ovs-appctl -t "`pwd`"/unixctl ovsdb-server/sync-status |grep active])
  OVS_WAIT_UNTIL([ovs-appctl -t "`pwd`"/unixctl2 ovsdb-server/sync-status |grep active])
-@@ -2177,7 +2163,7 @@ dnl Starting a dummy server only to reserve some tcp port.
+@@ -2177,7 +2181,7 @@ dnl Starting a dummy server only to reserve some tcp port.
  AT_CHECK([cp db db.tmp])
  AT_CHECK([ovsdb-server -vfile -vvlog:off --log-file=listener.log  dnl
              --detach --no-chdir                                   dnl
diff --git a/SPECS/openvswitch2.17.spec b/SPECS/openvswitch2.17.spec
index b97ad5a..6d78cf4 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: 62%{?dist}
+Release: 63%{?dist}
 
 # Nearly all of openvswitch is ASL 2.0.  The bugtool is LGPLv2+, and the
 # lib/sflow*.[ch] files are SISSL
@@ -748,6 +748,14 @@ exit 0
 %endif
 
 %changelog
+* Mon Jan 30 2023 Open vSwitch CI <ovs-ci@redhat.com> - 2.17.0-63
+- Merging upstream branch-2.17 [RH git: 64bd43b450]
+    Commit list:
+    32853c0844 tc: Add TCA_KIND flower to delete and get operation to avoid rtnl_lock().
+    037131229b netdev-offload-tc: Fix misaligned access to ct label.
+    206409bb79 ovsdb: Fix database statistics during the database replacement.
+
+
 * Mon Jan 09 2023 Open vSwitch CI <ovs-ci@redhat.com> - 2.17.0-62
 - Merging upstream branch-2.17 [RH git: 19293654b8]
     Commit list: