summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorimarom <imarom@cisco.com>2016-12-13 18:15:22 +0200
committerimarom <imarom@cisco.com>2016-12-13 18:15:22 +0200
commit0fdd81a94d62592b0ec9888022d793f670c8476f (patch)
treeec52cd0f090793e26f67bc017d402b737acd71b5
parent0c45815234abbb79b147b8093eb19e274ee65f52 (diff)
Major refactor - L2 / L3 modes for ports
Signed-off-by: imarom <imarom@cisco.com>
-rwxr-xr-xscripts/automation/trex_control_plane/stl/console/trex_console.py28
-rwxr-xr-xscripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py107
-rw-r--r--scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py59
-rw-r--r--scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_rx_features.py3
-rw-r--r--scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py1
-rwxr-xr-xscripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py47
-rwxr-xr-xsrc/bp_sim.h27
-rw-r--r--src/main_dpdk.cpp26
-rw-r--r--src/rpc-server/commands/trex_rpc_cmd_general.cpp128
-rw-r--r--src/rpc-server/commands/trex_rpc_cmds.h5
-rw-r--r--src/rpc-server/trex_rpc_cmds_table.cpp3
-rw-r--r--src/stateful_rx_core.h27
-rw-r--r--src/stateless/cp/trex_stateless_port.cpp59
-rw-r--r--src/stateless/cp/trex_stateless_port.h11
-rw-r--r--src/stateless/messaging/trex_stateless_messaging.cpp13
-rw-r--r--src/stateless/messaging/trex_stateless_messaging.h31
-rw-r--r--src/stateless/rx/trex_stateless_rx_core.cpp27
-rw-r--r--src/stateless/rx/trex_stateless_rx_core.h10
-rw-r--r--src/stateless/rx/trex_stateless_rx_port_mngr.cpp78
-rw-r--r--src/stateless/rx/trex_stateless_rx_port_mngr.h54
-rwxr-xr-xsrc/trex_port_attr.h7
21 files changed, 496 insertions, 255 deletions
diff --git a/scripts/automation/trex_control_plane/stl/console/trex_console.py b/scripts/automation/trex_control_plane/stl/console/trex_console.py
index 1a97ad0c..627761ff 100755
--- a/scripts/automation/trex_control_plane/stl/console/trex_console.py
+++ b/scripts/automation/trex_control_plane/stl/console/trex_console.py
@@ -330,23 +330,21 @@ class TRexConsole(TRexGeneralCmd):
self.do_portattr("-h")
@verify_connected
- def do_source (self, line):
- '''Configure source address for port(s)\n'''
- self.stateless_client.set_source_addr_line(line)
-
- def help_source (self):
- self.do_source("-h")
-
+ def do_l2 (self, line):
+ '''Configures a port in L2 mode'''
+ self.stateless_client.set_l2_mode_line(line)
+ def help_l2 (self):
+ self.do_l2("-h")
+
@verify_connected
- def do_dest (self, line):
- '''Configure destination address for port(s)\n'''
- self.stateless_client.set_dest_addr_line(line)
-
- def help_dest (self):
- self.do_dest("-h")
-
-
+ def do_l3 (self, line):
+ '''Configures a port in L3 mode'''
+ self.stateless_client.set_l3_mode_line(line)
+
+ def help_l3 (self):
+ self.do_l3("-h")
+
@verify_connected
def do_set_rx_sniffer (self, line):
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 80daadd2..ee5db1f0 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
@@ -1843,15 +1843,14 @@ class STLClient(object):
raise STLError(rc)
-
@__api_check(True)
- def set_source_addr (self, port, addr):
+ def set_l2_mode (self, port, dst_mac):
"""
- Configures a port with a source address
+ Sets the port mode to L2
:parameters:
- port - the port to set the source address
- addr - source address. currently only IPv4 is supported
+ port - the port to set the source address
+ dst_mac - destination MAC
:raises:
+ :exc:`STLError`
"""
@@ -1859,33 +1858,27 @@ class STLClient(object):
validate_type('port', port, int)
if port not in self.get_all_ports():
raise STLError("port {0} is not a valid port id".format(port))
-
- if not is_valid_ipv4(addr):
- raise STLError("addr is not a valid IPv4 address: '{0}'".format(addr))
-
- self.logger.pre_cmd("Setting port {0} source address as '{1}': ".format(port, addr))
- rc = self.ports[port].set_source_addr(addr)
- self.logger.post_cmd(rc)
+
+ if not is_valid_mac(dst_mac):
+ raise STLError("dest_mac is not a valid MAC address: '{0}'".format(dst_mac))
+
+ self.logger.pre_cmd("Setting port {0} in L2 mode: ".format(port))
+ rc = self.ports[port].set_l2_mode(dst_mac)
+ self.logger.post_cmd(rc)
if not rc:
raise STLError(rc)
-
- # for MAC dest - no resolve
- if not self.ports[port].get_dst_addr()['ipv4']:
- return rc
- # resolve the address
- return self.resolve(ports = port, verbose = False)
-
@__api_check(True)
- def set_dest_addr (self, port, addr):
+ def set_l3_mode (self, port, src_ipv4, dst_ipv4):
"""
- Configures a port with a destination address
+ Sets the port mode to L3
:parameters:
- port - the port to set the destination address
- addr - destination address. can be either MAC or IPv4
+ port - the port to set the source address
+ src_ipv4 - IPv4 source address for the port
+ dst_ipv4 - IPv4 destination address
:raises:
+ :exc:`STLError`
"""
@@ -1893,24 +1886,29 @@ class STLClient(object):
validate_type('port', port, int)
if port not in self.get_all_ports():
raise STLError("port {0} is not a valid port id".format(port))
-
- if not is_valid_ipv4(addr) and not is_valid_mac(addr):
- raise STLError("addr is not a valid IPv4 address or a MAC address: '{0}'".format(addr))
-
- if is_valid_ipv4(addr) and not self.ports[port].get_src_addr()['ipv4']:
- raise STLError("cannot configure destination as IPv4 address without IPv4 source address")
- self.logger.pre_cmd("Setting port {0} destination address as '{1}': ".format(port, addr))
- rc = self.ports[port].set_dest_addr(addr)
- self.logger.post_cmd(rc)
+ if not is_valid_ipv4(src_ipv4):
+ raise STLError("src_ipv4 is not a valid IPv4 address: '{0}'".format(src_ipv4))
+
+ if not is_valid_ipv4(dst_ipv4):
+ raise STLError("dst_ipv4 is not a valid IPv4 address: '{0}'".format(dst_ipv4))
+
+ self.logger.pre_cmd("Setting port {0} in L3 mode: ".format(port))
+ rc = self.ports[port].set_l3_mode(src_ipv4, dst_ipv4)
+ self.logger.post_cmd(rc)
if not rc:
raise STLError(rc)
-
- # resolve the address
- return self.resolve(ports = port, verbose = False)
-
-
+
+ # try to resolve
+ with self.logger.supress(level = LoggerApi.VERBOSE_REGULAR_SYNC):
+ self.logger.pre_cmd("ARP resolving address '{0}': ".format(dst_ipv4))
+ rc = self.ports[port].arp_resolve(0)
+ self.logger.post_cmd(rc)
+ if not rc:
+ raise STLError(rc)
+
+
@__api_check(True)
def ping_ip (self, src_port, dst_ipv4, pkt_size = 64, count = 5):
"""
@@ -3177,7 +3175,7 @@ class STLClient(object):
parser = parsing_opts.gen_parser(self,
"ping",
self.ping_line.__doc__,
- parsing_opts.SOURCE_PORT,
+ parsing_opts.SINGLE_PORT,
parsing_opts.PING_IPV4,
parsing_opts.PKT_SIZE,
parsing_opts.PING_COUNT)
@@ -3808,41 +3806,46 @@ class STLClient(object):
@__console
- def set_source_addr_line (self, line):
- '''Configures source address for port(s)'''
+ def set_l2_mode_line (self, line):
+ '''Configures a port in L2 mode'''
parser = parsing_opts.gen_parser(self,
- "source",
- self.set_source_addr_line.__doc__,
- parsing_opts.SOURCE_PORT,
- parsing_opts.IPV4)
+ "port",
+ self.set_l2_mode_line.__doc__,
+ parsing_opts.SINGLE_PORT,
+ parsing_opts.DST_MAC,
+ )
opts = parser.parse_args(line.split())
if not opts:
return opts
+
# source ports maps to ports as a single port
- self.set_source_addr(opts.ports[0], opts.ipv4)
+ self.set_l2_mode(opts.ports[0], dst_mac = opts.dst_mac)
return RC_OK()
@__console
- def set_dest_addr_line (self, line):
- '''Configures destination address for port(s)'''
+ def set_l3_mode_line (self, line):
+ '''Configures a port in L3 mode'''
parser = parsing_opts.gen_parser(self,
- "dest",
- self.set_dest_addr_line.__doc__,
- parsing_opts.SOURCE_PORT,
- parsing_opts.DEST)
+ "port",
+ self.set_l3_mode_line.__doc__,
+ parsing_opts.SINGLE_PORT,
+ parsing_opts.SRC_IPV4,
+ parsing_opts.DST_IPV4,
+ )
opts = parser.parse_args(line.split())
if not opts:
return opts
+
# source ports maps to ports as a single port
- self.set_dest_addr(opts.ports[0], opts.dest)
+ self.set_l3_mode(opts.ports[0], src_ipv4 = opts.src_ipv4, dst_ipv4 = opts.dst_ipv4)
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 5ec1f852..e44fe801 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
@@ -519,39 +519,40 @@ class Port(object):
return self.ok()
-
@owned
- def set_source_addr (self, addr):
+ def set_l2_mode (self, dst_mac):
if not self.is_service_mode_on():
- return self.err('port service mode must be enabled for configuring source address. Please enable service mode')
+ return self.err('port service mode must be enabled for configuring L2 mode. Please enable service mode')
- return self.set_attr(ipv4 = addr)
-
+ params = {"handler": self.handler,
+ "port_id": self.port_id,
+ "dst_mac": dst_mac}
- @owned
- def set_dest_addr (self, addr):
- if not self.is_service_mode_on():
- return self.err('port service mode must be enabled for configuring destination address. Please enable service mode')
-
- return self.set_attr(dest = addr)
+ rc = self.transmit("set_l2", params)
+ if rc.bad():
+ return self.err(rc.err())
+
+ return self.sync()
@owned
- def set_arp_resolution (self, ipv4, mac):
-
+ def set_l3_mode (self, src_addr, dest_addr, resolved_mac = None):
+ if not self.is_service_mode_on():
+ return self.err('port service mode must be enabled for configuring L3 mode. Please enable service mode')
+
params = {"handler": self.handler,
"port_id": self.port_id,
- "ipv4": ipv4,
- "mac": mac}
+ "src_addr": src_addr,
+ "dst_addr": dest_addr}
- rc = self.transmit("set_arp_resolution", params)
+ if resolved_mac:
+ params["resolved_mac"] = resolved_mac
+
+ rc = self.transmit("set_l3", params)
if rc.bad():
return self.err(rc.err())
- # instead of updating manualy - let's sync with the server
return self.sync()
-
-
@owned
@@ -700,15 +701,6 @@ class Port(object):
if kwargs.get('rx_filter_mode') is not None:
json_attr['rx_filter_mode'] = {'mode': kwargs.get('rx_filter_mode')}
- if kwargs.get('ipv4') is not None:
- json_attr['ipv4'] = {'addr': kwargs.get('ipv4')}
-
- if kwargs.get('dest') is not None:
- if not self.is_service_mode_on():
- return self.err('setting destination requires port to be in service mode')
-
- json_attr['dest'] = {'addr': kwargs.get('dest')}
-
params = {"handler": self.handler,
"port_id": self.port_id,
@@ -879,7 +871,7 @@ class Port(object):
info['src_ipv4'] = attr['src_ipv4']
if info['src_ipv4'] is None:
- info['src_ipv4'] = 'Not Configured'
+ info['src_ipv4'] = '-'
# dest
dest = attr['dest']
@@ -908,6 +900,14 @@ class Port(object):
queue = rx_info['queue']
info['rx_queue'] = '[{0} / {1}]'.format(queue['count'], queue['size']) if queue['is_active'] else 'off'
+ # Grat ARP
+ grat_arp = rx_info['grat_arp']
+ if grat_arp['is_active']:
+ info['grat_arp'] = grat_arp['interval_sec']
+ else:
+ info['grat_arp'] = "off"
+
+
return info
@@ -991,6 +991,7 @@ class Port(object):
"RX Filter Mode": info['rx_filter_mode'],
"RX Queueing": info['rx_queue'],
"RX sniffer": info['rx_sniffer'],
+ "Grat ARP": info['grat_arp'],
}
diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_rx_features.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_rx_features.py
index e0fc1724..ec83de5d 100644
--- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_rx_features.py
+++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_rx_features.py
@@ -164,7 +164,8 @@ class ARPResolver(Resolver):
return None
- rc = self.port.set_arp_resolution(arp.psrc, arp.hwsrc)
+ # update the port with L3 full configuration
+ rc = self.port.set_l3_mode(self.src['ipv4'], self.dst['ipv4'], arp.hwsrc)
if not rc:
return rc
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 6a59126f..c08a0af8 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
@@ -682,6 +682,7 @@ class CTRexInfoGenerator(object):
("RX Filter Mode", []),
("RX Queueing", []),
("RX sniffer", []),
+ ("Grat ARP", []),
]
)
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 c5f53d68..0a7b510f 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
@@ -49,17 +49,20 @@ OUTPUT_FILENAME = 31
LIMIT = 33
PORT_RESTART = 34
-IPV4 = 35
-DEST = 36
RETRIES = 37
-SOURCE_PORT = 39
+SINGLE_PORT = 38
+DST_MAC = 39
+
PING_IPV4 = 40
PING_COUNT = 41
PKT_SIZE = 42
SERVICE_OFF = 43
+SRC_IPV4 = 44
+DST_IPV4 = 45
+
GLOBAL_STATS = 50
PORT_STATS = 51
PORT_STATUS = 52
@@ -250,9 +253,9 @@ def check_pkt_size (pkt_size):
return pkt_size
-def check_dest_addr (addr):
- if not (is_valid_ipv4(addr) or is_valid_mac(addr)):
- raise argparse.ArgumentTypeError("not a valid IPv4 or MAC address: '{0}'".format(addr))
+def check_mac_addr (addr):
+ if not is_valid_mac(addr):
+ raise argparse.ArgumentTypeError("not a valid MAC address: '{0}'".format(addr))
return addr
@@ -341,18 +344,24 @@ OPTIONS_DB = {MULTIPLIER: ArgumentPack(['-m', '--multiplier'],
'dest': 'flow_ctrl',
'choices': FLOW_CTRL_DICT}),
- IPV4: ArgumentPack(['--ipv4'],
- {'help': 'IPv4 address(s) for the port(s)',
- 'dest': 'ipv4',
- 'required': True,
- 'type': check_ipv4_addr}),
-
- DEST: ArgumentPack(['--addr'],
- {'help': 'Destination address(s) for the port(s) in either IPv4 or MAC format',
- 'metavar': 'addr',
- 'dest': 'dest',
- 'required' : True,
- 'type': check_dest_addr}),
+ SRC_IPV4: ArgumentPack(['--src'],
+ {'help': 'Configure source IPv4 address',
+ 'dest': 'src_ipv4',
+ 'required': True,
+ 'type': check_ipv4_addr}),
+
+ DST_IPV4: ArgumentPack(['--dst'],
+ {'help': 'Configure destination IPv4 address',
+ 'dest': 'dst_ipv4',
+ 'required': True,
+ 'type': check_ipv4_addr}),
+
+
+ DST_MAC: ArgumentPack(['--dst'],
+ {'help': 'Configure destination MAC address',
+ 'dest': 'dst_mac',
+ 'required': True,
+ 'type': check_mac_addr}),
RETRIES: ArgumentPack(['-r', '--retries'],
{'help': 'retries count [default is zero]',
@@ -405,7 +414,7 @@ OPTIONS_DB = {MULTIPLIER: ArgumentPack(['-m', '--multiplier'],
'default': []}),
- SOURCE_PORT: ArgumentPack(['--port', '-p'],
+ SINGLE_PORT: ArgumentPack(['--port', '-p'],
{'dest':'ports',
'type': int,
'metavar': 'PORT',
diff --git a/src/bp_sim.h b/src/bp_sim.h
index 454f5f19..00699cd9 100755
--- a/src/bp_sim.h
+++ b/src/bp_sim.h
@@ -668,6 +668,7 @@ class CPerPortIPCfg {
uint16_t m_vlan;
};
+
class CParserOption {
public:
@@ -4239,6 +4240,32 @@ inline pkt_dir_t CGenNode::cur_interface_dir(){
}
}
+class CRXCoreIgnoreStat {
+ friend class CCPortLatency;
+ friend class CLatencyManager;
+ friend class RXGratARP;
+ public:
+ inline CRXCoreIgnoreStat operator- (const CRXCoreIgnoreStat &t_in) const {
+ CRXCoreIgnoreStat t_out;
+ t_out.m_tx_arp = this->m_tx_arp - t_in.m_tx_arp;
+ t_out.m_tx_ipv6_n_solic = this->m_tx_ipv6_n_solic - t_in.m_tx_ipv6_n_solic;
+ t_out.m_tot_bytes = this->m_tot_bytes - t_in.m_tot_bytes;
+ return t_out;
+ }
+ uint64_t get_tx_bytes() {return m_tot_bytes;}
+ uint64_t get_tx_pkts() {return m_tx_arp + m_tx_ipv6_n_solic;}
+ uint64_t get_tx_arp() {return m_tx_arp;}
+ uint64_t get_tx_n_solic() {return m_tx_ipv6_n_solic;}
+ void clear() {
+ m_tx_arp = 0;
+ m_tx_ipv6_n_solic = 0;
+ m_tot_bytes = 0;
+ }
+ private:
+ uint64_t m_tx_arp;
+ uint64_t m_tx_ipv6_n_solic;
+ uint64_t m_tot_bytes;
+};
#endif
diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp
index 03c41431..e26aaa22 100644
--- a/src/main_dpdk.cpp
+++ b/src/main_dpdk.cpp
@@ -3092,6 +3092,8 @@ public:
void dump_config(FILE *fd);
void dump_links_status(FILE *fd);
+ bool lookup_port_by_mac(const uint8_t *mac, uint8_t &port_id);
+
public:
port_cfg_t m_port_cfg;
uint32_t m_max_ports; /* active number of ports supported options are 2,4,8,10,12 */
@@ -3910,6 +3912,16 @@ void CGlobalTRex::dump_links_status(FILE *fd){
}
}
+bool CGlobalTRex::lookup_port_by_mac(const uint8_t *mac, uint8_t &port_id) {
+ for (int i = 0; i < m_max_ports; i++) {
+ if (memcmp(m_ports[i].get_port_attr()->get_src_mac(), mac, 6) == 0) {
+ port_id = i;
+ return true;
+ }
+ }
+
+ return false;
+}
void CGlobalTRex::dump_post_test_stats(FILE *fd){
uint64_t pkt_out=0;
@@ -4848,7 +4860,13 @@ static CGlobalTRex g_trex;
void CPhyEthIF::update_counters() {
get_ex_drv()->get_extended_stats(this, &m_stats);
CRXCoreIgnoreStat ign_stats;
- g_trex.m_mg.get_ignore_stats(m_port_id, ign_stats, true);
+
+ if (get_is_stateless()) {
+ g_trex.m_rx_sl.get_ignore_stats(m_port_id, ign_stats, true);
+ } else {
+ g_trex.m_mg.get_ignore_stats(m_port_id, ign_stats, true);
+ }
+
m_stats.obytes -= ign_stats.get_tx_bytes();
m_stats.opackets -= ign_stats.get_tx_pkts();
m_ignore_stats.opackets += ign_stats.get_tx_pkts();
@@ -7256,6 +7274,11 @@ int DpdkTRexPortAttr::set_rx_filter_mode(rx_filter_mode_e rx_filter_mode) {
return (0);
}
+bool DpdkTRexPortAttr::is_loopback() const {
+ uint8_t port_id;
+ return g_trex.lookup_port_by_mac(m_dest.get_dest_mac(), port_id);
+}
+
/**
* marks the control plane for a total server shutdown
*
@@ -7264,3 +7287,4 @@ int DpdkTRexPortAttr::set_rx_filter_mode(rx_filter_mode_e rx_filter_mode) {
void TrexDpdkPlatformApi::mark_for_shutdown() const {
g_trex.mark_for_shutdown(CGlobalTRex::SHUTDOWN_RPC_REQ);
}
+
diff --git a/src/rpc-server/commands/trex_rpc_cmd_general.cpp b/src/rpc-server/commands/trex_rpc_cmd_general.cpp
index 5c397fcd..c8b4841a 100644
--- a/src/rpc-server/commands/trex_rpc_cmd_general.cpp
+++ b/src/rpc-server/commands/trex_rpc_cmd_general.cpp
@@ -357,53 +357,6 @@ 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());
- }
-
- TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id);
- port->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_addr);
-
- } else if (utl_str_to_macaddr(addr, mac)) {
- port_attr->get_dest().set_dest(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
*
@@ -451,16 +404,6 @@ TrexRpcCmdSetPortAttr::_run(const Json::Value &params, Json::Value &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 + "'");
@@ -836,31 +779,78 @@ TrexRpcCmdGetRxQueuePkts::_run(const Json::Value &params, Json::Value &result) {
return (TREX_RPC_CMD_OK);
}
+
+/**
+ * configures a port in L2 mode
+ *
+ */
trex_rpc_cmd_rc_e
-TrexRpcCmdSetARPRes::_run(const Json::Value &params, Json::Value &result) {
+TrexRpcCmdSetL2::_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);
- const std::string ipv4_str = parse_string(params, "ipv4", result);
- const std::string mac_str = parse_string(params, "mac", result);
+ const std::string dst_mac_str = parse_string(params, "dst_mac", result);
+
+ uint8_t dst_mac[6];
+ if (!utl_str_to_macaddr(dst_mac_str, dst_mac)) {
+ std::stringstream ss;
+ ss << "'invalid MAC address: '" << dst_mac_str << "'";
+ generate_parse_err(result, ss.str());
+ }
+
+ port->set_l2_mode(dst_mac);
+
+ return (TREX_RPC_CMD_OK);
+}
+
+/**
+ * configures a port in L3 mode
+ *
+ */
+trex_rpc_cmd_rc_e
+TrexRpcCmdSetL3::_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);
+
+ const std::string src_ipv4_str = parse_string(params, "src_addr", result);
+ const std::string dst_ipv4_str = parse_string(params, "dst_addr", result);
- uint32_t ipv4_addr;
- if (!utl_ipv4_to_uint32(ipv4_str.c_str(), ipv4_addr)) {
+ uint32_t src_ipv4;
+ if (!utl_ipv4_to_uint32(src_ipv4_str.c_str(), src_ipv4)) {
std::stringstream ss;
- ss << "invalid IPv4 address: '" << ipv4_str << "'";
+ ss << "invalid source IPv4 address: '" << src_ipv4_str << "'";
generate_parse_err(result, ss.str());
}
- uint8_t mac[6];
- if (!utl_str_to_macaddr(mac_str, mac)) {
+ uint32_t dst_ipv4;
+ if (!utl_ipv4_to_uint32(dst_ipv4_str.c_str(), dst_ipv4)) {
std::stringstream ss;
- ss << "'invalid MAC address: '" << mac_str << "'";
+ ss << "invalid destination IPv4 address: '" << dst_ipv4_str << "'";
generate_parse_err(result, ss.str());
- }
+ }
+
+
- port->getPortAttrObj()->get_dest().set_dest(ipv4_addr, mac);
+ /* did we get a resolved MAC as well ? */
+ if (params["resolved_mac"] != Json::Value::null) {
+ const std::string resolved_mac = parse_string(params, "resolved_mac", result);
+
+ uint8_t mac[6];
+ if (!utl_str_to_macaddr(resolved_mac, mac)) {
+ std::stringstream ss;
+ ss << "'invalid MAC address: '" << resolved_mac << "'";
+ generate_parse_err(result, ss.str());
+ }
- return (TREX_RPC_CMD_OK);
+ port->set_l3_mode(src_ipv4, dst_ipv4, mac);
+
+ } else {
+
+ port->set_l3_mode(src_ipv4, dst_ipv4);
+ }
+
+ return (TREX_RPC_CMD_OK);
}
diff --git a/src/rpc-server/commands/trex_rpc_cmds.h b/src/rpc-server/commands/trex_rpc_cmds.h
index 2b2178e2..6639be7b 100644
--- a/src/rpc-server/commands/trex_rpc_cmds.h
+++ b/src/rpc-server/commands/trex_rpc_cmds.h
@@ -96,8 +96,6 @@ 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);
- int parse_dest(const Json::Value &msg, uint8_t port_id, Json::Value &result);
);
@@ -159,8 +157,9 @@ TREX_RPC_CMD_DEFINE_EXTENDED(TrexRpcCmdSetRxFeature, "set_rx_feature", 3, false,
);
+TREX_RPC_CMD_DEFINE(TrexRpcCmdSetL2, "set_l2", 2, false, APIClass::API_CLASS_TYPE_CORE);
+TREX_RPC_CMD_DEFINE(TrexRpcCmdSetL3, "set_l3", 3, false, APIClass::API_CLASS_TYPE_CORE);
TREX_RPC_CMD_DEFINE(TrexRpcCmdGetRxQueuePkts, "get_rx_queue_pkts", 2, false, APIClass::API_CLASS_TYPE_CORE);
-TREX_RPC_CMD_DEFINE(TrexRpcCmdSetARPRes, "set_arp_resolution", 2, false, APIClass::API_CLASS_TYPE_CORE);
#endif /* __TREX_RPC_CMD_H__ */
diff --git a/src/rpc-server/trex_rpc_cmds_table.cpp b/src/rpc-server/trex_rpc_cmds_table.cpp
index 919be1f1..94a3e1b9 100644
--- a/src/rpc-server/trex_rpc_cmds_table.cpp
+++ b/src/rpc-server/trex_rpc_cmds_table.cpp
@@ -75,7 +75,8 @@ TrexRpcCommandsTable::TrexRpcCommandsTable() {
register_command(new TrexRpcCmdSetRxFeature());
register_command(new TrexRpcCmdGetRxQueuePkts());
- register_command(new TrexRpcCmdSetARPRes());
+ register_command(new TrexRpcCmdSetL2());
+ register_command(new TrexRpcCmdSetL3());
}
diff --git a/src/stateful_rx_core.h b/src/stateful_rx_core.h
index 2df406de..8744a58a 100644
--- a/src/stateful_rx_core.h
+++ b/src/stateful_rx_core.h
@@ -32,33 +32,6 @@ limitations under the License.
class TrexWatchDog;
-class CRXCoreIgnoreStat {
- friend class CCPortLatency;
- friend class CLatencyManager;
- public:
- inline CRXCoreIgnoreStat operator- (const CRXCoreIgnoreStat &t_in) {
- CRXCoreIgnoreStat t_out;
- t_out.m_tx_arp = this->m_tx_arp - t_in.m_tx_arp;
- t_out.m_tx_ipv6_n_solic = this->m_tx_ipv6_n_solic - t_in.m_tx_ipv6_n_solic;
- t_out.m_tot_bytes = this->m_tot_bytes - t_in.m_tot_bytes;
- return t_out;
- }
- uint64_t get_tx_bytes() {return m_tot_bytes;}
- uint64_t get_tx_pkts() {return m_tx_arp + m_tx_ipv6_n_solic;}
- uint64_t get_tx_arp() {return m_tx_arp;}
- uint64_t get_tx_n_solic() {return m_tx_ipv6_n_solic;}
- void clear() {
- m_tx_arp = 0;
- m_tx_ipv6_n_solic = 0;
- m_tot_bytes = 0;
- }
-
- private:
- uint64_t m_tx_arp;
- uint64_t m_tx_ipv6_n_solic;
- uint64_t m_tot_bytes;
-};
-
class CLatencyPktInfo {
public:
void Create(class CLatencyPktMode *m_l_pkt_info);
diff --git a/src/stateless/cp/trex_stateless_port.cpp b/src/stateless/cp/trex_stateless_port.cpp
index 057f6521..62805dbc 100644
--- a/src/stateless/cp/trex_stateless_port.cpp
+++ b/src/stateless/cp/trex_stateless_port.cpp
@@ -988,18 +988,67 @@ TrexStatelessPort::get_rx_queue_pkts() {
}
+/**
+ * configures port in L2 mode
+ *
+ */
+void
+TrexStatelessPort::set_l2_mode(const uint8_t *dest_mac) {
+
+ /* no IPv4 src */
+ getPortAttrObj()->set_src_ipv4(0);
+
+ /* set destination as MAC */
+ getPortAttrObj()->get_dest().set_dest(dest_mac);
+
+ TrexStatelessRxSetL2Mode *msg = new TrexStatelessRxSetL2Mode(m_port_id);
+ send_message_to_rx( (TrexStatelessCpToRxMsgBase *)msg );
+}
+
+/**
+ * configures port in L3 mode - unresolved
+ */
+void
+TrexStatelessPort::set_l3_mode(uint32_t src_ipv4, uint32_t dest_ipv4) {
+
+ /* set src IPv4 */
+ getPortAttrObj()->set_src_ipv4(src_ipv4);
+
+ /* set dest IPv4 */
+ getPortAttrObj()->get_dest().set_dest(dest_ipv4);
+
+ /* send RX core the relevant info */
+ CManyIPInfo ip_info;
+ ip_info.insert(COneIPv4Info(src_ipv4, 0, getPortAttrObj()->get_src_mac()));
+
+ TrexStatelessRxSetL3Mode *msg = new TrexStatelessRxSetL3Mode(m_port_id, ip_info, false);
+ send_message_to_rx( (TrexStatelessCpToRxMsgBase *)msg );
+}
+
+/**
+ * configures port in L3 mode - resolved
+ *
+ */
void
-TrexStatelessPort::set_src_ipv4(uint32_t ipv4) {
+TrexStatelessPort::set_l3_mode(uint32_t src_ipv4, uint32_t dest_ipv4, const uint8_t *resolved_mac) {
- getPortAttrObj()->set_src_ipv4(ipv4);
+ /* set src IPv4 */
+ getPortAttrObj()->set_src_ipv4(src_ipv4);
- CManyIPInfo src_addr;
- src_addr.insert(COneIPv4Info(ipv4, 0, getPortAttrObj()->get_src_mac(), m_port_id));
+ /* set dest IPv4 + resolved MAC */
+ getPortAttrObj()->get_dest().set_dest(dest_ipv4, resolved_mac);
- TrexStatelessRxUpdateSrcAddr *msg = new TrexStatelessRxUpdateSrcAddr(m_port_id, src_addr);
+ /* send RX core the relevant info */
+ CManyIPInfo ip_info;
+ ip_info.insert(COneIPv4Info(src_ipv4, 0, getPortAttrObj()->get_src_mac()));
+
+ bool is_grat_arp_needed = !getPortAttrObj()->is_loopback();
+
+ TrexStatelessRxSetL3Mode *msg = new TrexStatelessRxSetL3Mode(m_port_id, ip_info, is_grat_arp_needed);
send_message_to_rx( (TrexStatelessCpToRxMsgBase *)msg );
}
+
Json::Value
TrexStatelessPort::rx_features_to_json() {
static MsgReply<Json::Value> reply;
diff --git a/src/stateless/cp/trex_stateless_port.h b/src/stateless/cp/trex_stateless_port.h
index 3ae74f5a..317f4f70 100644
--- a/src/stateless/cp/trex_stateless_port.h
+++ b/src/stateless/cp/trex_stateless_port.h
@@ -400,10 +400,17 @@ public:
const RXPacketBuffer *get_rx_queue_pkts();
/**
- * sets an IPv4 source address
+ * configures port for L2 mode
*
*/
- void set_src_ipv4(uint32_t ipv4);
+ void set_l2_mode(const uint8_t *dest_mac);
+
+ /**
+ * configures port in L3 mode
+ *
+ */
+ void set_l3_mode(uint32_t src_ipv4, uint32_t dest_ipv4);
+ void set_l3_mode(uint32_t src_ipv4, uint32_t dest_ipv4, const uint8_t *resolved_mac);
/**
* generate a JSON describing the status
diff --git a/src/stateless/messaging/trex_stateless_messaging.cpp b/src/stateless/messaging/trex_stateless_messaging.cpp
index dc656e67..2b8e93bb 100644
--- a/src/stateless/messaging/trex_stateless_messaging.cpp
+++ b/src/stateless/messaging/trex_stateless_messaging.cpp
@@ -317,7 +317,16 @@ TrexStatelessRxFeaturesToJson::handle(CRxCoreStateless *rx_core) {
}
bool
-TrexStatelessRxUpdateSrcAddr::handle(CRxCoreStateless *rx_core) {
- rx_core->get_rx_port_mngr(m_port_id).update_src_addr(m_src_addr);
+TrexStatelessRxSetL2Mode::handle(CRxCoreStateless *rx_core) {
+ rx_core->get_rx_port_mngr(m_port_id).set_l2_mode();
+
return true;
}
+
+bool
+TrexStatelessRxSetL3Mode::handle(CRxCoreStateless *rx_core) {
+ rx_core->get_rx_port_mngr(m_port_id).set_l3_mode(m_src_addr, m_is_grat_arp_needed);
+
+ return true;
+}
+
diff --git a/src/stateless/messaging/trex_stateless_messaging.h b/src/stateless/messaging/trex_stateless_messaging.h
index 5f00c244..dbdd9b56 100644
--- a/src/stateless/messaging/trex_stateless_messaging.h
+++ b/src/stateless/messaging/trex_stateless_messaging.h
@@ -569,13 +569,33 @@ private:
};
-class TrexStatelessRxUpdateSrcAddr : public TrexStatelessCpToRxMsgBase {
+/**
+ * updates the RX core that we are in L2 mode
+ */
+class TrexStatelessRxSetL2Mode : public TrexStatelessCpToRxMsgBase {
public:
- TrexStatelessRxUpdateSrcAddr(uint8_t port_id,
- const CManyIPInfo &src_addr) {
-
+ TrexStatelessRxSetL2Mode(uint8_t port_id) {
m_port_id = port_id;
- m_src_addr = src_addr;
+ }
+
+ virtual bool handle(CRxCoreStateless *rx_core);
+
+private:
+ uint8_t m_port_id;
+};
+
+/**
+ * updates the RX core that we are in a L3 mode
+ */
+class TrexStatelessRxSetL3Mode : public TrexStatelessCpToRxMsgBase {
+public:
+ TrexStatelessRxSetL3Mode(uint8_t port_id,
+ const CManyIPInfo &src_addr,
+ bool is_grat_arp_needed) {
+
+ m_port_id = port_id;
+ m_src_addr = src_addr;
+ m_is_grat_arp_needed = is_grat_arp_needed;
}
virtual bool handle(CRxCoreStateless *rx_core);
@@ -583,6 +603,7 @@ public:
private:
uint8_t m_port_id;
CManyIPInfo m_src_addr;
+ bool m_is_grat_arp_needed;
};
/**
diff --git a/src/stateless/rx/trex_stateless_rx_core.cpp b/src/stateless/rx/trex_stateless_rx_core.cpp
index 31fef68f..502af9c1 100644
--- a/src/stateless/rx/trex_stateless_rx_core.cpp
+++ b/src/stateless/rx/trex_stateless_rx_core.cpp
@@ -185,17 +185,30 @@ void CRxCoreStateless::port_manager_tick() {
}
}
+/**
+ * for each port handle the grat ARP mechansim
+ *
+ */
+void CRxCoreStateless::handle_grat_arp() {
+ for (int i = 0; i < m_max_ports; i++) {
+ m_rx_port_mngr[i].send_next_grat_arp();
+ }
+}
+
void CRxCoreStateless::handle_work_stage() {
/* set the next sync time to */
dsec_t sync_time_sec = now_sec() + (1.0 / 1000);
dsec_t tick_time_sec = now_sec() + 1.0;
-
+ dsec_t grat_arp_sec = now_sec() + (double)CGlobalInfo::m_options.m_arp_ref_per;
+
while (m_state == STATE_WORKING) {
process_all_pending_pkts();
dsec_t now = now_sec();
+ /* until a scheduler is added here - dirty IFs */
+
if ( (now - sync_time_sec) > 0 ) {
periodic_check_for_cp_messages();
}
@@ -204,7 +217,12 @@ void CRxCoreStateless::handle_work_stage() {
port_manager_tick();
tick_time_sec = now + 1.0;
}
-
+
+ if ( (now - grat_arp_sec) > 0) {
+ handle_grat_arp();
+ grat_arp_sec = now + (double)CGlobalInfo::m_options.m_arp_ref_per;
+ }
+
rte_pause();
}
@@ -346,3 +364,8 @@ CRxCoreStateless::get_rx_port_mngr(uint8_t port_id) {
return m_rx_port_mngr[port_id];
}
+
+void
+CRxCoreStateless::get_ignore_stats(int port_id, CRXCoreIgnoreStat &stat, bool get_diff) {
+ get_rx_port_mngr(port_id).get_ignore_stats(stat, get_diff);
+}
diff --git a/src/stateless/rx/trex_stateless_rx_core.h b/src/stateless/rx/trex_stateless_rx_core.h
index 96e511b4..4eed59a1 100644
--- a/src/stateless/rx/trex_stateless_rx_core.h
+++ b/src/stateless/rx/trex_stateless_rx_core.h
@@ -21,6 +21,7 @@
#ifndef __TREX_STATELESS_RX_CORE_H__
#define __TREX_STATELESS_RX_CORE_H__
#include <stdint.h>
+
#include "stateful_rx_core.h"
#include "os_time.h"
#include "pal/linux/sanb_atomic.h"
@@ -153,6 +154,12 @@ class CRxCoreStateless {
RXPortManager &get_rx_port_mngr(uint8_t port_id);
+ /**
+ * fetch the ignored stats for a port
+ *
+ */
+ void get_ignore_stats(int port_id, CRXCoreIgnoreStat &stat, bool get_diff);
+
private:
void handle_cp_msg(TrexStatelessCpToRxMsgBase *msg);
bool periodic_check_for_cp_messages();
@@ -166,7 +173,8 @@ class CRxCoreStateless {
void handle_rx_queue_msgs(uint8_t thread_id, CNodeRing * r);
void handle_work_stage();
void port_manager_tick();
-
+ void handle_grat_arp();
+
int process_all_pending_pkts(bool flush_rx = false);
void flush_all_pending_pkts() {
diff --git a/src/stateless/rx/trex_stateless_rx_port_mngr.cpp b/src/stateless/rx/trex_stateless_rx_port_mngr.cpp
index e36f825d..4c54a132 100644
--- a/src/stateless/rx/trex_stateless_rx_port_mngr.cpp
+++ b/src/stateless/rx/trex_stateless_rx_port_mngr.cpp
@@ -661,10 +661,15 @@ RXServer::duplicate_mbuf(const rte_mbuf_t *m) {
*
*************************************/
void
-RXGratARP::create(uint8_t port_id, CPortLatencyHWBase *io, CManyIPInfo *src_addr) {
- m_io = io;
- m_port_id = port_id;
- m_src_addr = src_addr;
+RXGratARP::create(uint8_t port_id,
+ CPortLatencyHWBase *io,
+ CManyIPInfo *src_addr,
+ CRXCoreIgnoreStat *ign_stats) {
+
+ m_port_id = port_id;
+ m_io = io;
+ m_src_addr = src_addr;
+ m_ign_stats = ign_stats;
}
void
@@ -689,9 +694,19 @@ RXGratARP::send_next_grat_arp() {
CTestPktGen::create_arp_req(p, sip, sip, src_mac, vlan, m_port_id);
- m_io->tx(m);
+ if (m_io->tx(m) == 0) {
+ m_ign_stats->m_tx_arp += 1;
+ m_ign_stats->m_tot_bytes += 64;
+ }
+}
+
+Json::Value
+RXGratARP::to_json() const {
+ Json::Value output = Json::objectValue;
+ output["interval_sec"] = (double)CGlobalInfo::m_options.m_arp_ref_per;
+ return output;
}
/**************************************
@@ -729,11 +744,10 @@ RXPortManager::create(const TRexPortAttr *port_attr,
/* init features */
m_latency.create(rfc2544, err_cntrs);
m_server.create(m_port_id, io, &m_src_addr);
- m_grat_arp.create(m_port_id, io, &m_src_addr);
+ m_grat_arp.create(m_port_id, io, &m_src_addr, &m_ign_stats);
- /* by default, server feature is always on */
+ /* by default, server is always on */
set_feature(SERVER);
- set_feature(GRAT_ARP);
}
void RXPortManager::handle_pkt(const rte_mbuf_t *m) {
@@ -797,13 +811,43 @@ RXPortManager::tick() {
if (is_feature_set(RECORDER)) {
m_recorder.flush_to_disk();
}
-
+}
+
+void
+RXPortManager::send_next_grat_arp() {
if (is_feature_set(GRAT_ARP)) {
m_grat_arp.send_next_grat_arp();
}
}
+
+void
+RXPortManager::set_l2_mode() {
+
+ /* no IPv4 addresses */
+ m_src_addr.clear();
+
+ /* stop grat arp */
+ stop_grat_arp();
+}
+
+void
+RXPortManager::set_l3_mode(const CManyIPInfo &ip_info, bool is_grat_arp_needed) {
+
+ /* copy L3 address */
+ m_src_addr = ip_info;
+
+ if (is_grat_arp_needed) {
+ start_grat_arp();
+ }
+ else {
+ stop_grat_arp();
+ }
+
+}
+
+
Json::Value
RXPortManager::to_json() const {
Json::Value output = Json::objectValue;
@@ -829,7 +873,23 @@ RXPortManager::to_json() const {
output["queue"]["is_active"] = false;
}
+ if (is_feature_set(GRAT_ARP)) {
+ output["grat_arp"] = m_grat_arp.to_json();
+ output["grat_arp"]["is_active"] = true;
+ } else {
+ output["grat_arp"]["is_active"] = false;
+ }
+
return output;
}
+void RXPortManager::get_ignore_stats(CRXCoreIgnoreStat &stat, bool get_diff) {
+ if (get_diff) {
+ stat = m_ign_stats - m_ign_stats_prev;
+ m_ign_stats_prev = m_ign_stats;
+ } else {
+ stat = m_ign_stats;
+ }
+}
+
diff --git a/src/stateless/rx/trex_stateless_rx_port_mngr.h b/src/stateless/rx/trex_stateless_rx_port_mngr.h
index e72b0ff0..8947def7 100644
--- a/src/stateless/rx/trex_stateless_rx_port_mngr.h
+++ b/src/stateless/rx/trex_stateless_rx_port_mngr.h
@@ -284,12 +284,16 @@ private:
class RXGratARP {
public:
RXGratARP() {
- m_io = NULL;
- m_port_id = UINT8_MAX;
- m_src_addr = NULL;
+ m_io = NULL;
+ m_port_id = UINT8_MAX;
+ m_src_addr = NULL;
+ m_ign_stats = NULL;
}
- void create(uint8_t port_id, CPortLatencyHWBase *io, CManyIPInfo *src_addr);
+ void create(uint8_t port_id,
+ CPortLatencyHWBase *io,
+ CManyIPInfo *src_addr,
+ CRXCoreIgnoreStat *ignore_stats);
/**
@@ -298,10 +302,13 @@ public:
*/
void send_next_grat_arp();
+ Json::Value to_json() const;
+
private:
+ uint8_t m_port_id;
CPortLatencyHWBase *m_io;
CManyIPInfo *m_src_addr;
- uint8_t m_port_id;
+ CRXCoreIgnoreStat *m_ign_stats;
};
/************************ manager ***************************/
@@ -389,7 +396,13 @@ public:
return m_queue.fetch();
}
+ void start_grat_arp() {
+ set_feature(GRAT_ARP);
+ }
+ void stop_grat_arp() {
+ unset_feature(GRAT_ARP);
+ }
/**
* fetch and process all packets
@@ -421,14 +434,25 @@ public:
void tick();
/**
- * updates the source addresses registered with the port
+ * send next grat arp (if on)
*
+ * @author imarom (12/13/2016)
*/
- void update_src_addr(const CManyIPInfo &new_src_addr) {
- /* deep copy */
- m_src_addr = new_src_addr;
- }
+ void send_next_grat_arp();
+
+ /**
+ * set port mode to L2
+ */
+ void set_l2_mode();
+ /**
+ * set port mode to L3
+ *
+ * @author imarom (12/13/2016)
+ */
+ void set_l3_mode(const CManyIPInfo &ip_info, bool is_grat_arp_needed);
+
+
bool has_features_set() {
return (m_features != NO_FEATURES);
}
@@ -439,6 +463,12 @@ public:
}
/**
+ * returns ignored set of stats
+ * (grat ARP, PING response and etc.)
+ */
+ void get_ignore_stats(CRXCoreIgnoreStat &stat, bool get_diff);
+
+ /**
* write the status to a JSON format
*/
Json::Value to_json() const;
@@ -475,6 +505,10 @@ private:
CCpuUtlDp *m_cpu_dp_u;
CPortLatencyHWBase *m_io;
CManyIPInfo m_src_addr;
+
+ /* stats to ignore (ARP and etc.) */
+ CRXCoreIgnoreStat m_ign_stats;
+ CRXCoreIgnoreStat m_ign_stats_prev;
};
diff --git a/src/trex_port_attr.h b/src/trex_port_attr.h
index 437fa8c7..7336befa 100755
--- a/src/trex_port_attr.h
+++ b/src/trex_port_attr.h
@@ -133,7 +133,8 @@ 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;
-
+ virtual bool is_loopback() const = 0;
+
uint32_t get_src_ipv4() const {return m_src_ipv4;}
DestAttr & get_dest() {return m_dest;}
@@ -219,7 +220,8 @@ public:
virtual int get_xstats_names(xstats_names_t &xstats_names);
virtual int get_flow_ctrl(int &mode);
virtual void get_supported_speeds(supp_speeds_t &supp_speeds);
-
+ virtual bool is_loopback() const;
+
/* SETTERS */
virtual int set_promiscuous(bool enabled);
virtual int add_mac(char * mac);
@@ -273,6 +275,7 @@ public:
int set_led(bool on) { return -ENOTSUP; }
void dump_link(FILE *fd) {}
int set_rx_filter_mode(rx_filter_mode_e mode) { return -ENOTSUP; }
+ virtual bool is_loopback() const { return false; }
};