diff options
Diffstat (limited to 'src/main_dpdk.cpp')
-rw-r--r-- | src/main_dpdk.cpp | 213 |
1 files changed, 153 insertions, 60 deletions
diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index 435481c1..fcafd322 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -486,11 +486,11 @@ public: private: - virtual void add_del_rules(enum rte_filter_op op, uint8_t port_id, - uint16_t type, uint8_t ttl, - uint16_t ip_id, + virtual void add_del_rules(enum rte_filter_op op, uint8_t port_id, + uint16_t type, uint8_t ttl, + uint16_t ip_id, uint8_t l4_proto, - int queue, + int queue, uint16_t stat_idx); virtual int configure_rx_filter_rules_statfull(CPhyEthIF * _if); @@ -1123,6 +1123,9 @@ static int parse_options(int argc, char *argv[], CParserOption* po, bool first_t if ( opt_vlan_was_set ) { po->preview.set_vlan_mode_enable(true); } + if (CGlobalInfo::m_options.client_cfg_file != "") { + parse_err("Client config file is not supported with interactive (stateless) mode "); + } if ( po->m_duration ) { parse_err("Duration is not supported with interactive (stateless) mode "); } @@ -3172,70 +3175,155 @@ void CGlobalTRex::pre_test() { CPretest pretest(m_max_ports); bool resolve_needed = false; uint8_t empty_mac[ETHER_ADDR_LEN] = {0,0,0,0,0,0}; - - for (int port_id = 0; port_id < m_max_ports; port_id++) { - CPhyEthIF *pif = &m_ports[port_id]; - // Configure port to send all packets to software - CTRexExtendedDriverDb::Ins()->get_drv()->set_rcv_all(pif, true); - if (! memcmp( CGlobalInfo::m_options.m_mac_addr[port_id].u.m_mac.dest, empty_mac, ETHER_ADDR_LEN)) { - resolve_needed = true; - } else { - resolve_needed = false; + bool need_grat_arp[TREX_MAX_PORTS]; + + if (CGlobalInfo::m_options.preview.get_is_client_cfg_enable()) { + std::vector<ClientCfgCompactEntry *> conf = m_fl.get_client_cfg_ip_list(); + + // If we got src MAC for port in global config, take it, otherwise use src MAC from DPDK + uint8_t port_macs[m_max_ports][ETHER_ADDR_LEN]; + for (int port_id = 0; port_id < m_max_ports; port_id++) { + uint8_t empty_mac[ETHER_ADDR_LEN] = {0,0,0,0,0,0}; + if (! memcmp( CGlobalInfo::m_options.m_mac_addr[port_id].u.m_mac.src, empty_mac, ETHER_ADDR_LEN)) { + rte_eth_macaddr_get(port_id, + (struct ether_addr *)&CGlobalInfo::m_options.m_mac_addr[port_id].u.m_mac.src); + } + memcpy(port_macs[port_id], CGlobalInfo::m_options.m_mac_addr[port_id].u.m_mac.src, ETHER_ADDR_LEN); } - if (! memcmp( CGlobalInfo::m_options.m_mac_addr[port_id].u.m_mac.src, empty_mac, ETHER_ADDR_LEN)) { - rte_eth_macaddr_get(port_id, - (struct ether_addr *)&CGlobalInfo::m_options.m_mac_addr[port_id].u.m_mac.src); - CGlobalInfo::m_options.m_ip_cfg[port_id].set_grat_arp_needed(true); - } else { - // If we got src MAC from config file, do not send gratuitous ARP for it (for compatibility with old behaviour) - CGlobalInfo::m_options.m_ip_cfg[port_id].set_grat_arp_needed(false); + + m_fl.dump_client_config(stdout); // remove ??? + printf("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&1\n"); + for (std::vector<ClientCfgCompactEntry *>::iterator it = conf.begin(); it != conf.end(); it++) { + uint8_t port = (*it)->get_port(); + uint16_t vlan = (*it)->get_vlan(); + uint32_t count = (*it)->get_count(); + uint32_t dst_ip = (*it)->get_dst_ip(); + uint32_t src_ip = (*it)->get_src_ip(); + + for (int i = 0; i < count; i++) { + //??? handle ipv6; + if ((*it)->is_ipv4()) { + pretest.add_next_hop(port, dst_ip + i, vlan); + } + } + if (!src_ip) { + src_ip = CGlobalInfo::m_options.m_ip_cfg[port].get_ip(); + if (!src_ip) { + fprintf(stderr, "No matching src ip for port: %d ip:%s vlan: %d\n" + , port, ip_to_str(dst_ip).c_str(), vlan); + fprintf(stderr, "You must specify src_ip in client config file or in TRex config file\n"); + exit(1); + } + } + pretest.add_ip(port, src_ip, vlan, port_macs[port]); + COneIPv4Info ipv4(src_ip, vlan, port_macs[port], port); + m_mg.add_grat_arp_src(ipv4); + + delete *it; } + if ( CGlobalInfo::m_options.preview.getVMode() > 1) { + fprintf(stdout, "*******Pretest for client cfg********\n"); + pretest.dump(stdout); + } + } else { + for (int port_id = 0; port_id < m_max_ports; port_id++) { + if (! memcmp( CGlobalInfo::m_options.m_mac_addr[port_id].u.m_mac.dest, empty_mac, ETHER_ADDR_LEN)) { + resolve_needed = true; + } else { + resolve_needed = false; + } + if (! memcmp( CGlobalInfo::m_options.m_mac_addr[port_id].u.m_mac.src, empty_mac, ETHER_ADDR_LEN)) { + rte_eth_macaddr_get(port_id, + (struct ether_addr *)&CGlobalInfo::m_options.m_mac_addr[port_id].u.m_mac.src); + need_grat_arp[port_id] = true; + } else { + // If we got src MAC from config file, do not send gratuitous ARP for it + // (for compatibility with old behaviour) + need_grat_arp[port_id] = false; + } - pretest.add_ip(port_id, CGlobalInfo::m_options.m_ip_cfg[port_id].get_ip() - , CGlobalInfo::m_options.m_ip_cfg[port_id].get_vlan() - , CGlobalInfo::m_options.m_mac_addr[port_id].u.m_mac.src); + pretest.add_ip(port_id, CGlobalInfo::m_options.m_ip_cfg[port_id].get_ip() + , CGlobalInfo::m_options.m_ip_cfg[port_id].get_vlan() + , CGlobalInfo::m_options.m_mac_addr[port_id].u.m_mac.src); - if (resolve_needed) { - pretest.add_next_hop(port_id, CGlobalInfo::m_options.m_ip_cfg[port_id].get_def_gw() - , CGlobalInfo::m_options.m_ip_cfg[port_id].get_vlan()); + if (resolve_needed) { + pretest.add_next_hop(port_id, CGlobalInfo::m_options.m_ip_cfg[port_id].get_def_gw() + , CGlobalInfo::m_options.m_ip_cfg[port_id].get_vlan()); + } } } + for (int port_id = 0; port_id < m_max_ports; port_id++) { + CPhyEthIF *pif = &m_ports[port_id]; + // Configure port to send all packets to software + CTRexExtendedDriverDb::Ins()->get_drv()->set_rcv_all(pif, true); + } + + pretest.send_grat_arp_all(); bool ret; int count = 0; + bool resolve_failed = false; do { ret = pretest.resolve_all(); count++; } while ((ret != true) && (count < 10)); + if (ret != true) { + resolve_failed = true; + } - if ( CGlobalInfo::m_options.preview.getVMode() > 0) { + if ( CGlobalInfo::m_options.preview.getVMode() > 1) { + fprintf(stdout, "*******Pretest after resolving ********\n"); pretest.dump(stdout); } - uint8_t mac[ETHER_ADDR_LEN]; - for (int port_id = 0; port_id < m_max_ports; port_id++) { - if (! memcmp(CGlobalInfo::m_options.m_mac_addr[port_id].u.m_mac.dest, empty_mac, ETHER_ADDR_LEN)) { - // we don't have dest MAC. Get it from what we resolved. - uint32_t ip = CGlobalInfo::m_options.m_ip_cfg[port_id].get_def_gw(); - uint16_t vlan = CGlobalInfo::m_options.m_ip_cfg[port_id].get_vlan(); - if (! pretest.get_mac(port_id, ip, vlan, mac)) { - fprintf(stderr, "Failed resolving dest MAC for default gateway:%d.%d.%d.%d on port %d\n" - , (ip >> 24) & 0xFF, (ip >> 16) & 0xFF, (ip >> 8) & 0xFF, ip & 0xFF, port_id); - exit(1); + + if (CGlobalInfo::m_options.preview.get_is_client_cfg_enable()) { + CManyIPInfo pretest_result; + pretest.get_results(pretest_result); + if (resolve_failed) { + 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); } - memcpy(CGlobalInfo::m_options.m_mac_addr[port_id].u.m_mac.dest, mac, ETHER_ADDR_LEN); - // if port is connected in loopback, no need to send gratuitous ARP. It will only confuse our ingress counters. - if (pretest.is_loopback(port_id)) - CGlobalInfo::m_options.m_ip_cfg[port_id].set_grat_arp_needed(false); + exit(-1); + } + m_fl.set_client_config_resolved_macs(pretest_result); + if ( CGlobalInfo::m_options.preview.getVMode() > 1) { + m_fl.dump_client_config(stdout); } - // update statistics baseline, so we can ignore what happened in pre test phase - CPhyEthIF *pif = &m_ports[port_id]; - CPreTestStats pre_stats = pretest.get_stats(port_id); - pif->set_ignore_stats_base(pre_stats); + } else { + uint8_t mac[ETHER_ADDR_LEN]; + for (int port_id = 0; port_id < m_max_ports; port_id++) { + if (! memcmp(CGlobalInfo::m_options.m_mac_addr[port_id].u.m_mac.dest, empty_mac, ETHER_ADDR_LEN)) { + // we don't have dest MAC. Get it from what we resolved. + uint32_t ip = CGlobalInfo::m_options.m_ip_cfg[port_id].get_def_gw(); + uint16_t vlan = CGlobalInfo::m_options.m_ip_cfg[port_id].get_vlan(); + if (! pretest.get_mac(port_id, ip, vlan, mac)) { + fprintf(stderr, "Failed resolving dest MAC for default gateway:%d.%d.%d.%d on port %d\n" + , (ip >> 24) & 0xFF, (ip >> 16) & 0xFF, (ip >> 8) & 0xFF, ip & 0xFF, port_id); + exit(1); + } + memcpy(CGlobalInfo::m_options.m_mac_addr[port_id].u.m_mac.dest, mac, ETHER_ADDR_LEN); + // if port is connected in loopback, no need to send gratuitous ARP. It will only confuse our ingress counters. + if (need_grat_arp[port_id] && (! pretest.is_loopback(port_id))) { + COneIPv4Info ipv4(CGlobalInfo::m_options.m_ip_cfg[port_id].get_ip() + , CGlobalInfo::m_options.m_ip_cfg[port_id].get_vlan() + , CGlobalInfo::m_options.m_mac_addr[port_id].u.m_mac.src + , port_id); + m_mg.add_grat_arp_src(ipv4); + } + } - // Configure port back to normal mode. Only relevant packets handled by software. - CTRexExtendedDriverDb::Ins()->get_drv()->set_rcv_all(pif, false); + // update statistics baseline, so we can ignore what happened in pre test phase + CPhyEthIF *pif = &m_ports[port_id]; + CPreTestStats pre_stats = pretest.get_stats(port_id); + pif->set_ignore_stats_base(pre_stats); + + // Configure port back to normal mode. Only relevant packets handled by software. + CTRexExtendedDriverDb::Ins()->get_drv()->set_rcv_all(pif, false); + } } } @@ -4738,6 +4826,8 @@ int CGlobalTRex::start_master_statefull() { exit(-1); } CGlobalInfo::m_options.preview.set_client_cfg_enable(true); + m_fl.set_client_config_tuple_gen_info(&m_fl.m_yaml_info.m_tuple_gen); + pre_test(); } /* verify options */ @@ -5467,7 +5557,10 @@ int main_test(int argc , char * argv[]){ } } - g_trex.pre_test(); + // in case of client config, we already run pretest + if (CGlobalInfo::m_options.preview.get_is_client_cfg_enable()) { + g_trex.pre_test(); + } // after doing all needed ARP resolution, we need to flush queues, and stop our drop queue g_trex.ixgbe_rx_queue_flush(); @@ -6424,15 +6517,15 @@ void CTRexExtendedDriverBaseMlnx5G::update_configuration(port_cfg_t * cfg){ cfg->m_port_conf.fdir_conf.mask.ipv4_mask.tos=0x01; cfg->m_port_conf.fdir_conf.mask.ipv6_mask.proto=0xff; cfg->m_port_conf.fdir_conf.mask.ipv6_mask.tc=0x01; - + } -void CTRexExtendedDriverBaseMlnx5G::add_del_rules(enum rte_filter_op op, uint8_t port_id, uint16_t type, - uint8_t ttl, - uint16_t ip_id, - uint8_t l4_proto, +void CTRexExtendedDriverBaseMlnx5G::add_del_rules(enum rte_filter_op op, uint8_t port_id, uint16_t type, + uint8_t ttl, + uint16_t ip_id, + uint8_t l4_proto, int queue, uint16_t stat_idx) { - /* Mellanox card does not have TTL support, + /* Mellanox card does not have TTL support, so we will replace it in low level with TOS */ int ret=rte_eth_dev_filter_supported(port_id, RTE_ETH_FILTER_FDIR); @@ -6502,8 +6595,8 @@ int CTRexExtendedDriverBaseMlnx5G::add_del_rx_flow_stat_rule(uint8_t port_id, en int CTRexExtendedDriverBaseMlnx5G::configure_rx_filter_rules_statfull(CPhyEthIF * _if) { uint32_t port_id = _if->get_port_id(); /* TTL==TOS */ - - /*PID=1 ==> MASK TOS=0x1/0x1*/ + + /*PID=1 ==> MASK TOS=0x1/0x1*/ add_del_rules(RTE_ETH_FILTER_ADD, port_id, RTE_ETH_FLOW_NONFRAG_IPV4_UDP, 0x1, 1, 17, MAIN_DPDK_RX_Q, 0); /*TCP/UDP */ add_del_rules(RTE_ETH_FILTER_ADD, port_id, RTE_ETH_FLOW_NONFRAG_IPV4_TCP, 0x1, 1, 6, MAIN_DPDK_RX_Q, 0); add_del_rules(RTE_ETH_FILTER_ADD, port_id, RTE_ETH_FLOW_NONFRAG_IPV4_OTHER, 0x1, 1, 132, MAIN_DPDK_RX_Q, 0); /*SCTP*/ @@ -6568,7 +6661,7 @@ void CTRexExtendedDriverBaseMlnx5G::get_extended_stats(CPhyEthIF * _if,CPhyEthIF rte_eth_stats_get(_if->get_port_id(), &stats1); stats->ipackets += stats1.ipackets - prev_stats->ipackets; - stats->ibytes += stats1.ibytes - prev_stats->ibytes + + 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 @@ -6742,7 +6835,7 @@ int CTRexExtendedDriverBaseVIC::configure_rx_filter_rules_statefull(CPhyEthIF * return 0; } -extern "C" int enicpmd_dev_get_fw_support(int port_id, +extern "C" int enicpmd_dev_get_fw_support(int port_id, uint32_t *ver); @@ -6753,7 +6846,7 @@ int CTRexExtendedDriverBaseVIC::verify_fw_ver(int port_id) { if (ret==0) { if (CGlobalInfo::m_options.preview.getVMode() >= 1) { - printf("VIC port %d: FW support advanced filtering \n", port_id); + printf("VIC port %d: FW support advanced filtering \n", port_id); } }else{ printf("Error: VIC firmware should upgrade to support advanced filtering \n"); @@ -6789,7 +6882,7 @@ int CTRexExtendedDriverBaseVIC::get_rx_stats(CPhyEthIF * _if, uint32_t *pkts, ui int CTRexExtendedDriverBaseVIC::dump_fdir_global_stats(CPhyEthIF * _if, FILE *fd) { //printf(" NOT supported yet \n"); - return (0); + return (0); } |