From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pj1-f42.google.com (mail-pj1-f42.google.com [209.85.216.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 23D173A8734 for ; Thu, 26 Mar 2026 18:17:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.42 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774549073; cv=none; b=L4ksNpXH4GU7vK2ws/aZjJmqrcivLXlbBUfv4P849roSGnS84pZ5fm83HClQmr40LW983oZ+5nQDs+p7zzFA/SWhm7EDQj9PxHXLA0pYiyvqhjaiO7uBG0+ZzvOi4t6N9n7GjTxAahzHLy2slR0VZrfrV3bXkrfPW2fXtb7BxZs= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774549073; c=relaxed/simple; bh=Ovj2Oa/Xx0/i5kgTK1bEvMR8Q57H9OPDgytFvPXI9Rg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Fsxg/E+vsxNGg9pzBMEo1+HQulMSXrt1Bk0d7kIeAqG4txotOfIi0Dfmt7PABpJqOULJ2uRZy2+AGWBy4S27zJ31jyuGm8jGIfgjR2FmgfBVReF1mGdudvrelrZFG0PRhHUnT+hC1DgBynui9Z05GUAbsJTvJ+cZ8xv5FcC2aEo= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=networkplumber.org; spf=pass smtp.mailfrom=networkplumber.org; dkim=pass (2048-bit key) header.d=networkplumber-org.20230601.gappssmtp.com header.i=@networkplumber-org.20230601.gappssmtp.com header.b=q97iVZo9; arc=none smtp.client-ip=209.85.216.42 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=networkplumber.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=networkplumber.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=networkplumber-org.20230601.gappssmtp.com header.i=@networkplumber-org.20230601.gappssmtp.com header.b="q97iVZo9" Received: by mail-pj1-f42.google.com with SMTP id 98e67ed59e1d1-35c1107d4b7so1097066a91.1 for ; Thu, 26 Mar 2026 11:17:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=networkplumber-org.20230601.gappssmtp.com; s=20230601; t=1774549068; x=1775153868; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=7AGIDQzjfRL8P4QWldXUcJASNu3iP9dOlm2OUCKQD7M=; b=q97iVZo9BAAap4BOVJN8d66JjzMRFQmkRl+EeyK5WFjjJJy+7o+8jWrLBrcdDYGjDA VGoVwvnpagQDuilKMksFmE8yYbLClPREmNwIIk2W15jlZF67As3a/SYDEgqe1hw2z+vN LShUH4vLIw1IZAlh+2rzoxx04IC1jpl0UQSgF0K6DWBOZ/eofCs+2JzXttsCe4DQpjhx A1/2DHiCYvezkF4DSQYJ805PCuSXiBDKAt/4+/Axaidu8qI41/wzznyVtvrLjeQHAMu7 mR/0RbJCamako/xFSOnSaYUELNpzBM0Xj7OqP0QgyCz7sHQPsRwVjWMcEn9u3fG7PEIj r0cw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774549068; x=1775153868; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=7AGIDQzjfRL8P4QWldXUcJASNu3iP9dOlm2OUCKQD7M=; b=LYWQ0K2GmnIfhI5twG9B45SGUyq9AiNcKsPM9hG/U0sofCYBn/IduwutREU/M3w8A+ FGBl8bEv88w9KR3YMBHUznyNVnBWkDwumKnCCw6oDhIF+hZjA5KgyhL91V14zaDnXle6 QxqZ37HJnwfN7ntvtNrFJ253T/udDvvsHBI/pjGenp+kzm0DYGfG3O1k+eUtV+65QeQJ LSMjBKC+6Yxr/5MbiVAVsfTCebbsXuFQUZoDjusAJA91uBV3CMRcZPfhngWkw13lVabz FvGrtydr2dAuRXZG6SCiQLUXaLpiIAslrE9PxPrC6Cx6PXpDA6aS/rZJms644JFGliJS lqfA== X-Forwarded-Encrypted: i=1; AJvYcCUuotmLPNCE83Ab8V/ve068rxx8bUj2Kzmr56DJHqqDcso3HoGqRHEcW374l8/Xa0Smp7gW9z7iA8gdons=@vger.kernel.org X-Gm-Message-State: AOJu0Yye0jvxfmyAiy/D+8TKaOm3Mm0YLhpVpHHXIjovd6WMIunMtz84 h1zi5oUmn7oXrbabv7teYFPm0OnEPLZQ6iMmNRRhs7M84u5Ps2JSMA2XIv6pzH+2/FQ= X-Gm-Gg: ATEYQzyoMs0ttqFFavG9q7yU7lOA5YsD7iZLenVumHri/Rwo6ahYsM4XDBwD05Zig65 D9TlBzQErd25o6Cqr1nH2GWkLm1TgryLu7USqMGW/Zc8O6KvumbzzB6eAmXpDKZklWvfJEJhDDY IjlgBewuCsUeaSeWfcq7HVBdjRItJ/JHu/sV7c3aIK6x8Uh0BhkwaUy5/1ux2OwAWCjstycCH0I VHsDEyh/Q9q9hMlOV830+FK8x2aozvUHzA6pFj7hLtYfwnP5Lh3R/hrKcnM4rtWmE3L0U5dNrQz chBqlLM8Qw7wyVwvivPeP76H5pwaELnWn1EAN6tQxOz8as234bPNI4SgGWGc3RLovJcKIN3GGpe ryalaHOIv09gdtyucwDyQSukwEvw9VHQd4D5RXw+qBxbkRHWStuSw1OLmlO3Ls1F3U3d5nExUPz OWpoBqWyNDny5H+MNDMjmd7f8vkEyB6SEh X-Received: by 2002:a17:903:2c7:b0:2ae:593c:48fc with SMTP id d9443c01a7336-2b0b0b2c128mr99486165ad.53.1774549068175; Thu, 26 Mar 2026 11:17:48 -0700 (PDT) Received: from phoenix.lan ([104.202.29.139]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2b0bc8c4bd3sm38590245ad.63.2026.03.26.11.17.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 26 Mar 2026 11:17:47 -0700 (PDT) From: Stephen Hemminger To: netdev@vger.kernel.org Cc: Jamal Hadi Salim , Victor Nogueira , Stephen Hemminger , Jiri Pirko , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= , Kuniyuki Iwashima , linux-kernel@vger.kernel.org (open list) Subject: [PATCH v3 5/7] net/sched: Fix ethx:ingress -> ethy:egress -> ethx:ingress mirred loop Date: Thu, 26 Mar 2026 11:01:04 -0700 Message-ID: <20260326181701.308275-6-stephen@networkplumber.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260326181701.308275-1-stephen@networkplumber.org> References: <20260326181701.308275-1-stephen@networkplumber.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: Jamal Hadi Salim When mirred redirects to ingress (from either ingress or egress) the loop state from sched_mirred_dev array dev is lost because of 1) the packet deferral into the backlog and 2) the fact the sched_mirred_dev array is cleared. In such cases, if there was a loop we won't discover it. Here's a simple test to reproduce: ip a add dev port0 10.10.10.11/24 tc qdisc add dev port0 clsact tc filter add dev port0 egress protocol ip \ prio 10 matchall action mirred ingress redirect dev port1 tc qdisc add dev port1 clsact tc filter add dev port1 ingress protocol ip \ prio 10 matchall action mirred egress redirect dev port0 ping -c 1 -W0.01 10.10.10.10 Fixes: fe946a751d9b ("net/sched: act_mirred: add loop detection") Tested-by: Victor Nogueira Signed-off-by: Jamal Hadi Salim Reviewed-by: Stephen Hemminger --- net/sched/act_mirred.c | 47 +++++++++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index 05e0b14b5773..001dd9275e9b 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c @@ -26,6 +26,10 @@ #include #include +#define MIRRED_DEFER_LIMIT 3 +_Static_assert(MIRRED_DEFER_LIMIT <= 3, + "MIRRED_DEFER_LIMIT exceeds tc_depth bitfield width"); + static LIST_HEAD(mirred_list); static DEFINE_SPINLOCK(mirred_list_lock); @@ -234,12 +238,15 @@ tcf_mirred_forward(bool at_ingress, bool want_ingress, struct sk_buff *skb) { int err; - if (!want_ingress) + if (!want_ingress) { err = tcf_dev_queue_xmit(skb, dev_queue_xmit); - else if (!at_ingress) - err = netif_rx(skb); - else - err = netif_receive_skb(skb); + } else { + skb->tc_depth++; + if (!at_ingress) + err = netif_rx(skb); + else + err = netif_receive_skb(skb); + } return err; } @@ -426,6 +433,7 @@ TC_INDIRECT_SCOPE int tcf_mirred_act(struct sk_buff *skb, struct netdev_xmit *xmit; bool m_mac_header_xmit; struct net_device *dev; + bool want_ingress; int i, m_eaction; u32 blockid; @@ -434,7 +442,8 @@ TC_INDIRECT_SCOPE int tcf_mirred_act(struct sk_buff *skb, #else xmit = this_cpu_ptr(&softnet_data.xmit); #endif - if (unlikely(xmit->sched_mirred_nest >= MIRRED_NEST_LIMIT)) { + if (unlikely(xmit->sched_mirred_nest >= MIRRED_NEST_LIMIT || + skb->tc_depth >= MIRRED_DEFER_LIMIT)) { net_warn_ratelimited("Packet exceeded mirred recursion limit on dev %s\n", netdev_name(skb->dev)); return TC_ACT_SHOT; @@ -453,23 +462,27 @@ TC_INDIRECT_SCOPE int tcf_mirred_act(struct sk_buff *skb, tcf_action_inc_overlimit_qstats(&m->common); return retval; } - for (i = 0; i < xmit->sched_mirred_nest; i++) { - if (xmit->sched_mirred_dev[i] != dev) - continue; - pr_notice_once("tc mirred: loop on device %s\n", - netdev_name(dev)); - tcf_action_inc_overlimit_qstats(&m->common); - return retval; - } - xmit->sched_mirred_dev[xmit->sched_mirred_nest++] = dev; + m_eaction = READ_ONCE(m->tcfm_eaction); + want_ingress = tcf_mirred_act_wants_ingress(m_eaction); + if (!want_ingress) { + for (i = 0; i < xmit->sched_mirred_nest; i++) { + if (xmit->sched_mirred_dev[i] != dev) + continue; + pr_notice_once("tc mirred: loop on device %s\n", + netdev_name(dev)); + tcf_action_inc_overlimit_qstats(&m->common); + return retval; + } + xmit->sched_mirred_dev[xmit->sched_mirred_nest++] = dev; + } m_mac_header_xmit = READ_ONCE(m->tcfm_mac_header_xmit); - m_eaction = READ_ONCE(m->tcfm_eaction); retval = tcf_mirred_to_dev(skb, m, dev, m_mac_header_xmit, m_eaction, retval); - xmit->sched_mirred_nest--; + if (!want_ingress) + xmit->sched_mirred_nest--; return retval; } -- 2.53.0