xref: /dpdk/doc/guides/sample_app_ug/server_node_efd.rst (revision 7917b0d38e92e8b9ec5a870415b791420e10f11a)
1..  SPDX-License-Identifier: BSD-3-Clause
2    Copyright(c) 2016-2017 Intel Corporation.
3
4Server-Node EFD Sample Application
5==================================
6
7This sample application demonstrates the use of EFD library as a flow-level
8load balancer, for more information about the EFD Library please refer to the
9DPDK programmer's guide.
10
11This sample application is a variant of the
12:ref:`client-server sample application <multi_process_app>`
13where a specific target node is specified for every and each flow
14(not in a round-robin fashion as the original load balancing sample application).
15
16Overview
17--------
18
19The architecture of the EFD flow-based load balancer sample application is
20presented in the following figure.
21
22.. _figure_efd_sample_app_overview:
23
24.. figure:: img/server_node_efd.*
25
26   Using EFD as a Flow-Level Load Balancer
27
28As shown in :numref:`figure_efd_sample_app_overview`,
29the sample application consists of a front-end node (server)
30using the EFD library to create a load-balancing table for flows,
31for each flow a target backend worker node is specified. The EFD table does not
32store the flow key (unlike a regular hash table), and hence, it can
33individually load-balance millions of flows (number of targets * maximum number
34of flows fit in a flow table per target) while still fitting in CPU cache.
35
36It should be noted that although they are referred to as nodes, the frontend
37server and worker nodes are processes running on the same platform.
38
39Front-end Server
40~~~~~~~~~~~~~~~~
41
42Upon initializing, the frontend server node (process) creates a flow
43distributor table (based on the EFD library) which is populated with flow
44information and its intended target node.
45
46The sample application assigns a specific target node_id (process) for each of
47the IP destination addresses as follows:
48
49.. code-block:: c
50
51    node_id = i % num_nodes; /* Target node id is generated */
52    ip_dst = rte_cpu_to_be_32(i); /* Specific ip destination address is
53                                     assigned to this target node */
54
55then the pair of <key,target> is inserted into the flow distribution table.
56
57The main loop of the server process receives a burst of packets, then for
58each packet, a flow key (IP destination address) is extracted. The flow
59distributor table is looked up and the target node id is returned.  Packets are
60then enqueued to the specified target node id.
61
62It should be noted that flow distributor table is not a membership test table.
63I.e. if the key has already been inserted the target node id will be correct,
64but for new keys the flow distributor table will return a value (which can be
65valid).
66
67Backend Worker Nodes
68~~~~~~~~~~~~~~~~~~~~
69
70Upon initializing, the worker node (process) creates a flow table (a regular
71hash table that stores the key default size 1M flows) which is populated with
72only the flow information that is serviced at this node. This flow key is
73essential to point out new keys that have not been inserted before.
74
75The worker node's main loop is simply receiving packets then doing a hash table
76lookup. If a match occurs then statistics are updated for flows serviced by
77this node. If no match is found in the local hash table then this indicates
78that this is a new flow, which is dropped.
79
80
81Compiling the Application
82-------------------------
83
84To compile the sample application see :doc:`compiling`.
85
86The application is located in the ``server_node_efd`` sub-directory.
87
88Running the Application
89-----------------------
90
91The application has two binaries to be run: the front-end server
92and the back-end node.
93
94The frontend server (server) has the following command line options::
95
96    ./<build_dir>/examples/dpdk-server [EAL options] -- -p PORTMASK -n NUM_NODES -f NUM_FLOWS
97
98Where,
99
100* ``-p PORTMASK:`` Hexadecimal bitmask of ports to configure
101* ``-n NUM_NODES:`` Number of back-end nodes that will be used
102* ``-f NUM_FLOWS:`` Number of flows to be added in the EFD table (1 million, by default)
103
104The back-end node (node) has the following command line options::
105
106    ./node [EAL options] -- -n NODE_ID
107
108Where,
109
110* ``-n NODE_ID:`` Node ID, which cannot be equal or higher than NUM_MODES
111
112
113First, the server app must be launched, with the number of nodes that will be run.
114Once it has been started, the node instances can be run, with different NODE_ID.
115These instances have to be run as secondary processes, with ``--proc-type=secondary``
116in the EAL options, which will attach to the primary process memory, and therefore,
117they can access the queues created by the primary process to distribute packets.
118
119To successfully run the application, the command line used to start the
120application has to be in sync with the traffic flows configured on the traffic
121generator side.
122
123For examples of application command lines and traffic generator flows, please
124refer to the DPDK Test Report. For more details on how to set up and run the
125sample applications provided with DPDK package, please refer to the
126:ref:`DPDK Getting Started Guide for Linux <linux_gsg>` and
127:ref:`DPDK Getting Started Guide for FreeBSD <freebsd_gsg>`.
128
129
130Explanation
131-----------
132
133As described in previous sections, there are two processes in this example.
134
135The first process, the front-end server, creates and populates the EFD table,
136which is used to distribute packets to nodes, which the number of flows
137specified in the command line (1 million, by default).
138
139
140.. literalinclude:: ../../../examples/server_node_efd/efd_server/init.c
141    :language: c
142    :start-after: Create EFD table. 8<
143    :end-before: >8 End of creation EFD table.
144
145After initialization, packets are received from the enabled ports, and the IPv4
146address from the packets is used as a key to look up in the EFD table,
147which tells the node where the packet has to be distributed.
148
149.. literalinclude:: ../../../examples/server_node_efd/efd_server/main.c
150    :language: c
151    :start-after: Processing packets. 8<
152    :end-before: >8 End of process_packets.
153
154The burst of packets received is enqueued in temporary buffers (per node),
155and enqueued in the shared ring between the server and the node.
156After this, a new burst of packets is received and this process is
157repeated infinitely.
158
159.. literalinclude:: ../../../examples/server_node_efd/efd_server/main.c
160    :language: c
161    :start-after: Flush rx queue. 8<
162    :end-before: >8 End of sending a burst of traffic to a node.
163
164The second process, the back-end node, receives the packets from the shared
165ring with the server and send them out, if they belong to the node.
166
167At initialization, it attaches to the server process memory, to have
168access to the shared ring, parameters and statistics.
169
170.. literalinclude:: ../../../examples/server_node_efd/efd_node/node.c
171    :language: c
172    :start-after: Attaching to the server process memory. 8<
173    :end-before: >8 End of attaching to the server process memory.
174    :dedent: 1
175
176Then, the hash table that contains the flows that will be handled
177by the node is created and populated.
178
179.. literalinclude:: ../../../examples/server_node_efd/efd_node/node.c
180    :language: c
181    :start-after: Creation of hash table. 8<
182    :end-before: >8 End of creation of hash table.
183
184After initialization, packets are dequeued from the shared ring
185(from the server) and, like in the server process,
186the IPv4 address from the packets is used as a key to look up in the hash table.
187If there is a hit, packet is stored in a buffer, to be eventually transmitted
188in one of the enabled ports. If key is not there, packet is dropped, since the
189flow is not handled by the node.
190
191.. literalinclude:: ../../../examples/server_node_efd/efd_node/node.c
192    :language: c
193    :start-after: Packets dequeued from the shared ring. 8<
194    :end-before: >8 End of packets dequeuing.
195
196Finally, note that both processes updates statistics, such as transmitted, received
197and dropped packets, which are shown and refreshed by the server app.
198
199.. literalinclude:: ../../../examples/server_node_efd/efd_server/main.c
200    :language: c
201    :start-after: Display recorded statistics. 8<
202    :end-before: >8 End of displaying the recorded statistics.
203