Skip to main content
Version: BSP 6.x.y

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.

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

Configuration

Setting up an access point consists of two main parts:

  1. 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.
  2. 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

  1. 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_%.bbappend
    FILESEXTRAPATHS:prepend := "${THISDIR}/systemd:"

    SRC_URI += "file://rndis.network"

    -PACKAGECONFIG:append = " networkd"
    +PACKAGECONFIG:append = " networkd iptc"

    PACKAGECONFIG[acl] = "-Dacl=true,-Dacl=false,acl"
  2. 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.

note

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.

  1. Set the Access Point interface IP and SSID in Hostapd configuration file. Change the following variables in /etc/hostapd.conf:

    /etc/hostapd.conf
    interface=uap0
    ssid=access-point
    hw_mode=g
    channel=1
    own_ip_addr=192.168.8.1

    An alternate hostapd.conf file that creates a WLan in the 5GHz range, protected with WPA2:

    /etc/hostapd.conf
    interface=uap0
    ssid=testwifi
    hw_mode=a
    channel=40
    ieee80211n=1
    own_ip_addr=192.168.8.1
    wpa=2
    wpa_passphrase=MyNotSoSecretPassword1234

    The 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

  2. 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.

  3. 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

  4. Edit the properties BindsTo and After from file /lib/systemd/system/hostapd.service:

    /lib/systemd/system/hostapd.service
    BindsTo=sys-subsystem-net-devices-uap0.device
    After=sys-subsystem-net-devices-uap0.device

    Both BindsTo and After are necessary in order to tell systemd the strong dependence that hostapd.service has on our case uap0.

  5. Reload the systemd configuration:

    # systemctl --system daemon-reload
  6. Enable and start hostapd service:

    • First, make sure to blacklist the uap0 interface on connmanctl by adding it to NetworkInterfaceBlacklist at connman/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
  1. 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:

/etc/hostapd.conf
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.

  1. Enable the Packet Forwarding settings:

    # sysctl net.ipv4.ip_forward=1
    # sysctl net.ipv6.conf.default.forwarding=1
    # sysctl net.ipv6.conf.all.forwarding=1

    These commands will not be kept between boots, they will just take effect at runtime.

  2. (Optional) Create a file to add the packet forwarding rules so that the configuration persists between boots.

    /etc/sysctl.d/30-ipforward.conf
    net.ipv4.ip_forward=1
    net.ipv6.conf.default.forwarding=1
    net.ipv6.conf.all.forwarding=1

    The changes will take effect after a reboot.

  3. 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
    ...
  4. 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.

  5. 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 ACCEPT
  6. Save the current config to /etc/iptables/iptables.rules:

    # mkdir /etc/iptables/
    # iptables-save > /etc/iptables/iptables.rules
  7. Create 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.target
  8. Reload 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:



Send Feedback!