Skip to content

Instantly share code, notes, and snippets.

@oliverkurth
Last active May 25, 2024 14:27
Show Gist options
  • Save oliverkurth/0e6dbdf3708b5bd1c69d4d34a648cbdd to your computer and use it in GitHub Desktop.
Save oliverkurth/0e6dbdf3708b5bd1c69d4d34a648cbdd to your computer and use it in GitHub Desktop.
Simultanous AP and managed mode in a Raspberry Pi 3 or Zero using systemd-networkd

Thanks to Albert for the initial hint, see https://blog.thewalr.us/2017/09/26/raspberry-pi-zero-w-simultaneous-ap-and-managed-mode-wifi/

However, I decided to use systemd-networkd instead of /e/n/i, and it seems no ugly workaround is needed.

I have this rule in /etc/udev/rules.d/70-phy.rules :

SUBSYSTEM=="ieee80211", ACTION=="add|change", DRIVERS=="brcmfmac", \
  RUN+="/sbin/iw phy %k interface add ap0 type __ap"

Note the absence of MAC address setting - it's weird, but when the MAC address is set to another value, any client trying to connect to the AP would successfully associate and then disassociate 18 seconds later in an endless cycle.

Additionally I have this rule in /etc/udev/rules.d/80-wpa.rules :

SUBSYSTEM=="net", ACTION=="add", DRIVERS=="brcmfmac", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="wlan*", NAME="sta0"

Strictly this isn't needed, however I intend to optionally add USB WiFi adapters, and this will make the device names predictable.

Interface config for ap0 in /etc/systemd/network/ap0.network :

[Match]
Name=ap0

[Network]
Address=192.168.10.254/24
IPForward=1

and /etc/systemd/network/sta.network

[Match]
Name=sta*

[Network]
DHCP=ipv4
IPForward=1

To start wpa_supplicant, this is the service file /etc/systemd/system/wpa_supplicant@.service :

[Unit]
Description=WPA supplicant daemon (interface-specific version)
Requires=sys-subsystem-net-devices-%i.device
After=sys-subsystem-net-devices-%i.device
BindsTo=sys-subsystem-net-devices-%i.device

[Service]
Type=simple
ExecStart=/sbin/wpa_supplicant -c/etc/wpa_supplicant/wpa_supplicant.conf -i %I

[Install]
Alias=multi-user.target.wants/wpa_supplicant@%I.service
WantedBy=multi-user.target

To start hostapd, /etc/systemd/system/hostapd@.service :

[Unit]
Description=HostAP Daemon
Requires=sys-subsystem-net-devices-%i.device
After=sys-subsystem-net-devices-%i.device
BindsTo=sys-subsystem-net-devices-%i.device

[Service]
Type=simple
ExecStart=/usr/sbin/hostapd /etc/hostapd/hostapd-%I.conf

[Install]
WantedBy=multi-user.target
Alias=multi-user.target.wants/hostapd@%I.service

Both services need to be enabled:

systemctl enable wpa_supplicant@sta0
systemctl enable hostapd@ap0

In any normal AP setup you will have a DHCP server running, and dnsmasq is easy to configure. The file /etc/dnsmasq.conf :

interface=ap0
dhcp-range=ap0,192.168.10.129,192.168.10.250,12h

You will also need files to configure wpa_supplicant and hostapd. There is nothing special about them, so I am not going to add them here.

@ajanulis
Copy link

Unfortunately I found it very fragmented instruction and using it wasn't able to set up my Rpi. Maybe for some Linux guru it is useful, but not for me. Will stick to Albert's version

@marcelser
Copy link

Must agree, very incomplete. Especially not supplying modifications to wpa_supplicant and hostapd config. Are they same as in Albert's description?

@miquelmp
Copy link

Hello.
I've tried to follow your instructions, but when sudo systemctl restart dnsmasq I get
Job for dnsmasq.service failed because the control process exited with error code.
See "systemctl status dnsmasq.service" and "journalctl -xe" for details.

pi@raspberrypi:~ $ systemctl status dnsmasq.service
● dnsmasq.service - dnsmasq - A lightweight DHCP and caching DNS server
Loaded: loaded (/lib/systemd/system/dnsmasq.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Sat 2019-04-20 00:07:25 BST; 2min 0s ago
Process: 1046 ExecStart=/etc/init.d/dnsmasq systemd-exec (code=exited, status=2)
Process: 1043 ExecStartPre=/usr/sbin/dnsmasq --test (code=exited, status=0/SUCCESS)

Apr 20 00:07:25 raspberrypi systemd[1]: Starting dnsmasq - A lightweight DHCP and caching DNS server...
Apr 20 00:07:25 raspberrypi dnsmasq[1043]: dnsmasq: syntax check OK.
Apr 20 00:07:25 raspberrypi dnsmasq[1046]: dnsmasq: unknown interface ap0
Apr 20 00:07:25 raspberrypi systemd[1]: dnsmasq.service: Control process exited, code=exited status=2
Apr 20 00:07:25 raspberrypi systemd[1]: Failed to start dnsmasq - A lightweight DHCP and caching DNS server.
Apr 20 00:07:25 raspberrypi systemd[1]: dnsmasq.service: Unit entered failed state.
Apr 20 00:07:25 raspberrypi systemd[1]: dnsmasq.service: Failed with result 'exit-code'.

sta0 works fine, but ap0: Not associated

What could be the problem?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment