From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by dpdk.org (Postfix) with ESMTP id 4980E3784 for ; Fri, 4 Sep 2015 19:17:45 +0200 (CEST) Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id 82CDEC0ADB5E for ; Fri, 4 Sep 2015 17:17:44 +0000 (UTC) Received: from indiana.gru.redhat.com (ovpn-113-136.phx2.redhat.com [10.3.113.136]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t84HHhoZ024945 for ; Fri, 4 Sep 2015 13:17:43 -0400 From: Thadeu Lima de Souza Cascardo To: dev@dpdk.org Date: Fri, 4 Sep 2015 14:17:37 -0300 Message-Id: <1441387057-31525-1-git-send-email-cascardo@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 Subject: [dpdk-dev] [PATCH] app/testpmd: add engine for UDP echo server support X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 04 Sep 2015 17:17:45 -0000 Adapt the ICMP echo code to reply to UDP echo requests on port 7. The testpmd forward engine udpecho is used for that. Signed-off-by: Thadeu Lima de Souza Cascardo --- app/test-pmd/config.c | 7 ++- app/test-pmd/icmpecho.c | 90 ++++++++++++++++++++++------- app/test-pmd/testpmd.c | 1 + app/test-pmd/testpmd.h | 1 + doc/guides/testpmd_app_ug/run_app.rst | 2 +- doc/guides/testpmd_app_ug/testpmd_funcs.rst | 6 +- 6 files changed, 79 insertions(+), 28 deletions(-) diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index cf2aa6e..0b5c4e6 100644 --- a/app/test-pmd/config.c +++ b/app/test-pmd/config.c @@ -1239,7 +1239,7 @@ dcb_fwd_config_setup(void) } static void -icmp_echo_config_setup(void) +echo_config_setup(void) { portid_t rxp; queueid_t rxq; @@ -1297,8 +1297,9 @@ void fwd_config_setup(void) { cur_fwd_config.fwd_eng = cur_fwd_eng; - if (strcmp(cur_fwd_eng->fwd_mode_name, "icmpecho") == 0) { - icmp_echo_config_setup(); + if (strcmp(cur_fwd_eng->fwd_mode_name, "icmpecho") == 0 || + strcmp(cur_fwd_eng->fwd_mode_name, "udpecho") == 0) { + echo_config_setup(); return; } if ((nb_rxq > 1) && (nb_txq > 1)){ diff --git a/app/test-pmd/icmpecho.c b/app/test-pmd/icmpecho.c index e510f9b..a7f882a 100644 --- a/app/test-pmd/icmpecho.c +++ b/app/test-pmd/icmpecho.c @@ -61,6 +61,7 @@ #include #include #include +#include #include #include "testpmd.h" @@ -301,7 +302,7 @@ ipv4_hdr_cksum(struct ipv4_hdr *ip_h) * send back ICMP echo replies. */ static void -reply_to_icmp_echo_rqsts(struct fwd_stream *fs) +reply_to_echo_rqsts(struct fwd_stream *fs, int proto) { struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; struct rte_mbuf *pkt; @@ -310,6 +311,7 @@ reply_to_icmp_echo_rqsts(struct fwd_stream *fs) struct arp_hdr *arp_h; struct ipv4_hdr *ip_h; struct icmp_hdr *icmp_h; + struct udp_hdr *udp_h; struct ether_addr eth_addr; uint32_t ip_addr; uint16_t nb_rx; @@ -319,6 +321,7 @@ reply_to_icmp_echo_rqsts(struct fwd_stream *fs) uint16_t vlan_id; uint16_t arp_op; uint16_t arp_pro; + uint16_t udp_port; uint32_t cksum; uint8_t i; int l2_len; @@ -448,24 +451,40 @@ reply_to_icmp_echo_rqsts(struct fwd_stream *fs) ip_proto_name(ip_h->next_proto_id)); } - /* - * Check if packet is a ICMP echo request. - */ - icmp_h = (struct icmp_hdr *) ((char *)ip_h + - sizeof(struct ipv4_hdr)); - if (! ((ip_h->next_proto_id == IPPROTO_ICMP) && - (icmp_h->icmp_type == IP_ICMP_ECHO_REQUEST) && - (icmp_h->icmp_code == 0))) { - rte_pktmbuf_free(pkt); - continue; + if (proto == IPPROTO_ICMP) { + /* + * Check if packet is a ICMP echo request. + */ + icmp_h = (struct icmp_hdr *) ((char *)ip_h + + sizeof(struct ipv4_hdr)); + if (! ((ip_h->next_proto_id == IPPROTO_ICMP) && + (icmp_h->icmp_type == IP_ICMP_ECHO_REQUEST) && + (icmp_h->icmp_code == 0))) { + rte_pktmbuf_free(pkt); + continue; + } + } else if (proto == IPPROTO_UDP) { + udp_h = (struct udp_hdr *) ((char *)ip_h + + sizeof(struct ipv4_hdr)); + if ((ip_h->next_proto_id != IPPROTO_UDP) && + (rte_be_to_cpu_16(udp_h->dst_port) != 7)) { + rte_pktmbuf_free(pkt); + continue; + } } - if (verbose_level > 0) - printf(" ICMP: echo request seq id=%d\n", - rte_be_to_cpu_16(icmp_h->icmp_seq_nb)); + if (proto == IPPROTO_ICMP) { + if (verbose_level > 0) + printf(" ICMP: echo request seq id=%d\n", + rte_be_to_cpu_16(icmp_h->icmp_seq_nb)); + } else if (proto == IPPROTO_UDP) { + if (verbose_level > 0) + printf(" UDP: echo request from port=%d\n", + rte_be_to_cpu_16(udp_h->src_port)); + } /* - * Prepare ICMP echo reply to be sent back. + * Prepare ICMP or UDP echo reply to be sent back. * - switch ethernet source and destinations addresses, * - use the request IP source address as the reply IP * destination address, @@ -479,6 +498,8 @@ reply_to_icmp_echo_rqsts(struct fwd_stream *fs) * addresses in the reply IP header, * - keep the IP header checksum unchanged. * - set IP_ICMP_ECHO_REPLY in ICMP header. + * - switch the UDP source and destination ports in the UDP + * header. * ICMP checksum is computed by assuming it is valid in the * echo request and not verified. */ @@ -501,13 +522,19 @@ reply_to_icmp_echo_rqsts(struct fwd_stream *fs) ip_h->src_addr = ip_h->dst_addr; ip_h->dst_addr = ip_addr; } - icmp_h->icmp_type = IP_ICMP_ECHO_REPLY; - cksum = ~icmp_h->icmp_cksum & 0xffff; - cksum += ~htons(IP_ICMP_ECHO_REQUEST << 8) & 0xffff; - cksum += htons(IP_ICMP_ECHO_REPLY << 8); - cksum = (cksum & 0xffff) + (cksum >> 16); - cksum = (cksum & 0xffff) + (cksum >> 16); - icmp_h->icmp_cksum = ~cksum; + if (proto == IPPROTO_ICMP) { + icmp_h->icmp_type = IP_ICMP_ECHO_REPLY; + cksum = ~icmp_h->icmp_cksum & 0xffff; + cksum += ~htons(IP_ICMP_ECHO_REQUEST << 8) & 0xffff; + cksum += htons(IP_ICMP_ECHO_REPLY << 8); + cksum = (cksum & 0xffff) + (cksum >> 16); + cksum = (cksum & 0xffff) + (cksum >> 16); + icmp_h->icmp_cksum = ~cksum; + } else if (proto == IPPROTO_UDP) { + udp_port = udp_h->src_port; + udp_h->src_port = udp_h->dst_port; + udp_h->dst_port = udp_port; + } pkts_burst[nb_replies++] = pkt; } @@ -534,9 +561,28 @@ reply_to_icmp_echo_rqsts(struct fwd_stream *fs) #endif } +static void +reply_to_icmp_echo_rqsts(struct fwd_stream *fs) +{ + reply_to_echo_rqsts(fs, IPPROTO_ICMP); +} + +static void +reply_to_udp_echo_rqsts(struct fwd_stream *fs) +{ + reply_to_echo_rqsts(fs, IPPROTO_UDP); +} + struct fwd_engine icmp_echo_engine = { .fwd_mode_name = "icmpecho", .port_fwd_begin = NULL, .port_fwd_end = NULL, .packet_fwd = reply_to_icmp_echo_rqsts, }; + +struct fwd_engine udp_echo_engine = { + .fwd_mode_name = "udpecho", + .port_fwd_begin = NULL, + .port_fwd_end = NULL, + .packet_fwd = reply_to_udp_echo_rqsts, +}; diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c index 386bf84..b9a0ddb 100644 --- a/app/test-pmd/testpmd.c +++ b/app/test-pmd/testpmd.c @@ -151,6 +151,7 @@ struct fwd_engine * fwd_engines[] = { &tx_only_engine, &csum_fwd_engine, &icmp_echo_engine, + &udp_echo_engine, #ifdef RTE_LIBRTE_IEEE1588 &ieee1588_fwd_engine, #endif diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h index d287274..612a4f4 100644 --- a/app/test-pmd/testpmd.h +++ b/app/test-pmd/testpmd.h @@ -229,6 +229,7 @@ extern struct fwd_engine rx_only_engine; extern struct fwd_engine tx_only_engine; extern struct fwd_engine csum_fwd_engine; extern struct fwd_engine icmp_echo_engine; +extern struct fwd_engine udp_echo_engine; #ifdef RTE_LIBRTE_IEEE1588 extern struct fwd_engine ieee1588_fwd_engine; #endif diff --git a/doc/guides/testpmd_app_ug/run_app.rst b/doc/guides/testpmd_app_ug/run_app.rst index 54ae2b2..6ad168a 100644 --- a/doc/guides/testpmd_app_ug/run_app.rst +++ b/doc/guides/testpmd_app_ug/run_app.rst @@ -315,7 +315,7 @@ They must be separated from the EAL options, shown in the previous section, with * --forward-mode=N - Set forwarding mode. (N: io|mac|mac_retry|mac_swap|flowgen|rxonly|txonly|csum|icmpecho|ieee1588) + Set forwarding mode. (N: io|mac|mac_retry|mac_swap|flowgen|rxonly|txonly|csum|icmpecho|udpecho|ieee1588) * --rss-ip diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst index 3f076c8..1be0ae8 100644 --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst @@ -609,7 +609,7 @@ set fwd Set the packet forwarding mode: -set fwd (io|mac|mac_retry|macswap|flowgen|rxonly|txonly|csum|icmpecho) +set fwd (io|mac|mac_retry|macswap|flowgen|rxonly|txonly|csum|icmpecho|udpecho) The available information categories are: @@ -633,7 +633,9 @@ The available information categories are: * csum: changes the checksum field with HW or SW methods depending on the offload flags on the packet. -* icmpecho: receives a burst of packets, lookup for IMCP echo requests and, if any, send back ICMP echo replies. +* icmpecho: receives a burst of packets, lookup for ICMP echo requests and, if any, send back ICMP echo replies. + +* udpecho: receives a burst of packets, lookup for UDP echo requests and, if any, send back UDP echo replies. * ieee1588: demonstrate L2 IEEE1588 V2 PTP timestamping for RX and TX. Requires ``CONFIG_RTE_LIBRTE_IEEE1588=y``. Note: TX timestamping is only available in the "Full Featured" TX path. To force ``testpmd`` into this mode set ``--txqflags=0``. -- 2.4.3