• 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这个接口实现发送操作。

  • 相关阅读:
    linux 命令展示该目录下的所有子目录及文件结构 tree
    ssh-keygen
    centos安装git
    spring-boot parent变更为依赖方式
    centos docker compose安装
    UML——活动图
    UML——构件图
    UML——部署图
    UML——用例图
    UML——关系
  • 原文地址:https://www.cnblogs.com/lknlfy/p/2844194.html
Copyright © 2020-2023  润新知