IEEE80211_NODE(9) | FreeBSD Kernel Developer's Manual | IEEE80211_NODE(9) |
名称
ieee80211_node — ソフトウェア 802.11 スタックノード管理関数書式
#include < net80211/ieee80211_var.h> struct ieee80211_node *
ieee80211_find_rxnode( struct ieee80211com *, const struct ieee80211_frame_min *);
struct ieee80211_node *
ieee80211_find_rxnode_withkey( struct ieee80211com *, const struct ieee80211_frame_min *, ieee80211_keyix);
struct ieee80211_node *
ieee80211_ref_node( struct ieee80211_node *);
void
ieee80211_unref_node( struct ieee80211_node *);
void
ieee80211_free_node( struct ieee80211_node *);
void
ieee80211_iterate_nodes( struct ieee80211_node_table *, ieee80211_iter_func *f, void *arg);
void
ieee80211_dump_nodes( struct ieee80211_node_table *);
void
ieee80211_dump_node( struct ieee80211_node *);
解説
802.11 のデバイスドライバをサポートする net80211 レイヤ (層) は、 ieee80211com 構造の ic_sta エントリで“node table” (ノードテーブル) を呼び出した相手側 (peer) ステーションのデータベースを維持します。ステーションモード vap は、ステーションが関連しているアクセスポイントのためのエントリを作成します。 AP モード vap は、関連ステーションのためのエントリを作成します。 adhoc とメッシュモード vap は、隣のステーションのためのエントリを作成します。 WDS モード vap は、相手側ステーションのためのエントリを作成します。すべての vap のためのステーションは、同じテーブルにあります。各ノードエントリには、それを作成した vap を識別する ni_vap フィールドがあります。ある場合には、(例えば、また、ダイナミックな WDS について、ap vap に関連するステーションは、WDS vap の相手側となるかもしれないので) エントリは、複数の vaps によって使用されます。ノードテーブルエントリは、カウントされる参照です。すなわち、エントリが再要求されるときを決定するすべての長期の参照のカウントがあります。参照は、エントリが、フレームがキューに入れられている間に、再要求されないことを保証するためにステーションに送信されたすべての飛行中 (in-flight) のフレームによって、保持されます、そうでなければ、ドライバによって保持されます。テーブルエントリを検索するルーチンは、“held reference” (保持された参照) (すなわち、増加された参照カウントがあるテーブルエントリへのポインタ) を返します。 ieee80211_ref_node() と ieee80211_unref_node() 呼び出しは、ノードの参照カウントを明白に増加するか、または減少させますが、まれにしか使用されません。ほとんどの呼び出し側が参照を解放するために ieee80211_free_node() を使用する代わりに、そして、カウントが 0 になるなら、テーブルエントリを再要求します。
ステーションテーブルとそのエントリは、いくつかの方法でドライバに公開されます。ステーションに転送された各フレームは、 m_pkthdr.rcvif フィールドの関連ノードへの参照を含んでいます。この参照は、転送処理が終了したとき、ドライバによって再要求されなければなりません。受信された各フレームに関して、ドライバは、フレーム“up the stack”のディスパッチに使用するためにテーブルエントリを検索しなければなりません。この検索は、暗黙にテーブルエントリへの参照を取得し、ドライバは、フレーム処理が完了されるとき、参照を再要求しなければなりません。そうでなければ、ドライバは、重要な情報としてステートマシンの変更を扱うことが、データ構造で維持されるときに、 iv_bss ノードの内容を頻繁に検査します。
ノードテーブルは、ドライバには不透明です。エントリは、事前に定義された API の 1 つを使用して検索されるか、または ieee80211_iterate_nodes() 呼び出しは、ノードごとの処理を行うため、または何らかの標準的でない検索メカニズムを実装するためにすべてのエントリを通して繰り返すために使用されます。 ieee80211_iterate_nodes() は、デバイスごとに単一でスレッド化されるので、関連する取り組の処理は、かなり実質的であるので、慎重に使用されるべきであることに注意してください。
2 つのルーチンが、デバッグのためのコンソールにノードの内容を印刷するために提供されています: ieee80211_dump_node() は、単一ノードの内容を表示し、一方 ieee80211_dump_nodes() は、指定されたノードテーブルの内容を表示します。また、ノードは、“show node”指示がある ddb(4) を使用して表示され、“show statab”でステーションノードテーブルを表示することができます。
ドライバのプライベート状態
ノードデータ構造は、ドライバのプライベートな状態を含むようにドライバによって拡張されます。これは、ノードテーブルエントリを割り付けるために使用される ic_node_alloc メソッドを上書きすることによって、行われます。ドライバのメソッドは、 ieee80211_node 構造の拡張である構造を割り付けなければなりません。例えば、 iwi(4) ドライバは、次のようなプライベートなノード構造を定義します:
struct iwi_node { struct ieee80211_node in_node; int in_station; };
そして、次に、これを行うプライベートな割り付けルーチンを提供します:
static struct ieee80211_node * iwi_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN]) { struct iwi_node *in; in = malloc(sizeof(struct iwi_node), M_80211_NODE, M_NOWAIT | M_ZERO); if (in == NULL) return NULL; in->in_station = -1; return &in->in_node; }
ドライバによって割り付けられたノードを再要求するとき、 net80211 状態が再要求されることを保証するために“parent method” (親メソッド) が呼び出されなければならないことに注意してください。例えば:
static void iwi_node_free(struct ieee80211_node *ni) { struct ieee80211com *ic = ni->ni_ic; struct iwi_softc *sc = ic->ic_ifp->if_softc; struct iwi_node *in = (struct iwi_node *)ni; if (in->in_station != -1) free_unr(sc->sc_unr, in->in_station); sc->sc_node_free(ni); /* invoke net80211 free handler */ }
ノードが再要求されることを引き起こすかもしれない参照を保持することを避けるために慎重でならないことに注意してください。 net80211 は、最後の参照がデータ構造で再要求されるとき、ノードを再要求します。しかしながら、ドライバが追加の参照を保持するなら、 net80211 は、これとテーブルエントリが再要求されないことを認識しません。ドライバが ic_node_cleanup および/または、 ic_node_free メソッドを上書きするなら、そのような参照を必要とするべきではありません。
キーテーブルサポート
ノードテーブル検索は、通常ステーションの mac アドレスのハッシュを使用して行われます。フレームを受信するとき、これは、転送側のためのノードテーブルエントリを見つけるために十分です。しかし、また、いくつかのデバイスは、各フレームで受信されるデバイス状態の送信ステーションを識別し、“keytab”と呼ばれる片方のテーブルを使用する受信で検索を最適化するためにこのデータを使用することができます。このテーブルは、テーブルインデックスを使用する任意のロックなしで取って来ることができる別々のノードテーブル参照を記録します。この論理は、 ieee80211_find_rxnode_withkey() 呼び出しで扱われます: keytab エントリがを指定されたインデックスを使用して見つけられるなら、直接それを返します。そうでなければ、正常な検索が行われ、keytab エントリは、指定されたインデックスを使用して書き込まれます。指定されたインデックスが IEEE80211_KEYIX_NONE であるなら、テーブルの更新なしで正常に検索が行われます。April 28, 2010 | FreeBSD |