mac80211을 읽어 보았습니다.

목적



최근 무선 통신에 대한 수요가 해마다 증가하고 있다.
한편, 무선 통신의 활용에 관해서는 Qiita에도 다루어지고 있지만, IEEE802.11에 대한 기사는 매우 적다(2017년 7월 현재, 10개 정도).
mac80211에 대한 지식을 자신 안에서 정리하는 것이 주된 목적이지만, 무선 통신의 하층에 흥미를 가져 주는 사람이 혼자라도 늘려 주면 다행입니다.

mac80211 배경



무선 LAN을 이용한 어플리케이션에는 hostapd나 wpa_supplicant 등이 있다.
이것들을 이용함으로써 Linux 단말의 AP화나 STA화가 가능하다.
hostapd나 wpa_supplicant는 mac80211이나 cfg80211이라는 커널을 사용하고 있다.
mac80211과 cfg80211이 NIC나 Wi-Fi 동글(하드웨어)과 애플리케이션(사용자 공간)의 교량을 하고 있다(정확하게 말하면 사이에 드라이버가 존재한다).
mac80211은 말 그대로 IEEE802.11의 MAC 계층 부분을 담당하고 있다. 종래의 시스템에서는 MAC층의 많은 처리는 하드웨어가 해 왔다. 최근에는 Atheros 등을 중심으로 IEEE802.11에서 규격화된 많은 처리를 소프트웨어로 처리하는 흐름이 되고 있다.

mac80211 구성



아래 그림은 리눅스에서 사용되는 커널의 구성을 보여준다[1]. ( htps : // 우우레 s s. 우키. 케 r네 l. 오 rg/_메아아/엔/으로 ゔぇぺぺrs/도쿠멘들 온/마 c80211. pdf )

기본적으로 무선 LAN에 대한 정보는 일단 mac80211에 전달됩니다.

mac80211의 예



커맨드 라인에서 "iw dev wlan0 info"를 입력하면 연결된 AP의 정보 (수신 전력, MAC 주소 등)가 표시되어야합니다.
이러한 정보는 net/mac80211.h에 정의된 구조 ieee80211_bss_conf에 저장된다. 이 구조체에는 자신이 접속하고 있는 BSS의 정보가 저장되어 있다. 저장된 변수는 매우 많기 때문에 여기에서는 일부만 소개합니다.

/include/net/mac80211.h
/**
 * struct ieee80211_bss_conf - holds the BSS's changing parameters
 * 
 * This structure keeps information about a BSS (and an association
 * to that BSS) that can change during the lifetime of the BSS.
 * (省略)
 * @sync_tsf: last beacon's/probe response's TSF timestamp (could be old
 *  as it may have been received during scanning long ago). If the
 *  HW flag %IEEE80211_HW_TIMING_BEACON_ONLY is set, then this can
 *  only come from a beacon, but might not become valid until after
 *  association when a beacon is received (which is notified with the
 *  %BSS_CHANGED_DTIM flag.). See also sync_dtim_count important notice.
 * (省略)
 * @bssid: The BSSID for this BSS

sync_tsf에는 AP가 전송하는 Beacon 프레임에 포함된 timestamp의 정보가 포함되어 있다.
bssid에는 말 그대로 BSSID에 관한 정보가 포함되어 있다.
ieee80211_bss_conf에는 AP의 송신 전력이나 Beacon 프레임의 송신 간격 등의 정보도 포함되어 있다. 이하에 구조체의 구성을 나타낸다.

/include/net/mac80211.h
struct ieee80211_bss_conf {
    const u8 *bssid;
    /* association related data */
    bool assoc, ibss_joined;
    bool ibss_creator;
    u16 aid;
    /* erp related data */
    bool use_cts_prot;
    bool use_short_preamble;
    bool use_short_slot;
    bool enable_beacon;
    u8 dtim_period;
    u16 beacon_int;
    u16 assoc_capability;
    u64 sync_tsf;
    u32 sync_device_ts;
    u8 sync_dtim_count;
    u32 basic_rates;
    struct ieee80211_rate *beacon_rate;
    int mcast_rate[NUM_NL80211_BANDS];
    u16 ht_operation_mode;
    s32 cqm_rssi_thold;
    u32 cqm_rssi_hyst;
    s32 cqm_rssi_low;
    s32 cqm_rssi_high;
    struct cfg80211_chan_def chandef;
    struct ieee80211_mu_group_data mu_group;
    __be32 arp_addr_list[IEEE80211_BSS_ARP_ADDR_LIST_LEN];
    int arp_addr_cnt;
    bool qos;
    bool idle;
    bool ps;
    u8 ssid[IEEE80211_MAX_SSID_LEN];
    size_t ssid_len;
    bool hidden_ssid;
    int txpower;
    enum nl80211_tx_power_setting txpower_type;
    struct ieee80211_p2p_noa_attr p2p_noa_attr;
    bool allow_p2p_go_ps;
    u16 max_idle_period;
    bool protected_keep_alive;
};

여기에서는 BSS의 정보만을 접했지만, 그 밖에도 MCS 번호나 대역폭 등의 정보를 가진 구조체도 정의되어 있다.

수신 측에서 mac80211의 간단한 흐름



위에서는 주로 mac80211.h를 언급했지만, mac80211에는 그 밖에도 많은 소스가 포함되어 있다.
프레임의 송신 수신에 관해서는/net/mac80211/tx.c나 rx.c.
다른 AP의 정보를 검사하는 스캔의 경우/net/mac80211/scan.c.
MLME 부분을 처리하는/net/mac80211/mlme.c.
본 기사에서는 모든 것을 설명할 수는 없지만, 수신측에서의 간단한 흐름을 설명한다.
1. 드라이버가 프레임을 획득
2. 수신 프레임을 ieee80211_rx()에 전달합니다. mac80211로 보냅니다. 이 때 드라이버로부터 수신 한 정보를 ieee80211_rx_status에 저장한다.
3. ieee80211_rx_data를 ieee80211_prepare_and_rx_handle()에 전달합니다. 이 중에서 수신 한 프레임의 수신처의 어드레스 등을 확인하여, 수용할지의 여부를 판정한다 (ieee80211_accept_frame ()).
4. 그 후, ieee80211_rx_handlers()에 전달되어 STA측에서 행해지는 다양한 처리를 행한다(ieee80211_rx_h_sta_process, ieee80211_rx_h_ctrl 등).
이하에 위에서 소개한 구조체 ieee80211_rx_status와 ieee80211_rx_data를 나타낸다.

/include/net/mac80211
/**
 * struct ieee80211_rx_status - receive status
 *
 * The low-level driver should provide this information (the subset
 * supported by hardware) to the 802.11 code with each received
 * frame, in the skb's control buffer (cb).
 *
 * @mactime: value in microseconds of the 64-bit Time Synchronization Function
 *  (TSF) timer when the first data symbol (MPDU) arrived at the hardware.
 * @boottime_ns: CLOCK_BOOTTIME timestamp the frame was received at, this is
 *  needed only for beacons and probe responses that update the scan cache.
 * @device_timestamp: arbitrary timestamp for the device, mac80211 doesn't use
 *  it but can store it and pass it back to the driver for synchronisation
 * @band: the active band when this frame was received
 * @freq: frequency the radio was tuned to when receiving this frame, in MHz
 *  This field must be set for management frames, but isn't strictly needed
 *  for data (other) frames - for those it only affects radiotap reporting.
 * @signal: signal strength when receiving this frame, either in dBm, in dB or
 *  unspecified depending on the hardware capabilities flags
 *  @IEEE80211_HW_SIGNAL_*
 * @chains: bitmask of receive chains for which separate signal strength
 *  values were filled.
 * @chain_signal: per-chain signal strength, in dBm (unlike @signal, doesn't
 *  support dB or unspecified units)
 * @antenna: antenna used
 * @rate_idx: index of data rate into band's supported rates or MCS index if
 *  HT or VHT is used (%RX_FLAG_HT/%RX_FLAG_VHT)
 * @nss: number of streams (VHT and HE only)
 * @flag: %RX_FLAG_\*
 * @encoding: &enum mac80211_rx_encoding
 * @bw: &enum rate_info_bw
 * @enc_flags: uses bits from &enum mac80211_rx_encoding_flags
 * @rx_flags: internal RX flags for mac80211
 * @ampdu_reference: A-MPDU reference number, must be a different value for
 *  each A-MPDU but the same for each subframe within one A-MPDU
 * @ampdu_delimiter_crc: A-MPDU delimiter CRC
 */
struct ieee80211_rx_status {
    u64 mactime;
    u64 boottime_ns;
    u32 device_timestamp;
    u32 ampdu_reference;
    u32 flag;
    u16 freq;
    u8 enc_flags;
    u8 encoding:2, bw:3;
    u8 rate_idx;
    u8 nss;
    u8 rx_flags;
    u8 band;
    u8 antenna;
    s8 signal;
    u8 chains;
    s8 chain_signal[IEEE80211_MAX_CHAINS];
    u8 ampdu_delimiter_crc;
};

/net/mac80211/ieee80211_i.h
struct ieee80211_rx_data {
    struct napi_struct *napi;
    struct sk_buff *skb;
    struct ieee80211_local *local;
    struct ieee80211_sub_if_data *sdata;
    struct sta_info *sta;
    struct ieee80211_key *key;

    unsigned int flags;

    /*
     * Index into sequence numbers array, 0..16
     * since the last (16) is used for non-QoS,
     * will be 16 on non-QoS frames.
     */
    int seqno_idx;

    /*
     * Index into the security IV/PN arrays, 0..16
     * since the last (16) is used for CCMP-encrypted
     * management frames, will be set to 16 on mgmt
     * frames and 0 on non-QoS frames.
     */
    int security_idx;

    u32 tkip_iv32;
    u16 tkip_iv16;
};

요약



이번에는 mac80211이 어떤 일을 하고 있는지를 간단히 정리했다.
본문에서는 수신측에 대해서만 접하고 있지만, 향후 송신측에 관한 내용도 추기할 예정이다.

참고문헌



"1" htps : // 우우레 s s. 우키. 케 r네 l. 오 rg/_메아아/엔/으로 ゔぇぺぺrs/도쿠멘들 온/마 c80211. pdf
[2] mac80211 소스 코드

좋은 웹페이지 즐겨찾기