doc: use code snippets in sample app guides
[dpdk.git] / doc / guides / sample_app_ug / server_node_efd.rst
index f27d1cc..605eb09 100644 (file)
@@ -137,120 +137,29 @@ which is used to distribute packets to nodes, which the number of flows
 specified in the command line (1 million, by default).
 
 
-.. code-block:: c
-
-    static void
-    create_efd_table(void)
-    {
-        uint8_t socket_id = rte_socket_id();
-
-        /* create table */
-        efd_table = rte_efd_create("flow table", num_flows * 2, sizeof(uint32_t),
-                        1 << socket_id, socket_id);
-
-        if (efd_table == NULL)
-            rte_exit(EXIT_FAILURE, "Problem creating the flow table\n");
-    }
-
-    static void
-    populate_efd_table(void)
-    {
-        unsigned int i;
-        int32_t ret;
-        uint32_t ip_dst;
-        uint8_t socket_id = rte_socket_id();
-        uint64_t node_id;
-
-        /* Add flows in table */
-        for (i = 0; i < num_flows; i++) {
-            node_id = i % num_nodes;
-
-            ip_dst = rte_cpu_to_be_32(i);
-            ret = rte_efd_update(efd_table, socket_id,
-                            (void *)&ip_dst, (efd_value_t)node_id);
-            if (ret < 0)
-                rte_exit(EXIT_FAILURE, "Unable to add entry %u in "
-                                    "EFD table\n", i);
-        }
-
-        printf("EFD table: Adding 0x%x keys\n", num_flows);
-    }
+.. literalinclude:: ../../../examples/server_node_efd/server/init.c
+    :language: c
+    :start-after: Create EFD table. 8<
+    :end-before: >8 End of creation EFD table.
 
 After initialization, packets are received from the enabled ports, and the IPv4
 address from the packets is used as a key to look up in the EFD table,
 which tells the node where the packet has to be distributed.
 
-.. code-block:: c
-
-    static void
-    process_packets(uint32_t port_num __rte_unused, struct rte_mbuf *pkts[],
-            uint16_t rx_count, unsigned int socket_id)
-    {
-        uint16_t i;
-        uint8_t node;
-        efd_value_t data[EFD_BURST_MAX];
-        const void *key_ptrs[EFD_BURST_MAX];
-
-        struct rte_ipv4_hdr *ipv4_hdr;
-        uint32_t ipv4_dst_ip[EFD_BURST_MAX];
-
-        for (i = 0; i < rx_count; i++) {
-            /* Handle IPv4 header.*/
-            ipv4_hdr = rte_pktmbuf_mtod_offset(pkts[i], struct rte_ipv4_hdr *,
-                    sizeof(struct rte_ether_hdr));
-            ipv4_dst_ip[i] = ipv4_hdr->dst_addr;
-            key_ptrs[i] = (void *)&ipv4_dst_ip[i];
-        }
-
-        rte_efd_lookup_bulk(efd_table, socket_id, rx_count,
-                    (const void **) key_ptrs, data);
-        for (i = 0; i < rx_count; i++) {
-            node = (uint8_t) ((uintptr_t)data[i]);
-
-            if (node >= num_nodes) {
-                /*
-                 * Node is out of range, which means that
-                 * flow has not been inserted
-                 */
-                flow_dist_stats.drop++;
-                rte_pktmbuf_free(pkts[i]);
-            } else {
-                flow_dist_stats.distributed++;
-                enqueue_rx_packet(node, pkts[i]);
-            }
-        }
-
-        for (i = 0; i < num_nodes; i++)
-            flush_rx_queue(i);
-    }
+.. literalinclude:: ../../../examples/server_node_efd/server/main.c
+    :language: c
+    :start-after: Processing packets. 8<
+    :end-before: >8 End of process_packets.
 
 The burst of packets received is enqueued in temporary buffers (per node),
 and enqueued in the shared ring between the server and the node.
 After this, a new burst of packets is received and this process is
 repeated infinitely.
 
-.. code-block:: c
-
-    static void
-    flush_rx_queue(uint16_t node)
-    {
-        uint16_t j;
-        struct node *cl;
-
-        if (cl_rx_buf[node].count == 0)
-            return;
-
-        cl = &nodes[node];
-        if (rte_ring_enqueue_bulk(cl->rx_q, (void **)cl_rx_buf[node].buffer,
-                cl_rx_buf[node].count, NULL) != cl_rx_buf[node].count){
-            for (j = 0; j < cl_rx_buf[node].count; j++)
-                rte_pktmbuf_free(cl_rx_buf[node].buffer[j]);
-            cl->stats.rx_drop += cl_rx_buf[node].count;
-        } else
-            cl->stats.rx += cl_rx_buf[node].count;
-
-        cl_rx_buf[node].count = 0;
-    }
+.. literalinclude:: ../../../examples/server_node_efd/server/main.c
+    :language: c
+    :start-after: Flush rx queue. 8<
+    :end-before: >8 End of sending a burst of traffic to a node.
 
 The second process, the back-end node, receives the packets from the shared
 ring with the server and send them out, if they belong to the node.
@@ -258,83 +167,19 @@ ring with the server and send them out, if they belong to the node.
 At initialization, it attaches to the server process memory, to have
 access to the shared ring, parameters and statistics.
 
-.. code-block:: c
-
-    rx_ring = rte_ring_lookup(get_rx_queue_name(node_id));
-    if (rx_ring == NULL)
-        rte_exit(EXIT_FAILURE, "Cannot get RX ring - "
-                "is server process running?\n");
-
-    mp = rte_mempool_lookup(PKTMBUF_POOL_NAME);
-    if (mp == NULL)
-        rte_exit(EXIT_FAILURE, "Cannot get mempool for mbufs\n");
-
-    mz = rte_memzone_lookup(MZ_SHARED_INFO);
-    if (mz == NULL)
-        rte_exit(EXIT_FAILURE, "Cannot get port info structure\n");
-    info = mz->addr;
-    tx_stats = &(info->tx_stats[node_id]);
-    filter_stats = &(info->filter_stats[node_id]);
+.. literalinclude:: ../../../examples/server_node_efd/node/node.c
+    :language: c
+    :start-after: Attaching to the server process memory. 8<
+    :end-before: >8 End of attaching to the server process memory.
+    :dedent: 1
 
 Then, the hash table that contains the flows that will be handled
 by the node is created and populated.
 
-.. code-block:: c
-
-    static struct rte_hash *
-    create_hash_table(const struct shared_info *info)
-    {
-        uint32_t num_flows_node = info->num_flows / info->num_nodes;
-        char name[RTE_HASH_NAMESIZE];
-        struct rte_hash *h;
-
-        /* create table */
-        struct rte_hash_parameters hash_params = {
-            .entries = num_flows_node * 2, /* table load = 50% */
-            .key_len = sizeof(uint32_t), /* Store IPv4 dest IP address */
-            .socket_id = rte_socket_id(),
-            .hash_func_init_val = 0,
-        };
-
-        snprintf(name, sizeof(name), "hash_table_%d", node_id);
-        hash_params.name = name;
-        h = rte_hash_create(&hash_params);
-
-        if (h == NULL)
-            rte_exit(EXIT_FAILURE,
-                    "Problem creating the hash table for node %d\n",
-                    node_id);
-        return h;
-    }
-
-    static void
-    populate_hash_table(const struct rte_hash *h, const struct shared_info *info)
-    {
-        unsigned int i;
-        int32_t ret;
-        uint32_t ip_dst;
-        uint32_t num_flows_node = 0;
-        uint64_t target_node;
-
-        /* Add flows in table */
-        for (i = 0; i < info->num_flows; i++) {
-            target_node = i % info->num_nodes;
-            if (target_node != node_id)
-                continue;
-
-            ip_dst = rte_cpu_to_be_32(i);
-
-            ret = rte_hash_add_key(h, (void *) &ip_dst);
-            if (ret < 0)
-                rte_exit(EXIT_FAILURE, "Unable to add entry %u "
-                        "in hash table\n", i);
-            else
-                num_flows_node++;
-
-        }
-
-        printf("Hash table: Adding 0x%x keys\n", num_flows_node);
-    }
+.. literalinclude:: ../../../examples/server_node_efd/node/node.c
+    :language: c
+    :start-after: Creation of hash table. 8<
+    :end-before: >8 End of creation of hash table.
 
 After initialization, packets are dequeued from the shared ring
 (from the server) and, like in the server process,
@@ -343,108 +188,15 @@ If there is a hit, packet is stored in a buffer, to be eventually transmitted
 in one of the enabled ports. If key is not there, packet is dropped, since the
 flow is not handled by the node.
 
-.. code-block:: c
-
-    static inline void
-    handle_packets(struct rte_hash *h, struct rte_mbuf **bufs, uint16_t num_packets)
-    {
-        struct rte_ipv4_hdr *ipv4_hdr;
-        uint32_t ipv4_dst_ip[PKT_READ_SIZE];
-        const void *key_ptrs[PKT_READ_SIZE];
-        unsigned int i;
-        int32_t positions[PKT_READ_SIZE] = {0};
-
-        for (i = 0; i < num_packets; i++) {
-            /* Handle IPv4 header.*/
-            ipv4_hdr = rte_pktmbuf_mtod_offset(bufs[i], struct rte_ipv4_hdr *,
-                    sizeof(struct rte_ether_hdr));
-            ipv4_dst_ip[i] = ipv4_hdr->dst_addr;
-            key_ptrs[i] = &ipv4_dst_ip[i];
-        }
-        /* Check if packets belongs to any flows handled by this node */
-        rte_hash_lookup_bulk(h, key_ptrs, num_packets, positions);
-
-        for (i = 0; i < num_packets; i++) {
-            if (likely(positions[i] >= 0)) {
-                filter_stats->passed++;
-                transmit_packet(bufs[i]);
-            } else {
-                filter_stats->drop++;
-                /* Drop packet, as flow is not handled by this node */
-                rte_pktmbuf_free(bufs[i]);
-            }
-        }
-    }
+.. literalinclude:: ../../../examples/server_node_efd/node/node.c
+    :language: c
+    :start-after: Packets dequeued from the shared ring. 8<
+    :end-before: >8 End of packets dequeueing.
 
 Finally, note that both processes updates statistics, such as transmitted, received
 and dropped packets, which are shown and refreshed by the server app.
 
-.. code-block:: c
-
-    static void
-    do_stats_display(void)
-    {
-        unsigned int i, j;
-        const char clr[] = {27, '[', '2', 'J', '\0'};
-        const char topLeft[] = {27, '[', '1', ';', '1', 'H', '\0'};
-        uint64_t port_tx[RTE_MAX_ETHPORTS], port_tx_drop[RTE_MAX_ETHPORTS];
-        uint64_t node_tx[MAX_NODES], node_tx_drop[MAX_NODES];
-
-        /* to get TX stats, we need to do some summing calculations */
-        memset(port_tx, 0, sizeof(port_tx));
-        memset(port_tx_drop, 0, sizeof(port_tx_drop));
-        memset(node_tx, 0, sizeof(node_tx));
-        memset(node_tx_drop, 0, sizeof(node_tx_drop));
-
-        for (i = 0; i < num_nodes; i++) {
-            const struct tx_stats *tx = &info->tx_stats[i];
-
-            for (j = 0; j < info->num_ports; j++) {
-                const uint64_t tx_val = tx->tx[info->id[j]];
-                const uint64_t drop_val = tx->tx_drop[info->id[j]];
-
-                port_tx[j] += tx_val;
-                port_tx_drop[j] += drop_val;
-                node_tx[i] += tx_val;
-                node_tx_drop[i] += drop_val;
-            }
-        }
-
-        /* Clear screen and move to top left */
-        printf("%s%s", clr, topLeft);
-
-        printf("PORTS\n");
-        printf("-----\n");
-        for (i = 0; i < info->num_ports; i++)
-            printf("Port %u: '%s'\t", (unsigned int)info->id[i],
-                    get_printable_mac_addr(info->id[i]));
-        printf("\n\n");
-        for (i = 0; i < info->num_ports; i++) {
-            printf("Port %u - rx: %9"PRIu64"\t"
-                    "tx: %9"PRIu64"\n",
-                    (unsigned int)info->id[i], info->rx_stats.rx[i],
-                    port_tx[i]);
-        }
-
-        printf("\nSERVER\n");
-        printf("-----\n");
-        printf("distributed: %9"PRIu64", drop: %9"PRIu64"\n",
-                flow_dist_stats.distributed, flow_dist_stats.drop);
-
-        printf("\nNODES\n");
-        printf("-------\n");
-        for (i = 0; i < num_nodes; i++) {
-            const unsigned long long rx = nodes[i].stats.rx;
-            const unsigned long long rx_drop = nodes[i].stats.rx_drop;
-            const struct filter_stats *filter = &info->filter_stats[i];
-
-            printf("Node %2u - rx: %9llu, rx_drop: %9llu\n"
-                    "            tx: %9"PRIu64", tx_drop: %9"PRIu64"\n"
-                    "            filter_passed: %9"PRIu64", "
-                    "filter_drop: %9"PRIu64"\n",
-                    i, rx, rx_drop, node_tx[i], node_tx_drop[i],
-                    filter->passed, filter->drop);
-        }
-
-        printf("\n");
-    }
+.. literalinclude:: ../../../examples/server_node_efd/server/main.c
+    :language: c
+    :start-after: Display recorded statistics. 8<
+    :end-before: >8 End of displaying the recorded statistics.