From bace2549d4b47524ba417b8dbbed00e4fffadb5b Mon Sep 17 00:00:00 2001 From: Open vSwitch CI Date: Jan 10 2023 03:11:43 +0000 Subject: Import openvswitch2.17-2.17.0-71 from Fast DataPath --- diff --git a/SOURCES/openvswitch-2.17.0.patch b/SOURCES/openvswitch-2.17.0.patch index a7c9106..48590fe 100644 --- a/SOURCES/openvswitch-2.17.0.patch +++ b/SOURCES/openvswitch-2.17.0.patch @@ -45,7 +45,7 @@ index 1fe890846e..321b9bf86e 100755 if [ "$M32" ]; then # Installing 32-bit libraries. diff --git a/.cirrus.yml b/.cirrus.yml -index a7ae793bc4..29be50029b 100644 +index a7ae793bc4..2fadab64a7 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -2,8 +2,8 @@ freebsd_build_task: @@ -54,7 +54,7 @@ index a7ae793bc4..29be50029b 100644 matrix: - image_family: freebsd-12-2-snap - image_family: freebsd-11-4-snap -+ image_family: freebsd-12-3-snap ++ image_family: freebsd-12-4-snap + image_family: freebsd-13-1-snap cpu: 4 memory: 4G @@ -56191,10 +56191,22 @@ 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..900a631553 100644 +index adb2d3182a..8bc999ca83 100644 --- a/lib/tc.c +++ b/lib/tc.c -@@ -395,8 +395,14 @@ static const struct nl_policy tca_flower_policy[] = { +@@ -84,6 +84,11 @@ struct flower_key_to_pedit { + int boundary_shift; + }; + ++struct tc_flow_stats { ++ uint64_t n_packets; ++ uint64_t n_bytes; ++}; ++ + static struct flower_key_to_pedit flower_pedit_map[] = { + { + TCA_PEDIT_KEY_EX_HDR_TYPE_IP4, +@@ -395,8 +400,14 @@ static const struct nl_policy tca_flower_policy[] = { [TCA_FLOWER_KEY_ENC_IPV6_DST_MASK] = { .type = NL_A_UNSPEC, .min_len = sizeof(struct in6_addr), .optional = true, }, @@ -56209,7 +56221,7 @@ index adb2d3182a..900a631553 100644 [TCA_FLOWER_KEY_FLAGS] = { .type = NL_A_BE32, .optional = true, }, [TCA_FLOWER_KEY_FLAGS_MASK] = { .type = NL_A_BE32, .optional = true, }, [TCA_FLOWER_KEY_IP_TTL] = { .type = NL_A_U8, -@@ -568,16 +574,17 @@ nl_parse_flower_vlan(struct nlattr **attrs, struct tc_flower *flower) +@@ -568,16 +579,17 @@ nl_parse_flower_vlan(struct nlattr **attrs, struct tc_flower *flower) flower->key.encap_eth_type[0] = nl_attr_get_be16(attrs[TCA_FLOWER_KEY_ETH_TYPE]); @@ -56229,7 +56241,7 @@ index adb2d3182a..900a631553 100644 } if (!attrs[TCA_FLOWER_KEY_VLAN_ETH_TYPE]) { -@@ -590,17 +597,18 @@ nl_parse_flower_vlan(struct nlattr **attrs, struct tc_flower *flower) +@@ -590,17 +602,18 @@ nl_parse_flower_vlan(struct nlattr **attrs, struct tc_flower *flower) } flower->key.encap_eth_type[1] = flower->key.encap_eth_type[0]; @@ -56250,7 +56262,7 @@ index adb2d3182a..900a631553 100644 } } -@@ -705,15 +713,17 @@ flower_tun_geneve_opt_check_len(struct tun_metadata *key, +@@ -705,15 +718,17 @@ flower_tun_geneve_opt_check_len(struct tun_metadata *key, const struct geneve_opt *opt, *opt_mask; int len, cnt = 0; @@ -56271,7 +56283,7 @@ index adb2d3182a..900a631553 100644 } cnt += sizeof(struct geneve_opt) / 4 + opt->length; -@@ -721,6 +731,11 @@ flower_tun_geneve_opt_check_len(struct tun_metadata *key, +@@ -721,6 +736,11 @@ flower_tun_geneve_opt_check_len(struct tun_metadata *key, } return 0; @@ -56283,7 +56295,7 @@ index adb2d3182a..900a631553 100644 } static int -@@ -758,7 +773,15 @@ nl_parse_flower_tunnel(struct nlattr **attrs, struct tc_flower *flower) +@@ -758,7 +778,15 @@ nl_parse_flower_tunnel(struct nlattr **attrs, struct tc_flower *flower) flower->key.tunnel.ipv6.ipv6_dst = nl_attr_get_in6_addr(attrs[TCA_FLOWER_KEY_ENC_IPV6_DST]); } @@ -56300,7 +56312,7 @@ index adb2d3182a..900a631553 100644 flower->key.tunnel.tp_dst = nl_attr_get_be16(attrs[TCA_FLOWER_KEY_ENC_UDP_DST_PORT]); } -@@ -937,24 +960,21 @@ nl_parse_flower_ip(struct nlattr **attrs, struct tc_flower *flower) { +@@ -937,24 +965,21 @@ nl_parse_flower_ip(struct nlattr **attrs, struct tc_flower *flower) { key->icmp_code = nl_attr_get_u8(attrs[TCA_FLOWER_KEY_ICMPV4_CODE]); mask->icmp_code = @@ -56330,7 +56342,7 @@ index adb2d3182a..900a631553 100644 mask->icmp_type = nl_attr_get_u8(attrs[TCA_FLOWER_KEY_ICMPV6_TYPE_MASK]); } -@@ -1006,14 +1026,14 @@ static const struct nl_policy pedit_policy[] = { +@@ -1006,14 +1031,14 @@ static const struct nl_policy pedit_policy[] = { static int nl_parse_act_pedit(struct nlattr *options, struct tc_flower *flower) { @@ -56348,7 +56360,7 @@ index adb2d3182a..900a631553 100644 size_t keys_ex_size, left; int type, i = 0, err; -@@ -1068,7 +1088,7 @@ nl_parse_act_pedit(struct nlattr *options, struct tc_flower *flower) +@@ -1068,7 +1093,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); @@ -56357,7 +56369,7 @@ index adb2d3182a..900a631553 100644 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) +@@ -1083,8 +1108,13 @@ nl_parse_act_pedit(struct nlattr *options, struct tc_flower *flower) mask &= htonl(UINT32_MAX << zero_bits); } @@ -56373,7 +56385,7 @@ index adb2d3182a..900a631553 100644 } } -@@ -1092,7 +1117,6 @@ nl_parse_act_pedit(struct nlattr *options, struct tc_flower *flower) +@@ -1092,7 +1122,6 @@ nl_parse_act_pedit(struct nlattr *options, struct tc_flower *flower) i++; } @@ -56381,7 +56393,7 @@ index adb2d3182a..900a631553 100644 action->type = TC_ACT_PEDIT; return 0; -@@ -1314,8 +1338,8 @@ nl_parse_act_gact(struct nlattr *options, struct tc_flower *flower) +@@ -1314,8 +1343,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; @@ -56391,7 +56403,7 @@ index adb2d3182a..900a631553 100644 if (!nl_parse_nested(options, gact_policy, gact_attrs, ARRAY_SIZE(gact_policy))) { -@@ -1335,8 +1359,9 @@ nl_parse_act_gact(struct nlattr *options, struct tc_flower *flower) +@@ -1335,8 +1364,9 @@ nl_parse_act_gact(struct nlattr *options, struct tc_flower *flower) return EINVAL; } @@ -56403,7 +56415,7 @@ index adb2d3182a..900a631553 100644 return 0; } -@@ -1357,9 +1382,9 @@ nl_parse_act_mirred(struct nlattr *options, struct tc_flower *flower) +@@ -1357,9 +1387,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; @@ -56414,7 +56426,7 @@ index adb2d3182a..900a631553 100644 if (!nl_parse_nested(options, mirred_policy, mirred_attrs, ARRAY_SIZE(mirred_policy))) { -@@ -1387,8 +1412,8 @@ nl_parse_act_mirred(struct nlattr *options, struct tc_flower *flower) +@@ -1387,8 +1417,8 @@ nl_parse_act_mirred(struct nlattr *options, struct tc_flower *flower) action->type = TC_ACT_OUTPUT; mirred_tm = mirred_attrs[TCA_MIRRED_TM]; @@ -56425,7 +56437,7 @@ index adb2d3182a..900a631553 100644 return 0; } -@@ -1487,7 +1512,9 @@ nl_parse_act_ct(struct nlattr *options, struct tc_flower *flower) +@@ -1487,7 +1517,9 @@ nl_parse_act_ct(struct nlattr *options, struct tc_flower *flower) if (ipv4_max) { ovs_be32 addr = nl_attr_get_be32(ipv4_max); @@ -56436,7 +56448,7 @@ index adb2d3182a..900a631553 100644 } } else if (ipv6_min) { action->ct.range.ip_family = AF_INET6; -@@ -1496,7 +1523,9 @@ nl_parse_act_ct(struct nlattr *options, struct tc_flower *flower) +@@ -1496,7 +1528,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); @@ -56447,7 +56459,7 @@ index adb2d3182a..900a631553 100644 } } -@@ -1504,6 +1533,10 @@ nl_parse_act_ct(struct nlattr *options, struct tc_flower *flower) +@@ -1504,6 +1538,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); @@ -56458,64 +56470,130 @@ index adb2d3182a..900a631553 100644 } } } -@@ -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, }, -+ [TCA_STATS_BASIC_HW] = { .type = NL_A_UNSPEC, -+ .min_len = sizeof(struct gnet_stats_basic), -+ .optional = true, }, +@@ -1698,24 +1736,89 @@ static const struct nl_policy act_policy[] = { + [TCA_ACT_STATS] = { .type = NL_A_NESTED, .optional = false, }, }; +-static const struct nl_policy stats_policy[] = { +- [TCA_STATS_BASIC] = { .type = NL_A_UNSPEC, +- .min_len = sizeof(struct gnet_stats_basic), +- .optional = false, }, +-}; ++static int ++nl_parse_action_stats(struct nlattr *act_stats, ++ struct ovs_flow_stats *stats_sw, ++ struct ovs_flow_stats *stats_hw) ++{ ++ struct tc_flow_stats s_sw = {0}, s_hw = {0}; ++ uint16_t prev_type = __TCA_STATS_MAX; ++ const struct nlattr *nla; ++ unsigned int seen = 0; ++ size_t left; ++ ++ /* Cannot use nl_parse_nested due to duplicate attributes. */ ++ NL_NESTED_FOR_EACH (nla, left, act_stats) { ++ struct gnet_stats_basic stats_basic; ++ uint16_t type = nl_attr_type(nla); ++ ++ seen |= 1 << type; ++ switch (type) { ++ case TCA_STATS_BASIC: ++ memcpy(&stats_basic, nl_attr_get_unspec(nla, sizeof stats_basic), ++ sizeof stats_basic); ++ s_sw.n_packets = stats_basic.packets; ++ s_sw.n_bytes = stats_basic.bytes; ++ break; ++ ++ case TCA_STATS_BASIC_HW: ++ memcpy(&stats_basic, nl_attr_get_unspec(nla, sizeof stats_basic), ++ sizeof stats_basic); ++ s_hw.n_packets = stats_basic.packets; ++ s_hw.n_bytes = stats_basic.bytes; ++ break; ++ ++ case TCA_STATS_PKT64: ++ if (prev_type == TCA_STATS_BASIC) { ++ s_sw.n_packets = nl_attr_get_u64(nla); ++ } else if (prev_type == TCA_STATS_BASIC_HW) { ++ s_hw.n_packets = nl_attr_get_u64(nla); ++ } else { ++ goto err; ++ } ++ break; ++ ++ default: ++ break; ++ } ++ prev_type = type; ++ } ++ ++ if (!(seen & (1 << TCA_STATS_BASIC))) { ++ goto err; ++ } ++ ++ if (seen & (1 << TCA_STATS_BASIC_HW)) { ++ s_sw.n_packets = s_sw.n_packets - s_hw.n_packets; ++ s_sw.n_bytes = s_sw.n_bytes - s_hw.n_bytes; ++ ++ if (s_hw.n_packets > get_32aligned_u64(&stats_hw->n_packets)) { ++ put_32aligned_u64(&stats_hw->n_packets, s_hw.n_packets); ++ put_32aligned_u64(&stats_hw->n_bytes, s_hw.n_bytes); ++ } ++ } ++ ++ if (s_sw.n_packets > get_32aligned_u64(&stats_sw->n_packets)) { ++ put_32aligned_u64(&stats_sw->n_packets, s_sw.n_packets); ++ put_32aligned_u64(&stats_sw->n_bytes, s_sw.n_bytes); ++ ++ } ++ ++ return 0; ++ ++err: ++ VLOG_ERR_RL(&error_rl, "Failed to parse action stats policy"); ++ return EPROTO; ++} + static int -@@ -1714,8 +1750,9 @@ nl_parse_single_action(struct nlattr *action, struct tc_flower *flower, + nl_parse_single_action(struct nlattr *action, struct tc_flower *flower, + bool terse) + { + struct nlattr *act_options; +- struct nlattr *act_stats; + struct nlattr *act_cookie; const char *act_kind; struct nlattr *action_attrs[ARRAY_SIZE(act_policy)]; - struct nlattr *stats_attrs[ARRAY_SIZE(stats_policy)]; +- struct nlattr *stats_attrs[ARRAY_SIZE(stats_policy)]; - struct ovs_flow_stats *stats = &flower->stats; - const struct gnet_stats_basic *bs; -+ struct ovs_flow_stats *stats_sw = &flower->stats_sw; -+ struct ovs_flow_stats *stats_hw = &flower->stats_hw; -+ struct gnet_stats_basic bs_all, bs_hw, bs_sw; int err = 0; if (!nl_parse_nested(action, act_policy, action_attrs, -@@ -1771,10 +1808,30 @@ nl_parse_single_action(struct nlattr *action, struct tc_flower *flower, - return EPROTO; +@@ -1763,21 +1866,8 @@ nl_parse_single_action(struct nlattr *action, struct tc_flower *flower, + flower->act_cookie.len = nl_attr_get_size(act_cookie); } +- act_stats = action_attrs[TCA_ACT_STATS]; +- +- if (!nl_parse_nested(act_stats, stats_policy, stats_attrs, +- ARRAY_SIZE(stats_policy))) { +- VLOG_ERR_RL(&error_rl, "failed to parse action stats policy"); +- return EPROTO; +- } +- - bs = nl_attr_get_unspec(stats_attrs[TCA_STATS_BASIC], sizeof *bs); - if (bs->packets) { - put_32aligned_u64(&stats->n_packets, bs->packets); - put_32aligned_u64(&stats->n_bytes, bs->bytes); -+ memcpy(&bs_all, -+ nl_attr_get_unspec(stats_attrs[TCA_STATS_BASIC], sizeof bs_all), -+ sizeof bs_all); -+ if (stats_attrs[TCA_STATS_BASIC_HW]) { -+ memcpy(&bs_hw, nl_attr_get_unspec(stats_attrs[TCA_STATS_BASIC_HW], -+ sizeof bs_hw), -+ sizeof bs_hw); -+ -+ bs_sw.packets = bs_all.packets - bs_hw.packets; -+ bs_sw.bytes = bs_all.bytes - bs_hw.bytes; -+ } else { -+ bs_sw.packets = bs_all.packets; -+ bs_sw.bytes = bs_all.bytes; -+ } -+ -+ if (bs_sw.packets > get_32aligned_u64(&stats_sw->n_packets)) { -+ put_32aligned_u64(&stats_sw->n_packets, bs_sw.packets); -+ put_32aligned_u64(&stats_sw->n_bytes, bs_sw.bytes); -+ } -+ -+ if (stats_attrs[TCA_STATS_BASIC_HW] -+ && bs_hw.packets > get_32aligned_u64(&stats_hw->n_packets)) { -+ put_32aligned_u64(&stats_hw->n_packets, bs_hw.packets); -+ put_32aligned_u64(&stats_hw->n_bytes, bs_hw.bytes); - } +- } +- +- return 0; ++ return nl_parse_action_stats(action_attrs[TCA_ACT_STATS], ++ &flower->stats_sw, &flower->stats_hw); + } - return 0; -@@ -2399,14 +2456,14 @@ nl_msg_put_act_flags(struct ofpbuf *request) { + #define TCA_ACT_MIN_PRIO 1 +@@ -2399,14 +2489,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 @@ -56533,7 +56611,7 @@ index adb2d3182a..900a631553 100644 max_offset = m->offset + m->size; start_offset = ROUND_DOWN(m->offset, 4); -@@ -2473,7 +2530,8 @@ csum_update_flag(struct tc_flower *flower, +@@ -2473,7 +2563,8 @@ csum_update_flag(struct tc_flower *flower, static int nl_msg_put_flower_rewrite_pedits(struct ofpbuf *request, @@ -56543,7 +56621,7 @@ index adb2d3182a..900a631553 100644 { struct { struct tc_pedit sel; -@@ -2497,12 +2555,12 @@ nl_msg_put_flower_rewrite_pedits(struct ofpbuf *request, +@@ -2497,12 +2588,12 @@ nl_msg_put_flower_rewrite_pedits(struct ofpbuf *request, continue; } @@ -56559,7 +56637,7 @@ index adb2d3182a..900a631553 100644 if (j == 0) { mask_word &= first_word_mask; -@@ -2556,6 +2614,29 @@ nl_msg_put_flower_acts_release(struct ofpbuf *request, uint16_t act_index) +@@ -2556,6 +2647,29 @@ nl_msg_put_flower_acts_release(struct ofpbuf *request, uint16_t act_index) nl_msg_end_nested(request, act_offset); } @@ -56589,7 +56667,7 @@ index adb2d3182a..900a631553 100644 static int 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) +@@ -2572,20 +2686,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++) { @@ -56618,7 +56696,7 @@ index adb2d3182a..900a631553 100644 } } break; -@@ -2792,13 +2875,16 @@ nl_msg_put_flower_tunnel(struct ofpbuf *request, struct tc_flower *flower) +@@ -2792,13 +2908,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; @@ -56636,7 +56714,7 @@ index adb2d3182a..900a631553 100644 if (ipv4_dst_mask || ipv4_src_mask) { nl_msg_put_be32(request, TCA_FLOWER_KEY_ENC_IPV4_DST_MASK, -@@ -2824,8 +2910,15 @@ nl_msg_put_flower_tunnel(struct ofpbuf *request, struct tc_flower *flower) +@@ -2824,8 +2943,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); } @@ -56653,7 +56731,7 @@ index adb2d3182a..900a631553 100644 } if (id_mask) { nl_msg_put_be32(request, TCA_FLOWER_KEY_ENC_KEY_ID, id); -@@ -2914,13 +3007,13 @@ nl_msg_put_flower_options(struct ofpbuf *request, struct tc_flower *flower) +@@ -2914,13 +3040,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); } @@ -56672,7 +56750,7 @@ index adb2d3182a..900a631553 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 +3086,79 @@ nl_msg_put_flower_options(struct ofpbuf *request, struct tc_flower *flower) +@@ -2993,12 +3119,79 @@ nl_msg_put_flower_options(struct ofpbuf *request, struct tc_flower *flower) return 0; } @@ -56753,7 +56831,7 @@ index adb2d3182a..900a631553 100644 return false; } -@@ -3011,8 +3171,8 @@ cmp_tc_flower_match_action(const struct tc_flower *a, +@@ -3011,8 +3204,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) { @@ -56764,7 +56842,7 @@ index adb2d3182a..900a631553 100644 return false; } } -@@ -3022,14 +3182,15 @@ cmp_tc_flower_match_action(const struct tc_flower *a, +@@ -3022,14 +3215,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) { diff --git a/SPECS/openvswitch2.17.spec b/SPECS/openvswitch2.17.spec index 820783f..99a258f 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: 69%{?dist} +Release: 71%{?dist} # Nearly all of openvswitch is ASL 2.0. The bugtool is LGPLv2+, and the # lib/sflow*.[ch] files are SISSL @@ -743,6 +743,18 @@ exit 0 %endif %changelog +* Mon Jan 09 2023 Open vSwitch CI - 2.17.0-71 +- Merging upstream branch-2.17 [RH git: 96d27acbea] + Commit list: + 0f55eced1e cirrus: Update to use FreeBSD 12.4. + + +* Mon Jan 09 2023 Open vSwitch CI - 2.17.0-70 +- Merging upstream branch-2.17 [RH git: 309fe521e9] + Commit list: + e9336a91f6 tc: Add support for TCA_STATS_PKT64. (#1776816) + + * Fri Jan 06 2023 Open vSwitch CI - 2.17.0-69 - Merging upstream branch-2.17 [RH git: a7b4835415] Commit list: