Example #1
0
static bool
insert_wildcards_match_entry( list_element **wildcards_table, struct ofp_match *match, uint16_t priority, void *data ) {
  assert( match != NULL );

  list_element *element;
  for ( element = *wildcards_table; element != NULL; element = element->next ) {
    match_entry *entry = element->data;
    if ( entry->priority < priority ) {
      break;
    }
    assert( entry != NULL );
    if ( entry->priority == priority && compare_match_strict( &entry->match, match ) ) {
      char match_string[ MATCH_STRING_LENGTH ];
      match_to_string( match, match_string, sizeof( match_string ) );
      warn( "wildcards match entry already exists ( match = [%s], priority = %u )",
            match_string, priority );
      return false;
    }
  }
  match_entry *new_entry = allocate_match_entry( match, priority, data );
  if ( element == NULL ) {
    // tail
    append_to_tail( wildcards_table, new_entry );
  }
  else if ( element == *wildcards_table ) {
    // head
    insert_in_front( wildcards_table, new_entry );
  }
  else {
    // insert before
    insert_before( wildcards_table, element->data, new_entry );
  }
  return true;
}
Example #2
0
static OFDPE
insert_flow_entry( flow_table *table, flow_entry *entry, const uint16_t flags ) {
  assert( table != NULL );
  assert( entry != NULL );

  list_element *element = table->entries;
  while( element != NULL ) {
    list_element *next = element->next;
    flow_entry *e = element->data;
    assert( e != NULL );
    if ( e->priority < entry->priority ) {
      break;
    }
    if ( e->priority == entry->priority ) {
      if ( e->table_miss && !entry->table_miss ) {
        break;
      }
      if ( ( flags & OFPFF_CHECK_OVERLAP ) != 0 && compare_match( e->match, entry->match ) ) {
        return ERROR_OFDPE_FLOW_MOD_FAILED_OVERLAP;
      }
      if ( compare_match_strict( e->match, entry->match ) ) {
        if ( ( flags & OFPFF_RESET_COUNTS ) != 0 ) {
          entry->byte_count = e->byte_count;
          entry->packet_count = e->packet_count;
        }
        flow_table *table = get_flow_table( e->table_id );
        assert( table != NULL );
        delete_flow_entry_from_table( table, e, 0, false );
      }
    }
    element = next;
  }

  if ( element == NULL ) {
    // tail
    append_to_tail( &table->entries, entry );
  }
  else if ( element == table->entries ) {
    // head
    insert_in_front( &table->entries, entry );
  }
  else {
    // insert before
    insert_before( &table->entries, element->data, entry );
  }

  increment_active_count( table->features.table_id );

  return OFDPE_SUCCESS;
}
Example #3
0
void
insert_match_entry( struct ofp_match *ofp_match, uint16_t priority, const char *service_name, const char *entry_name ) {
  match_entry *new_entry, *entry;
  list_element *list;

  pthread_mutex_lock( match_table_head.mutex );

  new_entry = allocate_match_entry( ofp_match, priority, service_name, entry_name );

  if ( !ofp_match->wildcards ) {
    entry = lookup_hash_entry( match_table_head.exact_table, ofp_match );
    if ( entry != NULL ) {
      warn( "insert entry exits" );
      free_match_entry( new_entry );
      pthread_mutex_unlock( match_table_head.mutex );
      return;
    }
    insert_hash_entry( match_table_head.exact_table, &new_entry->ofp_match, new_entry );
    pthread_mutex_unlock( match_table_head.mutex );
    return;
  }

  // wildcard flags are set
  for ( list = match_table_head.wildcard_table; list != NULL; list = list->next ) {
    entry = list->data;
    if ( entry->priority <= new_entry->priority ) {
      break;
    }
  }
  if ( list == NULL ) {
    // wildcard_table is null or tail
    append_to_tail( &match_table_head.wildcard_table, new_entry );
    pthread_mutex_unlock( match_table_head.mutex );
    return;
  }
  if ( list == match_table_head.wildcard_table ) {
    // head
    insert_in_front( &match_table_head.wildcard_table, new_entry );
    pthread_mutex_unlock( match_table_head.mutex );
    return;
  }

  // insert brefore
  insert_before( &match_table_head.wildcard_table, list->data, new_entry );
  pthread_mutex_unlock( match_table_head.mutex );
}
static void
insert_data( list_element **head, const topology_link_status *s ) {
  list_element *element;
  for ( element = *head; element != NULL; element = element->next ) {
    const topology_link_status *entry = element->data;
    if ( entry->from_dpid > s->from_dpid ) {
      break;
    }
    if ( entry->from_dpid < s->from_dpid ) {
      continue;
    }
    if ( entry->from_portno > s->from_portno ) {
      break;
    }
    if ( entry->from_portno < s->from_portno ) {
      continue;
    }
    if ( entry->to_dpid > s->to_dpid ) {
      break;
    }
    if ( entry->to_dpid < s->to_dpid ) {
      continue;
    }
    if ( entry->to_portno > s->to_portno ) {
      break;
    }
  }
  if ( element == NULL ) {
    append_to_tail( head, ( void * ) ( intptr_t ) s );
  }
  else if ( element == *head ) {
    insert_in_front( head, ( void * ) ( intptr_t ) s );
  }
  else {
    insert_before( head, element->data, ( void * ) ( intptr_t ) s );
  }
}
Example #5
0
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;
}
Example #6
0
File: switch.c Project: 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;
}