WOL and vlans

Since putting my home computers, raspberry pi/HA, and IOTs on different vlans, WOL no longer works. Is there something I can open up on my computer vlan so it can receive a magic packet from HA without destroying the safety of the vlan separation?

I do have some computers on the same vlan that are on all of the time that I could use to “wake” the other computers but I really like having automations all in the same place.

Are you routing between vlans? If A can ping B then WOL should work. Start there and move forward.

WOL requires the use of broadcast, as after the mac address times out from the switches mac cache, it will no longer deliver. Therefore you need to support broadcasting into remote VLANs, which on lot of network equipment is a security risk, and therefore disabled.

In the Cisco world, you’d be enabling ip directed-broadcast, and you would send the WoL packet to the broadcast address of the remote network (e.g. for a /24, x.x.x.255).

If its an unmanaged switch, you probably have no chance of getting this working in this way. As I run core, I just gave HA an interface in multiple VLANs and use that to WoL through the locally connected interface.

A WoL magic packet is not just a broadcast packet, so you need special forwarders/helpers for that packet type.

For WOL to work, your router must know the MAC address of the device you are turning on, otherwise it cannot route the packet to the correct LAN. Look into your router’s settings for anything related to static MAC assignment (in OpenWRT this is done in file /etc/ethers).

It’s a managed switch — it has VLANs.

But yeah, static MAC assignment on the switch + any intervening routers, is the only other way to do it.

1 Like

Also consider using an ESP device + ESPHome to turn power on electronically. Or put the ESP device in the same VLAN and use its power to send WOL packets from it by invoking its service from HA — presto, issue solved.

No, your device sending the magic packet must know it.

Static MAC assignment isnt required, you use a broadcast packet to a remote network, and it sends it to all ports. Use to do this with Cisco gear all the time.

Taken from Wake-on-LAN - Wikipedia

Subnet directed broadcasts

A principal limitation of standard broadcast Wake-on-LAN is that broadcast packets are generally not routed. This prevents the technique being used in larger networks or over the Internet. Subnet-directed broadcasts (SDBs)[9][10] may be used to overcome this limitation. SDB may require changes to the intermediate router configuration. SDBs are treated like unicast network packets until processed by the final (local) router. This router then broadcasts the packet using a layer-2 broadcast. This technique allows a broadcast to be initiated on a remote network but requires all intervening routers to forward the SDB.[11][12] When preparing a network to forward SDB packets, care must be taken to filter packets so that only desired (e.g. WoL) SDB packets are permitted – otherwise the network may become a participant in DDoS attacks such as the Smurf attack.[13]

Not the full truth in this scenario. In a scenario where the WOL packet must traverse multiple IPv4 segments (e.g. the packet is directed to a specfiic IP in another LAN rather than broadcast) the router must also know the MAC of the device that will get the packet. If not, then the router drops the packet. The sender must also know the MAC address of course, but that is because the MAC will apperr as part of the packet payload.

(Needless to say, routers drop broadcast packets directed to other LANs. Hence why the directed IPv4 technique must be used for WOL to reach other LANs. this avoids needing the subnet-directed broadcast technique and attendant hardware / net config.)

To avoid this network bullshit, the most expedient solution remains an ESP on the target LAN that can be commanded by HA to send the WOL messages.

The most basic magic packet is only a bit over 100 bytes long and have no IP information and no payload.
It has ff:ff:ff:ff:ff:ff as recipient address followed by a distinct part of the MAC address on the device that should be woken up.
It is optional to add a payload and it is mostly used for the wake pattern superset.

If a router just forward the most basic magic packet as a broadcast packet with a helper/forwarder, then the distinct part of MAC address added after the ff:ff:ff… might be lost in the rewriting of the header.

Router will not forward broadcast packets.

That’s why you need that Cisco trick mentioned here, or a unicast packet plus a static MAC assignment on the router that serves the target machine (so the machine knows to send the packet to that box’s MAC address).

The magic that makes the target box turn on is not in the Ethernet or IP header — it is in the content of the packet. As long as the packet payload makes it to the NIC, the NIC will signal the mobo to wake up.

True.
I have updated my text, so it explicitly states that this goes for routers with helpers/forwarders for broadcast packets.
The helper/forwarder needs to be tailored specifically for magic packets.

1 Like

FYI you can forward WOL packets using socat on Linux routers and it works great. Useful when you have networks that are connected by a layer 3 router or a point-to-point link or behind a proxy ARP node (very common in certain types of VM setup). Here’s a sample you’d install on the router:

broadcastip=192.168.1.255
/usr/bin/socat UDP4-RECVFROM:9,fork UDP4-SENDTO:$broadcastip:9,broadcast

My SaltStack recipe to make this a service:

#!objects

from salt://lib/qubes.sls import template, physical

bcast_ip = "192.168.1.255"

if template():

    p = Pkg.installed("socat").requisite
    f = File.managed(
        "/etc/systemd/system/wol-forwarder.service",
        contents=f"""
[Unit]
Description=Forward WOL packets

[Service]
Type=simple
ExecStart=/usr/bin/socat UDP4-RECVFROM:9,fork UDP4-SENDTO:{bcast_ip}:9,broadcast

[Install]
WantedBy=multi-user.target
""".strip(),
        require=[p]
    ).requisite
    Qubes.enable_dom0_managed_service("wol-forwarder", require=[f])

else:
    Service.running("wol-forwarder")

Never tried it with socat, but the same goes.
If the distinct address part is only present in the header, then the forwarder needs to preserve this part, which a normal broadcast forwarder normally do not.
Testing with a random device does not really say if it works or not generally.
The test should be done with the most basic magic packet. If it works with that type, then the ones with more information attached should work also.
If you test with a magic packet with more attached information, then it might work for you, but the next user that have a more basic magic packet might fail with same setup.