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 );