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};
	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);
}
Esempio n. 2
0
/* Try to modify a flow, which should succeed */
static void
test_flow_table_mod_flow(int argc, char *argv[])
{
	struct flow_key key1 = {1};
	struct action action_multiple[MAX_ACTIONS] = {0};
	struct action action_check[MAX_ACTIONS] = {0};
	struct flow_stats stats_zero = {0};
	struct flow_stats stats_check = {0};
	int ret = 0;

	flow_table_init();

	/* add a flow with 2 actions */
	action_output_build(&action_multiple[0], 2);
	action_output_build(&action_multiple[1], 1);
	action_null_build(&action_multiple[2]);
	flow_table_add_flow(&key1, action_multiple);
	action_output_build(&action_multiple[0], 1);
	action_null_build(&action_multiple[1]);
	/*modify it to only have 1 action */
	flow_table_mod_flow(&key1, action_multiple, true);

	ret = flow_table_get_flow(&key1, action_check, &stats_check);
	assert(ret >= 0);
	assert(memcmp(&action_multiple[0], action_check, sizeof(struct action)) == 0);
	/* check that our flow now only has one entry */
	assert(action_check[1].type == ACTION_NULL);
	assert(memcmp(&stats_zero, &stats_check , sizeof(struct flow_stats)) == 0 );
}