src/switch_manager/switch.c in trema-0.3.16 vs src/switch_manager/switch.c in trema-0.3.17
- old
+ new
@@ -24,24 +24,25 @@
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
+#include <assert.h>
#include "trema.h"
#include "cookie_table.h"
-#include "management_interface.h"
#include "message_queue.h"
#include "messenger.h"
#include "ofpmsg_send.h"
#include "openflow_service_interface.h"
#include "secure_channel_receiver.h"
#include "secure_channel_sender.h"
#include "service_interface.h"
#include "switch.h"
#include "xid_table.h"
+#include "switch_option.h"
+#include "event_forward_entry_manipulation.h"
-
#define SUB_TIMESPEC( _a, _b, _return ) \
do { \
( _return )->tv_sec = ( _a )->tv_sec - ( _b )->tv_sec; \
( _return )->tv_nsec = ( _a )->tv_nsec - ( _b )->tv_nsec; \
if ( ( _return )->tv_nsec < 0 ) { \
@@ -50,27 +51,10 @@
} \
} \
while ( 0 )
-enum long_options_val {
- NO_FLOW_CLEANUP_LONG_OPTION_VALUE = 1,
- NO_COOKIE_TRANSLATION_LONG_OPTION_VALUE = 2,
- NO_PACKET_IN_LONG_OPTION_VALUE = 3,
-};
-
-static struct option long_options[] = {
- { "socket", 1, NULL, 's' },
- { "no-flow-cleanup", 0, NULL, NO_FLOW_CLEANUP_LONG_OPTION_VALUE },
- { "no-cookie-translation", 0, NULL, NO_COOKIE_TRANSLATION_LONG_OPTION_VALUE },
- { "no-packet_in", 0, NULL, NO_PACKET_IN_LONG_OPTION_VALUE },
- { NULL, 0, NULL, 0 },
-};
-
-static char short_options[] = "s:";
-
-
struct switch_info switch_info;
static const time_t COOKIE_TABLE_AGING_INTERVAL = 3600; // sec.
static const time_t ECHO_REQUEST_INTERVAL = 60; // sec.
static const time_t ECHO_REPLY_TIMEOUT = 2; // ses.
@@ -136,11 +120,11 @@
switch_info.secure_channel_fd = 0; // stdin
switch_info.flow_cleanup = true;
switch_info.cookie_translation = true;
switch_info.deny_packet_in_on_startup = false;
- while ( ( c = getopt_long( argc, argv, short_options, long_options, NULL ) ) != -1 ) {
+ while ( ( c = getopt_long( argc, argv, switch_short_options, switch_long_options, NULL ) ) != -1 ) {
switch ( c ) {
case 's':
switch_info.secure_channel_fd = strtofd( optarg );
break;
@@ -496,10 +480,24 @@
// send secure channle disconnect state to application
service_send_state( sw_info, &sw_info->datapath_id, MESSENGER_OPENFLOW_DISCONNECTED );
}
flush_messenger();
+ // free service name list
+ iterate_list( sw_info->vendor_service_name_list, xfree_data, NULL );
+ delete_list( sw_info->vendor_service_name_list );
+ sw_info->vendor_service_name_list = NULL;
+ iterate_list( sw_info->packetin_service_name_list, xfree_data, NULL );
+ delete_list( sw_info->packetin_service_name_list );
+ sw_info->packetin_service_name_list = NULL;
+ iterate_list( sw_info->portstatus_service_name_list, xfree_data, NULL );
+ delete_list( sw_info->portstatus_service_name_list );
+ sw_info->portstatus_service_name_list = NULL;
+ iterate_list( sw_info->state_service_name_list, xfree_data, NULL );
+ delete_list( sw_info->state_service_name_list );
+ sw_info->state_service_name_list = NULL;
+
stop_trema();
return 0;
}
@@ -538,13 +536,78 @@
return -1;
}
static void
+management_event_forward_entry_operation( const messenger_context_handle *handle, uint32_t command, event_forward_operation_request *req, size_t data_len ) {
+
+ debug( "management efi command:%#x, type:%#x, n_services:%d", command, req->type, req->n_services );
+
+ list_element **subject = NULL;
+ switch ( req->type ) {
+ case EVENT_FORWARD_TYPE_VENDOR:
+ info( "Managing vendor event." );
+ subject = &switch_info.vendor_service_name_list;
+ break;
+
+ case EVENT_FORWARD_TYPE_PACKET_IN:
+ info( "Managing packet_in event." );
+ subject = &switch_info.packetin_service_name_list;
+ break;
+
+ case EVENT_FORWARD_TYPE_PORT_STATUS:
+ info( "Managing port_status event." );
+ subject = &switch_info.portstatus_service_name_list;
+ break;
+
+ case EVENT_FORWARD_TYPE_STATE_NOTIFY:
+ info( "Managing state_notify event." );
+ subject = &switch_info.state_service_name_list;
+ break;
+
+ default:
+ error( "Invalid EVENT_FWD_TYPE ( %#x )", req->type );
+ event_forward_operation_reply res;
+ memset( &res, 0, sizeof( event_forward_operation_reply ) );
+ res.type = req->type;
+ res.result = EFI_OPERATION_FAILED;
+ management_application_reply *reply = create_management_application_reply( MANAGEMENT_REQUEST_FAILED, command, &res, sizeof( event_forward_operation_reply ) );
+ send_management_application_reply( handle, reply );
+ xfree( reply );
+ return;
+ }
+ assert( subject != NULL );
+
+ switch ( command ) {
+ case EVENT_FORWARD_ENTRY_ADD:
+ management_event_forward_entry_add( subject, req, data_len );
+ break;
+
+ case EVENT_FORWARD_ENTRY_DELETE:
+ management_event_forward_entry_delete( subject, req, data_len );
+ break;
+
+ case EVENT_FORWARD_ENTRY_DUMP:
+ info( "Dumping current event filter." );
+ // do nothing
+ break;
+
+ case EVENT_FORWARD_ENTRY_SET:
+ management_event_forward_entries_set( subject, req, data_len );
+ break;
+ }
+
+ buffer *buf = create_event_forward_operation_reply( req->type, EFI_OPERATION_SUCCEEDED, *subject );
+ management_application_reply *reply = create_management_application_reply( MANAGEMENT_REQUEST_SUCCEEDED, command, buf->data, buf->length );
+ free_buffer( buf );
+ send_management_application_reply( handle, reply );
+ xfree( reply );
+}
+
+
+static void
management_recv( const messenger_context_handle *handle, uint32_t command, void *data, size_t data_len, void *user_data ) {
- UNUSED( data );
- UNUSED( data_len );
UNUSED( user_data );
switch ( command ) {
case DUMP_XID_TABLE:
{
@@ -575,10 +638,22 @@
age_cookie_table_enabled = true;
}
}
break;
+ case EVENT_FORWARD_ENTRY_ADD:
+ case EVENT_FORWARD_ENTRY_DELETE:
+ case EVENT_FORWARD_ENTRY_DUMP:
+ case EVENT_FORWARD_ENTRY_SET:
+ {
+ event_forward_operation_request *req = data;
+ req->n_services = ntohl( req->n_services );
+ management_event_forward_entry_operation( handle, command, req, data_len );
+ return;
+ }
+ break;
+
default:
{
error( "Undefined management command ( %#x )", command );
management_application_reply *reply = create_management_application_reply( MANAGEMENT_REQUEST_FAILED, command, NULL, 0 );
send_management_application_reply( handle, reply );
@@ -621,17 +696,12 @@
create_list( &switch_info.vendor_service_name_list );
create_list( &switch_info.packetin_service_name_list );
create_list( &switch_info.portstatus_service_name_list );
create_list( &switch_info.state_service_name_list );
- // FIXME
-#define VENDER_PREFIX "vendor::"
-#define PACKET_IN_PREFIX "packet_in::"
-#define PORTSTATUS_PREFIX "port_status::"
-#define STATE_PREFIX "state_notify::"
for ( i = optind; i < argc; i++ ) {
- if ( strncmp( argv[ i ], VENDER_PREFIX, strlen( VENDER_PREFIX ) ) == 0 ) {
- service_name = xstrdup( argv[ i ] + strlen( VENDER_PREFIX ) );
+ if ( strncmp( argv[ i ], VENDOR_PREFIX, strlen( VENDOR_PREFIX ) ) == 0 ) {
+ service_name = xstrdup( argv[ i ] + strlen( VENDOR_PREFIX ) );
insert_in_front( &switch_info.vendor_service_name_list, service_name );
}
else if ( strncmp( argv[ i ], PACKET_IN_PREFIX, strlen( PACKET_IN_PREFIX ) ) == 0 ) {
service_name = xstrdup( argv[ i ] + strlen( PACKET_IN_PREFIX ) );
insert_in_front( &switch_info.packetin_service_name_list, service_name );