summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorimarom <imarom@cisco.com>2016-11-03 16:33:52 +0200
committerimarom <imarom@cisco.com>2016-11-03 16:33:52 +0200
commit234779fd32e747f4ac918f3c39e59618dde0f2d7 (patch)
tree2ba641354b6d6c751f94de44f9453dcbec0e19aa
parent0ed685e077e8533ffe6d96f5d1fefcdd42626763 (diff)
moved RX filter feature to port attr
Signed-off-by: imarom <imarom@cisco.com>
-rwxr-xr-xscripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py42
-rw-r--r--scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py43
-rw-r--r--scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py2
-rw-r--r--scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_types.py6
-rwxr-xr-xscripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py7
-rwxr-xr-xscripts/trex_show_threads.py4
-rw-r--r--src/flow_stat.cpp4
-rw-r--r--src/internal_api/trex_platform_api.h5
-rw-r--r--src/main_dpdk.cpp25
-rw-r--r--src/rpc-server/commands/trex_rpc_cmd_general.cpp105
-rw-r--r--src/rpc-server/commands/trex_rpc_cmds.h15
-rw-r--r--src/stateless/cp/trex_stateless_port.cpp26
-rw-r--r--src/stateless/cp/trex_stateless_port.h24
-rw-r--r--src/stateless/messaging/trex_stateless_messaging.cpp19
-rw-r--r--src/stateless/messaging/trex_stateless_messaging.h27
-rw-r--r--src/stateless/rx/trex_stateless_rx_core.cpp61
-rw-r--r--src/stateless/rx/trex_stateless_rx_core.h45
-rw-r--r--src/stateless/rx/trex_stateless_rx_port_mngr.cpp4
-rw-r--r--src/stateless/rx/trex_stateless_rx_port_mngr.h55
-rwxr-xr-xsrc/trex_port_attr.h24
20 files changed, 368 insertions, 175 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 2e3f681c..907e405a 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
@@ -322,12 +322,16 @@ class EventsHandler(object):
# port attr changed
elif (event_type == 8):
+
port_id = int(data['port_id'])
+
if data['attr'] == self.client.ports[port_id].attr:
return # false alarm
- old_info = self.client.ports[port_id].get_info()
+
+ old_info = self.client.ports[port_id].get_formatted_info()
self.__async_event_port_attr_changed(port_id, data['attr'])
- new_info = self.client.ports[port_id].get_info()
+
+ new_info = self.client.ports[port_id].get_formatted_info()
ev = "port {0} attributes changed".format(port_id)
for key, old_val in old_info.items():
new_val = new_info[key]
@@ -1739,10 +1743,6 @@ class STLClient(object):
"""
- rc = self.ports[0].set_rx_filter_mode("all")
- if not rc:
- raise STLError(rc)
-
self.logger.pre_cmd("Pinging the server on '{0}' port '{1}': ".format(self.connection_info['server'],
self.connection_info['sync_port']))
rc = self._transmit("ping", api_class = None)
@@ -2630,7 +2630,13 @@ class STLClient(object):
@__api_check(True)
- def set_port_attr (self, ports = None, promiscuous = None, link_up = None, led_on = None, flow_ctrl = None):
+ def set_port_attr (self,
+ ports = None,
+ promiscuous = None,
+ link_up = None,
+ led_on = None,
+ flow_ctrl = None,
+ rx_filter_mode = None):
"""
Set port attributes
@@ -2639,7 +2645,7 @@ class STLClient(object):
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
-
+ rx_filter_mode - 'hw' for hardware rules matching packets only or 'all' all packets
:raises:
+ :exe:'STLError'
@@ -2653,6 +2659,7 @@ class STLClient(object):
validate_type('link_up', link_up, (bool, type(None)))
validate_type('led_on', led_on, (bool, type(None)))
validate_type('flow_ctrl', flow_ctrl, (int, type(None)))
+ validate_choice('rx_filter_mode', rx_filter_mode, ['hw', 'all'])
# build attributes
attr_dict = {}
@@ -2664,7 +2671,9 @@ class STLClient(object):
attr_dict['led_status'] = {'on': led_on}
if flow_ctrl is not None:
attr_dict['flow_ctrl_mode'] = {'mode': flow_ctrl}
-
+ if rx_filter_mode is not None:
+ attr_dict['rx_filter_mode'] = {'mode': rx_filter_mode}
+
# no attributes to set
if not attr_dict:
return
@@ -3234,7 +3243,7 @@ class STLClient(object):
'''Sets port attributes '''
parser = parsing_opts.gen_parser(self,
- "port_attr",
+ "portattr",
self.set_port_attr_line.__doc__,
parsing_opts.PORT_LIST_WITH_ALL,
parsing_opts.PROMISCUOUS,
@@ -3242,19 +3251,20 @@ class STLClient(object):
parsing_opts.LED_STATUS,
parsing_opts.FLOW_CTRL,
parsing_opts.SUPPORTED,
+ parsing_opts.RX_FILTER_MODE,
)
opts = parser.parse_args(line.split(), default_ports = self.get_acquired_ports(), verify_acquired = True)
if not opts:
return opts
- opts.prom = parsing_opts.ON_OFF_DICT.get(opts.prom)
- opts.link = parsing_opts.UP_DOWN_DICT.get(opts.link)
- opts.led = parsing_opts.ON_OFF_DICT.get(opts.led)
- opts.flow_ctrl = parsing_opts.FLOW_CTRL_DICT.get(opts.flow_ctrl)
+ opts.prom = parsing_opts.ON_OFF_DICT.get(opts.prom)
+ opts.link = parsing_opts.UP_DOWN_DICT.get(opts.link)
+ opts.led = parsing_opts.ON_OFF_DICT.get(opts.led)
+ opts.flow_ctrl = parsing_opts.FLOW_CTRL_DICT.get(opts.flow_ctrl)
# if no attributes - fall back to printing the status
- if not filter(lambda x:x is not None, [opts.prom, opts.link, opts.led, opts.flow_ctrl, opts.supp]):
+ if not list(filter(lambda x:x is not None, [opts.prom, opts.link, opts.led, opts.flow_ctrl, opts.supp, opts.rx_filter_mode])):
self.show_stats_line("--ps --port {0}".format(' '.join(str(port) for port in opts.ports)))
return
@@ -3268,7 +3278,7 @@ class STLClient(object):
print(' Flow control: %s' % info['fc_supported'])
print('')
else:
- return self.set_port_attr(opts.ports, opts.prom, opts.link, opts.led, opts.flow_ctrl)
+ return self.set_port_attr(opts.ports, opts.prom, opts.link, opts.led, opts.flow_ctrl, opts.rx_filter_mode)
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 bf0251b8..59793495 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
@@ -128,10 +128,10 @@ class Port(object):
return RC_OK(data)
def get_speed_bps (self):
- return (self.info['speed'] * 1000 * 1000 * 1000)
+ return (self.attr['speed'] * 1000 * 1000 * 1000)
def get_formatted_speed (self):
- return "{0} Gbps".format(self.info['speed'])
+ return "%g Gb/s" % (self.attr['speed'] / 1000)
def is_acquired(self):
return (self.handler != None)
@@ -252,9 +252,6 @@ class Port(object):
# attributes
self.attr = rc.data()['attr']
- if 'speed' in rc.data():
- self.info['speed'] = rc.data()['speed'] // 1000
-
return self.ok()
@@ -487,14 +484,19 @@ class Port(object):
return self.ok()
+ #
@writeable
- def set_rx_filter_mode (self, filter_mode):
- assert(filter_mode in ["hw", "all"])
+ def start_rx_capture (self, pcap_filename, limit):
+
+ prefix, suffix = pcap_filename.split('.')
+ filename = "{0}-{1}.{2}".format(prefix, self.port_id, suffix)
- params = {"handler": self.handler,
- "port_id": self.port_id,
- "type": "filter_mode",
- "filter_type": filter_mode}
+ params = {"handler": self.handler,
+ "port_id": self.port_id,
+ "type": "capture",
+ "enabled": True,
+ "pcap_filename": filename,
+ "limit": limit}
rc = self.transmit("set_rx_feature", params)
if rc.bad():
@@ -675,8 +677,8 @@ class Port(object):
format_time(exp_time_factor_sec)))
print("\n")
- # generate port info
- def get_info (self):
+ # generate formatted (console friendly) port info
+ def get_formatted_info (self):
info = dict(self.info)
info['status'] = self.get_port_state_name()
@@ -719,6 +721,13 @@ class Port(object):
else:
info['is_virtual'] = 'N/A'
+ if 'speed' in self.attr:
+ info['speed'] = self.get_formatted_speed()
+ else:
+ info['speed'] = 'N/A'
+
+ info['rx_filter_mode'] = self.attr.get('rx_filter_mode', 'N/A')
+
return info
@@ -731,7 +740,7 @@ class Port(object):
def generate_port_status(self):
- info = self.get_info()
+ info = self.get_formatted_info()
return {"driver": info['driver'],
"description": info.get('description', 'N/A')[:18],
@@ -742,11 +751,14 @@ class Port(object):
"NUMA Node": info['numa'],
"--": "",
"---": "",
- "link speed": "{speed} Gb/s".format(speed=info['speed']),
+ "----": "",
+ "link speed": info['speed'],
"port status": info['status'],
"link status": info['link'],
"promiscuous" : info['prom'],
"flow ctrl" : info['fc'],
+
+ "RX Filter Mode": info['rx_filter_mode'],
}
def clear_stats(self):
@@ -792,7 +804,6 @@ class Port(object):
self.last_factor_type = None
def async_event_port_attr_changed (self, attr):
- self.info['speed'] = attr['speed'] // 1000
self.attr = attr
# rest of the events are used for TUI / read only sessions
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 9f601484..7e47eb61 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
@@ -676,6 +676,8 @@ class CTRexInfoGenerator(object):
("---", []),
("PCI Address", []),
("NUMA Node", []),
+ ("----", []),
+ ("RX Filter Mode", []),
]
)
diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_types.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_types.py
index aa6c4218..81015ddc 100644
--- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_types.py
+++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_types.py
@@ -135,6 +135,12 @@ def validate_type(arg_name, arg, valid_types):
else:
raise STLError('validate_type: valid_types should be type or list or tuple of types')
+
+def validate_choice (arg_name, arg, choices):
+ if arg is not None and not arg in choices:
+ raise STLError("validate_choice: argument '{0}' can only be one of '{1}'".format(arg_name, choices))
+
+
# throws STLError if not exactly one argument is present
def verify_exclusive_arg (args_list):
if not (len(list(filter(lambda x: x is not None, args_list))) == 1):
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 7eda8635..0d316c9e 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
@@ -43,6 +43,7 @@ CORE_MASK = 26
DUAL = 27
FLOW_CTRL = 28
SUPPORTED = 29
+RX_FILTER_MODE = 30
GLOBAL_STATS = 50
PORT_STATS = 51
@@ -303,6 +304,12 @@ OPTIONS_DB = {MULTIPLIER: ArgumentPack(['-m', '--multiplier'],
'dest': 'flow_ctrl',
'choices': FLOW_CTRL_DICT}),
+ RX_FILTER_MODE: ArgumentPack(['--rxf'],
+ {'help': 'Set RX filtering mode',
+ 'dest': 'rx_filter_mode',
+ 'choices': ['hw', 'all']}),
+
+
SUPPORTED: ArgumentPack(['--supp'],
{'help': 'Show which attributes are supported by current NICs',
'default': None,
diff --git a/scripts/trex_show_threads.py b/scripts/trex_show_threads.py
index fabe6d68..1824d073 100755
--- a/scripts/trex_show_threads.py
+++ b/scripts/trex_show_threads.py
@@ -58,8 +58,8 @@ def isnum (x):
def find_trex_pid ():
procs = [x for x in os.listdir('/proc/') if isnum(x)]
for proc in procs:
- cmd = open('/proc/{0}/{1}'.format(proc, 'cmdline')).readline()
- if '_t-rex' in cmd:
+ cmd = open('/proc/{0}/{1}'.format(proc, 'comm')).readline()
+ if cmd.startswith('_t-rex-64'):
return proc
return None
diff --git a/src/flow_stat.cpp b/src/flow_stat.cpp
index 84be590f..dae29795 100644
--- a/src/flow_stat.cpp
+++ b/src/flow_stat.cpp
@@ -968,9 +968,9 @@ void CFlowStatRuleMgr::send_start_stop_msg_to_rx(bool is_start) {
TrexStatelessCpToRxMsgBase *msg;
if (is_start) {
- msg = new TrexStatelessRxStartMsg();
+ msg = new TrexStatelessRxEnableLatency();
} else {
- msg = new TrexStatelessRxStopMsg();
+ msg = new TrexStatelessRxDisableLatency();
}
m_ring_to_rx->Enqueue((CGenNode *)msg);
}
diff --git a/src/internal_api/trex_platform_api.h b/src/internal_api/trex_platform_api.h
index 4feb386f..1445d3e9 100644
--- a/src/internal_api/trex_platform_api.h
+++ b/src/internal_api/trex_platform_api.h
@@ -161,8 +161,6 @@ public:
virtual int get_xstats_values(uint8_t port_id, xstats_values_t &xstats_values) const = 0;
virtual int get_xstats_names(uint8_t port_id, xstats_names_t &xstats_names) const = 0;
- virtual void set_rx_filter_mode(uint8_t port_id, rx_filter_mode_e filter_mode) const = 0;
-
virtual ~TrexPlatformApi() {}
};
@@ -200,7 +198,6 @@ public:
int get_mbuf_util(Json::Value &result) const;
void mark_for_shutdown() const;
CFlowStatParser *get_flow_stat_parser() const;
- void set_rx_filter_mode(uint8_t port_id, rx_filter_mode_e filter_mode) const;
TRexPortAttr *getPortAttrObj(uint8_t port_id) const;
int get_xstats_values(uint8_t port_id, xstats_values_t &xstats_values) const;
@@ -281,8 +278,6 @@ public:
int get_xstats_values(uint8_t port_id, xstats_values_t &xstats_values) const {return 0;};
int get_xstats_names(uint8_t port_id, xstats_names_t &xstats_names) const {return 0;};
- void set_rx_filter_mode(uint8_t port_id, rx_filter_mode_e filter_mode) const {}
-
private:
int m_dp_core_count;
SimTRexPortAttr * m_port_attr;
diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp
index ecf09b46..fcee6a58 100644
--- a/src/main_dpdk.cpp
+++ b/src/main_dpdk.cpp
@@ -4175,6 +4175,8 @@ CGlobalTRex:: publish_async_port_attr_changed(uint8_t port_id) {
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) {
@@ -6595,6 +6597,21 @@ TRexPortAttr *TrexDpdkPlatformApi::getPortAttrObj(uint8_t port_id) const {
return g_trex.m_ports[port_id].get_port_attr();
}
+
+int DpdkTRexPortAttr::set_rx_filter_mode(rx_filter_mode_e rx_filter_mode) {
+
+ CPhyEthIF *_if = &g_trex.m_ports[m_port_id];
+ bool recv_all = (rx_filter_mode == RX_FILTER_MODE_ALL);
+ int rc = CTRexExtendedDriverDb::Ins()->get_drv()->set_rcv_all(_if, recv_all);
+ if (rc != 0) {
+ return (rc);
+ }
+
+ m_rx_filter_mode = rx_filter_mode;
+
+ return (0);
+}
+
/**
* marks the control plane for a total server shutdown
*
@@ -6605,12 +6622,4 @@ void TrexDpdkPlatformApi::mark_for_shutdown() const {
}
-void TrexDpdkPlatformApi::set_rx_filter_mode(uint8_t port_id, rx_filter_mode_e filter_mode) const {
-
- CPhyEthIF *_if = &g_trex.m_ports[port_id];
-
- bool recv_all = (filter_mode == RX_FILTER_MODE_ALL);
- CTRexExtendedDriverDb::Ins()->get_drv()->set_rcv_all(_if, recv_all);
-}
-
diff --git a/src/rpc-server/commands/trex_rpc_cmd_general.cpp b/src/rpc-server/commands/trex_rpc_cmd_general.cpp
index 8599b61b..7baae899 100644
--- a/src/rpc-server/commands/trex_rpc_cmd_general.cpp
+++ b/src/rpc-server/commands/trex_rpc_cmd_general.cpp
@@ -291,7 +291,6 @@ TrexRpcCmdGetSysInfo::_run(const Json::Value &params, 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;
@@ -302,7 +301,8 @@ TrexRpcCmdGetSysInfo::_run(const Json::Value &params, Json::Value &result) {
int numa;
TrexStatelessPort *port = main->get_port_by_id(i);
- port->get_properties(driver, speed);
+
+ port->get_properties(driver);
port->get_macaddr(hw_macaddr, src_macaddr, dst_macaddr);
port->get_pci_info(pci_addr, numa);
@@ -317,8 +317,8 @@ TrexRpcCmdGetSysInfo::_run(const Json::Value &params, Json::Value &result) {
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;
@@ -332,7 +332,6 @@ TrexRpcCmdGetSysInfo::_run(const Json::Value &params, 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();
@@ -347,6 +346,23 @@ TrexRpcCmdGetSysInfo::_run(const Json::Value &params, 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);
+}
+
/**
* set port commands
*
@@ -365,26 +381,39 @@ TrexRpcCmdSetPortAttr::_run(const Json::Value &params, Json::Value &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 {
+ }
+
+ else if (name == "rx_filter_mode") {
+ ret = parse_rx_filter_mode(attr[name], port_id, result);
+ }
+
+ 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.");
@@ -570,11 +599,12 @@ TrexRpcCmdGetPortStatus::_run(const Json::Value &params, 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();
+ 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) {
@@ -582,6 +612,9 @@ TrexRpcCmdGetPortStatus::_run(const Json::Value &params, Json::Value &result) {
}
result["result"]["attr"]["fc"]["mode"] = mode;
+ /* RX data */
+ result["result"]["attr"]["rx_filter_mode"] = get_stateless_obj()->get_platform_api()->getPortAttrObj(port_id)->get_rx_filter_mode();
+
return (TREX_RPC_CMD_OK);
}
@@ -650,15 +683,13 @@ trex_rpc_cmd_rc_e
TrexRpcCmdSetRxFeature::_run(const Json::Value &params, Json::Value &result) {
uint8_t port_id = parse_port(params, result);
- TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id);
+ 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", {"filter_mode", "record", "queue", "server"}, result);
+ const std::string type = parse_choice(params, "type", {"capture", "queue", "server"}, result);
- if (type == "filter_mode") {
- parse_filter_mode_msg(params, port, result);
- } else if (type == "record") {
- parse_record_msg(params, port, result);
+ if (type == "capture") {
+ parse_capture_msg(params, port, result);
} else if (type == "queue") {
parse_queue_msg(params, port, result);
} else if (type == "server") {
@@ -667,33 +698,39 @@ TrexRpcCmdSetRxFeature::_run(const Json::Value &params, Json::Value &result) {
assert(0);
}
- result["result"] = Json::objectValue;
+ result["result"] = Json::objectValue;
return (TREX_RPC_CMD_OK);
}
void
-TrexRpcCmdSetRxFeature::parse_filter_mode_msg(const Json::Value &msg, TrexStatelessPort *port, Json::Value &result) {
- const std::string type = parse_choice(msg, "filter_type", {"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);
- }
-
- try {
- port->set_rx_filter_mode(filter_mode);
- } catch (const TrexException &ex) {
- generate_execute_err(result, ex.what());
+TrexRpcCmdSetRxFeature::parse_capture_msg(const Json::Value &msg, TrexStatelessPort *port, Json::Value &result) {
+ std::string pcap_filename = parse_string(msg, "pcap_filename", result);
+ bool enabled = parse_bool(msg, "enabled", result);
+
+ if (enabled) {
+
+ 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_record_msg(const Json::Value &msg, TrexStatelessPort *port, Json::Value &result) {
}
void
diff --git a/src/rpc-server/commands/trex_rpc_cmds.h b/src/rpc-server/commands/trex_rpc_cmds.h
index 8d4aeb0c..26de717f 100644
--- a/src/rpc-server/commands/trex_rpc_cmds.h
+++ b/src/rpc-server/commands/trex_rpc_cmds.h
@@ -90,10 +90,16 @@ TREX_RPC_CMD_DEFINE(TrexRpcCmdRelease, "release", 1, true, APIClass:
*/
TREX_RPC_CMD_DEFINE(TrexRpcCmdGetPortStats, "get_port_stats", 1, false, APIClass::API_CLASS_TYPE_CORE);
TREX_RPC_CMD_DEFINE(TrexRpcCmdGetPortStatus, "get_port_status", 1, false, APIClass::API_CLASS_TYPE_CORE);
-TREX_RPC_CMD_DEFINE(TrexRpcCmdSetPortAttr, "set_port_attr", 2, true, APIClass::API_CLASS_TYPE_CORE);
TREX_RPC_CMD_DEFINE(TrexRpcCmdGetPortXStatsValues, "get_port_xstats_values", 1, false, APIClass::API_CLASS_TYPE_CORE);
TREX_RPC_CMD_DEFINE(TrexRpcCmdGetPortXStatsNames, "get_port_xstats_names", 1, false, APIClass::API_CLASS_TYPE_CORE);
+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);
+
+);
+
+
/**
* stream cmds
*/
@@ -146,10 +152,9 @@ TREX_RPC_CMD_DEFINE(TrexRpcCmdPushRemote, "push_remote", 6, true, APIClass::API_
TREX_RPC_CMD_DEFINE(TrexRpcCmdShutdown, "shutdown", 2, false, APIClass::API_CLASS_TYPE_CORE);
TREX_RPC_CMD_DEFINE_EXTENDED(TrexRpcCmdSetRxFeature, "set_rx_feature", 3, false, APIClass::API_CLASS_TYPE_CORE,
- void parse_filter_mode_msg(const Json::Value &msg, TrexStatelessPort *port, Json::Value &result);
- void parse_record_msg(const Json::Value &msg, TrexStatelessPort *port, Json::Value &result);
- void parse_queue_msg(const Json::Value &msg, TrexStatelessPort *port, Json::Value &result);
- void parse_server_msg(const Json::Value &msg, TrexStatelessPort *port, Json::Value &result);
+ void parse_capture_msg(const Json::Value &msg, TrexStatelessPort *port, Json::Value &result);
+ void parse_queue_msg(const Json::Value &msg, TrexStatelessPort *port, Json::Value &result);
+ void parse_server_msg(const Json::Value &msg, TrexStatelessPort *port, Json::Value &result);
);
diff --git a/src/stateless/cp/trex_stateless_port.cpp b/src/stateless/cp/trex_stateless_port.cpp
index 5d31abbf..c0156c12 100644
--- a/src/stateless/cp/trex_stateless_port.cpp
+++ b/src/stateless/cp/trex_stateless_port.cpp
@@ -157,9 +157,9 @@ private:
TrexStatelessPort::TrexStatelessPort(uint8_t port_id, const TrexPlatformApi *api) : m_dp_events(this) {
std::vector<std::pair<uint8_t, uint8_t>> core_pair_list;
- m_port_id = port_id;
- m_port_state = PORT_STATE_IDLE;
- m_platform_api = api;
+ m_port_id = port_id;
+ m_port_state = PORT_STATE_IDLE;
+ m_platform_api = api;
/* get the platform specific data */
api->get_interface_info(port_id, m_api_info);
@@ -585,10 +585,9 @@ TrexStatelessPort::get_max_stream_id() const {
}
void
-TrexStatelessPort::get_properties(std::string &driver, uint32_t &speed) {
+TrexStatelessPort::get_properties(std::string &driver) {
driver = m_api_info.driver_name;
- speed = m_platform_api->getPortAttrObj(m_port_id)->get_link_speed();
}
bool
@@ -945,16 +944,15 @@ TrexStatelessPort::remove_and_delete_all_streams() {
}
}
-/**
- * set the filter type for a port
- *
- * @author imarom (10/31/2016)
- *
- * @param rx_sw_cfg
- */
+void
+TrexStatelessPort::start_rx_capture(const std::string &pcap_filename, uint64_t limit) {
+ TrexStatelessCpToRxMsgBase *msg = new TrexStatelessRxStartCapture(m_port_id, pcap_filename, limit);
+ send_message_to_rx(msg);
+}
+
void
-TrexStatelessPort::set_rx_filter_mode(rx_filter_mode_e filter_mode) {
- TrexStatelessCpToRxMsgBase *msg = new TrexStatelessRxSetFilterMode(m_port_id, filter_mode);
+TrexStatelessPort::stop_rx_capture() {
+ TrexStatelessCpToRxMsgBase *msg = new TrexStatelessRxStopCapture(m_port_id);
send_message_to_rx(msg);
}
diff --git a/src/stateless/cp/trex_stateless_port.h b/src/stateless/cp/trex_stateless_port.h
index 41453caa..5a1935a1 100644
--- a/src/stateless/cp/trex_stateless_port.h
+++ b/src/stateless/cp/trex_stateless_port.h
@@ -257,11 +257,8 @@ public:
* @author imarom (16-Sep-15)
*
* @param driver
- * @param speed
*/
- void get_properties(std::string &driver, uint32_t &speed);
-
-
+ void get_properties(std::string &driver);
/**
* encode stats as JSON
@@ -371,11 +368,18 @@ public:
void get_pci_info(std::string &pci_addr, int &numa_node);
+
+ /**
+ * enable RX capture on port
+ *
+ */
+ void start_rx_capture(const std::string &pcap_filename, uint64_t limit);
+
/**
- * set RX filter mode
- * can be hardware or software
+ * disable RX capture if on
+ *
*/
- void set_rx_filter_mode(rx_filter_mode_e);
+ void stop_rx_capture();
/**
* fetch the RX software packets from the queue
@@ -515,9 +519,9 @@ public:
static const std::initializer_list<std::string> g_types;
static const std::initializer_list<std::string> g_ops;
- mul_type_e m_type;
- mul_op_e m_op;
- double m_value;
+ mul_type_e m_type;
+ mul_op_e m_op;
+ double m_value;
};
#endif /* __TREX_STATELESS_PORT_H__ */
diff --git a/src/stateless/messaging/trex_stateless_messaging.cpp b/src/stateless/messaging/trex_stateless_messaging.cpp
index 10b4355b..6e7bfee5 100644
--- a/src/stateless/messaging/trex_stateless_messaging.cpp
+++ b/src/stateless/messaging/trex_stateless_messaging.cpp
@@ -241,13 +241,13 @@ TrexDpPortEventMsg::handle() {
}
/************************* messages from CP to RX **********************/
-bool TrexStatelessRxStartMsg::handle (CRxCoreStateless *rx_core) {
- rx_core->work();
+bool TrexStatelessRxEnableLatency::handle (CRxCoreStateless *rx_core) {
+ rx_core->enable_latency();
return true;
}
-bool TrexStatelessRxStopMsg::handle (CRxCoreStateless *rx_core) {
- rx_core->idle();
+bool TrexStatelessRxDisableLatency::handle (CRxCoreStateless *rx_core) {
+ rx_core->disable_latency();
return true;
}
@@ -263,8 +263,15 @@ TrexStatelessRxSwGetPkts::TrexStatelessRxSwGetPkts(uint8_t port_id, TrexStateles
bool
-TrexStatelessRxSetFilterMode::handle(CRxCoreStateless *rx_core) {
- rx_core->set_rx_filter_mode(m_port_id, m_filter_mode);
+TrexStatelessRxStartCapture::handle(CRxCoreStateless *rx_core) {
+ rx_core->start_capture(m_port_id, m_pcap_filename, m_limit);
+
+ return true;
+}
+
+bool
+TrexStatelessRxStopCapture::handle(CRxCoreStateless *rx_core) {
+ rx_core->stop_capture(m_port_id);
return true;
}
diff --git a/src/stateless/messaging/trex_stateless_messaging.h b/src/stateless/messaging/trex_stateless_messaging.h
index 42a422b0..e96e83d6 100644
--- a/src/stateless/messaging/trex_stateless_messaging.h
+++ b/src/stateless/messaging/trex_stateless_messaging.h
@@ -408,11 +408,11 @@ public:
};
-class TrexStatelessRxStartMsg : public TrexStatelessCpToRxMsgBase {
+class TrexStatelessRxEnableLatency : public TrexStatelessCpToRxMsgBase {
bool handle (CRxCoreStateless *rx_core);
};
-class TrexStatelessRxStopMsg : public TrexStatelessCpToRxMsgBase {
+class TrexStatelessRxDisableLatency : public TrexStatelessCpToRxMsgBase {
bool handle (CRxCoreStateless *rx_core);
};
@@ -421,17 +421,32 @@ class TrexStatelessRxQuit : public TrexStatelessCpToRxMsgBase {
};
-class TrexStatelessRxSetFilterMode : public TrexStatelessCpToRxMsgBase {
+class TrexStatelessRxStartCapture : public TrexStatelessCpToRxMsgBase {
public:
- TrexStatelessRxSetFilterMode(uint8_t port_id, rx_filter_mode_e filter_mode) {
+ TrexStatelessRxStartCapture(uint8_t port_id, const std::string &pcap_filename, uint64_t limit) : m_pcap_filename(pcap_filename) {
m_port_id = port_id;
- m_filter_mode = filter_mode;
+ m_limit = limit;
}
+
+ virtual bool handle(CRxCoreStateless *rx_core);
+
+private:
+ uint8_t m_port_id;
+ std::string m_pcap_filename;
+ uint64_t m_limit;
+};
+
+
+class TrexStatelessRxStopCapture : public TrexStatelessCpToRxMsgBase {
+public:
+ TrexStatelessRxStopCapture(uint8_t port_id) {
+ m_port_id = port_id;
+ }
+
virtual bool handle(CRxCoreStateless *rx_core);
private:
uint8_t m_port_id;
- rx_filter_mode_e m_filter_mode;
};
diff --git a/src/stateless/rx/trex_stateless_rx_core.cpp b/src/stateless/rx/trex_stateless_rx_core.cpp
index ca39b8a0..ee9c64c4 100644
--- a/src/stateless/rx/trex_stateless_rx_core.cpp
+++ b/src/stateless/rx/trex_stateless_rx_core.cpp
@@ -121,10 +121,29 @@ bool CRxCoreStateless::periodic_check_for_cp_messages() {
handle_cp_msg(msg);
}
+ recalculate_next_state();
return true;
}
+void CRxCoreStateless::recalculate_next_state() {
+ if (m_state == STATE_QUIT) {
+ return;
+ }
+
+ /* next state is determine by the question are there any ports with active features ? */
+ m_state = (are_any_features_active() ? STATE_WORKING : STATE_IDLE);
+}
+
+bool CRxCoreStateless::are_any_features_active() {
+ for (int i = 0; i < m_max_ports; i++) {
+ if (m_rx_port_mngr[i].has_features_set()) {
+ return true;
+ }
+ }
+
+ return false;
+}
void CRxCoreStateless::idle_state_loop() {
const int SHORT_DELAY_MS = 2;
@@ -260,12 +279,12 @@ void CRxCoreStateless::try_rx_queues() {
int CRxCoreStateless::process_all_pending_pkts(bool flush_rx) {
- int total_pkts = 0;
- for (int i = 0; i < m_max_ports; i++) {
- total_pkts += m_rx_port_mngr[i].process_all_pending_pkts(flush_rx);
- }
+ int total_pkts = 0;
+ for (int i = 0; i < m_max_ports; i++) {
+ total_pkts += m_rx_port_mngr[i].process_all_pending_pkts(flush_rx);
+ }
- return total_pkts;
+ return total_pkts;
}
@@ -336,17 +355,27 @@ double CRxCoreStateless::get_cpu_util() {
}
-/**
- * configure RX filtering mode (HW or software)
- *
- * @author imarom (11/1/2016)
- *
- * @param port_id
- * @param filter_mode
- */
void
-CRxCoreStateless::set_rx_filter_mode(uint8_t port_id, rx_filter_mode_e filter_mode) {
- const TrexPlatformApi *api = get_stateless_obj()->get_platform_api();
- api->set_rx_filter_mode(port_id, filter_mode);
+CRxCoreStateless::start_capture(uint8_t port_id, const std::string &pcap_filename, uint64_t limit) {
+ m_rx_port_mngr[port_id].start_capture(pcap_filename, limit);
+}
+
+void
+CRxCoreStateless::stop_capture(uint8_t port_id) {
+ m_rx_port_mngr[port_id].stop_capture();
+}
+
+void
+CRxCoreStateless::enable_latency() {
+ for (int i = 0; i < m_max_ports; i++) {
+ m_rx_port_mngr[i].enable_latency();
+ }
+}
+
+void
+CRxCoreStateless::disable_latency() {
+ for (int i = 0; i < m_max_ports; i++) {
+ m_rx_port_mngr[i].disable_latency();
+ }
}
diff --git a/src/stateless/rx/trex_stateless_rx_core.h b/src/stateless/rx/trex_stateless_rx_core.h
index 2a59862b..425c15ae 100644
--- a/src/stateless/rx/trex_stateless_rx_core.h
+++ b/src/stateless/rx/trex_stateless_rx_core.h
@@ -103,11 +103,8 @@ class CRxCoreStateless {
, TrexPlatformApi::driver_stat_cap_e type);
int get_rfc2544_info(rfc2544_info_t *rfc2544_info, int min, int max, bool reset);
int get_rx_err_cntrs(CRxCoreErrCntrs *rx_err);
- void work() {
- m_state = STATE_WORKING;
- m_err_cntrs.reset(); // When starting to work, reset global counters
- }
- void idle() {m_state = STATE_IDLE;}
+
+
void quit() {m_state = STATE_QUIT;}
bool is_working() const {return (m_ack_start_work_msg == true);}
void set_working_msg_ack(bool val);
@@ -119,19 +116,33 @@ class CRxCoreStateless {
}
/**
- * sets the port filter mode
+ * start capturing of RX packets on a specific port
*
- * @author imarom (10/31/2016)
+ * @author imarom (11/2/2016)
*
- * @param filter_mode
+ * @param port_id
+ * @param pcap_filename
+ * @param limit
+ */
+ void start_capture(uint8_t port_id, const std::string &pcap_filename, uint64_t limit);
+ void stop_capture(uint8_t port_id);
+
+ /**
+ * enable latency feature for RX packets
+ * will be apply to all ports
*/
- void set_rx_filter_mode(uint8_t port_id, rx_filter_mode_e filter_mode);
+ void enable_latency();
+ void disable_latency();
private:
void handle_cp_msg(TrexStatelessCpToRxMsgBase *msg);
bool periodic_check_for_cp_messages();
void tickle();
void idle_state_loop();
+
+ void recalculate_next_state();
+ bool are_any_features_active();
+
void capture_pkt(rte_mbuf_t *m);
void handle_rx_queue_msgs(uint8_t thread_id, CNodeRing * r);
void handle_work_stage(bool do_try_rx_queue);
@@ -145,14 +156,14 @@ class CRxCoreStateless {
void try_rx_queues();
private:
- TrexMonitor m_monitor;
- uint32_t m_max_ports;
- bool m_capture;
- state_e m_state;
- CNodeRing *m_ring_from_cp;
- CNodeRing *m_ring_to_cp;
- CCpuUtlDp m_cpu_dp_u;
- CCpuUtlCp m_cpu_cp_u;
+ TrexMonitor m_monitor;
+ uint32_t m_max_ports;
+ bool m_capture;
+ state_e m_state;
+ CNodeRing *m_ring_from_cp;
+ CNodeRing *m_ring_to_cp;
+ CCpuUtlDp m_cpu_dp_u;
+ CCpuUtlCp m_cpu_cp_u;
// Used for acking "work" (go out of idle) messages from cp
volatile bool m_ack_start_work_msg __rte_cache_aligned;
diff --git a/src/stateless/rx/trex_stateless_rx_port_mngr.cpp b/src/stateless/rx/trex_stateless_rx_port_mngr.cpp
index 5b10eebf..35d331cf 100644
--- a/src/stateless/rx/trex_stateless_rx_port_mngr.cpp
+++ b/src/stateless/rx/trex_stateless_rx_port_mngr.cpp
@@ -148,7 +148,7 @@ RXPacketRecorder::~RXPacketRecorder() {
}
void
-RXPacketRecorder::start(const std::string &pcap, uint32_t limit) {
+RXPacketRecorder::start(const std::string &pcap, uint64_t limit) {
m_writer = CCapWriterFactory::CreateWriter(LIBPCAP, (char *)pcap.c_str());
if (m_writer == NULL) {
std::stringstream ss;
@@ -206,7 +206,7 @@ void RXPortManager::handle_pkt(const rte_mbuf_t *m) {
m_latency.handle_pkt(m);
}
- if (is_feature_set(RECORD)) {
+ if (is_feature_set(CAPTURE)) {
m_recorder.handle_pkt(m);
}
diff --git a/src/stateless/rx/trex_stateless_rx_port_mngr.h b/src/stateless/rx/trex_stateless_rx_port_mngr.h
index d197c423..7cc527d8 100644
--- a/src/stateless/rx/trex_stateless_rx_port_mngr.h
+++ b/src/stateless/rx/trex_stateless_rx_port_mngr.h
@@ -212,7 +212,7 @@ class RXPacketRecorder {
public:
RXPacketRecorder();
~RXPacketRecorder();
- void start(const std::string &pcap, uint32_t limit);
+ void start(const std::string &pcap, uint64_t limit);
void stop();
void handle_pkt(const rte_mbuf_t *m);
@@ -235,16 +235,15 @@ class RXPortManager {
public:
enum features_t {
LATENCY = 0x1,
- RECORD = 0x2,
+ CAPTURE = 0x2,
QUEUE = 0x4
};
RXPortManager() {
- m_features = 0;
- m_pkt_buffer = NULL;
- m_io = NULL;
- m_cpu_dp_u = NULL;
- set_feature(LATENCY);
+ m_features = 0;
+ m_pkt_buffer = NULL;
+ m_io = NULL;
+ m_cpu_dp_u = NULL;
}
void create(CPortLatencyHWBase *io,
@@ -264,16 +263,36 @@ public:
return m_latency;
}
- void start_recorder(const std::string &pcap, uint32_t limit_pkts) {
+ void enable_latency() {
+ set_feature(LATENCY);
+ }
+
+ void disable_latency() {
+ unset_feature(LATENCY);
+ }
+
+ /**
+ * capturing of RX packets
+ *
+ * @author imarom (11/2/2016)
+ *
+ * @param pcap
+ * @param limit_pkts
+ */
+ void start_capture(const std::string &pcap, uint64_t limit_pkts) {
m_recorder.start(pcap, limit_pkts);
- set_feature(RECORD);
+ set_feature(CAPTURE);
}
- void stop_recorder() {
+ void stop_capture() {
m_recorder.stop();
- unset_feature(RECORD);
+ unset_feature(CAPTURE);
}
+ /**
+ * queueing packets
+ *
+ */
void start_queue(uint32_t limit) {
if (m_pkt_buffer) {
delete m_pkt_buffer;
@@ -329,6 +348,16 @@ public:
*/
void handle_pkt(const rte_mbuf_t *m);
+
+ bool has_features_set() {
+ return (m_features != 0);
+ }
+
+
+ bool no_features_set() {
+ return (!has_features_set());
+ }
+
private:
@@ -344,10 +373,6 @@ private:
return ( (m_features & feature) == feature );
}
- bool no_features_set() {
- return (m_features == 0);
- }
-
uint32_t m_features;
RXPacketRecorder m_recorder;
RXLatency m_latency;
diff --git a/src/trex_port_attr.h b/src/trex_port_attr.h
index 9231e263..5ba4f7e2 100755
--- a/src/trex_port_attr.h
+++ b/src/trex_port_attr.h
@@ -33,7 +33,7 @@ public:
virtual void update_device_info() = 0;
virtual void reset_xstats() = 0;
virtual void update_description() = 0;
-
+
/* GETTERS */
virtual bool get_promiscuous() = 0;
virtual void macaddr_get(struct ether_addr *mac_addr) = 0;
@@ -51,12 +51,25 @@ public:
virtual void get_description(std::string &description) { description = intf_info_st.description; }
virtual void get_supported_speeds(supp_speeds_t &supp_speeds) = 0;
+ virtual std::string get_rx_filter_mode() {
+ switch (m_rx_filter_mode) {
+ case RX_FILTER_MODE_ALL:
+ return "all";
+ case RX_FILTER_MODE_HW:
+ return "hw";
+ default:
+ assert(0);
+ }
+ }
+
+
/* SETTERS */
virtual int set_promiscuous(bool enabled) = 0;
virtual int add_mac(char * mac) = 0;
virtual int set_link_up(bool up) = 0;
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;
/* DUMPS */
virtual void dump_link(FILE *fd) = 0;
@@ -65,10 +78,14 @@ protected:
uint8_t m_port_id;
rte_eth_link m_link;
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;
+
struct intf_info_st {
std::string pci_addr;
@@ -82,7 +99,10 @@ class DpdkTRexPortAttr : public TRexPortAttr {
public:
DpdkTRexPortAttr(uint8_t port_id, bool is_virtual, bool fc_change_allowed) {
+
m_port_id = port_id;
+ m_rx_filter_mode = RX_FILTER_MODE_HW;
+
flag_is_virtual = is_virtual;
int tmp;
flag_is_fc_change_supported = fc_change_allowed && (get_flow_ctrl(tmp) != -ENOTSUP);
@@ -114,6 +134,7 @@ public:
virtual int set_flow_ctrl(int mode);
virtual int set_led(bool on);
+ virtual int set_rx_filter_mode(rx_filter_mode_e mode);
/* DUMPS */
virtual void dump_link(FILE *fd);
@@ -158,6 +179,7 @@ public:
int set_flow_ctrl(int mode) { return -ENOTSUP; }
int set_led(bool on) { return -ENOTSUP; }
void dump_link(FILE *fd) {}
+ int set_rx_filter_mode(rx_filter_mode_e mode) { return -ENOTSUP; }
};