Can a Linux machine act as both a wireless client and access point simultaneously using a single physical WLAN interface?

I haven't done this before personally, but here's some information to get you headed in the right direction.

From a protocol perspective, it's definitely possible to have a single radio working as both an AP and a client STA. It works out best (or perhaps is nearly mandatory) if the AP you're creating and the one you're joining as a client are on the same channel. Having the radio card have to keep switching channels to service requests is a recipe for lost frames and terrible performance.

Software-wise, it's becoming possible. Several 802.11 card drivers on Linux support the concept of VAPs (virtual APs) which allows a single card to act as multiple APs (multiple SSIDs, even BSSIDs) at the same time. Counterintuitively, the term VAP has come to mean any kind of virtual interfaces on the same 802.11 card, regardless of whether the virtual interface is in AP mode or not. So on these card/driver combos, you could create two VAPs -- a STA-mode VAP

The MadWifi driver for Atheros-based cards is one that supports VAPs. If your 802.11 card uses an Atheros chipset, and you install the right version of the MadWifi driver, you might be able to configure your card for simultaneous STA + AP mode something like this:

wlanconfig ath0 create wlandev wifi0 wlanmode sta
wlanconfig ath1 create wlandev wifi0 wlanmode ap

Note that these are not complete instructions for setting everything up, but just an attempt to get you started.

You might want to Google for something like "wifi vap" for more information. I copied the above commands from here.

Oh, and some myth busting: Atheros cards are not uncommon in consumer machines. They're a major player in 802.11 chipsets, along with Broadcom, Marvell, Intel, and Ralink. And just because I used the example of MadWifi/Atheros, doesn't mean there aren't Linux drivers for the other major players' chips that can do a similar thing. Also, 802.11s is not required for this. Saying you have to do 802.11s to do this is like saying you have to support Spanning Tree Protocol just to forward frames from one interface to another.


source and more info:

https://wiki.archlinux.org/index.php/Software_access_point

Short answer

sudo iw dev wlan0 interface add wlan0_ap type managed
sudo create_ap wlan0_ap wlan0 createap mypassword

Wi-Fi device must support AP mode

You need a nl80211 compatible wireless device, which supports the AP operating mode. This can be verified by running iw list command, under the Supported interface modes block there should be AP listed:

...
    Supported interface modes:
         * IBSS
         * managed
         * AP
         * AP/VLAN
         * WDS
         * monitor
         * mesh point
...

Wireless client and software AP with a single Wi-Fi device

Creating a software AP is independent from your own network connection (Ethernet, wireless, ...). Many wireless devices even support simultaneous operation both as AP and as wireless "client" at the same time. Using that capability you can create a software AP acting as a "wireless repeater" for an existing network, using a single wireless device. The capability is listed in the following section in the output of iw list:

valid interface combinations:

$ iw list
...
valid interface combinations:
     * #{ managed } <= 1, #{ AP, P2P-client, P2P-GO } <= 1, #{ P2P-device } <= 1,
       total <= 3, #channels <= 2
...

The constraint #channels <= 1 means that your software AP must operate on the same channel as your Wi-Fi client connection; see the channel setting in hostapd.conf below.

If you want to use the capability/feature, perhaps because an Ethernet connection is not available, you need to create two separate virtual interfaces for using it. Virtual interfaces for a physical device wlan0 can be created as follows: The virtual interfaces with unique MAC address are created for the network connection (wlan0_sta) itself and for the software AP/hostapd "wireless repeater":

# iw dev wlan0 interface add wlan0_sta type managed 
# iw dev wlan0 interface add wlan0_ap  type managed

Configuration

Setting up an access point consists of two main parts:

  1. Setting up the Wi-Fi link layer, so that wireless clients can associate to your computer's software access point and exchange IP packets with it.
  2. Setting up the network configuration on your computer, so that it properly relays IP packets between its own internet connection and the wireless clients.

Tools

create_ap

The create_ap package provides a script that can create either a bridged or a NATed access point for internet sharing. It combines hostapd, dnsmasq and iptables for the good functioning of the access point. The basic syntax to create a NATed virtual network is the following:

# create_ap wlan0 eth0 MyAccessPoint MyPassPhrase

The nl80211 driver has something called the "managed" interface mode. You can configure it using the "iw" utility like so:

iw phy phy0 interface add wlan1 type managed

More info on this is available at https://wireless.wiki.kernel.org/en/users/documentation/iw. Phy0 refers to what you see in /sys/class/ieee80211/.

I've also seen the rPI3 do something similar, but with a more shady "__ap" interface mode. That way the user creates a second interface that only runs in AP mode, and uses the initial interface as client mode.

Whatever way you realize it (the driver obviously has to support it), you'll need two interfaces (from the same physical device). One interface can simply run wpa_supplicant as client mode, the other (AP mode) typically uses hostapd to play accesspoint.

[EDIT:]

The source code of the iw tool makes a lot clear about the shady __ap mode:

..
} else if (strcmp(tpstr, "__ap") == 0) {
    *type = NL80211_IFTYPE_AP;
    return 0;
} else if (strcmp(tpstr, "__ap_vlan") == 0) {
    *type = NL80211_IFTYPE_AP_VLAN;
    return 0;
} else if (strcmp(tpstr, "wds") == 0) {
    *type = NL80211_IFTYPE_WDS;
    return 0;
} else if (strcmp(tpstr, "managed") == 0 ||
       strcmp(tpstr, "mgd") == 0 ||
       strcmp(tpstr, "station") == 0) {
    *type = NL80211_IFTYPE_STATION;
    return 0;
} 
..

The __ap mode translates to a netlink type NL80211_IFTYPE_AP. I also tested this, and this works fine. Strange that the kernel documentation wiki does not metion it though.