Exemple #1
0
}

void CCPortLatency::Delete(){
    m_hist.Delete();
}

void CCPortLatency::update_packet(rte_mbuf_t * m, int port_id){
    uint8_t *p=rte_pktmbuf_mtod(m, uint8_t*);
    bool is_client_to_server=(port_id%2==0)?true:false;

    /* update mac addr dest/src 12 bytes */
    memcpy(p,CGlobalInfo::m_options.get_dst_src_mac_addr(m_id),12);

    latency_header * h=(latency_header *)(p+m_payload_offset);
    h->magic = LATENCY_MAGIC | m_id ;
    h->time_stamp = os_get_hr_tick_64();
    h->seq = m_tx_seq;
    m_tx_seq++;

    CLatencyPktMode *c_l_pkt_mode = m_parent->c_l_pkt_mode;
    c_l_pkt_mode->update_pkt(p + m_l4_offset, is_client_to_server, m_pkt_size - m_l4_offset, &m_icmp_tx_seq);    
}


void CCPortLatency::DumpShortHeader(FILE *fd){   
    fprintf(fd," if|   tx_ok , rx_ok  , rx check ,error,       latency (usec) ,    Jitter          max window \n");
	fprintf(fd,"   |         ,        ,          ,     ,   average   ,   max  ,    (usec)                     \n");
    fprintf(fd," ---------------------------------------------------------------------------------------------------------------- \n");
}

Exemple #2
0
// return false if no counters changed since last run. true otherwise
// s_json - flow statistics json
// l_json - latency data json
// baseline - If true, send flow statistics fields even if they were not changed since last run
bool CFlowStatRuleMgr::dump_json(std::string & s_json, std::string & l_json, bool baseline) {
    rx_per_flow_t rx_stats[MAX_FLOW_STATS];
    rx_per_flow_t rx_stats_payload[MAX_FLOW_STATS];
    tx_per_flow_t tx_stats[MAX_FLOW_STATS];
    tx_per_flow_t tx_stats_payload[MAX_FLOW_STATS_PAYLOAD];
    rfc2544_info_t rfc2544_info[MAX_FLOW_STATS_PAYLOAD];
    Json::FastWriter writer;
    Json::Value s_root;
    Json::Value l_root;

    s_root["name"] = "flow_stats";
    s_root["type"] = 0;
    l_root["name"] = "latency_stats";
    l_root["type"] = 0;

    if (baseline) {
        s_root["baseline"] = true;
        l_root["baseline"] = true;
    }

    Json::Value &s_data_section = s_root["data"];
    Json::Value &l_data_section = l_root["data"];
    s_data_section["ts"]["value"] = Json::Value::UInt64(os_get_hr_tick_64());
    s_data_section["ts"]["freq"] = Json::Value::UInt64(os_get_hr_freq());

    if (m_user_id_map.is_empty()) {
        s_json = writer.write(s_root);
        l_json = writer.write(l_root);
        return true;
    }

    m_api->get_rfc2544_info(rfc2544_info, 0, m_max_hw_id_payload, false);

    // read hw counters, and update
    for (uint8_t port = 0; port < m_num_ports; port++) {
        m_api->get_flow_stats(port, rx_stats, (void *)tx_stats, 0, m_max_hw_id, false, TrexPlatformApi::IF_STAT_IPV4_ID);
        for (int i = 0; i <= m_max_hw_id; i++) {
            if (rx_stats[i].get_pkts() != 0) {
                rx_per_flow_t rx_pkts = rx_stats[i];
                CFlowStatUserIdInfo *p_user_id = m_user_id_map.find_user_id(m_hw_id_map.get_user_id(i));
                if (likely(p_user_id != NULL)) {
                    if (p_user_id->get_rx_cntr(port) != rx_pkts) {
                        p_user_id->set_rx_cntr(port, rx_pkts);
                        p_user_id->set_need_to_send_rx(port);
                    }
                } else {
                    std::cerr <<  __METHOD_NAME__ << i << ":Could not count " << rx_pkts << " rx packets, on port "
                              << (uint16_t)port << ", because no mapping was found." << std::endl;
                }
            }
            if (tx_stats[i].get_pkts() != 0) {
                tx_per_flow_t tx_pkts = tx_stats[i];
                CFlowStatUserIdInfo *p_user_id = m_user_id_map.find_user_id(m_hw_id_map.get_user_id(i));
                if (likely(p_user_id != NULL)) {
                    if (p_user_id->get_tx_cntr(port) != tx_pkts) {
                        p_user_id->set_tx_cntr(port, tx_pkts);
                        p_user_id->set_need_to_send_tx(port);
                    }
                } else {
                    std::cerr <<  __METHOD_NAME__ << i << ":Could not count " << tx_pkts <<  " tx packets on port "
                              << (uint16_t)port << ", because no mapping was found." << std::endl;
                }
            }
        }
        // payload rules
        m_api->get_flow_stats(port, rx_stats_payload, (void *)tx_stats_payload, 0, m_max_hw_id_payload
                              , false, TrexPlatformApi::IF_STAT_PAYLOAD);
        for (int i = 0; i <= m_max_hw_id_payload; i++) {
            if (rx_stats_payload[i].get_pkts() != 0) {
                rx_per_flow_t rx_pkts = rx_stats_payload[i];
                CFlowStatUserIdInfo *p_user_id = m_user_id_map.find_user_id(m_hw_id_map_payload.get_user_id(i));
                if (likely(p_user_id != NULL)) {
                    if (p_user_id->get_rx_cntr(port) != rx_pkts) {
                        p_user_id->set_rx_cntr(port, rx_pkts);
                        p_user_id->set_need_to_send_rx(port);
                    }
                } else {
                    std::cerr <<  __METHOD_NAME__ << i << ":Could not count " << rx_pkts << " rx payload packets, on port "
                              << (uint16_t)port << ", because no mapping was found." << std::endl;
                }
            }
            if (tx_stats_payload[i].get_pkts() != 0) {
                tx_per_flow_t tx_pkts = tx_stats_payload[i];
                CFlowStatUserIdInfo *p_user_id = m_user_id_map.find_user_id(m_hw_id_map_payload.get_user_id(i));
                if (likely(p_user_id != NULL)) {
                    if (p_user_id->get_tx_cntr(port) != tx_pkts) {
                        p_user_id->set_tx_cntr(port, tx_pkts);
                        p_user_id->set_need_to_send_tx(port);
                    }
                } else {
                    std::cerr <<  __METHOD_NAME__ << i << ":Could not count " << tx_pkts <<  " tx packets on port "
                              << (uint16_t)port << ", because no mapping was found." << std::endl;
                }
            }
        }
    }

    // build json report
    flow_stat_user_id_map_it_t it;
    for (it = m_user_id_map.begin(); it != m_user_id_map.end(); it++) {
        bool send_empty = true;
        CFlowStatUserIdInfo *user_id_info = it->second;
        uint32_t user_id = it->first;
        std::string str_user_id = static_cast<std::ostringstream*>( &(std::ostringstream() << user_id) )->str();
        if (! user_id_info->was_sent()) {
            s_data_section[str_user_id]["first_time"] = true;
            user_id_info->set_was_sent(true);
            send_empty = false;
        }
        for (uint8_t port = 0; port < m_num_ports; port++) {
            std::string str_port = static_cast<std::ostringstream*>( &(std::ostringstream() << int(port) ) )->str();
            if (user_id_info->need_to_send_rx(port) || baseline) {
                user_id_info->set_no_need_to_send_rx(port);
                s_data_section[str_user_id]["rx_pkts"][str_port] = Json::Value::UInt64(user_id_info->get_rx_cntr(port).get_pkts());
                if (m_cap & TrexPlatformApi::IF_STAT_RX_BYTES_COUNT)
                    s_data_section[str_user_id]["rx_bytes"][str_port] = Json::Value::UInt64(user_id_info->get_rx_cntr(port).get_bytes());
                send_empty = false;
            }
            if (user_id_info->need_to_send_tx(port) || baseline) {
                user_id_info->set_no_need_to_send_tx(port);
                s_data_section[str_user_id]["tx_pkts"][str_port] = Json::Value::UInt64(user_id_info->get_tx_cntr(port).get_pkts());
                s_data_section[str_user_id]["tx_bytes"][str_port] = Json::Value::UInt64(user_id_info->get_tx_cntr(port).get_bytes());
                send_empty = false;
            }
        }
        if (send_empty) {
            s_data_section[str_user_id] = Json::objectValue;
        }

        if (user_id_info->rfc2544_support()) {
            CFlowStatUserIdInfoPayload *user_id_info_p = (CFlowStatUserIdInfoPayload *)user_id_info;
            // payload object. Send also latency, jitter...
            Json::Value lat_hist;
            if (user_id_info->is_hw_id()) {
                // if mapped to hw_id, take info from what we just got from rx core
                uint16_t hw_id = user_id_info->get_hw_id();
                rfc2544_info[hw_id].get_latency_json(lat_hist);
                user_id_info_p->set_seq_err_cnt(rfc2544_info[hw_id].get_seq_err_cnt());
                user_id_info_p->set_ooo_cnt(rfc2544_info[hw_id].get_ooo_cnt());
                user_id_info_p->set_dup_cnt(rfc2544_info[hw_id].get_dup_cnt());
                user_id_info_p->set_seq_err_big_cnt(rfc2544_info[hw_id].get_seq_err_ev_big());
                user_id_info_p->set_seq_err_low_cnt(rfc2544_info[hw_id].get_seq_err_ev_low());
                l_data_section[str_user_id]["latency"]["h"] = lat_hist;
                l_data_section[str_user_id]["latency"]["last_max"] = rfc2544_info[hw_id].get_last_max_usec();
                l_data_section[str_user_id]["latency"]["jitter"] = rfc2544_info[hw_id].get_jitter_usec();
            } else {
                // Not mapped to hw_id. Get saved info.
                user_id_info_p->get_latency_json(lat_hist);
                l_data_section[str_user_id]["latency"]["h"] = lat_hist;
                l_data_section[str_user_id]["latency"]["last_max"] = 0;
                l_data_section[str_user_id]["latency"]["jitter"] = user_id_info_p->get_jitter_usec();
            }
            //todo: add last 10 samples
            l_data_section[str_user_id]["err_cntrs"]["dropped"]
                = Json::Value::UInt64(user_id_info_p->get_seq_err_cnt());
            l_data_section[str_user_id]["err_cntrs"]["out_of_order"]
                = Json::Value::UInt64(user_id_info_p->get_ooo_cnt());
            l_data_section[str_user_id]["err_cntrs"]["dup"]
                = Json::Value::UInt64(user_id_info_p->get_dup_cnt());
            l_data_section[str_user_id]["err_cntrs"]["seq_too_high"]
                = Json::Value::UInt64(user_id_info_p->get_seq_err_big_cnt());
            l_data_section[str_user_id]["err_cntrs"]["seq_too_low"]
                = Json::Value::UInt64(user_id_info_p->get_seq_err_low_cnt());
        }
    }

    s_json = writer.write(s_root);
    l_json = writer.write(l_root);
    // We always want to publish, even only the timestamp.
    return true;
}