Lua(JIT) でpacket処理 -> 楽しい
Eishun Kondoh@shun159
npstudy 2016/11/29
Agenda
• Luaでpacket 処理?
• Snabbってズバリ何?
• 簡単なアプリをかく。
• パフォーマンスは?
• 最後に
Luaでpacket処理?
• そもそも”Lua”とは?
• リオデジャネイロ・カトリカ大学で開発されたスクリプト言語。
• 汎用言語であるが、同じようなスクリプト言語と比べて高速。
• 組み込み用途としても利用される。
• LuaJITで動作すれば型のないスクリプト言語としては最速。
• 言語仕様が小さい。学習しやすい(個人的感想)。
Luaでpacket処理?
• パケット処理とはまたおおざっぱな…
• 今回は”Snabb”という、高速パケットネットワークツールキットを使っ
てみて、面白さを共有できればよいとおもう。
• “Snabb”とは、DPDKと同じような方式を用いてNICを直で読み書きする
ためのツールキット。
Snabbってズバリ何?
• 高速パケットネットワークツールキットである。
• アプリ NICの読み書きの概念はまさにDPDKと似ているかもしれない(kernel をバイパ
スする、tight loopでポーリングする、アプリにはパケットが格納されたメモリ上のポイ
ンタを渡す、など)。
• LuaJIT上で駆動する。ここで動くLuaのコードはCのコードとも遜色のない速度である。
• LuaとCで実装されており、メモリをあれこれする箇所やデバイスドライバのほとんどが
Luaで書かれている。
• 今のところ、Intel(I350, 82599, XL710), Mellanox(connectx-4), virtio, vhost, rawsock, solarflare
などでテストされている様子。
Snabbってズバリ何?
• 個人的にユニークだと思っている点
• アプリケーション(Apps)
• RouterやFirewallはたまたLoad Generator、NICに至るまで、snabbのアプリケーショ
ンをこのAppsで構成する。
• アプリケーションネットワーク(App Networks)
• 上記のAppsを有向グラフでつなぐ。
Intel NIC
Filter1
Filter2
RawSock
input
inputoutput
output
tx
tx
rx
rx
簡単なアプリをかく
• さっそく書く(挨拶)
Module(…, package.seeall)
Function run(_args)
print(‘hello, snabb!’)
main.exit(0)
End
(prompt)> sudo snabb hello
# => hello, snabb!
定義済み関数を呼べる
ようにする
snabbを起動したとき、指定したモジュールの
run()が呼ばれる, ARGVがもらえます。
Printして、exit status 0
で終了
簡単なアプリをかく
• 単方向ブリッジ(raw sock版)
• requireのコードは除く…
function run(args)
local port1, port2 = args[1], args[2]
local c = config.new()
config.app(c, ‘port1’, rawsock, port1)
config.app(c, ‘port2’, rawsock, port2)
config.link(c, ‘port1.tx -> port2.rx’)
engine.configure(c)
engine.main()
end
配列は1から。
Configにパケット処理
ネットワークを表現す
る。初期化。
初期化したconfig
App名
App種別
引数
を与えて初期化。
2つのAppを接続する。
上記を適用し、起動。
簡単なアプリをかく
• Ethertype をプリントする
• 先ほどのrawsockのコードに printer というmoduleをかませるの
をイメージする。
• Printerはether typeに応じて文字列をプリントして、ポートに出すだけ
Rawsock printer RawSock
input outputtx rx
簡単なアプリをかく
• Packet dataの参照
• Ether type をとるには、例えば、このような感じ。
• ffi.C.ntohs(ffi.cast(‘uint16_t *’, packet.data + 12)[0])
• vlan tagをpopしたり、pushしたりするときも大体こういったAPIを読んで書いてい
る
• ほかには
• Packet.clone
• Packet.resize
• Packet.append
• Packet.prepend
• Packet.shift{left|right}
• などがある。
簡単なアプリをかく
• それをふまえて、
engine.configureの時に
呼ばれる。初期化
Appネットワークにパケットを
書き込む関数。
無限ループでもOK
簡単なアプリをかく
ether typeをとって
Printする
パフォーマンスは?
• これまで書いたコードとは別に、以下のような負荷試験アプリ
のネットワークを組む。
Intel
82599
Intel
82599
sinkinput
rx
source
tx rxtx
source: 負荷試験用の組み込みアプリ。20Mpps(60byte)程度の出力が可能
sink: 負荷試験用の組み込みアプリ。/dev/nullのようなもん
p1p1
p1p2
パフォーマンスは?
• 60 byte, 10millon packetsで 9.5Mpps(4.23Gbps)程度であった。
最後に
• 試験した環境では、性能はDPDKには及ばないものの、Luaでか
けるのは、非常に面白い。
• IPsecやIwAFTR, bridge, LISPの実装がすでにあるので、これらを組
み合わせるだけでもそれなりのアプリが出来上がってしまいそ
う。
• SDNなスイッチをかきたくなるよね…。

npstudy 161129