From 3c5912a2e4e687768a16b2291721895b59559b2d Mon Sep 17 00:00:00 2001 From: Open vSwitch CI Date: Mar 21 2022 13:49:58 +0000 Subject: Import openvswitch2.13-2.13.0-168 from Fast DataPath --- diff --git a/SOURCES/openvswitch-2.13.0.patch b/SOURCES/openvswitch-2.13.0.patch index fcc3f49..6f2f7f5 100644 --- a/SOURCES/openvswitch-2.13.0.patch +++ b/SOURCES/openvswitch-2.13.0.patch @@ -84096,7 +84096,7 @@ index f8c46bbaad..b42d314b65 100644 static int diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c -index 550e440b3a..0d0cafc14d 100644 +index 550e440b3a..6c89c70aba 100644 --- a/lib/netdev-offload-tc.c +++ b/lib/netdev-offload-tc.c @@ -48,6 +48,7 @@ static struct hmap ufid_to_tc = HMAP_INITIALIZER(&ufid_to_tc); @@ -84118,6 +84118,20 @@ index 550e440b3a..0d0cafc14d 100644 return err; } +@@ -407,10 +410,10 @@ netdev_tc_flow_dump_destroy(struct netdev_flow_dump *dump) + + static void + parse_flower_rewrite_to_netlink_action(struct ofpbuf *buf, +- struct tc_flower *flower) ++ struct tc_action *action) + { +- char *mask = (char *) &flower->rewrite.mask; +- char *data = (char *) &flower->rewrite.key; ++ char *mask = (char *) &action->rewrite.mask; ++ char *data = (char *) &action->rewrite.key; + + for (int type = 0; type < ARRAY_SIZE(set_flower_map); type++) { + char *put = NULL; @@ -502,6 +505,22 @@ flower_tun_opt_to_match(struct match *match, struct tc_flower *flower) match->wc.masks.tunnel.flags |= FLOW_TNL_F_UDPIF; } @@ -84141,6 +84155,15 @@ index 550e440b3a..0d0cafc14d 100644 static int parse_tc_flower_to_match(struct tc_flower *flower, struct match *match, +@@ -715,7 +734,7 @@ parse_tc_flower_to_match(struct tc_flower *flower, + } + break; + case TC_ACT_PEDIT: { +- parse_flower_rewrite_to_netlink_action(buf, flower); ++ parse_flower_rewrite_to_netlink_action(buf, action); + } + break; + case TC_ACT_ENCAP: { @@ -757,8 +776,7 @@ parse_tc_flower_to_match(struct tc_flower *flower, action->encap.tp_dst); } @@ -84165,7 +84188,42 @@ index 550e440b3a..0d0cafc14d 100644 attrs->offloaded = (flower->offloaded_state == TC_OFFLOADED_STATE_IN_HW) || (flower->offloaded_state == TC_OFFLOADED_STATE_UNDEFINED); -@@ -1352,6 +1365,66 @@ flower_match_to_tun_opt(struct tc_flower *flower, const struct flow_tnl *tnl, +@@ -1072,8 +1085,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; +- char *key = (char *) &flower->rewrite.key; +- char *mask = (char *) &flower->rewrite.mask; ++ char *key = (char *) &action->rewrite.key; ++ char *mask = (char *) &action->rewrite.mask; + const struct nlattr *attr; + int i, j, type; + size_t size; +@@ -1115,14 +1128,6 @@ parse_put_flow_set_masked_action(struct tc_flower *flower, + } + } + +- if (!is_all_zeros(&flower->rewrite, sizeof flower->rewrite)) { +- if (flower->rewrite.rewrite == false) { +- flower->rewrite.rewrite = true; +- action->type = TC_ACT_PEDIT; +- flower->action_count++; +- } +- } +- + if (hasmask && !is_all_zeros(set_mask, size)) { + VLOG_DBG_RL(&rl, "unsupported sub attribute of set action type %d", + type); +@@ -1131,6 +1136,8 @@ parse_put_flow_set_masked_action(struct tc_flower *flower, + } + + ofpbuf_uninit(&set_buf); ++ action->type = TC_ACT_PEDIT; ++ flower->action_count++; + return 0; + } + +@@ -1352,6 +1359,66 @@ flower_match_to_tun_opt(struct tc_flower *flower, const struct flow_tnl *tnl, flower->mask.tunnel.metadata.present.len = tnl->metadata.present.len; } @@ -84232,7 +84290,7 @@ index 550e440b3a..0d0cafc14d 100644 static int netdev_tc_flow_put(struct netdev *netdev, struct match *match, struct nlattr *actions, size_t actions_len, -@@ -1572,53 +1645,7 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, +@@ -1572,53 +1639,7 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, } } @@ -84287,7 +84345,33 @@ index 550e440b3a..0d0cafc14d 100644 /* ignore exact match on skb_mark of 0. */ if (mask->pkt_mark == UINT32_MAX && !key->pkt_mark) { -@@ -1699,6 +1726,10 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, +@@ -1644,7 +1665,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; + } ++ ++ if (!netdev_flow_api_equals(netdev, outdev)) { ++ VLOG_DBG_RL(&rl, ++ "Flow API provider mismatch between ingress (%s) " ++ "and egress (%s) ports", ++ netdev_get_name(netdev), netdev_get_name(outdev)); ++ netdev_close(outdev); ++ return EOPNOTSUPP; ++ } ++ + action->out.ifindex_out = netdev_get_ifindex(outdev); ++ if (action->out.ifindex_out < 0) { ++ VLOG_DBG_RL(&rl, ++ "Can't find ifindex for output port %s, error %d", ++ netdev_get_name(outdev), action->out.ifindex_out); ++ netdev_close(outdev); ++ return -action->out.ifindex_out; ++ } ++ + action->out.ingress = is_internal_port(netdev_get_type(outdev)); + action->type = TC_ACT_OUTPUT; + flower.action_count++; +@@ -1699,6 +1738,10 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, const struct nlattr *ct = nl_attr_get(nla); const size_t ct_len = nl_attr_get_size(nla); @@ -84298,7 +84382,7 @@ index 550e440b3a..0d0cafc14d 100644 err = parse_put_flow_ct_action(&flower, action, ct, ct_len); if (err) { return err; -@@ -1727,7 +1758,7 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, +@@ -1727,7 +1770,7 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, if (get_ufid_tc_mapping(ufid, &id) == 0) { VLOG_DBG_RL(&rl, "updating old handle: %d prio: %d", id.handle, id.prio); @@ -84307,7 +84391,7 @@ index 550e440b3a..0d0cafc14d 100644 } prio = get_prio_for_tc_flower(&flower); -@@ -1810,9 +1841,7 @@ netdev_tc_flow_del(struct netdev *netdev OVS_UNUSED, +@@ -1810,9 +1853,7 @@ netdev_tc_flow_del(struct netdev *netdev OVS_UNUSED, if (stats) { memset(stats, 0, sizeof *stats); if (!tc_get_flower(&id, &flower)) { @@ -84318,7 +84402,7 @@ index 550e440b3a..0d0cafc14d 100644 } } -@@ -1837,6 +1866,7 @@ probe_multi_mask_per_prio(int ifindex) +@@ -1837,6 +1878,7 @@ probe_multi_mask_per_prio(int ifindex) memset(&flower, 0, sizeof flower); @@ -84326,7 +84410,7 @@ index 550e440b3a..0d0cafc14d 100644 flower.key.eth_type = htons(ETH_P_IP); flower.mask.eth_type = OVS_BE16_MAX; memset(&flower.key.dst_mac, 0x11, sizeof flower.key.dst_mac); -@@ -1868,6 +1898,96 @@ out: +@@ -1868,6 +1910,96 @@ out: tc_add_del_qdisc(ifindex, false, block_id, TC_INGRESS); } @@ -84423,7 +84507,7 @@ index 550e440b3a..0d0cafc14d 100644 static void probe_tc_block_support(int ifindex) { -@@ -1884,6 +2004,7 @@ probe_tc_block_support(int ifindex) +@@ -1884,6 +2016,7 @@ probe_tc_block_support(int ifindex) memset(&flower, 0, sizeof flower); @@ -84431,7 +84515,7 @@ index 550e440b3a..0d0cafc14d 100644 flower.key.eth_type = htons(ETH_P_IP); flower.mask.eth_type = OVS_BE16_MAX; memset(&flower.key.dst_mac, 0x11, sizeof flower.key.dst_mac); -@@ -1907,6 +2028,7 @@ netdev_tc_init_flow_api(struct netdev *netdev) +@@ -1907,6 +2040,7 @@ netdev_tc_init_flow_api(struct netdev *netdev) static struct ovsthread_once block_once = OVSTHREAD_ONCE_INITIALIZER; enum tc_qdisc_hook hook = get_tc_qdisc_hook(netdev); uint32_t block_id = 0; @@ -84439,7 +84523,7 @@ index 550e440b3a..0d0cafc14d 100644 int ifindex; int error; -@@ -1917,20 +2039,30 @@ netdev_tc_init_flow_api(struct netdev *netdev) +@@ -1917,20 +2051,30 @@ netdev_tc_init_flow_api(struct netdev *netdev) return -ifindex; } @@ -84628,7 +84712,7 @@ index 42d3335f0f..97320a4dba 100644 } else { a = attrs[OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_LESS_EQUAL]; diff --git a/lib/odp-util.c b/lib/odp-util.c -index 746d1e97d4..57943df9ed 100644 +index 746d1e97d4..6daad7f58b 100644 --- a/lib/odp-util.c +++ b/lib/odp-util.c @@ -390,7 +390,8 @@ format_odp_push_nsh_action(struct ds *ds, @@ -84703,7 +84787,19 @@ index 746d1e97d4..57943df9ed 100644 } nl_msg_end_nested(a, tun_key_ofs); -@@ -4531,7 +4538,7 @@ odp_flow_format(const struct nlattr *key, size_t key_len, +@@ -4514,6 +4521,11 @@ odp_flow_format(const struct nlattr *key, size_t key_len, + ds_put_char(ds, ','); + } + ds_put_cstr(ds, "eth()"); ++ } else if (attr_type == OVS_KEY_ATTR_PACKET_TYPE && is_wildcard) { ++ /* See the above help text, however in the case where the ++ * packet type is not shown, we still need to display the ++ * eth() header if the packets type is wildcarded. */ ++ has_packet_type_key = false; + } + ofpbuf_clear(&ofp); + } +@@ -4531,7 +4543,7 @@ odp_flow_format(const struct nlattr *key, size_t key_len, } ds_put_char(ds, ')'); } @@ -84712,7 +84808,7 @@ index 746d1e97d4..57943df9ed 100644 const struct nlattr *ma = nl_attr_find__(mask, mask_len, OVS_KEY_ATTR_ETHERTYPE); if (ma) { -@@ -5428,13 +5435,16 @@ erspan_to_attr(struct ofpbuf *a, const void *data_) +@@ -5428,13 +5440,16 @@ erspan_to_attr(struct ofpbuf *a, const void *data_) do { \ len = 0; @@ -84736,7 +84832,7 @@ index 746d1e97d4..57943df9ed 100644 } #define SCAN_FIELD_NESTED__(NAME, TYPE, SCAN_AS, ATTR, FUNC) \ -@@ -6225,7 +6235,9 @@ odp_flow_key_from_flow__(const struct odp_flow_key_parms *parms, +@@ -6225,7 +6240,9 @@ odp_flow_key_from_flow__(const struct odp_flow_key_parms *parms, struct ovs_key_nd_extensions *nd_ext_key; if (data->igmp_group_ip4 != 0 || data->tcp_flags != 0) { @@ -84747,7 +84843,7 @@ index 746d1e97d4..57943df9ed 100644 OVS_KEY_ATTR_ND_EXTENSIONS, sizeof *nd_ext_key); nd_ext_key->nd_reserved = data->igmp_group_ip4; -@@ -6275,6 +6287,10 @@ odp_key_from_dp_packet(struct ofpbuf *buf, const struct dp_packet *packet) +@@ -6275,6 +6292,10 @@ odp_key_from_dp_packet(struct ofpbuf *buf, const struct dp_packet *packet) nl_msg_put_u32(buf, OVS_KEY_ATTR_PRIORITY, md->skb_priority); @@ -84758,7 +84854,7 @@ index 746d1e97d4..57943df9ed 100644 if (flow_tnl_dst_is_set(&md->tunnel)) { tun_key_to_attr(buf, &md->tunnel, &md->tunnel, NULL, NULL); } -@@ -7416,15 +7432,18 @@ odp_key_fitness_to_string(enum odp_key_fitness fitness) +@@ -7416,15 +7437,18 @@ odp_key_fitness_to_string(enum odp_key_fitness fitness) /* Appends an OVS_ACTION_ATTR_USERSPACE action to 'odp_actions' that specifies * Netlink PID 'pid'. If 'userdata' is nonnull, adds a userdata attribute @@ -84782,7 +84878,7 @@ index 746d1e97d4..57943df9ed 100644 { size_t userdata_ofs; size_t offset; -@@ -7432,6 +7451,9 @@ odp_put_userspace_action(uint32_t pid, +@@ -7432,6 +7456,9 @@ odp_put_userspace_action(uint32_t pid, offset = nl_msg_start_nested(odp_actions, OVS_ACTION_ATTR_USERSPACE); nl_msg_put_u32(odp_actions, OVS_USERSPACE_ATTR_PID, pid); if (userdata) { @@ -84792,7 +84888,7 @@ index 746d1e97d4..57943df9ed 100644 userdata_ofs = odp_actions->size + NLA_HDRLEN; /* The OVS kernel module before OVS 1.11 and the upstream Linux kernel -@@ -7457,9 +7479,16 @@ odp_put_userspace_action(uint32_t pid, +@@ -7457,9 +7484,16 @@ odp_put_userspace_action(uint32_t pid, if (include_actions) { nl_msg_put_flag(odp_actions, OVS_USERSPACE_ATTR_ACTIONS); } @@ -84810,7 +84906,7 @@ index 746d1e97d4..57943df9ed 100644 } void -@@ -7565,6 +7594,28 @@ struct offsetof_sizeof { +@@ -7565,6 +7599,28 @@ struct offsetof_sizeof { int size; }; @@ -84839,7 +84935,7 @@ index 746d1e97d4..57943df9ed 100644 /* Compares each of the fields in 'key0' and 'key1'. The fields are specified * in 'offsetof_sizeof_arr', which is an array terminated by a 0-size field. * Returns true if all of the fields are equal, false if at least one differs. -@@ -7643,9 +7694,10 @@ commit_set_ether_action(const struct flow *flow, struct flow *base_flow, +@@ -7643,9 +7699,10 @@ commit_set_ether_action(const struct flow *flow, struct flow *base_flow, struct flow_wildcards *wc, bool use_masked) { @@ -84851,7 +84947,7 @@ index 746d1e97d4..57943df9ed 100644 if (flow->packet_type != htonl(PT_ETH)) { return; } -@@ -7653,11 +7705,13 @@ commit_set_ether_action(const struct flow *flow, struct flow *base_flow, +@@ -7653,11 +7710,13 @@ commit_set_ether_action(const struct flow *flow, struct flow *base_flow, get_ethernet_key(flow, &key); get_ethernet_key(base_flow, &base); get_ethernet_key(&wc->masks, &mask); @@ -84865,7 +84961,7 @@ index 746d1e97d4..57943df9ed 100644 put_ethernet_key(&mask, &wc->masks); } } -@@ -7781,7 +7835,7 @@ commit_set_ipv4_action(const struct flow *flow, struct flow *base_flow, +@@ -7781,7 +7840,7 @@ commit_set_ipv4_action(const struct flow *flow, struct flow *base_flow, struct ofpbuf *odp_actions, struct flow_wildcards *wc, bool use_masked) { @@ -84874,7 +84970,7 @@ index 746d1e97d4..57943df9ed 100644 struct offsetof_sizeof ovs_key_ipv4_offsetof_sizeof_arr[] = OVS_KEY_IPV4_OFFSETOF_SIZEOF_ARR; -@@ -7792,6 +7846,7 @@ commit_set_ipv4_action(const struct flow *flow, struct flow *base_flow, +@@ -7792,6 +7851,7 @@ commit_set_ipv4_action(const struct flow *flow, struct flow *base_flow, get_ipv4_key(flow, &key, false); get_ipv4_key(base_flow, &base, false); get_ipv4_key(&wc->masks, &mask, true); @@ -84882,7 +84978,7 @@ index 746d1e97d4..57943df9ed 100644 mask.ipv4_proto = 0; /* Not writeable. */ mask.ipv4_frag = 0; /* Not writable. */ -@@ -7803,9 +7858,8 @@ commit_set_ipv4_action(const struct flow *flow, struct flow *base_flow, +@@ -7803,9 +7863,8 @@ commit_set_ipv4_action(const struct flow *flow, struct flow *base_flow, if (commit(OVS_KEY_ATTR_IPV4, use_masked, &key, &base, &mask, sizeof key, ovs_key_ipv4_offsetof_sizeof_arr, odp_actions)) { put_ipv4_key(&base, base_flow, false); @@ -84894,7 +84990,7 @@ index 746d1e97d4..57943df9ed 100644 } } -@@ -7838,7 +7892,7 @@ commit_set_ipv6_action(const struct flow *flow, struct flow *base_flow, +@@ -7838,7 +7897,7 @@ commit_set_ipv6_action(const struct flow *flow, struct flow *base_flow, struct ofpbuf *odp_actions, struct flow_wildcards *wc, bool use_masked) { @@ -84903,7 +84999,7 @@ index 746d1e97d4..57943df9ed 100644 struct offsetof_sizeof ovs_key_ipv6_offsetof_sizeof_arr[] = OVS_KEY_IPV6_OFFSETOF_SIZEOF_ARR; -@@ -7849,6 +7903,7 @@ commit_set_ipv6_action(const struct flow *flow, struct flow *base_flow, +@@ -7849,6 +7908,7 @@ commit_set_ipv6_action(const struct flow *flow, struct flow *base_flow, get_ipv6_key(flow, &key, false); get_ipv6_key(base_flow, &base, false); get_ipv6_key(&wc->masks, &mask, true); @@ -84911,7 +85007,7 @@ index 746d1e97d4..57943df9ed 100644 mask.ipv6_proto = 0; /* Not writeable. */ mask.ipv6_frag = 0; /* Not writable. */ mask.ipv6_label &= htonl(IPV6_LABEL_MASK); /* Not writable. */ -@@ -7861,9 +7916,8 @@ commit_set_ipv6_action(const struct flow *flow, struct flow *base_flow, +@@ -7861,9 +7921,8 @@ commit_set_ipv6_action(const struct flow *flow, struct flow *base_flow, if (commit(OVS_KEY_ATTR_IPV6, use_masked, &key, &base, &mask, sizeof key, ovs_key_ipv6_offsetof_sizeof_arr, odp_actions)) { put_ipv6_key(&base, base_flow, false); @@ -84923,7 +85019,7 @@ index 746d1e97d4..57943df9ed 100644 } } -@@ -7894,17 +7948,19 @@ static enum slow_path_reason +@@ -7894,17 +7953,19 @@ static enum slow_path_reason commit_set_arp_action(const struct flow *flow, struct flow *base_flow, struct ofpbuf *odp_actions, struct flow_wildcards *wc) { @@ -84944,7 +85040,7 @@ index 746d1e97d4..57943df9ed 100644 put_arp_key(&mask, &wc->masks); return SLOW_ACTION; } -@@ -7931,7 +7987,7 @@ static enum slow_path_reason +@@ -7931,7 +7992,7 @@ static enum slow_path_reason commit_set_icmp_action(const struct flow *flow, struct flow *base_flow, struct ofpbuf *odp_actions, struct flow_wildcards *wc) { @@ -84953,7 +85049,7 @@ index 746d1e97d4..57943df9ed 100644 struct offsetof_sizeof ovs_key_icmp_offsetof_sizeof_arr[] = OVS_KEY_ICMP_OFFSETOF_SIZEOF_ARR; enum ovs_key_attr attr; -@@ -7947,10 +8003,12 @@ commit_set_icmp_action(const struct flow *flow, struct flow *base_flow, +@@ -7947,10 +8008,12 @@ commit_set_icmp_action(const struct flow *flow, struct flow *base_flow, get_icmp_key(flow, &key); get_icmp_key(base_flow, &base); get_icmp_key(&wc->masks, &mask); @@ -84966,7 +85062,7 @@ index 746d1e97d4..57943df9ed 100644 put_icmp_key(&mask, &wc->masks); return SLOW_ACTION; } -@@ -7998,17 +8056,19 @@ commit_set_nd_action(const struct flow *flow, struct flow *base_flow, +@@ -7998,17 +8061,19 @@ commit_set_nd_action(const struct flow *flow, struct flow *base_flow, struct ofpbuf *odp_actions, struct flow_wildcards *wc, bool use_masked) { @@ -84987,7 +85083,7 @@ index 746d1e97d4..57943df9ed 100644 put_nd_key(&mask, &wc->masks); return SLOW_ACTION; } -@@ -8022,18 +8082,20 @@ commit_set_nd_extensions_action(const struct flow *flow, +@@ -8022,18 +8087,20 @@ commit_set_nd_extensions_action(const struct flow *flow, struct ofpbuf *odp_actions, struct flow_wildcards *wc, bool use_masked) { @@ -85009,7 +85105,7 @@ index 746d1e97d4..57943df9ed 100644 put_nd_extensions_key(&mask, &wc->masks); return SLOW_ACTION; } -@@ -8248,7 +8310,7 @@ commit_set_port_action(const struct flow *flow, struct flow *base_flow, +@@ -8248,7 +8315,7 @@ commit_set_port_action(const struct flow *flow, struct flow *base_flow, bool use_masked) { enum ovs_key_attr key_type; @@ -85018,7 +85114,7 @@ index 746d1e97d4..57943df9ed 100644 struct offsetof_sizeof ovs_key_tp_offsetof_sizeof_arr[] = OVS_KEY_TCP_OFFSETOF_SIZEOF_ARR; -@@ -8274,10 +8336,12 @@ commit_set_port_action(const struct flow *flow, struct flow *base_flow, +@@ -8274,10 +8341,12 @@ commit_set_port_action(const struct flow *flow, struct flow *base_flow, get_tp_key(flow, &key); get_tp_key(base_flow, &base); get_tp_key(&wc->masks, &mask); @@ -85031,7 +85127,7 @@ index 746d1e97d4..57943df9ed 100644 put_tp_key(&mask, &wc->masks); } } -@@ -8301,7 +8365,7 @@ commit_set_priority_action(const struct flow *flow, struct flow *base_flow, +@@ -8301,7 +8370,7 @@ commit_set_priority_action(const struct flow *flow, struct flow *base_flow, if (commit(OVS_KEY_ATTR_PRIORITY, use_masked, &key, &base, &mask, sizeof key, ovs_key_prio_offsetof_sizeof_arr, odp_actions)) { base_flow->skb_priority = base; @@ -85040,7 +85136,7 @@ index 746d1e97d4..57943df9ed 100644 } } -@@ -8325,7 +8389,7 @@ commit_set_pkt_mark_action(const struct flow *flow, struct flow *base_flow, +@@ -8325,7 +8394,7 @@ commit_set_pkt_mark_action(const struct flow *flow, struct flow *base_flow, sizeof key, ovs_key_pkt_mark_offsetof_sizeof_arr, odp_actions)) { base_flow->pkt_mark = base; @@ -86452,7 +86548,7 @@ index 809b405a52..a869b5f390 100644 goto out; } diff --git a/lib/tc.c b/lib/tc.c -index 12af0192b6..5337f104c6 100644 +index 12af0192b6..de3fc50dbb 100644 --- a/lib/tc.c +++ b/lib/tc.c @@ -60,12 +60,6 @@ VLOG_DEFINE_THIS_MODULE(tc); @@ -86477,7 +86573,66 @@ index 12af0192b6..5337f104c6 100644 } if (attrs[TCA_FLOWER_KEY_MPLS_TC]) { -@@ -934,6 +928,7 @@ nl_parse_act_pedit(struct nlattr *options, struct tc_flower *flower) +@@ -483,16 +477,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]); ++ flower->mask.encap_eth_type[0] = CONSTANT_HTONS(0xffff); + + if (attrs[TCA_FLOWER_KEY_VLAN_ID]) { + flower->key.vlan_id[0] = + nl_attr_get_u16(attrs[TCA_FLOWER_KEY_VLAN_ID]); +- flower->mask.vlan_id[0] = 0xffff; ++ flower->mask.vlan_id[0] = VLAN_VID_MASK >> VLAN_VID_SHIFT; + } + if (attrs[TCA_FLOWER_KEY_VLAN_PRIO]) { + flower->key.vlan_prio[0] = + nl_attr_get_u8(attrs[TCA_FLOWER_KEY_VLAN_PRIO]); +- flower->mask.vlan_prio[0] = 0xff; ++ flower->mask.vlan_prio[0] = VLAN_PCP_MASK >> VLAN_PCP_SHIFT; + } + + if (!attrs[TCA_FLOWER_KEY_VLAN_ETH_TYPE]) { +@@ -505,17 +500,18 @@ nl_parse_flower_vlan(struct nlattr **attrs, struct tc_flower *flower) + } + + flower->key.encap_eth_type[1] = flower->key.encap_eth_type[0]; ++ flower->mask.encap_eth_type[1] = CONSTANT_HTONS(0xffff); + flower->key.encap_eth_type[0] = encap_ethtype; + + if (attrs[TCA_FLOWER_KEY_CVLAN_ID]) { + flower->key.vlan_id[1] = + nl_attr_get_u16(attrs[TCA_FLOWER_KEY_CVLAN_ID]); +- flower->mask.vlan_id[1] = 0xffff; ++ flower->mask.vlan_id[1] = VLAN_VID_MASK >> VLAN_VID_SHIFT; + } + if (attrs[TCA_FLOWER_KEY_CVLAN_PRIO]) { + flower->key.vlan_prio[1] = + nl_attr_get_u8(attrs[TCA_FLOWER_KEY_CVLAN_PRIO]); +- flower->mask.vlan_prio[1] = 0xff; ++ flower->mask.vlan_prio[1] = VLAN_PCP_MASK >> VLAN_PCP_SHIFT; + } + } + +@@ -887,14 +883,14 @@ static const struct nl_policy pedit_policy[] = { + static int + nl_parse_act_pedit(struct nlattr *options, struct tc_flower *flower) + { +- struct tc_action *action; ++ struct tc_action *action = &flower->actions[flower->action_count++]; + struct nlattr *pe_attrs[ARRAY_SIZE(pedit_policy)]; + const struct tc_pedit *pe; + const struct tc_pedit_key *keys; + const struct nlattr *nla, *keys_ex, *ex_type; + const void *keys_attr; +- char *rewrite_key = (void *) &flower->rewrite.key; +- char *rewrite_mask = (void *) &flower->rewrite.mask; ++ char *rewrite_key = (void *) &action->rewrite.key; ++ char *rewrite_mask = (void *) &action->rewrite.mask; + size_t keys_ex_size, left; + int type, i = 0, err; + +@@ -934,6 +930,7 @@ nl_parse_act_pedit(struct nlattr *options, struct tc_flower *flower) int flower_off = m->flower_offset; int sz = m->size; int mf = m->offset; @@ -86485,7 +86640,7 @@ index 12af0192b6..5337f104c6 100644 if (m->htype != type) { continue; -@@ -941,9 +936,10 @@ nl_parse_act_pedit(struct nlattr *options, struct tc_flower *flower) +@@ -941,9 +938,10 @@ nl_parse_act_pedit(struct nlattr *options, struct tc_flower *flower) /* check overlap between current pedit key, which is always * 4 bytes (range [off, off + 3]), and a map entry in @@ -86498,7 +86653,48 @@ index 12af0192b6..5337f104c6 100644 int diff = flower_off + (keys->off - mf); ovs_be32 *dst = (void *) (rewrite_key + diff); ovs_be32 *dst_m = (void *) (rewrite_mask + diff); -@@ -1581,6 +1577,9 @@ static const struct nl_policy stats_policy[] = { +@@ -971,7 +969,6 @@ nl_parse_act_pedit(struct nlattr *options, struct tc_flower *flower) + i++; + } + +- action = &flower->actions[flower->action_count++]; + action->type = TC_ACT_PEDIT; + + return 0; +@@ -1366,7 +1363,9 @@ nl_parse_act_ct(struct nlattr *options, struct tc_flower *flower) + if (ipv4_max) { + ovs_be32 addr = nl_attr_get_be32(ipv4_max); + +- action->ct.range.ipv4.max = addr; ++ if (action->ct.range.ipv4.min != addr) { ++ action->ct.range.ipv4.max = addr; ++ } + } + } else if (ipv6_min) { + action->ct.range.ip_family = AF_INET6; +@@ -1375,7 +1374,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); + +- action->ct.range.ipv6.max = addr; ++ if (!ipv6_addr_equals(&action->ct.range.ipv6.min, &addr)) { ++ action->ct.range.ipv6.max = addr; ++ } + } + } + +@@ -1383,6 +1384,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); ++ if (action->ct.range.port.min == ++ action->ct.range.port.max) { ++ action->ct.range.port.max = 0; ++ } + } + } + } +@@ -1581,6 +1586,9 @@ static const struct nl_policy stats_policy[] = { [TCA_STATS_BASIC] = { .type = NL_A_UNSPEC, .min_len = sizeof(struct gnet_stats_basic), .optional = false, }, @@ -86508,7 +86704,7 @@ index 12af0192b6..5337f104c6 100644 }; static int -@@ -1592,8 +1591,11 @@ nl_parse_single_action(struct nlattr *action, struct tc_flower *flower) +@@ -1592,8 +1600,11 @@ 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)]; @@ -86522,7 +86718,7 @@ index 12af0192b6..5337f104c6 100644 int err = 0; if (!nl_parse_nested(action, act_policy, action_attrs, -@@ -1646,9 +1648,27 @@ nl_parse_single_action(struct nlattr *action, struct tc_flower *flower) +@@ -1646,9 +1657,27 @@ nl_parse_single_action(struct nlattr *action, struct tc_flower *flower) return EPROTO; } @@ -86553,7 +86749,44 @@ index 12af0192b6..5337f104c6 100644 return 0; } -@@ -2369,6 +2389,17 @@ nl_msg_put_flower_rewrite_pedits(struct ofpbuf *request, +@@ -2223,14 +2252,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 +-calc_offsets(struct tc_flower *flower, struct flower_key_to_pedit *m, ++calc_offsets(struct tc_action *action, struct flower_key_to_pedit *m, + int *cur_offset, int *cnt, ovs_be32 *last_word_mask, + ovs_be32 *first_word_mask, ovs_be32 **mask, ovs_be32 **data) + { + int start_offset, max_offset, total_size; + int diff, right_zero_bits, left_zero_bits; +- char *rewrite_key = (void *) &flower->rewrite.key; +- char *rewrite_mask = (void *) &flower->rewrite.mask; ++ char *rewrite_key = (void *) &action->rewrite.key; ++ char *rewrite_mask = (void *) &action->rewrite.mask; + + max_offset = m->offset + m->size; + start_offset = ROUND_DOWN(m->offset, 4); +@@ -2297,7 +2326,8 @@ csum_update_flag(struct tc_flower *flower, + + static int + nl_msg_put_flower_rewrite_pedits(struct ofpbuf *request, +- struct tc_flower *flower) ++ struct tc_flower *flower, ++ struct tc_action *action) + { + struct { + struct tc_pedit sel; +@@ -2321,7 +2351,7 @@ nl_msg_put_flower_rewrite_pedits(struct ofpbuf *request, + continue; + } + +- calc_offsets(flower, m, &cur_offset, &cnt, &last_word_mask, ++ calc_offsets(action, m, &cur_offset, &cnt, &last_word_mask, + &first_word_mask, &mask, &data); + + for (j = 0; j < cnt; j++, mask++, data++, cur_offset += 4) { +@@ -2369,6 +2399,40 @@ nl_msg_put_flower_rewrite_pedits(struct ofpbuf *request, return 0; } @@ -86568,10 +86801,59 @@ index 12af0192b6..5337f104c6 100644 + nl_msg_end_nested(request, act_offset); +} + ++/* Aggregates all previous successive pedit actions csum_update_flags ++ * to flower->csum_update_flags. Only append one csum action to the ++ * last pedit action. */ ++static void ++nl_msg_put_csum_act(struct ofpbuf *request, struct tc_flower *flower, ++ uint16_t *act_index) ++{ ++ size_t act_offset; ++ ++ /* No pedit actions or processed already. */ ++ if (!flower->csum_update_flags) { ++ return; ++ } ++ ++ act_offset = nl_msg_start_nested(request, (*act_index)++); ++ nl_msg_put_act_csum(request, flower->csum_update_flags); ++ nl_msg_put_act_flags(request); ++ nl_msg_end_nested(request, act_offset); ++ ++ /* Clear it. So we can have another series of pedit actions. */ ++ flower->csum_update_flags = 0; ++} ++ static int nl_msg_put_flower_acts(struct ofpbuf *request, struct tc_flower *flower) { -@@ -2403,6 +2434,11 @@ nl_msg_put_flower_acts(struct ofpbuf *request, struct tc_flower *flower) +@@ -2385,24 +2449,31 @@ nl_msg_put_flower_acts(struct ofpbuf *request, struct tc_flower *flower) + + action = flower->actions; + for (i = 0; i < flower->action_count; i++, action++) { ++ if (action->type != TC_ACT_PEDIT) { ++ nl_msg_put_csum_act(request, flower, &act_index); ++ } + switch (action->type) { + case TC_ACT_PEDIT: { + act_offset = nl_msg_start_nested(request, act_index++); +- error = nl_msg_put_flower_rewrite_pedits(request, flower); ++ error = nl_msg_put_flower_rewrite_pedits(request, flower, ++ action); + if (error) { + return error; + } + nl_msg_end_nested(request, act_offset); + +- if (flower->csum_update_flags) { +- act_offset = nl_msg_start_nested(request, act_index++); +- nl_msg_put_act_csum(request, flower->csum_update_flags); +- nl_msg_put_act_flags(request); +- nl_msg_end_nested(request, act_offset); ++ if (i == flower->action_count - 1) { ++ /* If this is the last action check csum calc again. */ ++ nl_msg_put_csum_act(request, flower, &act_index); + } } break; case TC_ACT_ENCAP: { @@ -86583,7 +86865,7 @@ index 12af0192b6..5337f104c6 100644 act_offset = nl_msg_start_nested(request, act_index++); nl_msg_put_act_tunnel_key_set(request, action->encap.id_present, action->encap.id, -@@ -2460,9 +2496,7 @@ nl_msg_put_flower_acts(struct ofpbuf *request, struct tc_flower *flower) +@@ -2460,9 +2531,7 @@ nl_msg_put_flower_acts(struct ofpbuf *request, struct tc_flower *flower) break; case TC_ACT_OUTPUT: { if (!released && flower->tunnel) { @@ -86594,7 +86876,7 @@ index 12af0192b6..5337f104c6 100644 released = true; } -@@ -2645,6 +2679,7 @@ nl_msg_put_flower_options(struct ofpbuf *request, struct tc_flower *flower) +@@ -2645,6 +2714,7 @@ nl_msg_put_flower_options(struct ofpbuf *request, struct tc_flower *flower) bool is_vlan = eth_type_vlan(flower->key.eth_type); bool is_qinq = is_vlan && eth_type_vlan(flower->key.encap_eth_type[0]); bool is_mpls = eth_type_mpls(flower->key.eth_type); @@ -86602,7 +86884,26 @@ index 12af0192b6..5337f104c6 100644 int err; /* need to parse acts first as some acts require changing the matching -@@ -2762,7 +2797,11 @@ nl_msg_put_flower_options(struct ofpbuf *request, struct tc_flower *flower) +@@ -2696,13 +2766,13 @@ nl_msg_put_flower_options(struct ofpbuf *request, struct tc_flower *flower) + FLOWER_PUT_MASKED_VALUE(sctp_src, TCA_FLOWER_KEY_SCTP_SRC); + FLOWER_PUT_MASKED_VALUE(sctp_dst, TCA_FLOWER_KEY_SCTP_DST); + } +- +- FLOWER_PUT_MASKED_VALUE(ct_state, TCA_FLOWER_KEY_CT_STATE); +- FLOWER_PUT_MASKED_VALUE(ct_zone, TCA_FLOWER_KEY_CT_ZONE); +- FLOWER_PUT_MASKED_VALUE(ct_mark, TCA_FLOWER_KEY_CT_MARK); +- FLOWER_PUT_MASKED_VALUE(ct_label, TCA_FLOWER_KEY_CT_LABELS); + } + ++ FLOWER_PUT_MASKED_VALUE(ct_state, TCA_FLOWER_KEY_CT_STATE); ++ FLOWER_PUT_MASKED_VALUE(ct_zone, TCA_FLOWER_KEY_CT_ZONE); ++ FLOWER_PUT_MASKED_VALUE(ct_mark, TCA_FLOWER_KEY_CT_MARK); ++ FLOWER_PUT_MASKED_VALUE(ct_label, TCA_FLOWER_KEY_CT_LABELS); ++ + 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); +@@ -2762,7 +2832,11 @@ nl_msg_put_flower_options(struct ofpbuf *request, struct tc_flower *flower) } } @@ -86615,16 +86916,83 @@ index 12af0192b6..5337f104c6 100644 if (flower->tunnel) { nl_msg_put_flower_tunnel(request, flower); -@@ -2771,6 +2810,50 @@ nl_msg_put_flower_options(struct ofpbuf *request, struct tc_flower *flower) +@@ -2771,6 +2845,118 @@ nl_msg_put_flower_options(struct ofpbuf *request, struct tc_flower *flower) return 0; } ++static void ++log_tc_flower_match(const char *msg, ++ const struct tc_flower *a, ++ const struct tc_flower *b) ++{ ++ uint8_t key_a[sizeof(struct tc_flower_key)]; ++ uint8_t key_b[sizeof(struct tc_flower_key)]; ++ struct ds s = DS_EMPTY_INITIALIZER; ++ ++ for (int i = 0; i < sizeof a->key; i++) { ++ uint8_t mask_a = ((uint8_t *) &a->mask)[i]; ++ uint8_t mask_b = ((uint8_t *) &b->mask)[i]; ++ ++ key_a[i] = ((uint8_t *) &a->key)[i] & mask_a; ++ key_b[i] = ((uint8_t *) &b->key)[i] & mask_b; ++ } ++ ds_put_cstr(&s, "\nExpected Mask:\n"); ++ ds_put_hex(&s, &a->mask, sizeof a->mask); ++ ds_put_cstr(&s, "\nReceived Mask:\n"); ++ ds_put_hex(&s, &b->mask, sizeof b->mask); ++ ds_put_cstr(&s, "\nExpected Key:\n"); ++ ds_put_hex(&s, &a->key, sizeof a->key); ++ ds_put_cstr(&s, "\nReceived Key:\n"); ++ ds_put_hex(&s, &b->key, sizeof b->key); ++ ds_put_cstr(&s, "\nExpected Masked Key:\n"); ++ ds_put_hex(&s, key_a, sizeof key_a); ++ ds_put_cstr(&s, "\nReceived Masked Key:\n"); ++ ds_put_hex(&s, key_b, sizeof key_b); ++ ++ if (a->action_count != b->action_count) { ++ /* If action count is not equal, we print all actions to see which ++ * ones are missing. */ ++ const struct tc_action *action; ++ int i; ++ ++ ds_put_cstr(&s, "\nExpected Actions:\n"); ++ for (i = 0, action = a->actions; i < a->action_count; i++, action++) { ++ ds_put_cstr(&s, " - "); ++ ds_put_hex(&s, action, sizeof *action); ++ ds_put_cstr(&s, "\n"); ++ } ++ ds_put_cstr(&s, "Received Actions:\n"); ++ for (i = 0, action = b->actions; i < b->action_count; i++, action++) { ++ ds_put_cstr(&s, " - "); ++ ds_put_hex(&s, action, sizeof *action); ++ ds_put_cstr(&s, "\n"); ++ } ++ } else { ++ /* Only dump the delta in actions. */ ++ const struct tc_action *action_a = a->actions; ++ const struct tc_action *action_b = b->actions; ++ ++ for (int i = 0; i < a->action_count; i++, action_a++, action_b++) { ++ if (memcmp(action_a, action_b, sizeof *action_a)) { ++ ds_put_format(&s, ++ "\nAction %d mismatch:\n - Expected Action: ", ++ i); ++ ds_put_hex(&s, action_a, sizeof *action_a); ++ ds_put_cstr(&s, "\n - Received Action: "); ++ ds_put_hex(&s, action_b, sizeof *action_b); ++ } ++ } ++ } ++ VLOG_DBG_RL(&error_rl, "%s%s", msg, ds_cstr(&s)); ++ ds_destroy(&s); ++} ++ +static bool +cmp_tc_flower_match_action(const struct tc_flower *a, + const struct tc_flower *b) +{ + if (memcmp(&a->mask, &b->mask, sizeof a->mask)) { -+ VLOG_DBG_RL(&error_rl, "tc flower compare failed mask compare"); ++ log_tc_flower_match("tc flower compare failed mask compare:", a, b); + return false; + } + @@ -86637,8 +87005,8 @@ index 12af0192b6..5337f104c6 100644 + uint8_t key_b = ((uint8_t *)&b->key)[i] & mask; + + if (key_a != key_b) { -+ VLOG_DBG_RL(&error_rl, "tc flower compare failed key compare at " -+ "%d", i); ++ log_tc_flower_match("tc flower compare failed masked key compare:", ++ a, b); + return false; + } + } @@ -86648,14 +87016,15 @@ index 12af0192b6..5337f104c6 100644 + const struct tc_action *action_b = b->actions; + + if (a->action_count != b->action_count) { -+ VLOG_DBG_RL(&error_rl, "tc flower compare failed action length check"); ++ log_tc_flower_match("tc flower compare failed action length check", ++ a, b); + return false; + } + + for (int i = 0; i < a->action_count; i++, action_a++, action_b++) { + if (memcmp(action_a, action_b, sizeof *action_a)) { -+ VLOG_DBG_RL(&error_rl, "tc flower compare failed action compare " -+ "for %d", i); ++ log_tc_flower_match("tc flower compare failed action compare", ++ a, b); + return false; + } + } @@ -86666,7 +87035,7 @@ index 12af0192b6..5337f104c6 100644 int tc_replace_flower(struct tcf_id *id, struct tc_flower *flower) { -@@ -2802,6 +2885,20 @@ tc_replace_flower(struct tcf_id *id, struct tc_flower *flower) +@@ -2802,6 +2988,20 @@ tc_replace_flower(struct tcf_id *id, struct tc_flower *flower) id->prio = tc_get_major(tc->tcm_info); id->handle = tc->tcm_handle; @@ -86688,7 +87057,7 @@ index 12af0192b6..5337f104c6 100644 } diff --git a/lib/tc.h b/lib/tc.h -index d31c0953ed..e5657e52dd 100644 +index d31c0953ed..b75af1a412 100644 --- a/lib/tc.h +++ b/lib/tc.h @@ -235,7 +235,7 @@ struct tc_action { @@ -86700,7 +87069,31 @@ index d31c0953ed..e5657e52dd 100644 ovs_be16 min; ovs_be16 max; } port; -@@ -304,6 +304,14 @@ is_tcf_id_eq(struct tcf_id *id1, struct tcf_id *id2) +@@ -245,11 +245,23 @@ struct tc_action { + bool force; + bool commit; + } ct; ++ ++ struct { ++ struct tc_flower_key key; ++ struct tc_flower_key mask; ++ } rewrite; + }; + + enum tc_action_type type; + }; + ++/* assert that if we overflow with a masked write of uint32_t to the last byte ++ * of action.rewrite we overflow inside struct tc_action. ++ * shouldn't happen unless someone moves rewrite to the end of action */ ++BUILD_ASSERT_DECL(offsetof(struct tc_action, rewrite) ++ + MEMBER_SIZEOF(struct tc_action, rewrite) ++ + sizeof(uint32_t) - 2 < sizeof(struct tc_action)); ++ + enum tc_offloaded_state { + TC_OFFLOADED_STATE_UNDEFINED, + TC_OFFLOADED_STATE_IN_HW, +@@ -304,6 +316,14 @@ is_tcf_id_eq(struct tcf_id *id1, struct tcf_id *id2) && id1->chain == id2->chain; } @@ -86715,7 +87108,7 @@ index d31c0953ed..e5657e52dd 100644 struct tc_flower { struct tc_flower_key key; struct tc_flower_key mask; -@@ -311,7 +319,8 @@ struct tc_flower { +@@ -311,15 +331,10 @@ struct tc_flower { int action_count; struct tc_action actions[TCA_ACT_MAX_NUM]; @@ -86724,8 +87117,16 @@ index d31c0953ed..e5657e52dd 100644 + struct ovs_flow_stats stats_hw; uint64_t lastused; - struct { -@@ -329,6 +338,8 @@ struct tc_flower { +- struct { +- bool rewrite; +- struct tc_flower_key key; +- struct tc_flower_key mask; +- } rewrite; +- + uint32_t csum_update_flags; + + bool tunnel; +@@ -329,15 +344,10 @@ struct tc_flower { bool needs_full_ip_proto_mask; enum tc_offloaded_state offloaded_state; @@ -86733,7 +87134,16 @@ index d31c0953ed..e5657e52dd 100644 + enum tc_offload_policy tc_policy; }; - /* assert that if we overflow with a masked write of uint32_t to the last byte +-/* assert that if we overflow with a masked write of uint32_t to the last byte +- * of flower.rewrite we overflow inside struct flower. +- * shouldn't happen unless someone moves rewrite to the end of flower */ +-BUILD_ASSERT_DECL(offsetof(struct tc_flower, rewrite) +- + MEMBER_SIZEOF(struct tc_flower, rewrite) +- + 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_get_flower(struct tcf_id *id, struct tc_flower *flower); diff --git a/lib/tnl-neigh-cache.c b/lib/tnl-neigh-cache.c index 5bda4af7e0..995c88bf17 100644 --- a/lib/tnl-neigh-cache.c diff --git a/SPECS/openvswitch2.13.spec b/SPECS/openvswitch2.13.spec index 39f8afa..7cf7f39 100644 --- a/SPECS/openvswitch2.13.spec +++ b/SPECS/openvswitch2.13.spec @@ -59,7 +59,7 @@ Summary: Open vSwitch Group: System Environment/Daemons daemon/database/utilities URL: http://www.openvswitch.org/ Version: 2.13.0 -Release: 167%{?commit0:.%{date}git%{shortcommit0}}%{?commit1:dpdk%{shortcommit1}}%{?dist} +Release: 168%{?commit0:.%{date}git%{shortcommit0}}%{?commit1:dpdk%{shortcommit1}}%{?dist} # Nearly all of openvswitch is ASL 2.0. The bugtool is LGPLv2+, and the # lib/sflow*.[ch] files are SISSL @@ -715,6 +715,18 @@ exit 0 %endif %changelog +* Mon Mar 21 2022 Open vSwitch CI - 2.13.0-168 +- Merging upstream branch-2.13 [RH git: a43ac9e3c0] + Commit list: + 67baf6c5ad odp-util: Fix output for tc to be equal to kernel. + d5a2b05e31 netdev-offload-tc: Fix IP and port ranges in flower returns. + c0b51d66cb netdev-offload-tc: Always include conntrack information to tc. + abd06ed63b netdev-offload-tc: Check for valid netdev ifindex in flow_put. + 36fe91237c netdev-offload-tc: Set the correct VLAN_VID and VLAN_PCP masks. + b69970b879 netdev-offload-tc: Add debug logs on tc rule verify failures. + 9f77633c66 tc: Keep header rewrite actions order. + + * Fri Mar 18 2022 Open vSwitch CI - 2.13.0-167 - Merging upstream branch-2.13 [RH git: 98b4b38f08] Commit list: