How to Setup Wi-Fi Access Point Mode (Linux)
Introduction
In this tutorial, we'll show you how to set up a Wi-Fi Access Point on Toradex Embedded Linux Reference Image using hostapd, a popular open-source software package for creating Wi-Fi networks. We'll guide you through the steps necessary to configure the hostapd software, the network interface, and IP forwarding. Once the Wi-Fi Access Point is set up, we'll also show you how to connect to it from a typical client device running Windows.
Why Wi-Fi Access Point
Wi-Fi Access Point (AP) mode allows you to turn your embedded Linux device that is wired connected to the internet (via ethernet cable) into a wireless router, creating a Wi-Fi network that other devices can connect to. This can be useful if you need to provide wireless internet connectivity to other devices that don't have a direct internet connection or if you need to extend the range of your existing Wi-Fi network.
Other Wi-Fi Related Articles
If this is not the information you are looking for, please, refer to the Wi-Fi Connectivity with Toradex’s Computer on Module (CoM) article for more Wi-Fi related information.
Torizon
The scope of this article does not include setting up Access Point on Torizon OS. For instructions on how to do so, please refer to Networking with Torizon OS.
Prerequisites
- A Toradex SoM with on board Wi-Fi
- Toradex Embedded Linux Reference Image version 6.x installed and running
- Antenna configured
- (Optional) An external Wi-Fi adapter with support for Access Point Mode. Check the list of tested modules in the Wi-Fi Connectivity on Toradex’s Computer on Module (CoM) article
Configuration
Setting up an access point consists of two main parts:
- Setting up the Wi-Fi Access Point mode, so that wireless clients can associate to your computer's software access point and exchange IP packets with it.
- Setting up the internet sharing on your Computer on Module, so that it properly relays IP packets between its own internet connection and the wireless clients.
1. Access Point Mode
When in BSP 6, the systemd recipe needs to be patched for this to work. So add proceed with the following modifications and rebuild your image for this to work.
/recipes-core/systemd/systemd_%.bbappendFILESEXTRAPATHS:prepend := "${THISDIR}/systemd:"
SRC_URI += "file://rndis.network"
-PACKAGECONFIG:append = " networkd"
+PACKAGECONFIG:append = " networkd iptc"
PACKAGECONFIG[acl] = "-Dacl=true,-Dacl=false,acl"Check the current mode and available interfaces with
iw dev
. For example, you should see a single interface in AP mode for the Colibri iMX6ULL:# iw dev
phy#0
Interface uap0
ifindex 6
wdev 0x2
addr c0:e4:34:2f:be:3b
type AP
txpower 0.00 dBm
Interface mlan0
ifindex 5
wdev 0x1
addr c0:e4:34:2f:bc:3b
type managed
txpower 0.00 dBm
Considering the test environment from Prerequisites section, the name of the AP-interface that is defined by the mwifiex kernel driver is uap0. This name can be different depending on userspace.
If the interface uap0
is not present, the mwifiexap
package may be missing.
This package is included by default in packagegroup-machine-tdx-cli for modules that include WiFi modules.
Set the Access Point interface IP and SSID in Hostapd configuration file. Change the following variables in
/etc/hostapd.conf
:/etc/hostapd.confinterface=uap0
ssid=access-point
hw_mode=g
channel=1
own_ip_addr=192.168.8.1An alternate
hostapd.conf
file that creates a WLan in the 5GHz range, protected with WPA2:/etc/hostapd.confinterface=uap0
ssid=testwifi
hw_mode=a
channel=40
ieee80211n=1
own_ip_addr=192.168.8.1
wpa=2
wpa_passphrase=MyNotSoSecretPassword1234The hostapd.conf is documented in the default hostapd.conf file that is deployed, as well as here: https://w1.fi/cgit/hostap/plain/hostapd/hostapd.conf
To provide the Access Point interface with a static IP address and DHCP, it is necessary to create the file
/etc/systemd/network/hostapd.network
:/etc/systemd/network/hostapd.network[Match]
Name=wlan0 uap0
WLANInterfaceType=ap
[Network]
Address=<IPV4_ADDR>/<IPV4_ADDR_NETMASK>
DHCPServer=true
IPMasquerade=yes
IPForward=ipv4
[DHCPServer]
PoolOffset=<DHCPD_POOL_OFFSET>
PoolSize=<DHCPD_POOL_SIZE>
EmitDNS=yes
DNS=<STATIC_DNS_ADRESS>Replace
<IPV4_ADDR>
,<IPV4_ADDR_NETMASK>
,<DHCPD_POOL_OFFSET>
,<DHCPD_POOL_SIZE>
and<STATIC_DNS_ADRESS>
accordingly. This also automatically sets up forwarding and the iptables masquerading rules, also including the setup of the AP sharing interface with a DHCP server. You can find more information and examples on the systemd-networkd documentation.Find out how the
*.device
file is named that is associated with the network device.# systemctl --all --full -t device
The Hostapd service starts by default after the network.target. This target is only loosely defined and means just "start after the network stack is up". This will fail by default because the network device (uap0 by default) is not up yet, or not every time. To fix this we can tell systemd that the hostapd.service file is depending on a device. In Toradex Reference Images, this is named
sys-subsystem-net-devices-uap0.device
Edit the properties BindsTo and After from file
/lib/systemd/system/hostapd.service
:/lib/systemd/system/hostapd.serviceBindsTo=sys-subsystem-net-devices-uap0.device
After=sys-subsystem-net-devices-uap0.deviceBoth BindsTo and After are necessary in order to tell systemd the strong dependence that hostapd.service has on our case uap0.
Reload the systemd configuration:
# systemctl --system daemon-reload
Enable and start hostapd service:
- First, make sure to blacklist the
uap0
interface on connmanctl by adding it toNetworkInterfaceBlacklist
atconnman/main.conf
.
# cat /etc/connman/main.conf | grep Black
NetworkInterfaceBlacklist = vmnet,vboxnet,virbr,ifb,ve-,vb-,usb,rndis, uap0- Then, proceed with the following commands:
# connmanctl enable wifi
# systemctl enable hostapd
# systemctl start hostapd- First, make sure to blacklist the
Check the Access Point interface:
# ip a s dev <IF_NAME>
Now you can connect to this Access Point from other Wi-Fi devices. Access Point will automatically start after reboot.
High-throughput Access Point
If you need higher throughputs of your access point, the right capabilities must be enabled using the configuration ht_capab
on the hostapd.conf
. By using the following hostapd.conf
file it’s possible to achieve throughputs higher than 54MBps:
ssid=
interface=uap0
hw_mode=a
own_ip_addr=192.168.8.1
ctrl_interface=/var/run/hostapd
auth_algs=1
wpa=2
wpa_key_mgmt=SAE
rsn_pairwise=CCMP
wpa_pairwise=CCMP
wpa_passphrase=
sae_require_mfp=1
ieee80211ac=1
ieee80211n=1
ieee80211w=2
wmm_enabled=1
country_code=JP
channel=36
ht_capab=[LDPC][HT40+][GF][SHORT-GI-20][SHORT-GI-40][TX-STBC][RX-STBC123][DELAYED-BA][DSSS_CCK-40]
Hostapd Example
Toradex provides a package in the BSP demo images called hostapd-example
which provides basically what was explained in the last section. To start the AP configured AP mode, enter:
$ systemctl start hostapd-example
If the AP should be started upon boot, enter:
$ systemctl enable hostapd-example
You can find the related openembedded recipe for this package in hostapd-example.
2. Internet Sharing
Once AP Mode is configured, it's a common scenario to share an internet connection from another interface. This section relies on the Internet Sharing article from the Arch Wiki. Please, make sure you have followed the steps described in section 1.Access Point Mode.
Enable the Packet Forwarding settings:
# sysctl net.ipv4.ip_forward=1
# sysctl net.ipv6.conf.default.forwarding=1
# sysctl net.ipv6.conf.all.forwarding=1These commands will not be kept between boots, they will just take effect at runtime.
(Optional) Create a file to add the packet forwarding rules so that the configuration persists between boots.
/etc/sysctl.d/30-ipforward.confnet.ipv4.ip_forward=1
net.ipv6.conf.default.forwarding=1
net.ipv6.conf.all.forwarding=1The changes will take effect after a reboot.
Toradex's provided Kernel configurations are insufficient for configuring NAT, thus it is important to add and enable the required kernel configs. For this, you can use the menuconfig:
$ bitbake virtual/kernel -c menuconfig
Or patch our BSP layers recipes.
meta-toradex-bsp-common/recipes-kernel/linux/linux-toradex-mainline-git/defconfig...
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_NF_CONNTRACK=y
+CONFIG_NF_TABLES=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_NAT=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
...After the new kernel is deployed, verify if it has the correct configs enabled by using:
# zcat /proc/config.gz | grep <CONFIG>
Replace
<CONFIG>
for one of the kernel configs previously enabled.You can use
iptables
to enable NAT and a systemd service to make it start on reboot. First, enable the rules for the current session:# iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
# iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
# iptables -A FORWARD -i uap0 -o eth0 -j ACCEPTSave the current config to
/etc/iptables/iptables.rules
:# mkdir /etc/iptables/
# iptables-save > /etc/iptables/iptables.rulesCreate a systemd service file
iptables.service
. The example is modified from the iptables package from Arch Linux:/lib/systemd/system/iptables.service[Unit]
Description=IPv4 Packet Filtering Framework
Before=network-pre.target
Wants=network-pre.target
[Service]
Type=oneshot
ExecStart=/usr/sbin/iptables-restore /etc/iptables/iptables.rules
ExecReload=/usr/sbin/iptables-restore /etc/iptables/iptables.rules
RemainAfterExit=yes
[Install]
WantedBy=multi-user.targetReload the systemd services and enable:
# systemctl --system daemon-reload
# systemctl enable iptables
Extra Resources
Here follows interesting extra documentation to help you understand the process described in this article: