diff options
author | imarom <imarom@cisco.com> | 2016-11-30 15:04:59 +0200 |
---|---|---|
committer | imarom <imarom@cisco.com> | 2016-11-30 15:04:59 +0200 |
commit | b812770167d37125b3f3e1b0673517d8f83393ac (patch) | |
tree | b99f73265f7f713995ed9ccdf5016e01c45b9ca9 /src | |
parent | 5b4fcd558793cf7222cc260d8d5aead03cf1cb86 (diff) | |
parent | 3beb07058c3781d9f3ce888be636b6484f750c96 (diff) |
merging with latest master
Signed-off-by: imarom <imarom@cisco.com>
Conflicts:
src/main_dpdk.cpp
Diffstat (limited to 'src')
-rw-r--r-- | src/dpdk/drivers/net/enic/enic_ethdev.c | 16 | ||||
-rw-r--r-- | src/dpdk/drivers/net/enic/enic_main.c | 3 | ||||
-rw-r--r-- | src/dpdk/drivers/net/ixgbe/ixgbe_ethdev.c | 6 | ||||
-rw-r--r-- | src/gtest/client_cfg_test.cpp | 2 | ||||
-rw-r--r-- | src/main_dpdk.cpp | 145 | ||||
-rw-r--r-- | src/pre_test.cpp | 20 | ||||
-rw-r--r-- | src/pre_test.h | 1 | ||||
-rw-r--r-- | src/utl_ip.cpp | 10 | ||||
-rw-r--r-- | src/utl_ip.h | 4 | ||||
-rwxr-xr-x | src/utl_term_io.cpp | 7 |
10 files changed, 172 insertions, 42 deletions
diff --git a/src/dpdk/drivers/net/enic/enic_ethdev.c b/src/dpdk/drivers/net/enic/enic_ethdev.c index c05476b2..6a86e23f 100644 --- a/src/dpdk/drivers/net/enic/enic_ethdev.c +++ b/src/dpdk/drivers/net/enic/enic_ethdev.c @@ -436,22 +436,6 @@ static void enicpmd_dev_stats_reset(struct rte_eth_dev *eth_dev) } -int enicpmd_dev_get_fw_support(int port_id, - uint32_t *ver){ - struct rte_eth_dev *dev; - - RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL); - - dev = &rte_eth_devices[port_id]; - *ver=0; - - struct enic *enic = pmd_priv(dev); - enic->adv_filters; - if ( enic->adv_filters ==0 ) { - return (-1); - } - return (0); -} static void enicpmd_dev_info_get(struct rte_eth_dev *eth_dev, diff --git a/src/dpdk/drivers/net/enic/enic_main.c b/src/dpdk/drivers/net/enic/enic_main.c index 889bc692..473bfc3c 100644 --- a/src/dpdk/drivers/net/enic/enic_main.c +++ b/src/dpdk/drivers/net/enic/enic_main.c @@ -166,6 +166,7 @@ void enic_dev_stats_get(struct enic *enic, struct rte_eth_stats *r_stats) return; } + /* The number of truncated packets can only be calculated by * subtracting a hardware counter from error packets received by * the driver. Note: this causes transient inaccuracies in the @@ -180,7 +181,7 @@ void enic_dev_stats_get(struct enic *enic, struct rte_eth_stats *r_stats) r_stats->ipackets = stats->rx.rx_frames_ok - rx_truncated; r_stats->opackets = stats->tx.tx_frames_ok; - r_stats->ibytes = stats->rx.rx_bytes_ok; + r_stats->ibytes = stats->rx.rx_unicast_bytes_ok+stats->rx.rx_multicast_bytes_ok+stats->rx.rx_broadcast_bytes_ok; r_stats->obytes = stats->tx.tx_bytes_ok; r_stats->ierrors = stats->rx.rx_errors + stats->rx.rx_drop; diff --git a/src/dpdk/drivers/net/ixgbe/ixgbe_ethdev.c b/src/dpdk/drivers/net/ixgbe/ixgbe_ethdev.c index d478a159..72963a89 100644 --- a/src/dpdk/drivers/net/ixgbe/ixgbe_ethdev.c +++ b/src/dpdk/drivers/net/ixgbe/ixgbe_ethdev.c @@ -5784,13 +5784,17 @@ ixgbe_add_del_ethertype_filter(struct rte_eth_dev *dev, if (filter->queue >= IXGBE_MAX_RX_QUEUE_NUM) return -EINVAL; - +#define TREX_PATCH +#ifndef TREX_PATCH + // no real reason to block this. + // We configure rules using FDIR and ethertype that point to same queue, so there are no race condition issues. if (filter->ether_type == ETHER_TYPE_IPv4 || filter->ether_type == ETHER_TYPE_IPv6) { PMD_DRV_LOG(ERR, "unsupported ether_type(0x%04x) in" " ethertype filter.", filter->ether_type); return -EINVAL; } +#endif if (filter->flags & RTE_ETHTYPE_FLAGS_MAC) { PMD_DRV_LOG(ERR, "mac compare is unsupported."); diff --git a/src/gtest/client_cfg_test.cpp b/src/gtest/client_cfg_test.cpp index 1e84e1d5..4e93f3c5 100644 --- a/src/gtest/client_cfg_test.cpp +++ b/src/gtest/client_cfg_test.cpp @@ -60,7 +60,7 @@ TEST_F(basic_client_cfg, test1) { CGlobalInfo::m_options.m_expected_portd = 4; printf("Expected ports %d\n", CGlobalInfo::m_options.m_expected_portd); - std::string tmp_file_name = "/tmp/client_cfg_gtest.yaml"; + std::string tmp_file_name = "client_cfg_gtest_GENERATED.yaml"; FILE *fd = fopen(tmp_file_name.c_str(), "w"); if (fd == NULL) { diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index 66a36110..2783182a 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -316,7 +316,8 @@ public: | TrexPlatformApi::IF_STAT_PAYLOAD; } virtual CFlowStatParser *get_flow_stat_parser(); - virtual int set_rcv_all(CPhyEthIF * _if, bool set_on) {return -ENOTSUP;} + int add_del_eth_filter(CPhyEthIF * _if, bool is_add, uint16_t ethertype); + virtual int set_rcv_all(CPhyEthIF * _if, bool set_on); }; class CTRexExtendedDriverBase40G : public CTRexExtendedDriverBase10G { @@ -379,7 +380,7 @@ private: uint8_t m_if_per_card; }; -class CTRexExtendedDriverBaseVIC : public CTRexExtendedDriverBase40G { +class CTRexExtendedDriverBaseVIC : public CTRexExtendedDriverBase { public: CTRexExtendedDriverBaseVIC(){ m_if_per_card=2; @@ -396,6 +397,22 @@ public: virtual bool is_hardware_filter_is_supported(){ return (true); } + virtual void update_global_config_fdir(port_cfg_t * cfg){ + } + + + virtual bool is_hardware_support_drop_queue(){ + return(true); + } + + void clear_extended_stats(CPhyEthIF * _if); + + void get_extended_stats(CPhyEthIF * _if,CPhyEthIFStats *stats); + + + virtual int get_min_sample_rate(void){ + return (RX_CHECK_MIX_SAMPLE_RATE); + } virtual int verify_fw_ver(int i); @@ -3291,15 +3308,33 @@ void CGlobalTRex::pre_test() { fprintf(stderr, "Resolution of following IPs failed. Exiting.\n"); for (const COneIPInfo *ip=pretest_result.get_next(); ip != NULL; ip = pretest_result.get_next()) { - ip->dump(stderr); + if (ip->resolve_needed()) { + ip->dump(stderr, " "); + } } - exit(-1); + exit(1); } m_fl.set_client_config_resolved_macs(pretest_result); if ( CGlobalInfo::m_options.preview.getVMode() > 1) { m_fl.dump_client_config(stdout); } + bool port_found[TREX_MAX_PORTS]; + for (int port_id = 0; port_id < m_max_ports; port_id++) { + port_found[port_id] = false; + } + // If client config enabled, we don't resolve MACs from trex_cfg.yaml. For latency (-l) + // We need to able to send packets from RX core, so need to configure MAC/vlan for each port. + for (const COneIPInfo *ip=pretest_result.get_next(); ip != NULL; ip = pretest_result.get_next()) { + // Use first MAC/vlan we see on each port + uint8_t port_id = ip->get_port(); + uint16_t vlan = ip->get_vlan(); + if ( ! port_found[port_id]) { + port_found[port_id] = true; + ip->get_mac(CGlobalInfo::m_options.m_mac_addr[port_id].u.m_mac.dest); + CGlobalInfo::m_options.m_ip_cfg[port_id].set_vlan(vlan); + } + } } else { uint8_t mac[ETHER_ADDR_LEN]; for (int port_id = 0; port_id < m_max_ports; port_id++) { @@ -6013,6 +6048,7 @@ void CTRexExtendedDriverBase10G::update_configuration(port_cfg_t * cfg){ } int CTRexExtendedDriverBase10G::configure_rx_filter_rules(CPhyEthIF * _if) { + set_rcv_all(_if, false); if ( get_is_stateless() ) { return configure_rx_filter_rules_stateless(_if); } else { @@ -6043,7 +6079,7 @@ int CTRexExtendedDriverBase10G::configure_rx_filter_rules_stateless(CPhyEthIF * res = rte_eth_dev_filter_ctrl(port_id, RTE_ETH_FILTER_FDIR, RTE_ETH_FILTER_ADD, &fdir_filter); if (res != 0) { - rte_exit(EXIT_FAILURE, " ERROR rte_eth_dev_filter_ctrl : %d\n",res); + rte_exit(EXIT_FAILURE, "Error: rte_eth_dev_filter_ctrl in configure_rx_filter_rules_stateless: %d\n",res); } } @@ -6112,12 +6148,51 @@ int CTRexExtendedDriverBase10G::configure_rx_filter_rules_statefull(CPhyEthIF * res = rte_eth_dev_filter_ctrl(port_id, RTE_ETH_FILTER_FDIR, RTE_ETH_FILTER_ADD, &fdir_filter); if (res != 0) { - rte_exit(EXIT_FAILURE, " ERROR rte_eth_dev_filter_ctrl : %d\n",res); + rte_exit(EXIT_FAILURE, "Error: rte_eth_dev_filter_ctrl in configure_rx_filter_rules_statefull: %d\n",res); } } return (0); } +int CTRexExtendedDriverBase10G::add_del_eth_filter(CPhyEthIF * _if, bool is_add, uint16_t ethertype) { + int res = 0; + uint8_t port_id=_if->get_rte_port_id(); + struct rte_eth_ethertype_filter filter; + enum rte_filter_op op; + + memset(&filter, 0, sizeof(filter)); + filter.ether_type = ethertype; + res = rte_eth_dev_filter_ctrl(port_id, RTE_ETH_FILTER_ETHERTYPE, RTE_ETH_FILTER_GET, &filter); + + if (is_add && (res >= 0)) + return 0; + if ((! is_add) && (res == -ENOENT)) + return 0; + + if (is_add) { + op = RTE_ETH_FILTER_ADD; + } else { + op = RTE_ETH_FILTER_DELETE; + } + + filter.queue = 1; + res = rte_eth_dev_filter_ctrl(port_id, RTE_ETH_FILTER_ETHERTYPE, op, &filter); + if (res != 0) { + printf("Error: %s L2 filter for ethertype 0x%04x returned %d\n", is_add ? "Adding":"Deleting", ethertype, res); + exit(1); + } + return 0; +} + +int CTRexExtendedDriverBase10G::set_rcv_all(CPhyEthIF * _if, bool set_on) { + int res = 0; + res = add_del_eth_filter(_if, set_on, ETHER_TYPE_ARP); + res |= add_del_eth_filter(_if, set_on, ETHER_TYPE_IPv4); + res |= add_del_eth_filter(_if, set_on, ETHER_TYPE_IPv6); + + return res; +} + void CTRexExtendedDriverBase10G::get_extended_stats(CPhyEthIF * _if,CPhyEthIFStats *stats){ int i; @@ -6864,26 +6939,58 @@ int CTRexExtendedDriverBaseVIC::configure_rx_filter_rules_statefull(CPhyEthIF * return 0; } -extern "C" int enicpmd_dev_get_fw_support(int port_id, - uint32_t *ver); + +void CTRexExtendedDriverBaseVIC::clear_extended_stats(CPhyEthIF * _if){ + rte_eth_stats_reset(_if->get_port_id()); +} + +void CTRexExtendedDriverBaseVIC::get_extended_stats(CPhyEthIF * _if,CPhyEthIFStats *stats) { + struct rte_eth_stats stats1; + struct rte_eth_stats *prev_stats = &stats->m_prev_stats; + rte_eth_stats_get(_if->get_port_id(), &stats1); + + stats->ipackets += stats1.ipackets - prev_stats->ipackets; + stats->ibytes += stats1.ibytes - prev_stats->ibytes + - ((stats1.ipackets << 2) - (prev_stats->ipackets << 2)); + stats->opackets += stats1.opackets - prev_stats->opackets; + stats->obytes += stats1.obytes - prev_stats->obytes; + stats->f_ipackets += 0; + stats->f_ibytes += 0; + stats->ierrors += stats1.imissed + stats1.ierrors + stats1.rx_nombuf + - prev_stats->imissed - prev_stats->ierrors - prev_stats->rx_nombuf; + stats->oerrors += stats1.oerrors - prev_stats->oerrors; + stats->imcasts += 0; + stats->rx_nombuf += stats1.rx_nombuf - prev_stats->rx_nombuf; + + prev_stats->ipackets = stats1.ipackets; + prev_stats->ibytes = stats1.ibytes; + prev_stats->opackets = stats1.opackets; + prev_stats->obytes = stats1.obytes; + prev_stats->imissed = stats1.imissed; + prev_stats->oerrors = stats1.oerrors; + prev_stats->ierrors = stats1.ierrors; + prev_stats->rx_nombuf = stats1.rx_nombuf; +} int CTRexExtendedDriverBaseVIC::verify_fw_ver(int port_id) { - uint32_t ver; - int ret=enicpmd_dev_get_fw_support(port_id,&ver); + struct rte_eth_fdir_info fdir_info; - if (ret==0) { - if (CGlobalInfo::m_options.preview.getVMode() >= 1) { - printf("VIC port %d: FW support advanced filtering \n", port_id); + if ( rte_eth_dev_filter_ctrl(port_id,RTE_ETH_FILTER_FDIR, RTE_ETH_FILTER_INFO,(void *)&fdir_info) == 0 ){ + if ( fdir_info.flow_types_mask[0] & (1<< RTE_ETH_FLOW_NONFRAG_IPV4_OTHER) ) { + /* support new features */ + if (CGlobalInfo::m_options.preview.getVMode() >= 1) { + printf("VIC port %d: FW support advanced filtering \n", port_id); + } + return (0); } - }else{ - printf("Error: VIC firmware should upgrade to support advanced filtering \n"); - printf(" Please refer to %s for upgrade instructions\n", - "https://trex-tgn.cisco.com/trex/doc/trex_manual.html"); - exit(1); } - return (0); + + printf("Error: VIC firmware should upgrade to support advanced filtering \n"); + printf(" Please refer to %s for upgrade instructions\n", + "https://trex-tgn.cisco.com/trex/doc/trex_manual.html"); + exit(1); } diff --git a/src/pre_test.cpp b/src/pre_test.cpp index 583427eb..7127645d 100644 --- a/src/pre_test.cpp +++ b/src/pre_test.cpp @@ -35,6 +35,15 @@ CPretestOnePortInfo::CPretestOnePortInfo() { m_stats.clear(); } +CPretestOnePortInfo::~CPretestOnePortInfo() { + for (std::vector<COneIPInfo *>::iterator it = m_src_info.begin(); it != m_src_info.end(); ++it) { + delete *it; + } + for (std::vector<COneIPInfo *>::iterator it = m_dst_info.begin(); it != m_dst_info.end(); ++it) { + delete *it; + } +} + void CPretestOnePortInfo::add_src(uint32_t ip, uint16_t vlan, MacAddress mac) { COneIPv4Info *one_ip = new COneIPv4Info(ip, vlan, mac); assert(one_ip); @@ -121,6 +130,8 @@ COneIPv6Info *CPretestOnePortInfo::find_ipv6(uint16_t ip[8], uint16_t vlan) { } bool CPretestOnePortInfo::get_mac(COneIPInfo *ip, uint8_t *mac) { + MacAddress defaultmac; + for (std::vector<COneIPInfo *>::iterator it = m_dst_info.begin(); it != m_dst_info.end(); ++it) { if (ip->ip_ver() != (*it)->ip_ver()) continue; @@ -139,7 +150,11 @@ bool CPretestOnePortInfo::get_mac(COneIPInfo *ip, uint8_t *mac) { } (*it)->get_mac(mac); - return true; + if (! memcmp(mac, defaultmac.GetConstBuffer(), ETHER_ADDR_LEN)) { + return false; + } else { + return true; + } } return false; @@ -361,7 +376,7 @@ bool CPretest::is_arp(const uint8_t *p, uint16_t pkt_size, ArpHdr *&arp, uint16_ EthernetHeader *m_ether = (EthernetHeader *)p; vlan_tag = 0; - if ((pkt_size < 60) || + if ((pkt_size < sizeof(EthernetHeader)) || ((m_ether->getNextProtocol() != EthernetHeader::Protocol::ARP) && (m_ether->getNextProtocol() != EthernetHeader::Protocol::VLAN))) return false; @@ -497,6 +512,7 @@ void CPretest::get_results(CManyIPInfo &resolved_ips) { for (std::vector<COneIPInfo *>::iterator it = m_port_info[port].m_dst_info.begin() ; it != m_port_info[port].m_dst_info.end(); ++it) { uint8_t ip_type = (*it)->ip_ver(); + (*it)->set_port(port); switch(ip_type) { case COneIPInfo::IP4_VER: resolved_ips.insert(*(COneIPv4Info *)(*it)); diff --git a/src/pre_test.h b/src/pre_test.h index 9573ff02..14b444cf 100644 --- a/src/pre_test.h +++ b/src/pre_test.h @@ -49,6 +49,7 @@ class CPretestOnePortInfo { public: CPretestOnePortInfo(); + ~CPretestOnePortInfo(); void add_src(uint32_t ip, uint16_t vlan, MacAddress mac); void add_dst(uint32_t ip, uint16_t vlan); void add_src(uint16_t ip[8], uint16_t vlan, MacAddress mac); diff --git a/src/utl_ip.cpp b/src/utl_ip.cpp index 5bd83f95..e7bb6fab 100644 --- a/src/utl_ip.cpp +++ b/src/utl_ip.cpp @@ -29,8 +29,14 @@ void COneIPInfo::dump(FILE *fd, const char *offset) const { get_ip_str(ip_str); std::string mac_str; utl_macaddr_to_str(mac, mac_str); - const char *mac_char = resolve_needed() ? "Not resolved" : mac_str.c_str(); - fprintf(fd, "%sip: %s vlan: %d port: %d mac: %s\n", offset, ip_str, m_vlan, m_port, mac_char); + const char *mac_char = resolve_needed() ? "Unknown" : mac_str.c_str(); + fprintf(fd, "%sip: %s ", offset, ip_str); + if (m_vlan != 0) + fprintf(fd, "vlan: %d ", m_vlan); + if (m_port != UINT8_MAX) + fprintf(fd, "port: %d ", m_port); + fprintf(fd, "mac: %s", mac_char); + fprintf(fd, "\n"); } bool COneIPInfo::resolve_needed() const { diff --git a/src/utl_ip.h b/src/utl_ip.h index 3a133a15..27bb6c81 100644 --- a/src/utl_ip.h +++ b/src/utl_ip.h @@ -105,6 +105,7 @@ class COneIPInfo { } COneIPInfo_ip_types; public: + virtual ~COneIPInfo() {} virtual void get_mac(uint8_t *mac) const { m_mac.copyToArray(mac); } @@ -113,6 +114,7 @@ class COneIPInfo { } uint16_t get_vlan() const {return m_vlan;} uint16_t get_port() const {return m_port;} + void set_port(uint8_t port) {m_port = port;} virtual void dump(FILE *fd) const { dump(fd, ""); } @@ -153,6 +155,7 @@ class COneIPv4Info : public COneIPInfo { COneIPv4Info(uint32_t ip, uint16_t vlan, MacAddress mac, uint8_t port) : COneIPInfo(vlan, mac, port) { m_ip = ip; } + ~COneIPv4Info() {}; uint32_t get_ip() {return m_ip;} virtual uint8_t ip_ver() const {return IP4_VER;} virtual uint32_t get_arp_req_len() const {return 60;} @@ -193,6 +196,7 @@ class COneIPv6Info : public COneIPInfo { COneIPv6Info(uint16_t ip[8], uint16_t vlan, MacAddress mac, uint8_t port) : COneIPInfo(vlan, mac, port) { memcpy(m_ip, ip, sizeof(m_ip)); } + ~COneIPv6Info() {} const uint8_t *get_ipv6() {return (uint8_t *)m_ip;} virtual uint8_t ip_ver() const {return IP6_VER;} diff --git a/src/utl_term_io.cpp b/src/utl_term_io.cpp index 8e561188..e45aeebd 100755 --- a/src/utl_term_io.cpp +++ b/src/utl_term_io.cpp @@ -78,6 +78,13 @@ int utl_termio_init(){ atexit(exit_handler1); save_termio(); set_conio_terminal_mode(); + + /* stdout is non-blocking */ + int fd = fileno(stdout); + int f = fcntl(fd, F_GETFL, 0); + f |= O_NONBLOCK; + fcntl(fd, F_SETFL, f); + return (0); } |