From: Rakesh Kudurumalla <rkuduruma...@marvell.com> Adds an use case l3fwd. It contains a dedicated l3fwd.cli file mentioning commands to configure the required resources.
Once application successfully parses the l3fwd.cli then a graph is created having below nodes: - ethdev_rx -> pkt_cls - pkt_cls -> ip4_lookup - pkt_cls -> ip6_lookup - pkt_cls -> pkt_drop - ip4_lookup -> ip4_rewrite - ip4_lookup -> pkt_drop - ip6_lookup -> ip6_rewrite - ip6_lookup -> pkt_drop - ip4_rewrite -> ethdev_tx - ip4_rewrite -> pkt_drop - ip6_rewrite -> ethdev_tx - ip6_rewrite -> pkt_drop - ethdev_tx -> pkt_drop Signed-off-by: Sunil Kumar Kori <sk...@marvell.com> Signed-off-by: Rakesh Kudurumalla <rkuduruma...@marvell.com> --- app/graph/examples/l3fwd.cli | 87 ++++++++ app/graph/graph.c | 2 +- app/graph/l3fwd.c | 136 ++++++++++++ app/graph/l3fwd.h | 11 + app/graph/meson.build | 1 + app/graph/module_api.h | 1 + doc/guides/tools/graph.rst | 11 + doc/guides/tools/img/graph-usecase-l3fwd.svg | 210 +++++++++++++++++++ 8 files changed, 458 insertions(+), 1 deletion(-) create mode 100644 app/graph/examples/l3fwd.cli create mode 100644 app/graph/l3fwd.c create mode 100644 app/graph/l3fwd.h create mode 100644 doc/guides/tools/img/graph-usecase-l3fwd.svg diff --git a/app/graph/examples/l3fwd.cli b/app/graph/examples/l3fwd.cli new file mode 100644 index 0000000000..1038fde04e --- /dev/null +++ b/app/graph/examples/l3fwd.cli @@ -0,0 +1,87 @@ +; SPDX-License-Identifier: BSD-3-Clause +; Copyright(c) 2023 Marvell. + +; +; Graph configuration for given usecase +; +graph l3fwd coremask 0xff bsz 32 tmo 10 model default pcap_enable 1 num_pcap_pkts 100000 pcap_file /tmp/output.pcap + +; +; Mempools to be attached with ethdev +; +mempool mempool0 size 8192 buffers 4000 cache 256 numa 0 + +; +; DPDK devices and configuration. +; +; Note: Customize the parameters below to match your setup. +; +ethdev 0002:04:00.0 rxq 1 txq 8 mempool0 +ethdev 0002:05:00.0 rxq 1 txq 8 mempool0 +ethdev 0002:06:00.0 rxq 1 txq 8 mempool0 +ethdev 0002:07:00.0 rxq 1 txq 8 mempool0 +ethdev 0002:04:00.0 mtu 1700 +ethdev 0002:05:00.0 promiscuous on + +; +; IPv4 addresses assigned to DPDK devices +; +ethdev 0002:04:00.0 ip4 addr add 10.0.2.1 netmask 255.255.255.0 +ethdev 0002:05:00.0 ip4 addr add 20.0.2.1 netmask 255.255.255.0 +ethdev 0002:06:00.0 ip4 addr add 30.0.2.1 netmask 255.255.255.0 +ethdev 0002:07:00.0 ip4 addr add 40.0.2.1 netmask 255.255.255.0 + +; +; IPv6 addresses assigned to DPDK devices +; +ethdev 0002:04:00.0 ip6 addr add 52:20:DA:4F:68:70:52:20:DA:4F:68:70:52:20:DA:4A netmask FF:FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00 +ethdev 0002:05:00.0 ip6 addr add 62:20:DA:4F:68:70:52:20:DA:4F:68:70:52:20:DA:4B netmask FF:FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00 +ethdev 0002:06:00.0 ip6 addr add 72:20:DA:4F:68:70:52:20:DA:4F:68:70:52:20:DA:4C netmask FF:FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00 +ethdev 0002:07:00.0 ip6 addr add 82:20:DA:4F:68:70:52:20:DA:4F:68:70:52:20:DA:4D netmask FF:FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00 + +; +; IPv4 routes which are installed to ipv4_lookup node for LPM processing +; +ipv4_lookup route add ipv4 10.0.2.0 netmask 255.255.255.0 via 10.0.2.1 +ipv4_lookup route add ipv4 20.0.2.0 netmask 255.255.255.0 via 20.0.2.1 +ipv4_lookup route add ipv4 30.0.2.0 netmask 255.255.255.0 via 30.0.2.1 +ipv4_lookup route add ipv4 40.0.2.0 netmask 255.255.255.0 via 40.0.2.1 + +; +; IPv6 routes which are installed to ipv6_lookup node for LPM processing +; +ipv6_lookup route add ipv6 52:20:DA:4F:68:70:52:20:DA:4F:68:70:52:20:DA:4A netmask FF:FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00 via 52:20:DA:4F:68:70:52:20:DA:4F:68:70:52:20:DA:4A +ipv6_lookup route add ipv6 62:20:DA:4F:68:70:52:20:DA:4F:68:70:52:20:DA:4B netmask FF:FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00 via 62:20:DA:4F:68:70:52:20:DA:4F:68:70:52:20:DA:4B +ipv6_lookup route add ipv6 72:20:DA:4F:68:70:52:20:DA:4F:68:70:52:20:DA:4C netmask FF:FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00 via 72:20:DA:4F:68:70:52:20:DA:4F:68:70:52:20:DA:4C +ipv6_lookup route add ipv6 82:20:DA:4F:68:70:52:20:DA:4F:68:70:52:20:DA:4D netmask FF:FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00 via 82:20:DA:4F:68:70:52:20:DA:4F:68:70:52:20:DA:4D + +; +; Peer MAC and IPv4 address mapping +; +neigh add ipv4 10.0.2.2 52:20:DA:4F:68:70 +neigh add ipv4 20.0.2.2 62:20:DA:4F:68:70 +neigh add ipv4 30.0.2.2 72:20:DA:4F:68:70 +neigh add ipv4 40.0.2.2 82:20:DA:4F:68:70 + +; +; Peer MAC and IPv6 address mapping +; +neigh add ipv6 52:20:DA:4F:68:70:52:20:DA:4F:68:70:52:20:DA:4A 52:20:DA:4F:68:70 +neigh add ipv6 62:20:DA:4F:68:70:52:20:DA:4F:68:70:52:20:DA:4B 62:20:DA:4F:68:70 +neigh add ipv6 72:20:DA:4F:68:70:52:20:DA:4F:68:70:52:20:DA:4C 72:20:DA:4F:68:70 +neigh add ipv6 82:20:DA:4F:68:70:52:20:DA:4F:68:70:52:20:DA:4D 82:20:DA:4F:68:70 + +; +; Port-Queue-Core mapping for ethdev_rx node +; +ethdev_rx map port 0002:04:00.0 queue 0 core 1 +ethdev_rx map port 0002:05:00.0 queue 0 core 2 +ethdev_rx map port 0002:06:00.0 queue 0 core 3 +ethdev_rx map port 0002:07:00.0 queue 0 core 4 + +; +; Graph start command to create graph. +; +; Note: No more command should come after this. +; +graph start diff --git a/app/graph/graph.c b/app/graph/graph.c index 4396f02da5..496105eef1 100644 --- a/app/graph/graph.c +++ b/app/graph/graph.c @@ -269,7 +269,7 @@ cli_graph_start(__rte_unused void *parsed_result, __rte_unused struct cmdline *c for (i = 0; i < MAX_GRAPH_USECASES; i++) { if (!strcmp(graph_config.usecases[i].name, "l3fwd")) { if (graph_config.usecases[i].enabled) { - RTE_SET_USED(conf); + rc = usecase_l3fwd_configure(conf, nb_conf, nb_graphs); break; } } diff --git a/app/graph/l3fwd.c b/app/graph/l3fwd.c new file mode 100644 index 0000000000..a2648df27d --- /dev/null +++ b/app/graph/l3fwd.c @@ -0,0 +1,136 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2023 Marvell. + */ + +#include <errno.h> +#include <stdbool.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <rte_common.h> +#include <rte_ethdev.h> +#include <rte_graph.h> +#include <rte_graph_worker.h> +#include <rte_lcore.h> +#include <rte_node_eth_api.h> + +#include "module_api.h" + +static int +l3fwd_pattern_configure(void) +{ + /* Graph initialization. 8< */ + static const char * const default_patterns[] = { + "ip4*", + "ethdev_tx-*", + "pkt_drop", + }; + struct rte_graph_param graph_conf; + const char **node_patterns; + uint64_t pcap_pkts_count; + struct lcore_conf *qconf; + uint16_t nb_patterns; + uint8_t pcap_ena; + int rc, lcore_id; + char *pcap_file; + + nb_patterns = RTE_DIM(default_patterns); + node_patterns = malloc((ETHDEV_RX_QUEUE_PER_LCORE_MAX + nb_patterns) * + sizeof(*node_patterns)); + if (!node_patterns) + return -ENOMEM; + memcpy(node_patterns, default_patterns, + nb_patterns * sizeof(*node_patterns)); + + memset(&graph_conf, 0, sizeof(graph_conf)); + graph_conf.node_patterns = node_patterns; + + /* Pcap config */ + graph_pcap_config_get(&pcap_ena, &pcap_pkts_count, &pcap_file); + graph_conf.pcap_enable = pcap_ena; + graph_conf.num_pkt_to_capture = pcap_pkts_count; + graph_conf.pcap_filename = strdup(pcap_file); + + for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) { + rte_graph_t graph_id; + rte_edge_t i; + + if (rte_lcore_is_enabled(lcore_id) == 0) + continue; + + qconf = &lcore_conf[lcore_id]; + + /* Skip graph creation if no source exists */ + if (!qconf->n_rx_queue) + continue; + + /* Add rx node patterns of this lcore */ + for (i = 0; i < qconf->n_rx_queue; i++) { + graph_conf.node_patterns[nb_patterns + i] = + qconf->rx_queue_list[i].node_name; + } + + graph_conf.nb_node_patterns = nb_patterns + i; + graph_conf.socket_id = rte_lcore_to_socket_id(lcore_id); + + snprintf(qconf->name, sizeof(qconf->name), "worker_%u", + lcore_id); + + graph_id = rte_graph_create(qconf->name, &graph_conf); + if (graph_id == RTE_GRAPH_ID_INVALID) + rte_exit(EXIT_FAILURE, + "rte_graph_create(): graph_id invalid" + " for lcore %u\n", lcore_id); + + qconf->graph_id = graph_id; + qconf->graph = rte_graph_lookup(qconf->name); + /* >8 End of graph initialization. */ + if (!qconf->graph) + rte_exit(EXIT_FAILURE, + "rte_graph_lookup(): graph %s not found\n", + qconf->name); + } + + rc = route_ip4_add_to_lookup(); + if (rc < 0) + rte_exit(EXIT_FAILURE, "Unable to add v4 route to lookup table\n"); + + rc = route_ip6_add_to_lookup(); + if (rc < 0) + rte_exit(EXIT_FAILURE, "Unable to add v6 route to lookup table\n"); + + rc = neigh_ip4_add_to_rewrite(); + if (rc < 0) + rte_exit(EXIT_FAILURE, "Unable to add v4 to rewrite node\n"); + + rc = neigh_ip6_add_to_rewrite(); + if (rc < 0) + rte_exit(EXIT_FAILURE, "Unable to add v6 to rewrite node\n"); + + /* Launch per-lcore init on every worker lcore */ + rte_eal_mp_remote_launch(graph_walk_start, NULL, SKIP_MAIN); + + /* Accumulate and print stats on main until exit */ + if (rte_graph_has_stats_feature() && app_graph_stats_enabled()) + graph_stats_print(); + + return rc; +} + +int +usecase_l3fwd_configure(struct rte_node_ethdev_config *conf, uint16_t nb_confs, uint16_t nb_graphs) +{ + int rc; + + rc = rte_node_eth_config(conf, nb_confs, nb_graphs); + if (rc) + rte_exit(EXIT_FAILURE, "rte_node_eth_config: err=%d\n", rc); + + rc = l3fwd_pattern_configure(); + if (rc) + rte_exit(EXIT_FAILURE, "l3fwd_pattern_failure: err=%d\n", rc); + + return rc; +} diff --git a/app/graph/l3fwd.h b/app/graph/l3fwd.h new file mode 100644 index 0000000000..e1d23165e6 --- /dev/null +++ b/app/graph/l3fwd.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2023 Marvell. + */ + +#ifndef APP_GRAPH_L3FWD_H +#define APP_GRAPH_L3FWD_H + +int usecase_l3fwd_configure(struct rte_node_ethdev_config *conf, uint16_t nb_conf, + uint16_t nb_graphs); + +#endif diff --git a/app/graph/meson.build b/app/graph/meson.build index 15d16a302e..5b0f966d99 100644 --- a/app/graph/meson.build +++ b/app/graph/meson.build @@ -17,6 +17,7 @@ sources = files( 'graph.c', 'ip4_route.c', 'ip6_route.c', + 'l3fwd.c', 'main.c', 'mempool.c', 'neigh.c', diff --git a/app/graph/module_api.h b/app/graph/module_api.h index a7d287f5c8..7193e0b616 100644 --- a/app/graph/module_api.h +++ b/app/graph/module_api.h @@ -13,6 +13,7 @@ #include "ethdev.h" #include "ethdev_rx.h" #include "graph.h" +#include "l3fwd.h" #include "mempool.h" #include "neigh.h" #include "route.h" diff --git a/doc/guides/tools/graph.rst b/doc/guides/tools/graph.rst index ed0fdfffe1..fc62e53ae1 100644 --- a/doc/guides/tools/graph.rst +++ b/doc/guides/tools/graph.rst @@ -12,6 +12,10 @@ Based on the input file, application creates a graph to cater the use case. Also this application framework can be used by other graph based applications. +Supported Use cases +------------------- + * l3fwd + Running the Application ----------------------- @@ -230,3 +234,10 @@ Created graph for use case On the successful execution of ``<usecase>.cli`` file, corresponding graph will be created. This section mentions the created graph for each use case. + +l3fwd +~~~~~ + +.. _figure_l3fwd_graph: + +.. figure:: img/graph-usecase-l3fwd.* diff --git a/doc/guides/tools/img/graph-usecase-l3fwd.svg b/doc/guides/tools/img/graph-usecase-l3fwd.svg new file mode 100644 index 0000000000..3b991c4cf0 --- /dev/null +++ b/doc/guides/tools/img/graph-usecase-l3fwd.svg @@ -0,0 +1,210 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Generated by graphviz version 2.43.0 (0) + --> +<!-- SPDX-License-Identifier: BSD-3-Clause --> +<!-- Copyright(C) 2023 Marvell. --> +<!-- + +Generated with following command +dot -Tsvg dot.dot -o doc/guides/tools/img/graph-usecase-l3fwd.svg + +cat dot.dot +digraph dpdk_app_graph_l3fwd_nodes_flow { + ingress_port [shape=rect] + ethdev_rx + pkt_cls + ip4_lookup + ip6_lookup + ip4_rewrite + ip6_rewrite + ethdev_tx + pkt_drop + egress_port [shape=rect] + + ingress_port -> ethdev_rx [label="ingress packet"] + + ethdev_rx -> pkt_cls + + pkt_cls -> ip4_lookup [color="green"] + pkt_cls -> ip6_lookup [color="blue"] + pkt_cls -> pkt_drop [color="red" style="dashed"] + + ip4_lookup -> ip4_rewrite [color="green"] + ip4_lookup -> pkt_drop [color="red" style="dashed"] + + ip6_lookup -> ip6_rewrite [color="blue"] + ip6_lookup -> pkt_drop [color="red" style="dashed"] + + ip4_rewrite -> ethdev_tx [color="green"] + ip4_rewrite -> pkt_drop [color="red" style="dashed"] + + ip6_rewrite -> ethdev_tx [color="blue"] + ip6_rewrite -> pkt_drop [color="red" style="dashed"] + + ethdev_tx -> egress_port [label="egress packet"] + ethdev_tx -> pkt_drop [color="red" style="dashed"] +} + + --> +<!-- Title: dpdk_app_graph_l3fwd_nodes_flow Pages: 1 --> +<svg width="550pt" height="510pt" + viewBox="0.00 0.00 549.50 510.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> +<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 506)"> +<title>dpdk_app_graph_l3fwd_nodes_flow</title> +<polygon fill="white" stroke="transparent" points="-4,4 -4,-506 545.5,-506 545.5,4 -4,4"/> +<!-- ingress_port --> +<g id="node1" class="node"> +<title>ingress_port</title> +<polygon fill="none" stroke="black" points="489.5,-502 383.5,-502 383.5,-466 489.5,-466 489.5,-502"/> +<text text-anchor="middle" x="436.5" y="-480.3" font-family="Times,serif" font-size="14.00">ingress_port</text> +</g> +<!-- ethdev_rx --> +<g id="node2" class="node"> +<title>ethdev_rx</title> +<ellipse fill="none" stroke="black" cx="436.5" cy="-397" rx="56.59" ry="18"/> +<text text-anchor="middle" x="436.5" y="-393.3" font-family="Times,serif" font-size="14.00">ethdev_rx</text> +</g> +<!-- ingress_port->ethdev_rx --> +<g id="edge1" class="edge"> +<title>ingress_port->ethdev_rx</title> +<path fill="none" stroke="black" d="M436.5,-465.8C436.5,-454.16 436.5,-438.55 436.5,-425.24"/> +<polygon fill="black" stroke="black" points="440,-425.18 436.5,-415.18 433,-425.18 440,-425.18"/> +<text text-anchor="middle" x="489" y="-436.8" font-family="Times,serif" font-size="14.00">ingress packet</text> +</g> +<!-- pkt_cls --> +<g id="node3" class="node"> +<title>pkt_cls</title> +<ellipse fill="none" stroke="black" cx="436.5" cy="-324" rx="42.79" ry="18"/> +<text text-anchor="middle" x="436.5" y="-320.3" font-family="Times,serif" font-size="14.00">pkt_cls</text> +</g> +<!-- ethdev_rx->pkt_cls --> +<g id="edge2" class="edge"> +<title>ethdev_rx->pkt_cls</title> +<path fill="none" stroke="black" d="M436.5,-378.81C436.5,-370.79 436.5,-361.05 436.5,-352.07"/> +<polygon fill="black" stroke="black" points="440,-352.03 436.5,-342.03 433,-352.03 440,-352.03"/> +</g> +<!-- ip4_lookup --> +<g id="node4" class="node"> +<title>ip4_lookup</title> +<ellipse fill="none" stroke="black" cx="436.5" cy="-251" rx="60.39" ry="18"/> +<text text-anchor="middle" x="436.5" y="-247.3" font-family="Times,serif" font-size="14.00">ip4_lookup</text> +</g> +<!-- pkt_cls->ip4_lookup --> +<g id="edge3" class="edge"> +<title>pkt_cls->ip4_lookup</title> +<path fill="none" stroke="green" d="M436.5,-305.81C436.5,-297.79 436.5,-288.05 436.5,-279.07"/> +<polygon fill="green" stroke="green" points="440,-279.03 436.5,-269.03 433,-279.03 440,-279.03"/> +</g> +<!-- ip6_lookup --> +<g id="node5" class="node"> +<title>ip6_lookup</title> +<ellipse fill="none" stroke="black" cx="297.5" cy="-251" rx="60.39" ry="18"/> +<text text-anchor="middle" x="297.5" y="-247.3" font-family="Times,serif" font-size="14.00">ip6_lookup</text> +</g> +<!-- pkt_cls->ip6_lookup --> +<g id="edge4" class="edge"> +<title>pkt_cls->ip6_lookup</title> +<path fill="none" stroke="blue" d="M410.36,-309.65C389.39,-298.94 359.66,-283.75 335.97,-271.65"/> +<polygon fill="blue" stroke="blue" points="337.39,-268.45 326.9,-267.02 334.21,-274.68 337.39,-268.45"/> +</g> +<!-- pkt_drop --> +<g id="node9" class="node"> +<title>pkt_drop</title> +<ellipse fill="none" stroke="black" cx="361.5" cy="-18" rx="51.99" ry="18"/> +<text text-anchor="middle" x="361.5" y="-14.3" font-family="Times,serif" font-size="14.00">pkt_drop</text> +</g> +<!-- pkt_cls->pkt_drop --> +<g id="edge5" class="edge"> +<title>pkt_cls->pkt_drop</title> +<path fill="none" stroke="red" stroke-dasharray="5,2" d="M468.77,-311.93C493.88,-301.02 524.5,-281.64 524.5,-252 524.5,-252 524.5,-252 524.5,-104 524.5,-55.68 467.5,-34.79 420.91,-25.78"/> +<polygon fill="red" stroke="red" points="421.31,-22.29 410.85,-23.98 420.08,-29.18 421.31,-22.29"/> +</g> +<!-- ip4_rewrite --> +<g id="node6" class="node"> +<title>ip4_rewrite</title> +<ellipse fill="none" stroke="black" cx="394.5" cy="-178" rx="63.89" ry="18"/> +<text text-anchor="middle" x="394.5" y="-174.3" font-family="Times,serif" font-size="14.00">ip4_rewrite</text> +</g> +<!-- ip4_lookup->ip4_rewrite --> +<g id="edge6" class="edge"> +<title>ip4_lookup->ip4_rewrite</title> +<path fill="none" stroke="green" d="M426.55,-233.17C421.55,-224.72 415.38,-214.29 409.79,-204.85"/> +<polygon fill="green" stroke="green" points="412.78,-203.02 404.67,-196.2 406.75,-206.59 412.78,-203.02"/> +</g> +<!-- ip4_lookup->pkt_drop --> +<g id="edge7" class="edge"> +<title>ip4_lookup->pkt_drop</title> +<path fill="none" stroke="red" stroke-dasharray="5,2" d="M449.33,-233.03C456.19,-222.87 463.94,-209.37 467.5,-196 471.62,-180.54 472.57,-175.18 467.5,-160 451.61,-112.41 412.64,-67.99 386.65,-42.17"/> +<polygon fill="red" stroke="red" points="388.97,-39.54 379.36,-35.08 384.09,-44.56 388.97,-39.54"/> +</g> +<!-- ip6_rewrite --> +<g id="node7" class="node"> +<title>ip6_rewrite</title> +<ellipse fill="none" stroke="black" cx="210.5" cy="-178" rx="63.89" ry="18"/> +<text text-anchor="middle" x="210.5" y="-174.3" font-family="Times,serif" font-size="14.00">ip6_rewrite</text> +</g> +<!-- ip6_lookup->ip6_rewrite --> +<g id="edge8" class="edge"> +<title>ip6_lookup->ip6_rewrite</title> +<path fill="none" stroke="blue" d="M277.76,-233.89C266.16,-224.42 251.31,-212.31 238.52,-201.87"/> +<polygon fill="blue" stroke="blue" points="240.43,-198.9 230.46,-195.29 236,-204.33 240.43,-198.9"/> +</g> +<!-- ip6_lookup->pkt_drop --> +<g id="edge9" class="edge"> +<title>ip6_lookup->pkt_drop</title> +<path fill="none" stroke="red" stroke-dasharray="5,2" d="M302.02,-232.72C306.79,-214.59 314.55,-185.26 321.5,-160 332.39,-120.41 345.45,-74.7 353.61,-46.32"/> +<polygon fill="red" stroke="red" points="357.08,-46.92 356.49,-36.34 350.35,-44.98 357.08,-46.92"/> +</g> +<!-- ethdev_tx --> +<g id="node8" class="node"> +<title>ethdev_tx</title> +<ellipse fill="none" stroke="black" cx="249.5" cy="-105" rx="55.79" ry="18"/> +<text text-anchor="middle" x="249.5" y="-101.3" font-family="Times,serif" font-size="14.00">ethdev_tx</text> +</g> +<!-- ip4_rewrite->ethdev_tx --> +<g id="edge10" class="edge"> +<title>ip4_rewrite->ethdev_tx</title> +<path fill="none" stroke="green" d="M364.1,-162.12C341.96,-151.27 311.81,-136.51 287.98,-124.84"/> +<polygon fill="green" stroke="green" points="289.39,-121.63 278.87,-120.38 286.31,-127.92 289.39,-121.63"/> +</g> +<!-- ip4_rewrite->pkt_drop --> +<g id="edge11" class="edge"> +<title>ip4_rewrite->pkt_drop</title> +<path fill="none" stroke="red" stroke-dasharray="5,2" d="M390.91,-159.79C385.2,-132.48 374.03,-78.99 367.22,-46.38"/> +<polygon fill="red" stroke="red" points="370.56,-45.26 365.09,-36.19 363.71,-46.69 370.56,-45.26"/> +</g> +<!-- ip6_rewrite->ethdev_tx --> +<g id="edge12" class="edge"> +<title>ip6_rewrite->ethdev_tx</title> +<path fill="none" stroke="blue" d="M219.74,-160.17C224.34,-151.81 230,-141.51 235.14,-132.14"/> +<polygon fill="blue" stroke="blue" points="238.31,-133.65 240.05,-123.2 232.17,-130.28 238.31,-133.65"/> +</g> +<!-- ip6_rewrite->pkt_drop --> +<g id="edge13" class="edge"> +<title>ip6_rewrite->pkt_drop</title> +<path fill="none" stroke="red" stroke-dasharray="5,2" d="M197.68,-160.05C184.87,-140.87 169.12,-109.39 184.5,-87 210.62,-48.98 261.18,-32.21 301.59,-24.82"/> +<polygon fill="red" stroke="red" points="302.35,-28.24 311.63,-23.13 301.19,-21.33 302.35,-28.24"/> +</g> +<!-- ethdev_tx->pkt_drop --> +<g id="edge15" class="edge"> +<title>ethdev_tx->pkt_drop</title> +<path fill="none" stroke="red" stroke-dasharray="5,2" d="M270.3,-88.21C287.91,-74.85 313.31,-55.57 332.84,-40.75"/> +<polygon fill="red" stroke="red" points="334.96,-43.54 340.81,-34.7 330.73,-37.96 334.96,-43.54"/> +</g> +<!-- egress_port --> +<g id="node10" class="node"> +<title>egress_port</title> +<polygon fill="none" stroke="black" points="101,-36 0,-36 0,0 101,0 101,-36"/> +<text text-anchor="middle" x="50.5" y="-14.3" font-family="Times,serif" font-size="14.00">egress_port</text> +</g> +<!-- ethdev_tx->egress_port --> +<g id="edge14" class="edge"> +<title>ethdev_tx->egress_port</title> +<path fill="none" stroke="black" d="M217.08,-90.15C185.34,-76.59 136.54,-55.75 99.95,-40.12"/> +<polygon fill="black" stroke="black" points="101.03,-36.78 90.45,-36.07 98.28,-43.21 101.03,-36.78"/> +<text text-anchor="middle" x="211.5" y="-57.8" font-family="Times,serif" font-size="14.00">egress packet</text> +</g> +</g> +</svg> -- 2.25.1