From patchwork Fri May 15 07:17:47 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 1290912 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.133; helo=hemlock.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ovn.org Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 49Nfry42xjz9sT8 for ; Fri, 15 May 2020 17:18:23 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id E8269899B0; Fri, 15 May 2020 07:18:21 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id qOdvK5K+GtBY; Fri, 15 May 2020 07:18:17 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by hemlock.osuosl.org (Postfix) with ESMTP id 7A0CC89928; Fri, 15 May 2020 07:18:17 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 54A8EC0859; Fri, 15 May 2020 07:18:17 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by lists.linuxfoundation.org (Postfix) with ESMTP id 9CA6DC016F for ; Fri, 15 May 2020 07:18:15 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id 92E7A88395 for ; Fri, 15 May 2020 07:18:15 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from whitealder.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id jog4v73RQnbg for ; Fri, 15 May 2020 07:18:11 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [217.70.183.193]) by whitealder.osuosl.org (Postfix) with ESMTPS id F023E8813E for ; Fri, 15 May 2020 07:18:10 +0000 (UTC) X-Originating-IP: 216.113.160.71 Received: from localhost.localdomain.localdomain (unknown [216.113.160.71]) (Authenticated sender: hzhou@ovn.org) by relay1-d.mail.gandi.net (Postfix) with ESMTPSA id 83949240002; Fri, 15 May 2020 07:18:05 +0000 (UTC) From: Han Zhou To: dev@openvswitch.org Date: Fri, 15 May 2020 00:17:47 -0700 Message-Id: <1589527067-91901-1-git-send-email-hzhou@ovn.org> X-Mailer: git-send-email 2.1.0 Cc: Han Zhou Subject: [ovs-dev] [PATCH] odp-util.c: Fix dp_hash execution with slowpath actions. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" When dp_hash is executed with slowpath actions, it results in endless recirc loop in kernel datapath, and finally drops the packet, with kernel logs: openvswitch: ovs-system: deferred action limit reached, drop recirc action The root cause is that the dp_hash value calculated by slowpath is not passed to datapath when executing the recirc action, thus when the recirced packet miss upcall comes to userspace again, it generates the dp_hash and recirc action again, with same recirc_id, which in turn generates a megaflow with recirc action with the recird_id same as the recirc_id in its match condition, which causes a loop in datapath. For example, this can be reproduced with below setup of OVN environment: LS1 LS2 | | |------R1------| VIF--LS0---R0-----| |------R3 |------R2------| Assume there is a route from the VIF to R3: R0 -> R1 -> R3, and there are two routes (ECMP) from R3 to the VIF: R3 -> R1 -> R0 R3 -> R2 -> R0 Now if we ping from the VIF to R3, the OVS flow execution on the HV of the VIF will hit the R3's datapath which has flows that responds to the ICMP packet by setting ICMP fields, which requires slowpath actions, and in later flow tables it will hit the "group" action that selects between the ECMP routes. By default OVN uses "dp_hash" method for the "group" action. For the first miss upcall packet, dp_hash value is empty, so the group action will be translated to "dp_hash" and "recirc". During action execution, because of the previous actions that sets ICMP fields, the whole execution requires slowpath, so it tries to execute all actions in userspace in odp_execute_actions(), including dp_hash action, except the recirc action, which can only be executed in datapath. So the dp_hash value is calculated in userspace, and then the packet is injected to datapath for recirc action execution. However, the dp_hash calculated by the userspace is not passed to datapath. Because of this, the packet recirc in datapath doesn't have dp_hash value, and the miss upcall for the recirced packet hits the same flow tables and triggers same "dp_hash" and "recirc" action again, with exactly same recirc_id! This time, the new upcall doesn't require any slowpath execution, so both the dp_hash and recirc actions are executed in datapath, after creating a datapath megaflow like: recirc_id(XYZ),..., actions:hash(l4(0)),recirc(XYZ) with match recirc_id equals the recirc id in the action, thus creating a loop. This patch fixes the problem by passing the calculated dp_hash value to datapath in odp_key_from_dp_packet(). Signed-off-by: Han Zhou Tested-by: Aliasgar Ginwala --- lib/odp-util.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/odp-util.c b/lib/odp-util.c index b66d266..ac532fe 100644 --- a/lib/odp-util.c +++ b/lib/odp-util.c @@ -6392,6 +6392,10 @@ odp_key_from_dp_packet(struct ofpbuf *buf, const struct dp_packet *packet) nl_msg_put_u32(buf, OVS_KEY_ATTR_PRIORITY, md->skb_priority); + if (md->dp_hash) { + nl_msg_put_u32(buf, OVS_KEY_ATTR_DP_HASH, md->dp_hash); + } + if (flow_tnl_dst_is_set(&md->tunnel)) { tun_key_to_attr(buf, &md->tunnel, &md->tunnel, NULL, NULL); }