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; }
/* Generated from of10/port_stats_reply.data */ static int test_of10_port_stats_reply(void) { uint8_t binary[] = { 0x01, 0x11, 0x00, 0xdc, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, }; of_object_t *obj; obj = of_port_stats_reply_new(OF_VERSION_1_0); { of_object_t list; of_port_stats_reply_entries_bind(obj, &list); { of_object_t *obj = of_port_stats_entry_new(OF_VERSION_1_0); of_port_stats_entry_collisions_set(obj, 5); of_port_stats_entry_port_no_set(obj, 1); of_port_stats_entry_rx_bytes_set(obj, 0); of_port_stats_entry_rx_crc_err_set(obj, 0); of_port_stats_entry_rx_dropped_set(obj, 0); of_port_stats_entry_rx_errors_set(obj, 0); of_port_stats_entry_rx_frame_err_set(obj, 0); of_port_stats_entry_rx_over_err_set(obj, 0); of_port_stats_entry_rx_packets_set(obj, 56); of_port_stats_entry_tx_bytes_set(obj, 0); of_port_stats_entry_tx_dropped_set(obj, 0); of_port_stats_entry_tx_errors_set(obj, 0); of_port_stats_entry_tx_packets_set(obj, 0); of_list_append(&list, obj); of_object_delete(obj); } { of_object_t *obj = of_port_stats_entry_new(OF_VERSION_1_0); of_port_stats_entry_collisions_set(obj, 1); of_port_stats_entry_port_no_set(obj, 65534); of_port_stats_entry_rx_bytes_set(obj, 0); of_port_stats_entry_rx_crc_err_set(obj, 0); of_port_stats_entry_rx_dropped_set(obj, 0); of_port_stats_entry_rx_errors_set(obj, 0); of_port_stats_entry_rx_frame_err_set(obj, 0); of_port_stats_entry_rx_over_err_set(obj, 0); of_port_stats_entry_rx_packets_set(obj, 1); of_port_stats_entry_tx_bytes_set(obj, 0); of_port_stats_entry_tx_dropped_set(obj, 0); of_port_stats_entry_tx_errors_set(obj, 0); of_port_stats_entry_tx_packets_set(obj, 0); of_list_append(&list, obj); of_object_delete(obj); } } of_port_stats_reply_flags_set(obj, 0); of_port_stats_reply_xid_set(obj, 5); if (sizeof(binary) != WBUF_CURRENT_BYTES(OF_OBJECT_TO_WBUF(obj)) || memcmp(binary, WBUF_BUF(OF_OBJECT_TO_WBUF(obj)), sizeof(binary))) { show_failure(binary, sizeof(binary), WBUF_BUF(OF_OBJECT_TO_WBUF(obj)), WBUF_CURRENT_BYTES(OF_OBJECT_TO_WBUF(obj))); of_object_delete(obj); return TEST_FAIL; } of_object_delete(obj); return TEST_PASS; }
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; }