【Linux】WLAN接口桥接

一、内核补丁

因为Linux内核会在注册特定设备时将会将dev->priv_flags置为IFF_DONT_BRIDGE ,所以现还不支持sta、p2p_client、adhoc等无线接口加入到桥接中去的,所以要支持WLAN接口桥接需要修改内核代码,如下内核补丁以3.10.63内核为例,其他版本类似,找到对应函数修改即可。

1.源文件 linux-3.10.63/net/wireless/util.c,
函数cfg80211_change_iface(),注释掉以下部分
在这里插入图片描述
2.源文件 linux-3.10.63/net/ wireless/util.c,
函数cfg80211_change_iface(),注释掉以下部分
请添加图片描述
3.源文件 linux-3.10.63/net/wireless/core.c,
函数 cfg80211_netdev_notifier_call(),注释掉以下部分
在这里插入图片描述
4.源文件 linux-3.10.63/net/bridge/br_if.c,
函数 br_port_carrier_check()
注释掉判断语句里netif_oper_up(dev)部分
在这里插入图片描述

5.源文件 linux-3.10.63/net/bridge/br_if.c,
函数br_add_if(),注释掉判断语句里 netif_oper_up(dev)部分
在这里插入图片描述
6.源文件 linux-3.10.63/net/bridge/br_notify.c,
函数br_device_event()
注释掉判断语句里netif_oper_up(dev)部分
在这里插入图片描述
7.源文件 linux-3.10.63/net/bridge/br_stp_if.c,
函数 br_stp_enable_bridge()
注释掉判断语句里 netif_oper_up(p->dev)部分
请添加图片描述

二、转发设置

工作原理:
内网主机向公网发送数据包时,由于目的主机跟源主机不在同一网段,所以数据包暂时发往内网默认网关处理,而本网段的主机对此数据包不做任何回应。由于源主机ip是私有的,禁止在公网使用,所以必须将数据包的源发送地址修改成公网上的可用ip,这就是网关收到数据包之后首先要做的工作–ip转换。然后网关再把数据包发往目的主机。目的主机收到数据包之后,只认为这是网关发送的请求,并不知道内网主机的存在,也没必要知道,目的主机处理完请求,把回应信息发还给网关。网关收到后,将目的主机发还的数据包的目的ip地址修改为发出请求的内网主机的ip地址,并将其发给内网主机。这就是网关的第二个工作–数据包的路由转发。内网的主机只要查看数据包的目的ip发送请求的源主机ip地址相同,就会回应,这就完成了一次请求。
出于安全考虑,Linux系统默认是禁止数据包转发的。所谓转发即当主机拥有多于一块的网卡时,其中一块收到数据包,根据数据包的目的ip地址将包发往本机另一网卡,该网卡根据路由表继续发送数据包。这通常就是路由器所要实现的功能。

设置
Linux系统缺省并没有打开IP转发功能,要确认IP转发功能的状态,可以查看/proc文件系统,使用下面命令: cat /proc/sys/net/ipv4/ip_forward
如果上述文件中的值为0,说明禁止进行IP转发;如果是1,则说明IP转发功能已经打开。
可以直接修改上述文件打开IP转发功能:echo 1 > /proc/sys/net/ipv4/ip_forward
上面的命令并没有保存对IP转发配置的更改,下次系统启动时仍会使用原来的值,要想永久修改IP转发,需要修改/etc/sysctl.conf文件,修改下面一行的值: net.ipv4.ip_forward = 1修改后可以重启系统来使修改生效,
也可以执行下面的命令来使修改生效: sysctl -p /etc/sysctl.conf进行了上面的配置后,IP转发功能就永久使能了

三、建立桥接

网络桥接命令 brctl,BusyBox 包含 brctl 命令,在配置编译 BusyBox 时选上即可。
以sta(wlan0)和softap(wlan1)桥接为例,

#创建网桥 br0
brctl addbr br0

#把wlan0 wlan1添加到网桥 br0
brctl addif br0 wlan0
brctl addif br0 wlan1

#将3个接口up起来
ifconfig br0 up
ifconfig wlan0 up
ifconfig wlan1 up

#在wlan0起wpa_supplicant
wpa_supplicant -iwlan0 -Dnl80211 -c wpa_supplicant.conf -b br0

#为br0获取ip
dhclient br0

#在wlan1起softap hostapd.conf配置有 bridge=br0
hostapd -iwlan1 -c hostapd.conf

#查看网桥信息
brctl show
#删除网桥
brctl delbr br0
#更多内容使用 brctl--help 查看

这样建立完桥接后,br0 MAC为wlan0、1中MAC地址较小一个,原理可以查看 br_add_if时调用的 br_stp_recalculate_bridge_id()函数,此时驱动需要对转发的DHCP包进行广播、ARP包修改target HWaddr、IP包修改MAC地址等等,此时连着softap的设备通过sta连着的路由分配IP,二者再同一网段,相当于wlan0与wlan1下的设备共享同一ap。

三、内核获取网络设备的网桥接口

#ifdef CONFIG_BR_EXT
void netdev_br_init(struct net_device *netdev)
{
	//内核 netdev_priv
	_adapter *adapter = (_adapter *)rtw_netdev_priv(netdev);

#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35))
	rcu_read_lock();
#endif

	/* if(check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE) == _TRUE) */
	{
		/* struct net_bridge	*br = netdev->br_port->br; */ /* ->dev->dev_addr; */
		#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
		if (netdev->br_port)
		#else
		//在添加桥接口时(br_add_if),调用函数(netdev_rx_handler_register)注册rx_handler,将网桥接口赋值给rx_handler_data变量
		if (rcu_dereference(adapter->pnetdev->rx_handler_data))
		#endif
		{
			struct net_device *br_netdev;

			//内核函数dev_get_by_name
			br_netdev = rtw_get_bridge_ndev_by_name(CONFIG_BR_SUPPORT_BRNAME);
			if (br_netdev) {
				memcpy(adapter->br_mac, br_netdev->dev_addr, ETH_ALEN);
				dev_put(br_netdev);
				RTW_INFO(FUNC_NDEV_FMT" bind bridge dev "NDEV_FMT"("MAC_FMT")\n"
					, FUNC_NDEV_ARG(netdev), NDEV_ARG(br_netdev), MAC_ARG(br_netdev->dev_addr));
			} else {
				RTW_INFO(FUNC_NDEV_FMT" can't get bridge dev by name \"%s\"\n"
					, FUNC_NDEV_ARG(netdev), CONFIG_BR_SUPPORT_BRNAME);
			}
		}

		adapter->ethBrExtInfo.addPPPoETag = 1;
	}

#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35))
	rcu_read_unlock();
#endif
}
#endif /* CONFIG_BR_EXT */

Linux内核中有两种获取网络设备的桥接口方法,其中一种是在控制路径上;另一种是在数据路径上。

https://blog.csdn.net/sinat_20184565/article/details/80390514

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值