X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=examples%2Fflow_filtering%2Fmain.c;h=bfc1949c8428cf848dd3f8887866cc8ce64a7ce2;hb=e7a7add13a0cd2eb64f62502cad005a97d8e3ee2;hp=cc955cd909ad58a254e4e61c9fd4df455dd7891f;hpb=6014215a8c5865e1b22749f83d91da55da0ce020;p=dpdk.git diff --git a/examples/flow_filtering/main.c b/examples/flow_filtering/main.c index cc955cd909..bfc1949c84 100644 --- a/examples/flow_filtering/main.c +++ b/examples/flow_filtering/main.c @@ -1,33 +1,5 @@ -/*- - * BSD LICENSE - * - * Copyright 2017 Mellanox. - * - * 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. 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 */ #include @@ -37,7 +9,6 @@ #include #include #include -#include #include #include #include @@ -55,6 +26,7 @@ #include #include #include +#include static volatile bool force_quit; @@ -72,23 +44,26 @@ struct rte_flow *flow; #include "flow_blocks.c" static inline void -print_ether_addr(const char *what, struct ether_addr *eth_addr) +print_ether_addr(const char *what, struct rte_ether_addr *eth_addr) { - char buf[ETHER_ADDR_FMT_SIZE]; - ether_format_addr(buf, ETHER_ADDR_FMT_SIZE, eth_addr); + char buf[RTE_ETHER_ADDR_FMT_SIZE]; + rte_ether_format_addr(buf, RTE_ETHER_ADDR_FMT_SIZE, eth_addr); printf("%s%s", what, buf); } -static void +/* Main_loop for flow filtering. 8< */ +static int main_loop(void) { struct rte_mbuf *mbufs[32]; - struct ether_hdr *eth_hdr; + struct rte_ether_hdr *eth_hdr; struct rte_flow_error error; uint16_t nb_rx; uint16_t i; uint16_t j; + int ret; + /* Reading the packets from all queues. 8< */ while (!force_quit) { for (i = 0; i < nr_queues; i++) { nb_rx = rte_eth_rx_burst(port_id, @@ -98,11 +73,11 @@ main_loop(void) 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); + ð_hdr->src_addr); print_ether_addr(" - dst=", - ð_hdr->d_addr); + ð_hdr->dst_addr); printf(" - queue=0x%x", (unsigned int)i); printf("\n"); @@ -112,49 +87,76 @@ main_loop(void) } } } + /* >8 End of reading the packets from all queues. */ /* closing and releasing resources */ rte_flow_flush(port_id, &error); - rte_eth_dev_stop(port_id); + ret = rte_eth_dev_stop(port_id); + if (ret < 0) + printf("Failed to stop port %u: %s", + port_id, rte_strerror(-ret)); rte_eth_dev_close(port_id); + return ret; } +/* >8 End of main_loop for flow filtering. */ + +#define CHECK_INTERVAL 1000 /* 100ms */ +#define MAX_REPEAT_TIMES 90 /* 9s (90 * 100ms) in total */ static void assert_link_status(void) { struct rte_eth_link link; + uint8_t rep_cnt = MAX_REPEAT_TIMES; + int link_get_err = -EINVAL; memset(&link, 0, sizeof(link)); - rte_eth_link_get(port_id, &link); - if (link.link_status == ETH_LINK_DOWN) + do { + link_get_err = rte_eth_link_get(port_id, &link); + if (link_get_err == 0 && link.link_status == RTE_ETH_LINK_UP) + break; + rte_delay_ms(CHECK_INTERVAL); + } while (--rep_cnt); + + if (link_get_err < 0) + rte_exit(EXIT_FAILURE, ":: error: link get is failing: %s\n", + rte_strerror(-link_get_err)); + if (link.link_status == RTE_ETH_LINK_DOWN) rte_exit(EXIT_FAILURE, ":: error: link is still down\n"); } +/* Port initialization used in flow filtering. 8< */ static void init_port(void) { int ret; uint16_t i; + /* Ethernet port configured with default settings. 8< */ struct rte_eth_conf port_conf = { .rxmode = { .split_hdr_size = 0, - .ignore_offload_bitfield = 1, - .offloads = DEV_RX_OFFLOAD_CRC_STRIP, }, .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, + RTE_ETH_TX_OFFLOAD_VLAN_INSERT | + RTE_ETH_TX_OFFLOAD_IPV4_CKSUM | + RTE_ETH_TX_OFFLOAD_UDP_CKSUM | + RTE_ETH_TX_OFFLOAD_TCP_CKSUM | + RTE_ETH_TX_OFFLOAD_SCTP_CKSUM | + RTE_ETH_TX_OFFLOAD_TCP_TSO, }, }; struct rte_eth_txconf txq_conf; struct rte_eth_rxconf rxq_conf; struct rte_eth_dev_info dev_info; + ret = rte_eth_dev_info_get(port_id, &dev_info); + if (ret != 0) + rte_exit(EXIT_FAILURE, + "Error during getting device (port %u) info: %s\n", + port_id, strerror(-ret)); + + port_conf.txmode.offloads &= dev_info.tx_offload_capa; printf(":: initializing port: %d\n", port_id); ret = rte_eth_dev_configure(port_id, nr_queues, nr_queues, &port_conf); @@ -164,10 +166,11 @@ init_port(void) 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 */ + /* >8 End of ethernet port configured with default settings. */ + + /* Configuring number of RX and TX queues connected to single port. 8< */ for (i = 0; i < nr_queues; i++) { ret = rte_eth_rx_queue_setup(port_id, i, 512, rte_eth_dev_socket_id(port_id), @@ -193,19 +196,30 @@ init_port(void) ret, port_id); } } + /* >8 End of Configuring RX and TX queues connected to single port. */ - rte_eth_promiscuous_enable(port_id); + /* Setting the RX port to promiscuous mode. 8< */ + ret = rte_eth_promiscuous_enable(port_id); + if (ret != 0) + rte_exit(EXIT_FAILURE, + ":: promiscuous mode enable failed: err=%s, port=%u\n", + rte_strerror(-ret), port_id); + /* >8 End of setting the RX port to promiscuous mode. */ + + /* Starting the port. 8< */ 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); } + /* >8 End of starting the port. */ assert_link_status(); printf(":: initializing port: %d done\n", port_id); } +/* >8 End of Port initialization used in flow filtering. */ static void signal_handler(int signum) @@ -221,18 +235,20 @@ int main(int argc, char **argv) { int ret; - uint8_t nr_ports; + uint16_t nr_ports; struct rte_flow_error error; + /* Initialize EAL. 8< */ ret = rte_eal_init(argc, argv); if (ret < 0) rte_exit(EXIT_FAILURE, ":: invalid EAL arguments\n"); + /* >8 End of Initialization of EAL. */ force_quit = false; signal(SIGINT, signal_handler); signal(SIGTERM, signal_handler); - nr_ports = rte_eth_dev_count(); + nr_ports = rte_eth_dev_count_avail(); if (nr_ports == 0) rte_exit(EXIT_FAILURE, ":: no Ethernet ports found\n"); port_id = 0; @@ -240,26 +256,37 @@ main(int argc, char **argv) printf(":: warn: %d ports detected, but we use only one: port %u\n", nr_ports, port_id); } + /* Allocates a mempool to hold the mbufs. 8< */ mbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", 4096, 128, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); + /* >8 End of allocating a mempool to hold the mbufs. */ if (mbuf_pool == NULL) rte_exit(EXIT_FAILURE, "Cannot init mbuf pool\n"); + /* Initializes all the ports using the user defined init_port(). 8< */ init_port(); + /* >8 End of Initializing the ports using user defined init_port(). */ - /* create flow for send packet with */ + /* Create flow for send packet with. 8< */ flow = generate_ipv4_flow(port_id, selected_queue, SRC_IP, EMPTY_MASK, DEST_IP, FULL_MASK, &error); + /* >8 End of create flow and the flow rule. */ 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"); } + /* >8 End of creating flow for send packet with. */ + + /* Launching main_loop(). 8< */ + ret = main_loop(); + /* >8 End of launching main_loop(). */ - main_loop(); + /* clean up the EAL */ + rte_eal_cleanup(); - return 0; + return ret; }