summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorVictor Nogueira <victor@mojatatu.com>2023-04-26 15:19:40 +0000
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-05-17 11:11:48 +0200
commitdda56b10a4472eac3176ee87d1aeb7250c9d57af (patch)
tree0957e755cb97df73da896d9ec6ba75d4d3a76ae7 /net
parentf5548a4589e30a7bcf39bc379458f802bf3c23bb (diff)
downloadlinux-dda56b10a4472eac3176ee87d1aeb7250c9d57af.tar.gz
linux-dda56b10a4472eac3176ee87d1aeb7250c9d57af.tar.bz2
linux-dda56b10a4472eac3176ee87d1aeb7250c9d57af.zip
net/sched: act_mirred: Add carrier check
[ Upstream commit 526f28bd0fbdc699cda31426928802650c1528e5 ] There are cases where the device is adminstratively UP, but operationally down. For example, we have a physical device (Nvidia ConnectX-6 Dx, 25Gbps) who's cable was pulled out, here is its ip link output: 5: ens2f1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN mode DEFAULT group default qlen 1000 link/ether b8:ce:f6:4b:68:35 brd ff:ff:ff:ff:ff:ff altname enp179s0f1np1 As you can see, it's administratively UP but operationally down. In this case, sending a packet to this port caused a nasty kernel hang (so nasty that we were unable to capture it). Aborting a transmit based on operational status (in addition to administrative status) fixes the issue. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Acked-by: Jamal Hadi Salim <jhs@mojatatu.com> Signed-off-by: Victor Nogueira <victor@mojatatu.com> v1->v2: Add fixes tag v2->v3: Remove blank line between tags + add change log, suggested by Leon Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'net')
-rw-r--r--net/sched/act_mirred.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c
index dcfaa4f9c7c5..0a032c4d26b8 100644
--- a/net/sched/act_mirred.c
+++ b/net/sched/act_mirred.c
@@ -181,7 +181,7 @@ static int tcf_mirred(struct sk_buff *skb, const struct tc_action *a,
goto out;
}
- if (unlikely(!(dev->flags & IFF_UP))) {
+ if (unlikely(!(dev->flags & IFF_UP)) || !netif_carrier_ok(dev)) {
net_notice_ratelimited("tc mirred to Houston: device %s is down\n",
dev->name);
goto out;