Example #1
0
static struct rte_mbuf *build_packet(const unsigned char *data, size_t len)
{
	struct rte_mempool *mp = pg_get_mempool();
	struct rte_mbuf *pkt = rte_pktmbuf_alloc(mp);
	void *packet;

	pkt->pkt_len = len;
	pkt->data_len = len;
	pkt->nb_segs = 1;
	pkt->next = NULL;

	packet = rte_pktmbuf_mtod(pkt, void*);
	memcpy(packet, data, len);
	return pkt;
}
Example #2
0
static struct rte_mbuf *build_ip_packet(const char *src_ip,
					const char *dst_ip, uint16_t data)
{
	struct rte_mempool *mp = pg_get_mempool();
	struct rte_mbuf *pkt = rte_pktmbuf_alloc(mp);
	uint16_t len = sizeof(struct ether_hdr) + sizeof(struct ip) +
		sizeof(uint16_t);
	struct ether_hdr *eth;
	struct ip *ip;
	uint16_t *payload_ip;

	pkt->pkt_len = len;
	pkt->data_len = len;
	pkt->nb_segs = 1;
	pkt->next = NULL;

	/* ethernet header */
	eth = rte_pktmbuf_mtod(pkt, struct ether_hdr*);
	memset(eth, 0, len);
	eth->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);

	/* ipv4 header */
	ip = (struct ip *)(eth + 1);
	ip->ip_v = IPVERSION;
	ip->ip_hl = sizeof(struct ip) >> 2;
	ip->ip_off = 0;
	ip->ip_ttl = 64;

	/* FEAR ! this is CHAOS ! */
	ip->ip_p = 16;
	ip->ip_len = htons(sizeof(struct ip) + 1);
	ip->ip_src.s_addr = inet_addr(src_ip);
	ip->ip_dst.s_addr = inet_addr(dst_ip);

	/* write some data */
	payload_ip = (uint16_t *)(ip + 1);
	*payload_ip = data;
	return pkt;
}
Example #3
0
static struct rte_mbuf *build_non_ip_packet(void)
{
	struct rte_mempool *mp = pg_get_mempool();
	struct rte_mbuf *pkt = rte_pktmbuf_alloc(mp);
	uint8_t *payload;
	struct ether_hdr *eth;
	uint16_t len = sizeof(struct ether_hdr) + 1;

	pkt->pkt_len = len;
	pkt->data_len = len;
	pkt->nb_segs = 1;
	pkt->next = NULL;

	/* ethernet header */
	eth = rte_pktmbuf_mtod(pkt, struct ether_hdr*);
	memset(eth, 0, len);
	eth->ether_type = rte_cpu_to_be_16(ETHER_TYPE_ARP);

	/* write some data */
	payload = (uint8_t *)(eth + 1);
	*payload = 42;
	return pkt;
}
Example #4
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();
}
Example #5
0
static void test_queue_reset(void)
{
#	define NB_PKTS 64
	struct pg_error *error = NULL;
	struct pg_brick *queue1, *queue2, *collect;
	struct rte_mbuf **result_pkts;
	struct rte_mbuf *pkts[NB_PKTS];
	uint64_t pkts_mask, i, j;
	uint16_t count = 0;
	struct rte_mempool *mbuf_pool = pg_get_mempool();

	/**
	 * Burst packets in queue1 and test reset of queue1
	 * [queue1] ~ [queue2]----[collect]
	 */
	queue1 = pg_queue_new("q1", 10, &error);
	CHECK_ERROR(error);
	queue2 = pg_queue_new("q2", 10, &error);
	CHECK_ERROR(error);
	collect = pg_collect_new("collect", 1, 1, &error);
	CHECK_ERROR(error);

	pg_brick_link(queue2, collect, &error);
	CHECK_ERROR(error);
	g_assert(!pg_queue_friend(queue1, queue2, &error));
	CHECK_ERROR(error);

	for (i = 0; i < NB_PKTS; i++) {
		pkts[i] = rte_pktmbuf_alloc(mbuf_pool);
		g_assert(pkts[i]);
		pkts[i]->udata64 = i;
		pg_set_mac_addrs(pkts[i],
				 "F0:F1:F2:F3:F4:F5",
				 "E0:E1:E2:E3:E4:E5");
	}

	for (j = 0; j < 100; j++) {
		for (i = 0; i < NB_PKTS; i++)
			pkts[i]->udata64 = i * j;
		/* burst and reset */
		pg_brick_burst_to_east(queue1, 0, pkts, pg_mask_firsts(NB_PKTS),
				       &error);
		CHECK_ERROR(error);
		g_assert(pg_queue_pressure(queue1) > 0);
		g_assert(!pg_brick_reset(queue1, &error));
		g_assert(pg_queue_get_friend(queue1) == NULL);
		g_assert(pg_queue_get_friend(queue2) == NULL);
		g_assert(pg_queue_pressure(queue1) == 0);
		g_assert(pg_queue_pressure(queue2) == 0);
		pg_brick_poll(queue2, &count, &error);
		g_assert(!error);
		g_assert(count == 0);

		/* refriend and burst ok */
		g_assert(!pg_queue_friend(queue1, queue2, &error));
		g_assert(!error);
		g_assert(pg_queue_are_friend(queue1, queue2));
		g_assert(!error);

		pg_brick_burst_to_east(queue1, 0, pkts, pg_mask_firsts(NB_PKTS),
				       &error);
		CHECK_ERROR(error);
		g_assert(pg_queue_pressure(queue1) > 0);
		pg_brick_poll(queue2, &count, &error);
		g_assert(count == NB_PKTS);
		result_pkts = pg_brick_west_burst_get(collect, &pkts_mask,
						      &error);
		CHECK_ERROR(error);
		g_assert(pkts_mask == pg_mask_firsts(NB_PKTS));
		for (i = 0; i < NB_PKTS; i++) {
			g_assert(result_pkts[i]);
			g_assert(result_pkts[i]->udata64 == i * j);
		}
		pg_brick_reset(collect, &error);
		CHECK_ERROR(error);
	}

	/* clean */
	for (i = 0; i < NB_PKTS; i++)
		rte_pktmbuf_free(pkts[i]);
	pg_brick_decref(queue1, &error);
	CHECK_ERROR(error);
	pg_brick_decref(queue2, &error);
	CHECK_ERROR(error);
	pg_brick_decref(collect, &error);
	CHECK_ERROR(error);
#	undef NB_PKTS
}
Example #6
-2
static int packetsgen_poll(struct pg_brick *brick,
			   uint16_t *pkts_cnt,
			   struct pg_error **errp)
{
	struct pg_packetsgen_state *state;
	struct rte_mempool *mp = pg_get_mempool();
	struct rte_mbuf **pkts;
	struct pg_brick_side *s;
	uint64_t pkts_mask;
	int ret;
	uint16_t i;

	state = pg_brick_get_state(brick, struct pg_packetsgen_state);
	s = &brick->sides[state->output];


	pkts = g_new0(struct rte_mbuf*, state->packets_nb);
	for (i = 0; i < state->packets_nb; i++) {
		pkts[i] = rte_pktmbuf_clone(state->packets[i], mp);
		pkts[i]->udata64 = i;
	}

	pkts_mask = pg_mask_firsts(state->packets_nb);
	*pkts_cnt = state->packets_nb;
	ret = pg_brick_side_forward(s, pg_flip_side(state->output),
				    pkts,
				    pkts_mask, errp);
	pg_packets_free(pkts, pkts_mask);
	g_free(pkts);
	return ret;
}