Open vSwitchソースコードリーディングに向けて その5
PORTINGの内容の続き
移植の戦略
OSのネットワークデバイスに対応したnetdevを実装したのちの移植戦略としては以下の3つがとれる。
一番手間がかからないのは"userspace switch"を使うこと。この場合、パケットの受信動作に対応するようにnetdevを実装していれば、追加のコードを書く必要はない。一方で、全てのパケットがovs-vswitchdのプロセスを通過するので性能は低くなる。"userspace swtich"の構成の仕方はINSTALL.userpaceに書いてある。
ユーザー空間のスイッチを使うことが移植の際に適切ではない場合には、よりコードを書く必要がある。"ofproto provider"か"dpif provider"どちらかを実装するかを選択でき、どちらを選択すべきなのかは状況によって異なる。
- ofproto providerを使う場合においてのみハードウェア的にワイルドカードをサポートする機能(たとえば、ACLテーブルやTCAM)を十分に活用できる。
- dpif providerを使うことで、Open vSwitchでサポートされているボンディング、LACP, 802.1ag, 802.1Q VLANなどの機能を活用できる。それらの機能についてハードウェアのサポートがある場合には、ofproto providerでは、独自の実装が必要になる。
- 通常は、dpif providerを実装する方が容易で、最もソフトウェアスイッチングに適した方法である。dpif providerを用いる場合には、ワイルドカードのルールをexact-matchエントリーの中に"爆発?"させる。
ofproto provider
"ofproto provider"は、ofprotoが直接OpenFlow-capableスイッチをモニターしたり制御したりするために使うものである。新規のハードウェア、ソフトウェアのためのofproto providerを実装するためのインターフェイスがofproto/ofproto-provider.hの中のofproto_class構造体で定義されている。この構造体には、多くの関数ポインタがあり、それぞれについてその動作の詳細を説明するコメントがある。もしそのコメントの意味が不明確であれば、バグとして報告してほしい。
ofproto providerのインターフェイスはまだ十分ではないので、もしあなたの目的にそぐわない場合には教えてほしい。改善するようにする。
dpif providerを書く
"dpif"と呼ばれるdatapathを操作するためのライブラリの最上部に作られた"ofproto-dpif"と呼ばれる組み込みのofproto providerがOpen vSwitchにある。"datapath"は単純なフローテーブルであり、exact-matchフローのみをサポートする。つまり、ワイルドカードはサポートしていない。ネットワークデバイスにパケットが到着すると、datapathはexact-matchテーブルから対応するものを探す。一致するものが存在すれば、対応するアクションを実行する。一致するものがなければ、ofproto-dpifにパケットが渡される。ofproto-dpifは、OpenFlowのフローテーブル(ワイルドカードをサポートしている)の状態を維持するものである。このフローテーブルに合致するならば、ofproto-dpifはそのアクションを実行し、新しいexact-matchエントリーとしてdpifフローテーブルにエントリーを追加する。(それ以外の場合には、ofproto-pdifはofprotoにパケットを渡し、パケットがOpenFlowコントローラに送信されるように設定されているならば、OpenFlowコントローラにパケットが送信される)
"dpif"ライブラリは自信の多くの機能を"dpif provider"に委譲している。以下の図が、dpif providerがどのようにOpen vSwtichのアーキテクチャに合わせているのかを示したものである。
_ | +-------------------+ | | ovs-vswitchd |<-->ovsdb-server | +-------------------+ | | ofproto |<-->OpenFlow controllers | +--------+-+--------+ _ | | netdev | |ofproto-| | userspace | +--------+ | dpif | | | | netdev | +--------+ | | |provider| | dpif | | | +---||---+ +--------+ | | || | dpif | | implementation of | || |provider| | ofproto provider |_ || +---||---+ | || || | _ +---||-----+---||---+ | | | |datapath| | kernel | | +--------+ _| | | | |_ +--------||---------+ || physical NIC
lib/dpif-provider.hの中にあるdpif_struct構造体は、新しいハードウェア、ソフトウェアのためのdpif providerを実装するために必要なインターフェイスを定義している。この構造体には、多くの関数ポインタがあり、それぞれについてその動作の詳細を説明するコメントがある。もしそのコメントの意味が不明確であれば、バグとして報告してほしい。
既存のdpifの実装は2種類あり、それらは移植の際に有用な実例として参考になるはずである。
- lib/dpif-linux.cはLinuxに特化したdpifの実装であり、Open vSwitch特有のカーネルモジュール(datapath/のディレクトリに格納されている)とやりとりを行う実装である。カーネルモジュールはスイッチングにに必要な作業全てを実行し、どのフローテーブルのエントリーにもマッチしないパケットをユーザー空間に渡す。dpifの実装は必然的にこのカーネルモジュールのラッパーになる。
- lib/dpif-netdev.cは一般的なdpifの実装で、スイッチング動作をその内部で全て行っている。Open vSwitchのユーザー空間のスイッチがこれによって実装されている。
その他
- uint_16t, uint32_t, uint64_tというホストバイトオーダーの固定長の型が使われている
- ovs_be16, ovs_be32, ovs_be64はネットワークバイトオーダーの固定長の型が使われている
- それぞれビット長が等しいものは等価なものであるが、使用意図を明確にするために名前を変えている
- lib/entropy.cは、起動時に/dev/urandomを読み出すことで得られる高品質な乱数のシードを得ることが出来るということを前提にしている。対象とするプラットフォームでその前提が成立しないなら変更する必要がある。
- vswitchd/system-stats.cはLinuxでのいくつかの統計情報の取得方法だけを知っている。対象とするプラとフォームにあわせて実装が必要になる可能性がある。