In the end, I decided to cheat and use socat instead of proper routing (like smcroute) due to the complexities described above. For anyone who is a lazy bones like me, here is my solution:
- Install
socat package.
- Put into
/etc/config/socat:
# Forward SSDP from LAN (br-lan.10) to IoT (br-lan.20)
# NAS DLNA server
config socat 'ssdp_ds2iot'
option enable '1'
list SocatOptions '-d0'
list SocatOptions 'UDP4-RECVFROM:1900,ip-add-membership=239.255.255.250:192.168.10.1,reuseaddr,fork,range=192.168.10.10/32'
list SocatOptions 'UDP4-DATAGRAM:239.255.255.250:1900,interface=br-lan.20'
# Laptop DLNA server
config socat 'ssdp_laptop2iot'
option enable '1'
list SocatOptions '-d0'
list SocatOptions 'UDP4-RECVFROM:1900,ip-add-membership=239.255.255.250:192.168.10.1,reuseaddr,fork,range=192.168.10.30/32'
list SocatOptions 'UDP4-DATAGRAM:239.255.255.250:1900,interface=br-lan.20'
# Forward SSDP from IoT (br-lan.20) to LAN (br-lan.10)
# TV
config socat 'ssdp_iot2lan'
option enable '1'
list SocatOptions '-d0'
list SocatOptions 'UDP4-RECVFROM:1900,ip-add-membership=239.255.255.250:192.168.20.1,reuseaddr,fork,range=192.168.20.20/32'
list SocatOptions 'UDP4-DATAGRAM:239.255.255.250:1900,interface=br-lan.10'
I am not enabling blanket relay of everything, the solution only covers the devices of interest (range option), and only SSDP multicast address/port. It also limits exposure of devices cross-networks (I have other devices I don’t want to be visible on the other side).
Note that the reverse path (from iot to lan) is optional, it is only required to immediately respond to M-SEARCH messages from the client and make discovery faster. Otherwise servers will send NOTIFY message every defined interval and the client will know anyway.
Not very universal, since I hardcode IPs of my equipment, but they are pinned anyway, so it will never break.
Also, the firewall rules are required for socat to see the traffic:
config rule
option src 'lan'
option name 'Allow-SSDP-from-lan'
list proto 'udp'
option target 'ACCEPT'
option dest_port '1900'
list dest_ip '239.255.255.250'
config rule
option src 'iot'
option name 'Allow-SSDP-from-iot'
list proto 'udp'
option target 'ACCEPT'
option dest_port '1900'
list dest_ip '239.255.255.250'
Of course, another set of rules (one per client-server pair) is required to enable actual connection from DLNA client to server. It seems like there is no standard ports for that, and you’d have to discover them if you want to punch port-specific holes only. To find that out, look into LOCATION field in NOTIFY announcements from the server through tcpdump or socat verbose log. After that, it will be trivial to create rules.