USENIX 2018の論文読み

軽く読んだので,雑なまとめ.
ほぼ自分用のメモ.

Elastic Scaling of Stateful Network Functions

  • https://www.usenix.org/conference/nsdi18/presentation/woo
  • NFV(Network Functions Virtualization)におけるスケーリングの弾力性は重要な要素
    • 実用レベルでの実現は難しかった
      • 多くのNFs(Network Functions)はステートフル
      • NFを構成するインスタンス同士での状態共有が必要である
      • NFでのスループットとレイテンシの要件を満たしたステート共有の実装は難しい
  • S6を提案
    • パフォーマンスの低下なしにNFにスケーリングの弾力性を提供するフレームワーク
    • ステートをDSO(distributed shared object)とする
      • 弾力性と高パフォーマンスの要件を満たすために拡張したもの
    • NFの管理者は,ステートがどのように分散・共有されているかを気にすることなくプログラミングできる
      • S6が透過的に処理をしてくれる(データの局所性や整合性等を抽象化する)
  • 実験・評価の結果
    • 現在のNFの動的スケーリング手法と比較
      • スケーリング: 100倍のパフォーマンス向上
      • 通常時: 2〜5倍のパフォーマンス向上

Stroboscope: Declarative Network Monitoring on a Budget

  • https://www.usenix.org/conference/nsdi18/presentation/tilmans
  • ISPにとって,ネットワークの動作がどうなっているのか等を正確に知ることは困難
    • エンドホストを制御するのは不可能
    • 大量にトラフィックの統計を取る,という方法に頼るしかなかった
      • 情報の粒度が粗いという問題がある
  • Stroboscopeを提案
    • どんなトラフィックフローでもきめ細かいモニタリングが可能
    • 高レベルのクエリを入力すると,自動でいろいろやってくれる
      • どのフローをミラーリングするか
      • ルールをどこに配置するか
      • カバレッジを最大化するためにはいつルールをスケジューリングすれば良いか
    • 既存のルータ上で動作する

SafeBricks: Shielding Network Functions in the Cloud

  • Network Function Virtualization (NFV) の出現により,企業等ではネットワークでの処理をクラウド側に任せることが増えた
    • セキュリティリスクもある
    • クラウドは攻撃の影響を受けやすい
  • SafeBricksを提案
    • 信頼できないクラウドからNFを守るシステム
    • 暗号化されたトラフィックのみがクラウドプロバイダの方に流れる
      • トラフィックとNFの両方の完全性を保つ
    • クライアントに最小権限を強制する
    • SafeBricks leverages a combination of hardware enclaves and language-based enforcement
    • SafeBricksによるオーバーヘッドは0〜15%

RyuによるOpenFlow入門 (2)

前回の続き.今回はMACアドレス学習機能のある,スイッチングハブを作成する.
前回同様,OpenFlowのバージョンは1.0を使用します.

スイッチングハブ

ソースコードは以下の通り.

L2のフレームをスイッチの他のポートに送信するという基本機能は前回実装したリピータハブと変わらない.
そのため,プログラムの大枠は同じである.

リピータハブとスイッチングハブの違いとして,スイッチングハブではMACアドレスの学習機能があるという点がある.
このため,一度MACアドレスの学習をした後は,そのMACアドレス宛のフレームはその機器が接続されているポートのみに送信するようになる.
(リピータハブでは,全てのフレームを全てのポート(フレームが入ってきたポート以外)に送信する)

では,プログラムを見てみる.
なお,リピータハブのプログラムと似たような部分は省略します.

L2Switch クラスのインスタンスを作成する際に,MACアドレスとポートの対応付けをするためのディクショナリ( mac_to_port )を作成しておく(19行目).
MACアドレスを学習したら,この辞書にポートとの対応付けを登録していく.

def __init__(self, *args, **kwargs):
    super(L2Switch, self).__init__(*args, **kwargs)
    self.mac_to_port = {}

MACアドレスの学習は,Packet Inでスイッチからのデータを受け取ったときに行う.
まず,スイッチから入ってきたフレームのMACアドレスとポートの対応付けを mac_to_port に登録する(63行目).

self.mac_to_port[dpid][src] = msg.in_port

その後,出力ポートを決定するために,宛先MACアドレスの対応付け情報が mac_to_port の中に存在するかどうかを確認する(66行目〜70行目).
もし存在していたら,見つかったポートを出力ポートとしてPacket Outメッセージを作成する.
もし存在していなかったら,全てのポートを出力ポートとしてPacket Outメッセージを作成する.

ofproto = dp.ofproto
if dst in self.mac_to_port[dpid]:
    out_port = self.mac_to_port[dpid][dst]
else:
    out_port = ofproto.OFPP_FLOOD

加えて,もし宛先MACアドレスの対応付け情報が存在していた場合,同じ宛先MACアドレスのフレームが再度コントローラに来るのを防ぐため,FlowModメッセージを使ってスイッチにフローエントリを書き込む(76行目〜77行目).
FlowModを使うのは,毎回コントローラにフレームが来てしまうとその分パフォーマンスが落ちてしまうため,それを避けるため.

if out_port != ofproto.OFPP_FLOOD:
    self.add_flow(dp, msg.in_port, dst, src, actions)

RyuによるOpenFlow入門 (1)

Ryuを使って簡単なL2スイッチを作ってみた.
Ryuについての理解が浅い状態でいきなりMACアドレスの学習機能を持ったL2スイッチを作成するのは難しいかと思ったので,まずMACアドレス学習機能のない単純なL2スイッチ(リピータハブ)を作成し,その後スイッチングハブを実装してみる.

リピータハブ

ソースコードは以下の通り.

OpenFlowスイッチに入ってきたパケットは,スイッチ内にあるフローテーブルを参照し,テーブル内にマッチするエントリがなければOpenFlowコントローラへPacket Inメッセージを送出する.
リピータハブでは,入ってきたパケットをそれ以外のポート全てにそのまま送信する(フラッディング)ので,Packet Inで入ってきたデータをそのまますべてのポートに向けて送ってあげれば良い.

コントローラからPacket Outメッセージを送ることで,OpenFlowスイッチからパケットを送出することができる.
これを利用して,データのフラッディングを行う.

Packet Outメッセージの作成部分は次のようになる.

actions = [ofp_parser.OFPActionOutput(ofp.OFPP_FLOOD)]
out = ofp_parser.OFPPacketOut(
    datapath=dp, buffer_id=msg.buffer_id, in_port=msg.in_port,
    actions=actions
)

Packet Outメッセージでは,アクションを指定することで,パケットの出力先を指定することができる.
今回は入力ポート以外全てに送りたいため, OFPActionOutput の引数として ofp.OFPP_FLOOD を指定する.

作成したアクション等の情報を OFPPacketOut の引数として与えてあげ,Packet Outメッセージを作成する.
指定した引数は次のような感じ.

  • datapath : データパス.OpenFlowスイッチを表す(みたい).それぞれのOpenFlowスイッチはユニークなID(Datapath ID)を持つ.
  • buffer_id : OpenFlowスイッチにバッファされているデータのID.
  • in_port : パケットの受信ポート.
  • actions : 上で作ったアクションを指定する.

最後に,作成したメッセージを send_msg() で送信してあげれば完了.

mininetを使って動作確認を行ってみる.

$ ryu-manager dumb_l2_switch.py

$ mn --switch ovs --controller remote
...
*** Starting CLI:
mininet> pingall
*** Ping: testing ping reachability
h1 -> h2
h2 -> h1
*** Results: 0% dropped (2/2 received)

ちゃんと疎通しているみたい.

スイッチングハブについては違う記事に分けて書きます.