Relay multicast and broadcast packets between network interfaces on OpenWrt — allowing device discovery (mDNS, SSDP, Sonos) to work across isolated VLANs without routing traffic between them.
Based on alsmith/multicast-relay.
When you isolate IoT devices on a separate VLAN/bridge (e.g. br-iot) they can no longer be discovered by devices on your main LAN (br-lan). This script selectively relays discovery protocols between bridges so your phone can find smart speakers, printers, and Chromecasts — without giving IoT devices full LAN access.
| Protocol | Address | Port | Purpose |
|---|---|---|---|
| mDNS | 224.0.0.251 | 5353 | AirPlay, Chromecast, printer discovery |
| SSDP | 239.255.255.250 | 1900 | UPnP device discovery |
| Sonos Discovery | 255.255.255.255 | 1900, 6969 | Sonos speaker discovery |
Additional multicast/broadcast addresses can be added with --relay A.B.C.D:PORT.
After an OpenWrt upgrade, clone or copy this repo to the router and run:
./install.shThis copies the script and service file into place, enables the service for boot, and starts it immediately.
To remove:
./uninstall.sh- Copies
multicast-relay.pyto/usr/bin/multicast-relay.py - Copies
serviceto/etc/init.d/multicast-relay - Makes both executable
- Enables and starts the procd service
The service file (service) contains the runtime flags. Edit it to match your network:
procd_set_param command python3 "$SCRIPT" \
--interfaces br-iot br-lan \
--noQueryInterfaces br-iot \
--ssdpUnicastAddr 192.168.10.1 \
--masquerade br-iot \
--noAdvertiseInterfaces br-iot \
--verbose \
--foreground| Flag | Purpose |
|---|---|
--interfaces br-iot br-lan |
Bridges to relay between |
--noQueryInterfaces br-iot |
Don't forward mDNS/SSDP queries originating from IoT |
--ssdpUnicastAddr 192.168.10.1 |
Router IP for SSDP unicast response relay |
--masquerade br-iot |
Rewrite source IP on packets sent to IoT so replies come back to the router |
--noAdvertiseInterfaces br-iot |
Don't relay mDNS advertisements (responses) to IoT |
This configuration lets LAN devices discover IoT devices, but not the reverse.
/etc/init.d/multicast-relay start
/etc/init.d/multicast-relay stop
/etc/init.d/multicast-relay restart
/etc/init.d/multicast-relay enable # start on boot
/etc/init.d/multicast-relay disable # don't start on bootCheck logs:
logread | grep multicast-relay--interfaces IF [IF ...] Interfaces to relay between (minimum 2)
--noTransmitInterfaces IF Listen-only interfaces (don't send packets out)
--noQueryInterfaces IF Don't relay queries from these interfaces
--noAdvertiseInterfaces IF Don't relay mDNS advertisements to these interfaces
--ifFilter FILE JSON file mapping source IPs to allowed relay interfaces
--ssdpUnicastAddr IP Relay SSDP unicast replies back to the querier
--masquerade IF [IF ...] Masquerade (NAT) packets leaving these interfaces
--relay A.B.C.D:PORT Relay additional multicast/broadcast address
--noMDNS Disable mDNS relay
--noSSDP Disable SSDP relay
--noSonosDiscovery Disable Sonos broadcast relay
--mdnsForceUnicast Set unicast-response bit on relayed mDNS queries
--oneInterface Single interface connected to two networks
--wait Wait for interfaces to get an IPv4 address
--ttl N Override TTL on relayed packets
--homebrewNetifaces Use built-in netifaces (no pip dependency)
--allowNonEther Allow non-ethernet interfaces
--listen A.B.C.D [...] Accept remote relay connections from these IPs
--remote A.B.C.D [...] Connect to remote relay instance(s)
--remotePort PORT Port for remote relay (default: 1900)
--remoteRetry N Seconds between remote reconnection attempts (default: 5)
--noRemoteRelay Don't forward remote packets to other remotes
--aes KEY Encrypt remote relay traffic with AES
--k8sport PORT Kubernetes health check endpoint
--foreground Run in foreground (required for procd)
--logfile PATH Log to file
--verbose Verbose logging
The script runs with Python 3 and only uses the standard library. Two optional packages enhance functionality:
- netifaces — network interface detection (has a built-in fallback via
--homebrewNetifaces) - pycryptodome — AES encryption for
--aesremote relay (only needed if using remote relay with encryption)
On OpenWrt, install Python 3:
opkg update && opkg install python3Original script by Al Smith (January 2018).