examples/l2fwd: add option --[no-]mac-updating

l2fwd could be useful for testing virtual devices without the need
of physical ones.

To achieve this, this patch adds a new option to enable/disable the
MAC addresses updating done at forwarding time: --[no-]mac-updating

It enables the use of l2fwd for basic VM to VM communication.

By default, MAC address updating remains enabled, to keep consistency
with previous usage.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Acked-by: John McNamara <john.mcnamara@intel.com>
This commit is contained in:
Maxime Coquelin 2016-09-23 15:50:53 +02:00 committed by Thomas Monjalon
parent edabd7fef5
commit cf435a07c0
3 changed files with 362 additions and 21 deletions

View File

@ -0,0 +1,311 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="554.46204"
height="443.63278"
viewBox="0 0 554.46204 443.63279"
id="svg3917"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="l2_fwd_vm2vm.svg">
<defs
id="defs3919">
<marker
inkscape:isstock="true"
style="overflow:visible"
id="marker8020"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="Arrow1Lend">
<path
transform="matrix(-0.8,0,0,-0.8,-10,0)"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
id="path8022"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:isstock="true"
style="overflow:visible"
id="marker7177"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="Arrow1Lend">
<path
transform="matrix(-0.8,0,0,-0.8,-10,0)"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
id="path7179"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:isstock="true"
style="overflow:visible"
id="marker6025"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="Arrow1Lend">
<path
transform="matrix(-0.8,0,0,-0.8,-10,0)"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
id="path6027"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow1Lend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Lend"
style="overflow:visible"
inkscape:isstock="true"
inkscape:collect="always">
<path
id="path5351"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
transform="matrix(-0.8,0,0,-0.8,-10,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow1Lstart"
orient="auto"
refY="0"
refX="0"
id="Arrow1Lstart"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path5348"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
transform="matrix(0.8,0,0,0.8,10,0)"
inkscape:connector-curvature="0" />
</marker>
<inkscape:path-effect
effect="powerstroke"
id="path-effect4780"
is_visible="true"
offset_points="0,0.5"
sort_points="true"
interpolator_type="Linear"
interpolator_beta="0.2"
start_linecap_type="zerowidth"
linejoin_type="round"
miter_limit="4"
end_linecap_type="zerowidth"
cusp_linecap_type="round" />
<linearGradient
id="linearGradient4729"
osb:paint="solid">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop4731" />
</linearGradient>
<marker
inkscape:stockid="Arrow1Lend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Lend-5"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path5351-3"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
transform="matrix(-0.8,0,0,-0.8,-10,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Lend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Lend-6"
style="overflow:visible"
inkscape:isstock="true"
inkscape:collect="always">
<path
inkscape:connector-curvature="0"
id="path5351-2"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
transform="matrix(-0.8,0,0,-0.8,-10,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Lend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Lend-6-1"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path5351-2-2"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
transform="matrix(-0.8,0,0,-0.8,-10,0)" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="323.29803"
inkscape:cy="27.634604"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:snap-nodes="false"
inkscape:snap-bbox="true"
inkscape:window-width="1276"
inkscape:window-height="1400"
inkscape:window-x="1280"
inkscape:window-y="38"
inkscape:window-maximized="0"
units="px"
fit-margin-top="5"
fit-margin-left="5"
fit-margin-right="5"
fit-margin-bottom="5" />
<metadata
id="metadata3922">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-0.56091356,-0.34416246)">
<rect
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:2.10537624;stroke-opacity:1"
id="rect4727"
width="542.35669"
height="431.5274"
x="6.6136017"
y="6.3968506" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:30.53249741px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="237.30467"
y="33.252548"
id="text4735"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4737"
x="237.30467"
y="33.252548">Host</tspan></text>
<rect
style="fill:none;fill-opacity:1;stroke:#000000;stroke-opacity:1"
id="rect4739"
width="207.08128"
height="202.03053"
x="38.385803"
y="45.240112" />
<rect
style="fill:none;fill-opacity:1;stroke:#000000;stroke-opacity:1"
id="rect4739-3"
width="207.08128"
height="202.03053"
x="301.53052"
y="44.22995" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:19.96650314px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="101.13004"
y="63.706543"
id="text4756"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4758"
x="101.13004"
y="63.706543">Guest1</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:19.96650314px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="369.73492"
y="63.619873"
id="text4756-6"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4758-7"
x="369.73492"
y="63.619873">Guest2</tspan></text>
<rect
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect5336"
width="477.80215"
height="85.862968"
x="39.39595"
y="316.97116" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:23.81648636px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="237.96404"
y="398.79352"
id="text5338"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan5340"
x="237.96404"
y="398.79352">L2FWD</tspan></text>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.9760201px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Lend)"
d="m 120.20815,247.27063 0,68.32236"
id="path5342"
inkscape:connector-curvature="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.9760201px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Lend-5)"
d="m 382.84782,246.56645 0,68.32236"
id="path5342-5"
inkscape:connector-curvature="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.9760201px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Lend-6)"
d="m 162.63455,316.66519 0,-68.32236"
id="path5342-9"
inkscape:connector-curvature="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.9760201px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Lend-6-1)"
d="m 423.25391,315.65504 0,-68.32236"
id="path5342-9-7"
inkscape:connector-curvature="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.60951841;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:4.82855511, 1.60951837;stroke-dashoffset:0;stroke-opacity:1"
d="m 119.48645,319.66266 0,47.47156 303.479,0 0,-51.26929"
id="path10412"
inkscape:connector-curvature="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.1137104;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:3.3411313, 1.11371043;stroke-dashoffset:0;stroke-opacity:1"
d="m 162.67537,318.28501 0,31.19206 221.14177,0 0,-33.68743"
id="path10412-0"
inkscape:connector-curvature="0" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -50,17 +50,14 @@ performs L2 forwarding for each packet that is received on an RX_PORT.
The destination port is the adjacent port from the enabled portmask, that is, The destination port is the adjacent port from the enabled portmask, that is,
if the first four ports are enabled (portmask 0xf), if the first four ports are enabled (portmask 0xf),
ports 1 and 2 forward into each other, and ports 3 and 4 forward into each other. ports 1 and 2 forward into each other, and ports 3 and 4 forward into each other.
Also, the MAC addresses are affected as follows: Also, if MAC addresses updating is enabled, the MAC addresses are affected as follows:
* The source MAC address is replaced by the TX_PORT MAC address * The source MAC address is replaced by the TX_PORT MAC address
* The destination MAC address is replaced by 02:00:00:00:00:TX_PORT_ID * The destination MAC address is replaced by 02:00:00:00:00:TX_PORT_ID
This application can be used to benchmark performance using a traffic-generator, as shown in the :numref:`figure_l2_fwd_benchmark_setup`. This application can be used to benchmark performance using a traffic-generator, as shown in the :numref:`figure_l2_fwd_benchmark_setup`,
or in a virtualized environment as shown in :numref:`figure_l2_fwd_virtenv_benchmark_setup`.
The application can also be used in a virtualized environment as shown in :numref:`figure_l2_fwd_virtenv_benchmark_setup`.
The L2 Forwarding application can also be used as a starting point for developing a new application based on the DPDK.
.. _figure_l2_fwd_benchmark_setup: .. _figure_l2_fwd_benchmark_setup:
@ -68,13 +65,23 @@ The L2 Forwarding application can also be used as a starting point for developin
Performance Benchmark Setup (Basic Environment) Performance Benchmark Setup (Basic Environment)
.. _figure_l2_fwd_virtenv_benchmark_setup: .. _figure_l2_fwd_virtenv_benchmark_setup:
.. figure:: img/l2_fwd_virtenv_benchmark_setup.* .. figure:: img/l2_fwd_virtenv_benchmark_setup.*
Performance Benchmark Setup (Virtualized Environment) Performance Benchmark Setup (Virtualized Environment)
This application may be used for basic VM to VM communication as shown in :numref:`figure_l2_fwd_vm2vm`,
when MAC addresses updating is disabled.
.. _figure_l2_fwd_vm2vm:
.. figure:: img/l2_fwd_vm2vm.*
Virtual Machine to Virtual Machine communication.
The L2 Forwarding application can also be used as a starting point for developing a new application based on the DPDK.
.. _l2_fwd_vf_setup: .. _l2_fwd_vf_setup:
Virtual Function Setup Instructions Virtual Function Setup Instructions
@ -128,7 +135,7 @@ The application requires a number of command line options:
.. code-block:: console .. code-block:: console
./build/l2fwd [EAL options] -- -p PORTMASK [-q NQ] ./build/l2fwd [EAL options] -- -p PORTMASK [-q NQ] --[no-]mac-updating
where, where,
@ -136,7 +143,10 @@ where,
* q NQ: A number of queues (=ports) per lcore (default is 1) * q NQ: A number of queues (=ports) per lcore (default is 1)
To run the application in linuxapp environment with 4 lcores, 16 ports and 8 RX queues per lcore, issue the command: * --[no-]mac-updating: Enable or disable MAC addresses updating (enabled by default).
To run the application in linuxapp environment with 4 lcores, 16 ports and 8 RX queues per lcore and MAC address
updating enabled, issue the command:
.. code-block:: console .. code-block:: console
@ -415,7 +425,8 @@ Packets are read in a burst of size MAX_PKT_BURST.
The rte_eth_rx_burst() function writes the mbuf pointers in a local table and returns the number of available mbufs in the table. The rte_eth_rx_burst() function writes the mbuf pointers in a local table and returns the number of available mbufs in the table.
Then, each mbuf in the table is processed by the l2fwd_simple_forward() function. Then, each mbuf in the table is processed by the l2fwd_simple_forward() function.
The processing is very simple: process the TX port from the RX port, then replace the source and destination MAC addresses. The processing is very simple: process the TX port from the RX port, then replace the source and destination MAC addresses if MAC
addresses updating is enabled.
.. note:: .. note::

View File

@ -73,6 +73,9 @@
static volatile bool force_quit; static volatile bool force_quit;
/* MAC updating enabled by default */
static int mac_updating = 1;
#define RTE_LOGTYPE_L2FWD RTE_LOGTYPE_USER1 #define RTE_LOGTYPE_L2FWD RTE_LOGTYPE_USER1
#define NB_MBUF 8192 #define NB_MBUF 8192
@ -185,23 +188,32 @@ print_stats(void)
} }
static void static void
l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid) l2fwd_mac_updating(struct rte_mbuf *m, unsigned dest_portid)
{ {
struct ether_hdr *eth; struct ether_hdr *eth;
void *tmp; void *tmp;
eth = rte_pktmbuf_mtod(m, struct ether_hdr *);
/* 02:00:00:00:00:xx */
tmp = &eth->d_addr.addr_bytes[0];
*((uint64_t *)tmp) = 0x000000000002 + ((uint64_t)dest_portid << 40);
/* src addr */
ether_addr_copy(&l2fwd_ports_eth_addr[dest_portid], &eth->s_addr);
}
static void
l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid)
{
unsigned dst_port; unsigned dst_port;
int sent; int sent;
struct rte_eth_dev_tx_buffer *buffer; struct rte_eth_dev_tx_buffer *buffer;
dst_port = l2fwd_dst_ports[portid]; dst_port = l2fwd_dst_ports[portid];
eth = rte_pktmbuf_mtod(m, struct ether_hdr *);
/* 02:00:00:00:00:xx */ if (mac_updating)
tmp = &eth->d_addr.addr_bytes[0]; l2fwd_mac_updating(m, dst_port);
*((uint64_t *)tmp) = 0x000000000002 + ((uint64_t)dst_port << 40);
/* src addr */
ether_addr_copy(&l2fwd_ports_eth_addr[dst_port], &eth->s_addr);
buffer = tx_buffer[dst_port]; buffer = tx_buffer[dst_port];
sent = rte_eth_tx_buffer(dst_port, 0, buffer, m); sent = rte_eth_tx_buffer(dst_port, 0, buffer, m);
@ -321,7 +333,11 @@ l2fwd_usage(const char *prgname)
printf("%s [EAL options] -- -p PORTMASK [-q NQ]\n" printf("%s [EAL options] -- -p PORTMASK [-q NQ]\n"
" -p PORTMASK: hexadecimal bitmask of ports to configure\n" " -p PORTMASK: hexadecimal bitmask of ports to configure\n"
" -q NQ: number of queue (=ports) per lcore (default is 1)\n" " -q NQ: number of queue (=ports) per lcore (default is 1)\n"
" -T PERIOD: statistics will be refreshed each PERIOD seconds (0 to disable, 10 default, 86400 maximum)\n", " -T PERIOD: statistics will be refreshed each PERIOD seconds (0 to disable, 10 default, 86400 maximum)\n"
" --[no-]mac-updating: Enable or disable MAC addresses updating (enabled by default)\n"
" When enabled:\n"
" - The source MAC address is replaced by the TX port MAC address\n"
" - The destination MAC address is replaced by 02:00:00:00:00:TX_PORT_ID\n",
prgname); prgname);
} }
@ -385,6 +401,8 @@ l2fwd_parse_args(int argc, char **argv)
int option_index; int option_index;
char *prgname = argv[0]; char *prgname = argv[0];
static struct option lgopts[] = { static struct option lgopts[] = {
{ "mac-updating", no_argument, &mac_updating, 1},
{ "no-mac-updating", no_argument, &mac_updating, 0},
{NULL, 0, 0, 0} {NULL, 0, 0, 0}
}; };
@ -427,8 +445,7 @@ l2fwd_parse_args(int argc, char **argv)
/* long options */ /* long options */
case 0: case 0:
l2fwd_usage(prgname); break;
return -1;
default: default:
l2fwd_usage(prgname); l2fwd_usage(prgname);
@ -541,6 +558,8 @@ main(int argc, char **argv)
if (ret < 0) if (ret < 0)
rte_exit(EXIT_FAILURE, "Invalid L2FWD arguments\n"); rte_exit(EXIT_FAILURE, "Invalid L2FWD arguments\n");
printf("MAC updating %s\n", mac_updating ? "enabled" : "disabled");
/* convert to number of cycles */ /* convert to number of cycles */
timer_period *= rte_get_timer_hz(); timer_period *= rte_get_timer_hz();