diff --git a/SOURCES/openvswitch-2.16.0.patch b/SOURCES/openvswitch-2.16.0.patch index 670bb60..3d969b7 100644 --- a/SOURCES/openvswitch-2.16.0.patch +++ b/SOURCES/openvswitch-2.16.0.patch @@ -43,7 +43,7 @@ index c55125cf78..c0b7473eda 100755 if [ "$M32" ]; then diff --git a/.cirrus.yml b/.cirrus.yml -index 358f2ba256..a4d2a5bbcd 100644 +index 358f2ba256..29be50029b 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -2,14 +2,14 @@ freebsd_build_task: @@ -53,7 +53,7 @@ index 358f2ba256..a4d2a5bbcd 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 @@ -86415,10 +86415,80 @@ index e4b42b0594..877bca3127 100644 struct eth_addr *mac); void tnl_neigh_cache_init(void); diff --git a/ofproto/bond.c b/ofproto/bond.c -index a4116588f4..2c0ad5ef84 100644 +index a4116588f4..e07d12e58a 100644 --- a/ofproto/bond.c +++ b/ofproto/bond.c -@@ -1253,7 +1253,7 @@ insert_bal(struct ovs_list *bals, struct bond_member *member) +@@ -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. */ + +@@ -1253,7 +1282,7 @@ insert_bal(struct ovs_list *bals, struct bond_member *member) break; } } @@ -86427,6 +86497,20 @@ index a4116588f4..2c0ad5ef84 100644 } /* Removes 'member' from its current list and then inserts it into 'bals' so +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/libofproto.pc.in b/ofproto/libofproto.pc.in index 2740712505..49894fb695 100644 --- a/ofproto/libofproto.pc.in @@ -86618,10 +86702,32 @@ index 864c136b5d..0f4a61ac6b 100644 * packet mark zero. */ diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c -index 1c9c720f04..57f94df544 100644 +index 1c9c720f04..fe47090584 100644 --- a/ofproto/ofproto-dpif-upcall.c +++ b/ofproto/ofproto-dpif-upcall.c -@@ -2971,11 +2971,11 @@ upcall_unixctl_show(struct unixctl_conn *conn, int argc OVS_UNUSED, +@@ -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); + } + } +@@ -2971,11 +2979,11 @@ upcall_unixctl_show(struct unixctl_conn *conn, int argc OVS_UNUSED, } ds_put_char(&ds, '\n'); @@ -86635,6 +86741,38 @@ index 1c9c720f04..57f94df544 100644 elements += cmap_count(&udpif->ukeys[j].cmap); } ds_put_format(&ds, " %u: (keys %d)\n", revalidator->id, elements); +@@ -3099,6 +3107,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 @@ -86672,7 +86810,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 a426fcfeb6..b8886105df 100644 +index a426fcfeb6..330ef0784a 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); @@ -86744,7 +86882,29 @@ index a426fcfeb6..b8886105df 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) @@ -86753,7 +86913,7 @@ index a426fcfeb6..b8886105df 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. */ @@ -86774,7 +86934,7 @@ index a426fcfeb6..b8886105df 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; @@ -86782,7 +86942,7 @@ index a426fcfeb6..b8886105df 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; @@ -86793,7 +86953,7 @@ index a426fcfeb6..b8886105df 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; @@ -86803,7 +86963,7 @@ index a426fcfeb6..b8886105df 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, @@ -86812,7 +86972,7 @@ index a426fcfeb6..b8886105df 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; @@ -86821,7 +86981,7 @@ index a426fcfeb6..b8886105df 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, @@ -86830,7 +86990,7 @@ index a426fcfeb6..b8886105df 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)) { @@ -86841,7 +87001,7 @@ index a426fcfeb6..b8886105df 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, @@ -86850,7 +87010,7 @@ index a426fcfeb6..b8886105df 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)) { @@ -86873,7 +87033,7 @@ index a426fcfeb6..b8886105df 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, @@ -86882,7 +87042,7 @@ index a426fcfeb6..b8886105df 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)); @@ -86893,7 +87053,7 @@ index a426fcfeb6..b8886105df 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"); } @@ -86902,7 +87062,7 @@ index a426fcfeb6..b8886105df 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. */ @@ -86912,7 +87072,7 @@ index a426fcfeb6..b8886105df 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) { @@ -86948,7 +87108,7 @@ index a426fcfeb6..b8886105df 100644 /* 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); @@ -86960,7 +87120,7 @@ index a426fcfeb6..b8886105df 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. */ @@ -86968,7 +87128,7 @@ index a426fcfeb6..b8886105df 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; @@ -86977,7 +87137,7 @@ index a426fcfeb6..b8886105df 100644 } static void -@@ -6738,13 +6803,14 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, +@@ -6738,13 +6812,14 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, return; } @@ -86993,7 +87153,7 @@ index a426fcfeb6..b8886105df 100644 if (ctx->error) { break; -@@ -6752,7 +6818,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, +@@ -6752,7 +6827,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, recirc_for_mpls(a, ctx); @@ -87002,7 +87162,7 @@ index a426fcfeb6..b8886105df 100644 /* Check if need to store the remaining actions for later * execution. */ if (ctx->freezing) { -@@ -7149,17 +7215,18 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, +@@ -7149,17 +7224,18 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, break; case OFPACT_CHECK_PKT_LARGER: { @@ -87026,7 +87186,7 @@ index a426fcfeb6..b8886105df 100644 break; } } -@@ -7623,6 +7690,12 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout) +@@ -7623,6 +7699,12 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout) goto exit; } @@ -89827,10 +89987,20 @@ index 2a2102d6be..99bf80ed62 100644 s += ["static struct ovsdb_datum %s = {" % name] s += [" .n = %d," % n] diff --git a/python/ovs/db/idl.py b/python/ovs/db/idl.py -index ecae5e1432..87ee06cdef 100644 +index ecae5e1432..57263d4638 100644 --- a/python/ovs/db/idl.py +++ b/python/ovs/db/idl.py -@@ -1505,6 +1505,11 @@ class Transaction(object): +@@ -1046,7 +1046,8 @@ class Row(object): + return "{table}({data})".format( + table=self._table.name, + data=", ".join("{col}={val}".format(col=c, val=getattr(self, c)) +- for c in sorted(self._table.columns))) ++ for c in sorted(self._table.columns) ++ if hasattr(self, c))) + + def __getattr__(self, column_name): + assert self._changes is not None +@@ -1505,6 +1506,11 @@ class Transaction(object): if self != self.idl.txn: return self._status @@ -90555,7 +90725,7 @@ index 757cf7186e..fe475e7b38 100644 + +AT_CLEANUP diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at -index 956a69e1fa..43cded03b8 100644 +index 956a69e1fa..eb64d9f867 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: @@ -90682,7 +90852,80 @@ index 956a69e1fa..43cded03b8 100644 ]) OVS_VSWITCHD_STOP -@@ -4862,6 +4862,54 @@ recirc_id(0),in_port(90),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(proto=6,fr +@@ -498,6 +498,72 @@ AT_CHECK([sed -n '/member p2/,/^$/p' bond3.txt | grep 'hash'], [0], [ignore]) + 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 ]) +@@ -4862,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 @@ -90737,7 +90980,7 @@ index 956a69e1fa..43cded03b8 100644 AT_SETUP([ofproto-dpif - exit]) OVS_VSWITCHD_START add_of_ports br0 1 2 3 10 11 12 13 14 -@@ -5525,7 +5573,36 @@ check_flows () { +@@ -5525,7 +5639,36 @@ check_flows () { echo "n_packets=$n" test "$n" = 1 } @@ -90775,7 +91018,7 @@ index 956a69e1fa..43cded03b8 100644 OVS_VSWITCHD_STOP AT_CLEANUP -@@ -7524,13 +7601,28 @@ dnl configure bridge IPFIX and ensure that sample action generation works at the +@@ -7524,13 +7667,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 @@ -90806,7 +91049,7 @@ index 956a69e1fa..43cded03b8 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)']) -@@ -7540,6 +7632,28 @@ flow-dump from the main thread: +@@ -7540,6 +7698,28 @@ flow-dump from the main thread: packets:2, bytes:68, used:0.001s, actions:userspace(pid=0,ipfix(output_port=4294967295)) ]) @@ -90835,7 +91078,7 @@ index 956a69e1fa..43cded03b8 100644 AT_CHECK([ovs-appctl revalidator/purge]) dnl dnl Add a slowpath meter. The userspace action should be metered. -@@ -8591,6 +8705,34 @@ AT_CHECK([sed -n 's/=[[0-9]][[0-9]]\(\.[[0-9]][[0-9]]*\)\{0,1\}s/=?s/p' stdout], +@@ -8591,6 +8771,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 @@ -90870,7 +91113,7 @@ index 956a69e1fa..43cded03b8 100644 dnl ---------------------------------------------------------------------- AT_BANNER([ofproto-dpif -- megaflows]) -@@ -9695,6 +9837,26 @@ OFPST_TABLE reply (OF1.3) (xid=0x2): +@@ -9695,6 +9903,26 @@ OFPST_TABLE reply (OF1.3) (xid=0x2): OVS_VSWITCHD_STOP AT_CLEANUP @@ -90897,7 +91140,7 @@ index 956a69e1fa..43cded03b8 100644 AT_SETUP([ofproto-dpif - ICMPv6]) OVS_VSWITCHD_START add_of_ports br0 1 -@@ -11404,6 +11566,23 @@ Megaflow: recirc_id=0x3,eth,ip,in_port=1,nw_frag=no +@@ -11404,6 +11632,23 @@ Megaflow: recirc_id=0x3,eth,ip,in_port=1,nw_frag=no Datapath actions: 4 ]) @@ -92846,7 +93089,7 @@ index a7ee595e0b..072a537252 100644 + +OVSTEST_REGISTER("json-string-benchmark", json_string_benchmark_main); 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) @@ -92867,7 +93110,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) { @@ -92881,7 +93133,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.16.spec b/SPECS/openvswitch2.16.spec index f1e5a6f..192ea7e 100644 --- a/SPECS/openvswitch2.16.spec +++ b/SPECS/openvswitch2.16.spec @@ -57,7 +57,7 @@ Summary: Open vSwitch Group: System Environment/Daemons daemon/database/utilities URL: http://www.openvswitch.org/ Version: 2.16.0 -Release: 98%{?dist} +Release: 100%{?dist} # Nearly all of openvswitch is ASL 2.0. The bugtool is LGPLv2+, and the # lib/sflow*.[ch] files are SISSL @@ -699,6 +699,21 @@ exit 0 %endif %changelog +* Mon Sep 19 2022 Open vSwitch CI - 2.16.0-100 +- Merging upstream branch-2.16 [RH git: 2a2df330a0] + Commit list: + 3c5902fa24 python: idl: Fix idl.Row.__str__ method. + + +* Mon Sep 19 2022 Open vSwitch CI - 2.16.0-99 +- Merging upstream branch-2.16 [RH git: 37cbf20177] + Commit list: + bae84a232f bond: Avoid deadlock while updating post recirculation rules. + 58e4668a4f ofproto-dpif-upcall: Add debug commands to pause/resume revalidators. + 6b1c9cd084 test-list: Fix false-positive build failure with GCC 12. + f459f9b90f cirrus: Upgrade to FreeBSD 13.1 image. + + * Tue Sep 06 2022 Timothy Redaelli - 2.16.0-98 - Merging 73655c6414 version: 20.11.6 [RH git: 6bbfe5da8f] Commit list: