Exemplo n.º 1
0
/* Try to execute action with the drop action, which should succeed */
static void
test_action_execute_drop(int argc, char *argv[])
{
	struct rte_mbuf buf_free;
	struct rte_mbuf buf_drop;
	struct action action_multiple[MAX_ACTIONS] = {0};
	struct action action_drop[MAX_ACTIONS] = {0};

	stats_init();
	stats_vswitch_clear();

	/* TODO: Break this into multiple tests? */
	/* check that mbuf is freed on drop */
	assert(memcmp(&buf_free, &buf_drop, sizeof(buf_drop)) != 0);
	buf_drop.pkt.next = NULL; /* Required for rte_pktmbuf_free */
	memcpy(&buf_free, &buf_drop, sizeof(buf_drop));
	assert(memcmp(&buf_free, &buf_drop, sizeof(buf_drop)) == 0);
	action_drop_build(&action_drop[0]);
	action_null_build(&action_drop[1]);
	action_execute(action_drop, &buf_free);
	assert(memcmp(&buf_free, &buf_drop, sizeof(buf_drop)) != 0);
	/* check that vswitch rx drop stats are increased */
	stats_vswitch_clear();
	assert(stats_vswitch_rx_drop_get() == 0);
	action_drop_build(&action_drop[0]);
	action_null_build(&action_drop[1]);
	action_execute(action_drop, &buf_drop);
	assert(stats_vswitch_rx_drop_get() == 1);
}
Exemplo n.º 2
0
/* Try to execute action with invalid parameters, which should fail
 * with -1 */
static void
test_action_execute_output__invalid_params(int argc, char *argv[])
{
	struct rte_mbuf buf_multiple[5];
	struct action action_multiple[MAX_ACTIONS] = {0};
	int ret = 0;

	/* check incorrect parameters */
	vport_init();
	action_output_build(&action_multiple[0], 17);
	action_null_build(&action_multiple[1]);
	ret = action_execute(NULL, &buf_multiple[1]);
	assert(ret < 0);
	ret = action_execute(action_multiple, NULL);
	assert(ret < 0);
}
Exemplo n.º 3
0
/* Try to execute action with a pop vlan and output action, which should succeed */
static void
test_action_execute_multiple_actions__pop_vlan_and_output(int argc, char *argv[])
{
	/* We write some data into the place where a VLAN tag would be and the 4
	 * bytes after. We then call action execute and make sure the fake VLAN tag
	 * is gone and has been replaced by the data in the 4 bytes after
	 *
	 * We then output the packet to a port and make the same checks
	 */
	struct rte_mempool *pktmbuf_pool;
	struct action action_multiple[MAX_ACTIONS] = {0};
	int count = 0;

	pktmbuf_pool = rte_mempool_create("MProc_pktmbuf_pool",
                    20, /* num mbufs */
                    2048 + sizeof(struct rte_mbuf) + 128, /*pktmbuf size */
                    32, /*cache size */
                    sizeof(struct rte_pktmbuf_pool_private),
                    rte_pktmbuf_pool_init,
                    NULL, rte_pktmbuf_init, NULL, 0, 0);

	struct rte_mbuf *vlan_output_buf = rte_pktmbuf_alloc(pktmbuf_pool);

	vport_init();

	/* We have no real packet but the function which pops the VLAN does
	 * some checks of pkt len so we define a fake one here
	 */
	vlan_output_buf->pkt.pkt_len = 20;
	action_pop_vlan_build(&action_multiple[0]);
	action_output_build(&action_multiple[1], 17);
	action_null_build(&action_multiple[2]);
	int *pktmbuf_data = rte_pktmbuf_mtod(vlan_output_buf, int *);
	*(pktmbuf_data + 2) = 0xCAFED00D;
	/* Note last 2 bytes must be 0081, ie 8100 in network format */
	*(pktmbuf_data + 3) = 0x00000081; /* 12 bytes after src/dst MAC is vlan */
	*(pktmbuf_data + 4) = 0xBABEFACE;
	action_execute(action_multiple, vlan_output_buf);
	pktmbuf_data = rte_pktmbuf_mtod(vlan_output_buf, int *);
	assert(*(pktmbuf_data + 3) != 0x00000081);
	assert(*(pktmbuf_data + 3) == 0xBABEFACE);
	count = receive_from_vport(17, &vlan_output_buf);
	pktmbuf_data = rte_pktmbuf_mtod(vlan_output_buf, int *);
	assert(count == 1);
	assert(*(pktmbuf_data + 3) != 0x00000081);
	assert(*(pktmbuf_data + 3) == 0xBABEFACE);
}
Exemplo n.º 4
0
/* Modify packet ethernet header */
static void
test_action_execute_set_ethernet(int argc, char *argv[])
{
	struct rte_mempool *pktmbuf_pool;
	struct action action_multiple[MAX_ACTIONS] = {0};

	pktmbuf_pool = rte_mempool_create("MProc_pktmbuf_pool",
                    20, /* num mbufs */
                    2048 + sizeof(struct rte_mbuf) + 128, /*pktmbuf size */
                    32, /*cache size */
                    sizeof(struct rte_pktmbuf_pool_private),
                    rte_pktmbuf_pool_init,
                    NULL, rte_pktmbuf_init, NULL, 0, 0);

	struct rte_mbuf *ethernet_buf = rte_pktmbuf_alloc(pktmbuf_pool);

	struct ovs_key_ethernet set_ethernet;
	__u8 eth_src_set[6] = {0xDE, 0xAD, 0xBE, 0xEF, 0xCA, 0xFE};
	__u8 eth_dst_set[6] = {0xCA, 0xFE, 0xDE, 0xAD, 0xBE, 0xEF};
	memcpy(&set_ethernet.eth_src, &eth_src_set, sizeof(eth_src_set));
	memcpy(&set_ethernet.eth_dst, &eth_dst_set, sizeof(eth_dst_set));

	struct ovs_key_ethernet ethernet_orig;
	__u8 eth_src_orig[6] = {0xFF, 0xFF, 0xFF, 0xCC, 0xCC, 0xCC};
	__u8 eth_dst_orig[6] = {0xAA, 0xAA, 0xAA, 0xEE, 0xEE, 0xEE};
	memcpy(&ethernet_orig.eth_src, &eth_src_orig, sizeof(eth_src_orig));
	memcpy(&ethernet_orig.eth_dst, &eth_dst_orig, sizeof(eth_dst_orig));

	vport_init();
	action_multiple[0].type = ACTION_SET_ETHERNET;
	action_multiple[0].data.ethernet = set_ethernet;
	action_null_build(&action_multiple[1]);

	struct ovs_key_ethernet *pktmbuf_data =
		rte_pktmbuf_mtod(ethernet_buf, struct ovs_key_ethernet *);
	memcpy(pktmbuf_data, &ethernet_orig, sizeof(ethernet_orig));

	action_execute(action_multiple, ethernet_buf);
	pktmbuf_data = rte_pktmbuf_mtod(ethernet_buf, struct ovs_key_ethernet *);
	/* Can't compare struct directly as ovs_key_ethernet has src first then
	 * dst whereas the real ethernet header has dst first then source
	 */
	assert(memcmp(pktmbuf_data, &set_ethernet.eth_dst, sizeof(eth_dst_set)) == 0);
	assert(memcmp((uint8_t *)pktmbuf_data + sizeof(eth_dst_set),
	              &set_ethernet.eth_src, sizeof(eth_src_set)) == 0);
	rte_pktmbuf_free(ethernet_buf);
}
Exemplo n.º 5
0
/* Try to execute action with the push vlan (PCP) action, which should
 * succeed */
static void
test_action_execute_push_vlan__pcp(int argc, char *argv[])
{
	/* Write Ethertype value of 0x0800 to byte 11 of the packet,
	 * where it is expected, and assign a length to the packet.
	 * After call to action_execute:
	 * - the length of the packet should have increased by 4 bytes
	 * - the value of byte 11 should by 0x8100 (0081 in network format)
	 * - the value of byte 15 should by 0x0800 (0008 in network format)
	 * - the value of the TCI field should be equal to the assigned
	 *   value
	*/
	struct rte_mempool *pktmbuf_pool;
	struct action action_multiple[MAX_ACTIONS] = {0};

	pktmbuf_pool = rte_mempool_create("MProc_pktmbuf_pool",
                    20, /* num mbufs */
                    2048 + sizeof(struct rte_mbuf) + 128, /*pktmbuf size */
                    32, /*cache size */
                    sizeof(struct rte_pktmbuf_pool_private),
                    rte_pktmbuf_pool_init,
                    NULL, rte_pktmbuf_init, NULL, 0, 0);

	struct rte_mbuf *pcp_buf = rte_pktmbuf_alloc(pktmbuf_pool);
	uint16_t pcp_tci = htons(0x2000); /* PCP is the upper 3 bits of the TCI */

	vport_init();

	/* Set the packet length - after the VLAN tag has been inserted,
	 * the value should increase by 4 bytes (i.e. the length of the tag)
	 */
	pcp_buf->pkt.pkt_len = 64;
	action_push_vlan_build(&action_multiple[0], pcp_tci);
	action_null_build(&action_multiple[1]);
	short *pkt_data = rte_pktmbuf_mtod(pcp_buf, short *);
	*(pkt_data + 6) = 0x0008; /* Set Ethertype to 0008, i.e. 0800 in network format */
	action_execute(action_multiple, pcp_buf);
	pkt_data = rte_pktmbuf_mtod(pcp_buf, short *);
	assert(*(pkt_data + 6) == 0x0081); /* 802.1Q Ethertype has been inserted */
	assert(*(pkt_data + 7) == 0x0020); /* TCI value has been inserted */
	assert(*(pkt_data + 8) == 0x0008); /* Ethertype has been shifted by 4 bytes */
	assert(pcp_buf->pkt.pkt_len == 68);/* Packet length has increased by 4 bytes */
	rte_pktmbuf_free(pcp_buf);
}
Exemplo n.º 6
0
/*
 * This function takes a packet and routes it as per the flow table.
 */
static void
switch_packet(struct rte_mbuf *pkt, uint8_t in_port)
{
	int pos = 0;
	struct dpdk_upcall info = {0};

	flow_key_extract(pkt, in_port, &info.key);

	pos = rte_hash_lookup(handle, &info.key);

	if (pos < 0) {
		/* flow table miss, send unmatched packet to the daemon */
		info.cmd = PACKET_CMD_MISS;
		send_packet_to_vswitchd(pkt, &info);
	} else {
		flow_table_update_stats(pos, pkt);
		action_execute(pos, pkt);
	}
}
Exemplo n.º 7
0
/*
 * This function takes a packet and routes it as per the flow table.
 */
void
switch_packet(struct rte_mbuf *pkt, uint8_t in_port)
{
	int ret = 0;
	struct dpdk_upcall info = {0};
	struct action action = {0};

	flow_key_extract(pkt, in_port, &info.key);

	ret = flow_table_get_flow(&info.key, &action, NULL);
	if (ret >= 0) {
		flow_table_update_stats(&info.key, pkt);
		action_execute(&action, pkt);
	} else {
		/* flow table miss, send unmatched packet to the daemon */
		info.cmd = PACKET_CMD_MISS;
		send_packet_to_vswitchd(pkt, &info);
	}
}
Exemplo n.º 8
0
/* Modify packet ipv4 header */
static void
test_action_execute_set_ipv4(int argc, char *argv[])
{
	struct rte_mempool *pktmbuf_pool;
	struct action action_multiple[MAX_ACTIONS] = {0};
	struct ipv4_hdr *pkt_ipv4;

	pktmbuf_pool = rte_mempool_create("MProc_pktmbuf_pool",
                    20, /* num mbufs */
                    2048 + sizeof(struct rte_mbuf) + 128, /*pktmbuf size */
                    32, /*cache size */
                    sizeof(struct rte_pktmbuf_pool_private),
                    rte_pktmbuf_pool_init,
                    NULL, rte_pktmbuf_init, NULL, 0, 0);

	struct rte_mbuf *ipv4_buf = rte_pktmbuf_alloc(pktmbuf_pool);

	struct ovs_key_ipv4 set_ipv4;
	set_ipv4.ipv4_tos = 0xFF;

	vport_init();
	action_multiple[0].type = ACTION_SET_IPV4;
	action_multiple[0].data.ipv4 = set_ipv4;
	action_null_build(&action_multiple[1]);

	uint8_t *pktmbuf_data =
	          rte_pktmbuf_mtod(ipv4_buf, uint8_t *);
	pktmbuf_data += sizeof(struct ether_hdr);
	pkt_ipv4 = (struct ipv4_hdr *)(pktmbuf_data);
	pkt_ipv4->type_of_service = 0xaa;

	action_execute(action_multiple, ipv4_buf);
	pktmbuf_data = rte_pktmbuf_mtod(ipv4_buf, uint8_t *);
	pktmbuf_data += sizeof(struct ether_hdr);
	pkt_ipv4 = (struct ipv4_hdr *)(pktmbuf_data);

	assert(pkt_ipv4->type_of_service == set_ipv4.ipv4_tos);
	rte_pktmbuf_free(ipv4_buf);
}
Exemplo n.º 9
0
/* Try to execute action with three output actions, which should succeed */
static void
test_action_execute_multiple_actions__three_output(int argc, char *argv[])
{
	/* Three different output ports */
	/* We need to be able to clone mbufs which requires an
	 * alloc which requires a mempool
	 */
	struct rte_mempool *pktmbuf_pool;
	struct rte_mbuf *mbuf_output = NULL;
	struct action action_multiple[MAX_ACTIONS] = {0};
	int count = 0;

	pktmbuf_pool = rte_mempool_create("MProc_pktmbuf_pool",
                    20, /* num mbufs */
                    2048 + sizeof(struct rte_mbuf) + 128, /*pktmbuf size */
                    32, /*cache size */
                    sizeof(struct rte_pktmbuf_pool_private),
                    rte_pktmbuf_pool_init,
                    NULL, rte_pktmbuf_init, NULL, 0, 0);

	mbuf_output = rte_pktmbuf_alloc(pktmbuf_pool);

	vport_init();
	action_output_build(&action_multiple[0], 3);
	action_output_build(&action_multiple[1], 33);
	action_output_build(&action_multiple[2], 17);
	action_null_build(&action_multiple[3]);

	action_execute(action_multiple, mbuf_output);

	count = receive_from_vport(3, &mbuf_output);
	assert(count == 1);
	count = receive_from_vport(33, &mbuf_output);
	assert(count == 1);
	count = receive_from_vport(17, &mbuf_output);
	assert(count == 1);
}
Exemplo n.º 10
0
/* Try to execute action with a client interface, which should succeed */
static void
test_action_execute_output(int argc, char *argv[])
{
	struct rte_mbuf buf_multiple[5];
	struct rte_mbuf *buf_p_multiple[5];
	struct action action_multiple[MAX_ACTIONS] = {0};
	int count = 0;
	uint8_t vportid = 3;

	buf_p_multiple[0] = &buf_multiple[0];
	buf_p_multiple[1] = &buf_multiple[1];
	buf_p_multiple[2] = &buf_multiple[2];
	buf_p_multiple[3] = &buf_multiple[3];
	buf_p_multiple[4] = &buf_multiple[4];

	/* client */
	vport_init();
	action_output_build(&action_multiple[0], vportid);
	action_null_build(&action_multiple[1]);
	action_execute(action_multiple, buf_multiple);
	count = receive_from_vport(vportid, buf_p_multiple);
	assert(count == 1);
	assert(buf_p_multiple[1] == &buf_multiple[1]);
}
Exemplo n.º 11
0
/**************************************
Return RET_NOK on error
**************************************/
ret_code_t parse_incoming_data(context_t * context, Uint32 command, Uint32 command_size, char * data)
{
	char * value = NULL;
	char * fullname;
	char * elements[512];
	char * cksum;
	int i;
	char * user_name;
	char * password;

	if( !context_get_connected(context) && ( command != CMD_REQ_LOGIN  && command != CMD_REQ_FILE) ) {
		werr(LOGUSER,"Request from not authenticated client, close connection");
		return RET_NOK;
	}

	switch(command) {
	case CMD_REQ_LOGIN:
		wlog(LOGDEBUG,"Received CMD_REQ_LOGIN");
		user_name = _strsep(&data,NETWORK_DELIMITER);
		password = _strsep(&data,NETWORK_DELIMITER);

		if(entry_read_string(PASSWD_TABLE, user_name, &value, PASSWD_KEY_PASSWORD,NULL) == RET_NOK) {
			return RET_NOK;
		}
		if( strcmp(value, password) != 0) {
			free(value);
			werr(LOGUSER,"Wrong login for %s",user_name);
			// send answer
			network_send_command(context, CMD_SEND_LOGIN_NOK, 0, NULL, false);
			// force client disconnection
			return RET_NOK;
		} else {
			free(value);

			if( context_set_username(context, user_name) == RET_NOK ) {
				return RET_NOK;
			}
			context_set_connected(context, true);

			// send answer
			network_send_command(context, CMD_SEND_LOGIN_OK, 0, NULL, false);
			wlog(LOGUSER,"Login successful for user %s",context->user_name);
		}
		break;
	case CMD_REQ_CHARACTER_LIST :
		wlog(LOGDEBUG,"Received CMD_REQ_CHARACTER_LIST");
		character_send_list(context);
		wlog(LOGDEBUG,"character list sent");
		break;
	case CMD_REQ_FILE :
		i = 0;
		elements[i] = _strsep(&data,NETWORK_DELIMITER);
		while(elements[i]) {
			i++;
			elements[i] = _strsep(&data,NETWORK_DELIMITER);
		}

		if(elements[0]==NULL || elements[1]==NULL) {
			werr(LOGDEV,"Received erroneous CMD_REQ_FILE");
			break;
		}
		wlog(LOGDEBUG,"Received CMD_REQ_FILE for %s",elements[0]);
		/* compare checksum */
		fullname = strconcat(base_directory,"/",elements[0],NULL);

		cksum = checksum_file(fullname);
		free(fullname);

		if( cksum == NULL) {
			werr(LOGUSER,"Required file %s doesn't exists",elements[0]);
			break;
		}

		if( strcmp(elements[1],cksum) == 0 ) {
			wlog(LOGDEBUG,"Client has already newest %s file",elements[0]);
			free(cksum);
			break;
		}
		free(cksum);

		network_send_file(context,elements[0]);
		wlog(LOGDEBUG,"File %s sent",elements[0]);
		break;
	case CMD_REQ_USER_CHARACTER_LIST :
		wlog(LOGDEBUG,"Received CMD_REQ_USER_CHARACTER_LIST");
		character_user_send_list(context);
		wlog(LOGDEBUG,"user %s's character list sent",context->user_name);
		break;
	case CMD_REQ_START :
		if( context->in_game == false ) {
			context->id = strdup(data);
			context->in_game = true;
			context_update_from_file(context);
			context_spread(context);
			context_request_other_context(context);
		}
		wlog(LOGDEBUG,"Received CMD_REQ_START for %s /%s",context->user_name,context->id);
		break;
	case CMD_REQ_STOP :
		wlog(LOGDEBUG,"Received CMD_REQ_STOP for %s /%s",context->user_name,context->id);
		if( context->in_game == true ) {
			context->in_game = false;
			if( context->map ) {
				free(context->map);
			}
			context->map = NULL;
			if( context->prev_map ) {
				free(context->prev_map);
			}
			context->prev_map = NULL;
			if( context->id ) {
				free(context->id);
			}
			context->id = NULL;
			context_spread(context);
		}
		break;
	case CMD_REQ_ACTION :
		i = 0;
		elements[i] = NULL;
		elements[i] = _strsep(&data,NETWORK_DELIMITER);
		while(elements[i]) {
			i++;
			elements[i] = _strsep(&data,NETWORK_DELIMITER);
		}
		elements[i+1] = NULL;

		wlog(LOGDEBUG,"Received CMD_REQ_ACTION %s from %s /%s",elements[0],context->user_name,context->character_name);

		action_execute(context,elements[0],&elements[1]);
		break;
	default:
		werr(LOGDEV,"Unknown request %d from client",command);
		return RET_NOK;
	}

	return RET_OK;
}
Exemplo n.º 12
0
/*
 * Handle packet commands
 */
static void
handle_packet_cmd(struct dpdk_packet_message *request, struct rte_mbuf *pkt)
{
	action_execute(request->actions, pkt);
}