Exemplo n.º 1
0
/***********************************************************************
 * 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;
}
Exemplo n.º 2
0
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);
        }
    }
}
Exemplo n.º 3
0
/***********************************************************************
 * 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;
}