Esempio n. 1
0
/*
 * Add or modify flow table entry.
 *
 * When modifying, the stats can be optionally cleared
 */
static void
flow_cmd_new(struct dpdk_flow_message *request)
{
	struct dpdk_message reply = {0};
	int32_t pos = 0;

	pos = rte_hash_lookup(handle, &request->key);

	if (pos < 0) {
        if (request->flags & FLAG_CREATE) {
			pos = rte_hash_add_key(handle, &request->key);
			flow_table_add_flow(pos, &request->key, request->action, true);
            reply.type = 0;
		} else {
			reply.type = ENOENT;
		}
	} else {
        if (request->flags & FLAG_REPLACE) {
		/* Retrieve flow stats*/
		flow_table_get_flow(pos, NULL, NULL, &request->stats);
		/* Depending on the value of request->clear we will either update
		 * or keep the same stats
		 */
		flow_table_add_flow(pos, &request->key, request->action, request->clear);
		reply.type = 0;
	} else {
			reply.type = EEXIST;
		}
	}

	reply.flow_msg = *request;

	send_reply_to_vswitchd(&reply);
}
Esempio n. 2
0
static const struct bundle_cfg *server_accept(struct task_gen_server *task, struct new_tuple *nt)
{
	int ret = rte_hash_lookup(task->listen_hash, nt);

	if (ret < 0)
		return NULL;
	else
		return task->listen_entries[ret];
}
Esempio n. 3
0
sflow_socket_t* sflow_socket_lookup(sflow_key_t* key) {
    sflow_key_dump("find socket for key", key);
    rte_rwlock_read_lock(&sflow_hash_lock);
    int32_t socket_id = rte_hash_lookup(sflow_hash, key);
    rte_rwlock_read_unlock(&sflow_hash_lock);
    sflow_socket_t* socket = ((int32_t) socket_id) < 0 ? NULL : sflow_sockets[socket_id];
    if (socket) {
        RTE_LOG(DEBUG, L3L4, "found socket at id: %u\n", socket_id);
    }
    return socket;
}
Esempio n. 4
0
/*
 * Dump all flows.
 *
 * The message that is received contains the key for the previously dumped
 * flow entry. If the key is zero then we are dumping the first entry. We
 * reply with EOF when we have dumped all flows
 *
 */
static void
flow_cmd_dump(struct dpdk_flow_message *request)
{
	struct dpdk_message reply = {0};
	struct flow_key empty = {0};
	int32_t pos = 0;

	if (!memcmp(&request->key, &empty, sizeof(request->key))) {
		/*
		 * if flow is empty, it is first call of dump(),
		 * and start searching from the first rule
		 */
		pos = 0;
	} else {
		/* last dumped flow */
		pos = rte_hash_lookup(handle, &request->key);

		if (pos < 0) {
			/* send error reply - the flow must be in the flow table */
			reply.type = ENOENT;
			goto out;
		}
		/* search starting from the next flow */
		pos++;
	}

	/* find next using flow */
	for(;pos < MAX_FLOWS && !flow_table->used[pos]; pos++)
		;

	if (pos < MAX_FLOWS) {
		flow_table_get_flow(pos, &request->key, &request->action, &request->stats);
		reply.type = 0;
	} else {
		/* it was last flow, send message that no more flows here */
		reply.type = EOF;
	}

out:
	reply.flow_msg = *request;

	send_reply_to_vswitchd(&reply);
}
Esempio n. 5
0
/*
 * Return flow entry to vswitchd if it exists
 */
static void
flow_cmd_get(struct dpdk_flow_message *request)
{
	struct dpdk_message reply = {0};
	int32_t pos = 0;

	pos = rte_hash_lookup(handle, &request->key);

	if (pos < 0) {
		reply.type = ENOENT;
	} else {
		flow_table_get_flow(pos, NULL, &request->action, &request->stats);
		reply.type = 0;
	}

	reply.flow_msg = *request;

	send_reply_to_vswitchd(&reply);
}
Esempio 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);
	}
}
Esempio n. 7
0
static int handle_gen_queued(struct task_gen_server *task)
{
	uint8_t out[MAX_PKT_BURST];
	struct bundle_ctx *conn;
	struct pkt_tuple pkt_tuple;
	struct l4_meta l4_meta;
	uint16_t j;
	uint16_t cancelled = 0;
	int ret;

	if (task->cur_mbufs_beg == task->cur_mbufs_end) {
		task->cur_mbufs_end = fqueue_get(task->fqueue, task->cur_mbufs, MAX_PKT_BURST);
		task->cur_mbufs_beg = 0;
	}
	uint16_t n_pkts = task->cur_mbufs_end - task->cur_mbufs_beg;
	struct rte_mbuf **mbufs = task->cur_mbufs + task->cur_mbufs_beg;

	j = task->cancelled;
	if (task->cancelled) {
		uint16_t pkt_len = mbuf_wire_size(mbufs[0]);

		if (token_time_take(&task->token_time, pkt_len) != 0)
			return -1;

		out[0] = task->out_saved;
		task->cancelled = 0;
	}

	/* Main proc loop */
	for (; j < n_pkts; ++j) {

		if (parse_pkt(mbufs[j], &pkt_tuple, &l4_meta)) {
			plogdx_err(mbufs[j], "Unknown packet, parsing failed\n");
			out[j] = OUT_DISCARD;
		}

		conn = NULL;
		ret = rte_hash_lookup(task->bundle_ctx_pool.hash, (const void *)&pkt_tuple);

		if (ret >= 0)
			conn = task->bundle_ctx_pool.hash_entries[ret];
		else {
			/* If not part of existing connection, try to create a connection */
			struct new_tuple nt;
			nt.dst_addr = pkt_tuple.dst_addr;
			nt.proto_id = pkt_tuple.proto_id;
			nt.dst_port = pkt_tuple.dst_port;
			rte_memcpy(nt.l2_types, pkt_tuple.l2_types, sizeof(nt.l2_types));
			const struct bundle_cfg *n;

			if (NULL != (n = server_accept(task, &nt))) {
				conn = bundle_ctx_pool_get(&task->bundle_ctx_pool);
				if (!conn) {
					out[j] = OUT_DISCARD;
					plogx_err("No more free bundles to accept new connection\n");
					continue;
				}
				ret = rte_hash_add_key(task->bundle_ctx_pool.hash, (const void *)&pkt_tuple);
				if (ret < 0) {
					out[j] = OUT_DISCARD;
					bundle_ctx_pool_put(&task->bundle_ctx_pool, conn);
					plog_err("Adding key failed while trying to accept connection\n");
					continue;
				}

				task->bundle_ctx_pool.hash_entries[ret] = conn;

				bundle_init_w_cfg(conn, n, task->heap, PEER_SERVER, &task->seed);
				conn->tuple = pkt_tuple;

				if (conn->ctx.stream_cfg->proto == IPPROTO_TCP)
					task->l4_stats.tcp_created++;
				else
					task->l4_stats.udp_created++;
			}
			else {
				plog_err("Packet received for service that does not exist :\n"
					 "source ip = %0x:%u\n"
					 "dst ip    = %0x:%u\n",
					 pkt_tuple.src_addr, rte_bswap16(pkt_tuple.src_port),
					 pkt_tuple.dst_addr, rte_bswap16(pkt_tuple.dst_port));
			}
		}

		/* bundle contains either an active connection or a
		   newly created connection. If it is NULL, then not
		   listening. */
		if (NULL != conn) {
			ret = bundle_proc_data(conn, mbufs[j], &l4_meta, &task->bundle_ctx_pool, &task->seed, &task->l4_stats);

			out[j] = ret == 0? 0: OUT_HANDLED;

			if (ret == 0) {
				uint16_t pkt_len = mbuf_wire_size(mbufs[j]);

				if (token_time_take(&task->token_time, pkt_len) != 0) {
					task->out_saved = out[j];
					task->cancelled = 1;
					task->base.tx_pkt(&task->base, mbufs, j, out);
					task->cur_mbufs_beg += j;
					return -1;
				}
			}
		}
		else {
			pkt_tuple_debug(&pkt_tuple);
			plogd_dbg(mbufs[j], NULL);
			out[j] = OUT_DISCARD;
		}
	}

	task->base.tx_pkt(&task->base, mbufs, j, out);

	task->cur_mbufs_beg += j;
	return 0;
}
Esempio n. 8
0
static int handle_gen_bulk_client(struct task_base *tbase, struct rte_mbuf **mbufs, uint16_t n_pkts)
{
	struct task_gen_client *task = (struct task_gen_client *)tbase;
	uint8_t out[MAX_PKT_BURST] = {0};
	struct bundle_ctx *conn;
	int ret;

	if (n_pkts) {
		for (int i = 0; i < n_pkts; ++i) {
			struct pkt_tuple pt;
			struct l4_meta l4_meta;

			if (parse_pkt(mbufs[i], &pt, &l4_meta)) {
				plogdx_err(mbufs[i], "Parsing failed\n");
				out[i] = OUT_DISCARD;
				continue;
			}

			ret = rte_hash_lookup(task->bundle_ctx_pool.hash, (const void *)&pt);

			if (ret < 0) {
				plogx_dbg("Client: packet RX that does not belong to connection:"
					  "Client = "IPv4_BYTES_FMT":%d, Server = "IPv4_BYTES_FMT":%d\n",
					  IPv4_BYTES(((uint8_t*)&pt.dst_addr)),
					  rte_bswap16(pt.dst_port),
					  IPv4_BYTES(((uint8_t*)&pt.src_addr)),
					  rte_bswap16(pt.src_port));

				plogdx_dbg(mbufs[i], NULL);

				if (pt.proto_id == IPPROTO_TCP) {
					stream_tcp_create_rst(mbufs[i], &l4_meta, &pt);
					out[i] = 0;
					continue;
				}
				else {
					out[i] = OUT_DISCARD;
					continue;
				}
			}

			conn = task->bundle_ctx_pool.hash_entries[ret];
			ret = bundle_proc_data(conn, mbufs[i], &l4_meta, &task->bundle_ctx_pool, &task->seed, &task->l4_stats);
			out[i] = ret == 0? 0: OUT_HANDLED;
		}
		task->base.tx_pkt(&task->base, mbufs, n_pkts, out);
	}

	/* If there is at least one callback to handle, handle at most MAX_PKT_BURST */
	if (heap_top_is_lower(task->heap, rte_rdtsc())) {
		if (0 != refill_mbufs(&task->n_new_mbufs, task->mempool, task->new_mbufs))
			return 0;

		uint16_t n_called_back = 0;
		while (heap_top_is_lower(task->heap, rte_rdtsc()) && n_called_back < MAX_PKT_BURST) {
			conn = BUNDLE_CTX_UPCAST(heap_pop(task->heap));

			/* handle packet TX (retransmit or delayed transmit) */
			ret = bundle_proc_data(conn, task->new_mbufs[n_called_back], NULL, &task->bundle_ctx_pool, &task->seed, &task->l4_stats);

			if (ret == 0) {
				out[n_called_back] = 0;
				n_called_back++;
			}
		}
		plogx_dbg("During callback, will send %d packets\n", n_called_back);

		task->base.tx_pkt(&task->base, task->new_mbufs, n_called_back, out);
		task->n_new_mbufs -= n_called_back;
	}

	uint32_t n_new = task->bundle_ctx_pool.n_free_bundles;
	n_new = n_new > MAX_PKT_BURST? MAX_PKT_BURST : n_new;

	uint64_t diff = (rte_rdtsc() - task->new_conn_last_tsc)/task->new_conn_cost;
	task->new_conn_last_tsc += diff * task->new_conn_cost;
	task->new_conn_tokens += diff;

	if (task->new_conn_tokens > 16)
		task->new_conn_tokens = 16;
	if (n_new > task->new_conn_tokens)
		n_new = task->new_conn_tokens;
	task->new_conn_tokens -= n_new;
	if (n_new == 0)
		return 0;

	if (0 != refill_mbufs(&task->n_new_mbufs, task->mempool, task->new_mbufs))
		return 0;

	for (uint32_t i = 0; i < n_new; ++i) {
		struct bundle_ctx *bundle_ctx = bundle_ctx_pool_get_w_cfg(&task->bundle_ctx_pool);
		PROX_ASSERT(bundle_ctx);

		struct pkt_tuple *pt = &bundle_ctx->tuple;

		int n_retries = 0;
		do {
			/* Note that the actual packet sent will
			   contain swapped addresses and ports
			   (i.e. pkt.src <=> tuple.dst). The incoming
			   packet will match this struct. */
			bundle_init(bundle_ctx, task->heap, PEER_CLIENT, &task->seed);

			ret = rte_hash_lookup(task->bundle_ctx_pool.hash, (const void *)pt);
			if (ret >= 0) {
				if (n_retries++ == 1000) {
					plogx_err("Already tried 1K times\n");
				}
			}
		} while (ret >= 0);

		ret = rte_hash_add_key(task->bundle_ctx_pool.hash, (const void *)pt);

		if (ret < 0) {
			plogx_err("Failed to add key ret = %d, n_free = %d\n", ret, task->bundle_ctx_pool.n_free_bundles);
			bundle_ctx_pool_put(&task->bundle_ctx_pool, bundle_ctx);

			pkt_tuple_debug2(pt);
			out[i] = OUT_DISCARD;
			continue;
		}

		task->bundle_ctx_pool.hash_entries[ret] = bundle_ctx;

		if (bundle_ctx->ctx.stream_cfg->proto == IPPROTO_TCP)
			task->l4_stats.tcp_created++;
		else
			task->l4_stats.udp_created++;

		task->l4_stats.bundles_created++;

		ret = bundle_proc_data(bundle_ctx, task->new_mbufs[i], NULL, &task->bundle_ctx_pool, &task->seed, &task->l4_stats);
		out[i] = ret == 0? 0: OUT_HANDLED;
	}

	int ret2 = task->base.tx_pkt(&task->base, task->new_mbufs, n_new, out);
	task->n_new_mbufs -= n_new;
	return ret2;
}
Esempio n. 9
0
static void handle_gen_bulk(struct task_base *tbase, struct rte_mbuf **mbufs, uint16_t n_pkts)
{
	struct task_gen_server *task = (struct task_gen_server *)tbase;
	struct pkt_tuple pkt_tuple[MAX_PKT_BURST];
	uint8_t out[MAX_PKT_BURST];
	struct l4_meta l4_meta[MAX_PKT_BURST];
	struct bundle_ctx *conn;
	int ret;

	for (uint16_t j = 0; j < n_pkts; ++j) {
		if (parse_pkt(mbufs[j], &pkt_tuple[j], &l4_meta[j]))
			plogdx_err(mbufs[j], "Unknown packet, parsing failed\n");
	}
	/* Main proc loop */
	for (uint16_t j = 0; j < n_pkts; ++j) {
		conn = NULL;
		ret = rte_hash_lookup(task->bundle_ctx_pool.hash, (const void *)&pkt_tuple[j]);

		if (ret >= 0)
			conn = task->bundle_ctx_pool.hash_entries[ret];

		/* If not part of existing connection, try to create a connection */
		if (NULL == conn) {
			struct new_tuple nt;
			nt.dst_addr = pkt_tuple[j].dst_addr;
			nt.proto_id = pkt_tuple[j].proto_id;
			nt.dst_port = pkt_tuple[j].dst_port;
			rte_memcpy(nt.l2_types, pkt_tuple[j].l2_types, sizeof(nt.l2_types));

			const struct bundle_cfg *n;

			if (NULL != (n = server_accept(task, &nt))) {
				conn = bundle_ctx_pool_get(&task->bundle_ctx_pool);
				if (!conn) {
					out[j] = NO_PORT_AVAIL;
					plogx_err("No more free bundles to accept new connection\n");
					continue;
				}
				ret = rte_hash_add_key(task->bundle_ctx_pool.hash, (const void *)&pkt_tuple[j]);
				if (ret < 0) {
					out[j] = NO_PORT_AVAIL;
					bundle_ctx_pool_put(&task->bundle_ctx_pool, conn);
					plog_err("Adding key failed while trying to accept connection\n");
					continue;
				}

				task->bundle_ctx_pool.hash_entries[ret] = conn;

				bundle_init(conn, n, task->heap, PEER_SERVER, &task->seed);
				conn->tuple = pkt_tuple[j];

				if (conn->ctx.stream_cfg->proto == IPPROTO_TCP)
					task->l4_stats.tcp_created++;
				else
					task->l4_stats.udp_created++;
			}
		}

		/* bundle contains either an active connection or a
		   newly created connection. If it is NULL, then not
		   listening. */
		if (NULL != conn) {
			int ret = bundle_proc_data(conn, mbufs[j], &l4_meta[j], &task->bundle_ctx_pool, &task->seed, &task->l4_stats);

			out[j] = ret == 0? 0: NO_PORT_AVAIL;
		}
		else {
			plog_err("Packet received for service that does not exist\n");
			pkt_tuple_debug(&pkt_tuple[j]);
			plogd_dbg(mbufs[j], NULL);
			out[j] = NO_PORT_AVAIL;
		}
	}
	conn = NULL;

	task->base.tx_pkt(&task->base, mbufs, n_pkts, out);

	if (!(task->heap->n_elems && rte_rdtsc() > heap_peek_prio(task->heap)))
		return ;

	if (task->n_new_mbufs < MAX_PKT_BURST) {
		if (rte_mempool_get_bulk(task->mempool, (void **)task->new_mbufs, MAX_PKT_BURST - task->n_new_mbufs) < 0) {
			return ;
 		}

		for (uint32_t i = 0; i < MAX_PKT_BURST - task->n_new_mbufs; ++i) {
			init_mbuf_seg(task->new_mbufs[i]);
		}

		task->n_new_mbufs = MAX_PKT_BURST;
	}

	if (task->heap->n_elems && rte_rdtsc() > heap_peek_prio(task->heap)) {
		uint16_t n_called_back = 0;
		while (task->heap->n_elems && rte_rdtsc() > heap_peek_prio(task->heap) && n_called_back < MAX_PKT_BURST) {
			conn = BUNDLE_CTX_UPCAST(heap_pop(task->heap));

			/* handle packet TX (retransmit or delayed transmit) */
			ret = bundle_proc_data(conn, task->new_mbufs[n_called_back], NULL, &task->bundle_ctx_pool, &task->seed, &task->l4_stats);

			if (ret == 0) {
				out[n_called_back] = 0;
				n_called_back++;
			}
		}

		task->base.tx_pkt(&task->base, task->new_mbufs, n_called_back, out);
		task->n_new_mbufs -= n_called_back;
	}
}
Esempio n. 10
0
static void handle_gen_bulk_client(struct task_base *tbase, struct rte_mbuf **mbufs, uint16_t n_pkts)
{
	struct task_gen_client *task = (struct task_gen_client *)tbase;
	uint8_t out[MAX_PKT_BURST] = {0};
	struct bundle_ctx *conn;
	int ret;

	if (n_pkts) {
		for (int i = 0; i < n_pkts; ++i) {
			struct pkt_tuple pt;
			struct l4_meta l4_meta;

			if (parse_pkt(mbufs[i], &pt, &l4_meta)) {
				plogdx_err(mbufs[i], "Parsing failed\n");
				out[i] = NO_PORT_AVAIL;
				continue;
			}

			ret = rte_hash_lookup(task->bundle_ctx_pool.hash, (const void *)&pt);

			if (ret < 0) {
				plogx_dbg("Client: packet RX that does not belong to connection:"
					  "Client = "IPv4_BYTES_FMT":%d, Server = "IPv4_BYTES_FMT":%d\n", IPv4_BYTES(((uint8_t*)&pt.dst_addr)), rte_bswap16(pt.dst_port), IPv4_BYTES(((uint8_t*)&pt.src_addr)), rte_bswap16(pt.src_port));
				plogdx_dbg(mbufs[i], NULL);
				// if tcp, send RST
				/* pkt_tuple_debug2(&pt); */
				out[i] = NO_PORT_AVAIL;
				continue;
			}

			conn = task->bundle_ctx_pool.hash_entries[ret];
			ret = bundle_proc_data(conn, mbufs[i], &l4_meta, &task->bundle_ctx_pool, &task->seed, &task->l4_stats);
			out[i] = ret == 0? 0: NO_PORT_AVAIL;
		}
		task->base.tx_pkt(&task->base, mbufs, n_pkts, out);
	}

	if (task->n_new_mbufs < MAX_PKT_BURST) {
		if (rte_mempool_get_bulk(task->mempool, (void **)task->new_mbufs, MAX_PKT_BURST - task->n_new_mbufs) < 0) {
			plogx_err("4Mempool alloc failed %d\n", MAX_PKT_BURST);
			return ;
 		}

		for (uint32_t i = 0; i < MAX_PKT_BURST - task->n_new_mbufs; ++i) {
			init_mbuf_seg(task->new_mbufs[i]);
		}

		task->n_new_mbufs = MAX_PKT_BURST;
	}

	/* If there is at least one callback to handle, handle at most MAX_PKT_BURST */
	if (task->heap->n_elems && rte_rdtsc() > heap_peek_prio(task->heap)) {
		uint16_t n_called_back = 0;
		while (task->heap->n_elems && rte_rdtsc() > heap_peek_prio(task->heap) && n_called_back < MAX_PKT_BURST) {
			conn = BUNDLE_CTX_UPCAST(heap_pop(task->heap));

			/* handle packet TX (retransmit or delayed transmit) */
			ret = bundle_proc_data(conn, task->new_mbufs[n_called_back], NULL, &task->bundle_ctx_pool, &task->seed, &task->l4_stats);

			if (ret == 0) {
				out[n_called_back] = 0;
				n_called_back++;
			}
		}
		plogx_dbg("During callback, will send %d packets\n", n_called_back);

		task->base.tx_pkt(&task->base, task->new_mbufs, n_called_back, out);
		task->n_new_mbufs -= n_called_back;
	}

	int n_new = task->bundle_ctx_pool.n_free_bundles;
	n_new = n_new > MAX_PKT_BURST? MAX_PKT_BURST : n_new;

	if (n_new == 0)
		return ;

	if (task->n_new_mbufs < MAX_PKT_BURST) {
		if (rte_mempool_get_bulk(task->mempool, (void **)task->new_mbufs, MAX_PKT_BURST - task->n_new_mbufs) < 0) {
			plogx_err("4Mempool alloc failed %d\n", MAX_PKT_BURST);
			return ;
		}

		for (uint32_t i = 0; i < MAX_PKT_BURST - task->n_new_mbufs; ++i) {
			init_mbuf_seg(task->new_mbufs[i]);
		}

		task->n_new_mbufs = MAX_PKT_BURST;
	}

	for (int i = 0; i < n_new; ++i) {
		int32_t ret = cdf_sample(task->cdf, &task->seed);
		/* Select a new bundle_cfg according to imix */
		struct bundle_cfg *bundle_cfg = &task->bundle_cfgs[ret];
		struct bundle_ctx *bundle_ctx;

		bundle_ctx = bundle_ctx_pool_get(&task->bundle_ctx_pool);

		/* Should be an assert: */
		if (!bundle_ctx) {
			plogx_err("No more available bundles\n");
			exit(-1);
		}

		struct pkt_tuple *pt = &bundle_ctx->tuple;

		int n_retries = 0;
		do {
			/* Note that the actual packet sent will
			   contain swapped addresses and ports
			   (i.e. pkt.src <=> tuple.dst). The incoming
			   packet will match this struct. */
			bundle_init(bundle_ctx, bundle_cfg, task->heap, PEER_CLIENT, &task->seed);

			ret = rte_hash_lookup(task->bundle_ctx_pool.hash, (const void *)pt);
			if (n_retries == 1000) {
				plogx_err("Already tried 1K times\n");
			}
			if (ret >= 0) {
				n_retries++;
			}
		} while (ret >= 0);

		ret = rte_hash_add_key(task->bundle_ctx_pool.hash, (const void *)pt);

		if (ret < 0) {
			plogx_err("Failed to add key ret = %d, n_free = %d\n", ret, task->bundle_ctx_pool.n_free_bundles);
			bundle_ctx_pool_put(&task->bundle_ctx_pool, bundle_ctx);

			pkt_tuple_debug2(pt);
			out[i] = NO_PORT_AVAIL;
			continue;
		}

		task->bundle_ctx_pool.hash_entries[ret] = bundle_ctx;

		if (bundle_ctx->ctx.stream_cfg->proto == IPPROTO_TCP)
			task->l4_stats.tcp_created++;
		else
			task->l4_stats.udp_created++;

		ret = bundle_proc_data(bundle_ctx, task->new_mbufs[i], NULL, &task->bundle_ctx_pool, &task->seed, &task->l4_stats);
		out[i] = ret == 0? 0: NO_PORT_AVAIL;
	}

	task->base.tx_pkt(&task->base, task->new_mbufs, n_new, out);
	task->n_new_mbufs -= n_new;
}
Esempio n. 11
0
int hash_table_lkup(const void *key)
{
    return rte_hash_lookup(ht_hdl, key);
}
Esempio n. 12
0
static int
timed_lookups(unsigned with_hash, unsigned with_data, unsigned table_index)
{
	unsigned i, j;
	const uint64_t start_tsc = rte_rdtsc();
	void *ret_data;
	void *expected_data;
	int32_t ret;

	for (i = 0; i < NUM_LOOKUPS/KEYS_TO_ADD; i++) {
		for (j = 0; j < KEYS_TO_ADD; j++) {
			if (with_hash && with_data) {
				ret = rte_hash_lookup_with_hash_data(h[table_index],
							(const void *) keys[j],
							signatures[j], &ret_data);
				if (ret < 0) {
					printf("Key number %u was not found\n", j);
					return -1;
				}
				expected_data = (void *) ((uintptr_t) signatures[j]);
				if (ret_data != expected_data) {
					printf("Data returned for key number %u is %p,"
					       " but should be %p\n", j, ret_data,
						expected_data);
					return -1;
				}
			} else if (with_hash && !with_data) {
				ret = rte_hash_lookup_with_hash(h[table_index],
							(const void *) keys[j],
							signatures[j]);
				if (ret < 0 || ret != positions[j]) {
					printf("Key looked up in %d, should be in %d\n",
						ret, positions[j]);
					return -1;
				}
			} else if (!with_hash && with_data) {
				ret = rte_hash_lookup_data(h[table_index],
							(const void *) keys[j], &ret_data);
				if (ret < 0) {
					printf("Key number %u was not found\n", j);
					return -1;
				}
				expected_data = (void *) ((uintptr_t) signatures[j]);
				if (ret_data != expected_data) {
					printf("Data returned for key number %u is %p,"
					       " but should be %p\n", j, ret_data,
						expected_data);
					return -1;
				}
			} else {
				ret = rte_hash_lookup(h[table_index], keys[j]);
				if (ret < 0 || ret != positions[j]) {
					printf("Key looked up in %d, should be in %d\n",
						ret, positions[j]);
					return -1;
				}
			}
		}
	}

	const uint64_t end_tsc = rte_rdtsc();
	const uint64_t time_taken = end_tsc - start_tsc;

	cycles[table_index][LOOKUP][with_hash][with_data] = time_taken/NUM_LOOKUPS;

	return 0;
}