diff --git a/SOURCES/openvswitch-2.15.0.patch b/SOURCES/openvswitch-2.15.0.patch index 5f997e5..a6f53ff 100644 --- a/SOURCES/openvswitch-2.15.0.patch +++ b/SOURCES/openvswitch-2.15.0.patch @@ -33,7 +33,7 @@ index 69a40011f4..0152168794 100755 if [ "$M32" ]; then diff --git a/.cirrus.yml b/.cirrus.yml -index 2caf36b85c..79271ff147 100644 +index 2caf36b85c..b4ce3cde16 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -2,14 +2,14 @@ freebsd_build_task: @@ -43,7 +43,7 @@ index 2caf36b85c..79271ff147 100644 - image_family: freebsd-12-2-snap - image_family: freebsd-11-4-snap + image_family: freebsd-12-3-snap -+ image_family: freebsd-13-0-snap ++ image_family: freebsd-13-1-snap cpu: 4 - memory: 8G + memory: 4G @@ -103065,10 +103065,80 @@ index 244ea0fbab..1f560a1f93 100644 AC_DEFUN([OVS_CHECK_WIN64], [AC_CACHE_CHECK( diff --git a/ofproto/bond.c b/ofproto/bond.c -index 35b9caac01..2c0ad5ef84 100644 +index 35b9caac01..e07d12e58a 100644 --- a/ofproto/bond.c +++ b/ofproto/bond.c -@@ -1173,49 +1173,72 @@ bond_shift_load(struct bond_entry *hash, struct bond_member *to) +@@ -185,10 +185,14 @@ static struct bond_member *choose_output_member(const struct bond *, + uint16_t vlan) + OVS_REQ_RDLOCK(rwlock); + static void update_recirc_rules__(struct bond *); ++static bool bond_may_recirc(const struct bond *); ++static void bond_update_post_recirc_rules__(struct bond *, bool force) ++ OVS_REQ_WRLOCK(rwlock); + static bool bond_is_falling_back_to_ab(const struct bond *); + static void bond_add_lb_output_buckets(const struct bond *); + static void bond_del_lb_output_buckets(const struct bond *); + ++ + /* Attempts to parse 's' as the name of a bond balancing mode. If successful, + * stores the mode in '*balance' and returns true. Otherwise returns false + * without modifying '*balance'. */ +@@ -510,6 +514,12 @@ bond_reconfigure(struct bond *bond, const struct bond_settings *s) + bond_entry_reset(bond); + } + ++ if (bond->ofproto->backer->rt_support.odp.recirc ++ && bond_may_recirc(bond)) { ++ /* Update rules to reflect possible recirc_id changes. */ ++ update_recirc_rules(bond); ++ } ++ + ovs_rwlock_unlock(&rwlock); + return revalidate; + } +@@ -718,6 +728,12 @@ bond_run(struct bond *bond, enum lacp_status lacp_status) + bond_choose_active_member(bond); + } + ++ if (bond->ofproto->backer->rt_support.odp.recirc ++ && bond_may_recirc(bond)) { ++ /* Update rules to reflect possible link state changes. */ ++ bond_update_post_recirc_rules__(bond, false); ++ } ++ + revalidate = bond->bond_revalidate; + bond->bond_revalidate = false; + ovs_rwlock_unlock(&rwlock); +@@ -1033,7 +1049,7 @@ bond_may_recirc(const struct bond *bond) + } + + static void +-bond_update_post_recirc_rules__(struct bond* bond, const bool force) ++bond_update_post_recirc_rules__(struct bond* bond, bool force) + OVS_REQ_WRLOCK(rwlock) + { + struct bond_entry *e; +@@ -1081,6 +1097,19 @@ bond_update_post_recirc_rules(struct bond *bond, uint32_t *recirc_id, + } + } + ++void ++bond_get_recirc_id_and_hash_basis(struct bond *bond, uint32_t *recirc_id, ++ uint32_t *hash_basis) ++{ ++ ovs_rwlock_rdlock(&rwlock); ++ if (bond_may_recirc(bond)) { ++ *recirc_id = bond->recirc_id; ++ *hash_basis = bond->basis; ++ } else { ++ *recirc_id = *hash_basis = 0; ++ } ++ ovs_rwlock_unlock(&rwlock); ++} + + /* Rebalancing. */ + +@@ -1173,49 +1202,72 @@ bond_shift_load(struct bond_entry *hash, struct bond_member *to) bond->bond_revalidate = true; } @@ -103168,7 +103238,7 @@ index 35b9caac01..2c0ad5ef84 100644 } /* Inserts 'member' into 'bals' so that descending order of 'tx_bytes' is -@@ -1230,7 +1253,7 @@ insert_bal(struct ovs_list *bals, struct bond_member *member) +@@ -1230,7 +1282,7 @@ insert_bal(struct ovs_list *bals, struct bond_member *member) break; } } @@ -103177,7 +103247,7 @@ index 35b9caac01..2c0ad5ef84 100644 } /* Removes 'member' from its current list and then inserts it into 'bals' so -@@ -1242,6 +1265,22 @@ reinsert_bal(struct ovs_list *bals, struct bond_member *member) +@@ -1242,6 +1294,22 @@ reinsert_bal(struct ovs_list *bals, struct bond_member *member) insert_bal(bals, member); } @@ -103200,7 +103270,7 @@ index 35b9caac01..2c0ad5ef84 100644 /* If 'bond' needs rebalancing, does so. * * The caller should have called bond_account() for each active flow, or in case -@@ -1251,8 +1290,8 @@ reinsert_bal(struct ovs_list *bals, struct bond_member *member) +@@ -1251,8 +1319,8 @@ reinsert_bal(struct ovs_list *bals, struct bond_member *member) void bond_rebalance(struct bond *bond) { @@ -103210,7 +103280,7 @@ index 35b9caac01..2c0ad5ef84 100644 struct ovs_list bals; bool rebalanced = false; bool use_recirc; -@@ -1276,7 +1315,15 @@ bond_rebalance(struct bond *bond) +@@ -1276,7 +1344,15 @@ bond_rebalance(struct bond *bond) member->tx_bytes = 0; ovs_list_init(&member->entries); } @@ -103227,7 +103297,7 @@ index 35b9caac01..2c0ad5ef84 100644 if (e->member && e->tx_bytes) { e->member->tx_bytes += e->tx_bytes; ovs_list_push_back(&e->member->entries, &e->list_node); -@@ -1311,15 +1358,23 @@ bond_rebalance(struct bond *bond) +@@ -1311,15 +1387,23 @@ bond_rebalance(struct bond *bond) break; } @@ -103255,7 +103325,7 @@ index 35b9caac01..2c0ad5ef84 100644 * 'e' to be migrated to another member in this rebalancing run, and * there is no point in doing that. */ ovs_list_remove(&e->list_node); -@@ -1327,12 +1382,8 @@ bond_rebalance(struct bond *bond) +@@ -1327,12 +1411,8 @@ bond_rebalance(struct bond *bond) /* Re-sort 'bals'. */ reinsert_bal(&bals, from); reinsert_bal(&bals, to); @@ -103269,6 +103339,20 @@ index 35b9caac01..2c0ad5ef84 100644 } /* Implement exponentially weighted moving average. A weight of 1/2 causes +diff --git a/ofproto/bond.h b/ofproto/bond.h +index 1683ec8781..e7f7ea7a95 100644 +--- a/ofproto/bond.h ++++ b/ofproto/bond.h +@@ -128,6 +128,9 @@ void bond_rebalance(struct bond *); + void bond_update_post_recirc_rules(struct bond *, uint32_t *recirc_id, + uint32_t *hash_basis); + ++void bond_get_recirc_id_and_hash_basis(struct bond *, uint32_t *recirc_id, ++ uint32_t *hash_basis); ++ + bool bond_use_lb_output_action(const struct bond *bond); + + #endif /* bond.h */ diff --git a/ofproto/connmgr.c b/ofproto/connmgr.c index 9c5c633b41..fa8f6cd0e8 100644 --- a/ofproto/connmgr.c @@ -103510,10 +103594,32 @@ index fdcb9eabbf..0f4a61ac6b 100644 /* Build a flow sample. */ memset(&fs, 0, sizeof fs); diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c -index 5fae46adfc..c710a5137f 100644 +index 5fae46adfc..df345cc8ae 100644 --- a/ofproto/ofproto-dpif-upcall.c +++ b/ofproto/ofproto-dpif-upcall.c -@@ -491,6 +491,11 @@ udpif_destroy(struct udpif *udpif) +@@ -362,6 +362,10 @@ static void upcall_unixctl_dump_wait(struct unixctl_conn *conn, int argc, + const char *argv[], void *aux); + static void upcall_unixctl_purge(struct unixctl_conn *conn, int argc, + const char *argv[], void *aux); ++static void upcall_unixctl_pause(struct unixctl_conn *conn, int argc, ++ const char *argv[], void *aux); ++static void upcall_unixctl_resume(struct unixctl_conn *conn, int argc, ++ const char *argv[], void *aux); + + static struct udpif_key *ukey_create_from_upcall(struct upcall *, + struct flow_wildcards *); +@@ -434,6 +438,10 @@ udpif_init(void) + upcall_unixctl_dump_wait, NULL); + unixctl_command_register("revalidator/purge", "", 0, 0, + upcall_unixctl_purge, NULL); ++ unixctl_command_register("revalidator/pause", NULL, 0, 0, ++ upcall_unixctl_pause, NULL); ++ unixctl_command_register("revalidator/resume", NULL, 0, 0, ++ upcall_unixctl_resume, NULL); + ovsthread_once_done(&once); + } + } +@@ -491,6 +499,11 @@ udpif_destroy(struct udpif *udpif) dpif_register_upcall_cb(udpif->dpif, NULL, udpif); for (int i = 0; i < N_UMAPS; i++) { @@ -103525,7 +103631,7 @@ index 5fae46adfc..c710a5137f 100644 cmap_destroy(&udpif->ukeys[i].cmap); ovs_mutex_destroy(&udpif->ukeys[i].mutex); } -@@ -2929,11 +2934,11 @@ upcall_unixctl_show(struct unixctl_conn *conn, int argc OVS_UNUSED, +@@ -2929,11 +2942,11 @@ upcall_unixctl_show(struct unixctl_conn *conn, int argc OVS_UNUSED, } ds_put_char(&ds, '\n'); @@ -103539,6 +103645,38 @@ index 5fae46adfc..c710a5137f 100644 elements += cmap_count(&udpif->ukeys[j].cmap); } ds_put_format(&ds, " %u: (keys %d)\n", revalidator->id, elements); +@@ -3057,6 +3070,31 @@ upcall_unixctl_purge(struct unixctl_conn *conn, int argc OVS_UNUSED, + unixctl_command_reply(conn, ""); + } + ++static void ++upcall_unixctl_pause(struct unixctl_conn *conn, int argc OVS_UNUSED, ++ const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED) ++{ ++ struct udpif *udpif; ++ ++ LIST_FOR_EACH (udpif, list_node, &all_udpifs) { ++ udpif_pause_revalidators(udpif); ++ } ++ unixctl_command_reply(conn, ""); ++} ++ ++static void ++upcall_unixctl_resume(struct unixctl_conn *conn, int argc OVS_UNUSED, ++ const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED) ++{ ++ struct udpif *udpif; ++ ++ LIST_FOR_EACH (udpif, list_node, &all_udpifs) { ++ udpif_resume_revalidators(udpif); ++ } ++ unixctl_command_reply(conn, ""); ++} ++ ++ + /* Flows are sorted in the following order: + * netdev, flow state (offloaded/kernel path), flow_pps_rate. + */ diff --git a/ofproto/ofproto-dpif-xlate-cache.c b/ofproto/ofproto-dpif-xlate-cache.c index dcc91cb380..9224ee2e6d 100644 --- a/ofproto/ofproto-dpif-xlate-cache.c @@ -103576,7 +103714,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 7108c8a301..a66c2be138 100644 +index 7108c8a301..f8b23ca3c3 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -460,7 +460,7 @@ static void xlate_commit_actions(struct xlate_ctx *ctx); @@ -103648,7 +103786,29 @@ index 7108c8a301..a66c2be138 100644 /* If this mirror selects on the basis of VLAN, and it does not select -@@ -3015,7 +3037,7 @@ xlate_normal(struct xlate_ctx *ctx) +@@ -2444,9 +2466,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. */ +- bond_update_post_recirc_rules(out_xbundle->bond, +- &xr.recirc_id, +- &xr.hash_basis); ++ if (ctx->xin->allow_side_effects) { ++ bond_update_post_recirc_rules(out_xbundle->bond, ++ &xr.recirc_id, ++ &xr.hash_basis); ++ } else { ++ /* If side effects are not allowed, only getting the bond ++ * configuration. Rule updates will be handled by the ++ * main thread later. */ ++ bond_get_recirc_id_and_hash_basis(out_xbundle->bond, ++ &xr.recirc_id, ++ &xr.hash_basis); ++ } + if (xr.recirc_id) { + /* Use recirculation instead of output. */ + use_recirc = true; +@@ -3015,7 +3046,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) @@ -103657,7 +103817,7 @@ index 7108c8a301..a66c2be138 100644 ) { update_learning_table(ctx, in_xbundle, flow->dl_src, vlan, is_grat_arp); -@@ -3024,12 +3046,14 @@ xlate_normal(struct xlate_ctx *ctx) +@@ -3024,12 +3055,14 @@ xlate_normal(struct xlate_ctx *ctx) struct xc_entry *entry; /* Save just enough info to update mac learning table later. */ @@ -103678,7 +103838,7 @@ index 7108c8a301..a66c2be138 100644 } /* Determine output bundle. */ -@@ -3048,7 +3072,6 @@ xlate_normal(struct xlate_ctx *ctx) +@@ -3048,7 +3081,6 @@ xlate_normal(struct xlate_ctx *ctx) */ ctx->xout->slow |= SLOW_ACTION; @@ -103686,7 +103846,7 @@ index 7108c8a301..a66c2be138 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) { -@@ -3272,7 +3295,9 @@ compose_ipfix_action(struct xlate_ctx *ctx, odp_port_t output_odp_port) +@@ -3272,7 +3304,9 @@ compose_ipfix_action(struct xlate_ctx *ctx, odp_port_t output_odp_port) struct dpif_ipfix *ipfix = ctx->xbridge->ipfix; odp_port_t tunnel_out_port = ODPP_NONE; @@ -103697,7 +103857,7 @@ index 7108c8a301..a66c2be138 100644 return; } -@@ -3521,6 +3546,9 @@ propagate_tunnel_data_to_flow__(struct flow *dst_flow, +@@ -3521,6 +3555,9 @@ propagate_tunnel_data_to_flow__(struct flow *dst_flow, dst_flow->dl_dst = dmac; dst_flow->dl_src = smac; @@ -103707,7 +103867,7 @@ index 7108c8a301..a66c2be138 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; -@@ -3598,7 +3626,7 @@ propagate_tunnel_data_to_flow(struct xlate_ctx *ctx, struct eth_addr dmac, +@@ -3598,7 +3635,7 @@ propagate_tunnel_data_to_flow(struct xlate_ctx *ctx, struct eth_addr dmac, static int native_tunnel_output(struct xlate_ctx *ctx, const struct xport *xport, const struct flow *flow, odp_port_t tunnel_odp_port, @@ -103716,7 +103876,7 @@ index 7108c8a301..a66c2be138 100644 { struct netdev_tnl_build_header_params tnl_params; struct ovs_action_push_tnl tnl_push_data; -@@ -3728,7 +3756,7 @@ native_tunnel_output(struct xlate_ctx *ctx, const struct xport *xport, +@@ -3728,7 +3765,7 @@ native_tunnel_output(struct xlate_ctx *ctx, const struct xport *xport, entry->tunnel_hdr.hdr_size = tnl_push_data.header_len; entry->tunnel_hdr.operation = ADD; @@ -103725,7 +103885,7 @@ index 7108c8a301..a66c2be138 100644 /* Similar to the stats update in revalidation, the x_cache entries * are populated by the previous translation are used to update the -@@ -3822,7 +3850,7 @@ xlate_flow_is_protected(const struct xlate_ctx *ctx, const struct flow *flow, co +@@ -3822,7 +3859,7 @@ xlate_flow_is_protected(const struct xlate_ctx *ctx, const struct flow *flow, co */ static void patch_port_output(struct xlate_ctx *ctx, const struct xport *in_dev, @@ -103734,7 +103894,7 @@ index 7108c8a301..a66c2be138 100644 { struct flow *flow = &ctx->xin->flow; struct flow old_flow = ctx->xin->flow; -@@ -3864,8 +3892,9 @@ patch_port_output(struct xlate_ctx *ctx, const struct xport *in_dev, +@@ -3864,8 +3901,9 @@ patch_port_output(struct xlate_ctx *ctx, const struct xport *in_dev, if (!process_special(ctx, out_dev) && may_receive(out_dev, ctx)) { if (xport_stp_forward_state(out_dev) && xport_rstp_forward_state(out_dev)) { @@ -103745,7 +103905,7 @@ index 7108c8a301..a66c2be138 100644 if (!ctx->freezing) { xlate_action_set(ctx); } -@@ -3880,7 +3909,7 @@ patch_port_output(struct xlate_ctx *ctx, const struct xport *in_dev, +@@ -3880,7 +3918,7 @@ patch_port_output(struct xlate_ctx *ctx, const struct xport *in_dev, mirror_mask_t old_mirrors2 = ctx->mirrors; xlate_table_action(ctx, flow->in_port.ofp_port, 0, true, true, @@ -103754,7 +103914,7 @@ index 7108c8a301..a66c2be138 100644 ctx->mirrors = old_mirrors2; ctx->base_flow = old_base_flow; ctx->odp_actions->size = old_size; -@@ -4097,7 +4126,21 @@ terminate_native_tunnel(struct xlate_ctx *ctx, struct flow *flow, +@@ -4097,7 +4135,21 @@ terminate_native_tunnel(struct xlate_ctx *ctx, struct flow *flow, (flow->dl_type == htons(ETH_TYPE_ARP) || flow->nw_proto == IPPROTO_ICMPV6) && is_neighbor_reply_correct(ctx, flow)) { @@ -103777,7 +103937,7 @@ index 7108c8a301..a66c2be138 100644 } } -@@ -4107,7 +4150,7 @@ terminate_native_tunnel(struct xlate_ctx *ctx, struct flow *flow, +@@ -4107,7 +4159,7 @@ terminate_native_tunnel(struct xlate_ctx *ctx, struct flow *flow, static void compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port, const struct xlate_bond_recirc *xr, bool check_stp, @@ -103786,7 +103946,7 @@ index 7108c8a301..a66c2be138 100644 { const struct xport *xport = get_ofp_port(ctx->xbridge, ofp_port); struct flow_wildcards *wc = ctx->wc; -@@ -4137,6 +4180,10 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port, +@@ -4137,6 +4189,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)); @@ -103797,7 +103957,7 @@ index 7108c8a301..a66c2be138 100644 } } -@@ -4144,7 +4191,7 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port, +@@ -4144,7 +4200,7 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port, if (truncate) { xlate_report_error(ctx, "Cannot truncate output to patch port"); } @@ -103806,7 +103966,7 @@ index 7108c8a301..a66c2be138 100644 return; } -@@ -4239,7 +4286,8 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port, +@@ -4239,7 +4295,8 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port, xr->recirc_id); } else if (is_native_tunnel) { /* Output to native tunnel port. */ @@ -103816,7 +103976,7 @@ index 7108c8a301..a66c2be138 100644 flow->tunnel = flow_tnl; /* Restore tunnel metadata */ } else if (terminate_native_tunnel(ctx, flow, wc, -@@ -6177,11 +6225,32 @@ static void +@@ -6177,11 +6234,32 @@ static void compose_conntrack_action(struct xlate_ctx *ctx, struct ofpact_conntrack *ofc, bool is_last_action) { @@ -103827,7 +103987,7 @@ index 7108c8a301..a66c2be138 100644 + if (ofc->zone_src.field) { + union mf_subvalue value; + memset(&value, 0xff, sizeof(value)); -+ + + zone = mf_get_subfield(&ofc->zone_src, &ctx->xin->flow); + if (ctx->xin->frozen_state) { + /* If the upcall is a resume of a recirculation, we only need to @@ -103845,14 +104005,14 @@ index 7108c8a301..a66c2be138 100644 + } else { + zone = ofc->zone_imm; + } - ++ + size_t ct_offset; + ovs_u128 old_ct_label_mask = ctx->wc->masks.ct_label; + uint32_t old_ct_mark_mask = ctx->wc->masks.ct_mark; /* Ensure that any prior actions are applied before composing the new * conntrack action. */ xlate_commit_actions(ctx); -@@ -6193,11 +6262,6 @@ compose_conntrack_action(struct xlate_ctx *ctx, struct ofpact_conntrack *ofc, +@@ -6193,11 +6271,6 @@ compose_conntrack_action(struct xlate_ctx *ctx, struct ofpact_conntrack *ofc, do_xlate_actions(ofc->actions, ofpact_ct_get_action_len(ofc), ctx, is_last_action, false); @@ -103864,7 +104024,7 @@ index 7108c8a301..a66c2be138 100644 ct_offset = nl_msg_start_nested(ctx->odp_actions, OVS_ACTION_ATTR_CT); if (ofc->flags & NX_CT_F_COMMIT) { -@@ -6333,6 +6397,7 @@ xlate_check_pkt_larger(struct xlate_ctx *ctx, +@@ -6333,6 +6406,7 @@ xlate_check_pkt_larger(struct xlate_ctx *ctx, * then ctx->exit would be true. Reset to false so that we can * do flow translation for 'IF_LESS_EQUAL' case. finish_freezing() * would have taken care of Undoing the changes done for freeze. */ @@ -103872,7 +104032,7 @@ index 7108c8a301..a66c2be138 100644 ctx->exit = false; offset_attr = nl_msg_start_nested( -@@ -6357,7 +6422,7 @@ xlate_check_pkt_larger(struct xlate_ctx *ctx, +@@ -6357,7 +6431,7 @@ xlate_check_pkt_larger(struct xlate_ctx *ctx, ctx->was_mpls = old_was_mpls; ctx->conntracked = old_conntracked; ctx->xin->flow = old_flow; @@ -103881,7 +104041,7 @@ index 7108c8a301..a66c2be138 100644 } static void -@@ -6736,13 +6801,14 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, +@@ -6736,13 +6810,14 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, return; } @@ -103897,7 +104057,7 @@ index 7108c8a301..a66c2be138 100644 if (ctx->error) { break; -@@ -6750,7 +6816,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, +@@ -6750,7 +6825,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, recirc_for_mpls(a, ctx); @@ -103906,7 +104066,7 @@ index 7108c8a301..a66c2be138 100644 /* Check if need to store the remaining actions for later * execution. */ if (ctx->freezing) { -@@ -7127,7 +7193,9 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, +@@ -7127,7 +7202,9 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, break; case OFPACT_CT_CLEAR: @@ -103917,7 +104077,7 @@ index 7108c8a301..a66c2be138 100644 break; case OFPACT_NAT: -@@ -7145,17 +7213,18 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, +@@ -7145,17 +7222,18 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, break; case OFPACT_CHECK_PKT_LARGER: { @@ -103941,7 +104101,7 @@ index 7108c8a301..a66c2be138 100644 break; } } -@@ -7619,6 +7688,12 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout) +@@ -7619,6 +7697,12 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout) goto exit; } @@ -106217,7 +106377,7 @@ index 199db8ed0f..59093c03c9 100644 bad_action 'fin_timeout(foo=bar)' "invalid key 'foo' in 'fin_timeout' argument" diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at -index 31064ed95e..ce81b6025b 100644 +index 31064ed95e..70b8f0edde 100644 --- a/tests/ofproto-dpif.at +++ b/tests/ofproto-dpif.at @@ -81,11 +81,12 @@ recirc_id(0),in_port(4),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:0b,dst=ff: @@ -106397,7 +106557,7 @@ index 31064ed95e..ce81b6025b 100644 ovs-appctl time/warp 300 100 AT_CHECK([ovs-appctl dpif/dump-flows br0 | grep tcp > br0_flows.txt]) AT_CHECK([ovs-appctl dpif/dump-flows br1 | grep tcp > br1_flows.txt]) -@@ -423,6 +427,78 @@ OVS_WAIT_UNTIL([test -z "$(ovs-appctl dpif-netdev/bond-show)"]) +@@ -423,6 +427,144 @@ OVS_WAIT_UNTIL([test -z "$(ovs-appctl dpif-netdev/bond-show)"]) OVS_VSWITCHD_STOP() AT_CLEANUP @@ -106472,11 +106632,77 @@ index 31064ed95e..ce81b6025b 100644 +OVS_VSWITCHD_STOP() +AT_CLEANUP + ++dnl Regression test for a deadlock / double lock on post-recirculation rule ++dnl updates while processing PACKET_OUT. ++AT_SETUP([ofproto-dpif - balance-tcp bonding rule updates on packet-out]) ++dnl Create br0 with interfaces bond0(p1, p2) and p5, ++dnl and br1 with interfaces bond1(p3, p4) and p6. ++dnl bond0 <-> bond1 ++OVS_VSWITCHD_START( ++ [add-bond br0 bond0 p1 p2 bond_mode=balance-tcp lacp=active dnl ++ other-config:lacp-time=fast other-config:bond-rebalance-interval=1000 -- dnl ++ set interface p1 type=dummy options:pstream=punix:$OVS_RUNDIR/p1.sock ofport_request=1 mtu_request=65535 -- dnl ++ set interface p2 type=dummy options:pstream=punix:$OVS_RUNDIR/p2.sock ofport_request=2 mtu_request=65535 -- dnl ++ add-port br0 p5 -- set interface p5 ofport_request=5 type=dummy mtu_request=65535 -- dnl ++ add-br br1 -- dnl ++ set bridge br1 other-config:hwaddr=aa:66:aa:66:00:00 -- dnl ++ set bridge br1 datapath-type=dummy other-config:datapath-id=1234 dnl ++ fail-mode=secure -- dnl ++ add-bond br1 bond1 p3 p4 bond_mode=balance-tcp lacp=active dnl ++ other-config:lacp-time=fast other-config:bond-rebalance-interval=1000 -- dnl ++ set interface p3 type=dummy options:stream=unix:$OVS_RUNDIR/p1.sock ofport_request=3 mtu_request=65535 -- dnl ++ set interface p4 type=dummy options:stream=unix:$OVS_RUNDIR/p2.sock ofport_request=4 mtu_request=65535 -- dnl ++ add-port br1 p6 -- set interface p6 ofport_request=6 type=dummy mtu_request=65535 --]) ++AT_CHECK([ovs-appctl vlog/set bond:dbg]) ++AT_CHECK([ovs-appctl netdev-dummy/set-admin-state up], 0, [OK ++]) ++AT_CHECK([ovs-ofctl add-flow br0 action=normal]) ++AT_CHECK([ovs-ofctl add-flow br1 action=normal]) ++OVS_WAIT_WHILE([ovs-appctl bond/show | grep "may_enable: false"]) ++ ++ovs-appctl time/stop ++ovs-appctl time/warp 2000 200 ++ ++dnl Send some traffic to distribute all the hashes between ports. ++AT_CHECK([SEND_TCP_BOND_PKTS([p5], [5], [65500])]) ++ ++dnl Wait for rebalancing for per-hash stats accounting. ++ovs-appctl time/warp 1000 100 ++ ++dnl Check that p2 handles some hashes. ++ovs-appctl bond/show > bond1.txt ++AT_CHECK([sed -n '/member p2/,/^$/p' bond1.txt | grep 'hash'], [0], [ignore]) ++ ++dnl Pause revalidators to be sure that they do not update flows while ++dnl the bonding configuration chnages. ++ovs-appctl revalidator/pause ++ ++dnl Move p2 down to trigger update of bonding post-recirculation rules by ++dnl forcing move of all the hashes to p1. ++AT_CHECK([ovs-appctl netdev-dummy/set-admin-state p2 down], 0, [OK ++]) ++ ++dnl Send PACKET_OUT that may lead to flow updates since the bonding ++dnl configuration changed. ++packet=ffffffffffff00102030405008004500001c00000000401100000a000002ffffffff0035111100080000 ++AT_CHECK([ovs-ofctl packet-out br0 "in_port=p5 packet=$packet actions=resubmit(,0)"]) ++ ++dnl Resume revalidators. ++ovs-appctl revalidator/resume ++ovs-appctl revalidator/wait ++ ++ovs-appctl time/warp 200 100 ++dnl Check that all hashes moved form p2 and OVS is still working. ++ovs-appctl bond/show > bond2.txt ++AT_CHECK([sed -n '/member p2/,/^$/p' bond2.txt | grep 'hash'], [1], [ignore]) ++ ++OVS_VSWITCHD_STOP() ++AT_CLEANUP + # Makes sure recirculation does not change the way packet is handled. AT_SETUP([ofproto-dpif - balance-tcp bonding, different recirc flow ]) OVS_VSWITCHD_START( -@@ -4786,6 +4862,54 @@ recirc_id(0),in_port(90),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(proto=6,fr +@@ -4786,6 +4928,54 @@ recirc_id(0),in_port(90),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(proto=6,fr OVS_VSWITCHD_STOP AT_CLEANUP @@ -106531,7 +106757,7 @@ index 31064ed95e..ce81b6025b 100644 AT_SETUP([ofproto-dpif - exit]) OVS_VSWITCHD_START add_of_ports br0 1 2 3 10 11 12 13 14 -@@ -5449,7 +5573,36 @@ check_flows () { +@@ -5449,7 +5639,36 @@ check_flows () { echo "n_packets=$n" test "$n" = 1 } @@ -106569,7 +106795,7 @@ index 31064ed95e..ce81b6025b 100644 OVS_VSWITCHD_STOP AT_CLEANUP -@@ -7349,13 +7502,28 @@ dnl configure bridge IPFIX and ensure that sample action generation works at the +@@ -7349,13 +7568,28 @@ dnl configure bridge IPFIX and ensure that sample action generation works at the dnl datapath level. AT_SETUP([ofproto-dpif - Bridge IPFIX sanity check]) OVS_VSWITCHD_START @@ -106600,7 +106826,7 @@ index 31064ed95e..ce81b6025b 100644 dnl Send some packets that should be sampled. for i in `seq 1 3`; do AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800)']) -@@ -7365,6 +7533,28 @@ flow-dump from the main thread: +@@ -7365,6 +7599,28 @@ flow-dump from the main thread: packets:2, bytes:68, used:0.001s, actions:userspace(pid=0,ipfix(output_port=4294967295)) ]) @@ -106629,7 +106855,7 @@ index 31064ed95e..ce81b6025b 100644 AT_CHECK([ovs-appctl revalidator/purge]) dnl dnl Add a slowpath meter. The userspace action should be metered. -@@ -8416,6 +8606,34 @@ AT_CHECK([sed -n 's/=[[0-9]][[0-9]]\(\.[[0-9]][[0-9]]*\)\{0,1\}s/=?s/p' stdout], +@@ -8416,6 +8672,34 @@ AT_CHECK([sed -n 's/=[[0-9]][[0-9]]\(\.[[0-9]][[0-9]]*\)\{0,1\}s/=?s/p' stdout], OVS_VSWITCHD_STOP AT_CLEANUP @@ -106664,7 +106890,7 @@ index 31064ed95e..ce81b6025b 100644 dnl ---------------------------------------------------------------------- AT_BANNER([ofproto-dpif -- megaflows]) -@@ -9520,6 +9738,26 @@ OFPST_TABLE reply (OF1.3) (xid=0x2): +@@ -9520,6 +9804,26 @@ OFPST_TABLE reply (OF1.3) (xid=0x2): OVS_VSWITCHD_STOP AT_CLEANUP @@ -106691,7 +106917,7 @@ index 31064ed95e..ce81b6025b 100644 AT_SETUP([ofproto-dpif - ICMPv6]) OVS_VSWITCHD_START add_of_ports br0 1 -@@ -10842,6 +11080,31 @@ dnl +@@ -10842,6 +11146,31 @@ dnl NXT_PACKET_IN (xid=0x0): table_id=1 cookie=0x0 total_len=106 in_port=2 (via action) data_len=106 (unbuffered) udp,vlan_tci=0x0000,dl_src=50:54:00:00:00:0a,dl_dst=50:54:00:00:00:09,nw_src=10.1.1.2,nw_dst=10.1.1.1,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=2,tp_dst=1 udp_csum:553 ]) @@ -106723,7 +106949,7 @@ index 31064ed95e..ce81b6025b 100644 OVS_VSWITCHD_STOP AT_CLEANUP -@@ -11204,6 +11467,23 @@ Megaflow: recirc_id=0x3,eth,ip,in_port=1,nw_frag=no +@@ -11204,6 +11533,23 @@ Megaflow: recirc_id=0x3,eth,ip,in_port=1,nw_frag=no Datapath actions: 4 ]) @@ -109881,7 +110107,7 @@ index 3eabcd78d5..1df5afa221 100644 import errno import os diff --git a/tests/test-list.c b/tests/test-list.c -index 6f1fb059bc..648e02a5e2 100644 +index 6f1fb059bc..d1dbde30a7 100644 --- a/tests/test-list.c +++ b/tests/test-list.c @@ -61,7 +61,7 @@ check_list(struct ovs_list *list, const int values[], size_t n) @@ -109902,7 +110128,16 @@ index 6f1fb059bc..648e02a5e2 100644 assert(i == n); assert(ovs_list_is_empty(list) == !n); -@@ -135,6 +135,13 @@ test_list_for_each_safe(void) +@@ -106,6 +106,8 @@ test_list_construction(void) + int values[MAX_ELEMS]; + struct ovs_list list; + ++ memset(elements, 0, sizeof elements); ++ memset(values, 0, sizeof values); + make_list(&list, elements, values, n); + check_list(&list, values, n); + } +@@ -135,6 +137,13 @@ test_list_for_each_safe(void) values_idx = 0; n_remaining = n; LIST_FOR_EACH_SAFE (e, next, node, &list) { @@ -109916,7 +110151,7 @@ index 6f1fb059bc..648e02a5e2 100644 assert(i < n); if (pattern & (1ul << i)) { ovs_list_remove(&e->node); -@@ -148,7 +155,8 @@ test_list_for_each_safe(void) +@@ -148,7 +157,8 @@ test_list_for_each_safe(void) i++; } assert(i == n); diff --git a/SPECS/openvswitch2.15.spec b/SPECS/openvswitch2.15.spec index 40d9f00..4762dcf 100644 --- a/SPECS/openvswitch2.15.spec +++ b/SPECS/openvswitch2.15.spec @@ -57,7 +57,7 @@ Summary: Open vSwitch Group: System Environment/Daemons daemon/database/utilities URL: http://www.openvswitch.org/ Version: 2.15.0 -Release: 119%{?dist} +Release: 120%{?dist} # Nearly all of openvswitch is ASL 2.0. The bugtool is LGPLv2+, and the # lib/sflow*.[ch] files are SISSL @@ -702,6 +702,15 @@ exit 0 %endif %changelog +* Mon Sep 19 2022 Open vSwitch CI - 2.15.0-120 +- Merging upstream branch-2.15 [RH git: 64fdb5d43f] + Commit list: + 60b1db0e22 bond: Avoid deadlock while updating post recirculation rules. + fb46fd5643 ofproto-dpif-upcall: Add debug commands to pause/resume revalidators. + 88a936a57c test-list: Fix false-positive build failure with GCC 12. + 7461f82acc cirrus: Upgrade to FreeBSD 13.1 image. + + * Tue Sep 06 2022 Timothy Redaelli - 2.15.0-119 - Merging 73655c64149 version: 20.11.6 [RH git: d8e8db8377] Commit list: