<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mishal Shah</title>
    <description>The latest articles on DEV Community by Mishal Shah (@mishal23).</description>
    <link>https://dev.to/mishal23</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F285511%2F8a6da331-1492-49ae-a69c-71c6678a4efb.jpeg</url>
      <title>DEV Community: Mishal Shah</title>
      <link>https://dev.to/mishal23</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mishal23"/>
    <language>en</language>
    <item>
      <title>Running DPDK Forwarding Applications with Pktgen-DPDK</title>
      <dc:creator>Mishal Shah</dc:creator>
      <pubDate>Thu, 16 Jul 2020 19:09:05 +0000</pubDate>
      <link>https://dev.to/mishal23/running-dpdk-forwarding-applications-with-pktgen-dpdk-ena</link>
      <guid>https://dev.to/mishal23/running-dpdk-forwarding-applications-with-pktgen-dpdk-ena</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This article is co-authored by &lt;a href="https://www.linkedin.com/in/mehnaz-yunus/"&gt;Mehnaz Yunus&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As part of the evaluation stage of our bachelor thesis, we set up a testbed for running forwarding applications in DPDK and with Pktgen-DPDK as the traffic generator. In this blog, we aim to cover&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;how to run Pktgen-DPDK using Lua scripts in some complex scenarios&lt;/li&gt;
&lt;li&gt;how to run L2fwd, L3fwd (with exact match and longest prefix match), and L3fwd power DPDK applications.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We weren't able to find a lot of resources for setting up these tests and with this blog, we aim to bridge the gap.&lt;/p&gt;

&lt;h2&gt;
  
  
  DPDK and Pktgen-DPDK
&lt;/h2&gt;

&lt;p&gt;The Data Plane Development Kit is an Open source software project managed by the Linux Foundation. It provides a set of data plane libraries and network interface controller polling-mode drivers running in userspace. This way, the NIC is directly accessible by the DPDK application.  The advantage of using DPDK is that you're able to utilize the link speed completely whereas, in the standard packet processing, the link goes underutilized. Thus, high performance can be achieved with DPDK. &lt;/p&gt;

&lt;p&gt;Pktgen-DPDK is a software-based traffic generator powered by DPDK. Traffic generators are often used to simulate various situations and test the performance of the application. &lt;/p&gt;

&lt;h2&gt;
  
  
  Test Setup
&lt;/h2&gt;

&lt;p&gt;All the tests were done with two systems, one as the &lt;strong&gt;System Under Test&lt;/strong&gt; which is a bare metal server, and the other one as a &lt;strong&gt;generator&lt;/strong&gt; which is a VM. The SUT has two NUMA sockets where each socket has two 14-core Intel Xeon Gold 5120 2.20 GHz processors, which has four Intel I350 10 Gigabit NICs and four Ethernet Controller X710/X557-AT 10GBASE-T NICs. The generator has two 12-core Intel Xeon Gold 5120 2.20 GHz processors, 94GB memory, and one Intel 82540EM Gigabit NIC and Ethernet Controller X710/X557-AT 10GBASE-T NICs. Each system runs Ubuntu 20.04 LTS. &lt;/p&gt;

&lt;p&gt;Installation of both DPDK and Pktgen-DPDK was done by compiling from source. igb_uio kernel driver was used and 2048 huge pages were allotted. Our systems had 4 NICs so we could utilize them, if your system doesn't have that many NICs, you could use tapped interfaces. Here's a diagrammatic representation of the setup.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FMuOLY7L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ellbiifhcnap7y1y5i59.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FMuOLY7L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ellbiifhcnap7y1y5i59.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Lua Scripts with Pktgen-DPDK
&lt;/h2&gt;

&lt;p&gt;We used Lua scripts to automate the process of setting parameters and configuring flows in Pktgen-DPDK. Pktgen-DPDK can be run on the generator using the command shown below. It is run in promiscuous mode with the first four cores (0,1,2,3), and 4 memory channels. The Lua script for each application is mentioned using the -f option. The port mapping to cores is done as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;core 1 handles port 0, 1 RX/TX&lt;/li&gt;
&lt;li&gt;core 2 handles port 2, 3 RX/TX.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 Note: The core 0 is used for keyboard, timer, and screen output and hence shouldn't be used for port mapping. pktgen-dpdk with Lua script should be run from the pktgen directory only, otherwise, it gives an error.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo&lt;/span&gt; ./app/x86_64-native-linux-gcc/pktgen &lt;span class="nt"&gt;-c&lt;/span&gt; 0xf &lt;span class="nt"&gt;-n&lt;/span&gt; 4 &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;-P&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt; 1.[0-1] &lt;span class="nt"&gt;-m&lt;/span&gt; 2.[2-3] &lt;span class="nt"&gt;-f&lt;/span&gt; /path/to/script.lua
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Situation 1: Long-Running Flow for Certain Time
&lt;/h3&gt;

&lt;p&gt;We were required to run tests where the packets were sent for a fixed time period. Since pktgen by default doesn't support timers, we used os functions for the same.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lua"&gt;&lt;code&gt;&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"0"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;send_for_secs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;start_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;os.time&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="nb"&gt;os.difftime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;os.time&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;start_time&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;send_for_secs&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;where send_for_secs is the time for which we want to send.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 Note: sleep(send_for_secs) was not used because it would block Pktgen's output refreshing. So continuous check after a second and checking until the difference reaches the send_for_secs is done here.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Situation 2: Different Packet Size and Rate
&lt;/h3&gt;

&lt;p&gt;We also wanted to test with different packet sizes and rates (rate in pktgen-dpdk is to be given as a percentage of the line rate). Since changing the packet size or rate in the Lua script after every run is tedious, we ask for user input for the packet size and rate at runtime using the script below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lua"&gt;&lt;code&gt;&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;pktSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;tonumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Enter the size of packets to send: "&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;pktSize&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
    &lt;span class="n"&gt;pktSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"size"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pktSize&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;rate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;tonumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Enter the sending rate: "&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;rate&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
    &lt;span class="n"&gt;rate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"rate"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rate&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Forwarding Applications in DPDK
&lt;/h2&gt;

&lt;p&gt;We mention the steps to run the forwarding application and a corresponding Lua script to set relevant parameters. The command to run Pktgen-DPDK with the Lua script has been given in the previous section.&lt;/p&gt;

&lt;h3&gt;
  
  
  l2fwd
&lt;/h3&gt;

&lt;p&gt;Layer 2 forwarding (switching) does not need IP addresses to work. Thus, we set only the MAC address in the packets sent from pktgen-DPDK. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Start the l2fwd application on the SUT:&lt;/strong&gt; The l2fwd example can be run with the following command on the SUT. This command starts l2fwd on four cores and with four ports. The SUT has two NUMA sockets but we use only one. The even-numbered cores are on socket 0 and we use the first four cores on it, i.e, cores 0,2,4,6. Thus the core mask is given as 0x55. The port mask is 0xf as we use four ports.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo&lt;/span&gt; ./&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;RTE_SDK&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/examples/l2fwd/&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;RTE_TARGET&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/app/l2fwd &lt;span class="nt"&gt;-c&lt;/span&gt; 0x55 &lt;span class="nt"&gt;-n&lt;/span&gt; 4 &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 0xf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--P5-D9RuR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9ee8kk2ocsaz1ottnu5h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P5-D9RuR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9ee8kk2ocsaz1ottnu5h.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Start pktgen-dpdk on the generator with Lua script:&lt;/strong&gt; Get the MAC address of the ports by starting the l2fwd application on the SUT. Set them as the destination MAC address for the ports 0 and 2 in pktgen through the Lua script shown below.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lua"&gt;&lt;code&gt;&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;port0&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"0"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;port2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;port0_mac&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"3C:FD:FE:7C:BC:E0"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;port2_mac&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"3C:FD:FE:7C:BC:E2"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_mac&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"dst"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port0_mac&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_mac&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"dst"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port2_mac&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- code for taking user input for packet size and rate&lt;/span&gt;
&lt;span class="c1"&gt;-- setting the packet size &amp;amp; rate&lt;/span&gt;

&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- code to check time to run&lt;/span&gt;

&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  l3fwd
&lt;/h3&gt;

&lt;p&gt;A layer 3 forwarder matches the destination IP of an incoming packet to the entries stored in its forwarding table and updates the layer 2 header before sending the packet to the next-hop.&lt;/p&gt;

&lt;h3&gt;
  
  
  Longest Prefix Match
&lt;/h3&gt;

&lt;p&gt;For the LPM method, an LPM object is used to emulate the forwarding stage for IPv4 packets. The LPM object is used as the routing table to identify the next hop for each input packet at runtime. The example can be run with the following command on the SUT.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo&lt;/span&gt; ./&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;RTE_SDK&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/examples/l3fwd/&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;RTE_TARGET&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/app/l3fwd &lt;span class="nt"&gt;-c&lt;/span&gt; 0x55 &lt;span class="nt"&gt;-n&lt;/span&gt; 4 &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;-P&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 0xf &lt;span class="nt"&gt;--config&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt;0,0,0&lt;span class="o"&gt;)&lt;/span&gt;,&lt;span class="o"&gt;(&lt;/span&gt;1,0,2&lt;span class="o"&gt;)&lt;/span&gt;,&lt;span class="o"&gt;(&lt;/span&gt;2,0,4&lt;span class="o"&gt;)&lt;/span&gt;,&lt;span class="o"&gt;(&lt;/span&gt;3,0,6&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The IP addresses obtained from the &lt;a href="https://github.com/DPDK/dpdk/blob/466032ef8012a7fddd8dda986c5977e9341e3c35/examples/l3fwd/l3fwd_lpm.c#L46"&gt;source code&lt;/a&gt; of l3fwd are set as shown below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lua"&gt;&lt;code&gt;&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;port0&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"0"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;port1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;port2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;port3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"3"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_ipaddr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"dst"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"198.18.1.1"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_ipaddr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"src"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"198.18.0.1"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_ipaddr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"dst"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"198.18.0.1"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_ipaddr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"src"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"198.18.1.1"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_ipaddr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"dst"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"198.18.3.1"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_ipaddr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"src"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"198.18.2.1"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_ipaddr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"dst"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"198.18.2.1"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_ipaddr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"src"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"198.18.3.1"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- code for taking input of packet size, rate from the user&lt;/span&gt;
&lt;span class="c1"&gt;-- setting the packet size &amp;amp; rate&lt;/span&gt;

&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- code to check time to run&lt;/span&gt;

&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Exact Match
&lt;/h3&gt;

&lt;p&gt;In the exact match lookup method, the forwarding is based on a hash for which a hash object is used to emulate the flow classification stage. The example can be run with the following command on the SUT. The -E parameter selects the exact match method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo&lt;/span&gt; ./&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;RTE_SDK&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/examples/l3fwd/&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;RTE_TARGET&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/app/l3fwd &lt;span class="nt"&gt;-c&lt;/span&gt; 0x55 &lt;span class="nt"&gt;-n&lt;/span&gt; 4 &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;-P&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="nt"&gt;--parse-ptype&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 0xf &lt;span class="nt"&gt;--config&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt;0,0,0&lt;span class="o"&gt;)&lt;/span&gt;,&lt;span class="o"&gt;(&lt;/span&gt;1,0,2&lt;span class="o"&gt;)&lt;/span&gt;,&lt;span class="o"&gt;(&lt;/span&gt;2,0,4&lt;span class="o"&gt;)&lt;/span&gt;,&lt;span class="o"&gt;(&lt;/span&gt;3,0,6&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From the code for the l3fwd application, the exact match works only with TCP packets and thus we set the protocol as TCP in the packets generated from pktgen. The exact match is based on the combination of IP addresses and port numbers, as seen in the routing table in the code. We set the IP addresses and destination and source ports as shown below obtained from the &lt;a href="https://github.com/DPDK/dpdk/blob/466032ef8012a7fddd8dda986c5977e9341e3c35/examples/l3fwd/l3fwd_em.c#L102"&gt;source code&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lua"&gt;&lt;code&gt;&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;port0&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"0"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;port1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;port2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;port3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"3"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_ipaddr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"dst"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"201.0.0.0"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_ipaddr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"src"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"200.20.0.1"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_ipaddr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"dst"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"101.0.0.0"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_ipaddr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"src"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"100.10.0.1"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_ipaddr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"dst"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"211.0.0.0"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_ipaddr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"src"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"200.40.0.1"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_ipaddr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"dst"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"111.0.0.0"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_ipaddr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"src"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"100.30.0.1"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"sport"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"dport"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;102&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"sport"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"dport"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;101&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"sport"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"dport"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;102&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"sport"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"dport"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;101&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- code for taking input of packet size, rate from the user&lt;/span&gt;
&lt;span class="c1"&gt;-- setting the packet size &amp;amp; rate&lt;/span&gt;

&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_proto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"all"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"tcp"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- code to check time to run&lt;/span&gt;

&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  l3fwd-power
&lt;/h3&gt;

&lt;p&gt;The L3 Forwarding with Power Management application is an example of power-aware packet processing using the DPDK. The example can be run with the following command on the SUT.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo&lt;/span&gt; ./&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;RTE_SDK&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/examples/l3fwd-power/&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;RTE_TARGET&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/app/l3fwd-power &lt;span class="nt"&gt;-c&lt;/span&gt; 0x55 &lt;span class="nt"&gt;-n&lt;/span&gt; 4 &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;-P&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 0xf &lt;span class="nt"&gt;--config&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt;0,0,0&lt;span class="o"&gt;)&lt;/span&gt;,&lt;span class="o"&gt;(&lt;/span&gt;1,0,2&lt;span class="o"&gt;)&lt;/span&gt;,&lt;span class="o"&gt;(&lt;/span&gt;2,0,4&lt;span class="o"&gt;)&lt;/span&gt;,&lt;span class="o"&gt;(&lt;/span&gt;3,0,6&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The flow configured on pktgen with IP addresses can be done as below. The IP addresses are obtained from the &lt;a href="https://github.com/DPDK/dpdk/blob/466032ef8012a7fddd8dda986c5977e9341e3c35/examples/l3fwd-power/main.c#L339"&gt;source code&lt;/a&gt; of l3fwd-power. It runs the longest prefix match by default.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lua"&gt;&lt;code&gt;&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;port0&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"0"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;port1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;port2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;port3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"3"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_ipaddr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"dst"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"1.1.1.1"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_ipaddr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"src"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"2.1.1.1"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_ipaddr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"dst"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"2.1.1.1"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_ipaddr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"src"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"1.1.1.1"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_ipaddr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"dst"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"4.1.1.1"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_ipaddr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"src"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"3.1.1.1"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_ipaddr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"dst"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"3.1.1.1"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_ipaddr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"src"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"4.1.1.1"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"sport"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"dport"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;102&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"sport"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"dport"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;101&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"sport"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"dport"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;102&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"sport"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"dport"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;101&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- code for taking input of packet size, rate from the user&lt;/span&gt;
&lt;span class="c1"&gt;-- setting the packet size &amp;amp; rate&lt;/span&gt;

&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_proto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"all"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"tcp"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- code to check time to run&lt;/span&gt;

&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pktgen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;In this article, we looked at running various forwarding applications of DPDK with pktgen-dpdk as the traffic generator with four ports. The main challenge we faced while trying to run these applications was a lack of proper documentation in setting up various cases with pktgen and making sure the traffic forwards on the application and reaches back to the other port. If you do not configure the IP/MAC address properly, it is possible that the packets do not reach the other port but come back on the same port. We hope with this blog, you'll be able to configure your flows with ease. &lt;/p&gt;

&lt;p&gt;Both DPDK and pktgen-dpdk require a bit of work to set up and understand how the applications work, and undoubtedly there is a good learning curve. The DPDK documentation is quite detailed on running the DPDK applications and thus, we've not gone much into deep covering it but concentrated on pktgen-dpdk.&lt;/p&gt;

&lt;p&gt;The complete Lua scripts can be found &lt;a href="https://gist.github.com/mishal23/f16dd3fde15695b18d8a52dc11dd8cf0"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Acknowledgment
&lt;/h2&gt;

&lt;p&gt;We thank our project guide, &lt;a href="https://www.linkedin.com/in/mohittahiliani/"&gt;Dr. Mohit P. Tahiliani&lt;/a&gt;, and mentor Leslie Monis for their continuous guidance throughout the course of the project and our project teammate &lt;a href="https://github.com/vachhanihpavan/"&gt;Pavan Vachhani&lt;/a&gt; for his valuable contribution to the final project. &lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;DPDK Sample Application Guide: &lt;a href="https://doc.dpdk.org/guides/sample_app_ug/l2_forward_real_virtual.html"&gt;l2fwd&lt;/a&gt;, &lt;a href="https://doc.dpdk.org/guides/sample_app_ug/l3_forward.html"&gt;l3fwd&lt;/a&gt;, &lt;a href="https://doc.dpdk.org/guides/sample_app_ug/l3_forward_power_man.html"&gt;l3fwd-power&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pktgen-dpdk.readthedocs.io/en/latest/getting_started.html"&gt;Pktgen-DPDK&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;DPDK Source Code: &lt;a href="https://github.com/DPDK/dpdk"&gt;https://github.com/DPDK/dpdk&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>An introduction to Chaos Engineering</title>
      <dc:creator>Mishal Shah</dc:creator>
      <pubDate>Wed, 08 Jul 2020 09:56:04 +0000</pubDate>
      <link>https://dev.to/mishal23/an-introduction-to-chaos-engineering-13hb</link>
      <guid>https://dev.to/mishal23/an-introduction-to-chaos-engineering-13hb</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Many of us would have heard about the two major WhatsApp outages recently when it was down for about an hour each time. For the general public, WhatsApp was down for an hour. But for software engineers, WhatsApp was back within an hour. This made me wonder what it was, that enabled the engineers working at WhatsApp to restore the services so fast.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NluvPNJP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mishal23.github.io/static/647f1be1968284700a874b3356b2c8de/a805e/whatsapp-outage.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NluvPNJP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mishal23.github.io/static/647f1be1968284700a874b3356b2c8de/a805e/whatsapp-outage.png" alt="whatsapp-outage"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What if I tell you, it was a very &lt;strong&gt;normal&lt;/strong&gt; turbulent production failure for them. Yes, huge companies like &lt;a href="https://www.netflix.com/in/"&gt;Netflix&lt;/a&gt;, &lt;a href="https://www.facebook.com/"&gt;Facebook&lt;/a&gt;, and &lt;a href="https://www.google.com/"&gt;Google&lt;/a&gt; use a method of engineering called &lt;strong&gt;Chaos Engineering&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;To explain Chaos Engineering in layman terms: To be good at something, if one practices it in extreme conditions then it would get easier for the person to perform in normal conditions. Similarly, if a software engineer has seen extreme conditions in production, it becomes a challenge for him/her to code in such a way that their service fails if such an extreme condition occurs. If at all it comes, they would have experienced it before and so it becomes easy to bring the services back.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QZWPuL60--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mishal23.github.io/static/1566b810aa17241f58a9b8731c8aeebb/aeb78/chaos-engineering.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QZWPuL60--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mishal23.github.io/static/1566b810aa17241f58a9b8731c8aeebb/aeb78/chaos-engineering.png" alt="chaos-engineering"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Principle of Choas Engineering
&lt;/h2&gt;

&lt;p&gt;The main idea of Chaos Engineering is to intentionally inject failures so as to be prepared for the worst conditions. A formal definition for Chaos Engineering given by Netflix:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Chaos Engineering is the discipline of experimenting on a distributed system in order to build confidence in the system’s capability to withstand turbulent conditions in production.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Chaos Engineering can be thought of as the facilitation of experiments to uncover systemic weaknesses. These experiments follow four steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start by defining ‘steady state’ as some measurable output of a system that indicates normal behavior.&lt;/li&gt;
&lt;li&gt;Hypothesize that this steady-state will continue in both the control group and the experimental group.&lt;/li&gt;
&lt;li&gt;Introduce variables that reflect real-world events like servers that crash, hard drives that malfunction, network connections that are severed, etc.&lt;/li&gt;
&lt;li&gt;Try to disprove the hypothesis by looking for a difference in the steady-state between the control group and the experimental group.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The harder it is to disrupt the steady-state, the more confidence we have in the behavior of the system. If a weakness is uncovered, we now have a target for improvement before that behavior manifests in the system at large. In layman terms: Break your system, see the difference between steady-state and experimental state, lesser the difference, lesser it will break in production. If the difference is more, you have a target for improvement before actually experiencing it in production.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical Use
&lt;/h2&gt;

&lt;p&gt;Netflix, a pioneer in the field of Chaos Engineering, uses a tool called Chaos Monkey. It randomly picks a server from production deployment on AWS (Amazon Web Services) and kills it. Executives at Netflix knew that server failures are guaranteed to happen and they wanted servers to fail during working-hours so that it could be fixed it in the presence of their engineers. They knew that they could rely on engineers to build resilient solutions if they were given context to expect servers to fail. If they could align their engineers to build services that survive a server failure, then when it actually happened, it wouldn’t be a big deal.&lt;/p&gt;

&lt;h2&gt;
  
  
  How can it help you?
&lt;/h2&gt;

&lt;p&gt;Suppose your team has built the next wave of advancement the whole world has been waiting for. You are to launch your service but there are questions rumbling in your mind:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is your application ready for production?&lt;/li&gt;
&lt;li&gt;Will the system survive the failures of other companies you are dependent on?&lt;/li&gt;
&lt;li&gt;Will the system survive the failure of your own configurations?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The truth is: You can never be sure. There will always be something that can be wrong or will go wrong. Some things aren’t in your control like denial-of-service attacks or network failures. Sometimes, bad things just happen.&lt;/p&gt;

&lt;p&gt;Possibly The only solution for it is to build quality software that is resilient to failures. As the saying goes - &lt;em&gt;"Hope for the best, prepare for the worst"&lt;/em&gt; But how can your team be sure that your system is ready for production and is ready to face all difficulties/failures? This is where Chaos Engineering comes into the picture.&lt;/p&gt;

&lt;h2&gt;
  
  
  Does this seem like testing?
&lt;/h2&gt;

&lt;p&gt;It may indeed sound like it, but it definitely isn’t testing. Chaos Engineering is an experiment on the production environment and there is certainly no way to accurately duplicate the production environment at scale (as in testing). The experiment itself is going to have a systemic effect that could change your results, so the only way to accurately build conflict in the system that you have now is to experiment on it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The purpose of Chaos Engineering is to experience disastrous conditions. This might sound like a difficult task and it does require a lot of creativity but the extra effort is worth it. You must inject failures in your system such that certain parts of your infrastructure becomes unavailable. Some examples are: terminate cluster machines, kill worker processes, delete database tables, cut off access to internal-external services, etc. Later you can also simulate events capable of disrupting steady-state like high latency due to slow networks.&lt;/p&gt;

&lt;p&gt;These experiments are a bit difficult but whatever you decide to do, you’ll be surprised at how much you can learn from chaos. There are a lot of tools worth mentioning :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/Netflix/chaosmonkey"&gt;Chaos Monkey&lt;/a&gt; - A resiliency tool that helps applications tolerate random instance failures&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/Netflix/SimianArmy"&gt;The Simian Army&lt;/a&gt; - A suite of tools for keeping your cloud operating in top form&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/asobti/kube-monkey"&gt;kube-monkey&lt;/a&gt; - An implementation of Netflix's Chaos Monkey for Kubernetes clusters&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.gremlin.com/"&gt;Gremlin Inc.&lt;/a&gt; - Failure as a Service&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/alexei-led/pumba"&gt;Pumba&lt;/a&gt; - Chaos testing and network emulation for Docker containers (and clusters)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/chaostoolkit/chaostoolkit"&gt;Chaos Toolkit&lt;/a&gt; - A chaos engineering toolkit to help you build confidence in your software system&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/github/orchestrator"&gt;orchestrator&lt;/a&gt; - MySQL replication topology management and HA&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I hope you got an idea about Chaos Engineering - a powerful approach to build resilient systems!&lt;/p&gt;

</description>
      <category>chaos</category>
      <category>chaosengineering</category>
      <category>netflix</category>
    </item>
    <item>
      <title>Migrating Jekyll Blog to Gatsby</title>
      <dc:creator>Mishal Shah</dc:creator>
      <pubDate>Wed, 08 Jul 2020 09:44:19 +0000</pubDate>
      <link>https://dev.to/mishal23/migrating-jekyll-blog-to-gatsby-1681</link>
      <guid>https://dev.to/mishal23/migrating-jekyll-blog-to-gatsby-1681</guid>
      <description>&lt;p&gt;I had started building my personal website in 2017 with static HTML, CSS, JS and in 2018 based on the available options, I went ahead with Jekyll. Overall, everything was working fine with Jekyll and was smooth. Although, my Twitter feed was filled with &lt;a href="https://www.gatsbyjs.org/"&gt;Gatsby&lt;/a&gt;, and I had seen some stickers named "My Website is faster than yours" of Gatsby while interacting with them for &lt;a href="https://hackverse.nitk.ac.in/"&gt;HackVerse Hackathon&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yYhxuByr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/w9gqya9sa1fgwydib5ji.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yYhxuByr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/w9gqya9sa1fgwydib5ji.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This really made me look at some of the Gatsby sites and it really felt that the websites were fast, and it had the support of PWA, something which I really wanted on my site. Moreover, since it was based on React, I decided to try out to move my personal website from Jekyll to Gatsby.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Migration
&lt;/h2&gt;

&lt;p&gt;I won't be listing the steps in detail on how I did the migration because there are plenty of blogs out there and the documentation provided by Gatsby is excellent. I could get anything I wanted on the Gatsby documentation. I started looking into the tutorial of Gatsby to get a hang of it and started my new website with the default starter code.&lt;/p&gt;

&lt;p&gt;Here are the major steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Started looking into the &lt;a href="https://www.gatsbyjs.org/tutorial/"&gt;tutorial&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;Took the gatsby default starter code,&lt;/li&gt;
&lt;li&gt;Added the initial components (

&lt;code&gt;sidebar&lt;/code&gt;

,

&lt;code&gt;post&lt;/code&gt;

,

&lt;code&gt;default&lt;/code&gt;

), and set up - the basic styling as per the old website,
- Added the content for the non-blog pages (

&lt;code&gt;about&lt;/code&gt;

,

&lt;code&gt;projects&lt;/code&gt;

,

&lt;code&gt;contact&lt;/code&gt;

,

&lt;code&gt;404&lt;/code&gt;

),
- Setup blog page component view (blogPost) from markdown pages using the

&lt;code&gt;onCreateNode&lt;/code&gt;

,

&lt;code&gt;createPages&lt;/code&gt;

APIs,
- Learnt a bit about using GraphQL and GraphiQL UI,
- Exported all the blog posts from the previous site,
- Index Page Display to list all the blog posts (

&lt;code&gt;blogList&lt;/code&gt;

),&lt;/li&gt;
&lt;li&gt;Added SEO for all pages,&lt;/li&gt;
&lt;li&gt;Added automatic deployment with TravisCI,&lt;/li&gt;
&lt;li&gt;Added Google Analytics &amp;amp; PWA support,&lt;/li&gt;
&lt;li&gt;Some other fixes for overall look &amp;amp; feel.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's the lighthouse report of the new website:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MqZtCKv6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mishal23.github.io/static/1558f1413b07985991012105d5a0e745/3cb18/lighthouse-report.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MqZtCKv6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mishal23.github.io/static/1558f1413b07985991012105d5a0e745/3cb18/lighthouse-report.jpg" alt="lighthouse report"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  GitHub Actions
&lt;/h2&gt;

&lt;p&gt;When GitHub Actions was released in &lt;a href="https://github.blog/2019-08-08-github-actions-now-supports-ci-cd/"&gt;August 2019&lt;/a&gt;, I always wanted to give it a try for some project but didn't get enough time to try it out. While I was using Travis CI with this deployment, I thought of giving GitHub Actions a try. Finally!&lt;/p&gt;

&lt;p&gt;Here are the steps I followed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Generated a New Token from

&lt;code&gt;GitHub Settings -&amp;gt; Developer Settings -&amp;gt; Personal access tokens&lt;/code&gt;

with &lt;strong&gt;repo&lt;/strong&gt; access scope.
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XOCnlxfn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mishal23.github.io/static/6c23295de0d6fad7f13f43dea6a57aec/a6d36/repo-token.png" alt="token"&gt;
&lt;/li&gt;
&lt;li&gt;I was deploying on my root github.io so the name of my repo is mishal23.github.io, I added the token in the repository

&lt;code&gt;Settings -&amp;gt; Secrets&lt;/code&gt;

with the name

&lt;code&gt;GH_TOKEN&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Y0a8d6Ez--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mishal23.github.io/static/455a3edaf409e257d143ca31a423ba8f/a6d36/set-secret.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Y0a8d6Ez--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mishal23.github.io/static/455a3edaf409e257d143ca31a423ba8f/a6d36/set-secret.png" alt="set-secret"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Created a file named

&lt;code&gt;gh-pages-deploy.yml&lt;/code&gt;

in the directory

&lt;code&gt;.github/workflows/&lt;/code&gt;

using the Simple Workflow template available under Actions tab on the repository.&lt;/li&gt;
&lt;li&gt;Since, the User pages must be built from the master branch, I set my default branch as &lt;strong&gt;source&lt;/strong&gt; on the repository and left the master branch for deployment and hence triggered the workflow only on &lt;strong&gt;source&lt;/strong&gt; branch push,&lt;/li&gt;
&lt;li&gt;I configured it to node.js environment with &lt;strong&gt;12.x&lt;/strong&gt; version, cached the dependencies so that it doesn't have to be installed every time and faster CI,&lt;/li&gt;
&lt;li&gt;Configured to initial git settings of user.name and user.email as it is required, used to &lt;strong&gt;GH_TOKEN&lt;/strong&gt; to give the access and then made the deployment run using the following command:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it! Pretty simple! Really like the simplicity of GitHub Actions. Find the complete configuration file &lt;a href="https://github.com/mishal23/mishal23.github.io/blob/source/.github/workflows/gh-pages-deploy.yml"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The migration was definitely worth it, the site is actually blazing fast 🚀 and moreover, got to pick up some new skills. Would recommend anyone to migrate to gatsby. There are certain features and fixes which I plan to do in due time. If you need any further help, feel free to take a look at &lt;a href="https://github.com/mishal23/mishal23.github.io/"&gt;the repo&lt;/a&gt; or &lt;a href="https://dev.to/misahl23"&gt;contact me&lt;/a&gt; If there are any issues you come across, please do open up &lt;a href="https://github.com/mishal23/mishal23.github.io/issues"&gt;here&lt;/a&gt; or would love it if you fix it :)&lt;/p&gt;

</description>
      <category>jekyll</category>
      <category>gatsby</category>
      <category>githubactions</category>
    </item>
    <item>
      <title>Virtual Clinic - An Integrated Care System</title>
      <dc:creator>Mishal Shah</dc:creator>
      <pubDate>Fri, 22 May 2020 07:47:18 +0000</pubDate>
      <link>https://dev.to/mishal23/virtual-clinic-an-integrated-care-system-oo1</link>
      <guid>https://dev.to/mishal23/virtual-clinic-an-integrated-care-system-oo1</guid>
      <description>&lt;h2&gt;
  
  
  My Project
&lt;/h2&gt;

&lt;p&gt;Virtual Clinic was an attempt to bring all the stakeholders of the healthcare system on one platform and make it easier for the patients to communicate and thus improve the operations. It has over 20+ features and a neat user interface.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;The application was deployed on Heroku with CI/CD using Travis CI, please find the link here: &lt;a href="http://virtual-clinic.herokuapp.com/"&gt;http://virtual-clinic.herokuapp.com/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Link to Code
&lt;/h2&gt;

&lt;p&gt;The entire code is open-sourced on my GitHub handle: &lt;a href="https://github.com/mishal23/virtual-clinic"&gt;https://github.com/mishal23/virtual-clinic&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How I built it
&lt;/h2&gt;

&lt;p&gt;The entire application is written in Python Framework - Django, with certain packages, unit tests, Travis CI for CI/CD, code coverage, documentation, followed all the Software Engineering Principles. There were many issues that I had faced building this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;multiple role-based access system&lt;/li&gt;
&lt;li&gt;ensuring the DRY principle&lt;/li&gt;
&lt;li&gt;session keys to maintain&lt;/li&gt;
&lt;li&gt;coupling the entire application together with a flow&lt;/li&gt;
&lt;li&gt;building a decent front-end&lt;/li&gt;
&lt;li&gt;migrating database from sqlite3 to MySQL&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Additional Thoughts
&lt;/h2&gt;

&lt;p&gt;The application is no unique, there would be many such existing apps, but this was an application that I built on my own alone completely from scratch, and at a point, only contributing to other projects in a team felt as if I haven't done anything on own and hence I don't know a lot of things. Hence, this was a very special project for me, it gave me the required confidence in my skills and the software engineering principles, the amount of confidence I had after this project to work on any other project was just boosted up. Having made a decent front-end design, automating the deploy, a bit complex backend, documenting, following SE principles - it helped me in all prospects.&lt;/p&gt;

&lt;p&gt;If you like my project, please do consider starring the repository or contributing to it either by code, opening issues, or adding more documentation.&lt;/p&gt;

</description>
      <category>octograd2020</category>
    </item>
  </channel>
</rss>
