On Thu, Jun 26, 2014 at 09:22:40PM +0100, Bruce Richardson wrote:
> This is a very simple example app for doing packet forwarding with the
> Intel DPDK. It's designed to serve as a start point for people new to
> the Intel DPDK and who want to develop a new app.
> 
> Therefore it's meant to:
> * have as good a performance out-of-the-box as possible, using the
>   best-known settings for configuring the PMDs, so that any new apps can
>   be based off it.
> * be kept as short as possible to make it easy to understand it and get
>   started with it.
> 
> Signed-off-by: Bruce Richardson <bruce.richardson at intel.com>
Isn't there already an l2fwd example app?
Neil

> ---
>  examples/Makefile                |   1 +
>  examples/skeleton_app/Makefile   |  57 ++++++++++
>  examples/skeleton_app/basicfwd.c | 236 
> +++++++++++++++++++++++++++++++++++++++
>  examples/skeleton_app/basicfwd.h |  46 ++++++++
>  4 files changed, 340 insertions(+)
>  create mode 100644 examples/skeleton_app/Makefile
>  create mode 100644 examples/skeleton_app/basicfwd.c
>  create mode 100644 examples/skeleton_app/basicfwd.h
> 
> diff --git a/examples/Makefile b/examples/Makefile
> index 4353b84..2605d1d 100644
> --- a/examples/Makefile
> +++ b/examples/Makefile
> @@ -60,6 +60,7 @@ DIRS-y += netmap_compat/bridge
>  DIRS-$(CONFIG_RTE_LIBRTE_METER) += qos_meter
>  DIRS-$(CONFIG_RTE_LIBRTE_SCHED) += qos_sched
>  DIRS-y += quota_watermark
> +DIRS-y += skeleton_app
>  DIRS-y += timer
>  DIRS-y += vhost
>  DIRS-$(CONFIG_RTE_LIBRTE_XEN_DOM0) += vhost_xen
> diff --git a/examples/skeleton_app/Makefile b/examples/skeleton_app/Makefile
> new file mode 100644
> index 0000000..244f4ef
> --- /dev/null
> +++ b/examples/skeleton_app/Makefile
> @@ -0,0 +1,57 @@
> +#   BSD LICENSE
> +#
> +#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
> +#   All rights reserved.
> +#
> +#   Redistribution and use in source and binary forms, with or without
> +#   modification, are permitted provided that the following conditions
> +#   are met:
> +#
> +#     * Redistributions of source code must retain the above copyright
> +#       notice, this list of conditions and the following disclaimer.
> +#     * Redistributions in binary form must reproduce the above copyright
> +#       notice, this list of conditions and the following disclaimer in
> +#       the documentation and/or other materials provided with the
> +#       distribution.
> +#     * Neither the name of Intel Corporation nor the names of its
> +#       contributors may be used to endorse or promote products derived
> +#       from this software without specific prior written permission.
> +#
> +#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> +#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> +#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> +#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> +#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> +#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> +#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> +#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> +#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> +#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> +#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> +
> +ifeq ($(RTE_SDK),)
> +$(error "Please define RTE_SDK environment variable")
> +endif
> +
> +# Default target, can be overriden by command line or environment
> +RTE_TARGET ?= x86_64-default-linuxapp-gcc
> +
> +include $(RTE_SDK)/mk/rte.vars.mk
> +
> +# binary name
> +APP = basicfwd
> +
> +# all source are stored in SRCS-y
> +SRCS-y := basicfwd.c
> +
> +CFLAGS += $(WERROR_FLAGS)
> +
> +# workaround for a gcc bug with noreturn attribute
> +# http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12603
> +ifeq ($(CONFIG_RTE_TOOLCHAIN_GCC),y)
> +CFLAGS_main.o += -Wno-return-type
> +endif
> +
> +EXTRA_CFLAGS += -O3 -g -Wfatal-errors
> +
> +include $(RTE_SDK)/mk/rte.extapp.mk
> diff --git a/examples/skeleton_app/basicfwd.c 
> b/examples/skeleton_app/basicfwd.c
> new file mode 100644
> index 0000000..bf51a9d
> --- /dev/null
> +++ b/examples/skeleton_app/basicfwd.c
> @@ -0,0 +1,236 @@
> +/*-
> + *   BSD LICENSE
> + *
> + *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
> + *   All rights reserved.
> + *
> + *   Redistribution and use in source and binary forms, with or without
> + *   modification, are permitted provided that the following conditions
> + *   are met:
> + *
> + *     * Redistributions of source code must retain the above copyright
> + *       notice, this list of conditions and the following disclaimer.
> + *     * Redistributions in binary form must reproduce the above copyright
> + *       notice, this list of conditions and the following disclaimer in
> + *       the documentation and/or other materials provided with the
> + *       distribution.
> + *     * Neither the name of Intel Corporation nor the names of its
> + *       contributors may be used to endorse or promote products derived
> + *       from this software without specific prior written permission.
> + *
> + *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#include <stdint.h>
> +#include <inttypes.h>
> +#include <rte_eal.h>
> +#include <rte_ethdev.h>
> +#include <rte_cycles.h>
> +#include <rte_lcore.h>
> +#include <rte_mbuf.h>
> +#include "basicfwd.h"
> +
> +#define RX_RING_SIZE 128
> +#define RX_FREE_THRESH 32
> +#define RX_PTHRESH 8
> +#define RX_HTHRESH 8
> +#define RX_WTHRESH 0
> +
> +#define TX_RING_SIZE 512
> +#define TX_FREE_THRESH 32
> +#define TX_PTHRESH 32
> +#define TX_HTHRESH 0
> +#define TX_WTHRESH 0
> +#define TX_RSBIT_THRESH 32
> +#define TX_Q_FLAGS (ETH_TXQ_FLAGS_NOMULTSEGS | ETH_TXQ_FLAGS_NOVLANOFFL |\
> +     ETH_TXQ_FLAGS_NOXSUMSCTP | ETH_TXQ_FLAGS_NOXSUMUDP | \
> +     ETH_TXQ_FLAGS_NOXSUMTCP)
> +
> +#define NUM_MBUFS 8191
> +#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
> +#define MBUF_CACHE_SIZE 250
> +#define BURST_SIZE 32
> +
> +static struct rte_eth_conf port_conf_default = {
> +     .rxmode = {
> +             .mq_mode = ETH_MQ_RX_NONE,
> +             .max_rx_pkt_len = ETHER_MAX_LEN,
> +             .split_hdr_size = 0,
> +             .header_split   = 0, /**< Header Split disabled */
> +             .hw_ip_checksum = 0, /**< IP checksum offload enabled */
> +             .hw_vlan_filter = 0, /**< VLAN filtering disabled */
> +             .jumbo_frame    = 0, /**< Jumbo Frame Support disabled */
> +             .hw_strip_crc   = 0, /**< CRC stripped by hardware */
> +     },
> +     .txmode = {
> +             .mq_mode = ETH_MQ_TX_NONE,
> +     },
> +     .lpbk_mode = 0,
> +};
> +
> +static const struct rte_eth_rxconf rx_conf_default = {
> +     .rx_thresh = {
> +             .pthresh = RX_PTHRESH,
> +             .hthresh = RX_HTHRESH,
> +             .wthresh = RX_WTHRESH,
> +     },
> +     .rx_free_thresh = RX_FREE_THRESH,
> +     .rx_drop_en = 0,
> +};
> +
> +static struct rte_eth_txconf tx_conf_default = {
> +     .tx_thresh = {
> +             .pthresh = TX_PTHRESH,
> +             .hthresh = TX_HTHRESH,
> +             .wthresh = TX_WTHRESH,
> +     },
> +     .tx_free_thresh = TX_FREE_THRESH,
> +     .tx_rs_thresh = TX_RSBIT_THRESH,
> +     .txq_flags = TX_Q_FLAGS
> +
> +};
> +
> +
> +/*
> + * Initialises a given port using global settings and with the rx buffers
> + * coming from the mbuf_pool passed as parameter
> + */
> +static inline int
> +port_init(uint8_t port, struct rte_mempool *mbuf_pool)
> +{
> +     struct rte_eth_conf port_conf = port_conf_default;
> +     const uint16_t rxRings = 1, txRings = 1;
> +     int retval;
> +     uint16_t q;
> +
> +     if (port >= rte_eth_dev_count())
> +             return -1;
> +
> +     retval = rte_eth_dev_configure(port, rxRings, txRings, &port_conf);
> +     if (retval != 0)
> +             return retval;
> +
> +     for (q = 0; q < rxRings; q++) {
> +             retval = rte_eth_rx_queue_setup(port, q, RX_RING_SIZE,
> +                             rte_eth_dev_socket_id(port), &rx_conf_default,
> +                             mbuf_pool);
> +             if (retval < 0)
> +                     return retval;
> +     }
> +
> +     for (q = 0; q < txRings; q++) {
> +             retval = rte_eth_tx_queue_setup(port, q, TX_RING_SIZE,
> +                             rte_eth_dev_socket_id(port), &tx_conf_default);
> +             if (retval < 0)
> +                     return retval;
> +     }
> +
> +     retval  = rte_eth_dev_start(port);
> +     if (retval < 0)
> +             return retval;
> +
> +     struct ether_addr addr;
> +     rte_eth_macaddr_get(port, &addr);
> +     printf("Port %u MAC: %02"PRIx8" %02"PRIx8" %02"PRIx8
> +                     " %02"PRIx8" %02"PRIx8" %02"PRIx8"\n",
> +                     (unsigned)port,
> +                     addr.addr_bytes[0], addr.addr_bytes[1],
> +                     addr.addr_bytes[2], addr.addr_bytes[3],
> +                     addr.addr_bytes[4], addr.addr_bytes[5]);
> +
> +     rte_eth_promiscuous_enable(port);
> +
> +     return 0;
> +}
> +
> +/*
> + * Main thread that does the work, reading from INPUT_PORT
> + * and writing to OUTPUT_PORT
> + */
> +static  __attribute__((noreturn)) void
> +lcore_main(void)
> +{
> +     const uint8_t nb_ports = rte_eth_dev_count();
> +     uint8_t port;
> +     for (port = 0; port < nb_ports; port++)
> +             if (rte_eth_dev_socket_id(port) > 0 &&
> +                             rte_eth_dev_socket_id(port) !=
> +                                             (int)rte_socket_id())
> +                     printf("WARNING, port %u is on remote NUMA node to "
> +                                     "polling thread.\n\tPerformance will "
> +                                     "not be optimal.\n", port);
> +
> +     printf("\nCore %u forwarding packets. [Ctrl+C to quit]\n",
> +                     rte_lcore_id());
> +     for (;;) {
> +             for (port = 0; port < nb_ports; port++) {
> +                     struct rte_mbuf *bufs[BURST_SIZE];
> +                     const uint16_t nb_rx = rte_eth_rx_burst(port, 0,
> +                                     bufs, BURST_SIZE);
> +                     if (unlikely(nb_rx == 0))
> +                             continue;
> +                     const uint16_t nb_tx = rte_eth_tx_burst(port ^ 1, 0,
> +                                     bufs, nb_rx);
> +                     if (unlikely(nb_tx < nb_rx)) {
> +                             uint16_t buf;
> +                             for (buf = nb_tx; buf < nb_rx; buf++)
> +                                     rte_pktmbuf_free(bufs[buf]);
> +                     }
> +             }
> +     }
> +}
> +
> +/* Main function, does initialisation and calls the per-lcore functions */
> +int
> +MAIN(int argc, char *argv[])
> +{
> +     struct rte_mempool *mbuf_pool;
> +     unsigned nb_ports;
> +     uint8_t portid;
> +
> +     /* init EAL */
> +     int ret = rte_eal_init(argc, argv);
> +     if (ret < 0)
> +             rte_exit(EXIT_FAILURE, "Error with EAL initialization\n");
> +     argc -= ret;
> +     argv += ret;
> +
> +     if (rte_eal_pci_probe() != 0)
> +             rte_exit(EXIT_FAILURE, "Error with PCI probing\n");
> +
> +     nb_ports = rte_eth_dev_count();
> +     if (nb_ports < 2 || (nb_ports & 1))
> +             rte_exit(EXIT_FAILURE, "Error: number of ports must be even\n");
> +
> +     mbuf_pool = rte_mempool_create("MBUF_POOL", NUM_MBUFS * nb_ports,
> +                                    MBUF_SIZE, MBUF_CACHE_SIZE,
> +                                    sizeof(struct rte_pktmbuf_pool_private),
> +                                    rte_pktmbuf_pool_init, NULL,
> +                                    rte_pktmbuf_init, NULL,
> +                                    rte_socket_id(), 0);
> +     if (mbuf_pool == NULL)
> +             rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
> +
> +     /* initialize all ports */
> +     for (portid = 0; portid < nb_ports; portid++)
> +             if (port_init(portid, mbuf_pool) != 0)
> +                     rte_exit(EXIT_FAILURE, "Cannot init port %"PRIu8"\n",
> +                                     portid);
> +
> +     if (rte_lcore_count() > 1)
> +             printf("\nWARNING: Coremask too big - App uses only 1 lcore\n");
> +
> +     /* call lcore_main on master core only */
> +     lcore_main();
> +     return 0;
> +}
> diff --git a/examples/skeleton_app/basicfwd.h 
> b/examples/skeleton_app/basicfwd.h
> new file mode 100644
> index 0000000..2682d15
> --- /dev/null
> +++ b/examples/skeleton_app/basicfwd.h
> @@ -0,0 +1,46 @@
> +/*-
> + *   BSD LICENSE
> + *
> + *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
> + *   All rights reserved.
> + *
> + *   Redistribution and use in source and binary forms, with or without
> + *   modification, are permitted provided that the following conditions
> + *   are met:
> + *
> + *     * Redistributions of source code must retain the above copyright
> + *       notice, this list of conditions and the following disclaimer.
> + *     * Redistributions in binary form must reproduce the above copyright
> + *       notice, this list of conditions and the following disclaimer in
> + *       the documentation and/or other materials provided with the
> + *       distribution.
> + *     * Neither the name of Intel Corporation nor the names of its
> + *       contributors may be used to endorse or promote products derived
> + *       from this software without specific prior written permission.
> + *
> + *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#ifndef _MAIN_H_
> +#define _MAIN_H_
> +
> +
> +#ifdef RTE_EXEC_ENV_BAREMETAL
> +#define MAIN _main
> +#else
> +#define MAIN main
> +#endif
> +
> +int MAIN(int argc, char *argv[]);
> +
> +#endif /* ifndef _MAIN_H_ */
> -- 
> 1.9.3
> 
> 

Reply via email to