diff options
Diffstat (limited to 'src/rpc-server/commands/trex_rpc_cmd_general.cpp')
-rw-r--r-- | src/rpc-server/commands/trex_rpc_cmd_general.cpp | 293 |
1 files changed, 254 insertions, 39 deletions
diff --git a/src/rpc-server/commands/trex_rpc_cmd_general.cpp b/src/rpc-server/commands/trex_rpc_cmd_general.cpp index 109cc1a4..14b38165 100644 --- a/src/rpc-server/commands/trex_rpc_cmd_general.cpp +++ b/src/rpc-server/commands/trex_rpc_cmd_general.cpp @@ -27,6 +27,8 @@ limitations under the License. #include <internal_api/trex_platform_api.h> +#include "trex_stateless_rx_core.h" + #include <fstream> #include <iostream> #include <unistd.h> @@ -289,19 +291,15 @@ TrexRpcCmdGetSysInfo::_run(const Json::Value ¶ms, Json::Value &result) { section["ports"] = Json::arrayValue; for (int i = 0; i < main->get_port_count(); i++) { - uint32_t speed; string driver; - string hw_macaddr; - string src_macaddr; - string dst_macaddr; string pci_addr; string description; supp_speeds_t supp_speeds; int numa; TrexStatelessPort *port = main->get_port_by_id(i); - port->get_properties(driver, speed); - port->get_macaddr(hw_macaddr, src_macaddr, dst_macaddr); + + port->get_properties(driver); port->get_pci_info(pci_addr, numa); main->get_platform_api()->getPortAttrObj(i)->get_description(description); @@ -311,12 +309,9 @@ TrexRpcCmdGetSysInfo::_run(const Json::Value ¶ms, Json::Value &result) { section["ports"][i]["driver"] = driver; section["ports"][i]["description"] = description; - section["ports"][i]["hw_macaddr"] = hw_macaddr; - section["ports"][i]["src_macaddr"] = src_macaddr; - section["ports"][i]["dst_macaddr"] = dst_macaddr; - section["ports"][i]["pci_addr"] = pci_addr; - section["ports"][i]["numa"] = numa; + section["ports"][i]["pci_addr"] = pci_addr; + section["ports"][i]["numa"] = numa; uint16_t caps = port->get_rx_caps(); section["ports"][i]["rx"]["caps"] = Json::arrayValue; @@ -330,7 +325,6 @@ TrexRpcCmdGetSysInfo::_run(const Json::Value ¶ms, Json::Value &result) { section["ports"][i]["rx"]["caps"].append("rx_bytes"); } section["ports"][i]["rx"]["counters"] = port->get_rx_count_num(); - section["ports"][i]["speed"] = (uint16_t) speed / 1000; section["ports"][i]["is_fc_supported"] = get_stateless_obj()->get_platform_api()->getPortAttrObj(i)->is_fc_change_supported(); section["ports"][i]["is_led_supported"] = get_stateless_obj()->get_platform_api()->getPortAttrObj(i)->is_led_change_supported(); section["ports"][i]["is_link_supported"] = get_stateless_obj()->get_platform_api()->getPortAttrObj(i)->is_link_change_supported(); @@ -345,6 +339,68 @@ TrexRpcCmdGetSysInfo::_run(const Json::Value ¶ms, Json::Value &result) { return (TREX_RPC_CMD_OK); } + +int +TrexRpcCmdSetPortAttr::parse_rx_filter_mode(const Json::Value &msg, uint8_t port_id, Json::Value &result) { + const std::string type = parse_choice(msg, "mode", {"hw", "all"}, result); + + rx_filter_mode_e filter_mode; + if (type == "hw") { + filter_mode = RX_FILTER_MODE_HW; + } else if (type == "all") { + filter_mode = RX_FILTER_MODE_ALL; + } else { + assert(0); + } + + return get_stateless_obj()->get_platform_api()->getPortAttrObj(port_id)->set_rx_filter_mode(filter_mode); +} + +int +TrexRpcCmdSetPortAttr::parse_ipv4(const Json::Value &msg, uint8_t port_id, Json::Value &result) { + + const std::string ipv4_str = parse_string(msg, "addr", result); + + uint32_t ipv4_addr; + if (!utl_ipv4_to_uint32(ipv4_str.c_str(), ipv4_addr)) { + std::stringstream ss; + ss << "invalid IPv4 address: '" << ipv4_str << "'"; + generate_parse_err(result, ss.str()); + } + + get_stateless_obj()->get_platform_api()->getPortAttrObj(port_id)->set_src_ipv4(ipv4_addr); + return (0); +} + +int +TrexRpcCmdSetPortAttr::parse_dest(const Json::Value &msg, uint8_t port_id, Json::Value &result) { + + /* can be either IPv4 or MAC */ + const std::string addr = parse_string(msg, "addr", result); + + TRexPortAttr *port_attr = get_stateless_obj()->get_platform_api()->getPortAttrObj(port_id); + + /* try IPv4 */ + uint32_t ipv4_addr; + uint8_t mac[6]; + + if (utl_ipv4_to_uint32(addr.c_str(), ipv4_addr)) { + port_attr->get_dest().set_dest_ipv4(ipv4_addr); + + } else if (utl_str_to_macaddr(addr, mac)) { + port_attr->get_dest().set_dest_mac(mac); + + } else { + std::stringstream ss; + ss << "'dest' is not an IPv4 address or a MAC address: '" << addr << "'"; + generate_parse_err(result, ss.str()); + } + + + return (0); +} + + /** * set port commands * @@ -361,46 +417,64 @@ TrexRpcCmdSetPortAttr::_run(const Json::Value ¶ms, Json::Value &result) { uint8_t port_id = parse_port(params, result); const Json::Value &attr = parse_object(params, "attr", result); + int ret = 0; - bool changed = false; + /* iterate over all attributes in the dict */ for (const std::string &name : attr.getMemberNames()) { + if (name == "promiscuous") { bool enabled = parse_bool(attr[name], "enabled", result); ret = get_stateless_obj()->get_platform_api()->getPortAttrObj(port_id)->set_promiscuous(enabled); } + else if (name == "link_status") { bool up = parse_bool(attr[name], "up", result); ret = get_stateless_obj()->get_platform_api()->getPortAttrObj(port_id)->set_link_up(up); } + else if (name == "led_status") { bool on = parse_bool(attr[name], "on", result); ret = get_stateless_obj()->get_platform_api()->getPortAttrObj(port_id)->set_led(on); - } else if (name == "flow_ctrl_mode") { + } + + else if (name == "flow_ctrl_mode") { int mode = parse_int(attr[name], "mode", result); ret = get_stateless_obj()->get_platform_api()->getPortAttrObj(port_id)->set_flow_ctrl(mode); - } else { - generate_execute_err(result, "Not recognized attribute: " + name); - break; } - if (ret != 0){ - if ( ret == -ENOTSUP ) { - generate_execute_err(result, "Error applying " + name + ": operation is not supported for this NIC."); - } - else if (ret) { - generate_execute_err(result, "Error applying " + name + " attribute, return value: " + to_string(ret)); - } + + else if (name == "rx_filter_mode") { + const Json::Value &rx = parse_object(attr, name, result); + ret = parse_rx_filter_mode(rx, port_id, result); + } + + else if (name == "ipv4") { + const Json::Value &ipv4 = parse_object(attr, name, result); + ret = parse_ipv4(ipv4, port_id, result); + } + + else if (name == "dest") { + const Json::Value &dest = parse_object(attr, name, result); + ret = parse_dest(dest, port_id, result); + } + + /* unknown attribute */ + else { + generate_execute_err(result, "unknown attribute type: '" + name + "'"); break; - } else { - changed = true; } - } - if (changed) { - get_stateless_obj()->get_platform_api()->publish_async_port_attr_changed(port_id); - } + /* check error code */ + if ( ret == -ENOTSUP ) { + generate_execute_err(result, "Error applying " + name + ": operation is not supported for this NIC."); + } else if (ret) { + generate_execute_err(result, "Error applying " + name + " attribute, return value: " + to_string(ret)); + } + } + result["result"] = Json::objectValue; return (TREX_RPC_CMD_OK); + } @@ -568,17 +642,12 @@ TrexRpcCmdGetPortStatus::_run(const Json::Value ¶ms, Json::Value &result) { result["result"]["owner"] = (port->get_owner().is_free() ? "" : port->get_owner().get_name()); result["result"]["state"] = port->get_state_as_string(); result["result"]["max_stream_id"] = port->get_max_stream_id(); - result["result"]["speed"] = get_stateless_obj()->get_platform_api()->getPortAttrObj(port_id)->get_link_speed(); /* attributes */ - result["result"]["attr"]["promiscuous"]["enabled"] = get_stateless_obj()->get_platform_api()->getPortAttrObj(port_id)->get_promiscuous(); - result["result"]["attr"]["link"]["up"] = get_stateless_obj()->get_platform_api()->getPortAttrObj(port_id)->is_link_up(); - int mode; - int ret = get_stateless_obj()->get_platform_api()->getPortAttrObj(port_id)->get_flow_ctrl(mode); - if (ret != 0) { - mode = -1; - } - result["result"]["attr"]["fc"]["mode"] = mode; + get_stateless_obj()->get_platform_api()->getPortAttrObj(port_id)->to_json(result["result"]["attr"]); + + /* RX info */ + port->get_rx_features().to_json(result["result"]["rx_info"]); return (TREX_RPC_CMD_OK); } @@ -640,3 +709,149 @@ TrexRpcCmdPushRemote::_run(const Json::Value ¶ms, Json::Value &result) { } +/** + * set on/off RX software receive mode + * + */ +trex_rpc_cmd_rc_e +TrexRpcCmdSetRxFeature::_run(const Json::Value ¶ms, Json::Value &result) { + + uint8_t port_id = parse_port(params, result); + TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id); + + /* decide which feature is being set */ + const std::string type = parse_choice(params, "type", {"capture", "queue", "server"}, result); + + if (type == "capture") { + parse_capture_msg(params, port, result); + } else if (type == "queue") { + parse_queue_msg(params, port, result); + } else if (type == "server") { + parse_server_msg(params, port, result); + } else { + assert(0); + } + + result["result"] = Json::objectValue; + return (TREX_RPC_CMD_OK); + +} + +void +TrexRpcCmdSetRxFeature::parse_capture_msg(const Json::Value &msg, TrexStatelessPort *port, Json::Value &result) { + + bool enabled = parse_bool(msg, "enabled", result); + + if (enabled) { + + std::string pcap_filename = parse_string(msg, "pcap_filename", result); + uint64_t limit = parse_uint32(msg, "limit", result); + + if (limit == 0) { + generate_parse_err(result, "limit cannot be zero"); + } + + try { + port->start_rx_capture(pcap_filename, limit); + } catch (const TrexException &ex) { + generate_execute_err(result, ex.what()); + } + + } else { + + try { + port->stop_rx_capture(); + } catch (const TrexException &ex) { + generate_execute_err(result, ex.what()); + } + + } + +} + +void +TrexRpcCmdSetRxFeature::parse_queue_msg(const Json::Value &msg, TrexStatelessPort *port, Json::Value &result) { + bool enabled = parse_bool(msg, "enabled", result); + + if (enabled) { + + uint64_t size = parse_uint32(msg, "size", result); + + if (size == 0) { + generate_parse_err(result, "queue size cannot be zero"); + } + + try { + port->start_rx_queue(size); + } catch (const TrexException &ex) { + generate_execute_err(result, ex.what()); + } + + } else { + + try { + port->stop_rx_queue(); + } catch (const TrexException &ex) { + generate_execute_err(result, ex.what()); + } + + } + +} + +void +TrexRpcCmdSetRxFeature::parse_server_msg(const Json::Value &msg, TrexStatelessPort *port, Json::Value &result) { +} + + +trex_rpc_cmd_rc_e +TrexRpcCmdGetRxQueuePkts::_run(const Json::Value ¶ms, Json::Value &result) { + + uint8_t port_id = parse_port(params, result); + + TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id); + + try { + const RxPacketBuffer *pkt_buffer = port->get_rx_queue_pkts(); + if (pkt_buffer) { + result["result"]["pkts"] = pkt_buffer->to_json(); + } else { + result["result"]["pkts"] = Json::arrayValue; + } + + } catch (const TrexException &ex) { + generate_execute_err(result, ex.what()); + } + + + return (TREX_RPC_CMD_OK); +} + +trex_rpc_cmd_rc_e +TrexRpcCmdSetARPRes::_run(const Json::Value ¶ms, Json::Value &result) { + uint8_t port_id = parse_port(params, result); + + TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id); + + const std::string ipv4_str = parse_string(params, "ipv4", result); + const std::string mac_str = parse_string(params, "mac", result); + + uint32_t ipv4_addr; + if (!utl_ipv4_to_uint32(ipv4_str.c_str(), ipv4_addr)) { + std::stringstream ss; + ss << "invalid IPv4 address: '" << ipv4_str << "'"; + generate_parse_err(result, ss.str()); + } + + uint8_t mac[6]; + if (!utl_str_to_macaddr(mac_str, mac)) { + std::stringstream ss; + ss << "'invalid MAC address: '" << mac_str << "'"; + generate_parse_err(result, ss.str()); + } + + port->getPortAttrObj()->get_dest().set_dest_ipv4(ipv4_addr, mac); + + return (TREX_RPC_CMD_OK); + +} |