static lagopus_result_t channel_id_eq(struct channel *chan, void *val) { struct channel_id_vars *v = val; if (channel_id_get(chan) == v->channel_id) { v->channel = chan; return 1; } return LAGOPUS_RESULT_OK; }
/* Packetout packet receive. */ lagopus_result_t ofp_packet_out_handle(struct channel *channel, struct pbuf *pbuf, struct ofp_header *xid_header, struct ofp_error *error) { lagopus_result_t res = LAGOPUS_RESULT_ANY_FAILURES; struct eventq_data *eventq_data = NULL; struct pbuf *data_pbuf = NULL; struct pbuf *req_pbuf = NULL; uint64_t dpid; uint16_t data_len = 0; /* check params */ if (channel != NULL && pbuf != NULL && xid_header != NULL && error != NULL) { dpid = channel_dpid_get(channel); /* create packet_out */ eventq_data = malloc(sizeof(*eventq_data)); if (eventq_data != NULL) { memset(eventq_data, 0, sizeof(*eventq_data)); /* Init action-list. */ TAILQ_INIT(&eventq_data->packet_out.action_list); eventq_data->packet_out.data = NULL; eventq_data->packet_out.req = NULL; /* decode. */ if ((res = ofp_packet_out_decode( pbuf, &(eventq_data->packet_out.ofp_packet_out))) != LAGOPUS_RESULT_OK) { lagopus_msg_warning("packet_out decode error.\n"); ofp_error_set(error, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN); res = LAGOPUS_RESULT_OFP_ERROR; } else if ((res = ofp_action_parse( pbuf, eventq_data->packet_out.ofp_packet_out.actions_len, &(eventq_data->packet_out.action_list), error)) != LAGOPUS_RESULT_OK) { lagopus_msg_warning("action_list decode error.\n"); } else { /* decode success */ /* set eventq_data members */ eventq_data->type = LAGOPUS_EVENTQ_PACKET_OUT; eventq_data->free = ofp_packet_out_free; eventq_data->packet_out.channel_id = channel_id_get(channel); /* copy packet_out.data if needed */ res = pbuf_length_get(pbuf, &data_len); if (res == LAGOPUS_RESULT_OK) { if (data_len != 0) { if (eventq_data->packet_out.ofp_packet_out.buffer_id == OFP_NO_BUFFER) { /* alloc packet_out.data */ data_pbuf = pbuf_alloc(data_len); if (data_pbuf != NULL) { res = pbuf_copy_with_length(data_pbuf, pbuf, data_len); if (res == LAGOPUS_RESULT_OK) { eventq_data->packet_out.data = data_pbuf; } else { lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(res)); } } else { lagopus_msg_warning("Can't allocate data_pbuf.\n"); res = LAGOPUS_RESULT_NO_MEMORY; } } else { lagopus_msg_warning("Not empty data filed in request(buffer_id = %x).\n", eventq_data->packet_out.ofp_packet_out.buffer_id); ofp_error_set(error, OFPET_BAD_REQUEST, OFPBRC_BUFFER_UNKNOWN); res = LAGOPUS_RESULT_OFP_ERROR; } } else { res = LAGOPUS_RESULT_OK; } /* Copy request for ofp_error. */ if (res == LAGOPUS_RESULT_OK && error->req != NULL) { req_pbuf = pbuf_alloc(OFP_ERROR_MAX_SIZE); if (req_pbuf != NULL) { res = pbuf_copy(req_pbuf, error->req); if (res == LAGOPUS_RESULT_OK) { eventq_data->packet_out.req = req_pbuf; } else { lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(res)); } } else { lagopus_msg_warning("Can't allocate data_pbuf.\n"); res = LAGOPUS_RESULT_NO_MEMORY; } } if (res == LAGOPUS_RESULT_OK) { /* dump trace.*/ packet_out_trace(&eventq_data->packet_out.ofp_packet_out, &eventq_data->packet_out.action_list); /* send to DataPlane */ res = ofp_handler_event_dataq_put(dpid, eventq_data); if (res != LAGOPUS_RESULT_OK) { lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(res)); } } } else { lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(res)); } } if (res != LAGOPUS_RESULT_OK && eventq_data != NULL) { ofp_packet_out_free(eventq_data); } } else { /* channel_pbuf_list_get returns NULL */ res = LAGOPUS_RESULT_NO_MEMORY; } } else { /* params are NULL */ res = LAGOPUS_RESULT_INVALID_ARGS; } return res; }
void test_channel_tcp(void) { int sock4, sock6; socklen_t size; struct sockaddr_in sin; lagopus_ip_address_t *addr4 = NULL; lagopus_ip_address_t *addr6 = NULL; struct channel_list *chan_list ; struct channel *chan4, *chan6, *chan = NULL; lagopus_result_t ret; int cnt; printf("test_channel_tcp in\n"); channel_mgr_initialize(); ret = channel_mgr_channels_lookup_by_dpid(dpid, &chan_list ); TEST_ASSERT_EQUAL(LAGOPUS_RESULT_NOT_FOUND, ret); TEST_ASSERT_EQUAL(NULL, chan_list ); ret = lagopus_ip_address_create("127.0.0.1", true, &addr4); TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, ret); ret = lagopus_ip_address_create("::1", false, &addr6); TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, ret); ret = channel_mgr_channel_add(bridge_name, dpid, addr4); TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, ret); ret = channel_mgr_channel_add(bridge_name, dpid, addr6); TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, ret); ret = channel_mgr_channel_add(bridge_name, dpid, addr4); TEST_ASSERT_EQUAL(LAGOPUS_RESULT_ALREADY_EXISTS, ret); ret = channel_mgr_channel_lookup(bridge_name, addr4, &chan4); TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, ret); TEST_ASSERT_EQUAL(0, channel_id_get(chan4)); ret = channel_port_set(chan4, 10022); TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, ret); ret = channel_local_port_set(chan4, 20022); TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, ret); ret = channel_local_addr_set(chan4, addr4); TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, ret); ret = channel_mgr_channel_add(bridge_name, dpid, addr6); TEST_ASSERT_EQUAL(LAGOPUS_RESULT_ALREADY_EXISTS, ret); ret = channel_mgr_channel_lookup(bridge_name, addr6, &chan6); TEST_ASSERT_EQUAL(1, channel_id_get(chan6)); TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, ret); ret = channel_port_set(chan6, 10023); TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, ret); ret = channel_local_port_set(chan6, 20023); TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, ret); ret = channel_local_addr_set(chan6, addr6); TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, ret); ret = channel_mgr_channel_lookup_by_channel_id(dpid, 1, &chan); TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, ret); TEST_ASSERT_NOT_EQUAL(NULL, chan); ret = channel_mgr_channel_lookup_by_channel_id(dpid, 9999, &chan); TEST_ASSERT_EQUAL(LAGOPUS_RESULT_NOT_FOUND, ret); TEST_ASSERT_EQUAL(NULL, chan); cnt = 0; ret = channel_mgr_channels_lookup_by_dpid(dpid, &chan_list ); TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, ret); ret = channel_list_iterate(chan_list , channel_count, &cnt); TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, ret); TEST_ASSERT_EQUAL(2, cnt); cnt = 0; ret = channel_mgr_dpid_iterate(dpid, channel_count, &cnt); TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, ret); TEST_ASSERT_EQUAL(2, cnt); run = true; size = sizeof(sin); printf("accept in\n"); sock4 = accept(s4, (struct sockaddr *)&sin, &size); TEST_ASSERT_NOT_EQUAL(-1, sock4); sock6 = accept(s6, (struct sockaddr *)&sin, &size); TEST_ASSERT_NOT_EQUAL(-1, sock6); ret = channel_mgr_channel_lookup(bridge_name, addr4, &chan4); TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, ret); channel_refs_get(chan4); ret = channel_mgr_channel_delete(bridge_name, addr4); TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, ret); channel_refs_put(chan4); ret = channel_mgr_channel_delete(bridge_name, addr4); TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, ret); ret = channel_mgr_channel_lookup(bridge_name, addr4, &chan4); TEST_ASSERT_EQUAL(LAGOPUS_RESULT_NOT_FOUND, ret); ret = channel_mgr_channel_delete(bridge_name, addr6); TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, ret); ret = channel_mgr_channel_lookup(bridge_name, addr6, &chan6); TEST_ASSERT_EQUAL(LAGOPUS_RESULT_NOT_FOUND, ret); TEST_ASSERT_FALSE(channel_mgr_has_alive_channel_by_dpid(dpid)); ret = channel_mgr_event_upcall(); TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, ret); lagopus_ip_address_destroy(addr4); lagopus_ip_address_destroy(addr6); close(sock4); close(sock6); }