summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorimarom <imarom@cisco.com>2016-11-09 18:19:09 +0200
committerimarom <imarom@cisco.com>2016-11-09 18:19:09 +0200
commitab28fccc187c6134eeb0400ce0b113a77e498bb2 (patch)
tree8ac54ad7a53992fb25e48d14eee274a2fdab3f37
parentd09b123992f990a6c219dd47707cc703fe9055b5 (diff)
RX features - added port attributes for IPv4 and DG
Signed-off-by: imarom <imarom@cisco.com>
-rwxr-xr-xscripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py94
-rw-r--r--scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py23
-rw-r--r--scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py10
-rw-r--r--scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/common.py7
-rwxr-xr-xscripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py8
-rwxr-xr-xsrc/common/basic_utils.cpp31
-rwxr-xr-xsrc/common/basic_utils.h5
-rw-r--r--src/main_dpdk.cpp26
-rw-r--r--src/rpc-server/commands/trex_rpc_cmd_general.cpp49
-rw-r--r--src/rpc-server/commands/trex_rpc_cmds.h2
-rwxr-xr-xsrc/trex_port_attr.h71
11 files changed, 240 insertions, 86 deletions
diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py
index b607ce23..d4d09cd7 100755
--- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py
+++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py
@@ -12,7 +12,7 @@ from .trex_stl_types import *
from .trex_stl_async_client import CTRexAsyncClient
from .utils import parsing_opts, text_tables, common
-from .utils.common import list_intersect, list_difference, is_sub_list, PassiveTimer
+from .utils.common import list_intersect, list_difference, is_sub_list, PassiveTimer, is_valid_ipv4
from .utils.text_opts import *
from functools import wraps
@@ -336,7 +336,7 @@ class EventsHandler(object):
new_info = self.client.ports[port_id].get_formatted_info(sync = False)
ev = "port {0} attributes changed".format(port_id)
for key, old_val in old_info.items():
- new_val = new_info[key]
+ new_val = new_info.get(key, 'N/A')
if old_val != new_val:
ev += '\n {key}: {old} -> {new}'.format(
key = key,
@@ -811,8 +811,8 @@ class STLClient(object):
port_id_list = self.__ports(port_id_list)
rc = RC()
- for port_id in port_id_list:
- rc.add(self.ports[port_id].set_attr(attr_dict))
+ for port_id, port_attr_dict in zip(port_id_list, attr_dict):
+ rc.add(self.ports[port_id].set_attr(port_attr_dict))
return rc
@@ -1775,6 +1775,9 @@ class STLClient(object):
self.reset(ports = [0, 1])
+ self.set_port_attr(ports = [0, 1], ipv4 = ['5.5.5.5', '6.6.6.6'])
+ return
+
self.set_rx_queue(ports = [0], size = 1000, rxf = 'all')
#base_pkt = Ether()/ARP()/('x'*50)
@@ -1914,7 +1917,7 @@ class STLClient(object):
@__api_check(True)
- def reset(self, ports = None):
+ def reset(self, ports = None, restart = False):
"""
Force acquire ports, stop the traffic, remove all streams and clear stats
@@ -1922,7 +1925,9 @@ class STLClient(object):
ports : list
Ports on which to execute the command
-
+ restart: bool
+ Restart the NICs (link down / up)
+
:raises:
+ :exc:`STLError`
@@ -1939,7 +1944,7 @@ class STLClient(object):
self.clear_stats(ports)
self.set_port_attr(ports,
promiscuous = False,
- #link_up = True,
+ link_up = True if restart else None,
rxf = 'hw')
self.remove_rx_sniffer(ports)
self.remove_rx_queue(ports)
@@ -2720,16 +2725,23 @@ class STLClient(object):
link_up = None,
led_on = None,
flow_ctrl = None,
- rxf = None):
+ rxf = None,
+ ipv4 = None,
+ default_gateway = None,
+ ):
"""
Set port attributes
:parameters:
- promiscuous - True or False
- link_up - True or False
- led_on - True or False
- flow_ctrl - 0: disable all, 1: enable tx side, 2: enable rx side, 3: full enable
- rxf - 'hw' for hardware rules matching packets only or 'all' all packets
+ promiscuous - True or False
+ link_up - True or False
+ led_on - True or False
+ flow_ctrl - 0: disable all, 1: enable tx side, 2: enable rx side, 3: full enable
+ rxf - 'hw' for hardware rules matching packets only or 'all' all packets
+ ipv4 - configure IPv4 address for port(s). for multiple ports should be a list
+ of IPv4 addresses in the same length of the ports array
+ default_gateway - configure default gateway for port(s). for multiple ports should be a list
+ in the same length of the ports array
:raises:
+ :exe:'STLError'
@@ -2744,22 +2756,55 @@ class STLClient(object):
validate_type('led_on', led_on, (bool, type(None)))
validate_type('flow_ctrl', flow_ctrl, (int, type(None)))
validate_choice('rxf', rxf, ['hw', 'all'])
-
- # build attributes
- attr_dict = {}
+
+ # common attributes for all ports
+ cmn_attr_dict = {}
if promiscuous is not None:
- attr_dict['promiscuous'] = {'enabled': promiscuous}
+ cmn_attr_dict['promiscuous'] = {'enabled': promiscuous}
+
if link_up is not None:
- attr_dict['link_status'] = {'up': link_up}
+ cmn_attr_dict['link_status'] = {'up': link_up}
+
if led_on is not None:
- attr_dict['led_status'] = {'on': led_on}
+ cmn_attr_dict['led_status'] = {'on': led_on}
+
if flow_ctrl is not None:
- attr_dict['flow_ctrl_mode'] = {'mode': flow_ctrl}
+ cmn_attr_dict['flow_ctrl_mode'] = {'mode': flow_ctrl}
+
if rxf is not None:
- attr_dict['rx_filter_mode'] = {'mode': rxf}
+ cmn_attr_dict['rx_filter_mode'] = {'mode': rxf}
+ # each port starts with a set of the common attributes
+ attr_dict = [dict(cmn_attr_dict) for _ in ports]
+
+ # IPv4
+ if ipv4 is not None:
+ ipv4_list = listify(ipv4)
+
+ if len(ipv4_list) != len(ports):
+ raise STLError("'ipv4' must be a list in the same length of ports - 'ports': {0}, 'ip': {1}".format(ports, ipv4_list))
+
+ for ipv4, port_attr in zip(ipv4_list, attr_dict):
+ if not is_valid_ipv4(ipv4):
+ raise STLError("invalid IPv4 address provided: '{0}'".format(ipv4))
+ port_attr['ipv4'] = {'addr': ipv4}
+
+
+ # default gateway
+ if default_gateway is not None:
+ dg_list = listfy(default_gateway)
+
+ if len(dg_list) != len(ports):
+ raise STLError("'default_gateway' must be a list in the same length of ports - 'ports': {0}, 'default_gateway': {1}".format(ports, dg_list))
+
+ for dg, port_attr in zip(dg_list, attr_dict):
+ if not is_valid_ipv4(dg):
+ raise STLError("invalid IPv4 address provided: '{0}'".format(ipv4))
+ port_attr['default_gateway'] = {'addr': dg}
+
+
# no attributes to set
- if not attr_dict:
+ if not any(attr_dict):
return
self.logger.pre_cmd("Applying attributes on port(s) {0}:".format(ports))
@@ -3076,13 +3121,14 @@ class STLClient(object):
parser = parsing_opts.gen_parser(self,
"reset",
self.reset_line.__doc__,
- parsing_opts.PORT_LIST_WITH_ALL)
+ parsing_opts.PORT_LIST_WITH_ALL,
+ parsing_opts.PORT_RESTART)
opts = parser.parse_args(line.split(), default_ports = self.get_acquired_ports(), verify_acquired = True)
if not opts:
return opts
- self.reset(ports = opts.ports)
+ self.reset(ports = opts.ports, restart = opts.restart)
return RC_OK()
diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py
index 96c5e832..418ee5a6 100644
--- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py
+++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py
@@ -785,10 +785,15 @@ class Port(object):
else:
info['rx_filter_mode'] = 'N/A'
+
+ info['mac_addr'] = attr.get('mac_addr', 'N/A')
+ info['ipv4'] = attr.get('ipv4', 'N/A')
+ info['default_gateway'] = attr.get('default_gateway', 'N/A')
+ info['next_hop_mac'] = attr.get('next_hop_mac', 'N/A')
+
# RX info
rx_info = self.status['rx_info']
-
# RX sniffer
if 'sniffer' in rx_info:
sniffer = rx_info['sniffer']
@@ -819,16 +824,18 @@ class Port(object):
info = self.get_formatted_info()
- return {"driver": info['driver'],
- "description": info.get('description', 'N/A')[:18],
- "HW src mac": info['hw_macaddr'],
- "SW src mac": info['src_macaddr'],
- "SW dst mac": info['dst_macaddr'],
- "PCI Address": info['pci_addr'],
- "NUMA Node": info['numa'],
+ return {"driver": info['driver'],
+ "description": info.get('description', 'N/A')[:18],
+ "MAC addr": info['mac_addr'],
+ "Next hop MAC": info['next_hop_mac'],
+ "IPv4": info['ipv4'],
+ "Default gateway": info['default_gateway'],
+ "PCI Address": info['pci_addr'],
+ "NUMA Node": info['numa'],
"--": "",
"---": "",
"----": "",
+ "-----": "",
"link speed": info['speed'],
"port status": info['status'],
"link status": info['link'],
diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py
index 5e71b7f2..55620689 100644
--- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py
+++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py
@@ -670,13 +670,15 @@ class CTRexInfoGenerator(object):
("promiscuous", []),
("flow ctrl", []),
("--", []),
- ("HW src mac", []),
- ("SW src mac", []),
- ("SW dst mac", []),
+ ("MAC addr", []),
+ ("Next hop MAC", []),
("---", []),
+ ("IPv4", []),
+ ("Default gateway", []),
+ ("----", []),
("PCI Address", []),
("NUMA Node", []),
- ("----", []),
+ ("-----", []),
("RX Filter Mode", []),
("RX Queueing", []),
("RX sniffer", []),
diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/common.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/common.py
index 72ee8972..f0da9a08 100644
--- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/common.py
+++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/common.py
@@ -3,6 +3,7 @@ import sys
import string
import random
import time
+import socket
try:
import pwd
@@ -86,3 +87,9 @@ class PassiveTimer(object):
return (time.time() > self.expr_sec)
+def is_valid_ipv4 (addr):
+ try:
+ socket.inet_pton(socket.AF_INET, addr)
+ return True
+ except socket.error:
+ return False
diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py
index 715a741e..b93a797d 100755
--- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py
+++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py
@@ -45,9 +45,11 @@ FLOW_CTRL = 28
SUPPORTED = 29
RX_FILTER_MODE = 30
+
OUTPUT_FILENAME = 31
ALL_FILES = 32
LIMIT = 33
+PORT_RESTART = 34
GLOBAL_STATS = 50
PORT_STATS = 51
@@ -322,6 +324,12 @@ OPTIONS_DB = {MULTIPLIER: ArgumentPack(['-m', '--multiplier'],
'type': str}),
+ PORT_RESTART: ArgumentPack(['-r', '--restart'],
+ {'help': 'hard restart port(s)',
+ 'dest': 'restart',
+ 'default': False,
+ 'action': 'store_true'}),
+
ALL_FILES: ArgumentPack(['--all'],
{'help': 'change RX port filter to fetch all packets',
diff --git a/src/common/basic_utils.cpp b/src/common/basic_utils.cpp
index f169c29f..52988131 100755
--- a/src/common/basic_utils.cpp
+++ b/src/common/basic_utils.cpp
@@ -20,6 +20,10 @@ limitations under the License.
#include <sstream>
#include <sys/resource.h>
+#include "pal_utl.h"
+
+int my_inet_pton4(const char *src, unsigned char *dst);
+
bool utl_is_file_exists (const std::string& name) {
if (FILE *file = fopen(name.c_str(), "r")) {
fclose(file);
@@ -190,6 +194,13 @@ void utl_macaddr_to_str(const uint8_t *macaddr, std::string &output) {
}
+std::string utl_macaddr_to_str(const uint8_t *macaddr) {
+ std::string tmp;
+ utl_macaddr_to_str(macaddr, tmp);
+
+ return tmp;
+}
+
/**
* generate a random connection handler
*
@@ -248,3 +259,23 @@ void utl_set_coredump_size(long size, bool map_huge_pages) {
fprintf(fp, "%08x\n", mask);
fclose(fp);
}
+
+uint32_t utl_ipv4_to_uint32(const char *ipv4_str, uint32_t &ipv4_num) {
+
+ uint32_t tmp;
+
+ int rc = my_inet_pton4(ipv4_str, (unsigned char *)&tmp);
+ if (!rc) {
+ return (0);
+ }
+
+ ipv4_num = PAL_NTOHL(tmp);
+
+ return (1);
+}
+
+std::string utl_uint32_to_ipv4(uint32_t ipv4_addr) {
+ std::stringstream ss;
+ ss << ((ipv4_addr >> 24) & 0xff) << "." << ((ipv4_addr >> 16) & 0xff) << "." << ((ipv4_addr >> 8) & 0xff) << "." << (ipv4_addr & 0xff);
+ return ss.str();
+}
diff --git a/src/common/basic_utils.h b/src/common/basic_utils.h
index f6250a2b..fdbd2f08 100755
--- a/src/common/basic_utils.h
+++ b/src/common/basic_utils.h
@@ -86,6 +86,8 @@ bool utl_is_file_exists (const std::string& name) ;
void utl_macaddr_to_str(const uint8_t *macaddr, std::string &output);
+std::string utl_macaddr_to_str(const uint8_t *macaddr);
+
std::string utl_generate_random_str(unsigned int &seed, int len);
/**
@@ -98,6 +100,9 @@ std::string utl_generate_random_str(unsigned int &seed, int len);
*/
void utl_set_coredump_size(long size, bool map_huge_pages = false);
+uint32_t utl_ipv4_to_uint32(const char *ipv4_str, uint32_t &ipv4_num);
+std::string utl_uint32_to_ipv4(uint32_t ipv4_addr);
+
#endif
diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp
index fcee6a58..406b9c20 100644
--- a/src/main_dpdk.cpp
+++ b/src/main_dpdk.cpp
@@ -308,7 +308,7 @@ public:
| TrexPlatformApi::IF_STAT_PAYLOAD;
}
virtual CFlowStatParser *get_flow_stat_parser();
- virtual int set_rcv_all(CPhyEthIF * _if, bool set_on) {return 0;}
+ virtual int set_rcv_all(CPhyEthIF * _if, bool set_on) {return -ENOTSUP;}
};
class CTRexExtendedDriverBase40G : public CTRexExtendedDriverBase10G {
@@ -1507,6 +1507,7 @@ int DpdkTRexPortAttr::set_led(bool on){
int DpdkTRexPortAttr::get_flow_ctrl(int &mode) {
int ret = rte_eth_dev_flow_ctrl_get(m_port_id, &fc_conf_tmp);
if (ret) {
+ mode = -1;
return ret;
}
mode = (int) fc_conf_tmp.mode;
@@ -3100,6 +3101,8 @@ void CGlobalTRex::pre_test() {
exit(1);
}
memcpy(CGlobalInfo::m_options.m_mac_addr[port_id].u.m_mac.dest, mac, ETHER_ADDR_LEN);
+ m_ports[port_id].get_port_attr()->set_next_hop_mac(mac);
+
// if port is connected in loopback, no need to send gratuitous ARP. It will only confuse our ingress counters.
if (pretest.is_loopback(port_id))
CGlobalInfo::m_options.m_ip_cfg[port_id].set_grat_arp_needed(false);
@@ -4170,20 +4173,9 @@ CGlobalTRex:: publish_async_port_attr_changed(uint8_t port_id) {
Json::Value data;
data["port_id"] = port_id;
TRexPortAttr * _attr = m_ports[port_id].get_port_attr();
-
- /* attributes */
- data["attr"]["speed"] = _attr->get_link_speed();
- data["attr"]["promiscuous"]["enabled"] = _attr->get_promiscuous();
- data["attr"]["link"]["up"] = _attr->is_link_up();
- data["attr"]["rx_filter_mode"] = _attr->get_rx_filter_mode();
-
- int mode;
- int ret = _attr->get_flow_ctrl(mode);
- if (ret != 0) {
- mode = -1;
- }
- data["attr"]["fc"]["mode"] = mode;
-
+
+ _attr->to_json(data["attr"]);
+
m_zmq_publisher.publish_event(TrexPublisher::EVENT_PORT_ATTR_CHANGED, data);
}
@@ -4687,6 +4679,10 @@ bool CPhyEthIF::Create(uint8_t portid) {
m_last_tx_pps = 0.0;
m_port_attr = g_trex.m_drv->create_port_attr(portid);
+
+ m_port_attr->set_ipv4(CGlobalInfo::m_options.m_ip_cfg[m_port_id].get_ip());
+ m_port_attr->set_default_gateway(CGlobalInfo::m_options.m_ip_cfg[m_port_id].get_def_gw());
+
return true;
}
diff --git a/src/rpc-server/commands/trex_rpc_cmd_general.cpp b/src/rpc-server/commands/trex_rpc_cmd_general.cpp
index b63c2faa..5ee853b8 100644
--- a/src/rpc-server/commands/trex_rpc_cmd_general.cpp
+++ b/src/rpc-server/commands/trex_rpc_cmd_general.cpp
@@ -292,9 +292,6 @@ TrexRpcCmdGetSysInfo::_run(const Json::Value &params, Json::Value &result) {
for (int i = 0; i < main->get_port_count(); i++) {
string driver;
- string hw_macaddr;
- string src_macaddr;
- string dst_macaddr;
string pci_addr;
string description;
supp_speeds_t supp_speeds;
@@ -303,7 +300,6 @@ TrexRpcCmdGetSysInfo::_run(const Json::Value &params, Json::Value &result) {
TrexStatelessPort *port = main->get_port_by_id(i);
port->get_properties(driver);
- port->get_macaddr(hw_macaddr, src_macaddr, dst_macaddr);
port->get_pci_info(pci_addr, numa);
main->get_platform_api()->getPortAttrObj(i)->get_description(description);
@@ -313,9 +309,6 @@ TrexRpcCmdGetSysInfo::_run(const Json::Value &params, 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;
@@ -363,6 +356,23 @@ TrexRpcCmdSetPortAttr::parse_rx_filter_mode(const Json::Value &msg, uint8_t port
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_ipv4(ipv4_addr);
+ return (0);
+}
+
+
/**
* set port commands
*
@@ -408,15 +418,20 @@ TrexRpcCmdSetPortAttr::_run(const Json::Value &params, Json::Value &result) {
ret = parse_rx_filter_mode(attr[name], port_id, result);
}
+ else if (name == "ipv4") {
+ ret = parse_ipv4(attr[name], port_id, result);
+ }
+
+ /* unknown attribute */
else {
generate_execute_err(result, "Not recognized attribute: " + name);
break;
}
+ /* check error code */
if ( ret == -ENOTSUP ) {
generate_execute_err(result, "Error applying " + name + ": operation is not supported for this NIC.");
- }
- else if (ret) {
+ } else if (ret) {
generate_execute_err(result, "Error applying " + name + " attribute, return value: " + to_string(ret));
}
}
@@ -592,20 +607,8 @@ TrexRpcCmdGetPortStatus::_run(const Json::Value &params, Json::Value &result) {
result["result"]["max_stream_id"] = port->get_max_stream_id();
/* 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();
- result["result"]["attr"]["speed"] = get_stateless_obj()->get_platform_api()->getPortAttrObj(port_id)->get_link_speed();
-
- 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;
-
- /* RX filter */
- result["result"]["attr"]["rx_filter_mode"] = get_stateless_obj()->get_platform_api()->getPortAttrObj(port_id)->get_rx_filter_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"]);
diff --git a/src/rpc-server/commands/trex_rpc_cmds.h b/src/rpc-server/commands/trex_rpc_cmds.h
index b8a5d323..49610eb8 100644
--- a/src/rpc-server/commands/trex_rpc_cmds.h
+++ b/src/rpc-server/commands/trex_rpc_cmds.h
@@ -96,7 +96,7 @@ TREX_RPC_CMD_DEFINE(TrexRpcCmdGetPortXStatsNames, "get_port_xstats_names", 1,
TREX_RPC_CMD_DEFINE_EXTENDED(TrexRpcCmdSetPortAttr, "set_port_attr", 2, true, APIClass::API_CLASS_TYPE_CORE,
int parse_rx_filter_mode(const Json::Value &msg, uint8_t port_id, Json::Value &result);
-
+ int parse_ipv4(const Json::Value &msg, uint8_t port_id, Json::Value &result);
);
diff --git a/src/trex_port_attr.h b/src/trex_port_attr.h
index 5ba4f7e2..ccf12ae2 100755
--- a/src/trex_port_attr.h
+++ b/src/trex_port_attr.h
@@ -21,10 +21,17 @@ limitations under the License.
#include <vector>
#include "rte_ethdev_includes.h"
#include "trex_defs.h"
-
+#include "common/basic_utils.h"
class TRexPortAttr {
public:
+
+ TRexPortAttr() {
+ m_ipv4 = 0;
+ m_default_gateway = 0;
+ memset(m_next_hop_mac, 0, sizeof(m_next_hop_mac));
+ }
+
virtual ~TRexPortAttr(){}
/* UPDATES */
@@ -50,7 +57,10 @@ public:
virtual bool is_link_change_supported() { return flag_is_link_change_supported; }
virtual void get_description(std::string &description) { description = intf_info_st.description; }
virtual void get_supported_speeds(supp_speeds_t &supp_speeds) = 0;
-
+ uint32_t get_ipv4() {return m_ipv4;}
+ uint32_t get_default_gateway() {return m_default_gateway;}
+ const uint8_t * get_next_hop_mac() {return m_next_hop_mac;}
+
virtual std::string get_rx_filter_mode() {
switch (m_rx_filter_mode) {
case RX_FILTER_MODE_ALL:
@@ -70,21 +80,60 @@ public:
virtual int set_flow_ctrl(int mode) = 0;
virtual int set_led(bool on) = 0;
virtual int set_rx_filter_mode(rx_filter_mode_e mode) = 0;
-
+
+ void set_ipv4(uint32_t addr) {
+ m_ipv4 = addr;
+ }
+
+ void set_default_gateway(uint32_t addr) {
+ m_default_gateway = addr;
+ }
+
+ void set_next_hop_mac(const uint8_t *next_hop_mac) {
+ memcpy(m_next_hop_mac, next_hop_mac, sizeof(m_next_hop_mac));
+ }
+
/* DUMPS */
virtual void dump_link(FILE *fd) = 0;
+ /* dump object status to JSON */
+ void to_json(Json::Value &output) {
+ struct ether_addr dpdk_mac_addr;
+ macaddr_get(&dpdk_mac_addr);
+
+ uint8_t mac_addr[6];
+ memcpy(mac_addr, dpdk_mac_addr.addr_bytes, 6);
+
+ output["mac_addr"] = utl_macaddr_to_str(mac_addr);
+ output["next_hop_mac"] = utl_macaddr_to_str(m_next_hop_mac);
+ output["promiscuous"]["enabled"] = get_promiscuous();
+ output["link"]["up"] = is_link_up();
+ output["speed"] = get_link_speed();
+ output["rx_filter_mode"] = get_rx_filter_mode();
+ output["ipv4"] = utl_uint32_to_ipv4(get_ipv4());
+ output["default_gateway"] = utl_uint32_to_ipv4(get_default_gateway());
+
+ int mode;
+ get_flow_ctrl(mode);
+ output["fc"]["mode"] = mode;
+
+ }
+
protected:
- uint8_t m_port_id;
- rte_eth_link m_link;
- struct rte_eth_dev_info dev_info;
-
+
+ uint8_t m_port_id;
+ rte_eth_link m_link;
+ uint32_t m_ipv4;
+ uint32_t m_default_gateway;
+ uint8_t m_next_hop_mac[6];
+ struct rte_eth_dev_info dev_info;
+
rx_filter_mode_e m_rx_filter_mode;
- bool flag_is_virtual;
- bool flag_is_fc_change_supported;
- bool flag_is_led_change_supported;
- bool flag_is_link_change_supported;
+ bool flag_is_virtual;
+ bool flag_is_fc_change_supported;
+ bool flag_is_led_change_supported;
+ bool flag_is_link_change_supported;
struct intf_info_st {