DPDK patches and discussions
 help / color / mirror / Atom feed
* [PATCH 1/2] node: add IPv4 local node to handle local pkts
@ 2023-07-03  9:13 Rakesh Kudurumalla
  2023-07-03  9:13 ` [PATCH 2/2] node: add UDP v4 support Rakesh Kudurumalla
  2023-07-03 10:05 ` [PATCH v2 1/2] node: add IPv4 local node to handle local pkts Rakesh Kudurumalla
  0 siblings, 2 replies; 16+ messages in thread
From: Rakesh Kudurumalla @ 2023-07-03  9:13 UTC (permalink / raw)
  To: Jerin Jacob, Kiran Kumar K, Nithin Dabilpuram, Zhirun Yan,
	Pavan Nikhilesh
  Cc: dev, Rakesh Kudurumalla

Local or Host destined pkts can be redirected IPv4 local node
using IP4 Lookup node entries with prefix of 32 and be redirected
to this IP4 local node for further processing.

Signed-off-by: Rakesh Kudurumalla <rkudurumalla@marvell.com>
---
Depends-on: series-28622 ("add inbuilt graph nodes data flow")

 doc/guides/prog_guide/graph_lib.rst           |  15 ++
 .../img/graph_inbuilt_node_flow.svg           | 138 ++++++++++--------
 lib/node/ip4_local.c                          |  88 +++++++++++
 lib/node/ip4_lookup.c                         |   1 +
 lib/node/meson.build                          |   1 +
 lib/node/rte_node_ip4_api.h                   |  12 ++
 6 files changed, 196 insertions(+), 59 deletions(-)
 create mode 100644 lib/node/ip4_local.c

diff --git a/doc/guides/prog_guide/graph_lib.rst b/doc/guides/prog_guide/graph_lib.rst
index 96af29e8da..eaa8ee337e 100644
--- a/doc/guides/prog_guide/graph_lib.rst
+++ b/doc/guides/prog_guide/graph_lib.rst
@@ -498,3 +498,18 @@ Uses ``poll`` function to poll on the socket fd
 for ``POLLIN`` events to read the packets from raw socket
 to stream buffer and does ``rte_node_next_stream_move()``
 when there are received packets.
+
+ip4_local
+~~~~~~~~~
+This node is an intermediate node that does ``packet_type`` lookup for
+the received ipv4 packets and the result determines each packets next node.
+
+On successful ``packet_type`` lookup, for any IPv4 protocol the result
+contains the ``next_node`` id and ``next-hop`` id with which the packet
+needs to be further processed.
+
+On packet_type lookup failure, objects are redirected to ``pkt_drop`` node.
+``rte_node_ip4_route_add()`` is control path API to add ipv4 address with 32 bit
+depth to receive to packets.
+To achieve home run, node use ``rte_node_stream_move()`` as mentioned in above
+sections.
diff --git a/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg b/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg
index 02fe768dfe..7a3ace48dc 100644
--- a/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg
+++ b/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg
@@ -37,174 +37,194 @@ digraph dpdk_inbuilt_nodes_flow {
     ethdev_tx -> pkt_drop [color="cyan" style="dashed"]
     pkt_cls->pkt_drop   [color="cyan" style="dashed"]
     kernel_tx -> kernel_rx [color="red" style="dashed"]
+    ip4_lookup -> ip4_local
+    ip4_local -> pkt_drop [color="cyan" style="dashed"]
 }
 
  -->
 <!-- input nodes -->
 <!-- Title: dpdk_inbuilt_nodes_flow Pages: 1 -->
-<svg width="470pt" height="425pt"
- viewBox="0.00 0.00 470.23 424.50" 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 420.5)">
+<svg width="525pt" height="458pt"
+ viewBox="0.00 0.00 524.91 458.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 454)">
 <title>dpdk_inbuilt_nodes_flow</title>
-<polygon fill="white" stroke="none" points="-4,4 -4,-420.5 466.23,-420.5 466.23,4 -4,4"/>
+<polygon fill="white" stroke="transparent" points="-4,4 -4,-454 520.91,-454 520.91,4 -4,4"/>
 <!-- ethdev_rx -->
 <g id="node1" class="node">
 <title>ethdev_rx</title>
-<ellipse fill="none" stroke="green" cx="219.23" cy="-398.5" rx="47.77" ry="18"/>
-<text text-anchor="middle" x="219.23" y="-393.45" font-family="Times,serif" font-size="14.00">ethdev_rx</text>
+<ellipse fill="none" stroke="green" cx="120" cy="-432" rx="56.59" ry="18"/>
+<text text-anchor="middle" x="120" y="-428.3" font-family="Times,serif" font-size="14.00">ethdev_rx</text>
 </g>
 <!-- pkt_cls -->
 <g id="node6" class="node">
 <title>pkt_cls</title>
-<ellipse fill="none" stroke="red" cx="219.23" cy="-325.5" rx="37.53" ry="18"/>
-<text text-anchor="middle" x="219.23" y="-320.45" font-family="Times,serif" font-size="14.00">pkt_cls</text>
+<ellipse fill="none" stroke="red" cx="120" cy="-359" rx="42.79" ry="18"/>
+<text text-anchor="middle" x="120" y="-355.3" font-family="Times,serif" font-size="14.00">pkt_cls</text>
 </g>
 <!-- ethdev_rx&#45;&gt;pkt_cls -->
 <g id="edge1" class="edge">
 <title>ethdev_rx&#45;&gt;pkt_cls</title>
-<path fill="none" stroke="black" d="M219.23,-380.31C219.23,-372.55 219.23,-363.18 219.23,-354.45"/>
-<polygon fill="black" stroke="black" points="222.73,-354.53 219.23,-344.53 215.73,-354.53 222.73,-354.53"/>
+<path fill="none" stroke="black" d="M120,-413.81C120,-405.79 120,-396.05 120,-387.07"/>
+<polygon fill="black" stroke="black" points="123.5,-387.03 120,-377.03 116.5,-387.03 123.5,-387.03"/>
 </g>
 <!-- kernel_rx -->
 <g id="node2" class="node">
 <title>kernel_rx</title>
-<ellipse fill="none" stroke="green" cx="46.23" cy="-164" rx="46.23" ry="18"/>
-<text text-anchor="middle" x="46.23" y="-158.95" font-family="Times,serif" font-size="14.00">kernel_rx</text>
+<ellipse fill="none" stroke="green" cx="82" cy="-199" rx="53.89" ry="18"/>
+<text text-anchor="middle" x="82" y="-195.3" font-family="Times,serif" font-size="14.00">kernel_rx</text>
 </g>
 <!-- kernel_rx&#45;&gt;pkt_cls -->
 <g id="edge2" class="edge">
 <title>kernel_rx&#45;&gt;pkt_cls</title>
-<path fill="none" stroke="black" d="M41.45,-182.08C37.1,-201.37 33.27,-232.96 47.23,-255 73.68,-296.74 130.21,-313.41 171.26,-320.07"/>
-<polygon fill="black" stroke="black" points="170.73,-323.68 181.13,-321.66 171.74,-316.75 170.73,-323.68"/>
+<path fill="none" stroke="black" d="M70.87,-216.92C60.28,-235.27 47.29,-265.24 57,-290 64.12,-308.16 78.62,-324.37 91.92,-336.4"/>
+<polygon fill="black" stroke="black" points="89.69,-339.1 99.54,-342.99 94.26,-333.8 89.69,-339.1"/>
 </g>
 <!-- ethdev_tx -->
 <g id="node3" class="node">
 <title>ethdev_tx</title>
-<ellipse fill="none" stroke="magenta" cx="293.23" cy="-91" rx="47.26" ry="18"/>
-<text text-anchor="middle" x="293.23" y="-85.95" font-family="Times,serif" font-size="14.00">ethdev_tx</text>
+<ellipse fill="none" stroke="magenta" cx="338" cy="-91" rx="55.79" ry="18"/>
+<text text-anchor="middle" x="338" y="-87.3" font-family="Times,serif" font-size="14.00">ethdev_tx</text>
 </g>
 <!-- pkt_drop -->
 <g id="node4" class="node">
 <title>pkt_drop</title>
-<ellipse fill="none" stroke="cyan" cx="349.23" cy="-18" rx="44.19" ry="18"/>
-<text text-anchor="middle" x="349.23" y="-12.95" font-family="Times,serif" font-size="14.00">pkt_drop</text>
+<ellipse fill="none" stroke="cyan" cx="254" cy="-18" rx="51.99" ry="18"/>
+<text text-anchor="middle" x="254" y="-14.3" font-family="Times,serif" font-size="14.00">pkt_drop</text>
 </g>
 <!-- ethdev_tx&#45;&gt;pkt_drop -->
 <g id="edge14" class="edge">
 <title>ethdev_tx&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M306.22,-73.53C313.15,-64.75 321.81,-53.76 329.55,-43.96"/>
-<polygon fill="cyan" stroke="cyan" points="332.87,-46.4 336.32,-36.38 327.37,-42.06 332.87,-46.4"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M318.94,-73.89C307.58,-64.29 293,-51.96 280.53,-41.42"/>
+<polygon fill="cyan" stroke="cyan" points="282.59,-38.58 272.7,-34.8 278.07,-43.93 282.59,-38.58"/>
 </g>
 <!-- kernel_tx -->
 <g id="node5" class="node">
 <title>kernel_tx</title>
-<ellipse fill="none" stroke="blue" cx="102.23" cy="-237" rx="45.72" ry="18"/>
-<text text-anchor="middle" x="102.23" y="-231.95" font-family="Times,serif" font-size="14.00">kernel_tx</text>
+<ellipse fill="none" stroke="blue" cx="120" cy="-272" rx="53.89" ry="18"/>
+<text text-anchor="middle" x="120" y="-268.3" font-family="Times,serif" font-size="14.00">kernel_tx</text>
 </g>
 <!-- kernel_tx&#45;&gt;kernel_rx -->
 <g id="edge16" class="edge">
 <title>kernel_tx&#45;&gt;kernel_rx</title>
-<path fill="none" stroke="red" stroke-dasharray="5,2" d="M89.25,-219.53C82.32,-210.75 73.65,-199.76 65.92,-189.96"/>
-<polygon fill="red" stroke="red" points="68.09,-188.06 59.15,-182.38 62.6,-192.4 68.09,-188.06"/>
+<path fill="none" stroke="red" stroke-dasharray="5,2" d="M110.99,-254.17C106.52,-245.81 101,-235.51 95.99,-226.14"/>
+<polygon fill="red" stroke="red" points="99.01,-224.36 91.2,-217.2 92.84,-227.67 99.01,-224.36"/>
 </g>
 <!-- pkt_cls&#45;&gt;pkt_drop -->
 <g id="edge15" class="edge">
 <title>pkt_cls&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M255.09,-319.38C322.68,-308.72 462.23,-281.44 462.23,-238 462.23,-238 462.23,-238 462.23,-90 462.23,-57.84 429.01,-39.68 398.59,-29.8"/>
-<polygon fill="cyan" stroke="cyan" points="400.02,-26.27 389.44,-26.75 398.01,-32.98 400.02,-26.27"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M84,-348.97C48.65,-337.7 0,-314.61 0,-273 0,-273 0,-273 0,-90 0,-49.99 118.4,-31.52 193.52,-23.82"/>
+<polygon fill="cyan" stroke="cyan" points="194.21,-27.27 203.82,-22.81 193.52,-20.31 194.21,-27.27"/>
 </g>
 <!-- pkt_cls&#45;&gt;kernel_tx -->
 <g id="edge5" class="edge">
 <title>pkt_cls&#45;&gt;kernel_tx</title>
-<path fill="none" stroke="blue" d="M186.99,-315.75C170.62,-310.16 151.14,-301.64 136.48,-289.5 128.23,-282.66 121.2,-273.31 115.7,-264.46"/>
-<polygon fill="blue" stroke="blue" points="118.38,-263.1 110.34,-256.2 112.32,-266.61 118.38,-263.1"/>
-<text text-anchor="middle" x="176.61" y="-276.2" font-family="Times,serif" font-size="14.00">exception pkts</text>
+<path fill="none" stroke="blue" d="M120,-340.8C120,-329.16 120,-313.55 120,-300.24"/>
+<polygon fill="blue" stroke="blue" points="123.5,-300.18 120,-290.18 116.5,-300.18 123.5,-300.18"/>
+<text text-anchor="middle" x="172.5" y="-311.8" font-family="Times,serif" font-size="14.00">exception pkts</text>
 </g>
 <!-- ip4_lookup -->
 <g id="node7" class="node">
 <title>ip4_lookup</title>
-<ellipse fill="none" stroke="black" cx="219.23" cy="-237" rx="52.89" ry="18"/>
-<text text-anchor="middle" x="219.23" y="-231.95" font-family="Times,serif" font-size="14.00">ip4_lookup</text>
+<ellipse fill="none" stroke="black" cx="252" cy="-272" rx="60.39" ry="18"/>
+<text text-anchor="middle" x="252" y="-268.3" font-family="Times,serif" font-size="14.00">ip4_lookup</text>
 </g>
 <!-- pkt_cls&#45;&gt;ip4_lookup -->
 <g id="edge3" class="edge">
 <title>pkt_cls&#45;&gt;ip4_lookup</title>
-<path fill="none" stroke="black" d="M219.23,-307.41C219.23,-295.64 219.23,-279.73 219.23,-266.11"/>
-<polygon fill="black" stroke="black" points="222.73,-266.35 219.23,-256.35 215.73,-266.35 222.73,-266.35"/>
-<text text-anchor="middle" x="231.23" y="-276.2" font-family="Times,serif" font-size="14.00">ipv4</text>
+<path fill="none" stroke="black" d="M160.54,-352.79C182.64,-348.15 209.23,-339.41 228,-323 235.09,-316.81 240.26,-308.05 243.95,-299.6"/>
+<polygon fill="black" stroke="black" points="247.32,-300.57 247.62,-289.98 240.78,-298.07 247.32,-300.57"/>
+<text text-anchor="middle" x="254.5" y="-311.8" font-family="Times,serif" font-size="14.00">ipv4</text>
 </g>
 <!-- ip6_lookup -->
 <g id="node8" class="node">
 <title>ip6_lookup</title>
-<ellipse fill="none" stroke="black" cx="343.23" cy="-237" rx="52.89" ry="18"/>
-<text text-anchor="middle" x="343.23" y="-231.95" font-family="Times,serif" font-size="14.00">ip6_lookup</text>
+<ellipse fill="none" stroke="black" cx="439" cy="-272" rx="60.39" ry="18"/>
+<text text-anchor="middle" x="439" y="-268.3" font-family="Times,serif" font-size="14.00">ip6_lookup</text>
 </g>
 <!-- pkt_cls&#45;&gt;ip6_lookup -->
 <g id="edge4" class="edge">
 <title>pkt_cls&#45;&gt;ip6_lookup</title>
-<path fill="none" stroke="black" d="M239.99,-310.02C259.62,-296.33 289.35,-275.59 311.88,-259.87"/>
-<polygon fill="black" stroke="black" points="313.53,-262.29 319.73,-253.7 309.53,-256.55 313.53,-262.29"/>
-<text text-anchor="middle" x="304.23" y="-276.2" font-family="Times,serif" font-size="14.00">ipv6</text>
+<path fill="none" stroke="black" d="M157.52,-350.25C188.82,-343.6 234.51,-333.46 274,-323 313.2,-312.62 357.13,-299.22 389.79,-288.91"/>
+<polygon fill="black" stroke="black" points="391.08,-292.17 399.55,-285.81 388.96,-285.5 391.08,-292.17"/>
+<text text-anchor="middle" x="339.5" y="-311.8" font-family="Times,serif" font-size="14.00">ipv6</text>
 </g>
 <!-- ip4_lookup&#45;&gt;pkt_drop -->
 <g id="edge7" class="edge">
 <title>ip4_lookup&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M192.86,-221.12C179.2,-211.83 163.82,-198.49 156.23,-182 149.55,-167.46 150.78,-161.04 156.23,-146 176.39,-90.45 198.32,-78.19 252.23,-54 269.14,-46.41 288.24,-39.24 304.98,-33.38"/>
-<polygon fill="cyan" stroke="cyan" points="305.75,-36.48 314.07,-29.92 303.47,-29.86 305.75,-36.48"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M239.17,-254.03C232.31,-243.87 224.56,-230.37 221,-217 204.89,-156.57 227.58,-83.56 242.59,-45.31"/>
+<polygon fill="cyan" stroke="cyan" points="245.89,-46.5 246.4,-35.92 239.4,-43.87 245.89,-46.5"/>
 </g>
 <!-- ip4_rewrite -->
 <g id="node9" class="node">
 <title>ip4_rewrite</title>
-<ellipse fill="none" stroke="black" cx="218.23" cy="-164" rx="53.4" ry="18"/>
-<text text-anchor="middle" x="218.23" y="-158.95" font-family="Times,serif" font-size="14.00">ip4_rewrite</text>
+<ellipse fill="none" stroke="black" cx="294" cy="-199" rx="63.89" ry="18"/>
+<text text-anchor="middle" x="294" y="-195.3" font-family="Times,serif" font-size="14.00">ip4_rewrite</text>
 </g>
 <!-- ip4_lookup&#45;&gt;ip4_rewrite -->
 <g id="edge6" class="edge">
 <title>ip4_lookup&#45;&gt;ip4_rewrite</title>
-<path fill="none" stroke="black" d="M218.99,-218.81C218.88,-211.05 218.75,-201.68 218.63,-192.95"/>
-<polygon fill="black" stroke="black" points="222.11,-192.98 218.47,-183.03 215.11,-193.08 222.11,-192.98"/>
+<path fill="none" stroke="black" d="M261.95,-254.17C266.95,-245.72 273.12,-235.29 278.71,-225.85"/>
+<polygon fill="black" stroke="black" points="281.75,-227.59 283.83,-217.2 275.72,-224.02 281.75,-227.59"/>
+</g>
+<!-- ip4_local -->
+<g id="node11" class="node">
+<title>ip4_local</title>
+<ellipse fill="none" stroke="black" cx="136" cy="-145" rx="51.19" ry="18"/>
+<text text-anchor="middle" x="136" y="-141.3" font-family="Times,serif" font-size="14.00">ip4_local</text>
+</g>
+<!-- ip4_lookup&#45;&gt;ip4_local -->
+<g id="edge17" class="edge">
+<title>ip4_lookup&#45;&gt;ip4_local</title>
+<path fill="none" stroke="black" d="M218.11,-256.86C207.64,-251.39 196.61,-244.41 188,-236 169.45,-217.88 155.34,-191.74 146.53,-172.29"/>
+<polygon fill="black" stroke="black" points="149.72,-170.86 142.52,-163.08 143.3,-173.65 149.72,-170.86"/>
 </g>
 <!-- ip6_lookup&#45;&gt;pkt_drop -->
 <g id="edge11" class="edge">
 <title>ip6_lookup&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M369.2,-221.03C382.65,-211.71 397.78,-198.37 405.23,-182 426.87,-134.45 392.95,-75.95 369.19,-43.54"/>
-<polygon fill="cyan" stroke="cyan" points="371.64,-41.98 362.81,-36.13 366.06,-46.21 371.64,-41.98"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M470.57,-256.44C486.08,-247.46 503.27,-234.31 512,-217 519.2,-202.71 517.24,-196.12 512,-181 486.88,-108.48 466,-83.15 395,-54 367.69,-42.79 335.88,-34.51 309.39,-28.83"/>
+<polygon fill="cyan" stroke="cyan" points="310.02,-25.39 299.52,-26.78 308.6,-32.24 310.02,-25.39"/>
 </g>
 <!-- ip6_rewrite -->
 <g id="node10" class="node">
 <title>ip6_rewrite</title>
-<ellipse fill="none" stroke="black" cx="343.23" cy="-164" rx="53.4" ry="18"/>
-<text text-anchor="middle" x="343.23" y="-158.95" font-family="Times,serif" font-size="14.00">ip6_rewrite</text>
+<ellipse fill="none" stroke="black" cx="439" cy="-199" rx="63.89" ry="18"/>
+<text text-anchor="middle" x="439" y="-195.3" font-family="Times,serif" font-size="14.00">ip6_rewrite</text>
 </g>
 <!-- ip6_lookup&#45;&gt;ip6_rewrite -->
 <g id="edge10" class="edge">
 <title>ip6_lookup&#45;&gt;ip6_rewrite</title>
-<path fill="none" stroke="black" d="M343.23,-218.81C343.23,-211.05 343.23,-201.68 343.23,-192.95"/>
-<polygon fill="black" stroke="black" points="346.73,-193.03 343.23,-183.03 339.73,-193.03 346.73,-193.03"/>
+<path fill="none" stroke="black" d="M439,-253.81C439,-245.79 439,-236.05 439,-227.07"/>
+<polygon fill="black" stroke="black" points="442.5,-227.03 439,-217.03 435.5,-227.03 442.5,-227.03"/>
 </g>
 <!-- ip4_rewrite&#45;&gt;ethdev_tx -->
 <g id="edge8" class="edge">
 <title>ip4_rewrite&#45;&gt;ethdev_tx</title>
-<path fill="none" stroke="green" d="M235.63,-146.53C245.35,-137.33 257.64,-125.7 268.36,-115.54"/>
-<polygon fill="green" stroke="green" points="270.34,-118.55 275.19,-109.13 265.52,-113.47 270.34,-118.55"/>
+<path fill="none" stroke="green" d="M301.07,-180.97C308.09,-164.05 318.96,-137.86 327.09,-118.28"/>
+<polygon fill="green" stroke="green" points="330.35,-119.57 330.95,-108.99 323.88,-116.88 330.35,-119.57"/>
 </g>
 <!-- ip4_rewrite&#45;&gt;pkt_drop -->
 <g id="edge9" class="edge">
 <title>ip4_rewrite&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M217.56,-145.54C217.71,-125.89 220.78,-93.99 237.23,-73 253.17,-52.67 278.68,-39.55 301.33,-31.33"/>
-<polygon fill="cyan" stroke="cyan" points="302.14,-34.42 310.5,-27.9 299.9,-27.79 302.14,-34.42"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M289.85,-180.97C285.53,-163.07 278.61,-134.1 273,-109 268.3,-87.99 263.29,-64.16 259.59,-46.3"/>
+<polygon fill="cyan" stroke="cyan" points="262.97,-45.37 257.52,-36.28 256.11,-46.78 262.97,-45.37"/>
 </g>
 <!-- ip6_rewrite&#45;&gt;ethdev_tx -->
 <g id="edge12" class="edge">
 <title>ip6_rewrite&#45;&gt;ethdev_tx</title>
-<path fill="none" stroke="green" d="M331.38,-146.17C325.34,-137.6 317.87,-126.99 311.15,-117.44"/>
-<polygon fill="green" stroke="green" points="313.62,-115.87 305,-109.71 307.89,-119.9 313.62,-115.87"/>
+<path fill="none" stroke="green" d="M423.22,-181.44C406.47,-163.86 379.84,-135.91 360.81,-115.94"/>
+<polygon fill="green" stroke="green" points="363.1,-113.27 353.67,-108.45 358.03,-118.1 363.1,-113.27"/>
 </g>
 <!-- ip6_rewrite&#45;&gt;pkt_drop -->
 <g id="edge13" class="edge">
 <title>ip6_rewrite&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M345.67,-145.53C347.02,-134.98 348.56,-121.24 349.23,-109 350.38,-88.27 350.34,-64.81 350.03,-47.04"/>
-<polygon fill="cyan" stroke="cyan" points="353.51,-47.19 349.8,-37.27 346.51,-47.34 353.51,-47.19"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M438.77,-180.67C437.49,-154.09 431.22,-103.19 403,-73 379.35,-47.7 342.93,-34.22 312.02,-27.06"/>
+<polygon fill="cyan" stroke="cyan" points="312.71,-23.63 302.2,-24.95 311.24,-30.47 312.71,-23.63"/>
+</g>
+<!-- ip4_local&#45;&gt;pkt_drop -->
+<g id="edge18" class="edge">
+<title>ip4_local&#45;&gt;pkt_drop</title>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M142.47,-126.87C150.6,-107.23 166.18,-75.04 188,-54 195,-47.25 203.56,-41.45 212.16,-36.63"/>
+<polygon fill="cyan" stroke="cyan" points="213.85,-39.7 221.08,-31.95 210.6,-33.5 213.85,-39.7"/>
 </g>
 </g>
 </svg>
diff --git a/lib/node/ip4_local.c b/lib/node/ip4_local.c
new file mode 100644
index 0000000000..fb31d0f970
--- /dev/null
+++ b/lib/node/ip4_local.c
@@ -0,0 +1,88 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2023 Marvell International Ltd.
+ */
+
+#include <arpa/inet.h>
+#include <sys/socket.h>
+
+#include <rte_ethdev.h>
+#include <rte_ether.h>
+#include <rte_graph.h>
+#include <rte_graph_worker.h>
+#include <rte_ip.h>
+#include <rte_lpm.h>
+#include <rte_hash.h>
+#include <rte_fbk_hash.h>
+#include <rte_jhash.h>
+#include <rte_hash_crc.h>
+
+
+#include "rte_node_ip4_api.h"
+
+#include "node_private.h"
+
+static uint16_t
+ip4_local_node_process_scalar(struct rte_graph *graph, struct rte_node *node,
+			      void **objs, uint16_t nb_objs)
+{
+	void **to_next, **from;
+	uint16_t last_spec = 0;
+	rte_edge_t next_index;
+	struct rte_mbuf *mbuf;
+	uint16_t held = 0;
+	uint32_t l4;
+	int i;
+
+	/* Speculative next */
+	next_index = RTE_NODE_IP4_LOCAL_NEXT_UDP4_INPUT;
+
+	from = objs;
+	to_next = rte_node_next_stream_get(graph, node, next_index, nb_objs);
+	for (i = 0; i < nb_objs; i++) {
+		uint16_t next;
+
+		mbuf = (struct rte_mbuf *)objs[i];
+		l4 = mbuf->packet_type & RTE_PTYPE_L4_MASK;
+
+		next = (l4 == RTE_PTYPE_L4_UDP)
+				? next_index
+				: RTE_NODE_IP4_LOCAL_NEXT_PKT_DROP;
+
+		if (unlikely(next_index != next)) {
+			/* Copy things successfully speculated till now */
+			rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
+			from += last_spec;
+			to_next += last_spec;
+			held += last_spec;
+			last_spec = 0;
+
+			rte_node_enqueue_x1(graph, node, next, from[0]);
+			from += 1;
+		} else {
+			last_spec += 1;
+		}
+	}
+	/* !!! Home run !!! */
+	if (likely(last_spec == nb_objs)) {
+		rte_node_next_stream_move(graph, node, next_index);
+		return nb_objs;
+	}
+	held += last_spec;
+	rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
+	rte_node_next_stream_put(graph, node, next_index, held);
+
+	return nb_objs;
+}
+
+static struct rte_node_register ip4_local_node = {
+	.process = ip4_local_node_process_scalar,
+	.name = "ip4_local",
+
+	.nb_edges = RTE_NODE_IP4_LOCAL_NEXT_PKT_DROP + 1,
+	.next_nodes = {
+		[RTE_NODE_IP4_LOCAL_NEXT_UDP4_INPUT] = "udp4_input",
+		[RTE_NODE_IP4_LOCAL_NEXT_PKT_DROP] = "pkt_drop",
+	},
+};
+
+RTE_NODE_REGISTER(ip4_local_node);
diff --git a/lib/node/ip4_lookup.c b/lib/node/ip4_lookup.c
index 8bce03d7db..d3fc48baf7 100644
--- a/lib/node/ip4_lookup.c
+++ b/lib/node/ip4_lookup.c
@@ -227,6 +227,7 @@ static struct rte_node_register ip4_lookup_node = {
 
 	.nb_edges = RTE_NODE_IP4_LOOKUP_NEXT_MAX,
 	.next_nodes = {
+		[RTE_NODE_IP4_LOOKUP_NEXT_IP4_LOCAL] = "ip4_local",
 		[RTE_NODE_IP4_LOOKUP_NEXT_REWRITE] = "ip4_rewrite",
 		[RTE_NODE_IP4_LOOKUP_NEXT_PKT_DROP] = "pkt_drop",
 	},
diff --git a/lib/node/meson.build b/lib/node/meson.build
index 2fa7c1c8f3..c0d5b09e2f 100644
--- a/lib/node/meson.build
+++ b/lib/node/meson.build
@@ -12,6 +12,7 @@ sources = files(
         'ethdev_rx.c',
         'ethdev_tx.c',
         'ip4_lookup.c',
+        'ip4_local.c',
         'ip4_rewrite.c',
         'ip6_lookup.c',
         'ip6_rewrite.c',
diff --git a/lib/node/rte_node_ip4_api.h b/lib/node/rte_node_ip4_api.h
index 3397da0ae8..405bdd3283 100644
--- a/lib/node/rte_node_ip4_api.h
+++ b/lib/node/rte_node_ip4_api.h
@@ -30,10 +30,22 @@ enum rte_node_ip4_lookup_next {
 	/**< Rewrite node. */
 	RTE_NODE_IP4_LOOKUP_NEXT_PKT_DROP,
 	/**< Packet drop node. */
+	RTE_NODE_IP4_LOOKUP_NEXT_IP4_LOCAL,
+	/** IP Local node. */
 	RTE_NODE_IP4_LOOKUP_NEXT_MAX,
 	/**< Number of next nodes of lookup node. */
 };
 
+/**
+ * IP4 Local next nodes.
+ */
+enum rte_node_ip4_local_next {
+	RTE_NODE_IP4_LOCAL_NEXT_UDP4_INPUT,
+	/**< ip4 Local node. */
+	RTE_NODE_IP4_LOCAL_NEXT_PKT_DROP,
+	/**< Packet drop node. */
+};
+
 /**
  * Add ipv4 route to lookup table.
  *
-- 
2.25.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 2/2] node: add UDP v4 support
  2023-07-03  9:13 [PATCH 1/2] node: add IPv4 local node to handle local pkts Rakesh Kudurumalla
@ 2023-07-03  9:13 ` Rakesh Kudurumalla
  2023-07-03 10:05 ` [PATCH v2 1/2] node: add IPv4 local node to handle local pkts Rakesh Kudurumalla
  1 sibling, 0 replies; 16+ messages in thread
From: Rakesh Kudurumalla @ 2023-07-03  9:13 UTC (permalink / raw)
  To: Jerin Jacob, Kiran Kumar K, Nithin Dabilpuram, Zhirun Yan,
	Pavan Nikhilesh
  Cc: dev, Rakesh Kudurumalla

IPv4 UDP packets are given to application
with specified UDP destination port given
by user.

Signed-off-by: Rakesh Kudurumalla <rkudurumalla@marvell.com>
---
 doc/api/doxy-api-index.md                     |   3 +-
 doc/guides/prog_guide/graph_lib.rst           |  25 ++
 .../img/graph_inbuilt_node_flow.svg           | 165 ++++++++-----
 lib/node/meson.build                          |   2 +
 lib/node/rte_node_udp4_input_api.h            |  60 +++++
 lib/node/udp4_input.c                         | 226 ++++++++++++++++++
 lib/node/version.map                          |   2 +
 7 files changed, 417 insertions(+), 66 deletions(-)
 create mode 100644 lib/node/rte_node_udp4_input_api.h
 create mode 100644 lib/node/udp4_input.c

diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index 3bc8778981..b81777b3fb 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -209,7 +209,8 @@ The public API headers are grouped by topics:
   * graph_nodes:
     [eth_node](@ref rte_node_eth_api.h),
     [ip4_node](@ref rte_node_ip4_api.h),
-    [ip6_node](@ref rte_node_ip6_api.h)
+    [ip6_node](@ref rte_node_ip6_api.h),
+    [udp4_input_node](@ref rte_node_udp4_input_api.h)
 
 - **basic**:
   [bitops](@ref rte_bitops.h),
diff --git a/doc/guides/prog_guide/graph_lib.rst b/doc/guides/prog_guide/graph_lib.rst
index eaa8ee337e..98473383f1 100644
--- a/doc/guides/prog_guide/graph_lib.rst
+++ b/doc/guides/prog_guide/graph_lib.rst
@@ -513,3 +513,28 @@ On packet_type lookup failure, objects are redirected to ``pkt_drop`` node.
 depth to receive to packets.
 To achieve home run, node use ``rte_node_stream_move()`` as mentioned in above
 sections.
+
+udp4_input
+~~~~~~~~~~
+This node is an intermediate node that does udp destination port lookup for
+the received ipv4 packets and the result determines each packets next node.
+
+User registers a new node ``udp4_input`` into graph library during initialization
+and attach user specified node as edege to this node using
+``rte_node_udp4_usr_node_add()``, and create empty hash table with destination
+port and node id as its feilds.
+
+After successful addition of user node as edege, edge id is returned to the user.
+
+User would register ``ip4_lookup`` table with specified ip address and 32 bit as mask
+for ip filtration using api ``rte_node_ip4_route_add()``.
+
+After graph is created user would update hash table with custom port with
+and previously obtained edge id using API ``rte_node_udp4_dst_port_add()``.
+
+When packet is received lpm look up is performed if ip is matched the packet
+is handed over to ip4_local node, then packet is verified for udp proto and
+on success packet is enqueued to ``udp4_input`` node.
+
+Hash lookup is performed in ``udp4_input`` node with registered destination port
+and destination port in UDP packet , on success packet is handed to ``udp_user_node``.
diff --git a/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg b/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg
index 7a3ace48dc..5db96adb01 100644
--- a/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg
+++ b/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg
@@ -39,192 +39,227 @@ digraph dpdk_inbuilt_nodes_flow {
     kernel_tx -> kernel_rx [color="red" style="dashed"]
     ip4_lookup -> ip4_local
     ip4_local -> pkt_drop [color="cyan" style="dashed"]
+    ip4_local -> udp4_input [ label="udpv4"]
+    udp4_input -> udp_user_node
+    udp4_input -> pkt_drop [color="cyan" style="dashed"]
+
 }
 
  -->
 <!-- input nodes -->
 <!-- Title: dpdk_inbuilt_nodes_flow Pages: 1 -->
-<svg width="525pt" height="458pt"
- viewBox="0.00 0.00 524.91 458.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 454)">
+<svg width="631pt" height="437pt"
+ viewBox="0.00 0.00 630.95 437.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 433)">
 <title>dpdk_inbuilt_nodes_flow</title>
-<polygon fill="white" stroke="transparent" points="-4,4 -4,-454 520.91,-454 520.91,4 -4,4"/>
+<polygon fill="white" stroke="transparent" points="-4,4 -4,-433 626.95,-433 626.95,4 -4,4"/>
 <!-- ethdev_rx -->
 <g id="node1" class="node">
 <title>ethdev_rx</title>
-<ellipse fill="none" stroke="green" cx="120" cy="-432" rx="56.59" ry="18"/>
-<text text-anchor="middle" x="120" y="-428.3" font-family="Times,serif" font-size="14.00">ethdev_rx</text>
+<ellipse fill="none" stroke="green" cx="261.95" cy="-411" rx="56.59" ry="18"/>
+<text text-anchor="middle" x="261.95" y="-407.3" font-family="Times,serif" font-size="14.00">ethdev_rx</text>
 </g>
 <!-- pkt_cls -->
 <g id="node6" class="node">
 <title>pkt_cls</title>
-<ellipse fill="none" stroke="red" cx="120" cy="-359" rx="42.79" ry="18"/>
-<text text-anchor="middle" x="120" y="-355.3" font-family="Times,serif" font-size="14.00">pkt_cls</text>
+<ellipse fill="none" stroke="red" cx="261.95" cy="-338" rx="42.79" ry="18"/>
+<text text-anchor="middle" x="261.95" y="-334.3" font-family="Times,serif" font-size="14.00">pkt_cls</text>
 </g>
 <!-- ethdev_rx&#45;&gt;pkt_cls -->
 <g id="edge1" class="edge">
 <title>ethdev_rx&#45;&gt;pkt_cls</title>
-<path fill="none" stroke="black" d="M120,-413.81C120,-405.79 120,-396.05 120,-387.07"/>
-<polygon fill="black" stroke="black" points="123.5,-387.03 120,-377.03 116.5,-387.03 123.5,-387.03"/>
+<path fill="none" stroke="black" d="M261.95,-392.81C261.95,-384.79 261.95,-375.05 261.95,-366.07"/>
+<polygon fill="black" stroke="black" points="265.45,-366.03 261.95,-356.03 258.45,-366.03 265.45,-366.03"/>
 </g>
 <!-- kernel_rx -->
 <g id="node2" class="node">
 <title>kernel_rx</title>
-<ellipse fill="none" stroke="green" cx="82" cy="-199" rx="53.89" ry="18"/>
-<text text-anchor="middle" x="82" y="-195.3" font-family="Times,serif" font-size="14.00">kernel_rx</text>
+<ellipse fill="none" stroke="green" cx="53.95" cy="-178" rx="53.89" ry="18"/>
+<text text-anchor="middle" x="53.95" y="-174.3" font-family="Times,serif" font-size="14.00">kernel_rx</text>
 </g>
 <!-- kernel_rx&#45;&gt;pkt_cls -->
 <g id="edge2" class="edge">
 <title>kernel_rx&#45;&gt;pkt_cls</title>
-<path fill="none" stroke="black" d="M70.87,-216.92C60.28,-235.27 47.29,-265.24 57,-290 64.12,-308.16 78.62,-324.37 91.92,-336.4"/>
-<polygon fill="black" stroke="black" points="89.69,-339.1 99.54,-342.99 94.26,-333.8 89.69,-339.1"/>
+<path fill="none" stroke="black" d="M74.75,-194.8C112.31,-223.33 191.45,-283.45 233.8,-315.62"/>
+<polygon fill="black" stroke="black" points="231.92,-318.59 242,-321.85 236.16,-313.01 231.92,-318.59"/>
 </g>
 <!-- ethdev_tx -->
 <g id="node3" class="node">
 <title>ethdev_tx</title>
-<ellipse fill="none" stroke="magenta" cx="338" cy="-91" rx="55.79" ry="18"/>
-<text text-anchor="middle" x="338" y="-87.3" font-family="Times,serif" font-size="14.00">ethdev_tx</text>
+<ellipse fill="none" stroke="magenta" cx="347.95" cy="-91" rx="55.79" ry="18"/>
+<text text-anchor="middle" x="347.95" y="-87.3" font-family="Times,serif" font-size="14.00">ethdev_tx</text>
 </g>
 <!-- pkt_drop -->
 <g id="node4" class="node">
 <title>pkt_drop</title>
-<ellipse fill="none" stroke="cyan" cx="254" cy="-18" rx="51.99" ry="18"/>
-<text text-anchor="middle" x="254" y="-14.3" font-family="Times,serif" font-size="14.00">pkt_drop</text>
+<ellipse fill="none" stroke="cyan" cx="404.95" cy="-18" rx="51.99" ry="18"/>
+<text text-anchor="middle" x="404.95" y="-14.3" font-family="Times,serif" font-size="14.00">pkt_drop</text>
 </g>
 <!-- ethdev_tx&#45;&gt;pkt_drop -->
 <g id="edge14" class="edge">
 <title>ethdev_tx&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M318.94,-73.89C307.58,-64.29 293,-51.96 280.53,-41.42"/>
-<polygon fill="cyan" stroke="cyan" points="282.59,-38.58 272.7,-34.8 278.07,-43.93 282.59,-38.58"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M361.45,-73.17C368.55,-64.33 377.39,-53.33 385.23,-43.55"/>
+<polygon fill="cyan" stroke="cyan" points="388,-45.69 391.53,-35.71 382.54,-41.31 388,-45.69"/>
 </g>
 <!-- kernel_tx -->
 <g id="node5" class="node">
 <title>kernel_tx</title>
-<ellipse fill="none" stroke="blue" cx="120" cy="-272" rx="53.89" ry="18"/>
-<text text-anchor="middle" x="120" y="-268.3" font-family="Times,serif" font-size="14.00">kernel_tx</text>
+<ellipse fill="none" stroke="blue" cx="53.95" cy="-251" rx="53.89" ry="18"/>
+<text text-anchor="middle" x="53.95" y="-247.3" font-family="Times,serif" font-size="14.00">kernel_tx</text>
 </g>
 <!-- kernel_tx&#45;&gt;kernel_rx -->
 <g id="edge16" class="edge">
 <title>kernel_tx&#45;&gt;kernel_rx</title>
-<path fill="none" stroke="red" stroke-dasharray="5,2" d="M110.99,-254.17C106.52,-245.81 101,-235.51 95.99,-226.14"/>
-<polygon fill="red" stroke="red" points="99.01,-224.36 91.2,-217.2 92.84,-227.67 99.01,-224.36"/>
+<path fill="none" stroke="red" stroke-dasharray="5,2" d="M53.95,-232.81C53.95,-224.79 53.95,-215.05 53.95,-206.07"/>
+<polygon fill="red" stroke="red" points="57.45,-206.03 53.95,-196.03 50.45,-206.03 57.45,-206.03"/>
 </g>
 <!-- pkt_cls&#45;&gt;pkt_drop -->
 <g id="edge15" class="edge">
 <title>pkt_cls&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M84,-348.97C48.65,-337.7 0,-314.61 0,-273 0,-273 0,-273 0,-90 0,-49.99 118.4,-31.52 193.52,-23.82"/>
-<polygon fill="cyan" stroke="cyan" points="194.21,-27.27 203.82,-22.81 193.52,-20.31 194.21,-27.27"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M304.77,-335.88C400.4,-332.2 622.95,-316.71 622.95,-252 622.95,-252 622.95,-252 622.95,-90 622.95,-56.33 527.72,-36.15 463.14,-26.34"/>
+<polygon fill="cyan" stroke="cyan" points="463.46,-22.85 453.06,-24.85 462.44,-29.77 463.46,-22.85"/>
 </g>
 <!-- pkt_cls&#45;&gt;kernel_tx -->
 <g id="edge5" class="edge">
 <title>pkt_cls&#45;&gt;kernel_tx</title>
-<path fill="none" stroke="blue" d="M120,-340.8C120,-329.16 120,-313.55 120,-300.24"/>
-<polygon fill="blue" stroke="blue" points="123.5,-300.18 120,-290.18 116.5,-300.18 123.5,-300.18"/>
-<text text-anchor="middle" x="172.5" y="-311.8" font-family="Times,serif" font-size="14.00">exception pkts</text>
+<path fill="none" stroke="blue" d="M219.14,-335.96C164.86,-333.64 75.77,-326.15 54.95,-302 49.6,-295.81 48.06,-287.4 48.24,-279.24"/>
+<polygon fill="blue" stroke="blue" points="51.73,-279.54 49.23,-269.24 44.76,-278.84 51.73,-279.54"/>
+<text text-anchor="middle" x="107.45" y="-290.8" font-family="Times,serif" font-size="14.00">exception pkts</text>
 </g>
 <!-- ip4_lookup -->
 <g id="node7" class="node">
 <title>ip4_lookup</title>
-<ellipse fill="none" stroke="black" cx="252" cy="-272" rx="60.39" ry="18"/>
-<text text-anchor="middle" x="252" y="-268.3" font-family="Times,serif" font-size="14.00">ip4_lookup</text>
+<ellipse fill="none" stroke="black" cx="261.95" cy="-251" rx="60.39" ry="18"/>
+<text text-anchor="middle" x="261.95" y="-247.3" font-family="Times,serif" font-size="14.00">ip4_lookup</text>
 </g>
 <!-- pkt_cls&#45;&gt;ip4_lookup -->
 <g id="edge3" class="edge">
 <title>pkt_cls&#45;&gt;ip4_lookup</title>
-<path fill="none" stroke="black" d="M160.54,-352.79C182.64,-348.15 209.23,-339.41 228,-323 235.09,-316.81 240.26,-308.05 243.95,-299.6"/>
-<polygon fill="black" stroke="black" points="247.32,-300.57 247.62,-289.98 240.78,-298.07 247.32,-300.57"/>
-<text text-anchor="middle" x="254.5" y="-311.8" font-family="Times,serif" font-size="14.00">ipv4</text>
+<path fill="none" stroke="black" d="M261.95,-319.8C261.95,-308.16 261.95,-292.55 261.95,-279.24"/>
+<polygon fill="black" stroke="black" points="265.45,-279.18 261.95,-269.18 258.45,-279.18 265.45,-279.18"/>
+<text text-anchor="middle" x="277.45" y="-290.8" font-family="Times,serif" font-size="14.00">ipv4</text>
 </g>
 <!-- ip6_lookup -->
 <g id="node8" class="node">
 <title>ip6_lookup</title>
-<ellipse fill="none" stroke="black" cx="439" cy="-272" rx="60.39" ry="18"/>
-<text text-anchor="middle" x="439" y="-268.3" font-family="Times,serif" font-size="14.00">ip6_lookup</text>
+<ellipse fill="none" stroke="black" cx="492.95" cy="-251" rx="60.39" ry="18"/>
+<text text-anchor="middle" x="492.95" y="-247.3" font-family="Times,serif" font-size="14.00">ip6_lookup</text>
 </g>
 <!-- pkt_cls&#45;&gt;ip6_lookup -->
 <g id="edge4" class="edge">
 <title>pkt_cls&#45;&gt;ip6_lookup</title>
-<path fill="none" stroke="black" d="M157.52,-350.25C188.82,-343.6 234.51,-333.46 274,-323 313.2,-312.62 357.13,-299.22 389.79,-288.91"/>
-<polygon fill="black" stroke="black" points="391.08,-292.17 399.55,-285.81 388.96,-285.5 391.08,-292.17"/>
-<text text-anchor="middle" x="339.5" y="-311.8" font-family="Times,serif" font-size="14.00">ipv6</text>
+<path fill="none" stroke="black" d="M293.1,-325.54C332.57,-311.01 400.93,-285.86 446.54,-269.07"/>
+<polygon fill="black" stroke="black" points="448.02,-272.26 456.2,-265.52 445.61,-265.69 448.02,-272.26"/>
+<text text-anchor="middle" x="407.45" y="-290.8" font-family="Times,serif" font-size="14.00">ipv6</text>
 </g>
 <!-- ip4_lookup&#45;&gt;pkt_drop -->
 <g id="edge7" class="edge">
 <title>ip4_lookup&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M239.17,-254.03C232.31,-243.87 224.56,-230.37 221,-217 204.89,-156.57 227.58,-83.56 242.59,-45.31"/>
-<polygon fill="cyan" stroke="cyan" points="245.89,-46.5 246.4,-35.92 239.4,-43.87 245.89,-46.5"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M258.85,-232.91C253.68,-198.83 247.1,-121.54 282.95,-73 299.1,-51.12 326.1,-37.95 350.6,-30.11"/>
+<polygon fill="cyan" stroke="cyan" points="351.6,-33.46 360.19,-27.26 349.61,-26.75 351.6,-33.46"/>
 </g>
 <!-- ip4_rewrite -->
 <g id="node9" class="node">
 <title>ip4_rewrite</title>
-<ellipse fill="none" stroke="black" cx="294" cy="-199" rx="63.89" ry="18"/>
-<text text-anchor="middle" x="294" y="-195.3" font-family="Times,serif" font-size="14.00">ip4_rewrite</text>
+<ellipse fill="none" stroke="black" cx="347.95" cy="-178" rx="63.89" ry="18"/>
+<text text-anchor="middle" x="347.95" y="-174.3" font-family="Times,serif" font-size="14.00">ip4_rewrite</text>
 </g>
 <!-- ip4_lookup&#45;&gt;ip4_rewrite -->
 <g id="edge6" class="edge">
 <title>ip4_lookup&#45;&gt;ip4_rewrite</title>
-<path fill="none" stroke="black" d="M261.95,-254.17C266.95,-245.72 273.12,-235.29 278.71,-225.85"/>
-<polygon fill="black" stroke="black" points="281.75,-227.59 283.83,-217.2 275.72,-224.02 281.75,-227.59"/>
+<path fill="none" stroke="black" d="M281.46,-233.89C292.92,-224.42 307.6,-212.31 320.25,-201.87"/>
+<polygon fill="black" stroke="black" points="322.73,-204.36 328.21,-195.29 318.27,-198.96 322.73,-204.36"/>
 </g>
 <!-- ip4_local -->
 <g id="node11" class="node">
 <title>ip4_local</title>
-<ellipse fill="none" stroke="black" cx="136" cy="-145" rx="51.19" ry="18"/>
-<text text-anchor="middle" x="136" y="-141.3" font-family="Times,serif" font-size="14.00">ip4_local</text>
+<ellipse fill="none" stroke="black" cx="176.95" cy="-178" rx="51.19" ry="18"/>
+<text text-anchor="middle" x="176.95" y="-174.3" font-family="Times,serif" font-size="14.00">ip4_local</text>
 </g>
 <!-- ip4_lookup&#45;&gt;ip4_local -->
 <g id="edge17" class="edge">
 <title>ip4_lookup&#45;&gt;ip4_local</title>
-<path fill="none" stroke="black" d="M218.11,-256.86C207.64,-251.39 196.61,-244.41 188,-236 169.45,-217.88 155.34,-191.74 146.53,-172.29"/>
-<polygon fill="black" stroke="black" points="149.72,-170.86 142.52,-163.08 143.3,-173.65 149.72,-170.86"/>
+<path fill="none" stroke="black" d="M242.66,-233.89C231.17,-224.29 216.41,-211.96 203.79,-201.42"/>
+<polygon fill="black" stroke="black" points="205.78,-198.53 195.86,-194.8 201.29,-203.9 205.78,-198.53"/>
 </g>
 <!-- ip6_lookup&#45;&gt;pkt_drop -->
 <g id="edge11" class="edge">
 <title>ip6_lookup&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M470.57,-256.44C486.08,-247.46 503.27,-234.31 512,-217 519.2,-202.71 517.24,-196.12 512,-181 486.88,-108.48 466,-83.15 395,-54 367.69,-42.79 335.88,-34.51 309.39,-28.83"/>
-<polygon fill="cyan" stroke="cyan" points="310.02,-25.39 299.52,-26.78 308.6,-32.24 310.02,-25.39"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M524.51,-235.44C540.02,-226.46 557.22,-213.31 565.95,-196 573.15,-181.71 572.55,-174.57 565.95,-160 540.59,-104.08 480.88,-61.6 441.74,-38.51"/>
+<polygon fill="cyan" stroke="cyan" points="443.16,-35.29 432.75,-33.34 439.67,-41.36 443.16,-35.29"/>
 </g>
 <!-- ip6_rewrite -->
 <g id="node10" class="node">
 <title>ip6_rewrite</title>
-<ellipse fill="none" stroke="black" cx="439" cy="-199" rx="63.89" ry="18"/>
-<text text-anchor="middle" x="439" y="-195.3" font-family="Times,serif" font-size="14.00">ip6_rewrite</text>
+<ellipse fill="none" stroke="black" cx="492.95" cy="-178" rx="63.89" ry="18"/>
+<text text-anchor="middle" x="492.95" y="-174.3" font-family="Times,serif" font-size="14.00">ip6_rewrite</text>
 </g>
 <!-- ip6_lookup&#45;&gt;ip6_rewrite -->
 <g id="edge10" class="edge">
 <title>ip6_lookup&#45;&gt;ip6_rewrite</title>
-<path fill="none" stroke="black" d="M439,-253.81C439,-245.79 439,-236.05 439,-227.07"/>
-<polygon fill="black" stroke="black" points="442.5,-227.03 439,-217.03 435.5,-227.03 442.5,-227.03"/>
+<path fill="none" stroke="black" d="M492.95,-232.81C492.95,-224.79 492.95,-215.05 492.95,-206.07"/>
+<polygon fill="black" stroke="black" points="496.45,-206.03 492.95,-196.03 489.45,-206.03 496.45,-206.03"/>
 </g>
 <!-- ip4_rewrite&#45;&gt;ethdev_tx -->
 <g id="edge8" class="edge">
 <title>ip4_rewrite&#45;&gt;ethdev_tx</title>
-<path fill="none" stroke="green" d="M301.07,-180.97C308.09,-164.05 318.96,-137.86 327.09,-118.28"/>
-<polygon fill="green" stroke="green" points="330.35,-119.57 330.95,-108.99 323.88,-116.88 330.35,-119.57"/>
+<path fill="none" stroke="green" d="M347.95,-159.8C347.95,-148.16 347.95,-132.55 347.95,-119.24"/>
+<polygon fill="green" stroke="green" points="351.45,-119.18 347.95,-109.18 344.45,-119.18 351.45,-119.18"/>
 </g>
 <!-- ip4_rewrite&#45;&gt;pkt_drop -->
 <g id="edge9" class="edge">
 <title>ip4_rewrite&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M289.85,-180.97C285.53,-163.07 278.61,-134.1 273,-109 268.3,-87.99 263.29,-64.16 259.59,-46.3"/>
-<polygon fill="cyan" stroke="cyan" points="262.97,-45.37 257.52,-36.28 256.11,-46.78 262.97,-45.37"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M370.32,-161.1C385.53,-148.83 404.37,-130.37 412.95,-109 421.04,-88.82 418.02,-64.12 413.56,-45.7"/>
+<polygon fill="cyan" stroke="cyan" points="416.9,-44.66 410.91,-35.93 410.15,-46.49 416.9,-44.66"/>
 </g>
 <!-- ip6_rewrite&#45;&gt;ethdev_tx -->
 <g id="edge12" class="edge">
 <title>ip6_rewrite&#45;&gt;ethdev_tx</title>
-<path fill="none" stroke="green" d="M423.22,-181.44C406.47,-163.86 379.84,-135.91 360.81,-115.94"/>
-<polygon fill="green" stroke="green" points="363.1,-113.27 353.67,-108.45 358.03,-118.1 363.1,-113.27"/>
+<path fill="none" stroke="green" d="M466.35,-161.41C442.8,-147.6 408.27,-127.36 382.57,-112.3"/>
+<polygon fill="green" stroke="green" points="384.28,-109.24 373.88,-107.21 380.74,-115.28 384.28,-109.24"/>
 </g>
 <!-- ip6_rewrite&#45;&gt;pkt_drop -->
 <g id="edge13" class="edge">
 <title>ip6_rewrite&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M438.77,-180.67C437.49,-154.09 431.22,-103.19 403,-73 379.35,-47.7 342.93,-34.22 312.02,-27.06"/>
-<polygon fill="cyan" stroke="cyan" points="312.71,-23.63 302.2,-24.95 311.24,-30.47 312.71,-23.63"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M485.15,-159.86C473.93,-135.7 452.15,-90.48 429.95,-54 427.97,-50.75 425.78,-47.4 423.55,-44.13"/>
+<polygon fill="cyan" stroke="cyan" points="426.28,-41.92 417.67,-35.75 420.55,-45.94 426.28,-41.92"/>
 </g>
 <!-- ip4_local&#45;&gt;pkt_drop -->
 <g id="edge18" class="edge">
 <title>ip4_local&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M142.47,-126.87C150.6,-107.23 166.18,-75.04 188,-54 195,-47.25 203.56,-41.45 212.16,-36.63"/>
-<polygon fill="cyan" stroke="cyan" points="213.85,-39.7 221.08,-31.95 210.6,-33.5 213.85,-39.7"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M191.02,-160.51C195.47,-154.86 200.21,-148.35 203.95,-142 225.57,-105.29 209.02,-81.03 241.95,-54 257.83,-40.96 306.22,-31.62 346.19,-25.89"/>
+<polygon fill="cyan" stroke="cyan" points="346.72,-29.35 356.14,-24.51 345.75,-22.41 346.72,-29.35"/>
+</g>
+<!-- udp4_input -->
+<g id="node12" class="node">
+<title>udp4_input</title>
+<ellipse fill="none" stroke="black" cx="126.95" cy="-91" rx="63.09" ry="18"/>
+<text text-anchor="middle" x="126.95" y="-87.3" font-family="Times,serif" font-size="14.00">udp4_input</text>
+</g>
+<!-- ip4_local&#45;&gt;udp4_input -->
+<g id="edge19" class="edge">
+<title>ip4_local&#45;&gt;udp4_input</title>
+<path fill="none" stroke="black" d="M167.07,-160.21C159.99,-148.18 150.33,-131.75 142.26,-118.03"/>
+<polygon fill="black" stroke="black" points="145.06,-115.89 136.97,-109.05 139.03,-119.44 145.06,-115.89"/>
+<text text-anchor="middle" x="177.45" y="-130.8" font-family="Times,serif" font-size="14.00">udpv4</text>
+</g>
+<!-- udp4_input&#45;&gt;pkt_drop -->
+<g id="edge21" class="edge">
+<title>udp4_input&#45;&gt;pkt_drop</title>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M154.75,-74.82C169.08,-67.56 187.05,-59.32 203.95,-54 250.51,-39.35 305.19,-30.33 345.76,-25.12"/>
+<polygon fill="cyan" stroke="cyan" points="346.26,-28.59 355.75,-23.88 345.4,-21.64 346.26,-28.59"/>
+</g>
+<!-- udp_user_node -->
+<g id="node13" class="node">
+<title>udp_user_node</title>
+<ellipse fill="none" stroke="black" cx="126.95" cy="-18" rx="79.89" ry="18"/>
+<text text-anchor="middle" x="126.95" y="-14.3" font-family="Times,serif" font-size="14.00">udp_user_node</text>
+</g>
+<!-- udp4_input&#45;&gt;udp_user_node -->
+<g id="edge20" class="edge">
+<title>udp4_input&#45;&gt;udp_user_node</title>
+<path fill="none" stroke="black" d="M126.95,-72.81C126.95,-64.79 126.95,-55.05 126.95,-46.07"/>
+<polygon fill="black" stroke="black" points="130.45,-46.03 126.95,-36.03 123.45,-46.03 130.45,-46.03"/>
 </g>
 </g>
 </svg>
diff --git a/lib/node/meson.build b/lib/node/meson.build
index c0d5b09e2f..c5b8ee656e 100644
--- a/lib/node/meson.build
+++ b/lib/node/meson.build
@@ -22,11 +22,13 @@ sources = files(
         'null.c',
         'pkt_cls.c',
         'pkt_drop.c',
+        'udp4_input.c',
 )
 headers = files(
         'rte_node_eth_api.h',
         'rte_node_ip4_api.h',
         'rte_node_ip6_api.h',
+        'rte_node_udp4_input_api.h',
 )
 
 # Strict-aliasing rules are violated by uint8_t[] to context size casts.
diff --git a/lib/node/rte_node_udp4_input_api.h b/lib/node/rte_node_udp4_input_api.h
new file mode 100644
index 0000000000..7217b914ec
--- /dev/null
+++ b/lib/node/rte_node_udp4_input_api.h
@@ -0,0 +1,60 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2023 Marvell International Ltd.
+ */
+
+#ifndef __INCLUDE_RTE_NODE_UDP4_INPUT_API_H__
+#define __INCLUDE_RTE_NODE_UDP4_INPUT_API_H__
+
+/**
+ * @file rte_node_udp4_input_api.h
+ *
+ * @warning
+ * @b EXPERIMENTAL:
+ * All functions in this file may be changed or removed without prior notice.
+ *
+ * This API allows to control path functions of udp4_* nodes
+ * like udp4_input.
+ *
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rte_common.h>
+#include <rte_compat.h>
+
+/**
+ * UDP4 lookup next nodes.
+ */
+enum rte_node_udp4_input_next {
+	RTE_NODE_UDP4_INPUT_NEXT_PKT_DROP,
+	/**< Packet drop node. */
+};
+
+/**
+ * Add usr node to receive udp4 frames.
+ *
+ * @param usr_node
+ * Node registered by user to receive data.
+ */
+__rte_experimental
+int rte_node_udp4_usr_node_add(const char *usr_node);
+
+/**
+ * Add udpv4 dst_port to lookup table.
+ *
+ * @param dst_port
+ *   Dst Port of packet to be added for consumption.
+ * @param next_node
+ *   Next node packet to be added for consumption.
+ * @return
+ *   0 on success, negative otherwise.
+ */
+__rte_experimental
+int rte_node_udp4_dst_port_add(uint32_t dst_port, rte_edge_t next_node);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __INCLUDE_RTE_NODE_UDP4_API_H__ */
diff --git a/lib/node/udp4_input.c b/lib/node/udp4_input.c
new file mode 100644
index 0000000000..c9ea58af4c
--- /dev/null
+++ b/lib/node/udp4_input.c
@@ -0,0 +1,226 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2023 Marvell International Ltd.
+ */
+
+#include <arpa/inet.h>
+#include <sys/socket.h>
+
+#include <rte_ethdev.h>
+#include <rte_ether.h>
+#include <rte_graph.h>
+#include <rte_graph_worker.h>
+#include <rte_ip.h>
+#include <rte_lpm.h>
+#include <rte_hash.h>
+#include <rte_fbk_hash.h>
+#include <rte_jhash.h>
+#include <rte_hash_crc.h>
+
+
+#include "rte_node_udp4_input_api.h"
+
+#include "node_private.h"
+
+#define UDP4_INPUT_HASH_TBL_SIZE 1024
+
+#define UDP4_INPUT_NODE_HASH(ctx) \
+	(((struct udp4_input_node_ctx *)ctx)->hash)
+
+#define UDP4_INPUT_NODE_NEXT_INDEX(ctx) \
+	(((struct udp4_input_node_ctx *)ctx)->next_index)
+
+
+static struct udp4_input_node_main udp4_input_nm;
+
+/* UDP4 input  global data struct */
+struct udp4_input_node_main {
+	struct rte_hash *hash_tbl[RTE_MAX_NUMA_NODES];
+};
+
+struct udp4_input_node_ctx {
+	/* Socket's Hash table */
+	struct rte_hash *hash;
+	/* Cached next index */
+	uint16_t next_index;
+};
+
+struct flow_key {
+	uint32_t prt_dst;
+};
+
+static struct rte_hash_parameters udp4_params = {
+	.entries = UDP4_INPUT_HASH_TBL_SIZE,
+	.key_len = sizeof(uint32_t),
+	.hash_func = rte_jhash,
+	.hash_func_init_val = 0,
+	.socket_id = 0,
+};
+
+int
+rte_node_udp4_dst_port_add(uint32_t dst_port, rte_edge_t next_node)
+{
+	uint8_t socket;
+	int rc;
+
+	for (socket = 0; socket < RTE_MAX_NUMA_NODES; socket++) {
+		if (!udp4_input_nm.hash_tbl[socket])
+			continue;
+
+		rc = rte_hash_add_key_data(udp4_input_nm.hash_tbl[socket],
+					   &dst_port, (void *)(uintptr_t)next_node);
+		if (rc < 0) {
+			node_err("udp4_lookup", "Failed to add key for sock %u, rc=%d",
+					socket, rc);
+			return rc;
+		}
+	}
+	return 0;
+}
+
+int
+rte_node_udp4_usr_node_add(const char *usr_node)
+{
+	const char *next_nodes = usr_node;
+	rte_node_t udp4_input_node_id, count;
+
+	udp4_input_node_id = rte_node_from_name("udp4_input");
+	count = rte_node_edge_update(udp4_input_node_id, RTE_EDGE_ID_INVALID,
+				     &next_nodes, 1);
+	if (count == 0) {
+		node_dbg("udp4_input", "Adding usr node as edge to udp4_input failed");
+		return count;
+	}
+	count = rte_node_edge_count(udp4_input_node_id) - 1;
+	return count;
+}
+
+static int
+setup_udp4_dstprt_hash(struct udp4_input_node_main *nm, int socket)
+{
+	struct rte_hash_parameters *hash_udp4 = &udp4_params;
+	char s[RTE_HASH_NAMESIZE];
+
+	/* One Hash table per socket */
+	if (nm->hash_tbl[socket])
+		return 0;
+
+	/* create Hash table */
+	snprintf(s, sizeof(s), "UDP4_INPUT_HASH_%d", socket);
+	hash_udp4->name = s;
+	hash_udp4->socket_id = socket;
+	nm->hash_tbl[socket] = rte_hash_create(hash_udp4);
+	if (nm->hash_tbl[socket] == NULL)
+		return -rte_errno;
+
+	return 0;
+}
+
+static int
+udp4_input_node_init(const struct rte_graph *graph, struct rte_node *node)
+{
+	uint16_t socket, lcore_id;
+	static uint8_t init_once;
+	int rc;
+
+	RTE_SET_USED(graph);
+	RTE_BUILD_BUG_ON(sizeof(struct udp4_input_node_ctx) > RTE_NODE_CTX_SZ);
+
+	if (!init_once) {
+
+		/* Setup HASH tables for all sockets */
+		RTE_LCORE_FOREACH(lcore_id)
+		{
+			socket = rte_lcore_to_socket_id(lcore_id);
+			rc = setup_udp4_dstprt_hash(&udp4_input_nm, socket);
+			if (rc) {
+				node_err("udp4_lookup",
+						"Failed to setup hash tbl for sock %u, rc=%d",
+						socket, rc);
+				return rc;
+			}
+		}
+		init_once = 1;
+	}
+
+	UDP4_INPUT_NODE_HASH(node->ctx) = udp4_input_nm.hash_tbl[graph->socket];
+
+	node_dbg("udp4_input", "Initialized udp4_input node");
+	return 0;
+}
+
+static uint16_t
+udp4_input_node_process_scalar(struct rte_graph *graph, struct rte_node *node,
+			       void **objs, uint16_t nb_objs)
+{
+	struct rte_hash *hash_tbl_handle = UDP4_INPUT_NODE_HASH(node->ctx);
+	rte_edge_t next_index, udplookup_node;
+	struct rte_udp_hdr *pkt_udp_hdr;
+	uint16_t last_spec = 0;
+	void **to_next, **from;
+	struct rte_mbuf *mbuf;
+	uint16_t held = 0;
+	uint16_t next;
+	int i, rc;
+
+	/* Speculative next */
+	next_index = UDP4_INPUT_NODE_NEXT_INDEX(node->ctx);
+
+	from = objs;
+
+	to_next = rte_node_next_stream_get(graph, node, next_index, nb_objs);
+	for (i = 0; i < nb_objs; i++) {
+		struct flow_key key_port;
+
+		mbuf = (struct rte_mbuf *)objs[i];
+		pkt_udp_hdr = rte_pktmbuf_mtod_offset(mbuf, struct rte_udp_hdr *,
+						sizeof(struct rte_ether_hdr) +
+						sizeof(struct rte_ipv4_hdr));
+
+		key_port.prt_dst = rte_cpu_to_be_16(pkt_udp_hdr->dst_port);
+		rc = rte_hash_lookup_data(hash_tbl_handle,
+					  &key_port.prt_dst,
+					  (void **)&udplookup_node);
+		next = (rc < 0) ? RTE_NODE_UDP4_INPUT_NEXT_PKT_DROP
+				    : udplookup_node;
+
+		if (unlikely(next_index != next)) {
+			/* Copy things successfully speculated till now */
+			rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
+			from += last_spec;
+			to_next += last_spec;
+			held += last_spec;
+			last_spec = 0;
+
+			rte_node_enqueue_x1(graph, node, next, from[0]);
+			from += 1;
+		} else {
+			last_spec += 1;
+		}
+	}
+	/* !!! Home run !!! */
+	if (likely(last_spec == nb_objs)) {
+		rte_node_next_stream_move(graph, node, next_index);
+		return nb_objs;
+	}
+	held += last_spec;
+	rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
+	rte_node_next_stream_put(graph, node, next_index, held);
+	/* Save the last next used */
+	UDP4_INPUT_NODE_NEXT_INDEX(node->ctx) = next;
+
+	return nb_objs;
+}
+
+static struct rte_node_register udp4_input_node = {
+	.process = udp4_input_node_process_scalar,
+	.name = "udp4_input",
+
+	.init = udp4_input_node_init,
+
+	.nb_edges = RTE_NODE_UDP4_INPUT_NEXT_PKT_DROP + 1,
+	.next_nodes = {
+		[RTE_NODE_UDP4_INPUT_NEXT_PKT_DROP] = "pkt_drop",
+	},
+};
+
+RTE_NODE_REGISTER(udp4_input_node);
diff --git a/lib/node/version.map b/lib/node/version.map
index 40df308bfe..c51befce09 100644
--- a/lib/node/version.map
+++ b/lib/node/version.map
@@ -6,6 +6,8 @@ EXPERIMENTAL {
 	rte_node_ip4_rewrite_add;
 	rte_node_ip6_rewrite_add;
 	rte_node_ip6_route_add;
+	rte_node_udp4_usr_node_add;
+	rte_node_udp4_dst_port_add;
 	rte_node_logtype;
 	local: *;
 };
-- 
2.25.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v2 1/2] node: add IPv4 local node to handle local pkts
  2023-07-03  9:13 [PATCH 1/2] node: add IPv4 local node to handle local pkts Rakesh Kudurumalla
  2023-07-03  9:13 ` [PATCH 2/2] node: add UDP v4 support Rakesh Kudurumalla
@ 2023-07-03 10:05 ` Rakesh Kudurumalla
  2023-07-03 10:05   ` [PATCH v2 2/2] node: add UDP v4 support Rakesh Kudurumalla
  2023-07-04 10:50   ` [PATCH v3 1/2] node: add IPv4 local node to handle local pkts Rakesh Kudurumalla
  1 sibling, 2 replies; 16+ messages in thread
From: Rakesh Kudurumalla @ 2023-07-03 10:05 UTC (permalink / raw)
  To: Jerin Jacob, Kiran Kumar K, Nithin Dabilpuram, Zhirun Yan,
	Pavan Nikhilesh
  Cc: dev, Rakesh Kudurumalla

Local or Host destined pkts can be redirected IPv4 local node
using IP4 Lookup node entries with prefix of 32 and be redirected
to this IP4 local node for further processing.

Signed-off-by: Rakesh Kudurumalla <rkudurumalla@marvell.com>
---
Depends-on: series-28622 ("add inbuilt graph nodes data flow")

v2 :
   - Resolve compilation on intel

 doc/guides/prog_guide/graph_lib.rst           |  15 ++
 .../img/graph_inbuilt_node_flow.svg           | 138 ++++++++++--------
 lib/node/ip4_local.c                          |  88 +++++++++++
 lib/node/ip4_lookup.c                         |   1 +
 lib/node/meson.build                          |   1 +
 lib/node/rte_node_ip4_api.h                   |  12 ++
 6 files changed, 196 insertions(+), 59 deletions(-)
 create mode 100644 lib/node/ip4_local.c

diff --git a/doc/guides/prog_guide/graph_lib.rst b/doc/guides/prog_guide/graph_lib.rst
index 96af29e8da..eaa8ee337e 100644
--- a/doc/guides/prog_guide/graph_lib.rst
+++ b/doc/guides/prog_guide/graph_lib.rst
@@ -498,3 +498,18 @@ Uses ``poll`` function to poll on the socket fd
 for ``POLLIN`` events to read the packets from raw socket
 to stream buffer and does ``rte_node_next_stream_move()``
 when there are received packets.
+
+ip4_local
+~~~~~~~~~
+This node is an intermediate node that does ``packet_type`` lookup for
+the received ipv4 packets and the result determines each packets next node.
+
+On successful ``packet_type`` lookup, for any IPv4 protocol the result
+contains the ``next_node`` id and ``next-hop`` id with which the packet
+needs to be further processed.
+
+On packet_type lookup failure, objects are redirected to ``pkt_drop`` node.
+``rte_node_ip4_route_add()`` is control path API to add ipv4 address with 32 bit
+depth to receive to packets.
+To achieve home run, node use ``rte_node_stream_move()`` as mentioned in above
+sections.
diff --git a/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg b/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg
index 02fe768dfe..7a3ace48dc 100644
--- a/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg
+++ b/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg
@@ -37,174 +37,194 @@ digraph dpdk_inbuilt_nodes_flow {
     ethdev_tx -> pkt_drop [color="cyan" style="dashed"]
     pkt_cls->pkt_drop   [color="cyan" style="dashed"]
     kernel_tx -> kernel_rx [color="red" style="dashed"]
+    ip4_lookup -> ip4_local
+    ip4_local -> pkt_drop [color="cyan" style="dashed"]
 }
 
  -->
 <!-- input nodes -->
 <!-- Title: dpdk_inbuilt_nodes_flow Pages: 1 -->
-<svg width="470pt" height="425pt"
- viewBox="0.00 0.00 470.23 424.50" 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 420.5)">
+<svg width="525pt" height="458pt"
+ viewBox="0.00 0.00 524.91 458.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 454)">
 <title>dpdk_inbuilt_nodes_flow</title>
-<polygon fill="white" stroke="none" points="-4,4 -4,-420.5 466.23,-420.5 466.23,4 -4,4"/>
+<polygon fill="white" stroke="transparent" points="-4,4 -4,-454 520.91,-454 520.91,4 -4,4"/>
 <!-- ethdev_rx -->
 <g id="node1" class="node">
 <title>ethdev_rx</title>
-<ellipse fill="none" stroke="green" cx="219.23" cy="-398.5" rx="47.77" ry="18"/>
-<text text-anchor="middle" x="219.23" y="-393.45" font-family="Times,serif" font-size="14.00">ethdev_rx</text>
+<ellipse fill="none" stroke="green" cx="120" cy="-432" rx="56.59" ry="18"/>
+<text text-anchor="middle" x="120" y="-428.3" font-family="Times,serif" font-size="14.00">ethdev_rx</text>
 </g>
 <!-- pkt_cls -->
 <g id="node6" class="node">
 <title>pkt_cls</title>
-<ellipse fill="none" stroke="red" cx="219.23" cy="-325.5" rx="37.53" ry="18"/>
-<text text-anchor="middle" x="219.23" y="-320.45" font-family="Times,serif" font-size="14.00">pkt_cls</text>
+<ellipse fill="none" stroke="red" cx="120" cy="-359" rx="42.79" ry="18"/>
+<text text-anchor="middle" x="120" y="-355.3" font-family="Times,serif" font-size="14.00">pkt_cls</text>
 </g>
 <!-- ethdev_rx&#45;&gt;pkt_cls -->
 <g id="edge1" class="edge">
 <title>ethdev_rx&#45;&gt;pkt_cls</title>
-<path fill="none" stroke="black" d="M219.23,-380.31C219.23,-372.55 219.23,-363.18 219.23,-354.45"/>
-<polygon fill="black" stroke="black" points="222.73,-354.53 219.23,-344.53 215.73,-354.53 222.73,-354.53"/>
+<path fill="none" stroke="black" d="M120,-413.81C120,-405.79 120,-396.05 120,-387.07"/>
+<polygon fill="black" stroke="black" points="123.5,-387.03 120,-377.03 116.5,-387.03 123.5,-387.03"/>
 </g>
 <!-- kernel_rx -->
 <g id="node2" class="node">
 <title>kernel_rx</title>
-<ellipse fill="none" stroke="green" cx="46.23" cy="-164" rx="46.23" ry="18"/>
-<text text-anchor="middle" x="46.23" y="-158.95" font-family="Times,serif" font-size="14.00">kernel_rx</text>
+<ellipse fill="none" stroke="green" cx="82" cy="-199" rx="53.89" ry="18"/>
+<text text-anchor="middle" x="82" y="-195.3" font-family="Times,serif" font-size="14.00">kernel_rx</text>
 </g>
 <!-- kernel_rx&#45;&gt;pkt_cls -->
 <g id="edge2" class="edge">
 <title>kernel_rx&#45;&gt;pkt_cls</title>
-<path fill="none" stroke="black" d="M41.45,-182.08C37.1,-201.37 33.27,-232.96 47.23,-255 73.68,-296.74 130.21,-313.41 171.26,-320.07"/>
-<polygon fill="black" stroke="black" points="170.73,-323.68 181.13,-321.66 171.74,-316.75 170.73,-323.68"/>
+<path fill="none" stroke="black" d="M70.87,-216.92C60.28,-235.27 47.29,-265.24 57,-290 64.12,-308.16 78.62,-324.37 91.92,-336.4"/>
+<polygon fill="black" stroke="black" points="89.69,-339.1 99.54,-342.99 94.26,-333.8 89.69,-339.1"/>
 </g>
 <!-- ethdev_tx -->
 <g id="node3" class="node">
 <title>ethdev_tx</title>
-<ellipse fill="none" stroke="magenta" cx="293.23" cy="-91" rx="47.26" ry="18"/>
-<text text-anchor="middle" x="293.23" y="-85.95" font-family="Times,serif" font-size="14.00">ethdev_tx</text>
+<ellipse fill="none" stroke="magenta" cx="338" cy="-91" rx="55.79" ry="18"/>
+<text text-anchor="middle" x="338" y="-87.3" font-family="Times,serif" font-size="14.00">ethdev_tx</text>
 </g>
 <!-- pkt_drop -->
 <g id="node4" class="node">
 <title>pkt_drop</title>
-<ellipse fill="none" stroke="cyan" cx="349.23" cy="-18" rx="44.19" ry="18"/>
-<text text-anchor="middle" x="349.23" y="-12.95" font-family="Times,serif" font-size="14.00">pkt_drop</text>
+<ellipse fill="none" stroke="cyan" cx="254" cy="-18" rx="51.99" ry="18"/>
+<text text-anchor="middle" x="254" y="-14.3" font-family="Times,serif" font-size="14.00">pkt_drop</text>
 </g>
 <!-- ethdev_tx&#45;&gt;pkt_drop -->
 <g id="edge14" class="edge">
 <title>ethdev_tx&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M306.22,-73.53C313.15,-64.75 321.81,-53.76 329.55,-43.96"/>
-<polygon fill="cyan" stroke="cyan" points="332.87,-46.4 336.32,-36.38 327.37,-42.06 332.87,-46.4"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M318.94,-73.89C307.58,-64.29 293,-51.96 280.53,-41.42"/>
+<polygon fill="cyan" stroke="cyan" points="282.59,-38.58 272.7,-34.8 278.07,-43.93 282.59,-38.58"/>
 </g>
 <!-- kernel_tx -->
 <g id="node5" class="node">
 <title>kernel_tx</title>
-<ellipse fill="none" stroke="blue" cx="102.23" cy="-237" rx="45.72" ry="18"/>
-<text text-anchor="middle" x="102.23" y="-231.95" font-family="Times,serif" font-size="14.00">kernel_tx</text>
+<ellipse fill="none" stroke="blue" cx="120" cy="-272" rx="53.89" ry="18"/>
+<text text-anchor="middle" x="120" y="-268.3" font-family="Times,serif" font-size="14.00">kernel_tx</text>
 </g>
 <!-- kernel_tx&#45;&gt;kernel_rx -->
 <g id="edge16" class="edge">
 <title>kernel_tx&#45;&gt;kernel_rx</title>
-<path fill="none" stroke="red" stroke-dasharray="5,2" d="M89.25,-219.53C82.32,-210.75 73.65,-199.76 65.92,-189.96"/>
-<polygon fill="red" stroke="red" points="68.09,-188.06 59.15,-182.38 62.6,-192.4 68.09,-188.06"/>
+<path fill="none" stroke="red" stroke-dasharray="5,2" d="M110.99,-254.17C106.52,-245.81 101,-235.51 95.99,-226.14"/>
+<polygon fill="red" stroke="red" points="99.01,-224.36 91.2,-217.2 92.84,-227.67 99.01,-224.36"/>
 </g>
 <!-- pkt_cls&#45;&gt;pkt_drop -->
 <g id="edge15" class="edge">
 <title>pkt_cls&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M255.09,-319.38C322.68,-308.72 462.23,-281.44 462.23,-238 462.23,-238 462.23,-238 462.23,-90 462.23,-57.84 429.01,-39.68 398.59,-29.8"/>
-<polygon fill="cyan" stroke="cyan" points="400.02,-26.27 389.44,-26.75 398.01,-32.98 400.02,-26.27"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M84,-348.97C48.65,-337.7 0,-314.61 0,-273 0,-273 0,-273 0,-90 0,-49.99 118.4,-31.52 193.52,-23.82"/>
+<polygon fill="cyan" stroke="cyan" points="194.21,-27.27 203.82,-22.81 193.52,-20.31 194.21,-27.27"/>
 </g>
 <!-- pkt_cls&#45;&gt;kernel_tx -->
 <g id="edge5" class="edge">
 <title>pkt_cls&#45;&gt;kernel_tx</title>
-<path fill="none" stroke="blue" d="M186.99,-315.75C170.62,-310.16 151.14,-301.64 136.48,-289.5 128.23,-282.66 121.2,-273.31 115.7,-264.46"/>
-<polygon fill="blue" stroke="blue" points="118.38,-263.1 110.34,-256.2 112.32,-266.61 118.38,-263.1"/>
-<text text-anchor="middle" x="176.61" y="-276.2" font-family="Times,serif" font-size="14.00">exception pkts</text>
+<path fill="none" stroke="blue" d="M120,-340.8C120,-329.16 120,-313.55 120,-300.24"/>
+<polygon fill="blue" stroke="blue" points="123.5,-300.18 120,-290.18 116.5,-300.18 123.5,-300.18"/>
+<text text-anchor="middle" x="172.5" y="-311.8" font-family="Times,serif" font-size="14.00">exception pkts</text>
 </g>
 <!-- ip4_lookup -->
 <g id="node7" class="node">
 <title>ip4_lookup</title>
-<ellipse fill="none" stroke="black" cx="219.23" cy="-237" rx="52.89" ry="18"/>
-<text text-anchor="middle" x="219.23" y="-231.95" font-family="Times,serif" font-size="14.00">ip4_lookup</text>
+<ellipse fill="none" stroke="black" cx="252" cy="-272" rx="60.39" ry="18"/>
+<text text-anchor="middle" x="252" y="-268.3" font-family="Times,serif" font-size="14.00">ip4_lookup</text>
 </g>
 <!-- pkt_cls&#45;&gt;ip4_lookup -->
 <g id="edge3" class="edge">
 <title>pkt_cls&#45;&gt;ip4_lookup</title>
-<path fill="none" stroke="black" d="M219.23,-307.41C219.23,-295.64 219.23,-279.73 219.23,-266.11"/>
-<polygon fill="black" stroke="black" points="222.73,-266.35 219.23,-256.35 215.73,-266.35 222.73,-266.35"/>
-<text text-anchor="middle" x="231.23" y="-276.2" font-family="Times,serif" font-size="14.00">ipv4</text>
+<path fill="none" stroke="black" d="M160.54,-352.79C182.64,-348.15 209.23,-339.41 228,-323 235.09,-316.81 240.26,-308.05 243.95,-299.6"/>
+<polygon fill="black" stroke="black" points="247.32,-300.57 247.62,-289.98 240.78,-298.07 247.32,-300.57"/>
+<text text-anchor="middle" x="254.5" y="-311.8" font-family="Times,serif" font-size="14.00">ipv4</text>
 </g>
 <!-- ip6_lookup -->
 <g id="node8" class="node">
 <title>ip6_lookup</title>
-<ellipse fill="none" stroke="black" cx="343.23" cy="-237" rx="52.89" ry="18"/>
-<text text-anchor="middle" x="343.23" y="-231.95" font-family="Times,serif" font-size="14.00">ip6_lookup</text>
+<ellipse fill="none" stroke="black" cx="439" cy="-272" rx="60.39" ry="18"/>
+<text text-anchor="middle" x="439" y="-268.3" font-family="Times,serif" font-size="14.00">ip6_lookup</text>
 </g>
 <!-- pkt_cls&#45;&gt;ip6_lookup -->
 <g id="edge4" class="edge">
 <title>pkt_cls&#45;&gt;ip6_lookup</title>
-<path fill="none" stroke="black" d="M239.99,-310.02C259.62,-296.33 289.35,-275.59 311.88,-259.87"/>
-<polygon fill="black" stroke="black" points="313.53,-262.29 319.73,-253.7 309.53,-256.55 313.53,-262.29"/>
-<text text-anchor="middle" x="304.23" y="-276.2" font-family="Times,serif" font-size="14.00">ipv6</text>
+<path fill="none" stroke="black" d="M157.52,-350.25C188.82,-343.6 234.51,-333.46 274,-323 313.2,-312.62 357.13,-299.22 389.79,-288.91"/>
+<polygon fill="black" stroke="black" points="391.08,-292.17 399.55,-285.81 388.96,-285.5 391.08,-292.17"/>
+<text text-anchor="middle" x="339.5" y="-311.8" font-family="Times,serif" font-size="14.00">ipv6</text>
 </g>
 <!-- ip4_lookup&#45;&gt;pkt_drop -->
 <g id="edge7" class="edge">
 <title>ip4_lookup&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M192.86,-221.12C179.2,-211.83 163.82,-198.49 156.23,-182 149.55,-167.46 150.78,-161.04 156.23,-146 176.39,-90.45 198.32,-78.19 252.23,-54 269.14,-46.41 288.24,-39.24 304.98,-33.38"/>
-<polygon fill="cyan" stroke="cyan" points="305.75,-36.48 314.07,-29.92 303.47,-29.86 305.75,-36.48"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M239.17,-254.03C232.31,-243.87 224.56,-230.37 221,-217 204.89,-156.57 227.58,-83.56 242.59,-45.31"/>
+<polygon fill="cyan" stroke="cyan" points="245.89,-46.5 246.4,-35.92 239.4,-43.87 245.89,-46.5"/>
 </g>
 <!-- ip4_rewrite -->
 <g id="node9" class="node">
 <title>ip4_rewrite</title>
-<ellipse fill="none" stroke="black" cx="218.23" cy="-164" rx="53.4" ry="18"/>
-<text text-anchor="middle" x="218.23" y="-158.95" font-family="Times,serif" font-size="14.00">ip4_rewrite</text>
+<ellipse fill="none" stroke="black" cx="294" cy="-199" rx="63.89" ry="18"/>
+<text text-anchor="middle" x="294" y="-195.3" font-family="Times,serif" font-size="14.00">ip4_rewrite</text>
 </g>
 <!-- ip4_lookup&#45;&gt;ip4_rewrite -->
 <g id="edge6" class="edge">
 <title>ip4_lookup&#45;&gt;ip4_rewrite</title>
-<path fill="none" stroke="black" d="M218.99,-218.81C218.88,-211.05 218.75,-201.68 218.63,-192.95"/>
-<polygon fill="black" stroke="black" points="222.11,-192.98 218.47,-183.03 215.11,-193.08 222.11,-192.98"/>
+<path fill="none" stroke="black" d="M261.95,-254.17C266.95,-245.72 273.12,-235.29 278.71,-225.85"/>
+<polygon fill="black" stroke="black" points="281.75,-227.59 283.83,-217.2 275.72,-224.02 281.75,-227.59"/>
+</g>
+<!-- ip4_local -->
+<g id="node11" class="node">
+<title>ip4_local</title>
+<ellipse fill="none" stroke="black" cx="136" cy="-145" rx="51.19" ry="18"/>
+<text text-anchor="middle" x="136" y="-141.3" font-family="Times,serif" font-size="14.00">ip4_local</text>
+</g>
+<!-- ip4_lookup&#45;&gt;ip4_local -->
+<g id="edge17" class="edge">
+<title>ip4_lookup&#45;&gt;ip4_local</title>
+<path fill="none" stroke="black" d="M218.11,-256.86C207.64,-251.39 196.61,-244.41 188,-236 169.45,-217.88 155.34,-191.74 146.53,-172.29"/>
+<polygon fill="black" stroke="black" points="149.72,-170.86 142.52,-163.08 143.3,-173.65 149.72,-170.86"/>
 </g>
 <!-- ip6_lookup&#45;&gt;pkt_drop -->
 <g id="edge11" class="edge">
 <title>ip6_lookup&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M369.2,-221.03C382.65,-211.71 397.78,-198.37 405.23,-182 426.87,-134.45 392.95,-75.95 369.19,-43.54"/>
-<polygon fill="cyan" stroke="cyan" points="371.64,-41.98 362.81,-36.13 366.06,-46.21 371.64,-41.98"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M470.57,-256.44C486.08,-247.46 503.27,-234.31 512,-217 519.2,-202.71 517.24,-196.12 512,-181 486.88,-108.48 466,-83.15 395,-54 367.69,-42.79 335.88,-34.51 309.39,-28.83"/>
+<polygon fill="cyan" stroke="cyan" points="310.02,-25.39 299.52,-26.78 308.6,-32.24 310.02,-25.39"/>
 </g>
 <!-- ip6_rewrite -->
 <g id="node10" class="node">
 <title>ip6_rewrite</title>
-<ellipse fill="none" stroke="black" cx="343.23" cy="-164" rx="53.4" ry="18"/>
-<text text-anchor="middle" x="343.23" y="-158.95" font-family="Times,serif" font-size="14.00">ip6_rewrite</text>
+<ellipse fill="none" stroke="black" cx="439" cy="-199" rx="63.89" ry="18"/>
+<text text-anchor="middle" x="439" y="-195.3" font-family="Times,serif" font-size="14.00">ip6_rewrite</text>
 </g>
 <!-- ip6_lookup&#45;&gt;ip6_rewrite -->
 <g id="edge10" class="edge">
 <title>ip6_lookup&#45;&gt;ip6_rewrite</title>
-<path fill="none" stroke="black" d="M343.23,-218.81C343.23,-211.05 343.23,-201.68 343.23,-192.95"/>
-<polygon fill="black" stroke="black" points="346.73,-193.03 343.23,-183.03 339.73,-193.03 346.73,-193.03"/>
+<path fill="none" stroke="black" d="M439,-253.81C439,-245.79 439,-236.05 439,-227.07"/>
+<polygon fill="black" stroke="black" points="442.5,-227.03 439,-217.03 435.5,-227.03 442.5,-227.03"/>
 </g>
 <!-- ip4_rewrite&#45;&gt;ethdev_tx -->
 <g id="edge8" class="edge">
 <title>ip4_rewrite&#45;&gt;ethdev_tx</title>
-<path fill="none" stroke="green" d="M235.63,-146.53C245.35,-137.33 257.64,-125.7 268.36,-115.54"/>
-<polygon fill="green" stroke="green" points="270.34,-118.55 275.19,-109.13 265.52,-113.47 270.34,-118.55"/>
+<path fill="none" stroke="green" d="M301.07,-180.97C308.09,-164.05 318.96,-137.86 327.09,-118.28"/>
+<polygon fill="green" stroke="green" points="330.35,-119.57 330.95,-108.99 323.88,-116.88 330.35,-119.57"/>
 </g>
 <!-- ip4_rewrite&#45;&gt;pkt_drop -->
 <g id="edge9" class="edge">
 <title>ip4_rewrite&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M217.56,-145.54C217.71,-125.89 220.78,-93.99 237.23,-73 253.17,-52.67 278.68,-39.55 301.33,-31.33"/>
-<polygon fill="cyan" stroke="cyan" points="302.14,-34.42 310.5,-27.9 299.9,-27.79 302.14,-34.42"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M289.85,-180.97C285.53,-163.07 278.61,-134.1 273,-109 268.3,-87.99 263.29,-64.16 259.59,-46.3"/>
+<polygon fill="cyan" stroke="cyan" points="262.97,-45.37 257.52,-36.28 256.11,-46.78 262.97,-45.37"/>
 </g>
 <!-- ip6_rewrite&#45;&gt;ethdev_tx -->
 <g id="edge12" class="edge">
 <title>ip6_rewrite&#45;&gt;ethdev_tx</title>
-<path fill="none" stroke="green" d="M331.38,-146.17C325.34,-137.6 317.87,-126.99 311.15,-117.44"/>
-<polygon fill="green" stroke="green" points="313.62,-115.87 305,-109.71 307.89,-119.9 313.62,-115.87"/>
+<path fill="none" stroke="green" d="M423.22,-181.44C406.47,-163.86 379.84,-135.91 360.81,-115.94"/>
+<polygon fill="green" stroke="green" points="363.1,-113.27 353.67,-108.45 358.03,-118.1 363.1,-113.27"/>
 </g>
 <!-- ip6_rewrite&#45;&gt;pkt_drop -->
 <g id="edge13" class="edge">
 <title>ip6_rewrite&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M345.67,-145.53C347.02,-134.98 348.56,-121.24 349.23,-109 350.38,-88.27 350.34,-64.81 350.03,-47.04"/>
-<polygon fill="cyan" stroke="cyan" points="353.51,-47.19 349.8,-37.27 346.51,-47.34 353.51,-47.19"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M438.77,-180.67C437.49,-154.09 431.22,-103.19 403,-73 379.35,-47.7 342.93,-34.22 312.02,-27.06"/>
+<polygon fill="cyan" stroke="cyan" points="312.71,-23.63 302.2,-24.95 311.24,-30.47 312.71,-23.63"/>
+</g>
+<!-- ip4_local&#45;&gt;pkt_drop -->
+<g id="edge18" class="edge">
+<title>ip4_local&#45;&gt;pkt_drop</title>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M142.47,-126.87C150.6,-107.23 166.18,-75.04 188,-54 195,-47.25 203.56,-41.45 212.16,-36.63"/>
+<polygon fill="cyan" stroke="cyan" points="213.85,-39.7 221.08,-31.95 210.6,-33.5 213.85,-39.7"/>
 </g>
 </g>
 </svg>
diff --git a/lib/node/ip4_local.c b/lib/node/ip4_local.c
new file mode 100644
index 0000000000..fb31d0f970
--- /dev/null
+++ b/lib/node/ip4_local.c
@@ -0,0 +1,88 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2023 Marvell International Ltd.
+ */
+
+#include <arpa/inet.h>
+#include <sys/socket.h>
+
+#include <rte_ethdev.h>
+#include <rte_ether.h>
+#include <rte_graph.h>
+#include <rte_graph_worker.h>
+#include <rte_ip.h>
+#include <rte_lpm.h>
+#include <rte_hash.h>
+#include <rte_fbk_hash.h>
+#include <rte_jhash.h>
+#include <rte_hash_crc.h>
+
+
+#include "rte_node_ip4_api.h"
+
+#include "node_private.h"
+
+static uint16_t
+ip4_local_node_process_scalar(struct rte_graph *graph, struct rte_node *node,
+			      void **objs, uint16_t nb_objs)
+{
+	void **to_next, **from;
+	uint16_t last_spec = 0;
+	rte_edge_t next_index;
+	struct rte_mbuf *mbuf;
+	uint16_t held = 0;
+	uint32_t l4;
+	int i;
+
+	/* Speculative next */
+	next_index = RTE_NODE_IP4_LOCAL_NEXT_UDP4_INPUT;
+
+	from = objs;
+	to_next = rte_node_next_stream_get(graph, node, next_index, nb_objs);
+	for (i = 0; i < nb_objs; i++) {
+		uint16_t next;
+
+		mbuf = (struct rte_mbuf *)objs[i];
+		l4 = mbuf->packet_type & RTE_PTYPE_L4_MASK;
+
+		next = (l4 == RTE_PTYPE_L4_UDP)
+				? next_index
+				: RTE_NODE_IP4_LOCAL_NEXT_PKT_DROP;
+
+		if (unlikely(next_index != next)) {
+			/* Copy things successfully speculated till now */
+			rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
+			from += last_spec;
+			to_next += last_spec;
+			held += last_spec;
+			last_spec = 0;
+
+			rte_node_enqueue_x1(graph, node, next, from[0]);
+			from += 1;
+		} else {
+			last_spec += 1;
+		}
+	}
+	/* !!! Home run !!! */
+	if (likely(last_spec == nb_objs)) {
+		rte_node_next_stream_move(graph, node, next_index);
+		return nb_objs;
+	}
+	held += last_spec;
+	rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
+	rte_node_next_stream_put(graph, node, next_index, held);
+
+	return nb_objs;
+}
+
+static struct rte_node_register ip4_local_node = {
+	.process = ip4_local_node_process_scalar,
+	.name = "ip4_local",
+
+	.nb_edges = RTE_NODE_IP4_LOCAL_NEXT_PKT_DROP + 1,
+	.next_nodes = {
+		[RTE_NODE_IP4_LOCAL_NEXT_UDP4_INPUT] = "udp4_input",
+		[RTE_NODE_IP4_LOCAL_NEXT_PKT_DROP] = "pkt_drop",
+	},
+};
+
+RTE_NODE_REGISTER(ip4_local_node);
diff --git a/lib/node/ip4_lookup.c b/lib/node/ip4_lookup.c
index 8bce03d7db..d3fc48baf7 100644
--- a/lib/node/ip4_lookup.c
+++ b/lib/node/ip4_lookup.c
@@ -227,6 +227,7 @@ static struct rte_node_register ip4_lookup_node = {
 
 	.nb_edges = RTE_NODE_IP4_LOOKUP_NEXT_MAX,
 	.next_nodes = {
+		[RTE_NODE_IP4_LOOKUP_NEXT_IP4_LOCAL] = "ip4_local",
 		[RTE_NODE_IP4_LOOKUP_NEXT_REWRITE] = "ip4_rewrite",
 		[RTE_NODE_IP4_LOOKUP_NEXT_PKT_DROP] = "pkt_drop",
 	},
diff --git a/lib/node/meson.build b/lib/node/meson.build
index 2fa7c1c8f3..c0d5b09e2f 100644
--- a/lib/node/meson.build
+++ b/lib/node/meson.build
@@ -12,6 +12,7 @@ sources = files(
         'ethdev_rx.c',
         'ethdev_tx.c',
         'ip4_lookup.c',
+        'ip4_local.c',
         'ip4_rewrite.c',
         'ip6_lookup.c',
         'ip6_rewrite.c',
diff --git a/lib/node/rte_node_ip4_api.h b/lib/node/rte_node_ip4_api.h
index 3397da0ae8..405bdd3283 100644
--- a/lib/node/rte_node_ip4_api.h
+++ b/lib/node/rte_node_ip4_api.h
@@ -30,10 +30,22 @@ enum rte_node_ip4_lookup_next {
 	/**< Rewrite node. */
 	RTE_NODE_IP4_LOOKUP_NEXT_PKT_DROP,
 	/**< Packet drop node. */
+	RTE_NODE_IP4_LOOKUP_NEXT_IP4_LOCAL,
+	/** IP Local node. */
 	RTE_NODE_IP4_LOOKUP_NEXT_MAX,
 	/**< Number of next nodes of lookup node. */
 };
 
+/**
+ * IP4 Local next nodes.
+ */
+enum rte_node_ip4_local_next {
+	RTE_NODE_IP4_LOCAL_NEXT_UDP4_INPUT,
+	/**< ip4 Local node. */
+	RTE_NODE_IP4_LOCAL_NEXT_PKT_DROP,
+	/**< Packet drop node. */
+};
+
 /**
  * Add ipv4 route to lookup table.
  *
-- 
2.25.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v2 2/2] node: add UDP v4 support
  2023-07-03 10:05 ` [PATCH v2 1/2] node: add IPv4 local node to handle local pkts Rakesh Kudurumalla
@ 2023-07-03 10:05   ` Rakesh Kudurumalla
  2023-07-04 10:50   ` [PATCH v3 1/2] node: add IPv4 local node to handle local pkts Rakesh Kudurumalla
  1 sibling, 0 replies; 16+ messages in thread
From: Rakesh Kudurumalla @ 2023-07-03 10:05 UTC (permalink / raw)
  To: Jerin Jacob, Kiran Kumar K, Nithin Dabilpuram, Zhirun Yan,
	Pavan Nikhilesh
  Cc: dev, Rakesh Kudurumalla

IPv4 UDP packets are given to application
with specified UDP destination port given
by user.

Signed-off-by: Rakesh Kudurumalla <rkudurumalla@marvell.com>
---
 doc/api/doxy-api-index.md                     |   3 +-
 doc/guides/prog_guide/graph_lib.rst           |  25 ++
 .../img/graph_inbuilt_node_flow.svg           | 165 ++++++++-----
 lib/node/meson.build                          |   2 +
 lib/node/rte_node_udp4_input_api.h            |  60 +++++
 lib/node/udp4_input.c                         | 226 ++++++++++++++++++
 lib/node/version.map                          |   2 +
 7 files changed, 417 insertions(+), 66 deletions(-)
 create mode 100644 lib/node/rte_node_udp4_input_api.h
 create mode 100644 lib/node/udp4_input.c

diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index 3bc8778981..b81777b3fb 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -209,7 +209,8 @@ The public API headers are grouped by topics:
   * graph_nodes:
     [eth_node](@ref rte_node_eth_api.h),
     [ip4_node](@ref rte_node_ip4_api.h),
-    [ip6_node](@ref rte_node_ip6_api.h)
+    [ip6_node](@ref rte_node_ip6_api.h),
+    [udp4_input_node](@ref rte_node_udp4_input_api.h)
 
 - **basic**:
   [bitops](@ref rte_bitops.h),
diff --git a/doc/guides/prog_guide/graph_lib.rst b/doc/guides/prog_guide/graph_lib.rst
index eaa8ee337e..98473383f1 100644
--- a/doc/guides/prog_guide/graph_lib.rst
+++ b/doc/guides/prog_guide/graph_lib.rst
@@ -513,3 +513,28 @@ On packet_type lookup failure, objects are redirected to ``pkt_drop`` node.
 depth to receive to packets.
 To achieve home run, node use ``rte_node_stream_move()`` as mentioned in above
 sections.
+
+udp4_input
+~~~~~~~~~~
+This node is an intermediate node that does udp destination port lookup for
+the received ipv4 packets and the result determines each packets next node.
+
+User registers a new node ``udp4_input`` into graph library during initialization
+and attach user specified node as edege to this node using
+``rte_node_udp4_usr_node_add()``, and create empty hash table with destination
+port and node id as its feilds.
+
+After successful addition of user node as edege, edge id is returned to the user.
+
+User would register ``ip4_lookup`` table with specified ip address and 32 bit as mask
+for ip filtration using api ``rte_node_ip4_route_add()``.
+
+After graph is created user would update hash table with custom port with
+and previously obtained edge id using API ``rte_node_udp4_dst_port_add()``.
+
+When packet is received lpm look up is performed if ip is matched the packet
+is handed over to ip4_local node, then packet is verified for udp proto and
+on success packet is enqueued to ``udp4_input`` node.
+
+Hash lookup is performed in ``udp4_input`` node with registered destination port
+and destination port in UDP packet , on success packet is handed to ``udp_user_node``.
diff --git a/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg b/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg
index 7a3ace48dc..5db96adb01 100644
--- a/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg
+++ b/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg
@@ -39,192 +39,227 @@ digraph dpdk_inbuilt_nodes_flow {
     kernel_tx -> kernel_rx [color="red" style="dashed"]
     ip4_lookup -> ip4_local
     ip4_local -> pkt_drop [color="cyan" style="dashed"]
+    ip4_local -> udp4_input [ label="udpv4"]
+    udp4_input -> udp_user_node
+    udp4_input -> pkt_drop [color="cyan" style="dashed"]
+
 }
 
  -->
 <!-- input nodes -->
 <!-- Title: dpdk_inbuilt_nodes_flow Pages: 1 -->
-<svg width="525pt" height="458pt"
- viewBox="0.00 0.00 524.91 458.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 454)">
+<svg width="631pt" height="437pt"
+ viewBox="0.00 0.00 630.95 437.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 433)">
 <title>dpdk_inbuilt_nodes_flow</title>
-<polygon fill="white" stroke="transparent" points="-4,4 -4,-454 520.91,-454 520.91,4 -4,4"/>
+<polygon fill="white" stroke="transparent" points="-4,4 -4,-433 626.95,-433 626.95,4 -4,4"/>
 <!-- ethdev_rx -->
 <g id="node1" class="node">
 <title>ethdev_rx</title>
-<ellipse fill="none" stroke="green" cx="120" cy="-432" rx="56.59" ry="18"/>
-<text text-anchor="middle" x="120" y="-428.3" font-family="Times,serif" font-size="14.00">ethdev_rx</text>
+<ellipse fill="none" stroke="green" cx="261.95" cy="-411" rx="56.59" ry="18"/>
+<text text-anchor="middle" x="261.95" y="-407.3" font-family="Times,serif" font-size="14.00">ethdev_rx</text>
 </g>
 <!-- pkt_cls -->
 <g id="node6" class="node">
 <title>pkt_cls</title>
-<ellipse fill="none" stroke="red" cx="120" cy="-359" rx="42.79" ry="18"/>
-<text text-anchor="middle" x="120" y="-355.3" font-family="Times,serif" font-size="14.00">pkt_cls</text>
+<ellipse fill="none" stroke="red" cx="261.95" cy="-338" rx="42.79" ry="18"/>
+<text text-anchor="middle" x="261.95" y="-334.3" font-family="Times,serif" font-size="14.00">pkt_cls</text>
 </g>
 <!-- ethdev_rx&#45;&gt;pkt_cls -->
 <g id="edge1" class="edge">
 <title>ethdev_rx&#45;&gt;pkt_cls</title>
-<path fill="none" stroke="black" d="M120,-413.81C120,-405.79 120,-396.05 120,-387.07"/>
-<polygon fill="black" stroke="black" points="123.5,-387.03 120,-377.03 116.5,-387.03 123.5,-387.03"/>
+<path fill="none" stroke="black" d="M261.95,-392.81C261.95,-384.79 261.95,-375.05 261.95,-366.07"/>
+<polygon fill="black" stroke="black" points="265.45,-366.03 261.95,-356.03 258.45,-366.03 265.45,-366.03"/>
 </g>
 <!-- kernel_rx -->
 <g id="node2" class="node">
 <title>kernel_rx</title>
-<ellipse fill="none" stroke="green" cx="82" cy="-199" rx="53.89" ry="18"/>
-<text text-anchor="middle" x="82" y="-195.3" font-family="Times,serif" font-size="14.00">kernel_rx</text>
+<ellipse fill="none" stroke="green" cx="53.95" cy="-178" rx="53.89" ry="18"/>
+<text text-anchor="middle" x="53.95" y="-174.3" font-family="Times,serif" font-size="14.00">kernel_rx</text>
 </g>
 <!-- kernel_rx&#45;&gt;pkt_cls -->
 <g id="edge2" class="edge">
 <title>kernel_rx&#45;&gt;pkt_cls</title>
-<path fill="none" stroke="black" d="M70.87,-216.92C60.28,-235.27 47.29,-265.24 57,-290 64.12,-308.16 78.62,-324.37 91.92,-336.4"/>
-<polygon fill="black" stroke="black" points="89.69,-339.1 99.54,-342.99 94.26,-333.8 89.69,-339.1"/>
+<path fill="none" stroke="black" d="M74.75,-194.8C112.31,-223.33 191.45,-283.45 233.8,-315.62"/>
+<polygon fill="black" stroke="black" points="231.92,-318.59 242,-321.85 236.16,-313.01 231.92,-318.59"/>
 </g>
 <!-- ethdev_tx -->
 <g id="node3" class="node">
 <title>ethdev_tx</title>
-<ellipse fill="none" stroke="magenta" cx="338" cy="-91" rx="55.79" ry="18"/>
-<text text-anchor="middle" x="338" y="-87.3" font-family="Times,serif" font-size="14.00">ethdev_tx</text>
+<ellipse fill="none" stroke="magenta" cx="347.95" cy="-91" rx="55.79" ry="18"/>
+<text text-anchor="middle" x="347.95" y="-87.3" font-family="Times,serif" font-size="14.00">ethdev_tx</text>
 </g>
 <!-- pkt_drop -->
 <g id="node4" class="node">
 <title>pkt_drop</title>
-<ellipse fill="none" stroke="cyan" cx="254" cy="-18" rx="51.99" ry="18"/>
-<text text-anchor="middle" x="254" y="-14.3" font-family="Times,serif" font-size="14.00">pkt_drop</text>
+<ellipse fill="none" stroke="cyan" cx="404.95" cy="-18" rx="51.99" ry="18"/>
+<text text-anchor="middle" x="404.95" y="-14.3" font-family="Times,serif" font-size="14.00">pkt_drop</text>
 </g>
 <!-- ethdev_tx&#45;&gt;pkt_drop -->
 <g id="edge14" class="edge">
 <title>ethdev_tx&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M318.94,-73.89C307.58,-64.29 293,-51.96 280.53,-41.42"/>
-<polygon fill="cyan" stroke="cyan" points="282.59,-38.58 272.7,-34.8 278.07,-43.93 282.59,-38.58"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M361.45,-73.17C368.55,-64.33 377.39,-53.33 385.23,-43.55"/>
+<polygon fill="cyan" stroke="cyan" points="388,-45.69 391.53,-35.71 382.54,-41.31 388,-45.69"/>
 </g>
 <!-- kernel_tx -->
 <g id="node5" class="node">
 <title>kernel_tx</title>
-<ellipse fill="none" stroke="blue" cx="120" cy="-272" rx="53.89" ry="18"/>
-<text text-anchor="middle" x="120" y="-268.3" font-family="Times,serif" font-size="14.00">kernel_tx</text>
+<ellipse fill="none" stroke="blue" cx="53.95" cy="-251" rx="53.89" ry="18"/>
+<text text-anchor="middle" x="53.95" y="-247.3" font-family="Times,serif" font-size="14.00">kernel_tx</text>
 </g>
 <!-- kernel_tx&#45;&gt;kernel_rx -->
 <g id="edge16" class="edge">
 <title>kernel_tx&#45;&gt;kernel_rx</title>
-<path fill="none" stroke="red" stroke-dasharray="5,2" d="M110.99,-254.17C106.52,-245.81 101,-235.51 95.99,-226.14"/>
-<polygon fill="red" stroke="red" points="99.01,-224.36 91.2,-217.2 92.84,-227.67 99.01,-224.36"/>
+<path fill="none" stroke="red" stroke-dasharray="5,2" d="M53.95,-232.81C53.95,-224.79 53.95,-215.05 53.95,-206.07"/>
+<polygon fill="red" stroke="red" points="57.45,-206.03 53.95,-196.03 50.45,-206.03 57.45,-206.03"/>
 </g>
 <!-- pkt_cls&#45;&gt;pkt_drop -->
 <g id="edge15" class="edge">
 <title>pkt_cls&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M84,-348.97C48.65,-337.7 0,-314.61 0,-273 0,-273 0,-273 0,-90 0,-49.99 118.4,-31.52 193.52,-23.82"/>
-<polygon fill="cyan" stroke="cyan" points="194.21,-27.27 203.82,-22.81 193.52,-20.31 194.21,-27.27"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M304.77,-335.88C400.4,-332.2 622.95,-316.71 622.95,-252 622.95,-252 622.95,-252 622.95,-90 622.95,-56.33 527.72,-36.15 463.14,-26.34"/>
+<polygon fill="cyan" stroke="cyan" points="463.46,-22.85 453.06,-24.85 462.44,-29.77 463.46,-22.85"/>
 </g>
 <!-- pkt_cls&#45;&gt;kernel_tx -->
 <g id="edge5" class="edge">
 <title>pkt_cls&#45;&gt;kernel_tx</title>
-<path fill="none" stroke="blue" d="M120,-340.8C120,-329.16 120,-313.55 120,-300.24"/>
-<polygon fill="blue" stroke="blue" points="123.5,-300.18 120,-290.18 116.5,-300.18 123.5,-300.18"/>
-<text text-anchor="middle" x="172.5" y="-311.8" font-family="Times,serif" font-size="14.00">exception pkts</text>
+<path fill="none" stroke="blue" d="M219.14,-335.96C164.86,-333.64 75.77,-326.15 54.95,-302 49.6,-295.81 48.06,-287.4 48.24,-279.24"/>
+<polygon fill="blue" stroke="blue" points="51.73,-279.54 49.23,-269.24 44.76,-278.84 51.73,-279.54"/>
+<text text-anchor="middle" x="107.45" y="-290.8" font-family="Times,serif" font-size="14.00">exception pkts</text>
 </g>
 <!-- ip4_lookup -->
 <g id="node7" class="node">
 <title>ip4_lookup</title>
-<ellipse fill="none" stroke="black" cx="252" cy="-272" rx="60.39" ry="18"/>
-<text text-anchor="middle" x="252" y="-268.3" font-family="Times,serif" font-size="14.00">ip4_lookup</text>
+<ellipse fill="none" stroke="black" cx="261.95" cy="-251" rx="60.39" ry="18"/>
+<text text-anchor="middle" x="261.95" y="-247.3" font-family="Times,serif" font-size="14.00">ip4_lookup</text>
 </g>
 <!-- pkt_cls&#45;&gt;ip4_lookup -->
 <g id="edge3" class="edge">
 <title>pkt_cls&#45;&gt;ip4_lookup</title>
-<path fill="none" stroke="black" d="M160.54,-352.79C182.64,-348.15 209.23,-339.41 228,-323 235.09,-316.81 240.26,-308.05 243.95,-299.6"/>
-<polygon fill="black" stroke="black" points="247.32,-300.57 247.62,-289.98 240.78,-298.07 247.32,-300.57"/>
-<text text-anchor="middle" x="254.5" y="-311.8" font-family="Times,serif" font-size="14.00">ipv4</text>
+<path fill="none" stroke="black" d="M261.95,-319.8C261.95,-308.16 261.95,-292.55 261.95,-279.24"/>
+<polygon fill="black" stroke="black" points="265.45,-279.18 261.95,-269.18 258.45,-279.18 265.45,-279.18"/>
+<text text-anchor="middle" x="277.45" y="-290.8" font-family="Times,serif" font-size="14.00">ipv4</text>
 </g>
 <!-- ip6_lookup -->
 <g id="node8" class="node">
 <title>ip6_lookup</title>
-<ellipse fill="none" stroke="black" cx="439" cy="-272" rx="60.39" ry="18"/>
-<text text-anchor="middle" x="439" y="-268.3" font-family="Times,serif" font-size="14.00">ip6_lookup</text>
+<ellipse fill="none" stroke="black" cx="492.95" cy="-251" rx="60.39" ry="18"/>
+<text text-anchor="middle" x="492.95" y="-247.3" font-family="Times,serif" font-size="14.00">ip6_lookup</text>
 </g>
 <!-- pkt_cls&#45;&gt;ip6_lookup -->
 <g id="edge4" class="edge">
 <title>pkt_cls&#45;&gt;ip6_lookup</title>
-<path fill="none" stroke="black" d="M157.52,-350.25C188.82,-343.6 234.51,-333.46 274,-323 313.2,-312.62 357.13,-299.22 389.79,-288.91"/>
-<polygon fill="black" stroke="black" points="391.08,-292.17 399.55,-285.81 388.96,-285.5 391.08,-292.17"/>
-<text text-anchor="middle" x="339.5" y="-311.8" font-family="Times,serif" font-size="14.00">ipv6</text>
+<path fill="none" stroke="black" d="M293.1,-325.54C332.57,-311.01 400.93,-285.86 446.54,-269.07"/>
+<polygon fill="black" stroke="black" points="448.02,-272.26 456.2,-265.52 445.61,-265.69 448.02,-272.26"/>
+<text text-anchor="middle" x="407.45" y="-290.8" font-family="Times,serif" font-size="14.00">ipv6</text>
 </g>
 <!-- ip4_lookup&#45;&gt;pkt_drop -->
 <g id="edge7" class="edge">
 <title>ip4_lookup&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M239.17,-254.03C232.31,-243.87 224.56,-230.37 221,-217 204.89,-156.57 227.58,-83.56 242.59,-45.31"/>
-<polygon fill="cyan" stroke="cyan" points="245.89,-46.5 246.4,-35.92 239.4,-43.87 245.89,-46.5"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M258.85,-232.91C253.68,-198.83 247.1,-121.54 282.95,-73 299.1,-51.12 326.1,-37.95 350.6,-30.11"/>
+<polygon fill="cyan" stroke="cyan" points="351.6,-33.46 360.19,-27.26 349.61,-26.75 351.6,-33.46"/>
 </g>
 <!-- ip4_rewrite -->
 <g id="node9" class="node">
 <title>ip4_rewrite</title>
-<ellipse fill="none" stroke="black" cx="294" cy="-199" rx="63.89" ry="18"/>
-<text text-anchor="middle" x="294" y="-195.3" font-family="Times,serif" font-size="14.00">ip4_rewrite</text>
+<ellipse fill="none" stroke="black" cx="347.95" cy="-178" rx="63.89" ry="18"/>
+<text text-anchor="middle" x="347.95" y="-174.3" font-family="Times,serif" font-size="14.00">ip4_rewrite</text>
 </g>
 <!-- ip4_lookup&#45;&gt;ip4_rewrite -->
 <g id="edge6" class="edge">
 <title>ip4_lookup&#45;&gt;ip4_rewrite</title>
-<path fill="none" stroke="black" d="M261.95,-254.17C266.95,-245.72 273.12,-235.29 278.71,-225.85"/>
-<polygon fill="black" stroke="black" points="281.75,-227.59 283.83,-217.2 275.72,-224.02 281.75,-227.59"/>
+<path fill="none" stroke="black" d="M281.46,-233.89C292.92,-224.42 307.6,-212.31 320.25,-201.87"/>
+<polygon fill="black" stroke="black" points="322.73,-204.36 328.21,-195.29 318.27,-198.96 322.73,-204.36"/>
 </g>
 <!-- ip4_local -->
 <g id="node11" class="node">
 <title>ip4_local</title>
-<ellipse fill="none" stroke="black" cx="136" cy="-145" rx="51.19" ry="18"/>
-<text text-anchor="middle" x="136" y="-141.3" font-family="Times,serif" font-size="14.00">ip4_local</text>
+<ellipse fill="none" stroke="black" cx="176.95" cy="-178" rx="51.19" ry="18"/>
+<text text-anchor="middle" x="176.95" y="-174.3" font-family="Times,serif" font-size="14.00">ip4_local</text>
 </g>
 <!-- ip4_lookup&#45;&gt;ip4_local -->
 <g id="edge17" class="edge">
 <title>ip4_lookup&#45;&gt;ip4_local</title>
-<path fill="none" stroke="black" d="M218.11,-256.86C207.64,-251.39 196.61,-244.41 188,-236 169.45,-217.88 155.34,-191.74 146.53,-172.29"/>
-<polygon fill="black" stroke="black" points="149.72,-170.86 142.52,-163.08 143.3,-173.65 149.72,-170.86"/>
+<path fill="none" stroke="black" d="M242.66,-233.89C231.17,-224.29 216.41,-211.96 203.79,-201.42"/>
+<polygon fill="black" stroke="black" points="205.78,-198.53 195.86,-194.8 201.29,-203.9 205.78,-198.53"/>
 </g>
 <!-- ip6_lookup&#45;&gt;pkt_drop -->
 <g id="edge11" class="edge">
 <title>ip6_lookup&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M470.57,-256.44C486.08,-247.46 503.27,-234.31 512,-217 519.2,-202.71 517.24,-196.12 512,-181 486.88,-108.48 466,-83.15 395,-54 367.69,-42.79 335.88,-34.51 309.39,-28.83"/>
-<polygon fill="cyan" stroke="cyan" points="310.02,-25.39 299.52,-26.78 308.6,-32.24 310.02,-25.39"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M524.51,-235.44C540.02,-226.46 557.22,-213.31 565.95,-196 573.15,-181.71 572.55,-174.57 565.95,-160 540.59,-104.08 480.88,-61.6 441.74,-38.51"/>
+<polygon fill="cyan" stroke="cyan" points="443.16,-35.29 432.75,-33.34 439.67,-41.36 443.16,-35.29"/>
 </g>
 <!-- ip6_rewrite -->
 <g id="node10" class="node">
 <title>ip6_rewrite</title>
-<ellipse fill="none" stroke="black" cx="439" cy="-199" rx="63.89" ry="18"/>
-<text text-anchor="middle" x="439" y="-195.3" font-family="Times,serif" font-size="14.00">ip6_rewrite</text>
+<ellipse fill="none" stroke="black" cx="492.95" cy="-178" rx="63.89" ry="18"/>
+<text text-anchor="middle" x="492.95" y="-174.3" font-family="Times,serif" font-size="14.00">ip6_rewrite</text>
 </g>
 <!-- ip6_lookup&#45;&gt;ip6_rewrite -->
 <g id="edge10" class="edge">
 <title>ip6_lookup&#45;&gt;ip6_rewrite</title>
-<path fill="none" stroke="black" d="M439,-253.81C439,-245.79 439,-236.05 439,-227.07"/>
-<polygon fill="black" stroke="black" points="442.5,-227.03 439,-217.03 435.5,-227.03 442.5,-227.03"/>
+<path fill="none" stroke="black" d="M492.95,-232.81C492.95,-224.79 492.95,-215.05 492.95,-206.07"/>
+<polygon fill="black" stroke="black" points="496.45,-206.03 492.95,-196.03 489.45,-206.03 496.45,-206.03"/>
 </g>
 <!-- ip4_rewrite&#45;&gt;ethdev_tx -->
 <g id="edge8" class="edge">
 <title>ip4_rewrite&#45;&gt;ethdev_tx</title>
-<path fill="none" stroke="green" d="M301.07,-180.97C308.09,-164.05 318.96,-137.86 327.09,-118.28"/>
-<polygon fill="green" stroke="green" points="330.35,-119.57 330.95,-108.99 323.88,-116.88 330.35,-119.57"/>
+<path fill="none" stroke="green" d="M347.95,-159.8C347.95,-148.16 347.95,-132.55 347.95,-119.24"/>
+<polygon fill="green" stroke="green" points="351.45,-119.18 347.95,-109.18 344.45,-119.18 351.45,-119.18"/>
 </g>
 <!-- ip4_rewrite&#45;&gt;pkt_drop -->
 <g id="edge9" class="edge">
 <title>ip4_rewrite&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M289.85,-180.97C285.53,-163.07 278.61,-134.1 273,-109 268.3,-87.99 263.29,-64.16 259.59,-46.3"/>
-<polygon fill="cyan" stroke="cyan" points="262.97,-45.37 257.52,-36.28 256.11,-46.78 262.97,-45.37"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M370.32,-161.1C385.53,-148.83 404.37,-130.37 412.95,-109 421.04,-88.82 418.02,-64.12 413.56,-45.7"/>
+<polygon fill="cyan" stroke="cyan" points="416.9,-44.66 410.91,-35.93 410.15,-46.49 416.9,-44.66"/>
 </g>
 <!-- ip6_rewrite&#45;&gt;ethdev_tx -->
 <g id="edge12" class="edge">
 <title>ip6_rewrite&#45;&gt;ethdev_tx</title>
-<path fill="none" stroke="green" d="M423.22,-181.44C406.47,-163.86 379.84,-135.91 360.81,-115.94"/>
-<polygon fill="green" stroke="green" points="363.1,-113.27 353.67,-108.45 358.03,-118.1 363.1,-113.27"/>
+<path fill="none" stroke="green" d="M466.35,-161.41C442.8,-147.6 408.27,-127.36 382.57,-112.3"/>
+<polygon fill="green" stroke="green" points="384.28,-109.24 373.88,-107.21 380.74,-115.28 384.28,-109.24"/>
 </g>
 <!-- ip6_rewrite&#45;&gt;pkt_drop -->
 <g id="edge13" class="edge">
 <title>ip6_rewrite&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M438.77,-180.67C437.49,-154.09 431.22,-103.19 403,-73 379.35,-47.7 342.93,-34.22 312.02,-27.06"/>
-<polygon fill="cyan" stroke="cyan" points="312.71,-23.63 302.2,-24.95 311.24,-30.47 312.71,-23.63"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M485.15,-159.86C473.93,-135.7 452.15,-90.48 429.95,-54 427.97,-50.75 425.78,-47.4 423.55,-44.13"/>
+<polygon fill="cyan" stroke="cyan" points="426.28,-41.92 417.67,-35.75 420.55,-45.94 426.28,-41.92"/>
 </g>
 <!-- ip4_local&#45;&gt;pkt_drop -->
 <g id="edge18" class="edge">
 <title>ip4_local&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M142.47,-126.87C150.6,-107.23 166.18,-75.04 188,-54 195,-47.25 203.56,-41.45 212.16,-36.63"/>
-<polygon fill="cyan" stroke="cyan" points="213.85,-39.7 221.08,-31.95 210.6,-33.5 213.85,-39.7"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M191.02,-160.51C195.47,-154.86 200.21,-148.35 203.95,-142 225.57,-105.29 209.02,-81.03 241.95,-54 257.83,-40.96 306.22,-31.62 346.19,-25.89"/>
+<polygon fill="cyan" stroke="cyan" points="346.72,-29.35 356.14,-24.51 345.75,-22.41 346.72,-29.35"/>
+</g>
+<!-- udp4_input -->
+<g id="node12" class="node">
+<title>udp4_input</title>
+<ellipse fill="none" stroke="black" cx="126.95" cy="-91" rx="63.09" ry="18"/>
+<text text-anchor="middle" x="126.95" y="-87.3" font-family="Times,serif" font-size="14.00">udp4_input</text>
+</g>
+<!-- ip4_local&#45;&gt;udp4_input -->
+<g id="edge19" class="edge">
+<title>ip4_local&#45;&gt;udp4_input</title>
+<path fill="none" stroke="black" d="M167.07,-160.21C159.99,-148.18 150.33,-131.75 142.26,-118.03"/>
+<polygon fill="black" stroke="black" points="145.06,-115.89 136.97,-109.05 139.03,-119.44 145.06,-115.89"/>
+<text text-anchor="middle" x="177.45" y="-130.8" font-family="Times,serif" font-size="14.00">udpv4</text>
+</g>
+<!-- udp4_input&#45;&gt;pkt_drop -->
+<g id="edge21" class="edge">
+<title>udp4_input&#45;&gt;pkt_drop</title>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M154.75,-74.82C169.08,-67.56 187.05,-59.32 203.95,-54 250.51,-39.35 305.19,-30.33 345.76,-25.12"/>
+<polygon fill="cyan" stroke="cyan" points="346.26,-28.59 355.75,-23.88 345.4,-21.64 346.26,-28.59"/>
+</g>
+<!-- udp_user_node -->
+<g id="node13" class="node">
+<title>udp_user_node</title>
+<ellipse fill="none" stroke="black" cx="126.95" cy="-18" rx="79.89" ry="18"/>
+<text text-anchor="middle" x="126.95" y="-14.3" font-family="Times,serif" font-size="14.00">udp_user_node</text>
+</g>
+<!-- udp4_input&#45;&gt;udp_user_node -->
+<g id="edge20" class="edge">
+<title>udp4_input&#45;&gt;udp_user_node</title>
+<path fill="none" stroke="black" d="M126.95,-72.81C126.95,-64.79 126.95,-55.05 126.95,-46.07"/>
+<polygon fill="black" stroke="black" points="130.45,-46.03 126.95,-36.03 123.45,-46.03 130.45,-46.03"/>
 </g>
 </g>
 </svg>
diff --git a/lib/node/meson.build b/lib/node/meson.build
index c0d5b09e2f..c5b8ee656e 100644
--- a/lib/node/meson.build
+++ b/lib/node/meson.build
@@ -22,11 +22,13 @@ sources = files(
         'null.c',
         'pkt_cls.c',
         'pkt_drop.c',
+        'udp4_input.c',
 )
 headers = files(
         'rte_node_eth_api.h',
         'rte_node_ip4_api.h',
         'rte_node_ip6_api.h',
+        'rte_node_udp4_input_api.h',
 )
 
 # Strict-aliasing rules are violated by uint8_t[] to context size casts.
diff --git a/lib/node/rte_node_udp4_input_api.h b/lib/node/rte_node_udp4_input_api.h
new file mode 100644
index 0000000000..7217b914ec
--- /dev/null
+++ b/lib/node/rte_node_udp4_input_api.h
@@ -0,0 +1,60 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2023 Marvell International Ltd.
+ */
+
+#ifndef __INCLUDE_RTE_NODE_UDP4_INPUT_API_H__
+#define __INCLUDE_RTE_NODE_UDP4_INPUT_API_H__
+
+/**
+ * @file rte_node_udp4_input_api.h
+ *
+ * @warning
+ * @b EXPERIMENTAL:
+ * All functions in this file may be changed or removed without prior notice.
+ *
+ * This API allows to control path functions of udp4_* nodes
+ * like udp4_input.
+ *
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rte_common.h>
+#include <rte_compat.h>
+
+/**
+ * UDP4 lookup next nodes.
+ */
+enum rte_node_udp4_input_next {
+	RTE_NODE_UDP4_INPUT_NEXT_PKT_DROP,
+	/**< Packet drop node. */
+};
+
+/**
+ * Add usr node to receive udp4 frames.
+ *
+ * @param usr_node
+ * Node registered by user to receive data.
+ */
+__rte_experimental
+int rte_node_udp4_usr_node_add(const char *usr_node);
+
+/**
+ * Add udpv4 dst_port to lookup table.
+ *
+ * @param dst_port
+ *   Dst Port of packet to be added for consumption.
+ * @param next_node
+ *   Next node packet to be added for consumption.
+ * @return
+ *   0 on success, negative otherwise.
+ */
+__rte_experimental
+int rte_node_udp4_dst_port_add(uint32_t dst_port, rte_edge_t next_node);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __INCLUDE_RTE_NODE_UDP4_API_H__ */
diff --git a/lib/node/udp4_input.c b/lib/node/udp4_input.c
new file mode 100644
index 0000000000..bc7f7d8fb3
--- /dev/null
+++ b/lib/node/udp4_input.c
@@ -0,0 +1,226 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2023 Marvell International Ltd.
+ */
+
+#include <arpa/inet.h>
+#include <sys/socket.h>
+
+#include <rte_ethdev.h>
+#include <rte_ether.h>
+#include <rte_graph.h>
+#include <rte_graph_worker.h>
+#include <rte_ip.h>
+#include <rte_lpm.h>
+#include <rte_hash.h>
+#include <rte_fbk_hash.h>
+#include <rte_jhash.h>
+#include <rte_hash_crc.h>
+
+
+#include "rte_node_udp4_input_api.h"
+
+#include "node_private.h"
+
+#define UDP4_INPUT_HASH_TBL_SIZE 1024
+
+#define UDP4_INPUT_NODE_HASH(ctx) \
+	(((struct udp4_input_node_ctx *)ctx)->hash)
+
+#define UDP4_INPUT_NODE_NEXT_INDEX(ctx) \
+	(((struct udp4_input_node_ctx *)ctx)->next_index)
+
+
+static struct udp4_input_node_main udp4_input_nm;
+
+/* UDP4 input  global data struct */
+struct udp4_input_node_main {
+	struct rte_hash *hash_tbl[RTE_MAX_NUMA_NODES];
+};
+
+struct udp4_input_node_ctx {
+	/* Socket's Hash table */
+	struct rte_hash *hash;
+	/* Cached next index */
+	uint16_t next_index;
+};
+
+struct flow_key {
+	uint32_t prt_dst;
+};
+
+static struct rte_hash_parameters udp4_params = {
+	.entries = UDP4_INPUT_HASH_TBL_SIZE,
+	.key_len = sizeof(uint32_t),
+	.hash_func = rte_jhash,
+	.hash_func_init_val = 0,
+	.socket_id = 0,
+};
+
+int
+rte_node_udp4_dst_port_add(uint32_t dst_port, rte_edge_t next_node)
+{
+	uint8_t socket;
+	int rc;
+
+	for (socket = 0; socket < RTE_MAX_NUMA_NODES; socket++) {
+		if (!udp4_input_nm.hash_tbl[socket])
+			continue;
+
+		rc = rte_hash_add_key_data(udp4_input_nm.hash_tbl[socket],
+					   &dst_port, (void *)(uintptr_t)next_node);
+		if (rc < 0) {
+			node_err("udp4_lookup", "Failed to add key for sock %u, rc=%d",
+					socket, rc);
+			return rc;
+		}
+	}
+	return 0;
+}
+
+int
+rte_node_udp4_usr_node_add(const char *usr_node)
+{
+	const char *next_nodes = usr_node;
+	rte_node_t udp4_input_node_id, count;
+
+	udp4_input_node_id = rte_node_from_name("udp4_input");
+	count = rte_node_edge_update(udp4_input_node_id, RTE_EDGE_ID_INVALID,
+				     &next_nodes, 1);
+	if (count == 0) {
+		node_dbg("udp4_input", "Adding usr node as edge to udp4_input failed");
+		return count;
+	}
+	count = rte_node_edge_count(udp4_input_node_id) - 1;
+	return count;
+}
+
+static int
+setup_udp4_dstprt_hash(struct udp4_input_node_main *nm, int socket)
+{
+	struct rte_hash_parameters *hash_udp4 = &udp4_params;
+	char s[RTE_HASH_NAMESIZE];
+
+	/* One Hash table per socket */
+	if (nm->hash_tbl[socket])
+		return 0;
+
+	/* create Hash table */
+	snprintf(s, sizeof(s), "UDP4_INPUT_HASH_%d", socket);
+	hash_udp4->name = s;
+	hash_udp4->socket_id = socket;
+	nm->hash_tbl[socket] = rte_hash_create(hash_udp4);
+	if (nm->hash_tbl[socket] == NULL)
+		return -rte_errno;
+
+	return 0;
+}
+
+static int
+udp4_input_node_init(const struct rte_graph *graph, struct rte_node *node)
+{
+	uint16_t socket, lcore_id;
+	static uint8_t init_once;
+	int rc;
+
+	RTE_SET_USED(graph);
+	RTE_BUILD_BUG_ON(sizeof(struct udp4_input_node_ctx) > RTE_NODE_CTX_SZ);
+
+	if (!init_once) {
+
+		/* Setup HASH tables for all sockets */
+		RTE_LCORE_FOREACH(lcore_id)
+		{
+			socket = rte_lcore_to_socket_id(lcore_id);
+			rc = setup_udp4_dstprt_hash(&udp4_input_nm, socket);
+			if (rc) {
+				node_err("udp4_lookup",
+						"Failed to setup hash tbl for sock %u, rc=%d",
+						socket, rc);
+				return rc;
+			}
+		}
+		init_once = 1;
+	}
+
+	UDP4_INPUT_NODE_HASH(node->ctx) = udp4_input_nm.hash_tbl[graph->socket];
+
+	node_dbg("udp4_input", "Initialized udp4_input node");
+	return 0;
+}
+
+static uint16_t
+udp4_input_node_process_scalar(struct rte_graph *graph, struct rte_node *node,
+			       void **objs, uint16_t nb_objs)
+{
+	struct rte_hash *hash_tbl_handle = UDP4_INPUT_NODE_HASH(node->ctx);
+	rte_edge_t next_index, udplookup_node;
+	struct rte_udp_hdr *pkt_udp_hdr;
+	uint16_t last_spec = 0;
+	void **to_next, **from;
+	struct rte_mbuf *mbuf;
+	uint16_t held = 0;
+	uint16_t next = 0;
+	int i, rc;
+
+	/* Speculative next */
+	next_index = UDP4_INPUT_NODE_NEXT_INDEX(node->ctx);
+
+	from = objs;
+
+	to_next = rte_node_next_stream_get(graph, node, next_index, nb_objs);
+	for (i = 0; i < nb_objs; i++) {
+		struct flow_key key_port;
+
+		mbuf = (struct rte_mbuf *)objs[i];
+		pkt_udp_hdr = rte_pktmbuf_mtod_offset(mbuf, struct rte_udp_hdr *,
+						sizeof(struct rte_ether_hdr) +
+						sizeof(struct rte_ipv4_hdr));
+
+		key_port.prt_dst = rte_cpu_to_be_16(pkt_udp_hdr->dst_port);
+		rc = rte_hash_lookup_data(hash_tbl_handle,
+					  &key_port.prt_dst,
+					  (void **)&udplookup_node);
+		next = (rc < 0) ? RTE_NODE_UDP4_INPUT_NEXT_PKT_DROP
+				    : udplookup_node;
+
+		if (unlikely(next_index != next)) {
+			/* Copy things successfully speculated till now */
+			rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
+			from += last_spec;
+			to_next += last_spec;
+			held += last_spec;
+			last_spec = 0;
+
+			rte_node_enqueue_x1(graph, node, next, from[0]);
+			from += 1;
+		} else {
+			last_spec += 1;
+		}
+	}
+	/* !!! Home run !!! */
+	if (likely(last_spec == nb_objs)) {
+		rte_node_next_stream_move(graph, node, next_index);
+		return nb_objs;
+	}
+	held += last_spec;
+	rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
+	rte_node_next_stream_put(graph, node, next_index, held);
+	/* Save the last next used */
+	UDP4_INPUT_NODE_NEXT_INDEX(node->ctx) = next;
+
+	return nb_objs;
+}
+
+static struct rte_node_register udp4_input_node = {
+	.process = udp4_input_node_process_scalar,
+	.name = "udp4_input",
+
+	.init = udp4_input_node_init,
+
+	.nb_edges = RTE_NODE_UDP4_INPUT_NEXT_PKT_DROP + 1,
+	.next_nodes = {
+		[RTE_NODE_UDP4_INPUT_NEXT_PKT_DROP] = "pkt_drop",
+	},
+};
+
+RTE_NODE_REGISTER(udp4_input_node);
diff --git a/lib/node/version.map b/lib/node/version.map
index 40df308bfe..c51befce09 100644
--- a/lib/node/version.map
+++ b/lib/node/version.map
@@ -6,6 +6,8 @@ EXPERIMENTAL {
 	rte_node_ip4_rewrite_add;
 	rte_node_ip6_rewrite_add;
 	rte_node_ip6_route_add;
+	rte_node_udp4_usr_node_add;
+	rte_node_udp4_dst_port_add;
 	rte_node_logtype;
 	local: *;
 };
-- 
2.25.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v3 1/2] node: add IPv4 local node to handle local pkts
  2023-07-03 10:05 ` [PATCH v2 1/2] node: add IPv4 local node to handle local pkts Rakesh Kudurumalla
  2023-07-03 10:05   ` [PATCH v2 2/2] node: add UDP v4 support Rakesh Kudurumalla
@ 2023-07-04 10:50   ` Rakesh Kudurumalla
  2023-07-04 10:50     ` [PATCH v3 2/2] node: add UDP v4 support Rakesh Kudurumalla
  2023-09-27  9:21     ` [PATCH v4 1/2] node: add IPv4 local node to handle local pkts Rakesh Kudurumalla
  1 sibling, 2 replies; 16+ messages in thread
From: Rakesh Kudurumalla @ 2023-07-04 10:50 UTC (permalink / raw)
  To: Jerin Jacob, Kiran Kumar K, Nithin Dabilpuram, Zhirun Yan,
	Pavan Nikhilesh
  Cc: dev, Rakesh Kudurumalla

Local or Host destined pkts can be redirected IPv4 local node
using IP4 Lookup node entries with prefix of 32 and be redirected
to this IP4 local node for further processing.

Signed-off-by: Rakesh Kudurumalla <rkudurumalla@marvell.com>
---
Depends-on: series-28622 ("add inbuilt graph nodes data flow")

v3 :
   - Resolve compilation issue

 doc/guides/prog_guide/graph_lib.rst           |  15 ++
 .../img/graph_inbuilt_node_flow.svg           | 138 ++++++++++--------
 lib/node/ip4_local.c                          |  88 +++++++++++
 lib/node/ip4_lookup.c                         |   1 +
 lib/node/meson.build                          |   1 +
 lib/node/rte_node_ip4_api.h                   |  12 ++
 6 files changed, 196 insertions(+), 59 deletions(-)
 create mode 100644 lib/node/ip4_local.c

diff --git a/doc/guides/prog_guide/graph_lib.rst b/doc/guides/prog_guide/graph_lib.rst
index 96af29e8da..eaa8ee337e 100644
--- a/doc/guides/prog_guide/graph_lib.rst
+++ b/doc/guides/prog_guide/graph_lib.rst
@@ -498,3 +498,18 @@ Uses ``poll`` function to poll on the socket fd
 for ``POLLIN`` events to read the packets from raw socket
 to stream buffer and does ``rte_node_next_stream_move()``
 when there are received packets.
+
+ip4_local
+~~~~~~~~~
+This node is an intermediate node that does ``packet_type`` lookup for
+the received ipv4 packets and the result determines each packets next node.
+
+On successful ``packet_type`` lookup, for any IPv4 protocol the result
+contains the ``next_node`` id and ``next-hop`` id with which the packet
+needs to be further processed.
+
+On packet_type lookup failure, objects are redirected to ``pkt_drop`` node.
+``rte_node_ip4_route_add()`` is control path API to add ipv4 address with 32 bit
+depth to receive to packets.
+To achieve home run, node use ``rte_node_stream_move()`` as mentioned in above
+sections.
diff --git a/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg b/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg
index 02fe768dfe..7a3ace48dc 100644
--- a/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg
+++ b/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg
@@ -37,174 +37,194 @@ digraph dpdk_inbuilt_nodes_flow {
     ethdev_tx -> pkt_drop [color="cyan" style="dashed"]
     pkt_cls->pkt_drop   [color="cyan" style="dashed"]
     kernel_tx -> kernel_rx [color="red" style="dashed"]
+    ip4_lookup -> ip4_local
+    ip4_local -> pkt_drop [color="cyan" style="dashed"]
 }
 
  -->
 <!-- input nodes -->
 <!-- Title: dpdk_inbuilt_nodes_flow Pages: 1 -->
-<svg width="470pt" height="425pt"
- viewBox="0.00 0.00 470.23 424.50" 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 420.5)">
+<svg width="525pt" height="458pt"
+ viewBox="0.00 0.00 524.91 458.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 454)">
 <title>dpdk_inbuilt_nodes_flow</title>
-<polygon fill="white" stroke="none" points="-4,4 -4,-420.5 466.23,-420.5 466.23,4 -4,4"/>
+<polygon fill="white" stroke="transparent" points="-4,4 -4,-454 520.91,-454 520.91,4 -4,4"/>
 <!-- ethdev_rx -->
 <g id="node1" class="node">
 <title>ethdev_rx</title>
-<ellipse fill="none" stroke="green" cx="219.23" cy="-398.5" rx="47.77" ry="18"/>
-<text text-anchor="middle" x="219.23" y="-393.45" font-family="Times,serif" font-size="14.00">ethdev_rx</text>
+<ellipse fill="none" stroke="green" cx="120" cy="-432" rx="56.59" ry="18"/>
+<text text-anchor="middle" x="120" y="-428.3" font-family="Times,serif" font-size="14.00">ethdev_rx</text>
 </g>
 <!-- pkt_cls -->
 <g id="node6" class="node">
 <title>pkt_cls</title>
-<ellipse fill="none" stroke="red" cx="219.23" cy="-325.5" rx="37.53" ry="18"/>
-<text text-anchor="middle" x="219.23" y="-320.45" font-family="Times,serif" font-size="14.00">pkt_cls</text>
+<ellipse fill="none" stroke="red" cx="120" cy="-359" rx="42.79" ry="18"/>
+<text text-anchor="middle" x="120" y="-355.3" font-family="Times,serif" font-size="14.00">pkt_cls</text>
 </g>
 <!-- ethdev_rx&#45;&gt;pkt_cls -->
 <g id="edge1" class="edge">
 <title>ethdev_rx&#45;&gt;pkt_cls</title>
-<path fill="none" stroke="black" d="M219.23,-380.31C219.23,-372.55 219.23,-363.18 219.23,-354.45"/>
-<polygon fill="black" stroke="black" points="222.73,-354.53 219.23,-344.53 215.73,-354.53 222.73,-354.53"/>
+<path fill="none" stroke="black" d="M120,-413.81C120,-405.79 120,-396.05 120,-387.07"/>
+<polygon fill="black" stroke="black" points="123.5,-387.03 120,-377.03 116.5,-387.03 123.5,-387.03"/>
 </g>
 <!-- kernel_rx -->
 <g id="node2" class="node">
 <title>kernel_rx</title>
-<ellipse fill="none" stroke="green" cx="46.23" cy="-164" rx="46.23" ry="18"/>
-<text text-anchor="middle" x="46.23" y="-158.95" font-family="Times,serif" font-size="14.00">kernel_rx</text>
+<ellipse fill="none" stroke="green" cx="82" cy="-199" rx="53.89" ry="18"/>
+<text text-anchor="middle" x="82" y="-195.3" font-family="Times,serif" font-size="14.00">kernel_rx</text>
 </g>
 <!-- kernel_rx&#45;&gt;pkt_cls -->
 <g id="edge2" class="edge">
 <title>kernel_rx&#45;&gt;pkt_cls</title>
-<path fill="none" stroke="black" d="M41.45,-182.08C37.1,-201.37 33.27,-232.96 47.23,-255 73.68,-296.74 130.21,-313.41 171.26,-320.07"/>
-<polygon fill="black" stroke="black" points="170.73,-323.68 181.13,-321.66 171.74,-316.75 170.73,-323.68"/>
+<path fill="none" stroke="black" d="M70.87,-216.92C60.28,-235.27 47.29,-265.24 57,-290 64.12,-308.16 78.62,-324.37 91.92,-336.4"/>
+<polygon fill="black" stroke="black" points="89.69,-339.1 99.54,-342.99 94.26,-333.8 89.69,-339.1"/>
 </g>
 <!-- ethdev_tx -->
 <g id="node3" class="node">
 <title>ethdev_tx</title>
-<ellipse fill="none" stroke="magenta" cx="293.23" cy="-91" rx="47.26" ry="18"/>
-<text text-anchor="middle" x="293.23" y="-85.95" font-family="Times,serif" font-size="14.00">ethdev_tx</text>
+<ellipse fill="none" stroke="magenta" cx="338" cy="-91" rx="55.79" ry="18"/>
+<text text-anchor="middle" x="338" y="-87.3" font-family="Times,serif" font-size="14.00">ethdev_tx</text>
 </g>
 <!-- pkt_drop -->
 <g id="node4" class="node">
 <title>pkt_drop</title>
-<ellipse fill="none" stroke="cyan" cx="349.23" cy="-18" rx="44.19" ry="18"/>
-<text text-anchor="middle" x="349.23" y="-12.95" font-family="Times,serif" font-size="14.00">pkt_drop</text>
+<ellipse fill="none" stroke="cyan" cx="254" cy="-18" rx="51.99" ry="18"/>
+<text text-anchor="middle" x="254" y="-14.3" font-family="Times,serif" font-size="14.00">pkt_drop</text>
 </g>
 <!-- ethdev_tx&#45;&gt;pkt_drop -->
 <g id="edge14" class="edge">
 <title>ethdev_tx&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M306.22,-73.53C313.15,-64.75 321.81,-53.76 329.55,-43.96"/>
-<polygon fill="cyan" stroke="cyan" points="332.87,-46.4 336.32,-36.38 327.37,-42.06 332.87,-46.4"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M318.94,-73.89C307.58,-64.29 293,-51.96 280.53,-41.42"/>
+<polygon fill="cyan" stroke="cyan" points="282.59,-38.58 272.7,-34.8 278.07,-43.93 282.59,-38.58"/>
 </g>
 <!-- kernel_tx -->
 <g id="node5" class="node">
 <title>kernel_tx</title>
-<ellipse fill="none" stroke="blue" cx="102.23" cy="-237" rx="45.72" ry="18"/>
-<text text-anchor="middle" x="102.23" y="-231.95" font-family="Times,serif" font-size="14.00">kernel_tx</text>
+<ellipse fill="none" stroke="blue" cx="120" cy="-272" rx="53.89" ry="18"/>
+<text text-anchor="middle" x="120" y="-268.3" font-family="Times,serif" font-size="14.00">kernel_tx</text>
 </g>
 <!-- kernel_tx&#45;&gt;kernel_rx -->
 <g id="edge16" class="edge">
 <title>kernel_tx&#45;&gt;kernel_rx</title>
-<path fill="none" stroke="red" stroke-dasharray="5,2" d="M89.25,-219.53C82.32,-210.75 73.65,-199.76 65.92,-189.96"/>
-<polygon fill="red" stroke="red" points="68.09,-188.06 59.15,-182.38 62.6,-192.4 68.09,-188.06"/>
+<path fill="none" stroke="red" stroke-dasharray="5,2" d="M110.99,-254.17C106.52,-245.81 101,-235.51 95.99,-226.14"/>
+<polygon fill="red" stroke="red" points="99.01,-224.36 91.2,-217.2 92.84,-227.67 99.01,-224.36"/>
 </g>
 <!-- pkt_cls&#45;&gt;pkt_drop -->
 <g id="edge15" class="edge">
 <title>pkt_cls&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M255.09,-319.38C322.68,-308.72 462.23,-281.44 462.23,-238 462.23,-238 462.23,-238 462.23,-90 462.23,-57.84 429.01,-39.68 398.59,-29.8"/>
-<polygon fill="cyan" stroke="cyan" points="400.02,-26.27 389.44,-26.75 398.01,-32.98 400.02,-26.27"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M84,-348.97C48.65,-337.7 0,-314.61 0,-273 0,-273 0,-273 0,-90 0,-49.99 118.4,-31.52 193.52,-23.82"/>
+<polygon fill="cyan" stroke="cyan" points="194.21,-27.27 203.82,-22.81 193.52,-20.31 194.21,-27.27"/>
 </g>
 <!-- pkt_cls&#45;&gt;kernel_tx -->
 <g id="edge5" class="edge">
 <title>pkt_cls&#45;&gt;kernel_tx</title>
-<path fill="none" stroke="blue" d="M186.99,-315.75C170.62,-310.16 151.14,-301.64 136.48,-289.5 128.23,-282.66 121.2,-273.31 115.7,-264.46"/>
-<polygon fill="blue" stroke="blue" points="118.38,-263.1 110.34,-256.2 112.32,-266.61 118.38,-263.1"/>
-<text text-anchor="middle" x="176.61" y="-276.2" font-family="Times,serif" font-size="14.00">exception pkts</text>
+<path fill="none" stroke="blue" d="M120,-340.8C120,-329.16 120,-313.55 120,-300.24"/>
+<polygon fill="blue" stroke="blue" points="123.5,-300.18 120,-290.18 116.5,-300.18 123.5,-300.18"/>
+<text text-anchor="middle" x="172.5" y="-311.8" font-family="Times,serif" font-size="14.00">exception pkts</text>
 </g>
 <!-- ip4_lookup -->
 <g id="node7" class="node">
 <title>ip4_lookup</title>
-<ellipse fill="none" stroke="black" cx="219.23" cy="-237" rx="52.89" ry="18"/>
-<text text-anchor="middle" x="219.23" y="-231.95" font-family="Times,serif" font-size="14.00">ip4_lookup</text>
+<ellipse fill="none" stroke="black" cx="252" cy="-272" rx="60.39" ry="18"/>
+<text text-anchor="middle" x="252" y="-268.3" font-family="Times,serif" font-size="14.00">ip4_lookup</text>
 </g>
 <!-- pkt_cls&#45;&gt;ip4_lookup -->
 <g id="edge3" class="edge">
 <title>pkt_cls&#45;&gt;ip4_lookup</title>
-<path fill="none" stroke="black" d="M219.23,-307.41C219.23,-295.64 219.23,-279.73 219.23,-266.11"/>
-<polygon fill="black" stroke="black" points="222.73,-266.35 219.23,-256.35 215.73,-266.35 222.73,-266.35"/>
-<text text-anchor="middle" x="231.23" y="-276.2" font-family="Times,serif" font-size="14.00">ipv4</text>
+<path fill="none" stroke="black" d="M160.54,-352.79C182.64,-348.15 209.23,-339.41 228,-323 235.09,-316.81 240.26,-308.05 243.95,-299.6"/>
+<polygon fill="black" stroke="black" points="247.32,-300.57 247.62,-289.98 240.78,-298.07 247.32,-300.57"/>
+<text text-anchor="middle" x="254.5" y="-311.8" font-family="Times,serif" font-size="14.00">ipv4</text>
 </g>
 <!-- ip6_lookup -->
 <g id="node8" class="node">
 <title>ip6_lookup</title>
-<ellipse fill="none" stroke="black" cx="343.23" cy="-237" rx="52.89" ry="18"/>
-<text text-anchor="middle" x="343.23" y="-231.95" font-family="Times,serif" font-size="14.00">ip6_lookup</text>
+<ellipse fill="none" stroke="black" cx="439" cy="-272" rx="60.39" ry="18"/>
+<text text-anchor="middle" x="439" y="-268.3" font-family="Times,serif" font-size="14.00">ip6_lookup</text>
 </g>
 <!-- pkt_cls&#45;&gt;ip6_lookup -->
 <g id="edge4" class="edge">
 <title>pkt_cls&#45;&gt;ip6_lookup</title>
-<path fill="none" stroke="black" d="M239.99,-310.02C259.62,-296.33 289.35,-275.59 311.88,-259.87"/>
-<polygon fill="black" stroke="black" points="313.53,-262.29 319.73,-253.7 309.53,-256.55 313.53,-262.29"/>
-<text text-anchor="middle" x="304.23" y="-276.2" font-family="Times,serif" font-size="14.00">ipv6</text>
+<path fill="none" stroke="black" d="M157.52,-350.25C188.82,-343.6 234.51,-333.46 274,-323 313.2,-312.62 357.13,-299.22 389.79,-288.91"/>
+<polygon fill="black" stroke="black" points="391.08,-292.17 399.55,-285.81 388.96,-285.5 391.08,-292.17"/>
+<text text-anchor="middle" x="339.5" y="-311.8" font-family="Times,serif" font-size="14.00">ipv6</text>
 </g>
 <!-- ip4_lookup&#45;&gt;pkt_drop -->
 <g id="edge7" class="edge">
 <title>ip4_lookup&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M192.86,-221.12C179.2,-211.83 163.82,-198.49 156.23,-182 149.55,-167.46 150.78,-161.04 156.23,-146 176.39,-90.45 198.32,-78.19 252.23,-54 269.14,-46.41 288.24,-39.24 304.98,-33.38"/>
-<polygon fill="cyan" stroke="cyan" points="305.75,-36.48 314.07,-29.92 303.47,-29.86 305.75,-36.48"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M239.17,-254.03C232.31,-243.87 224.56,-230.37 221,-217 204.89,-156.57 227.58,-83.56 242.59,-45.31"/>
+<polygon fill="cyan" stroke="cyan" points="245.89,-46.5 246.4,-35.92 239.4,-43.87 245.89,-46.5"/>
 </g>
 <!-- ip4_rewrite -->
 <g id="node9" class="node">
 <title>ip4_rewrite</title>
-<ellipse fill="none" stroke="black" cx="218.23" cy="-164" rx="53.4" ry="18"/>
-<text text-anchor="middle" x="218.23" y="-158.95" font-family="Times,serif" font-size="14.00">ip4_rewrite</text>
+<ellipse fill="none" stroke="black" cx="294" cy="-199" rx="63.89" ry="18"/>
+<text text-anchor="middle" x="294" y="-195.3" font-family="Times,serif" font-size="14.00">ip4_rewrite</text>
 </g>
 <!-- ip4_lookup&#45;&gt;ip4_rewrite -->
 <g id="edge6" class="edge">
 <title>ip4_lookup&#45;&gt;ip4_rewrite</title>
-<path fill="none" stroke="black" d="M218.99,-218.81C218.88,-211.05 218.75,-201.68 218.63,-192.95"/>
-<polygon fill="black" stroke="black" points="222.11,-192.98 218.47,-183.03 215.11,-193.08 222.11,-192.98"/>
+<path fill="none" stroke="black" d="M261.95,-254.17C266.95,-245.72 273.12,-235.29 278.71,-225.85"/>
+<polygon fill="black" stroke="black" points="281.75,-227.59 283.83,-217.2 275.72,-224.02 281.75,-227.59"/>
+</g>
+<!-- ip4_local -->
+<g id="node11" class="node">
+<title>ip4_local</title>
+<ellipse fill="none" stroke="black" cx="136" cy="-145" rx="51.19" ry="18"/>
+<text text-anchor="middle" x="136" y="-141.3" font-family="Times,serif" font-size="14.00">ip4_local</text>
+</g>
+<!-- ip4_lookup&#45;&gt;ip4_local -->
+<g id="edge17" class="edge">
+<title>ip4_lookup&#45;&gt;ip4_local</title>
+<path fill="none" stroke="black" d="M218.11,-256.86C207.64,-251.39 196.61,-244.41 188,-236 169.45,-217.88 155.34,-191.74 146.53,-172.29"/>
+<polygon fill="black" stroke="black" points="149.72,-170.86 142.52,-163.08 143.3,-173.65 149.72,-170.86"/>
 </g>
 <!-- ip6_lookup&#45;&gt;pkt_drop -->
 <g id="edge11" class="edge">
 <title>ip6_lookup&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M369.2,-221.03C382.65,-211.71 397.78,-198.37 405.23,-182 426.87,-134.45 392.95,-75.95 369.19,-43.54"/>
-<polygon fill="cyan" stroke="cyan" points="371.64,-41.98 362.81,-36.13 366.06,-46.21 371.64,-41.98"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M470.57,-256.44C486.08,-247.46 503.27,-234.31 512,-217 519.2,-202.71 517.24,-196.12 512,-181 486.88,-108.48 466,-83.15 395,-54 367.69,-42.79 335.88,-34.51 309.39,-28.83"/>
+<polygon fill="cyan" stroke="cyan" points="310.02,-25.39 299.52,-26.78 308.6,-32.24 310.02,-25.39"/>
 </g>
 <!-- ip6_rewrite -->
 <g id="node10" class="node">
 <title>ip6_rewrite</title>
-<ellipse fill="none" stroke="black" cx="343.23" cy="-164" rx="53.4" ry="18"/>
-<text text-anchor="middle" x="343.23" y="-158.95" font-family="Times,serif" font-size="14.00">ip6_rewrite</text>
+<ellipse fill="none" stroke="black" cx="439" cy="-199" rx="63.89" ry="18"/>
+<text text-anchor="middle" x="439" y="-195.3" font-family="Times,serif" font-size="14.00">ip6_rewrite</text>
 </g>
 <!-- ip6_lookup&#45;&gt;ip6_rewrite -->
 <g id="edge10" class="edge">
 <title>ip6_lookup&#45;&gt;ip6_rewrite</title>
-<path fill="none" stroke="black" d="M343.23,-218.81C343.23,-211.05 343.23,-201.68 343.23,-192.95"/>
-<polygon fill="black" stroke="black" points="346.73,-193.03 343.23,-183.03 339.73,-193.03 346.73,-193.03"/>
+<path fill="none" stroke="black" d="M439,-253.81C439,-245.79 439,-236.05 439,-227.07"/>
+<polygon fill="black" stroke="black" points="442.5,-227.03 439,-217.03 435.5,-227.03 442.5,-227.03"/>
 </g>
 <!-- ip4_rewrite&#45;&gt;ethdev_tx -->
 <g id="edge8" class="edge">
 <title>ip4_rewrite&#45;&gt;ethdev_tx</title>
-<path fill="none" stroke="green" d="M235.63,-146.53C245.35,-137.33 257.64,-125.7 268.36,-115.54"/>
-<polygon fill="green" stroke="green" points="270.34,-118.55 275.19,-109.13 265.52,-113.47 270.34,-118.55"/>
+<path fill="none" stroke="green" d="M301.07,-180.97C308.09,-164.05 318.96,-137.86 327.09,-118.28"/>
+<polygon fill="green" stroke="green" points="330.35,-119.57 330.95,-108.99 323.88,-116.88 330.35,-119.57"/>
 </g>
 <!-- ip4_rewrite&#45;&gt;pkt_drop -->
 <g id="edge9" class="edge">
 <title>ip4_rewrite&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M217.56,-145.54C217.71,-125.89 220.78,-93.99 237.23,-73 253.17,-52.67 278.68,-39.55 301.33,-31.33"/>
-<polygon fill="cyan" stroke="cyan" points="302.14,-34.42 310.5,-27.9 299.9,-27.79 302.14,-34.42"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M289.85,-180.97C285.53,-163.07 278.61,-134.1 273,-109 268.3,-87.99 263.29,-64.16 259.59,-46.3"/>
+<polygon fill="cyan" stroke="cyan" points="262.97,-45.37 257.52,-36.28 256.11,-46.78 262.97,-45.37"/>
 </g>
 <!-- ip6_rewrite&#45;&gt;ethdev_tx -->
 <g id="edge12" class="edge">
 <title>ip6_rewrite&#45;&gt;ethdev_tx</title>
-<path fill="none" stroke="green" d="M331.38,-146.17C325.34,-137.6 317.87,-126.99 311.15,-117.44"/>
-<polygon fill="green" stroke="green" points="313.62,-115.87 305,-109.71 307.89,-119.9 313.62,-115.87"/>
+<path fill="none" stroke="green" d="M423.22,-181.44C406.47,-163.86 379.84,-135.91 360.81,-115.94"/>
+<polygon fill="green" stroke="green" points="363.1,-113.27 353.67,-108.45 358.03,-118.1 363.1,-113.27"/>
 </g>
 <!-- ip6_rewrite&#45;&gt;pkt_drop -->
 <g id="edge13" class="edge">
 <title>ip6_rewrite&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M345.67,-145.53C347.02,-134.98 348.56,-121.24 349.23,-109 350.38,-88.27 350.34,-64.81 350.03,-47.04"/>
-<polygon fill="cyan" stroke="cyan" points="353.51,-47.19 349.8,-37.27 346.51,-47.34 353.51,-47.19"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M438.77,-180.67C437.49,-154.09 431.22,-103.19 403,-73 379.35,-47.7 342.93,-34.22 312.02,-27.06"/>
+<polygon fill="cyan" stroke="cyan" points="312.71,-23.63 302.2,-24.95 311.24,-30.47 312.71,-23.63"/>
+</g>
+<!-- ip4_local&#45;&gt;pkt_drop -->
+<g id="edge18" class="edge">
+<title>ip4_local&#45;&gt;pkt_drop</title>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M142.47,-126.87C150.6,-107.23 166.18,-75.04 188,-54 195,-47.25 203.56,-41.45 212.16,-36.63"/>
+<polygon fill="cyan" stroke="cyan" points="213.85,-39.7 221.08,-31.95 210.6,-33.5 213.85,-39.7"/>
 </g>
 </g>
 </svg>
diff --git a/lib/node/ip4_local.c b/lib/node/ip4_local.c
new file mode 100644
index 0000000000..fb31d0f970
--- /dev/null
+++ b/lib/node/ip4_local.c
@@ -0,0 +1,88 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2023 Marvell International Ltd.
+ */
+
+#include <arpa/inet.h>
+#include <sys/socket.h>
+
+#include <rte_ethdev.h>
+#include <rte_ether.h>
+#include <rte_graph.h>
+#include <rte_graph_worker.h>
+#include <rte_ip.h>
+#include <rte_lpm.h>
+#include <rte_hash.h>
+#include <rte_fbk_hash.h>
+#include <rte_jhash.h>
+#include <rte_hash_crc.h>
+
+
+#include "rte_node_ip4_api.h"
+
+#include "node_private.h"
+
+static uint16_t
+ip4_local_node_process_scalar(struct rte_graph *graph, struct rte_node *node,
+			      void **objs, uint16_t nb_objs)
+{
+	void **to_next, **from;
+	uint16_t last_spec = 0;
+	rte_edge_t next_index;
+	struct rte_mbuf *mbuf;
+	uint16_t held = 0;
+	uint32_t l4;
+	int i;
+
+	/* Speculative next */
+	next_index = RTE_NODE_IP4_LOCAL_NEXT_UDP4_INPUT;
+
+	from = objs;
+	to_next = rte_node_next_stream_get(graph, node, next_index, nb_objs);
+	for (i = 0; i < nb_objs; i++) {
+		uint16_t next;
+
+		mbuf = (struct rte_mbuf *)objs[i];
+		l4 = mbuf->packet_type & RTE_PTYPE_L4_MASK;
+
+		next = (l4 == RTE_PTYPE_L4_UDP)
+				? next_index
+				: RTE_NODE_IP4_LOCAL_NEXT_PKT_DROP;
+
+		if (unlikely(next_index != next)) {
+			/* Copy things successfully speculated till now */
+			rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
+			from += last_spec;
+			to_next += last_spec;
+			held += last_spec;
+			last_spec = 0;
+
+			rte_node_enqueue_x1(graph, node, next, from[0]);
+			from += 1;
+		} else {
+			last_spec += 1;
+		}
+	}
+	/* !!! Home run !!! */
+	if (likely(last_spec == nb_objs)) {
+		rte_node_next_stream_move(graph, node, next_index);
+		return nb_objs;
+	}
+	held += last_spec;
+	rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
+	rte_node_next_stream_put(graph, node, next_index, held);
+
+	return nb_objs;
+}
+
+static struct rte_node_register ip4_local_node = {
+	.process = ip4_local_node_process_scalar,
+	.name = "ip4_local",
+
+	.nb_edges = RTE_NODE_IP4_LOCAL_NEXT_PKT_DROP + 1,
+	.next_nodes = {
+		[RTE_NODE_IP4_LOCAL_NEXT_UDP4_INPUT] = "udp4_input",
+		[RTE_NODE_IP4_LOCAL_NEXT_PKT_DROP] = "pkt_drop",
+	},
+};
+
+RTE_NODE_REGISTER(ip4_local_node);
diff --git a/lib/node/ip4_lookup.c b/lib/node/ip4_lookup.c
index 8bce03d7db..d3fc48baf7 100644
--- a/lib/node/ip4_lookup.c
+++ b/lib/node/ip4_lookup.c
@@ -227,6 +227,7 @@ static struct rte_node_register ip4_lookup_node = {
 
 	.nb_edges = RTE_NODE_IP4_LOOKUP_NEXT_MAX,
 	.next_nodes = {
+		[RTE_NODE_IP4_LOOKUP_NEXT_IP4_LOCAL] = "ip4_local",
 		[RTE_NODE_IP4_LOOKUP_NEXT_REWRITE] = "ip4_rewrite",
 		[RTE_NODE_IP4_LOOKUP_NEXT_PKT_DROP] = "pkt_drop",
 	},
diff --git a/lib/node/meson.build b/lib/node/meson.build
index 2fa7c1c8f3..c0d5b09e2f 100644
--- a/lib/node/meson.build
+++ b/lib/node/meson.build
@@ -12,6 +12,7 @@ sources = files(
         'ethdev_rx.c',
         'ethdev_tx.c',
         'ip4_lookup.c',
+        'ip4_local.c',
         'ip4_rewrite.c',
         'ip6_lookup.c',
         'ip6_rewrite.c',
diff --git a/lib/node/rte_node_ip4_api.h b/lib/node/rte_node_ip4_api.h
index 3397da0ae8..405bdd3283 100644
--- a/lib/node/rte_node_ip4_api.h
+++ b/lib/node/rte_node_ip4_api.h
@@ -30,10 +30,22 @@ enum rte_node_ip4_lookup_next {
 	/**< Rewrite node. */
 	RTE_NODE_IP4_LOOKUP_NEXT_PKT_DROP,
 	/**< Packet drop node. */
+	RTE_NODE_IP4_LOOKUP_NEXT_IP4_LOCAL,
+	/** IP Local node. */
 	RTE_NODE_IP4_LOOKUP_NEXT_MAX,
 	/**< Number of next nodes of lookup node. */
 };
 
+/**
+ * IP4 Local next nodes.
+ */
+enum rte_node_ip4_local_next {
+	RTE_NODE_IP4_LOCAL_NEXT_UDP4_INPUT,
+	/**< ip4 Local node. */
+	RTE_NODE_IP4_LOCAL_NEXT_PKT_DROP,
+	/**< Packet drop node. */
+};
+
 /**
  * Add ipv4 route to lookup table.
  *
-- 
2.25.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v3 2/2] node: add UDP v4 support
  2023-07-04 10:50   ` [PATCH v3 1/2] node: add IPv4 local node to handle local pkts Rakesh Kudurumalla
@ 2023-07-04 10:50     ` Rakesh Kudurumalla
  2023-09-27  9:21     ` [PATCH v4 1/2] node: add IPv4 local node to handle local pkts Rakesh Kudurumalla
  1 sibling, 0 replies; 16+ messages in thread
From: Rakesh Kudurumalla @ 2023-07-04 10:50 UTC (permalink / raw)
  To: Jerin Jacob, Kiran Kumar K, Nithin Dabilpuram, Zhirun Yan,
	Pavan Nikhilesh
  Cc: dev, Rakesh Kudurumalla

IPv4 UDP packets are given to application
with specified UDP destination port given
by user.

Signed-off-by: Rakesh Kudurumalla <rkudurumalla@marvell.com>
---
 doc/api/doxy-api-index.md                     |   3 +-
 doc/guides/prog_guide/graph_lib.rst           |  25 ++
 .../img/graph_inbuilt_node_flow.svg           | 165 ++++++++-----
 lib/node/meson.build                          |   2 +
 lib/node/rte_node_udp4_input_api.h            |  60 +++++
 lib/node/udp4_input.c                         | 226 ++++++++++++++++++
 lib/node/version.map                          |   2 +
 7 files changed, 417 insertions(+), 66 deletions(-)
 create mode 100644 lib/node/rte_node_udp4_input_api.h
 create mode 100644 lib/node/udp4_input.c

diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index 3bc8778981..b81777b3fb 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -209,7 +209,8 @@ The public API headers are grouped by topics:
   * graph_nodes:
     [eth_node](@ref rte_node_eth_api.h),
     [ip4_node](@ref rte_node_ip4_api.h),
-    [ip6_node](@ref rte_node_ip6_api.h)
+    [ip6_node](@ref rte_node_ip6_api.h),
+    [udp4_input_node](@ref rte_node_udp4_input_api.h)
 
 - **basic**:
   [bitops](@ref rte_bitops.h),
diff --git a/doc/guides/prog_guide/graph_lib.rst b/doc/guides/prog_guide/graph_lib.rst
index eaa8ee337e..98473383f1 100644
--- a/doc/guides/prog_guide/graph_lib.rst
+++ b/doc/guides/prog_guide/graph_lib.rst
@@ -513,3 +513,28 @@ On packet_type lookup failure, objects are redirected to ``pkt_drop`` node.
 depth to receive to packets.
 To achieve home run, node use ``rte_node_stream_move()`` as mentioned in above
 sections.
+
+udp4_input
+~~~~~~~~~~
+This node is an intermediate node that does udp destination port lookup for
+the received ipv4 packets and the result determines each packets next node.
+
+User registers a new node ``udp4_input`` into graph library during initialization
+and attach user specified node as edege to this node using
+``rte_node_udp4_usr_node_add()``, and create empty hash table with destination
+port and node id as its feilds.
+
+After successful addition of user node as edege, edge id is returned to the user.
+
+User would register ``ip4_lookup`` table with specified ip address and 32 bit as mask
+for ip filtration using api ``rte_node_ip4_route_add()``.
+
+After graph is created user would update hash table with custom port with
+and previously obtained edge id using API ``rte_node_udp4_dst_port_add()``.
+
+When packet is received lpm look up is performed if ip is matched the packet
+is handed over to ip4_local node, then packet is verified for udp proto and
+on success packet is enqueued to ``udp4_input`` node.
+
+Hash lookup is performed in ``udp4_input`` node with registered destination port
+and destination port in UDP packet , on success packet is handed to ``udp_user_node``.
diff --git a/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg b/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg
index 7a3ace48dc..5db96adb01 100644
--- a/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg
+++ b/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg
@@ -39,192 +39,227 @@ digraph dpdk_inbuilt_nodes_flow {
     kernel_tx -> kernel_rx [color="red" style="dashed"]
     ip4_lookup -> ip4_local
     ip4_local -> pkt_drop [color="cyan" style="dashed"]
+    ip4_local -> udp4_input [ label="udpv4"]
+    udp4_input -> udp_user_node
+    udp4_input -> pkt_drop [color="cyan" style="dashed"]
+
 }
 
  -->
 <!-- input nodes -->
 <!-- Title: dpdk_inbuilt_nodes_flow Pages: 1 -->
-<svg width="525pt" height="458pt"
- viewBox="0.00 0.00 524.91 458.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 454)">
+<svg width="631pt" height="437pt"
+ viewBox="0.00 0.00 630.95 437.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 433)">
 <title>dpdk_inbuilt_nodes_flow</title>
-<polygon fill="white" stroke="transparent" points="-4,4 -4,-454 520.91,-454 520.91,4 -4,4"/>
+<polygon fill="white" stroke="transparent" points="-4,4 -4,-433 626.95,-433 626.95,4 -4,4"/>
 <!-- ethdev_rx -->
 <g id="node1" class="node">
 <title>ethdev_rx</title>
-<ellipse fill="none" stroke="green" cx="120" cy="-432" rx="56.59" ry="18"/>
-<text text-anchor="middle" x="120" y="-428.3" font-family="Times,serif" font-size="14.00">ethdev_rx</text>
+<ellipse fill="none" stroke="green" cx="261.95" cy="-411" rx="56.59" ry="18"/>
+<text text-anchor="middle" x="261.95" y="-407.3" font-family="Times,serif" font-size="14.00">ethdev_rx</text>
 </g>
 <!-- pkt_cls -->
 <g id="node6" class="node">
 <title>pkt_cls</title>
-<ellipse fill="none" stroke="red" cx="120" cy="-359" rx="42.79" ry="18"/>
-<text text-anchor="middle" x="120" y="-355.3" font-family="Times,serif" font-size="14.00">pkt_cls</text>
+<ellipse fill="none" stroke="red" cx="261.95" cy="-338" rx="42.79" ry="18"/>
+<text text-anchor="middle" x="261.95" y="-334.3" font-family="Times,serif" font-size="14.00">pkt_cls</text>
 </g>
 <!-- ethdev_rx&#45;&gt;pkt_cls -->
 <g id="edge1" class="edge">
 <title>ethdev_rx&#45;&gt;pkt_cls</title>
-<path fill="none" stroke="black" d="M120,-413.81C120,-405.79 120,-396.05 120,-387.07"/>
-<polygon fill="black" stroke="black" points="123.5,-387.03 120,-377.03 116.5,-387.03 123.5,-387.03"/>
+<path fill="none" stroke="black" d="M261.95,-392.81C261.95,-384.79 261.95,-375.05 261.95,-366.07"/>
+<polygon fill="black" stroke="black" points="265.45,-366.03 261.95,-356.03 258.45,-366.03 265.45,-366.03"/>
 </g>
 <!-- kernel_rx -->
 <g id="node2" class="node">
 <title>kernel_rx</title>
-<ellipse fill="none" stroke="green" cx="82" cy="-199" rx="53.89" ry="18"/>
-<text text-anchor="middle" x="82" y="-195.3" font-family="Times,serif" font-size="14.00">kernel_rx</text>
+<ellipse fill="none" stroke="green" cx="53.95" cy="-178" rx="53.89" ry="18"/>
+<text text-anchor="middle" x="53.95" y="-174.3" font-family="Times,serif" font-size="14.00">kernel_rx</text>
 </g>
 <!-- kernel_rx&#45;&gt;pkt_cls -->
 <g id="edge2" class="edge">
 <title>kernel_rx&#45;&gt;pkt_cls</title>
-<path fill="none" stroke="black" d="M70.87,-216.92C60.28,-235.27 47.29,-265.24 57,-290 64.12,-308.16 78.62,-324.37 91.92,-336.4"/>
-<polygon fill="black" stroke="black" points="89.69,-339.1 99.54,-342.99 94.26,-333.8 89.69,-339.1"/>
+<path fill="none" stroke="black" d="M74.75,-194.8C112.31,-223.33 191.45,-283.45 233.8,-315.62"/>
+<polygon fill="black" stroke="black" points="231.92,-318.59 242,-321.85 236.16,-313.01 231.92,-318.59"/>
 </g>
 <!-- ethdev_tx -->
 <g id="node3" class="node">
 <title>ethdev_tx</title>
-<ellipse fill="none" stroke="magenta" cx="338" cy="-91" rx="55.79" ry="18"/>
-<text text-anchor="middle" x="338" y="-87.3" font-family="Times,serif" font-size="14.00">ethdev_tx</text>
+<ellipse fill="none" stroke="magenta" cx="347.95" cy="-91" rx="55.79" ry="18"/>
+<text text-anchor="middle" x="347.95" y="-87.3" font-family="Times,serif" font-size="14.00">ethdev_tx</text>
 </g>
 <!-- pkt_drop -->
 <g id="node4" class="node">
 <title>pkt_drop</title>
-<ellipse fill="none" stroke="cyan" cx="254" cy="-18" rx="51.99" ry="18"/>
-<text text-anchor="middle" x="254" y="-14.3" font-family="Times,serif" font-size="14.00">pkt_drop</text>
+<ellipse fill="none" stroke="cyan" cx="404.95" cy="-18" rx="51.99" ry="18"/>
+<text text-anchor="middle" x="404.95" y="-14.3" font-family="Times,serif" font-size="14.00">pkt_drop</text>
 </g>
 <!-- ethdev_tx&#45;&gt;pkt_drop -->
 <g id="edge14" class="edge">
 <title>ethdev_tx&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M318.94,-73.89C307.58,-64.29 293,-51.96 280.53,-41.42"/>
-<polygon fill="cyan" stroke="cyan" points="282.59,-38.58 272.7,-34.8 278.07,-43.93 282.59,-38.58"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M361.45,-73.17C368.55,-64.33 377.39,-53.33 385.23,-43.55"/>
+<polygon fill="cyan" stroke="cyan" points="388,-45.69 391.53,-35.71 382.54,-41.31 388,-45.69"/>
 </g>
 <!-- kernel_tx -->
 <g id="node5" class="node">
 <title>kernel_tx</title>
-<ellipse fill="none" stroke="blue" cx="120" cy="-272" rx="53.89" ry="18"/>
-<text text-anchor="middle" x="120" y="-268.3" font-family="Times,serif" font-size="14.00">kernel_tx</text>
+<ellipse fill="none" stroke="blue" cx="53.95" cy="-251" rx="53.89" ry="18"/>
+<text text-anchor="middle" x="53.95" y="-247.3" font-family="Times,serif" font-size="14.00">kernel_tx</text>
 </g>
 <!-- kernel_tx&#45;&gt;kernel_rx -->
 <g id="edge16" class="edge">
 <title>kernel_tx&#45;&gt;kernel_rx</title>
-<path fill="none" stroke="red" stroke-dasharray="5,2" d="M110.99,-254.17C106.52,-245.81 101,-235.51 95.99,-226.14"/>
-<polygon fill="red" stroke="red" points="99.01,-224.36 91.2,-217.2 92.84,-227.67 99.01,-224.36"/>
+<path fill="none" stroke="red" stroke-dasharray="5,2" d="M53.95,-232.81C53.95,-224.79 53.95,-215.05 53.95,-206.07"/>
+<polygon fill="red" stroke="red" points="57.45,-206.03 53.95,-196.03 50.45,-206.03 57.45,-206.03"/>
 </g>
 <!-- pkt_cls&#45;&gt;pkt_drop -->
 <g id="edge15" class="edge">
 <title>pkt_cls&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M84,-348.97C48.65,-337.7 0,-314.61 0,-273 0,-273 0,-273 0,-90 0,-49.99 118.4,-31.52 193.52,-23.82"/>
-<polygon fill="cyan" stroke="cyan" points="194.21,-27.27 203.82,-22.81 193.52,-20.31 194.21,-27.27"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M304.77,-335.88C400.4,-332.2 622.95,-316.71 622.95,-252 622.95,-252 622.95,-252 622.95,-90 622.95,-56.33 527.72,-36.15 463.14,-26.34"/>
+<polygon fill="cyan" stroke="cyan" points="463.46,-22.85 453.06,-24.85 462.44,-29.77 463.46,-22.85"/>
 </g>
 <!-- pkt_cls&#45;&gt;kernel_tx -->
 <g id="edge5" class="edge">
 <title>pkt_cls&#45;&gt;kernel_tx</title>
-<path fill="none" stroke="blue" d="M120,-340.8C120,-329.16 120,-313.55 120,-300.24"/>
-<polygon fill="blue" stroke="blue" points="123.5,-300.18 120,-290.18 116.5,-300.18 123.5,-300.18"/>
-<text text-anchor="middle" x="172.5" y="-311.8" font-family="Times,serif" font-size="14.00">exception pkts</text>
+<path fill="none" stroke="blue" d="M219.14,-335.96C164.86,-333.64 75.77,-326.15 54.95,-302 49.6,-295.81 48.06,-287.4 48.24,-279.24"/>
+<polygon fill="blue" stroke="blue" points="51.73,-279.54 49.23,-269.24 44.76,-278.84 51.73,-279.54"/>
+<text text-anchor="middle" x="107.45" y="-290.8" font-family="Times,serif" font-size="14.00">exception pkts</text>
 </g>
 <!-- ip4_lookup -->
 <g id="node7" class="node">
 <title>ip4_lookup</title>
-<ellipse fill="none" stroke="black" cx="252" cy="-272" rx="60.39" ry="18"/>
-<text text-anchor="middle" x="252" y="-268.3" font-family="Times,serif" font-size="14.00">ip4_lookup</text>
+<ellipse fill="none" stroke="black" cx="261.95" cy="-251" rx="60.39" ry="18"/>
+<text text-anchor="middle" x="261.95" y="-247.3" font-family="Times,serif" font-size="14.00">ip4_lookup</text>
 </g>
 <!-- pkt_cls&#45;&gt;ip4_lookup -->
 <g id="edge3" class="edge">
 <title>pkt_cls&#45;&gt;ip4_lookup</title>
-<path fill="none" stroke="black" d="M160.54,-352.79C182.64,-348.15 209.23,-339.41 228,-323 235.09,-316.81 240.26,-308.05 243.95,-299.6"/>
-<polygon fill="black" stroke="black" points="247.32,-300.57 247.62,-289.98 240.78,-298.07 247.32,-300.57"/>
-<text text-anchor="middle" x="254.5" y="-311.8" font-family="Times,serif" font-size="14.00">ipv4</text>
+<path fill="none" stroke="black" d="M261.95,-319.8C261.95,-308.16 261.95,-292.55 261.95,-279.24"/>
+<polygon fill="black" stroke="black" points="265.45,-279.18 261.95,-269.18 258.45,-279.18 265.45,-279.18"/>
+<text text-anchor="middle" x="277.45" y="-290.8" font-family="Times,serif" font-size="14.00">ipv4</text>
 </g>
 <!-- ip6_lookup -->
 <g id="node8" class="node">
 <title>ip6_lookup</title>
-<ellipse fill="none" stroke="black" cx="439" cy="-272" rx="60.39" ry="18"/>
-<text text-anchor="middle" x="439" y="-268.3" font-family="Times,serif" font-size="14.00">ip6_lookup</text>
+<ellipse fill="none" stroke="black" cx="492.95" cy="-251" rx="60.39" ry="18"/>
+<text text-anchor="middle" x="492.95" y="-247.3" font-family="Times,serif" font-size="14.00">ip6_lookup</text>
 </g>
 <!-- pkt_cls&#45;&gt;ip6_lookup -->
 <g id="edge4" class="edge">
 <title>pkt_cls&#45;&gt;ip6_lookup</title>
-<path fill="none" stroke="black" d="M157.52,-350.25C188.82,-343.6 234.51,-333.46 274,-323 313.2,-312.62 357.13,-299.22 389.79,-288.91"/>
-<polygon fill="black" stroke="black" points="391.08,-292.17 399.55,-285.81 388.96,-285.5 391.08,-292.17"/>
-<text text-anchor="middle" x="339.5" y="-311.8" font-family="Times,serif" font-size="14.00">ipv6</text>
+<path fill="none" stroke="black" d="M293.1,-325.54C332.57,-311.01 400.93,-285.86 446.54,-269.07"/>
+<polygon fill="black" stroke="black" points="448.02,-272.26 456.2,-265.52 445.61,-265.69 448.02,-272.26"/>
+<text text-anchor="middle" x="407.45" y="-290.8" font-family="Times,serif" font-size="14.00">ipv6</text>
 </g>
 <!-- ip4_lookup&#45;&gt;pkt_drop -->
 <g id="edge7" class="edge">
 <title>ip4_lookup&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M239.17,-254.03C232.31,-243.87 224.56,-230.37 221,-217 204.89,-156.57 227.58,-83.56 242.59,-45.31"/>
-<polygon fill="cyan" stroke="cyan" points="245.89,-46.5 246.4,-35.92 239.4,-43.87 245.89,-46.5"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M258.85,-232.91C253.68,-198.83 247.1,-121.54 282.95,-73 299.1,-51.12 326.1,-37.95 350.6,-30.11"/>
+<polygon fill="cyan" stroke="cyan" points="351.6,-33.46 360.19,-27.26 349.61,-26.75 351.6,-33.46"/>
 </g>
 <!-- ip4_rewrite -->
 <g id="node9" class="node">
 <title>ip4_rewrite</title>
-<ellipse fill="none" stroke="black" cx="294" cy="-199" rx="63.89" ry="18"/>
-<text text-anchor="middle" x="294" y="-195.3" font-family="Times,serif" font-size="14.00">ip4_rewrite</text>
+<ellipse fill="none" stroke="black" cx="347.95" cy="-178" rx="63.89" ry="18"/>
+<text text-anchor="middle" x="347.95" y="-174.3" font-family="Times,serif" font-size="14.00">ip4_rewrite</text>
 </g>
 <!-- ip4_lookup&#45;&gt;ip4_rewrite -->
 <g id="edge6" class="edge">
 <title>ip4_lookup&#45;&gt;ip4_rewrite</title>
-<path fill="none" stroke="black" d="M261.95,-254.17C266.95,-245.72 273.12,-235.29 278.71,-225.85"/>
-<polygon fill="black" stroke="black" points="281.75,-227.59 283.83,-217.2 275.72,-224.02 281.75,-227.59"/>
+<path fill="none" stroke="black" d="M281.46,-233.89C292.92,-224.42 307.6,-212.31 320.25,-201.87"/>
+<polygon fill="black" stroke="black" points="322.73,-204.36 328.21,-195.29 318.27,-198.96 322.73,-204.36"/>
 </g>
 <!-- ip4_local -->
 <g id="node11" class="node">
 <title>ip4_local</title>
-<ellipse fill="none" stroke="black" cx="136" cy="-145" rx="51.19" ry="18"/>
-<text text-anchor="middle" x="136" y="-141.3" font-family="Times,serif" font-size="14.00">ip4_local</text>
+<ellipse fill="none" stroke="black" cx="176.95" cy="-178" rx="51.19" ry="18"/>
+<text text-anchor="middle" x="176.95" y="-174.3" font-family="Times,serif" font-size="14.00">ip4_local</text>
 </g>
 <!-- ip4_lookup&#45;&gt;ip4_local -->
 <g id="edge17" class="edge">
 <title>ip4_lookup&#45;&gt;ip4_local</title>
-<path fill="none" stroke="black" d="M218.11,-256.86C207.64,-251.39 196.61,-244.41 188,-236 169.45,-217.88 155.34,-191.74 146.53,-172.29"/>
-<polygon fill="black" stroke="black" points="149.72,-170.86 142.52,-163.08 143.3,-173.65 149.72,-170.86"/>
+<path fill="none" stroke="black" d="M242.66,-233.89C231.17,-224.29 216.41,-211.96 203.79,-201.42"/>
+<polygon fill="black" stroke="black" points="205.78,-198.53 195.86,-194.8 201.29,-203.9 205.78,-198.53"/>
 </g>
 <!-- ip6_lookup&#45;&gt;pkt_drop -->
 <g id="edge11" class="edge">
 <title>ip6_lookup&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M470.57,-256.44C486.08,-247.46 503.27,-234.31 512,-217 519.2,-202.71 517.24,-196.12 512,-181 486.88,-108.48 466,-83.15 395,-54 367.69,-42.79 335.88,-34.51 309.39,-28.83"/>
-<polygon fill="cyan" stroke="cyan" points="310.02,-25.39 299.52,-26.78 308.6,-32.24 310.02,-25.39"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M524.51,-235.44C540.02,-226.46 557.22,-213.31 565.95,-196 573.15,-181.71 572.55,-174.57 565.95,-160 540.59,-104.08 480.88,-61.6 441.74,-38.51"/>
+<polygon fill="cyan" stroke="cyan" points="443.16,-35.29 432.75,-33.34 439.67,-41.36 443.16,-35.29"/>
 </g>
 <!-- ip6_rewrite -->
 <g id="node10" class="node">
 <title>ip6_rewrite</title>
-<ellipse fill="none" stroke="black" cx="439" cy="-199" rx="63.89" ry="18"/>
-<text text-anchor="middle" x="439" y="-195.3" font-family="Times,serif" font-size="14.00">ip6_rewrite</text>
+<ellipse fill="none" stroke="black" cx="492.95" cy="-178" rx="63.89" ry="18"/>
+<text text-anchor="middle" x="492.95" y="-174.3" font-family="Times,serif" font-size="14.00">ip6_rewrite</text>
 </g>
 <!-- ip6_lookup&#45;&gt;ip6_rewrite -->
 <g id="edge10" class="edge">
 <title>ip6_lookup&#45;&gt;ip6_rewrite</title>
-<path fill="none" stroke="black" d="M439,-253.81C439,-245.79 439,-236.05 439,-227.07"/>
-<polygon fill="black" stroke="black" points="442.5,-227.03 439,-217.03 435.5,-227.03 442.5,-227.03"/>
+<path fill="none" stroke="black" d="M492.95,-232.81C492.95,-224.79 492.95,-215.05 492.95,-206.07"/>
+<polygon fill="black" stroke="black" points="496.45,-206.03 492.95,-196.03 489.45,-206.03 496.45,-206.03"/>
 </g>
 <!-- ip4_rewrite&#45;&gt;ethdev_tx -->
 <g id="edge8" class="edge">
 <title>ip4_rewrite&#45;&gt;ethdev_tx</title>
-<path fill="none" stroke="green" d="M301.07,-180.97C308.09,-164.05 318.96,-137.86 327.09,-118.28"/>
-<polygon fill="green" stroke="green" points="330.35,-119.57 330.95,-108.99 323.88,-116.88 330.35,-119.57"/>
+<path fill="none" stroke="green" d="M347.95,-159.8C347.95,-148.16 347.95,-132.55 347.95,-119.24"/>
+<polygon fill="green" stroke="green" points="351.45,-119.18 347.95,-109.18 344.45,-119.18 351.45,-119.18"/>
 </g>
 <!-- ip4_rewrite&#45;&gt;pkt_drop -->
 <g id="edge9" class="edge">
 <title>ip4_rewrite&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M289.85,-180.97C285.53,-163.07 278.61,-134.1 273,-109 268.3,-87.99 263.29,-64.16 259.59,-46.3"/>
-<polygon fill="cyan" stroke="cyan" points="262.97,-45.37 257.52,-36.28 256.11,-46.78 262.97,-45.37"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M370.32,-161.1C385.53,-148.83 404.37,-130.37 412.95,-109 421.04,-88.82 418.02,-64.12 413.56,-45.7"/>
+<polygon fill="cyan" stroke="cyan" points="416.9,-44.66 410.91,-35.93 410.15,-46.49 416.9,-44.66"/>
 </g>
 <!-- ip6_rewrite&#45;&gt;ethdev_tx -->
 <g id="edge12" class="edge">
 <title>ip6_rewrite&#45;&gt;ethdev_tx</title>
-<path fill="none" stroke="green" d="M423.22,-181.44C406.47,-163.86 379.84,-135.91 360.81,-115.94"/>
-<polygon fill="green" stroke="green" points="363.1,-113.27 353.67,-108.45 358.03,-118.1 363.1,-113.27"/>
+<path fill="none" stroke="green" d="M466.35,-161.41C442.8,-147.6 408.27,-127.36 382.57,-112.3"/>
+<polygon fill="green" stroke="green" points="384.28,-109.24 373.88,-107.21 380.74,-115.28 384.28,-109.24"/>
 </g>
 <!-- ip6_rewrite&#45;&gt;pkt_drop -->
 <g id="edge13" class="edge">
 <title>ip6_rewrite&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M438.77,-180.67C437.49,-154.09 431.22,-103.19 403,-73 379.35,-47.7 342.93,-34.22 312.02,-27.06"/>
-<polygon fill="cyan" stroke="cyan" points="312.71,-23.63 302.2,-24.95 311.24,-30.47 312.71,-23.63"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M485.15,-159.86C473.93,-135.7 452.15,-90.48 429.95,-54 427.97,-50.75 425.78,-47.4 423.55,-44.13"/>
+<polygon fill="cyan" stroke="cyan" points="426.28,-41.92 417.67,-35.75 420.55,-45.94 426.28,-41.92"/>
 </g>
 <!-- ip4_local&#45;&gt;pkt_drop -->
 <g id="edge18" class="edge">
 <title>ip4_local&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M142.47,-126.87C150.6,-107.23 166.18,-75.04 188,-54 195,-47.25 203.56,-41.45 212.16,-36.63"/>
-<polygon fill="cyan" stroke="cyan" points="213.85,-39.7 221.08,-31.95 210.6,-33.5 213.85,-39.7"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M191.02,-160.51C195.47,-154.86 200.21,-148.35 203.95,-142 225.57,-105.29 209.02,-81.03 241.95,-54 257.83,-40.96 306.22,-31.62 346.19,-25.89"/>
+<polygon fill="cyan" stroke="cyan" points="346.72,-29.35 356.14,-24.51 345.75,-22.41 346.72,-29.35"/>
+</g>
+<!-- udp4_input -->
+<g id="node12" class="node">
+<title>udp4_input</title>
+<ellipse fill="none" stroke="black" cx="126.95" cy="-91" rx="63.09" ry="18"/>
+<text text-anchor="middle" x="126.95" y="-87.3" font-family="Times,serif" font-size="14.00">udp4_input</text>
+</g>
+<!-- ip4_local&#45;&gt;udp4_input -->
+<g id="edge19" class="edge">
+<title>ip4_local&#45;&gt;udp4_input</title>
+<path fill="none" stroke="black" d="M167.07,-160.21C159.99,-148.18 150.33,-131.75 142.26,-118.03"/>
+<polygon fill="black" stroke="black" points="145.06,-115.89 136.97,-109.05 139.03,-119.44 145.06,-115.89"/>
+<text text-anchor="middle" x="177.45" y="-130.8" font-family="Times,serif" font-size="14.00">udpv4</text>
+</g>
+<!-- udp4_input&#45;&gt;pkt_drop -->
+<g id="edge21" class="edge">
+<title>udp4_input&#45;&gt;pkt_drop</title>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M154.75,-74.82C169.08,-67.56 187.05,-59.32 203.95,-54 250.51,-39.35 305.19,-30.33 345.76,-25.12"/>
+<polygon fill="cyan" stroke="cyan" points="346.26,-28.59 355.75,-23.88 345.4,-21.64 346.26,-28.59"/>
+</g>
+<!-- udp_user_node -->
+<g id="node13" class="node">
+<title>udp_user_node</title>
+<ellipse fill="none" stroke="black" cx="126.95" cy="-18" rx="79.89" ry="18"/>
+<text text-anchor="middle" x="126.95" y="-14.3" font-family="Times,serif" font-size="14.00">udp_user_node</text>
+</g>
+<!-- udp4_input&#45;&gt;udp_user_node -->
+<g id="edge20" class="edge">
+<title>udp4_input&#45;&gt;udp_user_node</title>
+<path fill="none" stroke="black" d="M126.95,-72.81C126.95,-64.79 126.95,-55.05 126.95,-46.07"/>
+<polygon fill="black" stroke="black" points="130.45,-46.03 126.95,-36.03 123.45,-46.03 130.45,-46.03"/>
 </g>
 </g>
 </svg>
diff --git a/lib/node/meson.build b/lib/node/meson.build
index c0d5b09e2f..c5b8ee656e 100644
--- a/lib/node/meson.build
+++ b/lib/node/meson.build
@@ -22,11 +22,13 @@ sources = files(
         'null.c',
         'pkt_cls.c',
         'pkt_drop.c',
+        'udp4_input.c',
 )
 headers = files(
         'rte_node_eth_api.h',
         'rte_node_ip4_api.h',
         'rte_node_ip6_api.h',
+        'rte_node_udp4_input_api.h',
 )
 
 # Strict-aliasing rules are violated by uint8_t[] to context size casts.
diff --git a/lib/node/rte_node_udp4_input_api.h b/lib/node/rte_node_udp4_input_api.h
new file mode 100644
index 0000000000..7217b914ec
--- /dev/null
+++ b/lib/node/rte_node_udp4_input_api.h
@@ -0,0 +1,60 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2023 Marvell International Ltd.
+ */
+
+#ifndef __INCLUDE_RTE_NODE_UDP4_INPUT_API_H__
+#define __INCLUDE_RTE_NODE_UDP4_INPUT_API_H__
+
+/**
+ * @file rte_node_udp4_input_api.h
+ *
+ * @warning
+ * @b EXPERIMENTAL:
+ * All functions in this file may be changed or removed without prior notice.
+ *
+ * This API allows to control path functions of udp4_* nodes
+ * like udp4_input.
+ *
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rte_common.h>
+#include <rte_compat.h>
+
+/**
+ * UDP4 lookup next nodes.
+ */
+enum rte_node_udp4_input_next {
+	RTE_NODE_UDP4_INPUT_NEXT_PKT_DROP,
+	/**< Packet drop node. */
+};
+
+/**
+ * Add usr node to receive udp4 frames.
+ *
+ * @param usr_node
+ * Node registered by user to receive data.
+ */
+__rte_experimental
+int rte_node_udp4_usr_node_add(const char *usr_node);
+
+/**
+ * Add udpv4 dst_port to lookup table.
+ *
+ * @param dst_port
+ *   Dst Port of packet to be added for consumption.
+ * @param next_node
+ *   Next node packet to be added for consumption.
+ * @return
+ *   0 on success, negative otherwise.
+ */
+__rte_experimental
+int rte_node_udp4_dst_port_add(uint32_t dst_port, rte_edge_t next_node);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __INCLUDE_RTE_NODE_UDP4_API_H__ */
diff --git a/lib/node/udp4_input.c b/lib/node/udp4_input.c
new file mode 100644
index 0000000000..80cedce548
--- /dev/null
+++ b/lib/node/udp4_input.c
@@ -0,0 +1,226 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2023 Marvell International Ltd.
+ */
+
+#include <arpa/inet.h>
+#include <sys/socket.h>
+
+#include <rte_ethdev.h>
+#include <rte_ether.h>
+#include <rte_graph.h>
+#include <rte_graph_worker.h>
+#include <rte_ip.h>
+#include <rte_lpm.h>
+#include <rte_hash.h>
+#include <rte_fbk_hash.h>
+#include <rte_jhash.h>
+#include <rte_hash_crc.h>
+
+
+#include "rte_node_udp4_input_api.h"
+
+#include "node_private.h"
+
+#define UDP4_INPUT_HASH_TBL_SIZE 1024
+
+#define UDP4_INPUT_NODE_HASH(ctx) \
+	(((struct udp4_input_node_ctx *)ctx)->hash)
+
+#define UDP4_INPUT_NODE_NEXT_INDEX(ctx) \
+	(((struct udp4_input_node_ctx *)ctx)->next_index)
+
+
+/* UDP4 input  global data struct */
+struct udp4_input_node_main {
+	struct rte_hash *hash_tbl[RTE_MAX_NUMA_NODES];
+};
+
+static struct udp4_input_node_main udp4_input_nm;
+
+struct udp4_input_node_ctx {
+	/* Socket's Hash table */
+	struct rte_hash *hash;
+	/* Cached next index */
+	uint16_t next_index;
+};
+
+struct flow_key {
+	uint32_t prt_dst;
+};
+
+static struct rte_hash_parameters udp4_params = {
+	.entries = UDP4_INPUT_HASH_TBL_SIZE,
+	.key_len = sizeof(uint32_t),
+	.hash_func = rte_jhash,
+	.hash_func_init_val = 0,
+	.socket_id = 0,
+};
+
+int
+rte_node_udp4_dst_port_add(uint32_t dst_port, rte_edge_t next_node)
+{
+	uint8_t socket;
+	int rc;
+
+	for (socket = 0; socket < RTE_MAX_NUMA_NODES; socket++) {
+		if (!udp4_input_nm.hash_tbl[socket])
+			continue;
+
+		rc = rte_hash_add_key_data(udp4_input_nm.hash_tbl[socket],
+					   &dst_port, (void *)(uintptr_t)next_node);
+		if (rc < 0) {
+			node_err("udp4_lookup", "Failed to add key for sock %u, rc=%d",
+					socket, rc);
+			return rc;
+		}
+	}
+	return 0;
+}
+
+int
+rte_node_udp4_usr_node_add(const char *usr_node)
+{
+	const char *next_nodes = usr_node;
+	rte_node_t udp4_input_node_id, count;
+
+	udp4_input_node_id = rte_node_from_name("udp4_input");
+	count = rte_node_edge_update(udp4_input_node_id, RTE_EDGE_ID_INVALID,
+				     &next_nodes, 1);
+	if (count == 0) {
+		node_dbg("udp4_input", "Adding usr node as edge to udp4_input failed");
+		return count;
+	}
+	count = rte_node_edge_count(udp4_input_node_id) - 1;
+	return count;
+}
+
+static int
+setup_udp4_dstprt_hash(struct udp4_input_node_main *nm, int socket)
+{
+	struct rte_hash_parameters *hash_udp4 = &udp4_params;
+	char s[RTE_HASH_NAMESIZE];
+
+	/* One Hash table per socket */
+	if (nm->hash_tbl[socket])
+		return 0;
+
+	/* create Hash table */
+	snprintf(s, sizeof(s), "UDP4_INPUT_HASH_%d", socket);
+	hash_udp4->name = s;
+	hash_udp4->socket_id = socket;
+	nm->hash_tbl[socket] = rte_hash_create(hash_udp4);
+	if (nm->hash_tbl[socket] == NULL)
+		return -rte_errno;
+
+	return 0;
+}
+
+static int
+udp4_input_node_init(const struct rte_graph *graph, struct rte_node *node)
+{
+	uint16_t socket, lcore_id;
+	static uint8_t init_once;
+	int rc;
+
+	RTE_SET_USED(graph);
+	RTE_BUILD_BUG_ON(sizeof(struct udp4_input_node_ctx) > RTE_NODE_CTX_SZ);
+
+	if (!init_once) {
+
+		/* Setup HASH tables for all sockets */
+		RTE_LCORE_FOREACH(lcore_id)
+		{
+			socket = rte_lcore_to_socket_id(lcore_id);
+			rc = setup_udp4_dstprt_hash(&udp4_input_nm, socket);
+			if (rc) {
+				node_err("udp4_lookup",
+						"Failed to setup hash tbl for sock %u, rc=%d",
+						socket, rc);
+				return rc;
+			}
+		}
+		init_once = 1;
+	}
+
+	UDP4_INPUT_NODE_HASH(node->ctx) = udp4_input_nm.hash_tbl[graph->socket];
+
+	node_dbg("udp4_input", "Initialized udp4_input node");
+	return 0;
+}
+
+static uint16_t
+udp4_input_node_process_scalar(struct rte_graph *graph, struct rte_node *node,
+			       void **objs, uint16_t nb_objs)
+{
+	struct rte_hash *hash_tbl_handle = UDP4_INPUT_NODE_HASH(node->ctx);
+	rte_edge_t next_index, udplookup_node;
+	struct rte_udp_hdr *pkt_udp_hdr;
+	uint16_t last_spec = 0;
+	void **to_next, **from;
+	struct rte_mbuf *mbuf;
+	uint16_t held = 0;
+	uint16_t next = 0;
+	int i, rc;
+
+	/* Speculative next */
+	next_index = UDP4_INPUT_NODE_NEXT_INDEX(node->ctx);
+
+	from = objs;
+
+	to_next = rte_node_next_stream_get(graph, node, next_index, nb_objs);
+	for (i = 0; i < nb_objs; i++) {
+		struct flow_key key_port;
+
+		mbuf = (struct rte_mbuf *)objs[i];
+		pkt_udp_hdr = rte_pktmbuf_mtod_offset(mbuf, struct rte_udp_hdr *,
+						sizeof(struct rte_ether_hdr) +
+						sizeof(struct rte_ipv4_hdr));
+
+		key_port.prt_dst = rte_cpu_to_be_16(pkt_udp_hdr->dst_port);
+		rc = rte_hash_lookup_data(hash_tbl_handle,
+					  &key_port.prt_dst,
+					  (void **)&udplookup_node);
+		next = (rc < 0) ? RTE_NODE_UDP4_INPUT_NEXT_PKT_DROP
+				    : udplookup_node;
+
+		if (unlikely(next_index != next)) {
+			/* Copy things successfully speculated till now */
+			rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
+			from += last_spec;
+			to_next += last_spec;
+			held += last_spec;
+			last_spec = 0;
+
+			rte_node_enqueue_x1(graph, node, next, from[0]);
+			from += 1;
+		} else {
+			last_spec += 1;
+		}
+	}
+	/* !!! Home run !!! */
+	if (likely(last_spec == nb_objs)) {
+		rte_node_next_stream_move(graph, node, next_index);
+		return nb_objs;
+	}
+	held += last_spec;
+	rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
+	rte_node_next_stream_put(graph, node, next_index, held);
+	/* Save the last next used */
+	UDP4_INPUT_NODE_NEXT_INDEX(node->ctx) = next;
+
+	return nb_objs;
+}
+
+static struct rte_node_register udp4_input_node = {
+	.process = udp4_input_node_process_scalar,
+	.name = "udp4_input",
+
+	.init = udp4_input_node_init,
+
+	.nb_edges = RTE_NODE_UDP4_INPUT_NEXT_PKT_DROP + 1,
+	.next_nodes = {
+		[RTE_NODE_UDP4_INPUT_NEXT_PKT_DROP] = "pkt_drop",
+	},
+};
+
+RTE_NODE_REGISTER(udp4_input_node);
diff --git a/lib/node/version.map b/lib/node/version.map
index 40df308bfe..c51befce09 100644
--- a/lib/node/version.map
+++ b/lib/node/version.map
@@ -6,6 +6,8 @@ EXPERIMENTAL {
 	rte_node_ip4_rewrite_add;
 	rte_node_ip6_rewrite_add;
 	rte_node_ip6_route_add;
+	rte_node_udp4_usr_node_add;
+	rte_node_udp4_dst_port_add;
 	rte_node_logtype;
 	local: *;
 };
-- 
2.25.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v4 1/2] node: add IPv4 local node to handle local pkts
  2023-07-04 10:50   ` [PATCH v3 1/2] node: add IPv4 local node to handle local pkts Rakesh Kudurumalla
  2023-07-04 10:50     ` [PATCH v3 2/2] node: add UDP v4 support Rakesh Kudurumalla
@ 2023-09-27  9:21     ` Rakesh Kudurumalla
  2023-09-27  9:21       ` [PATCH v4 2/2] node: add UDP v4 support Rakesh Kudurumalla
  2023-09-27 12:40       ` [PATCH v5 1/2] node: add IPv4 local node to handle local pkts Rakesh Kudurumalla
  1 sibling, 2 replies; 16+ messages in thread
From: Rakesh Kudurumalla @ 2023-09-27  9:21 UTC (permalink / raw)
  To: Jerin Jacob, Kiran Kumar K, Nithin Dabilpuram, Zhirun Yan,
	Pavan Nikhilesh
  Cc: dev, Rakesh Kudurumalla

Local or Host destined pkts can be redirected IPv4 local node
using IP4 Lookup node entries with prefix of 32 and be redirected
to this IP4 local node for further processing.

Signed-off-by: Rakesh Kudurumalla <rkudurumalla@marvell.com>
---
v4: Updated on TOT

 doc/guides/prog_guide/graph_lib.rst           |  15 ++
 .../img/graph_inbuilt_node_flow.svg           | 138 ++++++++++--------
 lib/node/ip4_local.c                          |  88 +++++++++++
 lib/node/ip4_lookup.c                         |   1 +
 lib/node/meson.build                          |   1 +
 lib/node/rte_node_ip4_api.h                   |  12 ++
 6 files changed, 196 insertions(+), 59 deletions(-)
 create mode 100644 lib/node/ip4_local.c

diff --git a/doc/guides/prog_guide/graph_lib.rst b/doc/guides/prog_guide/graph_lib.rst
index e7b6e12004..f2e04a68b9 100644
--- a/doc/guides/prog_guide/graph_lib.rst
+++ b/doc/guides/prog_guide/graph_lib.rst
@@ -498,3 +498,18 @@ Uses ``poll`` function to poll on the socket fd
 for ``POLLIN`` events to read the packets from raw socket
 to stream buffer and does ``rte_node_next_stream_move()``
 when there are received packets.
+
+ip4_local
+~~~~~~~~~
+This node is an intermediate node that does ``packet_type`` lookup for
+the received ipv4 packets and the result determines each packets next node.
+
+On successful ``packet_type`` lookup, for any IPv4 protocol the result
+contains the ``next_node`` id and ``next-hop`` id with which the packet
+needs to be further processed.
+
+On packet_type lookup failure, objects are redirected to ``pkt_drop`` node.
+``rte_node_ip4_route_add()`` is control path API to add ipv4 address with 32 bit
+depth to receive to packets.
+To achieve home run, node use ``rte_node_stream_move()`` as mentioned in above
+sections.
diff --git a/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg b/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg
index 7eea94701f..b954f6fba1 100644
--- a/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg
+++ b/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg
@@ -37,174 +37,194 @@ digraph dpdk_inbuilt_nodes_flow {
     ethdev_tx -> pkt_drop [color="cyan" style="dashed"]
     pkt_cls->pkt_drop   [color="cyan" style="dashed"]
     kernel_tx -> kernel_rx [color="red" style="dashed"]
+    ip4_lookup -> ip4_local
+    ip4_local -> pkt_drop [color="cyan" style="dashed"]
 }
 
  -->
 <!-- input nodes -->
 <!-- Title: dpdk_inbuilt_nodes_flow Pages: 1 -->
-<svg width="470pt" height="425pt"
- viewBox="0.00 0.00 470.23 424.50" 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 420.5)">
+<svg width="525pt" height="458pt"
+ viewBox="0.00 0.00 524.91 458.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 454)">
 <title>dpdk_inbuilt_nodes_flow</title>
-<polygon fill="white" stroke="none" points="-4,4 -4,-420.5 466.23,-420.5 466.23,4 -4,4"/>
+<polygon fill="white" stroke="transparent" points="-4,4 -4,-454 520.91,-454 520.91,4 -4,4"/>
 <!-- ethdev_rx -->
 <g id="node1" class="node">
 <title>ethdev_rx</title>
-<ellipse fill="none" stroke="green" cx="219.23" cy="-398.5" rx="47.77" ry="18"/>
-<text text-anchor="middle" x="219.23" y="-393.45" font-family="Times,serif" font-size="14.00">ethdev_rx</text>
+<ellipse fill="none" stroke="green" cx="120" cy="-432" rx="56.59" ry="18"/>
+<text text-anchor="middle" x="120" y="-428.3" font-family="Times,serif" font-size="14.00">ethdev_rx</text>
 </g>
 <!-- pkt_cls -->
 <g id="node6" class="node">
 <title>pkt_cls</title>
-<ellipse fill="none" stroke="red" cx="219.23" cy="-325.5" rx="37.53" ry="18"/>
-<text text-anchor="middle" x="219.23" y="-320.45" font-family="Times,serif" font-size="14.00">pkt_cls</text>
+<ellipse fill="none" stroke="red" cx="120" cy="-359" rx="42.79" ry="18"/>
+<text text-anchor="middle" x="120" y="-355.3" font-family="Times,serif" font-size="14.00">pkt_cls</text>
 </g>
 <!-- ethdev_rx&#45;&gt;pkt_cls -->
 <g id="edge1" class="edge">
 <title>ethdev_rx&#45;&gt;pkt_cls</title>
-<path fill="none" stroke="black" d="M219.23,-380.31C219.23,-372.55 219.23,-363.18 219.23,-354.45"/>
-<polygon fill="black" stroke="black" points="222.73,-354.53 219.23,-344.53 215.73,-354.53 222.73,-354.53"/>
+<path fill="none" stroke="black" d="M120,-413.81C120,-405.79 120,-396.05 120,-387.07"/>
+<polygon fill="black" stroke="black" points="123.5,-387.03 120,-377.03 116.5,-387.03 123.5,-387.03"/>
 </g>
 <!-- kernel_rx -->
 <g id="node2" class="node">
 <title>kernel_rx</title>
-<ellipse fill="none" stroke="green" cx="46.23" cy="-164" rx="46.23" ry="18"/>
-<text text-anchor="middle" x="46.23" y="-158.95" font-family="Times,serif" font-size="14.00">kernel_rx</text>
+<ellipse fill="none" stroke="green" cx="82" cy="-199" rx="53.89" ry="18"/>
+<text text-anchor="middle" x="82" y="-195.3" font-family="Times,serif" font-size="14.00">kernel_rx</text>
 </g>
 <!-- kernel_rx&#45;&gt;pkt_cls -->
 <g id="edge2" class="edge">
 <title>kernel_rx&#45;&gt;pkt_cls</title>
-<path fill="none" stroke="black" d="M41.45,-182.08C37.1,-201.37 33.27,-232.96 47.23,-255 73.68,-296.74 130.21,-313.41 171.26,-320.07"/>
-<polygon fill="black" stroke="black" points="170.73,-323.68 181.13,-321.66 171.74,-316.75 170.73,-323.68"/>
+<path fill="none" stroke="black" d="M70.87,-216.92C60.28,-235.27 47.29,-265.24 57,-290 64.12,-308.16 78.62,-324.37 91.92,-336.4"/>
+<polygon fill="black" stroke="black" points="89.69,-339.1 99.54,-342.99 94.26,-333.8 89.69,-339.1"/>
 </g>
 <!-- ethdev_tx -->
 <g id="node3" class="node">
 <title>ethdev_tx</title>
-<ellipse fill="none" stroke="magenta" cx="293.23" cy="-91" rx="47.26" ry="18"/>
-<text text-anchor="middle" x="293.23" y="-85.95" font-family="Times,serif" font-size="14.00">ethdev_tx</text>
+<ellipse fill="none" stroke="magenta" cx="338" cy="-91" rx="55.79" ry="18"/>
+<text text-anchor="middle" x="338" y="-87.3" font-family="Times,serif" font-size="14.00">ethdev_tx</text>
 </g>
 <!-- pkt_drop -->
 <g id="node4" class="node">
 <title>pkt_drop</title>
-<ellipse fill="none" stroke="cyan" cx="349.23" cy="-18" rx="44.19" ry="18"/>
-<text text-anchor="middle" x="349.23" y="-12.95" font-family="Times,serif" font-size="14.00">pkt_drop</text>
+<ellipse fill="none" stroke="cyan" cx="254" cy="-18" rx="51.99" ry="18"/>
+<text text-anchor="middle" x="254" y="-14.3" font-family="Times,serif" font-size="14.00">pkt_drop</text>
 </g>
 <!-- ethdev_tx&#45;&gt;pkt_drop -->
 <g id="edge14" class="edge">
 <title>ethdev_tx&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M306.22,-73.53C313.15,-64.75 321.81,-53.76 329.55,-43.96"/>
-<polygon fill="cyan" stroke="cyan" points="332.87,-46.4 336.32,-36.38 327.37,-42.06 332.87,-46.4"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M318.94,-73.89C307.58,-64.29 293,-51.96 280.53,-41.42"/>
+<polygon fill="cyan" stroke="cyan" points="282.59,-38.58 272.7,-34.8 278.07,-43.93 282.59,-38.58"/>
 </g>
 <!-- kernel_tx -->
 <g id="node5" class="node">
 <title>kernel_tx</title>
-<ellipse fill="none" stroke="blue" cx="102.23" cy="-237" rx="45.72" ry="18"/>
-<text text-anchor="middle" x="102.23" y="-231.95" font-family="Times,serif" font-size="14.00">kernel_tx</text>
+<ellipse fill="none" stroke="blue" cx="120" cy="-272" rx="53.89" ry="18"/>
+<text text-anchor="middle" x="120" y="-268.3" font-family="Times,serif" font-size="14.00">kernel_tx</text>
 </g>
 <!-- kernel_tx&#45;&gt;kernel_rx -->
 <g id="edge16" class="edge">
 <title>kernel_tx&#45;&gt;kernel_rx</title>
-<path fill="none" stroke="red" stroke-dasharray="5,2" d="M89.25,-219.53C82.32,-210.75 73.65,-199.76 65.92,-189.96"/>
-<polygon fill="red" stroke="red" points="68.09,-188.06 59.15,-182.38 62.6,-192.4 68.09,-188.06"/>
+<path fill="none" stroke="red" stroke-dasharray="5,2" d="M110.99,-254.17C106.52,-245.81 101,-235.51 95.99,-226.14"/>
+<polygon fill="red" stroke="red" points="99.01,-224.36 91.2,-217.2 92.84,-227.67 99.01,-224.36"/>
 </g>
 <!-- pkt_cls&#45;&gt;pkt_drop -->
 <g id="edge15" class="edge">
 <title>pkt_cls&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M255.09,-319.38C322.68,-308.72 462.23,-281.44 462.23,-238 462.23,-238 462.23,-238 462.23,-90 462.23,-57.84 429.01,-39.68 398.59,-29.8"/>
-<polygon fill="cyan" stroke="cyan" points="400.02,-26.27 389.44,-26.75 398.01,-32.98 400.02,-26.27"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M84,-348.97C48.65,-337.7 0,-314.61 0,-273 0,-273 0,-273 0,-90 0,-49.99 118.4,-31.52 193.52,-23.82"/>
+<polygon fill="cyan" stroke="cyan" points="194.21,-27.27 203.82,-22.81 193.52,-20.31 194.21,-27.27"/>
 </g>
 <!-- pkt_cls&#45;&gt;kernel_tx -->
 <g id="edge5" class="edge">
 <title>pkt_cls&#45;&gt;kernel_tx</title>
-<path fill="none" stroke="blue" d="M186.99,-315.75C170.62,-310.16 151.14,-301.64 136.48,-289.5 128.23,-282.66 121.2,-273.31 115.7,-264.46"/>
-<polygon fill="blue" stroke="blue" points="118.38,-263.1 110.34,-256.2 112.32,-266.61 118.38,-263.1"/>
-<text text-anchor="middle" x="176.61" y="-276.2" font-family="Times,serif" font-size="14.00">exception pkts</text>
+<path fill="none" stroke="blue" d="M120,-340.8C120,-329.16 120,-313.55 120,-300.24"/>
+<polygon fill="blue" stroke="blue" points="123.5,-300.18 120,-290.18 116.5,-300.18 123.5,-300.18"/>
+<text text-anchor="middle" x="172.5" y="-311.8" font-family="Times,serif" font-size="14.00">exception pkts</text>
 </g>
 <!-- ip4_lookup -->
 <g id="node7" class="node">
 <title>ip4_lookup</title>
-<ellipse fill="none" stroke="black" cx="219.23" cy="-237" rx="52.89" ry="18"/>
-<text text-anchor="middle" x="219.23" y="-231.95" font-family="Times,serif" font-size="14.00">ip4_lookup</text>
+<ellipse fill="none" stroke="black" cx="252" cy="-272" rx="60.39" ry="18"/>
+<text text-anchor="middle" x="252" y="-268.3" font-family="Times,serif" font-size="14.00">ip4_lookup</text>
 </g>
 <!-- pkt_cls&#45;&gt;ip4_lookup -->
 <g id="edge3" class="edge">
 <title>pkt_cls&#45;&gt;ip4_lookup</title>
-<path fill="none" stroke="black" d="M219.23,-307.41C219.23,-295.64 219.23,-279.73 219.23,-266.11"/>
-<polygon fill="black" stroke="black" points="222.73,-266.35 219.23,-256.35 215.73,-266.35 222.73,-266.35"/>
-<text text-anchor="middle" x="231.23" y="-276.2" font-family="Times,serif" font-size="14.00">ipv4</text>
+<path fill="none" stroke="black" d="M160.54,-352.79C182.64,-348.15 209.23,-339.41 228,-323 235.09,-316.81 240.26,-308.05 243.95,-299.6"/>
+<polygon fill="black" stroke="black" points="247.32,-300.57 247.62,-289.98 240.78,-298.07 247.32,-300.57"/>
+<text text-anchor="middle" x="254.5" y="-311.8" font-family="Times,serif" font-size="14.00">ipv4</text>
 </g>
 <!-- ip6_lookup -->
 <g id="node8" class="node">
 <title>ip6_lookup</title>
-<ellipse fill="none" stroke="black" cx="343.23" cy="-237" rx="52.89" ry="18"/>
-<text text-anchor="middle" x="343.23" y="-231.95" font-family="Times,serif" font-size="14.00">ip6_lookup</text>
+<ellipse fill="none" stroke="black" cx="439" cy="-272" rx="60.39" ry="18"/>
+<text text-anchor="middle" x="439" y="-268.3" font-family="Times,serif" font-size="14.00">ip6_lookup</text>
 </g>
 <!-- pkt_cls&#45;&gt;ip6_lookup -->
 <g id="edge4" class="edge">
 <title>pkt_cls&#45;&gt;ip6_lookup</title>
-<path fill="none" stroke="black" d="M239.99,-310.02C259.62,-296.33 289.35,-275.59 311.88,-259.87"/>
-<polygon fill="black" stroke="black" points="313.53,-262.29 319.73,-253.7 309.53,-256.55 313.53,-262.29"/>
-<text text-anchor="middle" x="304.23" y="-276.2" font-family="Times,serif" font-size="14.00">ipv6</text>
+<path fill="none" stroke="black" d="M157.52,-350.25C188.82,-343.6 234.51,-333.46 274,-323 313.2,-312.62 357.13,-299.22 389.79,-288.91"/>
+<polygon fill="black" stroke="black" points="391.08,-292.17 399.55,-285.81 388.96,-285.5 391.08,-292.17"/>
+<text text-anchor="middle" x="339.5" y="-311.8" font-family="Times,serif" font-size="14.00">ipv6</text>
 </g>
 <!-- ip4_lookup&#45;&gt;pkt_drop -->
 <g id="edge7" class="edge">
 <title>ip4_lookup&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M192.86,-221.12C179.2,-211.83 163.82,-198.49 156.23,-182 149.55,-167.46 150.78,-161.04 156.23,-146 176.39,-90.45 198.32,-78.19 252.23,-54 269.14,-46.41 288.24,-39.24 304.98,-33.38"/>
-<polygon fill="cyan" stroke="cyan" points="305.75,-36.48 314.07,-29.92 303.47,-29.86 305.75,-36.48"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M239.17,-254.03C232.31,-243.87 224.56,-230.37 221,-217 204.89,-156.57 227.58,-83.56 242.59,-45.31"/>
+<polygon fill="cyan" stroke="cyan" points="245.89,-46.5 246.4,-35.92 239.4,-43.87 245.89,-46.5"/>
 </g>
 <!-- ip4_rewrite -->
 <g id="node9" class="node">
 <title>ip4_rewrite</title>
-<ellipse fill="none" stroke="black" cx="218.23" cy="-164" rx="53.4" ry="18"/>
-<text text-anchor="middle" x="218.23" y="-158.95" font-family="Times,serif" font-size="14.00">ip4_rewrite</text>
+<ellipse fill="none" stroke="black" cx="294" cy="-199" rx="63.89" ry="18"/>
+<text text-anchor="middle" x="294" y="-195.3" font-family="Times,serif" font-size="14.00">ip4_rewrite</text>
 </g>
 <!-- ip4_lookup&#45;&gt;ip4_rewrite -->
 <g id="edge6" class="edge">
 <title>ip4_lookup&#45;&gt;ip4_rewrite</title>
-<path fill="none" stroke="black" d="M218.99,-218.81C218.88,-211.05 218.75,-201.68 218.63,-192.95"/>
-<polygon fill="black" stroke="black" points="222.11,-192.98 218.47,-183.03 215.11,-193.08 222.11,-192.98"/>
+<path fill="none" stroke="black" d="M261.95,-254.17C266.95,-245.72 273.12,-235.29 278.71,-225.85"/>
+<polygon fill="black" stroke="black" points="281.75,-227.59 283.83,-217.2 275.72,-224.02 281.75,-227.59"/>
+</g>
+<!-- ip4_local -->
+<g id="node11" class="node">
+<title>ip4_local</title>
+<ellipse fill="none" stroke="black" cx="136" cy="-145" rx="51.19" ry="18"/>
+<text text-anchor="middle" x="136" y="-141.3" font-family="Times,serif" font-size="14.00">ip4_local</text>
+</g>
+<!-- ip4_lookup&#45;&gt;ip4_local -->
+<g id="edge17" class="edge">
+<title>ip4_lookup&#45;&gt;ip4_local</title>
+<path fill="none" stroke="black" d="M218.11,-256.86C207.64,-251.39 196.61,-244.41 188,-236 169.45,-217.88 155.34,-191.74 146.53,-172.29"/>
+<polygon fill="black" stroke="black" points="149.72,-170.86 142.52,-163.08 143.3,-173.65 149.72,-170.86"/>
 </g>
 <!-- ip6_lookup&#45;&gt;pkt_drop -->
 <g id="edge11" class="edge">
 <title>ip6_lookup&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M369.2,-221.03C382.65,-211.71 397.78,-198.37 405.23,-182 426.87,-134.45 392.95,-75.95 369.19,-43.54"/>
-<polygon fill="cyan" stroke="cyan" points="371.64,-41.98 362.81,-36.13 366.06,-46.21 371.64,-41.98"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M470.57,-256.44C486.08,-247.46 503.27,-234.31 512,-217 519.2,-202.71 517.24,-196.12 512,-181 486.88,-108.48 466,-83.15 395,-54 367.69,-42.79 335.88,-34.51 309.39,-28.83"/>
+<polygon fill="cyan" stroke="cyan" points="310.02,-25.39 299.52,-26.78 308.6,-32.24 310.02,-25.39"/>
 </g>
 <!-- ip6_rewrite -->
 <g id="node10" class="node">
 <title>ip6_rewrite</title>
-<ellipse fill="none" stroke="black" cx="343.23" cy="-164" rx="53.4" ry="18"/>
-<text text-anchor="middle" x="343.23" y="-158.95" font-family="Times,serif" font-size="14.00">ip6_rewrite</text>
+<ellipse fill="none" stroke="black" cx="439" cy="-199" rx="63.89" ry="18"/>
+<text text-anchor="middle" x="439" y="-195.3" font-family="Times,serif" font-size="14.00">ip6_rewrite</text>
 </g>
 <!-- ip6_lookup&#45;&gt;ip6_rewrite -->
 <g id="edge10" class="edge">
 <title>ip6_lookup&#45;&gt;ip6_rewrite</title>
-<path fill="none" stroke="black" d="M343.23,-218.81C343.23,-211.05 343.23,-201.68 343.23,-192.95"/>
-<polygon fill="black" stroke="black" points="346.73,-193.03 343.23,-183.03 339.73,-193.03 346.73,-193.03"/>
+<path fill="none" stroke="black" d="M439,-253.81C439,-245.79 439,-236.05 439,-227.07"/>
+<polygon fill="black" stroke="black" points="442.5,-227.03 439,-217.03 435.5,-227.03 442.5,-227.03"/>
 </g>
 <!-- ip4_rewrite&#45;&gt;ethdev_tx -->
 <g id="edge8" class="edge">
 <title>ip4_rewrite&#45;&gt;ethdev_tx</title>
-<path fill="none" stroke="green" d="M235.63,-146.53C245.35,-137.33 257.64,-125.7 268.36,-115.54"/>
-<polygon fill="green" stroke="green" points="270.34,-118.55 275.19,-109.13 265.52,-113.47 270.34,-118.55"/>
+<path fill="none" stroke="green" d="M301.07,-180.97C308.09,-164.05 318.96,-137.86 327.09,-118.28"/>
+<polygon fill="green" stroke="green" points="330.35,-119.57 330.95,-108.99 323.88,-116.88 330.35,-119.57"/>
 </g>
 <!-- ip4_rewrite&#45;&gt;pkt_drop -->
 <g id="edge9" class="edge">
 <title>ip4_rewrite&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M217.56,-145.54C217.71,-125.89 220.78,-93.99 237.23,-73 253.17,-52.67 278.68,-39.55 301.33,-31.33"/>
-<polygon fill="cyan" stroke="cyan" points="302.14,-34.42 310.5,-27.9 299.9,-27.79 302.14,-34.42"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M289.85,-180.97C285.53,-163.07 278.61,-134.1 273,-109 268.3,-87.99 263.29,-64.16 259.59,-46.3"/>
+<polygon fill="cyan" stroke="cyan" points="262.97,-45.37 257.52,-36.28 256.11,-46.78 262.97,-45.37"/>
 </g>
 <!-- ip6_rewrite&#45;&gt;ethdev_tx -->
 <g id="edge12" class="edge">
 <title>ip6_rewrite&#45;&gt;ethdev_tx</title>
-<path fill="none" stroke="green" d="M331.38,-146.17C325.34,-137.6 317.87,-126.99 311.15,-117.44"/>
-<polygon fill="green" stroke="green" points="313.62,-115.87 305,-109.71 307.89,-119.9 313.62,-115.87"/>
+<path fill="none" stroke="green" d="M423.22,-181.44C406.47,-163.86 379.84,-135.91 360.81,-115.94"/>
+<polygon fill="green" stroke="green" points="363.1,-113.27 353.67,-108.45 358.03,-118.1 363.1,-113.27"/>
 </g>
 <!-- ip6_rewrite&#45;&gt;pkt_drop -->
 <g id="edge13" class="edge">
 <title>ip6_rewrite&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M345.67,-145.53C347.02,-134.98 348.56,-121.24 349.23,-109 350.38,-88.27 350.34,-64.81 350.03,-47.04"/>
-<polygon fill="cyan" stroke="cyan" points="353.51,-47.19 349.8,-37.27 346.51,-47.34 353.51,-47.19"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M438.77,-180.67C437.49,-154.09 431.22,-103.19 403,-73 379.35,-47.7 342.93,-34.22 312.02,-27.06"/>
+<polygon fill="cyan" stroke="cyan" points="312.71,-23.63 302.2,-24.95 311.24,-30.47 312.71,-23.63"/>
+</g>
+<!-- ip4_local&#45;&gt;pkt_drop -->
+<g id="edge18" class="edge">
+<title>ip4_local&#45;&gt;pkt_drop</title>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M142.47,-126.87C150.6,-107.23 166.18,-75.04 188,-54 195,-47.25 203.56,-41.45 212.16,-36.63"/>
+<polygon fill="cyan" stroke="cyan" points="213.85,-39.7 221.08,-31.95 210.6,-33.5 213.85,-39.7"/>
 </g>
 </g>
 </svg>
diff --git a/lib/node/ip4_local.c b/lib/node/ip4_local.c
new file mode 100644
index 0000000000..fb31d0f970
--- /dev/null
+++ b/lib/node/ip4_local.c
@@ -0,0 +1,88 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2023 Marvell International Ltd.
+ */
+
+#include <arpa/inet.h>
+#include <sys/socket.h>
+
+#include <rte_ethdev.h>
+#include <rte_ether.h>
+#include <rte_graph.h>
+#include <rte_graph_worker.h>
+#include <rte_ip.h>
+#include <rte_lpm.h>
+#include <rte_hash.h>
+#include <rte_fbk_hash.h>
+#include <rte_jhash.h>
+#include <rte_hash_crc.h>
+
+
+#include "rte_node_ip4_api.h"
+
+#include "node_private.h"
+
+static uint16_t
+ip4_local_node_process_scalar(struct rte_graph *graph, struct rte_node *node,
+			      void **objs, uint16_t nb_objs)
+{
+	void **to_next, **from;
+	uint16_t last_spec = 0;
+	rte_edge_t next_index;
+	struct rte_mbuf *mbuf;
+	uint16_t held = 0;
+	uint32_t l4;
+	int i;
+
+	/* Speculative next */
+	next_index = RTE_NODE_IP4_LOCAL_NEXT_UDP4_INPUT;
+
+	from = objs;
+	to_next = rte_node_next_stream_get(graph, node, next_index, nb_objs);
+	for (i = 0; i < nb_objs; i++) {
+		uint16_t next;
+
+		mbuf = (struct rte_mbuf *)objs[i];
+		l4 = mbuf->packet_type & RTE_PTYPE_L4_MASK;
+
+		next = (l4 == RTE_PTYPE_L4_UDP)
+				? next_index
+				: RTE_NODE_IP4_LOCAL_NEXT_PKT_DROP;
+
+		if (unlikely(next_index != next)) {
+			/* Copy things successfully speculated till now */
+			rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
+			from += last_spec;
+			to_next += last_spec;
+			held += last_spec;
+			last_spec = 0;
+
+			rte_node_enqueue_x1(graph, node, next, from[0]);
+			from += 1;
+		} else {
+			last_spec += 1;
+		}
+	}
+	/* !!! Home run !!! */
+	if (likely(last_spec == nb_objs)) {
+		rte_node_next_stream_move(graph, node, next_index);
+		return nb_objs;
+	}
+	held += last_spec;
+	rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
+	rte_node_next_stream_put(graph, node, next_index, held);
+
+	return nb_objs;
+}
+
+static struct rte_node_register ip4_local_node = {
+	.process = ip4_local_node_process_scalar,
+	.name = "ip4_local",
+
+	.nb_edges = RTE_NODE_IP4_LOCAL_NEXT_PKT_DROP + 1,
+	.next_nodes = {
+		[RTE_NODE_IP4_LOCAL_NEXT_UDP4_INPUT] = "udp4_input",
+		[RTE_NODE_IP4_LOCAL_NEXT_PKT_DROP] = "pkt_drop",
+	},
+};
+
+RTE_NODE_REGISTER(ip4_local_node);
diff --git a/lib/node/ip4_lookup.c b/lib/node/ip4_lookup.c
index 8bce03d7db..d3fc48baf7 100644
--- a/lib/node/ip4_lookup.c
+++ b/lib/node/ip4_lookup.c
@@ -227,6 +227,7 @@ static struct rte_node_register ip4_lookup_node = {
 
 	.nb_edges = RTE_NODE_IP4_LOOKUP_NEXT_MAX,
 	.next_nodes = {
+		[RTE_NODE_IP4_LOOKUP_NEXT_IP4_LOCAL] = "ip4_local",
 		[RTE_NODE_IP4_LOOKUP_NEXT_REWRITE] = "ip4_rewrite",
 		[RTE_NODE_IP4_LOOKUP_NEXT_PKT_DROP] = "pkt_drop",
 	},
diff --git a/lib/node/meson.build b/lib/node/meson.build
index 2fa7c1c8f3..c0d5b09e2f 100644
--- a/lib/node/meson.build
+++ b/lib/node/meson.build
@@ -12,6 +12,7 @@ sources = files(
         'ethdev_rx.c',
         'ethdev_tx.c',
         'ip4_lookup.c',
+        'ip4_local.c',
         'ip4_rewrite.c',
         'ip6_lookup.c',
         'ip6_rewrite.c',
diff --git a/lib/node/rte_node_ip4_api.h b/lib/node/rte_node_ip4_api.h
index 3397da0ae8..405bdd3283 100644
--- a/lib/node/rte_node_ip4_api.h
+++ b/lib/node/rte_node_ip4_api.h
@@ -30,10 +30,22 @@ enum rte_node_ip4_lookup_next {
 	/**< Rewrite node. */
 	RTE_NODE_IP4_LOOKUP_NEXT_PKT_DROP,
 	/**< Packet drop node. */
+	RTE_NODE_IP4_LOOKUP_NEXT_IP4_LOCAL,
+	/** IP Local node. */
 	RTE_NODE_IP4_LOOKUP_NEXT_MAX,
 	/**< Number of next nodes of lookup node. */
 };
 
+/**
+ * IP4 Local next nodes.
+ */
+enum rte_node_ip4_local_next {
+	RTE_NODE_IP4_LOCAL_NEXT_UDP4_INPUT,
+	/**< ip4 Local node. */
+	RTE_NODE_IP4_LOCAL_NEXT_PKT_DROP,
+	/**< Packet drop node. */
+};
+
 /**
  * Add ipv4 route to lookup table.
  *
-- 
2.25.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v4 2/2] node: add UDP v4 support
  2023-09-27  9:21     ` [PATCH v4 1/2] node: add IPv4 local node to handle local pkts Rakesh Kudurumalla
@ 2023-09-27  9:21       ` Rakesh Kudurumalla
  2023-09-27 12:40       ` [PATCH v5 1/2] node: add IPv4 local node to handle local pkts Rakesh Kudurumalla
  1 sibling, 0 replies; 16+ messages in thread
From: Rakesh Kudurumalla @ 2023-09-27  9:21 UTC (permalink / raw)
  To: Jerin Jacob, Kiran Kumar K, Nithin Dabilpuram, Zhirun Yan,
	Pavan Nikhilesh
  Cc: dev, Rakesh Kudurumalla

IPv4 UDP packets are given to application
with specified UDP destination port given
by user.

Signed-off-by: Rakesh Kudurumalla <rkudurumalla@marvell.com>
---
 doc/api/doxy-api-index.md                     |   3 +-
 doc/guides/prog_guide/graph_lib.rst           |  25 ++
 .../img/graph_inbuilt_node_flow.svg           | 165 ++++++++-----
 lib/node/meson.build                          |   2 +
 lib/node/rte_node_udp4_input_api.h            |  60 +++++
 lib/node/udp4_input.c                         | 226 ++++++++++++++++++
 lib/node/version.map                          |   2 +
 7 files changed, 417 insertions(+), 66 deletions(-)
 create mode 100644 lib/node/rte_node_udp4_input_api.h
 create mode 100644 lib/node/udp4_input.c

diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index fdeda13932..96282d3fd0 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -206,7 +206,8 @@ The public API headers are grouped by topics:
   * graph_nodes:
     [eth_node](@ref rte_node_eth_api.h),
     [ip4_node](@ref rte_node_ip4_api.h),
-    [ip6_node](@ref rte_node_ip6_api.h)
+    [ip6_node](@ref rte_node_ip6_api.h),
+    [udp4_input_node](@ref rte_node_udp4_input_api.h)
 
 - **basic**:
   [bitops](@ref rte_bitops.h),
diff --git a/doc/guides/prog_guide/graph_lib.rst b/doc/guides/prog_guide/graph_lib.rst
index f2e04a68b9..3572560362 100644
--- a/doc/guides/prog_guide/graph_lib.rst
+++ b/doc/guides/prog_guide/graph_lib.rst
@@ -513,3 +513,28 @@ On packet_type lookup failure, objects are redirected to ``pkt_drop`` node.
 depth to receive to packets.
 To achieve home run, node use ``rte_node_stream_move()`` as mentioned in above
 sections.
+
+udp4_input
+~~~~~~~~~~
+This node is an intermediate node that does udp destination port lookup for
+the received ipv4 packets and the result determines each packets next node.
+
+User registers a new node ``udp4_input`` into graph library during initialization
+and attach user specified node as edege to this node using
+``rte_node_udp4_usr_node_add()``, and create empty hash table with destination
+port and node id as its feilds.
+
+After successful addition of user node as edege, edge id is returned to the user.
+
+User would register ``ip4_lookup`` table with specified ip address and 32 bit as mask
+for ip filtration using api ``rte_node_ip4_route_add()``.
+
+After graph is created user would update hash table with custom port with
+and previously obtained edge id using API ``rte_node_udp4_dst_port_add()``.
+
+When packet is received lpm look up is performed if ip is matched the packet
+is handed over to ip4_local node, then packet is verified for udp proto and
+on success packet is enqueued to ``udp4_input`` node.
+
+Hash lookup is performed in ``udp4_input`` node with registered destination port
+and destination port in UDP packet , on success packet is handed to ``udp_user_node``.
diff --git a/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg b/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg
index b954f6fba1..7c451371a7 100644
--- a/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg
+++ b/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg
@@ -39,192 +39,227 @@ digraph dpdk_inbuilt_nodes_flow {
     kernel_tx -> kernel_rx [color="red" style="dashed"]
     ip4_lookup -> ip4_local
     ip4_local -> pkt_drop [color="cyan" style="dashed"]
+    ip4_local -> udp4_input [ label="udpv4"]
+    udp4_input -> udp_user_node
+    udp4_input -> pkt_drop [color="cyan" style="dashed"]
+
 }
 
  -->
 <!-- input nodes -->
 <!-- Title: dpdk_inbuilt_nodes_flow Pages: 1 -->
-<svg width="525pt" height="458pt"
- viewBox="0.00 0.00 524.91 458.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 454)">
+<svg width="631pt" height="437pt"
+ viewBox="0.00 0.00 630.95 437.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 433)">
 <title>dpdk_inbuilt_nodes_flow</title>
-<polygon fill="white" stroke="transparent" points="-4,4 -4,-454 520.91,-454 520.91,4 -4,4"/>
+<polygon fill="white" stroke="transparent" points="-4,4 -4,-433 626.95,-433 626.95,4 -4,4"/>
 <!-- ethdev_rx -->
 <g id="node1" class="node">
 <title>ethdev_rx</title>
-<ellipse fill="none" stroke="green" cx="120" cy="-432" rx="56.59" ry="18"/>
-<text text-anchor="middle" x="120" y="-428.3" font-family="Times,serif" font-size="14.00">ethdev_rx</text>
+<ellipse fill="none" stroke="green" cx="261.95" cy="-411" rx="56.59" ry="18"/>
+<text text-anchor="middle" x="261.95" y="-407.3" font-family="Times,serif" font-size="14.00">ethdev_rx</text>
 </g>
 <!-- pkt_cls -->
 <g id="node6" class="node">
 <title>pkt_cls</title>
-<ellipse fill="none" stroke="red" cx="120" cy="-359" rx="42.79" ry="18"/>
-<text text-anchor="middle" x="120" y="-355.3" font-family="Times,serif" font-size="14.00">pkt_cls</text>
+<ellipse fill="none" stroke="red" cx="261.95" cy="-338" rx="42.79" ry="18"/>
+<text text-anchor="middle" x="261.95" y="-334.3" font-family="Times,serif" font-size="14.00">pkt_cls</text>
 </g>
 <!-- ethdev_rx&#45;&gt;pkt_cls -->
 <g id="edge1" class="edge">
 <title>ethdev_rx&#45;&gt;pkt_cls</title>
-<path fill="none" stroke="black" d="M120,-413.81C120,-405.79 120,-396.05 120,-387.07"/>
-<polygon fill="black" stroke="black" points="123.5,-387.03 120,-377.03 116.5,-387.03 123.5,-387.03"/>
+<path fill="none" stroke="black" d="M261.95,-392.81C261.95,-384.79 261.95,-375.05 261.95,-366.07"/>
+<polygon fill="black" stroke="black" points="265.45,-366.03 261.95,-356.03 258.45,-366.03 265.45,-366.03"/>
 </g>
 <!-- kernel_rx -->
 <g id="node2" class="node">
 <title>kernel_rx</title>
-<ellipse fill="none" stroke="green" cx="82" cy="-199" rx="53.89" ry="18"/>
-<text text-anchor="middle" x="82" y="-195.3" font-family="Times,serif" font-size="14.00">kernel_rx</text>
+<ellipse fill="none" stroke="green" cx="53.95" cy="-178" rx="53.89" ry="18"/>
+<text text-anchor="middle" x="53.95" y="-174.3" font-family="Times,serif" font-size="14.00">kernel_rx</text>
 </g>
 <!-- kernel_rx&#45;&gt;pkt_cls -->
 <g id="edge2" class="edge">
 <title>kernel_rx&#45;&gt;pkt_cls</title>
-<path fill="none" stroke="black" d="M70.87,-216.92C60.28,-235.27 47.29,-265.24 57,-290 64.12,-308.16 78.62,-324.37 91.92,-336.4"/>
-<polygon fill="black" stroke="black" points="89.69,-339.1 99.54,-342.99 94.26,-333.8 89.69,-339.1"/>
+<path fill="none" stroke="black" d="M74.75,-194.8C112.31,-223.33 191.45,-283.45 233.8,-315.62"/>
+<polygon fill="black" stroke="black" points="231.92,-318.59 242,-321.85 236.16,-313.01 231.92,-318.59"/>
 </g>
 <!-- ethdev_tx -->
 <g id="node3" class="node">
 <title>ethdev_tx</title>
-<ellipse fill="none" stroke="magenta" cx="338" cy="-91" rx="55.79" ry="18"/>
-<text text-anchor="middle" x="338" y="-87.3" font-family="Times,serif" font-size="14.00">ethdev_tx</text>
+<ellipse fill="none" stroke="magenta" cx="347.95" cy="-91" rx="55.79" ry="18"/>
+<text text-anchor="middle" x="347.95" y="-87.3" font-family="Times,serif" font-size="14.00">ethdev_tx</text>
 </g>
 <!-- pkt_drop -->
 <g id="node4" class="node">
 <title>pkt_drop</title>
-<ellipse fill="none" stroke="cyan" cx="254" cy="-18" rx="51.99" ry="18"/>
-<text text-anchor="middle" x="254" y="-14.3" font-family="Times,serif" font-size="14.00">pkt_drop</text>
+<ellipse fill="none" stroke="cyan" cx="404.95" cy="-18" rx="51.99" ry="18"/>
+<text text-anchor="middle" x="404.95" y="-14.3" font-family="Times,serif" font-size="14.00">pkt_drop</text>
 </g>
 <!-- ethdev_tx&#45;&gt;pkt_drop -->
 <g id="edge14" class="edge">
 <title>ethdev_tx&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M318.94,-73.89C307.58,-64.29 293,-51.96 280.53,-41.42"/>
-<polygon fill="cyan" stroke="cyan" points="282.59,-38.58 272.7,-34.8 278.07,-43.93 282.59,-38.58"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M361.45,-73.17C368.55,-64.33 377.39,-53.33 385.23,-43.55"/>
+<polygon fill="cyan" stroke="cyan" points="388,-45.69 391.53,-35.71 382.54,-41.31 388,-45.69"/>
 </g>
 <!-- kernel_tx -->
 <g id="node5" class="node">
 <title>kernel_tx</title>
-<ellipse fill="none" stroke="blue" cx="120" cy="-272" rx="53.89" ry="18"/>
-<text text-anchor="middle" x="120" y="-268.3" font-family="Times,serif" font-size="14.00">kernel_tx</text>
+<ellipse fill="none" stroke="blue" cx="53.95" cy="-251" rx="53.89" ry="18"/>
+<text text-anchor="middle" x="53.95" y="-247.3" font-family="Times,serif" font-size="14.00">kernel_tx</text>
 </g>
 <!-- kernel_tx&#45;&gt;kernel_rx -->
 <g id="edge16" class="edge">
 <title>kernel_tx&#45;&gt;kernel_rx</title>
-<path fill="none" stroke="red" stroke-dasharray="5,2" d="M110.99,-254.17C106.52,-245.81 101,-235.51 95.99,-226.14"/>
-<polygon fill="red" stroke="red" points="99.01,-224.36 91.2,-217.2 92.84,-227.67 99.01,-224.36"/>
+<path fill="none" stroke="red" stroke-dasharray="5,2" d="M53.95,-232.81C53.95,-224.79 53.95,-215.05 53.95,-206.07"/>
+<polygon fill="red" stroke="red" points="57.45,-206.03 53.95,-196.03 50.45,-206.03 57.45,-206.03"/>
 </g>
 <!-- pkt_cls&#45;&gt;pkt_drop -->
 <g id="edge15" class="edge">
 <title>pkt_cls&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M84,-348.97C48.65,-337.7 0,-314.61 0,-273 0,-273 0,-273 0,-90 0,-49.99 118.4,-31.52 193.52,-23.82"/>
-<polygon fill="cyan" stroke="cyan" points="194.21,-27.27 203.82,-22.81 193.52,-20.31 194.21,-27.27"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M304.77,-335.88C400.4,-332.2 622.95,-316.71 622.95,-252 622.95,-252 622.95,-252 622.95,-90 622.95,-56.33 527.72,-36.15 463.14,-26.34"/>
+<polygon fill="cyan" stroke="cyan" points="463.46,-22.85 453.06,-24.85 462.44,-29.77 463.46,-22.85"/>
 </g>
 <!-- pkt_cls&#45;&gt;kernel_tx -->
 <g id="edge5" class="edge">
 <title>pkt_cls&#45;&gt;kernel_tx</title>
-<path fill="none" stroke="blue" d="M120,-340.8C120,-329.16 120,-313.55 120,-300.24"/>
-<polygon fill="blue" stroke="blue" points="123.5,-300.18 120,-290.18 116.5,-300.18 123.5,-300.18"/>
-<text text-anchor="middle" x="172.5" y="-311.8" font-family="Times,serif" font-size="14.00">exception pkts</text>
+<path fill="none" stroke="blue" d="M219.14,-335.96C164.86,-333.64 75.77,-326.15 54.95,-302 49.6,-295.81 48.06,-287.4 48.24,-279.24"/>
+<polygon fill="blue" stroke="blue" points="51.73,-279.54 49.23,-269.24 44.76,-278.84 51.73,-279.54"/>
+<text text-anchor="middle" x="107.45" y="-290.8" font-family="Times,serif" font-size="14.00">exception pkts</text>
 </g>
 <!-- ip4_lookup -->
 <g id="node7" class="node">
 <title>ip4_lookup</title>
-<ellipse fill="none" stroke="black" cx="252" cy="-272" rx="60.39" ry="18"/>
-<text text-anchor="middle" x="252" y="-268.3" font-family="Times,serif" font-size="14.00">ip4_lookup</text>
+<ellipse fill="none" stroke="black" cx="261.95" cy="-251" rx="60.39" ry="18"/>
+<text text-anchor="middle" x="261.95" y="-247.3" font-family="Times,serif" font-size="14.00">ip4_lookup</text>
 </g>
 <!-- pkt_cls&#45;&gt;ip4_lookup -->
 <g id="edge3" class="edge">
 <title>pkt_cls&#45;&gt;ip4_lookup</title>
-<path fill="none" stroke="black" d="M160.54,-352.79C182.64,-348.15 209.23,-339.41 228,-323 235.09,-316.81 240.26,-308.05 243.95,-299.6"/>
-<polygon fill="black" stroke="black" points="247.32,-300.57 247.62,-289.98 240.78,-298.07 247.32,-300.57"/>
-<text text-anchor="middle" x="254.5" y="-311.8" font-family="Times,serif" font-size="14.00">ipv4</text>
+<path fill="none" stroke="black" d="M261.95,-319.8C261.95,-308.16 261.95,-292.55 261.95,-279.24"/>
+<polygon fill="black" stroke="black" points="265.45,-279.18 261.95,-269.18 258.45,-279.18 265.45,-279.18"/>
+<text text-anchor="middle" x="277.45" y="-290.8" font-family="Times,serif" font-size="14.00">ipv4</text>
 </g>
 <!-- ip6_lookup -->
 <g id="node8" class="node">
 <title>ip6_lookup</title>
-<ellipse fill="none" stroke="black" cx="439" cy="-272" rx="60.39" ry="18"/>
-<text text-anchor="middle" x="439" y="-268.3" font-family="Times,serif" font-size="14.00">ip6_lookup</text>
+<ellipse fill="none" stroke="black" cx="492.95" cy="-251" rx="60.39" ry="18"/>
+<text text-anchor="middle" x="492.95" y="-247.3" font-family="Times,serif" font-size="14.00">ip6_lookup</text>
 </g>
 <!-- pkt_cls&#45;&gt;ip6_lookup -->
 <g id="edge4" class="edge">
 <title>pkt_cls&#45;&gt;ip6_lookup</title>
-<path fill="none" stroke="black" d="M157.52,-350.25C188.82,-343.6 234.51,-333.46 274,-323 313.2,-312.62 357.13,-299.22 389.79,-288.91"/>
-<polygon fill="black" stroke="black" points="391.08,-292.17 399.55,-285.81 388.96,-285.5 391.08,-292.17"/>
-<text text-anchor="middle" x="339.5" y="-311.8" font-family="Times,serif" font-size="14.00">ipv6</text>
+<path fill="none" stroke="black" d="M293.1,-325.54C332.57,-311.01 400.93,-285.86 446.54,-269.07"/>
+<polygon fill="black" stroke="black" points="448.02,-272.26 456.2,-265.52 445.61,-265.69 448.02,-272.26"/>
+<text text-anchor="middle" x="407.45" y="-290.8" font-family="Times,serif" font-size="14.00">ipv6</text>
 </g>
 <!-- ip4_lookup&#45;&gt;pkt_drop -->
 <g id="edge7" class="edge">
 <title>ip4_lookup&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M239.17,-254.03C232.31,-243.87 224.56,-230.37 221,-217 204.89,-156.57 227.58,-83.56 242.59,-45.31"/>
-<polygon fill="cyan" stroke="cyan" points="245.89,-46.5 246.4,-35.92 239.4,-43.87 245.89,-46.5"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M258.85,-232.91C253.68,-198.83 247.1,-121.54 282.95,-73 299.1,-51.12 326.1,-37.95 350.6,-30.11"/>
+<polygon fill="cyan" stroke="cyan" points="351.6,-33.46 360.19,-27.26 349.61,-26.75 351.6,-33.46"/>
 </g>
 <!-- ip4_rewrite -->
 <g id="node9" class="node">
 <title>ip4_rewrite</title>
-<ellipse fill="none" stroke="black" cx="294" cy="-199" rx="63.89" ry="18"/>
-<text text-anchor="middle" x="294" y="-195.3" font-family="Times,serif" font-size="14.00">ip4_rewrite</text>
+<ellipse fill="none" stroke="black" cx="347.95" cy="-178" rx="63.89" ry="18"/>
+<text text-anchor="middle" x="347.95" y="-174.3" font-family="Times,serif" font-size="14.00">ip4_rewrite</text>
 </g>
 <!-- ip4_lookup&#45;&gt;ip4_rewrite -->
 <g id="edge6" class="edge">
 <title>ip4_lookup&#45;&gt;ip4_rewrite</title>
-<path fill="none" stroke="black" d="M261.95,-254.17C266.95,-245.72 273.12,-235.29 278.71,-225.85"/>
-<polygon fill="black" stroke="black" points="281.75,-227.59 283.83,-217.2 275.72,-224.02 281.75,-227.59"/>
+<path fill="none" stroke="black" d="M281.46,-233.89C292.92,-224.42 307.6,-212.31 320.25,-201.87"/>
+<polygon fill="black" stroke="black" points="322.73,-204.36 328.21,-195.29 318.27,-198.96 322.73,-204.36"/>
 </g>
 <!-- ip4_local -->
 <g id="node11" class="node">
 <title>ip4_local</title>
-<ellipse fill="none" stroke="black" cx="136" cy="-145" rx="51.19" ry="18"/>
-<text text-anchor="middle" x="136" y="-141.3" font-family="Times,serif" font-size="14.00">ip4_local</text>
+<ellipse fill="none" stroke="black" cx="176.95" cy="-178" rx="51.19" ry="18"/>
+<text text-anchor="middle" x="176.95" y="-174.3" font-family="Times,serif" font-size="14.00">ip4_local</text>
 </g>
 <!-- ip4_lookup&#45;&gt;ip4_local -->
 <g id="edge17" class="edge">
 <title>ip4_lookup&#45;&gt;ip4_local</title>
-<path fill="none" stroke="black" d="M218.11,-256.86C207.64,-251.39 196.61,-244.41 188,-236 169.45,-217.88 155.34,-191.74 146.53,-172.29"/>
-<polygon fill="black" stroke="black" points="149.72,-170.86 142.52,-163.08 143.3,-173.65 149.72,-170.86"/>
+<path fill="none" stroke="black" d="M242.66,-233.89C231.17,-224.29 216.41,-211.96 203.79,-201.42"/>
+<polygon fill="black" stroke="black" points="205.78,-198.53 195.86,-194.8 201.29,-203.9 205.78,-198.53"/>
 </g>
 <!-- ip6_lookup&#45;&gt;pkt_drop -->
 <g id="edge11" class="edge">
 <title>ip6_lookup&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M470.57,-256.44C486.08,-247.46 503.27,-234.31 512,-217 519.2,-202.71 517.24,-196.12 512,-181 486.88,-108.48 466,-83.15 395,-54 367.69,-42.79 335.88,-34.51 309.39,-28.83"/>
-<polygon fill="cyan" stroke="cyan" points="310.02,-25.39 299.52,-26.78 308.6,-32.24 310.02,-25.39"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M524.51,-235.44C540.02,-226.46 557.22,-213.31 565.95,-196 573.15,-181.71 572.55,-174.57 565.95,-160 540.59,-104.08 480.88,-61.6 441.74,-38.51"/>
+<polygon fill="cyan" stroke="cyan" points="443.16,-35.29 432.75,-33.34 439.67,-41.36 443.16,-35.29"/>
 </g>
 <!-- ip6_rewrite -->
 <g id="node10" class="node">
 <title>ip6_rewrite</title>
-<ellipse fill="none" stroke="black" cx="439" cy="-199" rx="63.89" ry="18"/>
-<text text-anchor="middle" x="439" y="-195.3" font-family="Times,serif" font-size="14.00">ip6_rewrite</text>
+<ellipse fill="none" stroke="black" cx="492.95" cy="-178" rx="63.89" ry="18"/>
+<text text-anchor="middle" x="492.95" y="-174.3" font-family="Times,serif" font-size="14.00">ip6_rewrite</text>
 </g>
 <!-- ip6_lookup&#45;&gt;ip6_rewrite -->
 <g id="edge10" class="edge">
 <title>ip6_lookup&#45;&gt;ip6_rewrite</title>
-<path fill="none" stroke="black" d="M439,-253.81C439,-245.79 439,-236.05 439,-227.07"/>
-<polygon fill="black" stroke="black" points="442.5,-227.03 439,-217.03 435.5,-227.03 442.5,-227.03"/>
+<path fill="none" stroke="black" d="M492.95,-232.81C492.95,-224.79 492.95,-215.05 492.95,-206.07"/>
+<polygon fill="black" stroke="black" points="496.45,-206.03 492.95,-196.03 489.45,-206.03 496.45,-206.03"/>
 </g>
 <!-- ip4_rewrite&#45;&gt;ethdev_tx -->
 <g id="edge8" class="edge">
 <title>ip4_rewrite&#45;&gt;ethdev_tx</title>
-<path fill="none" stroke="green" d="M301.07,-180.97C308.09,-164.05 318.96,-137.86 327.09,-118.28"/>
-<polygon fill="green" stroke="green" points="330.35,-119.57 330.95,-108.99 323.88,-116.88 330.35,-119.57"/>
+<path fill="none" stroke="green" d="M347.95,-159.8C347.95,-148.16 347.95,-132.55 347.95,-119.24"/>
+<polygon fill="green" stroke="green" points="351.45,-119.18 347.95,-109.18 344.45,-119.18 351.45,-119.18"/>
 </g>
 <!-- ip4_rewrite&#45;&gt;pkt_drop -->
 <g id="edge9" class="edge">
 <title>ip4_rewrite&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M289.85,-180.97C285.53,-163.07 278.61,-134.1 273,-109 268.3,-87.99 263.29,-64.16 259.59,-46.3"/>
-<polygon fill="cyan" stroke="cyan" points="262.97,-45.37 257.52,-36.28 256.11,-46.78 262.97,-45.37"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M370.32,-161.1C385.53,-148.83 404.37,-130.37 412.95,-109 421.04,-88.82 418.02,-64.12 413.56,-45.7"/>
+<polygon fill="cyan" stroke="cyan" points="416.9,-44.66 410.91,-35.93 410.15,-46.49 416.9,-44.66"/>
 </g>
 <!-- ip6_rewrite&#45;&gt;ethdev_tx -->
 <g id="edge12" class="edge">
 <title>ip6_rewrite&#45;&gt;ethdev_tx</title>
-<path fill="none" stroke="green" d="M423.22,-181.44C406.47,-163.86 379.84,-135.91 360.81,-115.94"/>
-<polygon fill="green" stroke="green" points="363.1,-113.27 353.67,-108.45 358.03,-118.1 363.1,-113.27"/>
+<path fill="none" stroke="green" d="M466.35,-161.41C442.8,-147.6 408.27,-127.36 382.57,-112.3"/>
+<polygon fill="green" stroke="green" points="384.28,-109.24 373.88,-107.21 380.74,-115.28 384.28,-109.24"/>
 </g>
 <!-- ip6_rewrite&#45;&gt;pkt_drop -->
 <g id="edge13" class="edge">
 <title>ip6_rewrite&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M438.77,-180.67C437.49,-154.09 431.22,-103.19 403,-73 379.35,-47.7 342.93,-34.22 312.02,-27.06"/>
-<polygon fill="cyan" stroke="cyan" points="312.71,-23.63 302.2,-24.95 311.24,-30.47 312.71,-23.63"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M485.15,-159.86C473.93,-135.7 452.15,-90.48 429.95,-54 427.97,-50.75 425.78,-47.4 423.55,-44.13"/>
+<polygon fill="cyan" stroke="cyan" points="426.28,-41.92 417.67,-35.75 420.55,-45.94 426.28,-41.92"/>
 </g>
 <!-- ip4_local&#45;&gt;pkt_drop -->
 <g id="edge18" class="edge">
 <title>ip4_local&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M142.47,-126.87C150.6,-107.23 166.18,-75.04 188,-54 195,-47.25 203.56,-41.45 212.16,-36.63"/>
-<polygon fill="cyan" stroke="cyan" points="213.85,-39.7 221.08,-31.95 210.6,-33.5 213.85,-39.7"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M191.02,-160.51C195.47,-154.86 200.21,-148.35 203.95,-142 225.57,-105.29 209.02,-81.03 241.95,-54 257.83,-40.96 306.22,-31.62 346.19,-25.89"/>
+<polygon fill="cyan" stroke="cyan" points="346.72,-29.35 356.14,-24.51 345.75,-22.41 346.72,-29.35"/>
+</g>
+<!-- udp4_input -->
+<g id="node12" class="node">
+<title>udp4_input</title>
+<ellipse fill="none" stroke="black" cx="126.95" cy="-91" rx="63.09" ry="18"/>
+<text text-anchor="middle" x="126.95" y="-87.3" font-family="Times,serif" font-size="14.00">udp4_input</text>
+</g>
+<!-- ip4_local&#45;&gt;udp4_input -->
+<g id="edge19" class="edge">
+<title>ip4_local&#45;&gt;udp4_input</title>
+<path fill="none" stroke="black" d="M167.07,-160.21C159.99,-148.18 150.33,-131.75 142.26,-118.03"/>
+<polygon fill="black" stroke="black" points="145.06,-115.89 136.97,-109.05 139.03,-119.44 145.06,-115.89"/>
+<text text-anchor="middle" x="177.45" y="-130.8" font-family="Times,serif" font-size="14.00">udpv4</text>
+</g>
+<!-- udp4_input&#45;&gt;pkt_drop -->
+<g id="edge21" class="edge">
+<title>udp4_input&#45;&gt;pkt_drop</title>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M154.75,-74.82C169.08,-67.56 187.05,-59.32 203.95,-54 250.51,-39.35 305.19,-30.33 345.76,-25.12"/>
+<polygon fill="cyan" stroke="cyan" points="346.26,-28.59 355.75,-23.88 345.4,-21.64 346.26,-28.59"/>
+</g>
+<!-- udp_user_node -->
+<g id="node13" class="node">
+<title>udp_user_node</title>
+<ellipse fill="none" stroke="black" cx="126.95" cy="-18" rx="79.89" ry="18"/>
+<text text-anchor="middle" x="126.95" y="-14.3" font-family="Times,serif" font-size="14.00">udp_user_node</text>
+</g>
+<!-- udp4_input&#45;&gt;udp_user_node -->
+<g id="edge20" class="edge">
+<title>udp4_input&#45;&gt;udp_user_node</title>
+<path fill="none" stroke="black" d="M126.95,-72.81C126.95,-64.79 126.95,-55.05 126.95,-46.07"/>
+<polygon fill="black" stroke="black" points="130.45,-46.03 126.95,-36.03 123.45,-46.03 130.45,-46.03"/>
 </g>
 </g>
 </svg>
diff --git a/lib/node/meson.build b/lib/node/meson.build
index c0d5b09e2f..c5b8ee656e 100644
--- a/lib/node/meson.build
+++ b/lib/node/meson.build
@@ -22,11 +22,13 @@ sources = files(
         'null.c',
         'pkt_cls.c',
         'pkt_drop.c',
+        'udp4_input.c',
 )
 headers = files(
         'rte_node_eth_api.h',
         'rte_node_ip4_api.h',
         'rte_node_ip6_api.h',
+        'rte_node_udp4_input_api.h',
 )
 
 # Strict-aliasing rules are violated by uint8_t[] to context size casts.
diff --git a/lib/node/rte_node_udp4_input_api.h b/lib/node/rte_node_udp4_input_api.h
new file mode 100644
index 0000000000..7217b914ec
--- /dev/null
+++ b/lib/node/rte_node_udp4_input_api.h
@@ -0,0 +1,60 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2023 Marvell International Ltd.
+ */
+
+#ifndef __INCLUDE_RTE_NODE_UDP4_INPUT_API_H__
+#define __INCLUDE_RTE_NODE_UDP4_INPUT_API_H__
+
+/**
+ * @file rte_node_udp4_input_api.h
+ *
+ * @warning
+ * @b EXPERIMENTAL:
+ * All functions in this file may be changed or removed without prior notice.
+ *
+ * This API allows to control path functions of udp4_* nodes
+ * like udp4_input.
+ *
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rte_common.h>
+#include <rte_compat.h>
+
+/**
+ * UDP4 lookup next nodes.
+ */
+enum rte_node_udp4_input_next {
+	RTE_NODE_UDP4_INPUT_NEXT_PKT_DROP,
+	/**< Packet drop node. */
+};
+
+/**
+ * Add usr node to receive udp4 frames.
+ *
+ * @param usr_node
+ * Node registered by user to receive data.
+ */
+__rte_experimental
+int rte_node_udp4_usr_node_add(const char *usr_node);
+
+/**
+ * Add udpv4 dst_port to lookup table.
+ *
+ * @param dst_port
+ *   Dst Port of packet to be added for consumption.
+ * @param next_node
+ *   Next node packet to be added for consumption.
+ * @return
+ *   0 on success, negative otherwise.
+ */
+__rte_experimental
+int rte_node_udp4_dst_port_add(uint32_t dst_port, rte_edge_t next_node);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __INCLUDE_RTE_NODE_UDP4_API_H__ */
diff --git a/lib/node/udp4_input.c b/lib/node/udp4_input.c
new file mode 100644
index 0000000000..80cedce548
--- /dev/null
+++ b/lib/node/udp4_input.c
@@ -0,0 +1,226 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2023 Marvell International Ltd.
+ */
+
+#include <arpa/inet.h>
+#include <sys/socket.h>
+
+#include <rte_ethdev.h>
+#include <rte_ether.h>
+#include <rte_graph.h>
+#include <rte_graph_worker.h>
+#include <rte_ip.h>
+#include <rte_lpm.h>
+#include <rte_hash.h>
+#include <rte_fbk_hash.h>
+#include <rte_jhash.h>
+#include <rte_hash_crc.h>
+
+
+#include "rte_node_udp4_input_api.h"
+
+#include "node_private.h"
+
+#define UDP4_INPUT_HASH_TBL_SIZE 1024
+
+#define UDP4_INPUT_NODE_HASH(ctx) \
+	(((struct udp4_input_node_ctx *)ctx)->hash)
+
+#define UDP4_INPUT_NODE_NEXT_INDEX(ctx) \
+	(((struct udp4_input_node_ctx *)ctx)->next_index)
+
+
+/* UDP4 input  global data struct */
+struct udp4_input_node_main {
+	struct rte_hash *hash_tbl[RTE_MAX_NUMA_NODES];
+};
+
+static struct udp4_input_node_main udp4_input_nm;
+
+struct udp4_input_node_ctx {
+	/* Socket's Hash table */
+	struct rte_hash *hash;
+	/* Cached next index */
+	uint16_t next_index;
+};
+
+struct flow_key {
+	uint32_t prt_dst;
+};
+
+static struct rte_hash_parameters udp4_params = {
+	.entries = UDP4_INPUT_HASH_TBL_SIZE,
+	.key_len = sizeof(uint32_t),
+	.hash_func = rte_jhash,
+	.hash_func_init_val = 0,
+	.socket_id = 0,
+};
+
+int
+rte_node_udp4_dst_port_add(uint32_t dst_port, rte_edge_t next_node)
+{
+	uint8_t socket;
+	int rc;
+
+	for (socket = 0; socket < RTE_MAX_NUMA_NODES; socket++) {
+		if (!udp4_input_nm.hash_tbl[socket])
+			continue;
+
+		rc = rte_hash_add_key_data(udp4_input_nm.hash_tbl[socket],
+					   &dst_port, (void *)(uintptr_t)next_node);
+		if (rc < 0) {
+			node_err("udp4_lookup", "Failed to add key for sock %u, rc=%d",
+					socket, rc);
+			return rc;
+		}
+	}
+	return 0;
+}
+
+int
+rte_node_udp4_usr_node_add(const char *usr_node)
+{
+	const char *next_nodes = usr_node;
+	rte_node_t udp4_input_node_id, count;
+
+	udp4_input_node_id = rte_node_from_name("udp4_input");
+	count = rte_node_edge_update(udp4_input_node_id, RTE_EDGE_ID_INVALID,
+				     &next_nodes, 1);
+	if (count == 0) {
+		node_dbg("udp4_input", "Adding usr node as edge to udp4_input failed");
+		return count;
+	}
+	count = rte_node_edge_count(udp4_input_node_id) - 1;
+	return count;
+}
+
+static int
+setup_udp4_dstprt_hash(struct udp4_input_node_main *nm, int socket)
+{
+	struct rte_hash_parameters *hash_udp4 = &udp4_params;
+	char s[RTE_HASH_NAMESIZE];
+
+	/* One Hash table per socket */
+	if (nm->hash_tbl[socket])
+		return 0;
+
+	/* create Hash table */
+	snprintf(s, sizeof(s), "UDP4_INPUT_HASH_%d", socket);
+	hash_udp4->name = s;
+	hash_udp4->socket_id = socket;
+	nm->hash_tbl[socket] = rte_hash_create(hash_udp4);
+	if (nm->hash_tbl[socket] == NULL)
+		return -rte_errno;
+
+	return 0;
+}
+
+static int
+udp4_input_node_init(const struct rte_graph *graph, struct rte_node *node)
+{
+	uint16_t socket, lcore_id;
+	static uint8_t init_once;
+	int rc;
+
+	RTE_SET_USED(graph);
+	RTE_BUILD_BUG_ON(sizeof(struct udp4_input_node_ctx) > RTE_NODE_CTX_SZ);
+
+	if (!init_once) {
+
+		/* Setup HASH tables for all sockets */
+		RTE_LCORE_FOREACH(lcore_id)
+		{
+			socket = rte_lcore_to_socket_id(lcore_id);
+			rc = setup_udp4_dstprt_hash(&udp4_input_nm, socket);
+			if (rc) {
+				node_err("udp4_lookup",
+						"Failed to setup hash tbl for sock %u, rc=%d",
+						socket, rc);
+				return rc;
+			}
+		}
+		init_once = 1;
+	}
+
+	UDP4_INPUT_NODE_HASH(node->ctx) = udp4_input_nm.hash_tbl[graph->socket];
+
+	node_dbg("udp4_input", "Initialized udp4_input node");
+	return 0;
+}
+
+static uint16_t
+udp4_input_node_process_scalar(struct rte_graph *graph, struct rte_node *node,
+			       void **objs, uint16_t nb_objs)
+{
+	struct rte_hash *hash_tbl_handle = UDP4_INPUT_NODE_HASH(node->ctx);
+	rte_edge_t next_index, udplookup_node;
+	struct rte_udp_hdr *pkt_udp_hdr;
+	uint16_t last_spec = 0;
+	void **to_next, **from;
+	struct rte_mbuf *mbuf;
+	uint16_t held = 0;
+	uint16_t next = 0;
+	int i, rc;
+
+	/* Speculative next */
+	next_index = UDP4_INPUT_NODE_NEXT_INDEX(node->ctx);
+
+	from = objs;
+
+	to_next = rte_node_next_stream_get(graph, node, next_index, nb_objs);
+	for (i = 0; i < nb_objs; i++) {
+		struct flow_key key_port;
+
+		mbuf = (struct rte_mbuf *)objs[i];
+		pkt_udp_hdr = rte_pktmbuf_mtod_offset(mbuf, struct rte_udp_hdr *,
+						sizeof(struct rte_ether_hdr) +
+						sizeof(struct rte_ipv4_hdr));
+
+		key_port.prt_dst = rte_cpu_to_be_16(pkt_udp_hdr->dst_port);
+		rc = rte_hash_lookup_data(hash_tbl_handle,
+					  &key_port.prt_dst,
+					  (void **)&udplookup_node);
+		next = (rc < 0) ? RTE_NODE_UDP4_INPUT_NEXT_PKT_DROP
+				    : udplookup_node;
+
+		if (unlikely(next_index != next)) {
+			/* Copy things successfully speculated till now */
+			rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
+			from += last_spec;
+			to_next += last_spec;
+			held += last_spec;
+			last_spec = 0;
+
+			rte_node_enqueue_x1(graph, node, next, from[0]);
+			from += 1;
+		} else {
+			last_spec += 1;
+		}
+	}
+	/* !!! Home run !!! */
+	if (likely(last_spec == nb_objs)) {
+		rte_node_next_stream_move(graph, node, next_index);
+		return nb_objs;
+	}
+	held += last_spec;
+	rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
+	rte_node_next_stream_put(graph, node, next_index, held);
+	/* Save the last next used */
+	UDP4_INPUT_NODE_NEXT_INDEX(node->ctx) = next;
+
+	return nb_objs;
+}
+
+static struct rte_node_register udp4_input_node = {
+	.process = udp4_input_node_process_scalar,
+	.name = "udp4_input",
+
+	.init = udp4_input_node_init,
+
+	.nb_edges = RTE_NODE_UDP4_INPUT_NEXT_PKT_DROP + 1,
+	.next_nodes = {
+		[RTE_NODE_UDP4_INPUT_NEXT_PKT_DROP] = "pkt_drop",
+	},
+};
+
+RTE_NODE_REGISTER(udp4_input_node);
diff --git a/lib/node/version.map b/lib/node/version.map
index 40df308bfe..c51befce09 100644
--- a/lib/node/version.map
+++ b/lib/node/version.map
@@ -6,6 +6,8 @@ EXPERIMENTAL {
 	rte_node_ip4_rewrite_add;
 	rte_node_ip6_rewrite_add;
 	rte_node_ip6_route_add;
+	rte_node_udp4_usr_node_add;
+	rte_node_udp4_dst_port_add;
 	rte_node_logtype;
 	local: *;
 };
-- 
2.25.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v5 1/2] node: add IPv4 local node to handle local pkts
  2023-09-27  9:21     ` [PATCH v4 1/2] node: add IPv4 local node to handle local pkts Rakesh Kudurumalla
  2023-09-27  9:21       ` [PATCH v4 2/2] node: add UDP v4 support Rakesh Kudurumalla
@ 2023-09-27 12:40       ` Rakesh Kudurumalla
  2023-09-27 12:41         ` [PATCH v5 2/2] node: add UDP v4 support Rakesh Kudurumalla
  2023-09-28 10:25         ` [PATCH v6 1/2] node: add IPv4 local node to handle local pkts Rakesh Kudurumalla
  1 sibling, 2 replies; 16+ messages in thread
From: Rakesh Kudurumalla @ 2023-09-27 12:40 UTC (permalink / raw)
  To: Jerin Jacob, Kiran Kumar K, Nithin Dabilpuram, Zhirun Yan,
	Pavan Nikhilesh
  Cc: dev, Rakesh Kudurumalla

Local or Host destined pkts can be redirected IPv4 local node
using IP4 Lookup node entries with prefix of 32 and be redirected
to this IP4 local node for further processing.

Signed-off-by: Rakesh Kudurumalla <rkudurumalla@marvell.com>
---
 doc/guides/prog_guide/graph_lib.rst           |  15 ++
 .../img/graph_inbuilt_node_flow.svg           | 138 ++++++++++--------
 lib/node/ip4_local.c                          |  88 +++++++++++
 lib/node/ip4_lookup.c                         |   1 +
 lib/node/meson.build                          |   1 +
 lib/node/rte_node_ip4_api.h                   |  12 ++
 6 files changed, 196 insertions(+), 59 deletions(-)
 create mode 100644 lib/node/ip4_local.c

diff --git a/doc/guides/prog_guide/graph_lib.rst b/doc/guides/prog_guide/graph_lib.rst
index e7b6e12004..f2e04a68b9 100644
--- a/doc/guides/prog_guide/graph_lib.rst
+++ b/doc/guides/prog_guide/graph_lib.rst
@@ -498,3 +498,18 @@ Uses ``poll`` function to poll on the socket fd
 for ``POLLIN`` events to read the packets from raw socket
 to stream buffer and does ``rte_node_next_stream_move()``
 when there are received packets.
+
+ip4_local
+~~~~~~~~~
+This node is an intermediate node that does ``packet_type`` lookup for
+the received ipv4 packets and the result determines each packets next node.
+
+On successful ``packet_type`` lookup, for any IPv4 protocol the result
+contains the ``next_node`` id and ``next-hop`` id with which the packet
+needs to be further processed.
+
+On packet_type lookup failure, objects are redirected to ``pkt_drop`` node.
+``rte_node_ip4_route_add()`` is control path API to add ipv4 address with 32 bit
+depth to receive to packets.
+To achieve home run, node use ``rte_node_stream_move()`` as mentioned in above
+sections.
diff --git a/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg b/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg
index 7eea94701f..b954f6fba1 100644
--- a/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg
+++ b/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg
@@ -37,174 +37,194 @@ digraph dpdk_inbuilt_nodes_flow {
     ethdev_tx -> pkt_drop [color="cyan" style="dashed"]
     pkt_cls->pkt_drop   [color="cyan" style="dashed"]
     kernel_tx -> kernel_rx [color="red" style="dashed"]
+    ip4_lookup -> ip4_local
+    ip4_local -> pkt_drop [color="cyan" style="dashed"]
 }
 
  -->
 <!-- input nodes -->
 <!-- Title: dpdk_inbuilt_nodes_flow Pages: 1 -->
-<svg width="470pt" height="425pt"
- viewBox="0.00 0.00 470.23 424.50" 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 420.5)">
+<svg width="525pt" height="458pt"
+ viewBox="0.00 0.00 524.91 458.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 454)">
 <title>dpdk_inbuilt_nodes_flow</title>
-<polygon fill="white" stroke="none" points="-4,4 -4,-420.5 466.23,-420.5 466.23,4 -4,4"/>
+<polygon fill="white" stroke="transparent" points="-4,4 -4,-454 520.91,-454 520.91,4 -4,4"/>
 <!-- ethdev_rx -->
 <g id="node1" class="node">
 <title>ethdev_rx</title>
-<ellipse fill="none" stroke="green" cx="219.23" cy="-398.5" rx="47.77" ry="18"/>
-<text text-anchor="middle" x="219.23" y="-393.45" font-family="Times,serif" font-size="14.00">ethdev_rx</text>
+<ellipse fill="none" stroke="green" cx="120" cy="-432" rx="56.59" ry="18"/>
+<text text-anchor="middle" x="120" y="-428.3" font-family="Times,serif" font-size="14.00">ethdev_rx</text>
 </g>
 <!-- pkt_cls -->
 <g id="node6" class="node">
 <title>pkt_cls</title>
-<ellipse fill="none" stroke="red" cx="219.23" cy="-325.5" rx="37.53" ry="18"/>
-<text text-anchor="middle" x="219.23" y="-320.45" font-family="Times,serif" font-size="14.00">pkt_cls</text>
+<ellipse fill="none" stroke="red" cx="120" cy="-359" rx="42.79" ry="18"/>
+<text text-anchor="middle" x="120" y="-355.3" font-family="Times,serif" font-size="14.00">pkt_cls</text>
 </g>
 <!-- ethdev_rx&#45;&gt;pkt_cls -->
 <g id="edge1" class="edge">
 <title>ethdev_rx&#45;&gt;pkt_cls</title>
-<path fill="none" stroke="black" d="M219.23,-380.31C219.23,-372.55 219.23,-363.18 219.23,-354.45"/>
-<polygon fill="black" stroke="black" points="222.73,-354.53 219.23,-344.53 215.73,-354.53 222.73,-354.53"/>
+<path fill="none" stroke="black" d="M120,-413.81C120,-405.79 120,-396.05 120,-387.07"/>
+<polygon fill="black" stroke="black" points="123.5,-387.03 120,-377.03 116.5,-387.03 123.5,-387.03"/>
 </g>
 <!-- kernel_rx -->
 <g id="node2" class="node">
 <title>kernel_rx</title>
-<ellipse fill="none" stroke="green" cx="46.23" cy="-164" rx="46.23" ry="18"/>
-<text text-anchor="middle" x="46.23" y="-158.95" font-family="Times,serif" font-size="14.00">kernel_rx</text>
+<ellipse fill="none" stroke="green" cx="82" cy="-199" rx="53.89" ry="18"/>
+<text text-anchor="middle" x="82" y="-195.3" font-family="Times,serif" font-size="14.00">kernel_rx</text>
 </g>
 <!-- kernel_rx&#45;&gt;pkt_cls -->
 <g id="edge2" class="edge">
 <title>kernel_rx&#45;&gt;pkt_cls</title>
-<path fill="none" stroke="black" d="M41.45,-182.08C37.1,-201.37 33.27,-232.96 47.23,-255 73.68,-296.74 130.21,-313.41 171.26,-320.07"/>
-<polygon fill="black" stroke="black" points="170.73,-323.68 181.13,-321.66 171.74,-316.75 170.73,-323.68"/>
+<path fill="none" stroke="black" d="M70.87,-216.92C60.28,-235.27 47.29,-265.24 57,-290 64.12,-308.16 78.62,-324.37 91.92,-336.4"/>
+<polygon fill="black" stroke="black" points="89.69,-339.1 99.54,-342.99 94.26,-333.8 89.69,-339.1"/>
 </g>
 <!-- ethdev_tx -->
 <g id="node3" class="node">
 <title>ethdev_tx</title>
-<ellipse fill="none" stroke="magenta" cx="293.23" cy="-91" rx="47.26" ry="18"/>
-<text text-anchor="middle" x="293.23" y="-85.95" font-family="Times,serif" font-size="14.00">ethdev_tx</text>
+<ellipse fill="none" stroke="magenta" cx="338" cy="-91" rx="55.79" ry="18"/>
+<text text-anchor="middle" x="338" y="-87.3" font-family="Times,serif" font-size="14.00">ethdev_tx</text>
 </g>
 <!-- pkt_drop -->
 <g id="node4" class="node">
 <title>pkt_drop</title>
-<ellipse fill="none" stroke="cyan" cx="349.23" cy="-18" rx="44.19" ry="18"/>
-<text text-anchor="middle" x="349.23" y="-12.95" font-family="Times,serif" font-size="14.00">pkt_drop</text>
+<ellipse fill="none" stroke="cyan" cx="254" cy="-18" rx="51.99" ry="18"/>
+<text text-anchor="middle" x="254" y="-14.3" font-family="Times,serif" font-size="14.00">pkt_drop</text>
 </g>
 <!-- ethdev_tx&#45;&gt;pkt_drop -->
 <g id="edge14" class="edge">
 <title>ethdev_tx&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M306.22,-73.53C313.15,-64.75 321.81,-53.76 329.55,-43.96"/>
-<polygon fill="cyan" stroke="cyan" points="332.87,-46.4 336.32,-36.38 327.37,-42.06 332.87,-46.4"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M318.94,-73.89C307.58,-64.29 293,-51.96 280.53,-41.42"/>
+<polygon fill="cyan" stroke="cyan" points="282.59,-38.58 272.7,-34.8 278.07,-43.93 282.59,-38.58"/>
 </g>
 <!-- kernel_tx -->
 <g id="node5" class="node">
 <title>kernel_tx</title>
-<ellipse fill="none" stroke="blue" cx="102.23" cy="-237" rx="45.72" ry="18"/>
-<text text-anchor="middle" x="102.23" y="-231.95" font-family="Times,serif" font-size="14.00">kernel_tx</text>
+<ellipse fill="none" stroke="blue" cx="120" cy="-272" rx="53.89" ry="18"/>
+<text text-anchor="middle" x="120" y="-268.3" font-family="Times,serif" font-size="14.00">kernel_tx</text>
 </g>
 <!-- kernel_tx&#45;&gt;kernel_rx -->
 <g id="edge16" class="edge">
 <title>kernel_tx&#45;&gt;kernel_rx</title>
-<path fill="none" stroke="red" stroke-dasharray="5,2" d="M89.25,-219.53C82.32,-210.75 73.65,-199.76 65.92,-189.96"/>
-<polygon fill="red" stroke="red" points="68.09,-188.06 59.15,-182.38 62.6,-192.4 68.09,-188.06"/>
+<path fill="none" stroke="red" stroke-dasharray="5,2" d="M110.99,-254.17C106.52,-245.81 101,-235.51 95.99,-226.14"/>
+<polygon fill="red" stroke="red" points="99.01,-224.36 91.2,-217.2 92.84,-227.67 99.01,-224.36"/>
 </g>
 <!-- pkt_cls&#45;&gt;pkt_drop -->
 <g id="edge15" class="edge">
 <title>pkt_cls&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M255.09,-319.38C322.68,-308.72 462.23,-281.44 462.23,-238 462.23,-238 462.23,-238 462.23,-90 462.23,-57.84 429.01,-39.68 398.59,-29.8"/>
-<polygon fill="cyan" stroke="cyan" points="400.02,-26.27 389.44,-26.75 398.01,-32.98 400.02,-26.27"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M84,-348.97C48.65,-337.7 0,-314.61 0,-273 0,-273 0,-273 0,-90 0,-49.99 118.4,-31.52 193.52,-23.82"/>
+<polygon fill="cyan" stroke="cyan" points="194.21,-27.27 203.82,-22.81 193.52,-20.31 194.21,-27.27"/>
 </g>
 <!-- pkt_cls&#45;&gt;kernel_tx -->
 <g id="edge5" class="edge">
 <title>pkt_cls&#45;&gt;kernel_tx</title>
-<path fill="none" stroke="blue" d="M186.99,-315.75C170.62,-310.16 151.14,-301.64 136.48,-289.5 128.23,-282.66 121.2,-273.31 115.7,-264.46"/>
-<polygon fill="blue" stroke="blue" points="118.38,-263.1 110.34,-256.2 112.32,-266.61 118.38,-263.1"/>
-<text text-anchor="middle" x="176.61" y="-276.2" font-family="Times,serif" font-size="14.00">exception pkts</text>
+<path fill="none" stroke="blue" d="M120,-340.8C120,-329.16 120,-313.55 120,-300.24"/>
+<polygon fill="blue" stroke="blue" points="123.5,-300.18 120,-290.18 116.5,-300.18 123.5,-300.18"/>
+<text text-anchor="middle" x="172.5" y="-311.8" font-family="Times,serif" font-size="14.00">exception pkts</text>
 </g>
 <!-- ip4_lookup -->
 <g id="node7" class="node">
 <title>ip4_lookup</title>
-<ellipse fill="none" stroke="black" cx="219.23" cy="-237" rx="52.89" ry="18"/>
-<text text-anchor="middle" x="219.23" y="-231.95" font-family="Times,serif" font-size="14.00">ip4_lookup</text>
+<ellipse fill="none" stroke="black" cx="252" cy="-272" rx="60.39" ry="18"/>
+<text text-anchor="middle" x="252" y="-268.3" font-family="Times,serif" font-size="14.00">ip4_lookup</text>
 </g>
 <!-- pkt_cls&#45;&gt;ip4_lookup -->
 <g id="edge3" class="edge">
 <title>pkt_cls&#45;&gt;ip4_lookup</title>
-<path fill="none" stroke="black" d="M219.23,-307.41C219.23,-295.64 219.23,-279.73 219.23,-266.11"/>
-<polygon fill="black" stroke="black" points="222.73,-266.35 219.23,-256.35 215.73,-266.35 222.73,-266.35"/>
-<text text-anchor="middle" x="231.23" y="-276.2" font-family="Times,serif" font-size="14.00">ipv4</text>
+<path fill="none" stroke="black" d="M160.54,-352.79C182.64,-348.15 209.23,-339.41 228,-323 235.09,-316.81 240.26,-308.05 243.95,-299.6"/>
+<polygon fill="black" stroke="black" points="247.32,-300.57 247.62,-289.98 240.78,-298.07 247.32,-300.57"/>
+<text text-anchor="middle" x="254.5" y="-311.8" font-family="Times,serif" font-size="14.00">ipv4</text>
 </g>
 <!-- ip6_lookup -->
 <g id="node8" class="node">
 <title>ip6_lookup</title>
-<ellipse fill="none" stroke="black" cx="343.23" cy="-237" rx="52.89" ry="18"/>
-<text text-anchor="middle" x="343.23" y="-231.95" font-family="Times,serif" font-size="14.00">ip6_lookup</text>
+<ellipse fill="none" stroke="black" cx="439" cy="-272" rx="60.39" ry="18"/>
+<text text-anchor="middle" x="439" y="-268.3" font-family="Times,serif" font-size="14.00">ip6_lookup</text>
 </g>
 <!-- pkt_cls&#45;&gt;ip6_lookup -->
 <g id="edge4" class="edge">
 <title>pkt_cls&#45;&gt;ip6_lookup</title>
-<path fill="none" stroke="black" d="M239.99,-310.02C259.62,-296.33 289.35,-275.59 311.88,-259.87"/>
-<polygon fill="black" stroke="black" points="313.53,-262.29 319.73,-253.7 309.53,-256.55 313.53,-262.29"/>
-<text text-anchor="middle" x="304.23" y="-276.2" font-family="Times,serif" font-size="14.00">ipv6</text>
+<path fill="none" stroke="black" d="M157.52,-350.25C188.82,-343.6 234.51,-333.46 274,-323 313.2,-312.62 357.13,-299.22 389.79,-288.91"/>
+<polygon fill="black" stroke="black" points="391.08,-292.17 399.55,-285.81 388.96,-285.5 391.08,-292.17"/>
+<text text-anchor="middle" x="339.5" y="-311.8" font-family="Times,serif" font-size="14.00">ipv6</text>
 </g>
 <!-- ip4_lookup&#45;&gt;pkt_drop -->
 <g id="edge7" class="edge">
 <title>ip4_lookup&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M192.86,-221.12C179.2,-211.83 163.82,-198.49 156.23,-182 149.55,-167.46 150.78,-161.04 156.23,-146 176.39,-90.45 198.32,-78.19 252.23,-54 269.14,-46.41 288.24,-39.24 304.98,-33.38"/>
-<polygon fill="cyan" stroke="cyan" points="305.75,-36.48 314.07,-29.92 303.47,-29.86 305.75,-36.48"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M239.17,-254.03C232.31,-243.87 224.56,-230.37 221,-217 204.89,-156.57 227.58,-83.56 242.59,-45.31"/>
+<polygon fill="cyan" stroke="cyan" points="245.89,-46.5 246.4,-35.92 239.4,-43.87 245.89,-46.5"/>
 </g>
 <!-- ip4_rewrite -->
 <g id="node9" class="node">
 <title>ip4_rewrite</title>
-<ellipse fill="none" stroke="black" cx="218.23" cy="-164" rx="53.4" ry="18"/>
-<text text-anchor="middle" x="218.23" y="-158.95" font-family="Times,serif" font-size="14.00">ip4_rewrite</text>
+<ellipse fill="none" stroke="black" cx="294" cy="-199" rx="63.89" ry="18"/>
+<text text-anchor="middle" x="294" y="-195.3" font-family="Times,serif" font-size="14.00">ip4_rewrite</text>
 </g>
 <!-- ip4_lookup&#45;&gt;ip4_rewrite -->
 <g id="edge6" class="edge">
 <title>ip4_lookup&#45;&gt;ip4_rewrite</title>
-<path fill="none" stroke="black" d="M218.99,-218.81C218.88,-211.05 218.75,-201.68 218.63,-192.95"/>
-<polygon fill="black" stroke="black" points="222.11,-192.98 218.47,-183.03 215.11,-193.08 222.11,-192.98"/>
+<path fill="none" stroke="black" d="M261.95,-254.17C266.95,-245.72 273.12,-235.29 278.71,-225.85"/>
+<polygon fill="black" stroke="black" points="281.75,-227.59 283.83,-217.2 275.72,-224.02 281.75,-227.59"/>
+</g>
+<!-- ip4_local -->
+<g id="node11" class="node">
+<title>ip4_local</title>
+<ellipse fill="none" stroke="black" cx="136" cy="-145" rx="51.19" ry="18"/>
+<text text-anchor="middle" x="136" y="-141.3" font-family="Times,serif" font-size="14.00">ip4_local</text>
+</g>
+<!-- ip4_lookup&#45;&gt;ip4_local -->
+<g id="edge17" class="edge">
+<title>ip4_lookup&#45;&gt;ip4_local</title>
+<path fill="none" stroke="black" d="M218.11,-256.86C207.64,-251.39 196.61,-244.41 188,-236 169.45,-217.88 155.34,-191.74 146.53,-172.29"/>
+<polygon fill="black" stroke="black" points="149.72,-170.86 142.52,-163.08 143.3,-173.65 149.72,-170.86"/>
 </g>
 <!-- ip6_lookup&#45;&gt;pkt_drop -->
 <g id="edge11" class="edge">
 <title>ip6_lookup&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M369.2,-221.03C382.65,-211.71 397.78,-198.37 405.23,-182 426.87,-134.45 392.95,-75.95 369.19,-43.54"/>
-<polygon fill="cyan" stroke="cyan" points="371.64,-41.98 362.81,-36.13 366.06,-46.21 371.64,-41.98"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M470.57,-256.44C486.08,-247.46 503.27,-234.31 512,-217 519.2,-202.71 517.24,-196.12 512,-181 486.88,-108.48 466,-83.15 395,-54 367.69,-42.79 335.88,-34.51 309.39,-28.83"/>
+<polygon fill="cyan" stroke="cyan" points="310.02,-25.39 299.52,-26.78 308.6,-32.24 310.02,-25.39"/>
 </g>
 <!-- ip6_rewrite -->
 <g id="node10" class="node">
 <title>ip6_rewrite</title>
-<ellipse fill="none" stroke="black" cx="343.23" cy="-164" rx="53.4" ry="18"/>
-<text text-anchor="middle" x="343.23" y="-158.95" font-family="Times,serif" font-size="14.00">ip6_rewrite</text>
+<ellipse fill="none" stroke="black" cx="439" cy="-199" rx="63.89" ry="18"/>
+<text text-anchor="middle" x="439" y="-195.3" font-family="Times,serif" font-size="14.00">ip6_rewrite</text>
 </g>
 <!-- ip6_lookup&#45;&gt;ip6_rewrite -->
 <g id="edge10" class="edge">
 <title>ip6_lookup&#45;&gt;ip6_rewrite</title>
-<path fill="none" stroke="black" d="M343.23,-218.81C343.23,-211.05 343.23,-201.68 343.23,-192.95"/>
-<polygon fill="black" stroke="black" points="346.73,-193.03 343.23,-183.03 339.73,-193.03 346.73,-193.03"/>
+<path fill="none" stroke="black" d="M439,-253.81C439,-245.79 439,-236.05 439,-227.07"/>
+<polygon fill="black" stroke="black" points="442.5,-227.03 439,-217.03 435.5,-227.03 442.5,-227.03"/>
 </g>
 <!-- ip4_rewrite&#45;&gt;ethdev_tx -->
 <g id="edge8" class="edge">
 <title>ip4_rewrite&#45;&gt;ethdev_tx</title>
-<path fill="none" stroke="green" d="M235.63,-146.53C245.35,-137.33 257.64,-125.7 268.36,-115.54"/>
-<polygon fill="green" stroke="green" points="270.34,-118.55 275.19,-109.13 265.52,-113.47 270.34,-118.55"/>
+<path fill="none" stroke="green" d="M301.07,-180.97C308.09,-164.05 318.96,-137.86 327.09,-118.28"/>
+<polygon fill="green" stroke="green" points="330.35,-119.57 330.95,-108.99 323.88,-116.88 330.35,-119.57"/>
 </g>
 <!-- ip4_rewrite&#45;&gt;pkt_drop -->
 <g id="edge9" class="edge">
 <title>ip4_rewrite&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M217.56,-145.54C217.71,-125.89 220.78,-93.99 237.23,-73 253.17,-52.67 278.68,-39.55 301.33,-31.33"/>
-<polygon fill="cyan" stroke="cyan" points="302.14,-34.42 310.5,-27.9 299.9,-27.79 302.14,-34.42"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M289.85,-180.97C285.53,-163.07 278.61,-134.1 273,-109 268.3,-87.99 263.29,-64.16 259.59,-46.3"/>
+<polygon fill="cyan" stroke="cyan" points="262.97,-45.37 257.52,-36.28 256.11,-46.78 262.97,-45.37"/>
 </g>
 <!-- ip6_rewrite&#45;&gt;ethdev_tx -->
 <g id="edge12" class="edge">
 <title>ip6_rewrite&#45;&gt;ethdev_tx</title>
-<path fill="none" stroke="green" d="M331.38,-146.17C325.34,-137.6 317.87,-126.99 311.15,-117.44"/>
-<polygon fill="green" stroke="green" points="313.62,-115.87 305,-109.71 307.89,-119.9 313.62,-115.87"/>
+<path fill="none" stroke="green" d="M423.22,-181.44C406.47,-163.86 379.84,-135.91 360.81,-115.94"/>
+<polygon fill="green" stroke="green" points="363.1,-113.27 353.67,-108.45 358.03,-118.1 363.1,-113.27"/>
 </g>
 <!-- ip6_rewrite&#45;&gt;pkt_drop -->
 <g id="edge13" class="edge">
 <title>ip6_rewrite&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M345.67,-145.53C347.02,-134.98 348.56,-121.24 349.23,-109 350.38,-88.27 350.34,-64.81 350.03,-47.04"/>
-<polygon fill="cyan" stroke="cyan" points="353.51,-47.19 349.8,-37.27 346.51,-47.34 353.51,-47.19"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M438.77,-180.67C437.49,-154.09 431.22,-103.19 403,-73 379.35,-47.7 342.93,-34.22 312.02,-27.06"/>
+<polygon fill="cyan" stroke="cyan" points="312.71,-23.63 302.2,-24.95 311.24,-30.47 312.71,-23.63"/>
+</g>
+<!-- ip4_local&#45;&gt;pkt_drop -->
+<g id="edge18" class="edge">
+<title>ip4_local&#45;&gt;pkt_drop</title>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M142.47,-126.87C150.6,-107.23 166.18,-75.04 188,-54 195,-47.25 203.56,-41.45 212.16,-36.63"/>
+<polygon fill="cyan" stroke="cyan" points="213.85,-39.7 221.08,-31.95 210.6,-33.5 213.85,-39.7"/>
 </g>
 </g>
 </svg>
diff --git a/lib/node/ip4_local.c b/lib/node/ip4_local.c
new file mode 100644
index 0000000000..fb31d0f970
--- /dev/null
+++ b/lib/node/ip4_local.c
@@ -0,0 +1,88 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2023 Marvell International Ltd.
+ */
+
+#include <arpa/inet.h>
+#include <sys/socket.h>
+
+#include <rte_ethdev.h>
+#include <rte_ether.h>
+#include <rte_graph.h>
+#include <rte_graph_worker.h>
+#include <rte_ip.h>
+#include <rte_lpm.h>
+#include <rte_hash.h>
+#include <rte_fbk_hash.h>
+#include <rte_jhash.h>
+#include <rte_hash_crc.h>
+
+
+#include "rte_node_ip4_api.h"
+
+#include "node_private.h"
+
+static uint16_t
+ip4_local_node_process_scalar(struct rte_graph *graph, struct rte_node *node,
+			      void **objs, uint16_t nb_objs)
+{
+	void **to_next, **from;
+	uint16_t last_spec = 0;
+	rte_edge_t next_index;
+	struct rte_mbuf *mbuf;
+	uint16_t held = 0;
+	uint32_t l4;
+	int i;
+
+	/* Speculative next */
+	next_index = RTE_NODE_IP4_LOCAL_NEXT_UDP4_INPUT;
+
+	from = objs;
+	to_next = rte_node_next_stream_get(graph, node, next_index, nb_objs);
+	for (i = 0; i < nb_objs; i++) {
+		uint16_t next;
+
+		mbuf = (struct rte_mbuf *)objs[i];
+		l4 = mbuf->packet_type & RTE_PTYPE_L4_MASK;
+
+		next = (l4 == RTE_PTYPE_L4_UDP)
+				? next_index
+				: RTE_NODE_IP4_LOCAL_NEXT_PKT_DROP;
+
+		if (unlikely(next_index != next)) {
+			/* Copy things successfully speculated till now */
+			rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
+			from += last_spec;
+			to_next += last_spec;
+			held += last_spec;
+			last_spec = 0;
+
+			rte_node_enqueue_x1(graph, node, next, from[0]);
+			from += 1;
+		} else {
+			last_spec += 1;
+		}
+	}
+	/* !!! Home run !!! */
+	if (likely(last_spec == nb_objs)) {
+		rte_node_next_stream_move(graph, node, next_index);
+		return nb_objs;
+	}
+	held += last_spec;
+	rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
+	rte_node_next_stream_put(graph, node, next_index, held);
+
+	return nb_objs;
+}
+
+static struct rte_node_register ip4_local_node = {
+	.process = ip4_local_node_process_scalar,
+	.name = "ip4_local",
+
+	.nb_edges = RTE_NODE_IP4_LOCAL_NEXT_PKT_DROP + 1,
+	.next_nodes = {
+		[RTE_NODE_IP4_LOCAL_NEXT_UDP4_INPUT] = "udp4_input",
+		[RTE_NODE_IP4_LOCAL_NEXT_PKT_DROP] = "pkt_drop",
+	},
+};
+
+RTE_NODE_REGISTER(ip4_local_node);
diff --git a/lib/node/ip4_lookup.c b/lib/node/ip4_lookup.c
index 8bce03d7db..d3fc48baf7 100644
--- a/lib/node/ip4_lookup.c
+++ b/lib/node/ip4_lookup.c
@@ -227,6 +227,7 @@ static struct rte_node_register ip4_lookup_node = {
 
 	.nb_edges = RTE_NODE_IP4_LOOKUP_NEXT_MAX,
 	.next_nodes = {
+		[RTE_NODE_IP4_LOOKUP_NEXT_IP4_LOCAL] = "ip4_local",
 		[RTE_NODE_IP4_LOOKUP_NEXT_REWRITE] = "ip4_rewrite",
 		[RTE_NODE_IP4_LOOKUP_NEXT_PKT_DROP] = "pkt_drop",
 	},
diff --git a/lib/node/meson.build b/lib/node/meson.build
index 2fa7c1c8f3..c0d5b09e2f 100644
--- a/lib/node/meson.build
+++ b/lib/node/meson.build
@@ -12,6 +12,7 @@ sources = files(
         'ethdev_rx.c',
         'ethdev_tx.c',
         'ip4_lookup.c',
+        'ip4_local.c',
         'ip4_rewrite.c',
         'ip6_lookup.c',
         'ip6_rewrite.c',
diff --git a/lib/node/rte_node_ip4_api.h b/lib/node/rte_node_ip4_api.h
index 3397da0ae8..405bdd3283 100644
--- a/lib/node/rte_node_ip4_api.h
+++ b/lib/node/rte_node_ip4_api.h
@@ -30,10 +30,22 @@ enum rte_node_ip4_lookup_next {
 	/**< Rewrite node. */
 	RTE_NODE_IP4_LOOKUP_NEXT_PKT_DROP,
 	/**< Packet drop node. */
+	RTE_NODE_IP4_LOOKUP_NEXT_IP4_LOCAL,
+	/** IP Local node. */
 	RTE_NODE_IP4_LOOKUP_NEXT_MAX,
 	/**< Number of next nodes of lookup node. */
 };
 
+/**
+ * IP4 Local next nodes.
+ */
+enum rte_node_ip4_local_next {
+	RTE_NODE_IP4_LOCAL_NEXT_UDP4_INPUT,
+	/**< ip4 Local node. */
+	RTE_NODE_IP4_LOCAL_NEXT_PKT_DROP,
+	/**< Packet drop node. */
+};
+
 /**
  * Add ipv4 route to lookup table.
  *
-- 
2.25.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v5 2/2] node: add UDP v4 support
  2023-09-27 12:40       ` [PATCH v5 1/2] node: add IPv4 local node to handle local pkts Rakesh Kudurumalla
@ 2023-09-27 12:41         ` Rakesh Kudurumalla
  2023-09-28 10:25         ` [PATCH v6 1/2] node: add IPv4 local node to handle local pkts Rakesh Kudurumalla
  1 sibling, 0 replies; 16+ messages in thread
From: Rakesh Kudurumalla @ 2023-09-27 12:41 UTC (permalink / raw)
  To: Jerin Jacob, Kiran Kumar K, Nithin Dabilpuram, Zhirun Yan,
	Pavan Nikhilesh
  Cc: dev, Rakesh Kudurumalla

IPv4 UDP packets are given to application
with specified UDP destination port given
by user.

Signed-off-by: Rakesh Kudurumalla <rkudurumalla@marvell.com>
---

v5: Resolve ubuntu compilation issue

 doc/api/doxy-api-index.md                     |   3 +-
 doc/guides/prog_guide/graph_lib.rst           |  25 ++
 .../img/graph_inbuilt_node_flow.svg           | 165 ++++++++-----
 lib/node/meson.build                          |   2 +
 lib/node/rte_node_udp4_input_api.h            |  61 +++++
 lib/node/udp4_input.c                         | 226 ++++++++++++++++++
 lib/node/version.map                          |   2 +
 7 files changed, 418 insertions(+), 66 deletions(-)
 create mode 100644 lib/node/rte_node_udp4_input_api.h
 create mode 100644 lib/node/udp4_input.c

diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index fdeda13932..96282d3fd0 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -206,7 +206,8 @@ The public API headers are grouped by topics:
   * graph_nodes:
     [eth_node](@ref rte_node_eth_api.h),
     [ip4_node](@ref rte_node_ip4_api.h),
-    [ip6_node](@ref rte_node_ip6_api.h)
+    [ip6_node](@ref rte_node_ip6_api.h),
+    [udp4_input_node](@ref rte_node_udp4_input_api.h)
 
 - **basic**:
   [bitops](@ref rte_bitops.h),
diff --git a/doc/guides/prog_guide/graph_lib.rst b/doc/guides/prog_guide/graph_lib.rst
index f2e04a68b9..3572560362 100644
--- a/doc/guides/prog_guide/graph_lib.rst
+++ b/doc/guides/prog_guide/graph_lib.rst
@@ -513,3 +513,28 @@ On packet_type lookup failure, objects are redirected to ``pkt_drop`` node.
 depth to receive to packets.
 To achieve home run, node use ``rte_node_stream_move()`` as mentioned in above
 sections.
+
+udp4_input
+~~~~~~~~~~
+This node is an intermediate node that does udp destination port lookup for
+the received ipv4 packets and the result determines each packets next node.
+
+User registers a new node ``udp4_input`` into graph library during initialization
+and attach user specified node as edege to this node using
+``rte_node_udp4_usr_node_add()``, and create empty hash table with destination
+port and node id as its feilds.
+
+After successful addition of user node as edege, edge id is returned to the user.
+
+User would register ``ip4_lookup`` table with specified ip address and 32 bit as mask
+for ip filtration using api ``rte_node_ip4_route_add()``.
+
+After graph is created user would update hash table with custom port with
+and previously obtained edge id using API ``rte_node_udp4_dst_port_add()``.
+
+When packet is received lpm look up is performed if ip is matched the packet
+is handed over to ip4_local node, then packet is verified for udp proto and
+on success packet is enqueued to ``udp4_input`` node.
+
+Hash lookup is performed in ``udp4_input`` node with registered destination port
+and destination port in UDP packet , on success packet is handed to ``udp_user_node``.
diff --git a/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg b/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg
index b954f6fba1..7c451371a7 100644
--- a/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg
+++ b/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg
@@ -39,192 +39,227 @@ digraph dpdk_inbuilt_nodes_flow {
     kernel_tx -> kernel_rx [color="red" style="dashed"]
     ip4_lookup -> ip4_local
     ip4_local -> pkt_drop [color="cyan" style="dashed"]
+    ip4_local -> udp4_input [ label="udpv4"]
+    udp4_input -> udp_user_node
+    udp4_input -> pkt_drop [color="cyan" style="dashed"]
+
 }
 
  -->
 <!-- input nodes -->
 <!-- Title: dpdk_inbuilt_nodes_flow Pages: 1 -->
-<svg width="525pt" height="458pt"
- viewBox="0.00 0.00 524.91 458.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 454)">
+<svg width="631pt" height="437pt"
+ viewBox="0.00 0.00 630.95 437.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 433)">
 <title>dpdk_inbuilt_nodes_flow</title>
-<polygon fill="white" stroke="transparent" points="-4,4 -4,-454 520.91,-454 520.91,4 -4,4"/>
+<polygon fill="white" stroke="transparent" points="-4,4 -4,-433 626.95,-433 626.95,4 -4,4"/>
 <!-- ethdev_rx -->
 <g id="node1" class="node">
 <title>ethdev_rx</title>
-<ellipse fill="none" stroke="green" cx="120" cy="-432" rx="56.59" ry="18"/>
-<text text-anchor="middle" x="120" y="-428.3" font-family="Times,serif" font-size="14.00">ethdev_rx</text>
+<ellipse fill="none" stroke="green" cx="261.95" cy="-411" rx="56.59" ry="18"/>
+<text text-anchor="middle" x="261.95" y="-407.3" font-family="Times,serif" font-size="14.00">ethdev_rx</text>
 </g>
 <!-- pkt_cls -->
 <g id="node6" class="node">
 <title>pkt_cls</title>
-<ellipse fill="none" stroke="red" cx="120" cy="-359" rx="42.79" ry="18"/>
-<text text-anchor="middle" x="120" y="-355.3" font-family="Times,serif" font-size="14.00">pkt_cls</text>
+<ellipse fill="none" stroke="red" cx="261.95" cy="-338" rx="42.79" ry="18"/>
+<text text-anchor="middle" x="261.95" y="-334.3" font-family="Times,serif" font-size="14.00">pkt_cls</text>
 </g>
 <!-- ethdev_rx&#45;&gt;pkt_cls -->
 <g id="edge1" class="edge">
 <title>ethdev_rx&#45;&gt;pkt_cls</title>
-<path fill="none" stroke="black" d="M120,-413.81C120,-405.79 120,-396.05 120,-387.07"/>
-<polygon fill="black" stroke="black" points="123.5,-387.03 120,-377.03 116.5,-387.03 123.5,-387.03"/>
+<path fill="none" stroke="black" d="M261.95,-392.81C261.95,-384.79 261.95,-375.05 261.95,-366.07"/>
+<polygon fill="black" stroke="black" points="265.45,-366.03 261.95,-356.03 258.45,-366.03 265.45,-366.03"/>
 </g>
 <!-- kernel_rx -->
 <g id="node2" class="node">
 <title>kernel_rx</title>
-<ellipse fill="none" stroke="green" cx="82" cy="-199" rx="53.89" ry="18"/>
-<text text-anchor="middle" x="82" y="-195.3" font-family="Times,serif" font-size="14.00">kernel_rx</text>
+<ellipse fill="none" stroke="green" cx="53.95" cy="-178" rx="53.89" ry="18"/>
+<text text-anchor="middle" x="53.95" y="-174.3" font-family="Times,serif" font-size="14.00">kernel_rx</text>
 </g>
 <!-- kernel_rx&#45;&gt;pkt_cls -->
 <g id="edge2" class="edge">
 <title>kernel_rx&#45;&gt;pkt_cls</title>
-<path fill="none" stroke="black" d="M70.87,-216.92C60.28,-235.27 47.29,-265.24 57,-290 64.12,-308.16 78.62,-324.37 91.92,-336.4"/>
-<polygon fill="black" stroke="black" points="89.69,-339.1 99.54,-342.99 94.26,-333.8 89.69,-339.1"/>
+<path fill="none" stroke="black" d="M74.75,-194.8C112.31,-223.33 191.45,-283.45 233.8,-315.62"/>
+<polygon fill="black" stroke="black" points="231.92,-318.59 242,-321.85 236.16,-313.01 231.92,-318.59"/>
 </g>
 <!-- ethdev_tx -->
 <g id="node3" class="node">
 <title>ethdev_tx</title>
-<ellipse fill="none" stroke="magenta" cx="338" cy="-91" rx="55.79" ry="18"/>
-<text text-anchor="middle" x="338" y="-87.3" font-family="Times,serif" font-size="14.00">ethdev_tx</text>
+<ellipse fill="none" stroke="magenta" cx="347.95" cy="-91" rx="55.79" ry="18"/>
+<text text-anchor="middle" x="347.95" y="-87.3" font-family="Times,serif" font-size="14.00">ethdev_tx</text>
 </g>
 <!-- pkt_drop -->
 <g id="node4" class="node">
 <title>pkt_drop</title>
-<ellipse fill="none" stroke="cyan" cx="254" cy="-18" rx="51.99" ry="18"/>
-<text text-anchor="middle" x="254" y="-14.3" font-family="Times,serif" font-size="14.00">pkt_drop</text>
+<ellipse fill="none" stroke="cyan" cx="404.95" cy="-18" rx="51.99" ry="18"/>
+<text text-anchor="middle" x="404.95" y="-14.3" font-family="Times,serif" font-size="14.00">pkt_drop</text>
 </g>
 <!-- ethdev_tx&#45;&gt;pkt_drop -->
 <g id="edge14" class="edge">
 <title>ethdev_tx&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M318.94,-73.89C307.58,-64.29 293,-51.96 280.53,-41.42"/>
-<polygon fill="cyan" stroke="cyan" points="282.59,-38.58 272.7,-34.8 278.07,-43.93 282.59,-38.58"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M361.45,-73.17C368.55,-64.33 377.39,-53.33 385.23,-43.55"/>
+<polygon fill="cyan" stroke="cyan" points="388,-45.69 391.53,-35.71 382.54,-41.31 388,-45.69"/>
 </g>
 <!-- kernel_tx -->
 <g id="node5" class="node">
 <title>kernel_tx</title>
-<ellipse fill="none" stroke="blue" cx="120" cy="-272" rx="53.89" ry="18"/>
-<text text-anchor="middle" x="120" y="-268.3" font-family="Times,serif" font-size="14.00">kernel_tx</text>
+<ellipse fill="none" stroke="blue" cx="53.95" cy="-251" rx="53.89" ry="18"/>
+<text text-anchor="middle" x="53.95" y="-247.3" font-family="Times,serif" font-size="14.00">kernel_tx</text>
 </g>
 <!-- kernel_tx&#45;&gt;kernel_rx -->
 <g id="edge16" class="edge">
 <title>kernel_tx&#45;&gt;kernel_rx</title>
-<path fill="none" stroke="red" stroke-dasharray="5,2" d="M110.99,-254.17C106.52,-245.81 101,-235.51 95.99,-226.14"/>
-<polygon fill="red" stroke="red" points="99.01,-224.36 91.2,-217.2 92.84,-227.67 99.01,-224.36"/>
+<path fill="none" stroke="red" stroke-dasharray="5,2" d="M53.95,-232.81C53.95,-224.79 53.95,-215.05 53.95,-206.07"/>
+<polygon fill="red" stroke="red" points="57.45,-206.03 53.95,-196.03 50.45,-206.03 57.45,-206.03"/>
 </g>
 <!-- pkt_cls&#45;&gt;pkt_drop -->
 <g id="edge15" class="edge">
 <title>pkt_cls&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M84,-348.97C48.65,-337.7 0,-314.61 0,-273 0,-273 0,-273 0,-90 0,-49.99 118.4,-31.52 193.52,-23.82"/>
-<polygon fill="cyan" stroke="cyan" points="194.21,-27.27 203.82,-22.81 193.52,-20.31 194.21,-27.27"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M304.77,-335.88C400.4,-332.2 622.95,-316.71 622.95,-252 622.95,-252 622.95,-252 622.95,-90 622.95,-56.33 527.72,-36.15 463.14,-26.34"/>
+<polygon fill="cyan" stroke="cyan" points="463.46,-22.85 453.06,-24.85 462.44,-29.77 463.46,-22.85"/>
 </g>
 <!-- pkt_cls&#45;&gt;kernel_tx -->
 <g id="edge5" class="edge">
 <title>pkt_cls&#45;&gt;kernel_tx</title>
-<path fill="none" stroke="blue" d="M120,-340.8C120,-329.16 120,-313.55 120,-300.24"/>
-<polygon fill="blue" stroke="blue" points="123.5,-300.18 120,-290.18 116.5,-300.18 123.5,-300.18"/>
-<text text-anchor="middle" x="172.5" y="-311.8" font-family="Times,serif" font-size="14.00">exception pkts</text>
+<path fill="none" stroke="blue" d="M219.14,-335.96C164.86,-333.64 75.77,-326.15 54.95,-302 49.6,-295.81 48.06,-287.4 48.24,-279.24"/>
+<polygon fill="blue" stroke="blue" points="51.73,-279.54 49.23,-269.24 44.76,-278.84 51.73,-279.54"/>
+<text text-anchor="middle" x="107.45" y="-290.8" font-family="Times,serif" font-size="14.00">exception pkts</text>
 </g>
 <!-- ip4_lookup -->
 <g id="node7" class="node">
 <title>ip4_lookup</title>
-<ellipse fill="none" stroke="black" cx="252" cy="-272" rx="60.39" ry="18"/>
-<text text-anchor="middle" x="252" y="-268.3" font-family="Times,serif" font-size="14.00">ip4_lookup</text>
+<ellipse fill="none" stroke="black" cx="261.95" cy="-251" rx="60.39" ry="18"/>
+<text text-anchor="middle" x="261.95" y="-247.3" font-family="Times,serif" font-size="14.00">ip4_lookup</text>
 </g>
 <!-- pkt_cls&#45;&gt;ip4_lookup -->
 <g id="edge3" class="edge">
 <title>pkt_cls&#45;&gt;ip4_lookup</title>
-<path fill="none" stroke="black" d="M160.54,-352.79C182.64,-348.15 209.23,-339.41 228,-323 235.09,-316.81 240.26,-308.05 243.95,-299.6"/>
-<polygon fill="black" stroke="black" points="247.32,-300.57 247.62,-289.98 240.78,-298.07 247.32,-300.57"/>
-<text text-anchor="middle" x="254.5" y="-311.8" font-family="Times,serif" font-size="14.00">ipv4</text>
+<path fill="none" stroke="black" d="M261.95,-319.8C261.95,-308.16 261.95,-292.55 261.95,-279.24"/>
+<polygon fill="black" stroke="black" points="265.45,-279.18 261.95,-269.18 258.45,-279.18 265.45,-279.18"/>
+<text text-anchor="middle" x="277.45" y="-290.8" font-family="Times,serif" font-size="14.00">ipv4</text>
 </g>
 <!-- ip6_lookup -->
 <g id="node8" class="node">
 <title>ip6_lookup</title>
-<ellipse fill="none" stroke="black" cx="439" cy="-272" rx="60.39" ry="18"/>
-<text text-anchor="middle" x="439" y="-268.3" font-family="Times,serif" font-size="14.00">ip6_lookup</text>
+<ellipse fill="none" stroke="black" cx="492.95" cy="-251" rx="60.39" ry="18"/>
+<text text-anchor="middle" x="492.95" y="-247.3" font-family="Times,serif" font-size="14.00">ip6_lookup</text>
 </g>
 <!-- pkt_cls&#45;&gt;ip6_lookup -->
 <g id="edge4" class="edge">
 <title>pkt_cls&#45;&gt;ip6_lookup</title>
-<path fill="none" stroke="black" d="M157.52,-350.25C188.82,-343.6 234.51,-333.46 274,-323 313.2,-312.62 357.13,-299.22 389.79,-288.91"/>
-<polygon fill="black" stroke="black" points="391.08,-292.17 399.55,-285.81 388.96,-285.5 391.08,-292.17"/>
-<text text-anchor="middle" x="339.5" y="-311.8" font-family="Times,serif" font-size="14.00">ipv6</text>
+<path fill="none" stroke="black" d="M293.1,-325.54C332.57,-311.01 400.93,-285.86 446.54,-269.07"/>
+<polygon fill="black" stroke="black" points="448.02,-272.26 456.2,-265.52 445.61,-265.69 448.02,-272.26"/>
+<text text-anchor="middle" x="407.45" y="-290.8" font-family="Times,serif" font-size="14.00">ipv6</text>
 </g>
 <!-- ip4_lookup&#45;&gt;pkt_drop -->
 <g id="edge7" class="edge">
 <title>ip4_lookup&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M239.17,-254.03C232.31,-243.87 224.56,-230.37 221,-217 204.89,-156.57 227.58,-83.56 242.59,-45.31"/>
-<polygon fill="cyan" stroke="cyan" points="245.89,-46.5 246.4,-35.92 239.4,-43.87 245.89,-46.5"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M258.85,-232.91C253.68,-198.83 247.1,-121.54 282.95,-73 299.1,-51.12 326.1,-37.95 350.6,-30.11"/>
+<polygon fill="cyan" stroke="cyan" points="351.6,-33.46 360.19,-27.26 349.61,-26.75 351.6,-33.46"/>
 </g>
 <!-- ip4_rewrite -->
 <g id="node9" class="node">
 <title>ip4_rewrite</title>
-<ellipse fill="none" stroke="black" cx="294" cy="-199" rx="63.89" ry="18"/>
-<text text-anchor="middle" x="294" y="-195.3" font-family="Times,serif" font-size="14.00">ip4_rewrite</text>
+<ellipse fill="none" stroke="black" cx="347.95" cy="-178" rx="63.89" ry="18"/>
+<text text-anchor="middle" x="347.95" y="-174.3" font-family="Times,serif" font-size="14.00">ip4_rewrite</text>
 </g>
 <!-- ip4_lookup&#45;&gt;ip4_rewrite -->
 <g id="edge6" class="edge">
 <title>ip4_lookup&#45;&gt;ip4_rewrite</title>
-<path fill="none" stroke="black" d="M261.95,-254.17C266.95,-245.72 273.12,-235.29 278.71,-225.85"/>
-<polygon fill="black" stroke="black" points="281.75,-227.59 283.83,-217.2 275.72,-224.02 281.75,-227.59"/>
+<path fill="none" stroke="black" d="M281.46,-233.89C292.92,-224.42 307.6,-212.31 320.25,-201.87"/>
+<polygon fill="black" stroke="black" points="322.73,-204.36 328.21,-195.29 318.27,-198.96 322.73,-204.36"/>
 </g>
 <!-- ip4_local -->
 <g id="node11" class="node">
 <title>ip4_local</title>
-<ellipse fill="none" stroke="black" cx="136" cy="-145" rx="51.19" ry="18"/>
-<text text-anchor="middle" x="136" y="-141.3" font-family="Times,serif" font-size="14.00">ip4_local</text>
+<ellipse fill="none" stroke="black" cx="176.95" cy="-178" rx="51.19" ry="18"/>
+<text text-anchor="middle" x="176.95" y="-174.3" font-family="Times,serif" font-size="14.00">ip4_local</text>
 </g>
 <!-- ip4_lookup&#45;&gt;ip4_local -->
 <g id="edge17" class="edge">
 <title>ip4_lookup&#45;&gt;ip4_local</title>
-<path fill="none" stroke="black" d="M218.11,-256.86C207.64,-251.39 196.61,-244.41 188,-236 169.45,-217.88 155.34,-191.74 146.53,-172.29"/>
-<polygon fill="black" stroke="black" points="149.72,-170.86 142.52,-163.08 143.3,-173.65 149.72,-170.86"/>
+<path fill="none" stroke="black" d="M242.66,-233.89C231.17,-224.29 216.41,-211.96 203.79,-201.42"/>
+<polygon fill="black" stroke="black" points="205.78,-198.53 195.86,-194.8 201.29,-203.9 205.78,-198.53"/>
 </g>
 <!-- ip6_lookup&#45;&gt;pkt_drop -->
 <g id="edge11" class="edge">
 <title>ip6_lookup&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M470.57,-256.44C486.08,-247.46 503.27,-234.31 512,-217 519.2,-202.71 517.24,-196.12 512,-181 486.88,-108.48 466,-83.15 395,-54 367.69,-42.79 335.88,-34.51 309.39,-28.83"/>
-<polygon fill="cyan" stroke="cyan" points="310.02,-25.39 299.52,-26.78 308.6,-32.24 310.02,-25.39"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M524.51,-235.44C540.02,-226.46 557.22,-213.31 565.95,-196 573.15,-181.71 572.55,-174.57 565.95,-160 540.59,-104.08 480.88,-61.6 441.74,-38.51"/>
+<polygon fill="cyan" stroke="cyan" points="443.16,-35.29 432.75,-33.34 439.67,-41.36 443.16,-35.29"/>
 </g>
 <!-- ip6_rewrite -->
 <g id="node10" class="node">
 <title>ip6_rewrite</title>
-<ellipse fill="none" stroke="black" cx="439" cy="-199" rx="63.89" ry="18"/>
-<text text-anchor="middle" x="439" y="-195.3" font-family="Times,serif" font-size="14.00">ip6_rewrite</text>
+<ellipse fill="none" stroke="black" cx="492.95" cy="-178" rx="63.89" ry="18"/>
+<text text-anchor="middle" x="492.95" y="-174.3" font-family="Times,serif" font-size="14.00">ip6_rewrite</text>
 </g>
 <!-- ip6_lookup&#45;&gt;ip6_rewrite -->
 <g id="edge10" class="edge">
 <title>ip6_lookup&#45;&gt;ip6_rewrite</title>
-<path fill="none" stroke="black" d="M439,-253.81C439,-245.79 439,-236.05 439,-227.07"/>
-<polygon fill="black" stroke="black" points="442.5,-227.03 439,-217.03 435.5,-227.03 442.5,-227.03"/>
+<path fill="none" stroke="black" d="M492.95,-232.81C492.95,-224.79 492.95,-215.05 492.95,-206.07"/>
+<polygon fill="black" stroke="black" points="496.45,-206.03 492.95,-196.03 489.45,-206.03 496.45,-206.03"/>
 </g>
 <!-- ip4_rewrite&#45;&gt;ethdev_tx -->
 <g id="edge8" class="edge">
 <title>ip4_rewrite&#45;&gt;ethdev_tx</title>
-<path fill="none" stroke="green" d="M301.07,-180.97C308.09,-164.05 318.96,-137.86 327.09,-118.28"/>
-<polygon fill="green" stroke="green" points="330.35,-119.57 330.95,-108.99 323.88,-116.88 330.35,-119.57"/>
+<path fill="none" stroke="green" d="M347.95,-159.8C347.95,-148.16 347.95,-132.55 347.95,-119.24"/>
+<polygon fill="green" stroke="green" points="351.45,-119.18 347.95,-109.18 344.45,-119.18 351.45,-119.18"/>
 </g>
 <!-- ip4_rewrite&#45;&gt;pkt_drop -->
 <g id="edge9" class="edge">
 <title>ip4_rewrite&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M289.85,-180.97C285.53,-163.07 278.61,-134.1 273,-109 268.3,-87.99 263.29,-64.16 259.59,-46.3"/>
-<polygon fill="cyan" stroke="cyan" points="262.97,-45.37 257.52,-36.28 256.11,-46.78 262.97,-45.37"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M370.32,-161.1C385.53,-148.83 404.37,-130.37 412.95,-109 421.04,-88.82 418.02,-64.12 413.56,-45.7"/>
+<polygon fill="cyan" stroke="cyan" points="416.9,-44.66 410.91,-35.93 410.15,-46.49 416.9,-44.66"/>
 </g>
 <!-- ip6_rewrite&#45;&gt;ethdev_tx -->
 <g id="edge12" class="edge">
 <title>ip6_rewrite&#45;&gt;ethdev_tx</title>
-<path fill="none" stroke="green" d="M423.22,-181.44C406.47,-163.86 379.84,-135.91 360.81,-115.94"/>
-<polygon fill="green" stroke="green" points="363.1,-113.27 353.67,-108.45 358.03,-118.1 363.1,-113.27"/>
+<path fill="none" stroke="green" d="M466.35,-161.41C442.8,-147.6 408.27,-127.36 382.57,-112.3"/>
+<polygon fill="green" stroke="green" points="384.28,-109.24 373.88,-107.21 380.74,-115.28 384.28,-109.24"/>
 </g>
 <!-- ip6_rewrite&#45;&gt;pkt_drop -->
 <g id="edge13" class="edge">
 <title>ip6_rewrite&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M438.77,-180.67C437.49,-154.09 431.22,-103.19 403,-73 379.35,-47.7 342.93,-34.22 312.02,-27.06"/>
-<polygon fill="cyan" stroke="cyan" points="312.71,-23.63 302.2,-24.95 311.24,-30.47 312.71,-23.63"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M485.15,-159.86C473.93,-135.7 452.15,-90.48 429.95,-54 427.97,-50.75 425.78,-47.4 423.55,-44.13"/>
+<polygon fill="cyan" stroke="cyan" points="426.28,-41.92 417.67,-35.75 420.55,-45.94 426.28,-41.92"/>
 </g>
 <!-- ip4_local&#45;&gt;pkt_drop -->
 <g id="edge18" class="edge">
 <title>ip4_local&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M142.47,-126.87C150.6,-107.23 166.18,-75.04 188,-54 195,-47.25 203.56,-41.45 212.16,-36.63"/>
-<polygon fill="cyan" stroke="cyan" points="213.85,-39.7 221.08,-31.95 210.6,-33.5 213.85,-39.7"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M191.02,-160.51C195.47,-154.86 200.21,-148.35 203.95,-142 225.57,-105.29 209.02,-81.03 241.95,-54 257.83,-40.96 306.22,-31.62 346.19,-25.89"/>
+<polygon fill="cyan" stroke="cyan" points="346.72,-29.35 356.14,-24.51 345.75,-22.41 346.72,-29.35"/>
+</g>
+<!-- udp4_input -->
+<g id="node12" class="node">
+<title>udp4_input</title>
+<ellipse fill="none" stroke="black" cx="126.95" cy="-91" rx="63.09" ry="18"/>
+<text text-anchor="middle" x="126.95" y="-87.3" font-family="Times,serif" font-size="14.00">udp4_input</text>
+</g>
+<!-- ip4_local&#45;&gt;udp4_input -->
+<g id="edge19" class="edge">
+<title>ip4_local&#45;&gt;udp4_input</title>
+<path fill="none" stroke="black" d="M167.07,-160.21C159.99,-148.18 150.33,-131.75 142.26,-118.03"/>
+<polygon fill="black" stroke="black" points="145.06,-115.89 136.97,-109.05 139.03,-119.44 145.06,-115.89"/>
+<text text-anchor="middle" x="177.45" y="-130.8" font-family="Times,serif" font-size="14.00">udpv4</text>
+</g>
+<!-- udp4_input&#45;&gt;pkt_drop -->
+<g id="edge21" class="edge">
+<title>udp4_input&#45;&gt;pkt_drop</title>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M154.75,-74.82C169.08,-67.56 187.05,-59.32 203.95,-54 250.51,-39.35 305.19,-30.33 345.76,-25.12"/>
+<polygon fill="cyan" stroke="cyan" points="346.26,-28.59 355.75,-23.88 345.4,-21.64 346.26,-28.59"/>
+</g>
+<!-- udp_user_node -->
+<g id="node13" class="node">
+<title>udp_user_node</title>
+<ellipse fill="none" stroke="black" cx="126.95" cy="-18" rx="79.89" ry="18"/>
+<text text-anchor="middle" x="126.95" y="-14.3" font-family="Times,serif" font-size="14.00">udp_user_node</text>
+</g>
+<!-- udp4_input&#45;&gt;udp_user_node -->
+<g id="edge20" class="edge">
+<title>udp4_input&#45;&gt;udp_user_node</title>
+<path fill="none" stroke="black" d="M126.95,-72.81C126.95,-64.79 126.95,-55.05 126.95,-46.07"/>
+<polygon fill="black" stroke="black" points="130.45,-46.03 126.95,-36.03 123.45,-46.03 130.45,-46.03"/>
 </g>
 </g>
 </svg>
diff --git a/lib/node/meson.build b/lib/node/meson.build
index c0d5b09e2f..c5b8ee656e 100644
--- a/lib/node/meson.build
+++ b/lib/node/meson.build
@@ -22,11 +22,13 @@ sources = files(
         'null.c',
         'pkt_cls.c',
         'pkt_drop.c',
+        'udp4_input.c',
 )
 headers = files(
         'rte_node_eth_api.h',
         'rte_node_ip4_api.h',
         'rte_node_ip6_api.h',
+        'rte_node_udp4_input_api.h',
 )
 
 # Strict-aliasing rules are violated by uint8_t[] to context size casts.
diff --git a/lib/node/rte_node_udp4_input_api.h b/lib/node/rte_node_udp4_input_api.h
new file mode 100644
index 0000000000..c873acbbe0
--- /dev/null
+++ b/lib/node/rte_node_udp4_input_api.h
@@ -0,0 +1,61 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2023 Marvell International Ltd.
+ */
+
+#ifndef __INCLUDE_RTE_NODE_UDP4_INPUT_API_H__
+#define __INCLUDE_RTE_NODE_UDP4_INPUT_API_H__
+
+/**
+ * @file rte_node_udp4_input_api.h
+ *
+ * @warning
+ * @b EXPERIMENTAL:
+ * All functions in this file may be changed or removed without prior notice.
+ *
+ * This API allows to control path functions of udp4_* nodes
+ * like udp4_input.
+ *
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rte_common.h>
+#include <rte_compat.h>
+
+#include "rte_graph.h"
+/**
+ * UDP4 lookup next nodes.
+ */
+enum rte_node_udp4_input_next {
+	RTE_NODE_UDP4_INPUT_NEXT_PKT_DROP,
+	/**< Packet drop node. */
+};
+
+/**
+ * Add usr node to receive udp4 frames.
+ *
+ * @param usr_node
+ * Node registered by user to receive data.
+ */
+__rte_experimental
+int rte_node_udp4_usr_node_add(const char *usr_node);
+
+/**
+ * Add udpv4 dst_port to lookup table.
+ *
+ * @param dst_port
+ *   Dst Port of packet to be added for consumption.
+ * @param next_node
+ *   Next node packet to be added for consumption.
+ * @return
+ *   0 on success, negative otherwise.
+ */
+__rte_experimental
+int rte_node_udp4_dst_port_add(uint32_t dst_port, rte_edge_t next_node);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __INCLUDE_RTE_NODE_UDP4_API_H__ */
diff --git a/lib/node/udp4_input.c b/lib/node/udp4_input.c
new file mode 100644
index 0000000000..80cedce548
--- /dev/null
+++ b/lib/node/udp4_input.c
@@ -0,0 +1,226 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2023 Marvell International Ltd.
+ */
+
+#include <arpa/inet.h>
+#include <sys/socket.h>
+
+#include <rte_ethdev.h>
+#include <rte_ether.h>
+#include <rte_graph.h>
+#include <rte_graph_worker.h>
+#include <rte_ip.h>
+#include <rte_lpm.h>
+#include <rte_hash.h>
+#include <rte_fbk_hash.h>
+#include <rte_jhash.h>
+#include <rte_hash_crc.h>
+
+
+#include "rte_node_udp4_input_api.h"
+
+#include "node_private.h"
+
+#define UDP4_INPUT_HASH_TBL_SIZE 1024
+
+#define UDP4_INPUT_NODE_HASH(ctx) \
+	(((struct udp4_input_node_ctx *)ctx)->hash)
+
+#define UDP4_INPUT_NODE_NEXT_INDEX(ctx) \
+	(((struct udp4_input_node_ctx *)ctx)->next_index)
+
+
+/* UDP4 input  global data struct */
+struct udp4_input_node_main {
+	struct rte_hash *hash_tbl[RTE_MAX_NUMA_NODES];
+};
+
+static struct udp4_input_node_main udp4_input_nm;
+
+struct udp4_input_node_ctx {
+	/* Socket's Hash table */
+	struct rte_hash *hash;
+	/* Cached next index */
+	uint16_t next_index;
+};
+
+struct flow_key {
+	uint32_t prt_dst;
+};
+
+static struct rte_hash_parameters udp4_params = {
+	.entries = UDP4_INPUT_HASH_TBL_SIZE,
+	.key_len = sizeof(uint32_t),
+	.hash_func = rte_jhash,
+	.hash_func_init_val = 0,
+	.socket_id = 0,
+};
+
+int
+rte_node_udp4_dst_port_add(uint32_t dst_port, rte_edge_t next_node)
+{
+	uint8_t socket;
+	int rc;
+
+	for (socket = 0; socket < RTE_MAX_NUMA_NODES; socket++) {
+		if (!udp4_input_nm.hash_tbl[socket])
+			continue;
+
+		rc = rte_hash_add_key_data(udp4_input_nm.hash_tbl[socket],
+					   &dst_port, (void *)(uintptr_t)next_node);
+		if (rc < 0) {
+			node_err("udp4_lookup", "Failed to add key for sock %u, rc=%d",
+					socket, rc);
+			return rc;
+		}
+	}
+	return 0;
+}
+
+int
+rte_node_udp4_usr_node_add(const char *usr_node)
+{
+	const char *next_nodes = usr_node;
+	rte_node_t udp4_input_node_id, count;
+
+	udp4_input_node_id = rte_node_from_name("udp4_input");
+	count = rte_node_edge_update(udp4_input_node_id, RTE_EDGE_ID_INVALID,
+				     &next_nodes, 1);
+	if (count == 0) {
+		node_dbg("udp4_input", "Adding usr node as edge to udp4_input failed");
+		return count;
+	}
+	count = rte_node_edge_count(udp4_input_node_id) - 1;
+	return count;
+}
+
+static int
+setup_udp4_dstprt_hash(struct udp4_input_node_main *nm, int socket)
+{
+	struct rte_hash_parameters *hash_udp4 = &udp4_params;
+	char s[RTE_HASH_NAMESIZE];
+
+	/* One Hash table per socket */
+	if (nm->hash_tbl[socket])
+		return 0;
+
+	/* create Hash table */
+	snprintf(s, sizeof(s), "UDP4_INPUT_HASH_%d", socket);
+	hash_udp4->name = s;
+	hash_udp4->socket_id = socket;
+	nm->hash_tbl[socket] = rte_hash_create(hash_udp4);
+	if (nm->hash_tbl[socket] == NULL)
+		return -rte_errno;
+
+	return 0;
+}
+
+static int
+udp4_input_node_init(const struct rte_graph *graph, struct rte_node *node)
+{
+	uint16_t socket, lcore_id;
+	static uint8_t init_once;
+	int rc;
+
+	RTE_SET_USED(graph);
+	RTE_BUILD_BUG_ON(sizeof(struct udp4_input_node_ctx) > RTE_NODE_CTX_SZ);
+
+	if (!init_once) {
+
+		/* Setup HASH tables for all sockets */
+		RTE_LCORE_FOREACH(lcore_id)
+		{
+			socket = rte_lcore_to_socket_id(lcore_id);
+			rc = setup_udp4_dstprt_hash(&udp4_input_nm, socket);
+			if (rc) {
+				node_err("udp4_lookup",
+						"Failed to setup hash tbl for sock %u, rc=%d",
+						socket, rc);
+				return rc;
+			}
+		}
+		init_once = 1;
+	}
+
+	UDP4_INPUT_NODE_HASH(node->ctx) = udp4_input_nm.hash_tbl[graph->socket];
+
+	node_dbg("udp4_input", "Initialized udp4_input node");
+	return 0;
+}
+
+static uint16_t
+udp4_input_node_process_scalar(struct rte_graph *graph, struct rte_node *node,
+			       void **objs, uint16_t nb_objs)
+{
+	struct rte_hash *hash_tbl_handle = UDP4_INPUT_NODE_HASH(node->ctx);
+	rte_edge_t next_index, udplookup_node;
+	struct rte_udp_hdr *pkt_udp_hdr;
+	uint16_t last_spec = 0;
+	void **to_next, **from;
+	struct rte_mbuf *mbuf;
+	uint16_t held = 0;
+	uint16_t next = 0;
+	int i, rc;
+
+	/* Speculative next */
+	next_index = UDP4_INPUT_NODE_NEXT_INDEX(node->ctx);
+
+	from = objs;
+
+	to_next = rte_node_next_stream_get(graph, node, next_index, nb_objs);
+	for (i = 0; i < nb_objs; i++) {
+		struct flow_key key_port;
+
+		mbuf = (struct rte_mbuf *)objs[i];
+		pkt_udp_hdr = rte_pktmbuf_mtod_offset(mbuf, struct rte_udp_hdr *,
+						sizeof(struct rte_ether_hdr) +
+						sizeof(struct rte_ipv4_hdr));
+
+		key_port.prt_dst = rte_cpu_to_be_16(pkt_udp_hdr->dst_port);
+		rc = rte_hash_lookup_data(hash_tbl_handle,
+					  &key_port.prt_dst,
+					  (void **)&udplookup_node);
+		next = (rc < 0) ? RTE_NODE_UDP4_INPUT_NEXT_PKT_DROP
+				    : udplookup_node;
+
+		if (unlikely(next_index != next)) {
+			/* Copy things successfully speculated till now */
+			rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
+			from += last_spec;
+			to_next += last_spec;
+			held += last_spec;
+			last_spec = 0;
+
+			rte_node_enqueue_x1(graph, node, next, from[0]);
+			from += 1;
+		} else {
+			last_spec += 1;
+		}
+	}
+	/* !!! Home run !!! */
+	if (likely(last_spec == nb_objs)) {
+		rte_node_next_stream_move(graph, node, next_index);
+		return nb_objs;
+	}
+	held += last_spec;
+	rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
+	rte_node_next_stream_put(graph, node, next_index, held);
+	/* Save the last next used */
+	UDP4_INPUT_NODE_NEXT_INDEX(node->ctx) = next;
+
+	return nb_objs;
+}
+
+static struct rte_node_register udp4_input_node = {
+	.process = udp4_input_node_process_scalar,
+	.name = "udp4_input",
+
+	.init = udp4_input_node_init,
+
+	.nb_edges = RTE_NODE_UDP4_INPUT_NEXT_PKT_DROP + 1,
+	.next_nodes = {
+		[RTE_NODE_UDP4_INPUT_NEXT_PKT_DROP] = "pkt_drop",
+	},
+};
+
+RTE_NODE_REGISTER(udp4_input_node);
diff --git a/lib/node/version.map b/lib/node/version.map
index 40df308bfe..c51befce09 100644
--- a/lib/node/version.map
+++ b/lib/node/version.map
@@ -6,6 +6,8 @@ EXPERIMENTAL {
 	rte_node_ip4_rewrite_add;
 	rte_node_ip6_rewrite_add;
 	rte_node_ip6_route_add;
+	rte_node_udp4_usr_node_add;
+	rte_node_udp4_dst_port_add;
 	rte_node_logtype;
 	local: *;
 };
-- 
2.25.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v6 1/2] node: add IPv4 local node to handle local pkts
  2023-09-27 12:40       ` [PATCH v5 1/2] node: add IPv4 local node to handle local pkts Rakesh Kudurumalla
  2023-09-27 12:41         ` [PATCH v5 2/2] node: add UDP v4 support Rakesh Kudurumalla
@ 2023-09-28 10:25         ` Rakesh Kudurumalla
  2023-09-28 10:25           ` [PATCH v6 2/2] node: add UDP v4 support Rakesh Kudurumalla
  2023-09-29 10:54           ` [PATCH v6 1/2] node: add IPv4 local node to handle local pkts Nithin Dabilpuram
  1 sibling, 2 replies; 16+ messages in thread
From: Rakesh Kudurumalla @ 2023-09-28 10:25 UTC (permalink / raw)
  To: Jerin Jacob, Kiran Kumar K, Nithin Dabilpuram, Zhirun Yan,
	Pavan Nikhilesh
  Cc: dev, Rakesh Kudurumalla

Local or Host destined pkts can be redirected IPv4 local node
using IP4 Lookup node entries with prefix of 32 and be redirected
to this IP4 local node for further processing.

Signed-off-by: Rakesh Kudurumalla <rkudurumalla@marvell.com>
---
Depends-on: series-29670 ("remove MAX macro from all nodes")

v6: Resolve dependency

 doc/guides/prog_guide/graph_lib.rst           |  15 ++
 .../img/graph_inbuilt_node_flow.svg           | 138 ++++++++++--------
 lib/node/ip4_local.c                          |  88 +++++++++++
 lib/node/ip4_lookup.c                         |   1 +
 lib/node/meson.build                          |   1 +
 lib/node/rte_node_ip4_api.h                   |  12 ++
 6 files changed, 196 insertions(+), 59 deletions(-)
 create mode 100644 lib/node/ip4_local.c

diff --git a/doc/guides/prog_guide/graph_lib.rst b/doc/guides/prog_guide/graph_lib.rst
index e7b6e12004..f2e04a68b9 100644
--- a/doc/guides/prog_guide/graph_lib.rst
+++ b/doc/guides/prog_guide/graph_lib.rst
@@ -498,3 +498,18 @@ Uses ``poll`` function to poll on the socket fd
 for ``POLLIN`` events to read the packets from raw socket
 to stream buffer and does ``rte_node_next_stream_move()``
 when there are received packets.
+
+ip4_local
+~~~~~~~~~
+This node is an intermediate node that does ``packet_type`` lookup for
+the received ipv4 packets and the result determines each packets next node.
+
+On successful ``packet_type`` lookup, for any IPv4 protocol the result
+contains the ``next_node`` id and ``next-hop`` id with which the packet
+needs to be further processed.
+
+On packet_type lookup failure, objects are redirected to ``pkt_drop`` node.
+``rte_node_ip4_route_add()`` is control path API to add ipv4 address with 32 bit
+depth to receive to packets.
+To achieve home run, node use ``rte_node_stream_move()`` as mentioned in above
+sections.
diff --git a/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg b/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg
index 7eea94701f..b954f6fba1 100644
--- a/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg
+++ b/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg
@@ -37,174 +37,194 @@ digraph dpdk_inbuilt_nodes_flow {
     ethdev_tx -> pkt_drop [color="cyan" style="dashed"]
     pkt_cls->pkt_drop   [color="cyan" style="dashed"]
     kernel_tx -> kernel_rx [color="red" style="dashed"]
+    ip4_lookup -> ip4_local
+    ip4_local -> pkt_drop [color="cyan" style="dashed"]
 }
 
  -->
 <!-- input nodes -->
 <!-- Title: dpdk_inbuilt_nodes_flow Pages: 1 -->
-<svg width="470pt" height="425pt"
- viewBox="0.00 0.00 470.23 424.50" 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 420.5)">
+<svg width="525pt" height="458pt"
+ viewBox="0.00 0.00 524.91 458.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 454)">
 <title>dpdk_inbuilt_nodes_flow</title>
-<polygon fill="white" stroke="none" points="-4,4 -4,-420.5 466.23,-420.5 466.23,4 -4,4"/>
+<polygon fill="white" stroke="transparent" points="-4,4 -4,-454 520.91,-454 520.91,4 -4,4"/>
 <!-- ethdev_rx -->
 <g id="node1" class="node">
 <title>ethdev_rx</title>
-<ellipse fill="none" stroke="green" cx="219.23" cy="-398.5" rx="47.77" ry="18"/>
-<text text-anchor="middle" x="219.23" y="-393.45" font-family="Times,serif" font-size="14.00">ethdev_rx</text>
+<ellipse fill="none" stroke="green" cx="120" cy="-432" rx="56.59" ry="18"/>
+<text text-anchor="middle" x="120" y="-428.3" font-family="Times,serif" font-size="14.00">ethdev_rx</text>
 </g>
 <!-- pkt_cls -->
 <g id="node6" class="node">
 <title>pkt_cls</title>
-<ellipse fill="none" stroke="red" cx="219.23" cy="-325.5" rx="37.53" ry="18"/>
-<text text-anchor="middle" x="219.23" y="-320.45" font-family="Times,serif" font-size="14.00">pkt_cls</text>
+<ellipse fill="none" stroke="red" cx="120" cy="-359" rx="42.79" ry="18"/>
+<text text-anchor="middle" x="120" y="-355.3" font-family="Times,serif" font-size="14.00">pkt_cls</text>
 </g>
 <!-- ethdev_rx&#45;&gt;pkt_cls -->
 <g id="edge1" class="edge">
 <title>ethdev_rx&#45;&gt;pkt_cls</title>
-<path fill="none" stroke="black" d="M219.23,-380.31C219.23,-372.55 219.23,-363.18 219.23,-354.45"/>
-<polygon fill="black" stroke="black" points="222.73,-354.53 219.23,-344.53 215.73,-354.53 222.73,-354.53"/>
+<path fill="none" stroke="black" d="M120,-413.81C120,-405.79 120,-396.05 120,-387.07"/>
+<polygon fill="black" stroke="black" points="123.5,-387.03 120,-377.03 116.5,-387.03 123.5,-387.03"/>
 </g>
 <!-- kernel_rx -->
 <g id="node2" class="node">
 <title>kernel_rx</title>
-<ellipse fill="none" stroke="green" cx="46.23" cy="-164" rx="46.23" ry="18"/>
-<text text-anchor="middle" x="46.23" y="-158.95" font-family="Times,serif" font-size="14.00">kernel_rx</text>
+<ellipse fill="none" stroke="green" cx="82" cy="-199" rx="53.89" ry="18"/>
+<text text-anchor="middle" x="82" y="-195.3" font-family="Times,serif" font-size="14.00">kernel_rx</text>
 </g>
 <!-- kernel_rx&#45;&gt;pkt_cls -->
 <g id="edge2" class="edge">
 <title>kernel_rx&#45;&gt;pkt_cls</title>
-<path fill="none" stroke="black" d="M41.45,-182.08C37.1,-201.37 33.27,-232.96 47.23,-255 73.68,-296.74 130.21,-313.41 171.26,-320.07"/>
-<polygon fill="black" stroke="black" points="170.73,-323.68 181.13,-321.66 171.74,-316.75 170.73,-323.68"/>
+<path fill="none" stroke="black" d="M70.87,-216.92C60.28,-235.27 47.29,-265.24 57,-290 64.12,-308.16 78.62,-324.37 91.92,-336.4"/>
+<polygon fill="black" stroke="black" points="89.69,-339.1 99.54,-342.99 94.26,-333.8 89.69,-339.1"/>
 </g>
 <!-- ethdev_tx -->
 <g id="node3" class="node">
 <title>ethdev_tx</title>
-<ellipse fill="none" stroke="magenta" cx="293.23" cy="-91" rx="47.26" ry="18"/>
-<text text-anchor="middle" x="293.23" y="-85.95" font-family="Times,serif" font-size="14.00">ethdev_tx</text>
+<ellipse fill="none" stroke="magenta" cx="338" cy="-91" rx="55.79" ry="18"/>
+<text text-anchor="middle" x="338" y="-87.3" font-family="Times,serif" font-size="14.00">ethdev_tx</text>
 </g>
 <!-- pkt_drop -->
 <g id="node4" class="node">
 <title>pkt_drop</title>
-<ellipse fill="none" stroke="cyan" cx="349.23" cy="-18" rx="44.19" ry="18"/>
-<text text-anchor="middle" x="349.23" y="-12.95" font-family="Times,serif" font-size="14.00">pkt_drop</text>
+<ellipse fill="none" stroke="cyan" cx="254" cy="-18" rx="51.99" ry="18"/>
+<text text-anchor="middle" x="254" y="-14.3" font-family="Times,serif" font-size="14.00">pkt_drop</text>
 </g>
 <!-- ethdev_tx&#45;&gt;pkt_drop -->
 <g id="edge14" class="edge">
 <title>ethdev_tx&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M306.22,-73.53C313.15,-64.75 321.81,-53.76 329.55,-43.96"/>
-<polygon fill="cyan" stroke="cyan" points="332.87,-46.4 336.32,-36.38 327.37,-42.06 332.87,-46.4"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M318.94,-73.89C307.58,-64.29 293,-51.96 280.53,-41.42"/>
+<polygon fill="cyan" stroke="cyan" points="282.59,-38.58 272.7,-34.8 278.07,-43.93 282.59,-38.58"/>
 </g>
 <!-- kernel_tx -->
 <g id="node5" class="node">
 <title>kernel_tx</title>
-<ellipse fill="none" stroke="blue" cx="102.23" cy="-237" rx="45.72" ry="18"/>
-<text text-anchor="middle" x="102.23" y="-231.95" font-family="Times,serif" font-size="14.00">kernel_tx</text>
+<ellipse fill="none" stroke="blue" cx="120" cy="-272" rx="53.89" ry="18"/>
+<text text-anchor="middle" x="120" y="-268.3" font-family="Times,serif" font-size="14.00">kernel_tx</text>
 </g>
 <!-- kernel_tx&#45;&gt;kernel_rx -->
 <g id="edge16" class="edge">
 <title>kernel_tx&#45;&gt;kernel_rx</title>
-<path fill="none" stroke="red" stroke-dasharray="5,2" d="M89.25,-219.53C82.32,-210.75 73.65,-199.76 65.92,-189.96"/>
-<polygon fill="red" stroke="red" points="68.09,-188.06 59.15,-182.38 62.6,-192.4 68.09,-188.06"/>
+<path fill="none" stroke="red" stroke-dasharray="5,2" d="M110.99,-254.17C106.52,-245.81 101,-235.51 95.99,-226.14"/>
+<polygon fill="red" stroke="red" points="99.01,-224.36 91.2,-217.2 92.84,-227.67 99.01,-224.36"/>
 </g>
 <!-- pkt_cls&#45;&gt;pkt_drop -->
 <g id="edge15" class="edge">
 <title>pkt_cls&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M255.09,-319.38C322.68,-308.72 462.23,-281.44 462.23,-238 462.23,-238 462.23,-238 462.23,-90 462.23,-57.84 429.01,-39.68 398.59,-29.8"/>
-<polygon fill="cyan" stroke="cyan" points="400.02,-26.27 389.44,-26.75 398.01,-32.98 400.02,-26.27"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M84,-348.97C48.65,-337.7 0,-314.61 0,-273 0,-273 0,-273 0,-90 0,-49.99 118.4,-31.52 193.52,-23.82"/>
+<polygon fill="cyan" stroke="cyan" points="194.21,-27.27 203.82,-22.81 193.52,-20.31 194.21,-27.27"/>
 </g>
 <!-- pkt_cls&#45;&gt;kernel_tx -->
 <g id="edge5" class="edge">
 <title>pkt_cls&#45;&gt;kernel_tx</title>
-<path fill="none" stroke="blue" d="M186.99,-315.75C170.62,-310.16 151.14,-301.64 136.48,-289.5 128.23,-282.66 121.2,-273.31 115.7,-264.46"/>
-<polygon fill="blue" stroke="blue" points="118.38,-263.1 110.34,-256.2 112.32,-266.61 118.38,-263.1"/>
-<text text-anchor="middle" x="176.61" y="-276.2" font-family="Times,serif" font-size="14.00">exception pkts</text>
+<path fill="none" stroke="blue" d="M120,-340.8C120,-329.16 120,-313.55 120,-300.24"/>
+<polygon fill="blue" stroke="blue" points="123.5,-300.18 120,-290.18 116.5,-300.18 123.5,-300.18"/>
+<text text-anchor="middle" x="172.5" y="-311.8" font-family="Times,serif" font-size="14.00">exception pkts</text>
 </g>
 <!-- ip4_lookup -->
 <g id="node7" class="node">
 <title>ip4_lookup</title>
-<ellipse fill="none" stroke="black" cx="219.23" cy="-237" rx="52.89" ry="18"/>
-<text text-anchor="middle" x="219.23" y="-231.95" font-family="Times,serif" font-size="14.00">ip4_lookup</text>
+<ellipse fill="none" stroke="black" cx="252" cy="-272" rx="60.39" ry="18"/>
+<text text-anchor="middle" x="252" y="-268.3" font-family="Times,serif" font-size="14.00">ip4_lookup</text>
 </g>
 <!-- pkt_cls&#45;&gt;ip4_lookup -->
 <g id="edge3" class="edge">
 <title>pkt_cls&#45;&gt;ip4_lookup</title>
-<path fill="none" stroke="black" d="M219.23,-307.41C219.23,-295.64 219.23,-279.73 219.23,-266.11"/>
-<polygon fill="black" stroke="black" points="222.73,-266.35 219.23,-256.35 215.73,-266.35 222.73,-266.35"/>
-<text text-anchor="middle" x="231.23" y="-276.2" font-family="Times,serif" font-size="14.00">ipv4</text>
+<path fill="none" stroke="black" d="M160.54,-352.79C182.64,-348.15 209.23,-339.41 228,-323 235.09,-316.81 240.26,-308.05 243.95,-299.6"/>
+<polygon fill="black" stroke="black" points="247.32,-300.57 247.62,-289.98 240.78,-298.07 247.32,-300.57"/>
+<text text-anchor="middle" x="254.5" y="-311.8" font-family="Times,serif" font-size="14.00">ipv4</text>
 </g>
 <!-- ip6_lookup -->
 <g id="node8" class="node">
 <title>ip6_lookup</title>
-<ellipse fill="none" stroke="black" cx="343.23" cy="-237" rx="52.89" ry="18"/>
-<text text-anchor="middle" x="343.23" y="-231.95" font-family="Times,serif" font-size="14.00">ip6_lookup</text>
+<ellipse fill="none" stroke="black" cx="439" cy="-272" rx="60.39" ry="18"/>
+<text text-anchor="middle" x="439" y="-268.3" font-family="Times,serif" font-size="14.00">ip6_lookup</text>
 </g>
 <!-- pkt_cls&#45;&gt;ip6_lookup -->
 <g id="edge4" class="edge">
 <title>pkt_cls&#45;&gt;ip6_lookup</title>
-<path fill="none" stroke="black" d="M239.99,-310.02C259.62,-296.33 289.35,-275.59 311.88,-259.87"/>
-<polygon fill="black" stroke="black" points="313.53,-262.29 319.73,-253.7 309.53,-256.55 313.53,-262.29"/>
-<text text-anchor="middle" x="304.23" y="-276.2" font-family="Times,serif" font-size="14.00">ipv6</text>
+<path fill="none" stroke="black" d="M157.52,-350.25C188.82,-343.6 234.51,-333.46 274,-323 313.2,-312.62 357.13,-299.22 389.79,-288.91"/>
+<polygon fill="black" stroke="black" points="391.08,-292.17 399.55,-285.81 388.96,-285.5 391.08,-292.17"/>
+<text text-anchor="middle" x="339.5" y="-311.8" font-family="Times,serif" font-size="14.00">ipv6</text>
 </g>
 <!-- ip4_lookup&#45;&gt;pkt_drop -->
 <g id="edge7" class="edge">
 <title>ip4_lookup&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M192.86,-221.12C179.2,-211.83 163.82,-198.49 156.23,-182 149.55,-167.46 150.78,-161.04 156.23,-146 176.39,-90.45 198.32,-78.19 252.23,-54 269.14,-46.41 288.24,-39.24 304.98,-33.38"/>
-<polygon fill="cyan" stroke="cyan" points="305.75,-36.48 314.07,-29.92 303.47,-29.86 305.75,-36.48"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M239.17,-254.03C232.31,-243.87 224.56,-230.37 221,-217 204.89,-156.57 227.58,-83.56 242.59,-45.31"/>
+<polygon fill="cyan" stroke="cyan" points="245.89,-46.5 246.4,-35.92 239.4,-43.87 245.89,-46.5"/>
 </g>
 <!-- ip4_rewrite -->
 <g id="node9" class="node">
 <title>ip4_rewrite</title>
-<ellipse fill="none" stroke="black" cx="218.23" cy="-164" rx="53.4" ry="18"/>
-<text text-anchor="middle" x="218.23" y="-158.95" font-family="Times,serif" font-size="14.00">ip4_rewrite</text>
+<ellipse fill="none" stroke="black" cx="294" cy="-199" rx="63.89" ry="18"/>
+<text text-anchor="middle" x="294" y="-195.3" font-family="Times,serif" font-size="14.00">ip4_rewrite</text>
 </g>
 <!-- ip4_lookup&#45;&gt;ip4_rewrite -->
 <g id="edge6" class="edge">
 <title>ip4_lookup&#45;&gt;ip4_rewrite</title>
-<path fill="none" stroke="black" d="M218.99,-218.81C218.88,-211.05 218.75,-201.68 218.63,-192.95"/>
-<polygon fill="black" stroke="black" points="222.11,-192.98 218.47,-183.03 215.11,-193.08 222.11,-192.98"/>
+<path fill="none" stroke="black" d="M261.95,-254.17C266.95,-245.72 273.12,-235.29 278.71,-225.85"/>
+<polygon fill="black" stroke="black" points="281.75,-227.59 283.83,-217.2 275.72,-224.02 281.75,-227.59"/>
+</g>
+<!-- ip4_local -->
+<g id="node11" class="node">
+<title>ip4_local</title>
+<ellipse fill="none" stroke="black" cx="136" cy="-145" rx="51.19" ry="18"/>
+<text text-anchor="middle" x="136" y="-141.3" font-family="Times,serif" font-size="14.00">ip4_local</text>
+</g>
+<!-- ip4_lookup&#45;&gt;ip4_local -->
+<g id="edge17" class="edge">
+<title>ip4_lookup&#45;&gt;ip4_local</title>
+<path fill="none" stroke="black" d="M218.11,-256.86C207.64,-251.39 196.61,-244.41 188,-236 169.45,-217.88 155.34,-191.74 146.53,-172.29"/>
+<polygon fill="black" stroke="black" points="149.72,-170.86 142.52,-163.08 143.3,-173.65 149.72,-170.86"/>
 </g>
 <!-- ip6_lookup&#45;&gt;pkt_drop -->
 <g id="edge11" class="edge">
 <title>ip6_lookup&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M369.2,-221.03C382.65,-211.71 397.78,-198.37 405.23,-182 426.87,-134.45 392.95,-75.95 369.19,-43.54"/>
-<polygon fill="cyan" stroke="cyan" points="371.64,-41.98 362.81,-36.13 366.06,-46.21 371.64,-41.98"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M470.57,-256.44C486.08,-247.46 503.27,-234.31 512,-217 519.2,-202.71 517.24,-196.12 512,-181 486.88,-108.48 466,-83.15 395,-54 367.69,-42.79 335.88,-34.51 309.39,-28.83"/>
+<polygon fill="cyan" stroke="cyan" points="310.02,-25.39 299.52,-26.78 308.6,-32.24 310.02,-25.39"/>
 </g>
 <!-- ip6_rewrite -->
 <g id="node10" class="node">
 <title>ip6_rewrite</title>
-<ellipse fill="none" stroke="black" cx="343.23" cy="-164" rx="53.4" ry="18"/>
-<text text-anchor="middle" x="343.23" y="-158.95" font-family="Times,serif" font-size="14.00">ip6_rewrite</text>
+<ellipse fill="none" stroke="black" cx="439" cy="-199" rx="63.89" ry="18"/>
+<text text-anchor="middle" x="439" y="-195.3" font-family="Times,serif" font-size="14.00">ip6_rewrite</text>
 </g>
 <!-- ip6_lookup&#45;&gt;ip6_rewrite -->
 <g id="edge10" class="edge">
 <title>ip6_lookup&#45;&gt;ip6_rewrite</title>
-<path fill="none" stroke="black" d="M343.23,-218.81C343.23,-211.05 343.23,-201.68 343.23,-192.95"/>
-<polygon fill="black" stroke="black" points="346.73,-193.03 343.23,-183.03 339.73,-193.03 346.73,-193.03"/>
+<path fill="none" stroke="black" d="M439,-253.81C439,-245.79 439,-236.05 439,-227.07"/>
+<polygon fill="black" stroke="black" points="442.5,-227.03 439,-217.03 435.5,-227.03 442.5,-227.03"/>
 </g>
 <!-- ip4_rewrite&#45;&gt;ethdev_tx -->
 <g id="edge8" class="edge">
 <title>ip4_rewrite&#45;&gt;ethdev_tx</title>
-<path fill="none" stroke="green" d="M235.63,-146.53C245.35,-137.33 257.64,-125.7 268.36,-115.54"/>
-<polygon fill="green" stroke="green" points="270.34,-118.55 275.19,-109.13 265.52,-113.47 270.34,-118.55"/>
+<path fill="none" stroke="green" d="M301.07,-180.97C308.09,-164.05 318.96,-137.86 327.09,-118.28"/>
+<polygon fill="green" stroke="green" points="330.35,-119.57 330.95,-108.99 323.88,-116.88 330.35,-119.57"/>
 </g>
 <!-- ip4_rewrite&#45;&gt;pkt_drop -->
 <g id="edge9" class="edge">
 <title>ip4_rewrite&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M217.56,-145.54C217.71,-125.89 220.78,-93.99 237.23,-73 253.17,-52.67 278.68,-39.55 301.33,-31.33"/>
-<polygon fill="cyan" stroke="cyan" points="302.14,-34.42 310.5,-27.9 299.9,-27.79 302.14,-34.42"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M289.85,-180.97C285.53,-163.07 278.61,-134.1 273,-109 268.3,-87.99 263.29,-64.16 259.59,-46.3"/>
+<polygon fill="cyan" stroke="cyan" points="262.97,-45.37 257.52,-36.28 256.11,-46.78 262.97,-45.37"/>
 </g>
 <!-- ip6_rewrite&#45;&gt;ethdev_tx -->
 <g id="edge12" class="edge">
 <title>ip6_rewrite&#45;&gt;ethdev_tx</title>
-<path fill="none" stroke="green" d="M331.38,-146.17C325.34,-137.6 317.87,-126.99 311.15,-117.44"/>
-<polygon fill="green" stroke="green" points="313.62,-115.87 305,-109.71 307.89,-119.9 313.62,-115.87"/>
+<path fill="none" stroke="green" d="M423.22,-181.44C406.47,-163.86 379.84,-135.91 360.81,-115.94"/>
+<polygon fill="green" stroke="green" points="363.1,-113.27 353.67,-108.45 358.03,-118.1 363.1,-113.27"/>
 </g>
 <!-- ip6_rewrite&#45;&gt;pkt_drop -->
 <g id="edge13" class="edge">
 <title>ip6_rewrite&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M345.67,-145.53C347.02,-134.98 348.56,-121.24 349.23,-109 350.38,-88.27 350.34,-64.81 350.03,-47.04"/>
-<polygon fill="cyan" stroke="cyan" points="353.51,-47.19 349.8,-37.27 346.51,-47.34 353.51,-47.19"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M438.77,-180.67C437.49,-154.09 431.22,-103.19 403,-73 379.35,-47.7 342.93,-34.22 312.02,-27.06"/>
+<polygon fill="cyan" stroke="cyan" points="312.71,-23.63 302.2,-24.95 311.24,-30.47 312.71,-23.63"/>
+</g>
+<!-- ip4_local&#45;&gt;pkt_drop -->
+<g id="edge18" class="edge">
+<title>ip4_local&#45;&gt;pkt_drop</title>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M142.47,-126.87C150.6,-107.23 166.18,-75.04 188,-54 195,-47.25 203.56,-41.45 212.16,-36.63"/>
+<polygon fill="cyan" stroke="cyan" points="213.85,-39.7 221.08,-31.95 210.6,-33.5 213.85,-39.7"/>
 </g>
 </g>
 </svg>
diff --git a/lib/node/ip4_local.c b/lib/node/ip4_local.c
new file mode 100644
index 0000000000..fb31d0f970
--- /dev/null
+++ b/lib/node/ip4_local.c
@@ -0,0 +1,88 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2023 Marvell International Ltd.
+ */
+
+#include <arpa/inet.h>
+#include <sys/socket.h>
+
+#include <rte_ethdev.h>
+#include <rte_ether.h>
+#include <rte_graph.h>
+#include <rte_graph_worker.h>
+#include <rte_ip.h>
+#include <rte_lpm.h>
+#include <rte_hash.h>
+#include <rte_fbk_hash.h>
+#include <rte_jhash.h>
+#include <rte_hash_crc.h>
+
+
+#include "rte_node_ip4_api.h"
+
+#include "node_private.h"
+
+static uint16_t
+ip4_local_node_process_scalar(struct rte_graph *graph, struct rte_node *node,
+			      void **objs, uint16_t nb_objs)
+{
+	void **to_next, **from;
+	uint16_t last_spec = 0;
+	rte_edge_t next_index;
+	struct rte_mbuf *mbuf;
+	uint16_t held = 0;
+	uint32_t l4;
+	int i;
+
+	/* Speculative next */
+	next_index = RTE_NODE_IP4_LOCAL_NEXT_UDP4_INPUT;
+
+	from = objs;
+	to_next = rte_node_next_stream_get(graph, node, next_index, nb_objs);
+	for (i = 0; i < nb_objs; i++) {
+		uint16_t next;
+
+		mbuf = (struct rte_mbuf *)objs[i];
+		l4 = mbuf->packet_type & RTE_PTYPE_L4_MASK;
+
+		next = (l4 == RTE_PTYPE_L4_UDP)
+				? next_index
+				: RTE_NODE_IP4_LOCAL_NEXT_PKT_DROP;
+
+		if (unlikely(next_index != next)) {
+			/* Copy things successfully speculated till now */
+			rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
+			from += last_spec;
+			to_next += last_spec;
+			held += last_spec;
+			last_spec = 0;
+
+			rte_node_enqueue_x1(graph, node, next, from[0]);
+			from += 1;
+		} else {
+			last_spec += 1;
+		}
+	}
+	/* !!! Home run !!! */
+	if (likely(last_spec == nb_objs)) {
+		rte_node_next_stream_move(graph, node, next_index);
+		return nb_objs;
+	}
+	held += last_spec;
+	rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
+	rte_node_next_stream_put(graph, node, next_index, held);
+
+	return nb_objs;
+}
+
+static struct rte_node_register ip4_local_node = {
+	.process = ip4_local_node_process_scalar,
+	.name = "ip4_local",
+
+	.nb_edges = RTE_NODE_IP4_LOCAL_NEXT_PKT_DROP + 1,
+	.next_nodes = {
+		[RTE_NODE_IP4_LOCAL_NEXT_UDP4_INPUT] = "udp4_input",
+		[RTE_NODE_IP4_LOCAL_NEXT_PKT_DROP] = "pkt_drop",
+	},
+};
+
+RTE_NODE_REGISTER(ip4_local_node);
diff --git a/lib/node/ip4_lookup.c b/lib/node/ip4_lookup.c
index 72fd760512..0dbfde64fe 100644
--- a/lib/node/ip4_lookup.c
+++ b/lib/node/ip4_lookup.c
@@ -227,6 +227,7 @@ static struct rte_node_register ip4_lookup_node = {
 
 	.nb_edges = RTE_NODE_IP4_LOOKUP_NEXT_PKT_DROP + 1,
 	.next_nodes = {
+		[RTE_NODE_IP4_LOOKUP_NEXT_IP4_LOCAL] = "ip4_local",
 		[RTE_NODE_IP4_LOOKUP_NEXT_REWRITE] = "ip4_rewrite",
 		[RTE_NODE_IP4_LOOKUP_NEXT_PKT_DROP] = "pkt_drop",
 	},
diff --git a/lib/node/meson.build b/lib/node/meson.build
index 2fa7c1c8f3..c0d5b09e2f 100644
--- a/lib/node/meson.build
+++ b/lib/node/meson.build
@@ -12,6 +12,7 @@ sources = files(
         'ethdev_rx.c',
         'ethdev_tx.c',
         'ip4_lookup.c',
+        'ip4_local.c',
         'ip4_rewrite.c',
         'ip6_lookup.c',
         'ip6_rewrite.c',
diff --git a/lib/node/rte_node_ip4_api.h b/lib/node/rte_node_ip4_api.h
index 0f997761b6..40af3860b5 100644
--- a/lib/node/rte_node_ip4_api.h
+++ b/lib/node/rte_node_ip4_api.h
@@ -28,10 +28,22 @@ extern "C" {
 enum rte_node_ip4_lookup_next {
 	RTE_NODE_IP4_LOOKUP_NEXT_REWRITE,
 	/**< Rewrite node. */
+	RTE_NODE_IP4_LOOKUP_NEXT_IP4_LOCAL,
+	/** IP Local node. */
 	RTE_NODE_IP4_LOOKUP_NEXT_PKT_DROP,
 	/**< Number of next nodes of lookup node. */
 };
 
+/**
+ * IP4 Local next nodes.
+ */
+enum rte_node_ip4_local_next {
+	RTE_NODE_IP4_LOCAL_NEXT_UDP4_INPUT,
+	/**< ip4 Local node. */
+	RTE_NODE_IP4_LOCAL_NEXT_PKT_DROP,
+	/**< Packet drop node. */
+};
+
 /**
  * Add ipv4 route to lookup table.
  *
-- 
2.25.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v6 2/2] node: add UDP v4 support
  2023-09-28 10:25         ` [PATCH v6 1/2] node: add IPv4 local node to handle local pkts Rakesh Kudurumalla
@ 2023-09-28 10:25           ` Rakesh Kudurumalla
  2023-09-29 10:58             ` Nithin Dabilpuram
  2023-09-29 10:54           ` [PATCH v6 1/2] node: add IPv4 local node to handle local pkts Nithin Dabilpuram
  1 sibling, 1 reply; 16+ messages in thread
From: Rakesh Kudurumalla @ 2023-09-28 10:25 UTC (permalink / raw)
  To: Jerin Jacob, Kiran Kumar K, Nithin Dabilpuram, Zhirun Yan,
	Pavan Nikhilesh
  Cc: dev, Rakesh Kudurumalla

IPv4 UDP packets are given to application
with specified UDP destination port given
by user.

Signed-off-by: Rakesh Kudurumalla <rkudurumalla@marvell.com>
---
 doc/api/doxy-api-index.md                     |   3 +-
 doc/guides/prog_guide/graph_lib.rst           |  25 ++
 .../img/graph_inbuilt_node_flow.svg           | 165 ++++++++-----
 lib/node/meson.build                          |   2 +
 lib/node/rte_node_udp4_input_api.h            |  61 +++++
 lib/node/udp4_input.c                         | 226 ++++++++++++++++++
 lib/node/version.map                          |   2 +
 7 files changed, 418 insertions(+), 66 deletions(-)
 create mode 100644 lib/node/rte_node_udp4_input_api.h
 create mode 100644 lib/node/udp4_input.c

diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index fdeda13932..96282d3fd0 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -206,7 +206,8 @@ The public API headers are grouped by topics:
   * graph_nodes:
     [eth_node](@ref rte_node_eth_api.h),
     [ip4_node](@ref rte_node_ip4_api.h),
-    [ip6_node](@ref rte_node_ip6_api.h)
+    [ip6_node](@ref rte_node_ip6_api.h),
+    [udp4_input_node](@ref rte_node_udp4_input_api.h)
 
 - **basic**:
   [bitops](@ref rte_bitops.h),
diff --git a/doc/guides/prog_guide/graph_lib.rst b/doc/guides/prog_guide/graph_lib.rst
index f2e04a68b9..3572560362 100644
--- a/doc/guides/prog_guide/graph_lib.rst
+++ b/doc/guides/prog_guide/graph_lib.rst
@@ -513,3 +513,28 @@ On packet_type lookup failure, objects are redirected to ``pkt_drop`` node.
 depth to receive to packets.
 To achieve home run, node use ``rte_node_stream_move()`` as mentioned in above
 sections.
+
+udp4_input
+~~~~~~~~~~
+This node is an intermediate node that does udp destination port lookup for
+the received ipv4 packets and the result determines each packets next node.
+
+User registers a new node ``udp4_input`` into graph library during initialization
+and attach user specified node as edege to this node using
+``rte_node_udp4_usr_node_add()``, and create empty hash table with destination
+port and node id as its feilds.
+
+After successful addition of user node as edege, edge id is returned to the user.
+
+User would register ``ip4_lookup`` table with specified ip address and 32 bit as mask
+for ip filtration using api ``rte_node_ip4_route_add()``.
+
+After graph is created user would update hash table with custom port with
+and previously obtained edge id using API ``rte_node_udp4_dst_port_add()``.
+
+When packet is received lpm look up is performed if ip is matched the packet
+is handed over to ip4_local node, then packet is verified for udp proto and
+on success packet is enqueued to ``udp4_input`` node.
+
+Hash lookup is performed in ``udp4_input`` node with registered destination port
+and destination port in UDP packet , on success packet is handed to ``udp_user_node``.
diff --git a/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg b/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg
index b954f6fba1..7c451371a7 100644
--- a/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg
+++ b/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg
@@ -39,192 +39,227 @@ digraph dpdk_inbuilt_nodes_flow {
     kernel_tx -> kernel_rx [color="red" style="dashed"]
     ip4_lookup -> ip4_local
     ip4_local -> pkt_drop [color="cyan" style="dashed"]
+    ip4_local -> udp4_input [ label="udpv4"]
+    udp4_input -> udp_user_node
+    udp4_input -> pkt_drop [color="cyan" style="dashed"]
+
 }
 
  -->
 <!-- input nodes -->
 <!-- Title: dpdk_inbuilt_nodes_flow Pages: 1 -->
-<svg width="525pt" height="458pt"
- viewBox="0.00 0.00 524.91 458.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 454)">
+<svg width="631pt" height="437pt"
+ viewBox="0.00 0.00 630.95 437.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 433)">
 <title>dpdk_inbuilt_nodes_flow</title>
-<polygon fill="white" stroke="transparent" points="-4,4 -4,-454 520.91,-454 520.91,4 -4,4"/>
+<polygon fill="white" stroke="transparent" points="-4,4 -4,-433 626.95,-433 626.95,4 -4,4"/>
 <!-- ethdev_rx -->
 <g id="node1" class="node">
 <title>ethdev_rx</title>
-<ellipse fill="none" stroke="green" cx="120" cy="-432" rx="56.59" ry="18"/>
-<text text-anchor="middle" x="120" y="-428.3" font-family="Times,serif" font-size="14.00">ethdev_rx</text>
+<ellipse fill="none" stroke="green" cx="261.95" cy="-411" rx="56.59" ry="18"/>
+<text text-anchor="middle" x="261.95" y="-407.3" font-family="Times,serif" font-size="14.00">ethdev_rx</text>
 </g>
 <!-- pkt_cls -->
 <g id="node6" class="node">
 <title>pkt_cls</title>
-<ellipse fill="none" stroke="red" cx="120" cy="-359" rx="42.79" ry="18"/>
-<text text-anchor="middle" x="120" y="-355.3" font-family="Times,serif" font-size="14.00">pkt_cls</text>
+<ellipse fill="none" stroke="red" cx="261.95" cy="-338" rx="42.79" ry="18"/>
+<text text-anchor="middle" x="261.95" y="-334.3" font-family="Times,serif" font-size="14.00">pkt_cls</text>
 </g>
 <!-- ethdev_rx&#45;&gt;pkt_cls -->
 <g id="edge1" class="edge">
 <title>ethdev_rx&#45;&gt;pkt_cls</title>
-<path fill="none" stroke="black" d="M120,-413.81C120,-405.79 120,-396.05 120,-387.07"/>
-<polygon fill="black" stroke="black" points="123.5,-387.03 120,-377.03 116.5,-387.03 123.5,-387.03"/>
+<path fill="none" stroke="black" d="M261.95,-392.81C261.95,-384.79 261.95,-375.05 261.95,-366.07"/>
+<polygon fill="black" stroke="black" points="265.45,-366.03 261.95,-356.03 258.45,-366.03 265.45,-366.03"/>
 </g>
 <!-- kernel_rx -->
 <g id="node2" class="node">
 <title>kernel_rx</title>
-<ellipse fill="none" stroke="green" cx="82" cy="-199" rx="53.89" ry="18"/>
-<text text-anchor="middle" x="82" y="-195.3" font-family="Times,serif" font-size="14.00">kernel_rx</text>
+<ellipse fill="none" stroke="green" cx="53.95" cy="-178" rx="53.89" ry="18"/>
+<text text-anchor="middle" x="53.95" y="-174.3" font-family="Times,serif" font-size="14.00">kernel_rx</text>
 </g>
 <!-- kernel_rx&#45;&gt;pkt_cls -->
 <g id="edge2" class="edge">
 <title>kernel_rx&#45;&gt;pkt_cls</title>
-<path fill="none" stroke="black" d="M70.87,-216.92C60.28,-235.27 47.29,-265.24 57,-290 64.12,-308.16 78.62,-324.37 91.92,-336.4"/>
-<polygon fill="black" stroke="black" points="89.69,-339.1 99.54,-342.99 94.26,-333.8 89.69,-339.1"/>
+<path fill="none" stroke="black" d="M74.75,-194.8C112.31,-223.33 191.45,-283.45 233.8,-315.62"/>
+<polygon fill="black" stroke="black" points="231.92,-318.59 242,-321.85 236.16,-313.01 231.92,-318.59"/>
 </g>
 <!-- ethdev_tx -->
 <g id="node3" class="node">
 <title>ethdev_tx</title>
-<ellipse fill="none" stroke="magenta" cx="338" cy="-91" rx="55.79" ry="18"/>
-<text text-anchor="middle" x="338" y="-87.3" font-family="Times,serif" font-size="14.00">ethdev_tx</text>
+<ellipse fill="none" stroke="magenta" cx="347.95" cy="-91" rx="55.79" ry="18"/>
+<text text-anchor="middle" x="347.95" y="-87.3" font-family="Times,serif" font-size="14.00">ethdev_tx</text>
 </g>
 <!-- pkt_drop -->
 <g id="node4" class="node">
 <title>pkt_drop</title>
-<ellipse fill="none" stroke="cyan" cx="254" cy="-18" rx="51.99" ry="18"/>
-<text text-anchor="middle" x="254" y="-14.3" font-family="Times,serif" font-size="14.00">pkt_drop</text>
+<ellipse fill="none" stroke="cyan" cx="404.95" cy="-18" rx="51.99" ry="18"/>
+<text text-anchor="middle" x="404.95" y="-14.3" font-family="Times,serif" font-size="14.00">pkt_drop</text>
 </g>
 <!-- ethdev_tx&#45;&gt;pkt_drop -->
 <g id="edge14" class="edge">
 <title>ethdev_tx&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M318.94,-73.89C307.58,-64.29 293,-51.96 280.53,-41.42"/>
-<polygon fill="cyan" stroke="cyan" points="282.59,-38.58 272.7,-34.8 278.07,-43.93 282.59,-38.58"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M361.45,-73.17C368.55,-64.33 377.39,-53.33 385.23,-43.55"/>
+<polygon fill="cyan" stroke="cyan" points="388,-45.69 391.53,-35.71 382.54,-41.31 388,-45.69"/>
 </g>
 <!-- kernel_tx -->
 <g id="node5" class="node">
 <title>kernel_tx</title>
-<ellipse fill="none" stroke="blue" cx="120" cy="-272" rx="53.89" ry="18"/>
-<text text-anchor="middle" x="120" y="-268.3" font-family="Times,serif" font-size="14.00">kernel_tx</text>
+<ellipse fill="none" stroke="blue" cx="53.95" cy="-251" rx="53.89" ry="18"/>
+<text text-anchor="middle" x="53.95" y="-247.3" font-family="Times,serif" font-size="14.00">kernel_tx</text>
 </g>
 <!-- kernel_tx&#45;&gt;kernel_rx -->
 <g id="edge16" class="edge">
 <title>kernel_tx&#45;&gt;kernel_rx</title>
-<path fill="none" stroke="red" stroke-dasharray="5,2" d="M110.99,-254.17C106.52,-245.81 101,-235.51 95.99,-226.14"/>
-<polygon fill="red" stroke="red" points="99.01,-224.36 91.2,-217.2 92.84,-227.67 99.01,-224.36"/>
+<path fill="none" stroke="red" stroke-dasharray="5,2" d="M53.95,-232.81C53.95,-224.79 53.95,-215.05 53.95,-206.07"/>
+<polygon fill="red" stroke="red" points="57.45,-206.03 53.95,-196.03 50.45,-206.03 57.45,-206.03"/>
 </g>
 <!-- pkt_cls&#45;&gt;pkt_drop -->
 <g id="edge15" class="edge">
 <title>pkt_cls&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M84,-348.97C48.65,-337.7 0,-314.61 0,-273 0,-273 0,-273 0,-90 0,-49.99 118.4,-31.52 193.52,-23.82"/>
-<polygon fill="cyan" stroke="cyan" points="194.21,-27.27 203.82,-22.81 193.52,-20.31 194.21,-27.27"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M304.77,-335.88C400.4,-332.2 622.95,-316.71 622.95,-252 622.95,-252 622.95,-252 622.95,-90 622.95,-56.33 527.72,-36.15 463.14,-26.34"/>
+<polygon fill="cyan" stroke="cyan" points="463.46,-22.85 453.06,-24.85 462.44,-29.77 463.46,-22.85"/>
 </g>
 <!-- pkt_cls&#45;&gt;kernel_tx -->
 <g id="edge5" class="edge">
 <title>pkt_cls&#45;&gt;kernel_tx</title>
-<path fill="none" stroke="blue" d="M120,-340.8C120,-329.16 120,-313.55 120,-300.24"/>
-<polygon fill="blue" stroke="blue" points="123.5,-300.18 120,-290.18 116.5,-300.18 123.5,-300.18"/>
-<text text-anchor="middle" x="172.5" y="-311.8" font-family="Times,serif" font-size="14.00">exception pkts</text>
+<path fill="none" stroke="blue" d="M219.14,-335.96C164.86,-333.64 75.77,-326.15 54.95,-302 49.6,-295.81 48.06,-287.4 48.24,-279.24"/>
+<polygon fill="blue" stroke="blue" points="51.73,-279.54 49.23,-269.24 44.76,-278.84 51.73,-279.54"/>
+<text text-anchor="middle" x="107.45" y="-290.8" font-family="Times,serif" font-size="14.00">exception pkts</text>
 </g>
 <!-- ip4_lookup -->
 <g id="node7" class="node">
 <title>ip4_lookup</title>
-<ellipse fill="none" stroke="black" cx="252" cy="-272" rx="60.39" ry="18"/>
-<text text-anchor="middle" x="252" y="-268.3" font-family="Times,serif" font-size="14.00">ip4_lookup</text>
+<ellipse fill="none" stroke="black" cx="261.95" cy="-251" rx="60.39" ry="18"/>
+<text text-anchor="middle" x="261.95" y="-247.3" font-family="Times,serif" font-size="14.00">ip4_lookup</text>
 </g>
 <!-- pkt_cls&#45;&gt;ip4_lookup -->
 <g id="edge3" class="edge">
 <title>pkt_cls&#45;&gt;ip4_lookup</title>
-<path fill="none" stroke="black" d="M160.54,-352.79C182.64,-348.15 209.23,-339.41 228,-323 235.09,-316.81 240.26,-308.05 243.95,-299.6"/>
-<polygon fill="black" stroke="black" points="247.32,-300.57 247.62,-289.98 240.78,-298.07 247.32,-300.57"/>
-<text text-anchor="middle" x="254.5" y="-311.8" font-family="Times,serif" font-size="14.00">ipv4</text>
+<path fill="none" stroke="black" d="M261.95,-319.8C261.95,-308.16 261.95,-292.55 261.95,-279.24"/>
+<polygon fill="black" stroke="black" points="265.45,-279.18 261.95,-269.18 258.45,-279.18 265.45,-279.18"/>
+<text text-anchor="middle" x="277.45" y="-290.8" font-family="Times,serif" font-size="14.00">ipv4</text>
 </g>
 <!-- ip6_lookup -->
 <g id="node8" class="node">
 <title>ip6_lookup</title>
-<ellipse fill="none" stroke="black" cx="439" cy="-272" rx="60.39" ry="18"/>
-<text text-anchor="middle" x="439" y="-268.3" font-family="Times,serif" font-size="14.00">ip6_lookup</text>
+<ellipse fill="none" stroke="black" cx="492.95" cy="-251" rx="60.39" ry="18"/>
+<text text-anchor="middle" x="492.95" y="-247.3" font-family="Times,serif" font-size="14.00">ip6_lookup</text>
 </g>
 <!-- pkt_cls&#45;&gt;ip6_lookup -->
 <g id="edge4" class="edge">
 <title>pkt_cls&#45;&gt;ip6_lookup</title>
-<path fill="none" stroke="black" d="M157.52,-350.25C188.82,-343.6 234.51,-333.46 274,-323 313.2,-312.62 357.13,-299.22 389.79,-288.91"/>
-<polygon fill="black" stroke="black" points="391.08,-292.17 399.55,-285.81 388.96,-285.5 391.08,-292.17"/>
-<text text-anchor="middle" x="339.5" y="-311.8" font-family="Times,serif" font-size="14.00">ipv6</text>
+<path fill="none" stroke="black" d="M293.1,-325.54C332.57,-311.01 400.93,-285.86 446.54,-269.07"/>
+<polygon fill="black" stroke="black" points="448.02,-272.26 456.2,-265.52 445.61,-265.69 448.02,-272.26"/>
+<text text-anchor="middle" x="407.45" y="-290.8" font-family="Times,serif" font-size="14.00">ipv6</text>
 </g>
 <!-- ip4_lookup&#45;&gt;pkt_drop -->
 <g id="edge7" class="edge">
 <title>ip4_lookup&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M239.17,-254.03C232.31,-243.87 224.56,-230.37 221,-217 204.89,-156.57 227.58,-83.56 242.59,-45.31"/>
-<polygon fill="cyan" stroke="cyan" points="245.89,-46.5 246.4,-35.92 239.4,-43.87 245.89,-46.5"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M258.85,-232.91C253.68,-198.83 247.1,-121.54 282.95,-73 299.1,-51.12 326.1,-37.95 350.6,-30.11"/>
+<polygon fill="cyan" stroke="cyan" points="351.6,-33.46 360.19,-27.26 349.61,-26.75 351.6,-33.46"/>
 </g>
 <!-- ip4_rewrite -->
 <g id="node9" class="node">
 <title>ip4_rewrite</title>
-<ellipse fill="none" stroke="black" cx="294" cy="-199" rx="63.89" ry="18"/>
-<text text-anchor="middle" x="294" y="-195.3" font-family="Times,serif" font-size="14.00">ip4_rewrite</text>
+<ellipse fill="none" stroke="black" cx="347.95" cy="-178" rx="63.89" ry="18"/>
+<text text-anchor="middle" x="347.95" y="-174.3" font-family="Times,serif" font-size="14.00">ip4_rewrite</text>
 </g>
 <!-- ip4_lookup&#45;&gt;ip4_rewrite -->
 <g id="edge6" class="edge">
 <title>ip4_lookup&#45;&gt;ip4_rewrite</title>
-<path fill="none" stroke="black" d="M261.95,-254.17C266.95,-245.72 273.12,-235.29 278.71,-225.85"/>
-<polygon fill="black" stroke="black" points="281.75,-227.59 283.83,-217.2 275.72,-224.02 281.75,-227.59"/>
+<path fill="none" stroke="black" d="M281.46,-233.89C292.92,-224.42 307.6,-212.31 320.25,-201.87"/>
+<polygon fill="black" stroke="black" points="322.73,-204.36 328.21,-195.29 318.27,-198.96 322.73,-204.36"/>
 </g>
 <!-- ip4_local -->
 <g id="node11" class="node">
 <title>ip4_local</title>
-<ellipse fill="none" stroke="black" cx="136" cy="-145" rx="51.19" ry="18"/>
-<text text-anchor="middle" x="136" y="-141.3" font-family="Times,serif" font-size="14.00">ip4_local</text>
+<ellipse fill="none" stroke="black" cx="176.95" cy="-178" rx="51.19" ry="18"/>
+<text text-anchor="middle" x="176.95" y="-174.3" font-family="Times,serif" font-size="14.00">ip4_local</text>
 </g>
 <!-- ip4_lookup&#45;&gt;ip4_local -->
 <g id="edge17" class="edge">
 <title>ip4_lookup&#45;&gt;ip4_local</title>
-<path fill="none" stroke="black" d="M218.11,-256.86C207.64,-251.39 196.61,-244.41 188,-236 169.45,-217.88 155.34,-191.74 146.53,-172.29"/>
-<polygon fill="black" stroke="black" points="149.72,-170.86 142.52,-163.08 143.3,-173.65 149.72,-170.86"/>
+<path fill="none" stroke="black" d="M242.66,-233.89C231.17,-224.29 216.41,-211.96 203.79,-201.42"/>
+<polygon fill="black" stroke="black" points="205.78,-198.53 195.86,-194.8 201.29,-203.9 205.78,-198.53"/>
 </g>
 <!-- ip6_lookup&#45;&gt;pkt_drop -->
 <g id="edge11" class="edge">
 <title>ip6_lookup&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M470.57,-256.44C486.08,-247.46 503.27,-234.31 512,-217 519.2,-202.71 517.24,-196.12 512,-181 486.88,-108.48 466,-83.15 395,-54 367.69,-42.79 335.88,-34.51 309.39,-28.83"/>
-<polygon fill="cyan" stroke="cyan" points="310.02,-25.39 299.52,-26.78 308.6,-32.24 310.02,-25.39"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M524.51,-235.44C540.02,-226.46 557.22,-213.31 565.95,-196 573.15,-181.71 572.55,-174.57 565.95,-160 540.59,-104.08 480.88,-61.6 441.74,-38.51"/>
+<polygon fill="cyan" stroke="cyan" points="443.16,-35.29 432.75,-33.34 439.67,-41.36 443.16,-35.29"/>
 </g>
 <!-- ip6_rewrite -->
 <g id="node10" class="node">
 <title>ip6_rewrite</title>
-<ellipse fill="none" stroke="black" cx="439" cy="-199" rx="63.89" ry="18"/>
-<text text-anchor="middle" x="439" y="-195.3" font-family="Times,serif" font-size="14.00">ip6_rewrite</text>
+<ellipse fill="none" stroke="black" cx="492.95" cy="-178" rx="63.89" ry="18"/>
+<text text-anchor="middle" x="492.95" y="-174.3" font-family="Times,serif" font-size="14.00">ip6_rewrite</text>
 </g>
 <!-- ip6_lookup&#45;&gt;ip6_rewrite -->
 <g id="edge10" class="edge">
 <title>ip6_lookup&#45;&gt;ip6_rewrite</title>
-<path fill="none" stroke="black" d="M439,-253.81C439,-245.79 439,-236.05 439,-227.07"/>
-<polygon fill="black" stroke="black" points="442.5,-227.03 439,-217.03 435.5,-227.03 442.5,-227.03"/>
+<path fill="none" stroke="black" d="M492.95,-232.81C492.95,-224.79 492.95,-215.05 492.95,-206.07"/>
+<polygon fill="black" stroke="black" points="496.45,-206.03 492.95,-196.03 489.45,-206.03 496.45,-206.03"/>
 </g>
 <!-- ip4_rewrite&#45;&gt;ethdev_tx -->
 <g id="edge8" class="edge">
 <title>ip4_rewrite&#45;&gt;ethdev_tx</title>
-<path fill="none" stroke="green" d="M301.07,-180.97C308.09,-164.05 318.96,-137.86 327.09,-118.28"/>
-<polygon fill="green" stroke="green" points="330.35,-119.57 330.95,-108.99 323.88,-116.88 330.35,-119.57"/>
+<path fill="none" stroke="green" d="M347.95,-159.8C347.95,-148.16 347.95,-132.55 347.95,-119.24"/>
+<polygon fill="green" stroke="green" points="351.45,-119.18 347.95,-109.18 344.45,-119.18 351.45,-119.18"/>
 </g>
 <!-- ip4_rewrite&#45;&gt;pkt_drop -->
 <g id="edge9" class="edge">
 <title>ip4_rewrite&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M289.85,-180.97C285.53,-163.07 278.61,-134.1 273,-109 268.3,-87.99 263.29,-64.16 259.59,-46.3"/>
-<polygon fill="cyan" stroke="cyan" points="262.97,-45.37 257.52,-36.28 256.11,-46.78 262.97,-45.37"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M370.32,-161.1C385.53,-148.83 404.37,-130.37 412.95,-109 421.04,-88.82 418.02,-64.12 413.56,-45.7"/>
+<polygon fill="cyan" stroke="cyan" points="416.9,-44.66 410.91,-35.93 410.15,-46.49 416.9,-44.66"/>
 </g>
 <!-- ip6_rewrite&#45;&gt;ethdev_tx -->
 <g id="edge12" class="edge">
 <title>ip6_rewrite&#45;&gt;ethdev_tx</title>
-<path fill="none" stroke="green" d="M423.22,-181.44C406.47,-163.86 379.84,-135.91 360.81,-115.94"/>
-<polygon fill="green" stroke="green" points="363.1,-113.27 353.67,-108.45 358.03,-118.1 363.1,-113.27"/>
+<path fill="none" stroke="green" d="M466.35,-161.41C442.8,-147.6 408.27,-127.36 382.57,-112.3"/>
+<polygon fill="green" stroke="green" points="384.28,-109.24 373.88,-107.21 380.74,-115.28 384.28,-109.24"/>
 </g>
 <!-- ip6_rewrite&#45;&gt;pkt_drop -->
 <g id="edge13" class="edge">
 <title>ip6_rewrite&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M438.77,-180.67C437.49,-154.09 431.22,-103.19 403,-73 379.35,-47.7 342.93,-34.22 312.02,-27.06"/>
-<polygon fill="cyan" stroke="cyan" points="312.71,-23.63 302.2,-24.95 311.24,-30.47 312.71,-23.63"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M485.15,-159.86C473.93,-135.7 452.15,-90.48 429.95,-54 427.97,-50.75 425.78,-47.4 423.55,-44.13"/>
+<polygon fill="cyan" stroke="cyan" points="426.28,-41.92 417.67,-35.75 420.55,-45.94 426.28,-41.92"/>
 </g>
 <!-- ip4_local&#45;&gt;pkt_drop -->
 <g id="edge18" class="edge">
 <title>ip4_local&#45;&gt;pkt_drop</title>
-<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M142.47,-126.87C150.6,-107.23 166.18,-75.04 188,-54 195,-47.25 203.56,-41.45 212.16,-36.63"/>
-<polygon fill="cyan" stroke="cyan" points="213.85,-39.7 221.08,-31.95 210.6,-33.5 213.85,-39.7"/>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M191.02,-160.51C195.47,-154.86 200.21,-148.35 203.95,-142 225.57,-105.29 209.02,-81.03 241.95,-54 257.83,-40.96 306.22,-31.62 346.19,-25.89"/>
+<polygon fill="cyan" stroke="cyan" points="346.72,-29.35 356.14,-24.51 345.75,-22.41 346.72,-29.35"/>
+</g>
+<!-- udp4_input -->
+<g id="node12" class="node">
+<title>udp4_input</title>
+<ellipse fill="none" stroke="black" cx="126.95" cy="-91" rx="63.09" ry="18"/>
+<text text-anchor="middle" x="126.95" y="-87.3" font-family="Times,serif" font-size="14.00">udp4_input</text>
+</g>
+<!-- ip4_local&#45;&gt;udp4_input -->
+<g id="edge19" class="edge">
+<title>ip4_local&#45;&gt;udp4_input</title>
+<path fill="none" stroke="black" d="M167.07,-160.21C159.99,-148.18 150.33,-131.75 142.26,-118.03"/>
+<polygon fill="black" stroke="black" points="145.06,-115.89 136.97,-109.05 139.03,-119.44 145.06,-115.89"/>
+<text text-anchor="middle" x="177.45" y="-130.8" font-family="Times,serif" font-size="14.00">udpv4</text>
+</g>
+<!-- udp4_input&#45;&gt;pkt_drop -->
+<g id="edge21" class="edge">
+<title>udp4_input&#45;&gt;pkt_drop</title>
+<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M154.75,-74.82C169.08,-67.56 187.05,-59.32 203.95,-54 250.51,-39.35 305.19,-30.33 345.76,-25.12"/>
+<polygon fill="cyan" stroke="cyan" points="346.26,-28.59 355.75,-23.88 345.4,-21.64 346.26,-28.59"/>
+</g>
+<!-- udp_user_node -->
+<g id="node13" class="node">
+<title>udp_user_node</title>
+<ellipse fill="none" stroke="black" cx="126.95" cy="-18" rx="79.89" ry="18"/>
+<text text-anchor="middle" x="126.95" y="-14.3" font-family="Times,serif" font-size="14.00">udp_user_node</text>
+</g>
+<!-- udp4_input&#45;&gt;udp_user_node -->
+<g id="edge20" class="edge">
+<title>udp4_input&#45;&gt;udp_user_node</title>
+<path fill="none" stroke="black" d="M126.95,-72.81C126.95,-64.79 126.95,-55.05 126.95,-46.07"/>
+<polygon fill="black" stroke="black" points="130.45,-46.03 126.95,-36.03 123.45,-46.03 130.45,-46.03"/>
 </g>
 </g>
 </svg>
diff --git a/lib/node/meson.build b/lib/node/meson.build
index c0d5b09e2f..c5b8ee656e 100644
--- a/lib/node/meson.build
+++ b/lib/node/meson.build
@@ -22,11 +22,13 @@ sources = files(
         'null.c',
         'pkt_cls.c',
         'pkt_drop.c',
+        'udp4_input.c',
 )
 headers = files(
         'rte_node_eth_api.h',
         'rte_node_ip4_api.h',
         'rte_node_ip6_api.h',
+        'rte_node_udp4_input_api.h',
 )
 
 # Strict-aliasing rules are violated by uint8_t[] to context size casts.
diff --git a/lib/node/rte_node_udp4_input_api.h b/lib/node/rte_node_udp4_input_api.h
new file mode 100644
index 0000000000..c873acbbe0
--- /dev/null
+++ b/lib/node/rte_node_udp4_input_api.h
@@ -0,0 +1,61 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2023 Marvell International Ltd.
+ */
+
+#ifndef __INCLUDE_RTE_NODE_UDP4_INPUT_API_H__
+#define __INCLUDE_RTE_NODE_UDP4_INPUT_API_H__
+
+/**
+ * @file rte_node_udp4_input_api.h
+ *
+ * @warning
+ * @b EXPERIMENTAL:
+ * All functions in this file may be changed or removed without prior notice.
+ *
+ * This API allows to control path functions of udp4_* nodes
+ * like udp4_input.
+ *
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rte_common.h>
+#include <rte_compat.h>
+
+#include "rte_graph.h"
+/**
+ * UDP4 lookup next nodes.
+ */
+enum rte_node_udp4_input_next {
+	RTE_NODE_UDP4_INPUT_NEXT_PKT_DROP,
+	/**< Packet drop node. */
+};
+
+/**
+ * Add usr node to receive udp4 frames.
+ *
+ * @param usr_node
+ * Node registered by user to receive data.
+ */
+__rte_experimental
+int rte_node_udp4_usr_node_add(const char *usr_node);
+
+/**
+ * Add udpv4 dst_port to lookup table.
+ *
+ * @param dst_port
+ *   Dst Port of packet to be added for consumption.
+ * @param next_node
+ *   Next node packet to be added for consumption.
+ * @return
+ *   0 on success, negative otherwise.
+ */
+__rte_experimental
+int rte_node_udp4_dst_port_add(uint32_t dst_port, rte_edge_t next_node);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __INCLUDE_RTE_NODE_UDP4_API_H__ */
diff --git a/lib/node/udp4_input.c b/lib/node/udp4_input.c
new file mode 100644
index 0000000000..80cedce548
--- /dev/null
+++ b/lib/node/udp4_input.c
@@ -0,0 +1,226 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2023 Marvell International Ltd.
+ */
+
+#include <arpa/inet.h>
+#include <sys/socket.h>
+
+#include <rte_ethdev.h>
+#include <rte_ether.h>
+#include <rte_graph.h>
+#include <rte_graph_worker.h>
+#include <rte_ip.h>
+#include <rte_lpm.h>
+#include <rte_hash.h>
+#include <rte_fbk_hash.h>
+#include <rte_jhash.h>
+#include <rte_hash_crc.h>
+
+
+#include "rte_node_udp4_input_api.h"
+
+#include "node_private.h"
+
+#define UDP4_INPUT_HASH_TBL_SIZE 1024
+
+#define UDP4_INPUT_NODE_HASH(ctx) \
+	(((struct udp4_input_node_ctx *)ctx)->hash)
+
+#define UDP4_INPUT_NODE_NEXT_INDEX(ctx) \
+	(((struct udp4_input_node_ctx *)ctx)->next_index)
+
+
+/* UDP4 input  global data struct */
+struct udp4_input_node_main {
+	struct rte_hash *hash_tbl[RTE_MAX_NUMA_NODES];
+};
+
+static struct udp4_input_node_main udp4_input_nm;
+
+struct udp4_input_node_ctx {
+	/* Socket's Hash table */
+	struct rte_hash *hash;
+	/* Cached next index */
+	uint16_t next_index;
+};
+
+struct flow_key {
+	uint32_t prt_dst;
+};
+
+static struct rte_hash_parameters udp4_params = {
+	.entries = UDP4_INPUT_HASH_TBL_SIZE,
+	.key_len = sizeof(uint32_t),
+	.hash_func = rte_jhash,
+	.hash_func_init_val = 0,
+	.socket_id = 0,
+};
+
+int
+rte_node_udp4_dst_port_add(uint32_t dst_port, rte_edge_t next_node)
+{
+	uint8_t socket;
+	int rc;
+
+	for (socket = 0; socket < RTE_MAX_NUMA_NODES; socket++) {
+		if (!udp4_input_nm.hash_tbl[socket])
+			continue;
+
+		rc = rte_hash_add_key_data(udp4_input_nm.hash_tbl[socket],
+					   &dst_port, (void *)(uintptr_t)next_node);
+		if (rc < 0) {
+			node_err("udp4_lookup", "Failed to add key for sock %u, rc=%d",
+					socket, rc);
+			return rc;
+		}
+	}
+	return 0;
+}
+
+int
+rte_node_udp4_usr_node_add(const char *usr_node)
+{
+	const char *next_nodes = usr_node;
+	rte_node_t udp4_input_node_id, count;
+
+	udp4_input_node_id = rte_node_from_name("udp4_input");
+	count = rte_node_edge_update(udp4_input_node_id, RTE_EDGE_ID_INVALID,
+				     &next_nodes, 1);
+	if (count == 0) {
+		node_dbg("udp4_input", "Adding usr node as edge to udp4_input failed");
+		return count;
+	}
+	count = rte_node_edge_count(udp4_input_node_id) - 1;
+	return count;
+}
+
+static int
+setup_udp4_dstprt_hash(struct udp4_input_node_main *nm, int socket)
+{
+	struct rte_hash_parameters *hash_udp4 = &udp4_params;
+	char s[RTE_HASH_NAMESIZE];
+
+	/* One Hash table per socket */
+	if (nm->hash_tbl[socket])
+		return 0;
+
+	/* create Hash table */
+	snprintf(s, sizeof(s), "UDP4_INPUT_HASH_%d", socket);
+	hash_udp4->name = s;
+	hash_udp4->socket_id = socket;
+	nm->hash_tbl[socket] = rte_hash_create(hash_udp4);
+	if (nm->hash_tbl[socket] == NULL)
+		return -rte_errno;
+
+	return 0;
+}
+
+static int
+udp4_input_node_init(const struct rte_graph *graph, struct rte_node *node)
+{
+	uint16_t socket, lcore_id;
+	static uint8_t init_once;
+	int rc;
+
+	RTE_SET_USED(graph);
+	RTE_BUILD_BUG_ON(sizeof(struct udp4_input_node_ctx) > RTE_NODE_CTX_SZ);
+
+	if (!init_once) {
+
+		/* Setup HASH tables for all sockets */
+		RTE_LCORE_FOREACH(lcore_id)
+		{
+			socket = rte_lcore_to_socket_id(lcore_id);
+			rc = setup_udp4_dstprt_hash(&udp4_input_nm, socket);
+			if (rc) {
+				node_err("udp4_lookup",
+						"Failed to setup hash tbl for sock %u, rc=%d",
+						socket, rc);
+				return rc;
+			}
+		}
+		init_once = 1;
+	}
+
+	UDP4_INPUT_NODE_HASH(node->ctx) = udp4_input_nm.hash_tbl[graph->socket];
+
+	node_dbg("udp4_input", "Initialized udp4_input node");
+	return 0;
+}
+
+static uint16_t
+udp4_input_node_process_scalar(struct rte_graph *graph, struct rte_node *node,
+			       void **objs, uint16_t nb_objs)
+{
+	struct rte_hash *hash_tbl_handle = UDP4_INPUT_NODE_HASH(node->ctx);
+	rte_edge_t next_index, udplookup_node;
+	struct rte_udp_hdr *pkt_udp_hdr;
+	uint16_t last_spec = 0;
+	void **to_next, **from;
+	struct rte_mbuf *mbuf;
+	uint16_t held = 0;
+	uint16_t next = 0;
+	int i, rc;
+
+	/* Speculative next */
+	next_index = UDP4_INPUT_NODE_NEXT_INDEX(node->ctx);
+
+	from = objs;
+
+	to_next = rte_node_next_stream_get(graph, node, next_index, nb_objs);
+	for (i = 0; i < nb_objs; i++) {
+		struct flow_key key_port;
+
+		mbuf = (struct rte_mbuf *)objs[i];
+		pkt_udp_hdr = rte_pktmbuf_mtod_offset(mbuf, struct rte_udp_hdr *,
+						sizeof(struct rte_ether_hdr) +
+						sizeof(struct rte_ipv4_hdr));
+
+		key_port.prt_dst = rte_cpu_to_be_16(pkt_udp_hdr->dst_port);
+		rc = rte_hash_lookup_data(hash_tbl_handle,
+					  &key_port.prt_dst,
+					  (void **)&udplookup_node);
+		next = (rc < 0) ? RTE_NODE_UDP4_INPUT_NEXT_PKT_DROP
+				    : udplookup_node;
+
+		if (unlikely(next_index != next)) {
+			/* Copy things successfully speculated till now */
+			rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
+			from += last_spec;
+			to_next += last_spec;
+			held += last_spec;
+			last_spec = 0;
+
+			rte_node_enqueue_x1(graph, node, next, from[0]);
+			from += 1;
+		} else {
+			last_spec += 1;
+		}
+	}
+	/* !!! Home run !!! */
+	if (likely(last_spec == nb_objs)) {
+		rte_node_next_stream_move(graph, node, next_index);
+		return nb_objs;
+	}
+	held += last_spec;
+	rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
+	rte_node_next_stream_put(graph, node, next_index, held);
+	/* Save the last next used */
+	UDP4_INPUT_NODE_NEXT_INDEX(node->ctx) = next;
+
+	return nb_objs;
+}
+
+static struct rte_node_register udp4_input_node = {
+	.process = udp4_input_node_process_scalar,
+	.name = "udp4_input",
+
+	.init = udp4_input_node_init,
+
+	.nb_edges = RTE_NODE_UDP4_INPUT_NEXT_PKT_DROP + 1,
+	.next_nodes = {
+		[RTE_NODE_UDP4_INPUT_NEXT_PKT_DROP] = "pkt_drop",
+	},
+};
+
+RTE_NODE_REGISTER(udp4_input_node);
diff --git a/lib/node/version.map b/lib/node/version.map
index 40df308bfe..c51befce09 100644
--- a/lib/node/version.map
+++ b/lib/node/version.map
@@ -6,6 +6,8 @@ EXPERIMENTAL {
 	rte_node_ip4_rewrite_add;
 	rte_node_ip6_rewrite_add;
 	rte_node_ip6_route_add;
+	rte_node_udp4_usr_node_add;
+	rte_node_udp4_dst_port_add;
 	rte_node_logtype;
 	local: *;
 };
-- 
2.25.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v6 1/2] node: add IPv4 local node to handle local pkts
  2023-09-28 10:25         ` [PATCH v6 1/2] node: add IPv4 local node to handle local pkts Rakesh Kudurumalla
  2023-09-28 10:25           ` [PATCH v6 2/2] node: add UDP v4 support Rakesh Kudurumalla
@ 2023-09-29 10:54           ` Nithin Dabilpuram
  2023-09-29 10:58             ` Nithin Dabilpuram
  1 sibling, 1 reply; 16+ messages in thread
From: Nithin Dabilpuram @ 2023-09-29 10:54 UTC (permalink / raw)
  To: Rakesh Kudurumalla
  Cc: Jerin Jacob, Kiran Kumar K, Nithin Dabilpuram, Zhirun Yan,
	Pavan Nikhilesh, dev

Series-acked-by: Nithin Dabilpuram <ndabilpuram@marvell.com>


On Fri, Sep 29, 2023 at 1:21 AM Rakesh Kudurumalla
<rkudurumalla@marvell.com> wrote:
>
> Local or Host destined pkts can be redirected IPv4 local node
> using IP4 Lookup node entries with prefix of 32 and be redirected
> to this IP4 local node for further processing.
>
> Signed-off-by: Rakesh Kudurumalla <rkudurumalla@marvell.com>
> ---
> Depends-on: series-29670 ("remove MAX macro from all nodes")
>
> v6: Resolve dependency
>
>  doc/guides/prog_guide/graph_lib.rst           |  15 ++
>  .../img/graph_inbuilt_node_flow.svg           | 138 ++++++++++--------
>  lib/node/ip4_local.c                          |  88 +++++++++++
>  lib/node/ip4_lookup.c                         |   1 +
>  lib/node/meson.build                          |   1 +
>  lib/node/rte_node_ip4_api.h                   |  12 ++
>  6 files changed, 196 insertions(+), 59 deletions(-)
>  create mode 100644 lib/node/ip4_local.c
>
> diff --git a/doc/guides/prog_guide/graph_lib.rst b/doc/guides/prog_guide/graph_lib.rst
> index e7b6e12004..f2e04a68b9 100644
> --- a/doc/guides/prog_guide/graph_lib.rst
> +++ b/doc/guides/prog_guide/graph_lib.rst
> @@ -498,3 +498,18 @@ Uses ``poll`` function to poll on the socket fd
>  for ``POLLIN`` events to read the packets from raw socket
>  to stream buffer and does ``rte_node_next_stream_move()``
>  when there are received packets.
> +
> +ip4_local
> +~~~~~~~~~
> +This node is an intermediate node that does ``packet_type`` lookup for
> +the received ipv4 packets and the result determines each packets next node.
> +
> +On successful ``packet_type`` lookup, for any IPv4 protocol the result
> +contains the ``next_node`` id and ``next-hop`` id with which the packet
> +needs to be further processed.
> +
> +On packet_type lookup failure, objects are redirected to ``pkt_drop`` node.
> +``rte_node_ip4_route_add()`` is control path API to add ipv4 address with 32 bit
> +depth to receive to packets.
> +To achieve home run, node use ``rte_node_stream_move()`` as mentioned in above
> +sections.
> diff --git a/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg b/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg
> index 7eea94701f..b954f6fba1 100644
> --- a/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg
> +++ b/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg
> @@ -37,174 +37,194 @@ digraph dpdk_inbuilt_nodes_flow {
>      ethdev_tx -> pkt_drop [color="cyan" style="dashed"]
>      pkt_cls->pkt_drop   [color="cyan" style="dashed"]
>      kernel_tx -> kernel_rx [color="red" style="dashed"]
> +    ip4_lookup -> ip4_local
> +    ip4_local -> pkt_drop [color="cyan" style="dashed"]
>  }
>
>   -->
>  <!-- input nodes -->
>  <!-- Title: dpdk_inbuilt_nodes_flow Pages: 1 -->
> -<svg width="470pt" height="425pt"
> - viewBox="0.00 0.00 470.23 424.50" 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 420.5)">
> +<svg width="525pt" height="458pt"
> + viewBox="0.00 0.00 524.91 458.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 454)">
>  <title>dpdk_inbuilt_nodes_flow</title>
> -<polygon fill="white" stroke="none" points="-4,4 -4,-420.5 466.23,-420.5 466.23,4 -4,4"/>
> +<polygon fill="white" stroke="transparent" points="-4,4 -4,-454 520.91,-454 520.91,4 -4,4"/>
>  <!-- ethdev_rx -->
>  <g id="node1" class="node">
>  <title>ethdev_rx</title>
> -<ellipse fill="none" stroke="green" cx="219.23" cy="-398.5" rx="47.77" ry="18"/>
> -<text text-anchor="middle" x="219.23" y="-393.45" font-family="Times,serif" font-size="14.00">ethdev_rx</text>
> +<ellipse fill="none" stroke="green" cx="120" cy="-432" rx="56.59" ry="18"/>
> +<text text-anchor="middle" x="120" y="-428.3" font-family="Times,serif" font-size="14.00">ethdev_rx</text>
>  </g>
>  <!-- pkt_cls -->
>  <g id="node6" class="node">
>  <title>pkt_cls</title>
> -<ellipse fill="none" stroke="red" cx="219.23" cy="-325.5" rx="37.53" ry="18"/>
> -<text text-anchor="middle" x="219.23" y="-320.45" font-family="Times,serif" font-size="14.00">pkt_cls</text>
> +<ellipse fill="none" stroke="red" cx="120" cy="-359" rx="42.79" ry="18"/>
> +<text text-anchor="middle" x="120" y="-355.3" font-family="Times,serif" font-size="14.00">pkt_cls</text>
>  </g>
>  <!-- ethdev_rx&#45;&gt;pkt_cls -->
>  <g id="edge1" class="edge">
>  <title>ethdev_rx&#45;&gt;pkt_cls</title>
> -<path fill="none" stroke="black" d="M219.23,-380.31C219.23,-372.55 219.23,-363.18 219.23,-354.45"/>
> -<polygon fill="black" stroke="black" points="222.73,-354.53 219.23,-344.53 215.73,-354.53 222.73,-354.53"/>
> +<path fill="none" stroke="black" d="M120,-413.81C120,-405.79 120,-396.05 120,-387.07"/>
> +<polygon fill="black" stroke="black" points="123.5,-387.03 120,-377.03 116.5,-387.03 123.5,-387.03"/>
>  </g>
>  <!-- kernel_rx -->
>  <g id="node2" class="node">
>  <title>kernel_rx</title>
> -<ellipse fill="none" stroke="green" cx="46.23" cy="-164" rx="46.23" ry="18"/>
> -<text text-anchor="middle" x="46.23" y="-158.95" font-family="Times,serif" font-size="14.00">kernel_rx</text>
> +<ellipse fill="none" stroke="green" cx="82" cy="-199" rx="53.89" ry="18"/>
> +<text text-anchor="middle" x="82" y="-195.3" font-family="Times,serif" font-size="14.00">kernel_rx</text>
>  </g>
>  <!-- kernel_rx&#45;&gt;pkt_cls -->
>  <g id="edge2" class="edge">
>  <title>kernel_rx&#45;&gt;pkt_cls</title>
> -<path fill="none" stroke="black" d="M41.45,-182.08C37.1,-201.37 33.27,-232.96 47.23,-255 73.68,-296.74 130.21,-313.41 171.26,-320.07"/>
> -<polygon fill="black" stroke="black" points="170.73,-323.68 181.13,-321.66 171.74,-316.75 170.73,-323.68"/>
> +<path fill="none" stroke="black" d="M70.87,-216.92C60.28,-235.27 47.29,-265.24 57,-290 64.12,-308.16 78.62,-324.37 91.92,-336.4"/>
> +<polygon fill="black" stroke="black" points="89.69,-339.1 99.54,-342.99 94.26,-333.8 89.69,-339.1"/>
>  </g>
>  <!-- ethdev_tx -->
>  <g id="node3" class="node">
>  <title>ethdev_tx</title>
> -<ellipse fill="none" stroke="magenta" cx="293.23" cy="-91" rx="47.26" ry="18"/>
> -<text text-anchor="middle" x="293.23" y="-85.95" font-family="Times,serif" font-size="14.00">ethdev_tx</text>
> +<ellipse fill="none" stroke="magenta" cx="338" cy="-91" rx="55.79" ry="18"/>
> +<text text-anchor="middle" x="338" y="-87.3" font-family="Times,serif" font-size="14.00">ethdev_tx</text>
>  </g>
>  <!-- pkt_drop -->
>  <g id="node4" class="node">
>  <title>pkt_drop</title>
> -<ellipse fill="none" stroke="cyan" cx="349.23" cy="-18" rx="44.19" ry="18"/>
> -<text text-anchor="middle" x="349.23" y="-12.95" font-family="Times,serif" font-size="14.00">pkt_drop</text>
> +<ellipse fill="none" stroke="cyan" cx="254" cy="-18" rx="51.99" ry="18"/>
> +<text text-anchor="middle" x="254" y="-14.3" font-family="Times,serif" font-size="14.00">pkt_drop</text>
>  </g>
>  <!-- ethdev_tx&#45;&gt;pkt_drop -->
>  <g id="edge14" class="edge">
>  <title>ethdev_tx&#45;&gt;pkt_drop</title>
> -<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M306.22,-73.53C313.15,-64.75 321.81,-53.76 329.55,-43.96"/>
> -<polygon fill="cyan" stroke="cyan" points="332.87,-46.4 336.32,-36.38 327.37,-42.06 332.87,-46.4"/>
> +<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M318.94,-73.89C307.58,-64.29 293,-51.96 280.53,-41.42"/>
> +<polygon fill="cyan" stroke="cyan" points="282.59,-38.58 272.7,-34.8 278.07,-43.93 282.59,-38.58"/>
>  </g>
>  <!-- kernel_tx -->
>  <g id="node5" class="node">
>  <title>kernel_tx</title>
> -<ellipse fill="none" stroke="blue" cx="102.23" cy="-237" rx="45.72" ry="18"/>
> -<text text-anchor="middle" x="102.23" y="-231.95" font-family="Times,serif" font-size="14.00">kernel_tx</text>
> +<ellipse fill="none" stroke="blue" cx="120" cy="-272" rx="53.89" ry="18"/>
> +<text text-anchor="middle" x="120" y="-268.3" font-family="Times,serif" font-size="14.00">kernel_tx</text>
>  </g>
>  <!-- kernel_tx&#45;&gt;kernel_rx -->
>  <g id="edge16" class="edge">
>  <title>kernel_tx&#45;&gt;kernel_rx</title>
> -<path fill="none" stroke="red" stroke-dasharray="5,2" d="M89.25,-219.53C82.32,-210.75 73.65,-199.76 65.92,-189.96"/>
> -<polygon fill="red" stroke="red" points="68.09,-188.06 59.15,-182.38 62.6,-192.4 68.09,-188.06"/>
> +<path fill="none" stroke="red" stroke-dasharray="5,2" d="M110.99,-254.17C106.52,-245.81 101,-235.51 95.99,-226.14"/>
> +<polygon fill="red" stroke="red" points="99.01,-224.36 91.2,-217.2 92.84,-227.67 99.01,-224.36"/>
>  </g>
>  <!-- pkt_cls&#45;&gt;pkt_drop -->
>  <g id="edge15" class="edge">
>  <title>pkt_cls&#45;&gt;pkt_drop</title>
> -<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M255.09,-319.38C322.68,-308.72 462.23,-281.44 462.23,-238 462.23,-238 462.23,-238 462.23,-90 462.23,-57.84 429.01,-39.68 398.59,-29.8"/>
> -<polygon fill="cyan" stroke="cyan" points="400.02,-26.27 389.44,-26.75 398.01,-32.98 400.02,-26.27"/>
> +<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M84,-348.97C48.65,-337.7 0,-314.61 0,-273 0,-273 0,-273 0,-90 0,-49.99 118.4,-31.52 193.52,-23.82"/>
> +<polygon fill="cyan" stroke="cyan" points="194.21,-27.27 203.82,-22.81 193.52,-20.31 194.21,-27.27"/>
>  </g>
>  <!-- pkt_cls&#45;&gt;kernel_tx -->
>  <g id="edge5" class="edge">
>  <title>pkt_cls&#45;&gt;kernel_tx</title>
> -<path fill="none" stroke="blue" d="M186.99,-315.75C170.62,-310.16 151.14,-301.64 136.48,-289.5 128.23,-282.66 121.2,-273.31 115.7,-264.46"/>
> -<polygon fill="blue" stroke="blue" points="118.38,-263.1 110.34,-256.2 112.32,-266.61 118.38,-263.1"/>
> -<text text-anchor="middle" x="176.61" y="-276.2" font-family="Times,serif" font-size="14.00">exception pkts</text>
> +<path fill="none" stroke="blue" d="M120,-340.8C120,-329.16 120,-313.55 120,-300.24"/>
> +<polygon fill="blue" stroke="blue" points="123.5,-300.18 120,-290.18 116.5,-300.18 123.5,-300.18"/>
> +<text text-anchor="middle" x="172.5" y="-311.8" font-family="Times,serif" font-size="14.00">exception pkts</text>
>  </g>
>  <!-- ip4_lookup -->
>  <g id="node7" class="node">
>  <title>ip4_lookup</title>
> -<ellipse fill="none" stroke="black" cx="219.23" cy="-237" rx="52.89" ry="18"/>
> -<text text-anchor="middle" x="219.23" y="-231.95" font-family="Times,serif" font-size="14.00">ip4_lookup</text>
> +<ellipse fill="none" stroke="black" cx="252" cy="-272" rx="60.39" ry="18"/>
> +<text text-anchor="middle" x="252" y="-268.3" font-family="Times,serif" font-size="14.00">ip4_lookup</text>
>  </g>
>  <!-- pkt_cls&#45;&gt;ip4_lookup -->
>  <g id="edge3" class="edge">
>  <title>pkt_cls&#45;&gt;ip4_lookup</title>
> -<path fill="none" stroke="black" d="M219.23,-307.41C219.23,-295.64 219.23,-279.73 219.23,-266.11"/>
> -<polygon fill="black" stroke="black" points="222.73,-266.35 219.23,-256.35 215.73,-266.35 222.73,-266.35"/>
> -<text text-anchor="middle" x="231.23" y="-276.2" font-family="Times,serif" font-size="14.00">ipv4</text>
> +<path fill="none" stroke="black" d="M160.54,-352.79C182.64,-348.15 209.23,-339.41 228,-323 235.09,-316.81 240.26,-308.05 243.95,-299.6"/>
> +<polygon fill="black" stroke="black" points="247.32,-300.57 247.62,-289.98 240.78,-298.07 247.32,-300.57"/>
> +<text text-anchor="middle" x="254.5" y="-311.8" font-family="Times,serif" font-size="14.00">ipv4</text>
>  </g>
>  <!-- ip6_lookup -->
>  <g id="node8" class="node">
>  <title>ip6_lookup</title>
> -<ellipse fill="none" stroke="black" cx="343.23" cy="-237" rx="52.89" ry="18"/>
> -<text text-anchor="middle" x="343.23" y="-231.95" font-family="Times,serif" font-size="14.00">ip6_lookup</text>
> +<ellipse fill="none" stroke="black" cx="439" cy="-272" rx="60.39" ry="18"/>
> +<text text-anchor="middle" x="439" y="-268.3" font-family="Times,serif" font-size="14.00">ip6_lookup</text>
>  </g>
>  <!-- pkt_cls&#45;&gt;ip6_lookup -->
>  <g id="edge4" class="edge">
>  <title>pkt_cls&#45;&gt;ip6_lookup</title>
> -<path fill="none" stroke="black" d="M239.99,-310.02C259.62,-296.33 289.35,-275.59 311.88,-259.87"/>
> -<polygon fill="black" stroke="black" points="313.53,-262.29 319.73,-253.7 309.53,-256.55 313.53,-262.29"/>
> -<text text-anchor="middle" x="304.23" y="-276.2" font-family="Times,serif" font-size="14.00">ipv6</text>
> +<path fill="none" stroke="black" d="M157.52,-350.25C188.82,-343.6 234.51,-333.46 274,-323 313.2,-312.62 357.13,-299.22 389.79,-288.91"/>
> +<polygon fill="black" stroke="black" points="391.08,-292.17 399.55,-285.81 388.96,-285.5 391.08,-292.17"/>
> +<text text-anchor="middle" x="339.5" y="-311.8" font-family="Times,serif" font-size="14.00">ipv6</text>
>  </g>
>  <!-- ip4_lookup&#45;&gt;pkt_drop -->
>  <g id="edge7" class="edge">
>  <title>ip4_lookup&#45;&gt;pkt_drop</title>
> -<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M192.86,-221.12C179.2,-211.83 163.82,-198.49 156.23,-182 149.55,-167.46 150.78,-161.04 156.23,-146 176.39,-90.45 198.32,-78.19 252.23,-54 269.14,-46.41 288.24,-39.24 304.98,-33.38"/>
> -<polygon fill="cyan" stroke="cyan" points="305.75,-36.48 314.07,-29.92 303.47,-29.86 305.75,-36.48"/>
> +<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M239.17,-254.03C232.31,-243.87 224.56,-230.37 221,-217 204.89,-156.57 227.58,-83.56 242.59,-45.31"/>
> +<polygon fill="cyan" stroke="cyan" points="245.89,-46.5 246.4,-35.92 239.4,-43.87 245.89,-46.5"/>
>  </g>
>  <!-- ip4_rewrite -->
>  <g id="node9" class="node">
>  <title>ip4_rewrite</title>
> -<ellipse fill="none" stroke="black" cx="218.23" cy="-164" rx="53.4" ry="18"/>
> -<text text-anchor="middle" x="218.23" y="-158.95" font-family="Times,serif" font-size="14.00">ip4_rewrite</text>
> +<ellipse fill="none" stroke="black" cx="294" cy="-199" rx="63.89" ry="18"/>
> +<text text-anchor="middle" x="294" y="-195.3" font-family="Times,serif" font-size="14.00">ip4_rewrite</text>
>  </g>
>  <!-- ip4_lookup&#45;&gt;ip4_rewrite -->
>  <g id="edge6" class="edge">
>  <title>ip4_lookup&#45;&gt;ip4_rewrite</title>
> -<path fill="none" stroke="black" d="M218.99,-218.81C218.88,-211.05 218.75,-201.68 218.63,-192.95"/>
> -<polygon fill="black" stroke="black" points="222.11,-192.98 218.47,-183.03 215.11,-193.08 222.11,-192.98"/>
> +<path fill="none" stroke="black" d="M261.95,-254.17C266.95,-245.72 273.12,-235.29 278.71,-225.85"/>
> +<polygon fill="black" stroke="black" points="281.75,-227.59 283.83,-217.2 275.72,-224.02 281.75,-227.59"/>
> +</g>
> +<!-- ip4_local -->
> +<g id="node11" class="node">
> +<title>ip4_local</title>
> +<ellipse fill="none" stroke="black" cx="136" cy="-145" rx="51.19" ry="18"/>
> +<text text-anchor="middle" x="136" y="-141.3" font-family="Times,serif" font-size="14.00">ip4_local</text>
> +</g>
> +<!-- ip4_lookup&#45;&gt;ip4_local -->
> +<g id="edge17" class="edge">
> +<title>ip4_lookup&#45;&gt;ip4_local</title>
> +<path fill="none" stroke="black" d="M218.11,-256.86C207.64,-251.39 196.61,-244.41 188,-236 169.45,-217.88 155.34,-191.74 146.53,-172.29"/>
> +<polygon fill="black" stroke="black" points="149.72,-170.86 142.52,-163.08 143.3,-173.65 149.72,-170.86"/>
>  </g>
>  <!-- ip6_lookup&#45;&gt;pkt_drop -->
>  <g id="edge11" class="edge">
>  <title>ip6_lookup&#45;&gt;pkt_drop</title>
> -<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M369.2,-221.03C382.65,-211.71 397.78,-198.37 405.23,-182 426.87,-134.45 392.95,-75.95 369.19,-43.54"/>
> -<polygon fill="cyan" stroke="cyan" points="371.64,-41.98 362.81,-36.13 366.06,-46.21 371.64,-41.98"/>
> +<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M470.57,-256.44C486.08,-247.46 503.27,-234.31 512,-217 519.2,-202.71 517.24,-196.12 512,-181 486.88,-108.48 466,-83.15 395,-54 367.69,-42.79 335.88,-34.51 309.39,-28.83"/>
> +<polygon fill="cyan" stroke="cyan" points="310.02,-25.39 299.52,-26.78 308.6,-32.24 310.02,-25.39"/>
>  </g>
>  <!-- ip6_rewrite -->
>  <g id="node10" class="node">
>  <title>ip6_rewrite</title>
> -<ellipse fill="none" stroke="black" cx="343.23" cy="-164" rx="53.4" ry="18"/>
> -<text text-anchor="middle" x="343.23" y="-158.95" font-family="Times,serif" font-size="14.00">ip6_rewrite</text>
> +<ellipse fill="none" stroke="black" cx="439" cy="-199" rx="63.89" ry="18"/>
> +<text text-anchor="middle" x="439" y="-195.3" font-family="Times,serif" font-size="14.00">ip6_rewrite</text>
>  </g>
>  <!-- ip6_lookup&#45;&gt;ip6_rewrite -->
>  <g id="edge10" class="edge">
>  <title>ip6_lookup&#45;&gt;ip6_rewrite</title>
> -<path fill="none" stroke="black" d="M343.23,-218.81C343.23,-211.05 343.23,-201.68 343.23,-192.95"/>
> -<polygon fill="black" stroke="black" points="346.73,-193.03 343.23,-183.03 339.73,-193.03 346.73,-193.03"/>
> +<path fill="none" stroke="black" d="M439,-253.81C439,-245.79 439,-236.05 439,-227.07"/>
> +<polygon fill="black" stroke="black" points="442.5,-227.03 439,-217.03 435.5,-227.03 442.5,-227.03"/>
>  </g>
>  <!-- ip4_rewrite&#45;&gt;ethdev_tx -->
>  <g id="edge8" class="edge">
>  <title>ip4_rewrite&#45;&gt;ethdev_tx</title>
> -<path fill="none" stroke="green" d="M235.63,-146.53C245.35,-137.33 257.64,-125.7 268.36,-115.54"/>
> -<polygon fill="green" stroke="green" points="270.34,-118.55 275.19,-109.13 265.52,-113.47 270.34,-118.55"/>
> +<path fill="none" stroke="green" d="M301.07,-180.97C308.09,-164.05 318.96,-137.86 327.09,-118.28"/>
> +<polygon fill="green" stroke="green" points="330.35,-119.57 330.95,-108.99 323.88,-116.88 330.35,-119.57"/>
>  </g>
>  <!-- ip4_rewrite&#45;&gt;pkt_drop -->
>  <g id="edge9" class="edge">
>  <title>ip4_rewrite&#45;&gt;pkt_drop</title>
> -<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M217.56,-145.54C217.71,-125.89 220.78,-93.99 237.23,-73 253.17,-52.67 278.68,-39.55 301.33,-31.33"/>
> -<polygon fill="cyan" stroke="cyan" points="302.14,-34.42 310.5,-27.9 299.9,-27.79 302.14,-34.42"/>
> +<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M289.85,-180.97C285.53,-163.07 278.61,-134.1 273,-109 268.3,-87.99 263.29,-64.16 259.59,-46.3"/>
> +<polygon fill="cyan" stroke="cyan" points="262.97,-45.37 257.52,-36.28 256.11,-46.78 262.97,-45.37"/>
>  </g>
>  <!-- ip6_rewrite&#45;&gt;ethdev_tx -->
>  <g id="edge12" class="edge">
>  <title>ip6_rewrite&#45;&gt;ethdev_tx</title>
> -<path fill="none" stroke="green" d="M331.38,-146.17C325.34,-137.6 317.87,-126.99 311.15,-117.44"/>
> -<polygon fill="green" stroke="green" points="313.62,-115.87 305,-109.71 307.89,-119.9 313.62,-115.87"/>
> +<path fill="none" stroke="green" d="M423.22,-181.44C406.47,-163.86 379.84,-135.91 360.81,-115.94"/>
> +<polygon fill="green" stroke="green" points="363.1,-113.27 353.67,-108.45 358.03,-118.1 363.1,-113.27"/>
>  </g>
>  <!-- ip6_rewrite&#45;&gt;pkt_drop -->
>  <g id="edge13" class="edge">
>  <title>ip6_rewrite&#45;&gt;pkt_drop</title>
> -<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M345.67,-145.53C347.02,-134.98 348.56,-121.24 349.23,-109 350.38,-88.27 350.34,-64.81 350.03,-47.04"/>
> -<polygon fill="cyan" stroke="cyan" points="353.51,-47.19 349.8,-37.27 346.51,-47.34 353.51,-47.19"/>
> +<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M438.77,-180.67C437.49,-154.09 431.22,-103.19 403,-73 379.35,-47.7 342.93,-34.22 312.02,-27.06"/>
> +<polygon fill="cyan" stroke="cyan" points="312.71,-23.63 302.2,-24.95 311.24,-30.47 312.71,-23.63"/>
> +</g>
> +<!-- ip4_local&#45;&gt;pkt_drop -->
> +<g id="edge18" class="edge">
> +<title>ip4_local&#45;&gt;pkt_drop</title>
> +<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M142.47,-126.87C150.6,-107.23 166.18,-75.04 188,-54 195,-47.25 203.56,-41.45 212.16,-36.63"/>
> +<polygon fill="cyan" stroke="cyan" points="213.85,-39.7 221.08,-31.95 210.6,-33.5 213.85,-39.7"/>
>  </g>
>  </g>
>  </svg>
> diff --git a/lib/node/ip4_local.c b/lib/node/ip4_local.c
> new file mode 100644
> index 0000000000..fb31d0f970
> --- /dev/null
> +++ b/lib/node/ip4_local.c
> @@ -0,0 +1,88 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(C) 2023 Marvell International Ltd.
> + */
> +
> +#include <arpa/inet.h>
> +#include <sys/socket.h>
> +
> +#include <rte_ethdev.h>
> +#include <rte_ether.h>
> +#include <rte_graph.h>
> +#include <rte_graph_worker.h>
> +#include <rte_ip.h>
> +#include <rte_lpm.h>
> +#include <rte_hash.h>
> +#include <rte_fbk_hash.h>
> +#include <rte_jhash.h>
> +#include <rte_hash_crc.h>
> +
> +
> +#include "rte_node_ip4_api.h"
> +
> +#include "node_private.h"
> +
> +static uint16_t
> +ip4_local_node_process_scalar(struct rte_graph *graph, struct rte_node *node,
> +                             void **objs, uint16_t nb_objs)
> +{
> +       void **to_next, **from;
> +       uint16_t last_spec = 0;
> +       rte_edge_t next_index;
> +       struct rte_mbuf *mbuf;
> +       uint16_t held = 0;
> +       uint32_t l4;
> +       int i;
> +
> +       /* Speculative next */
> +       next_index = RTE_NODE_IP4_LOCAL_NEXT_UDP4_INPUT;
> +
> +       from = objs;
> +       to_next = rte_node_next_stream_get(graph, node, next_index, nb_objs);
> +       for (i = 0; i < nb_objs; i++) {
> +               uint16_t next;
> +
> +               mbuf = (struct rte_mbuf *)objs[i];
> +               l4 = mbuf->packet_type & RTE_PTYPE_L4_MASK;
> +
> +               next = (l4 == RTE_PTYPE_L4_UDP)
> +                               ? next_index
> +                               : RTE_NODE_IP4_LOCAL_NEXT_PKT_DROP;
> +
> +               if (unlikely(next_index != next)) {
> +                       /* Copy things successfully speculated till now */
> +                       rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
> +                       from += last_spec;
> +                       to_next += last_spec;
> +                       held += last_spec;
> +                       last_spec = 0;
> +
> +                       rte_node_enqueue_x1(graph, node, next, from[0]);
> +                       from += 1;
> +               } else {
> +                       last_spec += 1;
> +               }
> +       }
> +       /* !!! Home run !!! */
> +       if (likely(last_spec == nb_objs)) {
> +               rte_node_next_stream_move(graph, node, next_index);
> +               return nb_objs;
> +       }
> +       held += last_spec;
> +       rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
> +       rte_node_next_stream_put(graph, node, next_index, held);
> +
> +       return nb_objs;
> +}
> +
> +static struct rte_node_register ip4_local_node = {
> +       .process = ip4_local_node_process_scalar,
> +       .name = "ip4_local",
> +
> +       .nb_edges = RTE_NODE_IP4_LOCAL_NEXT_PKT_DROP + 1,
> +       .next_nodes = {
> +               [RTE_NODE_IP4_LOCAL_NEXT_UDP4_INPUT] = "udp4_input",
> +               [RTE_NODE_IP4_LOCAL_NEXT_PKT_DROP] = "pkt_drop",
> +       },
> +};
> +
> +RTE_NODE_REGISTER(ip4_local_node);
> diff --git a/lib/node/ip4_lookup.c b/lib/node/ip4_lookup.c
> index 72fd760512..0dbfde64fe 100644
> --- a/lib/node/ip4_lookup.c
> +++ b/lib/node/ip4_lookup.c
> @@ -227,6 +227,7 @@ static struct rte_node_register ip4_lookup_node = {
>
>         .nb_edges = RTE_NODE_IP4_LOOKUP_NEXT_PKT_DROP + 1,
>         .next_nodes = {
> +               [RTE_NODE_IP4_LOOKUP_NEXT_IP4_LOCAL] = "ip4_local",
>                 [RTE_NODE_IP4_LOOKUP_NEXT_REWRITE] = "ip4_rewrite",
>                 [RTE_NODE_IP4_LOOKUP_NEXT_PKT_DROP] = "pkt_drop",
>         },
> diff --git a/lib/node/meson.build b/lib/node/meson.build
> index 2fa7c1c8f3..c0d5b09e2f 100644
> --- a/lib/node/meson.build
> +++ b/lib/node/meson.build
> @@ -12,6 +12,7 @@ sources = files(
>          'ethdev_rx.c',
>          'ethdev_tx.c',
>          'ip4_lookup.c',
> +        'ip4_local.c',
>          'ip4_rewrite.c',
>          'ip6_lookup.c',
>          'ip6_rewrite.c',
> diff --git a/lib/node/rte_node_ip4_api.h b/lib/node/rte_node_ip4_api.h
> index 0f997761b6..40af3860b5 100644
> --- a/lib/node/rte_node_ip4_api.h
> +++ b/lib/node/rte_node_ip4_api.h
> @@ -28,10 +28,22 @@ extern "C" {
>  enum rte_node_ip4_lookup_next {
>         RTE_NODE_IP4_LOOKUP_NEXT_REWRITE,
>         /**< Rewrite node. */
> +       RTE_NODE_IP4_LOOKUP_NEXT_IP4_LOCAL,
> +       /** IP Local node. */
>         RTE_NODE_IP4_LOOKUP_NEXT_PKT_DROP,
>         /**< Number of next nodes of lookup node. */
>  };
>
> +/**
> + * IP4 Local next nodes.
> + */
> +enum rte_node_ip4_local_next {
> +       RTE_NODE_IP4_LOCAL_NEXT_UDP4_INPUT,
> +       /**< ip4 Local node. */
> +       RTE_NODE_IP4_LOCAL_NEXT_PKT_DROP,
> +       /**< Packet drop node. */
> +};
> +
>  /**
>   * Add ipv4 route to lookup table.
>   *
> --
> 2.25.1
>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v6 1/2] node: add IPv4 local node to handle local pkts
  2023-09-29 10:54           ` [PATCH v6 1/2] node: add IPv4 local node to handle local pkts Nithin Dabilpuram
@ 2023-09-29 10:58             ` Nithin Dabilpuram
  0 siblings, 0 replies; 16+ messages in thread
From: Nithin Dabilpuram @ 2023-09-29 10:58 UTC (permalink / raw)
  To: Rakesh Kudurumalla
  Cc: Jerin Jacob, Kiran Kumar K, Nithin Dabilpuram, Zhirun Yan,
	Pavan Nikhilesh, dev

Acked-by: Nithin Dabilpuram <ndabilpuram@marvell.com>

On Fri, Sep 29, 2023 at 4:24 PM Nithin Dabilpuram <nithind1988@gmail.com> wrote:
>
> Series-acked-by: Nithin Dabilpuram <ndabilpuram@marvell.com>
>
>
> On Fri, Sep 29, 2023 at 1:21 AM Rakesh Kudurumalla
> <rkudurumalla@marvell.com> wrote:
> >
> > Local or Host destined pkts can be redirected IPv4 local node
> > using IP4 Lookup node entries with prefix of 32 and be redirected
> > to this IP4 local node for further processing.
> >
> > Signed-off-by: Rakesh Kudurumalla <rkudurumalla@marvell.com>
> > ---
> > Depends-on: series-29670 ("remove MAX macro from all nodes")
> >
> > v6: Resolve dependency
> >
> >  doc/guides/prog_guide/graph_lib.rst           |  15 ++
> >  .../img/graph_inbuilt_node_flow.svg           | 138 ++++++++++--------
> >  lib/node/ip4_local.c                          |  88 +++++++++++
> >  lib/node/ip4_lookup.c                         |   1 +
> >  lib/node/meson.build                          |   1 +
> >  lib/node/rte_node_ip4_api.h                   |  12 ++
> >  6 files changed, 196 insertions(+), 59 deletions(-)
> >  create mode 100644 lib/node/ip4_local.c
> >
> > diff --git a/doc/guides/prog_guide/graph_lib.rst b/doc/guides/prog_guide/graph_lib.rst
> > index e7b6e12004..f2e04a68b9 100644
> > --- a/doc/guides/prog_guide/graph_lib.rst
> > +++ b/doc/guides/prog_guide/graph_lib.rst
> > @@ -498,3 +498,18 @@ Uses ``poll`` function to poll on the socket fd
> >  for ``POLLIN`` events to read the packets from raw socket
> >  to stream buffer and does ``rte_node_next_stream_move()``
> >  when there are received packets.
> > +
> > +ip4_local
> > +~~~~~~~~~
> > +This node is an intermediate node that does ``packet_type`` lookup for
> > +the received ipv4 packets and the result determines each packets next node.
> > +
> > +On successful ``packet_type`` lookup, for any IPv4 protocol the result
> > +contains the ``next_node`` id and ``next-hop`` id with which the packet
> > +needs to be further processed.
> > +
> > +On packet_type lookup failure, objects are redirected to ``pkt_drop`` node.
> > +``rte_node_ip4_route_add()`` is control path API to add ipv4 address with 32 bit
> > +depth to receive to packets.
> > +To achieve home run, node use ``rte_node_stream_move()`` as mentioned in above
> > +sections.
> > diff --git a/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg b/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg
> > index 7eea94701f..b954f6fba1 100644
> > --- a/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg
> > +++ b/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg
> > @@ -37,174 +37,194 @@ digraph dpdk_inbuilt_nodes_flow {
> >      ethdev_tx -> pkt_drop [color="cyan" style="dashed"]
> >      pkt_cls->pkt_drop   [color="cyan" style="dashed"]
> >      kernel_tx -> kernel_rx [color="red" style="dashed"]
> > +    ip4_lookup -> ip4_local
> > +    ip4_local -> pkt_drop [color="cyan" style="dashed"]
> >  }
> >
> >   -->
> >  <!-- input nodes -->
> >  <!-- Title: dpdk_inbuilt_nodes_flow Pages: 1 -->
> > -<svg width="470pt" height="425pt"
> > - viewBox="0.00 0.00 470.23 424.50" 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 420.5)">
> > +<svg width="525pt" height="458pt"
> > + viewBox="0.00 0.00 524.91 458.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 454)">
> >  <title>dpdk_inbuilt_nodes_flow</title>
> > -<polygon fill="white" stroke="none" points="-4,4 -4,-420.5 466.23,-420.5 466.23,4 -4,4"/>
> > +<polygon fill="white" stroke="transparent" points="-4,4 -4,-454 520.91,-454 520.91,4 -4,4"/>
> >  <!-- ethdev_rx -->
> >  <g id="node1" class="node">
> >  <title>ethdev_rx</title>
> > -<ellipse fill="none" stroke="green" cx="219.23" cy="-398.5" rx="47.77" ry="18"/>
> > -<text text-anchor="middle" x="219.23" y="-393.45" font-family="Times,serif" font-size="14.00">ethdev_rx</text>
> > +<ellipse fill="none" stroke="green" cx="120" cy="-432" rx="56.59" ry="18"/>
> > +<text text-anchor="middle" x="120" y="-428.3" font-family="Times,serif" font-size="14.00">ethdev_rx</text>
> >  </g>
> >  <!-- pkt_cls -->
> >  <g id="node6" class="node">
> >  <title>pkt_cls</title>
> > -<ellipse fill="none" stroke="red" cx="219.23" cy="-325.5" rx="37.53" ry="18"/>
> > -<text text-anchor="middle" x="219.23" y="-320.45" font-family="Times,serif" font-size="14.00">pkt_cls</text>
> > +<ellipse fill="none" stroke="red" cx="120" cy="-359" rx="42.79" ry="18"/>
> > +<text text-anchor="middle" x="120" y="-355.3" font-family="Times,serif" font-size="14.00">pkt_cls</text>
> >  </g>
> >  <!-- ethdev_rx&#45;&gt;pkt_cls -->
> >  <g id="edge1" class="edge">
> >  <title>ethdev_rx&#45;&gt;pkt_cls</title>
> > -<path fill="none" stroke="black" d="M219.23,-380.31C219.23,-372.55 219.23,-363.18 219.23,-354.45"/>
> > -<polygon fill="black" stroke="black" points="222.73,-354.53 219.23,-344.53 215.73,-354.53 222.73,-354.53"/>
> > +<path fill="none" stroke="black" d="M120,-413.81C120,-405.79 120,-396.05 120,-387.07"/>
> > +<polygon fill="black" stroke="black" points="123.5,-387.03 120,-377.03 116.5,-387.03 123.5,-387.03"/>
> >  </g>
> >  <!-- kernel_rx -->
> >  <g id="node2" class="node">
> >  <title>kernel_rx</title>
> > -<ellipse fill="none" stroke="green" cx="46.23" cy="-164" rx="46.23" ry="18"/>
> > -<text text-anchor="middle" x="46.23" y="-158.95" font-family="Times,serif" font-size="14.00">kernel_rx</text>
> > +<ellipse fill="none" stroke="green" cx="82" cy="-199" rx="53.89" ry="18"/>
> > +<text text-anchor="middle" x="82" y="-195.3" font-family="Times,serif" font-size="14.00">kernel_rx</text>
> >  </g>
> >  <!-- kernel_rx&#45;&gt;pkt_cls -->
> >  <g id="edge2" class="edge">
> >  <title>kernel_rx&#45;&gt;pkt_cls</title>
> > -<path fill="none" stroke="black" d="M41.45,-182.08C37.1,-201.37 33.27,-232.96 47.23,-255 73.68,-296.74 130.21,-313.41 171.26,-320.07"/>
> > -<polygon fill="black" stroke="black" points="170.73,-323.68 181.13,-321.66 171.74,-316.75 170.73,-323.68"/>
> > +<path fill="none" stroke="black" d="M70.87,-216.92C60.28,-235.27 47.29,-265.24 57,-290 64.12,-308.16 78.62,-324.37 91.92,-336.4"/>
> > +<polygon fill="black" stroke="black" points="89.69,-339.1 99.54,-342.99 94.26,-333.8 89.69,-339.1"/>
> >  </g>
> >  <!-- ethdev_tx -->
> >  <g id="node3" class="node">
> >  <title>ethdev_tx</title>
> > -<ellipse fill="none" stroke="magenta" cx="293.23" cy="-91" rx="47.26" ry="18"/>
> > -<text text-anchor="middle" x="293.23" y="-85.95" font-family="Times,serif" font-size="14.00">ethdev_tx</text>
> > +<ellipse fill="none" stroke="magenta" cx="338" cy="-91" rx="55.79" ry="18"/>
> > +<text text-anchor="middle" x="338" y="-87.3" font-family="Times,serif" font-size="14.00">ethdev_tx</text>
> >  </g>
> >  <!-- pkt_drop -->
> >  <g id="node4" class="node">
> >  <title>pkt_drop</title>
> > -<ellipse fill="none" stroke="cyan" cx="349.23" cy="-18" rx="44.19" ry="18"/>
> > -<text text-anchor="middle" x="349.23" y="-12.95" font-family="Times,serif" font-size="14.00">pkt_drop</text>
> > +<ellipse fill="none" stroke="cyan" cx="254" cy="-18" rx="51.99" ry="18"/>
> > +<text text-anchor="middle" x="254" y="-14.3" font-family="Times,serif" font-size="14.00">pkt_drop</text>
> >  </g>
> >  <!-- ethdev_tx&#45;&gt;pkt_drop -->
> >  <g id="edge14" class="edge">
> >  <title>ethdev_tx&#45;&gt;pkt_drop</title>
> > -<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M306.22,-73.53C313.15,-64.75 321.81,-53.76 329.55,-43.96"/>
> > -<polygon fill="cyan" stroke="cyan" points="332.87,-46.4 336.32,-36.38 327.37,-42.06 332.87,-46.4"/>
> > +<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M318.94,-73.89C307.58,-64.29 293,-51.96 280.53,-41.42"/>
> > +<polygon fill="cyan" stroke="cyan" points="282.59,-38.58 272.7,-34.8 278.07,-43.93 282.59,-38.58"/>
> >  </g>
> >  <!-- kernel_tx -->
> >  <g id="node5" class="node">
> >  <title>kernel_tx</title>
> > -<ellipse fill="none" stroke="blue" cx="102.23" cy="-237" rx="45.72" ry="18"/>
> > -<text text-anchor="middle" x="102.23" y="-231.95" font-family="Times,serif" font-size="14.00">kernel_tx</text>
> > +<ellipse fill="none" stroke="blue" cx="120" cy="-272" rx="53.89" ry="18"/>
> > +<text text-anchor="middle" x="120" y="-268.3" font-family="Times,serif" font-size="14.00">kernel_tx</text>
> >  </g>
> >  <!-- kernel_tx&#45;&gt;kernel_rx -->
> >  <g id="edge16" class="edge">
> >  <title>kernel_tx&#45;&gt;kernel_rx</title>
> > -<path fill="none" stroke="red" stroke-dasharray="5,2" d="M89.25,-219.53C82.32,-210.75 73.65,-199.76 65.92,-189.96"/>
> > -<polygon fill="red" stroke="red" points="68.09,-188.06 59.15,-182.38 62.6,-192.4 68.09,-188.06"/>
> > +<path fill="none" stroke="red" stroke-dasharray="5,2" d="M110.99,-254.17C106.52,-245.81 101,-235.51 95.99,-226.14"/>
> > +<polygon fill="red" stroke="red" points="99.01,-224.36 91.2,-217.2 92.84,-227.67 99.01,-224.36"/>
> >  </g>
> >  <!-- pkt_cls&#45;&gt;pkt_drop -->
> >  <g id="edge15" class="edge">
> >  <title>pkt_cls&#45;&gt;pkt_drop</title>
> > -<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M255.09,-319.38C322.68,-308.72 462.23,-281.44 462.23,-238 462.23,-238 462.23,-238 462.23,-90 462.23,-57.84 429.01,-39.68 398.59,-29.8"/>
> > -<polygon fill="cyan" stroke="cyan" points="400.02,-26.27 389.44,-26.75 398.01,-32.98 400.02,-26.27"/>
> > +<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M84,-348.97C48.65,-337.7 0,-314.61 0,-273 0,-273 0,-273 0,-90 0,-49.99 118.4,-31.52 193.52,-23.82"/>
> > +<polygon fill="cyan" stroke="cyan" points="194.21,-27.27 203.82,-22.81 193.52,-20.31 194.21,-27.27"/>
> >  </g>
> >  <!-- pkt_cls&#45;&gt;kernel_tx -->
> >  <g id="edge5" class="edge">
> >  <title>pkt_cls&#45;&gt;kernel_tx</title>
> > -<path fill="none" stroke="blue" d="M186.99,-315.75C170.62,-310.16 151.14,-301.64 136.48,-289.5 128.23,-282.66 121.2,-273.31 115.7,-264.46"/>
> > -<polygon fill="blue" stroke="blue" points="118.38,-263.1 110.34,-256.2 112.32,-266.61 118.38,-263.1"/>
> > -<text text-anchor="middle" x="176.61" y="-276.2" font-family="Times,serif" font-size="14.00">exception pkts</text>
> > +<path fill="none" stroke="blue" d="M120,-340.8C120,-329.16 120,-313.55 120,-300.24"/>
> > +<polygon fill="blue" stroke="blue" points="123.5,-300.18 120,-290.18 116.5,-300.18 123.5,-300.18"/>
> > +<text text-anchor="middle" x="172.5" y="-311.8" font-family="Times,serif" font-size="14.00">exception pkts</text>
> >  </g>
> >  <!-- ip4_lookup -->
> >  <g id="node7" class="node">
> >  <title>ip4_lookup</title>
> > -<ellipse fill="none" stroke="black" cx="219.23" cy="-237" rx="52.89" ry="18"/>
> > -<text text-anchor="middle" x="219.23" y="-231.95" font-family="Times,serif" font-size="14.00">ip4_lookup</text>
> > +<ellipse fill="none" stroke="black" cx="252" cy="-272" rx="60.39" ry="18"/>
> > +<text text-anchor="middle" x="252" y="-268.3" font-family="Times,serif" font-size="14.00">ip4_lookup</text>
> >  </g>
> >  <!-- pkt_cls&#45;&gt;ip4_lookup -->
> >  <g id="edge3" class="edge">
> >  <title>pkt_cls&#45;&gt;ip4_lookup</title>
> > -<path fill="none" stroke="black" d="M219.23,-307.41C219.23,-295.64 219.23,-279.73 219.23,-266.11"/>
> > -<polygon fill="black" stroke="black" points="222.73,-266.35 219.23,-256.35 215.73,-266.35 222.73,-266.35"/>
> > -<text text-anchor="middle" x="231.23" y="-276.2" font-family="Times,serif" font-size="14.00">ipv4</text>
> > +<path fill="none" stroke="black" d="M160.54,-352.79C182.64,-348.15 209.23,-339.41 228,-323 235.09,-316.81 240.26,-308.05 243.95,-299.6"/>
> > +<polygon fill="black" stroke="black" points="247.32,-300.57 247.62,-289.98 240.78,-298.07 247.32,-300.57"/>
> > +<text text-anchor="middle" x="254.5" y="-311.8" font-family="Times,serif" font-size="14.00">ipv4</text>
> >  </g>
> >  <!-- ip6_lookup -->
> >  <g id="node8" class="node">
> >  <title>ip6_lookup</title>
> > -<ellipse fill="none" stroke="black" cx="343.23" cy="-237" rx="52.89" ry="18"/>
> > -<text text-anchor="middle" x="343.23" y="-231.95" font-family="Times,serif" font-size="14.00">ip6_lookup</text>
> > +<ellipse fill="none" stroke="black" cx="439" cy="-272" rx="60.39" ry="18"/>
> > +<text text-anchor="middle" x="439" y="-268.3" font-family="Times,serif" font-size="14.00">ip6_lookup</text>
> >  </g>
> >  <!-- pkt_cls&#45;&gt;ip6_lookup -->
> >  <g id="edge4" class="edge">
> >  <title>pkt_cls&#45;&gt;ip6_lookup</title>
> > -<path fill="none" stroke="black" d="M239.99,-310.02C259.62,-296.33 289.35,-275.59 311.88,-259.87"/>
> > -<polygon fill="black" stroke="black" points="313.53,-262.29 319.73,-253.7 309.53,-256.55 313.53,-262.29"/>
> > -<text text-anchor="middle" x="304.23" y="-276.2" font-family="Times,serif" font-size="14.00">ipv6</text>
> > +<path fill="none" stroke="black" d="M157.52,-350.25C188.82,-343.6 234.51,-333.46 274,-323 313.2,-312.62 357.13,-299.22 389.79,-288.91"/>
> > +<polygon fill="black" stroke="black" points="391.08,-292.17 399.55,-285.81 388.96,-285.5 391.08,-292.17"/>
> > +<text text-anchor="middle" x="339.5" y="-311.8" font-family="Times,serif" font-size="14.00">ipv6</text>
> >  </g>
> >  <!-- ip4_lookup&#45;&gt;pkt_drop -->
> >  <g id="edge7" class="edge">
> >  <title>ip4_lookup&#45;&gt;pkt_drop</title>
> > -<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M192.86,-221.12C179.2,-211.83 163.82,-198.49 156.23,-182 149.55,-167.46 150.78,-161.04 156.23,-146 176.39,-90.45 198.32,-78.19 252.23,-54 269.14,-46.41 288.24,-39.24 304.98,-33.38"/>
> > -<polygon fill="cyan" stroke="cyan" points="305.75,-36.48 314.07,-29.92 303.47,-29.86 305.75,-36.48"/>
> > +<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M239.17,-254.03C232.31,-243.87 224.56,-230.37 221,-217 204.89,-156.57 227.58,-83.56 242.59,-45.31"/>
> > +<polygon fill="cyan" stroke="cyan" points="245.89,-46.5 246.4,-35.92 239.4,-43.87 245.89,-46.5"/>
> >  </g>
> >  <!-- ip4_rewrite -->
> >  <g id="node9" class="node">
> >  <title>ip4_rewrite</title>
> > -<ellipse fill="none" stroke="black" cx="218.23" cy="-164" rx="53.4" ry="18"/>
> > -<text text-anchor="middle" x="218.23" y="-158.95" font-family="Times,serif" font-size="14.00">ip4_rewrite</text>
> > +<ellipse fill="none" stroke="black" cx="294" cy="-199" rx="63.89" ry="18"/>
> > +<text text-anchor="middle" x="294" y="-195.3" font-family="Times,serif" font-size="14.00">ip4_rewrite</text>
> >  </g>
> >  <!-- ip4_lookup&#45;&gt;ip4_rewrite -->
> >  <g id="edge6" class="edge">
> >  <title>ip4_lookup&#45;&gt;ip4_rewrite</title>
> > -<path fill="none" stroke="black" d="M218.99,-218.81C218.88,-211.05 218.75,-201.68 218.63,-192.95"/>
> > -<polygon fill="black" stroke="black" points="222.11,-192.98 218.47,-183.03 215.11,-193.08 222.11,-192.98"/>
> > +<path fill="none" stroke="black" d="M261.95,-254.17C266.95,-245.72 273.12,-235.29 278.71,-225.85"/>
> > +<polygon fill="black" stroke="black" points="281.75,-227.59 283.83,-217.2 275.72,-224.02 281.75,-227.59"/>
> > +</g>
> > +<!-- ip4_local -->
> > +<g id="node11" class="node">
> > +<title>ip4_local</title>
> > +<ellipse fill="none" stroke="black" cx="136" cy="-145" rx="51.19" ry="18"/>
> > +<text text-anchor="middle" x="136" y="-141.3" font-family="Times,serif" font-size="14.00">ip4_local</text>
> > +</g>
> > +<!-- ip4_lookup&#45;&gt;ip4_local -->
> > +<g id="edge17" class="edge">
> > +<title>ip4_lookup&#45;&gt;ip4_local</title>
> > +<path fill="none" stroke="black" d="M218.11,-256.86C207.64,-251.39 196.61,-244.41 188,-236 169.45,-217.88 155.34,-191.74 146.53,-172.29"/>
> > +<polygon fill="black" stroke="black" points="149.72,-170.86 142.52,-163.08 143.3,-173.65 149.72,-170.86"/>
> >  </g>
> >  <!-- ip6_lookup&#45;&gt;pkt_drop -->
> >  <g id="edge11" class="edge">
> >  <title>ip6_lookup&#45;&gt;pkt_drop</title>
> > -<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M369.2,-221.03C382.65,-211.71 397.78,-198.37 405.23,-182 426.87,-134.45 392.95,-75.95 369.19,-43.54"/>
> > -<polygon fill="cyan" stroke="cyan" points="371.64,-41.98 362.81,-36.13 366.06,-46.21 371.64,-41.98"/>
> > +<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M470.57,-256.44C486.08,-247.46 503.27,-234.31 512,-217 519.2,-202.71 517.24,-196.12 512,-181 486.88,-108.48 466,-83.15 395,-54 367.69,-42.79 335.88,-34.51 309.39,-28.83"/>
> > +<polygon fill="cyan" stroke="cyan" points="310.02,-25.39 299.52,-26.78 308.6,-32.24 310.02,-25.39"/>
> >  </g>
> >  <!-- ip6_rewrite -->
> >  <g id="node10" class="node">
> >  <title>ip6_rewrite</title>
> > -<ellipse fill="none" stroke="black" cx="343.23" cy="-164" rx="53.4" ry="18"/>
> > -<text text-anchor="middle" x="343.23" y="-158.95" font-family="Times,serif" font-size="14.00">ip6_rewrite</text>
> > +<ellipse fill="none" stroke="black" cx="439" cy="-199" rx="63.89" ry="18"/>
> > +<text text-anchor="middle" x="439" y="-195.3" font-family="Times,serif" font-size="14.00">ip6_rewrite</text>
> >  </g>
> >  <!-- ip6_lookup&#45;&gt;ip6_rewrite -->
> >  <g id="edge10" class="edge">
> >  <title>ip6_lookup&#45;&gt;ip6_rewrite</title>
> > -<path fill="none" stroke="black" d="M343.23,-218.81C343.23,-211.05 343.23,-201.68 343.23,-192.95"/>
> > -<polygon fill="black" stroke="black" points="346.73,-193.03 343.23,-183.03 339.73,-193.03 346.73,-193.03"/>
> > +<path fill="none" stroke="black" d="M439,-253.81C439,-245.79 439,-236.05 439,-227.07"/>
> > +<polygon fill="black" stroke="black" points="442.5,-227.03 439,-217.03 435.5,-227.03 442.5,-227.03"/>
> >  </g>
> >  <!-- ip4_rewrite&#45;&gt;ethdev_tx -->
> >  <g id="edge8" class="edge">
> >  <title>ip4_rewrite&#45;&gt;ethdev_tx</title>
> > -<path fill="none" stroke="green" d="M235.63,-146.53C245.35,-137.33 257.64,-125.7 268.36,-115.54"/>
> > -<polygon fill="green" stroke="green" points="270.34,-118.55 275.19,-109.13 265.52,-113.47 270.34,-118.55"/>
> > +<path fill="none" stroke="green" d="M301.07,-180.97C308.09,-164.05 318.96,-137.86 327.09,-118.28"/>
> > +<polygon fill="green" stroke="green" points="330.35,-119.57 330.95,-108.99 323.88,-116.88 330.35,-119.57"/>
> >  </g>
> >  <!-- ip4_rewrite&#45;&gt;pkt_drop -->
> >  <g id="edge9" class="edge">
> >  <title>ip4_rewrite&#45;&gt;pkt_drop</title>
> > -<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M217.56,-145.54C217.71,-125.89 220.78,-93.99 237.23,-73 253.17,-52.67 278.68,-39.55 301.33,-31.33"/>
> > -<polygon fill="cyan" stroke="cyan" points="302.14,-34.42 310.5,-27.9 299.9,-27.79 302.14,-34.42"/>
> > +<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M289.85,-180.97C285.53,-163.07 278.61,-134.1 273,-109 268.3,-87.99 263.29,-64.16 259.59,-46.3"/>
> > +<polygon fill="cyan" stroke="cyan" points="262.97,-45.37 257.52,-36.28 256.11,-46.78 262.97,-45.37"/>
> >  </g>
> >  <!-- ip6_rewrite&#45;&gt;ethdev_tx -->
> >  <g id="edge12" class="edge">
> >  <title>ip6_rewrite&#45;&gt;ethdev_tx</title>
> > -<path fill="none" stroke="green" d="M331.38,-146.17C325.34,-137.6 317.87,-126.99 311.15,-117.44"/>
> > -<polygon fill="green" stroke="green" points="313.62,-115.87 305,-109.71 307.89,-119.9 313.62,-115.87"/>
> > +<path fill="none" stroke="green" d="M423.22,-181.44C406.47,-163.86 379.84,-135.91 360.81,-115.94"/>
> > +<polygon fill="green" stroke="green" points="363.1,-113.27 353.67,-108.45 358.03,-118.1 363.1,-113.27"/>
> >  </g>
> >  <!-- ip6_rewrite&#45;&gt;pkt_drop -->
> >  <g id="edge13" class="edge">
> >  <title>ip6_rewrite&#45;&gt;pkt_drop</title>
> > -<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M345.67,-145.53C347.02,-134.98 348.56,-121.24 349.23,-109 350.38,-88.27 350.34,-64.81 350.03,-47.04"/>
> > -<polygon fill="cyan" stroke="cyan" points="353.51,-47.19 349.8,-37.27 346.51,-47.34 353.51,-47.19"/>
> > +<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M438.77,-180.67C437.49,-154.09 431.22,-103.19 403,-73 379.35,-47.7 342.93,-34.22 312.02,-27.06"/>
> > +<polygon fill="cyan" stroke="cyan" points="312.71,-23.63 302.2,-24.95 311.24,-30.47 312.71,-23.63"/>
> > +</g>
> > +<!-- ip4_local&#45;&gt;pkt_drop -->
> > +<g id="edge18" class="edge">
> > +<title>ip4_local&#45;&gt;pkt_drop</title>
> > +<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M142.47,-126.87C150.6,-107.23 166.18,-75.04 188,-54 195,-47.25 203.56,-41.45 212.16,-36.63"/>
> > +<polygon fill="cyan" stroke="cyan" points="213.85,-39.7 221.08,-31.95 210.6,-33.5 213.85,-39.7"/>
> >  </g>
> >  </g>
> >  </svg>
> > diff --git a/lib/node/ip4_local.c b/lib/node/ip4_local.c
> > new file mode 100644
> > index 0000000000..fb31d0f970
> > --- /dev/null
> > +++ b/lib/node/ip4_local.c
> > @@ -0,0 +1,88 @@
> > +/* SPDX-License-Identifier: BSD-3-Clause
> > + * Copyright(C) 2023 Marvell International Ltd.
> > + */
> > +
> > +#include <arpa/inet.h>
> > +#include <sys/socket.h>
> > +
> > +#include <rte_ethdev.h>
> > +#include <rte_ether.h>
> > +#include <rte_graph.h>
> > +#include <rte_graph_worker.h>
> > +#include <rte_ip.h>
> > +#include <rte_lpm.h>
> > +#include <rte_hash.h>
> > +#include <rte_fbk_hash.h>
> > +#include <rte_jhash.h>
> > +#include <rte_hash_crc.h>
> > +
> > +
> > +#include "rte_node_ip4_api.h"
> > +
> > +#include "node_private.h"
> > +
> > +static uint16_t
> > +ip4_local_node_process_scalar(struct rte_graph *graph, struct rte_node *node,
> > +                             void **objs, uint16_t nb_objs)
> > +{
> > +       void **to_next, **from;
> > +       uint16_t last_spec = 0;
> > +       rte_edge_t next_index;
> > +       struct rte_mbuf *mbuf;
> > +       uint16_t held = 0;
> > +       uint32_t l4;
> > +       int i;
> > +
> > +       /* Speculative next */
> > +       next_index = RTE_NODE_IP4_LOCAL_NEXT_UDP4_INPUT;
> > +
> > +       from = objs;
> > +       to_next = rte_node_next_stream_get(graph, node, next_index, nb_objs);
> > +       for (i = 0; i < nb_objs; i++) {
> > +               uint16_t next;
> > +
> > +               mbuf = (struct rte_mbuf *)objs[i];
> > +               l4 = mbuf->packet_type & RTE_PTYPE_L4_MASK;
> > +
> > +               next = (l4 == RTE_PTYPE_L4_UDP)
> > +                               ? next_index
> > +                               : RTE_NODE_IP4_LOCAL_NEXT_PKT_DROP;
> > +
> > +               if (unlikely(next_index != next)) {
> > +                       /* Copy things successfully speculated till now */
> > +                       rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
> > +                       from += last_spec;
> > +                       to_next += last_spec;
> > +                       held += last_spec;
> > +                       last_spec = 0;
> > +
> > +                       rte_node_enqueue_x1(graph, node, next, from[0]);
> > +                       from += 1;
> > +               } else {
> > +                       last_spec += 1;
> > +               }
> > +       }
> > +       /* !!! Home run !!! */
> > +       if (likely(last_spec == nb_objs)) {
> > +               rte_node_next_stream_move(graph, node, next_index);
> > +               return nb_objs;
> > +       }
> > +       held += last_spec;
> > +       rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
> > +       rte_node_next_stream_put(graph, node, next_index, held);
> > +
> > +       return nb_objs;
> > +}
> > +
> > +static struct rte_node_register ip4_local_node = {
> > +       .process = ip4_local_node_process_scalar,
> > +       .name = "ip4_local",
> > +
> > +       .nb_edges = RTE_NODE_IP4_LOCAL_NEXT_PKT_DROP + 1,
> > +       .next_nodes = {
> > +               [RTE_NODE_IP4_LOCAL_NEXT_UDP4_INPUT] = "udp4_input",
> > +               [RTE_NODE_IP4_LOCAL_NEXT_PKT_DROP] = "pkt_drop",
> > +       },
> > +};
> > +
> > +RTE_NODE_REGISTER(ip4_local_node);
> > diff --git a/lib/node/ip4_lookup.c b/lib/node/ip4_lookup.c
> > index 72fd760512..0dbfde64fe 100644
> > --- a/lib/node/ip4_lookup.c
> > +++ b/lib/node/ip4_lookup.c
> > @@ -227,6 +227,7 @@ static struct rte_node_register ip4_lookup_node = {
> >
> >         .nb_edges = RTE_NODE_IP4_LOOKUP_NEXT_PKT_DROP + 1,
> >         .next_nodes = {
> > +               [RTE_NODE_IP4_LOOKUP_NEXT_IP4_LOCAL] = "ip4_local",
> >                 [RTE_NODE_IP4_LOOKUP_NEXT_REWRITE] = "ip4_rewrite",
> >                 [RTE_NODE_IP4_LOOKUP_NEXT_PKT_DROP] = "pkt_drop",
> >         },
> > diff --git a/lib/node/meson.build b/lib/node/meson.build
> > index 2fa7c1c8f3..c0d5b09e2f 100644
> > --- a/lib/node/meson.build
> > +++ b/lib/node/meson.build
> > @@ -12,6 +12,7 @@ sources = files(
> >          'ethdev_rx.c',
> >          'ethdev_tx.c',
> >          'ip4_lookup.c',
> > +        'ip4_local.c',
> >          'ip4_rewrite.c',
> >          'ip6_lookup.c',
> >          'ip6_rewrite.c',
> > diff --git a/lib/node/rte_node_ip4_api.h b/lib/node/rte_node_ip4_api.h
> > index 0f997761b6..40af3860b5 100644
> > --- a/lib/node/rte_node_ip4_api.h
> > +++ b/lib/node/rte_node_ip4_api.h
> > @@ -28,10 +28,22 @@ extern "C" {
> >  enum rte_node_ip4_lookup_next {
> >         RTE_NODE_IP4_LOOKUP_NEXT_REWRITE,
> >         /**< Rewrite node. */
> > +       RTE_NODE_IP4_LOOKUP_NEXT_IP4_LOCAL,
> > +       /** IP Local node. */
> >         RTE_NODE_IP4_LOOKUP_NEXT_PKT_DROP,
> >         /**< Number of next nodes of lookup node. */
> >  };
> >
> > +/**
> > + * IP4 Local next nodes.
> > + */
> > +enum rte_node_ip4_local_next {
> > +       RTE_NODE_IP4_LOCAL_NEXT_UDP4_INPUT,
> > +       /**< ip4 Local node. */
> > +       RTE_NODE_IP4_LOCAL_NEXT_PKT_DROP,
> > +       /**< Packet drop node. */
> > +};
> > +
> >  /**
> >   * Add ipv4 route to lookup table.
> >   *
> > --
> > 2.25.1
> >

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v6 2/2] node: add UDP v4 support
  2023-09-28 10:25           ` [PATCH v6 2/2] node: add UDP v4 support Rakesh Kudurumalla
@ 2023-09-29 10:58             ` Nithin Dabilpuram
  2023-10-17 11:44               ` Thomas Monjalon
  0 siblings, 1 reply; 16+ messages in thread
From: Nithin Dabilpuram @ 2023-09-29 10:58 UTC (permalink / raw)
  To: Rakesh Kudurumalla
  Cc: Jerin Jacob, Kiran Kumar K, Nithin Dabilpuram, Zhirun Yan,
	Pavan Nikhilesh, dev

Acked-by: Nithin Dabilpuram <ndabilpuram@marvell.com>

On Thu, Sep 28, 2023 at 4:06 PM Rakesh Kudurumalla
<rkudurumalla@marvell.com> wrote:
>
> IPv4 UDP packets are given to application
> with specified UDP destination port given
> by user.
>
> Signed-off-by: Rakesh Kudurumalla <rkudurumalla@marvell.com>
> ---
>  doc/api/doxy-api-index.md                     |   3 +-
>  doc/guides/prog_guide/graph_lib.rst           |  25 ++
>  .../img/graph_inbuilt_node_flow.svg           | 165 ++++++++-----
>  lib/node/meson.build                          |   2 +
>  lib/node/rte_node_udp4_input_api.h            |  61 +++++
>  lib/node/udp4_input.c                         | 226 ++++++++++++++++++
>  lib/node/version.map                          |   2 +
>  7 files changed, 418 insertions(+), 66 deletions(-)
>  create mode 100644 lib/node/rte_node_udp4_input_api.h
>  create mode 100644 lib/node/udp4_input.c
>
> diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
> index fdeda13932..96282d3fd0 100644
> --- a/doc/api/doxy-api-index.md
> +++ b/doc/api/doxy-api-index.md
> @@ -206,7 +206,8 @@ The public API headers are grouped by topics:
>    * graph_nodes:
>      [eth_node](@ref rte_node_eth_api.h),
>      [ip4_node](@ref rte_node_ip4_api.h),
> -    [ip6_node](@ref rte_node_ip6_api.h)
> +    [ip6_node](@ref rte_node_ip6_api.h),
> +    [udp4_input_node](@ref rte_node_udp4_input_api.h)
>
>  - **basic**:
>    [bitops](@ref rte_bitops.h),
> diff --git a/doc/guides/prog_guide/graph_lib.rst b/doc/guides/prog_guide/graph_lib.rst
> index f2e04a68b9..3572560362 100644
> --- a/doc/guides/prog_guide/graph_lib.rst
> +++ b/doc/guides/prog_guide/graph_lib.rst
> @@ -513,3 +513,28 @@ On packet_type lookup failure, objects are redirected to ``pkt_drop`` node.
>  depth to receive to packets.
>  To achieve home run, node use ``rte_node_stream_move()`` as mentioned in above
>  sections.
> +
> +udp4_input
> +~~~~~~~~~~
> +This node is an intermediate node that does udp destination port lookup for
> +the received ipv4 packets and the result determines each packets next node.
> +
> +User registers a new node ``udp4_input`` into graph library during initialization
> +and attach user specified node as edege to this node using
> +``rte_node_udp4_usr_node_add()``, and create empty hash table with destination
> +port and node id as its feilds.
> +
> +After successful addition of user node as edege, edge id is returned to the user.
> +
> +User would register ``ip4_lookup`` table with specified ip address and 32 bit as mask
> +for ip filtration using api ``rte_node_ip4_route_add()``.
> +
> +After graph is created user would update hash table with custom port with
> +and previously obtained edge id using API ``rte_node_udp4_dst_port_add()``.
> +
> +When packet is received lpm look up is performed if ip is matched the packet
> +is handed over to ip4_local node, then packet is verified for udp proto and
> +on success packet is enqueued to ``udp4_input`` node.
> +
> +Hash lookup is performed in ``udp4_input`` node with registered destination port
> +and destination port in UDP packet , on success packet is handed to ``udp_user_node``.
> diff --git a/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg b/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg
> index b954f6fba1..7c451371a7 100644
> --- a/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg
> +++ b/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg
> @@ -39,192 +39,227 @@ digraph dpdk_inbuilt_nodes_flow {
>      kernel_tx -> kernel_rx [color="red" style="dashed"]
>      ip4_lookup -> ip4_local
>      ip4_local -> pkt_drop [color="cyan" style="dashed"]
> +    ip4_local -> udp4_input [ label="udpv4"]
> +    udp4_input -> udp_user_node
> +    udp4_input -> pkt_drop [color="cyan" style="dashed"]
> +
>  }
>
>   -->
>  <!-- input nodes -->
>  <!-- Title: dpdk_inbuilt_nodes_flow Pages: 1 -->
> -<svg width="525pt" height="458pt"
> - viewBox="0.00 0.00 524.91 458.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 454)">
> +<svg width="631pt" height="437pt"
> + viewBox="0.00 0.00 630.95 437.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 433)">
>  <title>dpdk_inbuilt_nodes_flow</title>
> -<polygon fill="white" stroke="transparent" points="-4,4 -4,-454 520.91,-454 520.91,4 -4,4"/>
> +<polygon fill="white" stroke="transparent" points="-4,4 -4,-433 626.95,-433 626.95,4 -4,4"/>
>  <!-- ethdev_rx -->
>  <g id="node1" class="node">
>  <title>ethdev_rx</title>
> -<ellipse fill="none" stroke="green" cx="120" cy="-432" rx="56.59" ry="18"/>
> -<text text-anchor="middle" x="120" y="-428.3" font-family="Times,serif" font-size="14.00">ethdev_rx</text>
> +<ellipse fill="none" stroke="green" cx="261.95" cy="-411" rx="56.59" ry="18"/>
> +<text text-anchor="middle" x="261.95" y="-407.3" font-family="Times,serif" font-size="14.00">ethdev_rx</text>
>  </g>
>  <!-- pkt_cls -->
>  <g id="node6" class="node">
>  <title>pkt_cls</title>
> -<ellipse fill="none" stroke="red" cx="120" cy="-359" rx="42.79" ry="18"/>
> -<text text-anchor="middle" x="120" y="-355.3" font-family="Times,serif" font-size="14.00">pkt_cls</text>
> +<ellipse fill="none" stroke="red" cx="261.95" cy="-338" rx="42.79" ry="18"/>
> +<text text-anchor="middle" x="261.95" y="-334.3" font-family="Times,serif" font-size="14.00">pkt_cls</text>
>  </g>
>  <!-- ethdev_rx&#45;&gt;pkt_cls -->
>  <g id="edge1" class="edge">
>  <title>ethdev_rx&#45;&gt;pkt_cls</title>
> -<path fill="none" stroke="black" d="M120,-413.81C120,-405.79 120,-396.05 120,-387.07"/>
> -<polygon fill="black" stroke="black" points="123.5,-387.03 120,-377.03 116.5,-387.03 123.5,-387.03"/>
> +<path fill="none" stroke="black" d="M261.95,-392.81C261.95,-384.79 261.95,-375.05 261.95,-366.07"/>
> +<polygon fill="black" stroke="black" points="265.45,-366.03 261.95,-356.03 258.45,-366.03 265.45,-366.03"/>
>  </g>
>  <!-- kernel_rx -->
>  <g id="node2" class="node">
>  <title>kernel_rx</title>
> -<ellipse fill="none" stroke="green" cx="82" cy="-199" rx="53.89" ry="18"/>
> -<text text-anchor="middle" x="82" y="-195.3" font-family="Times,serif" font-size="14.00">kernel_rx</text>
> +<ellipse fill="none" stroke="green" cx="53.95" cy="-178" rx="53.89" ry="18"/>
> +<text text-anchor="middle" x="53.95" y="-174.3" font-family="Times,serif" font-size="14.00">kernel_rx</text>
>  </g>
>  <!-- kernel_rx&#45;&gt;pkt_cls -->
>  <g id="edge2" class="edge">
>  <title>kernel_rx&#45;&gt;pkt_cls</title>
> -<path fill="none" stroke="black" d="M70.87,-216.92C60.28,-235.27 47.29,-265.24 57,-290 64.12,-308.16 78.62,-324.37 91.92,-336.4"/>
> -<polygon fill="black" stroke="black" points="89.69,-339.1 99.54,-342.99 94.26,-333.8 89.69,-339.1"/>
> +<path fill="none" stroke="black" d="M74.75,-194.8C112.31,-223.33 191.45,-283.45 233.8,-315.62"/>
> +<polygon fill="black" stroke="black" points="231.92,-318.59 242,-321.85 236.16,-313.01 231.92,-318.59"/>
>  </g>
>  <!-- ethdev_tx -->
>  <g id="node3" class="node">
>  <title>ethdev_tx</title>
> -<ellipse fill="none" stroke="magenta" cx="338" cy="-91" rx="55.79" ry="18"/>
> -<text text-anchor="middle" x="338" y="-87.3" font-family="Times,serif" font-size="14.00">ethdev_tx</text>
> +<ellipse fill="none" stroke="magenta" cx="347.95" cy="-91" rx="55.79" ry="18"/>
> +<text text-anchor="middle" x="347.95" y="-87.3" font-family="Times,serif" font-size="14.00">ethdev_tx</text>
>  </g>
>  <!-- pkt_drop -->
>  <g id="node4" class="node">
>  <title>pkt_drop</title>
> -<ellipse fill="none" stroke="cyan" cx="254" cy="-18" rx="51.99" ry="18"/>
> -<text text-anchor="middle" x="254" y="-14.3" font-family="Times,serif" font-size="14.00">pkt_drop</text>
> +<ellipse fill="none" stroke="cyan" cx="404.95" cy="-18" rx="51.99" ry="18"/>
> +<text text-anchor="middle" x="404.95" y="-14.3" font-family="Times,serif" font-size="14.00">pkt_drop</text>
>  </g>
>  <!-- ethdev_tx&#45;&gt;pkt_drop -->
>  <g id="edge14" class="edge">
>  <title>ethdev_tx&#45;&gt;pkt_drop</title>
> -<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M318.94,-73.89C307.58,-64.29 293,-51.96 280.53,-41.42"/>
> -<polygon fill="cyan" stroke="cyan" points="282.59,-38.58 272.7,-34.8 278.07,-43.93 282.59,-38.58"/>
> +<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M361.45,-73.17C368.55,-64.33 377.39,-53.33 385.23,-43.55"/>
> +<polygon fill="cyan" stroke="cyan" points="388,-45.69 391.53,-35.71 382.54,-41.31 388,-45.69"/>
>  </g>
>  <!-- kernel_tx -->
>  <g id="node5" class="node">
>  <title>kernel_tx</title>
> -<ellipse fill="none" stroke="blue" cx="120" cy="-272" rx="53.89" ry="18"/>
> -<text text-anchor="middle" x="120" y="-268.3" font-family="Times,serif" font-size="14.00">kernel_tx</text>
> +<ellipse fill="none" stroke="blue" cx="53.95" cy="-251" rx="53.89" ry="18"/>
> +<text text-anchor="middle" x="53.95" y="-247.3" font-family="Times,serif" font-size="14.00">kernel_tx</text>
>  </g>
>  <!-- kernel_tx&#45;&gt;kernel_rx -->
>  <g id="edge16" class="edge">
>  <title>kernel_tx&#45;&gt;kernel_rx</title>
> -<path fill="none" stroke="red" stroke-dasharray="5,2" d="M110.99,-254.17C106.52,-245.81 101,-235.51 95.99,-226.14"/>
> -<polygon fill="red" stroke="red" points="99.01,-224.36 91.2,-217.2 92.84,-227.67 99.01,-224.36"/>
> +<path fill="none" stroke="red" stroke-dasharray="5,2" d="M53.95,-232.81C53.95,-224.79 53.95,-215.05 53.95,-206.07"/>
> +<polygon fill="red" stroke="red" points="57.45,-206.03 53.95,-196.03 50.45,-206.03 57.45,-206.03"/>
>  </g>
>  <!-- pkt_cls&#45;&gt;pkt_drop -->
>  <g id="edge15" class="edge">
>  <title>pkt_cls&#45;&gt;pkt_drop</title>
> -<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M84,-348.97C48.65,-337.7 0,-314.61 0,-273 0,-273 0,-273 0,-90 0,-49.99 118.4,-31.52 193.52,-23.82"/>
> -<polygon fill="cyan" stroke="cyan" points="194.21,-27.27 203.82,-22.81 193.52,-20.31 194.21,-27.27"/>
> +<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M304.77,-335.88C400.4,-332.2 622.95,-316.71 622.95,-252 622.95,-252 622.95,-252 622.95,-90 622.95,-56.33 527.72,-36.15 463.14,-26.34"/>
> +<polygon fill="cyan" stroke="cyan" points="463.46,-22.85 453.06,-24.85 462.44,-29.77 463.46,-22.85"/>
>  </g>
>  <!-- pkt_cls&#45;&gt;kernel_tx -->
>  <g id="edge5" class="edge">
>  <title>pkt_cls&#45;&gt;kernel_tx</title>
> -<path fill="none" stroke="blue" d="M120,-340.8C120,-329.16 120,-313.55 120,-300.24"/>
> -<polygon fill="blue" stroke="blue" points="123.5,-300.18 120,-290.18 116.5,-300.18 123.5,-300.18"/>
> -<text text-anchor="middle" x="172.5" y="-311.8" font-family="Times,serif" font-size="14.00">exception pkts</text>
> +<path fill="none" stroke="blue" d="M219.14,-335.96C164.86,-333.64 75.77,-326.15 54.95,-302 49.6,-295.81 48.06,-287.4 48.24,-279.24"/>
> +<polygon fill="blue" stroke="blue" points="51.73,-279.54 49.23,-269.24 44.76,-278.84 51.73,-279.54"/>
> +<text text-anchor="middle" x="107.45" y="-290.8" font-family="Times,serif" font-size="14.00">exception pkts</text>
>  </g>
>  <!-- ip4_lookup -->
>  <g id="node7" class="node">
>  <title>ip4_lookup</title>
> -<ellipse fill="none" stroke="black" cx="252" cy="-272" rx="60.39" ry="18"/>
> -<text text-anchor="middle" x="252" y="-268.3" font-family="Times,serif" font-size="14.00">ip4_lookup</text>
> +<ellipse fill="none" stroke="black" cx="261.95" cy="-251" rx="60.39" ry="18"/>
> +<text text-anchor="middle" x="261.95" y="-247.3" font-family="Times,serif" font-size="14.00">ip4_lookup</text>
>  </g>
>  <!-- pkt_cls&#45;&gt;ip4_lookup -->
>  <g id="edge3" class="edge">
>  <title>pkt_cls&#45;&gt;ip4_lookup</title>
> -<path fill="none" stroke="black" d="M160.54,-352.79C182.64,-348.15 209.23,-339.41 228,-323 235.09,-316.81 240.26,-308.05 243.95,-299.6"/>
> -<polygon fill="black" stroke="black" points="247.32,-300.57 247.62,-289.98 240.78,-298.07 247.32,-300.57"/>
> -<text text-anchor="middle" x="254.5" y="-311.8" font-family="Times,serif" font-size="14.00">ipv4</text>
> +<path fill="none" stroke="black" d="M261.95,-319.8C261.95,-308.16 261.95,-292.55 261.95,-279.24"/>
> +<polygon fill="black" stroke="black" points="265.45,-279.18 261.95,-269.18 258.45,-279.18 265.45,-279.18"/>
> +<text text-anchor="middle" x="277.45" y="-290.8" font-family="Times,serif" font-size="14.00">ipv4</text>
>  </g>
>  <!-- ip6_lookup -->
>  <g id="node8" class="node">
>  <title>ip6_lookup</title>
> -<ellipse fill="none" stroke="black" cx="439" cy="-272" rx="60.39" ry="18"/>
> -<text text-anchor="middle" x="439" y="-268.3" font-family="Times,serif" font-size="14.00">ip6_lookup</text>
> +<ellipse fill="none" stroke="black" cx="492.95" cy="-251" rx="60.39" ry="18"/>
> +<text text-anchor="middle" x="492.95" y="-247.3" font-family="Times,serif" font-size="14.00">ip6_lookup</text>
>  </g>
>  <!-- pkt_cls&#45;&gt;ip6_lookup -->
>  <g id="edge4" class="edge">
>  <title>pkt_cls&#45;&gt;ip6_lookup</title>
> -<path fill="none" stroke="black" d="M157.52,-350.25C188.82,-343.6 234.51,-333.46 274,-323 313.2,-312.62 357.13,-299.22 389.79,-288.91"/>
> -<polygon fill="black" stroke="black" points="391.08,-292.17 399.55,-285.81 388.96,-285.5 391.08,-292.17"/>
> -<text text-anchor="middle" x="339.5" y="-311.8" font-family="Times,serif" font-size="14.00">ipv6</text>
> +<path fill="none" stroke="black" d="M293.1,-325.54C332.57,-311.01 400.93,-285.86 446.54,-269.07"/>
> +<polygon fill="black" stroke="black" points="448.02,-272.26 456.2,-265.52 445.61,-265.69 448.02,-272.26"/>
> +<text text-anchor="middle" x="407.45" y="-290.8" font-family="Times,serif" font-size="14.00">ipv6</text>
>  </g>
>  <!-- ip4_lookup&#45;&gt;pkt_drop -->
>  <g id="edge7" class="edge">
>  <title>ip4_lookup&#45;&gt;pkt_drop</title>
> -<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M239.17,-254.03C232.31,-243.87 224.56,-230.37 221,-217 204.89,-156.57 227.58,-83.56 242.59,-45.31"/>
> -<polygon fill="cyan" stroke="cyan" points="245.89,-46.5 246.4,-35.92 239.4,-43.87 245.89,-46.5"/>
> +<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M258.85,-232.91C253.68,-198.83 247.1,-121.54 282.95,-73 299.1,-51.12 326.1,-37.95 350.6,-30.11"/>
> +<polygon fill="cyan" stroke="cyan" points="351.6,-33.46 360.19,-27.26 349.61,-26.75 351.6,-33.46"/>
>  </g>
>  <!-- ip4_rewrite -->
>  <g id="node9" class="node">
>  <title>ip4_rewrite</title>
> -<ellipse fill="none" stroke="black" cx="294" cy="-199" rx="63.89" ry="18"/>
> -<text text-anchor="middle" x="294" y="-195.3" font-family="Times,serif" font-size="14.00">ip4_rewrite</text>
> +<ellipse fill="none" stroke="black" cx="347.95" cy="-178" rx="63.89" ry="18"/>
> +<text text-anchor="middle" x="347.95" y="-174.3" font-family="Times,serif" font-size="14.00">ip4_rewrite</text>
>  </g>
>  <!-- ip4_lookup&#45;&gt;ip4_rewrite -->
>  <g id="edge6" class="edge">
>  <title>ip4_lookup&#45;&gt;ip4_rewrite</title>
> -<path fill="none" stroke="black" d="M261.95,-254.17C266.95,-245.72 273.12,-235.29 278.71,-225.85"/>
> -<polygon fill="black" stroke="black" points="281.75,-227.59 283.83,-217.2 275.72,-224.02 281.75,-227.59"/>
> +<path fill="none" stroke="black" d="M281.46,-233.89C292.92,-224.42 307.6,-212.31 320.25,-201.87"/>
> +<polygon fill="black" stroke="black" points="322.73,-204.36 328.21,-195.29 318.27,-198.96 322.73,-204.36"/>
>  </g>
>  <!-- ip4_local -->
>  <g id="node11" class="node">
>  <title>ip4_local</title>
> -<ellipse fill="none" stroke="black" cx="136" cy="-145" rx="51.19" ry="18"/>
> -<text text-anchor="middle" x="136" y="-141.3" font-family="Times,serif" font-size="14.00">ip4_local</text>
> +<ellipse fill="none" stroke="black" cx="176.95" cy="-178" rx="51.19" ry="18"/>
> +<text text-anchor="middle" x="176.95" y="-174.3" font-family="Times,serif" font-size="14.00">ip4_local</text>
>  </g>
>  <!-- ip4_lookup&#45;&gt;ip4_local -->
>  <g id="edge17" class="edge">
>  <title>ip4_lookup&#45;&gt;ip4_local</title>
> -<path fill="none" stroke="black" d="M218.11,-256.86C207.64,-251.39 196.61,-244.41 188,-236 169.45,-217.88 155.34,-191.74 146.53,-172.29"/>
> -<polygon fill="black" stroke="black" points="149.72,-170.86 142.52,-163.08 143.3,-173.65 149.72,-170.86"/>
> +<path fill="none" stroke="black" d="M242.66,-233.89C231.17,-224.29 216.41,-211.96 203.79,-201.42"/>
> +<polygon fill="black" stroke="black" points="205.78,-198.53 195.86,-194.8 201.29,-203.9 205.78,-198.53"/>
>  </g>
>  <!-- ip6_lookup&#45;&gt;pkt_drop -->
>  <g id="edge11" class="edge">
>  <title>ip6_lookup&#45;&gt;pkt_drop</title>
> -<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M470.57,-256.44C486.08,-247.46 503.27,-234.31 512,-217 519.2,-202.71 517.24,-196.12 512,-181 486.88,-108.48 466,-83.15 395,-54 367.69,-42.79 335.88,-34.51 309.39,-28.83"/>
> -<polygon fill="cyan" stroke="cyan" points="310.02,-25.39 299.52,-26.78 308.6,-32.24 310.02,-25.39"/>
> +<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M524.51,-235.44C540.02,-226.46 557.22,-213.31 565.95,-196 573.15,-181.71 572.55,-174.57 565.95,-160 540.59,-104.08 480.88,-61.6 441.74,-38.51"/>
> +<polygon fill="cyan" stroke="cyan" points="443.16,-35.29 432.75,-33.34 439.67,-41.36 443.16,-35.29"/>
>  </g>
>  <!-- ip6_rewrite -->
>  <g id="node10" class="node">
>  <title>ip6_rewrite</title>
> -<ellipse fill="none" stroke="black" cx="439" cy="-199" rx="63.89" ry="18"/>
> -<text text-anchor="middle" x="439" y="-195.3" font-family="Times,serif" font-size="14.00">ip6_rewrite</text>
> +<ellipse fill="none" stroke="black" cx="492.95" cy="-178" rx="63.89" ry="18"/>
> +<text text-anchor="middle" x="492.95" y="-174.3" font-family="Times,serif" font-size="14.00">ip6_rewrite</text>
>  </g>
>  <!-- ip6_lookup&#45;&gt;ip6_rewrite -->
>  <g id="edge10" class="edge">
>  <title>ip6_lookup&#45;&gt;ip6_rewrite</title>
> -<path fill="none" stroke="black" d="M439,-253.81C439,-245.79 439,-236.05 439,-227.07"/>
> -<polygon fill="black" stroke="black" points="442.5,-227.03 439,-217.03 435.5,-227.03 442.5,-227.03"/>
> +<path fill="none" stroke="black" d="M492.95,-232.81C492.95,-224.79 492.95,-215.05 492.95,-206.07"/>
> +<polygon fill="black" stroke="black" points="496.45,-206.03 492.95,-196.03 489.45,-206.03 496.45,-206.03"/>
>  </g>
>  <!-- ip4_rewrite&#45;&gt;ethdev_tx -->
>  <g id="edge8" class="edge">
>  <title>ip4_rewrite&#45;&gt;ethdev_tx</title>
> -<path fill="none" stroke="green" d="M301.07,-180.97C308.09,-164.05 318.96,-137.86 327.09,-118.28"/>
> -<polygon fill="green" stroke="green" points="330.35,-119.57 330.95,-108.99 323.88,-116.88 330.35,-119.57"/>
> +<path fill="none" stroke="green" d="M347.95,-159.8C347.95,-148.16 347.95,-132.55 347.95,-119.24"/>
> +<polygon fill="green" stroke="green" points="351.45,-119.18 347.95,-109.18 344.45,-119.18 351.45,-119.18"/>
>  </g>
>  <!-- ip4_rewrite&#45;&gt;pkt_drop -->
>  <g id="edge9" class="edge">
>  <title>ip4_rewrite&#45;&gt;pkt_drop</title>
> -<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M289.85,-180.97C285.53,-163.07 278.61,-134.1 273,-109 268.3,-87.99 263.29,-64.16 259.59,-46.3"/>
> -<polygon fill="cyan" stroke="cyan" points="262.97,-45.37 257.52,-36.28 256.11,-46.78 262.97,-45.37"/>
> +<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M370.32,-161.1C385.53,-148.83 404.37,-130.37 412.95,-109 421.04,-88.82 418.02,-64.12 413.56,-45.7"/>
> +<polygon fill="cyan" stroke="cyan" points="416.9,-44.66 410.91,-35.93 410.15,-46.49 416.9,-44.66"/>
>  </g>
>  <!-- ip6_rewrite&#45;&gt;ethdev_tx -->
>  <g id="edge12" class="edge">
>  <title>ip6_rewrite&#45;&gt;ethdev_tx</title>
> -<path fill="none" stroke="green" d="M423.22,-181.44C406.47,-163.86 379.84,-135.91 360.81,-115.94"/>
> -<polygon fill="green" stroke="green" points="363.1,-113.27 353.67,-108.45 358.03,-118.1 363.1,-113.27"/>
> +<path fill="none" stroke="green" d="M466.35,-161.41C442.8,-147.6 408.27,-127.36 382.57,-112.3"/>
> +<polygon fill="green" stroke="green" points="384.28,-109.24 373.88,-107.21 380.74,-115.28 384.28,-109.24"/>
>  </g>
>  <!-- ip6_rewrite&#45;&gt;pkt_drop -->
>  <g id="edge13" class="edge">
>  <title>ip6_rewrite&#45;&gt;pkt_drop</title>
> -<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M438.77,-180.67C437.49,-154.09 431.22,-103.19 403,-73 379.35,-47.7 342.93,-34.22 312.02,-27.06"/>
> -<polygon fill="cyan" stroke="cyan" points="312.71,-23.63 302.2,-24.95 311.24,-30.47 312.71,-23.63"/>
> +<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M485.15,-159.86C473.93,-135.7 452.15,-90.48 429.95,-54 427.97,-50.75 425.78,-47.4 423.55,-44.13"/>
> +<polygon fill="cyan" stroke="cyan" points="426.28,-41.92 417.67,-35.75 420.55,-45.94 426.28,-41.92"/>
>  </g>
>  <!-- ip4_local&#45;&gt;pkt_drop -->
>  <g id="edge18" class="edge">
>  <title>ip4_local&#45;&gt;pkt_drop</title>
> -<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M142.47,-126.87C150.6,-107.23 166.18,-75.04 188,-54 195,-47.25 203.56,-41.45 212.16,-36.63"/>
> -<polygon fill="cyan" stroke="cyan" points="213.85,-39.7 221.08,-31.95 210.6,-33.5 213.85,-39.7"/>
> +<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M191.02,-160.51C195.47,-154.86 200.21,-148.35 203.95,-142 225.57,-105.29 209.02,-81.03 241.95,-54 257.83,-40.96 306.22,-31.62 346.19,-25.89"/>
> +<polygon fill="cyan" stroke="cyan" points="346.72,-29.35 356.14,-24.51 345.75,-22.41 346.72,-29.35"/>
> +</g>
> +<!-- udp4_input -->
> +<g id="node12" class="node">
> +<title>udp4_input</title>
> +<ellipse fill="none" stroke="black" cx="126.95" cy="-91" rx="63.09" ry="18"/>
> +<text text-anchor="middle" x="126.95" y="-87.3" font-family="Times,serif" font-size="14.00">udp4_input</text>
> +</g>
> +<!-- ip4_local&#45;&gt;udp4_input -->
> +<g id="edge19" class="edge">
> +<title>ip4_local&#45;&gt;udp4_input</title>
> +<path fill="none" stroke="black" d="M167.07,-160.21C159.99,-148.18 150.33,-131.75 142.26,-118.03"/>
> +<polygon fill="black" stroke="black" points="145.06,-115.89 136.97,-109.05 139.03,-119.44 145.06,-115.89"/>
> +<text text-anchor="middle" x="177.45" y="-130.8" font-family="Times,serif" font-size="14.00">udpv4</text>
> +</g>
> +<!-- udp4_input&#45;&gt;pkt_drop -->
> +<g id="edge21" class="edge">
> +<title>udp4_input&#45;&gt;pkt_drop</title>
> +<path fill="none" stroke="cyan" stroke-dasharray="5,2" d="M154.75,-74.82C169.08,-67.56 187.05,-59.32 203.95,-54 250.51,-39.35 305.19,-30.33 345.76,-25.12"/>
> +<polygon fill="cyan" stroke="cyan" points="346.26,-28.59 355.75,-23.88 345.4,-21.64 346.26,-28.59"/>
> +</g>
> +<!-- udp_user_node -->
> +<g id="node13" class="node">
> +<title>udp_user_node</title>
> +<ellipse fill="none" stroke="black" cx="126.95" cy="-18" rx="79.89" ry="18"/>
> +<text text-anchor="middle" x="126.95" y="-14.3" font-family="Times,serif" font-size="14.00">udp_user_node</text>
> +</g>
> +<!-- udp4_input&#45;&gt;udp_user_node -->
> +<g id="edge20" class="edge">
> +<title>udp4_input&#45;&gt;udp_user_node</title>
> +<path fill="none" stroke="black" d="M126.95,-72.81C126.95,-64.79 126.95,-55.05 126.95,-46.07"/>
> +<polygon fill="black" stroke="black" points="130.45,-46.03 126.95,-36.03 123.45,-46.03 130.45,-46.03"/>
>  </g>
>  </g>
>  </svg>
> diff --git a/lib/node/meson.build b/lib/node/meson.build
> index c0d5b09e2f..c5b8ee656e 100644
> --- a/lib/node/meson.build
> +++ b/lib/node/meson.build
> @@ -22,11 +22,13 @@ sources = files(
>          'null.c',
>          'pkt_cls.c',
>          'pkt_drop.c',
> +        'udp4_input.c',
>  )
>  headers = files(
>          'rte_node_eth_api.h',
>          'rte_node_ip4_api.h',
>          'rte_node_ip6_api.h',
> +        'rte_node_udp4_input_api.h',
>  )
>
>  # Strict-aliasing rules are violated by uint8_t[] to context size casts.
> diff --git a/lib/node/rte_node_udp4_input_api.h b/lib/node/rte_node_udp4_input_api.h
> new file mode 100644
> index 0000000000..c873acbbe0
> --- /dev/null
> +++ b/lib/node/rte_node_udp4_input_api.h
> @@ -0,0 +1,61 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(C) 2023 Marvell International Ltd.
> + */
> +
> +#ifndef __INCLUDE_RTE_NODE_UDP4_INPUT_API_H__
> +#define __INCLUDE_RTE_NODE_UDP4_INPUT_API_H__
> +
> +/**
> + * @file rte_node_udp4_input_api.h
> + *
> + * @warning
> + * @b EXPERIMENTAL:
> + * All functions in this file may be changed or removed without prior notice.
> + *
> + * This API allows to control path functions of udp4_* nodes
> + * like udp4_input.
> + *
> + */
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +#include <rte_common.h>
> +#include <rte_compat.h>
> +
> +#include "rte_graph.h"
> +/**
> + * UDP4 lookup next nodes.
> + */
> +enum rte_node_udp4_input_next {
> +       RTE_NODE_UDP4_INPUT_NEXT_PKT_DROP,
> +       /**< Packet drop node. */
> +};
> +
> +/**
> + * Add usr node to receive udp4 frames.
> + *
> + * @param usr_node
> + * Node registered by user to receive data.
> + */
> +__rte_experimental
> +int rte_node_udp4_usr_node_add(const char *usr_node);
> +
> +/**
> + * Add udpv4 dst_port to lookup table.
> + *
> + * @param dst_port
> + *   Dst Port of packet to be added for consumption.
> + * @param next_node
> + *   Next node packet to be added for consumption.
> + * @return
> + *   0 on success, negative otherwise.
> + */
> +__rte_experimental
> +int rte_node_udp4_dst_port_add(uint32_t dst_port, rte_edge_t next_node);
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif /* __INCLUDE_RTE_NODE_UDP4_API_H__ */
> diff --git a/lib/node/udp4_input.c b/lib/node/udp4_input.c
> new file mode 100644
> index 0000000000..80cedce548
> --- /dev/null
> +++ b/lib/node/udp4_input.c
> @@ -0,0 +1,226 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(C) 2023 Marvell International Ltd.
> + */
> +
> +#include <arpa/inet.h>
> +#include <sys/socket.h>
> +
> +#include <rte_ethdev.h>
> +#include <rte_ether.h>
> +#include <rte_graph.h>
> +#include <rte_graph_worker.h>
> +#include <rte_ip.h>
> +#include <rte_lpm.h>
> +#include <rte_hash.h>
> +#include <rte_fbk_hash.h>
> +#include <rte_jhash.h>
> +#include <rte_hash_crc.h>
> +
> +
> +#include "rte_node_udp4_input_api.h"
> +
> +#include "node_private.h"
> +
> +#define UDP4_INPUT_HASH_TBL_SIZE 1024
> +
> +#define UDP4_INPUT_NODE_HASH(ctx) \
> +       (((struct udp4_input_node_ctx *)ctx)->hash)
> +
> +#define UDP4_INPUT_NODE_NEXT_INDEX(ctx) \
> +       (((struct udp4_input_node_ctx *)ctx)->next_index)
> +
> +
> +/* UDP4 input  global data struct */
> +struct udp4_input_node_main {
> +       struct rte_hash *hash_tbl[RTE_MAX_NUMA_NODES];
> +};
> +
> +static struct udp4_input_node_main udp4_input_nm;
> +
> +struct udp4_input_node_ctx {
> +       /* Socket's Hash table */
> +       struct rte_hash *hash;
> +       /* Cached next index */
> +       uint16_t next_index;
> +};
> +
> +struct flow_key {
> +       uint32_t prt_dst;
> +};
> +
> +static struct rte_hash_parameters udp4_params = {
> +       .entries = UDP4_INPUT_HASH_TBL_SIZE,
> +       .key_len = sizeof(uint32_t),
> +       .hash_func = rte_jhash,
> +       .hash_func_init_val = 0,
> +       .socket_id = 0,
> +};
> +
> +int
> +rte_node_udp4_dst_port_add(uint32_t dst_port, rte_edge_t next_node)
> +{
> +       uint8_t socket;
> +       int rc;
> +
> +       for (socket = 0; socket < RTE_MAX_NUMA_NODES; socket++) {
> +               if (!udp4_input_nm.hash_tbl[socket])
> +                       continue;
> +
> +               rc = rte_hash_add_key_data(udp4_input_nm.hash_tbl[socket],
> +                                          &dst_port, (void *)(uintptr_t)next_node);
> +               if (rc < 0) {
> +                       node_err("udp4_lookup", "Failed to add key for sock %u, rc=%d",
> +                                       socket, rc);
> +                       return rc;
> +               }
> +       }
> +       return 0;
> +}
> +
> +int
> +rte_node_udp4_usr_node_add(const char *usr_node)
> +{
> +       const char *next_nodes = usr_node;
> +       rte_node_t udp4_input_node_id, count;
> +
> +       udp4_input_node_id = rte_node_from_name("udp4_input");
> +       count = rte_node_edge_update(udp4_input_node_id, RTE_EDGE_ID_INVALID,
> +                                    &next_nodes, 1);
> +       if (count == 0) {
> +               node_dbg("udp4_input", "Adding usr node as edge to udp4_input failed");
> +               return count;
> +       }
> +       count = rte_node_edge_count(udp4_input_node_id) - 1;
> +       return count;
> +}
> +
> +static int
> +setup_udp4_dstprt_hash(struct udp4_input_node_main *nm, int socket)
> +{
> +       struct rte_hash_parameters *hash_udp4 = &udp4_params;
> +       char s[RTE_HASH_NAMESIZE];
> +
> +       /* One Hash table per socket */
> +       if (nm->hash_tbl[socket])
> +               return 0;
> +
> +       /* create Hash table */
> +       snprintf(s, sizeof(s), "UDP4_INPUT_HASH_%d", socket);
> +       hash_udp4->name = s;
> +       hash_udp4->socket_id = socket;
> +       nm->hash_tbl[socket] = rte_hash_create(hash_udp4);
> +       if (nm->hash_tbl[socket] == NULL)
> +               return -rte_errno;
> +
> +       return 0;
> +}
> +
> +static int
> +udp4_input_node_init(const struct rte_graph *graph, struct rte_node *node)
> +{
> +       uint16_t socket, lcore_id;
> +       static uint8_t init_once;
> +       int rc;
> +
> +       RTE_SET_USED(graph);
> +       RTE_BUILD_BUG_ON(sizeof(struct udp4_input_node_ctx) > RTE_NODE_CTX_SZ);
> +
> +       if (!init_once) {
> +
> +               /* Setup HASH tables for all sockets */
> +               RTE_LCORE_FOREACH(lcore_id)
> +               {
> +                       socket = rte_lcore_to_socket_id(lcore_id);
> +                       rc = setup_udp4_dstprt_hash(&udp4_input_nm, socket);
> +                       if (rc) {
> +                               node_err("udp4_lookup",
> +                                               "Failed to setup hash tbl for sock %u, rc=%d",
> +                                               socket, rc);
> +                               return rc;
> +                       }
> +               }
> +               init_once = 1;
> +       }
> +
> +       UDP4_INPUT_NODE_HASH(node->ctx) = udp4_input_nm.hash_tbl[graph->socket];
> +
> +       node_dbg("udp4_input", "Initialized udp4_input node");
> +       return 0;
> +}
> +
> +static uint16_t
> +udp4_input_node_process_scalar(struct rte_graph *graph, struct rte_node *node,
> +                              void **objs, uint16_t nb_objs)
> +{
> +       struct rte_hash *hash_tbl_handle = UDP4_INPUT_NODE_HASH(node->ctx);
> +       rte_edge_t next_index, udplookup_node;
> +       struct rte_udp_hdr *pkt_udp_hdr;
> +       uint16_t last_spec = 0;
> +       void **to_next, **from;
> +       struct rte_mbuf *mbuf;
> +       uint16_t held = 0;
> +       uint16_t next = 0;
> +       int i, rc;
> +
> +       /* Speculative next */
> +       next_index = UDP4_INPUT_NODE_NEXT_INDEX(node->ctx);
> +
> +       from = objs;
> +
> +       to_next = rte_node_next_stream_get(graph, node, next_index, nb_objs);
> +       for (i = 0; i < nb_objs; i++) {
> +               struct flow_key key_port;
> +
> +               mbuf = (struct rte_mbuf *)objs[i];
> +               pkt_udp_hdr = rte_pktmbuf_mtod_offset(mbuf, struct rte_udp_hdr *,
> +                                               sizeof(struct rte_ether_hdr) +
> +                                               sizeof(struct rte_ipv4_hdr));
> +
> +               key_port.prt_dst = rte_cpu_to_be_16(pkt_udp_hdr->dst_port);
> +               rc = rte_hash_lookup_data(hash_tbl_handle,
> +                                         &key_port.prt_dst,
> +                                         (void **)&udplookup_node);
> +               next = (rc < 0) ? RTE_NODE_UDP4_INPUT_NEXT_PKT_DROP
> +                                   : udplookup_node;
> +
> +               if (unlikely(next_index != next)) {
> +                       /* Copy things successfully speculated till now */
> +                       rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
> +                       from += last_spec;
> +                       to_next += last_spec;
> +                       held += last_spec;
> +                       last_spec = 0;
> +
> +                       rte_node_enqueue_x1(graph, node, next, from[0]);
> +                       from += 1;
> +               } else {
> +                       last_spec += 1;
> +               }
> +       }
> +       /* !!! Home run !!! */
> +       if (likely(last_spec == nb_objs)) {
> +               rte_node_next_stream_move(graph, node, next_index);
> +               return nb_objs;
> +       }
> +       held += last_spec;
> +       rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
> +       rte_node_next_stream_put(graph, node, next_index, held);
> +       /* Save the last next used */
> +       UDP4_INPUT_NODE_NEXT_INDEX(node->ctx) = next;
> +
> +       return nb_objs;
> +}
> +
> +static struct rte_node_register udp4_input_node = {
> +       .process = udp4_input_node_process_scalar,
> +       .name = "udp4_input",
> +
> +       .init = udp4_input_node_init,
> +
> +       .nb_edges = RTE_NODE_UDP4_INPUT_NEXT_PKT_DROP + 1,
> +       .next_nodes = {
> +               [RTE_NODE_UDP4_INPUT_NEXT_PKT_DROP] = "pkt_drop",
> +       },
> +};
> +
> +RTE_NODE_REGISTER(udp4_input_node);
> diff --git a/lib/node/version.map b/lib/node/version.map
> index 40df308bfe..c51befce09 100644
> --- a/lib/node/version.map
> +++ b/lib/node/version.map
> @@ -6,6 +6,8 @@ EXPERIMENTAL {
>         rte_node_ip4_rewrite_add;
>         rte_node_ip6_rewrite_add;
>         rte_node_ip6_route_add;
> +       rte_node_udp4_usr_node_add;
> +       rte_node_udp4_dst_port_add;
>         rte_node_logtype;
>         local: *;
>  };
> --
> 2.25.1
>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v6 2/2] node: add UDP v4 support
  2023-09-29 10:58             ` Nithin Dabilpuram
@ 2023-10-17 11:44               ` Thomas Monjalon
  0 siblings, 0 replies; 16+ messages in thread
From: Thomas Monjalon @ 2023-10-17 11:44 UTC (permalink / raw)
  To: Rakesh Kudurumalla
  Cc: dev, Jerin Jacob, Kiran Kumar K, Nithin Dabilpuram, Zhirun Yan,
	Pavan Nikhilesh, dev, Nithin Dabilpuram, david.marchand

29/09/2023 12:58, Nithin Dabilpuram:
> On Thu, Sep 28, 2023 at 4:06 PM Rakesh Kudurumalla
> <rkudurumalla@marvell.com> wrote:
> >
> > IPv4 UDP packets are given to application
> > with specified UDP destination port given
> > by user.
> >
> > Signed-off-by: Rakesh Kudurumalla <rkudurumalla@marvell.com>
> Acked-by: Nithin Dabilpuram <ndabilpuram@marvell.com>

Series applied, thanks.

Note: I've inserted version information in version.map
as we do for experimental symbols in other libraries.
It helps to check what is experimental for long.



^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2023-10-17 11:44 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-07-03  9:13 [PATCH 1/2] node: add IPv4 local node to handle local pkts Rakesh Kudurumalla
2023-07-03  9:13 ` [PATCH 2/2] node: add UDP v4 support Rakesh Kudurumalla
2023-07-03 10:05 ` [PATCH v2 1/2] node: add IPv4 local node to handle local pkts Rakesh Kudurumalla
2023-07-03 10:05   ` [PATCH v2 2/2] node: add UDP v4 support Rakesh Kudurumalla
2023-07-04 10:50   ` [PATCH v3 1/2] node: add IPv4 local node to handle local pkts Rakesh Kudurumalla
2023-07-04 10:50     ` [PATCH v3 2/2] node: add UDP v4 support Rakesh Kudurumalla
2023-09-27  9:21     ` [PATCH v4 1/2] node: add IPv4 local node to handle local pkts Rakesh Kudurumalla
2023-09-27  9:21       ` [PATCH v4 2/2] node: add UDP v4 support Rakesh Kudurumalla
2023-09-27 12:40       ` [PATCH v5 1/2] node: add IPv4 local node to handle local pkts Rakesh Kudurumalla
2023-09-27 12:41         ` [PATCH v5 2/2] node: add UDP v4 support Rakesh Kudurumalla
2023-09-28 10:25         ` [PATCH v6 1/2] node: add IPv4 local node to handle local pkts Rakesh Kudurumalla
2023-09-28 10:25           ` [PATCH v6 2/2] node: add UDP v4 support Rakesh Kudurumalla
2023-09-29 10:58             ` Nithin Dabilpuram
2023-10-17 11:44               ` Thomas Monjalon
2023-09-29 10:54           ` [PATCH v6 1/2] node: add IPv4 local node to handle local pkts Nithin Dabilpuram
2023-09-29 10:58             ` Nithin Dabilpuram

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).