void test_ofp_match_list_elem_free(void) { struct match_list match_list; struct match *match; int i; int max_cnt = 4; TAILQ_INIT(&match_list); /* data */ for (i = 0; i < max_cnt; i++) { match = (struct match *) malloc(sizeof(struct match)); TAILQ_INSERT_TAIL(&match_list, match, entry); } TEST_ASSERT_EQUAL_MESSAGE(TAILQ_EMPTY(&match_list), false, "not match list error."); /* call func. */ ofp_match_list_elem_free(&match_list); TEST_ASSERT_EQUAL_MESSAGE(TAILQ_EMPTY(&match_list), true, "match list error."); }
void test_ofp_flow_reply_create_01(void) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; struct flow_stats *flow_stats = NULL; struct instruction *instruction = NULL; struct match *match = NULL; const char *require[1] = { "04 13 00 58 00 00 00 10 00 01 00 00 00 00 00 00 " "00 48 01 00 00 00 00 02 00 00 00 03 00 04 00 05 " "00 06 00 07 00 00 00 00 00 00 00 00 00 00 00 08 " "00 00 00 00 00 00 00 09 00 00 00 00 00 00 00 0a " "00 01 00 10 00 00 01 08 00 00 00 00 00 00 00 00 " "00 01 00 08 00 00 00 00" }; TAILQ_INIT(&s_flow_stats_list); if ((flow_stats = s_flow_stats_alloc()) != NULL) { /* flow_stats = 48, match = 16, instruction = 8, sum = 72 */ flow_stats->ofp.length = 48 + 16 + 8; flow_stats->ofp.table_id = 0x01; flow_stats->ofp.duration_sec = 0x02; flow_stats->ofp.duration_nsec = 0x03; flow_stats->ofp.priority = 0x04; flow_stats->ofp.idle_timeout = 0x05; flow_stats->ofp.hard_timeout = 0x06; flow_stats->ofp.flags = 0x07; flow_stats->ofp.cookie = 0x08; flow_stats->ofp.packet_count = 0x09; flow_stats->ofp.byte_count = 0x0a; if ((match = match_alloc(8)) != NULL) { match->oxm_class = 0x00; match->oxm_field = 0x01; match->oxm_length = 0x08; TAILQ_INSERT_TAIL(&(flow_stats->match_list), match, entry); } if ((instruction = instruction_alloc()) != NULL) { instruction->ofpit_goto_table.type = OFPIT_GOTO_TABLE; instruction->ofpit_goto_table.len = 0x08; /* action_list empty */ instruction->ofpit_goto_table.table_id = 0x00; TAILQ_INSERT_TAIL(&(flow_stats->instruction_list), instruction, entry); } TAILQ_INSERT_TAIL(&s_flow_stats_list, flow_stats, entry); } else { TEST_FAIL_MESSAGE("allocation error."); } /* port 0 */ ret = check_pbuf_list_packet_create(s_ofp_flow_reply_create_wrap, require, 1); TEST_ASSERT_EQUAL_MESSAGE(LAGOPUS_RESULT_OK, ret, "create port 0 error."); /* free */ while ((flow_stats = TAILQ_FIRST(&s_flow_stats_list)) != NULL) { TAILQ_REMOVE(&s_flow_stats_list, flow_stats, entry); ofp_match_list_elem_free(&flow_stats->match_list); ofp_instruction_list_elem_free(&flow_stats->instruction_list); free(flow_stats); } }
/* Free PacketIn. */ void ofp_packet_in_free(struct eventq_data *data) { if (data != NULL) { ofp_match_list_elem_free(&data->packet_in.match_list); if (data->packet_in.data != NULL) { pbuf_free(data->packet_in.data); } free(data); } }
/* FlowMod packet receive. */ lagopus_result_t ofp_flow_mod_handle(struct channel *channel, struct pbuf *pbuf, struct ofp_header *xid_header, struct ofp_error *error) { lagopus_result_t ret; uint64_t dpid; struct ofp_flow_mod flow_mod; struct match_list match_list; struct instruction_list instruction_list; if (channel != NULL && pbuf != NULL && xid_header != NULL) { /* Init lists. */ TAILQ_INIT(&match_list); TAILQ_INIT(&instruction_list); /* Parse flow mod header. */ ret = ofp_flow_mod_decode(pbuf, &flow_mod); if (ret == LAGOPUS_RESULT_OK) { ret = flow_mod_flags_check(flow_mod.flags, error); if (ret == LAGOPUS_RESULT_OK) { /* Parse matches. */ ret = ofp_match_parse(channel, pbuf, &match_list, error); if (ret == LAGOPUS_RESULT_OK) { /* Parse instructions. */ if (flow_mod.command == OFPFC_DELETE || flow_mod.command == OFPFC_DELETE_STRICT) { /* skip pbuf. */ ret = pbuf_forward(pbuf, pbuf_plen_get(pbuf)); if (ret != LAGOPUS_RESULT_OK) { lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(ret)); } } else { while (pbuf_plen_get(pbuf) > 0) { ret = ofp_instruction_parse(pbuf, &instruction_list, error); if (ret != LAGOPUS_RESULT_OK) { lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(ret)); break; } } } if (ret == LAGOPUS_RESULT_OK) { /* trace. */ flow_mod_trace(&flow_mod, &match_list, &instruction_list); /* Flow add, modify, delete. */ dpid = channel_dpid_get(channel); switch (flow_mod.command) { case OFPFC_ADD: ret = ofp_flow_mod_check_add(dpid, &flow_mod, &match_list, &instruction_list, error); break; case OFPFC_MODIFY: case OFPFC_MODIFY_STRICT: ret = ofp_flow_mod_modify(dpid, &flow_mod, &match_list, &instruction_list, error); break; case OFPFC_DELETE: case OFPFC_DELETE_STRICT: ret = ofp_flow_mod_delete(dpid, &flow_mod, &match_list, error); break; default: ofp_error_set(error, OFPET_FLOW_MOD_FAILED, OFPFMFC_BAD_COMMAND); ret = LAGOPUS_RESULT_OFP_ERROR; break; } if (ret == LAGOPUS_RESULT_OFP_ERROR) { lagopus_msg_warning("OFP ERROR (%s).\n", lagopus_error_get_string(ret)); } } } else { lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(ret)); } } else { lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(ret)); } } else { lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(ret)); ret = LAGOPUS_RESULT_OFP_ERROR; ofp_error_set(error, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN); } /* free. */ if (ret != LAGOPUS_RESULT_OK) { ofp_instruction_list_elem_free(&instruction_list); ofp_match_list_elem_free(&match_list); } } else { ret = LAGOPUS_RESULT_INVALID_ARGS; } return ret; }
void test_ofp_flow_reply_create_02(void) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; struct flow_stats *flow_stats = NULL; struct match *match = NULL; const char *header_data[2] = { "04 13 ff b8 00 00 00 10 00 01 00 01 00 00 00 00 ", "04 13 00 58 00 00 00 10 00 01 00 00 00 00 00 00 " }; const char *body_data[2] = { "00 48 01 00 00 00 00 02 00 00 00 03 00 04 00 05 " "00 06 00 07 00 00 00 00 00 00 00 00 00 00 00 08 " "00 00 00 00 00 00 00 09 00 00 00 00 00 00 00 0a " "00 01 00 18 00 00 01 10 00 00 00 00 00 00 00 00 " "00 00 00 00 00 00 00 00", "00 48 01 00 00 00 00 02 00 00 00 03 00 04 00 05 " "00 06 00 07 00 00 00 00 00 00 00 00 00 00 00 08 " "00 00 00 00 00 00 00 09 00 00 00 00 00 00 00 0a " "00 01 00 18 00 00 01 10 00 00 00 00 00 00 00 00 " "00 00 00 00 00 00 00 00" }; size_t nums[2] = {909, 1}; int i; /* data */ TAILQ_INIT(&s_flow_stats_list); for (i = 0; i < 910; i++) { if ((flow_stats = s_flow_stats_alloc()) != NULL) { /* flow_stats = 48, match = 24, sum = 72 */ flow_stats->ofp.length = 0; flow_stats->ofp.table_id = 0x01; flow_stats->ofp.duration_sec = 0x02; flow_stats->ofp.duration_nsec = 0x03; flow_stats->ofp.priority = 0x04; flow_stats->ofp.idle_timeout = 0x05; flow_stats->ofp.hard_timeout = 0x06; flow_stats->ofp.flags = 0x07; flow_stats->ofp.cookie = 0x08; flow_stats->ofp.packet_count = 0x09; flow_stats->ofp.byte_count = 0x0a; if ((match = match_alloc(16)) != NULL) { match->oxm_class = 0x00; match->oxm_field = 0x01; match->oxm_length = 0x10; TAILQ_INSERT_TAIL(&(flow_stats->match_list), match, entry); } TAILQ_INSERT_TAIL(&s_flow_stats_list, flow_stats, entry); } else { TEST_FAIL_MESSAGE("allocation error."); } } ret = check_pbuf_list_across_packet_create(s_ofp_flow_reply_create_wrap, header_data, body_data, nums, 2); TEST_ASSERT_EQUAL_MESSAGE(LAGOPUS_RESULT_OK, ret, "create port 0 error."); /* free */ while ((flow_stats = TAILQ_FIRST(&s_flow_stats_list)) != NULL) { TAILQ_REMOVE(&s_flow_stats_list, flow_stats, entry); ofp_match_list_elem_free(&flow_stats->match_list); ofp_instruction_list_elem_free(&flow_stats->instruction_list); free(flow_stats); } }