コード例 #1
0
OFDPE
get_meter_stats( const uint32_t meter_id, meter_entry** entries, uint32_t *count ) {
  OFDPE ret = OFDPE_SUCCESS;
  if ( !lock_pipeline() ) {
    return ERROR_UNLOCK;
  }

  *entries = NULL;
  *count = 0;
  if ( meter_id == OFPM_ALL ) {
    *count = list_length_of(table->entries);
    meter_entry *head = xcalloc(*count, sizeof(meter_entry));
    int i=0;
    for ( list_element *e = table->entries; e != NULL; e=e->next,i++ ) {
      clone_meter_entry( head+i, e->data );
    }
    *entries = head;
  } else {
    meter_entry *entry = lookup_meter_entry( meter_id );
    if ( entry == NULL ) {
      ret = ERROR_OFDPE_METER_MOD_FAILED_UNKNOWN_METER;
    } else {
      *count = 1;
      *entries = clone_meter_entry( NULL, entry );
    }
  }

  if ( !unlock_pipeline() ) {
    return ERROR_UNLOCK;
  }
  return ret;
}
コード例 #2
0
ファイル: openflow_helper.c プロジェクト: axsh/trema-edge
bool
get_ofp_group_stats( const group_stats *stats, struct ofp_group_stats **translated, size_t *length ) {
  assert( stats != NULL );
  assert( translated != NULL );
  assert( length != NULL );

  unsigned int n_buckets = 0;
  if ( stats->bucket_stats != NULL ) {
    n_buckets = list_length_of( stats->bucket_stats );
  }

  *length = offsetof( struct ofp_group_stats, bucket_stats ) + sizeof( struct ofp_bucket_counter ) * n_buckets;
  *translated = xmalloc( *length );

  struct ofp_bucket_counter *counter = ( *translated )->bucket_stats;
  for ( list_element *e = stats->bucket_stats; e != NULL; e = e->next ) {
    if ( e->data == NULL ) {
      continue;
    }
    bucket_counter *bucket_counter = e->data;
    counter->packet_count = bucket_counter->packet_count;
    counter->byte_count = bucket_counter->byte_count;
    counter++;
  }
  
  ( *translated )->length = ( uint16_t ) *length;
  ( *translated )->group_id = stats->group_id;
  ( *translated )->ref_count = stats->ref_count;
  ( *translated )->packet_count = stats->packet_count;
  ( *translated )->byte_count = stats->byte_count;
  ( *translated )->duration_sec = stats->duration_sec;
  ( *translated )->duration_nsec = stats->duration_nsec;

  return true;
}
コード例 #3
0
meter_entry *
alloc_meter_entry( const uint16_t flags, const uint32_t meter_id, const list_element *bands ) {
  meter_band *bands_array = NULL;
  unsigned int bands_count = list_length_of( bands );
  if ( bands_count > 0 ) {
    bands_array = xcalloc( bands_count, sizeof( meter_entry ) );
    
    int i=0;
    for ( const list_element *e = bands; e != NULL; e = e->next, i++ ) {
      struct ofp_meter_band_header *band = e->data;
      meter_band *target = bands_array+i;
      target->type = band->type;
      target->rate = band->rate;
      target->burst_size = band->burst_size;
      if (band->type == OFPMBT_DSCP_REMARK ){
        target->prec_level = ((struct ofp_meter_band_dscp_remark *)band)->prec_level;
      }
    }
  }
  meter_entry *entry = xcalloc( 1, sizeof( meter_entry ) );

  entry->meter_id = meter_id;
  entry->flags = flags;
  entry->bands_count = bands_count;
  entry->bands = bands_array;
  struct timespec now = { 0, 0 };
  time_now( &now );
  entry->created_at = now;
  entry->meter_at = now;
  
  return entry;
}
コード例 #4
0
ファイル: port_manager.c プロジェクト: axsh/trema-edge
OFDPE
get_port_description( const uint32_t port_no, port_description **descriptions, uint32_t *n_ports ) {
  assert( port_no > 0 || port_no == OFPP_ALL );
  assert( descriptions != NULL );
  assert( n_ports != NULL );

  if ( !lock_mutex( &mutex ) ) {
    return ERROR_LOCK;
  }

  *n_ports = 0;
  *descriptions = NULL;

  list_element *ports = NULL;
  if ( port_no != OFPP_ALL ) {
    switch_port *port = lookup_switch_port( port_no );
    if ( ports == NULL ) {
      return unlock_mutex( &mutex ) ? OFDPE_SUCCESS : ERROR_UNLOCK;
    }
    create_list( &ports );
    append_to_tail( &ports, port );
  }
  else {
    ports = get_all_switch_ports();
    if ( ports == NULL ) {
      return unlock_mutex( &mutex ) ? OFDPE_SUCCESS : ERROR_UNLOCK;
    }
  }

  *n_ports = ( uint32_t ) list_length_of( ports );
  size_t length = ( *n_ports ) * sizeof( port_description );
  *descriptions = xmalloc( length );
  memset( *descriptions, 0, length );

  port_description *description = *descriptions;
  for ( list_element *e = ports; e != NULL; e = e->next ) {
    assert( e->data != NULL );
    switch_port *port = e->data;
    assert( port->device != NULL );
    // FIXME: we assume that "port_description" is the same structure as "struct ofp_port".
    switch_port_to_ofp_port( description, port );
    description++;
  }

  if ( !unlock_mutex( &mutex ) ) {
    return ERROR_UNLOCK;
  }

  return OFDPE_SUCCESS;
}
コード例 #5
0
ファイル: list_switches.c プロジェクト: Milstein/trema
static void
handle_list_switches_reply( const list_element *switches, void *user_data ) {
  UNUSED( user_data );

  unsigned int num_switch = list_length_of( switches );

  char *list = xmalloc( 20 * num_switch + 1 ); // 20 = dpid string (18 chars) + ", "
  list[ 0 ] = '\0';
  join( list, switches );
  info( "switches = %s", list );
  xfree( list );

  stop_trema();
}
コード例 #6
0
static bool
get_reflectors_to_update( list_element **reflectors_to_update, uint32_t vni ) {
  debug( "Retriving packet reflectors to update ( reflectors_to_update = %p, vni = %#x ).", reflectors_to_update, vni );

  assert( db != NULL );
  assert( reflectors_to_update != NULL );

  MYSQL_RES *result = NULL;

  bool ret = execute_query( db, "select reflectors.uri from reflectors,overlay_networks "
                            "where overlay_networks.reflector_group_id = reflectors.group_id and "
                            "overlay_networks.slice_id = %u", vni );
  if ( !ret ) {
    return false;
  }

  result = mysql_store_result( db );
  if ( result == NULL ) {
    error( "Failed to retrieve result from database ( %s ).", mysql_error( db ) );
    return false;
  }

  assert( mysql_num_fields( result ) == 1 );
  if ( mysql_num_rows( result ) == 0 ) {
    error( "Failed to retrieve packet reflector configuration ( vni = %#x ).", vni );
    mysql_free_result( result );
    return false;
  }

  create_list( reflectors_to_update );

  char *uri = NULL;
  MYSQL_ROW row;
  while ( ( row = mysql_fetch_row( result ) ) != NULL ) {
    uri = xstrdup( row[ 0 ] );
    append_to_tail( reflectors_to_update, uri );
  }

  if ( list_length_of( *reflectors_to_update ) == 0 ) {
    delete_list( *reflectors_to_update );
  }

  mysql_free_result( result );

  return true;
}
コード例 #7
0
ファイル: switch_info.c プロジェクト: Darma/trema
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
) {
  UNUSED( user_data );

  info( "datapath_id: %#" PRIx64, 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 ) );

  stop_trema();
}
コード例 #8
0
ファイル: port_manager.c プロジェクト: axsh/trema-edge
OFDPE
get_port_stats( const uint32_t port_no, port_stats **stats, uint32_t *n_ports ) {
  assert( ( port_no > 0 && port_no <= OFPP_MAX ) || port_no == OFPP_ANY );
  assert( stats != NULL );
  assert( n_ports != NULL );

  if ( !lock_mutex( &mutex ) ) {
    return ERROR_LOCK;
  }

  list_element *ports = NULL;
  *n_ports = 0;
  *stats = NULL;
  if ( port_no != OFPP_ANY ) {
    switch_port *port = lookup_switch_port( port_no );
    if ( port == NULL ) {
      if ( unlock_mutex( &mutex ) !=  OFDPE_SUCCESS ) {
        return ERROR_UNLOCK;
      }
      return ERROR_OFDPE_BAD_REQUEST_BAD_PORT;
    }
    create_list( &ports );
    append_to_tail( &ports, port );
  }
  else {
    ports = get_all_switch_ports();
    if ( ports == NULL ) {
      return unlock_mutex( &mutex ) ? OFDPE_SUCCESS : ERROR_UNLOCK;
    }
  }


  *n_ports = ( uint32_t ) list_length_of( ports );
  size_t length = ( *n_ports ) * sizeof( port_stats );
  *stats = xmalloc( length );
  memset( *stats, 0, length );

  port_stats *stat = *stats;
  for ( list_element *e = ports; e != NULL; e = e->next ) {
    assert( e->data != NULL );
    switch_port *port = e->data;
    stat->port_no = port->port_no;
    assert( port->device != NULL );
    stat->rx_packets = port->device->stats.rx_packets;
    stat->tx_packets = port->device->stats.tx_packets;
    stat->rx_bytes = port->device->stats.rx_bytes;
    stat->tx_bytes = port->device->stats.tx_bytes;
    stat->rx_dropped = port->device->stats.rx_dropped;
    stat->tx_dropped = port->device->stats.tx_dropped;
    stat->rx_errors = port->device->stats.rx_errors;
    stat->tx_errors = port->device->stats.tx_errors;
    stat->rx_frame_err = port->device->stats.rx_frame_err;
    stat->rx_over_err = port->device->stats.rx_over_err;
    stat->rx_crc_err = port->device->stats.rx_crc_err;
    stat->collisions = port->device->stats.collisions;
    struct timespec duration = get_switch_port_uptime( port );
    stat->duration_sec = ( uint32_t ) duration.tv_sec;
    stat->duration_nsec = ( uint32_t ) duration.tv_nsec;
    stat++;
  }

  if ( !unlock_mutex( &mutex ) ) {
    return ERROR_UNLOCK;
  }

  return OFDPE_SUCCESS;
}
コード例 #9
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 );
}