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; }
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; }