summaryrefslogtreecommitdiffstats
path: root/src/debug.cpp
diff options
context:
space:
mode:
authorIdo Barnea <ibarnea@cisco.com>2016-01-07 10:00:16 +0200
committerIdo Barnea <ibarnea@cisco.com>2016-01-07 10:00:16 +0200
commit429c0e40dae1b1d587ebdea18f92b57b53996c86 (patch)
treef7822ee1d100b3bdadea4f320ddde38ca579240e /src/debug.cpp
parentc068b9e06666534ac3a426cfe2eb8c3c844eaa95 (diff)
Added --send-debug-pkt
Moved code from main_dpdk.cpp to new files.
Diffstat (limited to 'src/debug.cpp')
-rw-r--r--src/debug.cpp330
1 files changed, 330 insertions, 0 deletions
diff --git a/src/debug.cpp b/src/debug.cpp
new file mode 100644
index 00000000..e5e207e1
--- /dev/null
+++ b/src/debug.cpp
@@ -0,0 +1,330 @@
+/*
+ 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.
+*/
+
+// DPDK c++ issue
+#define UINT8_MAX 255
+#define UINT16_MAX 0xFFFF
+// DPDK c++ issue
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <assert.h>
+#include <rte_mbuf.h>
+#include <rte_pci.h>
+#include <rte_ethdev.h>
+#include <common/basic_utils.h>
+#include "main_dpdk.h"
+#include "debug.h"
+
+const uint8_t udp_pkt[] = {
+ 0x00,0x00,0x00,0x01,0x00,0x00,
+ 0x00,0x00,0x00,0x01,0x00,0x00,
+ 0x08,0x00,
+
+ 0x45,0x00,0x00,0x81,
+ 0xaf,0x7e,0x00,0x00,
+ 0xfe,0x06,0xd9,0x23,
+ 0x01,0x01,0x01,0x01,
+ 0x3d,0xad,0x72,0x1b,
+
+ 0x11,0x11,
+ 0x11,0x11,
+ 0x00,0x6d,
+ 0x00,0x00,
+
+ 0x64,0x31,0x3a,0x61,
+ 0x64,0x32,0x3a,0x69,0x64,
+ 0x32,0x30,0x3a,0xd0,0x0e,
+ 0xa1,0x4b,0x7b,0xbd,0xbd,
+ 0x16,0xc6,0xdb,0xc4,0xbb,0x43,
+ 0xf9,0x4b,0x51,0x68,0x33,0x72,
+ 0x20,0x39,0x3a,0x69,0x6e,0x66,0x6f,
+ 0x5f,0x68,0x61,0x73,0x68,0x32,0x30,0x3a,0xee,0xc6,0xa3,
+ 0xd3,0x13,0xa8,0x43,0x06,0x03,0xd8,0x9e,0x3f,0x67,0x6f,
+ 0xe7,0x0a,0xfd,0x18,0x13,0x8d,0x65,0x31,0x3a,0x71,0x39,
+ 0x3a,0x67,0x65,0x74,0x5f,0x70,0x65,0x65,0x72,0x73,0x31,
+ 0x3a,0x74,0x38,0x3a,0x3d,0xeb,0x0c,0xbf,0x0d,0x6a,0x0d,
+ 0xa5,0x31,0x3a,0x79,0x31,0x3a,0x71,0x65,0x87,0xa6,0x7d,
+ 0xe7
+};
+
+CTrexDebug::CTrexDebug(CPhyEthIF m_ports_arg[12], int max_ports) {
+ m_test = NULL;
+ m_ports = m_ports_arg;
+ m_max_ports = max_ports;
+}
+
+int CTrexDebug::rcv_send(int port, int queue_id) {
+ CPhyEthIF * lp = &m_ports[port];
+ rte_mbuf_t * rx_pkts[32];
+ printf(" test rx port:%d queue:%d \n",port,queue_id);
+ printf(" --------------\n");
+ uint16_t cnt = lp->rx_burst(queue_id,rx_pkts,32);
+ int i;
+
+ for (i=0; i < (int)cnt; i++) {
+ rte_mbuf_t * m = rx_pkts[i];
+ int pkt_size = rte_pktmbuf_pkt_len(m);
+ char *p = rte_pktmbuf_mtod(m, char*);
+ utl_DumpBuffer(stdout, p, pkt_size, 0);
+ rte_pktmbuf_free(m);
+ }
+ return 0;
+}
+
+int CTrexDebug::rcv_send_all(int queue_id) {
+ int i;
+ for (i=0; i<m_max_ports; i++) {
+ rcv_send(i,queue_id);
+ }
+ return 0;
+}
+
+// For playing around, and testing packet sending in debug mode
+rte_mbuf_t *CTrexDebug::create_test_pkt(int pkt_type) {
+ uint8_t proto;
+ int pkt_size = 0;
+ // uint8_t dst_mac[6] = {0xd4, 0x8c, 0xb5, 0xc9, 0x54, 0x2b};
+ uint8_t dst_mac[6] = {0x79, 0xa2, 0xe6, 0xd5, 0x39, 0x25};
+ uint8_t src_mac[6] = {0xa0, 0x36, 0x9f, 0x38, 0xa4, 0x02};
+ uint16_t l2_proto = 0x0008;
+ uint8_t ip_header[] = {
+ 0x45,0x02,0x00,0x30,
+ 0x00,0x00,0x40,0x00,
+ 0xff,0x01,0xbd,0x04,
+ 0x10,0x0,0x0,0x1, //SIP
+ 0x30,0x0,0x0,0x1, //DIP
+ // 0x82, 0x0b, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // IP option. change 45 to 48 (header len) if using it.
+ };
+ uint8_t udp_header[] = {0x11, 0x11, 0x11,0x11, 0x00, 0x6d, 0x00, 0x00};
+ uint8_t udp_data[] = {0x64,0x31,0x3a,0x61,
+ 0x64,0x32,0x3a,0x69,0x64,
+ 0x32,0x30,0x3a,0xd0,0x0e,
+ 0xa1,0x4b,0x7b,0xbd,0xbd,
+ 0x16,0xc6,0xdb,0xc4,0xbb,0x43,
+ 0xf9,0x4b,0x51,0x68,0x33,0x72,
+ 0x20,0x39,0x3a,0x69,0x6e,0x66,0x6f,
+ 0x5f,0x68,0x61,0x73,0x68,0x32,0x30,0x3a,0xee,0xc6,0xa3,
+ 0xd3,0x13,0xa8,0x43,0x06,0x03,0xd8,0x9e,0x3f,0x67,0x6f,
+ 0xe7,0x0a,0xfd,0x18,0x13,0x8d,0x65,0x31,0x3a,0x71,0x39,
+ 0x3a,0x67,0x65,0x74,0x5f,0x70,0x65,0x65,0x72,0x73,0x31,
+ 0x3a,0x74,0x38,0x3a,0x3d,0xeb,0x0c,0xbf,0x0d,0x6a,0x0d,
+ 0xa5,0x31,0x3a,0x79,0x31,0x3a,0x71,0x65,0x87,0xa6,0x7d,
+ 0xe7
+ };
+ uint8_t tcp_header[] = {0xab, 0xcd, 0x00, 0x80, // src, dst ports
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // seq num, ack num
+ 0x50, 0x00, 0xff, 0xff, // Header size, flags, window size
+ 0x00, 0x00, 0x00, 0x00, // checksum ,urgent pointer
+ };
+
+ uint8_t tcp_data[] = {0x8, 0xa, 0x1, 0x2, 0x3, 0x4, 0x3, 0x4, 0x6, 0x5};
+
+ uint8_t icmp_header[] = {
+ 0x08, 0x00,
+ 0xb8, 0x21, //checksum
+ 0xaa, 0xbb, // id
+ 0x00, 0x01, // Sequence number
+ };
+ uint8_t icmp_data[] = {
+ 0xd6, 0x6e, 0x64, 0x34, // magic
+ 0x6a, 0xad, 0x0f, 0x00, //64 bit counter
+ 0x00, 0x56, 0x34, 0x12,
+ 0x78, 0x56, 0x34, 0x12, 0x00, 0x00 // seq
+ };
+
+ switch (pkt_type) {
+ case 1:
+ proto = IPPROTO_ICMP;
+ pkt_size = 14 + sizeof(ip_header) + sizeof(icmp_header) + sizeof (icmp_data);
+ break;
+ case 2:
+ proto = IPPROTO_UDP;
+ pkt_size = 14 + sizeof(ip_header) + sizeof(udp_header) + sizeof (udp_data);
+ break;
+ case 3:
+ proto = IPPROTO_TCP;
+ pkt_size = 14 + sizeof(ip_header) + sizeof(tcp_header) + sizeof (tcp_data);
+ break;
+ default:
+ return NULL;
+ }
+
+ rte_mbuf_t *m = CGlobalInfo::pktmbuf_alloc(0, pkt_size);
+ if ( unlikely(m == 0) ) {
+ printf("ERROR no packets \n");
+ return (NULL);
+ }
+ char *p = rte_pktmbuf_append(m, pkt_size);
+ assert(p);
+
+ /* set pkt data */
+ memcpy(p, dst_mac, sizeof(dst_mac)); p += sizeof(dst_mac);
+ memcpy(p, src_mac, sizeof(src_mac)); p += sizeof(src_mac);
+ memcpy(p, &l2_proto, sizeof(l2_proto)); p += sizeof(l2_proto);
+ struct IPHeader *ip = (IPHeader *)p;
+ memcpy(p, ip_header, sizeof(ip_header)); p += sizeof(ip_header);
+ ip->setProtocol(proto);
+ ip->setTotalLength(pkt_size - 14);
+
+ struct TCPHeader *tcp = (TCPHeader *)p;
+ struct ICMPHeader *icmp= (ICMPHeader *)p;
+ switch (pkt_type) {
+ case 1:
+ memcpy(p, icmp_header, sizeof(icmp_header)); p += sizeof(icmp_header);
+ memcpy(p, icmp_data, sizeof(icmp_data)); p += sizeof(icmp_data);
+ icmp->updateCheckSum(sizeof(icmp_header) + sizeof(icmp_data));
+ break;
+ case 2:
+ memcpy(p, udp_header, sizeof(udp_header)); p += sizeof(udp_header);
+ memcpy(p, udp_data, sizeof(udp_data)); p += sizeof(udp_data);
+ break;
+ case 3:
+ memcpy(p, tcp_header, sizeof(tcp_header)); p += sizeof(tcp_header);
+ memcpy(p, tcp_data, sizeof(tcp_data)); p += sizeof(tcp_data);
+ tcp->setSynFlag(true);
+ printf("Sending TCP header:");
+ tcp->dump(stdout);
+ break;
+ default:
+ return NULL;
+ }
+
+ ip->updateCheckSum();
+ return m;
+}
+
+rte_mbuf_t *CTrexDebug::create_pkt(uint8_t *pkt, int pkt_size) {
+ rte_mbuf_t *m = CGlobalInfo::pktmbuf_alloc(0, pkt_size);
+ if ( unlikely(m == 0) ) {
+ printf("ERROR no packets \n");
+ return 0;
+ }
+
+ char *p = rte_pktmbuf_append(m, pkt_size);
+ assert(p);
+ /* set pkt data */
+ memcpy(p, pkt, pkt_size);
+ return m;
+}
+
+rte_mbuf_t *CTrexDebug::create_pkt_indirect(rte_mbuf_t *m, uint32_t new_pkt_size){
+ rte_mbuf_t *d = CGlobalInfo::pktmbuf_alloc(0, 60);
+ assert(d);
+
+ rte_pktmbuf_attach(d, m);
+ d->data_len = new_pkt_size;
+ d->pkt_len = new_pkt_size;
+ return d;
+}
+
+rte_mbuf_t *CTrexDebug::create_udp_9k_pkt() {
+ rte_mbuf_t *m;
+ uint16_t pkt_size = 9*1024+21;
+ uint8_t *p = (uint8_t *)malloc(9*1024+22);
+ assert(p);
+ memset(p, 0x55, pkt_size);
+ memcpy(p, (uint8_t*)udp_pkt, sizeof(udp_pkt));
+ m = create_pkt(p, pkt_size);
+ free(p);
+ return m;
+}
+
+int CTrexDebug::test_send_pkts(rte_mbuf_t *m, uint16_t queue_id, int num_pkts, int port) {
+ CPhyEthIF * lp = &m_ports[port];
+ rte_mbuf_t * tx_pkts[32];
+ if (num_pkts > 32) {
+ num_pkts = 32;
+ }
+
+ int i;
+ for (i=0; i < num_pkts; i++) {
+ rte_mbuf_refcnt_update(m, 1);
+ tx_pkts[i] = m;
+ }
+ uint16_t res = lp->tx_burst(queue_id, tx_pkts, num_pkts);
+ if ((num_pkts - res) > 0) {
+ m_test_drop += (num_pkts - res);
+ }
+ return (0);
+}
+
+int CTrexDebug::set_promisc_all(bool enable) {
+ int i;
+ for (i=0; i < m_max_ports; i++) {
+ CPhyEthIF *_if = &m_ports[i];
+ _if->set_promiscuous(enable);
+ }
+
+ return 0;
+}
+
+int CTrexDebug::test_send(uint pkt_type) {
+ set_promisc_all(true);
+ rte_mbuf_t *m, *d;
+ if (pkt_type < 1 || pkt_type > 4) {
+ printf("Unsupported packet type %d\n", pkt_type);
+ printf("Supported packet types are: %d(ICMP), %d(UDP), %d(TCP) %d(9k UDP)\n", 1, 2, 3, 4);
+ exit(-1);
+ }
+
+ if (pkt_type == 4) {
+ m = create_udp_9k_pkt();
+ assert (m);
+ d = create_pkt_indirect(m, 9*1024+18);
+ } else {
+ d = create_test_pkt(pkt_type);
+ }
+ if (d == NULL) {
+ printf("Packet creation failed\n");
+ exit(-1);
+ }
+
+ printf("Sending packet:\n");
+ utl_DumpBuffer(stdout, rte_pktmbuf_mtod(d, char *), 64, 0);
+
+ test_send_pkts(d, 0, 2, 0);
+ test_send_pkts(d, 0, 1, 1);
+
+ delay(1000);
+
+ printf(" ---------\n");
+ printf(" rx queue 0 \n");
+ printf(" ---------\n");
+ rcv_send_all(0);
+ printf("\n\n");
+
+ printf(" ---------\n");
+ printf(" rx queue 1 \n");
+ printf(" ---------\n");
+ rcv_send_all(1);
+ printf(" ---------\n");
+
+ delay(1000);
+
+ int j=0;
+ for (j=0; j<m_max_ports; j++) {
+ CPhyEthIF * lp=&m_ports[j];
+ printf(" port : %d \n",j);
+ printf(" ----------\n");
+ lp->update_counters();
+ lp->get_stats().Dump(stdout);
+ lp->dump_stats_extended(stdout);
+ }
+
+ return (0);
+}