예제 #1
0
static void
recv_request( const messenger_context_handle *handle,
              uint16_t tag, void *data, size_t len ) {
  UNUSED( tag );
  UNUSED( data );
  UNUSED( len );

  buffer *reply = get_switches();
  send_reply_message( handle, 0, reply->data, reply->length );
  free_buffer( reply );
}
예제 #2
0
bool
_send_management_application_reply( const messenger_context_handle *handle, const management_application_reply *reply ) {
  if ( handle == NULL || reply == NULL ) {
    error( "Both context handle and reply message must not be NULL ( handle = %p, reply = %p ).", handle, reply );
    return false;
  }
  bool ret = send_reply_message( handle, MESSENGER_MANAGEMENT_REPLY, reply, ( size_t ) ntohl( reply->header.length ) );
  if ( !ret ) {
    error( "Failed to send an application specific management reply." );
    return false;
  }

  return true;
}
예제 #3
0
static void
handle_dump_filter_request( const messenger_context_handle *handle, dump_packetin_filter_request *request ) {
  assert( handle != NULL );
  assert( request != NULL );

  buffer *buf = alloc_buffer_with_length( 2048 );
  dump_packetin_filter_reply *reply = append_back_buffer( buf, offsetof( dump_packetin_filter_reply, entries ) );
  reply->status = PACKETIN_FILTER_OPERATION_SUCCEEDED;
  reply->n_entries = 0;

  struct ofp_match match;
  ntoh_match( &match, &request->criteria.match );
  uint16_t priority = ntohs( request->criteria.priority );
  if ( request->flags & PACKETIN_FILTER_FLAG_MATCH_STRICT ) {
    list_element *services = lookup_match_strict_entry( match, priority );
    while ( services != NULL ) {
      if ( strcmp( services->data, request->criteria.service_name ) == 0 ) {
        packetin_filter_entry *entry = append_back_buffer( buf, sizeof( packetin_filter_entry ) );
        reply->n_entries++;
        entry->match = request->criteria.match;
        entry->priority = request->criteria.priority;
        strncpy( entry->service_name, services->data, sizeof( entry->service_name ) );
        entry->service_name[ sizeof( entry->service_name ) - 1 ] = '\0';
      }
      services = services->next;
    }
  }
  else {
    map_match_table( match, dump_filter_walker, buf );
  }
  reply->n_entries = htonl( reply->n_entries );

  bool ret = send_reply_message( handle, MESSENGER_DUMP_PACKETIN_FILTER_REPLY, buf->data, buf->length );
  free_buffer( buf );
  if ( ret == false ) {
    error( "Failed to send a dump packetin filter reply." );
  }
}
예제 #4
0
static void
handle_add_filter_request( const messenger_context_handle *handle, add_packetin_filter_request *request ) {
  assert( handle != NULL );
  assert( request != NULL );

  request->entry.service_name[ MESSENGER_SERVICE_NAME_LENGTH - 1 ] = '\0';
  if ( strlen( request->entry.service_name ) == 0 ) {
    error( "Service name must be specified." );
    return;
  }
  struct ofp_match match;
  ntoh_match( &match, &request->entry.match );
  bool ret = add_packetin_match_entry( match, ntohs( request->entry.priority ), request->entry.service_name );

  add_packetin_filter_reply reply;
  memset( &reply, 0, sizeof( add_packetin_filter_reply ) );
  reply.status = ( uint8_t ) ( ret ? PACKETIN_FILTER_OPERATION_SUCCEEDED : PACKETIN_FILTER_OPERATION_FAILED );
  ret = send_reply_message( handle, MESSENGER_ADD_PACKETIN_FILTER_REPLY,
                            &reply, sizeof( add_packetin_filter_reply ) );
  if ( ret == false ) {
    error( "Failed to send an add filter reply." );
  }
}
예제 #5
0
static void
handle_show_stats_request( const messenger_context_handle *handle, management_show_stats_request *request ) {
  assert( handle != NULL );
  assert( request != NULL );
  assert( ntohs( request->header.type ) == MANAGEMENT_SHOW_STATS_REQUEST );
  assert( ntohl( request->header.length ) == sizeof( management_show_stats_request ) );

  debug( "Handling a show stats request from %s.", handle->service_name );

  list_element *stats = NULL;
  create_list( &stats );
  foreach_stat( append_stat, &stats );
  unsigned int n_stats = list_length_of( stats );

  const size_t send_queue_length = 400000; // MESSENGER_RECV_BUFFER * 4
  const size_t send_queue_margin = 256; // headroom for various headers
  unsigned int n_max_entries = ( unsigned int ) ( send_queue_length - send_queue_margin ) / sizeof( stat_entry );

  management_show_stats_reply *reply = NULL;
  size_t length = 0;

  if ( n_stats <= n_max_entries ) {
    length = offsetof( management_show_stats_reply, entries ) + sizeof( stat_entry ) * n_stats;
    reply = xmalloc( length );
    memset( reply, 0, length );
    reply->header.type = htons( MANAGEMENT_SHOW_STATS_REPLY );
    reply->header.length = htonl( ( uint32_t ) length );
    reply->header.status = MANAGEMENT_REQUEST_SUCCEEDED;

    stat_entry *p = reply->entries;
    for ( list_element *e = stats; e != NULL; e = e->next ) {
      assert( e->data != NULL );
      memcpy( p, e->data, sizeof( stat_entry ) );
      p++;
    }
  }
  else {
    // TODO: Send statistics via out-of-band channel or by multiple replies.

    error( "Too many statistic entries ( %u > %u ).", n_stats, n_max_entries );

    length = offsetof( management_show_stats_reply, entries );
    reply = xmalloc( length );
    memset( reply, 0, length );
    reply->header.type = htons( MANAGEMENT_SHOW_STATS_REPLY );
    reply->header.length = htonl( ( uint32_t ) length );
    reply->header.status = MANAGEMENT_REQUEST_FAILED;
  }

  if ( stats != NULL ) {
    for ( list_element *e = stats; e != NULL; e = e->next ) {
      assert( e->data != NULL );
      xfree( e->data );
    }
    delete_list( stats );
  }

  bool ret = send_reply_message( handle, MESSENGER_MANAGEMENT_REPLY, reply, length );
  if ( ret == false ) {
    error( "Failed to send a show stats reply." );
  }
  xfree( reply );
}