netflector available as plugin (mDNS, SSDP, DIAL, WSD, WoL reflector)

Started by UnicronHD, August 13, 2026, 02:44:16 PM

Previous topic - Next topic
Thanks both. I completely agree about avoiding a generic "Swiss army knife" with lots of special cases. That wasn't really what I had in mind either.

My suggestion was specifically a dedicated Roon/SOOD reflector, but only if the protocol fits cleanly within Netflector's existing model of explicitly supported discovery protocols such as mDNS, SSDP and WSD.

I mentioned the source-IP and WireGuard/roadwarrior details mainly so that, if Roon support is investigated, the important part of the use case is known from the start. If implementing that would require too many Roon-specific exceptions, keeping a dedicated tool such as udp-proxy-2020 or RoonBroadcastRelay is of course perfectly reasonable.

If it does fit, I'd be happy to test a development version on OPNsense with Roon across a WireGuard roadwarrior connection.
Deciso DEC850v2

Quote from: Monviech (Cedrik) on September 01, 2026, 06:40:25 PMCareful that you don't accumulate too many edge cases and turning it into an unmaintainable swiss army knife without a clear identity.

Thanks for the insight. I will definitely get familiar with the Roon/RAAT before making a decision. So far, everything netflector supports (except WSD) is something I actually use in my setup. WSD was added mostly because of its similarity to what I had already implemented by then.

Quote from: franco on September 01, 2026, 01:48:45 PMCan you create a PR for https://github.com/opnsense/ports preferably under opnsense/netreflector to avoid clashing with an eventual FreeBSD inclusion? The files can stay the same, but so we know it's out of tree.

Done: https://github.com/opnsense/ports/pull/286.

Quote from: RamSense on September 01, 2026, 05:46:59 PMWould you consider adding dedicated support for Roon discovery (SOOD/RAAT discovery) as an additional reflector type?

I have read a bit about SOOD discovery protocol. There are a few differences from existing protocols, but I still feel like it's a good match. Differences:

  • We need to preserve source IPs. This is easy because netflector already uses raw BPF devices for all UDP traffic.
  • There are 3 types of devices involved: remotes, server and outputs. Discovery would need to happen for remotes -> server and for server -> outputs. Potentially, all three could be in separate VLANs. For now, I think it would require two reflector entries.

Regarding your specific setup with blackjack and VPNs: I don't think we need to implement anything specific for that to work. If remotes are connected via VPN, that VPN interface would just be a source_if in the entry responsible for remote -> server discovery. I don't think that netflector needs to be aware of anything VPN-specific.

There is also the question of unicast responses. For SSDP and WSD netflector proxies these responses. For SOOD, I'm not yet sure what would be the best approach. The normal discovery flow is not a problem: remote sends "Q", server responds with "R". We can proxy the unicast response fine here, just use netflector's source IP/port when relaying "Q" to the server. However, it looks like "Q" does not necessarily mean Query. Output devices also send "Q" messages to server, which are not discovery queries. For these there is no unicast response, server connects directly to output device instead. So this "Q" must be relayed with the preserved IP/port. Naive solution here would be to not relay unicast responses and always preserve source IP/port for all relayed SOOD packets. This will require allowing UDP unicast packets from server back to remote (and from output back to server) in firewall. In your case you should probably already have that configured.

Thanks for looking into this in more detail. This sounds very promising.

I had a closer look at how udp-proxy-2020 actually handles this, since it is already proven to work with Roon across routed networks and VPN connections.

As far as I can see, udp-proxy-2020 does not implement any SOOD-aware query/response proxying and does not interpret the SOOD payload. It captures the configured UDP traffic and reinjects it onto the other interfaces while preserving the original source IP and UDP source/target ports.

So I think your "naive" solution may actually be the right model for SOOD: preserve the original endpoint and let subsequent unicast communication use normal routing, rather than making Netflector part of that unicast conversation.

That also seems to fit the output-device case you mentioned. Netflector would not need to decide whether a "Q" semantically represents a discovery query from a Remote or an announcement/discovery packet from an output device. It can simply relay the SOOD packet while preserving its original source identity.

There is another detail which seems relevant to your question about unicast responses. Aaron Turner's Roon Wireshark dissector indicates that, besides the normal Roon Server discovery on UDP/9003, there is also a Roon Discovery service where replies may originate from an ephemeral UDP port and the dissector therefore uses conversation tracking. To me that is another argument in favour of preserving the original source IP and port rather than introducing SOOD-specific response translation.

One implementation detail from udp-proxy-2020 may also be worth keeping in mind. In addition to BPF capture/injection it opens a normal UDP listener on the configured port and discards anything received there. That was added because ICMP Port Unreachable responses could otherwise cause problems for Roon clients, particularly iOS clients over VPN. I don't know whether that will be relevant to Netflector on OPNsense, but it seems worth being aware of when testing a first implementation.

So I would definitely start with the simple source-IP/source-port preserving model. If you build an initial SOOD implementation that way, I would be very happy to test it with Roon Remote over WireGuard and also with the Roon server/output side.
Deciso DEC850v2