void add_flow(u_int8_t dst[6],u_int8_t src[6],u_int16_t frame_type,u_int8_t inport,u_int8_t outport,u_int8_t idx) { struct sw_flow *flow = malloc(sizeof(struct sw_flow)); memset((char *)flow,0,16); flow->valid = 1; flow->input_port = inport; flow->action = outport; flow->frame_type = htons(frame_type); memcpy(flow->src_mac, src , 6); memcpy(flow->dst_mac, dst , 6); if ( add_flow_entry(flow, idx) == 0) { printf("add succ\n"); } else printf("add failed!\n"); free(flow); }
OFDPE update_or_add_flow_entry( const uint8_t table_id, const match *key, const uint64_t cookie, const uint64_t cookie_mask, const uint16_t priority, const uint16_t idle_timeout, const uint16_t hard_timeout, const uint16_t flags, const bool strict, instruction_set *instructions ) { if ( !valid_table_id( table_id ) ) { return ERROR_OFDPE_FLOW_MOD_FAILED_BAD_TABLE_ID; } if ( key == NULL ) { error( "Invalid match ( %p ).", key ); return ERROR_INVALID_PARAMETER; } if ( instructions == NULL ) { error( "Invalid instruction set ( %p ).", instructions ); return ERROR_INVALID_PARAMETER; } if ( !lock_pipeline() ) { return ERROR_LOCK; } flow_table *table = get_flow_table( table_id ); assert( table != NULL ); OFDPE ret = validate_instruction_set( instructions, table->features.metadata_write ); if ( ret != OFDPE_SUCCESS ) { error( "Invalid instruction set ( ret = %#x, instructions = %p ).", ret, instructions ); unlock_pipeline(); return ret; } list_element *list = lookup_flow_entries_with_table_id( table_id, key, priority, strict, false ); if ( list != NULL ) { update_flow_entries_in_list( list, cookie, cookie_mask, flags, instructions ); delete_list( list ); } else { match *duplicated_match = duplicate_match( key ); instruction_set *duplicated_instructions = duplicate_instructions( instructions ); flow_entry *entry = alloc_flow_entry( duplicated_match, duplicated_instructions, priority, idle_timeout, hard_timeout, flags, cookie ); if ( entry != NULL ) { ret = add_flow_entry( table_id, entry, flags ); if ( ret != OFDPE_SUCCESS ) { error( "Failed to add flow entry ( table_id = %#x, entry = %p, flags = %#x ).", table_id, entry, flags ); } } else { delete_match( duplicated_match ); delete_instructions( duplicated_instructions ); ret = OFDPE_FAILED; } } if ( !unlock_pipeline() ) { return ERROR_UNLOCK; } return ret; }
static void handle_flow_mod_add( const uint32_t transaction_id, const uint64_t cookie, const uint64_t cookie_mask, const uint8_t table_id, const uint16_t idle_timeout, const uint16_t hard_timeout, const uint16_t priority, const uint32_t buffer_id, const uint16_t flags, const oxm_matches *oxm, const openflow_instructions *instructions, struct protocol *protocol ) { UNUSED( cookie_mask ); /* * currently if flags set OFPFF_SEND_FLOW_REM and OFPFF_RESET_COUNTS are the only allowed value. */ if ( ( flags & ~( OFPFF_SEND_FLOW_REM | OFPFF_RESET_COUNTS ) ) != 0 ) { send_error_message( transaction_id, OFPET_FLOW_MOD_FAILED, OFPFMFC_BAD_FLAGS ); return; } /* * The use of OFPTT_ALL is only valid for delete requests. */ if ( table_id == OFPTT_ALL ) { send_error_message( transaction_id, OFPET_FLOW_MOD_FAILED, OFPFMFC_BAD_TABLE_ID ); return; } /* * If no buffered packet is associated with a flow mod it must be set * to OFP_NO_BUFFER otherwise it must be equal to the buffer_id sent to * controller by a packet-in message. */ match *match = create_match(); if ( oxm != NULL && oxm->n_matches > 0 ) { #ifdef DEBUG char oxm_str[ 2048 ]; match_to_string( oxm, oxm_str, sizeof( oxm_str ) ); printf( "%s\n", oxm_str ); #endif for ( list_element *e = oxm->list; e != NULL; e = e->next ) { oxm_match_header *hdr = e->data; assign_match( match, hdr ); } } instruction_set *instruction_set = create_instruction_set(); if ( instructions != NULL ) { OFDPE ret = assign_instructions( instruction_set, instructions->list ); if ( ret != OFDPE_SUCCESS ) { send_error_message( transaction_id, OFPET_FLOW_MOD_FAILED, OFPBIC_UNSUP_INST ); delete_instruction_set( instruction_set ); delete_match( match ); return; } } /* * When a flow entry is inserted in a table, its flags field is set with the * values from the message. * When a flow entry is inserted in a table, its idle_timeout and * hard_timeout fields are set with the values from the message. * When a flow entry is inserted in a table through an OFPFC_ADD message, * its cookie field is set to the provided value */ flow_entry *new_entry = alloc_flow_entry( match, instruction_set, priority, idle_timeout, hard_timeout, flags, cookie ); if ( new_entry == NULL ) { /* * TODO we should send a more appropriate error once we worked out the * datapath errors. */ delete_instruction_set( instruction_set ); delete_match( match ); send_error_message( transaction_id, OFPET_FLOW_MOD_FAILED, OFPFMFC_UNKNOWN ); return; } OFDPE ret = add_flow_entry( table_id, new_entry, flags ); if ( ret != OFDPE_SUCCESS ) { error( "Failed to add a flow entry ( ret = %d ).", ret ); delete_instruction_set( instruction_set ); delete_match( match ); uint16_t type = OFPET_FLOW_MOD_FAILED; uint16_t code = OFPFMFC_UNKNOWN; get_ofp_error( ret, &type, &code ); send_error_message( transaction_id, type, code ); return; } if ( buffer_id != OFP_NO_BUFFER ) { action_list *actions = create_action_list(); action *action = create_action_output( OFPP_TABLE, UINT16_MAX ); append_action( actions, action ); ret = execute_packet_out( buffer_id, 0, actions, NULL ); delete_action_list( actions ); if ( ret != OFDPE_SUCCESS ) { uint16_t type = OFPET_FLOW_MOD_FAILED; uint16_t code = OFPFMFC_UNKNOWN; get_ofp_error( ret, &type, &code ); send_error_message( transaction_id, type, code ); return; } wakeup_datapath( protocol ); } }