Esempio n. 1
0
void
_switch_response_timeout( void *user_data ) {
  struct txinfo *txinfo = user_data;
  const uint64_t dpid = txinfo->dpid;
  const uint32_t txid = txinfo->txid;
  //  xfree( txinfo ); // cannot free since _switch_response_handler may be called later.
  txinfo = NULL;
  debug( "txid %#x switch %#" PRIx64 " time out. called", txid, dpid );

  all_sw_tx *tx = lookup_hash_entry( efi_tx_table, &txid );
  if ( tx == NULL ) {
    // transaction already failed. Do nothing.
    return;
  }

  uint64_t *dpid_in_list = lookup_hash_entry( tx->waiting_dpid, &dpid );
  if ( dpid_in_list != NULL ) {
    info( "txid %#x switch %#" PRIx64 " timed out.", txid, dpid );
    delete_hash_entry( tx->waiting_dpid, &dpid );
    xfree( dpid_in_list );
    tx->tx_result = EFI_OPERATION_FAILED;
  }

  check_tx_result_and_respond( tx );
}
Esempio n. 2
0
static void
handle_switch_disconnected( uint64_t datapath_id, void *switch_db ) {
  known_switch *sw = delete_hash_entry( switch_db, &datapath_id );
  if ( sw != NULL ) {
    delete_switch( sw );
  }
}
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( transaction_id );
  UNUSED( n_buffers );
  UNUSED( n_tables );
  UNUSED( capabilities );
  UNUSED( actions );
  show_desc *show_desc = user_data;
  desc_entry *desc = lookup_hash_entry( show_desc->db, &datapath_id );
  if ( desc == NULL ) {
    return;
  }

  display_desc( &desc->desc_stats );
  display_datapath_id( datapath_id );
  list_element ports_list;
  memcpy( &ports_list, phy_ports, sizeof( list_element ) );
  for ( list_element *port = &ports_list; port != NULL; port = port->next ) {
    display_port( port->data );
  }

  delete_hash_entry( show_desc->db, &datapath_id );
  show_desc->count--;
  xfree( desc );

  if ( show_desc->count == 0 ) {
    stop_trema();
  }
}
Esempio n. 4
0
static void
age_forwarding_db( void *mac, void *entry, void *forwarding_db ) {
  if ( aged_out( entry ) ) {
    delete_hash_entry( forwarding_db, mac );
    xfree( entry );
  }
}
Esempio n. 5
0
void
delete_match_entry( struct ofp_match *ofp_match ) {
  match_entry *delete_entry;
  list_element *list;

  pthread_mutex_lock( match_table_head.mutex );

  assert( ofp_match != NULL );
  if ( !ofp_match->wildcards ) {
    delete_entry = delete_hash_entry( match_table_head.exact_table, ofp_match );
    if ( delete_entry == NULL ) {
      pthread_mutex_unlock( match_table_head.mutex );
      return;
    }
  }
  else {
    for ( list = match_table_head.wildcard_table; list != NULL; list = list->next ) {
      delete_entry = list->data;
      if ( ( ( ( delete_entry->ofp_match.wildcards ^ ofp_match->wildcards ) & OFPFW_ALL ) == 0 )
          && compare_match( &delete_entry->ofp_match, ofp_match ) ) {
        break;
      }
    }
    if ( list == NULL ) {
      pthread_mutex_unlock( match_table_head.mutex );
      return;
    }
    delete_element( &match_table_head.wildcard_table, delete_entry );
  }
  free_match_entry( delete_entry );
  pthread_mutex_unlock( match_table_head.mutex );
}
Esempio n. 6
0
static bool
delete_http_transaction( http_transaction *transaction ) {
  debug( "Deleting a HTTP transaction from database ( transaction = %p, handle = %p ).",
         transaction, transaction->handle );

  assert( transaction != NULL );
  assert( transaction->handle != NULL );

  assert( transactions != NULL );
  void *deleted = delete_hash_entry( transactions, transaction->handle );
  if ( deleted == NULL ) {
    error( "Failed to delete a HTTP transaction ( transaction = %p, handle = %p ).",
           transaction, transaction->handle );
    return false;
  }
  assert( deleted == transaction );

  assert( curl_handle != NULL );
  CURLMcode ret = curl_multi_remove_handle( curl_handle, transaction->handle );
  if ( ret != CURLM_OK  && ret != CURLM_CALL_MULTI_PERFORM ) {
    error( "Failed to remove an easy handle from a multi handle ( curl_handle = %p, handle = %p, error = %s ).",
           curl_handle, transaction->handle, curl_multi_strerror( ret ) );
  }
  if ( transaction->slist != NULL ) {
    curl_slist_free_all( transaction->slist );
    transaction->slist = NULL;
  }
  curl_easy_cleanup( transaction->handle );
  transaction->handle = NULL;

  debug( "A HTTP transaction is deleted from database ( transaction = %p, handle = %p ).", transaction, transaction->handle );

  return true;
}
Esempio n. 7
0
static void
age_forwarding_db( void *key, void *forwarding_entry, void *forwarding_db ) {
  if ( aged_out( forwarding_entry ) ) {
    delete_hash_entry( forwarding_db, key );
    xfree( forwarding_entry );
  }
}
Esempio n. 8
0
void
_switch_response_handler( event_forward_operation_result result, void *user_data ) {
  struct txinfo *txinfo = user_data;
  const uint64_t dpid = txinfo->dpid;
  const uint32_t txid = txinfo->txid;
  delete_timer_event( _switch_response_timeout, txinfo );
  xfree( txinfo );
  txinfo = NULL;
  debug( "txid %#x switch %#" PRIx64 " response.", txid, dpid );

  all_sw_tx *tx = lookup_hash_entry( efi_tx_table, &txid );
  if ( tx == NULL ) {
    // transaction already failed. Do nothing.
    return;
  }

  uint64_t *dpid_in_list = lookup_hash_entry( tx->waiting_dpid, &dpid );
  if ( dpid_in_list == NULL ) {
    // probably timed out. Do nothing.
    return;
  }
  delete_hash_entry( tx->waiting_dpid, &dpid );
  xfree( dpid_in_list );
  dpid_in_list = NULL;

  if ( result.result == EFI_OPERATION_FAILED ) {
    warn( "txid %#x Setting event forwarding entry to switch %#" PRIx64 " failed.", txid, dpid );
    tx->tx_result = EFI_OPERATION_FAILED;
  }

  bool tx_ended = check_tx_result_and_respond( tx );
  if ( tx_ended ) return;

  struct event_forward_operation_to_all_request_param *all_param = tx->request_param;
  if ( hash_table_is_empty( tx->waiting_dpid ) ) {
    // was last element in tx. callback result.
    if ( all_param->callback != NULL ) {
      all_param->callback( tx->tx_result, all_param->user_data );
    }

    info( "txid %#x complete.", tx->txid );
    // remove and cleanup tx
    delete_hash_entry( efi_tx_table, &tx->txid );
    xfree_all_sw_tx( tx );
    return;
  }
}
Esempio n. 9
0
static void
test_nonexistent_entry_returns_NULL() {
  table = create_hash( compare_string, hash_string );

  assert_true( delete_hash_entry( table, "NO SUCH KEY" ) == NULL );

  delete_hash( table );
}
Esempio n. 10
0
static void
test_foreach() {
  table = create_hash( compare_string, hash_string );
  insert_hash_entry( table, alpha, alpha );
  insert_hash_entry( table, bravo, bravo );
  insert_hash_entry( table, charlie, charlie );
  delete_hash_entry( table, bravo );
  delete_hash_entry( table, charlie );

  foreach_hash( table, append_back_foreach, NULL );

  assert_string_equal( abc[ 0 ], "alpha" );
  assert_true( abc[ 1 ] == NULL );
  assert_true( abc[ 2 ] == NULL );

  delete_hash( table );
}
Esempio n. 11
0
File: fdb.c Progetto: mq24705/apps
static void
age_fdb_entry( void *key, void *value, void *user_data ) {
    hash_table *fdb = user_data;
    fdb_entry *entry = value;

    if ( entry->updated_at + FDB_ENTRY_TIMEOUT < time( NULL ) ) {
        debug( "Age out" );
        void *deleted = delete_hash_entry( fdb, key );
        xfree( deleted );
    }
}
static transaction_entry *
delete_transaction_entry_by_xid( uint32_t transaction_id ) {
  debug( "Deleting a transaction entry by transaction id ( transaction_db = %p, transaction_id = %#x ).", transaction_db, transaction_id );

  assert( transaction_db != NULL );
  assert( transaction_db->xid != NULL );
  assert( transaction_db->barrier_xid != NULL );

  transaction_entry *deleted = delete_hash_entry( transaction_db->xid, &transaction_id );
  if ( deleted != NULL ) {
    debug( "A transaction entry is deleted by transaction_id ( transaction_db = %p, transaction_id = %#x ).", transaction_db, transaction_id );
    debug( "Deleting a transaction entry by barrier transaction id ( transaction_db = %p, transaction_id = %#x ).", transaction_db, transaction_id );
    delete_hash_entry( transaction_db->barrier_xid, &deleted->barrier_xid );
  }
  else {
    debug( "Failed to delete a transaction entry by transaction_id ( transaction_db = %p, transaction_id = %#x ).", transaction_db, transaction_id );
  }

  return deleted;
}
Esempio n. 13
0
void
_cleanup_tx_table() {
  hash_iterator it;
  init_hash_iterator( efi_tx_table, &it );
  hash_entry *e = NULL;
  while ( ( e = iterate_hash_next( &it ) ) != NULL ) {
    all_sw_tx *tx = e->value;
    warn( "txid:%#x was left behind.", tx->txid );

    delete_hash_entry( efi_tx_table, &tx->txid );
    xfree_all_sw_tx( tx );
  }
}
Esempio n. 14
0
void
delete_dpid_entry( uint64_t *dpid ) {
  assert( dpid_table != NULL );
  assert( dpid != NULL );

  uint64_t *deleted_entry = delete_hash_entry( dpid_table, dpid );
  if ( deleted_entry == NULL ) {
    warn( "datapath %#" PRIx64 " is not found.", *dpid );
    return;
  }

  xfree( deleted_entry );
}
Esempio n. 15
0
static void
test_multiple_inserts_and_deletes_then_iterate() {
  table = create_hash( compare_string, hash_string );

  char one[] = "one";
  insert_hash_entry( table, one, ( void * ) 1 );
  delete_hash_entry( table, one );
  insert_hash_entry( table, one, ( void * ) 1 );
  delete_hash_entry( table, one );
  insert_hash_entry( table, one, ( void * ) 1 );

  int sum = 0;
  hash_iterator iter;
  hash_entry *e;
  init_hash_iterator( table, &iter );
  while ( ( e = iterate_hash_next( &iter ) ) != NULL ) {
    sum += ( int ) ( uintptr_t ) e->value;
    delete_hash_entry( table, e->key );
  }
  assert_true( sum == 1 );

  delete_hash( table );
}
Esempio n. 16
0
File: stat.c Progetto: nhst/trema
/**
 * Delete the global hash_table which stored the stats of parameters.
 * @param None
 * @return None
 */
static void
delete_stats_table() {
  hash_iterator iter;
  hash_entry *e;

  assert( stats != NULL );

  init_hash_iterator( stats, &iter );
  while ( ( e = iterate_hash_next( &iter ) ) != NULL ) {
    void *value = delete_hash_entry( stats, e->key );
    xfree( value );
  }
  delete_hash( stats );
  stats = NULL;
}
Esempio n. 17
0
static void
test_delete_entry() {
  table = create_hash( compare_string, hash_string );

  insert_hash_entry( table, alpha, alpha );
  insert_hash_entry( table, bravo, bravo );
  insert_hash_entry( table, charlie, charlie );

  delete_hash_entry( table, bravo );
  assert_string_equal( lookup_hash_entry( table, alpha ), "alpha" );
  assert_true( lookup_hash_entry( table, bravo ) == NULL );
  assert_string_equal( lookup_hash_entry( table, charlie ), "charlie" );

  delete_hash( table );
}
Esempio n. 18
0
static void
age_host_db_entry( void *key, void *value, void *user_data ) {
  UNUSED( user_data );

  host_entry *entry = value;

  if ( entry->updated_at + HOST_DB_ENTRY_TIMEOUT < time( NULL ) ) {
    struct in_addr addr;
    addr.s_addr = htonl( entry->ip );
    debug( "Host DB: age out (ip = %s).", inet_ntoa( addr ) );
    delete_host_route( entry->ip );
    void *deleted = delete_hash_entry( host_db, key );
    xfree( deleted );
  }
}
Esempio n. 19
0
void
delete_xid_entry( xid_entry_t *delete_entry ) {
  debug( "Deleting xid entry ( xid = %#lx, original_xid = %#lx, service_name = %s, index = %d ).",
         delete_entry->xid, delete_entry->original_xid, delete_entry->service_name, delete_entry->index );

  xid_entry_t *deleted = delete_hash_entry( xid_table.hash, &delete_entry->xid );

  if ( deleted == NULL ) {
    error( "Failed to delete xid entry ( xid = %#lx ).", delete_entry->xid );
    free_xid_entry( ( xid_entry_t * ) delete_entry );
    return;
  }

  xid_table.entries[ deleted->index ] = NULL;
  free_xid_entry( deleted );
}
Esempio n. 20
0
static bool
check_tx_result_and_respond( all_sw_tx *tx ) {
  if ( tx->tx_result == EFI_OPERATION_FAILED ) {
    struct event_forward_operation_to_all_request_param *all_param = tx->request_param;
    if ( all_param->callback != NULL ) {
      all_param->callback( tx->tx_result, all_param->user_data );
    }

    info( "txid %#x completed with failure.", tx->txid );
    // remove and cleanup tx
    delete_hash_entry( efi_tx_table, &tx->txid );
    xfree_all_sw_tx( tx );
    return true;
  }
  return false;
}
Esempio n. 21
0
static void
test_iterator() {
  table = create_hash( compare_string, hash_string );

  char one[] = "one";
  insert_hash_entry( table, one, ( void * ) 1 );

  char two[] = "two";
  insert_hash_entry( table, two, ( void * ) 2 );

  char three[] = "three";
  insert_hash_entry( table, three, ( void * ) 3 );

  char four[] = "four";
  insert_hash_entry( table, four, ( void * ) 4 );

  char five[] = "five";
  insert_hash_entry( table, five, ( void * ) 5 );

  char six[] = "six";
  insert_hash_entry( table, six, ( void * ) 6 );

  char seven[] = "seven";
  insert_hash_entry( table, seven, ( void * ) 7 );

  char eight[] = "eight";
  insert_hash_entry( table, eight, ( void * ) 8 );

  char nine[] = "nine";
  insert_hash_entry( table, nine, ( void * ) 9 );

  char ten[] = "ten";
  insert_hash_entry( table, ten, ( void * ) 10 );

  int sum = 0;
  hash_iterator iter;
  hash_entry *e;
  init_hash_iterator( table, &iter );
  while ( ( e = iterate_hash_next( &iter ) ) != NULL ) {
    sum += ( int ) ( uintptr_t ) e->value;
    delete_hash_entry( table, e->key );
  }
  assert_true( sum == 55 );

  delete_hash( table );
}
Esempio n. 22
0
static void *
delete_exact_match_strict_entry( hash_table *exact_table, struct ofp_match *match ) {
  assert( exact_table != NULL );
  assert( match != NULL );

  match_entry *entry = lookup_hash_entry( exact_table, match );
  if ( entry == NULL ) {
    char match_string[ MATCH_STRING_LENGTH ];
    match_to_string( match, match_string, sizeof( match_string ) );
    warn( "exact match entry not found ( match = [%s] )",
          match_string );
    return NULL;
  }
  void *data = entry->data;
  delete_hash_entry( exact_table, match );
  free_match_entry( entry );
  return data;
}
void
print_with_graph_easy_format( void *param, size_t entries, const topology_link_status *s ) {
  size_t i;

  UNUSED( param );

  debug( "topology: entries %d", entries );

  hash_table *link_hash = create_hash( compare_link, hash_link );
  // show_topology graph-easy | graph-easy
  // Graph-Easy:
  //   http://search.cpan.org/~shlomif/Graph-Easy/bin/graph-easy
  printf("#! /usr/bin/env graph-easy\n" );

  for ( i = 0; i < entries; i++ ) {
    if ( s[ i ].status != TD_LINK_UP ) {
      continue;
    }
    topology_link_status r;
    r.from_dpid = s[ i ].to_dpid;
    r.from_portno = s[ i ].to_portno;
    r.to_dpid = s[ i ].from_dpid;
    r.to_portno = s[ i ].from_portno;

    topology_link_status *e = lookup_hash_entry( link_hash, &r );
    if ( e != NULL ) {
      delete_hash_entry( link_hash, e );
      print_link_status( e, true );
    } else {
      insert_hash_entry( link_hash, ( void * ) ( intptr_t ) &s[ i ], ( void *) ( intptr_t ) &s[ i ] );
    }
  }
  hash_iterator iter;
  init_hash_iterator( link_hash, &iter );
  hash_entry *e;
  while ( ( e = iterate_hash_next( &iter ) ) != NULL ) {
    topology_link_status *le = e->value;
    print_link_status( le, false );
  }

  delete_hash( link_hash );

  stop_trema();
}
static void
handle_port_desc_reply( uint64_t datapath_id, uint32_t transaction_id,
                        uint16_t type, uint16_t flags, const buffer *data,
                       void *user_data ) {
  UNUSED( transaction_id );
  UNUSED( type );
  UNUSED( flags );
  show_desc *show_desc = user_data;

  desc_entry *desc = lookup_hash_entry( show_desc->db, &datapath_id );
  if ( desc == NULL ) {
    return;
  }
  append_to_tail( &desc->port_desc, duplicate_buffer( data ) );

  if ( more_requests( flags ) ) {
    return;
  }

  display_desc( &desc->desc_stats );
  display_datapath_id( datapath_id );
  for ( list_element *e = desc->port_desc; e != NULL; e = e->next ) {
    buffer *data = e->data;
    struct ofp_port *port = ( struct ofp_port  * ) data->data;
    size_t length = data->length;
    while ( length >= sizeof( struct ofp_port ) ) {
      display_port( port );
      length -= ( uint16_t ) sizeof( struct ofp_port );
      port++;
    }
    free_buffer( e->data );
  }
  delete_list( desc->port_desc );
  delete_hash_entry( show_desc->db, &datapath_id );
  show_desc->count--;
  xfree( desc );

  if ( show_desc->count == 0 ) {
    stop_trema();
  }
}
static bool
delete_transaction( uint64_t datapath_id, uint32_t vni ) {
  debug( "Deleting a transaction record ( datapath_id = %#" PRIx64 ", vni = %#x ).", datapath_id, vni );

  if ( !valid_vni( vni ) ) {
    return false;
  }

  transaction_entry key = { datapath_id, vni, 0, 0, 0, 0, NULL, NULL };
  transaction_entry *entry = delete_hash_entry( transactions, &key );
  if ( entry == NULL ) {
    error( "Failed to find a transaction entry ( datapath_id %" PRIx64 ", vni = %#x ).",
           key.datapath_id, key.vni );
    return false;
  }
  xfree( entry );

  debug( "A transaction record is deleted ( datapath_id = %#" PRIx64 ", vni = %#x ).", datapath_id, vni );

  return true;
}
Esempio n. 26
0
void
finalize_switch_port() {
  assert( switch_ports != NULL );

  hash_iterator iter;
  hash_entry *e;
  init_hash_iterator( switch_ports, &iter );
  while ( ( e = iterate_hash_next( &iter ) ) != NULL ) {
    switch_port *port = delete_hash_entry( switch_ports, e->key );
    if ( port == NULL ) {
      continue;
    }

    if ( port->device != NULL ) {
      delete_ether_device( port->device );
    }
    xfree( port );
  }
  delete_hash( switch_ports );
  switch_ports = NULL;
}
Esempio n. 27
0
File: fdb.c Progetto: mq24705/apps
void
delete_fdb_entries( hash_table *fdb, uint64_t dpid, uint16_t port ) {
    if ( fdb == NULL ) {
        return;
    }

    debug( "Deleting fdb entries ( dpid = %#" PRIx64 ", port = %u ).", dpid, port );

    fdb_entry *entry = NULL;
    hash_iterator iter;
    hash_entry *e;
    init_hash_iterator( fdb, &iter );
    while ( ( e = iterate_hash_next( &iter ) ) != NULL ) {
        if ( e->value == NULL ) {
            continue;
        }
        entry = e->value;
        if ( entry->dpid == dpid && entry->port == port ) {
            delete_hash_entry( fdb, entry->mac );
            xfree( entry );
        }
    }
}
Esempio n. 28
0
void
_dispatch_to_all_switch( uint64_t *dpids, size_t n_dpids, void *user_data ) {
  struct event_forward_operation_to_all_request_param *param = user_data;

  all_sw_tx *tx = _insert_tx( n_dpids, param );
  info( "txid %#x Start dispatching to switches", tx->txid );
  debug( "dispatching to %zd switches", n_dpids );
  // copy dpid hash to transaction.
  for ( size_t i = 0 ; i < n_dpids ; ++i ) {
    uint64_t *dpid = xmalloc( sizeof( uint64_t ) );
    *dpid = dpids[i];
    uint64_t *dupe_dpid = insert_hash_entry( tx->waiting_dpid, dpid, dpid );
    if ( dupe_dpid == NULL ) {
      struct txinfo *txinfo = xcalloc( 1, sizeof( struct txinfo ) );
      txinfo->dpid = *dpid;
      txinfo->txid = tx->txid;
      bool send_ok;

      if ( param->add ) {
        send_ok = add_switch_event_forward_entry( *dpid, param->type, param->service_name, _switch_response_handler, txinfo );
      }
      else {
        send_ok = delete_switch_event_forward_entry( *dpid, param->type, param->service_name, _switch_response_handler, txinfo );
      }

      if ( !send_ok ) {
        tx->tx_result = EFI_OPERATION_FAILED;
        warn( "txid %#x Failed to send request to switch %#" PRIx64 ".", tx->txid, *dpid );
        xfree( delete_hash_entry( tx->waiting_dpid, dpid ) );
        dpid = NULL;
        xfree( txinfo );
        continue;
      }

      struct itimerspec interval;
      interval.it_interval.tv_sec = 0;
      interval.it_interval.tv_nsec = 0;
      interval.it_value.tv_sec = 5; // FIXME make this configurable?
      interval.it_value.tv_nsec = 0;
      bool set_ok = add_timer_event_callback( &interval, _switch_response_timeout, txinfo );
      if ( !set_ok ) {
        tx->tx_result = EFI_OPERATION_FAILED;
        warn( "txid %#x Failed to set timeout timer for switch %#" PRIx64 ".", tx->txid, *dpid );
        xfree( delete_hash_entry( tx->waiting_dpid, dpid ) );
        dpid = NULL;
        // txinfo will be freed by _switch_response_handler
        continue;
      }
    }
    else {
      warn( "Duplicate dpid returned %#." PRIx64, *dupe_dpid );
      xfree( dupe_dpid );
    }
  }

  if ( n_dpids == 0 || tx->tx_result == EFI_OPERATION_FAILED ) {
    if ( n_dpids == 0 ) {
      info( "txid %#x completed. No switches found.", tx->txid );
    }
    else if ( tx->tx_result == EFI_OPERATION_FAILED ) {
      info( "txid %#x completed with failure.", tx->txid );
    }
    if ( param->callback != NULL ) {
      param->callback( tx->tx_result, param->user_data );
    }
    // remove and cleanup tx
    delete_hash_entry( efi_tx_table, &tx->txid );
    xfree_all_sw_tx( tx );
  }
}
Esempio n. 29
0
void
delete_datapath_entry( hash_table *db, uint64_t datapath_id ) {
  datapath_entry *entry = delete_hash_entry( db, &datapath_id );
  free_datapath_entry( entry );
  debug( "delete datapath: %#" PRIx64 " ( entry = %p )", datapath_id, entry );
}
Esempio n. 30
0
switch_port *
delete_switch_port( uint32_t port_no ) {
  assert( switch_ports != NULL );

  return delete_hash_entry( switch_ports, &port_no );
}