From 68480486f9a51acdb61c0f8f374c253fff3f1d4d Mon Sep 17 00:00:00 2001 From: Open vSwitch CI Date: Apr 21 2021 23:19:35 +0000 Subject: Import openvswitch2.13-2.13.0-107 from Fast DataPath --- diff --git a/SOURCES/openvswitch-2.13.0.patch b/SOURCES/openvswitch-2.13.0.patch index 123143a..86f0713 100644 --- a/SOURCES/openvswitch-2.13.0.patch +++ b/SOURCES/openvswitch-2.13.0.patch @@ -1041,9 +1041,23 @@ index e06ddf2671..8e64d74aee 100644 :target: https://ci.appveyor.com/project/blp/ovs/history .. image:: https://api.cirrus-ci.com/github/openvswitch/ovs.svg diff --git a/acinclude.m4 b/acinclude.m4 -index c1470ccc6b..f4fd56e620 100644 +index c1470ccc6b..914e27b932 100644 --- a/acinclude.m4 +++ b/acinclude.m4 +@@ -192,10 +192,10 @@ dnl Configure Linux tc compat. + AC_DEFUN([OVS_CHECK_LINUX_TC], [ + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([#include ], [ +- int x = TCA_ACT_FLAGS; ++ int x = TCA_FLOWER_KEY_CT_FLAGS_REPLY; + ])], +- [AC_DEFINE([HAVE_TCA_ACT_FLAGS], [1], +- [Define to 1 if TCA_ACT_FLAGS is available.])]) ++ [AC_DEFINE([HAVE_TCA_FLOWER_KEY_CT_FLAGS_REPLY], [1], ++ [Define to 1 if TCA_FLOWER_KEY_CT_FLAGS_REPLY is available.])]) + + AC_CHECK_MEMBERS([struct tcf_t.firstuse], [], [], [#include ]) + @@ -250,6 +250,18 @@ AC_DEFUN([OVS_CHECK_LINUX_SCTP_CT], [ [Define to 1 if SCTP_CONNTRACK_HEARTBEAT_SENT is available.])]) ]) @@ -79764,6 +79778,29 @@ index 290345dcc4..35edb7cd26 100755 def interactiveMenu(self, sleep_time): # Creates Interactive menu within the script while self.choice != 4: +diff --git a/include/linux/pkt_cls.h b/include/linux/pkt_cls.h +index b0a5ce8bec..bc51a5767f 100644 +--- a/include/linux/pkt_cls.h ++++ b/include/linux/pkt_cls.h +@@ -1,7 +1,7 @@ + #ifndef __LINUX_PKT_CLS_WRAPPER_H + #define __LINUX_PKT_CLS_WRAPPER_H 1 + +-#if defined(__KERNEL__) || defined(HAVE_TCA_ACT_FLAGS) ++#if defined(__KERNEL__) || defined(HAVE_TCA_FLOWER_KEY_CT_FLAGS_REPLY) + #include_next + #else + +@@ -255,6 +255,9 @@ enum { + TCA_FLOWER_KEY_CT_FLAGS_ESTABLISHED = 1 << 1, /* Part of an existing connection. */ + TCA_FLOWER_KEY_CT_FLAGS_RELATED = 1 << 2, /* Related to an established connection. */ + TCA_FLOWER_KEY_CT_FLAGS_TRACKED = 1 << 3, /* Conntrack has occurred. */ ++ TCA_FLOWER_KEY_CT_FLAGS_INVALID = 1 << 4, /* Conntrack is invalid. */ ++ TCA_FLOWER_KEY_CT_FLAGS_REPLY = 1 << 5, /* Packet is in the reply direction. */ ++ __TCA_FLOWER_KEY_CT_FLAGS_MAX, + }; + + enum { diff --git a/include/openvswitch/compiler.h b/include/openvswitch/compiler.h index 5289a70f6e..cf009f8264 100644 --- a/include/openvswitch/compiler.h @@ -81046,7 +81083,7 @@ index d393aab5e3..5233908f29 100644 } else { atomic_count_set(&pmd->pmd_overloaded, 0); diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c -index 5b5c96d727..f9c732886f 100644 +index 5b5c96d727..54ca8d7e62 100644 --- a/lib/dpif-netlink.c +++ b/lib/dpif-netlink.c @@ -691,6 +691,7 @@ dpif_netlink_set_features(struct dpif *dpif_, uint32_t new_features) @@ -81057,14 +81094,14 @@ index 5b5c96d727..f9c732886f 100644 request.dp_ifindex = dpif->dp_ifindex; request.user_features = dpif->user_features | new_features; -@@ -2091,6 +2092,7 @@ parse_flow_put(struct dpif_netlink *dpif, struct dpif_flow_put *put) - info.tunnel_csum_on = csum_on; - info.recirc_id_shared_with_tc = (dpif->user_features - & OVS_DP_F_TC_RECIRC_SHARING); +@@ -2046,6 +2047,7 @@ parse_flow_put(struct dpif_netlink *dpif, struct dpif_flow_put *put) + uint8_t csum_on = false; + int err; + + info.tc_modify_flow_deleted = false; - err = netdev_flow_put(dev, &match, - CONST_CAST(struct nlattr *, put->actions), - put->actions_len, + if (put->flags & DPIF_FP_PROBE) { + return EOPNOTSUPP; + } @@ -2141,7 +2143,11 @@ parse_flow_put(struct dpif_netlink *dpif, struct dpif_flow_put *put) out: if (err && err != EEXIST && (put->flags & DPIF_FP_MODIFY)) { @@ -81078,6 +81115,31 @@ index 5b5c96d727..f9c732886f 100644 if (!del_err) { /* Delete from hw success, so old flow was offloaded. +diff --git a/lib/dpif.c b/lib/dpif.c +index 9d9c716c13..1847689114 100644 +--- a/lib/dpif.c ++++ b/lib/dpif.c +@@ -1235,6 +1235,7 @@ dpif_execute_helper_cb(void *aux_, struct dp_packet_batch *packets_, + execute.needs_help = false; + execute.probe = false; + execute.mtu = 0; ++ execute.hash = 0; + aux->error = dpif_execute(aux->dpif, &execute); + log_execute_message(aux->dpif, &this_module, &execute, + true, aux->error); +diff --git a/lib/dpif.h b/lib/dpif.h +index 4df8f7c8b7..31d3139845 100644 +--- a/lib/dpif.h ++++ b/lib/dpif.h +@@ -725,7 +725,7 @@ struct dpif_execute { + bool probe; /* Suppress error messages. */ + unsigned int mtu; /* Maximum transmission unit to fragment. + 0 if not a fragmented packet */ +- uint64_t hash; ++ uint64_t hash; /* Packet flow hash. 0 if not specified. */ + const struct flow *flow; /* Flow extracted from 'packet'. */ + + /* Input, but possibly modified as a side effect of execution. */ diff --git a/lib/flow.c b/lib/flow.c index 45bb96b543..353d5cd3ed 100644 --- a/lib/flow.c @@ -81981,10 +82043,18 @@ index f8c46bbaad..b42d314b65 100644 static int diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c -index 550e440b3a..c00505d181 100644 +index 550e440b3a..2507f7d8bd 100644 --- a/lib/netdev-offload-tc.c +++ b/lib/netdev-offload-tc.c -@@ -198,7 +198,9 @@ del_filter_and_ufid_mapping(struct tcf_id *id, const ovs_u128 *ufid) +@@ -48,6 +48,7 @@ static struct hmap ufid_to_tc = HMAP_INITIALIZER(&ufid_to_tc); + static struct hmap tc_to_ufid = HMAP_INITIALIZER(&tc_to_ufid); + static bool multi_mask_per_prio = false; + static bool block_support = false; ++static uint16_t ct_state_support; + + struct netlink_field { + int offset; +@@ -198,7 +199,9 @@ del_filter_and_ufid_mapping(struct tcf_id *id, const ovs_u128 *ufid) int err; err = tc_del_filter(id); @@ -81995,39 +82065,140 @@ index 550e440b3a..c00505d181 100644 return err; } -@@ -1578,6 +1580,7 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, - flower.key.ct_state |= TCA_FLOWER_KEY_CT_FLAGS_NEW; - } - flower.mask.ct_state |= TCA_FLOWER_KEY_CT_FLAGS_NEW; -+ mask->ct_state &= ~OVS_CS_F_NEW; - } +@@ -1352,6 +1355,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; + } - if (mask->ct_state & OVS_CS_F_ESTABLISHED) { -@@ -1585,6 +1588,7 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, - flower.key.ct_state |= TCA_FLOWER_KEY_CT_FLAGS_ESTABLISHED; - } - flower.mask.ct_state |= TCA_FLOWER_KEY_CT_FLAGS_ESTABLISHED; ++static void ++parse_match_ct_state_to_flower(struct tc_flower *flower, struct match *match) ++{ ++ const struct flow *key = &match->flow; ++ struct flow *mask = &match->wc.masks; ++ ++ if (!ct_state_support) { ++ return; ++ } ++ ++ if ((ct_state_support & mask->ct_state) == mask->ct_state) { ++ if (mask->ct_state & OVS_CS_F_NEW) { ++ if (key->ct_state & OVS_CS_F_NEW) { ++ flower->key.ct_state |= TCA_FLOWER_KEY_CT_FLAGS_NEW; ++ } ++ flower->mask.ct_state |= TCA_FLOWER_KEY_CT_FLAGS_NEW; ++ mask->ct_state &= ~OVS_CS_F_NEW; ++ } ++ ++ if (mask->ct_state & OVS_CS_F_ESTABLISHED) { ++ if (key->ct_state & OVS_CS_F_ESTABLISHED) { ++ flower->key.ct_state |= TCA_FLOWER_KEY_CT_FLAGS_ESTABLISHED; ++ } ++ flower->mask.ct_state |= TCA_FLOWER_KEY_CT_FLAGS_ESTABLISHED; + mask->ct_state &= ~OVS_CS_F_ESTABLISHED; - } - - if (mask->ct_state & OVS_CS_F_TRACKED) { -@@ -1592,14 +1596,13 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, - flower.key.ct_state |= TCA_FLOWER_KEY_CT_FLAGS_TRACKED; - } - flower.mask.ct_state |= TCA_FLOWER_KEY_CT_FLAGS_TRACKED; ++ } ++ ++ if (mask->ct_state & OVS_CS_F_TRACKED) { ++ if (key->ct_state & OVS_CS_F_TRACKED) { ++ flower->key.ct_state |= TCA_FLOWER_KEY_CT_FLAGS_TRACKED; ++ } ++ flower->mask.ct_state |= TCA_FLOWER_KEY_CT_FLAGS_TRACKED; + mask->ct_state &= ~OVS_CS_F_TRACKED; ++ } ++ ++ if (flower->key.ct_state & TCA_FLOWER_KEY_CT_FLAGS_ESTABLISHED) { ++ flower->key.ct_state &= ~(TCA_FLOWER_KEY_CT_FLAGS_NEW); ++ flower->mask.ct_state &= ~(TCA_FLOWER_KEY_CT_FLAGS_NEW); ++ } ++ } ++ ++ if (mask->ct_zone) { ++ flower->key.ct_zone = key->ct_zone; ++ flower->mask.ct_zone = mask->ct_zone; ++ mask->ct_zone = 0; ++ } ++ ++ if (mask->ct_mark) { ++ flower->key.ct_mark = key->ct_mark; ++ flower->mask.ct_mark = mask->ct_mark; ++ mask->ct_mark = 0; ++ } ++ ++ if (!ovs_u128_is_zero(mask->ct_label)) { ++ flower->key.ct_label = key->ct_label; ++ flower->mask.ct_label = mask->ct_label; ++ mask->ct_label = OVS_U128_ZERO; ++ } ++} ++ + static int + netdev_tc_flow_put(struct netdev *netdev, struct match *match, + struct nlattr *actions, size_t actions_len, +@@ -1572,53 +1635,7 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, } + } - if (flower.key.ct_state & TCA_FLOWER_KEY_CT_FLAGS_ESTABLISHED) { - flower.key.ct_state &= ~(TCA_FLOWER_KEY_CT_FLAGS_NEW); - flower.mask.ct_state &= ~(TCA_FLOWER_KEY_CT_FLAGS_NEW); - } +- if (mask->ct_state) { +- if (mask->ct_state & OVS_CS_F_NEW) { +- if (key->ct_state & OVS_CS_F_NEW) { +- flower.key.ct_state |= TCA_FLOWER_KEY_CT_FLAGS_NEW; +- } +- flower.mask.ct_state |= TCA_FLOWER_KEY_CT_FLAGS_NEW; +- } +- +- if (mask->ct_state & OVS_CS_F_ESTABLISHED) { +- if (key->ct_state & OVS_CS_F_ESTABLISHED) { +- flower.key.ct_state |= TCA_FLOWER_KEY_CT_FLAGS_ESTABLISHED; +- } +- flower.mask.ct_state |= TCA_FLOWER_KEY_CT_FLAGS_ESTABLISHED; +- } +- +- if (mask->ct_state & OVS_CS_F_TRACKED) { +- if (key->ct_state & OVS_CS_F_TRACKED) { +- flower.key.ct_state |= TCA_FLOWER_KEY_CT_FLAGS_TRACKED; +- } +- flower.mask.ct_state |= TCA_FLOWER_KEY_CT_FLAGS_TRACKED; +- } +- +- if (flower.key.ct_state & TCA_FLOWER_KEY_CT_FLAGS_ESTABLISHED) { +- flower.key.ct_state &= ~(TCA_FLOWER_KEY_CT_FLAGS_NEW); +- flower.mask.ct_state &= ~(TCA_FLOWER_KEY_CT_FLAGS_NEW); +- } - - mask->ct_state = 0; - } +- } +- +- if (mask->ct_zone) { +- flower.key.ct_zone = key->ct_zone; +- flower.mask.ct_zone = mask->ct_zone; +- mask->ct_zone = 0; +- } +- +- if (mask->ct_mark) { +- flower.key.ct_mark = key->ct_mark; +- flower.mask.ct_mark = mask->ct_mark; +- mask->ct_mark = 0; +- } +- +- if (!ovs_u128_is_zero(mask->ct_label)) { +- flower.key.ct_label = key->ct_label; +- flower.mask.ct_label = mask->ct_label; +- mask->ct_label = OVS_U128_ZERO; +- } ++ parse_match_ct_state_to_flower(&flower, match); + + /* ignore exact match on skb_mark of 0. */ + if (mask->pkt_mark == UINT32_MAX && !key->pkt_mark) { +@@ -1699,6 +1716,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); - if (mask->ct_zone) { -@@ -1727,7 +1730,7 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, ++ if (!ct_state_support) { ++ return -EOPNOTSUPP; ++ } ++ + err = parse_put_flow_ct_action(&flower, action, ct, ct_len); + if (err) { + return err; +@@ -1727,7 +1748,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); @@ -82036,7 +82207,120 @@ index 550e440b3a..c00505d181 100644 } prio = get_prio_for_tc_flower(&flower); -@@ -1907,6 +1910,7 @@ netdev_tc_init_flow_api(struct netdev *netdev) +@@ -1837,6 +1858,7 @@ probe_multi_mask_per_prio(int ifindex) + + memset(&flower, 0, sizeof flower); + ++ flower.tc_policy = TC_POLICY_SKIP_HW; + 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 +1890,96 @@ out: + tc_add_del_qdisc(ifindex, false, block_id, TC_INGRESS); + } + ++ ++static int ++probe_insert_ct_state_rule(int ifindex, uint16_t ct_state, struct tcf_id *id) ++{ ++ int prio = TC_RESERVED_PRIORITY_MAX + 1; ++ struct tc_flower flower; ++ ++ memset(&flower, 0, sizeof flower); ++ flower.key.ct_state = ct_state; ++ flower.mask.ct_state = ct_state; ++ flower.tc_policy = TC_POLICY_SKIP_HW; ++ flower.key.eth_type = htons(ETH_P_IP); ++ flower.mask.eth_type = OVS_BE16_MAX; ++ ++ *id = tc_make_tcf_id(ifindex, 0, prio, TC_INGRESS); ++ return tc_replace_flower(id, &flower); ++} ++ ++static void ++probe_ct_state_support(int ifindex) ++{ ++ struct tc_flower flower; ++ uint16_t ct_state; ++ struct tcf_id id; ++ int error; ++ ++ error = tc_add_del_qdisc(ifindex, true, 0, TC_INGRESS); ++ if (error) { ++ return; ++ } ++ ++ /* Test for base ct_state match support */ ++ ct_state = TCA_FLOWER_KEY_CT_FLAGS_NEW | TCA_FLOWER_KEY_CT_FLAGS_TRACKED; ++ error = probe_insert_ct_state_rule(ifindex, ct_state, &id); ++ if (error) { ++ goto out; ++ } ++ ++ error = tc_get_flower(&id, &flower); ++ if (error || flower.mask.ct_state != ct_state) { ++ goto out_del; ++ } ++ ++ tc_del_filter(&id); ++ ct_state_support = OVS_CS_F_NEW | ++ OVS_CS_F_ESTABLISHED | ++ OVS_CS_F_TRACKED | ++ OVS_CS_F_RELATED; ++ ++ /* Test for reject, ct_state >= MAX */ ++ ct_state = ~0; ++ error = probe_insert_ct_state_rule(ifindex, ct_state, &id); ++ if (!error) { ++ /* No reject, can't continue probing other flags */ ++ goto out_del; ++ } ++ ++ tc_del_filter(&id); ++ ++ /* Test for ct_state INVALID support */ ++ memset(&flower, 0, sizeof flower); ++ ct_state = TCA_FLOWER_KEY_CT_FLAGS_TRACKED | ++ TCA_FLOWER_KEY_CT_FLAGS_INVALID; ++ error = probe_insert_ct_state_rule(ifindex, ct_state, &id); ++ if (error) { ++ goto out; ++ } ++ ++ tc_del_filter(&id); ++ ct_state_support |= OVS_CS_F_INVALID; ++ ++ /* Test for ct_state REPLY support */ ++ memset(&flower, 0, sizeof flower); ++ ct_state = TCA_FLOWER_KEY_CT_FLAGS_TRACKED | ++ TCA_FLOWER_KEY_CT_FLAGS_ESTABLISHED | ++ TCA_FLOWER_KEY_CT_FLAGS_REPLY; ++ error = probe_insert_ct_state_rule(ifindex, ct_state, &id); ++ if (error) { ++ goto out; ++ } ++ ++ ct_state_support |= OVS_CS_F_REPLY_DIR; ++ ++out_del: ++ tc_del_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); ++} ++ + static void + probe_tc_block_support(int ifindex) + { +@@ -1884,6 +1996,7 @@ probe_tc_block_support(int ifindex) + + memset(&flower, 0, sizeof flower); + ++ flower.tc_policy = TC_POLICY_SKIP_HW; + 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 +2020,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; @@ -82044,7 +82328,7 @@ index 550e440b3a..c00505d181 100644 int ifindex; int error; -@@ -1917,11 +1921,21 @@ netdev_tc_init_flow_api(struct netdev *netdev) +@@ -1917,20 +2031,30 @@ netdev_tc_init_flow_api(struct netdev *netdev) return -ifindex; } @@ -82066,7 +82350,9 @@ index 550e440b3a..c00505d181 100644 ovsthread_once_done(&block_once); } -@@ -1930,7 +1944,6 @@ netdev_tc_init_flow_api(struct netdev *netdev) + if (ovsthread_once_start(&multi_mask_once)) { + probe_multi_mask_per_prio(ifindex); ++ probe_ct_state_support(ifindex); ovsthread_once_done(&multi_mask_once); } @@ -82218,7 +82504,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..b288269fc4 100644 +index 746d1e97d4..9701f1a763 100644 --- a/lib/odp-util.c +++ b/lib/odp-util.c @@ -390,7 +390,8 @@ format_odp_push_nsh_action(struct ds *ds, @@ -82258,6 +82544,32 @@ index 746d1e97d4..b288269fc4 100644 goto out; } } +@@ -3136,17 +3143,17 @@ tun_key_to_attr(struct ofpbuf *a, const struct flow_tnl *tun_key, + if ((!tnl_type || !strcmp(tnl_type, "erspan") || + !strcmp(tnl_type, "ip6erspan")) && + (tun_key->erspan_ver == 1 || tun_key->erspan_ver == 2)) { +- struct erspan_metadata opts; ++ struct erspan_metadata *opts; + +- opts.version = tun_key->erspan_ver; +- if (opts.version == 1) { +- opts.u.index = htonl(tun_key->erspan_idx); ++ opts = nl_msg_put_unspec_zero(a, OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS, ++ sizeof *opts); ++ opts->version = tun_key->erspan_ver; ++ if (opts->version == 1) { ++ opts->u.index = htonl(tun_key->erspan_idx); + } else { +- opts.u.md2.dir = tun_key->erspan_dir; +- set_hwid(&opts.u.md2, tun_key->erspan_hwid); ++ opts->u.md2.dir = tun_key->erspan_dir; ++ set_hwid(&opts->u.md2, tun_key->erspan_hwid); + } +- nl_msg_put_unspec(a, OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS, +- &opts, sizeof(opts)); + } + + nl_msg_end_nested(a, tun_key_ofs); @@ -5428,13 +5435,16 @@ erspan_to_attr(struct ofpbuf *a, const void *data_) do { \ len = 0; @@ -83672,10 +83984,23 @@ index eda265dfc5..a635ff7689 100644 #define SHA1_FMT \ "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" \ diff --git a/lib/tc.c b/lib/tc.c -index 12af0192b6..5a6f76a209 100644 +index 12af0192b6..65938d7bee 100644 --- a/lib/tc.c +++ b/lib/tc.c -@@ -456,7 +456,7 @@ nl_parse_flower_mpls(struct nlattr **attrs, struct tc_flower *flower) +@@ -60,12 +60,6 @@ VLOG_DEFINE_THIS_MODULE(tc); + + static struct vlog_rate_limit error_rl = VLOG_RATE_LIMIT_INIT(60, 5); + +-enum tc_offload_policy { +- TC_POLICY_NONE, +- TC_POLICY_SKIP_SW, +- TC_POLICY_SKIP_HW +-}; +- + static enum tc_offload_policy tc_policy = TC_POLICY_NONE; + + struct tc_pedit_key_ex { +@@ -456,7 +450,7 @@ nl_parse_flower_mpls(struct nlattr **attrs, struct tc_flower *flower) if (attrs[TCA_FLOWER_KEY_MPLS_BOS]) { bos = nl_attr_get_u8(attrs[TCA_FLOWER_KEY_MPLS_BOS]); set_mpls_lse_bos(&flower->key.mpls_lse, bos); @@ -83684,7 +84009,7 @@ index 12af0192b6..5a6f76a209 100644 } if (attrs[TCA_FLOWER_KEY_MPLS_TC]) { -@@ -934,6 +934,7 @@ nl_parse_act_pedit(struct nlattr *options, struct tc_flower *flower) +@@ -934,6 +928,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; @@ -83692,7 +84017,7 @@ index 12af0192b6..5a6f76a209 100644 if (m->htype != type) { continue; -@@ -941,9 +942,10 @@ nl_parse_act_pedit(struct nlattr *options, struct tc_flower *flower) +@@ -941,9 +936,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 @@ -83705,7 +84030,7 @@ index 12af0192b6..5a6f76a209 100644 int diff = flower_off + (keys->off - mf); ovs_be32 *dst = (void *) (rewrite_key + diff); ovs_be32 *dst_m = (void *) (rewrite_mask + diff); -@@ -1647,8 +1649,10 @@ nl_parse_single_action(struct nlattr *action, struct tc_flower *flower) +@@ -1647,8 +1643,10 @@ nl_parse_single_action(struct nlattr *action, struct tc_flower *flower) } bs = nl_attr_get_unspec(stats_attrs[TCA_STATS_BASIC], sizeof *bs); @@ -83718,8 +84043,29 @@ index 12af0192b6..5a6f76a209 100644 return 0; } +@@ -2645,6 +2643,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); ++ enum tc_offload_policy policy = flower->tc_policy; + int err; + + /* need to parse acts first as some acts require changing the matching +@@ -2762,7 +2761,11 @@ nl_msg_put_flower_options(struct ofpbuf *request, struct tc_flower *flower) + } + } + +- nl_msg_put_u32(request, TCA_FLOWER_FLAGS, tc_get_tc_cls_policy(tc_policy)); ++ if (policy == TC_POLICY_NONE) { ++ policy = tc_policy; ++ } ++ ++ nl_msg_put_u32(request, TCA_FLOWER_FLAGS, tc_get_tc_cls_policy(policy)); + + if (flower->tunnel) { + nl_msg_put_flower_tunnel(request, flower); diff --git a/lib/tc.h b/lib/tc.h -index d31c0953ed..24a4994fd1 100644 +index d31c0953ed..0dc62bd83f 100644 --- a/lib/tc.h +++ b/lib/tc.h @@ -235,7 +235,7 @@ struct tc_action { @@ -83731,6 +84077,30 @@ index d31c0953ed..24a4994fd1 100644 ovs_be16 min; ovs_be16 max; } port; +@@ -304,6 +304,14 @@ is_tcf_id_eq(struct tcf_id *id1, struct tcf_id *id2) + && id1->chain == id2->chain; + } + ++enum tc_offload_policy { ++ TC_POLICY_NONE = 0, ++ TC_POLICY_SKIP_SW, ++ TC_POLICY_SKIP_HW ++}; ++ ++BUILD_ASSERT_DECL(TC_POLICY_NONE == 0); ++ + struct tc_flower { + struct tc_flower_key key; + struct tc_flower_key mask; +@@ -329,6 +337,8 @@ struct tc_flower { + bool needs_full_ip_proto_mask; + + enum tc_offloaded_state offloaded_state; ++ /* Used to force skip_hw when probing tc features. */ ++ enum tc_offload_policy tc_policy; + }; + + /* assert that if we overflow with a masked write of uint32_t to the last byte diff --git a/lib/util.c b/lib/util.c index 830e14516f..25635b27ff 100644 --- a/lib/util.c @@ -83901,6 +84271,23 @@ index 147ef9c333..97699cb905 100644 flow->metadata = md->metadata; memcpy(flow->regs, md->regs, sizeof flow->regs); flow->in_port.ofp_port = md->in_port; +diff --git a/ofproto/ofproto-dpif-sflow.c b/ofproto/ofproto-dpif-sflow.c +index f9ea47a2f1..6324e74d52 100644 +--- a/ofproto/ofproto-dpif-sflow.c ++++ b/ofproto/ofproto-dpif-sflow.c +@@ -1291,10 +1291,10 @@ dpif_sflow_received(struct dpif_sflow *ds, const struct dp_packet *packet, + ovs_be16 vlan_tci; + + ovs_mutex_lock(&mutex); +- sampler = ds->sflow_agent->samplers; +- if (!sampler) { ++ if (!ds->sflow_agent || !ds->sflow_agent->samplers) { + goto out; + } ++ sampler = ds->sflow_agent->samplers; + + /* Build a flow sample. */ + memset(&fs, 0, sizeof fs); diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c index 409286ab15..cb197e9010 100644 --- a/ofproto/ofproto-dpif-upcall.c diff --git a/SPECS/openvswitch2.13.spec b/SPECS/openvswitch2.13.spec index fa413e9..dae1d22 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: 105%{?commit0:.%{date}git%{shortcommit0}}%{?commit1:dpdk%{shortcommit1}}%{?dist} +Release: 107%{?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 @@ -710,6 +710,14 @@ exit 0 %endif %changelog +* Wed Apr 21 2021 Open vSwitch CI - 2.13.0-107 +- Merging upstream branch-2.13 + [9a8a64930161e8b1721509c8ca3562fbd837be49] + +* Tue Apr 20 2021 Timothy Redaelli - 2.13.0-106 +- Fix typo in rh-mock-srpm + [5641bf9d72c0bb4a56a4a84dfb9d673ef60b42ab] + * Wed Apr 14 2021 Open vSwitch CI - 2.13.0-105 - Merging upstream branch-2.13 [0aaf7c02b702ebd002e5936868dd117706c505b4]