Пример #1
0
static void
make_path( sliceable_switch *sliceable_switch, uint64_t in_datapath_id, uint16_t in_port, uint16_t in_vid,
           uint64_t out_datapath_id, uint16_t out_port, uint16_t out_vid, const buffer *packet ) {
  dlist_element *hops = resolve_path( sliceable_switch->pathresolver, in_datapath_id, in_port, out_datapath_id, out_port );
  if ( hops == NULL ) {
    warn( "No available path found ( %#" PRIx64 ":%u -> %#" PRIx64 ":%u ).",
          in_datapath_id, in_port, out_datapath_id, out_port );
    discard_packet_in( in_datapath_id, in_port, packet );
    return;
  }

  // check if the packet is ARP or not
  if ( sliceable_switch->handle_arp_with_packetout && packet_type_arp( packet ) ) {
    // send packet out for tail switch
    free_hop_list( hops );
    output_packet( packet, out_datapath_id, out_port, out_vid );
    return;
  }

  const uint32_t wildcards = 0;
  struct ofp_match match;
  set_match_from_packet( &match, in_port, wildcards, packet );

  if ( lookup_path( in_datapath_id, match, PRIORITY ) != NULL ) {
    warn( "Duplicated path found." );
    output_packet( packet, out_datapath_id, out_port, out_vid );
    return;
  }

  const uint16_t hard_timeout = 0;
  path *p = create_path( match, PRIORITY, sliceable_switch->idle_timeout, hard_timeout );
  assert( p != NULL );
  for ( dlist_element *e = get_first_element( hops ); e != NULL; e = e->next ) {
    pathresolver_hop *rh = e->data;
    hop *h = create_hop( rh->dpid, rh->in_port_no, rh->out_port_no, NULL );
    assert( h != NULL );
    append_hop_to_path( p, h );
  } // for(;;)

  dlist_element *e = get_last_element( hops );
  pathresolver_hop *last_hop = e->data;
  packet_out_params *params = xmalloc( sizeof( struct packet_out_params ) );
  params->packet = duplicate_buffer( packet );
  params->out_datapath_id = last_hop->dpid;
  params->out_port_no = last_hop->out_port_no;
  params->out_vid = out_vid;

  bool ret = setup_path( p, handle_setup, params, NULL, NULL );
  if ( ret != true ) {
    error( "Failed to set up path." );
    output_packet( packet, out_datapath_id, out_port, out_vid );
    free_buffer( params->packet );
    xfree( params );
  }

  delete_path( p );

  // free them
  free_hop_list( hops );
}
static void
make_path( routing_switch *routing_switch, uint64_t in_datapath_id, uint16_t in_port,
           uint64_t out_datapath_id, uint16_t out_port, const buffer *packet ) {
  dlist_element *hops = resolve_path( routing_switch->pathresolver, in_datapath_id, in_port, out_datapath_id, out_port );

  if ( hops == NULL ) {
    warn( "No available path found ( %#" PRIx64 ":%u -> %#" PRIx64 ":%u ).",
          in_datapath_id, in_port, out_datapath_id, out_port );
    discard_packet_in( in_datapath_id, in_port, packet );
    return;
  }

  // count elements
  uint32_t hop_count = count_hops( hops );

  // send flow entry from tail switch
  for ( dlist_element *e = get_last_element( hops ); e != NULL; e = e->prev, hop_count-- ) {
    uint16_t idle_timer = ( uint16_t ) ( routing_switch->idle_timeout + hop_count );
    modify_flow_entry( e->data, packet, idle_timer );
  } // for(;;)

  // send packet out for tail switch
  dlist_element *e = get_last_element( hops );
  pathresolver_hop *last_hop = e->data;
  output_packet_from_last_switch( last_hop, packet );

  // free them
  free_hop_list( hops );
}
Пример #3
0
Файл: switch.c Проект: iqm/apps
static void
make_path( routing_switch *routing_switch, uint64_t in_datapath_id, uint16_t in_port,
           uint64_t out_datapath_id, uint16_t out_port, const buffer *packet ) {
  dlist_element *hops = resolve_path( routing_switch->path_resolver, in_datapath_id, in_port, out_datapath_id, out_port );

  if ( hops == NULL ) {
    warn( "No available path found ( %#" PRIx64 ":%u -> %#" PRIx64 ":%u ).",
          in_datapath_id, in_port, out_datapath_id, out_port );
    discard_packet_in( in_datapath_id, in_port, packet );
    return;
  }

  // ask path manager to install flow entries
  size_t length = offsetof( path_manager_path, hops ) + sizeof( path_manager_hop ) * count_hops( hops );
  path_manager_path *path = xmalloc( length );
  set_match_from_packet( &path->match, OFPP_NONE, 0, packet );
  path->n_hops = count_hops( hops );
  dlist_element *e = get_first_element( hops );
  for( int i = 0; e != NULL; e = e->next, i++ ) {
    path_resolver_hop *hop = e->data;
    path->hops[ i ].datapath_id = hop->dpid;
    path->hops[ i ].in_port = hop->in_port_no;
    path->hops[ i ].out_port = hop->out_port_no;
  }
  send_message( PATH_SETUP_SERVICE_NAME, MESSENGER_PATH_SETUP_REQUEST, ( void * ) path, length );
  xfree( path );

  // send packet out to tail switch
  output_packet_from_last_switch( hops, packet );

  // free hop list
  free_hop_list( hops );
}
Пример #4
0
static void
resolve_path_replied( void *user_data, dlist_element *hops ) {
  assert( user_data != NULL );

  resolve_path_replied_params *param = user_data;
  routing_switch *routing_switch = param->routing_switch;
  buffer *original_packet = param->original_packet;

  if ( hops == NULL ) {
    warn( "No available path found." );
    free_buffer( original_packet );
    xfree( param );
    return;
  }

  original_packet->user_data = NULL;
  if ( !parse_packet( original_packet ) ) {
    warn( "Received unsupported packet" );
    free_packet( original_packet );
    free_hop_list( hops );
    xfree( param );
    return;
  }

  // count elements
  uint32_t hop_count = count_hops( hops );

  // send flow entry from tail switch
  for ( dlist_element *e  = get_last_element( hops ); e != NULL; e = e->prev, hop_count-- ) {
    uint16_t idle_timer = ( uint16_t ) ( routing_switch->idle_timeout + hop_count );
    modify_flow_entry( e->data, original_packet, idle_timer );
  } // for(;;)

  // send packet out for tail switch
  dlist_element *e = get_last_element( hops );
  pathresolver_hop *last_hop = e->data;
  output_packet_from_last_switch( last_hop, original_packet );

  // free them
  free_hop_list( hops );
  free_packet( original_packet );
  xfree( param );
}