/*********************************************************************** * Handle the instruction with POFIT_GOTO_DIRECT_TABLE type. * Form: uint32_t pofdp_instruction_handle_goto_direct_table(uint8_t *packet, \ * uint8_t *ins_data, \ * uint8_t *table_type, \ * uint8_t *table_id, \ * uint32_t *packet_over, \ * pof_flow_entry **entry_ptrptr) * Input: packet, length of packet, instruction data * Output: table type, table id, packet over identifier, Entry * Return: POF_OK or Error code * Discribe: This function forward the packet to the direct table. The * type and id of the next table will be calculated according * to the table_ID which is global number given in ins_data. * NOTE: If there is an ERROR, The packet_over identifier will be TRUE. ***********************************************************************/ static uint32_t execute_GOTO_DIRECT_TABLE(POFDP_ARG) { pof_instruction_goto_direct_table *p = \ (pof_instruction_goto_direct_table *)dpp->ins->instruction_data; poflr_flow_table *tmp_table; poflr_flow_entry *tmp_entry; uint8_t *table_type = &dpp->table_type; uint8_t *table_id = &dpp->table_id; uint32_t i, ret, entry_index; p = (pof_instruction_goto_direct_table *)dpp->ins->instruction_data; /* The packet forward to the next table. */ ret = move_packet_offset_forward(dpp, p->packet_offset); POF_CHECK_RETVALUE_RETURN_NO_UPWARD(ret); /* Find the table type and id of the next direct table. */ ret = poflr_table_ID_to_id(p->next_table_id, table_type, table_id); POF_CHECK_RETVALUE_RETURN_NO_UPWARD(ret); entry_index = p->table_entry_index; poflr_get_flow_table(&tmp_table, *table_type, *table_id); POF_DEBUG_CPRINT_FL(1,YELLOW,"Go to DT table[%d][%d][%d]!", *table_type, *table_id, entry_index); /* Check the table type. */ if(*table_type != POF_LINEAR_TABLE){ POF_ERROR_HANDLE_RETURN_UPWARD(POFET_BAD_ACTION, POFBIC_BAD_TABLE_TYPE, g_upward_xid++); } /* Check the table state. */ if(tmp_table->state == POFLR_STATE_INVALID){ POF_ERROR_HANDLE_RETURN_UPWARD(POFET_BAD_ACTION, POFBIC_TABLE_UNEXIST, g_upward_xid++); } tmp_entry = &(tmp_table->entry_ptr[entry_index]); /* Check the flow entry. */ if(tmp_entry->state == POFLR_STATE_INVALID){ POF_ERROR_HANDLE_RETURN_UPWARD(POFET_BAD_ACTION, POFBIC_ENTRY_UNEXIST, g_upward_xid++); } /* Load the flow entry data. */ dpp->flow_entry = &tmp_entry->entry; /* Increase the counter value. */ ret = poflr_counter_increace(dpp->flow_entry->counter_id); POF_CHECK_RETVALUE_RETURN_NO_UPWARD(ret); /* Update the instruction number and the instruction data corresponding to the * matched flow entry in the current flow table. */ dpp->ins = dpp->flow_entry->instruction; dpp->ins_todo_num = dpp->flow_entry->instruction_num; dpp->ins_done_num = 0; POF_DEBUG_CPRINT_FL(1,GREEN,"Match entry! "); return POF_OK; }
static void flow_table(){ poflr_flow_table *p = NULL; uint8_t *table_num = NULL; int type, table_id, entry_id; poflr_get_table_number(&table_num); for(type=0; type<POF_MAX_TABLE_TYPE; type++){ for(table_id=0; table_id<table_num[type]; table_id++){ poflr_get_flow_table(&p, type, table_id); if(p->state == POFLR_STATE_INVALID){ continue; } flow_table_single(*p); } } }
/*********************************************************************** * Handle the instruction with POFIT_GOTO_TABLE type. * Form: uint32_t pofdp_instruction_handle_goto_table(uint8_t **pp_Packet, \ * uint8_t *ins_data, \ struct pofdp_metadata *metadata, \ * uint8_t *table_type, \ * uint8_t *table_id, \ * uint32_t *packet_over, \ * pof_flow_entry **entry_ptrptr) * Input: packet, length of packet, instruction data * Output: packet, length of packet, table type, table id, * packet over identifier, Entry * Return: POF_OK or Error code * Discribe: This function forward the packet to the next table. The * type and id of the next table will be calculated according * to the table_ID which is global number given in ins_data. * Before forwarding the packet to the next table, the packet key * will be calculated first. After forwarding, we lookup the * matched flow entry in the table using the packet key. Then, * the infomation of the matched flow entry will be write in * the entry_ptrptr. * NOTE: If there is an ERROR, The packet_over identifier will be TRUE. * If there is no flow entry can match the packet key, the * packet_over identifier will be TRUE. ***********************************************************************/ static uint32_t execute_GOTO_TABLE(POFDP_ARG) { struct pof_instruction_goto_table *p = \ (pof_instruction_goto_table *)dpp->ins->instruction_data; poflr_flow_table *table_vhal_ptr; uint32_t i, j, ret = POF_OK; uint8_t *table_type = &dpp->table_type; uint8_t *table_id = &dpp->table_id; uint8_t **key_ptr; p = (pof_instruction_goto_table *)dpp->ins->instruction_data; /* The packet forward to the next table. */ ret = move_packet_offset_forward(dpp, p->packet_offset); POF_CHECK_RETVALUE_RETURN_NO_UPWARD(ret); /* The table type and id. */ ret = poflr_table_ID_to_id(p->next_table_id, table_type, table_id); POF_CHECK_RETVALUE_RETURN_NO_UPWARD(ret); POF_DEBUG_CPRINT_FL(1,YELLOW,"Go to table[%d][%d]!", *table_type, *table_id); poflr_get_flow_table(&table_vhal_ptr, *table_type, *table_id); /* Find the key corresponding to the next table infomation. */ key_ptr = (uint8_t **)malloc(POF_MAX_MATCH_FIELD_NUM * sizeof(ptr_t)); POF_MALLOC_ERROR_HANDLE_RETURN_NO_UPWARD(key_ptr); for(i=0; i<POF_MAX_MATCH_FIELD_NUM; i++){ key_ptr[i] = (uint8_t *)malloc(POF_MAX_FIELD_LENGTH_IN_BYTE); if(key_ptr[i] == NULL){ for(j=0; j<i; j++){ free(key_ptr[j]); } free(key_ptr); POF_ERROR_HANDLE_RETURN_NO_UPWARD(POFET_SOFTWARE_FAILED, POF_ALLOCATE_RESOURCE_FAILURE); } } pofdp_find_key(dpp->buf_offset, (uint8_t *)dpp->metadata, (uint8_t **)(key_ptr), table_vhal_ptr->tbl_base_info.match_field_num, table_vhal_ptr->tbl_base_info.match); /* Lookup the flow entry which matches the packet in the next table. */ if(pofdp_lookup_in_table((uint8_t **)key_ptr, table_vhal_ptr->tbl_base_info.match_field_num, \ *table_vhal_ptr, &dpp->flow_entry) != POF_OK){ /* No match. */ POF_DEBUG_CPRINT_FL(1,RED,"Cannot find the right entry in table[%d][%d]!",*table_type,*table_id); ret = pofdp_entry_nomatch(dpp); POF_CHECK_RETVALUE_NO_RETURN_NO_UPWARD(ret); dpp->packet_done = TRUE; }else{ /* Match. Increace the counter value. */ ret = poflr_counter_increace(dpp->flow_entry->counter_id); POF_CHECK_RETVALUE_NO_RETURN_NO_UPWARD(ret); /* Update the instruction number and the instruction data corresponding to the * matched flow entry in the current flow table. */ dpp->ins = dpp->flow_entry->instruction; dpp->ins_todo_num = dpp->flow_entry->instruction_num; dpp->ins_done_num = 0; } /* Free the memory. */ for(i=0; i<POF_MAX_MATCH_FIELD_NUM; i++){ free(key_ptr[i]); } free(key_ptr); return ret; }