/* Features Request packet receive. */ lagopus_result_t ofp_features_request_handle(struct channel *channel, struct pbuf *pbuf, struct ofp_header *xid_header, struct ofp_error *error) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; struct pbuf *send_pbuf = NULL; /* Parse packet. */ ret = ofp_header_handle(channel, pbuf, error); if (ret == LAGOPUS_RESULT_OK) { /* Features request reply. */ ret = ofp_features_reply_create(channel, &send_pbuf, xid_header); if (ret == LAGOPUS_RESULT_OK) { features_request_trace(xid_header); channel_send_packet(channel, send_pbuf); ret = LAGOPUS_RESULT_OK; } else { lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(ret)); } } if (ret != LAGOPUS_RESULT_OK && send_pbuf != NULL) { channel_pbuf_list_unget(channel, send_pbuf); } return ret; }
/* Experimenter packet receive. */ lagopus_result_t ofp_experimenter_request_handle(struct channel *channel, struct pbuf *pbuf, struct ofp_header *xid_header) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; struct pbuf *send_pbuf = NULL; struct ofp_experimenter_header exper_req; if (channel != NULL && pbuf != NULL && xid_header != NULL) { /* Parse packet. */ ret = ofp_experimenter_header_decode(pbuf, &exper_req); if (ret == LAGOPUS_RESULT_OK) { /* Experimenter request reply. */ ret = ofp_experimenter_reply_create(channel, &send_pbuf, xid_header, &exper_req); if (ret == LAGOPUS_RESULT_OK) { channel_send_packet(channel, send_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)); ret = LAGOPUS_RESULT_OFP_ERROR; } if (ret != LAGOPUS_RESULT_OK && send_pbuf != NULL) { channel_pbuf_list_unget(channel, send_pbuf); } } else { ret = LAGOPUS_RESULT_INVALID_ARGS; } return ret; }
lagopus_result_t ofp_get_async_request_handle(struct channel *channel, struct pbuf *pbuf, struct ofp_header *xid_header, struct ofp_error *error) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; struct pbuf *send_pbuf = NULL; /* check params */ if (channel != NULL && pbuf != NULL && xid_header != NULL && error != NULL) { ret = pbuf_plen_check(pbuf, xid_header->length); if (ret == LAGOPUS_RESULT_OK) { /* Parse packet. */ ret = ofp_header_handle(channel, pbuf, error); if (ret == LAGOPUS_RESULT_OK) { /* dump trace. */ get_async_request_trace(xid_header); /* Reply send.*/ ret = ofp_get_async_reply_create(channel, &send_pbuf, xid_header); if (ret == LAGOPUS_RESULT_OK) { channel_send_packet(channel, send_pbuf); } else { lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(ret)); } } else { lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(ret)); ofp_error_set(error, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN); ret = LAGOPUS_RESULT_OFP_ERROR; } if (ret != LAGOPUS_RESULT_OK && send_pbuf != NULL) { channel_pbuf_list_unget(channel, send_pbuf); } } else { lagopus_msg_warning("bad length.\n"); ofp_error_set(error, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN); ret = LAGOPUS_RESULT_OFP_ERROR; } } 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; }
static lagopus_result_t ofp_write_channel(struct channel *channel, struct pbuf *pbuf) { lagopus_result_t ret = LAGOPUS_RESULT_OK; struct pbuf *send_pbuf = NULL; uint16_t len = 0; if (channel != NULL && pbuf != NULL) { ret = pbuf_length_get(pbuf, &len); if (ret == LAGOPUS_RESULT_OK) { send_pbuf = channel_pbuf_list_get(channel, (size_t) len); if (send_pbuf != NULL) { /* Copy pbuf. */ ret = pbuf_copy(send_pbuf, pbuf); if (ret == LAGOPUS_RESULT_OK) { ret = ofp_header_packet_set(channel, send_pbuf); if (ret == LAGOPUS_RESULT_OK) { channel_send_packet(channel, send_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("Can't allocate pbuf.\n"); ret = LAGOPUS_RESULT_NO_MEMORY; } } else { lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(ret)); } if (ret != LAGOPUS_RESULT_OK && send_pbuf != NULL) { channel_pbuf_list_unget(channel, send_pbuf); } } else { ret = LAGOPUS_RESULT_INVALID_ARGS; } return ret; }
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; }
lagopus_result_t ofp_role_request_handle(struct channel *channel, struct pbuf *pbuf, struct ofp_header *xid_header, struct ofp_error *error) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; struct ofp_role_request role_request; struct ofp_role_request modified_role_request; struct pbuf *send_pbuf = NULL; uint64_t dpid; if (channel != NULL && pbuf != NULL && xid_header != NULL && error != NULL) { /* Parse packet. */ ret = ofp_role_request_decode(pbuf, &role_request); if (ret == LAGOPUS_RESULT_OK) { /* dump trace. */ role_request_trace(&role_request); ret = role_check(role_request.role, error); if (ret == LAGOPUS_RESULT_OK) { dpid = channel_dpid_get(channel); if (ofp_role_generation_id_check(dpid, role_request.role, role_request.generation_id) == true) { /* copy role request. */ modified_role_request = role_request; ret = ofp_role_channel_update(channel, &modified_role_request, dpid); if (ret == LAGOPUS_RESULT_OK) { /* Reply send.*/ ret = ofp_role_reply_create(channel, &send_pbuf, xid_header, &modified_role_request); if (ret == LAGOPUS_RESULT_OK) { channel_send_packet(channel, send_pbuf); } 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("bad generation_id.\n"); ofp_error_set(error, OFPET_ROLE_REQUEST_FAILED, OFPRRFC_STALE); ret = LAGOPUS_RESULT_OFP_ERROR; } if (ret != LAGOPUS_RESULT_OK && send_pbuf != NULL) { channel_pbuf_list_unget(channel, send_pbuf); } } } else { lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(ret)); ofp_error_set(error, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN); ret = LAGOPUS_RESULT_OFP_ERROR; } } else { ret = LAGOPUS_RESULT_INVALID_ARGS; } return ret; }