diff options
author | Luca Boccassi <luca.boccassi@gmail.com> | 2017-11-08 14:50:17 +0000 |
---|---|---|
committer | Luca Boccassi <luca.boccassi@gmail.com> | 2017-11-08 14:50:22 +0000 |
commit | b30bf840574a70b892bebc6e5281cd614cfc82c5 (patch) | |
tree | af9a3331209ba3eb575e2de2a41da99a9dd40954 /doc/guides/sample_app_ug | |
parent | 01dc13012315b1f147ccce80aed68050c9e31c2d (diff) | |
parent | 055c52583a2794da8ba1e85a48cce3832372b12f (diff) |
Merge branch 'upstream' into 17.11.x
Change-Id: I9f728c5947bfb5ba81f00306b7997685463ca13e
Signed-off-by: Luca Boccassi <luca.boccassi@gmail.com>
Diffstat (limited to 'doc/guides/sample_app_ug')
46 files changed, 1723 insertions, 871 deletions
diff --git a/doc/guides/sample_app_ug/cmd_line.rst b/doc/guides/sample_app_ug/cmd_line.rst index 36c7971c..eabbac15 100644 --- a/doc/guides/sample_app_ug/cmd_line.rst +++ b/doc/guides/sample_app_ug/cmd_line.rst @@ -68,26 +68,9 @@ There are three simple commands: Compiling the Application ------------------------- -#. Go to example directory: +To compile the sample application see :doc:`compiling` - .. code-block:: console - - export RTE_SDK=/path/to/rte_sdk - cd ${RTE_SDK}/examples/cmdline - -#. Set the target (a default target is used if not specified). For example: - - .. code-block:: console - - export RTE_TARGET=x86_64-native-linuxapp-gcc - - Refer to the *DPDK Getting Started Guide* for possible RTE_TARGET values. - -#. Build the application: - - .. code-block:: console - - make +The application is located in the ``cmd_line`` sub-directory. Running the Application ----------------------- diff --git a/doc/guides/sample_app_ug/compiling.rst b/doc/guides/sample_app_ug/compiling.rst new file mode 100644 index 00000000..8bedaa79 --- /dev/null +++ b/doc/guides/sample_app_ug/compiling.rst @@ -0,0 +1,122 @@ + .. BSD LICENSE + Copyright(c) 2015 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. + +Compiling the Sample Applications +================================= + +This section explains how to compile the DPDK sample applications. + +To compile all the sample applications +-------------------------------------- + + +Set the path to DPDK source code if its not set: + + .. code-block:: console + + export RTE_SDK=/path/to/rte_sdk + +Go to DPDK source: + + .. code-block:: console + + cd $RTE_SDK + +Build DPDK: + + .. code-block:: console + + make defconfig + make + +Build the sample applications: + + .. code-block:: console + + export RTE_TARGET=build + make -C examples + +For other possible ``RTE_TARGET`` values and additional information on +compiling see +:ref:`Compiling DPDK on Linux <linux_gsg_compiling_dpdk>` or +:ref:`Compiling DPDK on FreeBSD <building_from_source>`. +Applications are output to: ``$RTE_SDK/examples/app-dir/build`` or +``$RTE_SDK/examples/app-dir/$RTE_TARGET``. + + +In the example above the compiled application is written to the ``build`` subdirectory. +To have the applications written to a different location, +the ``O=/path/to/build/directory`` option may be specified in the make command. + + .. code-block:: console + + make O=/tmp + +To build the applications for debugging use the ``DEBUG`` option. +This option adds some extra flags, disables compiler optimizations and +sets verbose output. + + .. code-block:: console + + make DEBUG=1 + + +To compile a single application +------------------------------- + +Set the path to DPDK source code: + + .. code-block:: console + + export RTE_SDK=/path/to/rte_sdk + +Go to DPDK source: + + .. code-block:: console + + cd $RTE_SDK + +Build DPDK: + + .. code-block:: console + + make defconfig + make + +Go to the sample application directory. Unless otherwise specified the sample +applications are located in ``$RTE_SDK/examples/``. + + +Build the application: + + .. code-block:: console + + export RTE_TARGET=build + make diff --git a/doc/guides/sample_app_ug/dist_app.rst b/doc/guides/sample_app_ug/dist_app.rst index 1cae4739..45a51313 100644 --- a/doc/guides/sample_app_ug/dist_app.rst +++ b/doc/guides/sample_app_ug/dist_app.rst @@ -53,30 +53,12 @@ generator as shown in the figure below. Performance Benchmarking Setup (Basic Environment) - Compiling the Application ------------------------- -#. Go to the sample application directory: - - .. code-block:: console - - export RTE_SDK=/path/to/rte_sdk - cd ${RTE_SDK}/examples/distributor - -#. Set the target (a default target is used if not specified). For example: - - .. code-block:: console - - export RTE_TARGET=x86_64-native-linuxapp-gcc - - See the DPDK Getting Started Guide for possible RTE_TARGET values. - -#. Build the application: - - .. code-block:: console +To compile the sample application see :doc:`compiling`. - make +The application is located in the ``distributor`` sub-directory. Running the Application ----------------------- diff --git a/doc/guides/sample_app_ug/ethtool.rst b/doc/guides/sample_app_ug/ethtool.rst index 67797954..6dd11dc9 100644 --- a/doc/guides/sample_app_ug/ethtool.rst +++ b/doc/guides/sample_app_ug/ethtool.rst @@ -40,28 +40,9 @@ is based upon a simple L2 frame reflector. Compiling the Application ------------------------- -To compile the application: +To compile the sample application see :doc:`compiling`. -#. Go to the sample application directory: - - .. code-block:: console - - export RTE_SDK=/path/to/rte_sdk - cd ${RTE_SDK}/examples/ethtool - -#. Set the target (a default target is used if not specified). For example: - - .. code-block:: console - - export RTE_TARGET=x86_64-native-linuxapp-gcc - - See the *DPDK Getting Started Guide* for possible RTE_TARGET values. - -#. Build the application: - - .. code-block:: console - - make +The application is located in the ``ethtool`` sub-directory. Running the Application ----------------------- diff --git a/doc/guides/sample_app_ug/eventdev_pipeline_sw_pmd.rst b/doc/guides/sample_app_ug/eventdev_pipeline_sw_pmd.rst index b1b18dd0..01a5f9b2 100644 --- a/doc/guides/sample_app_ug/eventdev_pipeline_sw_pmd.rst +++ b/doc/guides/sample_app_ug/eventdev_pipeline_sw_pmd.rst @@ -46,28 +46,11 @@ a particular pipeline configuration. Compiling the Application ------------------------- -To compile the application: +To compile the sample application see :doc:`compiling`. -#. Go to the sample application directory: +The application is located in the ``examples`` sub-directory. - .. code-block:: console - export RTE_SDK=/path/to/rte_sdk - cd ${RTE_SDK}/examples/eventdev_pipeline_sw_pmd - -#. Set the target (a default target is used if not specified). For example: - - .. code-block:: console - - export RTE_TARGET=x86_64-native-linuxapp-gcc - - See the *DPDK Getting Started Guide* for possible RTE_TARGET values. - -#. Build the application: - - .. code-block:: console - - make Running the Application ----------------------- diff --git a/doc/guides/sample_app_ug/exception_path.rst b/doc/guides/sample_app_ug/exception_path.rst index e505fb32..d7f45e6d 100644 --- a/doc/guides/sample_app_ug/exception_path.rst +++ b/doc/guides/sample_app_ug/exception_path.rst @@ -58,28 +58,9 @@ To make throughput measurements, kernel bridges must be setup to forward data be Compiling the Application ------------------------- -#. Go to example directory: +To compile the sample application see :doc:`compiling`. - .. code-block:: console - - export RTE_SDK=/path/to/rte_sdk - cd ${RTE_SDK}/examples/exception_path - -#. Set the target (a default target will be used if not specified). - For example: - - .. code-block:: console - - export RTE_TARGET=x86_64-native-linuxapp-gcc - -This application is intended as a linuxapp only. -See the *DPDK Getting Started Guide* for possible RTE_TARGET values. - -#. Build the application: - - .. code-block:: console - - make +The application is located in the ``exception_path`` sub-directory. Running the Application ----------------------- diff --git a/doc/guides/sample_app_ug/flow_classify.rst b/doc/guides/sample_app_ug/flow_classify.rst new file mode 100644 index 00000000..bc12b87d --- /dev/null +++ b/doc/guides/sample_app_ug/flow_classify.rst @@ -0,0 +1,575 @@ +.. BSD LICENSE + Copyright(c) 2017 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. + +Flow Classify Sample Application +================================ + +The Flow Classify sample application is based on the simple *skeleton* example +of a forwarding application. + +It is intended as a demonstration of the basic components of a DPDK forwarding +application which uses the Flow Classify library API's. + +Please refer to the +:doc:`../prog_guide/flow_classify_lib` +for more information. + +Compiling the Application +------------------------- + +To compile the sample application see :doc:`compiling`. + +The application is located in the ``flow_classify`` sub-directory. + +Running the Application +----------------------- + +To run the example in a ``linuxapp`` environment: + +.. code-block:: console + + cd ~/dpdk/examples/flow_classify + ./build/flow_classify -c 4 -n 4 -- --rule_ipv4="../ipv4_rules_file.txt" + +Please refer to the *DPDK Getting Started Guide*, section +:doc:`../linux_gsg/build_sample_apps` +for general information on running applications and the Environment Abstraction +Layer (EAL) options. + + +Sample ipv4_rules_file.txt +-------------------------- + +.. code-block:: console + + #file format: + #src_ip/masklen dst_ip/masklen src_port : mask dst_port : mask proto/mask priority + # + 2.2.2.3/24 2.2.2.7/24 32 : 0xffff 33 : 0xffff 17/0xff 0 + 9.9.9.3/24 9.9.9.7/24 32 : 0xffff 33 : 0xffff 17/0xff 1 + 9.9.9.3/24 9.9.9.7/24 32 : 0xffff 33 : 0xffff 6/0xff 2 + 9.9.8.3/24 9.9.8.7/24 32 : 0xffff 33 : 0xffff 6/0xff 3 + 6.7.8.9/24 2.3.4.5/24 32 : 0x0000 33 : 0x0000 132/0xff 4 + +Explanation +----------- + +The following sections provide an explanation of the main components of the +code. + +All DPDK library functions used in the sample code are prefixed with ``rte_`` +and are explained in detail in the *DPDK API Documentation*. + +ACL field definitions for the IPv4 5 tuple rule +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The following field definitions are used when creating the ACL table during +initialisation of the ``Flow Classify`` application.. + +.. code-block:: c + + enum { + PROTO_FIELD_IPV4, + SRC_FIELD_IPV4, + DST_FIELD_IPV4, + SRCP_FIELD_IPV4, + DSTP_FIELD_IPV4, + NUM_FIELDS_IPV4 + }; + + enum { + PROTO_INPUT_IPV4, + SRC_INPUT_IPV4, + DST_INPUT_IPV4, + SRCP_DESTP_INPUT_IPV4 + }; + + static struct rte_acl_field_def ipv4_defs[NUM_FIELDS_IPV4] = { + /* first input field - always one byte long. */ + { + .type = RTE_ACL_FIELD_TYPE_BITMASK, + .size = sizeof(uint8_t), + .field_index = PROTO_FIELD_IPV4, + .input_index = PROTO_INPUT_IPV4, + .offset = sizeof(struct ether_hdr) + + offsetof(struct ipv4_hdr, next_proto_id), + }, + /* next input field (IPv4 source address) - 4 consecutive bytes. */ + { + /* rte_flow uses a bit mask for IPv4 addresses */ + .type = RTE_ACL_FIELD_TYPE_BITMASK, + .size = sizeof(uint32_t), + .field_index = SRC_FIELD_IPV4, + .input_index = SRC_INPUT_IPV4, + .offset = sizeof(struct ether_hdr) + + offsetof(struct ipv4_hdr, src_addr), + }, + /* next input field (IPv4 destination address) - 4 consecutive bytes. */ + { + /* rte_flow uses a bit mask for IPv4 addresses */ + .type = RTE_ACL_FIELD_TYPE_BITMASK, + .size = sizeof(uint32_t), + .field_index = DST_FIELD_IPV4, + .input_index = DST_INPUT_IPV4, + .offset = sizeof(struct ether_hdr) + + offsetof(struct ipv4_hdr, dst_addr), + }, + /* + * Next 2 fields (src & dst ports) form 4 consecutive bytes. + * They share the same input index. + */ + { + /* rte_flow uses a bit mask for protocol ports */ + .type = RTE_ACL_FIELD_TYPE_BITMASK, + .size = sizeof(uint16_t), + .field_index = SRCP_FIELD_IPV4, + .input_index = SRCP_DESTP_INPUT_IPV4, + .offset = sizeof(struct ether_hdr) + + sizeof(struct ipv4_hdr) + + offsetof(struct tcp_hdr, src_port), + }, + { + /* rte_flow uses a bit mask for protocol ports */ + .type = RTE_ACL_FIELD_TYPE_BITMASK, + .size = sizeof(uint16_t), + .field_index = DSTP_FIELD_IPV4, + .input_index = SRCP_DESTP_INPUT_IPV4, + .offset = sizeof(struct ether_hdr) + + sizeof(struct ipv4_hdr) + + offsetof(struct tcp_hdr, dst_port), + }, + }; + +The Main Function +~~~~~~~~~~~~~~~~~ + +The ``main()`` function performs the initialization and calls the execution +threads for each lcore. + +The first task is to initialize the Environment Abstraction Layer (EAL). +The ``argc`` and ``argv`` arguments are provided to the ``rte_eal_init()`` +function. The value returned is the number of parsed arguments: + +.. code-block:: c + + int ret = rte_eal_init(argc, argv); + if (ret < 0) + rte_exit(EXIT_FAILURE, "Error with EAL initialization\n"); + +It then parses the flow_classify application arguments + +.. code-block:: c + + ret = parse_args(argc, argv); + if (ret < 0) + rte_exit(EXIT_FAILURE, "Invalid flow_classify parameters\n"); + +The ``main()`` function also allocates a mempool to hold the mbufs +(Message Buffers) used by the application: + +.. code-block:: c + + 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); + +mbufs are the packet buffer structure used by DPDK. They are explained in +detail in the "Mbuf Library" section of the *DPDK Programmer's Guide*. + +The ``main()`` function also initializes all the ports using the user defined +``port_init()`` function which is explained in the next section: + +.. code-block:: c + + for (portid = 0; portid < nb_ports; portid++) { + if (port_init(portid, mbuf_pool) != 0) { + rte_exit(EXIT_FAILURE, + "Cannot init port %" PRIu8 "\n", portid); + } + } + +The ``main()`` function creates the ``flow classifier object`` and adds an ``ACL +table`` to the flow classifier. + +.. code-block:: c + + struct flow_classifier { + struct rte_flow_classifier *cls; + uint32_t table_id[RTE_FLOW_CLASSIFY_TABLE_MAX]; + }; + + struct flow_classifier_acl { + struct flow_classifier cls; + } __rte_cache_aligned; + + /* Memory allocation */ + size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct flow_classifier_acl)); + cls_app = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE); + if (cls_app == NULL) + rte_exit(EXIT_FAILURE, "Cannot allocate classifier memory\n"); + + cls_params.name = "flow_classifier"; + cls_params.socket_id = socket_id; + cls_params.type = RTE_FLOW_CLASSIFY_TABLE_TYPE_ACL; + + cls_app->cls = rte_flow_classifier_create(&cls_params); + if (cls_app->cls == NULL) { + rte_free(cls_app); + rte_exit(EXIT_FAILURE, "Cannot create classifier\n"); + } + + /* initialise ACL table params */ + table_acl_params.name = "table_acl_ipv4_5tuple"; + table_acl_params.n_rule_fields = RTE_DIM(ipv4_defs); + table_acl_params.n_rules = FLOW_CLASSIFY_MAX_RULE_NUM; + memcpy(table_acl_params.field_format, ipv4_defs, sizeof(ipv4_defs)); + + /* initialise table create params */ + cls_table_params.ops = &rte_table_acl_ops, + cls_table_params.arg_create = &table_acl_params, + cls_table_params.table_metadata_size = 0; + + ret = rte_flow_classify_table_create(cls_app->cls, &cls_table_params, + &cls->table_id[0]); + if (ret) { + rte_flow_classifier_free(cls_app->cls); + rte_free(cls); + rte_exit(EXIT_FAILURE, "Failed to create classifier table\n"); + } + +It then reads the ipv4_rules_file.txt file and initialises the parameters for +the ``rte_flow_classify_table_entry_add`` API. +This API adds a rule to the ACL table. + +.. code-block:: c + + if (add_rules(parm_config.rule_ipv4_name)) { + rte_flow_classifier_free(cls_app->cls); + rte_free(cls_app); + rte_exit(EXIT_FAILURE, "Failed to add rules\n"); + } + +Once the initialization is complete, the application is ready to launch a +function on an lcore. In this example ``lcore_main()`` is called on a single +lcore. + +.. code-block:: c + + lcore_main(cls_app); + +The ``lcore_main()`` function is explained below. + +The Port Initialization Function +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The main functional part of the port initialization used in the Basic +Forwarding application is shown below: + +.. code-block:: c + + 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 rx_rings = 1, tx_rings = 1; + struct ether_addr addr; + int retval; + uint16_t q; + + if (port >= rte_eth_dev_count()) + return -1; + + /* Configure the Ethernet device. */ + retval = rte_eth_dev_configure(port, rx_rings, tx_rings, &port_conf); + if (retval != 0) + return retval; + + /* Allocate and set up 1 RX queue per Ethernet port. */ + for (q = 0; q < rx_rings; q++) { + retval = rte_eth_rx_queue_setup(port, q, RX_RING_SIZE, + rte_eth_dev_socket_id(port), NULL, mbuf_pool); + if (retval < 0) + return retval; + } + + /* Allocate and set up 1 TX queue per Ethernet port. */ + for (q = 0; q < tx_rings; q++) { + retval = rte_eth_tx_queue_setup(port, q, TX_RING_SIZE, + rte_eth_dev_socket_id(port), NULL); + if (retval < 0) + return retval; + } + + /* Start the Ethernet port. */ + retval = rte_eth_dev_start(port); + if (retval < 0) + return retval; + + /* Display the port MAC address. */ + rte_eth_macaddr_get(port, &addr); + printf("Port %u MAC: %02" PRIx8 " %02" PRIx8 " %02" PRIx8 + " %02" PRIx8 " %02" PRIx8 " %02" PRIx8 "\n", + 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]); + + /* Enable RX in promiscuous mode for the Ethernet device. */ + rte_eth_promiscuous_enable(port); + + return 0; + } + +The Ethernet ports are configured with default settings using the +``rte_eth_dev_configure()`` function and the ``port_conf_default`` struct. + +.. code-block:: c + + static const struct rte_eth_conf port_conf_default = { + .rxmode = { .max_rx_pkt_len = ETHER_MAX_LEN } + }; + +For this example the ports are set up with 1 RX and 1 TX queue using the +``rte_eth_rx_queue_setup()`` and ``rte_eth_tx_queue_setup()`` functions. + +The Ethernet port is then started: + +.. code-block:: c + + retval = rte_eth_dev_start(port); + + +Finally the RX port is set in promiscuous mode: + +.. code-block:: c + + rte_eth_promiscuous_enable(port); + +The Add Rules function +~~~~~~~~~~~~~~~~~~~~~~ + +The ``add_rules`` function reads the ``ipv4_rules_file.txt`` file and calls the +``add_classify_rule`` function which calls the +``rte_flow_classify_table_entry_add`` API. + +.. code-block:: c + + static int + add_rules(const char *rule_path) + { + FILE *fh; + char buff[LINE_MAX]; + unsigned int i = 0; + unsigned int total_num = 0; + struct rte_eth_ntuple_filter ntuple_filter; + + fh = fopen(rule_path, "rb"); + if (fh == NULL) + rte_exit(EXIT_FAILURE, "%s: Open %s failed\n", __func__, + rule_path); + + fseek(fh, 0, SEEK_SET); + + i = 0; + while (fgets(buff, LINE_MAX, fh) != NULL) { + i++; + + if (is_bypass_line(buff)) + continue; + + if (total_num >= FLOW_CLASSIFY_MAX_RULE_NUM - 1) { + printf("\nINFO: classify rule capacity %d reached\n", + total_num); + break; + } + + if (parse_ipv4_5tuple_rule(buff, &ntuple_filter) != 0) + rte_exit(EXIT_FAILURE, + "%s Line %u: parse rules error\n", + rule_path, i); + + if (add_classify_rule(&ntuple_filter) != 0) + rte_exit(EXIT_FAILURE, "add rule error\n"); + + total_num++; + } + + fclose(fh); + return 0; + } + + +The Lcore Main function +~~~~~~~~~~~~~~~~~~~~~~~ + +As we saw above the ``main()`` function calls an application function on the +available lcores. +The ``lcore_main`` function calls the ``rte_flow_classifier_query`` API. +For the Basic Forwarding application the ``lcore_main`` function looks like the +following: + +.. code-block:: c + + /* flow classify data */ + static int num_classify_rules; + static struct rte_flow_classify_rule *rules[MAX_NUM_CLASSIFY]; + static struct rte_flow_classify_ipv4_5tuple_stats ntuple_stats; + static struct rte_flow_classify_stats classify_stats = { + .stats = (void *)&ntuple_stats + }; + + static __attribute__((noreturn)) void + lcore_main(cls_app) + { + const uint8_t nb_ports = rte_eth_dev_count(); + uint8_t port; + + /* + * Check that the port is on the same NUMA node as the polling thread + * for best performance. + */ + 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("\n\n"); + printf("WARNING: port %u is on remote NUMA node\n", + port); + printf("to polling thread.\n"); + printf("Performance will not be optimal.\n"); + + printf("\nCore %u forwarding packets. \n", + rte_lcore_id()); + printf("[Ctrl+C to quit]\n + } + + /* Run until the application is quit or killed. */ + for (;;) { + /* + * Receive packets on a port and forward them on the paired + * port. The mapping is 0 -> 1, 1 -> 0, 2 -> 3, 3 -> 2, etc. + */ + for (port = 0; port < nb_ports; port++) { + + /* Get burst of RX packets, from first port of pair. */ + 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; + + for (i = 0; i < MAX_NUM_CLASSIFY; i++) { + if (rules[i]) { + ret = rte_flow_classifier_query( + cls_app->cls, + cls_app->table_id[0], + bufs, nb_rx, rules[i], + &classify_stats); + if (ret) + printf( + "rule [%d] query failed ret [%d]\n\n", + i, ret); + else { + printf( + "rule[%d] count=%"PRIu64"\n", + i, ntuple_stats.counter1); + + printf("proto = %d\n", + ntuple_stats.ipv4_5tuple.proto); + } + } + } + + /* Send burst of TX packets, to second port of pair. */ + const uint16_t nb_tx = rte_eth_tx_burst(port ^ 1, 0, + bufs, nb_rx); + + /* Free any unsent packets. */ + if (unlikely(nb_tx < nb_rx)) { + uint16_t buf; + for (buf = nb_tx; buf < nb_rx; buf++) + rte_pktmbuf_free(bufs[buf]); + } + } + } + } + +The main work of the application is done within the loop: + +.. code-block:: c + + for (;;) { + for (port = 0; port < nb_ports; port++) { + + /* Get burst of RX packets, from first port of pair. */ + 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; + + /* Send burst of TX packets, to second port of pair. */ + const uint16_t nb_tx = rte_eth_tx_burst(port ^ 1, 0, + bufs, nb_rx); + + /* Free any unsent packets. */ + if (unlikely(nb_tx < nb_rx)) { + uint16_t buf; + for (buf = nb_tx; buf < nb_rx; buf++) + rte_pktmbuf_free(bufs[buf]); + } + } + } + +Packets are received in bursts on the RX ports and transmitted in bursts on +the TX ports. The ports are grouped in pairs with a simple mapping scheme +using the an XOR on the port number:: + + 0 -> 1 + 1 -> 0 + + 2 -> 3 + 3 -> 2 + + etc. + +The ``rte_eth_tx_burst()`` function frees the memory buffers of packets that +are transmitted. If packets fail to transmit, ``(nb_tx < nb_rx)``, then they +must be freed explicitly using ``rte_pktmbuf_free()``. + +The forwarding loop can be interrupted and the application closed using +``Ctrl-C``. diff --git a/doc/guides/sample_app_ug/flow_filtering.rst b/doc/guides/sample_app_ug/flow_filtering.rst new file mode 100644 index 00000000..725dcb44 --- /dev/null +++ b/doc/guides/sample_app_ug/flow_filtering.rst @@ -0,0 +1,545 @@ +.. BSD LICENSE + Copyright(c) 2017 Mellanox 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 Mellanox 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. + + +Basic RTE Flow Filtering Sample Application +=========================================== + +The Basic RTE flow filtering sample application is a simple example of a +creating a RTE flow rule. + +It is intended as a demonstration of the basic components RTE flow rules. + + +Compiling the Application +------------------------- + +To compile the application export the path to the DPDK source tree and go to +the example directory: + +.. code-block:: console + + export RTE_SDK=/path/to/rte_sdk + + cd ${RTE_SDK}/examples/flow_filtering + +Set the target, for example: + +.. code-block:: console + + export RTE_TARGET=x86_64-native-linuxapp-gcc + +See the *DPDK Getting Started* Guide for possible ``RTE_TARGET`` values. + +Build the application as follows: + +.. code-block:: console + + make + + +Running the Application +----------------------- + +To run the example in a ``linuxapp`` environment: + +.. code-block:: console + + ./build/flow -l 1 -n 1 + +Refer to *DPDK Getting Started Guide* for general information on running +applications and the Environment Abstraction Layer (EAL) options. + + +Explanation +----------- + +The example is build from 2 main files, +``main.c`` which holds the example logic and ``flow_blocks.c`` that holds the +implementation for building the flow rule. + +The following sections provide an explanation of the main components of the +code. + +All DPDK library functions used in the sample code are prefixed with ``rte_`` +and are explained in detail in the *DPDK API Documentation*. + + +The Main Function +~~~~~~~~~~~~~~~~~ + +The ``main()`` function located in ``main.c`` file performs the initialization +and runs the main loop function. + +The first task is to initialize the Environment Abstraction Layer (EAL). The +``argc`` and ``argv`` arguments are provided to the ``rte_eal_init()`` +function. The value returned is the number of parsed arguments: + +.. code-block:: c + + int ret = rte_eal_init(argc, argv); + if (ret < 0) + rte_exit(EXIT_FAILURE, "Error with EAL initialization\n"); + + +The ``main()`` also allocates a mempool to hold the mbufs (Message Buffers) +used by the application: + +.. code-block:: c + + mbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", 4096, 128, 0, + RTE_MBUF_DEFAULT_BUF_SIZE, + rte_socket_id()); + +Mbufs are the packet buffer structure used by DPDK. They are explained in +detail in the "Mbuf Library" section of the *DPDK Programmer's Guide*. + +The ``main()`` function also initializes all the ports using the user defined +``init_port()`` function which is explained in the next section: + +.. code-block:: c + + init_port(); + +Once the initialization is complete, we set the flow rule using the +following code: + +.. code-block:: c + + /* create flow for send packet with */ + flow = generate_ipv4_flow(port_id, selected_queue, + SRC_IP, EMPTY_MASK, + DEST_IP, FULL_MASK, &error); + if (!flow) { + printf("Flow can't be created %d message: %s\n", + error.type, + error.message ? error.message : "(no stated reason)"); + rte_exit(EXIT_FAILURE, "error in creating flow"); + } + +In the last part the application is ready to launch the +``main_loop()`` function. Which is explained below. + + +.. code-block:: c + + main_loop(); + +The Port Initialization Function +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The main functional part of the port initialization used in the flow filtering +application is shown below: + +.. code-block:: c + + init_port(void) + { + int ret; + uint16_t i; + struct rte_eth_conf port_conf = { + .rxmode = { + .split_hdr_size = 0, + /**< Header Split disabled */ + .header_split = 0, + /**< IP checksum offload disabled */ + .hw_ip_checksum = 0, + /**< VLAN filtering disabled */ + .hw_vlan_filter = 0, + /**< Jumbo Frame Support disabled */ + .jumbo_frame = 0, + /**< CRC stripped by hardware */ + .hw_strip_crc = 1, + }, + }; + + printf(":: initializing port: %d\n", port_id); + ret = rte_eth_dev_configure(port_id, + nr_queues, nr_queues, &port_conf); + if (ret < 0) { + rte_exit(EXIT_FAILURE, + ":: cannot configure device: err=%d, port=%u\n", + ret, port_id); + } + + /* only set Rx queues: something we care only so far */ + for (i = 0; i < nr_queues; i++) { + ret = rte_eth_rx_queue_setup(port_id, i, 512, + rte_eth_dev_socket_id(port_id), + NULL, + mbuf_pool); + if (ret < 0) { + rte_exit(EXIT_FAILURE, + ":: Rx queue setup failed: err=%d, port=%u\n", + ret, port_id); + } + } + + + rte_eth_promiscuous_enable(port_id); + + ret = rte_eth_dev_start(port_id); + if (ret < 0) { + rte_exit(EXIT_FAILURE, + "rte_eth_dev_start:err=%d, port=%u\n", + ret, port_id); + } + + assert_link_status(); + + printf(":: initializing port: %d done\n", port_id); + } + +The Ethernet port is configured with default settings using the +``rte_eth_dev_configure()`` function and the ``port_conf_default`` struct: + +.. code-block:: c + + struct rte_eth_conf port_conf = { + .rxmode = { + .split_hdr_size = 0, + /**< Header Split disabled */ + .header_split = 0, + /**< IP checksum offload disabled */ + .hw_ip_checksum = 0, + /**< VLAN filtering disabled */ + .hw_vlan_filter = 0, + /**< Jumbo Frame Support disabled */ + .jumbo_frame = 0, + /**< CRC stripped by hardware */ + .hw_strip_crc = 1, + }, + }; + + ret = rte_eth_dev_configure(port_id, nr_queues, nr_queues, &port_conf); + if (ret < 0) { + rte_exit(EXIT_FAILURE, + ":: cannot configure device: err=%d, port=%u\n", + ret, port_id); + } + +For this example we are configuring number of rx queues that are connected to +a single port. + +.. code-block:: c + + for (i = 0; i < nr_queues; i++) { + ret = rte_eth_rx_queue_setup(port_id, i, 512, + rte_eth_dev_socket_id(port_id), + NULL, + mbuf_pool); + if (ret < 0) { + rte_exit(EXIT_FAILURE, + ":: Rx queue setup failed: err=%d, port=%u\n", + ret, port_id); + } + } + +In the next step we create and apply the flow rule. which is to send packets +with destination ip equals to 192.168.1.1 to queue number 1. The detail +explanation of the ``generate_ipv4_flow()`` appears later in this document: + +.. code-block:: c + + flow = generate_ipv4_flow(port_id, selected_queue, + SRC_IP, EMPTY_MASK, + DEST_IP, FULL_MASK, &error); + +We are setting the RX port to promiscuous mode: + +.. code-block:: c + + rte_eth_promiscuous_enable(port_id); + +The last step is to start the port. + +.. code-block:: c + + ret = rte_eth_dev_start(port_id); + if (ret < 0) { + rte_exit(EXIT_FAILURE, "rte_eth_dev_start:err%d, port=%u\n", + ret, port_id); + } + + +The main_loop function +~~~~~~~~~~~~~~~~~~~~~~ + +As we saw above the ``main()`` function calls an application function to handle +the main loop. For the flow filtering application the main_loop function +looks like the following: + +.. code-block:: c + + static void + main_loop(void) + { + struct rte_mbuf *mbufs[32]; + struct ether_hdr *eth_hdr; + uint16_t nb_rx; + uint16_t i; + uint16_t j; + + while (!force_quit) { + for (i = 0; i < nr_queues; i++) { + nb_rx = rte_eth_rx_burst(port_id, + i, mbufs, 32); + if (nb_rx) { + for (j = 0; j < nb_rx; j++) { + struct rte_mbuf *m = mbufs[j]; + + eth_hdr = rte_pktmbuf_mtod(m, + struct ether_hdr *); + print_ether_addr("src=", + ð_hdr->s_addr); + print_ether_addr(" - dst=", + ð_hdr->d_addr); + printf(" - queue=0x%x", + (unsigned int)i); + printf("\n"); + rte_pktmbuf_free(m); + } + } + } + } + /* closing and releasing resources */ + rte_flow_flush(port_id, &error); + rte_eth_dev_stop(port_id); + rte_eth_dev_close(port_id); + } + +The main work of the application is reading the packets from all +queues and printing for each packet the destination queue: + +.. code-block:: c + + while (!force_quit) { + for (i = 0; i < nr_queues; i++) { + nb_rx = rte_eth_rx_burst(port_id, i, mbufs, 32); + if (nb_rx) { + for (j = 0; j < nb_rx; j++) { + struct rte_mbuf *m = mbufs[j]; + eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *); + print_ether_addr("src=", ð_hdr->s_addr); + print_ether_addr(" - dst=", ð_hdr->d_addr); + printf(" - queue=0x%x", (unsigned int)i); + printf("\n"); + rte_pktmbuf_free(m); + } + } + } + } + + +The forwarding loop can be interrupted and the application closed using +``Ctrl-C``. Which results in closing the port and the device using +``rte_eth_dev_stop`` and ``rte_eth_dev_close`` + +The generate_ipv4_flow function +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The generate_ipv4_rule function is responsible for creating the flow rule. +This function is located in the ``flow_blocks.c`` file. + +.. code-block:: c + + static struct rte_flow * + generate_ipv4_flow(uint8_t port_id, uint16_t rx_q, + uint32_t src_ip, uint32_t src_mask, + uint32_t dest_ip, uint32_t dest_mask, + struct rte_flow_error *error) + { + struct rte_flow_attr attr; + struct rte_flow_item pattern[MAX_PATTERN_NUM]; + struct rte_flow_action action[MAX_PATTERN_NUM]; + struct rte_flow *flow = NULL; + struct rte_flow_action_queue queue = { .index = rx_q }; + struct rte_flow_item_eth eth_spec; + struct rte_flow_item_eth eth_mask; + struct rte_flow_item_vlan vlan_spec; + struct rte_flow_item_vlan vlan_mask; + struct rte_flow_item_ipv4 ip_spec; + struct rte_flow_item_ipv4 ip_mask; + + memset(pattern, 0, sizeof(pattern)); + memset(action, 0, sizeof(action)); + + /* + * set the rule attribute. + * in this case only ingress packets will be checked. + */ + memset(&attr, 0, sizeof(struct rte_flow_attr)); + attr.ingress = 1; + + /* + * create the action sequence. + * one action only, move packet to queue + */ + + action[0].type = RTE_FLOW_ACTION_TYPE_QUEUE; + action[0].conf = &queue; + action[1].type = RTE_FLOW_ACTION_TYPE_END; + + /* + * set the first level of the pattern (eth). + * since in this example we just want to get the + * ipv4 we set this level to allow all. + */ + memset(ð_spec, 0, sizeof(struct rte_flow_item_eth)); + memset(ð_mask, 0, sizeof(struct rte_flow_item_eth)); + eth_spec.type = 0; + eth_mask.type = 0; + pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH; + pattern[0].spec = ð_spec; + pattern[0].mask = ð_mask; + + /* + * setting the second level of the pattern (vlan). + * since in this example we just want to get the + * ipv4 we also set this level to allow all. + */ + memset(&vlan_spec, 0, sizeof(struct rte_flow_item_vlan)); + memset(&vlan_mask, 0, sizeof(struct rte_flow_item_vlan)); + pattern[1].type = RTE_FLOW_ITEM_TYPE_VLAN; + pattern[1].spec = &vlan_spec; + pattern[1].mask = &vlan_mask; + + /* + * setting the third level of the pattern (ip). + * in this example this is the level we care about + * so we set it according to the parameters. + */ + memset(&ip_spec, 0, sizeof(struct rte_flow_item_ipv4)); + memset(&ip_mask, 0, sizeof(struct rte_flow_item_ipv4)); + ip_spec.hdr.dst_addr = htonl(dest_ip); + ip_mask.hdr.dst_addr = dest_mask; + ip_spec.hdr.src_addr = htonl(src_ip); + ip_mask.hdr.src_addr = src_mask; + pattern[2].type = RTE_FLOW_ITEM_TYPE_IPV4; + pattern[2].spec = &ip_spec; + pattern[2].mask = &ip_mask; + + /* the final level must be always type end */ + pattern[3].type = RTE_FLOW_ITEM_TYPE_END; + + int res = rte_flow_validate(port_id, &attr, pattern, action, error); + if(!res) + flow = rte_flow_create(port_id, &attr, pattern, action, error); + + return flow; + } + +The first part of the function is declaring the structures that will be used. + +.. code-block:: c + + struct rte_flow_attr attr; + struct rte_flow_item pattern[MAX_PATTERN_NUM]; + struct rte_flow_action action[MAX_PATTERN_NUM]; + struct rte_flow *flow; + struct rte_flow_error error; + struct rte_flow_action_queue queue = { .index = rx_q }; + struct rte_flow_item_eth eth_spec; + struct rte_flow_item_eth eth_mask; + struct rte_flow_item_vlan vlan_spec; + struct rte_flow_item_vlan vlan_mask; + struct rte_flow_item_ipv4 ip_spec; + struct rte_flow_item_ipv4 ip_mask; + +The following part create the flow attributes, in our case ingress. + +.. code-block:: c + + memset(&attr, 0, sizeof(struct rte_flow_attr)); + attr.ingress = 1; + +The third part defines the action to be taken when a packet matches +the rule. In this case send the packet to queue. + +.. code-block:: c + + action[0].type = RTE_FLOW_ACTION_TYPE_QUEUE; + action[0].conf = &queue; + action[1].type = RTE_FLOW_ACTION_TYPE_END; + +The forth part is responsible for creating the pattern and is build from +number of step. In each step we build one level of the pattern starting with +the lowest one. + +Setting the first level of the pattern ETH: + +.. code-block:: c + + memset(ð_spec, 0, sizeof(struct rte_flow_item_eth)); + memset(ð_mask, 0, sizeof(struct rte_flow_item_eth)); + eth_spec.type = 0; + eth_mask.type = 0; + pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH; + pattern[0].spec = ð_spec; + pattern[0].mask = ð_mask; + +Setting the second level of the pattern VLAN: + +.. code-block:: c + + memset(&vlan_spec, 0, sizeof(struct rte_flow_item_vlan)); + memset(&vlan_mask, 0, sizeof(struct rte_flow_item_vlan)); + pattern[1].type = RTE_FLOW_ITEM_TYPE_VLAN; + pattern[1].spec = &vlan_spec; + pattern[1].mask = &vlan_mask; + +Setting the third level ip: + +.. code-block:: c + + memset(&ip_spec, 0, sizeof(struct rte_flow_item_ipv4)); + memset(&ip_mask, 0, sizeof(struct rte_flow_item_ipv4)); + ip_spec.hdr.dst_addr = htonl(dest_ip); + ip_mask.hdr.dst_addr = dest_mask; + ip_spec.hdr.src_addr = htonl(src_ip); + ip_mask.hdr.src_addr = src_mask; + pattern[2].type = RTE_FLOW_ITEM_TYPE_IPV4; + pattern[2].spec = &ip_spec; + pattern[2].mask = &ip_mask; + +Closing the pattern part. + +.. code-block:: c + + pattern[3].type = RTE_FLOW_ITEM_TYPE_END; + +The last part of the function is to validate the rule and create it. + +.. code-block:: c + + int res = rte_flow_validate(port_id, &attr, pattern, action, &error); + if (!res) + flow = rte_flow_create(port_id, &attr, pattern, action, &error); + diff --git a/doc/guides/sample_app_ug/hello_world.rst b/doc/guides/sample_app_ug/hello_world.rst index f4753af0..3018d459 100644 --- a/doc/guides/sample_app_ug/hello_world.rst +++ b/doc/guides/sample_app_ug/hello_world.rst @@ -37,26 +37,9 @@ The application simply prints an "helloworld" message on every enabled lcore. Compiling the Application ------------------------- -#. Go to the example directory: +To compile the sample application see :doc:`compiling`. - .. code-block:: console - - export RTE_SDK=/path/to/rte_sdk - cd ${RTE_SDK}/examples/helloworld - -#. Set the target (a default target is used if not specified). For example: - - .. code-block:: console - - export RTE_TARGET=x86_64-native-linuxapp-gcc - - See the *DPDK Getting Started* Guide for possible RTE_TARGET values. - -#. Build the application: - - .. code-block:: console - - make +The application is located in the ``helloworld`` sub-directory. Running the Application ----------------------- diff --git a/doc/guides/sample_app_ug/index.rst b/doc/guides/sample_app_ug/index.rst index 069d4f12..db68ef76 100644 --- a/doc/guides/sample_app_ug/index.rst +++ b/doc/guides/sample_app_ug/index.rst @@ -36,12 +36,15 @@ Sample Applications User Guides :numbered: intro + compiling cmd_line ethtool exception_path hello_world skeleton rxtx_callbacks + flow_classify + flow_filtering ip_frag ipv4_multicast ip_reassembly @@ -58,6 +61,7 @@ Sample Applications User Guides link_status_intr load_balancer server_node_efd + service_cores multi_process qos_metering qos_scheduler diff --git a/doc/guides/sample_app_ug/intro.rst b/doc/guides/sample_app_ug/intro.rst index d3f261b3..ae12503b 100644 --- a/doc/guides/sample_app_ug/intro.rst +++ b/doc/guides/sample_app_ug/intro.rst @@ -1,5 +1,5 @@ .. BSD LICENSE - Copyright(c) 2010-2014 Intel Corporation. All rights reserved. + Copyright(c) 2010-2017 Intel Corporation. All rights reserved. All rights reserved. Redistribution and use in source and binary forms, with or without @@ -28,42 +28,115 @@ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -Introduction -============ - -This document describes the sample applications that are included in the Data Plane Development Kit (DPDK). -Each chapter describes a sample application that showcases specific functionality and -provides instructions on how to compile, run and use the sample application. - -Documentation Roadmap ---------------------- - -The following is a list of DPDK documents in suggested reading order: - -* **Release Notes** : Provides release-specific information, including supported features, - limitations, fixed issues, known issues and so on. - Also, provides the answers to frequently asked questions in FAQ format. - -* **Getting Started Guides** : Describes how to install and - configure the DPDK software for your operating system; - designed to get users up and running quickly with the software. - -* **Programmer's Guide:** Describes: - - * The software architecture and how to use it (through examples), - specifically in a Linux* application (linuxapp) environment. - - * The content of the DPDK, the build system - (including the commands that can be used in the root DPDK Makefile to build the development kit and an application) - and guidelines for porting an application. - - * Optimizations used in the software and those that should be considered for new development - -A glossary of terms is also provided. - -* **API Reference** : Provides detailed information about DPDK functions, - data structures and other programming constructs. - -* **Sample Applications User Guide** : Describes a set of sample applications. - Each chapter describes a sample application that showcases specific functionality and - provides instructions on how to compile, run and use the sample application. +Introduction to the DPDK Sample Applications +============================================ + +The DPDK Sample Applications are small standalone applications which +demonstrate various features of DPDK. They can be considered as a cookbook of +DPDK features. Users interested in getting started with DPDK can take the +applications, try out the features, and then extend them to fit their needs. + + +The DPDK Sample Applications +---------------------------- + +Table :numref:`table_sample_apps` shows a list of some of the main sample +applications that are available in the examples directory of DPDK: + + .. _table_sample_apps: + + .. table:: **Some of the DPDK Sample applications** + + +---------------------------------------+--------------------------------------+ + | Bonding | Netmap Compatibility | + +---------------------------------------+--------------------------------------+ + | Command Line | Packet Ordering | + +---------------------------------------+--------------------------------------+ + | Distributor | Performance Thread | + +---------------------------------------+--------------------------------------+ + | Ethtool | Precision Time Protocol (PTP) Client | + +---------------------------------------+--------------------------------------+ + | Exception Path | Quality of Service (QoS) Metering | + +---------------------------------------+--------------------------------------+ + | Hello World | QoS Scheduler | + +---------------------------------------+--------------------------------------+ + | Internet Protocol (IP) Fragmentation | Quota and Watermark | + +---------------------------------------+--------------------------------------+ + | IP Pipeline | RX/TX Callbacks | + +---------------------------------------+--------------------------------------+ + | IP Reassembly | Server node EFD | + +---------------------------------------+--------------------------------------+ + | IPsec Security Gateway | Basic Forwarding/Skeleton App | + +---------------------------------------+--------------------------------------+ + | IPv4 multicast | Tunnel End Point (TEP) termination | + +---------------------------------------+--------------------------------------+ + | Kernel NIC Interface | Timer | + +---------------------------------------+--------------------------------------+ + | Network Layer 2 Forwarding + variants | Vhost | + +---------------------------------------+--------------------------------------+ + | Network Layer 3 Forwarding + variants | Vhost Xen | + +---------------------------------------+--------------------------------------+ + | Link Status Interrupt | VMDQ Forwarding | + +---------------------------------------+--------------------------------------+ + | Load Balancer | VMDQ and DCB Forwarding | + +---------------------------------------+--------------------------------------+ + | Multi-process | VM Power Management | + +---------------------------------------+--------------------------------------+ + +These examples range from simple to reasonably complex but most are designed +to demonstrate one particular feature of DPDK. Some of the more interesting +examples are highlighted below. + + +* :doc:`Hello World<hello_world>`: As with most introductions to a + programming framework a good place to start is with the Hello World + application. The Hello World example sets up the DPDK Environment Abstraction + Layer (EAL), and prints a simple "Hello World" message to each of the DPDK + enabled cores. This application doesn't do any packet forwarding but it is a + good way to test if the DPDK environment is compiled and set up properly. + +* :doc:`Basic Forwarding/Skeleton Application<skeleton>`: The Basic + Forwarding/Skeleton contains the minimum amount of code required to enable + basic packet forwarding with DPDK. This allows you to test if your network + interfaces are working with DPDK. + +* :doc:`Network Layer 2 forwarding<l2_forward_real_virtual>`: The Network Layer 2 + forwarding, or ``l2fwd`` application does forwarding based on Ethernet MAC + addresses like a simple switch. + +* :doc:`Network Layer 3 forwarding<l3_forward>`: The Network Layer3 + forwarding, or ``l3fwd`` application does forwarding based on Internet + Protocol, IPv4 or IPv6 like a simple router. + +* :doc:`Packet Distributor<dist_app>`: The Packet Distributor + demonstrates how to distribute packets arriving on an Rx port to different + cores for processing and transmission. + +* :doc:`Multi-Process Application<multi_process>`: The + multi-process application shows how two DPDK processes can work together using + queues and memory pools to share information. + +* :doc:`RX/TX callbacks Application<rxtx_callbacks>`: The RX/TX + callbacks sample application is a packet forwarding application that + demonstrates the use of user defined callbacks on received and transmitted + packets. The application calculates the latency of a packet between RX + (packet arrival) and TX (packet transmission) by adding callbacks to the RX + and TX packet processing functions. + +* :doc:`IPSec Security Gateway<ipsec_secgw>`: The IPSec Security + Gateway application is minimal example of something closer to a real world + example. This is also a good example of an application using the DPDK + Cryptodev framework. + +* :doc:`Precision Time Protocol (PTP) client<ptpclient>`: The PTP + client is another minimal implementation of a real world application. + In this case the application is a PTP client that communicates with a PTP + master clock to synchronize time on a Network Interface Card (NIC) using the + IEEE1588 protocol. + +* :doc:`Quality of Service (QoS) Scheduler<qos_scheduler>`: The QoS + Scheduler application demonstrates the use of DPDK to provide QoS scheduling. + +There are many more examples shown in the following chapters. Each of the +documented sample applications show how to compile, configure and run the +application as well as explaining the main functionality of the code. diff --git a/doc/guides/sample_app_ug/ip_frag.rst b/doc/guides/sample_app_ug/ip_frag.rst index bd1fe2dc..f45adfe7 100644 --- a/doc/guides/sample_app_ug/ip_frag.rst +++ b/doc/guides/sample_app_ug/ip_frag.rst @@ -59,31 +59,12 @@ Any unmatched packets are forwarded to the originating port. By default, input frame sizes up to 9.5 KB are supported. Before forwarding, the input IP packet is fragmented to fit into the "standard" Ethernet* v2 MTU (1500 bytes). -Building the Application ------------------------- +Compiling the Application +------------------------- -To build the application: +To compile the sample application see :doc:`compiling`. -#. Go to the sample application directory: - - .. code-block:: console - - export RTE_SDK=/path/to/rte_sdk - cd ${RTE_SDK}/examples/ip_fragmentation - -#. Set the target (a default target is used if not specified). For example: - - .. code-block:: console - - export RTE_TARGET=x86_64-native-linuxapp-gcc - -See the *DPDK Getting Started Guide* for possible RTE_TARGET values. - -#. Build the application: - - .. code-block:: console - - make +The application is located in the ``ip_fragmentation`` sub-directory. Running the Application ----------------------- diff --git a/doc/guides/sample_app_ug/ip_reassembly.rst b/doc/guides/sample_app_ug/ip_reassembly.rst index cc9e5911..7dc80d0b 100644 --- a/doc/guides/sample_app_ug/ip_reassembly.rst +++ b/doc/guides/sample_app_ug/ip_reassembly.rst @@ -53,28 +53,14 @@ There are two key differences from the L2 Forwarding sample application: The Longest Prefix Match (LPM for IPv4, LPM6 for IPv6) table is used to store/lookup an outgoing port number, associated with that IPv4 address. Any unmatched packets are forwarded to the originating port.Compiling the Application -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -To compile the application: -#. Go to the sample application directory: +Compiling the Application +------------------------- - .. code-block:: console +To compile the sample application see :doc:`compiling`. - export RTE_SDK=/path/to/rte_sdk - cd ${RTE_SDK}/examples/ip_reassembly +The application is located in the ``ip_reassembly`` sub-directory. -#. Set the target (a default target is used if not specified). For example: - - .. code-block:: console - - export RTE_TARGET=x86_64-native-linuxapp-gcc - -See the *DPDK Getting Started Guide* for possible RTE_TARGET values. - -#. Build the application: - - .. code-block:: console - - make Running the Application ----------------------- diff --git a/doc/guides/sample_app_ug/ipsec_secgw.rst b/doc/guides/sample_app_ug/ipsec_secgw.rst index b675cbae..d6cfdbf7 100644 --- a/doc/guides/sample_app_ug/ipsec_secgw.rst +++ b/doc/guides/sample_app_ug/ipsec_secgw.rst @@ -52,13 +52,22 @@ The application classifies the ports as *Protected* and *Unprotected*. Thus, traffic received on an Unprotected or Protected port is consider Inbound or Outbound respectively. +The application also supports complete IPSec protocol offload to hardware +(Look aside crypto accelarator or using ethernet device). It also support +inline ipsec processing by the supported ethernet device during transmission. +These modes can be selected during the SA creation configuration. + +In case of complete protocol offload, the processing of headers(ESP and outer +IP header) is done by the hardware and the application does not need to +add/remove them during outbound/inbound processing. + The Path for IPsec Inbound traffic is: * Read packets from the port. * Classify packets between IPv4 and ESP. * Perform Inbound SA lookup for ESP packets based on their SPI. -* Perform Verification/Decryption. -* Remove ESP and outer IP header +* Perform Verification/Decryption (Not needed in case of inline ipsec). +* Remove ESP and outer IP header (Not needed in case of protocol offload). * Inbound SP check using ACL of decrypted packets and any other IPv4 packets. * Routing. * Write packet to port. @@ -68,8 +77,8 @@ The Path for the IPsec Outbound traffic is: * Read packets from the port. * Perform Outbound SP check using ACL of all IPv4 traffic. * Perform Outbound SA lookup for packets that need IPsec protection. -* Add ESP and outer IP header. -* Perform Encryption/Digest. +* Add ESP and outer IP header (Not needed in case protocol offload). +* Perform Encryption/Digest (Not needed in case of inline ipsec). * Routing. * Write packet to port. @@ -83,27 +92,12 @@ Constraints * Each SA must be handle by a unique lcore (*1 RX queue per port*). * No chained mbufs. - Compiling the Application ------------------------- -To compile the application: - -#. Go to the sample application directory:: - - export RTE_SDK=/path/to/rte_sdk - cd ${RTE_SDK}/examples/ipsec-secgw - -#. Set the target (a default target is used if not specified). For example:: - +To compile the sample application see :doc:`compiling`. - export RTE_TARGET=x86_64-native-linuxapp-gcc - - See the *DPDK Getting Started Guide* for possible RTE_TARGET values. - -#. Build the application:: - - make +The application is located in the ``rpsec-secgw`` sub-directory. #. [Optional] Build the application for debugging: This option adds some extra flags, disables compiler optimizations and @@ -119,7 +113,7 @@ The application has a number of command line options:: ./build/ipsec-secgw [EAL options] -- - -p PORTMASK -P -u PORTMASK + -p PORTMASK -P -u PORTMASK -j FRAMESIZE --config (port,queue,lcore)[,(port,queue,lcore] --single-sa SAIDX -f CONFIG_FILE_PATH @@ -135,6 +129,10 @@ Where: * ``-u PORTMASK``: hexadecimal bitmask of unprotected ports +* ``-j FRAMESIZE``: *optional*. Enables jumbo frames with the maximum size + specified as FRAMESIZE. If an invalid value is provided as FRAMESIZE + then the default value 9000 is used. + * ``--config (port,queue,lcore)[,(port,queue,lcore)]``: determines which queues from which ports are mapped to which cores. @@ -385,7 +383,7 @@ The SA rule syntax is shown as follows: .. code-block:: console sa <dir> <spi> <cipher_algo> <cipher_key> <auth_algo> <auth_key> - <mode> <src_ip> <dst_ip> + <mode> <src_ip> <dst_ip> <action_type> <port_id> where each options means: @@ -526,6 +524,34 @@ where each options means: * *dst X.X.X.X* for IPv4 * *dst XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX* for IPv6 +``<type>`` + + * Action type to specify the security action. This option specify + the SA to be performed with look aside protocol offload to HW + accelerator or protocol offload on ethernet device or inline + crypto processing on the ethernet device during transmission. + + * Optional: Yes, default type *no-offload* + + * Available options: + + * *lookaside-protocol-offload*: look aside protocol offload to HW accelerator + * *inline-protocol-offload*: inline protocol offload on ethernet device + * *inline-crypto-offload*: inline crypto processing on ethernet device + * *no-offload*: no offloading to hardware + + ``<port_id>`` + + * Port/device ID of the ethernet/crypto accelerator for which the SA is + configured. This option is used when *type* is NOT *no-offload* + + * Optional: No, if *type* is not *no-offload* + + * Syntax: + + * *port_id X* X is a valid device number in decimal + + Example SA rules: .. code-block:: console @@ -545,6 +571,11 @@ Example SA rules: aead_key de:ad:be:ef:de:ad:be:ef:de:ad:be:ef:de:ad:be:ef:de:ad:be:ef \ mode ipv4-tunnel src 172.16.2.5 dst 172.16.1.5 + sa out 5 cipher_algo aes-128-cbc cipher_key 0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0 \ + auth_algo sha1-hmac auth_key 0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0 \ + mode ipv4-tunnel src 172.16.1.5 dst 172.16.2.5 \ + type lookaside-protocol-offload port_id 4 + Routing rule syntax ^^^^^^^^^^^^^^^^^^^ diff --git a/doc/guides/sample_app_ug/ipv4_multicast.rst b/doc/guides/sample_app_ug/ipv4_multicast.rst index 49712a0f..fd1af006 100644 --- a/doc/guides/sample_app_ug/ipv4_multicast.rst +++ b/doc/guides/sample_app_ug/ipv4_multicast.rst @@ -63,37 +63,12 @@ with the mask of ports to multicast packets to. Also, the application does not consider the Ethernet addresses; it looks only at the IPv4 destination address for any given packet. -Building the Application ------------------------- +Compiling the Application +------------------------- -To compile the application: +To compile the sample application see :doc:`compiling`. -#. Go to the sample application directory: - - .. code-block:: console - - export RTE_SDK=/path/to/rte_sdk - cd ${RTE_SDK}/examples/ipv4_multicast - -#. Set the target (a default target is used if not specified). For example: - - .. code-block:: console - - export RTE_TARGET=x86_64-native-linuxapp-gcc - -See the *DPDK Getting Started Guide* for possible RTE_TARGET values. - -#. Build the application: - - .. code-block:: console - - make - -.. note:: - - The compiled application is written to the build subdirectory. - To have the application written to a different location, - the O=/path/to/build/directory option may be specified in the make command. +The application is located in the ``ipv4_multicast`` sub-directory. Running the Application ----------------------- @@ -268,7 +243,7 @@ The actual packet transmission is done in the mcast_send_pkt() function: .. code-block:: c - static inline void mcast_send_pkt(struct rte_mbuf *pkt, struct ether_addr *dest_addr, struct lcore_queue_conf *qconf, uint8_t port) + static inline void mcast_send_pkt(struct rte_mbuf *pkt, struct ether_addr *dest_addr, struct lcore_queue_conf *qconf, uint16_t port) { struct ether_hdr *ethdr; uint16_t len; diff --git a/doc/guides/sample_app_ug/keep_alive.rst b/doc/guides/sample_app_ug/keep_alive.rst index fe908206..9b8be489 100644 --- a/doc/guides/sample_app_ug/keep_alive.rst +++ b/doc/guides/sample_app_ug/keep_alive.rst @@ -66,27 +66,9 @@ of the L2 forwarding application. Compiling the Application ------------------------- -To compile the application: +To compile the sample application see :doc:`compiling`. -#. Go to the sample application directory: - - .. code-block:: console - - export RTE_SDK=/path/to/rte_sdk cd ${RTE_SDK}/examples/keep_alive - -#. Set the target (a default target is used if not specified). For example: - - .. code-block:: console - - export RTE_TARGET=x86_64-native-linuxapp-gcc - - See the *DPDK Getting Started Guide* for possible RTE_TARGET values. - -#. Build the application: - - .. code-block:: console - - make +The application is located in the ``l2fwd_keep_alive`` sub-directory. Running the Application ----------------------- diff --git a/doc/guides/sample_app_ug/kernel_nic_interface.rst b/doc/guides/sample_app_ug/kernel_nic_interface.rst index 619a7b52..e1ac4153 100644 --- a/doc/guides/sample_app_ug/kernel_nic_interface.rst +++ b/doc/guides/sample_app_ug/kernel_nic_interface.rst @@ -77,35 +77,17 @@ The packet flow through the Kernel NIC Interface application is as shown in the Kernel NIC Application Packet Flow - Compiling the Application ------------------------- -Compile the application as follows: - -#. Go to the example directory: - - .. code-block:: console +To compile the sample application see :doc:`compiling`. - export RTE_SDK=/path/to/rte_sdk - cd ${RTE_SDK}/examples/kni +The application is located in the ``kni`` sub-directory. -#. Set the target (a default target is used if not specified) - - .. note:: +.. note:: This application is intended as a linuxapp only. - .. code-block:: console - - export RTE_TARGET=x86_64-native-linuxapp-gcc - -#. Build the application: - - .. code-block:: console - - make - Loading the Kernel Module ------------------------- @@ -246,7 +228,7 @@ The code for allocating the kernel NIC interfaces for a specific port is as foll .. code-block:: c static int - kni_alloc(uint8_t port_id) + kni_alloc(uint16_t port_id) { uint8_t i; struct rte_kni *kni; @@ -335,7 +317,7 @@ The code is as follows: int i, j, nb_token; char *str_fld[_NUM_FLD]; unsigned long int_fld[_NUM_FLD]; - uint8_t port_id, nb_kni_port_params = 0; + uint16_t port_id, nb_kni_port_params = 0; memset(&kni_port_params_array, 0, sizeof(kni_port_params_array)); @@ -532,7 +514,7 @@ Currently, setting a new MTU and configuring the network interface (up/ down) ar /* Callback for request of changing MTU */ static int - kni_change_mtu(uint8_t port_id, unsigned new_mtu) + kni_change_mtu(uint16_t port_id, unsigned new_mtu) { int ret; struct rte_eth_conf conf; @@ -581,7 +563,7 @@ Currently, setting a new MTU and configuring the network interface (up/ down) ar /* Callback for request of configuring network interface up/down */ static int - kni_config_network_interface(uint8_t port_id, uint8_t if_up) + kni_config_network_interface(uint16_t port_id, uint8_t if_up) { int ret = 0; diff --git a/doc/guides/sample_app_ug/l2_forward_cat.rst b/doc/guides/sample_app_ug/l2_forward_cat.rst index b0c2e109..a10f23a1 100644 --- a/doc/guides/sample_app_ug/l2_forward_cat.rst +++ b/doc/guides/sample_app_ug/l2_forward_cat.rst @@ -67,38 +67,28 @@ White paper demonstrating example use case: Compiling the Application ------------------------- +.. note:: -Requires ``libpqos`` from Intel's -`intel-cmt-cat software package <https://github.com/01org/intel-cmt-cat>`_ -hosted on GitHub repository. For installation notes, please see ``README`` file. + Requires ``libpqos`` from Intel's + `intel-cmt-cat software package <https://github.com/01org/intel-cmt-cat>`_ + hosted on GitHub repository. For installation notes, please see ``README`` file. -GIT: + GIT: -* https://github.com/01org/intel-cmt-cat - -To compile the application export the path to PQoS lib -and the DPDK source tree and go to the example directory: - -.. code-block:: console + * https://github.com/01org/intel-cmt-cat - export PQOS_INSTALL_PATH=/path/to/libpqos - export RTE_SDK=/path/to/rte_sdk - cd ${RTE_SDK}/examples/l2fwd-cat +#. To compile the application export the path to PQoS lib + and the DPDK source tree and go to the example directory: -Set the target, for example: + .. code-block:: console -.. code-block:: console - - export RTE_TARGET=x86_64-native-linuxapp-gcc + export PQOS_INSTALL_PATH=/path/to/libpqos -See the *DPDK Getting Started* Guide for possible ``RTE_TARGET`` values. -Build the application as follows: - -.. code-block:: console +To compile the sample application see :doc:`compiling`. - make +The application is located in the ``l2fwd-cat`` sub-directory. Running the Application diff --git a/doc/guides/sample_app_ug/l2_forward_crypto.rst b/doc/guides/sample_app_ug/l2_forward_crypto.rst index 158f4b44..1e85b4a3 100644 --- a/doc/guides/sample_app_ug/l2_forward_crypto.rst +++ b/doc/guides/sample_app_ug/l2_forward_crypto.rst @@ -55,26 +55,9 @@ Also, if MAC addresses updating is enabled, the MAC addresses are affected as fo Compiling the Application ------------------------- -#. Go to the example directory: +To compile the sample application see :doc:`compiling`. - .. code-block:: console - - export RTE_SDK=/path/to/rte_sdk - cd ${RTE_SDK}/examples/l2fwd-crypto - -#. Set the target (a default target is used if not specified). For example: - - .. code-block:: console - - export RTE_TARGET=x86_64-native-linuxapp-gcc - - *See the DPDK Getting Started Guide* for possible RTE_TARGET values. - -#. Build the application: - - .. code-block:: console - - make +The application is located in the ``l2fwd-crypt`` sub-directory. Running the Application ----------------------- diff --git a/doc/guides/sample_app_ug/l2_forward_job_stats.rst b/doc/guides/sample_app_ug/l2_forward_job_stats.rst index 1029cc8f..54b970f8 100644 --- a/doc/guides/sample_app_ug/l2_forward_job_stats.rst +++ b/doc/guides/sample_app_ug/l2_forward_job_stats.rst @@ -97,26 +97,9 @@ in this case enabling a total of four Virtual Functions. Compiling the Application ------------------------- -#. Go to the example directory: +To compile the sample application see :doc:`compiling`. - .. code-block:: console - - export RTE_SDK=/path/to/rte_sdk - cd ${RTE_SDK}/examples/l2fwd-jobstats - -#. Set the target (a default target is used if not specified). For example: - - .. code-block:: console - - export RTE_TARGET=x86_64-native-linuxapp-gcc - - *See the DPDK Getting Started Guide* for possible RTE_TARGET values. - -#. Build the application: - - .. code-block:: console - - make +The application is located in the ``l2fwd-jobstats`` sub-directory. Running the Application ----------------------- @@ -558,7 +541,7 @@ If the table is full, the whole packets table is transmitted using the l2fwd_sen /* Send the packet on an output interface */ static int - l2fwd_send_packet(struct rte_mbuf *m, uint8_t port) + l2fwd_send_packet(struct rte_mbuf *m, uint16_t port) { unsigned lcore_id, len; struct lcore_queue_conf *qconf; @@ -593,7 +576,7 @@ however it improves performance: unsigned lcore_id; struct lcore_queue_conf *qconf; struct mbuf_table *m_table; - uint8_t portid; + uint16_t portid; lcore_id = rte_lcore_id(); qconf = &lcore_queue_conf[lcore_id]; diff --git a/doc/guides/sample_app_ug/l2_forward_real_virtual.rst b/doc/guides/sample_app_ug/l2_forward_real_virtual.rst index f579c8fe..4d9cae43 100644 --- a/doc/guides/sample_app_ug/l2_forward_real_virtual.rst +++ b/doc/guides/sample_app_ug/l2_forward_real_virtual.rst @@ -107,26 +107,9 @@ in this case enabling a total of four Virtual Functions. Compiling the Application ------------------------- -#. Go to the example directory: +To compile the sample application see :doc:`compiling`. - .. code-block:: console - - export RTE_SDK=/path/to/rte_sdk - cd ${RTE_SDK}/examples/l2fwd - -#. Set the target (a default target is used if not specified). For example: - - .. code-block:: console - - export RTE_TARGET=x86_64-native-linuxapp-gcc - - *See the DPDK Getting Started Guide* for possible RTE_TARGET values. - -#. Build the application: - - .. code-block:: console - - make +The application is located in the ``l2fwd`` sub-directory. Running the Application ----------------------- @@ -474,7 +457,7 @@ If the table is full, the whole packets table is transmitted using the l2fwd_sen /* Send the packet on an output interface */ static int - l2fwd_send_packet(struct rte_mbuf *m, uint8_t port) + l2fwd_send_packet(struct rte_mbuf *m, uint16_t port) { unsigned lcore_id, len; struct lcore_queue_conf *qconf; diff --git a/doc/guides/sample_app_ug/l3_forward.rst b/doc/guides/sample_app_ug/l3_forward.rst index 6a6b8fbe..19b91e27 100644 --- a/doc/guides/sample_app_ug/l3_forward.rst +++ b/doc/guides/sample_app_ug/l3_forward.rst @@ -62,28 +62,9 @@ In the sample application, hash-based forwarding supports IPv4 and IPv6. LPM-bas Compiling the Application ------------------------- -To compile the application: +To compile the sample application see :doc:`compiling`. -#. Go to the sample application directory: - - .. code-block:: console - - export RTE_SDK=/path/to/rte_sdk - cd ${RTE_SDK}/examples/l3fwd - -#. Set the target (a default target is used if not specified). For example: - - .. code-block:: console - - export RTE_TARGET=x86_64-native-linuxapp-gcc - - See the *DPDK Getting Started Guide* for possible RTE_TARGET values. - -#. Build the application: - - .. code-block:: console - - make +The application is located in the ``l3fwd`` sub-directory. Running the Application ----------------------- @@ -283,7 +264,7 @@ The get_ipv4_dst_port() function is shown below: .. code-block:: c static inline uint8_t - get_ipv4_dst_port(void *ipv4_hdr, uint8_t portid, lookup_struct_t *ipv4_l3fwd_lookup_struct) + get_ipv4_dst_port(void *ipv4_hdr, uint16_t portid, lookup_struct_t *ipv4_l3fwd_lookup_struct) { int ret = 0; union ipv4_5tuple_host key; @@ -312,7 +293,7 @@ The key code snippet of simple_ipv4_fwd_4pkts() is shown below: .. code-block:: c static inline void - simple_ipv4_fwd_4pkts(struct rte_mbuf* m[4], uint8_t portid, struct lcore_conf *qconf) + simple_ipv4_fwd_4pkts(struct rte_mbuf* m[4], uint16_t portid, struct lcore_conf *qconf) { // ... @@ -351,10 +332,10 @@ for LPM-based lookups is done by the get_ipv4_dst_port() function below: .. code-block:: c - static inline uint8_t - get_ipv4_dst_port(struct ipv4_hdr *ipv4_hdr, uint8_t portid, lookup_struct_t *ipv4_l3fwd_lookup_struct) + static inline uint16_t + get_ipv4_dst_port(struct ipv4_hdr *ipv4_hdr, uint16_t portid, lookup_struct_t *ipv4_l3fwd_lookup_struct) { uint8_t next_hop; - return (uint8_t) ((rte_lpm_lookup(ipv4_l3fwd_lookup_struct, rte_be_to_cpu_32(ipv4_hdr->dst_addr), &next_hop) == 0)? next_hop : portid); + return ((rte_lpm_lookup(ipv4_l3fwd_lookup_struct, rte_be_to_cpu_32(ipv4_hdr->dst_addr), &next_hop) == 0)? next_hop : portid); } diff --git a/doc/guides/sample_app_ug/l3_forward_access_ctrl.rst b/doc/guides/sample_app_ug/l3_forward_access_ctrl.rst index a6aa4fb1..dfd372fb 100644 --- a/doc/guides/sample_app_ug/l3_forward_access_ctrl.rst +++ b/doc/guides/sample_app_ug/l3_forward_access_ctrl.rst @@ -252,28 +252,9 @@ Once the application starts, it transitions through three phases: Compiling the Application ------------------------- -To compile the application: +To compile the sample application see :doc:`compiling`. -#. Go to the sample application directory: - - .. code-block:: console - - export RTE_SDK=/path/to/rte_sdk - cd ${RTE_SDK}/examples/l3fwd-acl - -#. Set the target (a default target is used if not specified). For example: - - .. code-block:: console - - export RTE_TARGET=x86_64-native-linuxapp-gcc - - See the *DPDK IPL Getting Started Guide* for possible RTE_TARGET values. - -#. Build the application: - - .. code-block:: console - - make +The application is located in the ``l3fwd-acl`` sub-directory. Running the Application ----------------------- diff --git a/doc/guides/sample_app_ug/l3_forward_power_man.rst b/doc/guides/sample_app_ug/l3_forward_power_man.rst index ea9c404d..20fcc3c6 100644 --- a/doc/guides/sample_app_ug/l3_forward_power_man.rst +++ b/doc/guides/sample_app_ug/l3_forward_power_man.rst @@ -104,28 +104,9 @@ instead of always running to the C0 state waiting for packets. Compiling the Application ------------------------- -To compile the application: +To compile the sample application see :doc:`compiling`. -#. Go to the sample application directory: - - .. code-block:: console - - export RTE_SDK=/path/to/rte_sdk - cd ${RTE_SDK}/examples/l3fwd-power - -#. Set the target (a default target is used if not specified). For example: - - .. code-block:: console - - export RTE_TARGET=x86_64-native-linuxapp-gcc - - See the *DPDK Getting Started Guide* for possible RTE_TARGET values. - -#. Build the application: - - .. code-block:: console - - make +The application is located in the ``l3fwd-power`` sub-directory. Running the Application ----------------------- @@ -181,11 +162,11 @@ responsible for checking if it needs to scale down frequency at run time by chec struct lcore_conf *qconf; int ret; unsigned nb_ports; - uint16_t queueid; + uint16_t queueid, portid; unsigned lcore_id; uint64_t hz; uint32_t n_tx_queue, nb_lcores; - uint8_t portid, nb_rx_queue, queue, socketid; + uint8_t nb_rx_queue, queue, socketid; // ... diff --git a/doc/guides/sample_app_ug/l3_forward_virtual.rst b/doc/guides/sample_app_ug/l3_forward_virtual.rst index 5f9d8948..95e89651 100644 --- a/doc/guides/sample_app_ug/l3_forward_virtual.rst +++ b/doc/guides/sample_app_ug/l3_forward_virtual.rst @@ -64,34 +64,9 @@ The set of LPM rules used by the application is statically configured and loaded Compiling the Application ------------------------- -To compile the application: +To compile the sample application see :doc:`compiling`. -#. Go to the sample application directory: - - .. code-block:: console - - export RTE_SDK=/path/to/rte_sdk - cd ${RTE_SDK}/examples/l3fwd-vf - -#. Set the target (a default target is used if not specified). For example: - - .. code-block:: console - - export RTE_TARGET=x86_64-native-linuxapp-gcc - - See the *DPDK Getting Started Guide* for possible RTE_TARGET values. - -#. Build the application: - - .. code-block:: console - - make - -.. note:: - - The compiled application is written to the build subdirectory. - To have the application written to a different location, - the O=/path/to/build/directory option may be specified in the make command. +The application is located in the ``l3fwd-vf`` sub-directory. Running the Application ----------------------- diff --git a/doc/guides/sample_app_ug/link_status_intr.rst b/doc/guides/sample_app_ug/link_status_intr.rst index f9af4749..358524c3 100644 --- a/doc/guides/sample_app_ug/link_status_intr.rst +++ b/doc/guides/sample_app_ug/link_status_intr.rst @@ -55,32 +55,9 @@ and the behavior of L2 forwarding each time the link status changes. Compiling the Application ------------------------- -#. Go to the example directory: +To compile the sample application see :doc:`compiling`. - .. code-block:: console - - export RTE_SDK=/path/to/rte_sdk - cd ${RTE_SDK}/examples/link_status_interrupt - -#. Set the target (a default target is used if not specified). For example: - - .. code-block:: console - - export RTE_TARGET=x86_64-native-linuxapp-gcc - - See the *DPDK Getting Started Guide* for possible RTE_TARGET values. - -#. Build the application: - - .. code-block:: console - - make - -.. note:: - - The compiled application is written to the build subdirectory. - To have the application written to a different location, - the O=/path/to/build/directory option may be specified on the make command line. +The application is located in the ``link_status_interrupt`` sub-directory. Running the Application ----------------------- @@ -219,7 +196,7 @@ An example callback function that has been written as indicated below. .. code-block:: c static void - lsi_event_callback(uint8_t port_id, enum rte_eth_event_type type, void *param) + lsi_event_callback(uint16_t port_id, enum rte_eth_event_type type, void *param) { struct rte_eth_link link; @@ -405,7 +382,7 @@ If the table is full, the whole packets table is transmitted using the lsi_send_ /* Send the packet on an output interface */ static int - lsi_send_packet(struct rte_mbuf *m, uint8_t port) + lsi_send_packet(struct rte_mbuf *m, uint16_t port) { unsigned lcore_id, len; struct lcore_queue_conf *qconf; diff --git a/doc/guides/sample_app_ug/load_balancer.rst b/doc/guides/sample_app_ug/load_balancer.rst index e101a5f2..18b29b24 100644 --- a/doc/guides/sample_app_ug/load_balancer.rst +++ b/doc/guides/sample_app_ug/load_balancer.rst @@ -86,24 +86,9 @@ The routing logic is LPM based, with all the worker threads sharing the same LPM Compiling the Application ------------------------- -The sequence of steps used to build the application is: +To compile the sample application see :doc:`compiling`. -#. Export the required environment variables: - - .. code-block:: console - - export RTE_SDK=<Path to the DPDK installation folder> - export RTE_TARGET=x86_64-native-linuxapp-gcc - -#. Build the application executable file: - - .. code-block:: console - - cd ${RTE_SDK}/examples/load_balancer - make - - For more details on how to build the DPDK libraries and sample applications, - please refer to the *DPDK Getting Started Guide.* +The application is located in the ``load_balancer`` sub-directory. Running the Application ----------------------- diff --git a/doc/guides/sample_app_ug/multi_process.rst b/doc/guides/sample_app_ug/multi_process.rst index d4df2fa7..95a32432 100644 --- a/doc/guides/sample_app_ug/multi_process.rst +++ b/doc/guides/sample_app_ug/multi_process.rst @@ -40,31 +40,13 @@ Example Applications Building the Sample Applications ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - The multi-process example applications are built in the same way as other sample applications, and as documented in the *DPDK Getting Started Guide*. -To build all the example applications: - -#. Set RTE_SDK and go to the example directory: - - .. code-block:: console - - export RTE_SDK=/path/to/rte_sdk - cd ${RTE_SDK}/examples/multi_process - -#. Set the target (a default target will be used if not specified). For example: - - .. code-block:: console - - export RTE_TARGET=x86_64-native-linuxapp-gcc - - See the *DPDK Getting Started Guide* for possible RTE_TARGET values. -#. Build the applications: - .. code-block:: console +To compile the sample application see :doc:`compiling`. - make +The applications are located in the ``multi_process`` sub-directory. .. note:: diff --git a/doc/guides/sample_app_ug/netmap_compatibility.rst b/doc/guides/sample_app_ug/netmap_compatibility.rst index 030fd980..955f86b9 100644 --- a/doc/guides/sample_app_ug/netmap_compatibility.rst +++ b/doc/guides/sample_app_ug/netmap_compatibility.rst @@ -121,29 +121,12 @@ The bridge application is an example largely based on the bridge example shipped It shows how a minimal Netmap application with minimal and straightforward source code changes can be run on top of the DPDK. Please refer to ``$RTE_SDK/examples/netmap_compat/bridge/bridge.c`` for an example of a ported application. -Compiling the "bridge" Sample Application ------------------------------------------ +Compiling the Application +------------------------- -#. Go to the example directory: +To compile the sample application see :doc:`compiling`. - .. code-block:: console - - export RTE_SDK=/path/to/rte_sdk - cd ${RTE_SDK}/examples/netmap_compat - -#. Set the target (a default target is used if not specified). For example: - - .. code-block:: console - - export RTE_TARGET=x86_64-native-linuxapp-gcc - - See the *DPDK Getting Started Guide for Linux* for possible ``RTE_TARGET`` values. - -#. Build the application: - - .. code-block:: console - - make +The application is located in the ``netmap_compat`` sub-directory. Running the "bridge" Sample Application --------------------------------------- diff --git a/doc/guides/sample_app_ug/packet_ordering.rst b/doc/guides/sample_app_ug/packet_ordering.rst index ef851500..098cc89f 100644 --- a/doc/guides/sample_app_ug/packet_ordering.rst +++ b/doc/guides/sample_app_ug/packet_ordering.rst @@ -51,28 +51,11 @@ The application uses at least three CPU cores: from the reorder buffer and sends them to the NIC ports for transmission. Compiling the Application --------------------------- +------------------------- -#. Go to the example directory: +To compile the sample application see :doc:`compiling`. - .. code-block:: console - - export RTE_SDK=/path/to/rte_sdk - cd ${RTE_SDK}/examples/helloworld - -#. Set the target (a default target is used if not specified). For example: - - .. code-block:: console - - export RTE_TARGET=x86_64-native-linuxapp-gcc - - See the *DPDK Getting Started* Guide for possible RTE_TARGET values. - -#. Build the application: - - .. code-block:: console - - make +The application is located in the ``packet_ordering`` sub-directory. Running the Application ----------------------- diff --git a/doc/guides/sample_app_ug/performance_thread.rst b/doc/guides/sample_app_ug/performance_thread.rst index a55a6246..57391caf 100644 --- a/doc/guides/sample_app_ug/performance_thread.rst +++ b/doc/guides/sample_app_ug/performance_thread.rst @@ -73,28 +73,10 @@ invalid. Compiling the Application ------------------------- -The application is located in the sample application folder in the -``performance-thread`` folder. -#. Go to the example applications folder - - .. code-block:: console - - export RTE_SDK=/path/to/rte_sdk - cd ${RTE_SDK}/examples/performance-thread/l3fwd-thread - -#. Set the target (a default target is used if not specified). For example: - - .. code-block:: console - - export RTE_TARGET=x86_64-native-linuxapp-gcc - - See the *DPDK Linux Getting Started Guide* for possible RTE_TARGET values. - -#. Build the application: - - make +To compile the sample application see :doc:`compiling`. +The application is located in the `performance-thread/l3fwd-thread` sub-directory. Running the Application ----------------------- diff --git a/doc/guides/sample_app_ug/ptpclient.rst b/doc/guides/sample_app_ug/ptpclient.rst index d3ef1d11..9cbb6c2a 100644 --- a/doc/guides/sample_app_ug/ptpclient.rst +++ b/doc/guides/sample_app_ug/ptpclient.rst @@ -78,39 +78,20 @@ The adjustment for slave can be represented as: If the command line parameter ``-T 1`` is used the application also synchronizes the PTP PHC clock with the Linux kernel clock. - Compiling the Application ------------------------- -To compile the application, export the path to the DPDK source tree and edit -the ``config/common_linuxapp`` configuration file to enable IEEE1588: - -.. code-block:: console - - export RTE_SDK=/path/to/rte_sdk - - # Edit common_linuxapp and set the following options: - CONFIG_RTE_LIBRTE_IEEE1588=y - -Set the target, for example: +To compile the sample application see :doc:`compiling`. -.. code-block:: console - - export RTE_TARGET=x86_64-native-linuxapp-gcc - -See the *DPDK Getting Started* Guide for possible ``RTE_TARGET`` values. - -Build the application as follows: - -.. code-block:: console +The application is located in the ``ptpclient`` sub-directory. - # Recompile DPDK. - make install T=$RTE_TARGET +.. note:: + To compile the application edit the ``config/common_linuxapp`` configuration file to enable IEEE1588 + and then recompile DPDK: - # Compile the application. - cd ${RTE_SDK}/examples/ptpclient - make + .. code-block:: console + CONFIG_RTE_LIBRTE_IEEE1588=y Running the Application ----------------------- @@ -257,7 +238,7 @@ PTP IEEE1588 L2 functionality. .. code-block:: c void - parse_ptp_frames(uint8_t portid, struct rte_mbuf *m) { + parse_ptp_frames(uint16_t portid, struct rte_mbuf *m) { struct ptp_header *ptp_hdr; struct ether_hdr *eth_hdr; uint16_t eth_type; diff --git a/doc/guides/sample_app_ug/qos_metering.rst b/doc/guides/sample_app_ug/qos_metering.rst index e1a6ac7a..067de9e1 100644 --- a/doc/guides/sample_app_ug/qos_metering.rst +++ b/doc/guides/sample_app_ug/qos_metering.rst @@ -64,29 +64,9 @@ all the incoming packets are colored as green. Compiling the Application ------------------------- -#. Go to the example directory: +To compile the sample application see :doc:`compiling`. - .. code-block:: console - - export RTE_SDK=/path/to/rte_sdk - cd ${RTE_SDK}/examples/qos_meter - -#. Set the target - (a default target is used if not specified): - - .. note:: - - This application is intended as a linuxapp only. - - .. code-block:: console - - export RTE_TARGET=x86_64-native-linuxapp-gcc - -#. Build the application: - - .. code-block:: console - - make +The application is located in the ``qos_meter`` sub-directory. Running the Application ----------------------- diff --git a/doc/guides/sample_app_ug/qos_scheduler.rst b/doc/guides/sample_app_ug/qos_scheduler.rst index a6654cb5..1c38d191 100644 --- a/doc/guides/sample_app_ug/qos_scheduler.rst +++ b/doc/guides/sample_app_ug/qos_scheduler.rst @@ -58,31 +58,14 @@ The TX thread, if present, reads from the TX ring and write the packets to the T Compiling the Application ------------------------- -To compile the application: +To compile the sample application see :doc:`compiling`. -#. Go to the sample application directory: - - .. code-block:: console - - export RTE_SDK=/path/to/rte_sdk - cd ${RTE_SDK}/examples/qos_sched - -#. Set the target (a default target is used if not specified). For example: +The application is located in the ``qos_sched`` sub-directory. .. note:: This application is intended as a linuxapp only. - .. code-block:: console - - export RTE_TARGET=x86_64-native-linuxapp-gcc - -#. Build the application: - - .. code-block:: console - - make - .. note:: To get statistics on the sample app using the command line interface as described in the next section, diff --git a/doc/guides/sample_app_ug/quota_watermark.rst b/doc/guides/sample_app_ug/quota_watermark.rst index 2c3a4320..32bd78d7 100644 --- a/doc/guides/sample_app_ug/quota_watermark.rst +++ b/doc/guides/sample_app_ug/quota_watermark.rst @@ -88,30 +88,12 @@ as shown in :numref:`figure_ring_pipeline_perf_setup`. Ring-based Processing Pipeline Performance Setup - Compiling the Application ------------------------- -#. Go to the example directory: - - .. code-block:: console - - export RTE_SDK=/path/to/rte_sdk - cd ${RTE_SDK}/examples/quota_watermark - -#. Set the target (a default target is used if not specified). For example: - - .. code-block:: console - - export RTE_TARGET=x86_64-native-linuxapp-gcc - - See the *DPDK Getting Started Guide* for possible RTE_TARGET values. - -#. Build the application: - - .. code-block:: console +To compile the sample application see :doc:`compiling`. - make +The application is located in the ``quota_watermark`` sub-directory. Running the Application ----------------------- diff --git a/doc/guides/sample_app_ug/rxtx_callbacks.rst b/doc/guides/sample_app_ug/rxtx_callbacks.rst index 8d1bb86f..928c9635 100644 --- a/doc/guides/sample_app_ug/rxtx_callbacks.rst +++ b/doc/guides/sample_app_ug/rxtx_callbacks.rst @@ -45,23 +45,9 @@ prior to transmission to calculate the elapsed time, in CPU cycles. Compiling the Application ------------------------- -To compile the application export the path to the DPDK source tree and go to -the example directory: +To compile the sample application see :doc:`compiling`. -.. code-block:: console - - export RTE_SDK=/path/to/rte_sdk - - cd ${RTE_SDK}/examples/rxtx_callbacks - - -Set the target, for example: - -.. code-block:: console - - export RTE_TARGET=x86_64-native-linuxapp-gcc - -See the *DPDK Getting Started* Guide for possible ``RTE_TARGET`` values. +The application is located in the ``rxtx_callbacks`` sub-directory. The callbacks feature requires that the ``CONFIG_RTE_ETHDEV_RXTX_CALLBACKS`` setting is on in the ``config/common_`` config file that applies to the @@ -71,13 +57,6 @@ target. This is generally on by default: CONFIG_RTE_ETHDEV_RXTX_CALLBACKS=y -Build the application as follows: - -.. code-block:: console - - make - - Running the Application ----------------------- @@ -124,7 +103,7 @@ comments: .. code-block:: c static inline int - port_init(uint8_t port, struct rte_mempool *mbuf_pool) + port_init(uint16_t port, struct rte_mempool *mbuf_pool) { struct rte_eth_conf port_conf = port_conf_default; const uint16_t rx_rings = 1, tx_rings = 1; @@ -196,7 +175,7 @@ all packets received: .. code-block:: c static uint16_t - add_timestamps(uint8_t port __rte_unused, uint16_t qidx __rte_unused, + add_timestamps(uint16_t port __rte_unused, uint16_t qidx __rte_unused, struct rte_mbuf **pkts, uint16_t nb_pkts, void *_ __rte_unused) { unsigned i; @@ -222,7 +201,7 @@ packets prior to transmission: .. code-block:: c static uint16_t - calc_latency(uint8_t port __rte_unused, uint16_t qidx __rte_unused, + calc_latency(uint16_t port __rte_unused, uint16_t qidx __rte_unused, struct rte_mbuf **pkts, uint16_t nb_pkts, void *_ __rte_unused) { uint64_t cycles = 0; diff --git a/doc/guides/sample_app_ug/server_node_efd.rst b/doc/guides/sample_app_ug/server_node_efd.rst index c2a5f20a..8891f3b3 100644 --- a/doc/guides/sample_app_ug/server_node_efd.rst +++ b/doc/guides/sample_app_ug/server_node_efd.rst @@ -108,26 +108,9 @@ that this is a new flow, which is dropped. Compiling the Application ------------------------- -The sequence of steps used to build the application is: - -#. Export the required environment variables: - - .. code-block:: console - - export RTE_SDK=/path/to/rte_sdk - export RTE_TARGET=x86_64-native-linuxapp-gcc - -#. Build the application executable file: - - .. code-block:: console - - cd ${RTE_SDK}/examples/server_node_efd/ - make - - For more details on how to build the DPDK libraries and sample - applications, - please refer to the *DPDK Getting Started Guide.* +To compile the sample application see :doc:`compiling`. +The application is located in the ``server_node_efd`` sub-directory. Running the Application ----------------------- diff --git a/doc/guides/sample_app_ug/service_cores.rst b/doc/guides/sample_app_ug/service_cores.rst new file mode 100644 index 00000000..36c1b3c5 --- /dev/null +++ b/doc/guides/sample_app_ug/service_cores.rst @@ -0,0 +1,172 @@ +.. BSD LICENSE + Copyright(c) 2017 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. + +Service Cores Sample Application +================================ + +The service cores sample application demonstrates the service cores capabilities +of DPDK. The service cores infrastructure is part of the DPDK EAL, and allows +any DPDK component to register a service. A service is a work item or task, that +requires CPU time to perform its duty. + +This sample application registers 5 dummy services. These 5 services are used +to show how the service_cores API can be used to orchestrate these services to +run on different service lcores. This orchestration is done by calling the +service cores APIs, however the sample application introduces a "profile" +concept to contain the service mapping details. Note that the profile concept +is application specific, and not a part of the service cores API. + + +Compiling the Application +------------------------- + +#. Go to the example directory: + + .. code-block:: console + + export RTE_SDK=/path/to/rte_sdk + cd ${RTE_SDK}/examples/service_cores + +#. Set the target (a default target is used if not specified). For example: + + .. code-block:: console + + export RTE_TARGET=x86_64-native-linuxapp-gcc + + See the *DPDK Getting Started* Guide for possible RTE_TARGET values. + +#. Build the application: + + .. code-block:: console + + make + +Running the Application +----------------------- + +To run the example, just execute the binary. Since the application dynamically +adds service cores in the application code itself, there is no requirement to +pass a service core-mask as an EAL argument at startup time. + +.. code-block:: console + + $ ./build/service_cores + + +Explanation +----------- + +The following sections provide some explanation of code focusing on +registering applications from an applications point of view, and modifying the +service core counts and mappings at runtime. + + +Registering a Service +~~~~~~~~~~~~~~~~~~~~~ + +The following code section shows how to register a service as an application. +Note that the service component header must be included by the application in +order to register services: ``rte_service_component.h``, in addition +to the ordinary service cores header ``rte_service.h`` which provides +the runtime functions to add, remove and remap service cores. + +.. code-block:: c + + struct rte_service_spec service = { + .name = "service_name", + }; + int ret = rte_service_component_register(services, &id); + if (ret) + return -1; + + /* set the service itself to be ready to run. In the case of + * ethdev, eventdev etc PMDs, this will be set when the + * appropriate configure or setup function is called. + */ + rte_service_component_runstate_set(id, 1); + + /* Collect statistics for the service */ + rte_service_set_stats_enable(id, 1); + + /* The application sets the service to running state. Note that this + * function enables the service to run - while the 'component' version + * of this function (as above) marks the service itself as ready */ + ret = rte_service_runstate_set(id, 1); + + +Controlling A Service Core +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This section demonstrates how to add a service core. The ``rte_service.h`` +header file provides the functions for dynamically adding and removing cores. +The APIs to add and remove cores use lcore IDs similar to existing DPDK +functions. + +These are the functions to start a service core, and have it run a service: + +.. code-block:: c + + /* the lcore ID to use as a service core */ + uint32_t service_core_id = 7; + ret = rte_service_lcore_add(service_core_id); + if(ret) + return -1; + + /* service cores are in "stopped" state when added, so start it */ + ret = rte_service_lcore_start(service_core_id); + if(ret) + return -1; + + /* map a service to the service core, causing it to run the service */ + uint32_t service_id; /* ID of a registered service */ + uint32_t enable = 1; /* 1 maps the service, 0 unmaps */ + ret = rte_service_map_lcore_set(service_id, service_core_id, enable); + if(ret) + return -1; + + +Removing A Service Core +~~~~~~~~~~~~~~~~~~~~~~~ + +To remove a service core, the steps are similar to adding but in reverse order. +Note that it is not allowed to remove a service core if the service is running, +and the service-core is the only core running that service (see documentation +for ``rte_service_lcore_stop`` function for details). + + +Conclusion +~~~~~~~~~~ + +The service cores infrastructure provides DPDK with two main features. The first +is to abstract away hardware differences: the service core can CPU cycles to +a software fallback implementation, allowing the application to be abstracted +from the difference in HW / SW availability. The second feature is a flexible +method of registering functions to be run, allowing the running of the +functions to be scaled across multiple CPUs. diff --git a/doc/guides/sample_app_ug/skeleton.rst b/doc/guides/sample_app_ug/skeleton.rst index c39b0332..9c78f494 100644 --- a/doc/guides/sample_app_ug/skeleton.rst +++ b/doc/guides/sample_app_ug/skeleton.rst @@ -39,33 +39,12 @@ It is intended as a demonstration of the basic components of a DPDK forwarding application. For more detailed implementations see the L2 and L3 forwarding sample applications. - Compiling the Application ------------------------- -To compile the application export the path to the DPDK source tree and go to -the example directory: - -.. code-block:: console - - export RTE_SDK=/path/to/rte_sdk - - cd ${RTE_SDK}/examples/skeleton - -Set the target, for example: - -.. code-block:: console - - export RTE_TARGET=x86_64-native-linuxapp-gcc - -See the *DPDK Getting Started* Guide for possible ``RTE_TARGET`` values. - -Build the application as follows: - -.. code-block:: console - - make +To compile the sample application see :doc:`compiling`. +The application is located in the ``skeleton`` sub-directory. Running the Application ----------------------- @@ -160,7 +139,7 @@ Forwarding application is shown below: .. code-block:: c static inline int - port_init(uint8_t port, struct rte_mempool *mbuf_pool) + port_init(uint16_t port, struct rte_mempool *mbuf_pool) { struct rte_eth_conf port_conf = port_conf_default; const uint16_t rx_rings = 1, tx_rings = 1; @@ -241,8 +220,8 @@ looks like the following: static __attribute__((noreturn)) void lcore_main(void) { - const uint8_t nb_ports = rte_eth_dev_count(); - uint8_t port; + const uint16_t nb_ports = rte_eth_dev_count(); + uint16_t port; /* * Check that the port is on the same NUMA node as the polling thread diff --git a/doc/guides/sample_app_ug/tep_termination.rst b/doc/guides/sample_app_ug/tep_termination.rst index 087823b1..04bf8a2c 100644 --- a/doc/guides/sample_app_ug/tep_termination.rst +++ b/doc/guides/sample_app_ug/tep_termination.rst @@ -121,39 +121,16 @@ The example in this section have been validated with the following distributions Compiling the Sample Code ------------------------- -#. Compile vhost lib: - To enable vhost, turn on vhost library in the configure file config/common_linuxapp. +To enable vhost, turn on vhost library in the configure file +``config/common_linuxapp``. .. code-block:: console CONFIG_RTE_LIBRTE_VHOST=y - -#. Go to the examples directory: - - .. code-block:: console - - export RTE_SDK=/path/to/rte_sdk - cd ${RTE_SDK}/examples/tep_termination - -#. Set the target (a default target is used if not specified). For example: - - .. code-block:: console - - export RTE_TARGET=x86_64-native-linuxapp-gcc - - See the DPDK Getting Started Guide for possible RTE_TARGET values. - -#. Build the application: - - .. code-block:: console - - cd ${RTE_SDK} - make config ${RTE_TARGET} - make install ${RTE_TARGET} - cd ${RTE_SDK}/examples/tep_termination - make +Then following the to compile the sample application shown in +:doc:`compiling`. Running the Sample Code ----------------------- diff --git a/doc/guides/sample_app_ug/test_pipeline.rst b/doc/guides/sample_app_ug/test_pipeline.rst index 95c7e0fc..f538cd05 100644 --- a/doc/guides/sample_app_ug/test_pipeline.rst +++ b/doc/guides/sample_app_ug/test_pipeline.rst @@ -55,28 +55,12 @@ The application uses three CPU cores: Test Pipeline Application - Compiling the Application ------------------------- +To compile the sample application see :doc:`compiling` -#. Go to the app/test directory: - - .. code-block:: console - - export RTE_SDK=/path/to/rte_sdk - cd ${RTE_SDK}/app/test/test-pipeline - -#. Set the target (a default target is used if not specified): - - .. code-block:: console - - export RTE_TARGET=x86_64-native-linuxapp-gcc - -#. Build the application: - - .. code-block:: console +The application is located in the ``$RTE_SDK/test/test-pipline`` directory. - make Running the Application ----------------------- diff --git a/doc/guides/sample_app_ug/timer.rst b/doc/guides/sample_app_ug/timer.rst index 00b69532..46a3a2fa 100644 --- a/doc/guides/sample_app_ug/timer.rst +++ b/doc/guides/sample_app_ug/timer.rst @@ -37,26 +37,9 @@ This application prints some messages from different lcores regularly, demonstra Compiling the Application ------------------------- -#. Go to the example directory: +To compile the sample application see :doc:`compiling`. - .. code-block:: console - - export RTE_SDK=/path/to/rte_sdk - cd ${RTE_SDK}/examples/timer - -#. Set the target (a default target is used if not specified). For example: - - .. code-block:: console - - export RTE_TARGET=x86_64-native-linuxapp-gcc - - See the *DPDK Getting Started Guide* for possible *RTE_TARGET* values. - -#. Build the application: - - .. code-block:: console - - make +The application is located in the ``timer`` sub-directory. Running the Application ----------------------- diff --git a/doc/guides/sample_app_ug/vhost.rst b/doc/guides/sample_app_ug/vhost.rst index a2a3909e..5735adbb 100644 --- a/doc/guides/sample_app_ug/vhost.rst +++ b/doc/guides/sample_app_ug/vhost.rst @@ -55,20 +55,12 @@ puts back to the same physical NIC port. Build ~~~~~ -Follow the *Getting Started Guide for Linux* on generic info about -environment setup and building DPDK from source. +To compile the sample application see :doc:`compiling`. -In this example, you need build DPDK both on the host and inside guest. -Also, you need build this example. - -.. code-block:: console - - export RTE_SDK=/path/to/dpdk_source - export RTE_TARGET=x86_64-native-linuxapp-gcc - - cd ${RTE_SDK}/examples/vhost - make +The application is located in the ``vhost`` sub-directory. +.. note:: + In this example, you need build DPDK both on the host and inside guest. Start the vswitch example ~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/guides/sample_app_ug/vhost_scsi.rst b/doc/guides/sample_app_ug/vhost_scsi.rst index 8be069e0..1b4dab32 100644 --- a/doc/guides/sample_app_ug/vhost_scsi.rst +++ b/doc/guides/sample_app_ug/vhost_scsi.rst @@ -51,23 +51,14 @@ Testing steps This section shows the steps how to start a VM with the block device as fast data path for critical application. -Build -~~~~~ +Compiling the Application +------------------------- -Follow the *Getting Started Guide for Linux* on generic info about -environment setup and building DPDK from source. +To compile the sample application see :doc:`compiling`. -In this example, you need build DPDK both on the host and inside guest. -Also, you need build this example. - -.. code-block:: console - - export RTE_SDK=/path/to/dpdk_source - export RTE_TARGET=x86_64-native-linuxapp-gcc - - cd ${RTE_SDK}/examples/vhost_scsi - make +The application is located in the ``examples`` sub-directory. +You will also need to build DPDK both on the host and inside the guest Start the vhost_scsi example ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/guides/sample_app_ug/vm_power_management.rst b/doc/guides/sample_app_ug/vm_power_management.rst index 05c26b03..fe53706e 100644 --- a/doc/guides/sample_app_ug/vm_power_management.rst +++ b/doc/guides/sample_app_ug/vm_power_management.rst @@ -201,9 +201,12 @@ Compiling and Running the Host Application Compiling ~~~~~~~~~ -#. export RTE_SDK=/path/to/rte_sdk -#. cd ${RTE_SDK}/examples/vm_power_manager -#. make +Compiling the Application +------------------------- + +To compile the sample application see :doc:`compiling`. + +The application is located in the ``vm_power_manager`` sub-directory. Running ~~~~~~~ diff --git a/doc/guides/sample_app_ug/vmdq_dcb_forwarding.rst b/doc/guides/sample_app_ug/vmdq_dcb_forwarding.rst index 70e1d19e..4a6c70d2 100644 --- a/doc/guides/sample_app_ug/vmdq_dcb_forwarding.rst +++ b/doc/guides/sample_app_ug/vmdq_dcb_forwarding.rst @@ -86,26 +86,11 @@ No command-line options are taken by this application apart from the standard EA Compiling the Application ------------------------- -#. Go to the examples directory: - .. code-block:: console - export RTE_SDK=/path/to/rte_sdk - cd ${RTE_SDK}/examples/vmdq_dcb +To compile the sample application see :doc:`compiling`. -#. Set the target (a default target is used if not specified). For example: - - .. code-block:: console - - export RTE_TARGET=x86_64-native-linuxapp-gcc - - See the *DPDK Getting Started Guide* for possible RTE_TARGET values. - -#. Build the application: - - .. code-block:: console - - make +The application is located in the ``vmdq_dcb`` sub-directory. Running the Application ----------------------- |