wmaster0接口的简单介绍
wmaster0是linux无线网络设备的主接口,根据官方说明,从linux2.6.32开始删除了这个接口,所以从linux2.6.32版本开始不会再看到这个接口,我们比较熟悉的是类似于waln0这种接口,因为简单来说,一个wlanx(0,1,2,…)接口就代表一张无线网卡。但是,在linux2.6.31以前,所有的发送操作(还有其他一些操作)都要通过wmaster0来实现,下面以ath5k驱动程序为例简单分析一些发送操作这个过程。
首先,从ieee80211_register_hw()函数看看wmaster0的注册过程:
1 … 2 mdev = alloc_netdev_mq(sizeof(struct ieee80211_master_priv), 3 "wmaster%d", ieee80211_master_setup, 4 hw->queues); 5 …
通过alloc_netdev_mq()函数来注册wmaster0接口,其中ieee80211_master_setup是函数名,其原型如下所示:
1 …
2 static const struct net_device_ops ieee80211_master_ops = {
3 .ndo_start_xmit = ieee80211_master_start_xmit,
4 .ndo_open = ieee80211_master_open,
5 .ndo_stop = ieee80211_master_stop,
6 .ndo_set_multicast_list = ieee80211_master_set_multicast_list,
7 .ndo_select_queue = ieee80211_select_queue,
8 };
9
10 static void ieee80211_master_setup(struct net_device *mdev)
11 {
12 mdev->type = ARPHRD_IEEE80211;
13 mdev->netdev_ops = &ieee80211_master_ops;
14 mdev->header_ops = &ieee80211_header_ops;
15 mdev->tx_queue_len = 1000;
16 mdev->addr_len = ETH_ALEN;
17 }
18 …
其中ieee80211_master_start_xmit就是实现真正发送操作的函数,从ieee80211_register_hw()函数继续往下看:
1 …
2 if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
3 result = ieee80211_if_add(local, "wlan%d", NULL,
4 NL80211_IFTYPE_STATION, NULL);
5 …
在这里终于注册了wlan0这个接口,下面简单看一下ieee80211_if_add()函数:
1 … 2 ndev = alloc_netdev(sizeof(*sdata) + local->hw.vif_data_size, 3 name, ieee80211_if_setup); 4 …
再看ieee_if_setup()函数:
1 …
2 static const struct net_device_ops ieee80211_dataif_ops = {
3 .ndo_open = ieee80211_open,
4 .ndo_stop = ieee80211_stop,
5 .ndo_uninit = ieee80211_teardown_sdata,
6 .ndo_start_xmit = ieee80211_subif_start_xmit,
7 .ndo_set_multicast_list = ieee80211_set_multicast_list,
8 .ndo_change_mtu = ieee80211_change_mtu,
9 .ndo_set_mac_address = eth_mac_addr,
10 };
11 …
12 static void ieee80211_if_setup(struct net_device *dev)
13 {
14 ether_setup(dev);
15 dev->netdev_ops = &ieee80211_dataif_ops;
16 dev->wireless_handlers = &ieee80211_iw_handler_def;
17 dev->destructor = free_netdev;
18 }
19 …
其中,dev->netdev_ops = &ieee80211_dataif_ops这是关键,下面看它里面的.ndo_start_xmit = ieee80211_subif_start_xmit成员:
1 int ieee80211_subif_start_xmit(struct sk_buff *skb,
2 struct net_device *dev)
3 {
4 …
5 skb->iif = dev->ifindex;
6 skb->dev = local->mdev;
7 dev->stats.tx_packets++;
8 dev->stats.tx_bytes += skb->len;
9 …
10 dev_queue_xmit(skb);
11 …
12 }
第6行,medv就是wmaster0接口,第10行,调用了dev_queue_xmit()函数,这个函数是网络层进入数据链路层的关键函数:
1 int dev_queue_xmit(struct sk_buff *skb)
2 {
3 struct net_device *dev = skb->dev;
4 …
5 txq = dev_pick_tx(dev, skb);
6 …
7 }
第3行,skb->dev就是wmaster0接口,以后有关网络设备的操作都是用它了,第5行,通过dev_pick_tx()函数选出当前socket所需要的TOS(Type Of Service)队列,想了解TOS和MAC层中关于QoS的可以看看这个函数,这里不分析。
到这里可以看出,发送数据时,上层使用wlan0接口,到了数据链路层以下开始使用wmaster0这个接口实现发送操作。

浙公网安备 33010602011771号