/* header only packet. */ lagopus_result_t ofp_header_create(struct channel *channel, uint8_t type, struct ofp_header *xid_header, struct ofp_header *header, struct pbuf *pbuf) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; uint32_t xid; if (channel != NULL && header != NULL && pbuf != NULL) { if (xid_header != NULL) { xid = xid_header->xid; } else { xid = channel_xid_get(channel); } ofp_header_set(header, channel_version_get(channel), type, (uint16_t) pbuf_plen_get(pbuf), xid); ret = ofp_header_encode(pbuf, header); if (ret != LAGOPUS_RESULT_OK) { lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(ret)); } } else { ret = LAGOPUS_RESULT_INVALID_ARGS; } return ret; }
STATIC lagopus_result_t ofp_role_reply_create(struct channel *channel, struct pbuf **pbuf, struct ofp_header *xid_header, struct ofp_role_request *role_request) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; /* reply is ofp_role_request structure. */ struct ofp_role_request role_reply; /* check params */ if (channel != NULL && pbuf != NULL && xid_header != NULL && role_request != NULL) { /* alloc */ *pbuf = channel_pbuf_list_get(channel, sizeof(struct ofp_role_request)); if (*pbuf != NULL) { pbuf_plen_set(*pbuf, sizeof(struct ofp_role_request)); /* Fill in header. */ ofp_header_set(&role_reply.header, channel_version_get(channel), OFPT_ROLE_REPLY, (uint16_t) pbuf_plen_get(*pbuf), xid_header->xid); role_reply.role = role_request->role; memset(role_reply.pad, 0, sizeof(role_request->pad)); role_reply.generation_id = role_request->generation_id; /* Encode message. */ ret = ofp_role_request_encode(*pbuf, &role_reply); if (ret != LAGOPUS_RESULT_OK) { lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(ret)); } if (ret != LAGOPUS_RESULT_OK && *pbuf != NULL) { channel_pbuf_list_unget(channel, *pbuf); *pbuf = NULL; } } else { lagopus_msg_warning("Can't allocate pbuf.\n"); ret = LAGOPUS_RESULT_NO_MEMORY; } } else { ret = LAGOPUS_RESULT_INVALID_ARGS; } return ret; }
lagopus_result_t channel_mgr_ofp_version_get(const char *channel_name, uint8_t *version) { lagopus_result_t ret; struct channel *chan; ret = channel_mgr_channel_lookup_by_name(channel_name, &chan); if (ret != LAGOPUS_RESULT_OK) { return ret; } *version = channel_version_get(chan); return LAGOPUS_RESULT_OK; }
STATIC lagopus_result_t ofp_get_async_reply_create(struct channel *channel, struct pbuf **pbuf, struct ofp_header *xid_header) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; struct ofp_async_config async_config; /* check params */ if (channel != NULL && pbuf != NULL && xid_header != NULL) { /* alloc */ *pbuf = channel_pbuf_list_get(channel, sizeof(struct ofp_async_config)); if (*pbuf != NULL) { pbuf_plen_set(*pbuf, sizeof(struct ofp_async_config)); /* Copy packet_in_mask, port_status_mask, flow_removed_mask. */ channel_role_mask_get(channel, &async_config); /* Fill in header. */ ofp_header_set(&async_config.header, channel_version_get(channel), OFPT_GET_ASYNC_REPLY, (uint16_t) pbuf_plen_get(*pbuf), xid_header->xid); /* Encode message. */ ret = ofp_async_config_encode(*pbuf, &async_config); if (ret != LAGOPUS_RESULT_OK) { lagopus_msg_warning("FAILED : ofp_async_config_encode (%s).\n", lagopus_error_get_string(ret)); } } else { lagopus_msg_warning("Can't allocate pbuf.\n"); ret = LAGOPUS_RESULT_NO_MEMORY; } if (ret != LAGOPUS_RESULT_OK && *pbuf != NULL) { channel_pbuf_list_unget(channel, *pbuf); *pbuf = NULL; } } else { ret = LAGOPUS_RESULT_INVALID_ARGS; } return ret; }
/* Send switch features reply. */ STATIC lagopus_result_t ofp_features_reply_create(struct channel *channel, struct pbuf **pbuf, struct ofp_header *xid_header) { struct ofp_switch_features features; lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; if (channel != NULL && pbuf != NULL && xid_header != NULL) { /* alloc */ *pbuf = channel_pbuf_list_get(channel, sizeof(struct ofp_switch_features)); if (*pbuf != NULL) { pbuf_plen_set(*pbuf, sizeof(struct ofp_switch_features)); ret = features_reply_features_get(channel, &features); if (ret == LAGOPUS_RESULT_OK) { /* Fill in header. */ ofp_header_set(&features.header, channel_version_get(channel), OFPT_FEATURES_REPLY, (uint16_t) pbuf_plen_get(*pbuf), xid_header->xid); /* Encode message. */ ret = ofp_switch_features_encode(*pbuf, &features); if (ret != LAGOPUS_RESULT_OK) { 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("Can't allocate pbuf.\n"); ret = LAGOPUS_RESULT_NO_MEMORY; } if (ret != LAGOPUS_RESULT_OK && *pbuf != NULL) { channel_pbuf_list_unget(channel, *pbuf); *pbuf = NULL; } } else { ret = LAGOPUS_RESULT_INVALID_ARGS; } return ret; }
/* Send experimenter reply. */ STATIC lagopus_result_t ofp_experimenter_reply_create(struct channel *channel, struct pbuf **pbuf, struct ofp_header *xid_header, struct ofp_experimenter_header *exper_req) { struct ofp_experimenter_header exper_reply; lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; if (channel != NULL && pbuf != NULL && xid_header != NULL && exper_req != NULL) { *pbuf = NULL; /* alloc */ *pbuf = channel_pbuf_list_get(channel, sizeof(struct ofp_experimenter_header)); if (*pbuf != NULL) { pbuf_plen_set(*pbuf, sizeof(struct ofp_experimenter_header)); exper_reply.experimenter = exper_req->experimenter; exper_reply.exp_type = exper_req->exp_type; /* Fill in header. */ ofp_header_set(&exper_reply.header, channel_version_get(channel), OFPT_EXPERIMENTER, (uint16_t) pbuf_plen_get(*pbuf), xid_header->xid); /* Encode message. */ ret = ofp_experimenter_header_encode(*pbuf, &exper_reply); if (ret != LAGOPUS_RESULT_OK) { lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(ret)); } } else { lagopus_msg_warning("Can't allocate pbuf.\n"); ret = LAGOPUS_RESULT_NO_MEMORY; } if (ret != LAGOPUS_RESULT_OK && *pbuf != NULL) { channel_pbuf_list_unget(channel, *pbuf); *pbuf = NULL; } } else { ret = LAGOPUS_RESULT_INVALID_ARGS; } return ret; }
void test_channel_version_get_set(void) { struct channel *channel; uint8_t ret_version; uint8_t version = 0x10; channel = s_create_data_channel(); /* Call func. */ channel_version_set(channel, version); ret_version = channel_version_get(channel); TEST_ASSERT_EQUAL_MESSAGE(ret_version, version, "version error."); session_destroy(channel_session_get(channel)); free(channel); }
/* Header only packet receive. */ lagopus_result_t ofp_header_handle(struct channel *channel, struct pbuf *pbuf, struct ofp_error *error) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; struct ofp_header msg; if (channel != NULL && pbuf != NULL && error != NULL) { /* Parse ofp_header. */ ret = ofp_header_decode(pbuf, &msg); if (ret == LAGOPUS_RESULT_OK) { /* Skip payload if it exists. */ if (pbuf_plen_get(pbuf) > 0) { ret = pbuf_forward(pbuf, pbuf_plen_get(pbuf)); if (ret != LAGOPUS_RESULT_OK) { lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(ret)); if (ret == LAGOPUS_RESULT_OUT_OF_RANGE) { ofp_error_set(error, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN); ret = LAGOPUS_RESULT_OFP_ERROR; } } } if (ret == LAGOPUS_RESULT_OK && channel_version_get(channel) != msg.version) { lagopus_msg_warning("Unsupported vetsion.\n"); ofp_error_set(error, OFPET_BAD_REQUEST, OFPBRC_BAD_VERSION); ret = LAGOPUS_RESULT_OFP_ERROR; } } else { lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(ret)); ofp_error_set(error, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN); return LAGOPUS_RESULT_OFP_ERROR; } } else { ret = LAGOPUS_RESULT_INVALID_ARGS; } return ret; }
/* Send experimenter multipart reply. */ STATIC lagopus_result_t ofp_experimenter_mp_reply_create( struct channel *channel, struct pbuf_list **pbuf_list, struct ofp_header *xid_header, struct ofp_experimenter_multipart_header *exper_req) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; uint16_t tmp_length = 0; uint16_t length = 0; struct ofp_multipart_reply mp_reply; struct pbuf *pbuf = NULL; struct ofp_experimenter_multipart_header exper_reply; if (channel != NULL && pbuf_list != NULL && xid_header != NULL && exper_req != NULL) { /* alloc */ *pbuf_list = pbuf_list_alloc(); if (*pbuf_list != NULL) { pbuf = pbuf_list_last_get(*pbuf_list); if (pbuf != NULL) { pbuf_plen_set(pbuf, pbuf_size_get(pbuf)); /* Fill in header. */ memset(&mp_reply, 0, sizeof(mp_reply)); ofp_header_set(&mp_reply.header, channel_version_get(channel), OFPT_MULTIPART_REPLY, tmp_length, xid_header->xid); mp_reply.type = OFPMP_EXPERIMENTER; mp_reply.flags = 0; /* Encode multipart reply. */ ret = ofp_multipart_reply_encode(pbuf, &mp_reply); if (ret == LAGOPUS_RESULT_OK) { exper_reply.experimenter = exper_req->experimenter; exper_reply.exp_type = exper_req->exp_type; /* Encode message. */ ret = ofp_experimenter_multipart_header_encode( pbuf, &exper_reply); if (ret == LAGOPUS_RESULT_OK) { /* set length for last pbuf. */ ret = pbuf_length_get(pbuf, &length); if (ret == LAGOPUS_RESULT_OK) { ret = ofp_header_length_set(pbuf, length); if (ret == LAGOPUS_RESULT_OK) { pbuf_plen_reset(pbuf); ret = LAGOPUS_RESULT_OK; } 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)); } } else { lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(ret)); } } else { lagopus_msg_warning("Can't allocate pbuf.\n"); ret = LAGOPUS_RESULT_NO_MEMORY; } } else { lagopus_msg_warning("Can't allocate pbuf_list.\n"); ret = LAGOPUS_RESULT_NO_MEMORY; } if (ret != LAGOPUS_RESULT_OK && *pbuf_list != NULL) { pbuf_list_free(*pbuf_list); *pbuf_list = NULL; } } else { ret = LAGOPUS_RESULT_INVALID_ARGS; } return ret; }
STATIC lagopus_result_t ofp_meter_features_reply_create(struct channel *channel, struct pbuf_list **pbuf_list, struct ofp_meter_features *ofp_meter_features, struct ofp_header *xid_header) { lagopus_result_t res = LAGOPUS_RESULT_ANY_FAILURES; uint16_t length = 0; struct pbuf *pbuf = NULL; struct ofp_multipart_reply ofpmp_reply; /* check params */ if (channel != NULL && pbuf_list != NULL && ofp_meter_features != NULL && xid_header != NULL) { /* alloc */ *pbuf_list = NULL; *pbuf_list = pbuf_list_alloc(); if (*pbuf_list != NULL) { /* alloc&get tail of pbuf_list */ pbuf = pbuf_list_last_get(*pbuf_list); if (pbuf != NULL) { /* set data. */ memset(&ofpmp_reply, 0, sizeof(ofpmp_reply)); ofp_header_set(&ofpmp_reply.header, channel_version_get(channel), OFPT_MULTIPART_REPLY, 0, /* length set in ofp_header_length_set() */ xid_header->xid); ofpmp_reply.type = OFPMP_METER_FEATURES; /* encode message. */ pbuf_plen_set(pbuf, pbuf_size_get(pbuf)); res = ofp_multipart_reply_encode_list(*pbuf_list, &pbuf, &ofpmp_reply); if (res == LAGOPUS_RESULT_OK) { res = ofp_meter_features_encode_list(*pbuf_list, &pbuf, ofp_meter_features); if (res == LAGOPUS_RESULT_OK) { /* set packet length */ res = pbuf_length_get(pbuf, &length); if (res == LAGOPUS_RESULT_OK) { res = ofp_header_length_set(pbuf, length); if (res == LAGOPUS_RESULT_OK) { pbuf_plen_reset(pbuf); } else { lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(res)); } } else { lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(res)); } } else { lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(res)); } } else { lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(res)); } } else { res = LAGOPUS_RESULT_NO_MEMORY; } } else { res = LAGOPUS_RESULT_NO_MEMORY; } } else { res = LAGOPUS_RESULT_INVALID_ARGS; } return res; }