summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIdo Barnea <ibarnea@cisco.com>2016-09-26 16:26:37 +0300
committerIdo Barnea <ibarnea@cisco.com>2016-10-05 10:45:28 +0300
commit2223955b8eb3b378c1ab79e3735ed340852b04b9 (patch)
tree334b533001dd013a5e5293f61b835341fdf1f300
parenta42bf7bc43e78e63c266c22cccf15ce3f4cab297 (diff)
pre test: Some small fixes
-rwxr-xr-xsrc/bp_sim.h8
-rw-r--r--src/common/Network/Packet/Arp.h46
-rwxr-xr-xsrc/common/Network/Packet/MacAddress.h11
-rw-r--r--src/latency.cpp15
-rw-r--r--src/main_dpdk.cpp32
-rw-r--r--src/pre_test.cpp50
-rw-r--r--src/pre_test.h3
-rw-r--r--src/test_pkt_gen.cpp24
8 files changed, 128 insertions, 61 deletions
diff --git a/src/bp_sim.h b/src/bp_sim.h
index 5f21ca26..d28968f6 100755
--- a/src/bp_sim.h
+++ b/src/bp_sim.h
@@ -701,19 +701,19 @@ class CPerPortIPCfg {
uint32_t get_mask() {return m_mask;}
uint32_t get_def_gw() {return m_def_gw;}
uint32_t get_vlan() {return m_vlan;}
- bool is_loopback() {return m_is_loopback;}
+ bool grat_arp_needed() {return m_grat_arp_needed;}
void set_ip(uint32_t val) {m_ip = val;}
void set_mask(uint32_t val) {m_mask = val;}
void set_def_gw(uint32_t val) {m_def_gw = val;}
void set_vlan(uint16_t val) {m_vlan = val;}
- void set_loopback(bool val) {m_is_loopback = val;}
+ void set_grat_arp_needed(bool val) {m_grat_arp_needed = val;}
private:
uint32_t m_def_gw;
uint32_t m_ip;
uint32_t m_mask;
uint16_t m_vlan;
- bool m_is_loopback;
+ bool m_grat_arp_needed;
};
class CParserOption {
@@ -767,6 +767,7 @@ public:
m_run_mode = RUN_MODE_INVALID;
m_l_pkt_mode = 0;
m_rx_thread_enabled = false;
+ m_arp_ref_per = 120; // in seconds
}
@@ -793,6 +794,7 @@ public:
uint8_t m_l_pkt_mode;
uint8_t m_learn_mode;
uint16_t m_debug_pkt_proto;
+ uint16_t m_arp_ref_per;
bool m_rx_thread_enabled;
trex_run_mode_e m_run_mode;
diff --git a/src/common/Network/Packet/Arp.h b/src/common/Network/Packet/Arp.h
new file mode 100644
index 00000000..a16605bd
--- /dev/null
+++ b/src/common/Network/Packet/Arp.h
@@ -0,0 +1,46 @@
+/*
+Copyright (c) 2016-2016 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.
+*/
+#ifndef _ARP_H_
+#define _ARP_H_
+#include "MacAddress.h"
+
+#pragma pack(push, 1)
+class ArpHdr {
+ public:
+ enum arp_hdr_enum_e {
+ ARP_HDR_HRD_ETHER = 1,
+ ARP_HDR_OP_REQUEST = 1, /* request to resolve address */
+ ARP_HDR_OP_REPLY = 2, /* response to previous request */
+ ARP_HDR_OP_REVREQUEST = 3, /* request proto addr given hardware */
+ ARP_HDR_OP_REVREPLY = 4, /* response giving protocol address */
+ ARP_HDR_OP_INVREQUEST = 5, /* request to identify peer */
+ ARP_HDR_OP_INVREPLY = 6, /* response identifying peer */
+ };
+
+ public:
+ uint16_t m_arp_hrd; /* format of hardware address */
+ uint16_t m_arp_pro; /* format of protocol address */
+ uint8_t m_arp_hln; /* length of hardware address */
+ uint8_t m_arp_pln; /* length of protocol address */
+ uint16_t m_arp_op; /* ARP opcode (command) */
+ MacAddress m_arp_sha; /**< sender hardware address */
+ uint32_t m_arp_sip; /**< sender IP address */
+ MacAddress m_arp_tha; /**< target hardware address */
+ uint32_t m_arp_tip; /**< target IP address */
+};
+#pragma pack(pop)
+
+#endif
diff --git a/src/common/Network/Packet/MacAddress.h b/src/common/Network/Packet/MacAddress.h
index 69272339..7e872fd6 100755
--- a/src/common/Network/Packet/MacAddress.h
+++ b/src/common/Network/Packet/MacAddress.h
@@ -19,7 +19,10 @@ limitations under the License.
#include "CPktCmn.h"
-
+#ifndef ETHER_ADDR_LEN
+#define ETHER_ADDR_LEN 6 /**< Length of Ethernet address. */
+#endif
+
class MacAddress
{
public:
@@ -44,7 +47,7 @@ public:
a5);
};
- MacAddress(uint8_t macAddr[6])
+ MacAddress(uint8_t macAddr[ETHER_ADDR_LEN])
{
set(macAddr[0],
macAddr[1],
@@ -97,7 +100,7 @@ public:
bool operator == (const MacAddress& rhs) const
{
- for(int i=0; i<6; i++)
+ for(int i = 0; i < ETHER_ADDR_LEN; i++)
{
if(data[i] != rhs.data[i])
return false;
@@ -124,7 +127,7 @@ public:
}
public:
- uint8_t data[6];
+ uint8_t data[ETHER_ADDR_LEN];
};
#endif //_MAC_ADDRESS_H_
diff --git a/src/latency.cpp b/src/latency.cpp
index 675cf80a..76f12b46 100644
--- a/src/latency.cpp
+++ b/src/latency.cpp
@@ -583,8 +583,7 @@ void CLatencyManager::send_pkt_all_ports(){
void CLatencyManager::send_grat_arp_all_ports() {
for (int port_id = 0; port_id < m_max_ports; port_id++) {
- // if port is connected in loopback, no need to send. It will only confuse our ingress counters.
- if (CGlobalInfo::m_options.m_ip_cfg[port_id].is_loopback())
+ if (! CGlobalInfo::m_options.m_ip_cfg[port_id].grat_arp_needed())
continue;
CLatencyManagerPerPort * lp = &m_ports[port_id];
@@ -750,10 +749,12 @@ void CLatencyManager::start(int iter, bool activate_watchdog) {
node->m_time = now_sec(); /* 1/cps rate */
m_p_queue.push(node);
- node = new CGenNode();
- node->m_type = CGenNode::GRAT_ARP; /* gratuitous ARP */
- node->m_time = now_sec() + 120;
- m_p_queue.push(node);
+ if (CGlobalInfo::m_options.m_arp_ref_per > 0) {
+ node = new CGenNode();
+ node->m_type = CGenNode::GRAT_ARP; /* gratuitous ARP */
+ node->m_time = now_sec() + CGlobalInfo::m_options.m_arp_ref_per;
+ m_p_queue.push(node);
+ }
bool do_try_rx_queue = CGlobalInfo::m_options.preview.get_vm_one_queue_enable() ? true : false;
@@ -806,7 +807,7 @@ void CLatencyManager::start(int iter, bool activate_watchdog) {
m_cpu_dp_u.start_work1();
send_grat_arp_all_ports();
m_p_queue.pop();
- node->m_time += 120; // every two minutes
+ node->m_time += CGlobalInfo::m_options.m_arp_ref_per;
m_p_queue.push(node);
m_cpu_dp_u.commit1();
break;
diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp
index e1cbf9de..a6ea3876 100644
--- a/src/main_dpdk.cpp
+++ b/src/main_dpdk.cpp
@@ -544,6 +544,7 @@ enum { OPT_HELP,
OPT_ALLOW_COREDUMP,
OPT_CHECKSUM_OFFLOAD,
OPT_CLOSE,
+ OPT_ARP_REF_PER,
};
/* these are the argument types:
@@ -601,6 +602,7 @@ static CSimpleOpt::SOption parser_options[] =
{ OPT_ALLOW_COREDUMP , "--allow-coredump", SO_NONE },
{ OPT_CHECKSUM_OFFLOAD, "--checksum-offload", SO_NONE },
{ OPT_CLOSE, "--close-at-end", SO_NONE },
+ { OPT_ARP_REF_PER, "--arp-refresh-period", SO_REQ_SEP },
SO_END_OF_OPTIONS
};
@@ -619,7 +621,7 @@ static int usage(){
printf(" --client_cfg [file] : YAML file which describes clients configuration\n");
printf(" \n\n");
- printf(" -c [number of threads] : default is 1. number of threads to allocate for each dual ports. \n");
+ printf(" -c [number of threads] : Default is 1. Number of threads to allocate for each port pair. \n");
printf(" \n");
printf(" -s : run only one data path core. for debug\n");
printf(" \n");
@@ -697,16 +699,17 @@ static int usage(){
printf(" This it temporary option. Will be removed in the future.\n");
printf(" --no-key : daemon mode, don't get input from keyboard \n");
printf(" --no-flow-control-change : By default TRex disables flow-control. If this option is given, it does not touch it\n");
- printf(" --prefix : for multi trex, each instance should have a different name \n");
- printf(" --mbuf-factor : factor for packet memory \n");
+ printf(" --prefix : For multi trex, each instance should have a different name \n");
+ printf(" --mbuf-factor : Factor for packet memory \n");
printf(" \n");
- printf(" --no-watchdog : disable watchdog \n");
+ printf(" --no-watchdog : Disable watchdog \n");
printf(" \n");
- printf(" --allow-coredump : allow a creation of core dump \n");
+ printf(" --allow-coredump : Allow a creation of core dump \n");
printf(" \n");
- printf(" --vm-sim : simulate vm with driver of one input queue and one output queue \n");
+ printf(" --vm-sim : Simulate vm with driver of one input queue and one output queue \n");
printf(" \n");
- printf(" --checksum-offload : enable IP, TCP and UDP tx checksum offloading with DPDK. This requires all used interfaces to support this \n");
+ printf(" --checksum-offload : Enable IP, TCP and UDP tx checksum offloading with DPDK. This requires all used interfaces to support this \n");
+ printf(" --arp-refresh-period : Period in seconds between sending of gratuitous ARP for out addresses. Value of 0, means 'never send'\n");
printf(" \n");
printf(" Examples: ");
printf(" basic trex run for 10 sec and multiplier of x10 \n");
@@ -984,6 +987,10 @@ static int parse_options(int argc, char *argv[], CParserOption* po, bool first_t
case OPT_CLOSE:
po->preview.setCloseEnable(true);
break;
+ case OPT_ARP_REF_PER:
+ sscanf(args.OptionArg(),"%d", &tmp_data);
+ po->m_arp_ref_per=(uint16_t)tmp_data;
+ break;
default:
usage();
@@ -2975,7 +2982,7 @@ public:
};
-// Before starting, send gratitues ARP on our addresses, and try to resolve dst MAC addresses.
+// Before starting, send gratuitous ARP on our addresses, and try to resolve dst MAC addresses.
void CGlobalTRex::pre_test() {
CPretest pretest(m_max_ports);
bool resolve_needed = false;
@@ -2993,6 +3000,10 @@ void CGlobalTRex::pre_test() {
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);
}
pretest.set_port_params(port_id, CGlobalInfo::m_options.m_ip_cfg[port_id]
, CGlobalInfo::m_options.m_mac_addr[port_id].u.m_mac.src
@@ -3007,6 +3018,7 @@ void CGlobalTRex::pre_test() {
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();
if (! pretest.get_mac(port_id, ip, mac)) {
fprintf(stderr, "Failed resolving dest MAC for default gateway:%d.%d.%d.%d on port %d\n"
@@ -3014,7 +3026,9 @@ void CGlobalTRex::pre_test() {
exit(1);
}
memcpy(CGlobalInfo::m_options.m_mac_addr[port_id].u.m_mac.dest, mac, ETHER_ADDR_LEN);
- CGlobalInfo::m_options.m_ip_cfg[port_id].set_loopback(pretest.is_loopback(port_id));
+ // 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);
}
CPhyEthIF *pif = &m_ports[port_id];
diff --git a/src/pre_test.cpp b/src/pre_test.cpp
index b1401112..0639d9c8 100644
--- a/src/pre_test.cpp
+++ b/src/pre_test.cpp
@@ -19,10 +19,10 @@
limitations under the License.
*/
-#include <rte_arp.h>
#include <rte_ethdev.h>
#include <arpa/inet.h>
#include <common/Network/Packet/EthernetHeader.h>
+#include <common/Network/Packet/Arp.h>
#include "common/basic_utils.h"
#include "bp_sim.h"
#include "main_dpdk.h"
@@ -111,22 +111,22 @@ int CPretest::handle_rx(int port_id, int queue_id) {
rte_mbuf_t * m = rx_pkts[i];
int pkt_size = rte_pktmbuf_pkt_len(m);
uint8_t *p = rte_pktmbuf_mtod(m, uint8_t *);
- struct arp_hdr *arp;
+ ArpHdr *arp;
CPretestPortInfo *port = &m_port_info[port_id];
if (is_arp(p, pkt_size, arp)) {
- if (arp->arp_op == htons(ARP_OP_REQUEST)) {
- if (verbose >= 3) {
- fprintf(stdout, "RX ARP request on port %d queue %d sip:0x%08x tip:0x%08x\n", port_id, queue_id
- , ntohl(arp->arp_data.arp_sip)
- , ntohl(arp->arp_data.arp_tip));
- }
+ if (arp->m_arp_op == htons(ArpHdr::ARP_HDR_OP_REQUEST)) {
+ if (verbose >= 3) {
+ fprintf(stdout, "RX ARP request on port %d queue %d sip:0x%08x tip:0x%08x\n", port_id, queue_id
+ , ntohl(arp->m_arp_sip)
+ , ntohl(arp->m_arp_tip));
+ }
// is this request for our IP?
- if (ntohl(arp->arp_data.arp_tip) == port->m_ip) {
+ if (ntohl(arp->m_arp_tip) == port->m_ip) {
// If our request(i.e. we are connected in loopback)
// , do a shortcut, and write info directly to asking port
uint8_t magic[5] = {0x1, 0x3, 0x5, 0x7, 0x9};
- if (! memcmp((uint8_t *)&arp->arp_data.arp_tha, magic, 5)) {
- uint8_t sent_port_id = arp->arp_data.arp_tha.addr_bytes[5];
+ if (! memcmp((uint8_t *)&arp->m_arp_tha.data, magic, 5)) {
+ uint8_t sent_port_id = arp->m_arp_tha.data[5];
if ((sent_port_id < m_max_ports) &&
(m_port_info[sent_port_id].m_def_gw == port->m_ip)) {
memcpy(m_port_info[sent_port_id].m_dst_mac, port->m_src_mac, ETHER_ADDR_LEN);
@@ -137,19 +137,19 @@ int CPretest::handle_rx(int port_id, int queue_id) {
} else {
// ARP request not to our IP. At the moment, we ignore this.
}
- } else {
- if (arp->arp_op == htons(ARP_OP_REPLY)) {
- if (verbose >= 3) {
- fprintf(stdout, "RX ARP response on port %d queue %d sip:0x%08x tip:0x%08x\n", port_id, queue_id
- , ntohl(arp->arp_data.arp_sip)
- , ntohl(arp->arp_data.arp_tip));
- }
- // If this is response to our request, update our tables
- if (port->m_def_gw == ntohl(arp->arp_data.arp_sip)) {
- port->set_dst_mac((uint8_t *)&arp->arp_data.arp_sha);
- }
+ } else {
+ if (arp->m_arp_op == htons(ArpHdr::ARP_HDR_OP_REPLY)) {
+ if (verbose >= 3) {
+ fprintf(stdout, "RX ARP response on port %d queue %d sip:0x%08x tip:0x%08x\n", port_id, queue_id
+ , ntohl(arp->m_arp_sip)
+ , ntohl(arp->m_arp_tip));
+ }
+ // If this is response to our request, update our tables
+ if (port->m_def_gw == ntohl(arp->m_arp_sip)) {
+ port->set_dst_mac((uint8_t *)&arp->m_arp_sha);
}
}
+ }
}
rte_pktmbuf_free(m);
@@ -256,7 +256,7 @@ void CPretest::send_grat_arp_all() {
}
}
-bool CPretest::is_arp(const uint8_t *p, uint16_t pkt_size, struct arp_hdr *&arp) {
+bool CPretest::is_arp(const uint8_t *p, uint16_t pkt_size, ArpHdr *&arp) {
EthernetHeader *m_ether = (EthernetHeader *)p;
if ((pkt_size < 60) ||
@@ -265,12 +265,12 @@ bool CPretest::is_arp(const uint8_t *p, uint16_t pkt_size, struct arp_hdr *&arp)
return false;
if (m_ether->getNextProtocol() == EthernetHeader::Protocol::ARP) {
- arp = (struct arp_hdr *)(p + 14);
+ arp = (ArpHdr *)(p + 14);
} else {
if (m_ether->getVlanProtocol() != EthernetHeader::Protocol::ARP) {
return false;
} else {
- arp = (struct arp_hdr *)(p + 18);
+ arp = (ArpHdr *)(p + 18);
}
}
diff --git a/src/pre_test.h b/src/pre_test.h
index bd908cbb..7bbeb40d 100644
--- a/src/pre_test.h
+++ b/src/pre_test.h
@@ -23,6 +23,7 @@
#define __PRE_TEST_H__
#include <iostream>
+#include <common/Network/Packet/Arp.h>
#include "bp_sim.h"
#include "trex_defs.h"
@@ -68,7 +69,7 @@ class CPretest {
bool resolve_all();
void send_arp_req(uint16_t port, bool is_grat);
void send_grat_arp_all();
- bool is_arp(const uint8_t *p, uint16_t pkt_size, struct arp_hdr *&arp);
+ bool is_arp(const uint8_t *p, uint16_t pkt_size, ArpHdr *&arp);
void dump(FILE *fd);
void test();
diff --git a/src/test_pkt_gen.cpp b/src/test_pkt_gen.cpp
index 14547c41..502e84dc 100644
--- a/src/test_pkt_gen.cpp
+++ b/src/test_pkt_gen.cpp
@@ -21,13 +21,13 @@
#include <assert.h>
#include <netinet/in.h>
-#include <rte_arp.h>
#include <common/Network/Packet/TcpHeader.h>
#include <common/Network/Packet/UdpHeader.h>
#include <common/Network/Packet/IcmpHeader.h>
#include <common/Network/Packet/IPHeader.h>
#include <common/Network/Packet/IPv6Header.h>
#include <common/Network/Packet/EthernetHeader.h>
+#include <common/Network/Packet/Arp.h>
#include "rx_check_header.h"
#include "test_pkt_gen.h"
@@ -267,18 +267,18 @@ void CTestPktGen::create_arp_req(uint8_t *pkt, uint32_t sip, uint32_t tip, uint8
memcpy(pkt, &l2_proto, sizeof(l2_proto));
pkt += 2;
- struct arp_hdr *arp = (struct arp_hdr *)pkt;
- arp->arp_hrd = htons(ARP_HRD_ETHER); // Format of hardware address
- arp->arp_pro = htons(EthernetHeader::Protocol::IP); // Format of protocol address
- arp->arp_hln = ETHER_ADDR_LEN; // Length of hardware address
- arp->arp_pln = 4; // Length of protocol address
- arp->arp_op = htons(ARP_OP_REQUEST); // ARP opcode (command)
+ ArpHdr *arp = (ArpHdr *)pkt;
+ arp->m_arp_hrd = htons(ArpHdr::ARP_HDR_HRD_ETHER); // Format of hardware address
+ arp->m_arp_pro = htons(EthernetHeader::Protocol::IP); // Format of protocol address
+ arp->m_arp_hln = ETHER_ADDR_LEN; // Length of hardware address
+ arp->m_arp_pln = 4; // Length of protocol address
+ arp->m_arp_op = htons(ArpHdr::ARP_HDR_OP_REQUEST); // ARP opcode (command)
- memcpy(&arp->arp_data.arp_sha, src_mac, ETHER_ADDR_LEN); // Sender MAC address
- arp->arp_data.arp_sip = htonl(sip); // Sender IP address
+ memcpy(&arp->m_arp_sha.data, src_mac, ETHER_ADDR_LEN); // Sender MAC address
+ arp->m_arp_sip = htonl(sip); // Sender IP address
uint8_t magic[5] = {0x1, 0x3, 0x5, 0x7, 0x9};
- memcpy(&arp->arp_data.arp_tha, magic, 5); // Target MAC address
- arp->arp_data.arp_tha.addr_bytes[5] = port;
- arp->arp_data.arp_tip = htonl(tip);
+ memcpy(&arp->m_arp_tha.data, magic, 5); // Target MAC address
+ arp->m_arp_tha.data[5] = port;
+ arp->m_arp_tip = htonl(tip);
}