Gentoo Wiki


This article is part of the HOWTO series.
Installation Kernel & Hardware Networks Portage Software System X Server Gaming Non-x86 Emulators Misc


Purpose of this document

Many drivers these days automatically create an access point, but some will need to create their own if they have to use an older driver or if they want to use multiple access points. The access point also called in some places the "Interface" is the client, software created, viewport to a wireless network. It is necessary to have one to connect wireless network (station).

Buy a wireless card that supports "master mode"

What we need for a wireless "base-station" or "access-point" is a wireless network card that does "master mode", which allows our Linux box to behave just like products from the likes of Linksys, Netgear and Belkin - later sections of this HOWTO should be pretty much the same whether you can find a 802.11a, 802.11b or g card that does master mode in Linux.

Do be careful when buying a card for this project - WLAN cards documented as Linux-supported often become no longer available and it's not uncommon for manufacturers of wireless cards to sell completely different cards with a completely new chipset under the model number of a card that is already currently sold. I guess this saves them the trouble and expense of having new packaging and advertising printed, but it causes copious confusion for the Linux-loving enthusiast. Also look out for D-Link's evil naming conventions - the 3 different revisions of the DWL-520 are all different from the DWL-520+, which is different from the DWL-G520, which is different from the DWL-A520 and so on. When you throw into the mix the eight different cards with "DWL" and "650" in their names it can give you a headache just trying to work out which one your supplier is listing, never mind installing the drivers.

Prism (HostAP)

Note that cards using these drivers are 11MBPS only.

Jason Boxman provides quite an excellent description of these drivers:
HostAP enables 802.11b access point functionality utilizing the secondary (STA) firmware of Intersil's Prism2, Prism2.5, or Prism3 chipsets for time sensitive tasks. All other functionality is handled via the driver, including WEP and passing frames off to a port authenticator, like FreeRADIUS. Presently, HostAP works with Intersil's Prism chipset and cards utilizing PCI and PC Card interfaces to the host system. (PLX bridging is also supported)

Atheros chipsets (MadWifi)

These cards are well-supported by Linux. See Atheros 5xxx for a compatibility list.


NDISwrapper cards are not suitable for base-station use - they don't do master mode. NDISwrapper is basically a layer of interfacing glue to use Microsoft Windows drivers with Linux, and so it denies access to some of the more interesting and/or esoteric functions of the wireless card (because NDIS has no programming interface for them).

If you have a wireless card that you're currently using with NDISwrapper then it's possible that there are native drivers for it - I've seen quite a few posters to the Ubuntu forums suggesting using NDISwrapper with Ralink cards, for instance - but it's more likely that you'll have to bin it (or put it in your sister's Windows PC) and get a card with native drivers that interface properly with the kernel.

Note: You can accomplish a similar goal with an Ad-Hoc network; this might help.


I wanted a card that supported the Prism54 drivers, as they seemed to be about the most mature ones for "54G" wireless cards under Linux at the time I was looking - my Powerbook has Airport Extreme, Apple's name for 802.11g, so I might as well make use of it. I took a good look through the supported cards and decided upon the Allnet ALL0271. It seemed to be fairly well-recommended on the forums - there are too many short comments saying "worked for me" for me to post all the individual links, so do a search & read all the threads for yourself.

You can order the ALL0271 from the US, from Germany or if you're in the UK, I actually bought a handful, so email me if you'd like to buy one. I also recently got one of these cards working on a friend's SuSE 9.1 box, although the process isn't as brain-dead as it is under Gentoo - portage & the ebuilds automate the process so well.

Ralink rt2400

Its unable to set master mode on rt2400 (using rt2400-cvs-2008051522 driver) - this driver supports only ad-hoc and managed mode.

Ralink rt2500

As I see on the rt2x00 project page, the new branch rt2x00 beta drivers support master mode and all advanced features, but legacy rt2500, rt2570, rt61 drivers do not, but I have no way to test such setup.

For more details on this driver see the project homepage.

You may also want to check Wireless/libnl Access Point. I was in fact able to put my rt2500-based car in Master mode using the instructions from there.

Broadcom 43xx cards (b43)

Broadcom cards support master mode using the reverse-engineered kernel driver. You need to enable (or make as a module) the Softmac wireless extensions and b43 wireless driver. See the Broadcom 43xx article.

If the above method don't work for you, you can set up a libnl-based Wireless Access Point by following these instructions : Wireless/libnl Access Point. Reported successful on 9 october 2008.

Realtek RTL8180 cards (rtl8180-sa2400 project)

Master mode is working correctly together with promiscuous mode, but there are problems with Wireless Extensions with version available in Portage together with kernels >=2.6.19 and the card may be handled incorrectly by init scripts. Supports WEP open encryption and possibly TKIP/CCMP(not tested). Broken with new(2.6.20+) kernels. Supports only 1/2/5.5/11M modes.

Texas Instruments ACX100/ACX111

In cards based on this chip (ex. D-Link DWL-520+) master mode is not fully implemented (as of 2007-01-01 driver) and there are some different problems like sometimes no beacons are broadcasted and card can't be properly initiated. Supports 1/2/5.5/11M(b) and 22M(b+) modes.

Intel PRO/Wireless (ipwXXXX) series

For ipw2100/ipw2200, unfortunately there is no way to use them as AP, but this can be done for ipw3945 and ipw4965, maybe ipw2915 too, which are pretty good cards anyway, using fully open-source iwlwifi drivers, but it can't be done with old Intel drivers with closed microcode.

Build a base Gentoo system

I'm assuming you've built Gentoo before - I just followed the Gentoo Quick Install Guide.

In order to run your wireless drivers you need a couple of options enabled in your kernel, so you might as well do this during your original build. Look for:

Linux Kernel Configuration:
  Bus options (PCI, PCMCIA, EISA, MCA, ISA) --->
    Support for hot-pluggable devices

CONFIG_FW_LOADER: m/y (either one will work)
  Generic Driver Options  --->
     Hotplug firmware loading support

  Device Drivers --->
    Networking support --->
      Wireless LAN (non-hamradio) --->

This is because:

from /usr/src/linux/drivers/net/wireless/Kconfig

Saying Y here also enables the Wireless Extensions (creates /proc/net/wireless and enables iwconfig access). The Wireless Extension is a generic API allowing a driver to expose to the user space configuration and statistics specific to common Wireless LANs. The beauty of it is that a single set of tool can support all the variations of Wireless LANs, regardless of their type (as long as the driver supports Wireless Extension). Another advantage is that these parameters may be changed on the fly without restarting the driver (or Linux). [This is handy for wireless PCMCIA (PC-) cards]

Now it's time to find and enable your drivers.

To determine type of your card, emerge pciutils if you haven't done before, and lspci.

You'll have to look under Wireless LAN category mentioned above, or in the portage, in the net-wireless category. Sometimes, when you choose to use driver from kernel, you should also pull in firmware for your card from portage, but not for every card.

To install in-kernel driver enable it either statically or as a module, by pressing y or m over desired item, then recompile and install new kernel or kernel modules.

If you want to use driver outside of kernel tree, proceed to next section.


If you want to use driver outside of the kernel tree or your kernel driver depends on a firmware, you'll have to find it in portage, for example by checking /usr/portage/net-wireless/ or by using eix to list all packages: eix net-wireless/. Then you can use emerge to install the package.

Some of driver package are available only with testing keyword, others (e.g. rt2x00) require setting USE flags. In that case:

# set the testing keyword
echo net-wireless/rtl8180 ~x86 >> /etc/portage/package.keywords

# set the right USE flags
echo net-wireless/rt2x00 rt2500 >> /etc/portage/package.use

Of course replace package names, categories and use flags with ones you need.

If you've compiled your wireless driver as a module, don't forget to ensure that it's loaded at boot:

echo module_name >> /etc/modules.autoload.d/kernel-2.6

The ebuild is clever enough to pull in everything else it needs:

So now you're ready to go. Neither of the above should be masked, but if they are add them to /etc/portage/package.keywords the same as you did for the driver itself above. If you've chosen just to use the drivers supplied with your kernel then you'll need to emerge these two ebuilds separately.

Check if your wireless card is already working

Please load, if not already done, the proper module for your wireless card using modprobe. Then use iwconfig to check if your card has already been recognized.

Code: iwconfig
eth0      no wireless extensions.

lo        no wireless extensions.

wlan0     NOT READY!  ESSID:off/any
          Mode:Managed  Channel:6  Access Point: 00:00:00:00:00:00
          Tx-Power=31 dBm   Sensitivity=0/200
          Retry min limit:0   RTS thr=0 B   Fragment thr=0 B
          Link Quality:0  Signal level:0  Noise level:0
          Rx invalid nwid:0  Rx invalid crypt:0  Rx invalid frag:0
          Tx excessive retries:0  Invalid misc:0   Missed beacon:0

In this example eth0 is the wired Ethernet network card. I compile drivers for the most common types of network cards - any I recognise the name of when I'm doing make menuconfig - statically into the kernel.

It's fairly obvious from the above that wlan0 is the wireless card. So note now which interface name iwconfig is showing for your wireless card, because you'll need it later on.

Setup the wireless interface

Note: If you are using MadWifi, please also read this page which will deal with some MadWifi-specific options.
Note: Please ensure, you have a baselayout which handles wireless config. This is the case for version 1.11.10 or later.

You'll need to create a symlink first. The "-s" option causes the ln to act upon the symlink, rather than following it to the original file.

ln -s /etc/init.d/net.lo /etc/init.d/net.wlan0

Here's all the configuration for the wireless interface - eth1 was indicated by iwconfig earlier:

File: /etc/conf.d/net
config_wlan0=( " netmask" )

# It is best to choose a channel on which there are no others access points to get a faster connection.
# Use iwlist scan to check the channels the other access points are on.
Note: You can alternatively put this is /etc/conf.d/wireless - both files seem to be parsed equally by the init scripts, but /etc/conf.d/wireless is now deprecated. They also have the same format, which I didn't initially realize from reading /etc/conf.d/wireless.example - /etc/conf.d/net.example is also worth perusing.

You will need to load the interface:

/etc/init.d/net.wlan0 start

You will probably want to bring the wireless interface up at boot:

rc-update add net.wlan0 default

Now other computers should be able to connect to your access point. It is still unprotected and you cannot access WAN but you can try to ping it. You do not have DHCP enabled on your server yet so you need to think of an own IP in the range 192.168.0.XXX. The access point has the IP and the subnet Make sure you set up your machine you're testing with to be on the right subnet. If you are connected with your access point, you can use ping to check if you can reach your server from outside.

Simple NAT-forwarding setup

The server has access to WAN but if you are connected using your access point, you cannot access it. This is because you need to forward all WAN traffic from your LAN interface (eth0) to your WLAN interface (wlan0). If you are using a PPPoE connection that is established on eth0, you probably have to use the interface ppp0. The following lines were copied from The Gentoo Home Router Guide, so if you have any problems with this, the best place is to look there. Here's the essentials, but you should consider putting a bit more in there, like the way vapier does it.

Code: Enable forwarding
iptables -F
iptables -t nat -F
iptables -A FORWARD -i wlan0 -s -j ACCEPT
iptables -A FORWARD -i eth0  -d -j ACCEPT
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
echo 1 > /proc/sys/net/ipv4/ip_forward

Note also how vapier saves his configuration for future boots:

Code: Enable forwarding
/etc/init.d/iptables save
rc-update add iptables default

Then add or uncomment the following lines in /etc/sysctl.conf:

File: /etc/sysctl.conf
net.ipv4.ip_forward = 1
net.ipv4.conf.default.rp_filter = 1

If you do not want to set up an IP address manually on each machine, you can also use DHCP. Then your clients assign an IP from the server automatically.



Warning: WEP is unsecure, you should use WPA instead. Please skip to the next section.

Now that we have a usable setup, we'd better enable some encryption, so our neighbours don't start making free with our connection. There are two ways to generate a WEP key from the command-line; the more traditional way would involve cat /dev/random and piping it somewhere, but when I did this a few times to get the syntax right I found that I ran out of entropy pretty quick. Since we all have OpenSSL installed (and you would think that OpenSSL's random number generator might be particularly good, anyway) here's how I obtained a random WEP key:

Code: Generating a random WEP key
openssl rand 13 | xxd -ps

Add this line to /etc/conf.d/net in order to set the key:


There are loads of pages on the web that will generate a WEP key randomly for you, but I wanted to do it entirely from the terminal, to save you copying & pasting from a web-browser. man openssl explains that openssl rand 13 generates 13 "pseudo-random bytes" and the xxd converts these bytes into a hex string. The next line adds the random string to /etc/conf.d/net in a suitable format for the init scripts to parse it, and finally we need to see what the key is, so we can make a note of it and enter it on the other machine.

The above generates a "128-bit" WEP key - actually, the "13" indicates that you're actually only generating 8 x 13 = 104 bits, but in fact there are another 20 non-random bits on each WEP key, so the name is a bit of a misnomer. If you want a WEP key of only 40 bits, then change the 13 to 5.

If you restart the interface, your other machine should now tell you that Tux is a secure network and ask you for the key.


It's possible to use WPA encryption together with master mode, but as it requires hostapd, it can be only supported on Prism and Atheros-based cards. In future, maybe it could be used with any card using Mac80211 stack. It can support anything from dynamic WEP through WPA-PSK to WPA2 (RSN) with AES/CCMP encryption with RADIUS accounting. Check out [1] for more information.

Note: If you have an Atheros card, add "hostapd madwifi" to your /etc/portage/package.use.

Start by emerging hostapd.

emerge -av hostapd

Now you need to edit the /etc/hostapd/hostapd.conf. This is just an example, change as necessary.

File: /etc/hostapd/hostapd.conf
wpa_pairwise=CCMP TKIP

Now you need to test that everything is working:

/etc/init.d/net.wlan0 restart

Check that hostapd is working by running:

hostapd -dd /etc/hostapd/hostapd.conf

If everything is working, you should see something like this:

Configuration file: /etc/hostapd/hostapd.conf
madwifi_set_iface_flags: dev_up=0
Using interface wlan0 with hwaddr 00:01:02:03:04:05 and ssid 'Tux'
madwifi_set_ieee8021x: enabled=1
madwifi_configure_wpa: group key cipher=1
madwifi_configure_wpa: pairwise key ciphers=0xa
madwifi_configure_wpa: key management algorithms=0x2
madwifi_configure_wpa: rsn capabilities=0x0
madwifi_configure_wpa: enable WPA= 0x1
madwifi_set_iface_flags: dev_up=1
madwifi_set_privacy: enabled=1
WPA: group state machine entering state GTK_INIT
WPA: group state machine entering state SETKEYSDONE
madwifi_set_key: alg=TKIP addr=00:00:00:00:00:00 key_idx=1
Flushing old station entries
madwifi_sta_deauth: addr=ff:ff:ff:ff:ff:ff reason_code=3
Deauthenticate all stations
l2_packet_receive - recvfrom: Network is down

When that is working, you can kill hostapd and use its init script:

/etc/init.d/hostapd start
rc-update add hostapd default

Your client machines are now going to need wpa_supplicant to associate. See Wireless/Configuration and [2] for more information

Bridging the wired and wireless segments

Our setup will work great so far if you're plugging an Ethernet cable-modem into the wired NIC and only using wireless clients with it - but there are some things it doesn't do so well. If we have one machine connected to the router's wired port and another connecting wirelessly, we won't be able to stream music between them, for instance - that requires them both to be on the same subnet. You'll need to get the bridging tools - the init.d scripts depend upon these: emerge bridge-utils

And ensure that your kernel supports bridging:

Linux Kernel Configuration: Bridging
Networking  --->
  Networking options  --->
    <*> 802.1d Ethernet Bridging

Your /etc/conf.d/net will require a complete overhaul - probably best to back it up first! Add the following settings to your /etc/conf.d/net for a bridge with two interfaces.

File: /etc/conf.d/net
config_ath0=( "null" ) # Wireless access point
config_eth0=( "null" ) # DSL modem (eth0 -> ppp0)
config_eth1=( "null" ) # LAN 1

# ...
# Settings for ath0
# Note: You '''must not''' set an IP for ''config_ath0''. Please comment this line out so that the ''null'' value is being used.
# ...

bridge_br0=( "eth1" "ath0" )
config_br0=( " netmask broadcast" )

depend_br0() {
        need net.ath0

route -n should now show you the following routes:

Code: route -n
<Your WAN IP> UH    0      0        0 ppp0   U     0      0        0 br0       U     0      0        0 lo         <Your WAN IP>         UG    0      0        0 ppp0

There must not be a ath0-route. WLAN is already working but if you try to connect using ethernet, it will use the ath0 device instead of br0 so that the pings fail. ath0 occurs in the routing table list because you have set an IP for it in /etc/conf.d/net. Set it to null and your problems should vanish. If there are other routes, that are not mentioned in the list above and you do not know what they are for, it is best to delete all net.* from your runlevels (using rc-update del net.<interface>) and only add net.ppp0 (if you are connecting via PPPoE, otherwise it will be net.eth0) and net.br0.

Code: Placing the bridge in the default runlevel
cd /etc/init.d/
ln -s net.lo net.br0
ln -s net.lo net.eth1
rc-update -a net.ppp0 default  # optional
rc-update -a net.br0 default

Now you need to change the interfaces of your HostAP and of the Dnsmasq. For Dnsmasq, edit the line interface /etc/dnsmasq.conf so that it points to br0 instead of ath0:

File: /etc/dnsmasq.conf

Then add the lines interface=ath0 and bridge=br0 to your hostapd.conf:

File: /etc/hostapd.conf

If you are using dhcpcd instead of Dnsmasq, you need to change the line DHCPD_IFACE:

File: /etc/conf.d/dhcpd

The best way to test your setup is to reboot. The bridge should successfully bring the interface net.ath0 up before coming up itself due to the presence of the depends statement. Please check out brctl show to see if the interfaces have been bridged properly.

Now you should now be able to ping across the bridge without needing any forwarding enabled. In the example below I'm sitting at my desktop computer, and ping first the bridge and then a laptop connected to the wireless network. Notice how the first ping response from the laptop is delayed, as the bridge initialises its stuff.

Code: Testing the bridge
Last login: Sat Feb 26 13:35:38 on ttyp1
Welcome to Darwin!
515 ~ $ ifconfig en0
        inet6 fe80::20d:93ff:fe70:1b3e prefixlen 64 scopeid 0x4
        inet netmask 0xffffff00 broadcast
        ether 00:0d:93:70:1b:3e
        media: autoselect (100baseTX <full-duplex>) status: active
        supported media: none autoselect 10baseT/UTP <half-duplex> 10baseT/UTP <
full-duplex> 10baseT/UTP <full-duplex,hw-loopback> 100baseTX <half-duplex> 100ba
seTX <full-duplex> 100baseTX <full-duplex,hw-loopback> 1000baseTX <full-duplex>
1000baseTX <full-duplex,hw-loopback> 1000baseTX <full-duplex,flow-control> 1000b
aseTX <full-duplex,flow-control,hw-loopback>
516 ~ $ ping
PING ( 56 data bytes
64 bytes from icmp_seq=0 ttl=64 time=0.36 ms
64 bytes from icmp_seq=1 ttl=64 time=0.25 ms
64 bytes from icmp_seq=2 ttl=64 time=0.239 ms
--- ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.239/0.283/0.36 ms
517 ~ $ ping
PING ( 56 data bytes
64 bytes from icmp_seq=0 ttl=64 time=486.961 ms
64 bytes from icmp_seq=1 ttl=64 time=201 ms
64 bytes from icmp_seq=2 ttl=64 time=2.271 ms
--- ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 2.271/230.077/486.961 ms
518 ~ $ 

If you have more interfaces, you could of course create NAT on the interface not in the bridge, so computers on wireless and wired segments not only see each other, but also have Internet access, in case of having only one IP, exactly the same way as written in NAT section.

Known problems

Unwanted IP-based bridge filtering

Sometimes after bridge is being set up, only ARP and STP packets are coming through the bridge. The first symptom is that PCs from the other side of the bridge are in the ARP caches but no communication is possible, and communication with the bridge itself is possible. Try pinging hosts on the other side of the bridge and then run:
arp -a
It applies not only to wireless bridging. It's fault of Bridged IP/ARP filtering enabled which lets iptables/arptables see and manipulate bridged traffic. To fix it we have to either disable the following in kernel option in kernel:


Networking  --->
  Networking support  --->
    Networking options  --->
      Network packet filtering (replaces ipchains) --->
       [ ] Bridged IP/ARP packets filtering

Or we have to disable some "features" in /proc/sys/net/bridge:

Code: Disabling netfilter on bridge
 # cd /proc/sys/net/bridge
 # ls
 bridge-nf-call-arptables  bridge-nf-call-iptables
 bridge-nf-call-ip6tables  bridge-nf-filter-vlan-tagged
 # for f in bridge-nf-*; do echo 0 > $f; done

And don't forget to add some lines to /etc/sysctl.conf so everything is correct on boot:

File: /etc/sysctl.conf
# Disable bridge filtering
net.bridge.bridge-nf-call-arptables = 0
net.bridge.bridge-nf-call-ip6tables = 0
net.bridge.bridge-nf-call-iptables = 0
net.bridge.bridge-nf-filter-vlan-tagged = 0

Wireless card is unable to transmit packets with other source MAC than it's own

Sometimes only packets transmitted from wireless segment are forwarded to wired segment but do not in opposite direction. The cause of it is a "feature" of wireless NIC, that it can't transmit packets with other source MAC address than it's own.
This is most probably dependent on card's firmware as EXACTLY the same chips are used in commercial hardware APs.
If you know which cards/chips/drivers suffer this problem, please write it!
To fix it we'll need ebtables. Assuming you have already configured your bridge, you have to enable ebtables in your kernel if you didn't already:


Networking  --->
  Networking support  --->
    Networking options  --->
      Network packet filtering (replaces ipchains) --->
        Bridge: Netfilter Configuration --->
         <M> Ethernet Bridge tables (ebtables) support --->
          <M> ebt: broute table support
          <M> ebt: filter table support
          <M> ebt: nat table support
          <M> ebt: snat target support

I would also recommend enabling other filters/targets, but possibly you'll have to use the fix written before.
Don't forget to recompile and set up the kernel or to load apropriate modules.
The next thing you have to do is:
emerge ebtables
After emerge completes, we have to know the MAC address (HWAddr) of WLAN card. Assuming your wireless card is eth1, to get it type: ifconfig eth1 And lastly, enable the MAC Source NAT:

Code: Enabling MAC address Source NAT
ebtables -t nat -A POSTROUTING -o eth1 -j snat --to-src <MAC address of eth1> 

Alternatively, use this script to automatically create the rule, don't forget to replace eth1 with correct interface name


export WLAN=eth1
export WLAN_MAC=$(ifconfig ${WLAN} | grep HWaddr | cut -d ' ' -f 11)

ebtables -t nat -A POSTROUTING -o ${WLAN} -j snat --to-src ${WLAN_MAC}

As of ebtables- there is an official init script which I made, utilizing ebtables-save and ebtables-restore so saving and restoring configuration is pretty easy.

Code: Saving rules and adding ebtables to default runlevel
# Save the already enabled rules:
/etc/init.d/ebtables save

# Add the script to the default runlevel:
rc-update add ebtables default

Now everything should be working fine.

Init script failing with net.wlan0

If you have problems with the init script asking for net.wlan0 which doesn't exist because your interface is named different, you can fix this by modifying /etc/conf.d/hostapd.

Code: Original Interface List in /etc/conf.d/hostapd
# Space separated List of interfaces which needs to be started before
# hostapd
Code: Modified Interface List in /etc/conf.d/hostapd
# Space separated List of interfaces which needs to be started before
# hostapd
Retrieved from ""

Last modified: Thu, 09 Oct 2008 11:19:00 +0000 Hits: 92,057