mac80211解析四

本文详细解析mac80211驱动中Station的创建过程,从用户空间通过nl80211发起请求,分配对象空间,设置station参数,到加入管理结构,并最终通知驱动。同时,介绍了Station的删除操作,如何逆向执行添加时的步骤。
摘要由CSDN通过智能技术生成

mac80211中创建station由用户空间通过nl80211发起,首先要分配sta_info对象空间,sta_info的定义如下:



/**
 * struct sta_info - STA information
 *
 * This structure collects information about a station that
 * mac80211 is communicating with.
 */
struct sta_info {
    /* General information, mostly static */
    struct list_head list, free_list;
    struct rcu_head rcu_head;
    struct sta_info __rcu *hnext;
    struct ieee80211_local *local;
    struct ieee80211_sub_if_data *sdata;
    struct ieee80211_key __rcu *gtk[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS];
    struct ieee80211_key __rcu *ptk[NUM_DEFAULT_KEYS];
    u8 gtk_idx;
    u8 ptk_idx;
    struct rate_control_ref *rate_ctrl;
    void *rate_ctrl_priv;
    spinlock_t lock;

    struct work_struct drv_unblock_wk;

    u16 listen_interval;

    bool dead;

    bool uploaded;

    enum ieee80211_sta_state sta_state;

    /* use the accessors defined below */
    unsigned long _flags;

    /* STA powersave lock and frame queues */
    spinlock_t ps_lock;
    struct sk_buff_head ps_tx_buf[IEEE80211_NUM_ACS];
    struct sk_buff_head tx_filtered[IEEE80211_NUM_ACS];
    unsigned long driver_buffered_tids;

    /* Updated from RX path only, no locking requirements */
    unsigned long rx_packets;
    u64 rx_bytes;
    unsigned long wep_weak_iv_count;
    unsigned long last_rx;
    long last_connected;
    unsigned long num_duplicates;
    unsigned long rx_fragments;
    unsigned long rx_dropped;
    int last_signal;
    struct ewma avg_signal;
    int last_ack_signal;

    u8 chains;
    s8 chain_signal_last[IEEE80211_MAX_CHAINS];
    struct ewma chain_signal_avg[IEEE80211_MAX_CHAINS];

    /* Plus 1 for non-QoS frames */
    __le16 last_seq_ctrl[IEEE80211_NUM_TIDS + 1];

    /* Updated from TX status path only, no locking requirements */
    unsigned long tx_filtered_count;
    unsigned long tx_retry_failed, tx_retry_count;
    /* moving percentage of failed MSDUs */
    unsigned int fail_avg;

    /* Updated from TX path only, no locking requirements */
    u32 tx_fragments;
    u64 tx_packets[IEEE80211_NUM_ACS];
    u64 tx_bytes[IEEE80211_NUM_ACS];
    struct ieee80211_tx_rate last_tx_rate;
    int last_rx_rate_idx;
    u32 last_rx_rate_flag;
    u32 last_rx_rate_vht_flag;
    u8 last_rx_rate_vht_nss;
    u16 tid_seq[IEEE80211_QOS_CTL_TID_MASK + 1];

    /*
     * Aggregation information, locked with lock.
     */
    struct sta_ampdu_mlme ampdu_mlme;
    u8 timer_to_tid[IEEE80211_NUM_TIDS];

    struct ieee80211_tx_latency_stat *tx_lat;

#ifdef CPTCFG_MAC80211_MESH
    /*
     * Mesh peer link attributes
     * TODO: move to a sub-structure that is referenced with pointer?
     */
    u16 llid;
    u16 plid;
    u16 reason;
    u8 plink_retries;
    bool ignore_plink_timer;
    enum nl80211_plink_state plink_state;
    u32 plink_timeout;
    struct timer_list plink_timer;
    s64 t_offset;
    s64 t_offset_setpoint;
    /* mesh power save */
    enum nl80211_mesh_power_mode local_pm;
    enum nl80211_mesh_power_mode peer_pm;
    enum nl80211_mesh_power_mode nonpeer_pm;
#endif

#ifdef CPTCFG_MAC80211_DEBUGFS
    struct sta_info_debugfsdentries {
        struct dentry *dir;
        bool add_has_run;
    } debugfs;
#endif

    enum ieee80211_sta_rx_bandwidth cur_max_bandwidth;

    unsigned int lost_packets;
    unsigned int beacon_loss_count;

    enum ieee80211_smps_mode known_smps_mode;
    const struct ieee80211_cipher_scheme *cipher_scheme;

    /* keep last! */
    struct ieee80211_sta sta;
};

调用了ieee80211_add_station函数来实现创建,ieee80211_add_station函数内容如下:


static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
                 const u8 *mac,
                 struct station_parameters *params)
{
    struct ieee80211_local *local = wiphy_priv(wiphy);
    struct sta_info *sta;
    struct ieee80211_sub_if_data *sdata;
    int err;
    int layer2_update;

    if (params->vlan) {
        sdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);

        if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
            sdata->vif.type != NL80211_IFTYPE_AP)
            return -EINVAL;
    } else
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);

    if (ether_addr_equal(mac, sdata->vif.addr))
        return 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值