-
Notifications
You must be signed in to change notification settings - Fork 0
Query switch information
In this tutorial, we develop an application to query switch information in more detail. The information that can be got from an OpenFlow switch is defined in the OpenFlow specification as follows.
- datapath ID
- max packets buffered at once
- number of flow tables
- capbility
- OpenFlow actions supported
- information of physical ports
In order to get the information of an OpenFlow switch, you should send the features request message to it.
// create a features request message
buffer *message = create_features_request( get_transaction_id() );
// send out the message
send_openflow_message( datapath_id, message );
// free the buffer
free_buffer( message );
When is the proper time to send a feature request message? The answer is after the preparation of OpenFlow switch is completed. You can send the message inside the event handler function of switch_ready, which we developed in the previous tutorial.
static void
handle_switch_ready( uint64_t datapath_id, void *user_data ) {
// create a features request message
buffer *message = create_features_request( get_transaction_id() );
// send out the message
send_openflow_message( datapath_id, message );
// free the buffer
free_buffer( message );
}
To handle the reply of features request, we should create a features_reply event handler function. A possible sample code of a features_reply event handler function is as follows, in which all information is printed out by info() function.
static void
handle_features_reply (
uint64_t datapath_id,
uint32_t transaction_id,
uint32_t n_buffers,
uint8_t n_tables,
uint32_t capabilities,
uint32_t actions,
const list_element *phy_ports,
void *user_data
) {
info( "datapath_id: %#llx", datapath_id );
info( "transaction_id: %#lx", transaction_id );
info( "n_buffers: %lu", n_buffers );
info( "n_tables: %u", n_tables );
info( "capabilities: %lu", capabilities );
info( "actions: %lu", actions );
info( "#ports: %d", list_length_of( phy_ports ) );
}
In the above sample code, list_length_of is another standard function in Trema. It returns the number of elements.
The final code is as follows.
#include "trema.h"
static void
handle_switch_ready( uint64_t datapath_id, void *user_data ) {
buffer *message = create_features_request( get_transaction_id() );
send_openflow_message( datapath_id, message );
free_buffer( message );
}
static void
handle_features_reply (
uint64_t datapath_id,
uint32_t transaction_id,
uint32_t n_buffers,
uint8_t n_tables,
uint32_t capabilities,
uint32_t actions,
const list_element *phy_ports,
void *user_data
) {
info( "datapath_id: %#llx", datapath_id );
info( "transaction_id: %#lx", transaction_id );
info( "n_buffers: %lu", n_buffers );
info( "n_tables: %u", n_tables );
info( "capabilities: %lu", capabilities );
info( "actions: %lu", actions );
info( "#ports: %d", list_length_of( phy_ports ) );
}
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;
}
OK, let us build and run it.
% gcc -o features_request features_request.c `./trema-config --cflags --libs`
% ./trema
trema> vswitch { datapath_id "0xabc" }
trema> app { path "./features_request" }
trema> run
datapath_id: 0xabc
transaction_id: 0x27aa0001
n_buffers: 256
n_tables: 2
capabilities: 135
actions: 2047
#ports: 1
The information of the virtual swicth is shown as above, the datapath_id should be 0xabc if it works well. Please note that the number of port is 1, and the port is used to control the OpenFlow switch.
Let us have more fun! First, increase the port number and then confirm the information from the newly added port. As following code shows, we first add a switch 0xdef. Then we connect the previous switch with the new one.
trema> vswitch { datapath_id "0xdef" }
trema> link "0xabc", "0xdef" # switch 0xabc is connected to a port of switch 0xdef
The connection is completed by link, whose synax is as follows.
trema> link switch_name_1, switch_name_2
When the code is executed, each switch consists of two ports: one is connected to the controller and the other is connected the other switch.
trema> run
datapath_id: 0xdef
transaction_id: 0x7200002
n_buffers: 256
n_tables: 2
capabilities: 135
actions: 2047
#ports: 2 # it has 2 ports
datapath_id: 0xabc
transaction_id: 0x7200001
n_buffers: 256
n_tables: 2
capabilities: 135
actions: 2047
#ports: 2 # it has 2 ports
In this tutorial, we have developed an application to query the information of an OpenFlow switch. What we learned is summarized as follows.
- In order to get the information of an OpenFlow switch, you should send features request message first
- create_features_request() is in charge of creating features reqeust messages
- send_openflow_message() is used to send messages
- set_features_reply_handler() is in charge of registering the handler of features reply messages
- How to use link to create a link between switches