X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=doc%2Fguides%2Fsample_app_ug%2Fflow_filtering.rst;h=02fc675506ffb39950bfd7acefcc9436982fa23e;hb=6d13ea8e8e49ab957deae2bba5ecf4a4bfe747d1;hp=725dcb44517b3095bc83f453a6830d5e22f3d2b3;hpb=4a3ef59a10c89adf1040eb308939317fcbc06962;p=dpdk.git diff --git a/doc/guides/sample_app_ug/flow_filtering.rst b/doc/guides/sample_app_ug/flow_filtering.rst index 725dcb4451..02fc675506 100644 --- a/doc/guides/sample_app_ug/flow_filtering.rst +++ b/doc/guides/sample_app_ug/flow_filtering.rst @@ -1,33 +1,5 @@ -.. 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. - +.. SPDX-License-Identifier: BSD-3-Clause + Copyright 2017 Mellanox Technologies, Ltd Basic RTE Flow Filtering Sample Application =========================================== @@ -54,7 +26,7 @@ Set the target, for example: .. code-block:: console - export RTE_TARGET=x86_64-native-linuxapp-gcc + export RTE_TARGET=x86_64-native-linux-gcc See the *DPDK Getting Started* Guide for possible ``RTE_TARGET`` values. @@ -68,7 +40,7 @@ Build the application as follows: Running the Application ----------------------- -To run the example in a ``linuxapp`` environment: +To run the example in a ``linux`` environment: .. code-block:: console @@ -81,7 +53,7 @@ applications and the Environment Abstraction Layer (EAL) options. Explanation ----------- -The example is build from 2 main files, +The example is built from 2 files, ``main.c`` which holds the example logic and ``flow_blocks.c`` that holds the implementation for building the flow rule. @@ -167,44 +139,61 @@ application is shown below: 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, + }, + .txmode = { + .offloads = + DEV_TX_OFFLOAD_VLAN_INSERT | + DEV_TX_OFFLOAD_IPV4_CKSUM | + DEV_TX_OFFLOAD_UDP_CKSUM | + DEV_TX_OFFLOAD_TCP_CKSUM | + DEV_TX_OFFLOAD_SCTP_CKSUM | + DEV_TX_OFFLOAD_TCP_TSO, }, }; + struct rte_eth_txconf txq_conf; + struct rte_eth_rxconf rxq_conf; + struct rte_eth_dev_info dev_info; printf(":: initializing port: %d\n", port_id); ret = rte_eth_dev_configure(port_id, - nr_queues, nr_queues, &port_conf); + nr_queues, nr_queues, &port_conf); if (ret < 0) { rte_exit(EXIT_FAILURE, ":: cannot configure device: err=%d, port=%u\n", ret, port_id); } + rte_eth_dev_info_get(port_id, &dev_info); + rxq_conf = dev_info.default_rxconf; + rxq_conf.offloads = port_conf.rxmode.offloads; /* 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); + rte_eth_dev_socket_id(port_id), + &rxq_conf, + mbuf_pool); if (ret < 0) { - rte_exit(EXIT_FAILURE, - ":: Rx queue setup failed: err=%d, port=%u\n", - ret, port_id); + rte_exit(EXIT_FAILURE, + ":: Rx queue setup failed: err=%d, port=%u\n", + ret, port_id); } } + txq_conf = dev_info.default_txconf; + txq_conf.offloads = port_conf.txmode.offloads; - rte_eth_promiscuous_enable(port_id); + for (i = 0; i < nr_queues; i++) { + ret = rte_eth_tx_queue_setup(port_id, i, 512, + rte_eth_dev_socket_id(port_id), + &txq_conf); + if (ret < 0) { + rte_exit(EXIT_FAILURE, + ":: Tx 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, @@ -223,20 +212,19 @@ The Ethernet port is configured with default settings using the .. 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, - }, - }; + .rxmode = { + .split_hdr_size = 0, + }, + .txmode = { + .offloads = + DEV_TX_OFFLOAD_VLAN_INSERT | + DEV_TX_OFFLOAD_IPV4_CKSUM | + DEV_TX_OFFLOAD_UDP_CKSUM | + DEV_TX_OFFLOAD_TCP_CKSUM | + DEV_TX_OFFLOAD_SCTP_CKSUM | + DEV_TX_OFFLOAD_TCP_TSO, + }, + }; ret = rte_eth_dev_configure(port_id, nr_queues, nr_queues, &port_conf); if (ret < 0) { @@ -244,23 +232,37 @@ The Ethernet port is configured with default settings using the ":: cannot configure device: err=%d, port=%u\n", ret, port_id); } + rte_eth_dev_info_get(port_id, &dev_info); + rxq_conf = dev_info.default_rxconf; + rxq_conf.offloads = port_conf.rxmode.offloads; -For this example we are configuring number of rx queues that are connected to -a single port. +For this example we are configuring number of rx and tx 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, + &rxq_conf, mbuf_pool); if (ret < 0) { rte_exit(EXIT_FAILURE, ":: Rx queue setup failed: err=%d, port=%u\n", ret, port_id); } - } + } + + for (i = 0; i < nr_queues; i++) { + ret = rte_eth_tx_queue_setup(port_id, i, 512, + rte_eth_dev_socket_id(port_id), + &txq_conf); + if (ret < 0) { + rte_exit(EXIT_FAILURE, + ":: Tx 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 @@ -302,7 +304,7 @@ looks like the following: main_loop(void) { struct rte_mbuf *mbufs[32]; - struct ether_hdr *eth_hdr; + struct rte_ether_hdr *eth_hdr; uint16_t nb_rx; uint16_t i; uint16_t j; @@ -316,7 +318,7 @@ looks like the following: struct rte_mbuf *m = mbufs[j]; eth_hdr = rte_pktmbuf_mtod(m, - struct ether_hdr *); + struct rte_ether_hdr *); print_ether_addr("src=", ð_hdr->s_addr); print_ether_addr(" - dst=", @@ -346,7 +348,7 @@ queues and printing for each packet the destination queue: 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 *); + eth_hdr = rte_pktmbuf_mtod(m, struct rte_ether_hdr *); print_ether_addr("src=", ð_hdr->s_addr); print_ether_addr(" - dst=", ð_hdr->d_addr); printf(" - queue=0x%x", (unsigned int)i); @@ -365,7 +367,7 @@ The forwarding loop can be interrupted and the application closed using The generate_ipv4_flow function ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The generate_ipv4_rule function is responsible for creating the flow rule. +The generate_ipv4_flow function is responsible for creating the flow rule. This function is located in the ``flow_blocks.c`` file. .. code-block:: c @@ -378,13 +380,9 @@ This function is located in the ``flow_blocks.c`` file. { struct rte_flow_attr attr; struct rte_flow_item pattern[MAX_PATTERN_NUM]; - struct rte_flow_action action[MAX_PATTERN_NUM]; + struct rte_flow_action action[MAX_ACTION_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; @@ -402,37 +400,19 @@ This function is located in the ``flow_blocks.c`` file. * 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). + * 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). + * setting the second level of the pattern (IP). * in this example this is the level we care about * so we set it according to the parameters. */ @@ -442,12 +422,12 @@ This function is located in the ``flow_blocks.c`` file. 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; + pattern[1].type = RTE_FLOW_ITEM_TYPE_IPV4; + pattern[1].spec = &ip_spec; + pattern[1].mask = &ip_mask; /* the final level must be always type end */ - pattern[3].type = RTE_FLOW_ITEM_TYPE_END; + pattern[2].type = RTE_FLOW_ITEM_TYPE_END; int res = rte_flow_validate(port_id, &attr, pattern, action, error); if(!res) @@ -462,14 +442,10 @@ The first part of the function is declaring the structures that will be used. struct rte_flow_attr attr; struct rte_flow_item pattern[MAX_PATTERN_NUM]; - struct rte_flow_action action[MAX_PATTERN_NUM]; + struct rte_flow_action action[MAX_ACTION_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; @@ -489,33 +465,17 @@ the rule. In this case send the packet to 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 fourth part is responsible for creating the pattern and is built from +number of steps. 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: +Setting the second level of the pattern IP: .. code-block:: c @@ -525,15 +485,15 @@ Setting the third level 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; + pattern[1].type = RTE_FLOW_ITEM_TYPE_IPV4; + pattern[1].spec = &ip_spec; + pattern[1].mask = &ip_mask; Closing the pattern part. .. code-block:: c - pattern[3].type = RTE_FLOW_ITEM_TYPE_END; + pattern[2].type = RTE_FLOW_ITEM_TYPE_END; The last part of the function is to validate the rule and create it.