예제 #1
0
/***********************************************************************
 * The task function of the datapath task
 * Form:     static void pofdp_main_task(void *arg_ptr)
 * Input:    NONE
 * Output:   NONE
 * Return:   VOID
 * Discribe: This is the main function of the datapath task, which is
 *           infinite loop running. It receive the RAW packet, and forward.
 *           The next RAW packet will be not proceeded until the forward
 *           process of the last packet is over.
 * NOTE:     The datapath task will be terminated if some ERROR occurs
 *           during the receive process and the datapath process.
 ***********************************************************************/
static uint32_t pofdp_main_task(void *arg_ptr){
    uint8_t recv_buf[POFDP_PACKET_RAW_MAX_LEN] = {0};
	struct pofdp_packet dpp[1] = {0};
	struct pof_instruction first_ins[1] = {0};
    uint32_t len_B = 0, port_id = 0;
    uint32_t ret;

	/* Set GOTO_TABLE instruction to go to the first flow table. */
	set_goto_first_table_instruction(first_ins);

    while(1){
        /* Receive raw packet through local physical OpenFlow-enabled ports. */
        ret = pofdp_recv_raw(dpp);
        if(ret != POF_OK){
            POF_CHECK_RETVALUE_NO_RETURN_NO_UPWARD(ret);
            /* Delay 0.1s to send error message upward to the Controller. */
            pofbf_task_delay(100);
            terminate_handler();
        }

        /* Check the packet length. */
        if(dpp->ori_len > POFDP_PACKET_RAW_MAX_LEN){
			free_packet_data(dpp);
            POF_ERROR_HANDLE_NO_RETURN_NO_UPWARD(POFET_SOFTWARE_FAILED, POF_PACKET_LEN_ERROR);
            continue;
        }

		/* Check whether the first flow table exist. */
		if(POF_OK != poflr_check_flow_table_exist(POFDP_FIRST_TABLE_ID)){
			POF_DEBUG_CPRINT_FL(1,RED,"Received a packet, but the first flow table does NOT exist.");
			free_packet_data(dpp);
			continue;
		}

        /* Forward the packet. */
        ret = pofdp_forward(dpp, first_ins);
        POF_CHECK_RETVALUE_NO_RETURN_NO_UPWARD(ret);

		free_packet_data(dpp);
        POF_DEBUG_CPRINT_FL(1,GREEN,"one packet_raw has been processed!\n");
    }
    return POF_OK;
}
예제 #2
0
void free_packet(struct packet *p)
{
	assert(p != NULL);
	assert(p->pdata != NULL);
	assert_packet_type(p->header.type);
	assert_valid_pdata(p);
	assert_valid_ndata(p);

	if (p->pdata && p->pdata_len > 0) {
		free_packet_data(p);
		free(p->pdata);
		p->pdata_len = 0;
	}

	if (p->ndata && p->ndata_len > 0) {
		free(p->ndata);
		p->ndata_len = 0;
	}
}
예제 #3
0
/***********************************************************************
 * The task function of receive task
 * Form:     static void pofdp_recv_raw_task(void *arg_ptr)
 * Input:    port infomation
 * Output:   NONE
 * Return:   VOID
 * Discribe: This is the task function of receive task, which is infinite
 *           loop running. It receives RAW packet by binding socket to the
 *           local physical net port spicified in the port infomation.
 *           After filtering, the packet data and port infomation will be
 *           assembled with format of struct pofdp_packet, and be send
 *           into the receive queue. The only parameter arg_ptr is the
 *           pointer of the local physical net port infomation which has
 *           been assembled with format of struct pof_port.
 * NOTE:     This task will be terminated if any ERRORs occur.
 *           If the openflow function of this physical port is disable,
 *           it will be still loop running but nothing will be received.
 ***********************************************************************/
static uint32_t pofdp_recv_raw_task(void *arg_ptr){
    pof_port *port_ptr = (pof_port *)arg_ptr;
    struct pofdp_packet *dpp = malloc(sizeof *dpp);
    struct   sockaddr_ll sockadr, from;
    uint32_t from_len, len_B;
    uint8_t  buf[POFDP_PACKET_RAW_MAX_LEN];
    int      sock;

    from_len = sizeof(struct sockaddr_ll);

    /* Create socket, and bind it to the specific port. */
    if((sock = socket(AF_PACKET, SOCK_RAW, POF_HTONS(ETH_P_ALL))) == -1){
        POF_ERROR_HANDLE_NO_RETURN_UPWARD(POFET_SOFTWARE_FAILED, POF_CREATE_SOCKET_FAILURE, g_upward_xid++);
        /* Delay 0.1s to send error message upward to the Controller. */
        pofbf_task_delay(100);
        terminate_handler();
    }

    sockadr.sll_family = AF_PACKET;
    sockadr.sll_protocol = POF_HTONS(ETH_P_ALL);
    sockadr.sll_ifindex = port_ptr->port_id;

    if(bind(sock, (struct sockaddr *)&sockadr, sizeof(struct sockaddr_ll)) != 0){
       POF_ERROR_HANDLE_NO_RETURN_UPWARD(POFET_SOFTWARE_FAILED, POF_BIND_SOCKET_FAILURE, g_upward_xid++);
        /* Delay 0.1s to send error message upward to the Controller. */
        pofbf_task_delay(100);
        terminate_handler();
    }

    /* Receive the raw packet through the specific port. */
    while(1){
		pthread_testcancel();

        /* Receive the raw packet. */
        if((len_B = recvfrom(sock, buf, POFDP_PACKET_RAW_MAX_LEN, 0, (struct sockaddr *)&from, &from_len)) <=0){
            POF_ERROR_HANDLE_NO_RETURN_UPWARD(POFET_SOFTWARE_FAILED, POF_RECEIVE_MSG_FAILURE, g_upward_xid++);
            continue;
        }

        /* Check whether the OpenFlow-enabled of the port is on or not. */
        if(port_ptr->of_enable == POFLR_PORT_DISABLE){
            continue;
        }

        /* Check the packet length. */
        if(len_B > POF_MTU_LENGTH){
            POF_DEBUG_CPRINT_FL(1,RED,"The packet received is longer than MTU. DROP!");
            continue;
        }

        /* Filter the received raw packet by some rules. */
        if(pofdp_packet_raw_filter(buf, port_ptr) != POF_OK){
            continue;
        }
		
        /* Store packet data, length, received port infomation into the message queue. */
		memset(dpp, 0, sizeof *dpp);
        dpp->ori_port_id = port_ptr->port_id;
		malloc_packet_data(dpp, len_B);
        memcpy(dpp->buf, buf, len_B);

        if(pofbf_queue_write(g_pofdp_recv_q_id, dpp, sizeof *dpp, POF_WAIT_FOREVER) != POF_OK){
            POF_ERROR_HANDLE_NO_RETURN_UPWARD(POFET_SOFTWARE_FAILED, POF_WRITE_MSG_QUEUE_FAILURE, g_upward_xid++);
			free_packet_data(dpp);

            pofbf_task_delay(100);
            terminate_handler();
        }
    }

    close(sock);
    return POF_OK;
}