summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Weiser <martin.weiser@allegro-packets.com>2016-07-15 15:59:54 +0200
committerMartin Weiser <martin.weiser@allegro-packets.com>2016-07-15 15:59:54 +0200
commit659ba2606be997631d736070d2efd92472496a11 (patch)
treec05dd3947851fcdbb2baa36cf7b57715ed237dec
parent783f8a04fb04266c6d6e9a857a74962e81db96df (diff)
add option to use DPDK tx checksum offloading to generate packets with correct IP, TCP and UDP checksums
-rwxr-xr-xlinux_dpdk/ws_main.py1
-rwxr-xr-xsrc/bp_sim.h58
-rw-r--r--src/main_dpdk.cpp24
3 files changed, 81 insertions, 2 deletions
diff --git a/linux_dpdk/ws_main.py b/linux_dpdk/ws_main.py
index dde94dc4..72ea5e3d 100755
--- a/linux_dpdk/ws_main.py
+++ b/linux_dpdk/ws_main.py
@@ -492,6 +492,7 @@ includes_path =''' ../src/pal/linux_dpdk/
../src/dpdk22/lib/librte_mempool/
../src/dpdk22/lib/librte_pipeline/
../src/dpdk22/lib/librte_ring/
+../src/dpdk22/lib/librte_net/
../src/dpdk22/
''';
diff --git a/src/bp_sim.h b/src/bp_sim.h
index e396a710..18db61ca 100755
--- a/src/bp_sim.h
+++ b/src/bp_sim.h
@@ -62,6 +62,10 @@ limitations under the License.
#include <trex_stateless_dp_core.h>
+#ifdef RTE_DPDK
+# include <rte_ip.h>
+#endif /* RTE_DPDK */
+
class CGenNodePCAP;
#undef NAT_TRACE_
@@ -707,6 +711,14 @@ public:
return (btGetMaskBit32(m_flags1, 7, 7) ? true : false);
}
+ void setChecksumOffloadEnable(bool enable) {
+ btSetMaskBit32(m_flags1, 8, 8, (enable ? 1 : 0) );
+ }
+
+ bool getChecksumOffloadEnable(){
+ return (btGetMaskBit32(m_flags1, 8, 8) ? true : false);
+ }
+
public:
void Dump(FILE *fd);
@@ -3106,7 +3118,15 @@ inline void CFlowPktInfo::update_pkt_info(char *p,
}
}
+#ifdef RTE_DPDK
+ if (CGlobalInfo::m_options.preview.getChecksumOffloadEnable()) {
+ ipv4->myChecksum = 0;
+ } else {
+ ipv4->updateCheckSum();
+ }
+#else
ipv4->updateCheckSum();
+#endif
}
@@ -3120,16 +3140,36 @@ inline void CFlowPktInfo::update_pkt_info(char *p,
}else{
m_tcp->setDestPort(src_port);
}
+
+#ifdef RTE_DPDK
+ if (CGlobalInfo::m_options.preview.getChecksumOffloadEnable()) {
+ /* set pseudo-header checksum */
+ m_tcp->setChecksum(PKT_NTOHS(rte_ipv4_phdr_cksum((struct ipv4_hdr *)ipv4->getPointer(),
+ PKT_TX_IPV4 | PKT_TX_IP_CKSUM | PKT_TX_TCP_CKSUM)));
+ }
+#endif
}else {
if ( m_pkt_indication.m_desc.IsUdp() ){
UDPHeader * m_udp =(UDPHeader *)(p +m_pkt_indication.getFastTcpOffset() );
BP_ASSERT(m_udp);
- m_udp->setChecksum(0);
+
if ( port_dir == CLIENT_SIDE ) {
m_udp->setSourcePort(src_port);
}else{
m_udp->setDestPort(src_port);
}
+
+#ifdef RTE_DPDK
+ if (CGlobalInfo::m_options.preview.getChecksumOffloadEnable()) {
+ /* set pseudo-header checksum */
+ m_udp->setChecksum(PKT_NTOHS(rte_ipv4_phdr_cksum((struct ipv4_hdr *) ipv4->getPointer(),
+ PKT_TX_IPV4 | PKT_TX_IP_CKSUM | PKT_TX_UDP_CKSUM)));
+ } else {
+ m_udp->setChecksum(0);
+ }
+#else
+ m_udp->setChecksum(0);
+#endif
}else{
#ifdef _DEBUG
if (!m_pkt_indication.m_desc.IsIcmp()) {
@@ -3260,6 +3300,22 @@ inline rte_mbuf_t * CFlowPktInfo::do_generate_new_mbuf(CGenNode * node){
memcpy(p,m_packet->raw,len);
+#ifdef RTE_DPDK
+ if (CGlobalInfo::m_options.preview.getChecksumOffloadEnable()) {
+ if (m_pkt_indication.m_desc.IsTcp()) {
+ m->l2_len = 14;
+ m->l3_len = 20;
+ m->ol_flags |= PKT_TX_IPV4 | PKT_TX_IP_CKSUM | PKT_TX_TCP_CKSUM;
+ } else {
+ if (m_pkt_indication.m_desc.IsUdp()) {
+ m->l2_len = 14;
+ m->l3_len = 20;
+ m->ol_flags |= PKT_TX_IPV4 | PKT_TX_IP_CKSUM | PKT_TX_UDP_CKSUM;
+ }
+ }
+ }
+#endif
+
update_pkt_info(p,node);
append_big_mbuf(m,node);
diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp
index 45e46810..820371ab 100644
--- a/src/main_dpdk.cpp
+++ b/src/main_dpdk.cpp
@@ -50,6 +50,7 @@
#include <rte_mbuf.h>
#include <rte_random.h>
#include <rte_version.h>
+#include <rte_ip.h>
#include "bp_sim.h"
#include "os_time.h"
@@ -555,7 +556,8 @@ enum { OPT_HELP,
OPT_MAC_SPLIT,
OPT_SEND_DEBUG_PKT,
OPT_NO_WATCHDOG,
- OPT_ALLOW_COREDUMP
+ OPT_ALLOW_COREDUMP,
+ OPT_CHECKSUM_OFFLOAD,
};
@@ -620,6 +622,7 @@ static CSimpleOpt::SOption parser_options[] =
{ OPT_MBUF_FACTOR , "--mbuf-factor", SO_REQ_SEP },
{ OPT_NO_WATCHDOG , "--no-watchdog", SO_NONE },
{ OPT_ALLOW_COREDUMP , "--allow-coredump", SO_NONE },
+ { OPT_CHECKSUM_OFFLOAD, "--checksum-offload", SO_NONE },
SO_END_OF_OPTIONS
@@ -725,6 +728,8 @@ static int usage(){
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(" \n");
+ printf(" --checksum-offload : enable IP, TCP and UDP tx checksum offloading with DPDK. This requires all used interfaces to support this \n");
printf(" \n");
printf(" Examples: ");
printf(" basic trex run for 10 sec and multiplier of x10 \n");
@@ -987,6 +992,10 @@ static int parse_options(int argc, char *argv[], CParserOption* po, bool first_t
po->m_debug_pkt_proto = (uint8_t)tmp_data;
break;
+ case OPT_CHECKSUM_OFFLOAD:
+ po->preview.setChecksumOffloadEnable(true);
+ break;
+
default:
usage();
@@ -1341,6 +1350,19 @@ void CPhyEthIF::configure(uint16_t nb_rx_queue,
/* get device info */
rte_eth_dev_info_get(m_port_id, &m_dev_info);
+ if (CGlobalInfo::m_options.preview.getChecksumOffloadEnable()) {
+ /* check if the device supports TCP and UDP checksum offloading */
+ if ((m_dev_info.tx_offload_capa & DEV_TX_OFFLOAD_UDP_CKSUM) == 0) {
+ rte_exit(EXIT_FAILURE, "Device does not support UDP checksum offload: "
+ "port=%u\n",
+ m_port_id);
+ }
+ if ((m_dev_info.tx_offload_capa & DEV_TX_OFFLOAD_TCP_CKSUM) == 0) {
+ rte_exit(EXIT_FAILURE, "Device does not support TCP checksum offload: "
+ "port=%u\n",
+ m_port_id);
+ }
+ }
}