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

はじめに

引き続き MyRoutingSwitch いじり。複数スイッチで経路選択ができるのであればやっぱりトポロジ変更時に物理経路切り替えて通信を継続させる、というのをやりたいわけです。ということで試してみました。

トポロジ変更

複数スイッチ環境におけるトポロジ変更は大きく以下のように分類されます。

  • リンク状態の変化(リンクダウン・リンクアップ)
    • スイッチ間リンクの状態変化: ネットワークトポロジの変化
    • エンドポイントノードの状態変化: PC等通信ノードの状態変化あるいは移動
  • スイッチの状態変化(スイッチの起動・停止)
    • スイッチの状態変化による、付随する複数のリンクアップダウン
    • OpenFlow Controller において "スイッチ" が Secure Channel 接続において認識されていることを考えれば、何らかの理由でセキュアチャネルの状態が変わる(チャネル確立・停止)もスイッチの状態変更として加味する必要がある。

いまはまずリンクダウンを中心に考えていきます。

OpenFlow1.0/Tremaにおけるトポロジ変更

スイッチのポート状態変更は、スイッチからコントローラへ、OFPT_PORT_STATUS メッセージを送ることで通知されます。Trema では port_status というイベントハンドラでキャッチします。あと、スイッチの起動停止(セキュアチャネルによるスイッチの補足)は switch_ready/switch_disconnected ですね。この辺は便利なもんです。

気をつけるのは、こうしたイベントが同時に・複数・非同期で発生するということかな。スイッチが起動(あるいは停止)すると併せて周辺スイッチのリンクアップ(リンクダウン)が発生します。セキュアチャネルが確立されても周辺のスイッチとつながっていない(スタンドアロンスイッチ)なんて場合もあるわけで。

…というあたり、トポロジ変更イベントの補足と情報取得については、ベースにした yasuhito/ruby_topology で既に実装済みなので、あとは経路制御処理をどうにかすれば良いと。

そのまえに、どういうイベントに対してトポロジ変更処理を行っているのかおさらいをしておきます。


MyRoutingSwitch の動作おさらい

複数スイッチ環境における動作を見ていくわけですが、現状の経路制御動作の処理を復習しておきます。

  • Host: host(a), host(b)
  • Switch: sw1, sw2, sw3, sw4

が一列に接続されている環境を例に取ってみます。以下は初期状態(ARP Table も Flow Table も空っぽの状態)


host(a) to host(b)

host(a) から host(b) に対して通信を開始します。


  • [1] host(a) が host(b) へパケットを送信。
  • [2] sw1 は、入ってきたパケットを処理するフローエントリがないので packet-in を発生させる。
  • [3] Controller は、パケットが入ってきた位置を arp table に記録する。
  • [4] 宛先(host(b)) の位置がわからない(arp tableにない)ので、各スイッチでフラッディングする。
    • いまの実装では packet-in があった場所(dpid & in-port)を記録しておくことを覚えておいてください。
  • [5] host(b) はフラッディングされたパケットを受信。
host(b) to host(a)

host(b) は host(a) に返信します。


  • [6] host(b) は host(a) にパケット(リプライ)を送付。
  • [7] sw4 は、入ってきたパケットを処理するフローエントリがないので packet-in を発生させる。
  • [8] Controller は、パケットが入ってきた位置を arp table に記録する。宛先(host(a)) の位置がわかる(arp tableにある)ので、host(b)→host(a) への経最短路を計算する。
  • [9] Controller は、得られた経路の中間スイッチそれぞれにフローエントリを送る(flow mod)。また末尾(sw1)については packet-out を同時に行う。
    • 末尾については、フローエントリを削減するために宛先のみマッチ (ANY:"*"→host(a)) にしてあります。
  • [10] sw1 は packet-out メッセージを受け取って、host(b) が送付したパケットを host(a) 向けに出力する。

host(a)-host(b) 間の双方向にパケットが送付された時点で、片方向(host(b)→host(a))のフローエントリができます。

host(a) to host(b)

また host(a) が host(b) 宛てにパケットを送ります。


  • [11] host(a) は続けて host(b) にパケットを送付。
  • [12] sw1 は相変わらず対応するフローエントリがないので packet_in を発生させる。
  • [13] Controller は、パケットが入ってきた位置を arp table に記録する。宛先(host(b)) の位置がわかる(arp tableにある)ので、host(a)→host(b) への経最短路を計算する。
  • [14] Controller は、得られた経路の中間スイッチそれぞれにフローエントリを送る(flow mod)。また末尾(sw4)については packet-out を同時に行う。
  • [15] sw4 は packet-out メッセージを受け取って、host(a) が送付したパケットを host(b) 向けに出力する。

host(a)-host(b) 間で1往復半パケットが行き来した時点で、双方向(host(b) <=> host(a))のフローエントリができます。ここから先は、フローエントリのエイジアウトが起きるまで、host(a)-host(b) 間のトラフィックはすべてスイッチによって処理され、コントローラとスイッチとのメッセージ交換は発生しません。

まとめ

まずは基礎の復習でした。

次回は re-route 処理の実装方針と問題点について。