From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CC1B23769FD; Thu, 30 Jul 2026 15:47:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785426478; cv=none; b=YU8RydPyVRloi6S+O98eOG4mua3vV7cFF/4fRdm5B17/TYlsb+tyciuAm4mkYC8nRbF4/P+RXNTT6UEhnp5OZxLCr0Gvn+lSW7waxTJWUDN5LD3XYMAuXQ13AqWkSMO57htyB8texWkfQcD+ZeGgaQu+v3A1uxZbSL3DdYHL5FQ= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785426478; c=relaxed/simple; bh=gNq88ONT7p4I8FzBQtmn2gkvtxbcK8IMU3f4oaABUs0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=bjBrPFsT55c5zkwgn6wCv477A0SRRmnXwk1j5ByQabBbPZ/hgVSDKhA6xcwgunwhQ6ZA53CftHkPoetXnJsP/ZC2zrWvedoqL9G1Un1G5JIT0blep+w5Op6xaWOPPqHk5fFqQQPONTKn+6NCgJn3aPAMsSMx94EDdedA4/8RGQQ= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=qIb05jwI; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="qIb05jwI" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D88111F000E9; Thu, 30 Jul 2026 15:47:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1785426476; bh=bKETUbwvCmqMCNlOZdqnI0an6XCBen/cEdFfIIztCtQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=qIb05jwI+zdBXWannIvMS0CDYG25YphSB1CLgRqPg7fiTQedA0TlIt8v/g58i9lZN 0jah6WcpmrwyCtUpjJ9FxVeRQess7eHZEN6oTBpUzJ9Gg/FSiFc4cwS743nIn5xeyg 00x28mREK22BQbe7+1JCUL8wqskaZiI6myZ/k2eI= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, James Raphael Tiovalen , Ido Schimmel , Antoine Tenart , Nikolay Aleksandrov , Jakub Kicinski Subject: [PATCH 6.12 434/602] vxlan: mdb: Fix source list corruption on a failed replace Date: Thu, 30 Jul 2026 16:13:46 +0200 Message-ID: <20260730141445.086150394@linuxfoundation.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260730141435.976815864@linuxfoundation.org> References: <20260730141435.976815864@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: patches@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 6.12-stable review patch. If anyone has any objections, please let me know. ------------------ From: James Raphael Tiovalen commit dcd9b465965422b9654f6026e8a2fa8984f74c3c upstream. When replacing the source list of an MDB remote entry, all existing sources are first marked for deletion and vxlan_mdb_remote_srcs_add() is then called to add the new source list. Sources present in the new list have their deletion mark cleared, and any sources left marked afterwards are removed. If vxlan_mdb_remote_srcs_add() fails partway through, its error path deletes all entries on the remote's source list. That rollback is only correct for its other caller, vxlan_mdb_remote_add(), where the remote was just allocated and the list contains solely entries added during the call. On the replace path the list also holds pre-existing sources, so a failed replace tears them down together with their (S, G) forwarding entries instead of leaving the entry unchanged. This is reachable from an existing (*, G) remote. An EXCLUDE filter that loses sources starts forwarding traffic that should be blocked, while an INCLUDE filter that loses sources drops traffic that should be forwarded. Mark entries created during the current pass with a new VXLAN_SGRP_F_NEW flag. On failure, delete only those entries and clear the deletion mark on the pre-existing ones, so a failed replace leaves the source list untouched. Retain the flag until the whole operation succeeds and then clear it. Also stop vxlan_mdb_remote_src_add() from deleting a pre-existing entry it only looked up when adding that entry's forwarding entry fails. Fixes: a3a48de5eade ("vxlan: mdb: Add MDB control path support") Cc: stable@vger.kernel.org Signed-off-by: James Raphael Tiovalen Reviewed-by: Ido Schimmel Reviewed-by: Antoine Tenart Reviewed-by: Nikolay Aleksandrov Link: https://patch.msgid.link/20260720160428.249356-1-jamestiotio@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- drivers/net/vxlan/vxlan_mdb.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) --- a/drivers/net/vxlan/vxlan_mdb.c +++ b/drivers/net/vxlan/vxlan_mdb.c @@ -42,6 +42,7 @@ struct vxlan_mdb_remote { }; #define VXLAN_SGRP_F_DELETE BIT(0) +#define VXLAN_SGRP_F_NEW BIT(1) struct vxlan_mdb_src_entry { struct hlist_node node; @@ -844,6 +845,7 @@ vxlan_mdb_remote_src_add(const struct vx ent = vxlan_mdb_remote_src_entry_add(remote, &src->addr); if (!ent) return -ENOMEM; + ent->flags |= VXLAN_SGRP_F_NEW; } else if (!(cfg->nlflags & NLM_F_REPLACE)) { NL_SET_ERR_MSG_MOD(extack, "Source entry already exists"); return -EEXIST; @@ -853,15 +855,16 @@ vxlan_mdb_remote_src_add(const struct vx if (err) goto err_src_del; - /* Clear flags in case source entry was marked for deletion as part of - * replace flow. + /* Clear the deletion mark so the entry survives the replace sweep. + * The new mark is retained until the whole operation succeeds. */ - ent->flags = 0; + ent->flags &= ~VXLAN_SGRP_F_DELETE; return 0; err_src_del: - vxlan_mdb_remote_src_entry_del(ent); + if (ent->flags & VXLAN_SGRP_F_NEW) + vxlan_mdb_remote_src_entry_del(ent); return err; } @@ -889,11 +892,19 @@ static int vxlan_mdb_remote_srcs_add(con goto err_src_del; } + hlist_for_each_entry(ent, &remote->src_list, node) + ent->flags &= ~VXLAN_SGRP_F_NEW; + return 0; err_src_del: - hlist_for_each_entry_safe(ent, tmp, &remote->src_list, node) - vxlan_mdb_remote_src_del(cfg->vxlan, &cfg->group, remote, ent); + hlist_for_each_entry_safe(ent, tmp, &remote->src_list, node) { + if (ent->flags & VXLAN_SGRP_F_NEW) + vxlan_mdb_remote_src_del(cfg->vxlan, &cfg->group, remote, + ent); + else + ent->flags &= ~VXLAN_SGRP_F_DELETE; + } return err; } @@ -1069,7 +1080,7 @@ vxlan_mdb_remote_srcs_replace(const stru err = vxlan_mdb_remote_srcs_add(cfg, remote, extack); if (err) - goto err_clear_delete; + return err; hlist_for_each_entry_safe(ent, tmp, &remote->src_list, node) { if (ent->flags & VXLAN_SGRP_F_DELETE) @@ -1078,11 +1089,6 @@ vxlan_mdb_remote_srcs_replace(const stru } return 0; - -err_clear_delete: - hlist_for_each_entry(ent, &remote->src_list, node) - ent->flags &= ~VXLAN_SGRP_F_DELETE; - return err; } static int vxlan_mdb_remote_replace(const struct vxlan_mdb_config *cfg,