コード例 #1
0
ファイル: switch.c プロジェクト: s-zenke/trema
int
switch_event_recv_featuresreply( struct switch_info *sw_info, uint64_t *dpid ) {
  int ret;
  uint16_t new_service_name_len;
  char *new_service_name;

  switch ( sw_info->state ) {
  case SWITCH_STATE_WAIT_FEATURES_REPLY:

    sw_info->datapath_id = *dpid;
    sw_info->state = SWITCH_STATE_COMPLETED;

    // cancel to features_reply_wait-timeout timer
    switch_unset_timeout( switch_event_timeout_features_reply );

    // TODO: change process name
    // TODO: set keepalive-timeout

    new_service_name_len = SWITCH_MANAGER_PREFIX_STR_LEN + SWITCH_MANAGER_DPID_STR_LEN + 1;
    new_service_name = xmalloc( new_service_name_len );
    snprintf( new_service_name, new_service_name_len, "%s%" PRIx64, SWITCH_MANAGER_PREFIX, sw_info->datapath_id );

    // rename service_name of messenger
    rename_message_received_callback( get_trema_name(), new_service_name );
    debug( "Rename service name to %s from %s.", new_service_name, get_trema_name() );

    if ( messenger_dump_enabled() ) {
      stop_messenger_dump();
      start_messenger_dump( new_service_name, DEFAULT_DUMP_SERVICE_NAME );
    }

    // notify state and datapath_id
    service_send_state( sw_info, &sw_info->datapath_id, MESSENGER_OPENFLOW_READY );
    debug( "send ready state" );

    ret = ofpmsg_send_setconfig( sw_info );
    if ( ret < 0 ) {
      return ret;
    }
    ret = ofpmsg_send_delete_all_flows( sw_info );
    if ( ret < 0 ) {
      return ret;
    }
    break;

  case SWITCH_STATE_COMPLETED:
    // NOP
    break;

  default:
    notice( "Invalid event 'features reply' from a switch." );
    return -1;

    break;
  }

  return 0;
}
コード例 #2
0
bool
finalize_management_interface() {
  if ( !initialized ) {
    error( "Management interface is not initialized yet or already finalized." );
    return false;
  }

  delete_message_requested_callback( get_management_service_name( get_trema_name() ), handle_request );

  initialized = false;

  debug( "Management interface is finalized ( trema_name = %s ).", get_trema_name() );

  return true;
}
コード例 #3
0
bool
init_management_interface() {
  if ( initialized ) {
    error( "Management interface is already initialized." );
    return false;
  }

  add_message_requested_callback( get_management_service_name( get_trema_name() ), handle_request );

  initialized = true;

  debug( "Management interface is initialized ( trema_name = %s, service_name = %s ).",
         get_trema_name(), get_management_service_name( get_trema_name() ) );

  return true;
}
コード例 #4
0
ファイル: list_switches.c プロジェクト: n-tada/trema
int
main( int argc, char *argv[] ) {
  init_trema( &argc, &argv );
  add_periodic_event_callback( 1, send_request, NULL );
  add_message_replied_callback( get_trema_name(), recv_reply );
  start_trema();
}
コード例 #5
0
ファイル: switch_manager.c プロジェクト: TakumiKomada/trema
static bool
start_switch_management( void ) {
  init_openflow_application_interface( get_trema_name() );
  set_switch_ready_handler( handle_switch_ready, NULL );
  set_switch_disconnected_handler( handle_switch_disconnected, NULL );

  return true;
}
コード例 #6
0
ファイル: topology_management.c プロジェクト: kazuyas/apps
bool
start_topology_management( void ) {
  init_openflow_application_interface( get_trema_name() );
  set_switch_ready_handler( handle_switch_ready, NULL );
  set_switch_disconnected_handler( switch_disconnected, NULL );
  set_features_reply_handler( switch_features_reply, NULL );
  set_port_status_handler( port_status, NULL );

  return true;
}
コード例 #7
0
static void
add_filter( void ) {
  static struct ofp_match match;
  memset( &match, 0, sizeof( struct ofp_match ) );
  match.wildcards = OFPFW_ALL;
  char *service_name = xstrdup( get_trema_name() );

  bool ret = add_packetin_filter( match, UINT16_MAX, service_name, add_filter_completed, &match );
  xfree( service_name );
  if ( ret == false ) {
    error( "Failed to add a packetin filter." );
  }
}
コード例 #8
0
static void
dump_and_delete_filters( int status, int n_entries, packetin_filter_entry *entries, void *user_data ) {
  dump_filters( status, n_entries, entries, user_data );

  struct ofp_match *match = user_data;
  char *service_name = xstrdup( get_trema_name() );
  bool ret = delete_packetin_filter( *match, UINT16_MAX, service_name, true, delete_filter_completed, user_data );
  xfree( service_name );
  if ( ret == false ) {
    error( "Failed to delete a packetin filter." );
  }
  ret = delete_packetin_filter( *match, UINT16_MAX, NULL, false, delete_filter_completed, user_data );
  if ( ret == false ) {
    error( "Failed to delete all packetin filters." );
  }
}
コード例 #9
0
static void
add_filter_completed( int status, void *user_data ) {
  if ( status != PACKETIN_FILTER_OPERATION_SUCCEEDED ) {
    error( "Failed to add a packetin filter." );
  }
  info( "A packetin filter was added successfully." );

  struct ofp_match *match = user_data;
  char *service_name = xstrdup( get_trema_name() );
  bool ret = dump_packetin_filter( *match, UINT16_MAX, service_name, true, dump_filters, user_data );
  xfree( service_name );
  if ( ret == false ) {
    error( "Failed to dump a packetin filter." );
  }
  ret = dump_packetin_filter( *match, UINT16_MAX, NULL, false, dump_and_delete_filters, user_data );
  if ( ret == false ) {
    error( "Failed to dump all packetin filters." );
  }
}
コード例 #10
0
ファイル: stdin_relay.c プロジェクト: axsh/trema-edge
static void
relay_string( buffer *string ) {
  // retrieve current time
  struct timespec now;
  if ( clock_gettime( CLOCK_REALTIME, &now ) == -1 ) {
    error( "Failed to retrieve system-wide real-time clock ( %s [%d] ).", strerror( errno ), errno );
    return;
  }

  // allocate buffer
  char *service_name = xstrdup( get_trema_name() );
  uint16_t service_name_length = ( uint16_t ) ( strlen( service_name ) + 1 );
  size_t buffer_length = sizeof( message_dump_header ) + service_name_length + sizeof( syslog_dump_header ) + string->length + 1;
  buffer *buf = alloc_buffer_with_length( buffer_length );

  // syslog_dump_header + service_name
  message_dump_header *mdh = append_back_buffer( buf, sizeof( message_dump_header ) );
  mdh->sent_time.sec = htonl( ( uint32_t ) now.tv_sec );
  mdh->sent_time.nsec = htonl( ( uint32_t ) now.tv_nsec );
  mdh->app_name_length = htons( 0 );
  mdh->service_name_length = htons( service_name_length );
  mdh->data_length = htonl( ( uint32_t ) ( sizeof( text_dump_header ) + string->length + 1 ) );
  void *svn = append_back_buffer( buf, service_name_length );
  memcpy( svn, service_name, service_name_length );
  xfree( service_name );

  // text_dump_header
  text_dump_header *tdh = append_back_buffer( buf, sizeof( text_dump_header ) );
  tdh->sent_time.sec = htonl( ( uint32_t ) now.tv_sec );
  tdh->sent_time.nsec = htonl( ( uint32_t ) now.tv_nsec );

  // message
  void *p = append_back_buffer( buf, string->length + 1 );
  memset( p, '\0', string->length + 1 );
  memcpy( p, string->data, string->length );

  bool ret = send_message( dump_service_name, MESSENGER_DUMP_TEXT, buf->data, buf->length );
  if ( !ret ) {
    error( "Failed to relay syslog message." );
  }
  free_buffer( buf );
}
コード例 #11
0
ファイル: packet_capture.c プロジェクト: Darma/trema
static void
handle_packet( u_char *args, const struct pcap_pkthdr *header, const u_char *packet ) {
  // allocate buffer
  char *app_name = interface_name;
  uint16_t app_name_length = ( uint16_t ) ( strlen( interface_name ) + 1 );
  char *service_name = xstrdup( get_trema_name() );
  uint16_t service_name_length = ( uint16_t ) ( strlen( service_name ) + 1 );
  size_t buffer_length = sizeof( message_dump_header ) + app_name_length + service_name_length + sizeof( pcap_dump_header ) + sizeof( struct pcap_pkthdr_private ) + header->caplen;
  buffer *buf = alloc_buffer_with_length( buffer_length );

  // message_dump_header + app_name + service_name
  message_dump_header *mdh = append_back_buffer( buf, sizeof( message_dump_header ) );
  mdh->sent_time.sec = htonl( ( uint32_t ) header->ts.tv_sec );
  mdh->sent_time.nsec = htonl( ( uint32_t ) ( header->ts.tv_usec * 1000 ) );
  mdh->app_name_length = htons( app_name_length );
  mdh->service_name_length = htons( service_name_length );
  mdh->data_length = htonl( ( uint32_t ) ( sizeof( pcap_dump_header ) + sizeof( struct pcap_pkthdr_private ) + header->caplen ) );
  void *apn = append_back_buffer( buf, app_name_length );
  memcpy( apn, app_name, app_name_length );
  void *svn = append_back_buffer( buf, service_name_length );
  memcpy( svn, service_name, service_name_length );
  xfree( service_name );

  // pcap_dump_header
  pcap_dump_header *pdh = append_back_buffer( buf, sizeof( pcap_dump_header ) );
  int *dlt = ( int * ) args;
  pdh->datalink = htonl( ( uint32_t ) *dlt );
  strncpy( ( char * ) pdh->interface, interface_name, sizeof( pdh->interface ) );
  pdh->interface[ sizeof( pdh->interface ) - 1 ] = '\0';

  // pcap_pkthdr_private + packet
  struct pcap_pkthdr_private *pph = append_back_buffer( buf, sizeof( struct pcap_pkthdr_private ) );
  pph->ts.tv_sec = ( bpf_int32 ) htonl( ( uint32_t ) header->ts.tv_sec );
  pph->ts.tv_usec = ( bpf_int32 ) htonl( ( uint32_t ) header->ts.tv_usec );
  pph->caplen = htonl( header->caplen );
  pph->len = htonl( header->len );
  void *pkt = append_back_buffer( buf, header->caplen );
  memcpy( pkt, packet, header->caplen );

  enqueue( packet_queue, buf );
}
コード例 #12
0
ファイル: application.c プロジェクト: TakumiKomada/trema
static void
send_application_request() {
  size_t length = offsetof( management_application_request, data ) + data_length;
  management_application_request *request = xmalloc( length );
  memset( request, 0, sizeof( management_application_request ) );
  request->header.type = htons( MANAGEMENT_APPLICATION_REQUEST );
  request->header.length = htonl( ( uint32_t ) length );
  request->application_id = htonl( application_id );
  if ( data_length > 0 && data != NULL ) {
    memcpy( request->data, data, data_length );
    xfree( data );
  }

  bool ret = send_request_message( service_name, get_trema_name(), MESSENGER_MANAGEMENT_REQUEST,
                                   request, length, NULL );
  xfree( request );
  if ( !ret ) {
    printf( "Failed to send an application specific management request to %s.\n", service_name );
    exit( EXIT_FAILURE );
  }
}
コード例 #13
0
ファイル: application.c プロジェクト: TakumiKomada/trema
int
main( int argc, char *argv[] ) {
  // Initialize the Trema world
  init_trema( &argc, &argv );

  // Parse arguments
  parse_arguments( argc, argv );

  // Set a handler to handle application specific management reply
  add_message_replied_callback( get_trema_name(), handle_reply );

  // Send an application specific management request
  send_application_request();

  // Set timeout
  add_periodic_event_callback( 5, timeout, NULL );

  // Main loop
  start_trema();

  return EXIT_SUCCESS;
}
コード例 #14
0
bool
init_event_forward_interface( void ) {
  if ( efi_queue_name != NULL ) {
    warn( "already initialized." );
    return false;
  }

  efi_queue_name = xcalloc( 1, MESSENGER_SERVICE_NAME_LENGTH );

  int chWrite = snprintf( efi_queue_name, MESSENGER_SERVICE_NAME_LENGTH,
                          "%s-efic-%d", get_trema_name(), trema_getpid() );
  if ( chWrite >= MESSENGER_SERVICE_NAME_LENGTH ) {
    snprintf( efi_queue_name, MESSENGER_SERVICE_NAME_LENGTH,
              "efic-%d", trema_getpid() );
  }

  // management reply handler
  add_message_replied_callback( efi_queue_name, handle_efi_reply );

  efi_tx_table = create_hash( compare_uint32, hash_uint32 );
  return true;
}
コード例 #15
0
ファイル: switch.c プロジェクト: Darma/trema
int
main( int argc, char *argv[] ) {
  int ret;
  int i;
  char *service_name;
  char management_service_name[ MESSENGER_SERVICE_NAME_LENGTH ];

  init_trema( &argc, &argv );
  option_parser( argc, argv );

  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 ) );
      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 );
    }
    else if ( strncmp( argv[i], PORTSTATUS_PREFIX, strlen( PORTSTATUS_PREFIX ) ) == 0 ) {
      service_name = xstrdup( argv[i] + strlen( PORTSTATUS_PREFIX ) );
      insert_in_front( &switch_info.portstatus_service_name_list, service_name );
    }
    else if ( strncmp( argv[i], STATE_PREFIX, strlen( STATE_PREFIX ) ) == 0 ) {
      service_name = xstrdup( argv[i] + strlen( STATE_PREFIX ) );
      insert_in_front( &switch_info.state_service_name_list, service_name );
    }
  }

  struct sigaction signal_exit;
  memset( &signal_exit, 0, sizeof( struct sigaction ) );
  signal_exit.sa_handler = handle_sigterm;
  sigaction( SIGINT, &signal_exit, NULL );
  sigaction( SIGTERM, &signal_exit, NULL );

  fcntl( switch_info.secure_channel_fd, F_SETFL, O_NONBLOCK );

  set_fd_handler( switch_info.secure_channel_fd, secure_channel_read, NULL, secure_channel_write, NULL );
  set_readable( switch_info.secure_channel_fd, true );
  set_writable( switch_info.secure_channel_fd, false );

  // default switch configuration
  switch_info.config_flags = OFPC_FRAG_NORMAL;
  switch_info.miss_send_len = UINT16_MAX;

  switch_info.fragment_buf = NULL;
  switch_info.send_queue = create_message_queue();
  switch_info.recv_queue = create_message_queue();
  switch_info.running_timer = false;
  switch_info.echo_request_xid = 0;

  init_xid_table();
  if ( switch_info.cookie_translation ) {
    init_cookie_table();
  }

  add_message_received_callback( get_trema_name(), service_recv );

  snprintf( management_service_name , MESSENGER_SERVICE_NAME_LENGTH,
            "%s.m", get_trema_name() );
  management_service_name[ MESSENGER_SERVICE_NAME_LENGTH - 1 ] = '\0';
  add_message_received_callback( management_service_name, management_recv );

  ret = switch_event_connected( &switch_info );
  if ( ret < 0 ) {
    error( "Failed to set connected state." );
    return -1;
  }
  flush_secure_channel( &switch_info );

  start_trema();

  finalize_xid_table();
  if ( switch_info.cookie_translation ) {
    finalize_cookie_table();
  }

  if ( switch_info.secure_channel_fd >= 0 ) {
    delete_fd_handler( switch_info.secure_channel_fd );
  }

  return 0;
}
コード例 #16
0
ファイル: switch.c プロジェクト: Milstein/trema
int
switch_event_recv_featuresreply( struct switch_info *sw_info, uint64_t *dpid ) {
  int ret;
  char new_service_name[ SWITCH_MANAGER_PREFIX_STR_LEN + SWITCH_MANAGER_DPID_STR_LEN + 1 ];
  const uint16_t new_service_name_len = SWITCH_MANAGER_PREFIX_STR_LEN + SWITCH_MANAGER_DPID_STR_LEN + 1;

  switch ( sw_info->state ) {
  case SWITCH_STATE_WAIT_FEATURES_REPLY:

    sw_info->datapath_id = *dpid;
    sw_info->state = SWITCH_STATE_WAIT_REGISTRATION;

    // cancel to features_reply_wait-timeout timer
    switch_unset_timeout( switch_event_timeout_features_reply, NULL );

    // TODO: set keepalive-timeout
    snprintf( new_service_name, new_service_name_len, "%s%#" PRIx64, SWITCH_MANAGER_PREFIX, sw_info->datapath_id );

    // checking duplicate service
    pid_t pid = get_pid_by_trema_name( new_service_name );
    if ( pid > 0 ) {
      debug( "duplicated datapath-id %#" PRIx64, sw_info->datapath_id );
      if ( !terminate_trema_process( pid ) ) {
        return -1;
      }
    }
    // rename service_name of messenger
    rename_message_received_callback( get_trema_name(), new_service_name );

    // rename management service name
    char *management_service_name = xstrdup( get_management_service_name( get_trema_name() ) );
    char *new_management_service_name = xstrdup( get_management_service_name( new_service_name ) );
    rename_message_requested_callback( management_service_name, new_management_service_name );
    xfree( management_service_name );
    xfree( new_management_service_name );

    debug( "Rename service name from %s to %s.", get_trema_name(), new_service_name );
    if ( messenger_dump_enabled() ) {
      stop_messenger_dump();
      start_messenger_dump( new_service_name, DEFAULT_DUMP_SERVICE_NAME );
    }
    set_trema_name( new_service_name );

    // reset to default config
    ret = ofpmsg_send_setconfig( sw_info );
    if ( ret < 0 ) {
      error( "Failed to send setconfig." );
      return ret;
    }
    if ( switch_info.flow_cleanup ) {
      debug( "Deleting all flows." );
      ret = ofpmsg_send_delete_all_flows( sw_info );
      if ( ret < 0 ) {
        error( "Failed to send delete all flows." );
        return ret;
      }
    }

    // switch_ready to switch_manager
    debug( "Notify switch_ready to switch manager." );
    char switch_manager[] =  SWITCH_MANAGER;
    list_element switch_manager_only_list;
    switch_manager_only_list.next = NULL;
    switch_manager_only_list.data = switch_manager;
    service_send_to_application( &switch_manager_only_list, MESSENGER_OPENFLOW_READY, &sw_info->datapath_id, NULL );

    init_event_forward_interface();
    // Check switch_manager registration
    debug( "Checking switch manager's switch list." );
    sw_info->retry_count = REGISTRATION_RETRY_COUNT;
    set_list_switches_reply_handler( confirm_self_dpid_is_registered );
    if ( send_list_switches_request( sw_info ) ) {
      switch_set_timeout( REGISTRATION_TIMEOUT, registration_timeout, sw_info );
    }
    else {
      error( "Failed to send switch list request to switch manager." );
      return -1;
    }
    break;

  case SWITCH_STATE_WAIT_REGISTRATION:
  case SWITCH_STATE_COMPLETED:
    // NOP
    break;

  default:
    notice( "Invalid event 'features reply' from a switch." );
    return -1;

    break;
  }

  return 0;
}
コード例 #17
0
ファイル: switch_manager.c プロジェクト: TakumiKomada/trema
static bool
start_service_management( void ) {
  return add_message_requested_callback( get_trema_name(), recv_request );
}
コード例 #18
0
ファイル: list_switches.c プロジェクト: n-tada/trema
static void
send_request( void *user_data ) {
  UNUSED( user_data );
  send_request_message( "switch_manager", get_trema_name(), 0, NULL, 0, NULL );
}
コード例 #19
0
ファイル: switch.c プロジェクト: s-zenke/trema
int
main( int argc, char *argv[] ) {
  int ret;
  int i;
  char *service_name;
  char management_service_name[ MESSENGER_SERVICE_NAME_LENGTH ];

  init_trema( &argc, &argv );
  option_parser( argc, argv );

  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 ) );
      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 );
    }
    else if ( strncmp( argv[i], PORTSTATUS_PREFIX, strlen( PORTSTATUS_PREFIX ) ) == 0 ) {
      service_name = xstrdup( argv[i] + strlen( PORTSTATUS_PREFIX ) );
      insert_in_front( &switch_info.portstatus_service_name_list, service_name );
    }
    else if ( strncmp( argv[i], STATE_PREFIX, strlen( STATE_PREFIX ) ) == 0 ) {
      service_name = xstrdup( argv[i] + strlen( STATE_PREFIX ) );
      insert_in_front( &switch_info.state_service_name_list, service_name );
    }
  }

  fcntl( switch_info.secure_channel_fd, F_SETFL, O_NONBLOCK );
  // default switch configuration
  switch_info.config_flags = OFPC_FRAG_NORMAL;
  switch_info.miss_send_len = UINT16_MAX;

  switch_info.fragment_buf = NULL;
  switch_info.send_queue = create_message_queue();
  switch_info.recv_queue = create_message_queue();

  init_xid_table();
  init_cookie_table();

  set_fd_set_callback( secure_channel_fd_set );
  set_check_fd_isset_callback( secure_channel_fd_isset );
  add_message_received_callback( get_trema_name(), service_recv );

  snprintf( management_service_name , MESSENGER_SERVICE_NAME_LENGTH,
            "%s.m", get_trema_name() );
  management_service_name[ MESSENGER_SERVICE_NAME_LENGTH - 1 ] = '\0';
  add_message_received_callback( management_service_name, management_recv );

  ret = switch_event_connected( &switch_info );
  if ( ret < 0 ) {
    error( "Failed to set connected state." );
    return -1;
  }

  start_trema();

  finalize_xid_table();
  finalize_cookie_table();

  return 0;
}
コード例 #20
0
ファイル: switch.c プロジェクト: Milstein/trema
int
main( int argc, char *argv[] ) {
  int ret;
  int i;
  char *service_name;

  init_trema( &argc, &argv );
  option_parser( argc, argv );

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

  for ( i = optind; i < argc; i++ ) {
    if ( strncmp( argv[ i ], VENDOR_PREFIX, strlen( VENDOR_PREFIX ) ) == 0 ) {
      service_name = xstrdup( argv[ i ] + strlen( VENDOR_PREFIX ) );
      append_to_tail( &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 ) );
      append_to_tail( &switch_info.packetin_service_name_list, service_name );
    }
    else if ( strncmp( argv[ i ], PORTSTATUS_PREFIX, strlen( PORTSTATUS_PREFIX ) ) == 0 ) {
      service_name = xstrdup( argv[ i ] + strlen( PORTSTATUS_PREFIX ) );
      append_to_tail( &switch_info.portstatus_service_name_list, service_name );
    }
    else if ( strncmp( argv[ i ], STATE_PREFIX, strlen( STATE_PREFIX ) ) == 0 ) {
      service_name = xstrdup( argv[ i ] + strlen( STATE_PREFIX ) );
      append_to_tail( &switch_info.state_service_name_list, service_name );
    }
  }

  struct sigaction signal_exit;
  memset( &signal_exit, 0, sizeof( struct sigaction ) );
  signal_exit.sa_handler = handle_sigterm;
  sigaction( SIGINT, &signal_exit, NULL );
  sigaction( SIGTERM, &signal_exit, NULL );

  fcntl( switch_info.secure_channel_fd, F_SETFL, O_NONBLOCK );

  set_fd_handler( switch_info.secure_channel_fd, secure_channel_read, NULL, secure_channel_write, NULL );
  set_readable( switch_info.secure_channel_fd, true );
  set_writable( switch_info.secure_channel_fd, false );

  // default switch configuration
  switch_info.config_flags = OFPC_FRAG_NORMAL;
  switch_info.miss_send_len = UINT16_MAX;

  switch_info.fragment_buf = NULL;
  switch_info.send_queue = create_message_queue();
  switch_info.recv_queue = create_message_queue();
  switch_info.running_timer = false;
  switch_info.echo_request_xid = 0;

  init_xid_table();
  if ( switch_info.cookie_translation ) {
    init_cookie_table();
  }

  add_message_received_callback( get_trema_name(), service_recv );
  set_management_application_request_handler( management_recv, NULL );

  ret = switch_event_connected( &switch_info );
  if ( ret < 0 ) {
    error( "Failed to set connected state." );
    return -1;
  }
  ret = flush_secure_channel( &switch_info );
  if ( ret < 0 ) {
    error( "Failed to flush secure channel. Terminating %s.", argv[ 0 ] );
    return -1;
  }

  start_trema();

  // Note: init_event_forward_interface will be called on feature_reply.
  finalize_event_forward_interface();

  finalize_xid_table();
  if ( switch_info.cookie_translation ) {
    finalize_cookie_table();
  }

  if ( switch_info.secure_channel_fd >= 0 ) {
    delete_fd_handler( switch_info.secure_channel_fd );
  }

  return 0;
}
コード例 #21
0
ファイル: switch.c プロジェクト: miyakz1192/trema
int
switch_event_recv_featuresreply( struct switch_info *sw_info, uint64_t *dpid ) {
  int ret;
  char new_service_name[ SWITCH_MANAGER_PREFIX_STR_LEN + SWITCH_MANAGER_DPID_STR_LEN + 1 ];
  const uint16_t new_service_name_len = SWITCH_MANAGER_PREFIX_STR_LEN + SWITCH_MANAGER_DPID_STR_LEN + 1;

  switch ( sw_info->state ) {
  case SWITCH_STATE_WAIT_FEATURES_REPLY:

    sw_info->datapath_id = *dpid;
    sw_info->state = SWITCH_STATE_COMPLETED;

    // cancel to features_reply_wait-timeout timer
    switch_unset_timeout( switch_event_timeout_features_reply, NULL );

    // TODO: set keepalive-timeout
    snprintf( new_service_name, new_service_name_len, "%s%#" PRIx64, SWITCH_MANAGER_PREFIX, sw_info->datapath_id );

    // checking duplicate service
    pid_t pid = get_trema_process_from_name( new_service_name );
    if ( pid > 0 ) {
      // duplicated
      if ( !terminate_trema_process( pid ) ) {
        return -1;
      }
    }
    // rename service_name of messenger
    rename_message_received_callback( get_trema_name(), new_service_name );

    debug( "Rename service name from %s to %s.", get_trema_name(), new_service_name );
    if ( messenger_dump_enabled() ) {
      stop_messenger_dump();
      start_messenger_dump( new_service_name, DEFAULT_DUMP_SERVICE_NAME );
    }
    set_trema_name( new_service_name );

    // notify state and datapath_id
    service_send_state( sw_info, &sw_info->datapath_id, MESSENGER_OPENFLOW_READY );
    debug( "send ready state" );

    ret = ofpmsg_send_setconfig( sw_info );
    if ( ret < 0 ) {
      return ret;
    }
    if ( switch_info.flow_cleanup ) {
      ret = ofpmsg_send_delete_all_flows( sw_info );
      if ( ret < 0 ) {
        return ret;
      }
    }
    break;

  case SWITCH_STATE_COMPLETED:
    // NOP
    break;

  default:
    notice( "Invalid event 'features reply' from a switch." );
    return -1;

    break;
  }

  return 0;
}