示例#1
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)
{
	int ret = 0;
	struct dpdk_message reply = {0};
	struct flow_key empty = {0};
	struct flow_key key = {0};
	struct flow_stats stats = {0};

	if (!memcmp(&request->key, &empty, sizeof(request->key))) {
		/*
		 * if key is empty, it is first call of dump(), so we
		 * need to reply using the first flow
		 */
		ret = flow_table_get_first_flow(&key, request->actions, &stats);
	} else {
		/* next flow */
		ret = flow_table_get_next_flow(&request->key,
		               &key, request->actions, &stats);
	}

	if (ret >= 0) {
		request->key = key;
		request->stats = stats;
		reply.type = 0;
	} else {
		/* Reached the end of the flow table */
		reply.type = EOF;
	}

	reply.flow_msg = *request;
	send_reply_to_vswitchd(&reply);
}
示例#2
0
/*
 * Delete single flow or all flows.
 *
 * When request->key is empty delete all flows
 */
static void
flow_cmd_del(struct dpdk_flow_message *request)
{
	struct dpdk_message reply = {0};
	struct flow_key empty = {0};
	int pos = 0;

	if (!memcmp(&request->key, &empty, sizeof(request->key))) {
		flow_table_del_all();
		reply.type = 0;
	} else {
		pos = flow_table_lookup(&request->key);
		if (pos < 0) {
			reply.type = ENOENT;
		} else {
			/* Retrieve flow stats*/
			flow_table_get_flow(&request->key,
			               NULL, &request->stats);
			flow_table_del_flow(&request->key);
			reply.type = 0;
		}
	}

	reply.flow_msg = *request;
	send_reply_to_vswitchd(&reply);
}
示例#3
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};
	int pos = 0;

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

	reply.flow_msg = *request;

	send_reply_to_vswitchd(&reply);
}
示例#4
0
文件: main.c 项目: weixu8/dpdk-ovs
/*
 * Delete single flow or all flows.
 *
 * When request->key is empty delete all flows
 */
static void
flow_cmd_del(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, delete all flows */
		for (pos = 0; pos < MAX_FLOWS; pos++) {
			if (flow_table->used[pos]) {
				rte_hash_del_key(handle, &request->key);
				flow_table_del_flow(pos);
			}
		}
		reply.type = 0;
	} else {
		/* delete specified flow */
		pos = rte_hash_del_key(handle, &request->key);

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

	reply.flow_msg = *request;

	send_reply_to_vswitchd(&reply);
}
示例#5
0
/*
 * Send message to vswitchd indicating message type is not known
 */
static void
handle_unknown_cmd(void)
{
	struct dpdk_message reply = {0};

	reply.type = EINVAL;

	send_reply_to_vswitchd(&reply);
}
示例#6
0
/*
 * Return flow entry to vswitchd if it exists
 */
static void
flow_cmd_get(struct dpdk_flow_message *request)
{
	struct dpdk_message reply = {0};
	int ret = 0;

	ret = flow_table_get_flow(&request->key, request->actions, &request->stats);
	if (ret < 0) {
		reply.type = ENOENT;
	} else {
		reply.type = 0;
	}

	reply.flow_msg = *request;
	send_reply_to_vswitchd(&reply);
}
示例#7
0
文件: main.c 项目: weixu8/dpdk-ovs
/*
 * 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);
}
示例#8
0
文件: main.c 项目: weixu8/dpdk-ovs
/*
 * 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);
}