How to filter uplinks from non-owned devices on ChirpStack Gateway Mesh (to comply with EU868 Duty Cycle)

Viewed 108

Hi everyone,

I'm currently running a private LoRaWAN network based on ChirpStack.
My setup includes several gateways connected through ChirpStack Gateway Mesh, with one border gateway connected to the Network Server and multiple mesh relay gateways forwarding uplinks through the mesh network.

Everything works correctly — however, I have a major issue regarding duty-cycle compliance.

The mesh relay gateways are currently forwarding uplinks from end-devices that are not part of my network (e.g. packets from other nearby LoRaWAN devices in the area).
This causes unnecessary radio transmissions between gateways and can easily lead to overuse of the EU868 ISM band and violation of the ETSI duty-cycle limit.

What I want to achieve

I would like to configure my mesh gateways so that they only forward uplinks from my own devices — ideally filtered by:

DevAddr (for ABP devices), or

JoinEUI / DevEUI (for OTAA devices)

What I have tried :

I attempted to filter on the border gateway (MQTT forwarder) using DevAddr filters — this works at MQTT level but not at the mesh level (the mesh relays still forward all uplinks).

I also tried to define filters in the mesh configuration TOML (e.g., [filters] dev_addr = [...]), but this did not seem to have any effect on the relay gateways.

My gateways run:

RAK7289v2

ChirpStack Gateway OS 4.8.1

ChirpStack Gateway Mesh 4.1.0

LuCI (OpenWrt 24.10)

My question

Is there a way to:

Filter uplinks at the mesh relay level, so that only uplinks from specific devices (or DevAddr ranges) are forwarded,

Or alternatively, extend chirpstack-gateway-mesh to support a "trusted device" or "DevAddr" filtering mechanism similar to the LoRaWAN Relay Specification?

I'm looking for the best technical approach (configuration, patch, or roadmap feature) to ensure my gateways only forward traffic from my own end-devices to stay compliant with ETSI Duty Cycle regulations.

Any guidance, ideas, or examples would be greatly appreciated 🙏

Thanks a lot for your help!

4 Answers

While this has been implemented (https://github.com/chirpstack/chirpstack-gateway-mesh/blob/master/src/config.rs#L68), this feature hasn't been documented yet and it and the filter configuration hasn't been integrated yet in the ChirpStack Gateway OS. Would you mind creating a GitHub issue to request this implementation? Or even better create a PR :)

This is the proper repo to create an issue for this:
https://github.com/chirpstack/chirpstack-openwrt-feed/

EDIT: This has been implemented in https://github.com/chirpstack/chirpstack-openwrt-feed/commit/0d905e23ecab022ba1fbc0f14e1f621cd291ef30 and is part of the v4.9.0-test.1.

Hello,
Thank you for your quick response and for integrating the request.
We will be testing v4.9.0-test.1 this week

Would you like me to creating a GitHub issue or it is not useful ?

Hello everyone,

First of all, thank you very much for implementing the filters for gateway-mesh on October 14th (v4.9.0-test).

I. Gateway-mesh filter problem

However, there seems to be an issue with their functionality. I noticed that even when configuring a filter, all packets continue to pass through without distinction.
Inspecting the source code, specifically the backend.rs (https://github.com/chirpstack/chirpstack-gateway-mesh/blob/master/src/backend.rs#L306) file at line 307, it seems that a return Ok(()); statement is missing after applying the filter. This could explain why the filtering isn't effective. Has anyone else encountered this issue?
source_code

II. Improvement suggestion

Also, I have a suggestion regarding filtering. Would it be possible to add an option to automatically filter DevAddrs that are not provisioned on the LNS?
Currently, to avoid relaying packets from nodes that don't belong to me, the main solution is to use a different NetID. However, being able to stay to shared NetIDs (0x00 or 0x01) while ignoring unknown devices would be extremely useful for reducing network traffic unnecessarily relayed by the mesh.

III. Increase LOG LEVEL

I would like to increase the log level of the chirpstack-gateway-mesh service for testing.
Is there an official way to set the log level to DEBUG (through configuration or runtime parameter)?
Or is this log level not supported by the binary?

Thank you in advance for your time and help!

Regarding changing the log level, there are a couple of ways you can do this. The temporary method is to

vi /var/etc/chirpstack-gateway-mesh/chirpstack-gateway-mesh.toml

under [logging] add your level:
level="debug"

(Note that it is not log_level here.)
Then save, kill the current chirpstack-gateway-mesh function, and it should respawn with the changes. Don't restart it, otherwise it will regenerate the toml file and you'll lose the edits.

The more permanent method is to add it as a uci setting:

uci set chirpstack-gateway-mesh.global.log_level='debug'
uci commit

Then edit your /etc/init.d/chirpstack-gateway-mesh init script so that the start_service section reads it from uci:

start_service() {
	[ "$(uci get $PACKAGE_NAME.@global[0].enabled)" != "1" ] && return 1

        # --- NEW: read log level from UCI, default to 'info'
        local level
        level="$(uci -q get $PACKAGE_NAME.@global[0].log_level || echo info)"


	configuration

	procd_open_instance
	procd_set_param command /usr/bin/chirpstack-gateway-mesh -c /var/etc/$PACKAGE_NAME/chirpstack-gateway-mesh.toml -c /var/etc/$PACKAGE_NAME/region.toml

	procd_set_param env RUST_LOG="$level" RUST_BACKTRACE=1
	procd_set_param respawn 3600 5 -1
	procd_set_param file /etc/config/$PACKAGE_NAME
	procd_close_instance
}

Then save and restart the script and check your log levels:

/etc/init.d/chirpstack-gateway-mesh restart