From patchwork Fri Jan 12 19:19:34 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aaron Conole X-Patchwork-Id: 860154 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zJCHL1XsRz9sBd for ; Sat, 13 Jan 2018 06:19:42 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id BCE2BE4F; Fri, 12 Jan 2018 19:19:40 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 0093EE33 for ; Fri, 12 Jan 2018 19:19:39 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 581FD473 for ; Fri, 12 Jan 2018 19:19:38 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E5D7720273 for ; Fri, 12 Jan 2018 19:19:37 +0000 (UTC) Received: from dhcp-25.97.bos.redhat.com (unknown [10.18.25.61]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9E8F518F00 for ; Fri, 12 Jan 2018 19:19:37 +0000 (UTC) From: Aaron Conole To: dev@openvswitch.org Date: Fri, 12 Jan 2018 14:19:34 -0500 Message-Id: <20180112191935.1589-2-aconole@redhat.com> In-Reply-To: <20180112191935.1589-1-aconole@redhat.com> References: <20180112191935.1589-1-aconole@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Fri, 12 Jan 2018 19:19:37 +0000 (UTC) X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [RFC 1/2] datapath: prevent deletion of flows / datapaths X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org Introduce a way of telling the revalidators not to delete flows from the datapath. This means that even during the dump/sweep behavior, flows which might have been expired will stick around in the kernel datapath. Such an effect is potentially disastrous (since the kernel flow cache will never empty, only fill). On the other hand, in conjunction with other user actions, this can implement a "graceful restart." This will be used in an upcoming commit. Signed-off-by: Aaron Conole --- lib/dpctl.c | 27 ++++++++++++++++++++++ lib/dpif-netdev.c | 2 ++ lib/dpif-netlink.c | 65 ++++++++++++++++++++++++++++++++++++++++------------- lib/dpif-provider.h | 8 +++++++ lib/dpif.c | 22 ++++++++++++++++++ lib/dpif.h | 2 ++ 6 files changed, 110 insertions(+), 16 deletions(-) diff --git a/lib/dpctl.c b/lib/dpctl.c index 6520788aa..ed4e17f3b 100644 --- a/lib/dpctl.c +++ b/lib/dpctl.c @@ -1885,6 +1885,32 @@ out: return error; } + +static int +dpctl_icing_dp(int argc, const char *argv[], struct dpctl_params *dpctl_p) +{ + struct dpif *dpif; + int error; + + error = parsed_dpif_open(argv[1], false, &dpif); + if (error) { + dpctl_error(dpctl_p, error, "icing_dp"); + return error; + } + + if (argc > 2) { + bool icing_status = false; + if (!strcmp(argv[2], "enabled")) { + icing_status = true; + } + dpif_set_ice_status(dpif, icing_status); + } + + dpctl_print(dpctl_p, dpif_get_ice_status(dpif) ? "enabled" : "disabled"); + dpif_close(dpif); + return 0; +} + static const struct dpctl_command all_commands[] = { { "add-dp", "dp [iface...]", 1, INT_MAX, dpctl_add_dp, DP_RW }, @@ -1913,6 +1939,7 @@ static const struct dpctl_command all_commands[] = { { "parse-actions", "actions", 1, INT_MAX, dpctl_parse_actions, DP_RO }, { "normalize-actions", "actions", 2, INT_MAX, dpctl_normalize_actions, DP_RO }, + { "datapath-icing", "dp [enabled|disabled]", 1, 2, dpctl_icing_dp, DP_RW }, { NULL, NULL, 0, 0, NULL, DP_RO }, }; diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 0a62630c2..08a8503b0 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -5790,6 +5790,8 @@ const struct dpif_class dpif_netdev_class = { dpif_netdev_meter_set, dpif_netdev_meter_get, dpif_netdev_meter_del, + NULL, + NULL }; static void diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c index c265909f8..05a04b1fb 100644 --- a/lib/dpif-netlink.c +++ b/lib/dpif-netlink.c @@ -196,6 +196,7 @@ struct dpif_netlink { /* Change notification. */ struct nl_sock *port_notifier; /* vport multicast group subscriber. */ bool refresh_channels; + }; static void report_loss(struct dpif_netlink *, struct dpif_channel *, @@ -211,6 +212,8 @@ static int ovs_vport_family; static int ovs_flow_family; static int ovs_packet_family; +static bool ice_status = false; + /* Generic Netlink multicast groups for OVS. * * Initialized by dpif_netlink_init(). */ @@ -707,6 +710,9 @@ dpif_netlink_destroy(struct dpif *dpif_) dpif_netlink_dp_init(&dp); dp.cmd = OVS_DP_CMD_DEL; dp.dp_ifindex = dpif->dp_ifindex; + if (ice_status) { + return 0; + } return dpif_netlink_dp_transact(&dp, NULL, NULL); } @@ -1159,6 +1165,10 @@ dpif_netlink_flow_flush(struct dpif *dpif_) flow.cmd = OVS_FLOW_CMD_DEL; flow.dp_ifindex = dpif->dp_ifindex; + if (ice_status) { + return 0; + } + if (netdev_is_flow_api_enabled()) { netdev_ports_flow_flush(dpif_->dpif_class); } @@ -1916,13 +1926,15 @@ dpif_netlink_operate__(struct dpif_netlink *dpif, break; case DPIF_OP_FLOW_DEL: - del = &op->u.flow_del; - dpif_netlink_init_flow_del(dpif, del, &flow); - if (del->stats) { - flow.nlmsg_flags |= NLM_F_ECHO; - aux->txn.reply = &aux->reply; + if (!ice_status) { + del = &op->u.flow_del; + dpif_netlink_init_flow_del(dpif, del, &flow); + if (del->stats) { + flow.nlmsg_flags |= NLM_F_ECHO; + aux->txn.reply = &aux->reply; + } + dpif_netlink_flow_to_ofpbuf(&flow, &aux->request); } - dpif_netlink_flow_to_ofpbuf(&flow, &aux->request); break; case DPIF_OP_EXECUTE: @@ -1990,15 +2002,17 @@ dpif_netlink_operate__(struct dpif_netlink *dpif, break; case DPIF_OP_FLOW_DEL: - del = &op->u.flow_del; - if (del->stats) { - if (!op->error) { - struct dpif_netlink_flow reply; - - op->error = dpif_netlink_flow_from_ofpbuf(&reply, - txn->reply); + if (!ice_status) { + del = &op->u.flow_del; + if (del->stats) { if (!op->error) { - dpif_netlink_flow_get_stats(&reply, del->stats); + struct dpif_netlink_flow reply; + + op->error = dpif_netlink_flow_from_ofpbuf(&reply, + txn->reply); + if (!op->error) { + dpif_netlink_flow_get_stats(&reply, del->stats); + } } } } @@ -2156,7 +2170,9 @@ parse_flow_put(struct dpif_netlink *dpif, struct dpif_flow_put *put) op.u.flow_del.terse = false; opp = &op; - dpif_netlink_operate__(dpif, &opp, 1); + if (!ice_status) { + dpif_netlink_operate__(dpif, &opp, 1); + } } VLOG_DBG("added flow"); @@ -2207,7 +2223,7 @@ try_send_to_netdev(struct dpif_netlink *dpif, struct dpif_op *op) case DPIF_OP_FLOW_DEL: { struct dpif_flow_del *del = &op->u.flow_del; - if (!del->ufid) { + if (ice_status || !del->ufid) { break; } @@ -2941,6 +2957,21 @@ dpif_netlink_meter_del(struct dpif *dpif OVS_UNUSED, } + +static int +dpif_netlink_set_ice_status(struct dpif *dpif_ OVS_UNUSED, bool set_ice_status) +{ + ice_status = set_ice_status; + return 0; +} + +static bool +dpif_netlink_get_ice_status(struct dpif *dpif_ OVS_UNUSED) +{ + return ice_status; +} + + const struct dpif_class dpif_netlink_class = { "system", NULL, /* init */ @@ -2990,6 +3021,8 @@ const struct dpif_class dpif_netlink_class = { dpif_netlink_meter_set, dpif_netlink_meter_get, dpif_netlink_meter_del, + dpif_netlink_set_ice_status, + dpif_netlink_get_ice_status }; static int diff --git a/lib/dpif-provider.h b/lib/dpif-provider.h index 1d82a0939..d2582418a 100644 --- a/lib/dpif-provider.h +++ b/lib/dpif-provider.h @@ -456,6 +456,14 @@ struct dpif_class { * zero. */ int (*meter_del)(struct dpif *, ofproto_meter_id meter_id, struct ofputil_meter_stats *, uint16_t n_bands); + + /* Set / clear the 'ice' status of the 'dpif'. If this is set to 'true' + * the ice flag will stop any deletion or purging of flows from the flow + * tables which are implemented by 'dpif'. */ + int (*set_ice_status)(struct dpif *, bool ice); + + /* Get the 'ice' status of the 'dpif'. */ + bool (*get_ice_status)(const struct dpif *); }; extern const struct dpif_class dpif_netlink_class; diff --git a/lib/dpif.c b/lib/dpif.c index 310dec146..202670055 100644 --- a/lib/dpif.c +++ b/lib/dpif.c @@ -1953,3 +1953,25 @@ dpif_meter_del(struct dpif *dpif, ofproto_meter_id meter_id, } return error; } + +int +dpif_set_ice_status(struct dpif *dpif, bool ice) +{ + int error = EOPNOTSUPP; + + if (dpif->dpif_class->set_ice_status) { + error = dpif->dpif_class->set_ice_status(dpif, ice); + } + + return error; +} + +bool +dpif_get_ice_status(struct dpif *dpif) +{ + if (dpif->dpif_class->get_ice_status) { + return dpif->dpif_class->get_ice_status(dpif); + } + + return false; +} diff --git a/lib/dpif.h b/lib/dpif.h index ab898f4be..539bda71e 100644 --- a/lib/dpif.h +++ b/lib/dpif.h @@ -871,6 +871,8 @@ int dpif_meter_del(struct dpif *, ofproto_meter_id meter_id, struct ofputil_meter_stats *, uint16_t n_bands); /* Miscellaneous. */ +int dpif_set_ice_status(struct dpif *, bool ice); +bool dpif_get_ice_status(struct dpif *); void dpif_get_netflow_ids(const struct dpif *, uint8_t *engine_type, uint8_t *engine_id); From patchwork Fri Jan 12 19:19:35 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aaron Conole X-Patchwork-Id: 860156 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zJCJR50W0z9sBd for ; Sat, 13 Jan 2018 06:20:39 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id CF850E9E; Fri, 12 Jan 2018 19:19:43 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 84D19E37 for ; Fri, 12 Jan 2018 19:19:40 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id CC52E477 for ; Fri, 12 Jan 2018 19:19:38 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 5C4D8C04AC49 for ; Fri, 12 Jan 2018 19:19:38 +0000 (UTC) Received: from dhcp-25.97.bos.redhat.com (unknown [10.18.25.61]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0DB10189F9 for ; Fri, 12 Jan 2018 19:19:37 +0000 (UTC) From: Aaron Conole To: dev@openvswitch.org Date: Fri, 12 Jan 2018 14:19:35 -0500 Message-Id: <20180112191935.1589-3-aconole@redhat.com> In-Reply-To: <20180112191935.1589-1-aconole@redhat.com> References: <20180112191935.1589-1-aconole@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Fri, 12 Jan 2018 19:19:38 +0000 (UTC) X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [RFC 2/2] rhel: tell ovsctl to freeze the datapath X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org This commit uses the previous to stop it from deleting active flows in the datapath. Signed-off-by: Aaron Conole --- rhel/usr_lib_systemd_system_ovs-vswitchd.service.in | 2 +- utilities/ovs-ctl.in | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/rhel/usr_lib_systemd_system_ovs-vswitchd.service.in b/rhel/usr_lib_systemd_system_ovs-vswitchd.service.in index c6d9aa1b8..4c0703b23 100644 --- a/rhel/usr_lib_systemd_system_ovs-vswitchd.service.in +++ b/rhel/usr_lib_systemd_system_ovs-vswitchd.service.in @@ -23,7 +23,7 @@ ExecStart=/usr/share/openvswitch/scripts/ovs-ctl \ start $OPTIONS ExecStop=/usr/share/openvswitch/scripts/ovs-ctl --no-ovsdb-server stop ExecReload=/usr/share/openvswitch/scripts/ovs-ctl --no-ovsdb-server \ - --no-monitor --system-id=random \ + --no-monitor --system-id=random --freeze-datapath \ --ovs-user=${OVS_USER_ID} \ restart $OPTIONS TimeoutSec=300 diff --git a/utilities/ovs-ctl.in b/utilities/ovs-ctl.in index f1b01d1d3..3e02613eb 100755 --- a/utilities/ovs-ctl.in +++ b/utilities/ovs-ctl.in @@ -306,6 +306,9 @@ ovs_save () { } save_flows_if_required () { + if test X"$FREEZE_DATAPATH" != Xyes; then + action "Freezing datapath" ovs-appctl dpctl/datapath-icing system@ovs-system enabled + fi if test X"$DELETE_BRIDGES" != Xyes; then action "Saving flows" ovs_save save-flows "${script_flows}" fi @@ -494,6 +497,7 @@ set_defaults () { DELETE_BRIDGES=no DELETE_TRANSIENT_PORTS=no + FREEZE_DATAPATH=no DAEMON_CWD=/ FORCE_COREFILES=yes