今日も秋田で IoT

旧 Trema 日記

C 言語で packet_in ハンドラを書く (その2)

今回は packet_in ハンドラを使って、簡単なコントローラを書いてみましょう。

以下のソースの handle_packet_in() がハンドラです。packet_in メッセージの送りもとのスイッチの datapath_id および受信ポートを表示する簡単なハンドラです。

1.  #include <stdio.h>
2.  #include "trema.h"
3.
4.  static void
5.  handle_packet_in( uint64_t datapath_id, packet_in message )
6.  {
7.    printf( "datapath_id : 0x%lx, in_port : %d\n", datapath_id, message.in_port );
8.  }
9. 
10. int
11. main( int argc, char *argv[] )
12. {
13.   init_trema( &argc, &argv );
14.   set_packet_in_handler( handle_packet_in, NULL );
15.   start_trema();
16. 
17.   return 0;
18. }

main() 関数の中身を少し解説します。13 行目の init_trema() で trema の初期化を行っています。14 行目では、前回の記事で紹介した set_packet_in_handler() を使って、packet_in ハンドラの登録を行っています。15 行目は、trema のメインループです。

今回の main() 関数中で行われている処理の流れは、trema でコントローラを書く際の典型的なパターンです。

このファイルを packetin_display.c という名前で保存し、build しましょう。

$ gcc `./trema/trema-config --cflag` -c packetin_display.c
$ gcc packetin_display.o `./trema/trema-config --libs` -o packetin_display

それでは、作成した packetin_display を動作させてみましょう。その前に、ネットワークエミュレーション機能を使うための以下のファイルを用意します。network.conf という名前で保存してください。

vswitch { datapath_id "0xabc" }

vhost ( "host1" )
vhost ( "host2" )

link "0xabc", "host1"
link "0xabc", "host2"

packetin_display を起動しましょう。

$ ./trema run ./packetin_display -c ./network.conf

上記と別のシェルで、以下のようにパケットを出してみましょう。

$ ./trema send_packets --source host1 --dest host2
$ ./trema send_packets --source host2 --dest host1

packetin_display 側のシェルで、以下のように表示されるはずです。

$ ./trema run ./packetin_display -c ./network.conf
datapath_id : 0xabc, in_port : 2
datapath_id : 0xabc, in_port : 1

今回は、packet_in ハンドラを使った簡単なコントローラの書き方を紹介しました。次回は、packet_in であがってきたパケットの中身を見る方法について紹介します。