Beispiel #1
0
lagopus_result_t
ofp_header_mp_copy(struct pbuf *dst_pbuf,
                   struct pbuf *src_pbuf) {
  struct ofp_multipart_reply mp_reply;
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;
  pbuf_info_t cur_src_pbuf_info;
  pbuf_info_t cur_dst_pbuf_info;
  pbuf_info_t update_pbuf_info;
  uint16_t cur_src_length = 0;

  if (dst_pbuf != NULL && src_pbuf != NULL) {
    /* Store current dst/src_pbuf info. */
    pbuf_info_store(dst_pbuf, &cur_dst_pbuf_info);
    pbuf_info_store(src_pbuf, &cur_src_pbuf_info);
    ret = pbuf_length_get(src_pbuf, &cur_src_length);

    if (ret == LAGOPUS_RESULT_OK) {
      /* Update src_pbuf info for ofp_multipart_reply_decode. */
      pbuf_getp_set(&update_pbuf_info, pbuf_data_get(src_pbuf));
      pbuf_putp_set(&update_pbuf_info,
                    pbuf_data_get(src_pbuf) + sizeof(struct ofp_multipart_reply));
      pbuf_plen_set(&update_pbuf_info, sizeof(struct ofp_multipart_reply));
      pbuf_info_load(src_pbuf, &update_pbuf_info);

      ret = ofp_multipart_reply_decode(src_pbuf, &mp_reply);

      if (ret == LAGOPUS_RESULT_OK) {
        /* Set length/flag in src_pbuf. */
        mp_reply.header.length = cur_src_length;
        mp_reply.flags = OFPMPF_REPLY_MORE;
        /* Update src_pbuf info for ofp_multipart_reply_encode. */
        pbuf_reset(src_pbuf);
        pbuf_plen_set(src_pbuf, sizeof(struct ofp_multipart_reply));

        ret = ofp_multipart_reply_encode(src_pbuf, &mp_reply);

        if (ret == LAGOPUS_RESULT_OK) {
          /* Set length/flag in dst_pbuf. */
          mp_reply.header.length = sizeof(struct ofp_multipart_reply);
          mp_reply.flags = 0;
          /* Update dst_pbuf info for ofp_multipart_reply_encode. */
          pbuf_reset(dst_pbuf);
          pbuf_plen_set(dst_pbuf, pbuf_plen_get(&cur_dst_pbuf_info));

          ret = ofp_multipart_reply_encode(dst_pbuf, &mp_reply);
          if (ret == LAGOPUS_RESULT_OK) {
            /* Load pbuf info. */
            pbuf_info_load(src_pbuf, &cur_src_pbuf_info);
          } 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 {
    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;
}