Trema/MyRoutingSwitch(5), Topology Change and Re-route(8)

トポロジ変化の処理についてどういう対応ができそうか、というのについてこれまであれこれ見てきたのですが、気づいたところとかをだらっと上げておきたいと思います。

前提・条件を明示する

作っているうちに暗黙的に仮定している物があって、そういうのが「予想外の動作」につながってきます。…というのにいろいろやっていると気づかされる。例えばこういうの。

  • 環境内はすべて openflow switch で構成されて(hop-by-hop model)いる。すべての endpoint node は openflow switch に直接接続されている。
  • packet-in dpid/in-port は endpoint node が接続されている場所でははない。あるいは、packet-in は常に endpoint node が接続されているスイッチからだけ発生するわけではない。
  • arp table はかならず endpoint position の情報を記録することにする。
  • endpoint node は lldp をしゃべらない。(今の仕掛けだと、endpoint に lldpd とか入れて lldp packet 吐かせると、多分上手く動かない)

今までの前提(トポロジ変化が起きない)では、それなりに成立していた暗黙の仮定が、トポロジ変化アリになったときにマッチしなくなります。すべての状況を見越して何かできるわけではないのですが、その時々の条件設定はちゃんと考えておく必要があるでしょう。例えば、今は 1 フロー(L2/L3)に対して 1 経路(固定)なわけですがトラフィック種別(L4)とか流量によるバランシング動作とかを考えるとどうなるか? 今は 1 L2 domain (1 broadcast domain) 環境を想定しているけど VLAN 的な動作やあるいは L3 の動作を入れて複数の L2 domain を操作するように変えるとどうなるか? それぞれ、またひっくり返る条件があるはず。

……というような話を考えていくつかテスト組んでて気づいたんですが、じつは、環境の初期状態(arp table が空っぽ)の状態では、スイッチ間のトポロジに寄らず broadcast/flooding してしまうので、src/dst hosts 間に経路がない場合でもパケットが届いてしまったりします。(management network 経由で controller が dst にパケットを投げてしまう。) この辺は自律分散ネットワーク的な考え方だと思考が追いつかなかったですね……。OpenFlow Network 側でこれ(BUM*1: broadcast/fooding) をコントロールしようと思うと、トポロジに基づいて flooding を指示するスイッチを判断してやらなければいけない → 環境内、スイッチ間のパスがあるかどうか経路情報を持っておかなければいけない、ということに。うへえ。今はそこまでやっていません…。

テストについてのアレコレ

単一/複数, 直接/間接のテストケースを設定すること

これはまあ、一般的なソフトウェア開発におけるテストケースの設定の定石でしょう。

  • 「1以上の複数」については「単数」テストと「複数」テストが必要。
    • 思った以上に単数のテスト(今回なら単一スイッチのみのテスト)で引っかかりました。
    • たとえば、経路(path)の計算: 処理の上では、last hop + last hop までの経路、を求めるようになっているので、経路が出てこない → 間がつながっていない or 単一のスイッチのみで構成されている、という場合分けが起きています。複数スイッチ環境のみを念頭に置いて処理を組むと、実は単一スイッチ環境で上手く動かない、という状況が起きます。
    • 1個/2個/3個以上、くらいでパターン分けしておくのが無難なんだろうなあ。
  • 通常動作のトリガがかからないところでのイベント発生を試すこと。
    • 今回の例だと、通常 packet-in が上がらないはずの、経路中間でのリンクアップ・リンクダウンの発生 → フロー書換によるパケットのスイッチバック動作。
    • スイッチの役割について、いくつかのパターン分けというかグループ分けを考えておくのがいいと思う。Edge (endpointが接続されている), Transport (スイッチ間中継)というのがひとつのパターンとしてあるはず。
      • そういえば、ポート落とすテストも、本当はスイッチ間リンクのポートを落とす(スイッチ間リンクダウン)と endpoint のつながっているところのポートを落とすのとあるけど、後者のテストは今やってないな…。endpoint のポートが落ちたときは arp table のエントリを消す、とかそういう処理があるはず。

あとは controller の組み方次第かなあ。イベントの基点(処理のトリガ)がどこで起こるかというのはチェックポイントのひとつになるはず。基点・基点と直接隣接しているところ・その他(直接つながっていないところ)、で何が起きるか。

変化のシーケンスと環境内の状態を追いかけること

これは「ネットワークのテスト」としての観点。

  • いくつかステップを踏まないと、不具合が起きる状況が発生しない、というのが結構厄介でした。
    • 例えば、リンクアップによるトポロジ変化時の処理の場合、リンク落とす→通信→リンク上げる→通信、という手順を経てようやく、不要になったフローエントリが本来残すべきフローエントリ情報を消してしまう、というバグに遭遇できるわけです。こういうのはただ単純に落として上げて終わり、みたいな単純なテストを組むだけだと見えてこない(見えてこなかった)ですね。*2
    • なるべく規模の小さなテスト環境で、なるべく汎用的な状態を作れるかどうか、というのがテスターには求められることになりそうです。
  • あと、今のところちゃんとテストしきれていないけど、各種情報の timeout/age-out の動作についてどう動くか、みたいなところもチェックが必要。第5回にもちょっと書いたけど、テストする上では age out しない方がやりやすいこともあるし。コントローラ内にハードコードせず設定ファイルとか別出しして、テストシナリオから操作できるようにしておいた方がいいだろう。
    • 要は、CRUD な処理のサイクルをちゃんと見ましょう…と。あと「過程で発生する不要な物」が発生していないか、発生している場合、それは放置して良いのか悪いのか、とか。
テストツールとしての trema
  • 便利なところ
    • スクリプトだけでテスト環境が定義できる・テスト手順と状態(情報)取得がかけるというのはものすごく便利ですね…。
      • 実機ベースのテストって、個別のデバイスにログインして実際にリンク落として機材の状態確認して……というテスト手順を実行することそのものにすごくコストがかかる。ましてや個別のデバイスで状態を取って、テストシーケンスを通して全体でどういう動作が起こっていたのかってのを見ていくのは、それはもう面倒くさいですよ。
      • シミュレーション上のテストなので実機ベースにするとまた別な問題がありそうですが、それでも、VM ひとつあればこういうのが作れて動作が追えるというのはまあ楽ですわ。
      • とにかく、同じテストを何回も繰り返せるというのは本当に楽だな…。上にも書いたけど、問題になる状況を作り出すまでに複数の手順を経る必要があるのが普通なので、スクリプト書いて後は自動処理っていうのが本当に楽です。実環境でもこういうのちゃんとやれるようになったらいいのに。
  • 不便なところ
    • これは trema というよりは ovs の話なんですが、スイッチのポート番号が実際にシミュレーション実行してみないとわからないっていうのがやりにくいなあと。
      • トポロジ変化とそれに伴うフロー操作、という話だと、どうしてもフロー情報のチェックにおいてポート番号がどう付け替えられるか、というのが必要になってきます。が、環境定義(conf作成)の段階だとスイッチ間のポート番号が何番になるかわからないんだよね。
      • 1回定義された環境(conf file)についてはポート番号が同じになるので、テスト上は1回トポロジ確認のためだけの実行やればいいんだけど。シナリオ書く前に一度実行して、出力されるポート番号情報を図の上に記載して、テストシナリオ書き換えて…というのをやるのがなあ。conf 各段階でポート番号も決め打ちできたらいいのになあ、と思う。
    • phost については前にちょっと書いたけど、「自分宛にきていないけど届いてしまっているパケット」の情報が見えるともうちょっと細かいテストがやれるかなあ。
      • 上にも書いたけど、BUM の処理ってすごく厄介なんだよね。届いてはいけない(届かないで欲しい) broadcast/flooding が届いている…みたいなチェックが今のシミュレータだと難しいので、そのへんどうにかなるといいなあ。
      • 今は単一 L2 domain という前提でやっているからいいけど、複数セグメントとかマルチテナントほげほげ…みたいなのをやろうとすると、BUM をどうハンドリングするか……テストとしては BUM が想定通りにハンドリングできているかどうか、というのが確認できる必要がある。従来のネットワークでだってこういうのは難しいんだけどね。さてどうしたものやら。
    • もうひとつ。ポート(リンク)を新しく作るとか、host を別なポート(別なスイッチ)に付け替える、とか、そういうのの操作ができるといいなあ。別名で同一 mac/ip なホスト用意しておいて port up/down でつけ変わったように見せる、とかやれば良いのか? endpoint port の up/down とあわせて、host の移動とかもまだちゃんとテストできてない。

この辺チビチビやってるあいだに Interop Tokyo 2013 があって、OpenFlow Showcase とかいってたんですが、

これ見て、こういうの欲しくなるよねえ…と思いましたね……。Volt はとても開発者視点なツールだと思いました。誰が必要とするって、OpenFlow 使ってコントローラ書こうとしてる人がまずほしがるんじゃないかあれは。今回もテストやるたびに毎度毎度 dump flows して何がどう流れるか追いかけていたわけですが。こういう情報を食わせると可視化して表示してくれるツールとかホント欲しいわ…。OF1.0 のレベルでこれだから、OF1.3 以降マルチテーブルとか使うようになったらどうなるんだよ……と。

まとめ

ざっと思いついたことを並べているだけなので、まとめも何もないのですが。

感想としてはやっぱり、やってみないとわかららないことがやっぱり多いよなあ、と。いつも書いてる気がしますが。

お仕事柄、製品調査とか技術動向調査とかやるわけですが、こういう技術面の話がわからないと、そのプロダクトがどういう思想で・どういう原理で・どういうことをしようとしているのか、というのがなかなかわからないんだよね。「なんか上手いことトラフィックどうにかしてくれる魔法の箱」としてみていいのはコントローラ上位 (Northbound API から上)のレベルで使ったり作ったりする人でしょう。システム基盤としてのネットワーク、リソースとしてのネットワーク……「ネットワークそのもの」見る必要がある人は、やっぱりある程度手を動かしてトレーニングしていくのがいいんじゃないかなーと思いました。

*1:Broadcast, Unknown Unicast, Multicast

*2:単純なテストが要らないというわけではなくて、それは必要です。ただそれだけだと見えない物もやっぱりあるって事で。