C 言語で packet_in ハンドラを書く (その1)
C 言語を使った Trema 上でのコントローラプログラミングに関する話です。今回は packet_in を扱う方法について解説します。
packet_in は、OpenFlow スイッチがフローエントリにマッチしなかったパケットをコントローラに送るためのメッセージです。このメッセージは、スイッチ側から送られるので、コントローラ側からみるといつ送られてくるかわかりません。そのため、packet_in メッセージが送られてきたとき呼び出す関数(packet_in ハンドラ)を用意し、それを set_packet_in_handler() 関数で登録しておきます。
set_packet_in_handler( my_packet_in_handler, my_user_data );
上記の my_packet_in_handler の部分が、用意した packet_in ハンドラです。このハンドラに渡したいデータがある場合は、my_user_data のところに指定します。
それでは、どのような引数をとる packet_in ハンドラを用意すればよいでしょうか?openflow_application_interface.h には以下のように定義されています。
typedef void ( simple_packet_in_handler )( uint64_t datapath_id, packet_in message ); typedef void ( packet_in_handler )( uint64_t datapath_id, uint32_t transaction_id, uint32_t buffer_id, uint16_t total_len, uint16_t in_port, uint8_t reason, const buffer *data, void *user_data );
simple_packet_in_handler と packet_in_handler の二つが typedef されていますが、set_packet_in_handler() ではどちらの型を使ってもよいように定義されています。simple_packet_in_handler() の引数の packet_in 型は以下のように定義されています。
typedef struct { uint64_t datapath_id; uint32_t transaction_id; uint32_t buffer_id; uint16_t total_len; uint16_t in_port; uint8_t reason; const buffer *data; void *user_data; } packet_in;
つまり、どちらの型でハンドラを書いてもわたってくる情報は同じです。
次回、具体的に packet_in ハンドラを書く際のポイントについて解説します。