diff --git a/SOURCES/openvswitch-2.15.0.patch b/SOURCES/openvswitch-2.15.0.patch index 9f25b49..b9ee44f 100644 --- a/SOURCES/openvswitch-2.15.0.patch +++ b/SOURCES/openvswitch-2.15.0.patch @@ -20240,6 +20240,19 @@ index 3c965699ac..9698576d07 100644 bfd_put_details(&ds, bfd); VLOG(level, "%s", ds_cstr(&ds)); ds_destroy(&ds); +diff --git a/lib/classifier.c b/lib/classifier.c +index 2a1d155dad..c4790ee6ba 100644 +--- a/lib/classifier.c ++++ b/lib/classifier.c +@@ -1683,7 +1683,7 @@ find_match(const struct cls_subtable *subtable, ovs_version_t version, + + static const struct cls_match * + find_match_wc(const struct cls_subtable *subtable, ovs_version_t version, +- const struct flow *flow, struct trie_ctx trie_ctx[CLS_MAX_TRIES], ++ const struct flow *flow, struct trie_ctx *trie_ctx, + unsigned int n_tries, struct flow_wildcards *wc) + { + if (OVS_UNLIKELY(!wc)) { diff --git a/lib/cmap.h b/lib/cmap.h index d9db3c915c..8655f76d92 100644 --- a/lib/cmap.h @@ -22266,7 +22279,7 @@ index 47077e9478..5cb96fa6ec 100644 } else { txn->error = 0; diff --git a/lib/odp-util.c b/lib/odp-util.c -index a8598d52af..102003fc80 100644 +index a8598d52af..4983ab114b 100644 --- a/lib/odp-util.c +++ b/lib/odp-util.c @@ -2937,7 +2937,7 @@ odp_nsh_key_from_attr__(const struct nlattr *attr, bool is_mask, @@ -22334,6 +22347,18 @@ index a8598d52af..102003fc80 100644 const struct nlattr *ma = nl_attr_find__(mask, mask_len, OVS_KEY_ATTR_ETHERTYPE); if (ma) { +@@ -7119,11 +7124,6 @@ parse_l2_5_onward(const struct nlattr *attrs[OVS_KEY_ATTR_MAX + 1], + } + } + } +- } else if (src_flow->nw_proto == IPPROTO_IGMP +- && src_flow->dl_type == htons(ETH_TYPE_IP)) { +- /* OVS userspace parses the IGMP type, code, and group, but its +- * datapaths do not, so there is always missing information. */ +- return ODP_FIT_TOO_LITTLE; + } + if (is_mask && expected_bit != OVS_KEY_ATTR_UNSPEC) { + if ((flow->tp_src || flow->tp_dst) && flow->nw_proto != 0xff) { diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c index e2e829772a..0831d811ed 100644 --- a/lib/ofp-actions.c @@ -24491,7 +24516,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..83e405f684 100644 +index 7108c8a301..901e03e971 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); @@ -24593,7 +24618,15 @@ index 7108c8a301..83e405f684 100644 } /* Determine output bundle. */ -@@ -3272,7 +3296,9 @@ compose_ipfix_action(struct xlate_ctx *ctx, odp_port_t output_odp_port) +@@ -3048,7 +3072,6 @@ xlate_normal(struct xlate_ctx *ctx) + */ + ctx->xout->slow |= SLOW_ACTION; + +- memset(&wc->masks.tp_src, 0xff, sizeof wc->masks.tp_src); + 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) struct dpif_ipfix *ipfix = ctx->xbridge->ipfix; odp_port_t tunnel_out_port = ODPP_NONE; @@ -24604,7 +24637,7 @@ index 7108c8a301..83e405f684 100644 return; } -@@ -3521,6 +3547,9 @@ propagate_tunnel_data_to_flow__(struct flow *dst_flow, +@@ -3521,6 +3546,9 @@ propagate_tunnel_data_to_flow__(struct flow *dst_flow, dst_flow->dl_dst = dmac; dst_flow->dl_src = smac; @@ -24614,7 +24647,7 @@ index 7108c8a301..83e405f684 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 +3627,7 @@ propagate_tunnel_data_to_flow(struct xlate_ctx *ctx, struct eth_addr dmac, +@@ -3598,7 +3626,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, @@ -24623,7 +24656,7 @@ index 7108c8a301..83e405f684 100644 { struct netdev_tnl_build_header_params tnl_params; struct ovs_action_push_tnl tnl_push_data; -@@ -3728,7 +3757,7 @@ native_tunnel_output(struct xlate_ctx *ctx, const struct xport *xport, +@@ -3728,7 +3756,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; @@ -24632,7 +24665,7 @@ index 7108c8a301..83e405f684 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 +3851,7 @@ xlate_flow_is_protected(const struct xlate_ctx *ctx, const struct flow *flow, co +@@ -3822,7 +3850,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, @@ -24641,7 +24674,7 @@ index 7108c8a301..83e405f684 100644 { struct flow *flow = &ctx->xin->flow; struct flow old_flow = ctx->xin->flow; -@@ -3864,8 +3893,9 @@ patch_port_output(struct xlate_ctx *ctx, const struct xport *in_dev, +@@ -3864,8 +3892,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)) { @@ -24652,7 +24685,7 @@ index 7108c8a301..83e405f684 100644 if (!ctx->freezing) { xlate_action_set(ctx); } -@@ -3880,7 +3910,7 @@ patch_port_output(struct xlate_ctx *ctx, const struct xport *in_dev, +@@ -3880,7 +3909,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, @@ -24661,7 +24694,7 @@ index 7108c8a301..83e405f684 100644 ctx->mirrors = old_mirrors2; ctx->base_flow = old_base_flow; ctx->odp_actions->size = old_size; -@@ -4097,7 +4127,21 @@ terminate_native_tunnel(struct xlate_ctx *ctx, struct flow *flow, +@@ -4097,7 +4126,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)) { @@ -24684,7 +24717,7 @@ index 7108c8a301..83e405f684 100644 } } -@@ -4107,7 +4151,7 @@ terminate_native_tunnel(struct xlate_ctx *ctx, struct flow *flow, +@@ -4107,7 +4150,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, @@ -24693,7 +24726,7 @@ index 7108c8a301..83e405f684 100644 { const struct xport *xport = get_ofp_port(ctx->xbridge, ofp_port); struct flow_wildcards *wc = ctx->wc; -@@ -4137,6 +4181,10 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port, +@@ -4137,6 +4180,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)); @@ -24704,7 +24737,7 @@ index 7108c8a301..83e405f684 100644 } } -@@ -4144,7 +4192,7 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port, +@@ -4144,7 +4191,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"); } @@ -24713,7 +24746,7 @@ index 7108c8a301..83e405f684 100644 return; } -@@ -4239,7 +4287,8 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port, +@@ -4239,7 +4286,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. */ @@ -24723,7 +24756,7 @@ index 7108c8a301..83e405f684 100644 flow->tunnel = flow_tnl; /* Restore tunnel metadata */ } else if (terminate_native_tunnel(ctx, flow, wc, -@@ -6177,11 +6226,32 @@ static void +@@ -6177,11 +6225,32 @@ static void compose_conntrack_action(struct xlate_ctx *ctx, struct ofpact_conntrack *ofc, bool is_last_action) { @@ -24759,7 +24792,7 @@ index 7108c8a301..83e405f684 100644 /* Ensure that any prior actions are applied before composing the new * conntrack action. */ xlate_commit_actions(ctx); -@@ -6193,11 +6263,6 @@ compose_conntrack_action(struct xlate_ctx *ctx, struct ofpact_conntrack *ofc, +@@ -6193,11 +6262,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); @@ -24771,7 +24804,7 @@ index 7108c8a301..83e405f684 100644 ct_offset = nl_msg_start_nested(ctx->odp_actions, OVS_ACTION_ATTR_CT); if (ofc->flags & NX_CT_F_COMMIT) { -@@ -6333,6 +6398,7 @@ xlate_check_pkt_larger(struct xlate_ctx *ctx, +@@ -6333,6 +6397,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. */ @@ -24779,7 +24812,7 @@ index 7108c8a301..83e405f684 100644 ctx->exit = false; offset_attr = nl_msg_start_nested( -@@ -6357,7 +6423,7 @@ xlate_check_pkt_larger(struct xlate_ctx *ctx, +@@ -6357,7 +6422,7 @@ xlate_check_pkt_larger(struct xlate_ctx *ctx, ctx->was_mpls = old_was_mpls; ctx->conntracked = old_conntracked; ctx->xin->flow = old_flow; @@ -24788,7 +24821,7 @@ index 7108c8a301..83e405f684 100644 } static void -@@ -6736,13 +6802,14 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, +@@ -6736,13 +6801,14 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, return; } @@ -24804,7 +24837,7 @@ index 7108c8a301..83e405f684 100644 if (ctx->error) { break; -@@ -6750,7 +6817,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, +@@ -6750,7 +6816,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, recirc_for_mpls(a, ctx); @@ -24813,7 +24846,7 @@ index 7108c8a301..83e405f684 100644 /* Check if need to store the remaining actions for later * execution. */ if (ctx->freezing) { -@@ -7127,7 +7194,9 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, +@@ -7127,7 +7193,9 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, break; case OFPACT_CT_CLEAR: @@ -24824,7 +24857,7 @@ index 7108c8a301..83e405f684 100644 break; case OFPACT_NAT: -@@ -7145,17 +7214,18 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, +@@ -7145,17 +7213,18 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, break; case OFPACT_CHECK_PKT_LARGER: { @@ -24861,7 +24894,7 @@ index 3426a27b2d..e4959ec686 100644 void xlate_bundle_set(struct ofproto_dpif *, struct ofbundle *, const char *name, enum port_vlan_mode, diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c -index fd0b2fdea0..1f4c8e00fd 100644 +index fd0b2fdea0..12781d6ae0 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -215,10 +215,6 @@ struct shash all_dpif_backers = SHASH_INITIALIZER(&all_dpif_backers); @@ -24992,7 +25025,31 @@ index fd0b2fdea0..1f4c8e00fd 100644 cdtp.id = ct_tp->tp_id; SIMAP_FOR_EACH (node, &ct_tp->tp) { ct_dpif_set_timeout_policy_attr_by_name(&cdtp, node->name, node->data); -@@ -5603,6 +5625,7 @@ get_datapath_cap(const char *datapath_type, struct smap *cap) +@@ -5535,6 +5557,7 @@ ct_set_zone_timeout_policy(const char *datapath_type, uint16_t zone_id, + ct_timeout_policy_unref(backer, ct_zone->ct_tp); + ct_zone->ct_tp = ct_tp; + ct_tp->ref_count++; ++ backer->need_revalidate = REV_RECONFIGURE; + } + } else { + struct ct_zone *new_ct_zone = ct_zone_alloc(zone_id); +@@ -5542,6 +5565,7 @@ ct_set_zone_timeout_policy(const char *datapath_type, uint16_t zone_id, + cmap_insert(&backer->ct_zones, &new_ct_zone->node, + hash_int(zone_id, 0)); + ct_tp->ref_count++; ++ backer->need_revalidate = REV_RECONFIGURE; + } + } + +@@ -5558,6 +5582,7 @@ ct_del_zone_timeout_policy(const char *datapath_type, uint16_t zone_id) + if (ct_zone) { + ct_timeout_policy_unref(backer, ct_zone->ct_tp); + ct_zone_remove_and_destroy(backer, ct_zone); ++ backer->need_revalidate = REV_RECONFIGURE; + } + } + +@@ -5603,6 +5628,7 @@ get_datapath_cap(const char *datapath_type, struct smap *cap) smap_add(cap, "explicit_drop_action", s.explicit_drop_action ? "true" :"false"); smap_add(cap, "lb_output_action", s.lb_output_action ? "true" : "false"); @@ -25000,7 +25057,7 @@ index fd0b2fdea0..1f4c8e00fd 100644 } /* Gets timeout policy name in 'backer' based on 'zone', 'dl_type' and -@@ -5757,15 +5780,7 @@ ofproto_dpif_lookup_by_name(const char *name) +@@ -5757,15 +5783,7 @@ ofproto_dpif_lookup_by_name(const char *name) struct ofproto_dpif * ofproto_dpif_lookup_by_uuid(const struct uuid *uuid) { @@ -25017,7 +25074,7 @@ index fd0b2fdea0..1f4c8e00fd 100644 } static void -@@ -6375,6 +6390,7 @@ ofproto_unixctl_dpif_show_dp_features(struct unixctl_conn *conn, +@@ -6375,6 +6393,7 @@ ofproto_unixctl_dpif_show_dp_features(struct unixctl_conn *conn, dpif_show_support(&ofproto->backer->bt_support, &ds); unixctl_command_reply(conn, ds_cstr(&ds)); @@ -25595,18 +25652,23 @@ index 26d39a087f..7b7bcd74ac 100644 } return NULL; diff --git a/ovsdb/raft.c b/ovsdb/raft.c -index ea91d1fdba..a11144edcd 100644 +index ea91d1fdba..86d4e3e623 100644 --- a/ovsdb/raft.c +++ b/ovsdb/raft.c -@@ -74,6 +74,7 @@ enum raft_failure_test { +@@ -74,8 +74,11 @@ enum raft_failure_test { FT_CRASH_BEFORE_SEND_EXEC_REQ, FT_CRASH_AFTER_SEND_EXEC_REQ, FT_CRASH_AFTER_RECV_APPEND_REQ_UPDATE, + FT_CRASH_BEFORE_SEND_SNAPSHOT_REP, FT_DELAY_ELECTION, - FT_DONT_SEND_VOTE_REQUEST +- FT_DONT_SEND_VOTE_REQUEST ++ FT_DONT_SEND_VOTE_REQUEST, ++ FT_TRANSFER_LEADERSHIP, ++ FT_TRANSFER_LEADERSHIP_AFTER_SEND_APPEND_REQ, }; -@@ -376,12 +377,19 @@ static bool raft_handle_write_error(struct raft *, struct ovsdb_error *); + static enum raft_failure_test failure_test; + +@@ -376,12 +379,19 @@ static bool raft_handle_write_error(struct raft *, struct ovsdb_error *); static void raft_run_reconfigure(struct raft *); static void raft_set_leader(struct raft *, const struct uuid *sid); @@ -25626,7 +25688,7 @@ index ea91d1fdba..a11144edcd 100644 static char * raft_make_address_passive(const char *address_) { -@@ -940,6 +948,34 @@ raft_reset_ping_timer(struct raft *raft) +@@ -940,6 +950,34 @@ raft_reset_ping_timer(struct raft *raft) raft->ping_timeout = time_msec() + raft->election_timer / 3; } @@ -25661,7 +25723,7 @@ index ea91d1fdba..a11144edcd 100644 static void raft_add_conn(struct raft *raft, struct jsonrpc_session *js, const struct uuid *sid, bool incoming) -@@ -954,7 +990,7 @@ raft_add_conn(struct raft *raft, struct jsonrpc_session *js, +@@ -954,7 +992,7 @@ raft_add_conn(struct raft *raft, struct jsonrpc_session *js, &conn->sid); conn->incoming = incoming; conn->js_seqno = jsonrpc_session_get_seqno(conn->js); @@ -25670,7 +25732,7 @@ index ea91d1fdba..a11144edcd 100644 jsonrpc_session_set_backlog_threshold(js, raft->conn_backlog_max_n_msgs, raft->conn_backlog_max_n_bytes); } -@@ -1774,6 +1810,8 @@ raft_open_conn(struct raft *raft, const char *address, const struct uuid *sid) +@@ -1774,6 +1812,8 @@ raft_open_conn(struct raft *raft, const char *address, const struct uuid *sid) static void raft_conn_close(struct raft_conn *conn) { @@ -25679,7 +25741,21 @@ index ea91d1fdba..a11144edcd 100644 jsonrpc_session_close(conn->js); ovs_list_remove(&conn->list_node); free(conn->nickname); -@@ -1864,16 +1902,30 @@ raft_run(struct raft *raft) +@@ -1828,6 +1868,13 @@ raft_run(struct raft *raft) + return; + } + ++ if (failure_test == FT_TRANSFER_LEADERSHIP) { ++ /* Using this function as it conveniently implements all we need and ++ * snapshotting is the main test scenario for leadership transfer. */ ++ raft_notify_snapshot_recommended(raft); ++ failure_test = FT_NO_TEST; ++ } ++ + raft_waiters_run(raft); + + if (!raft->listener && time_msec() >= raft->listen_backoff) { +@@ -1864,16 +1911,30 @@ raft_run(struct raft *raft) } /* Close unneeded sessions. */ @@ -25711,23 +25787,163 @@ index ea91d1fdba..a11144edcd 100644 HMAP_FOR_EACH (server, hmap_node, &raft->servers) { raft_open_conn(raft, server->address, &server->sid); } -@@ -2804,6 +2856,7 @@ raft_update_commit_index(struct raft *raft, uint64_t new_commit_index) - raft->election_timer, e->election_timer); - raft->election_timer = e->election_timer; - raft->election_timer_new = 0; -+ raft_update_probe_intervals(raft); +@@ -1950,7 +2011,14 @@ raft_run(struct raft *raft) + HMAP_FOR_EACH_SAFE (cmd, next_cmd, hmap_node, &raft->commands) { + if (cmd->timestamp + && now - cmd->timestamp > raft->election_timer * 2) { +- raft_command_complete(raft, cmd, RAFT_CMD_TIMEOUT); ++ if (cmd->index && raft->role != RAFT_LEADER) { ++ /* This server lost leadership and command didn't complete ++ * in time. Likely, it wasn't replicated to the majority ++ * of servers before losing the leadership. */ ++ raft_command_complete(raft, cmd, RAFT_CMD_LOST_LEADERSHIP); ++ } else { ++ raft_command_complete(raft, cmd, RAFT_CMD_TIMEOUT); ++ } } - if (e->servers) { - /* raft_run_reconfigure() can write a new Raft entry, which can -@@ -2820,6 +2873,7 @@ raft_update_commit_index(struct raft *raft, uint64_t new_commit_index) - VLOG_INFO("Election timer changed from %"PRIu64" to %"PRIu64, - raft->election_timer, e->election_timer); - raft->election_timer = e->election_timer; -+ raft_update_probe_intervals(raft); + } + raft_reset_ping_timer(raft); +@@ -2140,6 +2208,9 @@ raft_command_initiate(struct raft *raft, + if (failure_test == FT_CRASH_AFTER_SEND_APPEND_REQ) { + ovs_fatal(0, "Raft test: crash after sending append_request."); + } ++ if (failure_test == FT_TRANSFER_LEADERSHIP_AFTER_SEND_APPEND_REQ) { ++ failure_test = FT_TRANSFER_LEADERSHIP; ++ } + raft_reset_ping_timer(raft); + + return cmd; +@@ -2506,7 +2577,13 @@ raft_become_follower(struct raft *raft) + * configuration is already part of the log. Possibly the configuration + * log entry will not be committed, but until we know that we must use the + * new configuration. Our AppendEntries processing will properly update +- * the server configuration later, if necessary. */ ++ * the server configuration later, if necessary. ++ * ++ * Also we do not complete commands here, as they can still be completed ++ * if their log entries have already been replicated to other servers. ++ * If the entries were actually committed according to the new leader, our ++ * AppendEntries processing will complete the corresponding commands. ++ */ + struct raft_server *s; + HMAP_FOR_EACH (s, hmap_node, &raft->add_servers) { + raft_send_add_server_reply__(raft, &s->sid, s->address, false, +@@ -2520,8 +2597,6 @@ raft_become_follower(struct raft *raft) + raft_server_destroy(raft->remove_server); + raft->remove_server = NULL; + } +- +- raft_complete_all_commands(raft, RAFT_CMD_LOST_LEADERSHIP); + } + + static void +@@ -2782,59 +2857,56 @@ raft_update_commit_index(struct raft *raft, uint64_t new_commit_index) + return false; + } + +- if (raft->role == RAFT_LEADER) { +- while (raft->commit_index < new_commit_index) { +- uint64_t index = ++raft->commit_index; +- const struct raft_entry *e = raft_get_entry(raft, index); +- if (e->data) { +- struct raft_command *cmd +- = raft_find_command_by_eid(raft, &e->eid); +- if (cmd) { +- if (!cmd->index) { +- VLOG_DBG("Command completed after role change from" +- " follower to leader "UUID_FMT, +- UUID_ARGS(&e->eid)); +- cmd->index = index; +- } +- raft_command_complete(raft, cmd, RAFT_CMD_SUCCESS); ++ while (raft->commit_index < new_commit_index) { ++ uint64_t index = ++raft->commit_index; ++ const struct raft_entry *e = raft_get_entry(raft, index); ++ ++ if (e->data) { ++ struct raft_command *cmd = raft_find_command_by_eid(raft, &e->eid); ++ static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 5); ++ ++ if (cmd) { ++ if (!cmd->index && raft->role == RAFT_LEADER) { ++ VLOG_INFO_RL(&rl, ++ "command completed after role change from " ++ "follower to leader (eid: "UUID_FMT", " ++ "commit index: %"PRIu64")", UUID_ARGS(&e->eid), index); ++ } else if (!cmd->index && raft->role != RAFT_LEADER) { ++ /* This can happen when leader fail-over before sending ++ * execute_command_reply. */ ++ VLOG_INFO_RL(&rl, ++ "command completed without reply (eid: "UUID_FMT", " ++ "commit index: %"PRIu64")", UUID_ARGS(&e->eid), index); ++ } else if (cmd->index && raft->role != RAFT_LEADER) { ++ /* This can happen if current server lost leadership after ++ * sending append requests to the majority of servers, but ++ * before receiving majority of append replies. */ ++ VLOG_INFO_RL(&rl, ++ "command completed after role change from " ++ "leader to follower (eid: "UUID_FMT", " ++ "commit index: %"PRIu64")", UUID_ARGS(&e->eid), index); ++ /* Clearing 'sid' to avoid sending cmd execution reply. */ ++ cmd->sid = UUID_ZERO; ++ } else { ++ /* (cmd->index && raft->role == RAFT_LEADER) ++ * Normal command completion on a leader. */ + } +- } +- if (e->election_timer) { +- VLOG_INFO("Election timer changed from %"PRIu64" to %"PRIu64, +- raft->election_timer, e->election_timer); +- raft->election_timer = e->election_timer; +- raft->election_timer_new = 0; +- } +- if (e->servers) { +- /* raft_run_reconfigure() can write a new Raft entry, which can +- * reallocate raft->entries, which would invalidate 'e', so +- * this case must be last, after the one for 'e->data'. */ +- raft_run_reconfigure(raft); ++ cmd->index = index; ++ raft_command_complete(raft, cmd, RAFT_CMD_SUCCESS); } } - /* Check if any pending command can be completed, and complete it. -@@ -3258,12 +3312,6 @@ raft_find_peer(struct raft *raft, const struct uuid *uuid) +- } else { +- while (raft->commit_index < new_commit_index) { +- uint64_t index = ++raft->commit_index; +- const struct raft_entry *e = raft_get_entry(raft, index); +- if (e->election_timer) { +- VLOG_INFO("Election timer changed from %"PRIu64" to %"PRIu64, +- raft->election_timer, e->election_timer); +- raft->election_timer = e->election_timer; +- } ++ if (e->election_timer) { ++ VLOG_INFO("Election timer changed from %"PRIu64" to %"PRIu64, ++ raft->election_timer, e->election_timer); ++ raft->election_timer = e->election_timer; ++ raft->election_timer_new = 0; ++ raft_update_probe_intervals(raft); + } +- /* Check if any pending command can be completed, and complete it. +- * This can happen when leader fail-over before sending +- * execute_command_reply. */ +- const struct uuid *eid = raft_get_eid(raft, new_commit_index); +- struct raft_command *cmd = raft_find_command_by_eid(raft, eid); +- if (cmd) { +- static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 5); +- VLOG_INFO_RL(&rl, +- "Command completed without reply (eid: "UUID_FMT", " +- "commit index: %"PRIu64")", +- UUID_ARGS(eid), new_commit_index); +- cmd->index = new_commit_index; +- raft_command_complete(raft, cmd, RAFT_CMD_SUCCESS); ++ if (e->servers && raft->role == RAFT_LEADER) { ++ /* raft_run_reconfigure() can write a new Raft entry, which can ++ * reallocate raft->entries, which would invalidate 'e', so ++ * this case must be last, after the one for 'e->data'. */ ++ raft_run_reconfigure(raft); + } + } + +@@ -3258,12 +3330,6 @@ raft_find_peer(struct raft *raft, const struct uuid *uuid) return s && !uuid_equals(&raft->sid, &s->sid) ? s : NULL; } @@ -25740,7 +25956,7 @@ index ea91d1fdba..a11144edcd 100644 /* Figure 3.1: "If there exists an N such that N > commitIndex, a * majority of matchIndex[i] >= N, and log[N].term == currentTerm, set * commitIndex = N (sections 3.5 and 3.6)." */ -@@ -4038,6 +4086,10 @@ static void +@@ -4038,6 +4104,10 @@ static void raft_handle_install_snapshot_request( struct raft *raft, const struct raft_install_snapshot_request *rq) { @@ -25751,7 +25967,7 @@ index ea91d1fdba..a11144edcd 100644 if (raft_handle_install_snapshot_request__(raft, rq)) { union raft_rpc rpy = { .install_snapshot_reply = { -@@ -4122,9 +4174,24 @@ raft_may_snapshot(const struct raft *raft) +@@ -4122,9 +4192,24 @@ raft_may_snapshot(const struct raft *raft) && !raft->leaving && !raft->left && !raft->failed @@ -25776,7 +25992,7 @@ index ea91d1fdba..a11144edcd 100644 /* Replaces the log for 'raft', up to the last log entry read, by * 'new_snapshot_data'. Returns NULL if successful, otherwise an error that * the caller must eventually free. -@@ -4468,6 +4535,8 @@ raft_unixctl_status(struct unixctl_conn *conn, +@@ -4468,6 +4553,8 @@ raft_unixctl_status(struct unixctl_conn *conn, : raft->leaving ? "leaving cluster" : raft->left ? "left cluster" : raft->failed ? "failed" @@ -25785,7 +26001,7 @@ index ea91d1fdba..a11144edcd 100644 : "cluster member"); if (raft->joining) { ds_put_format(&s, "Remotes for joining:"); -@@ -4814,6 +4883,8 @@ raft_unixctl_failure_test(struct unixctl_conn *conn OVS_UNUSED, +@@ -4814,6 +4901,8 @@ raft_unixctl_failure_test(struct unixctl_conn *conn OVS_UNUSED, failure_test = FT_CRASH_AFTER_SEND_EXEC_REQ; } else if (!strcmp(test, "crash-after-receiving-append-request-update")) { failure_test = FT_CRASH_AFTER_RECV_APPEND_REQ_UPDATE; @@ -25794,6 +26010,18 @@ index ea91d1fdba..a11144edcd 100644 } else if (!strcmp(test, "delay-election")) { failure_test = FT_DELAY_ELECTION; struct raft *raft; +@@ -4824,6 +4913,11 @@ raft_unixctl_failure_test(struct unixctl_conn *conn OVS_UNUSED, + } + } else if (!strcmp(test, "dont-send-vote-request")) { + failure_test = FT_DONT_SEND_VOTE_REQUEST; ++ } else if (!strcmp(test, ++ "transfer-leadership-after-sending-append-request")) { ++ failure_test = FT_TRANSFER_LEADERSHIP_AFTER_SEND_APPEND_REQ; ++ } else if (!strcmp(test, "transfer-leadership")) { ++ failure_test = FT_TRANSFER_LEADERSHIP; + } else if (!strcmp(test, "clear")) { + failure_test = FT_NO_TEST; + unixctl_command_reply(conn, "test dismissed"); diff --git a/ovsdb/raft.h b/ovsdb/raft.h index 99d5307e54..59902fe825 100644 --- a/ovsdb/raft.h @@ -26633,6 +26861,81 @@ index e3173fb88f..2347c690ef 100644 diff --git a/tests/fuzz-regression/ofp_print_fuzzer-6540965472632832 b/tests/fuzz-regression/ofp_print_fuzzer-6540965472632832 new file mode 100644 index 0000000000..e69de29bb2 +diff --git a/tests/mcast-snooping.at b/tests/mcast-snooping.at +index 757cf7186e..fe475e7b38 100644 +--- a/tests/mcast-snooping.at ++++ b/tests/mcast-snooping.at +@@ -216,3 +216,70 @@ AT_CHECK([ovs-appctl mdb/show br0], [0], [dnl + ]) + + AT_CLEANUP ++ ++ ++AT_SETUP([mcast - igmp flood for non-snoop enabled]) ++OVS_VSWITCHD_START([]) ++ ++AT_CHECK([ ++ ovs-vsctl set bridge br0 \ ++ datapath_type=dummy], [0]) ++ ++add_of_ports br0 1 2 ++ ++AT_CHECK([ovs-ofctl add-flow br0 action=normal]) ++ ++ovs-appctl time/stop ++ ++dnl Basic scenario - needs to flood for IGMP followed by unicast ICMP ++dnl in reverse direction ++AT_CHECK([ovs-appctl netdev-dummy/receive p1 \ ++ '0101000c29a0aa55aa550001080046c00028000040000102d3494565eb4ae0000016940400002200f9020000000104000000e00000fb000000000000']) ++AT_CHECK([ovs-appctl netdev-dummy/receive p2 \ ++ 'aa55aa5500010101000c29a008004500001c00010000400164dc0a0101010a0101020800f7ffffffffff']) ++ ++ ++AT_CHECK([ovs-appctl dpctl/dump-flows | grep -e .*ipv4 | sort | dnl ++ strip_stats | strip_used | strip_recirc | dnl ++ sed -e 's/,packet_type(ns=[[0-9]]*,id=[[0-9]]*),/,/'], ++ [0], [dnl ++recirc_id(),in_port(1),eth(src=aa:55:aa:55:00:01,dst=01:01:00:0c:29:a0),eth_type(0x0800),ipv4(frag=no), packets:0, bytes:0, used:never, actions:100,2 ++recirc_id(),in_port(2),eth(src=01:01:00:0c:29:a0,dst=aa:55:aa:55:00:01),eth_type(0x0800),ipv4(frag=no), packets:0, bytes:0, used:never, actions:1 ++]) ++ ++ovs-appctl time/warp 100000 ++ ++dnl Next we should clear the flows and install a complex case ++AT_CHECK([ovs-ofctl del-flows br0]) ++ ++AT_DATA([flows.txt], [dnl ++table=0, arp actions=NORMAL ++table=0, ip,in_port=1 actions=ct(table=1,zone=64000) ++table=0, in_port=2 actions=output:1 ++table=1, ip,ct_state=+trk+inv actions=drop ++table=1 ip,in_port=1,icmp,ct_state=+trk+new actions=output:2 ++table=1, in_port=1,ip,ct_state=+trk+new actions=controller(userdata=00.de.ad.be.ef.ca.fe.01) ++table=1, in_port=1,ip,ct_state=+trk+est actions=output:2 ++]) ++AT_CHECK([ovs-ofctl add-flows br0 flows.txt]) ++ ++ovs-appctl time/warp 100000 ++ ++dnl Send the IGMP, followed by a unicast ICMP - ensure we won't black hole ++AT_CHECK([ovs-appctl netdev-dummy/receive p1 \ ++ '0101000c29a0aa55aa550001080046c00028000040000102d3494565eb4ae0000016940400002200f9020000000104000000e00000fb000000000000']) ++AT_CHECK([ovs-appctl netdev-dummy/receive p1 \ ++ 'aa55aa550001aa55aa55000208004500001c00010000400164dc0a0101010a0101020800f7ffffffffff']) ++ ++ ++AT_CHECK([ovs-appctl dpctl/dump-flows | grep -e .*ipv4 | sort | dnl ++ strip_stats | strip_used | strip_recirc | dnl ++ sed 's/pid=[[0-9]]*,// ++ s/,packet_type(ns=[[0-9]]*,id=[[0-9]]*),/,/'], ++ [0], [dnl ++ct_state(+new-inv+trk),recirc_id(),in_port(1),eth_type(0x0800),ipv4(proto=1,frag=no), packets:0, bytes:0, used:never, actions:2 ++ct_state(+new-inv+trk),recirc_id(),in_port(1),eth_type(0x0800),ipv4(proto=2,frag=no), packets:0, bytes:0, used:never, actions:userspace(controller(reason=1,dont_send=0,continuation=0,recirc_id=,rule_cookie=0,controller_id=0,max_len=65535)) ++recirc_id(),in_port(1),eth_type(0x0800),ipv4(frag=no), packets:0, bytes:0, used:0.0s, actions:ct(zone=64000),recirc() ++]) ++ ++AT_CLEANUP diff --git a/tests/ofp-actions.at b/tests/ofp-actions.at index 199db8ed0f..59093c03c9 100644 --- a/tests/ofp-actions.at @@ -27168,6 +27471,32 @@ index 31064ed95e..9ca18a4107 100644 OVS_VSWITCHD_STOP AT_CLEANUP +diff --git a/tests/ofproto-macros.at b/tests/ofproto-macros.at +index 736d9809cb..f906b5c3b5 100644 +--- a/tests/ofproto-macros.at ++++ b/tests/ofproto-macros.at +@@ -134,6 +134,21 @@ strip_ufid () { + sed 's/mega_ufid:[[-0-9a-f]]* // + s/ufid:[[-0-9a-f]]* //' + } ++ ++# Strips packets: and bytes: from output ++strip_stats () { ++ sed 's/packets:[[0-9]]*/packets:0/ ++ s/bytes:[[0-9]]*/bytes:0/' ++} ++ ++# Changes all 'recirc(...)' and 'recirc=...' to say 'recirc()' and ++# 'recirc=' respectively. This should make output easier to ++# compare. ++strip_recirc() { ++ sed 's/recirc_id([[x0-9]]*)/recirc_id()/ ++ s/recirc_id=[[x0-9]]*/recirc_id=/ ++ s/recirc([[x0-9]]*)/recirc()/' ++} + m4_divert_pop([PREPARE_TESTS]) + + m4_define([TESTABLE_LOG], [-vPATTERN:ANY:'%c|%p|%m']) diff --git a/tests/ovs-macros.at b/tests/ovs-macros.at index 66545da572..e6c5bc6e94 100644 --- a/tests/ovs-macros.at @@ -27344,7 +27673,7 @@ index 8d777a0275..52a15f3dd1 100644 AT_KEYWORDS([ovsdb client positive]) diff --git a/tests/ovsdb-cluster.at b/tests/ovsdb-cluster.at -index 92aa427093..efb0efd7f7 100644 +index 92aa427093..2ed656c745 100644 --- a/tests/ovsdb-cluster.at +++ b/tests/ovsdb-cluster.at @@ -128,7 +128,7 @@ ovsdb_test_cluster_disconnect () { @@ -27418,7 +27747,11 @@ index 92aa427093..efb0efd7f7 100644 OVS_START_SHELL_HELPERS -@@ -406,9 +461,8 @@ ovsdb_cluster_failure_test () { +@@ -403,12 +458,12 @@ ovsdb_cluster_failure_test () { + if test "$crash_node" == "1"; then + new_leader=$5 + fi ++ log_grep=$6 cp $top_srcdir/vswitchd/vswitch.ovsschema schema schema=`ovsdb-tool schema-name schema` @@ -27430,7 +27763,57 @@ index 92aa427093..efb0efd7f7 100644 n=3 join_cluster() { -@@ -619,9 +673,8 @@ ovsdb_torture_test () { +@@ -424,7 +479,7 @@ ovsdb|WARN|schema: changed 30 columns in 'Open_vSwitch' database from ephemeral + start_server() { + local i=$1 + printf "\ns$i: starting\n" +- AT_CHECK([ovsdb-server -vjsonrpc -vconsole:off -vsyslog:off --detach --no-chdir --log-file=s$i.log --pidfile=s$i.pid --unixctl=s$i --remote=punix:s$i.ovsdb s$i.db]) ++ AT_CHECK([ovsdb-server -vjsonrpc -vraft -vconsole:off -vsyslog:off --detach --no-chdir --log-file=s$i.log --pidfile=s$i.pid --unixctl=s$i --remote=punix:s$i.ovsdb s$i.db]) + } + connect_server() { + local i=$1 +@@ -450,14 +505,23 @@ ovsdb|WARN|schema: changed 30 columns in 'Open_vSwitch' database from ephemeral + fi + AT_CHECK([ovs-appctl -t "`pwd`"/s$delay_election_node cluster/failure-test delay-election], [0], [ignore]) + fi ++ ++ # Initializing the database separately to avoid extra 'wait' operation ++ # in later transactions. ++ AT_CHECK([ovs-vsctl -v --db="$db" --no-leader-only --no-shuffle-remotes --no-wait init], [0], [ignore], [ignore]) ++ + AT_CHECK([ovs-appctl -t "`pwd`"/s$crash_node cluster/failure-test $crash_command], [0], [ignore]) + AT_CHECK([ovs-vsctl -v --db="$db" --no-leader-only --no-shuffle-remotes --no-wait create QoS type=x], [0], [ignore], [ignore]) + +- # Make sure that the node really crashed. +- AT_CHECK([ls s$crash_node.ovsdb], [2], [ignore], [ignore]) +- # XXX: Client will fail if remotes contains unix socket that doesn't exist (killed). +- if test "$remote_1" = "$crash_node"; then +- db=unix:s$remote_2.ovsdb ++ # Make sure that the node really crashed or has specific log message. ++ if test -z "$log_grep"; then ++ AT_CHECK([ls s$crash_node.ovsdb], [2], [ignore], [ignore]) ++ # XXX: Client will fail if remotes contains unix socket that doesn't exist (killed). ++ if test "$remote_1" = "$crash_node"; then ++ db=unix:s$remote_2.ovsdb ++ fi ++ else ++ OVS_WAIT_UNTIL([grep -q "$log_grep" s${crash_node}.log]) + fi + AT_CHECK([ovs-vsctl --db="$db" --no-leader-only --no-wait --columns=type --bare list QoS], [0], [x + ]) +@@ -553,6 +617,11 @@ AT_KEYWORDS([ovsdb server negative unix cluster pending-txn]) + ovsdb_cluster_failure_test 2 2 3 crash-after-receiving-append-request-update + AT_CLEANUP + ++AT_SETUP([OVSDB cluster - txn on leader, leader transfers leadership after sending appendReq]) ++AT_KEYWORDS([ovsdb server negative unix cluster pending-txn transfer]) ++ovsdb_cluster_failure_test 1 2 1 transfer-leadership-after-sending-append-request -1 "Transferring leadership" ++AT_CLEANUP ++ + + AT_SETUP([OVSDB cluster - competing candidates]) + AT_KEYWORDS([ovsdb server negative unix cluster competing-candidates]) +@@ -619,9 +688,8 @@ ovsdb_torture_test () { local variant=$3 # 'kill' and restart or 'remove' and add cp $top_srcdir/vswitchd/vswitch.ovsschema schema schema=`ovsdb-tool schema-name schema` @@ -29316,7 +29699,7 @@ index 1714273e35..270956d13f 100644 dnl Delete ip address. AT_CHECK([ip addr del 10.0.0.17/24 dev p1-route], [0], [stdout]) diff --git a/tests/system-traffic.at b/tests/system-traffic.at -index fb5b9a36d2..d3853bc94c 100644 +index fb5b9a36d2..38ff4837c0 100644 --- a/tests/system-traffic.at +++ b/tests/system-traffic.at @@ -218,6 +218,7 @@ OVS_TRAFFIC_VSWITCHD_STOP @@ -29833,6 +30216,92 @@ index fb5b9a36d2..d3853bc94c 100644 echo Request $i NS_CHECK_EXEC([at_ns1], [wget 10.1.1.64 -t 5 -T 1 --retry-connrefused -v -o wget$i.log]) done +@@ -5971,6 +6315,85 @@ AT_CHECK([ovs-ofctl dump-flows br0 | grep table=2, | OFPROTO_CLEAR_DURATION_IDLE + OVS_TRAFFIC_VSWITCHD_STOP + AT_CLEANUP + ++AT_BANNER([IGMP]) ++ ++AT_SETUP([IGMP - flood under normal action]) ++ ++OVS_TRAFFIC_VSWITCHD_START() ++ADD_NAMESPACES(at_ns0, at_ns1) ++ ++ADD_VETH(p1, at_ns0, br0, "10.1.1.1/24", "f0:00:00:01:01:01") ++ADD_VETH(p2, at_ns1, br0, "10.1.1.2/24", "f0:00:00:01:01:02") ++ ++AT_CHECK([ovs-ofctl add-flow br0 "actions=NORMAL"]) ++ ++NS_CHECK_EXEC([at_ns0], [$PYTHON3 $srcdir/sendpkt.py p1 01 00 5e 01 01 03 dnl ++f0 00 00 01 01 01 08 00 46 c0 00 28 00 00 40 00 01 02 d3 49 45 65 eb 4a e0 dnl ++00 00 16 94 04 00 00 22 00 f9 02 00 00 00 01 04 00 00 00 e0 00 00 fb 00 00 dnl ++00 00 00 00 > /dev/null]) ++ ++AT_CHECK([ovs-appctl dpctl/dump-flows --names | grep -e .*ipv4 | sort | dnl ++ strip_stats | strip_used | strip_recirc | dnl ++ sed 's/,packet_type(ns=[[0-9]]*,id=[[0-9]]*),/,/'], ++ [0], [dnl ++recirc_id(),in_port(ovs-p1),eth(src=f0:00:00:01:01:01,dst=01:00:5e:01:01:03),eth_type(0x0800),ipv4(frag=no), packets:0, bytes:0, used:never, actions:br0,ovs-p2 ++]) ++OVS_TRAFFIC_VSWITCHD_STOP ++AT_CLEANUP ++ ++AT_SETUP([IGMP - forward with ICMP]) ++ ++OVS_TRAFFIC_VSWITCHD_START() ++ADD_NAMESPACES(at_ns0, at_ns1) ++ ++ADD_VETH(p1, at_ns0, br0, "10.1.1.1/24", "f0:00:00:01:01:01") ++ADD_VETH(p2, at_ns1, br0, "10.1.1.2/24", "f0:00:00:01:01:02") ++ ++AT_DATA([flows.txt], [dnl ++table=0, arp actions=NORMAL ++table=0, ip,in_port=1 actions=ct(table=1,zone=64000) ++table=0, in_port=2 actions=output:1 ++table=1, ip,ct_state=+trk+inv actions=drop ++table=1 ip,in_port=1,icmp,ct_state=+trk+new actions=output:2 ++table=1, in_port=1,ip,ct_state=+trk+new actions=controller(userdata=00.de.ad.be.ef.ca.fe.01) ++table=1, in_port=1,ip,ct_state=+trk+est actions=output:2 ++]) ++AT_CHECK([ovs-ofctl del-flows br0]) ++AT_CHECK([ovs-ofctl add-flows br0 flows.txt]) ++ ++dnl Send the IGMP, followed by a unicast ICMP - ensure we won't black hole ++ ++NS_CHECK_EXEC([at_ns0], [$PYTHON3 $srcdir/sendpkt.py p1 f0 00 00 01 01 02 dnl ++f0 00 00 01 01 01 08 00 46 c0 00 28 00 00 40 00 01 02 d3 49 45 65 eb 4a e0 dnl ++00 00 16 94 04 00 00 22 00 f9 02 00 00 00 01 04 00 00 00 e0 00 00 fb 00 00 dnl ++00 00 00 00 > /dev/null]) ++ ++NS_CHECK_EXEC([at_ns0], [$PYTHON3 $srcdir/sendpkt.py p1 f0 00 00 01 01 02 dnl ++f0 00 00 01 01 01 08 00 45 00 00 1c 00 01 00 00 40 01 64 dc 0a 01 01 01 0a dnl ++01 01 02 08 00 f7 ff ff ff ff ff > /dev/null]) ++ ++sleep 1 ++ ++dnl Prefer the OpenFlow rules, because different datapaths will behave slightly ++dnl differently with respect to the exact dp rules. ++dnl ++dnl This is also why we clear n_bytes / n_packets - some kernels with ipv6 ++dnl enabled will bump some of these counters non-deterministically ++ ++AT_CHECK([ovs-ofctl dump-flows br0 | grep -v NXST | dnl ++ strip_duration | grep -v arp | grep -v n_packets=0 | dnl ++ grep -v 'in_port=2 actions=output:1' | dnl ++ sed 's/n_bytes=[[0-9]]*/n_bytes=0/ ++ s/idle_age=[[0-9]]*/idle_age=0/ ++ s/n_packets=[[1-9]]/n_packets=0/' | sort], [0], [dnl ++ cookie=0x0, table=0, n_packets=0, n_bytes=0, idle_age=0, ip,in_port=1 actions=ct(table=1,zone=64000) ++ cookie=0x0, table=1, n_packets=0, n_bytes=0, idle_age=0, ct_state=+new+trk,icmp,in_port=1 actions=output:2 ++ cookie=0x0, table=1, n_packets=0, n_bytes=0, idle_age=0, ct_state=+new+trk,ip,in_port=1 actions=controller(userdata=00.de.ad.be.ef.ca.fe.01) ++]) ++ ++OVS_TRAFFIC_VSWITCHD_STOP ++AT_CLEANUP ++ + AT_BANNER([802.1ad]) + + AT_SETUP([802.1ad - vlan_limit]) diff --git a/tests/system-tso-macros.at b/tests/system-tso-macros.at index 406334f3e0..1a80047619 100644 --- a/tests/system-tso-macros.at diff --git a/SPECS/openvswitch2.15.spec b/SPECS/openvswitch2.15.spec index 37cc44c..c958827 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: 102%{?dist} +Release: 103%{?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 +* Thu May 26 2022 Open vSwitch CI - 2.15.0-103 +- Merging upstream branch-2.15 [RH git: d93e08b22f] + Commit list: + 18a8b7d5d8 classifier: Make find_match_wc() prototype and definition match. + cc783da5d9 ovsdb: raft: Fix transaction double commit due to lost leadership. (#2046340) + 292e018e27 Revert "odp-util: Always report ODP_FIT_TOO_LITTLE for IGMP." + ecfd0b783f ofproto-dpif: Trigger revalidation if ct tp changes. + + * Wed May 25 2022 Open vSwitch CI - 2.15.0-102 - Merging upstream branch-2.15 [RH git: 08671b1f53] Commit list: