summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorimarom <imarom@cisco.com>2016-11-15 19:20:10 +0200
committerimarom <imarom@cisco.com>2016-11-15 19:20:10 +0200
commit558ce764c2a5feaf376b562e455a2e9c1115701a (patch)
treef4275f10641958fce04f6f865195adea415bd0ac
parent6e1919c3aebabc0977a8ab40b5c60cbd0e7114d0 (diff)
RX features - another refinement
Signed-off-by: imarom <imarom@cisco.com>
-rwxr-xr-xlinux/ws_main.py1
-rwxr-xr-xlinux_dpdk/ws_main.py1
-rwxr-xr-xscripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py59
-rw-r--r--scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py189
-rw-r--r--scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py8
-rw-r--r--src/internal_api/trex_platform_api.h10
-rw-r--r--src/main_dpdk.cpp15
-rw-r--r--src/rpc-server/commands/trex_rpc_cmd_general.cpp37
-rw-r--r--src/rpc-server/commands/trex_rpc_cmds.h1
-rw-r--r--src/rpc-server/trex_rpc_cmds_table.cpp2
-rw-r--r--src/stateless/cp/trex_stateless_port.cpp14
-rw-r--r--src/stateless/cp/trex_stateless_port.h13
-rw-r--r--src/stateless/dp/trex_stateless_dp_core.cpp29
-rw-r--r--src/stateless/rx/trex_stateless_rx_defs.h9
-rw-r--r--src/trex_port_attr.cpp71
-rwxr-xr-xsrc/trex_port_attr.h75
16 files changed, 417 insertions, 117 deletions
diff --git a/linux/ws_main.py b/linux/ws_main.py
index 79e26915..9e77485d 100755
--- a/linux/ws_main.py
+++ b/linux/ws_main.py
@@ -119,6 +119,7 @@ main_src = SrcGroup(dir='src',
'utl_json.cpp',
'utl_cpuu.cpp',
'msg_manager.cpp',
+ 'trex_port_attr.cpp',
'publisher/trex_publisher.cpp',
'stateful_rx_core.cpp',
'flow_stat.cpp',
diff --git a/linux_dpdk/ws_main.py b/linux_dpdk/ws_main.py
index 91cd728a..7477065e 100755
--- a/linux_dpdk/ws_main.py
+++ b/linux_dpdk/ws_main.py
@@ -132,6 +132,7 @@ main_src = SrcGroup(dir='src',
'nat_check.cpp',
'nat_check_flow_table.cpp',
'msg_manager.cpp',
+ 'trex_port_attr.cpp',
'publisher/trex_publisher.cpp',
'pal/linux_dpdk/pal_utl.cpp',
'pal/linux_dpdk/mbuf.cpp',
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 2ee5225c..3a37524c 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
@@ -804,6 +804,17 @@ class STLClient(object):
return rc
+ def __resolve (self, port_id_list = None, retries = 0):
+ port_id_list = self.__ports(port_id_list)
+
+ rc = RC()
+
+ for port_id in port_id_list:
+ rc.add(self.ports[port_id].resolve(retries))
+
+ return rc
+
+
def __set_port_attr (self, port_id_list = None, attr_dict = None):
port_id_list = self.__ports(port_id_list)
@@ -1770,6 +1781,9 @@ class STLClient(object):
raise STLError(rc)
def test (self):
+ self.resolve()
+ return
+
#rc = self.ports[0].resolve()
#if not rc:
# raise STLError(rc)
@@ -1827,7 +1841,8 @@ class STLClient(object):
+ :exc:`STLError`
"""
- self.test()
+ self.resolve()
+ return
self.logger.pre_cmd("Pinging the server on '{0}' port '{1}': ".format(self.connection_info['server'],
self.connection_info['sync_port']))
@@ -2151,7 +2166,7 @@ class STLClient(object):
validate_type('core_mask', core_mask, (int, list))
# verify link status
- ports_link_down = [port_id for port_id in ports if self.ports[port_id].attr.get('link',{}).get('up') == False]
+ ports_link_down = [port_id for port_id in ports if not self.ports[port_id].is_up()]
if not force and ports_link_down:
raise STLError("Port(s) %s - link DOWN - check the connection or specify 'force'" % ports_link_down)
@@ -2808,6 +2823,36 @@ class STLClient(object):
@__api_check(True)
+ def resolve (self, ports = None, retries = 0):
+ """
+ Resolves ports (ARP resolution)
+
+ :parameters:
+ ports - for which ports to apply a unique sniffer (each port gets a unique file)
+ retires - how many times to retry on each port (intervals of 100 milliseconds)
+ :raises:
+ + :exe:'STLError'
+
+ """
+ # by default - resolve all the ports that are configured with IPv4 dest
+ if ports is None:
+ ports = [port_id for port_id in self.get_acquired_ports() if self.ports[port_id].get_dest()['type'] == 'ipv4']
+
+ ports = self._validate_port_list(ports)
+
+
+ self.logger.pre_cmd("Resolving destination on port(s) {0}:".format(ports))
+ with self.logger.supress():
+ rc = self.__resolve(ports, retries)
+ self.logger.post_cmd(rc)
+
+ if not rc:
+ raise STLError(rc)
+
+
+
+
+ @__api_check(True)
def set_rx_sniffer (self, ports = None, base_filename = 'rx_capture', limit = 1000, rxf = None):
"""
Sets RX sniffer for port(s) written to a PCAP file
@@ -2871,7 +2916,7 @@ class STLClient(object):
The queue is cyclic and will hold last 'size' packets
:parameters:
- ports - for which ports to apply a unique sniffer (each port gets a unique file)
+ ports - for which ports to apply a queue
size - size of the queue
rxf - which RX filter to use on those ports: 'hw' or 'all'
:raises:
@@ -2905,6 +2950,8 @@ class STLClient(object):
"""
Removes RX queue from port(s)
+ :parameters:
+ ports - for which ports to remove the RX queue
:raises:
+ :exe:'STLError'
@@ -2927,7 +2974,10 @@ class STLClient(object):
Returns any packets queued on the RX side by the server
return value is a dictonary per port
+ :parameters:
+ ports - for which ports to fetch
"""
+
ports = ports if ports is not None else self.get_acquired_ports()
ports = self._validate_port_list(ports)
@@ -3667,3 +3717,6 @@ class STLClient(object):
else:
return "{0} {1}>".format(prefix, self.get_acquired_ports())
+
+
+
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 3fd00391..e19eebe1 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
@@ -2,15 +2,18 @@
from collections import namedtuple, OrderedDict
from .trex_stl_packet_builder_scapy import STLPktBuilder
-from .trex_stl_streams import STLStream
+from .trex_stl_streams import STLStream, STLTXSingleBurst
from .trex_stl_types import *
from . import trex_stl_stats
from .utils.constants import FLOW_CTRL_DICT_REVERSED
+from scapy.layers.l2 import Ether, ARP
+
import base64
import copy
from datetime import datetime, timedelta
import threading
+import time
StreamOnPort = namedtuple('StreamOnPort', ['compiled_stream', 'metadata'])
@@ -143,7 +146,7 @@ class Port(object):
return (self.handler != None)
def is_up (self):
- return (self.state != self.STATE_DOWN)
+ return self.__attr['link']['up']
def is_active(self):
return (self.state == self.STATE_TX ) or (self.state == self.STATE_PAUSE) or (self.state == self.STATE_PCAP_TX)
@@ -171,7 +174,6 @@ class Port(object):
# take the port
- @up
def acquire(self, force = False, sync_streams = True):
params = {"port_id": self.port_id,
"user": self.user,
@@ -191,7 +193,6 @@ class Port(object):
# sync all the streams with the server
- @up
def sync_streams (self):
params = {"port_id": self.port_id}
@@ -207,7 +208,6 @@ class Port(object):
return self.ok()
# release the port
- @up
def release(self):
params = {"port_id": self.port_id,
"handler": self.handler}
@@ -225,7 +225,6 @@ class Port(object):
- @up
def sync(self):
params = {"port_id": self.port_id}
@@ -511,6 +510,21 @@ class Port(object):
return self.ok()
@owned
+ def set_arp_resolution (self, ipv4, mac):
+
+ params = {"handler": self.handler,
+ "port_id": self.port_id,
+ "ipv4": ipv4,
+ "mac": mac}
+
+ rc = self.transmit("set_arp_resolution", params)
+ if rc.bad():
+ return self.err(rc.err())
+
+ return self.ok()
+
+
+ @owned
def remove_rx_sniffer (self):
params = {"handler": self.handler,
"port_id": self.port_id,
@@ -658,11 +672,11 @@ class Port(object):
if kwargs.get('promiscuous') is not None:
json_attr['promiscuous'] = {'enabled': kwargs.get('promiscuous')}
- if kwargs.get('link_up') is not None:
- json_attr['link_status'] = {'up': kwargs.get('link_up')}
+ if kwargs.get('link_status') is not None:
+ json_attr['link_status'] = {'up': kwargs.get('link_status')}
- if kwargs.get('led_on') is not None:
- json_attr['led_status'] = {'on': kwargs.get('led_on')}
+ if kwargs.get('led_status') is not None:
+ json_attr['led_status'] = {'on': kwargs.get('led_status')}
if kwargs.get('flow_ctrl_mode') is not None:
json_attr['flow_ctrl_mode'] = {'on': kwargs.get('flow_ctrl_mode')}
@@ -713,7 +727,35 @@ class Port(object):
def get_profile (self):
return self.profile
-
+ # invalidates the current ARP
+ def invalidate_arp (self):
+ dest = self.__attr['dest']
+
+ if dest['type'] != 'mac':
+ return self.set_attr(dest = dest['addr'])
+ else:
+ return self.ok()
+
+
+ @writeable
+ def add_arp_request (self):
+ ipv4 = self.__attr['src_ipv4']
+ dest = self.__attr['dest']
+ mac = self.__attr['src_mac']
+
+ if ipv4 == 'none':
+ return self.err('port must have a configured IPv4')
+
+ if dest['type'] == 'mac':
+ return self.err('port must have an IPv4 destination')
+
+
+ base_pkt = Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(psrc = ipv4, pdst = dest['addr'], hwsrc = mac)
+ s1 = STLStream( packet = STLPktBuilder(pkt = base_pkt), mode = STLTXSingleBurst(total_pkts = 1) )
+
+ return self.add_streams([s1])
+
+
def print_profile (self, mult, duration):
if not self.get_profile():
return
@@ -874,10 +916,17 @@ class Port(object):
src_ipv4 = None
return src_ipv4
+
+ def get_dest (self):
+ return self.__attr['dest']
def get_src_mac (self):
return self.__attr['src_mac']
-
+
+
+ def resolve (self, retries):
+ return ARPResolver(self).resolve(retries)
+
################# stats handler ######################
def generate_port_stats(self):
@@ -944,7 +993,7 @@ class Port(object):
return {"streams" : OrderedDict(sorted(data.items())) }
-
+
######## attributes are a complex type (dict) that might be manipulated through the async thread #############
# get in a thread safe manner a duplication of attributes
@@ -1017,3 +1066,117 @@ class Port(object):
def async_event_released (self):
self.owner = ''
+
+# a class to handle port ARP resolution
+class ARPResolver(object):
+ def __init__ (self, port):
+ self.port = port
+
+ # some sanity checks before resolving
+ def sanity (self):
+ if self.port.get_dest()['type'] == 'mac':
+ return self.port.err('resolve - port does not have an IPv4 as destination')
+
+ if self.port.get_src_ipv4() is None:
+ return self.port.err('resolve - port does not have an IPv4 address configured')
+
+ return self.port.ok()
+
+ # main resolve function
+ def resolve (self, retries):
+ rc = self.sanity()
+ if not rc:
+ return rc
+
+ # invalidate the current ARP resolution (if exists)
+ rc = self.port.invalidate_arp()
+ if not rc:
+ return rc
+
+ rc = self.port.remove_all_streams()
+ if not rc:
+ return rc
+
+ rc = self.port.set_rx_queue(size = 100)
+ if not rc:
+ return rc
+
+ rc = self.port.add_arp_request()
+ if not rc:
+ return rc
+
+
+ # retry for 'retries'
+ index = 0
+ while True:
+ response = self.resolve_iteration()
+ if response:
+ break
+
+ if index >= retries:
+ return self.port.err('failed to receive ARP response ({0} retries)'.format(retries))
+
+ index += 1
+ time.sleep(0.1)
+
+
+ # set ARP resolution result
+ rc = self.port.set_arp_resolution(response['ipv4'], response['mac'])
+ if not rc:
+ return rc
+
+ return self.port.ok()
+
+
+ def resolve_iteration (self):
+
+ mult = {'op': 'abs', 'type' : 'percentage', 'value': 100}
+ rc = self.port.start(mul = mult, force = False, duration = -1, mask = 0xffffffff)
+ if not rc:
+ return rc
+
+ # block until traffic finishes
+ while self.port.is_active():
+ time.sleep(0.01)
+
+ return self.wait_for_rx_response()
+
+
+ def wait_for_rx_response (self):
+
+ # we try to fetch response for 5 times
+ polling = 5
+
+ while polling > 0:
+ rx_pkts = self.port.get_rx_queue_pkts()
+ response = self.find_arp_response(rx_pkts)
+
+ if response:
+ return response
+
+ if polling == 0:
+ return None
+
+ polling -= 1
+ time.sleep(0.1)
+
+
+ # search in 'pkts' for an ARP response that matches the dest
+ def find_arp_response (self, pkts):
+
+ for pkt in pkts:
+ scapy_pkt = Ether(pkt)
+ if not 'ARP' in scapy_pkt:
+ continue
+
+ arp = scapy_pkt['ARP']
+ dest = self.port.get_dest()
+
+ # check this is the right ARP (ARP reply with the address)
+ if (arp.op != 2) or (arp.psrc != dest['addr']):
+ continue
+
+ return {'ipv4': arp.psrc, 'mac': arp.hwsrc}
+
+ return None
+
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 f0293016..2efb5a84 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
@@ -1109,13 +1109,7 @@ class CPortStats(CTRexStats):
port_state = format_text(port_state, 'bold')
if self._port_obj:
- if 'link' in self._port_obj.attr:
- if self._port_obj.attr.get('link', {}).get('up') == False:
- link_state = format_text('DOWN', 'red', 'bold')
- else:
- link_state = 'UP'
- else:
- link_state = 'N/A'
+ link_state = 'UP' if self._port_obj.is_up() else format_text('DOWN', 'red', 'bold')
else:
link_state = ''
diff --git a/src/internal_api/trex_platform_api.h b/src/internal_api/trex_platform_api.h
index 1445d3e9..5723503c 100644
--- a/src/internal_api/trex_platform_api.h
+++ b/src/internal_api/trex_platform_api.h
@@ -113,19 +113,13 @@ public:
IF_STAT_RX_BYTES_COUNT = 8, // Card support counting rx bytes
};
- struct mac_cfg_st {
- uint8_t hw_macaddr[6];
- uint8_t src_macaddr[6];
- uint8_t dst_macaddr[6];
- };
-
/**
* interface static info
*
*/
struct intf_info_st {
std::string driver_name;
- mac_cfg_st mac_info;
+ uint8_t hw_macaddr[6];
std::string pci_addr;
int numa_node;
bool has_crc;
@@ -235,7 +229,7 @@ public:
info.has_crc = true;
info.numa_node = 0;
- memset(&info.mac_info, 0, sizeof(info.mac_info));
+ memset(&info.hw_macaddr, 0, sizeof(info.hw_macaddr));
}
virtual void get_interface_stats(uint8_t interface_id, TrexPlatformInterfaceStats &stats) const {
diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp
index 8f887006..fed7a348 100644
--- a/src/main_dpdk.cpp
+++ b/src/main_dpdk.cpp
@@ -1659,7 +1659,7 @@ bool DpdkTRexPortAttr::get_promiscuous(){
}
-void DpdkTRexPortAttr::macaddr_get(struct ether_addr *mac_addr){
+void DpdkTRexPortAttr::get_hw_src_mac(struct ether_addr *mac_addr){
rte_eth_macaddr_get(m_port_id , mac_addr);
}
@@ -6502,19 +6502,10 @@ TrexDpdkPlatformApi::get_interface_info(uint8_t interface_id, intf_info_st &info
/* mac INFO */
/* hardware */
- g_trex.m_ports[interface_id].get_port_attr()->macaddr_get(&rte_mac_addr);
+ g_trex.m_ports[interface_id].get_port_attr()->get_hw_src_mac(&rte_mac_addr);
assert(ETHER_ADDR_LEN == 6);
- /* software */
- uint8_t sw_macaddr[12];
- memcpy(sw_macaddr, CGlobalInfo::m_options.get_dst_src_mac_addr(interface_id), 12);
-
- for (int i = 0; i < 6; i++) {
- info.mac_info.hw_macaddr[i] = rte_mac_addr.addr_bytes[i];
- info.mac_info.dst_macaddr[i] = sw_macaddr[i];
- info.mac_info.src_macaddr[i] = sw_macaddr[6 + i];
-
- }
+ memcpy(info.hw_macaddr, rte_mac_addr.addr_bytes, 6);
info.numa_node = g_trex.m_ports[interface_id].m_dev_info.pci_dev->numa_node;
struct rte_pci_addr *loc = &g_trex.m_ports[interface_id].m_dev_info.pci_dev->addr;
diff --git a/src/rpc-server/commands/trex_rpc_cmd_general.cpp b/src/rpc-server/commands/trex_rpc_cmd_general.cpp
index 8d61ecba..e7f0de7b 100644
--- a/src/rpc-server/commands/trex_rpc_cmd_general.cpp
+++ b/src/rpc-server/commands/trex_rpc_cmd_general.cpp
@@ -846,8 +846,12 @@ TrexRpcCmdGetRxQueuePkts::_run(const Json::Value &params, Json::Value &result) {
TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id);
try {
- RxPacketBuffer *pkt_buffer = port->get_rx_queue_pkts();
- result["result"]["pkts"] = pkt_buffer->to_json();
+ const RxPacketBuffer *pkt_buffer = port->get_rx_queue_pkts();
+ if (pkt_buffer) {
+ result["result"]["pkts"] = pkt_buffer->to_json();
+ } else {
+ result["result"]["pkts"] = Json::arrayValue;
+ }
} catch (const TrexException &ex) {
generate_execute_err(result, ex.what());
@@ -856,3 +860,32 @@ TrexRpcCmdGetRxQueuePkts::_run(const Json::Value &params, Json::Value &result) {
return (TREX_RPC_CMD_OK);
}
+
+trex_rpc_cmd_rc_e
+TrexRpcCmdSetARPRes::_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);
+
+ uint32_t ipv4_addr;
+ if (!utl_ipv4_to_uint32(ipv4_str.c_str(), ipv4_addr)) {
+ std::stringstream ss;
+ ss << "invalid IPv4 address: '" << ipv4_str << "'";
+ generate_parse_err(result, ss.str());
+ }
+
+ uint8_t mac[6];
+ if (!utl_str_to_macaddr(mac_str, mac)) {
+ std::stringstream ss;
+ ss << "'invalid MAC address: '" << mac_str << "'";
+ generate_parse_err(result, ss.str());
+ }
+
+ port->getPortAttrObj()->get_dest().set_dest_ipv4(ipv4_addr, mac);
+
+ return (TREX_RPC_CMD_OK);
+
+}
diff --git a/src/rpc-server/commands/trex_rpc_cmds.h b/src/rpc-server/commands/trex_rpc_cmds.h
index 9fb4d551..fab81f67 100644
--- a/src/rpc-server/commands/trex_rpc_cmds.h
+++ b/src/rpc-server/commands/trex_rpc_cmds.h
@@ -162,6 +162,7 @@ TREX_RPC_CMD_DEFINE_EXTENDED(TrexRpcCmdSetRxFeature, "set_rx_feature", 3, false,
);
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 f006a4cd..919be1f1 100644
--- a/src/rpc-server/trex_rpc_cmds_table.cpp
+++ b/src/rpc-server/trex_rpc_cmds_table.cpp
@@ -74,6 +74,8 @@ TrexRpcCommandsTable::TrexRpcCommandsTable() {
register_command(new TrexRpcCmdSetRxFeature());
register_command(new TrexRpcCmdGetRxQueuePkts());
+
+ register_command(new TrexRpcCmdSetARPRes());
}
diff --git a/src/stateless/cp/trex_stateless_port.cpp b/src/stateless/cp/trex_stateless_port.cpp
index ff83087c..d4bc5c36 100644
--- a/src/stateless/cp/trex_stateless_port.cpp
+++ b/src/stateless/cp/trex_stateless_port.cpp
@@ -888,16 +888,6 @@ TrexStatelessPort::get_port_effective_rate(double &pps,
}
void
-TrexStatelessPort::get_macaddr(std::string &hw_macaddr,
- std::string &src_macaddr,
- std::string &dst_macaddr) {
-
- utl_macaddr_to_str(m_api_info.mac_info.hw_macaddr, hw_macaddr);
- utl_macaddr_to_str(m_api_info.mac_info.src_macaddr, src_macaddr);
- utl_macaddr_to_str(m_api_info.mac_info.dst_macaddr, dst_macaddr);
-}
-
-void
TrexStatelessPort::get_pci_info(std::string &pci_addr, int &numa_node) {
pci_addr = m_api_info.pci_addr;
numa_node = m_api_info.numa_node;
@@ -980,6 +970,10 @@ TrexStatelessPort::stop_rx_queue() {
RxPacketBuffer *
TrexStatelessPort::get_rx_queue_pkts() {
+ if (m_rx_features_info.m_rx_queue_info.is_empty()) {
+ return NULL;
+ }
+
/* ask RX core for the pkt queue */
TrexStatelessMsgReply<RxPacketBuffer *> msg_reply;
diff --git a/src/stateless/cp/trex_stateless_port.h b/src/stateless/cp/trex_stateless_port.h
index d71ba932..cf6b2716 100644
--- a/src/stateless/cp/trex_stateless_port.h
+++ b/src/stateless/cp/trex_stateless_port.h
@@ -362,11 +362,6 @@ public:
double &bps_L2,
double &percentage);
-
- void get_macaddr(std::string &hw_macaddr,
- std::string &src_macaddr,
- std::string &dst_macaddr);
-
void get_pci_info(std::string &pci_addr, int &numa_node);
@@ -413,6 +408,14 @@ public:
*/
RxPacketBuffer *get_rx_queue_pkts();
+ /**
+ * return the port attribute object
+ *
+ */
+ TRexPortAttr *getPortAttrObj() {
+ return m_platform_api->getPortAttrObj(m_port_id);
+ }
+
private:
bool is_core_active(int core_id);
diff --git a/src/stateless/dp/trex_stateless_dp_core.cpp b/src/stateless/dp/trex_stateless_dp_core.cpp
index 857ac8f9..43b77bee 100644
--- a/src/stateless/dp/trex_stateless_dp_core.cpp
+++ b/src/stateless/dp/trex_stateless_dp_core.cpp
@@ -26,7 +26,7 @@ limitations under the License.
#include "trex_stream_node.h"
#include "trex_streams_compiler.h"
#include "mbuf.h"
-
+#include "trex_stateless.h"
@@ -495,12 +495,14 @@ bool TrexStatelessDpPerPort::push_pcap(uint8_t port_id,
/* main port */
uint8_t mac_addr[12];
- m_core->m_node_gen.m_v_if->update_mac_addr_from_global_cfg(dir, mac_addr);
-
+ TRexPortAttr *master_port_attr = get_stateless_obj()->get_platform_api()->getPortAttrObj(port_id);
+ master_port_attr->update_src_dst_mac(mac_addr);
+
/* for dual */
uint8_t slave_mac_addr[12];
- m_core->m_node_gen.m_v_if->update_mac_addr_from_global_cfg(dir ^ 0x1, slave_mac_addr);
-
+ TRexPortAttr *slave_port_attr = get_stateless_obj()->get_platform_api()->getPortAttrObj(port_id ^ 0x1);
+ slave_port_attr->update_src_dst_mac(slave_mac_addr);
+
bool rc = pcap_node->create(port_id,
dir,
socket_id,
@@ -823,8 +825,9 @@ void TrexStatelessDpCore::update_mac_addr(TrexStream * stream,
CGenNodeStateless *node,
pkt_dir_t dir,
char *raw_pkt){
- bool ov_src = stream->get_override_src_mac_by_pkt_data();
- TrexStream::stream_dst_mac_t ov_dst = stream->get_override_dst_mac_mode();
+
+ bool ov_src = stream->get_override_src_mac_by_pkt_data();
+ TrexStream::stream_dst_mac_t ov_dst = stream->get_override_dst_mac_mode();
if ( (ov_src == true) && (ov_dst == TrexStream::stPKT) ) {
@@ -832,11 +835,13 @@ void TrexStatelessDpCore::update_mac_addr(TrexStream * stream,
return;
}
- /* take from cfg_file */
+ TRexPortAttr *port_attr = get_stateless_obj()->get_platform_api()->getPortAttrObj(node->get_port_id());
+
+ /* take from cfg_file */
if ( (ov_src == false) &&
(ov_dst == TrexStream::stCFG_FILE) ){
-
- m_core->m_node_gen.m_v_if->update_mac_addr_from_global_cfg(dir,(uint8_t*)raw_pkt);
+
+ port_attr->update_src_dst_mac((uint8_t *)raw_pkt);
return;
}
@@ -844,8 +849,8 @@ void TrexStatelessDpCore::update_mac_addr(TrexStream * stream,
char tmp_pkt[12];
memcpy(tmp_pkt,raw_pkt,12);
- m_core->m_node_gen.m_v_if->update_mac_addr_from_global_cfg(dir,(uint8_t*)raw_pkt);
-
+ port_attr->update_src_dst_mac((uint8_t *)raw_pkt);
+
if ((ov_src == true) && (ov_dst == TrexStream::stCFG_FILE)) {
memcpy(raw_pkt+6,tmp_pkt+6,6);
}
diff --git a/src/stateless/rx/trex_stateless_rx_defs.h b/src/stateless/rx/trex_stateless_rx_defs.h
index bdd86a72..7b1e0f32 100644
--- a/src/stateless/rx/trex_stateless_rx_defs.h
+++ b/src/stateless/rx/trex_stateless_rx_defs.h
@@ -79,6 +79,10 @@ public:
m_limit = 0;
}
+ bool is_empty() const {
+ return (m_shared_counter == 0);
+ }
+
void to_json(Json::Value &output) const {
output["is_active"] = m_is_active;
if (m_is_active) {
@@ -114,7 +118,10 @@ public:
m_size = 0;
}
-
+ bool is_empty() const {
+ return (m_shared_counter == 0);
+ }
+
void to_json(Json::Value &output) const {
output["is_active"] = m_is_active;
if (m_is_active) {
diff --git a/src/trex_port_attr.cpp b/src/trex_port_attr.cpp
new file mode 100644
index 00000000..08e151b6
--- /dev/null
+++ b/src/trex_port_attr.cpp
@@ -0,0 +1,71 @@
+/*
+Copyright (c) 2015-2015 Cisco Systems, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+#include "trex_port_attr.h"
+#include "bp_sim.h"
+
+const uint8_t DestAttr::g_dummy_mac[6] = {0x0,0x0,0x0,0x1,0x0,0x0};
+
+
+const uint8_t *
+TRexPortAttr::get_src_mac() const {
+ return CGlobalInfo::m_options.get_src_mac_addr(m_port_id);
+}
+
+
+std::string
+TRexPortAttr::get_rx_filter_mode() const {
+ switch (m_rx_filter_mode) {
+ case RX_FILTER_MODE_ALL:
+ return "all";
+ case RX_FILTER_MODE_HW:
+ return "hw";
+ default:
+ assert(0);
+ }
+}
+
+
+void
+TRexPortAttr::to_json(Json::Value &output) {
+
+ output["src_mac"] = utl_macaddr_to_str(get_src_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();
+
+ if (get_src_ipv4() != 0) {
+ output["src_ipv4"] = utl_uint32_to_ipv4(get_src_ipv4());
+ } else {
+ output["src_ipv4"] = "none";
+ }
+
+
+ int mode;
+ get_flow_ctrl(mode);
+ output["fc"]["mode"] = mode;
+
+ m_dest.to_json(output["dest"]);
+
+}
+
+void
+TRexPortAttr::update_src_dst_mac(uint8_t *raw_pkt) {
+ memcpy(raw_pkt, get_dest().get_dest_mac(), 6);
+ memcpy(raw_pkt + 6, get_src_mac(), 6);
+}
+
diff --git a/src/trex_port_attr.h b/src/trex_port_attr.h
index cdbb466c..68f9f82e 100755
--- a/src/trex_port_attr.h
+++ b/src/trex_port_attr.h
@@ -22,18 +22,21 @@ limitations under the License.
#include "rte_ethdev_includes.h"
#include "trex_defs.h"
#include "common/basic_utils.h"
+#include <json/json.h>
+#include "trex_stateless_rx_defs.h"
/**
* destination port attribute
*
*/
class DestAttr {
+private:
+ static const uint8_t g_dummy_mac[6];
public:
DestAttr() {
/* use a dummy MAC as default */
- uint8_t dummy_mac [] = {0xff,0xff,0xff,0xff,0xff,0xff};
- set_dest_mac(dummy_mac);
+ set_dest_mac(g_dummy_mac);
}
enum dest_type_e {
@@ -90,6 +93,20 @@ public:
}
/**
+ * get the dest mac
+ * if no MAC is configured and dest was not resolved
+ * will return a dummy
+ */
+ const uint8_t *get_dest_mac() {
+
+ if (is_resolved()) {
+ return m_mac;
+ } else {
+ return g_dummy_mac;
+ }
+ }
+
+ /**
* when link gets down - this should be called
*
*/
@@ -149,7 +166,7 @@ public:
/* GETTERS */
virtual bool get_promiscuous() = 0;
- virtual void macaddr_get(struct ether_addr *mac_addr) = 0;
+ virtual void get_hw_src_mac(struct ether_addr *mac_addr) = 0;
virtual uint32_t get_link_speed() { return m_link.link_speed; } // L1 Mbps
virtual bool is_link_duplex() { return (m_link.link_duplex ? true : false); }
virtual bool is_link_autoneg() { return (m_link.link_autoneg ? true : false); }
@@ -163,21 +180,16 @@ 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_src_ipv4() {return m_src_ipv4;}
DestAttr & get_dest() {return m_dest;}
- 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);
- }
- }
-
+ const uint8_t *get_src_mac() const;
+ std::string get_rx_filter_mode() const;
+ /* for a raw packet, write the src/dst MACs */
+ void update_src_dst_mac(uint8_t *raw_pkt);
+
/* SETTERS */
virtual int set_promiscuous(bool enabled) = 0;
virtual int add_mac(char * mac) = 0;
@@ -190,37 +202,12 @@ public:
m_src_ipv4 = addr;
}
-/* DUMPS */
+ /* 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["src_mac"] = utl_macaddr_to_str(mac_addr);
- output["promiscuous"]["enabled"] = get_promiscuous();
- output["link"]["up"] = is_link_up();
- output["speed"] = get_link_speed();
- output["rx_filter_mode"] = get_rx_filter_mode();
-
- if (get_src_ipv4() != 0) {
- output["src_ipv4"] = utl_uint32_to_ipv4(get_src_ipv4());
- } else {
- output["src_ipv4"] = "none";
- }
-
-
- int mode;
- get_flow_ctrl(mode);
- output["fc"]["mode"] = mode;
-
- m_dest.to_json(output["dest"]);
-
- }
+ void to_json(Json::Value &output);
+
protected:
@@ -273,7 +260,7 @@ public:
/* GETTERS */
virtual bool get_promiscuous();
- virtual void macaddr_get(struct ether_addr *mac_addr);
+ virtual void get_hw_src_mac(struct ether_addr *mac_addr);
virtual int get_xstats_values(xstats_values_t &xstats_values);
virtual int get_xstats_names(xstats_names_t &xstats_names);
virtual int get_flow_ctrl(int &mode);
@@ -319,7 +306,7 @@ public:
void reset_xstats() {}
void update_description() {}
bool get_promiscuous() { return false; }
- void macaddr_get(struct ether_addr *mac_addr) {}
+ void get_hw_src_mac(struct ether_addr *mac_addr) {}
int get_xstats_values(xstats_values_t &xstats_values) { return -ENOTSUP; }
int get_xstats_names(xstats_names_t &xstats_names) { return -ENOTSUP; }
int get_flow_ctrl(int &mode) { return -ENOTSUP; }