[PATCH net v2 2/2] bridge: cfm: ignore CCM while CC is disabled
From: Baek Kyu, Kim
Date: Wed Oct 28 2026 - 12:50:49 EST
A valid CCM received after CC is disabled can clear the peer defect
and restart its RX timer. Cancelling pending work does not stop a later
receive from queuing it again. Even with RX work disabled, that receive
can still update peer status and notify userspace.
Keep RX work disabled until CC is explicitly enabled, and skip CCM
processing while CC is disabled. This prevents a later CCM from changing
peer status or restarting RX monitoring.
Fixes: dc32cbb3dbd7 ("bridge: cfm: Kernel space implementation of CFM. CCM frame RX added.")
Signed-off-by: Baek Kyu, Kim <pocj8ur4in@xxxxxxxxx>
---
On ARM64 QEMU/KVM with bridge/veth, a valid CCM after the disable ACK
cleared the peer defect on v1 but left it set on the combined v2 kernel.
Re-enabling CC allowed a valid CCM to clear the defect. All 3 status
checks passed on v2; 2 failed on v1 as expected.
net/bridge/br_cfm.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/net/bridge/br_cfm.c b/net/bridge/br_cfm.c
index 28b40dbf4073..115cccf1d327 100644
--- a/net/bridge/br_cfm.c
+++ b/net/bridge/br_cfm.c
@@ -150,12 +150,13 @@ static void cc_peer_enable(struct br_cfm_peer_mep *peer_mep)
memset(&peer_mep->cc_status, 0, sizeof(peer_mep->cc_status));
peer_mep->ccm_rx_count_miss = 0;
+ enable_delayed_work(&peer_mep->ccm_rx_dwork);
ccm_rx_timer_start(peer_mep);
}
static void cc_peer_disable(struct br_cfm_peer_mep *peer_mep)
{
- cancel_delayed_work_sync(&peer_mep->ccm_rx_dwork);
+ disable_delayed_work_sync(&peer_mep->ccm_rx_dwork);
}
static struct sk_buff *ccm_frame_build(struct br_cfm_mep *mep,
@@ -414,6 +415,9 @@ int br_cfm_frame_rx(struct net_bridge_port *port, struct sk_buff *skb)
if (hdr->opcode == BR_CFM_OPCODE_CCM) {
/* CCM PDU received. */
+ if (!READ_ONCE(mep->cc_config.enable))
+ return 1;
+
/* MA ID is after common header + sequence number + MEP ID */
maid = skb_header_pointer(skb,
CFM_CCM_PDU_MAID_OFFSET,
@@ -699,6 +703,8 @@ int br_cfm_cc_peer_mep_add(struct net_bridge *br, const u32 instance,
peer_mep->mepid = mepid;
peer_mep->mep = mep;
INIT_DELAYED_WORK(&peer_mep->ccm_rx_dwork, ccm_rx_work_expired);
+ /* Keep RX work disabled until CC is enabled. */
+ disable_delayed_work(&peer_mep->ccm_rx_dwork);
if (mep->cc_config.enable)
cc_peer_enable(peer_mep);
--
2.55.0