Esempio n. 1
0
/* Copy out all the pbufs in a chain into a string, and ack/free pbuf.
 * @return 0: nothing, -1: closed connection, +n: bytes read
 */
CAMLprim value
caml_tcp_read(value v_tw)
{
    CAMLparam1(v_tw);
    CAMLlocal1(v_str);
    /* Not using tcp_wrap_of_value as we need to clear out the remaining
       RX queue before raising the Connection_closed exception. Check that
       tw->pcb is set for the rest of the function before using it. */
    tcp_wrap *tw = Tcp_wrap_val(v_tw);
    struct pbuf_list *pl = tw->desc->rx;
    unsigned int tot_len;
    char *s;

    LWIP_STUB_DPRINTF("caml_tcp_rx_read");
    if (!pl) {
        v_str = caml_alloc_string(0);
        CAMLreturn(v_str);
    }

    tot_len = pbuf_list_length(pl);
    v_str = caml_alloc_string(tot_len);
    s = String_val(v_str);
    do {
        pbuf_copy_partial(pl->p, s, pl->p->tot_len, 0);
        s += pl->p->tot_len;
    } while ((pl = pl->next));
    if (tw->pcb)
        tcp_recved(tw->pcb, tot_len);
    pbuf_list_free(tw->desc->rx);
    tw->desc->rx = NULL;
    CAMLreturn(v_str);   
}
lagopus_result_t
ofp_meter_features_request_handle(struct channel *channel,
                                  struct pbuf *pbuf,
                                  struct ofp_header *xid_header,
                                  struct ofp_error *error) {
  lagopus_result_t res = LAGOPUS_RESULT_ANY_FAILURES;
  uint64_t dpid;
  struct ofp_meter_features ofp_meter_features;
  struct pbuf_list *send_pbuf_list = NULL;

  /* check params */
  if (channel != NULL && pbuf != NULL &&
      xid_header != NULL && error != NULL) {
    if (pbuf_plen_equal_check(pbuf, 0) == LAGOPUS_RESULT_OK) {
      /* get datas */
      memset(&ofp_meter_features, 0, sizeof(ofp_meter_features));
      dpid = channel_dpid_get(channel);
      res = ofp_meter_features_get(dpid, &ofp_meter_features, error);
      if (res == LAGOPUS_RESULT_OK) {
        /* create desc reply. */
        res = ofp_meter_features_reply_create(channel,
                                              &send_pbuf_list,
                                              &ofp_meter_features,
                                              xid_header);
        if (res == LAGOPUS_RESULT_OK) {
          /* send desc reply */
          res = channel_send_packet_list(channel, send_pbuf_list);
          if (res != LAGOPUS_RESULT_OK) {
            lagopus_msg_warning("Socket write error (%s).\n",
                                lagopus_error_get_string(res));
          }
        } else {
          lagopus_msg_warning("reply creation failed, (%s).\n",
                              lagopus_error_get_string(res));
        }
        /* free. */
        if (send_pbuf_list != NULL) {
          pbuf_list_free(send_pbuf_list);
        }
      }
    } else {
      lagopus_msg_warning("over packet length.\n");
      ofp_error_set(error, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
      res = LAGOPUS_RESULT_OFP_ERROR;
    }
  } else {
    res = LAGOPUS_RESULT_INVALID_ARGS;
  }
  return res;
}
/* Group Features Request packet receive. */
lagopus_result_t
ofp_group_features_request_handle(struct channel *channel, struct pbuf *pbuf,
                                  struct ofp_header *xid_header,
                                  struct ofp_error *error) {
  lagopus_result_t ret;
  uint64_t dpid;
  struct ofp_group_features group_features;
  struct pbuf_list *pbuf_list = NULL;

  if (channel != NULL && pbuf != NULL &&
      xid_header != NULL && error != NULL) {
    if (pbuf_plen_equal_check(pbuf, 0) == LAGOPUS_RESULT_OK) {
      dpid = channel_dpid_get(channel);

      ret = ofp_group_features_get(dpid,
                                   &group_features,
                                   error);
      if (ret == LAGOPUS_RESULT_OK) {
        ret = ofp_group_features_reply_create(channel, &pbuf_list,
                                              &group_features,
                                              xid_header);
        if (ret == LAGOPUS_RESULT_OK) {
          /* write packets. */
          ret = channel_send_packet_list(channel, pbuf_list);
          if (ret != LAGOPUS_RESULT_OK) {
            lagopus_msg_warning("Can't write\n");
          }
        } 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("over packet length.\n");
      ofp_error_set(error, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
      ret = LAGOPUS_RESULT_OFP_ERROR;
    }

    /* free. */
    if (pbuf_list != NULL) {
      pbuf_list_free(pbuf_list);
    }
  } else {
    ret = LAGOPUS_RESULT_INVALID_ARGS;
  }

  return ret;
}
Esempio n. 4
0
static void
tcp_wrap_finalize(value v_tw)
{
    tcp_wrap *tw = Tcp_wrap_val(v_tw);
    LWIP_STUB_DPRINTF("tcp_wrap_finalize");
    if (tw->pcb) {
        if (tcp_close(tw->pcb) != ERR_OK)
            tcp_abort(tw->pcb);
        tw->pcb = NULL;
    }
    if (tw->desc->rx)
        pbuf_list_free(tw->desc->rx);
    if (tw->desc)
        free(tw->desc);
    if (tw->v)
        caml_remove_generational_global_root(&tw->v);
    free(tw);
}
/* Experimenter multipart packet receive. */
lagopus_result_t
ofp_experimenter_mp_request_handle(struct channel *channel, struct pbuf *pbuf,
                                   struct ofp_header *xid_header) {
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;
  struct pbuf_list *pbuf_list = NULL;
  struct ofp_experimenter_multipart_header exper_req;

  if (channel != NULL && pbuf != NULL &&
      xid_header != NULL) {
    /* Parse packet. */
    ret = ofp_experimenter_multipart_header_decode(pbuf, &exper_req);
    if (ret == LAGOPUS_RESULT_OK) {
      /* Experimenter request reply. */
      ret = ofp_experimenter_mp_reply_create(channel, &pbuf_list,
                                             xid_header, &exper_req);
      if (ret == LAGOPUS_RESULT_OK) {
        ret = channel_send_packet_list(channel, pbuf_list);
        if (ret != LAGOPUS_RESULT_OK) {
          lagopus_msg_warning("Can't write.\n");
          ret = LAGOPUS_RESULT_OFP_ERROR;
        }
      } 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;
    }

    /* free. */
    if (pbuf_list != NULL) {
      pbuf_list_free(pbuf_list);
    }
  } else {
    ret = LAGOPUS_RESULT_INVALID_ARGS;
  }

  return ret;
}
Esempio n. 6
0
/* Desc Request packet receive. */
lagopus_result_t
ofp_desc_request_handle(struct channel *channel, struct pbuf *pbuf,
                        struct ofp_header *xid_header,
                        struct ofp_error *error) {
  lagopus_result_t res = LAGOPUS_RESULT_ANY_FAILURES;
  uint64_t dpid;
  struct ofp_desc ofp_desc;
  struct pbuf_list *send_pbuf_list = NULL;

  /* check params */
  if (channel != NULL && pbuf != NULL &&
      xid_header != NULL && error != NULL) {
    dpid = channel_dpid_get(channel);

    /* get datas */
    memset(&ofp_desc, 0, sizeof(ofp_desc));
    res = ofp_desc_get(dpid, &ofp_desc, error);
    if (res == LAGOPUS_RESULT_OK) {
      /* create desc reply. */
      res = ofp_desc_reply_create(channel, &send_pbuf_list,
                                  &ofp_desc, xid_header);
      if (res == LAGOPUS_RESULT_OK) {
        /* send desc reply */
        res = channel_send_packet_list(channel, send_pbuf_list);
        if (res != LAGOPUS_RESULT_OK) {
          lagopus_msg_warning("Socket write error (%s).\n",
                              lagopus_error_get_string(res));
        }
      } else {
        lagopus_msg_warning("reply creation failed, (%s).\n",
                            lagopus_error_get_string(res));
      }
      pbuf_list_free(send_pbuf_list);
    }
  } else {
    res = LAGOPUS_RESULT_INVALID_ARGS;
  }
  return res;
}
/* 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;
}