Example #1
0
static void
pbuf_list_append(pbuf_list *hd, struct pbuf *p)
{
    pbuf_list *tl = hd;
    while (tl->next) tl=tl->next;
    tl->next = pbuf_list_alloc(p);
}
Example #2
0
err_t
tcp_recv_cb(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
    tcp_wrap *tw = (tcp_wrap *)arg;
    value v_unit;
    err_t ret_err;
    if (p == NULL || err != ERR_OK) {
        LWIP_STUB_DPRINTF("tcp_recv_cb: p==NULL || err!=ERR_OK state->CLOSING");
        tw->desc->state = TCP_CLOSING;
        /* Wake up any listeners, which will get a read error once the
           pending receive queue has been handled by the application */
        v_unit = caml_callback(Field(tw->v, 0), Val_unit);
        if (p) pbuf_free(p);
        ret_err = ERR_OK;
    } else {
        if (tw->desc->rx == NULL) {
            LWIP_STUB_DPRINTF("tcp_recv_cb: rx first packet");
            tw->desc->rx = pbuf_list_alloc(p);
            v_unit = caml_callback(Field(tw->v, 0), Val_unit);
            ret_err = ERR_OK;
        } else if (tw->desc->state == TCP_ACCEPTED) {
            /* Should be no need to wake up listeners here as nothing
               can sleep if there are already pending packets in rx queue */
            LWIP_STUB_DPRINTF("tcp_recv_cb: rx chaining packet");
            pbuf_list_append(tw->desc->rx, p);
            ret_err = ERR_OK;
        } else if (tw->desc->state == TCP_CLOSING) {
            /* Remote side closing twice, trash the data */
            tcp_recved(pcb, p->tot_len);
            pbuf_free(p);
            ret_err = ERR_OK;
        } else {
            LWIP_STUB_DPRINTF1("tcp_recv_cb: rx unknown else; state=%d", tw->desc->state);
            tcp_recved(pcb, p->tot_len);
            pbuf_free(p);
            ret_err = ERR_OK;
        }
    }
    return ret_err;
}
/* 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;
}