From 2647801da8e6c8004a22f5bac1b6f40a82268192 Mon Sep 17 00:00:00 2001 From: Open vSwitch CI Date: Aug 10 2023 02:07:27 +0000 Subject: Import openvswitch2.17-2.17.0-113 from Fast DataPath --- diff --git a/SOURCES/openvswitch-2.17.0.patch b/SOURCES/openvswitch-2.17.0.patch index 9d2ccdc..b95502d 100644 --- a/SOURCES/openvswitch-2.17.0.patch +++ b/SOURCES/openvswitch-2.17.0.patch @@ -60765,7 +60765,7 @@ index 114aff8ea3..0fc6d2ea60 100644 enum xc_type type; union { diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c -index 578cbfe581..4b4d5c7a76 100644 +index 578cbfe581..2b1611c912 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -66,6 +66,7 @@ @@ -60776,7 +60776,92 @@ index 578cbfe581..4b4d5c7a76 100644 COVERAGE_DEFINE(xlate_actions); COVERAGE_DEFINE(xlate_actions_oversize); -@@ -865,7 +866,7 @@ xlate_xbridge_init(struct xlate_cfg *xcfg, struct xbridge *xbridge) +@@ -500,6 +501,84 @@ ctx_cancel_freeze(struct xlate_ctx *ctx) + + static void finish_freezing(struct xlate_ctx *ctx); + ++/* These functions and structure are used to save stack space in actions that ++ * need to retain a large amount of xlate_ctx state. */ ++struct xretained_state { ++ union mf_subvalue new_stack[1024 / sizeof(union mf_subvalue)]; ++ uint64_t actset_stub[1024 / 8]; ++ struct ofpbuf old_stack; ++ struct ofpbuf old_action_set; ++ struct flow old_flow; ++ struct flow old_base; ++ struct flow_tnl flow_tnl_mask; ++}; ++ ++/* The return of this function must be freed by ++ * xretain_state_restore_and_free(). */ ++static struct xretained_state * ++xretain_state_save(struct xlate_ctx *ctx) ++{ ++ struct xretained_state *retained = xmalloc(sizeof *retained); ++ ++ retained->old_flow = ctx->xin->flow; ++ retained->old_stack = ctx->stack; ++ retained->old_action_set = ctx->action_set; ++ ofpbuf_use_stub(&ctx->stack, retained->new_stack, ++ sizeof retained->new_stack); ++ ofpbuf_use_stub(&ctx->action_set, retained->actset_stub, ++ sizeof retained->actset_stub); ++ ++ return retained; ++} ++ ++static void ++xretain_tunnel_mask_save(const struct xlate_ctx *ctx, ++ struct xretained_state *retained) ++{ ++ retained->flow_tnl_mask = ctx->wc->masks.tunnel; ++} ++ ++static void ++xretain_base_flow_save(const struct xlate_ctx *ctx, ++ struct xretained_state *retained) ++{ ++ retained->old_base = ctx->base_flow; ++} ++ ++static void ++xretain_base_flow_restore(struct xlate_ctx *ctx, ++ const struct xretained_state *retained) ++{ ++ ctx->base_flow = retained->old_base; ++} ++ ++static void ++xretain_flow_restore(struct xlate_ctx *ctx, ++ const struct xretained_state *retained) ++{ ++ ctx->xin->flow = retained->old_flow; ++} ++ ++static void ++xretain_tunnel_mask_restore(struct xlate_ctx *ctx, ++ const struct xretained_state *retained) ++{ ++ ctx->wc->masks.tunnel = retained->flow_tnl_mask; ++} ++ ++static void ++xretain_state_restore_and_free(struct xlate_ctx *ctx, ++ struct xretained_state *retained) ++{ ++ ctx->xin->flow = retained->old_flow; ++ ofpbuf_uninit(&ctx->action_set); ++ ctx->action_set = retained->old_action_set; ++ ofpbuf_uninit(&ctx->stack); ++ ctx->stack = retained->old_stack; ++ ++ free(retained); ++} ++ + /* A controller may use OFPP_NONE as the ingress port to indicate that + * it did not arrive on a "real" port. 'ofpp_none_bundle' exists for + * when an input bundle is needed for validation (e.g., mirroring or +@@ -865,7 +944,7 @@ xlate_xbridge_init(struct xlate_cfg *xcfg, struct xbridge *xbridge) ovs_list_init(&xbridge->xbundles); hmap_init(&xbridge->xports); hmap_insert(&xcfg->xbridges, &xbridge->hmap_node, @@ -60785,7 +60870,7 @@ index 578cbfe581..4b4d5c7a76 100644 } static void -@@ -1017,7 +1018,10 @@ xlate_xbundle_set(struct xbundle *xbundle, +@@ -1017,7 +1096,10 @@ xlate_xbundle_set(struct xbundle *xbundle, xbundle->qinq_ethtype = qinq_ethtype; xbundle->vlan = vlan; xbundle->trunks = trunks; @@ -60797,7 +60882,7 @@ index 578cbfe581..4b4d5c7a76 100644 xbundle->use_priority_tags = use_priority_tags; xbundle->floodable = floodable; xbundle->protected = protected; -@@ -1222,13 +1226,13 @@ xlate_txn_start(void) +@@ -1222,13 +1304,13 @@ xlate_txn_start(void) static void xlate_xcfg_free(struct xlate_cfg *xcfg) { @@ -60813,7 +60898,7 @@ index 578cbfe581..4b4d5c7a76 100644 xlate_xbridge_remove(xcfg, xbridge); } -@@ -1282,18 +1286,18 @@ xlate_ofproto_set(struct ofproto_dpif *ofproto, const char *name, +@@ -1282,18 +1364,18 @@ xlate_ofproto_set(struct ofproto_dpif *ofproto, const char *name, static void xlate_xbridge_remove(struct xlate_cfg *xcfg, struct xbridge *xbridge) { @@ -60836,7 +60921,7 @@ index 578cbfe581..4b4d5c7a76 100644 xlate_xbundle_remove(xcfg, xbundle); } -@@ -1369,6 +1373,7 @@ xlate_xbundle_remove(struct xlate_cfg *xcfg, struct xbundle *xbundle) +@@ -1369,6 +1451,7 @@ xlate_xbundle_remove(struct xlate_cfg *xcfg, struct xbundle *xbundle) ovs_list_remove(&xbundle->list_node); bond_unref(xbundle->bond); lacp_unref(xbundle->lacp); @@ -60844,7 +60929,7 @@ index 578cbfe581..4b4d5c7a76 100644 free(xbundle->name); free(xbundle); } -@@ -1515,7 +1520,7 @@ xlate_lookup_ofproto_(const struct dpif_backer *backer, +@@ -1515,7 +1598,7 @@ xlate_lookup_ofproto_(const struct dpif_backer *backer, if (OVS_UNLIKELY(!recirc_id_node)) { if (errorp) { *errorp = xasprintf("no recirculation data for recirc_id " @@ -60853,7 +60938,7 @@ index 578cbfe581..4b4d5c7a76 100644 } return NULL; } -@@ -1556,8 +1561,8 @@ xlate_lookup_ofproto_(const struct dpif_backer *backer, +@@ -1556,8 +1639,8 @@ xlate_lookup_ofproto_(const struct dpif_backer *backer, if (errorp) { *errorp = (tnl_port_should_receive(flow) ? xstrdup("no OpenFlow tunnel port for this packet") @@ -60864,7 +60949,7 @@ index 578cbfe581..4b4d5c7a76 100644 } return NULL; } -@@ -1639,7 +1644,7 @@ xbridge_lookup(struct xlate_cfg *xcfg, const struct ofproto_dpif *ofproto) +@@ -1639,7 +1722,7 @@ xbridge_lookup(struct xlate_cfg *xcfg, const struct ofproto_dpif *ofproto) xbridges = &xcfg->xbridges; @@ -60873,7 +60958,7 @@ index 578cbfe581..4b4d5c7a76 100644 xbridges) { if (xbridge->ofproto == ofproto) { return xbridge; -@@ -1661,6 +1666,23 @@ xbridge_lookup_by_uuid(struct xlate_cfg *xcfg, const struct uuid *uuid) +@@ -1661,6 +1744,23 @@ xbridge_lookup_by_uuid(struct xlate_cfg *xcfg, const struct uuid *uuid) return NULL; } @@ -60897,7 +60982,7 @@ index 578cbfe581..4b4d5c7a76 100644 static struct xbundle * xbundle_lookup(struct xlate_cfg *xcfg, const struct ofbundle *ofbundle) { -@@ -1894,8 +1916,8 @@ group_is_alive(const struct xlate_ctx *ctx, uint32_t group_id, int depth) +@@ -1894,8 +1994,8 @@ group_is_alive(const struct xlate_ctx *ctx, uint32_t group_id, int depth) #define MAX_LIVENESS_RECURSION 128 /* Arbitrary limit */ static bool @@ -60908,7 +60993,7 @@ index 578cbfe581..4b4d5c7a76 100644 { if (depth >= MAX_LIVENESS_RECURSION) { xlate_report_error(ctx, "bucket chaining exceeded %d links", -@@ -1903,6 +1925,12 @@ bucket_is_alive(const struct xlate_ctx *ctx, +@@ -1903,6 +2003,12 @@ bucket_is_alive(const struct xlate_ctx *ctx, return false; } @@ -60921,7 +61006,7 @@ index 578cbfe581..4b4d5c7a76 100644 return (!ofputil_bucket_has_liveness(bucket) || (bucket->watch_port != OFPP_ANY && bucket->watch_port != OFPP_CONTROLLER -@@ -1943,7 +1971,7 @@ group_first_live_bucket(const struct xlate_ctx *ctx, +@@ -1943,7 +2049,7 @@ group_first_live_bucket(const struct xlate_ctx *ctx, { struct ofputil_bucket *bucket; LIST_FOR_EACH (bucket, list_node, &group->up.buckets) { @@ -60930,7 +61015,7 @@ index 578cbfe581..4b4d5c7a76 100644 return bucket; } xlate_report_bucket_not_live(ctx, bucket); -@@ -1962,7 +1990,7 @@ group_best_live_bucket(const struct xlate_ctx *ctx, +@@ -1962,7 +2068,7 @@ group_best_live_bucket(const struct xlate_ctx *ctx, struct ofputil_bucket *bucket; LIST_FOR_EACH (bucket, list_node, &group->up.buckets) { @@ -60939,7 +61024,7 @@ index 578cbfe581..4b4d5c7a76 100644 uint32_t score = (hash_int(bucket->bucket_id, basis) & 0xffff) * bucket->weight; if (score >= best_score) { -@@ -2125,9 +2153,14 @@ mirror_packet(struct xlate_ctx *ctx, struct xbundle *xbundle, +@@ -2125,9 +2231,14 @@ mirror_packet(struct xlate_ctx *ctx, struct xbundle *xbundle, int snaplen; /* Get the details of the mirror represented by the rightmost 1-bit. */ @@ -60957,7 +61042,7 @@ index 578cbfe581..4b4d5c7a76 100644 /* If this mirror selects on the basis of VLAN, and it does not select -@@ -2444,9 +2477,18 @@ output_normal(struct xlate_ctx *ctx, const struct xbundle *out_xbundle, +@@ -2444,9 +2555,18 @@ output_normal(struct xlate_ctx *ctx, const struct xbundle *out_xbundle, /* In case recirculation is not actually in use, 'xr.recirc_id' * will be set to '0', since a valid 'recirc_id' can * not be zero. */ @@ -60979,7 +61064,7 @@ index 578cbfe581..4b4d5c7a76 100644 if (xr.recirc_id) { /* Use recirculation instead of output. */ use_recirc = true; -@@ -3015,7 +3057,7 @@ xlate_normal(struct xlate_ctx *ctx) +@@ -3015,7 +3135,7 @@ xlate_normal(struct xlate_ctx *ctx) bool is_grat_arp = is_gratuitous_arp(flow, wc); if (ctx->xin->allow_side_effects && flow->packet_type == htonl(PT_ETH) @@ -60988,7 +61073,7 @@ index 578cbfe581..4b4d5c7a76 100644 ) { update_learning_table(ctx, in_xbundle, flow->dl_src, vlan, is_grat_arp); -@@ -3024,12 +3066,14 @@ xlate_normal(struct xlate_ctx *ctx) +@@ -3024,12 +3144,14 @@ xlate_normal(struct xlate_ctx *ctx) struct xc_entry *entry; /* Save just enough info to update mac learning table later. */ @@ -61009,7 +61094,7 @@ index 578cbfe581..4b4d5c7a76 100644 } /* Determine output bundle. */ -@@ -3048,7 +3092,6 @@ xlate_normal(struct xlate_ctx *ctx) +@@ -3048,7 +3170,6 @@ xlate_normal(struct xlate_ctx *ctx) */ ctx->xout->slow |= SLOW_ACTION; @@ -61017,7 +61102,7 @@ index 578cbfe581..4b4d5c7a76 100644 if (mcast_snooping_is_membership(flow->tp_src) || mcast_snooping_is_query(flow->tp_src)) { if (ctx->xin->allow_side_effects && ctx->xin->packet) { -@@ -3523,6 +3566,9 @@ propagate_tunnel_data_to_flow__(struct flow *dst_flow, +@@ -3523,6 +3644,9 @@ propagate_tunnel_data_to_flow__(struct flow *dst_flow, dst_flow->dl_dst = dmac; dst_flow->dl_src = smac; @@ -61027,7 +61112,7 @@ index 578cbfe581..4b4d5c7a76 100644 dst_flow->packet_type = htonl(PT_ETH); dst_flow->nw_dst = src_flow->tunnel.ip_dst; dst_flow->nw_src = src_flow->tunnel.ip_src; -@@ -3654,14 +3700,27 @@ native_tunnel_output(struct xlate_ctx *ctx, const struct xport *xport, +@@ -3654,14 +3778,27 @@ native_tunnel_output(struct xlate_ctx *ctx, const struct xport *xport, err = tnl_neigh_lookup(out_dev->xbridge->name, &d_ip6, &dmac); if (err) { @@ -61057,7 +61142,76 @@ index 578cbfe581..4b4d5c7a76 100644 } return err; } -@@ -4099,6 +4158,16 @@ xport_has_ip(const struct xport *xport) +@@ -3827,20 +3964,17 @@ static void + patch_port_output(struct xlate_ctx *ctx, const struct xport *in_dev, + struct xport *out_dev, bool is_last_action) + { ++ bool old_was_mpls = ctx->was_mpls; + struct flow *flow = &ctx->xin->flow; +- struct flow old_flow = ctx->xin->flow; +- struct flow_tnl old_flow_tnl_wc = ctx->wc->masks.tunnel; + bool old_conntrack = ctx->conntracked; +- bool old_was_mpls = ctx->was_mpls; +- ovs_version_t old_version = ctx->xin->tables_version; +- struct ofpbuf old_stack = ctx->stack; +- uint8_t new_stack[1024]; +- struct ofpbuf old_action_set = ctx->action_set; ++ struct xretained_state *retained_state; + struct ovs_list *old_trace = ctx->xin->trace; +- uint64_t actset_stub[1024 / 8]; ++ ovs_version_t old_version = ctx->xin->tables_version; ++ ++ retained_state = xretain_state_save(ctx); ++ ++ xretain_tunnel_mask_save(ctx, retained_state); + +- ofpbuf_use_stub(&ctx->stack, new_stack, sizeof new_stack); +- ofpbuf_use_stub(&ctx->action_set, actset_stub, sizeof actset_stub); + flow->in_port.ofp_port = out_dev->ofp_port; + flow->metadata = htonll(0); + memset(&flow->tunnel, 0, sizeof flow->tunnel); +@@ -3879,14 +4013,15 @@ patch_port_output(struct xlate_ctx *ctx, const struct xport *in_dev, + } else { + /* Forwarding is disabled by STP and RSTP. Let OFPP_NORMAL and + * the learning action look at the packet, then drop it. */ +- struct flow old_base_flow = ctx->base_flow; + size_t old_size = ctx->odp_actions->size; ++ ++ xretain_base_flow_save(ctx, retained_state); + mirror_mask_t old_mirrors2 = ctx->mirrors; + + xlate_table_action(ctx, flow->in_port.ofp_port, 0, true, true, + false, is_last_action, clone_xlate_actions); + ctx->mirrors = old_mirrors2; +- ctx->base_flow = old_base_flow; ++ xretain_base_flow_restore(ctx, retained_state); + ctx->odp_actions->size = old_size; + + /* Undo changes that may have been done for freezing. */ +@@ -3898,18 +4033,15 @@ patch_port_output(struct xlate_ctx *ctx, const struct xport *in_dev, + if (independent_mirrors) { + ctx->mirrors = old_mirrors; + } +- ctx->xin->flow = old_flow; + ctx->xbridge = in_dev->xbridge; +- ofpbuf_uninit(&ctx->action_set); +- ctx->action_set = old_action_set; +- ofpbuf_uninit(&ctx->stack); +- ctx->stack = old_stack; + + /* Restore calling bridge's lookup version. */ + ctx->xin->tables_version = old_version; + +- /* Restore to calling bridge tunneling information */ +- ctx->wc->masks.tunnel = old_flow_tnl_wc; ++ /* Restore to calling bridge tunneling information; the ctx flow, actions, ++ * and stack. And free the retained state. */ ++ xretain_tunnel_mask_restore(ctx, retained_state); ++ xretain_state_restore_and_free(ctx, retained_state); + + /* The out bridge popping MPLS should have no effect on the original + * bridge. */ +@@ -4099,6 +4231,16 @@ xport_has_ip(const struct xport *xport) return n_in6 ? true : false; } @@ -61074,7 +61228,7 @@ index 578cbfe581..4b4d5c7a76 100644 static bool terminate_native_tunnel(struct xlate_ctx *ctx, const struct xport *xport, struct flow *flow, struct flow_wildcards *wc, -@@ -4119,9 +4188,7 @@ terminate_native_tunnel(struct xlate_ctx *ctx, const struct xport *xport, +@@ -4119,9 +4261,7 @@ terminate_native_tunnel(struct xlate_ctx *ctx, const struct xport *xport, /* If no tunnel port was found and it's about an ARP or ICMPv6 packet, * do tunnel neighbor snooping. */ if (*tnl_port == ODPP_NONE && @@ -61085,7 +61239,24 @@ index 578cbfe581..4b4d5c7a76 100644 tnl_neigh_snoop(flow, wc, ctx->xbridge->name, ctx->xin->allow_side_effects); } else if (*tnl_port != ODPP_NONE && -@@ -4176,6 +4243,10 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port, +@@ -4151,7 +4291,7 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port, + const struct xport *xport = get_ofp_port(ctx->xbridge, ofp_port); + struct flow_wildcards *wc = ctx->wc; + struct flow *flow = &ctx->xin->flow; +- struct flow_tnl flow_tnl; ++ struct flow_tnl *flow_tnl = NULL; + union flow_vlan_hdr flow_vlans[FLOW_MAX_VLAN_HEADERS]; + uint8_t flow_nw_tos; + odp_port_t out_port, odp_port, odp_tnl_port; +@@ -4165,7 +4305,6 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port, + /* If 'struct flow' gets additional metadata, we'll need to zero it out + * before traversing a patch port. */ + BUILD_ASSERT_DECL(FLOW_WC_SEQ == 42); +- memset(&flow_tnl, 0, sizeof flow_tnl); + + if (!check_output_prerequisites(ctx, xport, flow, check_stp)) { + return; +@@ -4176,6 +4315,10 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port, if (xport->pt_mode == NETDEV_PT_LEGACY_L3) { flow->packet_type = PACKET_TYPE_BE(OFPHTN_ETHERTYPE, ntohs(flow->dl_type)); @@ -61096,7 +61267,52 @@ index 578cbfe581..4b4d5c7a76 100644 } } -@@ -4678,7 +4749,7 @@ pick_dp_hash_select_group(struct xlate_ctx *ctx, struct group_dpif *group) +@@ -4205,7 +4348,7 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port, + * the Logical (tunnel) Port are not visible for any further + * matches, while explicit set actions on tunnel metadata are. + */ +- flow_tnl = flow->tunnel; ++ flow_tnl = xmemdup(&flow->tunnel, sizeof *flow_tnl); + odp_port = tnl_port_send(xport->ofport, flow, ctx->wc); + if (odp_port == ODPP_NONE) { + xlate_report(ctx, OFT_WARN, "Tunneling decided against output"); +@@ -4236,7 +4379,7 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port, + tnl_type = tnl_port_get_type(xport->ofport); + commit_odp_tunnel_action(flow, &ctx->base_flow, + ctx->odp_actions, tnl_type); +- flow->tunnel = flow_tnl; /* Restore tunnel metadata */ ++ flow->tunnel = *flow_tnl; /* Restore tunnel metadata. */ + } + } else { + odp_port = xport->odp_port; +@@ -4280,7 +4423,8 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port, + /* Output to native tunnel port. */ + native_tunnel_output(ctx, xport, flow, odp_port, truncate, + is_last_action); +- flow->tunnel = flow_tnl; /* Restore tunnel metadata */ ++ ovs_assert(flow_tnl); ++ flow->tunnel = *flow_tnl; /* Restore tunnel metadata. */ + + } else if (terminate_native_tunnel(ctx, xport, flow, wc, + &odp_tnl_port)) { +@@ -4323,7 +4467,7 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port, + xport->xbundle)); + } + +- out: ++out: + /* Restore flow */ + memcpy(flow->vlans, flow_vlans, sizeof flow->vlans); + flow->nw_tos = flow_nw_tos; +@@ -4331,6 +4475,7 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port, + flow->dl_src = flow_dl_src; + flow->packet_type = flow_packet_type; + flow->dl_type = flow_dl_type; ++ free(flow_tnl); + } + + static void +@@ -4678,7 +4823,7 @@ pick_dp_hash_select_group(struct xlate_ctx *ctx, struct group_dpif *group) for (int i = 0; i <= hash_mask; i++) { struct ofputil_bucket *b = group->hash_map[(dp_hash + i) & hash_mask]; @@ -61105,7 +61321,7 @@ index 578cbfe581..4b4d5c7a76 100644 return b; } } -@@ -5120,6 +5191,7 @@ compose_dec_ttl(struct xlate_ctx *ctx, struct ofpact_cnt_ids *ids) +@@ -5120,6 +5265,7 @@ compose_dec_ttl(struct xlate_ctx *ctx, struct ofpact_cnt_ids *ids) } ctx->wc->masks.nw_ttl = 0xff; @@ -61113,7 +61329,28 @@ index 578cbfe581..4b4d5c7a76 100644 if (flow->nw_ttl > 1) { flow->nw_ttl--; return false; -@@ -5622,7 +5694,8 @@ xlate_sample_action(struct xlate_ctx *ctx, +@@ -5308,15 +5454,15 @@ xlate_output_reg_action(struct xlate_ctx *ctx, + { + uint64_t port = mf_get_subfield(&or->src, &ctx->xin->flow); + if (port <= UINT16_MAX) { +- xlate_report(ctx, OFT_DETAIL, "output port is %"PRIu64, port); ++ union mf_subvalue *value = xmalloc(sizeof *value); + +- union mf_subvalue value; +- +- memset(&value, 0xff, sizeof value); +- mf_write_subfield_flow(&or->src, &value, &ctx->wc->masks); ++ xlate_report(ctx, OFT_DETAIL, "output port is %"PRIu64, port); ++ memset(value, 0xff, sizeof *value); ++ mf_write_subfield_flow(&or->src, value, &ctx->wc->masks); + xlate_output_action(ctx, u16_to_ofp(port), or->max_len, + false, is_last_action, false, + group_bucket_action); ++ free(value); + } else { + xlate_report(ctx, OFT_WARN, "output port %"PRIu64" is out of range", + port); +@@ -5622,7 +5768,8 @@ xlate_sample_action(struct xlate_ctx *ctx, /* Scale the probability from 16-bit to 32-bit while representing * the same percentage. */ @@ -61123,7 +61360,207 @@ index 578cbfe581..4b4d5c7a76 100644 /* If ofp_port in flow sample action is equel to ofp_port, * this sample action is a input port action. */ -@@ -6887,6 +6960,107 @@ xlate_ofpact_unroll_xlate(struct xlate_ctx *ctx, +@@ -5656,13 +5803,15 @@ xlate_sample_action(struct xlate_ctx *ctx, + struct flow *flow = &ctx->xin->flow; + tnl_port_send(xport->ofport, flow, ctx->wc); + if (!ovs_native_tunneling_is_on(ctx->xbridge->ofproto)) { +- struct flow_tnl flow_tnl = flow->tunnel; ++ struct flow_tnl *flow_tnl; + const char *tnl_type; + ++ flow_tnl = xmemdup(&flow->tunnel, sizeof *flow_tnl); + tnl_type = tnl_port_get_type(xport->ofport); + commit_odp_tunnel_action(flow, &ctx->base_flow, + ctx->odp_actions, tnl_type); +- flow->tunnel = flow_tnl; ++ flow->tunnel = *flow_tnl; ++ free(flow_tnl); + } + } else { + xlate_report_error(ctx, +@@ -5772,21 +5921,12 @@ clone_xlate_actions(const struct ofpact *actions, size_t actions_len, + struct xlate_ctx *ctx, bool is_last_action, + bool group_bucket_action OVS_UNUSED) + { +- struct ofpbuf old_stack = ctx->stack; +- union mf_subvalue new_stack[1024 / sizeof(union mf_subvalue)]; +- ofpbuf_use_stub(&ctx->stack, new_stack, sizeof new_stack); +- ofpbuf_put(&ctx->stack, old_stack.data, old_stack.size); +- +- struct ofpbuf old_action_set = ctx->action_set; +- uint64_t actset_stub[1024 / 8]; +- ofpbuf_use_stub(&ctx->action_set, actset_stub, sizeof actset_stub); +- ofpbuf_put(&ctx->action_set, old_action_set.data, old_action_set.size); +- ++ struct xretained_state *retained_state; + size_t offset, ac_offset; +- struct flow old_flow = ctx->xin->flow; ++ ++ retained_state = xretain_state_save(ctx); + + if (reversible_actions(actions, actions_len) || is_last_action) { +- old_flow = ctx->xin->flow; + do_xlate_actions(actions, actions_len, ctx, is_last_action, false); + if (!ctx->freezing) { + xlate_action_set(ctx); +@@ -5801,7 +5941,8 @@ clone_xlate_actions(const struct ofpact *actions, size_t actions_len, + * avoid emitting those actions twice. Once inside + * the clone, another time for the action after clone. */ + xlate_commit_actions(ctx); +- struct flow old_base = ctx->base_flow; ++ xretain_base_flow_save(ctx, retained_state); ++ + bool old_was_mpls = ctx->was_mpls; + bool old_conntracked = ctx->conntracked; + +@@ -5858,14 +5999,10 @@ dp_clone_done: + ctx->was_mpls = old_was_mpls; + + /* Restore the 'base_flow' for the next action. */ +- ctx->base_flow = old_base; ++ xretain_base_flow_restore(ctx, retained_state); + + xlate_done: +- ofpbuf_uninit(&ctx->action_set); +- ctx->action_set = old_action_set; +- ofpbuf_uninit(&ctx->stack); +- ctx->stack = old_stack; +- ctx->xin->flow = old_flow; ++ xretain_state_restore_and_free(ctx, retained_state); + } + + static void +@@ -6241,8 +6378,8 @@ compose_conntrack_action(struct xlate_ctx *ctx, struct ofpact_conntrack *ofc, + { + uint16_t zone; + if (ofc->zone_src.field) { +- union mf_subvalue value; +- memset(&value, 0xff, sizeof(value)); ++ union mf_subvalue *value = xmalloc(sizeof *value); ++ memset(value, 0xff, sizeof *value); + + zone = mf_get_subfield(&ofc->zone_src, &ctx->xin->flow); + if (ctx->xin->frozen_state) { +@@ -6252,12 +6389,13 @@ compose_conntrack_action(struct xlate_ctx *ctx, struct ofpact_conntrack *ofc, + * which will invalidate the megaflow with old the recirc_id. + */ + if (!mf_is_frozen_metadata(ofc->zone_src.field)) { +- mf_write_subfield_flow(&ofc->zone_src, &value, ++ mf_write_subfield_flow(&ofc->zone_src, value, + &ctx->wc->masks); + } + } else { +- mf_write_subfield_flow(&ofc->zone_src, &value, &ctx->wc->masks); ++ mf_write_subfield_flow(&ofc->zone_src, value, &ctx->wc->masks); + } ++ free(value); + } else { + zone = ofc->zone_imm; + } +@@ -6347,16 +6485,16 @@ xlate_check_pkt_larger(struct xlate_ctx *ctx, + const struct ofpact *remaining_acts, + size_t remaining_acts_len) + { +- union mf_subvalue value; +- memset(&value, 0, sizeof value); ++ union mf_subvalue *value = xmalloc(sizeof *value); ++ memset(value, 0, sizeof *value); + if (!ctx->xbridge->support.check_pkt_len) { + uint8_t is_pkt_larger = 0; + if (ctx->xin->packet) { + is_pkt_larger = + dp_packet_size(ctx->xin->packet) > check_pkt_larger->pkt_len; + } +- value.u8_val = is_pkt_larger; +- mf_write_subfield_flow(&check_pkt_larger->dst, &value, ++ value->u8_val = is_pkt_larger; ++ mf_write_subfield_flow(&check_pkt_larger->dst, value, + &ctx->xin->flow); + /* If datapath doesn't support check_pkt_len action, then set the + * SLOW_ACTION flag. If we don't set SLOW_ACTION, we +@@ -6366,22 +6504,17 @@ xlate_check_pkt_larger(struct xlate_ctx *ctx, + * the packet length. This results in wrong actions being applied. + */ + ctx->xout->slow |= SLOW_ACTION; ++ free(value); + return; + } + +- struct ofpbuf old_stack = ctx->stack; +- union mf_subvalue new_stack[1024 / sizeof(union mf_subvalue)]; +- ofpbuf_use_stub(&ctx->stack, new_stack, sizeof new_stack); +- ofpbuf_put(&ctx->stack, old_stack.data, old_stack.size); ++ struct xretained_state *retained_state; + +- struct ofpbuf old_action_set = ctx->action_set; +- uint64_t actset_stub[1024 / 8]; +- ofpbuf_use_stub(&ctx->action_set, actset_stub, sizeof actset_stub); +- ofpbuf_put(&ctx->action_set, old_action_set.data, old_action_set.size); ++ retained_state = xretain_state_save(ctx); + +- struct flow old_flow = ctx->xin->flow; + xlate_commit_actions(ctx); +- struct flow old_base = ctx->base_flow; ++ xretain_base_flow_save(ctx, retained_state); ++ + bool old_was_mpls = ctx->was_mpls; + bool old_conntracked = ctx->conntracked; + +@@ -6391,8 +6524,8 @@ xlate_check_pkt_larger(struct xlate_ctx *ctx, + check_pkt_larger->pkt_len); + size_t offset_attr = nl_msg_start_nested( + ctx->odp_actions, OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_GREATER); +- value.u8_val = 1; +- mf_write_subfield_flow(&check_pkt_larger->dst, &value, &ctx->xin->flow); ++ value->u8_val = 1; ++ mf_write_subfield_flow(&check_pkt_larger->dst, value, &ctx->xin->flow); + do_xlate_actions(remaining_acts, remaining_acts_len, ctx, true, false); + if (!ctx->freezing) { + xlate_action_set(ctx); +@@ -6402,10 +6535,10 @@ xlate_check_pkt_larger(struct xlate_ctx *ctx, + } + nl_msg_end_nested(ctx->odp_actions, offset_attr); + +- ctx->base_flow = old_base; ++ xretain_base_flow_restore(ctx, retained_state); ++ xretain_flow_restore(ctx, retained_state); + ctx->was_mpls = old_was_mpls; + ctx->conntracked = old_conntracked; +- ctx->xin->flow = old_flow; + + /* If the flow translation for the IF_GREATER case requires freezing, + * then ctx->exit would be true. Reset to false so that we can +@@ -6416,8 +6549,8 @@ xlate_check_pkt_larger(struct xlate_ctx *ctx, + + offset_attr = nl_msg_start_nested( + ctx->odp_actions, OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_LESS_EQUAL); +- value.u8_val = 0; +- mf_write_subfield_flow(&check_pkt_larger->dst, &value, &ctx->xin->flow); ++ value->u8_val = 0; ++ mf_write_subfield_flow(&check_pkt_larger->dst, value, &ctx->xin->flow); + do_xlate_actions(remaining_acts, remaining_acts_len, ctx, true, false); + if (!ctx->freezing) { + xlate_action_set(ctx); +@@ -6428,15 +6561,12 @@ xlate_check_pkt_larger(struct xlate_ctx *ctx, + nl_msg_end_nested(ctx->odp_actions, offset_attr); + nl_msg_end_nested(ctx->odp_actions, offset); + +- ofpbuf_uninit(&ctx->action_set); +- ctx->action_set = old_action_set; +- ofpbuf_uninit(&ctx->stack); +- ctx->stack = old_stack; +- ctx->base_flow = old_base; + ctx->was_mpls = old_was_mpls; + ctx->conntracked = old_conntracked; +- ctx->xin->flow = old_flow; + ctx->exit = old_exit; ++ xretain_base_flow_restore(ctx, retained_state); ++ xretain_state_restore_and_free(ctx, retained_state); ++ free(value); + } + + static void +@@ -6887,6 +7017,107 @@ xlate_ofpact_unroll_xlate(struct xlate_ctx *ctx, "cookie=%#"PRIx64, a->rule_table_id, a->rule_cookie); } @@ -61231,7 +61668,7 @@ index 578cbfe581..4b4d5c7a76 100644 static void do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, struct xlate_ctx *ctx, bool is_last_action, -@@ -6928,6 +7102,8 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, +@@ -6928,6 +7159,8 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, break; } @@ -61240,7 +61677,7 @@ index 578cbfe581..4b4d5c7a76 100644 if (OVS_UNLIKELY(ctx->xin->trace)) { struct ds s = DS_EMPTY_INITIALIZER; struct ofpact_format_params fp = { .s = &s }; -@@ -7027,6 +7203,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, +@@ -7027,6 +7260,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, case OFPACT_SET_IPV4_SRC: if (flow->dl_type == htons(ETH_TYPE_IP)) { memset(&wc->masks.nw_src, 0xff, sizeof wc->masks.nw_src); @@ -61248,7 +61685,7 @@ index 578cbfe581..4b4d5c7a76 100644 flow->nw_src = ofpact_get_SET_IPV4_SRC(a)->ipv4; } break; -@@ -7034,12 +7211,14 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, +@@ -7034,12 +7268,14 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, case OFPACT_SET_IPV4_DST: if (flow->dl_type == htons(ETH_TYPE_IP)) { memset(&wc->masks.nw_dst, 0xff, sizeof wc->masks.nw_dst); @@ -61263,7 +61700,7 @@ index 578cbfe581..4b4d5c7a76 100644 wc->masks.nw_tos |= IP_DSCP_MASK; flow->nw_tos &= ~IP_DSCP_MASK; flow->nw_tos |= ofpact_get_SET_IP_DSCP(a)->dscp; -@@ -7048,6 +7227,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, +@@ -7048,6 +7284,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, case OFPACT_SET_IP_ECN: if (is_ip_any(flow)) { @@ -61271,7 +61708,7 @@ index 578cbfe581..4b4d5c7a76 100644 wc->masks.nw_tos |= IP_ECN_MASK; flow->nw_tos &= ~IP_ECN_MASK; flow->nw_tos |= ofpact_get_SET_IP_ECN(a)->ecn; -@@ -7056,6 +7236,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, +@@ -7056,6 +7293,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, case OFPACT_SET_IP_TTL: if (is_ip_any(flow)) { @@ -61279,7 +61716,7 @@ index 578cbfe581..4b4d5c7a76 100644 wc->masks.nw_ttl = 0xff; flow->nw_ttl = ofpact_get_SET_IP_TTL(a)->ttl; } -@@ -7123,6 +7304,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, +@@ -7123,6 +7361,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, /* Set the field only if the packet actually has it. */ if (mf_are_prereqs_ok(mf, flow, wc)) { @@ -61287,7 +61724,7 @@ index 578cbfe581..4b4d5c7a76 100644 mf_mask_field_masked(mf, ofpact_set_field_mask(set_field), wc); mf_set_flow_value_masked(mf, set_field->value, ofpact_set_field_mask(set_field), -@@ -7179,6 +7361,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, +@@ -7179,6 +7418,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, case OFPACT_DEC_TTL: wc->masks.nw_ttl = 0xff; @@ -61295,7 +61732,7 @@ index 578cbfe581..4b4d5c7a76 100644 if (compose_dec_ttl(ctx, ofpact_get_DEC_TTL(a))) { return; } -@@ -7609,6 +7792,43 @@ xlate_wc_finish(struct xlate_ctx *ctx) +@@ -7609,6 +7849,43 @@ xlate_wc_finish(struct xlate_ctx *ctx) ctx->wc->masks.vlans[i].tci = 0; } } @@ -61339,7 +61776,7 @@ index 578cbfe581..4b4d5c7a76 100644 } /* Translates the flow, actions, or rule in 'xin' into datapath actions in -@@ -7784,6 +8004,12 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout) +@@ -7784,6 +8061,12 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout) goto exit; } @@ -61352,7 +61789,7 @@ index 578cbfe581..4b4d5c7a76 100644 /* Tunnel metadata in udpif format must be normalized before translation. */ if (flow->tunnel.flags & FLOW_TNL_F_UDPIF) { const struct tun_table *tun_tab = ofproto_get_tun_tab( -@@ -8030,6 +8256,10 @@ exit: +@@ -8030,6 +8313,10 @@ exit: if (xin->odp_actions) { ofpbuf_clear(xin->odp_actions); } diff --git a/SPECS/openvswitch2.17.spec b/SPECS/openvswitch2.17.spec index 92a65fd..0bdeb6a 100644 --- a/SPECS/openvswitch2.17.spec +++ b/SPECS/openvswitch2.17.spec @@ -63,7 +63,7 @@ Summary: Open vSwitch Group: System Environment/Daemons daemon/database/utilities URL: http://www.openvswitch.org/ Version: 2.17.0 -Release: 112%{?dist} +Release: 113%{?dist} # Nearly all of openvswitch is ASL 2.0. The bugtool is LGPLv2+, and the # lib/sflow*.[ch] files are SISSL @@ -749,6 +749,12 @@ exit 0 %endif %changelog +* Wed Aug 09 2023 Open vSwitch CI - 2.17.0-113 +- Merging upstream branch-2.17 [RH git: 6994290c64] + Commit list: + f04bfd5e47 ofproto-dpif-xlate: Reduce stack usage in recursive xlate functions. (#2104779) + + * Mon Aug 07 2023 Open vSwitch CI - 2.17.0-112 - Merging upstream branch-2.17 [RH git: aa728a7f25] Commit list: