add option to use DPDK tx checksum offloading to generate packets with correct IP...
authorMartin Weiser <[email protected]>
Fri, 15 Jul 2016 13:59:54 +0000 (15:59 +0200)
committerMartin Weiser <[email protected]>
Fri, 15 Jul 2016 13:59:54 +0000 (15:59 +0200)
linux_dpdk/ws_main.py
src/bp_sim.h
src/main_dpdk.cpp

index dde94dc..72ea5e3 100755 (executable)
@@ -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/
               ''';
 
index e396a71..18db61c 100755 (executable)
@@ -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);
index 45e4681..820371a 100644 (file)
@@ -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);
+               }
+    }
 }