/* * 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); }
/* Try to get next flow, which should succeed */ static void test_flow_table_get_next_flow(int argc, char *argv[]) { struct flow_key key1 = {1}; struct flow_key key2 = {2}; struct flow_key key_check = {0}; 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(); flow_table_del_all(); action_output_build(&action_multiple[0], 1); action_null_build(&action_multiple[1]); ret = flow_table_add_flow(&key1, action_multiple); assert(ret >= 0); ret = flow_table_add_flow(&key2, action_multiple); assert(ret >= 0); ret = flow_table_get_first_flow(&key_check, action_check, &stats_check); assert(ret >= 0); if (memcmp(&key1, &key_check, sizeof(struct flow_key)) == 0 ) { ret = flow_table_get_next_flow(&key_check, &key_check, action_check, &stats_check); assert(ret >= 0); assert(memcmp(action_multiple, action_check, sizeof(struct action)) == 0); assert(memcmp(&stats_zero, &stats_check, sizeof(struct flow_stats)) == 0 ); assert(memcmp(&key2, &key_check, sizeof(struct flow_key)) == 0 ); } else if (memcmp(&key2, &key_check, sizeof(struct flow_key) == 0)) { ret = flow_table_get_next_flow(&key_check, &key_check, action_check, &stats_check); assert(ret >= 0); assert(memcmp(action_multiple, action_check, sizeof(struct action)) == 0); assert(memcmp(&stats_zero, &stats_check, sizeof(struct flow_stats)) == 0 ); assert(memcmp(&key1, &key_check, sizeof(struct flow_key)) == 0 ); } else { assert(1==0); } }