xref: /dpdk/doc/guides/prog_guide/rib_lib.rst (revision 41dd9a6bc2d9c6e20e139ad713cc9d172572dd43)
1f3aa363dSVladimir Medvedkin..  SPDX-License-Identifier: BSD-3-Clause
2f3aa363dSVladimir Medvedkin    Copyright(c) 2021 Intel Corporation.
3f3aa363dSVladimir Medvedkin
4*41dd9a6bSDavid YoungRouting Information Base (RIB) Library
5*41dd9a6bSDavid Young======================================
6f3aa363dSVladimir Medvedkin
7f3aa363dSVladimir MedvedkinThe Routing Information Base (RIB) library provides a data store for routing information.
8f3aa363dSVladimir MedvedkinThis library is intended for use in control or management plane applications.
9f3aa363dSVladimir MedvedkinThere are more suitable libraries for use in data plane applications such as
10f3aa363dSVladimir Medvedkin:doc:`lpm_lib` or :doc:`fib_lib`.
11f3aa363dSVladimir Medvedkin
12f3aa363dSVladimir Medvedkin
13f3aa363dSVladimir MedvedkinImplementation details
14f3aa363dSVladimir Medvedkin----------------------
15f3aa363dSVladimir Medvedkin
16f3aa363dSVladimir MedvedkinRIB implements a key-value store for routing information.
17f3aa363dSVladimir Medvedkin
18f3aa363dSVladimir MedvedkinRouting information is represented by a prefix (key) and a next hop ID (value).
19f3aa363dSVladimir MedvedkinThe prefix type depends on the address family. IPv4 addresses are represented by
20f3aa363dSVladimir Medvedkin``uint32_t`` values. IPv6 addresses are represented as ``uint8_t[16]`` values.
21f3aa363dSVladimir MedvedkinNext hop IDs are represented by ``uint64_t`` values.
22f3aa363dSVladimir Medvedkin
23f3aa363dSVladimir Medvedkin.. note::
24f3aa363dSVladimir Medvedkin
25f3aa363dSVladimir Medvedkin   The API and implementation are very similar for IPv4 ``rte_rib`` API and IPv6 ``rte_rib6``
26f3aa363dSVladimir Medvedkin   API, therefore only the ``rte_rib`` API will be discussed here.
27f3aa363dSVladimir Medvedkin   Everything within this document except for the size of the prefixes is applicable to  the
28f3aa363dSVladimir Medvedkin   ``rte_rib6`` API.
29f3aa363dSVladimir Medvedkin
30f3aa363dSVladimir MedvedkinInternally RIB is represented as a binary tree as shown in :numref:`figure_rib_internals`:
31f3aa363dSVladimir Medvedkin
32f3aa363dSVladimir Medvedkin.. _figure_rib_internals:
33f3aa363dSVladimir Medvedkin
34f3aa363dSVladimir Medvedkin.. figure:: img/rib_internals.*
35f3aa363dSVladimir Medvedkin
36f3aa363dSVladimir Medvedkin   RIB internals overview
37f3aa363dSVladimir Medvedkin
38f3aa363dSVladimir MedvedkinThe binary tree consists of two types of nodes:
39f3aa363dSVladimir Medvedkin
40f3aa363dSVladimir Medvedkin* Actual Routes.
41f3aa363dSVladimir Medvedkin
42f3aa363dSVladimir Medvedkin* Intermediate Nodes which are used internally to preserve the binary tree structure.
43f3aa363dSVladimir Medvedkin
44f3aa363dSVladimir Medvedkin
45f3aa363dSVladimir MedvedkinRIB API Overview
46f3aa363dSVladimir Medvedkin----------------
47f3aa363dSVladimir Medvedkin
48f3aa363dSVladimir MedvedkinRIB has two configuration parameters:
49f3aa363dSVladimir Medvedkin
50f3aa363dSVladimir Medvedkin* The maximum number of nodes.
51f3aa363dSVladimir Medvedkin
52f3aa363dSVladimir Medvedkin* The size of the extension block within each node. This space is used to store
53f3aa363dSVladimir Medvedkin  additional user defined data.
54f3aa363dSVladimir Medvedkin
55f3aa363dSVladimir MedvedkinThe main methods within the ``rte_rib`` API are:
56f3aa363dSVladimir Medvedkin
57f3aa363dSVladimir Medvedkin* ``rte_rib_insert()``: Add new routes.
58f3aa363dSVladimir Medvedkin
59f3aa363dSVladimir Medvedkin* ``rte_rib_remove()``: Delete an existing route.
60f3aa363dSVladimir Medvedkin
61f3aa363dSVladimir Medvedkin* ``rte_rib_lookup()``: Lookup an IP in the structure using longest match.
62f3aa363dSVladimir Medvedkin
63f3aa363dSVladimir Medvedkin* ``rte_rib_lookup_exact()``: Lookup an IP in the structure using exact match.
64f3aa363dSVladimir Medvedkin
65f3aa363dSVladimir Medvedkin* ``rte_rib_lookup_parent()``: Find a parent prefix within the structure.
66f3aa363dSVladimir Medvedkin
67f3aa363dSVladimir Medvedkin* ``rte_rib_get_nxt()``: Traverse a subtree within the structure.
68f3aa363dSVladimir Medvedkin
69f3aa363dSVladimir MedvedkinGiven a RIB structure with the routes depicted in :numref:`figure_rib_internals`,
70f3aa363dSVladimir Medvedkinhere are several usage examples:
71f3aa363dSVladimir Medvedkin
72f3aa363dSVladimir Medvedkin* The best route for ``10.0.0.1`` can be found by calling:
73f3aa363dSVladimir Medvedkin
74f3aa363dSVladimir Medvedkin.. code-block:: c
75f3aa363dSVladimir Medvedkin
76f3aa363dSVladimir Medvedkin      struct rte_rib_node *route = rte_rib_lookup(rib, RTE_IPV4(10,0,0,1));
77f3aa363dSVladimir Medvedkin
78f3aa363dSVladimir MedvedkinThis returns an ``rte_rib_node`` pointing to the ``10.0.0.0/29`` prefix.
79f3aa363dSVladimir Medvedkin
80f3aa363dSVladimir Medvedkin* To find an exact match route:
81f3aa363dSVladimir Medvedkin
82f3aa363dSVladimir Medvedkin.. code-block:: c
83f3aa363dSVladimir Medvedkin
84f3aa363dSVladimir Medvedkin      struct rte_rib_node *route = rte_rib_lookup_exact(rib, RTE_IPV4(10,0,0,128), 25);
85f3aa363dSVladimir Medvedkin
86f3aa363dSVladimir MedvedkinThis returns an ``rte_rib_node`` pointing to the ``10.0.0.128/25`` prefix.
87f3aa363dSVladimir Medvedkin
88f3aa363dSVladimir Medvedkin.. code-block:: c
89f3aa363dSVladimir Medvedkin
90f3aa363dSVladimir Medvedkin      struct rte_rib_node *route = rte_rib_lookup_exact(rib, RTE_IPV4(10,0,0,0), 24);
91f3aa363dSVladimir Medvedkin
92f3aa363dSVladimir MedvedkinThis returns ``NULL`` as no exact match can be found.
93f3aa363dSVladimir Medvedkin
94f3aa363dSVladimir Medvedkin* To retrieve a group of routes under the common prefix ``10.0.0.0/24``
95f3aa363dSVladimir Medvedkin  (yellow triangle in :numref:`figure_rib_internals`):
96f3aa363dSVladimir Medvedkin
97f3aa363dSVladimir Medvedkin.. code-block:: c
98f3aa363dSVladimir Medvedkin
99f3aa363dSVladimir Medvedkin      struct rte_rib_node *route = NULL;
100f3aa363dSVladimir Medvedkin      do {
101f3aa363dSVladimir Medvedkin         route = rte_rib_get_nxt(rib, RTE_IPV4(10,0,0,0), 24, route, RTE_RIB_GET_NXT_ALL);
102f3aa363dSVladimir Medvedkin      } while (route != NULL)
103f3aa363dSVladimir Medvedkin
104f3aa363dSVladimir MedvedkinThis returns 3 ``rte_rib_node`` nodes pointing to ``10.0.0.0/29``, ``10.0.0.160/27``
105f3aa363dSVladimir Medvedkinand ``10.0.0.128/25``.
106f3aa363dSVladimir Medvedkin
107f3aa363dSVladimir Medvedkin
108f3aa363dSVladimir MedvedkinExtensions usage example
109f3aa363dSVladimir Medvedkin------------------------
110f3aa363dSVladimir Medvedkin
111f3aa363dSVladimir MedvedkinExtensions can be used for a wide range of tasks.
112f3aa363dSVladimir MedvedkinBy default, an ``rte_rib_node`` node contains only crucial information such as the prefix and
113f3aa363dSVladimir Medvedkinnext hop ID, but it doesn't contain protocol specific information such as
114f3aa363dSVladimir Medvedkinmetrics, administrative distance and other routing protocol information.
115f3aa363dSVladimir MedvedkinThese examples are application specific data and the user can decide what to keep
116f3aa363dSVladimir Medvedkinand how it is stored within the extension memory region in each ``rte_rib_node``.
117f3aa363dSVladimir Medvedkin
118f3aa363dSVladimir MedvedkinIt is possible to implement a prefix independent convergence using the RIB extension feature.
119f3aa363dSVladimir MedvedkinIf the routing daemon can provide a feasible next hop ID along with a best (active) next hop ID,
120f3aa363dSVladimir Medvedkinit is possible to react to a neighbour failing relatively fast.
121f3aa363dSVladimir MedvedkinConsider a RIB with a number of routes with different next hops (A and B) as
122f3aa363dSVladimir Medvedkinshown in :numref:`figure_rib_pic`. Every route can have a feasible next hop
123f3aa363dSVladimir Medvedkinprovided by the routing daemon.
124f3aa363dSVladimir Medvedkin
125f3aa363dSVladimir Medvedkin.. _figure_rib_pic:
126f3aa363dSVladimir Medvedkin
127f3aa363dSVladimir Medvedkin.. figure:: img/rib_pic.*
128f3aa363dSVladimir Medvedkin
129f3aa363dSVladimir Medvedkin   RIB prefix independent convergence
130f3aa363dSVladimir Medvedkin
131f3aa363dSVladimir MedvedkinIn case of a next hop failure, we need to replace an active failed next hop with a
132f3aa363dSVladimir Medvedkinfeasible next hop for every corresponding route without waiting for the routing daemon
133f3aa363dSVladimir Medvedkinrecalculation process to complete.
134f3aa363dSVladimir MedvedkinTo achieve this we can link all existing routes with the same active next hop in a linked list,
135f3aa363dSVladimir Medvedkinsaving the feasible next hop ID and a pointer inside the extension space of each ``rte_rib_node``.
136f3aa363dSVladimir Medvedkin
137f3aa363dSVladimir Medvedkin.. code-block:: c
138f3aa363dSVladimir Medvedkin
139f3aa363dSVladimir Medvedkin      struct my_route_ext {
140f3aa363dSVladimir Medvedkin         struct rte_rib_node *next;
141f3aa363dSVladimir Medvedkin         uint64_t feasible_nh;
142f3aa363dSVladimir Medvedkin      };
143f3aa363dSVladimir Medvedkin
144f3aa363dSVladimir Medvedkin      struct rte_rib_conf conf;
145f3aa363dSVladimir Medvedkin      conf.ext_sz = sizeof(struct my_route_ext);
146f3aa363dSVladimir Medvedkin      rib = rte_rib_create("test", 0, &conf);
147f3aa363dSVladimir Medvedkin      ...
148f3aa363dSVladimir Medvedkin      /* routing daemon task */
149f3aa363dSVladimir Medvedkin      struct rte_rib_node *route = rte_rib_insert(rib, RTE_IPV4(192,0,2,0), 24);
150f3aa363dSVladimir Medvedkin      rte_rib_set_nh(route, active_nh_from_rd);
151f3aa363dSVladimir Medvedkin      struct my_route_ext *ext = rte_rib_get_ext(route);
152f3aa363dSVladimir Medvedkin      ext->feasible_nh = feasible_nh_from_rd;
153f3aa363dSVladimir Medvedkin      list_insert(nh_table[active_nh_from_rd].list_head, route);
154f3aa363dSVladimir Medvedkin      ...
155f3aa363dSVladimir Medvedkin      /* dataplane monitoring thread */
156f3aa363dSVladimir Medvedkin      /* nexthop id fail_nh fails */
157f3aa363dSVladimir Medvedkin      route = NULL;
158f3aa363dSVladimir Medvedkin      do {
159f3aa363dSVladimir Medvedkin         route = get_next(nh_table[fail_nh].list_head, route);
160f3aa363dSVladimir Medvedkin         uint32_t ip;
161f3aa363dSVladimir Medvedkin         uint8_t depth;
162f3aa363dSVladimir Medvedkin         rte_rib_get_ip(route, &ip);
163f3aa363dSVladimir Medvedkin         rte_rib_get_depth(route, &depth);
164f3aa363dSVladimir Medvedkin         ext = rte_rib_get_ext(route);
165f3aa363dSVladimir Medvedkin         uint64_t new_nh = ext->feasible_nh;
166f3aa363dSVladimir Medvedkin         /* do update to the dataplane, for example to the fib */
167f3aa363dSVladimir Medvedkin         rte_fib_add(fib, ip, depth, new_nh);
168f3aa363dSVladimir Medvedkin         /* update nexthop if necessary */
169f3aa363dSVladimir Medvedkin         rte_rib_set_nh(route, new_nh);
170f3aa363dSVladimir Medvedkin      } while (route != NULL);
171