예제 #1
0
파일: vport.c 프로젝트: Sovietaced/ivs
indigo_error_t
indigo_port_stats_get(
    of_port_stats_request_t *port_stats_request,
    of_port_stats_reply_t **port_stats_reply_ptr)
{
    of_port_no_t req_of_port_num;
    of_port_stats_reply_t *port_stats_reply;
    indigo_error_t err = INDIGO_ERROR_NONE;

    port_stats_reply = of_port_stats_reply_new(port_stats_request->version);
    if (port_stats_reply == NULL) {
        err = INDIGO_ERROR_RESOURCE;
        goto out;
    }

    of_list_port_stats_entry_t list;
    of_port_stats_reply_entries_bind(port_stats_reply, &list);

    of_port_stats_request_port_no_get(port_stats_request, &req_of_port_num);
    int dump_all = req_of_port_num == OF_PORT_DEST_NONE_BY_VERSION(port_stats_request->version);

    /* Refresh statistics */
    nl_cache_refill(route_cache_sock, link_cache);

    struct nl_msg *msg = ind_ovs_create_nlmsg(ovs_vport_family, OVS_VPORT_CMD_GET);
    if (dump_all) {
        nlmsg_hdr(msg)->nlmsg_flags |= NLM_F_DUMP;
    } else {
        nla_put_u32(msg, OVS_VPORT_ATTR_PORT_NO, req_of_port_num);
    }

    /* Ask kernel to send us one or more OVS_VPORT_CMD_NEW messages */
    if (nl_send_auto(ind_ovs_socket, msg) < 0) {
        err = INDIGO_ERROR_UNKNOWN;
        goto out;
    }
    ind_ovs_nlmsg_freelist_free(msg);

    /* Handle OVS_VPORT_CMD_NEW messages */
    nl_cb_set(netlink_callbacks, NL_CB_VALID, NL_CB_CUSTOM,
              port_stats_iterator, &list);
    if (nl_recvmsgs(ind_ovs_socket, netlink_callbacks) < 0) {
        err = INDIGO_ERROR_UNKNOWN;
        goto out;
    }

out:
    if (err != INDIGO_ERROR_NONE) {
        of_port_stats_reply_delete(port_stats_reply);
        port_stats_reply = NULL;
    }

    *port_stats_reply_ptr = port_stats_reply;
    return err;
}
예제 #2
0
indigo_error_t indigo_port_stats_get(of_port_stats_request_t *port_stats_request,
                                     of_port_stats_reply_t **port_stats_reply)
{
  indigo_error_t err = INDIGO_ERROR_NONE;
  OFDPA_ERROR_t ofdpa_rv = OFDPA_E_NONE;
  of_port_no_t req_of_port_num;
  of_port_stats_reply_t *reply;
  int dump_all = 0;
  uint32_t port = 0;

  LOG_TRACE("%s() called", __FUNCTION__);

  if (port_stats_request->version < OF_VERSION_1_3)
  {
    LOG_ERROR("Unsupported OpenFlow version 0x%x.", port_stats_request->version);
    return INDIGO_ERROR_VERSION;
  }

  /* Allocate memory for the port stats reply
     Note: Memory allocated is freed by the caller
     of indigo_port_stats_get()*/
  reply = of_port_stats_reply_new(port_stats_request->version);
  if (reply == NULL)
  {
    LOG_ERROR("Error allocating memory for port stats reply.");
    return INDIGO_ERROR_RESOURCE;
  }

  *port_stats_reply = reply;

  of_list_port_stats_entry_t list;
  of_port_stats_reply_entries_bind(*port_stats_reply, &list);

  of_port_stats_request_port_no_get(port_stats_request, &req_of_port_num);
  if (req_of_port_num == OF_PORT_DEST_NONE_BY_VERSION(port_stats_request->version))
  {
    ofdpa_rv = ofdpaPortNextGet(0, &port);
    if (ofdpa_rv != OFDPA_E_NONE)
    {
      LOG_ERROR("Failed to get first port.");
      of_port_stats_reply_delete(*port_stats_reply);
      return indigoConvertOfdpaRv(ofdpa_rv) ;
    }

    /* dump the stats of all the ports */
    dump_all = 1;
  }
  else
  {
    port = req_of_port_num;
  }

  do
  {
    err = ind_ofdpa_port_stats_set(port, &list);
    if (err != INDIGO_ERROR_NONE)
    {
      LOG_ERROR("Error setting port stats LOCI object.");
      break;
    }
    /* Break from the loop if he request is for a single port */
    if (!dump_all)
    {
      break;
    }

  }while((ofdpaPortNextGet(port, &port) == OFDPA_E_NONE));

  /* Free the reply message only on failure.
     Reply message is freed by the caller on success */
  if (err != INDIGO_ERROR_NONE)
  {
    of_port_stats_reply_delete(*port_stats_reply);
    *port_stats_reply = NULL;
  }

  return err;
}