Linux无线AP隔离功能分析
shixudong163.com无线AP上大都有一个选项AP隔离启用该功能后连接到同一个AP的无线终端之间不能互相通信但该功能并不限制无线终端和有线终端之间的通信。本人对Linux下用hostapd实现AP隔离进行了一些分析特此记录。Hostapd选项ap_isolate用于控制AP隔离但hostapd本身并不实现这一功能只是将该选项通过nl80211传递给mac80211由mac80211来实现AP隔离功能。由于mac80211与SoftMAC无线网卡配合使用FullMAC无线网卡压根不使用mac80211所以FullMAC无线网卡不保证支持AP隔离功能。经对mac80211相关源码进行分析ap_isolate的真实作用是控制无线AP收到包后是通过调用dev_queue_xmit将数据包直接通过无线网卡发送出去ap_isolate0无隔离还是通过调用netif_receive_skb交由本机上层网络栈处理ap_isolate1可隔离。ap_isolate0时无线终端之间数据包经由AP无线网卡直接通信此时AP行为如同HUB无隔离并不涉及AP上层网络栈。ap_isolate1时无线终端之间数据包全部发往AP上层网络栈如AP没加入网桥其上层网络栈为IP协议栈因数据包目标MAC不是AP无线网卡MAC包类型对应PACKET_OTHERHOST包将被IP层DROP如AP已启用网桥其上层网络栈为网桥无线终端之间数据包由网桥进行二层转发但由于桥转发本身的内在机制网桥收到的包不允许从同一端口再次转发出去故包被二层DROP。故ap_isolate1时无论AP是否加入网桥无线终端之间都无法通信从而实现AP隔离。同一网桥的无线终端和有线终端之间则不存在上述二层转发限制可以互相访问。在与网桥配合使用时ap_isolate1除了实现AP隔离外还可利用multicast_snooping优化组播性能或利用SDN对无线终端进行管控其实质都是将无线终端之间的数据包引导到AP的网桥处理。由此引发了一个新的挑战既希望利用网桥处理数据包的优势又需要关闭AP隔离功能让无线终端之间互相通信。显然此时无法通过改变ap_isolate来实现上述目的为此可利用网桥物理端口hairpin模式控制AP是否隔离。设置网桥无线端口hairpin_mode1后从同一无线端口进来的包允许通过hairpin功能原路返回无线终端之间数据包可以恢复二层转发从而实现互相通信这也是新版Openwrt实现无线AP的标准配置ap_isolate1、hairpin_mode1。其实Linux相当灵活可以用多种方式实现同一目的。当ap_isolate1的主要目的是为了将无线终端之间数据包引导到AP的网桥处理时还可以通过网桥无线端口的isolated功能控制AP是否隔离此时hairpin_mode应固定为1否则AP始终隔离isolated1开启AP隔离isolated0关闭AP隔离。上文分析了ap_isolate1时网桥无线端口hairpin_mode、isolated如何控制无线终端之间的通信行为这两个功能属于“或”关系某种意义上是等效的。1hairpin_mode0始终开启AP隔离hairpin_mode1通过isolated控制AP隔离开启与否。2isolated1始终开启AP隔离isolated0通过hairpin_mode控制AP隔离开启与否。但如ap_isolate0无线终端之间相互通信根本不用经过网桥此时hairpin_mode、isolated压根无法影响或控制无线终端之间的通信AP隔离始终处于关闭状态。顺便提一下isolated作为网桥物理端口选项本意就是用来隔离网桥物理端口之间的通信将数据包进出端口的isolated均设为1即可隔离两个端口上所连接设备之间的相互通信。当无线AP的ap_isolate1时无线终端之间数据包必须经由网桥处理此时方可使用isolated实现AP隔离虽然进出都是同一个wlan口但仍然符合进出端口都启用isolated的约束。此外由于isolated和hairpin_mode都是网桥附带功能因此在NAT模式下使用hostapd时由于不涉及网桥无线AP上层网络栈不再是网桥直接就是IP协议栈此时就只能老老实实使用ap_isolate选项控制AP隔离了。