From d5049202d46f906b2de83efa8e27ac1844a684b4 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Mon, 5 Oct 2026 11:30:56 -0400 Subject: [PATCH] MT#66221 support loop detection in kernel Closes #2175 Change-Id: Ib7bf569a21bff407c427ffed1d9e64a0046463d0 --- daemon/media_socket.c | 1 + kernel-module/common.c | 1 + kernel-module/nft_rtpengine.c | 27 +++++++++++++++++++++++++++ kernel-module/nft_rtpengine.h | 1 + 4 files changed, 30 insertions(+) create mode 100644 kernel-module/common.c diff --git a/daemon/media_socket.c b/daemon/media_socket.c index 71bd7f30f..2a87dadef 100644 --- a/daemon/media_socket.c +++ b/daemon/media_socket.c @@ -1600,6 +1600,7 @@ static const char *kernelize_target(kernelize_state *s, struct packet_stream *st reti->dtls = MEDIA_ISSET(media, DTLS); reti->non_forwarding = s->non_forwarding ? 1 : 0; reti->blackhole = s->blackhole ? 1 : 0; + reti->loop_protect = MEDIA_ISSET(media, LOOP_CHECK) ? 1 : 0; reti->rtp_stats = (rtpe_config.measure_rtp || MEDIA_ISSET(media, RTCP_GEN) || (mqtt_publish_scope() != MPS_NONE)) ? 1 : 0; diff --git a/kernel-module/common.c b/kernel-module/common.c new file mode 100644 index 000000000..46cce38a4 --- /dev/null +++ b/kernel-module/common.c @@ -0,0 +1 @@ +#include "common.inc" diff --git a/kernel-module/nft_rtpengine.c b/kernel-module/nft_rtpengine.c index 601491e93..24a24697c 100644 --- a/kernel-module/nft_rtpengine.c +++ b/kernel-module/nft_rtpengine.c @@ -46,6 +46,7 @@ #endif #include "nft_rtpengine.h" +#include "common.h" // fix for older compilers #ifndef RHEL_RELEASE_VERSION @@ -356,6 +357,10 @@ struct rtpengine_target { struct re_crypto_context decrypt_rtp; struct re_crypto_context decrypt_rtcp; +#if RTP_LOOP_PROTECT + struct loop_protector loop_protector; +#endif + rwlock_t outputs_lock; struct rtpengine_output *outputs; unsigned int outputs_unfilled; // only ever decreases @@ -1923,6 +1928,8 @@ static int proc_list_show(struct seq_file *f, void *v) { seq_printf(f, " non-forwarding"); if (g->target.blackhole) seq_printf(f, " blackhole"); + if (g->target.loop_protect) + seq_printf(f, " loop-protect"); if (g->target.rtp_stats) seq_printf(f, " RTP-stats"); if (g->target.track_ssrc) @@ -7109,6 +7116,10 @@ static void rtpe_pull_trim(struct sk_buff *skb, unsigned int datalen) { } +#define dbg_int(...) log_err(__VA_ARGS__) +#include "common.inc" + + static int rtpengine46(struct sk_buff *oskb, struct rtpengine_table *t, struct re_address *src, struct re_address *dst, uint8_t in_tos) @@ -7204,6 +7215,22 @@ static int rtpengine46(struct sk_buff *oskb, goto out_target; // pass to userspace } +#if RTP_LOOP_PROTECT + if (g->target.loop_protect) { + spin_lock_irqsave(&g->ssrc_stats_lock, flags); + + bool lp = loop_detect(&g->loop_protector, data, datalen, packet_ts); + + spin_unlock_irqrestore(&g->ssrc_stats_lock, flags); + + if (!lp) { + errstr = "duplicate packet (loop protection)"; + nf_action = NF_DROP; + goto out_error; + } + } +#endif + // RTP processing rtp.ok = 0; rtp.rtcp = 0; diff --git a/kernel-module/nft_rtpengine.h b/kernel-module/nft_rtpengine.h index ffde11345..b6772c5ee 100644 --- a/kernel-module/nft_rtpengine.h +++ b/kernel-module/nft_rtpengine.h @@ -149,6 +149,7 @@ struct rtpengine_target_info { pt_filter:1, non_forwarding:1, // empty src/dst addr blackhole:1, + loop_protect:1, rtp_stats:1; // requires SSRC and clock_rates to be set };