Esempio n. 1
0
static void test_vhost_fd(void)
{
	struct pg_brick *vhost[VHOST_CNT];
	struct pg_error *error = NULL;

	g_assert(pg_vhost_start("/tmp", &error) == 0);
	g_assert(!error);

	for (int j = 0; j < 10; j++) {
		for (int i = 0; i < VHOST_CNT; i++) {
			gchar *name = g_strdup_printf("vhost-%i", i);
			vhost[i] = pg_vhost_new(name, &error);
			g_free(name);
			g_assert(!error);
			g_assert(vhost[i]);
		}
		for (int i = 0; i < VHOST_CNT; i++) {
			pg_brick_destroy(vhost[i]);
			g_assert(!error);
		}
	}
	pg_vhost_stop();
}
Esempio n. 2
0
/* this test harness a Linux guest to check that packet are send and received
 * by the vhost brick. An ethernet bridge inside the guest will forward packets
 * between the two vhost-user virtio interfaces.
 */
static void test_vhost_flow_(int qemu_exit_signal)
{
	const char mac_addr_0[18] = "52:54:00:12:34:11";
	const char mac_addr_1[18] = "52:54:00:12:34:12";
	struct rte_mempool *mbuf_pool = pg_get_mempool();
	struct pg_brick *vhost_0, *vhost_1, *collect;
	struct rte_mbuf *pkts[PG_MAX_PKTS_BURST];
	const char *socket_path_0, *socket_path_1;
	struct pg_error *error = NULL;
	struct rte_mbuf **result_pkts;
	int ret, qemu_pid, i;
	uint64_t pkts_mask;

	/* start vhost */
	ret = pg_vhost_start("/tmp", &error);
	g_assert(ret == 0);
	g_assert(!error);

	/* instanciate brick */
	vhost_0 = pg_vhost_new("vhost-0", &error);
	g_assert(!error);
	g_assert(vhost_0);

	vhost_1 = pg_vhost_new("vhost-1", &error);
	g_assert(!error);
	g_assert(vhost_1);

	collect = pg_collect_new("collect", &error);
	g_assert(!error);
	g_assert(collect);

	/* build the graph */
	pg_brick_link(collect, vhost_1, &error);
	g_assert(!error);

	/* spawn first QEMU */
	socket_path_0 = pg_vhost_socket_path(vhost_0, &error);
	g_assert(!error);
	g_assert(socket_path_0);
	socket_path_1 = pg_vhost_socket_path(vhost_1, &error);
	g_assert(!error);
	g_assert(socket_path_1);

	qemu_pid = pg_util_spawn_qemu(socket_path_0, socket_path_1,
				      mac_addr_0, mac_addr_1,
				      glob_vm_path,
				      glob_vm_key_path,
				      glob_hugepages_path, &error);

	g_assert(!error);
	g_assert(qemu_pid);

	/* Prepare VM's bridge. */
#	define SSH(c) \
		g_assert(pg_util_ssh("localhost", ssh_port_id, glob_vm_key_path, c) == 0)
	SSH("brctl addbr br0");
	SSH("ifconfig br0 up");
	SSH("ifconfig ens4 up");
	SSH("ifconfig ens5 up");
	SSH("brctl addif br0 ens4");
	SSH("brctl addif br0 ens5");
	SSH("brctl setfd br0 0");
	SSH("brctl stp br0 off");
#	undef SSH
	ssh_port_id++;

	/* prepare packet to send */
	for (i = 0; i < NB_PKTS; i++) {
		pkts[i] = rte_pktmbuf_alloc(mbuf_pool);
		g_assert(pkts[i]);
		rte_pktmbuf_append(pkts[i], ETHER_MIN_LEN);
		/* set random dst/src mac address so the linux guest bridge
		 * will not filter them
		 */
		pg_set_mac_addrs(pkts[i],
			      "52:54:00:12:34:15", "52:54:00:12:34:16");
		/* set size */
		pg_set_ether_type(pkts[i], ETHER_MIN_LEN - ETHER_HDR_LEN - 4);
	}

	/* send packet to the guest via one interface */
	pg_brick_burst_to_east(vhost_0, 0, pkts,
			       pg_mask_firsts(NB_PKTS), &error);
	g_assert(!error);

	/* let the packet propagate and flow */
	for (i = 0; i < 10; i++) {
		uint16_t count = 0;

		usleep(100000);
		pg_brick_poll(vhost_1, &count, &error);
		g_assert(!error);
		if (count)
			break;
	}

	result_pkts = pg_brick_east_burst_get(collect, &pkts_mask, &error);
	g_assert(!error);
	g_assert(result_pkts);
	g_assert(pg_brick_rx_bytes(vhost_0) == 0);
	g_assert(pg_brick_tx_bytes(vhost_0) != 0);
	g_assert(pg_brick_rx_bytes(vhost_1) != 0);
	g_assert(pg_brick_tx_bytes(vhost_1) == 0);

	/* kill QEMU */
	pg_util_stop_qemu(qemu_pid, qemu_exit_signal);

	/* free result packets */
	pg_packets_free(result_pkts, pkts_mask);

	/* free sent packet */
	for (i = 0; i < NB_PKTS; i++)
		rte_pktmbuf_free(pkts[i]);

	/* break the graph */
	pg_brick_unlink(collect, &error);
	g_assert(!error);

	/* clean up */
	/* pg_brick_decref(vhost_0, &error); */
	pg_brick_destroy(vhost_0);
	g_assert(!error);
	pg_brick_destroy(vhost_1);
	/* pg_brick_decref(vhost_1, &error); */
	g_assert(!error);
	pg_brick_decref(collect, &error);
	g_assert(!error);

	/* stop vhost */
	pg_vhost_stop();
}
Esempio n. 3
0
static int start_loop(int verbose, int nb_vhost)
{
 	struct pg_error *error = NULL;
	struct pg_brick *nic_tmp, *switch_east, *print_tmp;
	uint16_t port_count = rte_eth_dev_count();
	GList *nic_manager = NULL;
	GList *manager = NULL;
	int ret = -1;


	/*
	 * Here is an ascii graph of the links:
	 *
	 * [NIC-X] - [PRINT-X]   --\
	 *		            \
	 * [NIC-X+1] - [PRINT-X+1]   } -- [SWITCH]
	 *		            /
	 * [NIC-X+2] - [PRINT-X+2] /
	 * ....
	 */
	switch_east = pg_switch_new("switch", 20, 20, EAST_SIDE, &error);
	CHECK_ERROR(error);
	PG_BM_ADD(manager, switch_east);

	if (nb_vhost) {
		if (pg_vhost_start("/tmp", &error) < 0)
			goto free_switch;
		port_count = nb_vhost;
	}
	g_assert(port_count > 1);

	
	for (int i = 0; i < port_count; ++i) {
		char *tmp_name;

		if (nb_vhost) {
			tmp_name = g_strdup_printf("vhost-%d", i);
			nic_tmp = pg_vhost_new(tmp_name, 1, 1,
					       WEST_SIDE, &error);
		} else {
			tmp_name = g_strdup_printf("nic-%d", i);
			nic_tmp = pg_nic_new_by_id(tmp_name, i, &error);
		}

		g_free(tmp_name);
		CHECK_ERROR(error);
		tmp_name = g_strdup_printf("print-%d", i);
		print_tmp = pg_print_new(tmp_name, 1, 1, NULL,
					 PG_PRINT_FLAG_MAX, NULL,
					 &error);
		g_free(tmp_name);
		CHECK_ERROR(error);
		if (!verbose)
			pg_brick_chained_links(&error, nic_tmp, switch_east);
		else
			pg_brick_chained_links(&error, nic_tmp,
					       print_tmp, switch_east);
		CHECK_ERROR(error);
		PG_BM_ADD(nic_manager, nic_tmp);
		PG_BM_ADD(manager, print_tmp);
	}
	while (1) {
		uint64_t tot_send_pkts = 0;
		for (int i = 0; i < 100000; ++i) {
			uint16_t nb_send_pkts;

			PG_BM_GET_NEXT(nic_manager, nic_tmp);
			pg_brick_poll(nic_tmp, &nb_send_pkts, &error);
			tot_send_pkts += nb_send_pkts;
			CHECK_ERROR(error);
			usleep(1);
		}
		printf("poll pkts: %lu\n", tot_send_pkts);
	}
	ret = 0;
	nic_manager = g_list_first(nic_manager);
	PG_BM_DESTROY(nic_manager);
free_switch:
	PG_BM_DESTROY(manager);
	pg_vhost_stop();
	return ret;
}