blob: 65fc7775cc4147513c392455393b525d2e85a9ad [file] [log] [blame]
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001/*
2 * Copyright (c) 2016 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15/**
16 * @brief The IPv4 FIB
17 *
18 * FIBs are composed of two prefix data-bases (akak tables). The non-forwarding
19 * table contains all the routes that the control plane has programmed, the
20 * forwarding table contains the sub-set of those routes that can be used to
21 * forward packets.
22 * In the IPv4 FIB the non-forwarding table is an array of hash tables indexed
23 * by mask length, the forwarding table is an mtrie
24 *
25 * This IPv4 FIB is used by the protocol independent FIB. So directly using
26 * this APIs in client code is not encouraged. However, this IPv4 FIB can be
27 * used if all the client wants is an IPv4 prefix data-base
28 */
29
30#ifndef __IP4_FIB_H__
31#define __IP4_FIB_H__
32
33#include <vlib/vlib.h>
34#include <vnet/ip/ip.h>
35#include <vnet/fib/fib_entry.h>
36#include <vnet/fib/fib_table.h>
Neale Rannsd6953332021-08-10 07:39:18 +000037#include <vnet/fib/ip4_fib_8.h>
38#include <vnet/fib/ip4_fib_16.h>
Neale Ranns0bfe5d82016-08-25 15:29:12 +010039
Neale Rannsa70b0152021-08-10 14:37:11 +000040// for the VPP_IP_FIB_MTRIE_16 definition
41#include <vpp/vnet/config.h>
42
Neale Ranns0bfe5d82016-08-25 15:29:12 +010043/**
Neale Rannsd6953332021-08-10 07:39:18 +000044 * the FIB module uses the 16-8-8 stride trie
Neale Ranns32e1c012016-11-22 17:07:28 +000045 */
Neale Rannsa70b0152021-08-10 14:37:11 +000046#ifdef VPP_IP_FIB_MTRIE_16
Neale Rannsd6953332021-08-10 07:39:18 +000047typedef ip4_fib_16_t ip4_fib_t;
Neale Ranns32e1c012016-11-22 17:07:28 +000048
Neale Rannsd6953332021-08-10 07:39:18 +000049#define ip4_fibs ip4_fib_16s
50#define ip4_fib_table_lookup ip4_fib_16_table_lookup
51#define ip4_fib_table_lookup_exact_match ip4_fib_16_table_lookup_exact_match
52#define ip4_fib_table_entry_remove ip4_fib_16_table_entry_remove
53#define ip4_fib_table_entry_insert ip4_fib_16_table_entry_insert
54#define ip4_fib_table_fwding_dpo_update ip4_fib_16_table_fwding_dpo_update
55#define ip4_fib_table_fwding_dpo_remove ip4_fib_16_table_fwding_dpo_remove
56#define ip4_fib_table_lookup_lb ip4_fib_16_table_lookup_lb
57#define ip4_fib_table_walk ip4_fib_16_table_walk
58#define ip4_fib_table_sub_tree_walk ip4_fib_16_table_sub_tree_walk
59#define ip4_fib_table_init ip4_fib_16_table_init
60#define ip4_fib_table_free ip4_fib_16_table_free
61#define ip4_mtrie_memory_usage ip4_mtrie_16_memory_usage
62#define format_ip4_mtrie format_ip4_mtrie_16
Neale Ranns89541992017-04-06 04:41:02 -070063
Neale Rannsa70b0152021-08-10 14:37:11 +000064#else
65typedef ip4_fib_8_t ip4_fib_t;
66
67#define ip4_fibs ip4_fib_8s
68#define ip4_fib_table_lookup ip4_fib_8_table_lookup
69#define ip4_fib_table_lookup_exact_match ip4_fib_8_table_lookup_exact_match
70#define ip4_fib_table_entry_remove ip4_fib_8_table_entry_remove
71#define ip4_fib_table_entry_insert ip4_fib_8_table_entry_insert
72#define ip4_fib_table_fwding_dpo_update ip4_fib_8_table_fwding_dpo_update
73#define ip4_fib_table_fwding_dpo_remove ip4_fib_8_table_fwding_dpo_remove
74#define ip4_fib_table_lookup_lb ip4_fib_8_table_lookup_lb
75#define ip4_fib_table_walk ip4_fib_8_table_walk
76#define ip4_fib_table_sub_tree_walk ip4_fib_8_table_sub_tree_walk
77#define ip4_fib_table_init ip4_fib_8_table_init
78#define ip4_fib_table_free ip4_fib_8_table_free
79#define ip4_mtrie_memory_usage ip4_mtrie_8_memory_usage
80#define format_ip4_mtrie format_ip4_mtrie_8
81
82#endif
83
Neale Ranns89541992017-04-06 04:41:02 -070084/**
Neale Ranns0bfe5d82016-08-25 15:29:12 +010085 * @brief Get the FIB at the given index
86 */
87static inline ip4_fib_t *
88ip4_fib_get (u32 index)
89{
Neale Rannsd6953332021-08-10 07:39:18 +000090 return (pool_elt_at_index(ip4_fibs, index));
Neale Ranns0bfe5d82016-08-25 15:29:12 +010091}
92
93always_inline u32
94ip4_fib_lookup (ip4_main_t * im, u32 sw_if_index, ip4_address_t * dst)
95{
96 return (ip4_fib_table_lookup_lb(
97 ip4_fib_get(vec_elt (im->fib_index_by_sw_if_index, sw_if_index)),
98 dst));
99}
100
101/**
102 * @brief Get or create an IPv4 fib.
103 *
104 * Get or create an IPv4 fib with the provided table ID.
105 *
106 * @param table_id
107 * When set to \c ~0, an arbitrary and unused fib ID is picked
108 * and can be retrieved with \c ret->table_id.
109 * Otherwise, the fib ID to be used to retrieve or create the desired fib.
110 * @returns A pointer to the retrieved or created fib.
111 *
112 */
Neale Ranns15002542017-09-10 04:39:11 -0700113extern u32 ip4_fib_table_find_or_create_and_lock(u32 table_id,
114 fib_source_t src);
115extern u32 ip4_fib_table_create_and_lock(fib_source_t src);
Neale Rannsd6953332021-08-10 07:39:18 +0000116extern void ip4_fib_table_destroy(u32 fib_index);
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100117
Neale Rannsc87aafa2017-11-29 00:59:31 -0800118extern u8 *format_ip4_fib_table_memory(u8 * s, va_list * args);
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100119
120static inline
121u32 ip4_fib_index_from_table_id (u32 table_id)
122{
123 ip4_main_t * im = &ip4_main;
124 uword * p;
125
126 p = hash_get (im->fib_index_by_table_id, table_id);
127 if (!p)
128 return ~0;
129
130 return p[0];
131}
132
133extern u32 ip4_fib_table_get_index_for_sw_if_index(u32 sw_if_index);
134
Neale Rannsa70b0152021-08-10 14:37:11 +0000135#ifdef VPP_IP_FIB_MTRIE_16
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100136always_inline index_t
137ip4_fib_forwarding_lookup (u32 fib_index,
138 const ip4_address_t * addr)
139{
Neale Ranns6bb2db02021-08-06 12:24:14 +0000140 ip4_mtrie_leaf_t leaf;
141 ip4_mtrie_16_t * mtrie;
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100142
143 mtrie = &ip4_fib_get(fib_index)->mtrie;
144
Neale Ranns6bb2db02021-08-06 12:24:14 +0000145 leaf = ip4_mtrie_16_lookup_step_one (mtrie, addr);
Neale Ranns7244a702021-08-06 13:12:00 +0000146 leaf = ip4_mtrie_16_lookup_step (leaf, addr, 2);
147 leaf = ip4_mtrie_16_lookup_step (leaf, addr, 3);
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100148
Neale Ranns6bb2db02021-08-06 12:24:14 +0000149 return (ip4_mtrie_leaf_get_adj_index(leaf));
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100150}
151
Neale Rannsd724e4f2020-04-02 15:02:16 +0000152static_always_inline void
153ip4_fib_forwarding_lookup_x2 (u32 fib_index0,
154 u32 fib_index1,
155 const ip4_address_t * addr0,
156 const ip4_address_t * addr1,
157 index_t *lb0,
158 index_t *lb1)
159{
Neale Ranns6bb2db02021-08-06 12:24:14 +0000160 ip4_mtrie_leaf_t leaf[2];
161 ip4_mtrie_16_t * mtrie[2];
Neale Rannsd724e4f2020-04-02 15:02:16 +0000162
163 mtrie[0] = &ip4_fib_get(fib_index0)->mtrie;
164 mtrie[1] = &ip4_fib_get(fib_index1)->mtrie;
165
Neale Ranns6bb2db02021-08-06 12:24:14 +0000166 leaf[0] = ip4_mtrie_16_lookup_step_one (mtrie[0], addr0);
167 leaf[1] = ip4_mtrie_16_lookup_step_one (mtrie[1], addr1);
Neale Ranns7244a702021-08-06 13:12:00 +0000168 leaf[0] = ip4_mtrie_16_lookup_step (leaf[0], addr0, 2);
169 leaf[1] = ip4_mtrie_16_lookup_step (leaf[1], addr1, 2);
170 leaf[0] = ip4_mtrie_16_lookup_step (leaf[0], addr0, 3);
171 leaf[1] = ip4_mtrie_16_lookup_step (leaf[1], addr1, 3);
Neale Rannsd724e4f2020-04-02 15:02:16 +0000172
Neale Ranns6bb2db02021-08-06 12:24:14 +0000173 *lb0 = ip4_mtrie_leaf_get_adj_index(leaf[0]);
174 *lb1 = ip4_mtrie_leaf_get_adj_index(leaf[1]);
Neale Rannsd724e4f2020-04-02 15:02:16 +0000175}
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100176
Neale Ranns31a4aa72021-08-10 12:35:57 +0000177static_always_inline void
178ip4_fib_forwarding_lookup_x4 (u32 fib_index0,
179 u32 fib_index1,
180 u32 fib_index2,
181 u32 fib_index3,
182 const ip4_address_t * addr0,
183 const ip4_address_t * addr1,
184 const ip4_address_t * addr2,
185 const ip4_address_t * addr3,
186 index_t *lb0,
187 index_t *lb1,
188 index_t *lb2,
189 index_t *lb3)
190{
Neale Ranns6bb2db02021-08-06 12:24:14 +0000191 ip4_mtrie_leaf_t leaf[4];
192 ip4_mtrie_16_t * mtrie[4];
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100193
Neale Ranns31a4aa72021-08-10 12:35:57 +0000194 mtrie[0] = &ip4_fib_get(fib_index0)->mtrie;
195 mtrie[1] = &ip4_fib_get(fib_index1)->mtrie;
196 mtrie[2] = &ip4_fib_get(fib_index2)->mtrie;
197 mtrie[3] = &ip4_fib_get(fib_index3)->mtrie;
198
Neale Ranns6bb2db02021-08-06 12:24:14 +0000199 leaf[0] = ip4_mtrie_16_lookup_step_one (mtrie[0], addr0);
200 leaf[1] = ip4_mtrie_16_lookup_step_one (mtrie[1], addr1);
201 leaf[2] = ip4_mtrie_16_lookup_step_one (mtrie[2], addr2);
202 leaf[3] = ip4_mtrie_16_lookup_step_one (mtrie[3], addr3);
Neale Ranns31a4aa72021-08-10 12:35:57 +0000203
Neale Ranns7244a702021-08-06 13:12:00 +0000204 leaf[0] = ip4_mtrie_16_lookup_step (leaf[0], addr0, 2);
205 leaf[1] = ip4_mtrie_16_lookup_step (leaf[1], addr1, 2);
206 leaf[2] = ip4_mtrie_16_lookup_step (leaf[2], addr2, 2);
207 leaf[3] = ip4_mtrie_16_lookup_step (leaf[3], addr3, 2);
Neale Ranns31a4aa72021-08-10 12:35:57 +0000208
Neale Ranns7244a702021-08-06 13:12:00 +0000209 leaf[0] = ip4_mtrie_16_lookup_step (leaf[0], addr0, 3);
210 leaf[1] = ip4_mtrie_16_lookup_step (leaf[1], addr1, 3);
211 leaf[2] = ip4_mtrie_16_lookup_step (leaf[2], addr2, 3);
212 leaf[3] = ip4_mtrie_16_lookup_step (leaf[3], addr3, 3);
Neale Ranns31a4aa72021-08-10 12:35:57 +0000213
Neale Ranns6bb2db02021-08-06 12:24:14 +0000214 *lb0 = ip4_mtrie_leaf_get_adj_index(leaf[0]);
215 *lb1 = ip4_mtrie_leaf_get_adj_index(leaf[1]);
216 *lb2 = ip4_mtrie_leaf_get_adj_index(leaf[2]);
217 *lb3 = ip4_mtrie_leaf_get_adj_index(leaf[3]);
Neale Ranns31a4aa72021-08-10 12:35:57 +0000218}
219
Neale Rannsa70b0152021-08-10 14:37:11 +0000220#else
221
222always_inline index_t
223ip4_fib_forwarding_lookup (u32 fib_index,
224 const ip4_address_t * addr)
225{
226 ip4_mtrie_leaf_t leaf;
227 ip4_mtrie_8_t * mtrie;
228
229 mtrie = &ip4_fib_get(fib_index)->mtrie;
230
231 leaf = ip4_mtrie_8_lookup_step_one (mtrie, addr);
232 leaf = ip4_mtrie_8_lookup_step (leaf, addr, 1);
233 leaf = ip4_mtrie_8_lookup_step (leaf, addr, 2);
234 leaf = ip4_mtrie_8_lookup_step (leaf, addr, 3);
235
236 return (ip4_mtrie_leaf_get_adj_index(leaf));
237}
238
239static_always_inline void
240ip4_fib_forwarding_lookup_x2 (u32 fib_index0,
241 u32 fib_index1,
242 const ip4_address_t * addr0,
243 const ip4_address_t * addr1,
244 index_t *lb0,
245 index_t *lb1)
246{
247 ip4_mtrie_leaf_t leaf[2];
248 ip4_mtrie_8_t * mtrie[2];
249
250 mtrie[0] = &ip4_fib_get(fib_index0)->mtrie;
251 mtrie[1] = &ip4_fib_get(fib_index1)->mtrie;
252
253 leaf[0] = ip4_mtrie_8_lookup_step_one (mtrie[0], addr0);
254 leaf[1] = ip4_mtrie_8_lookup_step_one (mtrie[1], addr1);
255 leaf[0] = ip4_mtrie_8_lookup_step (leaf[0], addr0, 1);
256 leaf[1] = ip4_mtrie_8_lookup_step (leaf[1], addr1, 1);
257 leaf[0] = ip4_mtrie_8_lookup_step (leaf[0], addr0, 2);
258 leaf[1] = ip4_mtrie_8_lookup_step (leaf[1], addr1, 2);
259 leaf[0] = ip4_mtrie_8_lookup_step (leaf[0], addr0, 3);
260 leaf[1] = ip4_mtrie_8_lookup_step (leaf[1], addr1, 3);
261
262 *lb0 = ip4_mtrie_leaf_get_adj_index(leaf[0]);
263 *lb1 = ip4_mtrie_leaf_get_adj_index(leaf[1]);
264}
265
266static_always_inline void
267ip4_fib_forwarding_lookup_x4 (u32 fib_index0,
268 u32 fib_index1,
269 u32 fib_index2,
270 u32 fib_index3,
271 const ip4_address_t * addr0,
272 const ip4_address_t * addr1,
273 const ip4_address_t * addr2,
274 const ip4_address_t * addr3,
275 index_t *lb0,
276 index_t *lb1,
277 index_t *lb2,
278 index_t *lb3)
279{
280 ip4_mtrie_leaf_t leaf[4];
281 ip4_mtrie_8_t * mtrie[4];
282
283 mtrie[0] = &ip4_fib_get(fib_index0)->mtrie;
284 mtrie[1] = &ip4_fib_get(fib_index1)->mtrie;
285 mtrie[2] = &ip4_fib_get(fib_index2)->mtrie;
286 mtrie[3] = &ip4_fib_get(fib_index3)->mtrie;
287
288 leaf[0] = ip4_mtrie_8_lookup_step_one (mtrie[0], addr0);
289 leaf[1] = ip4_mtrie_8_lookup_step_one (mtrie[1], addr1);
290 leaf[2] = ip4_mtrie_8_lookup_step_one (mtrie[2], addr2);
291 leaf[3] = ip4_mtrie_8_lookup_step_one (mtrie[3], addr3);
292
293 leaf[0] = ip4_mtrie_8_lookup_step (leaf[0], addr0, 1);
294 leaf[1] = ip4_mtrie_8_lookup_step (leaf[1], addr1, 1);
295 leaf[2] = ip4_mtrie_8_lookup_step (leaf[2], addr2, 1);
296 leaf[3] = ip4_mtrie_8_lookup_step (leaf[3], addr3, 1);
297
298 leaf[0] = ip4_mtrie_8_lookup_step (leaf[0], addr0, 2);
299 leaf[1] = ip4_mtrie_8_lookup_step (leaf[1], addr1, 2);
300 leaf[2] = ip4_mtrie_8_lookup_step (leaf[2], addr2, 2);
301 leaf[3] = ip4_mtrie_8_lookup_step (leaf[3], addr3, 2);
302
303 leaf[0] = ip4_mtrie_8_lookup_step (leaf[0], addr0, 3);
304 leaf[1] = ip4_mtrie_8_lookup_step (leaf[1], addr1, 3);
305 leaf[2] = ip4_mtrie_8_lookup_step (leaf[2], addr2, 3);
306 leaf[3] = ip4_mtrie_8_lookup_step (leaf[3], addr3, 3);
307
308 *lb0 = ip4_mtrie_leaf_get_adj_index(leaf[0]);
309 *lb1 = ip4_mtrie_leaf_get_adj_index(leaf[1]);
310 *lb2 = ip4_mtrie_leaf_get_adj_index(leaf[2]);
311 *lb3 = ip4_mtrie_leaf_get_adj_index(leaf[3]);
312}
313
314#endif
315
Neale Ranns31a4aa72021-08-10 12:35:57 +0000316#endif