Features Request でスイッチから情報を取得する (その2)
前回、Ruby でコントローラを書きましたが、もちろん C 言語でも同様なことができます。
#include <stdio.h> #include "trema.h" static void handle_switch_ready( uint64_t dpid, void *user_data ) { UNUSED( user_data ); buffer *features_request = create_features_request( get_transaction_id() ); send_openflow_message( dpid, features_request ); free_buffer( features_request ); } static void handle_features_reply( uint64_t dpid, uint32_t txid, uint32_t n_buffers, uint8_t n_tables, uint32_t capabilities, uint32_t actions, const list_element *phy_ports, void *user_data ) { UNUSED( user_data ); UNUSED( n_buffers ); UNUSED( n_tables ); UNUSED( actions ); UNUSED( txid ); printf( "Datapath ID: %#" PRIx64 "\n", dpid ); const list_element *p; for ( p = phy_ports; p != NULL; p = p->next ) { struct ofp_phy_port *port = p->data; printf( "Port no: %u\n", port->port_no ); printf( " Hardware address: %02x:%02x:%02x:%02x:%02x:%02x\n", port->hw_addr[0], port->hw_addr[1], port->hw_addr[2], port->hw_addr[3], port->hw_addr[4], port->hw_addr[5] ); printf( " Port name: %s\n", port->name ); } } int main( int argc, char *argv[] ) { init_trema( &argc, &argv ); set_switch_ready_handler( handle_switch_ready, NULL ); set_features_reply_handler( handle_features_reply, NULL ); start_trema(); return 0; }
上記のファイルを show_features.c として保存し、以下のようにコンパイル、実行をします。
$ gcc `trema-config --cflag` -c show_features.c $ gcc show_features.o `trema-config --libs` -o show_features $ sudo trema run ./show_features -c ./network.conf Datapath ID: 0xabc Port no: 2 Hardware address: f6:1d:1b:91:e6:ae Port name: trema0-1 Port no: 65534 Hardware address: 8e:14:20:6f:54:15 Port name: vsw_0xabc Port no: 1 Hardware address: b2:69:85:cf:91:aa Port name: trema1-1 ^C terminated
Ruby と比べると、コードが長くなりますが、同じ実行結果を得ることができるはずです。
次回、OpenFlow の仕様を参考に、Features Request でどのような情報が表示できるかを見ていきましょう。