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 ); }
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 ); }
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 ); }