blob: 8f7bba0369a9b40b34bd02d1362277172bf2d16f [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
Neale Rannsd792d9c2017-10-21 10:53:20 -070016#include <vnet/fib/fib_test.h>
Neale Ranns0bfe5d82016-08-25 15:29:12 +010017#include <vnet/fib/ip6_fib.h>
18#include <vnet/fib/ip4_fib.h>
19#include <vnet/fib/mpls_fib.h>
20#include <vnet/adj/adj.h>
21#include <vnet/dpo/load_balance.h>
22#include <vnet/dpo/load_balance_map.h>
23#include <vnet/dpo/mpls_label_dpo.h>
24#include <vnet/dpo/lookup_dpo.h>
25#include <vnet/dpo/drop_dpo.h>
26#include <vnet/dpo/receive_dpo.h>
Neale Ranns948e00f2016-10-20 13:39:34 +010027#include <vnet/dpo/ip_null_dpo.h>
Neale Ranns88fc83e2017-04-05 08:11:14 -070028#include <vnet/bfd/bfd_main.h>
Neale Ranns43161a82017-08-12 02:12:00 -070029#include <vnet/dpo/interface_rx_dpo.h>
Neale Ranns0f26c5a2017-03-01 15:12:11 -080030#include <vnet/dpo/replicate_dpo.h>
Neale Rannsf068c3e2018-01-03 04:18:48 -080031#include <vnet/dpo/dvr_dpo.h>
Neale Ranns62fe07c2017-10-31 12:28:22 -070032#include <vnet/dpo/mpls_disposition.h>
Neale Ranns0bfe5d82016-08-25 15:29:12 +010033
34#include <vnet/mpls/mpls.h>
35
Neale Ranns6f631152017-10-03 08:20:21 -070036#include <vnet/fib/fib_test.h>
Neale Ranns0bfe5d82016-08-25 15:29:12 +010037#include <vnet/fib/fib_path_list.h>
Neale Rannsad422ed2016-11-02 14:20:04 +000038#include <vnet/fib/fib_entry_src.h>
Neale Ranns0bfe5d82016-08-25 15:29:12 +010039#include <vnet/fib/fib_walk.h>
40#include <vnet/fib/fib_node_list.h>
Neale Ranns3ee44042016-10-03 13:05:48 +010041#include <vnet/fib/fib_urpf_list.h>
Neale Ranns0bfe5d82016-08-25 15:29:12 +010042
Neale Ranns88fc83e2017-04-05 08:11:14 -070043/*
44 * Add debugs for passing tests
45 */
46static int fib_test_do_debug;
47
Neale Ranns0bfe5d82016-08-25 15:29:12 +010048#define FIB_TEST_I(_cond, _comment, _args...) \
49({ \
50 int _evald = (_cond); \
51 if (!(_evald)) { \
52 fformat(stderr, "FAIL:%d: " _comment "\n", \
53 __LINE__, ##_args); \
54 } else { \
Neale Ranns88fc83e2017-04-05 08:11:14 -070055 if (fib_test_do_debug) \
56 fformat(stderr, "PASS:%d: " _comment "\n", \
57 __LINE__, ##_args); \
Neale Ranns0bfe5d82016-08-25 15:29:12 +010058 } \
59 _evald; \
60})
61#define FIB_TEST(_cond, _comment, _args...) \
62{ \
63 if (!FIB_TEST_I(_cond, _comment, ##_args)) { \
Neale Ranns0ebe8d72016-12-08 19:48:11 +000064 return 1; \
Neale Ranns0bfe5d82016-08-25 15:29:12 +010065 ASSERT(!("FAIL: " _comment)); \
66 } \
67}
68
69/**
70 * A 'i'm not fussed is this is not efficient' store of test data
71 */
72typedef struct test_main_t_ {
73 /**
74 * HW if indicies
75 */
76 u32 hw_if_indicies[4];
77 /**
78 * HW interfaces
79 */
80 vnet_hw_interface_t * hw[4];
81
82} test_main_t;
83static test_main_t test_main;
84
85/* fake ethernet device class, distinct from "fake-ethX" */
86static u8 * format_test_interface_name (u8 * s, va_list * args)
87{
88 u32 dev_instance = va_arg (*args, u32);
89 return format (s, "test-eth%d", dev_instance);
90}
91
92static uword dummy_interface_tx (vlib_main_t * vm,
93 vlib_node_runtime_t * node,
94 vlib_frame_t * frame)
95{
96 clib_warning ("you shouldn't be here, leaking buffers...");
97 return frame->n_vectors;
98}
99
Neale Ranns8b37b872016-11-21 12:25:22 +0000100static clib_error_t *
101test_interface_admin_up_down (vnet_main_t * vnm,
102 u32 hw_if_index,
103 u32 flags)
104{
105 u32 hw_flags = (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) ?
106 VNET_HW_INTERFACE_FLAG_LINK_UP : 0;
107 vnet_hw_interface_set_flags (vnm, hw_if_index, hw_flags);
108 return 0;
109}
110
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100111VNET_DEVICE_CLASS (test_interface_device_class,static) = {
112 .name = "Test interface",
113 .format_device_name = format_test_interface_name,
114 .tx_function = dummy_interface_tx,
Neale Ranns8b37b872016-11-21 12:25:22 +0000115 .admin_up_down_function = test_interface_admin_up_down,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100116};
117
118static u8 *hw_address;
119
Neale Ranns0ebe8d72016-12-08 19:48:11 +0000120static int
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100121fib_test_mk_intf (u32 ninterfaces)
122{
123 clib_error_t * error = NULL;
124 test_main_t *tm = &test_main;
125 u8 byte;
126 u32 i;
127
128 ASSERT(ninterfaces <= ARRAY_LEN(tm->hw_if_indicies));
129
130 for (i=0; i<6; i++)
131 {
132 byte = 0xd0+i;
133 vec_add1(hw_address, byte);
134 }
135
136 for (i = 0; i < ninterfaces; i++)
137 {
138 hw_address[5] = i;
139
140 error = ethernet_register_interface(vnet_get_main(),
Neale Ranns8b37b872016-11-21 12:25:22 +0000141 test_interface_device_class.index,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100142 i /* instance */,
143 hw_address,
144 &tm->hw_if_indicies[i],
145 /* flag change */ 0);
146
147 FIB_TEST((NULL == error), "ADD interface %d", i);
148
Neale Ranns8b37b872016-11-21 12:25:22 +0000149 error = vnet_hw_interface_set_flags(vnet_get_main(),
150 tm->hw_if_indicies[i],
151 VNET_HW_INTERFACE_FLAG_LINK_UP);
152 tm->hw[i] = vnet_get_hw_interface(vnet_get_main(),
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100153 tm->hw_if_indicies[i]);
Neale Ranns8b37b872016-11-21 12:25:22 +0000154 vec_validate (ip4_main.fib_index_by_sw_if_index,
155 tm->hw[i]->sw_if_index);
156 vec_validate (ip6_main.fib_index_by_sw_if_index,
157 tm->hw[i]->sw_if_index);
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100158 ip4_main.fib_index_by_sw_if_index[tm->hw[i]->sw_if_index] = 0;
159 ip6_main.fib_index_by_sw_if_index[tm->hw[i]->sw_if_index] = 0;
Neale Ranns8b37b872016-11-21 12:25:22 +0000160
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100161 error = vnet_sw_interface_set_flags(vnet_get_main(),
162 tm->hw[i]->sw_if_index,
163 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
164 FIB_TEST((NULL == error), "UP interface %d", i);
165 }
166 /*
167 * re-eval after the inevitable realloc
168 */
169 for (i = 0; i < ninterfaces; i++)
170 {
171 tm->hw[i] = vnet_get_hw_interface(vnet_get_main(),
172 tm->hw_if_indicies[i]);
173 }
Neale Ranns0ebe8d72016-12-08 19:48:11 +0000174
175 return (0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100176}
177
Neale Ranns3ee44042016-10-03 13:05:48 +0100178#define FIB_TEST_REC_FORW(_rec_prefix, _via_prefix, _bucket) \
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100179{ \
180 const dpo_id_t *_rec_dpo = fib_entry_contribute_ip_forwarding( \
181 fib_table_lookup_exact_match(fib_index, (_rec_prefix))); \
182 const dpo_id_t *_via_dpo = fib_entry_contribute_ip_forwarding( \
183 fib_table_lookup(fib_index, (_via_prefix))); \
184 FIB_TEST(!dpo_cmp(_via_dpo, \
Neale Ranns3ee44042016-10-03 13:05:48 +0100185 load_balance_get_bucket(_rec_dpo->dpoi_index, \
186 _bucket)), \
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100187 "%U is recursive via %U", \
188 format_fib_prefix, (_rec_prefix), \
189 format_fib_prefix, _via_prefix); \
190}
191
192#define FIB_TEST_LB_BUCKET_VIA_ADJ(_prefix, _bucket, _ai) \
193{ \
194 const dpo_id_t *_dpo = fib_entry_contribute_ip_forwarding( \
195 fib_table_lookup_exact_match(fib_index, (_prefix))); \
196 const dpo_id_t *_dpo1 = \
197 load_balance_get_bucket(_dpo->dpoi_index, _bucket); \
198 FIB_TEST(DPO_ADJACENCY == _dpo1->dpoi_type, "type is %U", \
199 format_dpo_type, _dpo1->dpoi_type); \
200 FIB_TEST((_ai == _dpo1->dpoi_index), \
201 "%U bucket %d resolves via %U", \
202 format_fib_prefix, (_prefix), \
203 _bucket, \
204 format_dpo_id, _dpo1, 0); \
205}
206
Neale Ranns3ee44042016-10-03 13:05:48 +0100207#define FIB_TEST_RPF(_cond, _comment, _args...) \
208{ \
209 if (!FIB_TEST_I(_cond, _comment, ##_args)) { \
210 return (0); \
211 } \
212}
213
214static int
215fib_test_urpf_is_equal (fib_node_index_t fei,
216 fib_forward_chain_type_t fct,
217 u32 num, ...)
218{
Neale Ranns948e00f2016-10-20 13:39:34 +0100219 dpo_id_t dpo = DPO_INVALID;
Neale Ranns3ee44042016-10-03 13:05:48 +0100220 fib_urpf_list_t *urpf;
221 index_t ui;
222 va_list ap;
223 int ii;
224
225 va_start(ap, num);
226
227 fib_entry_contribute_forwarding(fei, fct, &dpo);
228 ui = load_balance_get_urpf(dpo.dpoi_index);
229
230 urpf = fib_urpf_list_get(ui);
231
232 FIB_TEST_RPF(num == vec_len(urpf->furpf_itfs),
233 "RPF:%U len %d == %d",
234 format_fib_urpf_list, ui,
235 num, vec_len(urpf->furpf_itfs));
236 FIB_TEST_RPF(num == fib_urpf_check_size(ui),
237 "RPF:%U check-size %d == %d",
238 format_fib_urpf_list, ui,
239 num, vec_len(urpf->furpf_itfs));
240
241 for (ii = 0; ii < num; ii++)
242 {
243 adj_index_t ai = va_arg(ap, adj_index_t);
244
245 FIB_TEST_RPF(ai == urpf->furpf_itfs[ii],
246 "RPF:%d item:%d - %d == %d",
247 ui, ii, ai, urpf->furpf_itfs[ii]);
248 FIB_TEST_RPF(fib_urpf_check(ui, ai),
249 "RPF:%d %d found",
250 ui, ai);
251 }
252
253 dpo_reset(&dpo);
254
Neale Ranns5899fde2016-10-12 13:51:05 +0100255 va_end(ap);
256
Neale Ranns3ee44042016-10-03 13:05:48 +0100257 return (1);
258}
259
Neale Rannsb80c5362016-10-08 13:03:40 +0100260static u8*
261fib_test_build_rewrite (u8 *eth_addr)
262{
263 u8* rewrite = NULL;
264
265 vec_validate(rewrite, 13);
266
267 memcpy(rewrite, eth_addr, 6);
268 memcpy(rewrite+6, eth_addr, 6);
269
270 return (rewrite);
271}
272
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000273#define FIB_TEST_LB(_cond, _comment, _args...) \
274{ \
275 if (!FIB_TEST_I(_cond, _comment, ##_args)) { \
276 return (0); \
277 } \
278}
279
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800280int
281fib_test_validate_rep_v (const replicate_t *rep,
282 u16 n_buckets,
Christophe Fontained3c008d2017-10-02 18:10:54 +0200283 va_list *ap)
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800284{
285 const fib_test_rep_bucket_t *exp;
286 const dpo_id_t *dpo;
287 int bucket;
288
289 FIB_TEST_LB((n_buckets == rep->rep_n_buckets),
290 "n_buckets = %d", rep->rep_n_buckets);
291
292 for (bucket = 0; bucket < n_buckets; bucket++)
293 {
Christophe Fontained3c008d2017-10-02 18:10:54 +0200294 exp = va_arg(*ap, fib_test_rep_bucket_t*);
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800295
296 dpo = replicate_get_bucket_i(rep, bucket);
297
298 switch (exp->type)
299 {
300 case FT_REP_LABEL_O_ADJ:
301 {
302 const mpls_label_dpo_t *mld;
303 mpls_label_t hdr;
Neale Ranns31ed7442018-02-23 05:29:09 -0800304 FIB_TEST_LB((mpls_label_dpo_get_type(MPLS_LABEL_DPO_FLAG_NONE)
305 == dpo->dpoi_type),
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800306 "bucket %d stacks on %U",
307 bucket,
308 format_dpo_type, dpo->dpoi_type);
309
310 mld = mpls_label_dpo_get(dpo->dpoi_index);
311 hdr = clib_net_to_host_u32(mld->mld_hdr[0].label_exp_s_ttl);
312
313 FIB_TEST_LB((vnet_mpls_uc_get_label(hdr) ==
314 exp->label_o_adj.label),
315 "bucket %d stacks on label %d",
316 bucket,
317 exp->label_o_adj.label);
318
319 FIB_TEST_LB((vnet_mpls_uc_get_s(hdr) ==
320 exp->label_o_adj.eos),
321 "bucket %d stacks on label %d %U",
322 bucket,
323 exp->label_o_adj.label,
324 format_mpls_eos_bit, exp->label_o_adj.eos);
325
326 FIB_TEST_LB((DPO_ADJACENCY_INCOMPLETE == mld->mld_dpo.dpoi_type),
327 "bucket %d label stacks on %U",
328 bucket,
329 format_dpo_type, mld->mld_dpo.dpoi_type);
330
331 FIB_TEST_LB((exp->label_o_adj.adj == mld->mld_dpo.dpoi_index),
332 "bucket %d label stacks on adj %d",
333 bucket,
334 exp->label_o_adj.adj);
335 }
336 break;
337 case FT_REP_INTF:
Neale Ranns43161a82017-08-12 02:12:00 -0700338 FIB_TEST_LB((DPO_INTERFACE_RX == dpo->dpoi_type),
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800339 "bucket %d stacks on %U",
340 bucket,
341 format_dpo_type, dpo->dpoi_type);
342
343 FIB_TEST_LB((exp->adj.adj == dpo->dpoi_index),
344 "bucket %d stacks on adj %d",
345 bucket,
346 exp->adj.adj);
347 break;
348 case FT_REP_DISP_MFIB_LOOKUP:
349// ASSERT(0);
350 break;
351 }
352 }
353
354 return (!0);
355}
356
357int
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000358fib_test_validate_lb_v (const load_balance_t *lb,
Damjan Marionbb17f3c2018-02-06 19:29:35 +0100359 int n_buckets,
Christophe Fontained3c008d2017-10-02 18:10:54 +0200360 va_list *ap)
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000361{
362 const dpo_id_t *dpo;
363 int bucket;
364
365 FIB_TEST_LB((n_buckets == lb->lb_n_buckets), "n_buckets = %d", lb->lb_n_buckets);
366
367 for (bucket = 0; bucket < n_buckets; bucket++)
368 {
369 const fib_test_lb_bucket_t *exp;
370
Christophe Fontained3c008d2017-10-02 18:10:54 +0200371 exp = va_arg(*ap, fib_test_lb_bucket_t*);
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000372 dpo = load_balance_get_bucket_i(lb, bucket);
373
374 switch (exp->type)
375 {
Neale Rannsad422ed2016-11-02 14:20:04 +0000376 case FT_LB_LABEL_STACK_O_ADJ:
377 {
378 const mpls_label_dpo_t *mld;
Neale Ranns31ed7442018-02-23 05:29:09 -0800379 mpls_label_dpo_flags_t mf;
Neale Rannsad422ed2016-11-02 14:20:04 +0000380 mpls_label_t hdr;
381 u32 ii;
382
Neale Ranns31ed7442018-02-23 05:29:09 -0800383 mf = ((exp->label_stack_o_adj.mode ==
384 FIB_MPLS_LSP_MODE_UNIFORM) ?
385 MPLS_LABEL_DPO_FLAG_UNIFORM_MODE :
386 MPLS_LABEL_DPO_FLAG_NONE);
387 FIB_TEST_LB((mpls_label_dpo_get_type(mf) == dpo->dpoi_type),
Neale Rannsad422ed2016-11-02 14:20:04 +0000388 "bucket %d stacks on %U",
389 bucket,
390 format_dpo_type, dpo->dpoi_type);
Neale Ranns31ed7442018-02-23 05:29:09 -0800391
Neale Rannsad422ed2016-11-02 14:20:04 +0000392 mld = mpls_label_dpo_get(dpo->dpoi_index);
393
394 FIB_TEST_LB(exp->label_stack_o_adj.label_stack_size == mld->mld_n_labels,
395 "label stack size",
396 mld->mld_n_labels);
397
398 for (ii = 0; ii < mld->mld_n_labels; ii++)
399 {
400 hdr = clib_net_to_host_u32(mld->mld_hdr[ii].label_exp_s_ttl);
401 FIB_TEST_LB((vnet_mpls_uc_get_label(hdr) ==
402 exp->label_stack_o_adj.label_stack[ii]),
403 "bucket %d stacks on label %d",
404 bucket,
405 exp->label_stack_o_adj.label_stack[ii]);
406
407 if (ii == mld->mld_n_labels-1)
408 {
409 FIB_TEST_LB((vnet_mpls_uc_get_s(hdr) ==
410 exp->label_o_adj.eos),
411 "bucket %d stacks on label %d %U!=%U",
412 bucket,
413 exp->label_stack_o_adj.label_stack[ii],
414 format_mpls_eos_bit, exp->label_o_adj.eos,
415 format_mpls_eos_bit, vnet_mpls_uc_get_s(hdr));
416 }
417 else
418 {
419 FIB_TEST_LB((vnet_mpls_uc_get_s(hdr) == MPLS_NON_EOS),
420 "bucket %d stacks on label %d %U",
421 bucket,
422 exp->label_stack_o_adj.label_stack[ii],
423 format_mpls_eos_bit, vnet_mpls_uc_get_s(hdr));
424 }
425 }
426
427 FIB_TEST_LB((DPO_ADJACENCY_INCOMPLETE == mld->mld_dpo.dpoi_type),
428 "bucket %d label stacks on %U",
429 bucket,
430 format_dpo_type, mld->mld_dpo.dpoi_type);
431
432 FIB_TEST_LB((exp->label_stack_o_adj.adj == mld->mld_dpo.dpoi_index),
433 "bucket %d label stacks on adj %d",
434 bucket,
435 exp->label_stack_o_adj.adj);
436 }
437 break;
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000438 case FT_LB_LABEL_O_ADJ:
439 {
440 const mpls_label_dpo_t *mld;
441 mpls_label_t hdr;
Neale Ranns31ed7442018-02-23 05:29:09 -0800442 FIB_TEST_LB((mpls_label_dpo_get_type(MPLS_LABEL_DPO_FLAG_NONE)
443 == dpo->dpoi_type),
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000444 "bucket %d stacks on %U",
445 bucket,
446 format_dpo_type, dpo->dpoi_type);
447
448 mld = mpls_label_dpo_get(dpo->dpoi_index);
Neale Rannsad422ed2016-11-02 14:20:04 +0000449 hdr = clib_net_to_host_u32(mld->mld_hdr[0].label_exp_s_ttl);
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000450
451 FIB_TEST_LB((vnet_mpls_uc_get_label(hdr) ==
452 exp->label_o_adj.label),
453 "bucket %d stacks on label %d",
454 bucket,
455 exp->label_o_adj.label);
456
457 FIB_TEST_LB((vnet_mpls_uc_get_s(hdr) ==
458 exp->label_o_adj.eos),
459 "bucket %d stacks on label %d %U",
460 bucket,
461 exp->label_o_adj.label,
462 format_mpls_eos_bit, exp->label_o_adj.eos);
463
464 FIB_TEST_LB((DPO_ADJACENCY_INCOMPLETE == mld->mld_dpo.dpoi_type),
465 "bucket %d label stacks on %U",
466 bucket,
467 format_dpo_type, mld->mld_dpo.dpoi_type);
468
469 FIB_TEST_LB((exp->label_o_adj.adj == mld->mld_dpo.dpoi_index),
470 "bucket %d label stacks on adj %d",
471 bucket,
472 exp->label_o_adj.adj);
473 }
474 break;
475 case FT_LB_LABEL_O_LB:
476 {
477 const mpls_label_dpo_t *mld;
Neale Ranns31ed7442018-02-23 05:29:09 -0800478 mpls_label_dpo_flags_t mf;
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000479 mpls_label_t hdr;
480
Neale Ranns31ed7442018-02-23 05:29:09 -0800481 mf = ((exp->label_o_lb.mode ==
482 FIB_MPLS_LSP_MODE_UNIFORM) ?
483 MPLS_LABEL_DPO_FLAG_UNIFORM_MODE :
484 MPLS_LABEL_DPO_FLAG_NONE);
485 FIB_TEST_LB((mpls_label_dpo_get_type(mf) == dpo->dpoi_type),
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000486 "bucket %d stacks on %U",
487 bucket,
488 format_dpo_type, dpo->dpoi_type);
Neale Ranns31ed7442018-02-23 05:29:09 -0800489
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000490 mld = mpls_label_dpo_get(dpo->dpoi_index);
Neale Rannsad422ed2016-11-02 14:20:04 +0000491 hdr = clib_net_to_host_u32(mld->mld_hdr[0].label_exp_s_ttl);
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000492
Neale Rannsad422ed2016-11-02 14:20:04 +0000493 FIB_TEST_LB(1 == mld->mld_n_labels, "label stack size",
494 mld->mld_n_labels);
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000495 FIB_TEST_LB((vnet_mpls_uc_get_label(hdr) ==
496 exp->label_o_lb.label),
497 "bucket %d stacks on label %d",
498 bucket,
499 exp->label_o_lb.label);
500
501 FIB_TEST_LB((vnet_mpls_uc_get_s(hdr) ==
502 exp->label_o_lb.eos),
503 "bucket %d stacks on label %d %U",
504 bucket,
505 exp->label_o_lb.label,
506 format_mpls_eos_bit, exp->label_o_lb.eos);
507
508 FIB_TEST_LB((DPO_LOAD_BALANCE == mld->mld_dpo.dpoi_type),
509 "bucket %d label stacks on %U",
510 bucket,
511 format_dpo_type, mld->mld_dpo.dpoi_type);
512
513 FIB_TEST_LB((exp->label_o_lb.lb == mld->mld_dpo.dpoi_index),
514 "bucket %d label stacks on LB %d",
515 bucket,
516 exp->label_o_lb.lb);
517 }
518 break;
519 case FT_LB_ADJ:
520 FIB_TEST_I(((DPO_ADJACENCY == dpo->dpoi_type) ||
521 (DPO_ADJACENCY_INCOMPLETE == dpo->dpoi_type)),
522 "bucket %d stacks on %U",
523 bucket,
524 format_dpo_type, dpo->dpoi_type);
525 FIB_TEST_LB((exp->adj.adj == dpo->dpoi_index),
526 "bucket %d stacks on adj %d",
527 bucket,
528 exp->adj.adj);
529 break;
Neale Ranns31ed7442018-02-23 05:29:09 -0800530 case FT_LB_MPLS_DISP_PIPE_O_ADJ:
Neale Ranns62fe07c2017-10-31 12:28:22 -0700531 {
532 const mpls_disp_dpo_t *mdd;
533
Neale Ranns31ed7442018-02-23 05:29:09 -0800534 FIB_TEST_I((DPO_MPLS_DISPOSITION_PIPE == dpo->dpoi_type),
Neale Ranns62fe07c2017-10-31 12:28:22 -0700535 "bucket %d stacks on %U",
536 bucket,
537 format_dpo_type, dpo->dpoi_type);
Neale Ranns31ed7442018-02-23 05:29:09 -0800538
Neale Ranns62fe07c2017-10-31 12:28:22 -0700539 mdd = mpls_disp_dpo_get(dpo->dpoi_index);
540
541 dpo = &mdd->mdd_dpo;
542
543 FIB_TEST_I(((DPO_ADJACENCY == dpo->dpoi_type) ||
544 (DPO_ADJACENCY_INCOMPLETE == dpo->dpoi_type)),
545 "bucket %d stacks on %U",
546 bucket,
547 format_dpo_type, dpo->dpoi_type);
548 FIB_TEST_LB((exp->adj.adj == dpo->dpoi_index),
549 "bucket %d stacks on adj %d",
550 bucket,
551 exp->adj.adj);
552 break;
553 }
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800554 case FT_LB_INTF:
Neale Ranns43161a82017-08-12 02:12:00 -0700555 FIB_TEST_I((DPO_INTERFACE_RX == dpo->dpoi_type),
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800556 "bucket %d stacks on %U",
557 bucket,
558 format_dpo_type, dpo->dpoi_type);
559 FIB_TEST_LB((exp->adj.adj == dpo->dpoi_index),
560 "bucket %d stacks on adj %d",
561 bucket,
562 exp->adj.adj);
563 break;
Neale Ranns6f631152017-10-03 08:20:21 -0700564 case FT_LB_L2:
Neale Rannsf068c3e2018-01-03 04:18:48 -0800565 FIB_TEST_I((DPO_DVR == dpo->dpoi_type),
Neale Ranns6f631152017-10-03 08:20:21 -0700566 "bucket %d stacks on %U",
567 bucket,
568 format_dpo_type, dpo->dpoi_type);
569 FIB_TEST_LB((exp->adj.adj == dpo->dpoi_index),
570 "bucket %d stacks on adj %d",
571 bucket,
572 exp->adj.adj);
573 break;
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000574 case FT_LB_O_LB:
575 FIB_TEST_I((DPO_LOAD_BALANCE == dpo->dpoi_type),
576 "bucket %d stacks on %U",
577 bucket,
578 format_dpo_type, dpo->dpoi_type);
579 FIB_TEST_LB((exp->lb.lb == dpo->dpoi_index),
Neale Ranns57b58602017-07-15 07:37:25 -0700580 "bucket %d stacks on lb %d not %d",
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000581 bucket,
Neale Ranns57b58602017-07-15 07:37:25 -0700582 dpo->dpoi_index,
583 exp->lb.lb);
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000584 break;
Neale Rannsd792d9c2017-10-21 10:53:20 -0700585 case FT_LB_BIER_TABLE:
586 FIB_TEST_LB((DPO_BIER_TABLE == dpo->dpoi_type),
587 "bucket %d stacks on %U",
588 bucket,
589 format_dpo_type, dpo->dpoi_type);
590 FIB_TEST_LB((exp->bier.table == dpo->dpoi_index),
591 "bucket %d stacks on lb %d",
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000592 bucket,
Neale Rannsd792d9c2017-10-21 10:53:20 -0700593 exp->bier.table);
594 break;
595 case FT_LB_BIER_FMASK:
596 FIB_TEST_LB((DPO_BIER_FMASK == dpo->dpoi_type),
597 "bucket %d stacks on %U",
598 bucket,
599 format_dpo_type, dpo->dpoi_type);
600 FIB_TEST_LB((exp->bier.fmask == dpo->dpoi_index),
601 "bucket %d stacks on lb %d",
602 bucket,
603 exp->bier.fmask);
604 break;
605 case FT_LB_DROP:
606 FIB_TEST_LB((DPO_DROP == dpo->dpoi_type),
607 "bucket %d stacks on %U",
608 bucket,
609 format_dpo_type, dpo->dpoi_type);
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000610 break;
611 }
612 }
613 return (!0);
614}
615
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800616int
Neale Rannsd792d9c2017-10-21 10:53:20 -0700617fib_test_validate_lb (const dpo_id_t *dpo,
Damjan Marionbb17f3c2018-02-06 19:29:35 +0100618 int n_buckets,
Neale Rannsd792d9c2017-10-21 10:53:20 -0700619 ...)
620{
621 const load_balance_t *lb;
622 va_list ap;
623 int res;
624
625 va_start(ap, n_buckets);
626
Neale Ranns93149bb2017-11-15 10:44:07 -0800627 if (FIB_TEST_I((DPO_LOAD_BALANCE == dpo->dpoi_type),
628 "Entry links to %U",
629 format_dpo_type, dpo->dpoi_type))
630 {
631 lb = load_balance_get(dpo->dpoi_index);
Neale Rannsd792d9c2017-10-21 10:53:20 -0700632
Neale Ranns93149bb2017-11-15 10:44:07 -0800633 res = fib_test_validate_lb_v(lb, n_buckets, &ap);
634 }
635 else
636 {
637 res = !0;
638 }
Neale Rannsd792d9c2017-10-21 10:53:20 -0700639
640 va_end(ap);
641
642 return (res);
643}
644
645int
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000646fib_test_validate_entry (fib_node_index_t fei,
647 fib_forward_chain_type_t fct,
Gabriel Ganned71e0fc2017-10-26 10:35:28 +0200648 int n_buckets,
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000649 ...)
650{
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000651 dpo_id_t dpo = DPO_INVALID;
652 fib_prefix_t pfx;
653 index_t fw_lbi;
654 u32 fib_index;
655 va_list ap;
656 int res;
657
658 va_start(ap, n_buckets);
659
660 fib_entry_get_prefix(fei, &pfx);
661 fib_index = fib_entry_get_fib_index(fei);
662 fib_entry_contribute_forwarding(fei, fct, &dpo);
663
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800664 if (DPO_REPLICATE == dpo.dpoi_type)
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000665 {
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800666 const replicate_t *rep;
667
668 rep = replicate_get(dpo.dpoi_index);
Christophe Fontained3c008d2017-10-02 18:10:54 +0200669 res = fib_test_validate_rep_v(rep, n_buckets, &ap);
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800670 }
671 else
672 {
673 const load_balance_t *lb;
674
675 FIB_TEST_LB((DPO_LOAD_BALANCE == dpo.dpoi_type),
Neale Ranns89541992017-04-06 04:41:02 -0700676 "%U Entry links to %U",
677 format_fib_prefix, &pfx,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800678 format_dpo_type, dpo.dpoi_type);
679
680 lb = load_balance_get(dpo.dpoi_index);
Christophe Fontained3c008d2017-10-02 18:10:54 +0200681 res = fib_test_validate_lb_v(lb, n_buckets, &ap);
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800682
683 /*
684 * ensure that the LB contributed by the entry is the
685 * same as the LB in the forwarding tables
686 */
687 if (fct == fib_entry_get_default_chain_type(fib_entry_get(fei)))
Neale Rannsad422ed2016-11-02 14:20:04 +0000688 {
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800689 switch (pfx.fp_proto)
Neale Rannsad422ed2016-11-02 14:20:04 +0000690 {
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800691 case FIB_PROTOCOL_IP4:
692 fw_lbi = ip4_fib_forwarding_lookup(fib_index, &pfx.fp_addr.ip4);
Neale Rannsad422ed2016-11-02 14:20:04 +0000693 break;
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800694 case FIB_PROTOCOL_IP6:
695 fw_lbi = ip6_fib_table_fwding_lookup(&ip6_main, fib_index, &pfx.fp_addr.ip6);
696 break;
697 case FIB_PROTOCOL_MPLS:
698 {
699 mpls_unicast_header_t hdr = {
700 .label_exp_s_ttl = 0,
701 };
702
703 vnet_mpls_uc_set_label(&hdr.label_exp_s_ttl, pfx.fp_label);
704 vnet_mpls_uc_set_s(&hdr.label_exp_s_ttl, pfx.fp_eos);
705 hdr.label_exp_s_ttl = clib_host_to_net_u32(hdr.label_exp_s_ttl);
706
707 fw_lbi = mpls_fib_table_forwarding_lookup(fib_index, &hdr);
708 break;
709 }
710 default:
711 fw_lbi = 0;
Neale Rannsad422ed2016-11-02 14:20:04 +0000712 }
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800713 FIB_TEST_LB((fw_lbi == dpo.dpoi_index),
Neale Ranns89541992017-04-06 04:41:02 -0700714 "Contributed LB = FW LB:\n fwd:%U\n cont:%U",
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800715 format_load_balance, fw_lbi, 0,
716 format_load_balance, dpo.dpoi_index, 0);
Neale Rannsad422ed2016-11-02 14:20:04 +0000717 }
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000718 }
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000719
720 dpo_reset(&dpo);
721
722 va_end(ap);
723
724 return (res);
725}
726
Neale Ranns0ebe8d72016-12-08 19:48:11 +0000727static int
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100728fib_test_v4 (void)
729{
730 /*
731 * In the default table check for the presence and correct forwarding
732 * of the special entries
733 */
734 fib_node_index_t dfrt, fei, ai, ai2, locked_ai, ai_01, ai_02, ai_03;
735 const dpo_id_t *dpo, *dpo1, *dpo2, *dpo_drop;
736 const ip_adjacency_t *adj;
737 const load_balance_t *lb;
738 test_main_t *tm;
739 u32 fib_index;
Neale Ranns994dab42017-04-18 12:56:45 -0700740 int lb_count;
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100741 int ii;
742
743 /* via 10.10.10.1 */
744 ip46_address_t nh_10_10_10_1 = {
745 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
746 };
747 /* via 10.10.10.2 */
748 ip46_address_t nh_10_10_10_2 = {
749 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02),
750 };
751
Neale Rannsf12a83f2017-04-18 09:09:40 -0700752 FIB_TEST((0 == pool_elts(load_balance_map_pool)), "LB-map pool size is %d",
753 pool_elts(load_balance_map_pool));
754
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100755 tm = &test_main;
756
Neale Ranns994dab42017-04-18 12:56:45 -0700757 /* record the nubmer of load-balances in use before we start */
758 lb_count = pool_elts(load_balance_pool);
759
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100760 /* Find or create FIB table 11 */
Neale Ranns15002542017-09-10 04:39:11 -0700761 fib_index = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP4, 11,
762 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100763
764 for (ii = 0; ii < 4; ii++)
765 {
766 ip4_main.fib_index_by_sw_if_index[tm->hw[ii]->sw_if_index] = fib_index;
767 }
768
769 fib_prefix_t pfx_0_0_0_0_s_0 = {
770 .fp_len = 0,
771 .fp_proto = FIB_PROTOCOL_IP4,
772 .fp_addr = {
773 .ip4 = {
774 {0}
775 },
776 },
777 };
778
779 fib_prefix_t pfx = {
780 .fp_len = 0,
781 .fp_proto = FIB_PROTOCOL_IP4,
782 .fp_addr = {
783 .ip4 = {
784 {0}
785 },
786 },
787 };
788
789 dpo_drop = drop_dpo_get(DPO_PROTO_IP4);
790
791 dfrt = fib_table_lookup(fib_index, &pfx_0_0_0_0_s_0);
792 FIB_TEST((FIB_NODE_INDEX_INVALID != dfrt), "default route present");
793 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(dfrt)),
794 "Default route is DROP");
795
796 pfx.fp_len = 32;
797 fei = fib_table_lookup(fib_index, &pfx);
798 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "all zeros route present");
799 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
800 "all 0s route is DROP");
801
802 pfx.fp_addr.ip4.as_u32 = clib_host_to_net_u32(0xffffffff);
803 pfx.fp_len = 32;
804 fei = fib_table_lookup(fib_index, &pfx);
805 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "all ones route present");
806 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
807 "all 1s route is DROP");
808
809 pfx.fp_addr.ip4.as_u32 = clib_host_to_net_u32(0xe0000000);
810 pfx.fp_len = 8;
811 fei = fib_table_lookup(fib_index, &pfx);
812 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "all-mcast route present");
813 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
814 "all-mcast route is DROP");
815
816 pfx.fp_addr.ip4.as_u32 = clib_host_to_net_u32(0xf0000000);
817 pfx.fp_len = 8;
818 fei = fib_table_lookup(fib_index, &pfx);
819 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "class-e route present");
820 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
821 "class-e route is DROP");
822
823 /*
824 * at this stage there are 5 entries in the test FIB (plus 5 in the default),
825 * all of which are special sourced and so none of which share path-lists.
Neale Ranns32e1c012016-11-22 17:07:28 +0000826 * There are also 2 entries, and 2 non-shared path-lists, in the v6 default
827 * table, and 4 path-lists in the v6 MFIB table
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100828 */
Neale Ranns32e1c012016-11-22 17:07:28 +0000829#define ENBR (5+5+2)
830#define PNBR (5+5+6)
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100831 FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +0000832 FIB_TEST((PNBR == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100833 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +0000834 FIB_TEST((ENBR == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100835 fib_entry_pool_size());
836
837 /*
838 * add interface routes.
839 * validate presence of /24 attached and /32 recieve.
840 * test for the presence of the receive address in the glean and local adj
841 */
842 fib_prefix_t local_pfx = {
843 .fp_len = 24,
844 .fp_proto = FIB_PROTOCOL_IP4,
845 .fp_addr = {
846 .ip4 = {
847 .as_u32 = clib_host_to_net_u32(0x0a0a0a0a),
848 },
849 },
850 };
851
852 fib_table_entry_update_one_path(fib_index, &local_pfx,
853 FIB_SOURCE_INTERFACE,
854 (FIB_ENTRY_FLAG_CONNECTED |
855 FIB_ENTRY_FLAG_ATTACHED),
Neale Rannsda78f952017-05-24 09:15:43 -0700856 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100857 NULL,
858 tm->hw[0]->sw_if_index,
859 ~0, // invalid fib index
860 1, // weight
Neale Rannsad422ed2016-11-02 14:20:04 +0000861 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100862 FIB_ROUTE_PATH_FLAG_NONE);
863 fei = fib_table_lookup(fib_index, &local_pfx);
864 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached interface route present");
865 FIB_TEST(((FIB_ENTRY_FLAG_ATTACHED | FIB_ENTRY_FLAG_CONNECTED) ==
866 fib_entry_get_flags(fei)),
867 "Flags set on attached interface");
868
869 ai = fib_entry_get_adj(fei);
Neale Ranns81424992017-05-18 03:03:22 -0700870 FIB_TEST((FIB_NODE_INDEX_INVALID != ai),
871 "attached interface route adj present %d", ai);
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100872 adj = adj_get(ai);
873 FIB_TEST((IP_LOOKUP_NEXT_GLEAN == adj->lookup_next_index),
874 "attached interface adj is glean");
875 FIB_TEST((0 == ip46_address_cmp(&local_pfx.fp_addr,
876 &adj->sub_type.glean.receive_addr)),
877 "attached interface adj is receive ok");
878
879 local_pfx.fp_len = 32;
880 fib_table_entry_update_one_path(fib_index, &local_pfx,
881 FIB_SOURCE_INTERFACE,
882 (FIB_ENTRY_FLAG_CONNECTED |
883 FIB_ENTRY_FLAG_LOCAL),
Neale Rannsda78f952017-05-24 09:15:43 -0700884 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100885 NULL,
886 tm->hw[0]->sw_if_index,
887 ~0, // invalid fib index
888 1, // weight
Neale Rannsad422ed2016-11-02 14:20:04 +0000889 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100890 FIB_ROUTE_PATH_FLAG_NONE);
891 fei = fib_table_lookup(fib_index, &local_pfx);
892 FIB_TEST(((FIB_ENTRY_FLAG_LOCAL | FIB_ENTRY_FLAG_CONNECTED) ==
893 fib_entry_get_flags(fei)),
894 "Flags set on local interface");
895
896 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local interface route present");
897
898 dpo = fib_entry_contribute_ip_forwarding(fei);
Neale Ranns3ee44042016-10-03 13:05:48 +0100899 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 0),
900 "RPF list for local length 0");
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100901 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
902 FIB_TEST((DPO_RECEIVE == dpo->dpoi_type),
903 "local interface adj is local");
904 receive_dpo_t *rd = receive_dpo_get(dpo->dpoi_index);
905
906 FIB_TEST((0 == ip46_address_cmp(&local_pfx.fp_addr,
907 &rd->rd_addr)),
908 "local interface adj is receive ok");
909
910 FIB_TEST((2 == fib_table_get_num_entries(fib_index,
911 FIB_PROTOCOL_IP4,
912 FIB_SOURCE_INTERFACE)),
913 "2 Interface Source'd prefixes");
914
915 /*
916 * +2 interface routes +2 non-shared path-lists
917 */
918 FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +0000919 FIB_TEST((PNBR+2 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100920 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +0000921 FIB_TEST((ENBR+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100922 fib_entry_pool_size());
923
924 /*
925 * Modify the default route to be via an adj not yet known.
926 * this sources the defalut route with the API source, which is
927 * a higher preference to the DEFAULT_ROUTE source
928 */
929 pfx.fp_addr.ip4.as_u32 = 0;
930 pfx.fp_len = 0;
931 fib_table_entry_path_add(fib_index, &pfx,
932 FIB_SOURCE_API,
933 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -0700934 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100935 &nh_10_10_10_1,
936 tm->hw[0]->sw_if_index,
937 ~0, // invalid fib index
938 1,
Neale Rannsad422ed2016-11-02 14:20:04 +0000939 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100940 FIB_ROUTE_PATH_FLAG_NONE);
941 fei = fib_table_lookup(fib_index, &pfx);
942 FIB_TEST((FIB_ENTRY_FLAG_NONE == fib_entry_get_flags(fei)),
943 "Flags set on API route");
944
945 FIB_TEST((fei == dfrt), "default route same index");
946 ai = fib_entry_get_adj(fei);
947 FIB_TEST((FIB_NODE_INDEX_INVALID != ai), "default route adj present");
948 adj = adj_get(ai);
949 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
950 "adj is incomplete");
951 FIB_TEST((0 == ip46_address_cmp(&nh_10_10_10_1, &adj->sub_type.nbr.next_hop)),
952 "adj nbr next-hop ok");
953 FIB_TEST((1 == fib_table_get_num_entries(fib_index,
954 FIB_PROTOCOL_IP4,
955 FIB_SOURCE_API)),
956 "1 API Source'd prefixes");
957
958 /*
959 * find the adj in the shared db
960 */
961 locked_ai = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +0100962 VNET_LINK_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100963 &nh_10_10_10_1,
964 tm->hw[0]->sw_if_index);
965 FIB_TEST((locked_ai == ai), "ADJ NBR DB find");
966 adj_unlock(locked_ai);
967
968 /*
969 * +1 shared path-list
970 */
971 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
972 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +0000973 FIB_TEST((PNBR+3 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100974 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +0000975 FIB_TEST((ENBR+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100976 fib_entry_pool_size());
977
978 /*
979 * remove the API source from the default route. We expected
980 * the route to remain, sourced by DEFAULT_ROUTE, and hence a DROP
981 */
982 pfx.fp_addr.ip4.as_u32 = 0;
983 pfx.fp_len = 0;
984 fib_table_entry_path_remove(fib_index, &pfx,
985 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -0700986 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100987 &nh_10_10_10_1,
988 tm->hw[0]->sw_if_index,
989 ~0, // non-recursive path, so no FIB index
990 1,
991 FIB_ROUTE_PATH_FLAG_NONE);
992
993 fei = fib_table_lookup(fib_index, &pfx);
994
995 FIB_TEST((fei == dfrt), "default route same index");
996 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
997 "Default route is DROP");
998
999 /*
1000 * -1 shared-path-list
1001 */
1002 FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00001003 FIB_TEST((PNBR+2 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001004 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001005 FIB_TEST((ENBR+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001006 fib_entry_pool_size());
1007
1008 /*
1009 * Add an 2 ARP entry => a complete ADJ plus adj-fib.
1010 */
1011 fib_prefix_t pfx_10_10_10_1_s_32 = {
1012 .fp_len = 32,
1013 .fp_proto = FIB_PROTOCOL_IP4,
1014 .fp_addr = {
1015 /* 10.10.10.1 */
1016 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
1017 },
1018 };
1019 fib_prefix_t pfx_10_10_10_2_s_32 = {
1020 .fp_len = 32,
1021 .fp_proto = FIB_PROTOCOL_IP4,
1022 .fp_addr = {
1023 /* 10.10.10.2 */
1024 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02),
1025 },
1026 };
1027 fib_prefix_t pfx_11_11_11_11_s_32 = {
1028 .fp_len = 32,
1029 .fp_proto = FIB_PROTOCOL_IP4,
1030 .fp_addr = {
1031 /* 11.11.11.11 */
1032 .ip4.as_u32 = clib_host_to_net_u32(0x0b0b0b0b),
1033 },
1034 };
1035 u8 eth_addr[] = {
1036 0xde, 0xde, 0xde, 0xba, 0xba, 0xba,
1037 };
Neale Rannsb80c5362016-10-08 13:03:40 +01001038
Neale Ranns3ee44042016-10-03 13:05:48 +01001039 ip46_address_t nh_12_12_12_12 = {
1040 .ip4.as_u32 = clib_host_to_net_u32(0x0c0c0c0c),
1041 };
1042 adj_index_t ai_12_12_12_12;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001043
1044 /*
1045 * Add a route via an incomplete ADJ. then complete the ADJ
1046 * Expect the route LB is updated to use complete adj type.
1047 */
1048 fei = fib_table_entry_update_one_path(fib_index,
1049 &pfx_11_11_11_11_s_32,
1050 FIB_SOURCE_API,
1051 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07001052 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001053 &pfx_10_10_10_1_s_32.fp_addr,
1054 tm->hw[0]->sw_if_index,
1055 ~0, // invalid fib index
1056 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001057 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001058 FIB_ROUTE_PATH_FLAG_NONE);
1059
1060 dpo = fib_entry_contribute_ip_forwarding(fei);
1061 dpo1 = load_balance_get_bucket(dpo->dpoi_index, 0);
1062 FIB_TEST(DPO_ADJACENCY_INCOMPLETE == dpo1->dpoi_type,
1063 "11.11.11.11/32 via incomplete adj");
1064
1065 ai_01 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01001066 VNET_LINK_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001067 &pfx_10_10_10_1_s_32.fp_addr,
1068 tm->hw[0]->sw_if_index);
1069 FIB_TEST((FIB_NODE_INDEX_INVALID != ai_01), "adj created");
1070 adj = adj_get(ai_01);
1071 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
1072 "adj is incomplete");
1073 FIB_TEST((0 == ip46_address_cmp(&pfx_10_10_10_1_s_32.fp_addr,
1074 &adj->sub_type.nbr.next_hop)),
1075 "adj nbr next-hop ok");
1076
Neale Rannsb80c5362016-10-08 13:03:40 +01001077 adj_nbr_update_rewrite(ai_01, ADJ_NBR_REWRITE_FLAG_COMPLETE,
1078 fib_test_build_rewrite(eth_addr));
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001079 FIB_TEST((IP_LOOKUP_NEXT_REWRITE == adj->lookup_next_index),
1080 "adj is complete");
1081 FIB_TEST((0 == ip46_address_cmp(&pfx_10_10_10_1_s_32.fp_addr,
1082 &adj->sub_type.nbr.next_hop)),
1083 "adj nbr next-hop ok");
1084 ai = fib_entry_get_adj(fei);
1085 FIB_TEST((ai_01 == ai), "ADJ-FIB resolves via adj");
1086
1087 dpo = fib_entry_contribute_ip_forwarding(fei);
1088 dpo1 = load_balance_get_bucket(dpo->dpoi_index, 0);
1089 FIB_TEST(DPO_ADJACENCY == dpo1->dpoi_type,
1090 "11.11.11.11/32 via complete adj");
Neale Ranns3ee44042016-10-03 13:05:48 +01001091 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 1,
1092 tm->hw[0]->sw_if_index),
1093 "RPF list for adj-fib contains adj");
1094
1095 ai_12_12_12_12 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01001096 VNET_LINK_IP4,
Neale Ranns3ee44042016-10-03 13:05:48 +01001097 &nh_12_12_12_12,
1098 tm->hw[1]->sw_if_index);
1099 FIB_TEST((FIB_NODE_INDEX_INVALID != ai_12_12_12_12), "adj created");
1100 adj = adj_get(ai_12_12_12_12);
1101 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
1102 "adj is incomplete");
1103 FIB_TEST((0 == ip46_address_cmp(&nh_12_12_12_12,
1104 &adj->sub_type.nbr.next_hop)),
1105 "adj nbr next-hop ok");
Neale Rannsb80c5362016-10-08 13:03:40 +01001106 adj_nbr_update_rewrite(ai_12_12_12_12, ADJ_NBR_REWRITE_FLAG_COMPLETE,
1107 fib_test_build_rewrite(eth_addr));
Neale Ranns3ee44042016-10-03 13:05:48 +01001108 FIB_TEST((IP_LOOKUP_NEXT_REWRITE == adj->lookup_next_index),
1109 "adj is complete");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001110
1111 /*
1112 * add the adj fib
1113 */
Neale Ranns81424992017-05-18 03:03:22 -07001114 fei = fib_table_entry_path_add(fib_index,
1115 &pfx_10_10_10_1_s_32,
1116 FIB_SOURCE_ADJ,
1117 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07001118 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07001119 &pfx_10_10_10_1_s_32.fp_addr,
1120 tm->hw[0]->sw_if_index,
1121 ~0, // invalid fib index
1122 1,
1123 NULL,
1124 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001125 FIB_TEST((FIB_ENTRY_FLAG_ATTACHED == fib_entry_get_flags(fei)),
1126 "Flags set on adj-fib");
1127 ai = fib_entry_get_adj(fei);
Neale Ranns81424992017-05-18 03:03:22 -07001128 FIB_TEST((ai_01 == ai), "ADJ-FIB resolves via adj, %d", ai);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001129
1130 fib_table_entry_path_remove(fib_index,
1131 &pfx_11_11_11_11_s_32,
1132 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07001133 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001134 &pfx_10_10_10_1_s_32.fp_addr,
1135 tm->hw[0]->sw_if_index,
1136 ~0, // invalid fib index
1137 1,
1138 FIB_ROUTE_PATH_FLAG_NONE);
1139
1140 eth_addr[5] = 0xb2;
1141
1142 ai_02 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01001143 VNET_LINK_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001144 &pfx_10_10_10_2_s_32.fp_addr,
1145 tm->hw[0]->sw_if_index);
1146 FIB_TEST((FIB_NODE_INDEX_INVALID != ai_02), "adj created");
1147 adj = adj_get(ai_02);
1148 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
1149 "adj is incomplete");
1150 FIB_TEST((0 == ip46_address_cmp(&pfx_10_10_10_2_s_32.fp_addr,
1151 &adj->sub_type.nbr.next_hop)),
1152 "adj nbr next-hop ok");
1153
Neale Rannsb80c5362016-10-08 13:03:40 +01001154 adj_nbr_update_rewrite(ai_02, ADJ_NBR_REWRITE_FLAG_COMPLETE,
1155 fib_test_build_rewrite(eth_addr));
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001156 FIB_TEST((IP_LOOKUP_NEXT_REWRITE == adj->lookup_next_index),
1157 "adj is complete");
1158 FIB_TEST((0 == ip46_address_cmp(&pfx_10_10_10_2_s_32.fp_addr,
1159 &adj->sub_type.nbr.next_hop)),
1160 "adj nbr next-hop ok");
1161 FIB_TEST((ai_01 != ai_02), "ADJs are different");
1162
Neale Ranns81424992017-05-18 03:03:22 -07001163 fib_table_entry_path_add(fib_index,
1164 &pfx_10_10_10_2_s_32,
1165 FIB_SOURCE_ADJ,
1166 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07001167 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07001168 &pfx_10_10_10_2_s_32.fp_addr,
1169 tm->hw[0]->sw_if_index,
1170 ~0, // invalid fib index
1171 1,
1172 NULL,
1173 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001174
1175 fei = fib_table_lookup(fib_index, &pfx_10_10_10_2_s_32);
1176 ai = fib_entry_get_adj(fei);
1177 FIB_TEST((ai_02 == ai), "ADJ-FIB resolves via adj");
1178
1179 /*
1180 * +2 adj-fibs, and their non-shared path-lists
1181 */
1182 FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00001183 FIB_TEST((PNBR+4 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001184 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001185 FIB_TEST((ENBR+4 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001186 fib_entry_pool_size());
1187
1188 /*
Neale Ranns3ee44042016-10-03 13:05:48 +01001189 * Add 2 routes via the first ADJ. ensure path-list sharing
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001190 */
1191 fib_prefix_t pfx_1_1_1_1_s_32 = {
1192 .fp_len = 32,
1193 .fp_proto = FIB_PROTOCOL_IP4,
1194 .fp_addr = {
1195 /* 1.1.1.1/32 */
1196 .ip4.as_u32 = clib_host_to_net_u32(0x01010101),
1197 },
1198 };
1199
1200 fib_table_entry_path_add(fib_index,
1201 &pfx_1_1_1_1_s_32,
1202 FIB_SOURCE_API,
1203 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001204 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001205 &nh_10_10_10_1,
1206 tm->hw[0]->sw_if_index,
1207 ~0, // invalid fib index
1208 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001209 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001210 FIB_ROUTE_PATH_FLAG_NONE);
1211 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
1212 ai = fib_entry_get_adj(fei);
1213 FIB_TEST((ai_01 == ai), "1.1.1.1 resolves via 10.10.10.1");
1214
1215 /*
1216 * +1 entry and a shared path-list
1217 */
1218 FIB_TEST((1 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00001219 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001220 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001221 FIB_TEST((ENBR+5 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001222 fib_entry_pool_size());
1223
1224 /* 1.1.2.0/24 */
1225 fib_prefix_t pfx_1_1_2_0_s_24 = {
1226 .fp_len = 24,
1227 .fp_proto = FIB_PROTOCOL_IP4,
1228 .fp_addr = {
1229 .ip4.as_u32 = clib_host_to_net_u32(0x01010200),
1230 }
1231 };
1232
1233 fib_table_entry_path_add(fib_index,
1234 &pfx_1_1_2_0_s_24,
1235 FIB_SOURCE_API,
1236 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001237 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001238 &nh_10_10_10_1,
1239 tm->hw[0]->sw_if_index,
1240 ~0, // invalid fib index
1241 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001242 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001243 FIB_ROUTE_PATH_FLAG_NONE);
1244 fei = fib_table_lookup(fib_index, &pfx_1_1_2_0_s_24);
1245 ai = fib_entry_get_adj(fei);
1246 FIB_TEST((ai_01 == ai), "1.1.2.0/24 resolves via 10.10.10.1");
1247
1248 /*
1249 * +1 entry only
1250 */
1251 FIB_TEST((1 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00001252 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001253 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001254 FIB_TEST((ENBR+6 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001255 fib_entry_pool_size());
1256
1257 /*
1258 * modify 1.1.2.0/24 to use multipath.
1259 */
1260 fib_table_entry_path_add(fib_index,
1261 &pfx_1_1_2_0_s_24,
1262 FIB_SOURCE_API,
1263 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001264 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001265 &nh_10_10_10_2,
1266 tm->hw[0]->sw_if_index,
1267 ~0, // invalid fib index
1268 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001269 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001270 FIB_ROUTE_PATH_FLAG_NONE);
1271 fei = fib_table_lookup(fib_index, &pfx_1_1_2_0_s_24);
1272 dpo = fib_entry_contribute_ip_forwarding(fei);
Neale Ranns3ee44042016-10-03 13:05:48 +01001273 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1274 1, tm->hw[0]->sw_if_index),
1275 "RPF list for 1.1.2.0/24 contains both adjs");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001276
1277 dpo1 = load_balance_get_bucket(dpo->dpoi_index, 0);
1278 FIB_TEST(DPO_ADJACENCY == dpo1->dpoi_type, "type is %d", dpo1->dpoi_type);
1279 FIB_TEST((ai_01 == dpo1->dpoi_index),
1280 "1.1.2.0/24 bucket 0 resolves via 10.10.10.1 (%d=%d)",
1281 ai_01, dpo1->dpoi_index);
1282
1283 dpo1 = load_balance_get_bucket(dpo->dpoi_index, 1);
1284 FIB_TEST(DPO_ADJACENCY == dpo1->dpoi_type, "type is %d", dpo1->dpoi_type);
1285 FIB_TEST((ai_02 == dpo1->dpoi_index),
1286 "1.1.2.0/24 bucket 1 resolves via 10.10.10.2");
1287
1288 /*
1289 * +1 shared-pathlist
1290 */
1291 FIB_TEST((2 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00001292 FIB_TEST((PNBR+6 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001293 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001294 FIB_TEST((ENBR+6 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001295 fib_entry_pool_size());
1296
1297 /*
1298 * revert the modify
1299 */
1300 fib_table_entry_path_remove(fib_index,
1301 &pfx_1_1_2_0_s_24,
1302 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07001303 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001304 &nh_10_10_10_2,
1305 tm->hw[0]->sw_if_index,
1306 ~0,
1307 1,
1308 FIB_ROUTE_PATH_FLAG_NONE);
1309 fei = fib_table_lookup(fib_index, &pfx_1_1_2_0_s_24);
Neale Ranns3ee44042016-10-03 13:05:48 +01001310 dpo = fib_entry_contribute_ip_forwarding(fei);
1311 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1312 1, tm->hw[0]->sw_if_index),
1313 "RPF list for 1.1.2.0/24 contains one adj");
1314
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001315 ai = fib_entry_get_adj(fei);
1316 FIB_TEST((ai_01 == ai), "1.1.2.0/24 resolves via 10.10.10.1");
1317
1318 /*
1319 * +1 shared-pathlist
1320 */
1321 FIB_TEST((1 == fib_path_list_db_size()), "path list DB is %d",
1322 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001323 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001324 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001325 FIB_TEST((ENBR+6 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001326 fib_entry_pool_size());
1327
1328 /*
1329 * Add 2 recursive routes:
1330 * 100.100.100.100/32 via 1.1.1.1/32 => the via entry is installed.
1331 * 100.100.100.101/32 via 1.1.1.1/32 => the via entry is installed.
1332 */
1333 fib_prefix_t bgp_100_pfx = {
1334 .fp_len = 32,
1335 .fp_proto = FIB_PROTOCOL_IP4,
1336 .fp_addr = {
1337 /* 100.100.100.100/32 */
1338 .ip4.as_u32 = clib_host_to_net_u32(0x64646464),
1339 },
1340 };
1341 /* via 1.1.1.1 */
1342 ip46_address_t nh_1_1_1_1 = {
1343 .ip4.as_u32 = clib_host_to_net_u32(0x01010101),
1344 };
1345
Neale Ranns3ee44042016-10-03 13:05:48 +01001346 fei = fib_table_entry_path_add(fib_index,
1347 &bgp_100_pfx,
1348 FIB_SOURCE_API,
1349 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001350 DPO_PROTO_IP4,
Neale Ranns3ee44042016-10-03 13:05:48 +01001351 &nh_1_1_1_1,
1352 ~0, // no index provided.
1353 fib_index, // nexthop in same fib as route
1354 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001355 NULL,
Neale Ranns3ee44042016-10-03 13:05:48 +01001356 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001357
Neale Ranns3ee44042016-10-03 13:05:48 +01001358 FIB_TEST_REC_FORW(&bgp_100_pfx, &pfx_1_1_1_1_s_32, 0);
1359 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 1,
1360 tm->hw[0]->sw_if_index),
1361 "RPF list for adj-fib contains adj");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001362
1363 /*
1364 * +1 entry and +1 shared-path-list
1365 */
1366 FIB_TEST((2 == fib_path_list_db_size()), "path list DB population:%d",
1367 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001368 FIB_TEST((PNBR+6 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001369 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001370 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001371 fib_entry_pool_size());
1372
1373 fib_prefix_t bgp_101_pfx = {
1374 .fp_len = 32,
1375 .fp_proto = FIB_PROTOCOL_IP4,
1376 .fp_addr = {
1377 /* 100.100.100.101/32 */
1378 .ip4.as_u32 = clib_host_to_net_u32(0x64646465),
1379 },
1380 };
1381
1382 fib_table_entry_path_add(fib_index,
1383 &bgp_101_pfx,
1384 FIB_SOURCE_API,
1385 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001386 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001387 &nh_1_1_1_1,
1388 ~0, // no index provided.
1389 fib_index, // nexthop in same fib as route
1390 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001391 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001392 FIB_ROUTE_PATH_FLAG_NONE);
1393
Neale Ranns3ee44042016-10-03 13:05:48 +01001394 FIB_TEST_REC_FORW(&bgp_101_pfx, &pfx_1_1_1_1_s_32, 0);
1395 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 1,
1396 tm->hw[0]->sw_if_index),
1397 "RPF list for adj-fib contains adj");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001398
1399 /*
1400 * +1 entry, but the recursive path-list is shared.
1401 */
1402 FIB_TEST((2 == fib_path_list_db_size()), "path list DB population:%d",
1403 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001404 FIB_TEST((PNBR+6 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001405 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001406 FIB_TEST((ENBR+8 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001407 fib_entry_pool_size());
1408
1409 /*
Neale Rannsa0558302017-04-13 00:44:52 -07001410 * An special route; one where the user (me) provides the
1411 * adjacency through which the route will resovle by setting the flags
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001412 */
1413 fib_prefix_t ex_pfx = {
1414 .fp_len = 32,
1415 .fp_proto = FIB_PROTOCOL_IP4,
1416 .fp_addr = {
1417 /* 4.4.4.4/32 */
1418 .ip4.as_u32 = clib_host_to_net_u32(0x04040404),
1419 },
1420 };
1421
1422 fib_table_entry_special_add(fib_index,
1423 &ex_pfx,
1424 FIB_SOURCE_SPECIAL,
Neale Rannsa0558302017-04-13 00:44:52 -07001425 FIB_ENTRY_FLAG_LOCAL);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001426 fei = fib_table_lookup_exact_match(fib_index, &ex_pfx);
Neale Rannsa0558302017-04-13 00:44:52 -07001427 dpo = fib_entry_contribute_ip_forwarding(fei);
1428 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
1429 FIB_TEST((DPO_RECEIVE == dpo->dpoi_type),
1430 "local interface adj is local");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001431
1432 fib_table_entry_special_remove(fib_index,
1433 &ex_pfx,
1434 FIB_SOURCE_SPECIAL);
1435 FIB_TEST(FIB_NODE_INDEX_INVALID ==
1436 fib_table_lookup_exact_match(fib_index, &ex_pfx),
1437 "Exclusive reoute removed");
1438
1439 /*
1440 * An EXCLUSIVE route; one where the user (me) provides the exclusive
1441 * adjacency through which the route will resovle
1442 */
Neale Ranns948e00f2016-10-20 13:39:34 +01001443 dpo_id_t ex_dpo = DPO_INVALID;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001444
1445 lookup_dpo_add_or_lock_w_fib_index(fib_index,
1446 DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001447 LOOKUP_UNICAST,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001448 LOOKUP_INPUT_DST_ADDR,
1449 LOOKUP_TABLE_FROM_CONFIG,
1450 &ex_dpo);
1451
1452 fib_table_entry_special_dpo_add(fib_index,
1453 &ex_pfx,
1454 FIB_SOURCE_SPECIAL,
1455 FIB_ENTRY_FLAG_EXCLUSIVE,
1456 &ex_dpo);
1457 fei = fib_table_lookup_exact_match(fib_index, &ex_pfx);
1458 dpo = fib_entry_contribute_ip_forwarding(fei);
1459 FIB_TEST(!dpo_cmp(&ex_dpo, load_balance_get_bucket(dpo->dpoi_index, 0)),
1460 "exclusive remote uses lookup DPO");
1461
Neale Ranns948e00f2016-10-20 13:39:34 +01001462 /*
1463 * update the exclusive to use a different DPO
1464 */
Neale Ranns450cd302016-11-09 17:49:42 +00001465 ip_null_dpo_add_and_lock(DPO_PROTO_IP4,
Neale Ranns948e00f2016-10-20 13:39:34 +01001466 IP_NULL_ACTION_SEND_ICMP_UNREACH,
1467 &ex_dpo);
1468 fib_table_entry_special_dpo_update(fib_index,
1469 &ex_pfx,
1470 FIB_SOURCE_SPECIAL,
1471 FIB_ENTRY_FLAG_EXCLUSIVE,
1472 &ex_dpo);
1473 dpo = fib_entry_contribute_ip_forwarding(fei);
1474 FIB_TEST(!dpo_cmp(&ex_dpo, load_balance_get_bucket(dpo->dpoi_index, 0)),
1475 "exclusive remote uses now uses NULL DPO");
1476
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001477 fib_table_entry_special_remove(fib_index,
1478 &ex_pfx,
1479 FIB_SOURCE_SPECIAL);
1480 FIB_TEST(FIB_NODE_INDEX_INVALID ==
1481 fib_table_lookup_exact_match(fib_index, &ex_pfx),
1482 "Exclusive reoute removed");
1483 dpo_reset(&ex_dpo);
1484
1485 /*
1486 * Add a recursive route:
1487 * 200.200.200.200/32 via 1.1.1.2/32 => the via entry is NOT installed.
1488 */
1489 fib_prefix_t bgp_200_pfx = {
1490 .fp_len = 32,
1491 .fp_proto = FIB_PROTOCOL_IP4,
1492 .fp_addr = {
1493 /* 200.200.200.200/32 */
1494 .ip4.as_u32 = clib_host_to_net_u32(0xc8c8c8c8),
1495 },
1496 };
1497 /* via 1.1.1.2 */
1498 fib_prefix_t pfx_1_1_1_2_s_32 = {
1499 .fp_len = 32,
1500 .fp_proto = FIB_PROTOCOL_IP4,
1501 .fp_addr = {
1502 .ip4.as_u32 = clib_host_to_net_u32(0x01010102),
1503 },
1504 };
1505
Neale Ranns57b58602017-07-15 07:37:25 -07001506 fei = fib_table_entry_path_add(fib_index,
1507 &bgp_200_pfx,
1508 FIB_SOURCE_API,
1509 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001510 DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07001511 &pfx_1_1_1_2_s_32.fp_addr,
1512 ~0, // no index provided.
1513 fib_index, // nexthop in same fib as route
1514 1,
1515 NULL,
1516 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001517
Neale Ranns57b58602017-07-15 07:37:25 -07001518 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
1519 "Recursive via unresolved is drop");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001520
1521 /*
1522 * the adj should be recursive via drop, since the route resolves via
1523 * the default route, which is itself a DROP
1524 */
1525 fei = fib_table_lookup(fib_index, &pfx_1_1_1_2_s_32);
1526 dpo1 = fib_entry_contribute_ip_forwarding(fei);
1527 FIB_TEST(load_balance_is_drop(dpo1), "1.1.1.2/32 is drop");
Neale Ranns3ee44042016-10-03 13:05:48 +01001528 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 0),
1529 "RPF list for 1.1.1.2/32 contains 0 adjs");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001530
1531 /*
1532 * +2 entry and +1 shared-path-list
1533 */
1534 FIB_TEST((3 == fib_path_list_db_size()), "path list DB population:%d",
1535 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001536 FIB_TEST((PNBR+7 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001537 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001538 FIB_TEST((ENBR+10 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001539 fib_entry_pool_size());
1540
1541 /*
1542 * Unequal Cost load-balance. 3:1 ratio. fits in a 4 bucket LB
Neale Ranns3ee44042016-10-03 13:05:48 +01001543 * The paths are sort by NH first. in this case the the path with greater
1544 * weight is first in the set. This ordering is to test the RPF sort|uniq logic
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001545 */
1546 fib_prefix_t pfx_1_2_3_4_s_32 = {
1547 .fp_len = 32,
1548 .fp_proto = FIB_PROTOCOL_IP4,
1549 .fp_addr = {
1550 .ip4.as_u32 = clib_host_to_net_u32(0x01020304),
1551 },
1552 };
1553 fib_table_entry_path_add(fib_index,
1554 &pfx_1_2_3_4_s_32,
1555 FIB_SOURCE_API,
1556 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001557 DPO_PROTO_IP4,
Neale Ranns3ee44042016-10-03 13:05:48 +01001558 &nh_10_10_10_1,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001559 tm->hw[0]->sw_if_index,
1560 ~0,
1561 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001562 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001563 FIB_ROUTE_PATH_FLAG_NONE);
1564 fei = fib_table_entry_path_add(fib_index,
1565 &pfx_1_2_3_4_s_32,
1566 FIB_SOURCE_API,
1567 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001568 DPO_PROTO_IP4,
Neale Ranns3ee44042016-10-03 13:05:48 +01001569 &nh_12_12_12_12,
1570 tm->hw[1]->sw_if_index,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001571 ~0,
1572 3,
Neale Rannsad422ed2016-11-02 14:20:04 +00001573 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001574 FIB_ROUTE_PATH_FLAG_NONE);
1575
1576 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "1.2.3.4/32 presnet");
1577 dpo = fib_entry_contribute_ip_forwarding(fei);
1578 lb = load_balance_get(dpo->dpoi_index);
1579 FIB_TEST((lb->lb_n_buckets == 4),
1580 "1.2.3.4/32 LB has %d bucket",
1581 lb->lb_n_buckets);
1582
Neale Ranns3ee44042016-10-03 13:05:48 +01001583 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_4_s_32, 0, ai_12_12_12_12);
1584 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_4_s_32, 1, ai_12_12_12_12);
1585 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_4_s_32, 2, ai_12_12_12_12);
1586 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_4_s_32, 3, ai_01);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001587
Neale Ranns3ee44042016-10-03 13:05:48 +01001588 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 2,
1589 tm->hw[0]->sw_if_index,
1590 tm->hw[1]->sw_if_index),
1591 "RPF list for 1.2.3.4/32 contains both adjs");
1592
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001593
1594 /*
1595 * Unequal Cost load-balance. 4:1 ratio.
1596 * fits in a 16 bucket LB with ratio 13:3
1597 */
1598 fib_prefix_t pfx_1_2_3_5_s_32 = {
1599 .fp_len = 32,
1600 .fp_proto = FIB_PROTOCOL_IP4,
1601 .fp_addr = {
1602 .ip4.as_u32 = clib_host_to_net_u32(0x01020305),
1603 },
1604 };
1605 fib_table_entry_path_add(fib_index,
1606 &pfx_1_2_3_5_s_32,
1607 FIB_SOURCE_API,
1608 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001609 DPO_PROTO_IP4,
Neale Ranns3ee44042016-10-03 13:05:48 +01001610 &nh_12_12_12_12,
1611 tm->hw[1]->sw_if_index,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001612 ~0,
1613 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001614 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001615 FIB_ROUTE_PATH_FLAG_NONE);
1616 fei = fib_table_entry_path_add(fib_index,
1617 &pfx_1_2_3_5_s_32,
1618 FIB_SOURCE_API,
1619 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001620 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001621 &nh_10_10_10_1,
1622 tm->hw[0]->sw_if_index,
1623 ~0,
1624 4,
Neale Rannsad422ed2016-11-02 14:20:04 +00001625 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001626 FIB_ROUTE_PATH_FLAG_NONE);
1627
1628 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "1.2.3.5/32 presnet");
1629 dpo = fib_entry_contribute_ip_forwarding(fei);
1630 lb = load_balance_get(dpo->dpoi_index);
1631 FIB_TEST((lb->lb_n_buckets == 16),
1632 "1.2.3.5/32 LB has %d bucket",
1633 lb->lb_n_buckets);
1634
1635 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 0, ai_01);
1636 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 1, ai_01);
1637 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 2, ai_01);
1638 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 3, ai_01);
1639 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 4, ai_01);
1640 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 5, ai_01);
1641 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 6, ai_01);
1642 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 7, ai_01);
1643 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 8, ai_01);
1644 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 9, ai_01);
1645 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 10, ai_01);
1646 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 11, ai_01);
1647 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 12, ai_01);
Neale Ranns3ee44042016-10-03 13:05:48 +01001648 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 13, ai_12_12_12_12);
1649 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 14, ai_12_12_12_12);
1650 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 15, ai_12_12_12_12);
1651
1652 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 2,
1653 tm->hw[0]->sw_if_index,
1654 tm->hw[1]->sw_if_index),
1655 "RPF list for 1.2.3.4/32 contains both adjs");
1656
1657 /*
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001658 * Test UCMP with a large weight skew - this produces load-balance objects with large
1659 * numbers of buckets to accommodate the skew. By updating said load-balances we are
1660 * laso testing the LB in placce modify code when number of buckets is large.
1661 */
1662 fib_prefix_t pfx_6_6_6_6_s_32 = {
1663 .fp_len = 32,
1664 .fp_proto = FIB_PROTOCOL_IP4,
1665 .fp_addr = {
1666 /* 1.1.1.1/32 */
1667 .ip4.as_u32 = clib_host_to_net_u32(0x06060606),
1668 },
1669 };
Neale Ranns81424992017-05-18 03:03:22 -07001670 fib_test_lb_bucket_t ip_o_10_10_10_1 = {
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001671 .type = FT_LB_ADJ,
1672 .adj = {
1673 .adj = ai_01,
1674 },
1675 };
Neale Ranns81424992017-05-18 03:03:22 -07001676 fib_test_lb_bucket_t ip_o_10_10_10_2 = {
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001677 .type = FT_LB_ADJ,
1678 .adj = {
1679 .adj = ai_02,
1680 },
1681 };
1682 fib_test_lb_bucket_t ip_6_6_6_6_o_12_12_12_12 = {
1683 .type = FT_LB_ADJ,
1684 .adj = {
1685 .adj = ai_12_12_12_12,
1686 },
1687 };
1688 fib_table_entry_update_one_path(fib_index,
1689 &pfx_6_6_6_6_s_32,
1690 FIB_SOURCE_API,
1691 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001692 DPO_PROTO_IP4,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001693 &nh_10_10_10_1,
1694 tm->hw[0]->sw_if_index,
1695 ~0, // invalid fib index
1696 0, // zero weigth
Neale Rannsad422ed2016-11-02 14:20:04 +00001697 NULL,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001698 FIB_ROUTE_PATH_FLAG_NONE);
1699
1700 fei = fib_table_lookup(fib_index, &pfx_6_6_6_6_s_32);
1701 FIB_TEST(fib_test_validate_entry(fei,
1702 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1703 1,
Neale Ranns81424992017-05-18 03:03:22 -07001704 &ip_o_10_10_10_1),
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001705 "6.6.6.6/32 via 10.10.10.1");
1706
1707 fib_table_entry_path_add(fib_index,
1708 &pfx_6_6_6_6_s_32,
1709 FIB_SOURCE_API,
1710 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001711 DPO_PROTO_IP4,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001712 &nh_10_10_10_2,
1713 tm->hw[0]->sw_if_index,
1714 ~0, // invalid fib index
1715 100,
Neale Rannsad422ed2016-11-02 14:20:04 +00001716 NULL,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001717 FIB_ROUTE_PATH_FLAG_NONE);
1718
1719 fei = fib_table_lookup(fib_index, &pfx_6_6_6_6_s_32);
1720 FIB_TEST(fib_test_validate_entry(fei,
1721 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1722 64,
Neale Ranns81424992017-05-18 03:03:22 -07001723 &ip_o_10_10_10_2,
1724 &ip_o_10_10_10_2,
1725 &ip_o_10_10_10_2,
1726 &ip_o_10_10_10_2,
1727 &ip_o_10_10_10_2,
1728 &ip_o_10_10_10_2,
1729 &ip_o_10_10_10_2,
1730 &ip_o_10_10_10_2,
1731 &ip_o_10_10_10_2,
1732 &ip_o_10_10_10_2,
1733 &ip_o_10_10_10_2,
1734 &ip_o_10_10_10_2,
1735 &ip_o_10_10_10_2,
1736 &ip_o_10_10_10_2,
1737 &ip_o_10_10_10_2,
1738 &ip_o_10_10_10_2,
1739 &ip_o_10_10_10_2,
1740 &ip_o_10_10_10_2,
1741 &ip_o_10_10_10_2,
1742 &ip_o_10_10_10_2,
1743 &ip_o_10_10_10_2,
1744 &ip_o_10_10_10_2,
1745 &ip_o_10_10_10_2,
1746 &ip_o_10_10_10_2,
1747 &ip_o_10_10_10_2,
1748 &ip_o_10_10_10_2,
1749 &ip_o_10_10_10_2,
1750 &ip_o_10_10_10_2,
1751 &ip_o_10_10_10_2,
1752 &ip_o_10_10_10_2,
1753 &ip_o_10_10_10_2,
1754 &ip_o_10_10_10_2,
1755 &ip_o_10_10_10_2,
1756 &ip_o_10_10_10_2,
1757 &ip_o_10_10_10_2,
1758 &ip_o_10_10_10_2,
1759 &ip_o_10_10_10_2,
1760 &ip_o_10_10_10_2,
1761 &ip_o_10_10_10_2,
1762 &ip_o_10_10_10_2,
1763 &ip_o_10_10_10_2,
1764 &ip_o_10_10_10_2,
1765 &ip_o_10_10_10_2,
1766 &ip_o_10_10_10_2,
1767 &ip_o_10_10_10_2,
1768 &ip_o_10_10_10_2,
1769 &ip_o_10_10_10_2,
1770 &ip_o_10_10_10_2,
1771 &ip_o_10_10_10_2,
1772 &ip_o_10_10_10_2,
1773 &ip_o_10_10_10_2,
1774 &ip_o_10_10_10_2,
1775 &ip_o_10_10_10_2,
1776 &ip_o_10_10_10_2,
1777 &ip_o_10_10_10_2,
1778 &ip_o_10_10_10_2,
1779 &ip_o_10_10_10_2,
1780 &ip_o_10_10_10_2,
1781 &ip_o_10_10_10_2,
1782 &ip_o_10_10_10_2,
1783 &ip_o_10_10_10_2,
1784 &ip_o_10_10_10_2,
1785 &ip_o_10_10_10_2,
1786 &ip_o_10_10_10_1),
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001787 "6.6.6.6/32 via 10.10.10.1 and 10.10.10.2 in 63:1 ratio");
1788
1789 fib_table_entry_path_add(fib_index,
1790 &pfx_6_6_6_6_s_32,
1791 FIB_SOURCE_API,
1792 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001793 DPO_PROTO_IP4,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001794 &nh_12_12_12_12,
1795 tm->hw[1]->sw_if_index,
1796 ~0, // invalid fib index
1797 100,
Neale Rannsad422ed2016-11-02 14:20:04 +00001798 NULL,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001799 FIB_ROUTE_PATH_FLAG_NONE);
1800
1801 fei = fib_table_lookup(fib_index, &pfx_6_6_6_6_s_32);
1802 FIB_TEST(fib_test_validate_entry(fei,
1803 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1804 128,
Neale Ranns81424992017-05-18 03:03:22 -07001805 &ip_o_10_10_10_1,
1806 &ip_o_10_10_10_2,
1807 &ip_o_10_10_10_2,
1808 &ip_o_10_10_10_2,
1809 &ip_o_10_10_10_2,
1810 &ip_o_10_10_10_2,
1811 &ip_o_10_10_10_2,
1812 &ip_o_10_10_10_2,
1813 &ip_o_10_10_10_2,
1814 &ip_o_10_10_10_2,
1815 &ip_o_10_10_10_2,
1816 &ip_o_10_10_10_2,
1817 &ip_o_10_10_10_2,
1818 &ip_o_10_10_10_2,
1819 &ip_o_10_10_10_2,
1820 &ip_o_10_10_10_2,
1821 &ip_o_10_10_10_2,
1822 &ip_o_10_10_10_2,
1823 &ip_o_10_10_10_2,
1824 &ip_o_10_10_10_2,
1825 &ip_o_10_10_10_2,
1826 &ip_o_10_10_10_2,
1827 &ip_o_10_10_10_2,
1828 &ip_o_10_10_10_2,
1829 &ip_o_10_10_10_2,
1830 &ip_o_10_10_10_2,
1831 &ip_o_10_10_10_2,
1832 &ip_o_10_10_10_2,
1833 &ip_o_10_10_10_2,
1834 &ip_o_10_10_10_2,
1835 &ip_o_10_10_10_2,
1836 &ip_o_10_10_10_2,
1837 &ip_o_10_10_10_2,
1838 &ip_o_10_10_10_2,
1839 &ip_o_10_10_10_2,
1840 &ip_o_10_10_10_2,
1841 &ip_o_10_10_10_2,
1842 &ip_o_10_10_10_2,
1843 &ip_o_10_10_10_2,
1844 &ip_o_10_10_10_2,
1845 &ip_o_10_10_10_2,
1846 &ip_o_10_10_10_2,
1847 &ip_o_10_10_10_2,
1848 &ip_o_10_10_10_2,
1849 &ip_o_10_10_10_2,
1850 &ip_o_10_10_10_2,
1851 &ip_o_10_10_10_2,
1852 &ip_o_10_10_10_2,
1853 &ip_o_10_10_10_2,
1854 &ip_o_10_10_10_2,
1855 &ip_o_10_10_10_2,
1856 &ip_o_10_10_10_2,
1857 &ip_o_10_10_10_2,
1858 &ip_o_10_10_10_2,
1859 &ip_o_10_10_10_2,
1860 &ip_o_10_10_10_2,
1861 &ip_o_10_10_10_2,
1862 &ip_o_10_10_10_2,
1863 &ip_o_10_10_10_2,
1864 &ip_o_10_10_10_2,
1865 &ip_o_10_10_10_2,
1866 &ip_o_10_10_10_2,
1867 &ip_o_10_10_10_2,
1868 &ip_o_10_10_10_2,
1869 &ip_o_10_10_10_2,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001870 &ip_6_6_6_6_o_12_12_12_12,
1871 &ip_6_6_6_6_o_12_12_12_12,
1872 &ip_6_6_6_6_o_12_12_12_12,
1873 &ip_6_6_6_6_o_12_12_12_12,
1874 &ip_6_6_6_6_o_12_12_12_12,
1875 &ip_6_6_6_6_o_12_12_12_12,
1876 &ip_6_6_6_6_o_12_12_12_12,
1877 &ip_6_6_6_6_o_12_12_12_12,
1878 &ip_6_6_6_6_o_12_12_12_12,
1879 &ip_6_6_6_6_o_12_12_12_12,
1880 &ip_6_6_6_6_o_12_12_12_12,
1881 &ip_6_6_6_6_o_12_12_12_12,
1882 &ip_6_6_6_6_o_12_12_12_12,
1883 &ip_6_6_6_6_o_12_12_12_12,
1884 &ip_6_6_6_6_o_12_12_12_12,
1885 &ip_6_6_6_6_o_12_12_12_12,
1886 &ip_6_6_6_6_o_12_12_12_12,
1887 &ip_6_6_6_6_o_12_12_12_12,
1888 &ip_6_6_6_6_o_12_12_12_12,
1889 &ip_6_6_6_6_o_12_12_12_12,
1890 &ip_6_6_6_6_o_12_12_12_12,
1891 &ip_6_6_6_6_o_12_12_12_12,
1892 &ip_6_6_6_6_o_12_12_12_12,
1893 &ip_6_6_6_6_o_12_12_12_12,
1894 &ip_6_6_6_6_o_12_12_12_12,
1895 &ip_6_6_6_6_o_12_12_12_12,
1896 &ip_6_6_6_6_o_12_12_12_12,
1897 &ip_6_6_6_6_o_12_12_12_12,
1898 &ip_6_6_6_6_o_12_12_12_12,
1899 &ip_6_6_6_6_o_12_12_12_12,
1900 &ip_6_6_6_6_o_12_12_12_12,
1901 &ip_6_6_6_6_o_12_12_12_12,
1902 &ip_6_6_6_6_o_12_12_12_12,
1903 &ip_6_6_6_6_o_12_12_12_12,
1904 &ip_6_6_6_6_o_12_12_12_12,
1905 &ip_6_6_6_6_o_12_12_12_12,
1906 &ip_6_6_6_6_o_12_12_12_12,
1907 &ip_6_6_6_6_o_12_12_12_12,
1908 &ip_6_6_6_6_o_12_12_12_12,
1909 &ip_6_6_6_6_o_12_12_12_12,
1910 &ip_6_6_6_6_o_12_12_12_12,
1911 &ip_6_6_6_6_o_12_12_12_12,
1912 &ip_6_6_6_6_o_12_12_12_12,
1913 &ip_6_6_6_6_o_12_12_12_12,
1914 &ip_6_6_6_6_o_12_12_12_12,
1915 &ip_6_6_6_6_o_12_12_12_12,
1916 &ip_6_6_6_6_o_12_12_12_12,
1917 &ip_6_6_6_6_o_12_12_12_12,
1918 &ip_6_6_6_6_o_12_12_12_12,
1919 &ip_6_6_6_6_o_12_12_12_12,
1920 &ip_6_6_6_6_o_12_12_12_12,
1921 &ip_6_6_6_6_o_12_12_12_12,
1922 &ip_6_6_6_6_o_12_12_12_12,
1923 &ip_6_6_6_6_o_12_12_12_12,
1924 &ip_6_6_6_6_o_12_12_12_12,
1925 &ip_6_6_6_6_o_12_12_12_12,
1926 &ip_6_6_6_6_o_12_12_12_12,
1927 &ip_6_6_6_6_o_12_12_12_12,
1928 &ip_6_6_6_6_o_12_12_12_12,
1929 &ip_6_6_6_6_o_12_12_12_12,
1930 &ip_6_6_6_6_o_12_12_12_12,
1931 &ip_6_6_6_6_o_12_12_12_12,
1932 &ip_6_6_6_6_o_12_12_12_12),
1933 "6.6.6.6/32 via 10.10.10.1 and 10.10.10.2 in 63:1 ratio");
1934
1935 fib_table_entry_path_remove(fib_index,
1936 &pfx_6_6_6_6_s_32,
1937 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07001938 DPO_PROTO_IP4,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001939 &nh_12_12_12_12,
1940 tm->hw[1]->sw_if_index,
1941 ~0, // invalid fib index
1942 100,
1943 FIB_ROUTE_PATH_FLAG_NONE);
1944
1945 fei = fib_table_lookup(fib_index, &pfx_6_6_6_6_s_32);
1946 FIB_TEST(fib_test_validate_entry(fei,
1947 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1948 64,
Neale Ranns81424992017-05-18 03:03:22 -07001949 &ip_o_10_10_10_2,
1950 &ip_o_10_10_10_2,
1951 &ip_o_10_10_10_2,
1952 &ip_o_10_10_10_2,
1953 &ip_o_10_10_10_2,
1954 &ip_o_10_10_10_2,
1955 &ip_o_10_10_10_2,
1956 &ip_o_10_10_10_2,
1957 &ip_o_10_10_10_2,
1958 &ip_o_10_10_10_2,
1959 &ip_o_10_10_10_2,
1960 &ip_o_10_10_10_2,
1961 &ip_o_10_10_10_2,
1962 &ip_o_10_10_10_2,
1963 &ip_o_10_10_10_2,
1964 &ip_o_10_10_10_2,
1965 &ip_o_10_10_10_2,
1966 &ip_o_10_10_10_2,
1967 &ip_o_10_10_10_2,
1968 &ip_o_10_10_10_2,
1969 &ip_o_10_10_10_2,
1970 &ip_o_10_10_10_2,
1971 &ip_o_10_10_10_2,
1972 &ip_o_10_10_10_2,
1973 &ip_o_10_10_10_2,
1974 &ip_o_10_10_10_2,
1975 &ip_o_10_10_10_2,
1976 &ip_o_10_10_10_2,
1977 &ip_o_10_10_10_2,
1978 &ip_o_10_10_10_2,
1979 &ip_o_10_10_10_2,
1980 &ip_o_10_10_10_2,
1981 &ip_o_10_10_10_2,
1982 &ip_o_10_10_10_2,
1983 &ip_o_10_10_10_2,
1984 &ip_o_10_10_10_2,
1985 &ip_o_10_10_10_2,
1986 &ip_o_10_10_10_2,
1987 &ip_o_10_10_10_2,
1988 &ip_o_10_10_10_2,
1989 &ip_o_10_10_10_2,
1990 &ip_o_10_10_10_2,
1991 &ip_o_10_10_10_2,
1992 &ip_o_10_10_10_2,
1993 &ip_o_10_10_10_2,
1994 &ip_o_10_10_10_2,
1995 &ip_o_10_10_10_2,
1996 &ip_o_10_10_10_2,
1997 &ip_o_10_10_10_2,
1998 &ip_o_10_10_10_2,
1999 &ip_o_10_10_10_2,
2000 &ip_o_10_10_10_2,
2001 &ip_o_10_10_10_2,
2002 &ip_o_10_10_10_2,
2003 &ip_o_10_10_10_2,
2004 &ip_o_10_10_10_2,
2005 &ip_o_10_10_10_2,
2006 &ip_o_10_10_10_2,
2007 &ip_o_10_10_10_2,
2008 &ip_o_10_10_10_2,
2009 &ip_o_10_10_10_2,
2010 &ip_o_10_10_10_2,
2011 &ip_o_10_10_10_2,
2012 &ip_o_10_10_10_1),
Neale Ranns0bd36ea2016-11-16 11:47:44 +00002013 "6.6.6.6/32 via 10.10.10.1 and 10.10.10.2 in 63:1 ratio");
2014
2015 fib_table_entry_path_remove(fib_index,
2016 &pfx_6_6_6_6_s_32,
2017 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002018 DPO_PROTO_IP4,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00002019 &nh_10_10_10_2,
2020 tm->hw[0]->sw_if_index,
2021 ~0, // invalid fib index
2022 100,
2023 FIB_ROUTE_PATH_FLAG_NONE);
2024
2025 fei = fib_table_lookup(fib_index, &pfx_6_6_6_6_s_32);
2026 FIB_TEST(fib_test_validate_entry(fei,
2027 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
2028 1,
Neale Ranns81424992017-05-18 03:03:22 -07002029 &ip_o_10_10_10_1),
Neale Ranns0bd36ea2016-11-16 11:47:44 +00002030 "6.6.6.6/32 via 10.10.10.1");
2031
2032 fib_table_entry_delete(fib_index, &pfx_6_6_6_6_s_32, FIB_SOURCE_API);
2033
2034 /*
Neale Ranns3ee44042016-10-03 13:05:48 +01002035 * A recursive via the two unequal cost entries
2036 */
2037 fib_prefix_t bgp_44_s_32 = {
2038 .fp_len = 32,
2039 .fp_proto = FIB_PROTOCOL_IP4,
2040 .fp_addr = {
2041 /* 200.200.200.201/32 */
2042 .ip4.as_u32 = clib_host_to_net_u32(0x44444444),
2043 },
2044 };
2045 fei = fib_table_entry_path_add(fib_index,
2046 &bgp_44_s_32,
2047 FIB_SOURCE_API,
2048 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002049 DPO_PROTO_IP4,
Neale Ranns3ee44042016-10-03 13:05:48 +01002050 &pfx_1_2_3_4_s_32.fp_addr,
2051 ~0,
2052 fib_index,
2053 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002054 NULL,
Neale Ranns3ee44042016-10-03 13:05:48 +01002055 FIB_ROUTE_PATH_FLAG_NONE);
2056 fei = fib_table_entry_path_add(fib_index,
2057 &bgp_44_s_32,
2058 FIB_SOURCE_API,
2059 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002060 DPO_PROTO_IP4,
Neale Ranns3ee44042016-10-03 13:05:48 +01002061 &pfx_1_2_3_5_s_32.fp_addr,
2062 ~0,
2063 fib_index,
2064 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002065 NULL,
Neale Ranns3ee44042016-10-03 13:05:48 +01002066 FIB_ROUTE_PATH_FLAG_NONE);
2067
2068 FIB_TEST_REC_FORW(&bgp_44_s_32, &pfx_1_2_3_4_s_32, 0);
2069 FIB_TEST_REC_FORW(&bgp_44_s_32, &pfx_1_2_3_5_s_32, 1);
2070 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 2,
2071 tm->hw[0]->sw_if_index,
2072 tm->hw[1]->sw_if_index),
2073 "RPF list for 1.2.3.4/32 contains both adjs");
2074
2075 /*
2076 * test the uRPF check functions
2077 */
Neale Ranns948e00f2016-10-20 13:39:34 +01002078 dpo_id_t dpo_44 = DPO_INVALID;
Neale Ranns3ee44042016-10-03 13:05:48 +01002079 index_t urpfi;
2080
2081 fib_entry_contribute_forwarding(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, &dpo_44);
2082 urpfi = load_balance_get_urpf(dpo_44.dpoi_index);
2083
2084 FIB_TEST(fib_urpf_check(urpfi, tm->hw[0]->sw_if_index),
2085 "uRPF check for 68.68.68.68/32 on %d OK",
2086 tm->hw[0]->sw_if_index);
2087 FIB_TEST(fib_urpf_check(urpfi, tm->hw[1]->sw_if_index),
2088 "uRPF check for 68.68.68.68/32 on %d OK",
2089 tm->hw[1]->sw_if_index);
2090 FIB_TEST(!fib_urpf_check(urpfi, 99),
2091 "uRPF check for 68.68.68.68/32 on 99 not-OK",
2092 99);
2093 dpo_reset(&dpo_44);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002094
2095 fib_table_entry_delete(fib_index,
Neale Ranns3ee44042016-10-03 13:05:48 +01002096 &bgp_44_s_32,
2097 FIB_SOURCE_API);
2098 fib_table_entry_delete(fib_index,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002099 &pfx_1_2_3_5_s_32,
2100 FIB_SOURCE_API);
Neale Ranns3ee44042016-10-03 13:05:48 +01002101 fib_table_entry_delete(fib_index,
2102 &pfx_1_2_3_4_s_32,
2103 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002104
2105 /*
2106 * Add a recursive route:
2107 * 200.200.200.201/32 via 1.1.1.200/32 => the via entry is NOT installed.
2108 */
2109 fib_prefix_t bgp_201_pfx = {
2110 .fp_len = 32,
2111 .fp_proto = FIB_PROTOCOL_IP4,
2112 .fp_addr = {
2113 /* 200.200.200.201/32 */
2114 .ip4.as_u32 = clib_host_to_net_u32(0xc8c8c8c9),
2115 },
2116 };
2117 /* via 1.1.1.200 */
2118 fib_prefix_t pfx_1_1_1_200_s_32 = {
2119 .fp_len = 32,
2120 .fp_proto = FIB_PROTOCOL_IP4,
2121 .fp_addr = {
2122 .ip4.as_u32 = clib_host_to_net_u32(0x010101c8),
2123 },
2124 };
2125
Neale Ranns57b58602017-07-15 07:37:25 -07002126 fei = fib_table_entry_path_add(fib_index,
2127 &bgp_201_pfx,
2128 FIB_SOURCE_API,
2129 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002130 DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07002131 &pfx_1_1_1_200_s_32.fp_addr,
2132 ~0, // no index provided.
2133 fib_index, // nexthop in same fib as route
2134 1,
2135 NULL,
2136 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002137
Neale Ranns57b58602017-07-15 07:37:25 -07002138 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2139 "Recursive via unresolved is drop");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002140
2141 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_200_s_32);
2142 FIB_TEST((FIB_ENTRY_FLAG_NONE == fib_entry_get_flags(fei)),
2143 "Flags set on RR via non-attached");
Neale Ranns3ee44042016-10-03 13:05:48 +01002144 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 0),
2145 "RPF list for BGP route empty");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002146
2147 /*
2148 * +2 entry (BGP & RR) and +1 shared-path-list
2149 */
2150 FIB_TEST((4 == fib_path_list_db_size()), "path list DB population:%d",
2151 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002152 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002153 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002154 FIB_TEST((ENBR+12 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002155 fib_entry_pool_size());
2156
2157 /*
2158 * insert a route that covers the missing 1.1.1.2/32. we epxect
2159 * 200.200.200.200/32 and 200.200.200.201/32 to resolve through it.
2160 */
2161 fib_prefix_t pfx_1_1_1_0_s_24 = {
2162 .fp_len = 24,
2163 .fp_proto = FIB_PROTOCOL_IP4,
2164 .fp_addr = {
2165 /* 1.1.1.0/24 */
2166 .ip4.as_u32 = clib_host_to_net_u32(0x01010100),
2167 },
2168 };
2169
2170 fib_table_entry_path_add(fib_index,
2171 &pfx_1_1_1_0_s_24,
2172 FIB_SOURCE_API,
2173 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002174 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002175 &nh_10_10_10_1,
2176 tm->hw[0]->sw_if_index,
2177 ~0, // invalid fib index
2178 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002179 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002180 FIB_ROUTE_PATH_FLAG_NONE);
2181 fei = fib_table_lookup(fib_index, &pfx_1_1_1_0_s_24);
2182 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2183 ai = fib_entry_get_adj(fei);
2184 FIB_TEST((ai_01 == ai), "1.1.1.0/24 resolves via 10.10.10.1");
2185 fei = fib_table_lookup(fib_index, &pfx_1_1_1_2_s_32);
2186 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2187 ai = fib_entry_get_adj(fei);
2188 FIB_TEST((ai_01 == ai), "1.1.1.2/32 resolves via 10.10.10.1");
2189 fei = fib_table_lookup(fib_index, &pfx_1_1_1_200_s_32);
2190 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2191 ai = fib_entry_get_adj(fei);
2192 FIB_TEST((ai_01 == ai), "1.1.1.200/24 resolves via 10.10.10.1");
2193
2194 /*
2195 * +1 entry. 1.1.1.1/32 already uses 10.10.10.1 so no new pah-list
2196 */
2197 FIB_TEST((4 == fib_path_list_db_size()), "path list DB population:%d",
2198 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002199 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002200 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002201 FIB_TEST((ENBR+13 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002202 fib_entry_pool_size());
2203
2204 /*
2205 * the recursive adj for 200.200.200.200 should be updated.
2206 */
Neale Ranns3ee44042016-10-03 13:05:48 +01002207 FIB_TEST_REC_FORW(&bgp_201_pfx, &pfx_1_1_1_200_s_32, 0);
2208 FIB_TEST_REC_FORW(&bgp_200_pfx, &pfx_1_1_1_2_s_32, 0);
2209 fei = fib_table_lookup(fib_index, &bgp_200_pfx);
2210 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 1,
2211 tm->hw[0]->sw_if_index),
2212 "RPF list for BGP route has itf index 0");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002213
2214 /*
2215 * insert a more specific route than 1.1.1.0/24 that also covers the
2216 * missing 1.1.1.2/32, but not 1.1.1.200/32. we epxect
2217 * 200.200.200.200 to resolve through it.
2218 */
2219 fib_prefix_t pfx_1_1_1_0_s_28 = {
2220 .fp_len = 28,
2221 .fp_proto = FIB_PROTOCOL_IP4,
2222 .fp_addr = {
2223 /* 1.1.1.0/24 */
2224 .ip4.as_u32 = clib_host_to_net_u32(0x01010100),
2225 },
2226 };
2227
2228 fib_table_entry_path_add(fib_index,
2229 &pfx_1_1_1_0_s_28,
2230 FIB_SOURCE_API,
2231 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002232 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002233 &nh_10_10_10_2,
2234 tm->hw[0]->sw_if_index,
2235 ~0, // invalid fib index
2236 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002237 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002238 FIB_ROUTE_PATH_FLAG_NONE);
2239 fei = fib_table_lookup(fib_index, &pfx_1_1_1_0_s_28);
2240 dpo2 = fib_entry_contribute_ip_forwarding(fei);
2241 ai = fib_entry_get_adj(fei);
2242 FIB_TEST((ai_02 == ai), "1.1.1.0/24 resolves via 10.10.10.2");
2243
2244 /*
2245 * +1 entry. +1 shared path-list
2246 */
2247 FIB_TEST((5 == fib_path_list_db_size()), "path list DB population:%d",
2248 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002249 FIB_TEST((PNBR+9 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002250 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002251 FIB_TEST((ENBR+14 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002252 fib_entry_pool_size());
2253
2254 /*
2255 * the recursive adj for 200.200.200.200 should be updated.
2256 * 200.200.200.201 remains unchanged.
2257 */
Neale Ranns3ee44042016-10-03 13:05:48 +01002258 FIB_TEST_REC_FORW(&bgp_201_pfx, &pfx_1_1_1_200_s_32, 0);
2259 FIB_TEST_REC_FORW(&bgp_200_pfx, &pfx_1_1_1_2_s_32, 0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002260
2261 /*
2262 * remove this /28. 200.200.200.200/32 should revert back to via 1.1.1.0/24
2263 */
2264 fib_table_entry_path_remove(fib_index,
2265 &pfx_1_1_1_0_s_28,
2266 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002267 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002268 &nh_10_10_10_2,
2269 tm->hw[0]->sw_if_index,
2270 ~0,
2271 1,
2272 FIB_ROUTE_PATH_FLAG_NONE);
2273 FIB_TEST((fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_0_s_28) ==
2274 FIB_NODE_INDEX_INVALID),
2275 "1.1.1.0/28 removed");
2276 FIB_TEST((fib_table_lookup(fib_index, &pfx_1_1_1_0_s_28) ==
2277 fib_table_lookup(fib_index, &pfx_1_1_1_0_s_24)),
2278 "1.1.1.0/28 lookup via /24");
Neale Ranns3ee44042016-10-03 13:05:48 +01002279 FIB_TEST_REC_FORW(&bgp_201_pfx, &pfx_1_1_1_200_s_32, 0);
2280 FIB_TEST_REC_FORW(&bgp_200_pfx, &pfx_1_1_1_2_s_32, 0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002281
2282 /*
2283 * -1 entry. -1 shared path-list
2284 */
2285 FIB_TEST((4 == fib_path_list_db_size()), "path list DB population:%d",
2286 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002287 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002288 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002289 FIB_TEST((ENBR+13 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002290 fib_entry_pool_size());
2291
2292 /*
2293 * remove 1.1.1.0/24. 200.200.200.200/32 should revert back to via 0.0.0.0/0
2294 */
2295 fib_table_entry_path_remove(fib_index,
2296 &pfx_1_1_1_0_s_24,
2297 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002298 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002299 &nh_10_10_10_1,
2300 tm->hw[0]->sw_if_index,
2301 ~0,
2302 1,
2303 FIB_ROUTE_PATH_FLAG_NONE);
2304 FIB_TEST((fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_0_s_24) ==
2305 FIB_NODE_INDEX_INVALID),
2306 "1.1.1.0/24 removed");
2307
2308 fei = fib_table_lookup(fib_index, &pfx_1_1_1_2_s_32);
2309 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2310 "1.1.1.2/32 route is DROP");
Neale Ranns57b58602017-07-15 07:37:25 -07002311 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_200_s_32);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002312 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2313 "1.1.1.200/32 route is DROP");
2314
Neale Ranns57b58602017-07-15 07:37:25 -07002315 fei = fib_table_lookup_exact_match(fib_index, &bgp_201_pfx);
2316 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2317 "201 is drop");
2318 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
2319 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2320 "200 is drop");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002321
2322 /*
2323 * -1 entry
2324 */
2325 FIB_TEST((4 == fib_path_list_db_size()), "path list DB population:%d",
2326 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002327 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002328 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002329 FIB_TEST((ENBR+12 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002330 fib_entry_pool_size());
2331
2332 /*
2333 * insert the missing 1.1.1.2/32
2334 */
2335 fei = fib_table_entry_path_add(fib_index,
2336 &pfx_1_1_1_2_s_32,
2337 FIB_SOURCE_API,
2338 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002339 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002340 &nh_10_10_10_1,
2341 tm->hw[0]->sw_if_index,
2342 ~0, // invalid fib index
2343 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002344 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002345 FIB_ROUTE_PATH_FLAG_NONE);
2346 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2347 ai = fib_entry_get_adj(fei);
2348 FIB_TEST((ai = ai_01), "1.1.1.2/32 resolves via 10.10.10.1");
2349
Neale Ranns57b58602017-07-15 07:37:25 -07002350 fei = fib_table_lookup_exact_match(fib_index, &bgp_201_pfx);
2351 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2352 "201 is drop");
Neale Ranns3ee44042016-10-03 13:05:48 +01002353 FIB_TEST_REC_FORW(&bgp_200_pfx, &pfx_1_1_1_2_s_32, 0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002354
2355 /*
2356 * no change. 1.1.1.2/32 was already there RR sourced.
2357 */
2358 FIB_TEST((4 == fib_path_list_db_size()), "path list DB population:%d",
2359 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002360 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002361 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002362 FIB_TEST((ENBR+12 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002363 fib_entry_pool_size());
2364
2365 /*
Neale Ranns57b58602017-07-15 07:37:25 -07002366 * give 201 a resolved path.
2367 * it now has the unresolved 1.1.1.200 and the resolved 1.1.1.2,
2368 * only the latter contributes forwarding.
2369 */
2370 fei = fib_table_entry_path_add(fib_index,
2371 &bgp_201_pfx,
2372 FIB_SOURCE_API,
2373 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002374 DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07002375 &pfx_1_1_1_2_s_32.fp_addr,
2376 ~0,
2377 fib_index,
2378 1,
2379 NULL,
2380 FIB_ROUTE_PATH_FLAG_NONE);
2381 FIB_TEST_REC_FORW(&bgp_201_pfx, &pfx_1_1_1_2_s_32, 0);
2382 fib_table_entry_path_remove(fib_index,
2383 &bgp_201_pfx,
2384 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002385 DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07002386 &pfx_1_1_1_2_s_32.fp_addr,
2387 ~0,
2388 fib_index,
2389 1,
2390 FIB_ROUTE_PATH_FLAG_NONE);
2391
2392 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002393 * remove 200.200.200.201/32 which does not have a valid via FIB
2394 */
2395 fib_table_entry_path_remove(fib_index,
2396 &bgp_201_pfx,
2397 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002398 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002399 &pfx_1_1_1_200_s_32.fp_addr,
2400 ~0, // no index provided.
2401 fib_index,
2402 1,
2403 FIB_ROUTE_PATH_FLAG_NONE);
2404
2405 /*
2406 * -2 entries (BGP and RR). -1 shared path-list;
2407 */
2408 FIB_TEST((fib_table_lookup_exact_match(fib_index, &bgp_201_pfx) ==
2409 FIB_NODE_INDEX_INVALID),
2410 "200.200.200.201/32 removed");
2411 FIB_TEST((fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_200_s_32) ==
2412 FIB_NODE_INDEX_INVALID),
2413 "1.1.1.200/32 removed");
2414
2415 FIB_TEST((3 == fib_path_list_db_size()), "path list DB population:%d",
2416 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002417 FIB_TEST((PNBR+7 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002418 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002419 FIB_TEST((ENBR+10 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002420 fib_entry_pool_size());
2421
2422 /*
2423 * remove 200.200.200.200/32 which does have a valid via FIB
2424 */
2425 fib_table_entry_path_remove(fib_index,
2426 &bgp_200_pfx,
2427 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002428 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002429 &pfx_1_1_1_2_s_32.fp_addr,
2430 ~0, // no index provided.
2431 fib_index,
2432 1,
2433 FIB_ROUTE_PATH_FLAG_NONE);
2434
2435 FIB_TEST((fib_table_lookup_exact_match(fib_index, &bgp_200_pfx) ==
2436 FIB_NODE_INDEX_INVALID),
2437 "200.200.200.200/32 removed");
2438 FIB_TEST((fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_2_s_32) !=
2439 FIB_NODE_INDEX_INVALID),
2440 "1.1.1.2/32 still present");
2441
2442 /*
2443 * -1 entry (BGP, the RR source is also API sourced). -1 shared path-list;
2444 */
2445 FIB_TEST((2 == fib_path_list_db_size()), "path list DB population:%d",
2446 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002447 FIB_TEST((PNBR+6 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002448 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002449 FIB_TEST((ENBR+9 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002450 fib_entry_pool_size());
2451
2452 /*
2453 * A recursive prefix that has a 2 path load-balance.
2454 * It also shares a next-hop with other BGP prefixes and hence
2455 * test the ref counting of RR sourced prefixes and 2 level LB.
2456 */
2457 const fib_prefix_t bgp_102 = {
2458 .fp_len = 32,
2459 .fp_proto = FIB_PROTOCOL_IP4,
2460 .fp_addr = {
2461 /* 100.100.100.101/32 */
2462 .ip4.as_u32 = clib_host_to_net_u32(0x64646466),
2463 },
2464 };
2465 fib_table_entry_path_add(fib_index,
2466 &bgp_102,
2467 FIB_SOURCE_API,
2468 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002469 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002470 &pfx_1_1_1_1_s_32.fp_addr,
2471 ~0, // no index provided.
2472 fib_index, // same as route
2473 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002474 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002475 FIB_ROUTE_PATH_FLAG_NONE);
2476 fib_table_entry_path_add(fib_index,
2477 &bgp_102,
2478 FIB_SOURCE_API,
2479 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002480 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002481 &pfx_1_1_1_2_s_32.fp_addr,
2482 ~0, // no index provided.
2483 fib_index, // same as route's FIB
2484 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002485 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002486 FIB_ROUTE_PATH_FLAG_NONE);
2487 fei = fib_table_lookup_exact_match(fib_index, &bgp_102);
2488 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "100.100.100.102/32 presnet");
2489 dpo = fib_entry_contribute_ip_forwarding(fei);
2490
2491 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_1_s_32);
2492 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2493 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_2_s_32);
2494 dpo2 = fib_entry_contribute_ip_forwarding(fei);
2495
2496 lb = load_balance_get(dpo->dpoi_index);
2497 FIB_TEST((lb->lb_n_buckets == 2), "Recursive LB has %d bucket", lb->lb_n_buckets);
2498 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket(dpo->dpoi_index, 0)),
2499 "First via 10.10.10.1");
2500 FIB_TEST(!dpo_cmp(dpo2, load_balance_get_bucket(dpo->dpoi_index, 1)),
2501 "Second via 10.10.10.1");
2502
2503 fib_table_entry_path_remove(fib_index,
2504 &bgp_102,
2505 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002506 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002507 &pfx_1_1_1_1_s_32.fp_addr,
2508 ~0, // no index provided.
2509 fib_index, // same as route's FIB
2510 1,
2511 FIB_ROUTE_PATH_FLAG_NONE);
2512 fib_table_entry_path_remove(fib_index,
2513 &bgp_102,
2514 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002515 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002516 &pfx_1_1_1_2_s_32.fp_addr,
2517 ~0, // no index provided.
2518 fib_index, // same as route's FIB
2519 1,
2520 FIB_ROUTE_PATH_FLAG_NONE);
2521 fei = fib_table_lookup_exact_match(fib_index, &bgp_102);
2522 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "100.100.100.102/32 removed");
2523
2524 /*
2525 * remove the remaining recursives
2526 */
2527 fib_table_entry_path_remove(fib_index,
2528 &bgp_100_pfx,
2529 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002530 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002531 &pfx_1_1_1_1_s_32.fp_addr,
2532 ~0, // no index provided.
2533 fib_index, // same as route's FIB
2534 1,
2535 FIB_ROUTE_PATH_FLAG_NONE);
2536 fib_table_entry_path_remove(fib_index,
2537 &bgp_101_pfx,
2538 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002539 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002540 &pfx_1_1_1_1_s_32.fp_addr,
2541 ~0, // no index provided.
2542 fib_index, // same as route's FIB
2543 1,
2544 FIB_ROUTE_PATH_FLAG_NONE);
2545 FIB_TEST((fib_table_lookup_exact_match(fib_index, &bgp_100_pfx) ==
2546 FIB_NODE_INDEX_INVALID),
2547 "100.100.100.100/32 removed");
2548 FIB_TEST((fib_table_lookup_exact_match(fib_index, &bgp_101_pfx) ==
2549 FIB_NODE_INDEX_INVALID),
2550 "100.100.100.101/32 removed");
2551
2552 /*
2553 * -2 entry (2*BGP, the RR source is also API sourced). -1 shared path-list;
2554 */
2555 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
2556 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002557 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002558 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002559 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002560 fib_entry_pool_size());
2561
2562 /*
2563 * Add a recursive route via a connected cover, using an adj-fib that does exist
2564 */
2565 fib_table_entry_path_add(fib_index,
2566 &bgp_200_pfx,
2567 FIB_SOURCE_API,
2568 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002569 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002570 &nh_10_10_10_1,
2571 ~0, // no index provided.
2572 fib_index, // Same as route's FIB
2573 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002574 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002575 FIB_ROUTE_PATH_FLAG_NONE);
2576
2577 /*
2578 * +1 entry. +1 shared path-list (recursive via 10.10.10.1)
2579 */
2580 FIB_TEST((2 == fib_path_list_db_size()), "path list DB population:%d",
2581 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002582 FIB_TEST((PNBR+6 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002583 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002584 FIB_TEST((ENBR+8 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002585 fib_entry_pool_size());
2586
2587 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
2588 dpo = fib_entry_contribute_ip_forwarding(fei);
2589
2590 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
2591 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2592
2593 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket(dpo->dpoi_index, 0)),
2594 "200.200.200.200/32 is recursive via adj for 10.10.10.1");
2595
2596 FIB_TEST((FIB_ENTRY_FLAG_ATTACHED == fib_entry_get_flags(fei)),
2597 "Flags set on RR via existing attached");
2598
2599 /*
2600 * Add a recursive route via a connected cover, using and adj-fib that does
2601 * not exist
2602 */
2603 ip46_address_t nh_10_10_10_3 = {
2604 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a03),
2605 };
2606 fib_prefix_t pfx_10_10_10_3 = {
2607 .fp_len = 32,
2608 .fp_proto = FIB_PROTOCOL_IP4,
2609 .fp_addr = nh_10_10_10_3,
2610 };
2611
2612 fib_table_entry_path_add(fib_index,
2613 &bgp_201_pfx,
2614 FIB_SOURCE_API,
2615 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002616 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002617 &nh_10_10_10_3,
2618 ~0, // no index provided.
2619 fib_index,
2620 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002621 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002622 FIB_ROUTE_PATH_FLAG_NONE);
2623
2624 /*
2625 * +2 entries (BGP and RR). +1 shared path-list (recursive via 10.10.10.3) and
2626 * one unshared non-recursive via 10.10.10.3
2627 */
2628 FIB_TEST((3 == fib_path_list_db_size()), "path list DB population:%d",
2629 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002630 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002631 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002632 FIB_TEST((ENBR+10 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002633 fib_entry_pool_size());
2634
2635 ai_03 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01002636 VNET_LINK_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002637 &nh_10_10_10_3,
2638 tm->hw[0]->sw_if_index);
2639
2640 fei = fib_table_lookup_exact_match(fib_index, &bgp_201_pfx);
2641 dpo = fib_entry_contribute_ip_forwarding(fei);
2642 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_3);
2643 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2644
2645 ai = fib_entry_get_adj(fei);
2646 FIB_TEST((ai == ai_03), "adj for 10.10.10.3/32 is via adj for 10.10.10.3");
2647 FIB_TEST(((FIB_ENTRY_FLAG_ATTACHED | FIB_ENTRY_FLAG_CONNECTED) ==
2648 fib_entry_get_flags(fei)),
2649 "Flags set on RR via non-existing attached");
2650
2651 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket(dpo->dpoi_index, 0)),
2652 "adj for 200.200.200.200/32 is recursive via adj for 10.10.10.3");
2653
2654 adj_unlock(ai_03);
2655
2656 /*
2657 * remove the recursives
2658 */
2659 fib_table_entry_path_remove(fib_index,
2660 &bgp_200_pfx,
2661 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002662 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002663 &nh_10_10_10_1,
2664 ~0, // no index provided.
2665 fib_index, // same as route's FIB
2666 1,
2667 FIB_ROUTE_PATH_FLAG_NONE);
2668 fib_table_entry_path_remove(fib_index,
2669 &bgp_201_pfx,
2670 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002671 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002672 &nh_10_10_10_3,
2673 ~0, // no index provided.
2674 fib_index, // same as route's FIB
2675 1,
2676 FIB_ROUTE_PATH_FLAG_NONE);
2677
2678 FIB_TEST((fib_table_lookup_exact_match(fib_index, &bgp_201_pfx) ==
2679 FIB_NODE_INDEX_INVALID),
2680 "200.200.200.201/32 removed");
2681 FIB_TEST((fib_table_lookup_exact_match(fib_index, &bgp_200_pfx) ==
2682 FIB_NODE_INDEX_INVALID),
2683 "200.200.200.200/32 removed");
2684 FIB_TEST((fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_3) ==
2685 FIB_NODE_INDEX_INVALID),
2686 "10.10.10.3/32 removed");
2687
2688 /*
2689 * -3 entries (2*BGP and RR). -2 shared path-list (recursive via 10.10.10.3 &
2690 * 10.10.10.1) and one unshared non-recursive via 10.10.10.3
2691 */
2692 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
2693 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002694 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002695 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002696 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002697 fib_entry_pool_size());
2698
2699
2700 /*
2701 * RECURSION LOOPS
2702 * Add 5.5.5.5/32 -> 5.5.5.6/32 -> 5.5.5.7/32 -> 5.5.5.5/32
2703 */
2704 fib_prefix_t pfx_5_5_5_5_s_32 = {
2705 .fp_len = 32,
2706 .fp_proto = FIB_PROTOCOL_IP4,
2707 .fp_addr = {
2708 .ip4.as_u32 = clib_host_to_net_u32(0x05050505),
2709 },
2710 };
2711 fib_prefix_t pfx_5_5_5_6_s_32 = {
2712 .fp_len = 32,
2713 .fp_proto = FIB_PROTOCOL_IP4,
2714 .fp_addr = {
2715 .ip4.as_u32 = clib_host_to_net_u32(0x05050506),
2716 },
2717 };
2718 fib_prefix_t pfx_5_5_5_7_s_32 = {
2719 .fp_len = 32,
2720 .fp_proto = FIB_PROTOCOL_IP4,
2721 .fp_addr = {
2722 .ip4.as_u32 = clib_host_to_net_u32(0x05050507),
2723 },
2724 };
2725
2726 fib_table_entry_path_add(fib_index,
2727 &pfx_5_5_5_5_s_32,
2728 FIB_SOURCE_API,
2729 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002730 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002731 &pfx_5_5_5_6_s_32.fp_addr,
2732 ~0, // no index provided.
2733 fib_index,
2734 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002735 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002736 FIB_ROUTE_PATH_FLAG_NONE);
2737 fib_table_entry_path_add(fib_index,
2738 &pfx_5_5_5_6_s_32,
2739 FIB_SOURCE_API,
2740 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002741 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002742 &pfx_5_5_5_7_s_32.fp_addr,
2743 ~0, // no index provided.
2744 fib_index,
2745 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002746 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002747 FIB_ROUTE_PATH_FLAG_NONE);
2748 fib_table_entry_path_add(fib_index,
2749 &pfx_5_5_5_7_s_32,
2750 FIB_SOURCE_API,
2751 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002752 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002753 &pfx_5_5_5_5_s_32.fp_addr,
2754 ~0, // no index provided.
2755 fib_index,
2756 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002757 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002758 FIB_ROUTE_PATH_FLAG_NONE);
2759 /*
2760 * +3 entries, +3 shared path-list
2761 */
2762 FIB_TEST((4 == fib_path_list_db_size()), "path list DB population:%d",
2763 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002764 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002765 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002766 FIB_TEST((ENBR+10 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002767 fib_entry_pool_size());
2768
2769 /*
2770 * All the entries have only looped paths, so they are all drop
2771 */
2772 fei = fib_table_lookup(fib_index, &pfx_5_5_5_7_s_32);
2773 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2774 "LB for 5.5.5.7/32 is via adj for DROP");
2775 fei = fib_table_lookup(fib_index, &pfx_5_5_5_5_s_32);
2776 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2777 "LB for 5.5.5.5/32 is via adj for DROP");
2778 fei = fib_table_lookup(fib_index, &pfx_5_5_5_6_s_32);
2779 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2780 "LB for 5.5.5.6/32 is via adj for DROP");
2781
2782 /*
2783 * provide 5.5.5.6/32 with alternate path.
2784 * this will allow only 5.5.5.6/32 to forward with this path, the others
2785 * are still drop since the loop is still present.
2786 */
2787 fib_table_entry_path_add(fib_index,
2788 &pfx_5_5_5_6_s_32,
2789 FIB_SOURCE_API,
2790 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002791 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002792 &nh_10_10_10_1,
2793 tm->hw[0]->sw_if_index,
2794 ~0,
2795 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002796 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002797 FIB_ROUTE_PATH_FLAG_NONE);
2798
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002799 fei = fib_table_lookup(fib_index, &pfx_5_5_5_6_s_32);
2800 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2801
2802 lb = load_balance_get(dpo1->dpoi_index);
2803 FIB_TEST((lb->lb_n_buckets == 1), "5.5.5.6 LB has %d bucket", lb->lb_n_buckets);
2804
2805 dpo2 = load_balance_get_bucket(dpo1->dpoi_index, 0);
2806 FIB_TEST(DPO_ADJACENCY == dpo2->dpoi_type, "type is %d", dpo2->dpoi_type);
2807 FIB_TEST((ai_01 == dpo2->dpoi_index),
2808 "5.5.5.6 bucket 0 resolves via 10.10.10.2");
2809
2810 fei = fib_table_lookup(fib_index, &pfx_5_5_5_7_s_32);
2811 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2812 "LB for 5.5.5.7/32 is via adj for DROP");
2813 fei = fib_table_lookup(fib_index, &pfx_5_5_5_5_s_32);
2814 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2815 "LB for 5.5.5.5/32 is via adj for DROP");
2816
2817 /*
2818 * remove the alternate path for 5.5.5.6/32
2819 * back to all drop
2820 */
2821 fib_table_entry_path_remove(fib_index,
2822 &pfx_5_5_5_6_s_32,
2823 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002824 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002825 &nh_10_10_10_1,
2826 tm->hw[0]->sw_if_index,
2827 ~0,
2828 1,
2829 FIB_ROUTE_PATH_FLAG_NONE);
2830
2831 fei = fib_table_lookup(fib_index, &pfx_5_5_5_7_s_32);
2832 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2833 "LB for 5.5.5.7/32 is via adj for DROP");
2834 fei = fib_table_lookup(fib_index, &pfx_5_5_5_5_s_32);
2835 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2836 "LB for 5.5.5.5/32 is via adj for DROP");
2837 fei = fib_table_lookup(fib_index, &pfx_5_5_5_6_s_32);
2838 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2839 "LB for 5.5.5.6/32 is via adj for DROP");
2840
2841 /*
2842 * break the loop by giving 5.5.5.5/32 a new set of paths
2843 * expect all to forward via this new path.
2844 */
2845 fib_table_entry_update_one_path(fib_index,
2846 &pfx_5_5_5_5_s_32,
2847 FIB_SOURCE_API,
2848 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002849 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002850 &nh_10_10_10_1,
2851 tm->hw[0]->sw_if_index,
2852 ~0, // invalid fib index
2853 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002854 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002855 FIB_ROUTE_PATH_FLAG_NONE);
2856
2857 fei = fib_table_lookup(fib_index, &pfx_5_5_5_5_s_32);
2858 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2859 lb = load_balance_get(dpo1->dpoi_index);
2860 FIB_TEST((lb->lb_n_buckets == 1), "5.5.5.5 LB has %d bucket", lb->lb_n_buckets);
2861
2862 dpo2 = load_balance_get_bucket(dpo1->dpoi_index, 0);
2863 FIB_TEST(DPO_ADJACENCY == dpo2->dpoi_type, "type is %d", dpo2->dpoi_type);
2864 FIB_TEST((ai_01 == dpo2->dpoi_index),
2865 "5.5.5.5 bucket 0 resolves via 10.10.10.2");
2866
2867 fei = fib_table_lookup_exact_match(fib_index, &pfx_5_5_5_7_s_32);
2868 dpo2 = fib_entry_contribute_ip_forwarding(fei);
2869
2870 lb = load_balance_get(dpo2->dpoi_index);
2871 FIB_TEST((lb->lb_n_buckets == 1), "Recursive LB has %d bucket", lb->lb_n_buckets);
2872 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket(dpo2->dpoi_index, 0)),
2873 "5.5.5.5.7 via 5.5.5.5");
2874
2875 fei = fib_table_lookup_exact_match(fib_index, &pfx_5_5_5_6_s_32);
2876 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2877
2878 lb = load_balance_get(dpo1->dpoi_index);
2879 FIB_TEST((lb->lb_n_buckets == 1), "Recursive LB has %d bucket", lb->lb_n_buckets);
2880 FIB_TEST(!dpo_cmp(dpo2, load_balance_get_bucket(dpo1->dpoi_index, 0)),
2881 "5.5.5.5.6 via 5.5.5.7");
2882
2883 /*
2884 * revert back to the loop. so we can remove the prefixes with
2885 * the loop intact
2886 */
2887 fib_table_entry_update_one_path(fib_index,
2888 &pfx_5_5_5_5_s_32,
2889 FIB_SOURCE_API,
2890 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002891 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002892 &pfx_5_5_5_6_s_32.fp_addr,
2893 ~0, // no index provided.
2894 fib_index,
2895 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002896 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002897 FIB_ROUTE_PATH_FLAG_NONE);
2898
2899 fei = fib_table_lookup(fib_index, &pfx_5_5_5_7_s_32);
2900 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2901 "LB for 5.5.5.7/32 is via adj for DROP");
2902 fei = fib_table_lookup(fib_index, &pfx_5_5_5_5_s_32);
2903 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2904 "LB for 5.5.5.5/32 is via adj for DROP");
2905 fei = fib_table_lookup(fib_index, &pfx_5_5_5_6_s_32);
2906 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2907 "LB for 5.5.5.6/32 is via adj for DROP");
2908
2909 /*
2910 * remove all the 5.5.5.x/32 prefixes
2911 */
2912 fib_table_entry_path_remove(fib_index,
2913 &pfx_5_5_5_5_s_32,
2914 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002915 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002916 &pfx_5_5_5_6_s_32.fp_addr,
2917 ~0, // no index provided.
2918 fib_index, // same as route's FIB
2919 1,
2920 FIB_ROUTE_PATH_FLAG_NONE);
2921 fib_table_entry_path_remove(fib_index,
2922 &pfx_5_5_5_6_s_32,
2923 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002924 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002925 &pfx_5_5_5_7_s_32.fp_addr,
2926 ~0, // no index provided.
2927 fib_index, // same as route's FIB
2928 1,
2929 FIB_ROUTE_PATH_FLAG_NONE);
2930 fib_table_entry_path_remove(fib_index,
2931 &pfx_5_5_5_7_s_32,
2932 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002933 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002934 &pfx_5_5_5_5_s_32.fp_addr,
2935 ~0, // no index provided.
2936 fib_index, // same as route's FIB
2937 1,
2938 FIB_ROUTE_PATH_FLAG_NONE);
2939 fib_table_entry_path_remove(fib_index,
2940 &pfx_5_5_5_6_s_32,
2941 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002942 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002943 &nh_10_10_10_2,
2944 ~0, // no index provided.
2945 fib_index, // same as route's FIB
2946 1,
2947 FIB_ROUTE_PATH_FLAG_NONE);
2948
2949 /*
2950 * -3 entries, -3 shared path-list
2951 */
2952 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
2953 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002954 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002955 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002956 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002957 fib_entry_pool_size());
2958
2959 /*
2960 * Single level loop 5.5.5.5/32 via 5.5.5.5/32
2961 */
2962 fib_table_entry_path_add(fib_index,
2963 &pfx_5_5_5_6_s_32,
2964 FIB_SOURCE_API,
2965 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002966 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002967 &pfx_5_5_5_6_s_32.fp_addr,
2968 ~0, // no index provided.
2969 fib_index,
2970 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002971 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002972 FIB_ROUTE_PATH_FLAG_NONE);
2973 fei = fib_table_lookup(fib_index, &pfx_5_5_5_6_s_32);
2974 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2975 "1-level 5.5.5.6/32 loop is via adj for DROP");
2976
2977 fib_table_entry_path_remove(fib_index,
2978 &pfx_5_5_5_6_s_32,
2979 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002980 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002981 &pfx_5_5_5_6_s_32.fp_addr,
2982 ~0, // no index provided.
2983 fib_index, // same as route's FIB
2984 1,
2985 FIB_ROUTE_PATH_FLAG_NONE);
2986 FIB_TEST(FIB_NODE_INDEX_INVALID ==
2987 fib_table_lookup_exact_match(fib_index, &pfx_5_5_5_6_s_32),
2988 "1-level 5.5.5.6/32 loop is removed");
2989
2990 /*
Neale Ranns3dffb1e2016-11-01 20:38:53 +00002991 * A recursive route whose next-hop is covered by the prefix.
2992 * This would mean the via-fib, which inherits forwarding from its
2993 * cover, thus picks up forwarding from the prfix, which is via the
2994 * via-fib, and we have a loop.
2995 */
2996 fib_prefix_t pfx_23_23_23_0_s_24 = {
2997 .fp_len = 24,
2998 .fp_proto = FIB_PROTOCOL_IP4,
2999 .fp_addr = {
3000 .ip4.as_u32 = clib_host_to_net_u32(0x17171700),
3001 },
3002 };
3003 fib_prefix_t pfx_23_23_23_23_s_32 = {
3004 .fp_len = 32,
3005 .fp_proto = FIB_PROTOCOL_IP4,
3006 .fp_addr = {
3007 .ip4.as_u32 = clib_host_to_net_u32(0x17171717),
3008 },
3009 };
3010 fei = fib_table_entry_path_add(fib_index,
3011 &pfx_23_23_23_0_s_24,
3012 FIB_SOURCE_API,
3013 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003014 DPO_PROTO_IP4,
Neale Ranns3dffb1e2016-11-01 20:38:53 +00003015 &pfx_23_23_23_23_s_32.fp_addr,
3016 ~0, // recursive
3017 fib_index,
3018 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003019 NULL,
Neale Ranns3dffb1e2016-11-01 20:38:53 +00003020 FIB_ROUTE_PATH_FLAG_NONE);
3021 dpo = fib_entry_contribute_ip_forwarding(fei);
3022 FIB_TEST(load_balance_is_drop(dpo),
3023 "23.23.23.0/24 via covered is DROP");
3024 fib_table_entry_delete_index(fei, FIB_SOURCE_API);
3025
3026 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003027 * add-remove test. no change.
3028 */
3029 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
3030 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003031 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003032 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003033 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003034 fib_entry_pool_size());
3035
3036 /*
Neale Ranns08b16482017-05-13 05:52:58 -07003037 * Make the default route recursive via a unknown next-hop. Thus the
3038 * next hop's cover would be the default route
3039 */
3040 fei = fib_table_entry_path_add(fib_index,
3041 &pfx_0_0_0_0_s_0,
3042 FIB_SOURCE_API,
3043 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003044 DPO_PROTO_IP4,
Neale Ranns08b16482017-05-13 05:52:58 -07003045 &pfx_23_23_23_23_s_32.fp_addr,
3046 ~0, // recursive
3047 fib_index,
3048 1,
3049 NULL,
3050 FIB_ROUTE_PATH_FLAG_NONE);
3051 dpo = fib_entry_contribute_ip_forwarding(fei);
3052 FIB_TEST(load_balance_is_drop(dpo),
3053 "0.0.0.0.0/0 via is DROP");
3054 FIB_TEST((fib_entry_get_resolving_interface(fei) == ~0),
3055 "no resolving interface for looped 0.0.0.0/0");
3056
3057 fei = fib_table_lookup_exact_match(fib_index, &pfx_23_23_23_23_s_32);
3058 dpo = fib_entry_contribute_ip_forwarding(fei);
3059 FIB_TEST(load_balance_is_drop(dpo),
3060 "23.23.23.23/32 via is DROP");
3061 FIB_TEST((fib_entry_get_resolving_interface(fei) == ~0),
3062 "no resolving interface for looped 23.23.23.23/32");
3063
3064 fib_table_entry_delete(fib_index, &pfx_0_0_0_0_s_0, FIB_SOURCE_API);
3065
3066 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003067 * A recursive route with recursion constraints.
3068 * 200.200.200.200/32 via 1.1.1.1 is recurse via host constrained
3069 */
3070 fib_table_entry_path_add(fib_index,
3071 &bgp_200_pfx,
3072 FIB_SOURCE_API,
3073 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003074 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003075 &nh_1_1_1_1,
3076 ~0,
3077 fib_index,
3078 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003079 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003080 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
3081
3082 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_1_s_32);
3083 dpo2 = fib_entry_contribute_ip_forwarding(fei);
3084
3085 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
3086 dpo1 = fib_entry_contribute_ip_forwarding(fei);
3087
3088 FIB_TEST(!dpo_cmp(dpo2, load_balance_get_bucket(dpo1->dpoi_index, 0)),
3089 "adj for 200.200.200.200/32 is recursive via adj for 1.1.1.1");
3090
3091 /*
3092 * save the load-balance. we expect it to be inplace modified
3093 */
3094 lb = load_balance_get(dpo1->dpoi_index);
3095
3096 /*
3097 * add a covering prefix for the via fib that would otherwise serve
3098 * as the resolving route when the host is removed
3099 */
3100 fib_table_entry_path_add(fib_index,
3101 &pfx_1_1_1_0_s_28,
3102 FIB_SOURCE_API,
3103 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003104 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003105 &nh_10_10_10_1,
3106 tm->hw[0]->sw_if_index,
3107 ~0, // invalid fib index
3108 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003109 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003110 FIB_ROUTE_PATH_FLAG_NONE);
3111 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_0_s_28);
3112 ai = fib_entry_get_adj(fei);
3113 FIB_TEST((ai == ai_01),
3114 "adj for 1.1.1.0/28 is via adj for 1.1.1.1");
3115
3116 /*
3117 * remove the host via FIB - expect the BGP prefix to be drop
3118 */
3119 fib_table_entry_path_remove(fib_index,
3120 &pfx_1_1_1_1_s_32,
3121 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07003122 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003123 &nh_10_10_10_1,
3124 tm->hw[0]->sw_if_index,
3125 ~0, // invalid fib index
3126 1,
3127 FIB_ROUTE_PATH_FLAG_NONE);
3128
3129 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo1->dpoi_index, 0)),
3130 "adj for 200.200.200.200/32 is recursive via adj for DROP");
3131
3132 /*
3133 * add the via-entry host reoute back. expect to resolve again
3134 */
3135 fib_table_entry_path_add(fib_index,
3136 &pfx_1_1_1_1_s_32,
3137 FIB_SOURCE_API,
3138 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003139 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003140 &nh_10_10_10_1,
3141 tm->hw[0]->sw_if_index,
3142 ~0, // invalid fib index
3143 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003144 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003145 FIB_ROUTE_PATH_FLAG_NONE);
3146 FIB_TEST(!dpo_cmp(dpo2, load_balance_get_bucket(dpo1->dpoi_index, 0)),
3147 "adj for 200.200.200.200/32 is recursive via adj for 1.1.1.1");
3148
3149 /*
3150 * add another path for the recursive. it will then have 2.
3151 */
3152 fib_prefix_t pfx_1_1_1_3_s_32 = {
3153 .fp_len = 32,
3154 .fp_proto = FIB_PROTOCOL_IP4,
3155 .fp_addr = {
3156 .ip4.as_u32 = clib_host_to_net_u32(0x01010103),
3157 },
3158 };
3159 fib_table_entry_path_add(fib_index,
3160 &pfx_1_1_1_3_s_32,
3161 FIB_SOURCE_API,
3162 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003163 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003164 &nh_10_10_10_2,
3165 tm->hw[0]->sw_if_index,
3166 ~0, // invalid fib index
3167 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003168 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003169 FIB_ROUTE_PATH_FLAG_NONE);
3170
3171 fib_table_entry_path_add(fib_index,
3172 &bgp_200_pfx,
3173 FIB_SOURCE_API,
3174 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003175 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003176 &pfx_1_1_1_3_s_32.fp_addr,
3177 ~0,
3178 fib_index,
3179 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003180 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003181 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
3182
Neale Rannsf12a83f2017-04-18 09:09:40 -07003183 /*
3184 * add a bunch load more entries using this path combo so that we get
3185 * an LB-map created.
3186 */
3187#define N_P 128
3188 fib_prefix_t bgp_78s[N_P];
3189 for (ii = 0; ii < N_P; ii++)
3190 {
3191 bgp_78s[ii].fp_len = 32;
3192 bgp_78s[ii].fp_proto = FIB_PROTOCOL_IP4;
3193 bgp_78s[ii].fp_addr.ip4.as_u32 = clib_host_to_net_u32(0x4e000000+ii);
3194
3195
3196 fib_table_entry_path_add(fib_index,
3197 &bgp_78s[ii],
3198 FIB_SOURCE_API,
3199 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003200 DPO_PROTO_IP4,
Neale Rannsf12a83f2017-04-18 09:09:40 -07003201 &pfx_1_1_1_3_s_32.fp_addr,
3202 ~0,
3203 fib_index,
3204 1,
3205 NULL,
3206 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
3207 fib_table_entry_path_add(fib_index,
3208 &bgp_78s[ii],
3209 FIB_SOURCE_API,
3210 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003211 DPO_PROTO_IP4,
Neale Rannsf12a83f2017-04-18 09:09:40 -07003212 &nh_1_1_1_1,
3213 ~0,
3214 fib_index,
3215 1,
3216 NULL,
3217 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
3218 }
3219
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003220 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
3221 dpo = fib_entry_contribute_ip_forwarding(fei);
3222
3223 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_1_s_32);
3224 dpo2 = fib_entry_contribute_ip_forwarding(fei);
3225 FIB_TEST(!dpo_cmp(dpo2, load_balance_get_bucket(dpo->dpoi_index, 0)),
3226 "adj for 200.200.200.200/32 is recursive via adj for 1.1.1.1");
3227 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_3_s_32);
3228 dpo1 = fib_entry_contribute_ip_forwarding(fei);
3229 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket(dpo->dpoi_index, 1)),
3230 "adj for 200.200.200.200/32 is recursive via adj for 1.1.1.3");
3231
3232 /*
3233 * expect the lb-map used by the recursive's load-balance is using both buckets
3234 */
3235 load_balance_map_t *lbm;
3236 index_t lbmi;
3237
3238 lb = load_balance_get(dpo->dpoi_index);
3239 lbmi = lb->lb_map;
3240 load_balance_map_lock(lbmi);
3241 lbm = load_balance_map_get(lbmi);
3242
3243 FIB_TEST(lbm->lbm_buckets[0] == 0,
3244 "LB maps's bucket 0 is %d",
3245 lbm->lbm_buckets[0]);
3246 FIB_TEST(lbm->lbm_buckets[1] == 1,
3247 "LB maps's bucket 1 is %d",
3248 lbm->lbm_buckets[1]);
3249
3250 /*
3251 * withdraw one of the /32 via-entrys.
3252 * that ECMP path will be unresolved and forwarding should continue on the
3253 * other available path. this is an iBGP PIC edge failover.
3254 * Test the forwarding changes without re-fetching the adj from the
3255 * recursive entry. this ensures its the same one that is updated; i.e. an
3256 * inplace-modify.
3257 */
3258 fib_table_entry_path_remove(fib_index,
3259 &pfx_1_1_1_1_s_32,
3260 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07003261 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003262 &nh_10_10_10_1,
3263 tm->hw[0]->sw_if_index,
3264 ~0, // invalid fib index
3265 1,
3266 FIB_ROUTE_PATH_FLAG_NONE);
3267
Neale Rannsf12a83f2017-04-18 09:09:40 -07003268 /* suspend so the update walk kicks int */
3269 vlib_process_suspend(vlib_get_main(), 1e-5);
3270
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003271 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
3272 FIB_TEST(!dpo_cmp(dpo, fib_entry_contribute_ip_forwarding(fei)),
3273 "post PIC 200.200.200.200/32 was inplace modified");
3274
3275 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket_i(lb, 0)),
3276 "post PIC adj for 200.200.200.200/32 is recursive"
3277 " via adj for 1.1.1.3");
3278
3279 /*
3280 * the LB maps that was locked above should have been modified to remove
3281 * the path that was down, and thus its bucket points to a path that is
3282 * still up.
3283 */
3284 FIB_TEST(lbm->lbm_buckets[0] == 1,
3285 "LB maps's bucket 0 is %d",
3286 lbm->lbm_buckets[0]);
3287 FIB_TEST(lbm->lbm_buckets[1] == 1,
3288 "LB maps's bucket 1 is %d",
3289 lbm->lbm_buckets[1]);
3290
Neale Ranns994dab42017-04-18 12:56:45 -07003291 load_balance_map_unlock(lbmi);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003292
3293 /*
3294 * add it back. again
3295 */
3296 fib_table_entry_path_add(fib_index,
3297 &pfx_1_1_1_1_s_32,
3298 FIB_SOURCE_API,
3299 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003300 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003301 &nh_10_10_10_1,
3302 tm->hw[0]->sw_if_index,
3303 ~0, // invalid fib index
3304 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003305 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003306 FIB_ROUTE_PATH_FLAG_NONE);
3307
Neale Rannsf12a83f2017-04-18 09:09:40 -07003308 /* suspend so the update walk kicks in */
3309 vlib_process_suspend(vlib_get_main(), 1e-5);
3310
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003311 FIB_TEST(!dpo_cmp(dpo2, load_balance_get_bucket_i(lb, 0)),
3312 "post PIC recovery adj for 200.200.200.200/32 is recursive "
3313 "via adj for 1.1.1.1");
3314 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket_i(lb, 1)),
3315 "post PIC recovery adj for 200.200.200.200/32 is recursive "
3316 "via adj for 1.1.1.3");
3317
3318 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
3319 dpo = fib_entry_contribute_ip_forwarding(fei);
3320 FIB_TEST(lb == load_balance_get(dpo->dpoi_index),
3321 "post PIC 200.200.200.200/32 was inplace modified");
3322
3323 /*
3324 * add a 3rd path. this makes the LB 16 buckets.
3325 */
3326 fib_table_entry_path_add(fib_index,
3327 &bgp_200_pfx,
3328 FIB_SOURCE_API,
3329 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003330 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003331 &pfx_1_1_1_2_s_32.fp_addr,
3332 ~0,
3333 fib_index,
3334 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003335 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003336 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
Neale Rannsf12a83f2017-04-18 09:09:40 -07003337 for (ii = 0; ii < N_P; ii++)
3338 {
3339 fib_table_entry_path_add(fib_index,
3340 &bgp_78s[ii],
3341 FIB_SOURCE_API,
3342 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003343 DPO_PROTO_IP4,
Neale Rannsf12a83f2017-04-18 09:09:40 -07003344 &pfx_1_1_1_2_s_32.fp_addr,
3345 ~0,
3346 fib_index,
3347 1,
3348 NULL,
3349 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
3350 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003351
3352 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
3353 dpo = fib_entry_contribute_ip_forwarding(fei);
3354 FIB_TEST(lb == load_balance_get(dpo->dpoi_index),
3355 "200.200.200.200/32 was inplace modified for 3rd path");
3356 FIB_TEST(16 == lb->lb_n_buckets,
3357 "200.200.200.200/32 was inplace modified for 3rd path to 16 buckets");
3358
3359 lbmi = lb->lb_map;
3360 load_balance_map_lock(lbmi);
3361 lbm = load_balance_map_get(lbmi);
3362
3363 for (ii = 0; ii < 16; ii++)
3364 {
3365 FIB_TEST(lbm->lbm_buckets[ii] == ii,
3366 "LB Map for 200.200.200.200/32 at %d is %d",
3367 ii, lbm->lbm_buckets[ii]);
3368 }
3369
3370 /*
3371 * trigger PIC by removing the first via-entry
3372 * the first 6 buckets of the map should map to the next 6
3373 */
3374 fib_table_entry_path_remove(fib_index,
3375 &pfx_1_1_1_1_s_32,
3376 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07003377 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003378 &nh_10_10_10_1,
3379 tm->hw[0]->sw_if_index,
3380 ~0,
3381 1,
3382 FIB_ROUTE_PATH_FLAG_NONE);
Neale Rannsf12a83f2017-04-18 09:09:40 -07003383 /* suspend so the update walk kicks int */
3384 vlib_process_suspend(vlib_get_main(), 1e-5);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003385
3386 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
3387 dpo = fib_entry_contribute_ip_forwarding(fei);
3388 FIB_TEST(lb == load_balance_get(dpo->dpoi_index),
3389 "200.200.200.200/32 was inplace modified for 3rd path");
3390 FIB_TEST(2 == lb->lb_n_buckets,
3391 "200.200.200.200/32 was inplace modified for 3rd path remove to 2 buckets");
3392
3393 for (ii = 0; ii < 6; ii++)
3394 {
3395 FIB_TEST(lbm->lbm_buckets[ii] == ii+6,
3396 "LB Map for 200.200.200.200/32 at %d is %d",
3397 ii, lbm->lbm_buckets[ii]);
3398 }
3399 for (ii = 6; ii < 16; ii++)
3400 {
3401 FIB_TEST(lbm->lbm_buckets[ii] == ii,
3402 "LB Map for 200.200.200.200/32 at %d is %d",
3403 ii, lbm->lbm_buckets[ii]);
3404 }
Neale Ranns994dab42017-04-18 12:56:45 -07003405 load_balance_map_unlock(lbmi);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003406
3407 /*
3408 * tidy up
3409 */
3410 fib_table_entry_path_add(fib_index,
3411 &pfx_1_1_1_1_s_32,
3412 FIB_SOURCE_API,
3413 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003414 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003415 &nh_10_10_10_1,
3416 tm->hw[0]->sw_if_index,
3417 ~0,
3418 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003419 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003420 FIB_ROUTE_PATH_FLAG_NONE);
3421
Neale Rannsf12a83f2017-04-18 09:09:40 -07003422 for (ii = 0; ii < N_P; ii++)
3423 {
3424 fib_table_entry_delete(fib_index,
3425 &bgp_78s[ii],
3426 FIB_SOURCE_API);
3427 FIB_TEST((FIB_NODE_INDEX_INVALID ==
3428 fib_table_lookup_exact_match(fib_index, &bgp_78s[ii])),
3429 "%U removed",
3430 format_fib_prefix, &bgp_78s[ii]);
3431 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003432 fib_table_entry_path_remove(fib_index,
3433 &bgp_200_pfx,
3434 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07003435 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003436 &pfx_1_1_1_2_s_32.fp_addr,
3437 ~0,
3438 fib_index,
3439 1,
3440 MPLS_LABEL_INVALID);
3441 fib_table_entry_path_remove(fib_index,
3442 &bgp_200_pfx,
3443 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07003444 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003445 &nh_1_1_1_1,
3446 ~0,
3447 fib_index,
3448 1,
3449 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
3450 fib_table_entry_path_remove(fib_index,
3451 &bgp_200_pfx,
3452 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07003453 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003454 &pfx_1_1_1_3_s_32.fp_addr,
3455 ~0,
3456 fib_index,
3457 1,
3458 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
3459 fib_table_entry_delete(fib_index,
3460 &pfx_1_1_1_3_s_32,
3461 FIB_SOURCE_API);
3462 fib_table_entry_delete(fib_index,
3463 &pfx_1_1_1_0_s_28,
3464 FIB_SOURCE_API);
Neale Rannsf12a83f2017-04-18 09:09:40 -07003465 /* suspend so the update walk kicks int */
3466 vlib_process_suspend(vlib_get_main(), 1e-5);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003467 FIB_TEST((FIB_NODE_INDEX_INVALID ==
3468 fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_0_s_28)),
3469 "1.1.1.1/28 removed");
3470 FIB_TEST((FIB_NODE_INDEX_INVALID ==
3471 fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_3_s_32)),
3472 "1.1.1.3/32 removed");
3473 FIB_TEST((FIB_NODE_INDEX_INVALID ==
3474 fib_table_lookup_exact_match(fib_index, &bgp_200_pfx)),
3475 "200.200.200.200/32 removed");
3476
3477 /*
3478 * add-remove test. no change.
3479 */
3480 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
3481 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003482 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003483 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003484 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003485 fib_entry_pool_size());
3486
3487 /*
3488 * A route whose paths are built up iteratively and then removed
3489 * all at once
3490 */
3491 fib_prefix_t pfx_4_4_4_4_s_32 = {
3492 .fp_len = 32,
3493 .fp_proto = FIB_PROTOCOL_IP4,
3494 .fp_addr = {
3495 /* 4.4.4.4/32 */
3496 .ip4.as_u32 = clib_host_to_net_u32(0x04040404),
3497 },
3498 };
3499
3500 fib_table_entry_path_add(fib_index,
3501 &pfx_4_4_4_4_s_32,
3502 FIB_SOURCE_API,
3503 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003504 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003505 &nh_10_10_10_1,
3506 tm->hw[0]->sw_if_index,
3507 ~0,
3508 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003509 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003510 FIB_ROUTE_PATH_FLAG_NONE);
3511 fib_table_entry_path_add(fib_index,
3512 &pfx_4_4_4_4_s_32,
3513 FIB_SOURCE_API,
3514 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003515 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003516 &nh_10_10_10_2,
3517 tm->hw[0]->sw_if_index,
3518 ~0,
3519 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003520 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003521 FIB_ROUTE_PATH_FLAG_NONE);
3522 fib_table_entry_path_add(fib_index,
3523 &pfx_4_4_4_4_s_32,
3524 FIB_SOURCE_API,
3525 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003526 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003527 &nh_10_10_10_3,
3528 tm->hw[0]->sw_if_index,
3529 ~0,
3530 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003531 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003532 FIB_ROUTE_PATH_FLAG_NONE);
3533 FIB_TEST(FIB_NODE_INDEX_INVALID !=
3534 fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32),
3535 "4.4.4.4/32 present");
3536
3537 fib_table_entry_delete(fib_index,
3538 &pfx_4_4_4_4_s_32,
3539 FIB_SOURCE_API);
3540 FIB_TEST(FIB_NODE_INDEX_INVALID ==
3541 fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32),
3542 "4.4.4.4/32 removed");
3543
3544 /*
3545 * add-remove test. no change.
3546 */
3547 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
3548 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003549 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003550 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003551 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003552 fib_entry_pool_size());
3553
3554 /*
3555 * A route with multiple paths at once
3556 */
3557 fib_route_path_t *r_paths = NULL;
3558
3559 for (ii = 0; ii < 4; ii++)
3560 {
3561 fib_route_path_t r_path = {
Neale Rannsda78f952017-05-24 09:15:43 -07003562 .frp_proto = DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003563 .frp_addr = {
3564 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02 + ii),
3565 },
3566 .frp_sw_if_index = tm->hw[0]->sw_if_index,
3567 .frp_weight = 1,
3568 .frp_fib_index = ~0,
3569 };
3570 vec_add1(r_paths, r_path);
3571 }
3572
3573 fib_table_entry_update(fib_index,
3574 &pfx_4_4_4_4_s_32,
3575 FIB_SOURCE_API,
3576 FIB_ENTRY_FLAG_NONE,
3577 r_paths);
3578
3579 fei = fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32);
3580 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "4.4.4.4/32 present");
3581 dpo = fib_entry_contribute_ip_forwarding(fei);
3582
3583 lb = load_balance_get(dpo->dpoi_index);
3584 FIB_TEST((lb->lb_n_buckets == 4), "4.4.4.4/32 lb over %d paths", lb->lb_n_buckets);
3585
3586 fib_table_entry_delete(fib_index,
3587 &pfx_4_4_4_4_s_32,
3588 FIB_SOURCE_API);
3589 FIB_TEST(FIB_NODE_INDEX_INVALID ==
3590 fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32),
3591 "4.4.4.4/32 removed");
3592 vec_free(r_paths);
3593
3594 /*
3595 * add-remove test. no change.
3596 */
3597 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
3598 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003599 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003600 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003601 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003602 fib_entry_pool_size());
3603
3604 /*
3605 * A route deag route
3606 */
3607 fib_table_entry_path_add(fib_index,
3608 &pfx_4_4_4_4_s_32,
3609 FIB_SOURCE_API,
3610 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003611 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003612 &zero_addr,
3613 ~0,
3614 fib_index,
3615 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003616 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003617 FIB_ROUTE_PATH_FLAG_NONE);
3618
3619 fei = fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32);
3620 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "4.4.4.4/32 present");
3621
3622 dpo = fib_entry_contribute_ip_forwarding(fei);
3623 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
3624 lookup_dpo_t *lkd = lookup_dpo_get(dpo->dpoi_index);
3625
3626 FIB_TEST((fib_index == lkd->lkd_fib_index),
3627 "4.4.4.4/32 is deag in %d %U",
3628 lkd->lkd_fib_index,
3629 format_dpo_id, dpo, 0);
Neale Ranns054c03a2017-10-13 05:15:07 -07003630 FIB_TEST((LOOKUP_INPUT_DST_ADDR == lkd->lkd_input),
3631 "4.4.4.4/32 is source deag in %d %U",
3632 lkd->lkd_input,
3633 format_dpo_id, dpo, 0);
3634
3635 fib_table_entry_delete(fib_index,
3636 &pfx_4_4_4_4_s_32,
3637 FIB_SOURCE_API);
3638 FIB_TEST(FIB_NODE_INDEX_INVALID ==
3639 fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32),
3640 "4.4.4.4/32 removed");
3641 vec_free(r_paths);
3642
3643 /*
3644 * A route deag route in a source lookup table
3645 */
3646 fib_table_entry_path_add(fib_index,
3647 &pfx_4_4_4_4_s_32,
3648 FIB_SOURCE_API,
3649 FIB_ENTRY_FLAG_NONE,
3650 DPO_PROTO_IP4,
3651 &zero_addr,
3652 ~0,
3653 fib_index,
3654 1,
3655 NULL,
3656 FIB_ROUTE_PATH_SOURCE_LOOKUP);
3657
3658 fei = fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32);
3659 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "4.4.4.4/32 present");
3660
3661 dpo = fib_entry_contribute_ip_forwarding(fei);
3662 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
3663 lkd = lookup_dpo_get(dpo->dpoi_index);
3664
3665 FIB_TEST((fib_index == lkd->lkd_fib_index),
3666 "4.4.4.4/32 is deag in %d %U",
3667 lkd->lkd_fib_index,
3668 format_dpo_id, dpo, 0);
3669 FIB_TEST((LOOKUP_INPUT_SRC_ADDR == lkd->lkd_input),
3670 "4.4.4.4/32 is source deag in %d %U",
3671 lkd->lkd_input,
3672 format_dpo_id, dpo, 0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003673
3674 fib_table_entry_delete(fib_index,
3675 &pfx_4_4_4_4_s_32,
3676 FIB_SOURCE_API);
3677 FIB_TEST(FIB_NODE_INDEX_INVALID ==
3678 fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32),
3679 "4.4.4.4/32 removed");
3680 vec_free(r_paths);
3681
3682 /*
3683 * add-remove test. no change.
3684 */
3685 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
3686 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003687 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003688 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003689 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003690 fib_entry_pool_size());
3691
3692 /*
Neale Rannsbcc889c2016-11-03 14:15:28 -07003693 * Duplicate paths:
3694 * add a recursive with duplicate paths. Expect the duplicate to be ignored.
3695 */
3696 fib_prefix_t pfx_34_1_1_1_s_32 = {
3697 .fp_len = 32,
3698 .fp_proto = FIB_PROTOCOL_IP4,
3699 .fp_addr = {
3700 .ip4.as_u32 = clib_host_to_net_u32(0x22010101),
3701 },
3702 };
3703 fib_prefix_t pfx_34_34_1_1_s_32 = {
3704 .fp_len = 32,
3705 .fp_proto = FIB_PROTOCOL_IP4,
3706 .fp_addr = {
3707 .ip4.as_u32 = clib_host_to_net_u32(0x22220101),
3708 },
3709 };
3710 fei = fib_table_entry_path_add(fib_index,
Neale Ranns57b58602017-07-15 07:37:25 -07003711 &pfx_34_34_1_1_s_32,
3712 FIB_SOURCE_API,
3713 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003714 DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07003715 &nh_10_10_10_1,
3716 tm->hw[0]->sw_if_index,
3717 0,
3718 1,
3719 NULL,
3720 FIB_ROUTE_PATH_FLAG_NONE);
3721 fei = fib_table_entry_path_add(fib_index,
Neale Rannsbcc889c2016-11-03 14:15:28 -07003722 &pfx_34_1_1_1_s_32,
3723 FIB_SOURCE_API,
3724 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003725 DPO_PROTO_IP4,
Neale Rannsbcc889c2016-11-03 14:15:28 -07003726 &pfx_34_34_1_1_s_32.fp_addr,
3727 ~0,
3728 fib_index,
3729 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003730 NULL,
Neale Rannsbcc889c2016-11-03 14:15:28 -07003731 FIB_ROUTE_PATH_FLAG_NONE);
3732 fei = fib_table_entry_path_add(fib_index,
3733 &pfx_34_1_1_1_s_32,
3734 FIB_SOURCE_API,
3735 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003736 DPO_PROTO_IP4,
Neale Rannsbcc889c2016-11-03 14:15:28 -07003737 &pfx_34_34_1_1_s_32.fp_addr,
3738 ~0,
3739 fib_index,
3740 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003741 NULL,
Neale Rannsbcc889c2016-11-03 14:15:28 -07003742 FIB_ROUTE_PATH_FLAG_NONE);
3743 FIB_TEST_REC_FORW(&pfx_34_1_1_1_s_32, &pfx_34_34_1_1_s_32, 0);
3744 fib_table_entry_delete_index(fei, FIB_SOURCE_API);
Neale Ranns57b58602017-07-15 07:37:25 -07003745 fib_table_entry_delete(fib_index,
3746 &pfx_34_34_1_1_s_32,
3747 FIB_SOURCE_API);
Neale Rannsbcc889c2016-11-03 14:15:28 -07003748
3749 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003750 * CLEANUP
3751 * remove: 1.1.1.2/32, 1.1.2.0/24 and 1.1.1.1/32
3752 * all of which are via 10.10.10.1, Itf1
3753 */
3754 fib_table_entry_path_remove(fib_index,
3755 &pfx_1_1_1_2_s_32,
3756 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07003757 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003758 &nh_10_10_10_1,
3759 tm->hw[0]->sw_if_index,
3760 ~0,
3761 1,
3762 FIB_ROUTE_PATH_FLAG_NONE);
3763 fib_table_entry_path_remove(fib_index,
3764 &pfx_1_1_1_1_s_32,
3765 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07003766 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003767 &nh_10_10_10_1,
3768 tm->hw[0]->sw_if_index,
3769 ~0,
3770 1,
3771 FIB_ROUTE_PATH_FLAG_NONE);
3772 fib_table_entry_path_remove(fib_index,
3773 &pfx_1_1_2_0_s_24,
3774 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07003775 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003776 &nh_10_10_10_1,
3777 tm->hw[0]->sw_if_index,
3778 ~0,
3779 1,
3780 FIB_ROUTE_PATH_FLAG_NONE);
3781
3782 FIB_TEST(FIB_NODE_INDEX_INVALID ==
3783 fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_1_s_32),
3784 "1.1.1.1/32 removed");
3785 FIB_TEST(FIB_NODE_INDEX_INVALID ==
3786 fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_2_s_32),
3787 "1.1.1.2/32 removed");
3788 FIB_TEST(FIB_NODE_INDEX_INVALID ==
3789 fib_table_lookup_exact_match(fib_index, &pfx_1_1_2_0_s_24),
3790 "1.1.2.0/24 removed");
3791
3792 /*
3793 * -3 entries and -1 shared path-list
3794 */
3795 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
3796 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003797 FIB_TEST((PNBR+4 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003798 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003799 FIB_TEST((ENBR+4 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003800 fib_entry_pool_size());
3801
3802 /*
3803 * An attached-host route. Expect to link to the incomplete adj
3804 */
3805 fib_prefix_t pfx_4_1_1_1_s_32 = {
3806 .fp_len = 32,
3807 .fp_proto = FIB_PROTOCOL_IP4,
3808 .fp_addr = {
3809 /* 4.1.1.1/32 */
3810 .ip4.as_u32 = clib_host_to_net_u32(0x04010101),
3811 },
3812 };
3813 fib_table_entry_path_add(fib_index,
3814 &pfx_4_1_1_1_s_32,
3815 FIB_SOURCE_API,
3816 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003817 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003818 &zero_addr,
3819 tm->hw[0]->sw_if_index,
3820 fib_index,
3821 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003822 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003823 FIB_ROUTE_PATH_FLAG_NONE);
3824
3825 fei = fib_table_lookup_exact_match(fib_index, &pfx_4_1_1_1_s_32);
3826 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "4.1.1.1/32 present");
3827 ai = fib_entry_get_adj(fei);
3828
3829 ai2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01003830 VNET_LINK_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003831 &pfx_4_1_1_1_s_32.fp_addr,
3832 tm->hw[0]->sw_if_index);
3833 FIB_TEST((ai == ai2), "Attached-host link to incomplete ADJ");
3834 adj_unlock(ai2);
3835
3836 /*
3837 * +1 entry and +1 shared path-list
3838 */
3839 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
3840 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003841 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003842 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003843 FIB_TEST((ENBR+5 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003844 fib_entry_pool_size());
3845
3846 fib_table_entry_delete(fib_index,
3847 &pfx_4_1_1_1_s_32,
3848 FIB_SOURCE_API);
3849
3850 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
3851 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003852 FIB_TEST((PNBR+4 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003853 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003854 FIB_TEST((ENBR+4 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003855 fib_entry_pool_size());
3856
3857 /*
3858 * add a v6 prefix via v4 next-hops
3859 */
3860 fib_prefix_t pfx_2001_s_64 = {
3861 .fp_len = 64,
3862 .fp_proto = FIB_PROTOCOL_IP6,
3863 .fp_addr = {
3864 .ip6.as_u64[0] = clib_host_to_net_u64(0x2001000000000000),
3865 },
3866 };
3867 fei = fib_table_entry_path_add(0, //default v6 table
3868 &pfx_2001_s_64,
3869 FIB_SOURCE_API,
3870 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003871 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003872 &nh_10_10_10_1,
3873 tm->hw[0]->sw_if_index,
3874 fib_index,
3875 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003876 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003877 FIB_ROUTE_PATH_FLAG_NONE);
3878
3879 fei = fib_table_lookup_exact_match(0, &pfx_2001_s_64);
3880 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "2001::/64 present");
3881 ai = fib_entry_get_adj(fei);
3882 adj = adj_get(ai);
3883 FIB_TEST((adj->lookup_next_index == IP_LOOKUP_NEXT_ARP),
3884 "2001::/64 via ARP-adj");
Neale Ranns924d03a2016-10-19 08:25:46 +01003885 FIB_TEST((adj->ia_link == VNET_LINK_IP6),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003886 "2001::/64 is link type v6");
3887 FIB_TEST((adj->ia_nh_proto == FIB_PROTOCOL_IP4),
3888 "2001::/64 ADJ-adj is NH proto v4");
3889 fib_table_entry_delete(0, &pfx_2001_s_64, FIB_SOURCE_API);
3890
Neale Ranns3ee44042016-10-03 13:05:48 +01003891 /*
3892 * add a uRPF exempt prefix:
3893 * test:
3894 * - it's forwarding is drop
3895 * - it's uRPF list is not empty
3896 * - the uRPF list for the default route (it's cover) is empty
3897 */
3898 fei = fib_table_entry_special_add(fib_index,
3899 &pfx_4_1_1_1_s_32,
3900 FIB_SOURCE_URPF_EXEMPT,
Neale Rannsa0558302017-04-13 00:44:52 -07003901 FIB_ENTRY_FLAG_DROP);
Neale Ranns3ee44042016-10-03 13:05:48 +01003902 dpo = fib_entry_contribute_ip_forwarding(fei);
3903 FIB_TEST(load_balance_is_drop(dpo),
3904 "uRPF exempt 4.1.1.1/32 DROP");
3905 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 1, 0),
3906 "uRPF list for exempt prefix has itf index 0");
3907 fei = fib_table_lookup_exact_match(fib_index, &pfx_0_0_0_0_s_0);
3908 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 0),
3909 "uRPF list for 0.0.0.0/0 empty");
3910
3911 fib_table_entry_delete(fib_index, &pfx_4_1_1_1_s_32, FIB_SOURCE_URPF_EXEMPT);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003912
3913 /*
Neale Ranns3983ac22017-03-10 11:53:27 -08003914 * An adj-fib that fails the refinement criteria - no connected cover
3915 */
3916 fib_prefix_t pfx_12_10_10_2_s_32 = {
3917 .fp_len = 32,
3918 .fp_proto = FIB_PROTOCOL_IP4,
3919 .fp_addr = {
3920 /* 12.10.10.2 */
3921 .ip4.as_u32 = clib_host_to_net_u32(0x0c0a0a02),
3922 },
3923 };
3924
Neale Ranns81424992017-05-18 03:03:22 -07003925 fib_table_entry_path_add(fib_index,
3926 &pfx_12_10_10_2_s_32,
3927 FIB_SOURCE_ADJ,
3928 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07003929 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07003930 &pfx_12_10_10_2_s_32.fp_addr,
3931 tm->hw[0]->sw_if_index,
3932 ~0, // invalid fib index
3933 1,
3934 NULL,
3935 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns3983ac22017-03-10 11:53:27 -08003936
3937 fei = fib_table_lookup_exact_match(fib_index, &pfx_12_10_10_2_s_32);
3938 dpo = fib_entry_contribute_ip_forwarding(fei);
3939 FIB_TEST(!dpo_id_is_valid(dpo),
3940 "no connected cover adj-fib fails refinement");
3941
3942 fib_table_entry_delete(fib_index,
3943 &pfx_12_10_10_2_s_32,
3944 FIB_SOURCE_ADJ);
3945
3946 /*
3947 * An adj-fib that fails the refinement criteria - cover is connected
3948 * but on a different interface
3949 */
3950 fib_prefix_t pfx_10_10_10_127_s_32 = {
3951 .fp_len = 32,
3952 .fp_proto = FIB_PROTOCOL_IP4,
3953 .fp_addr = {
3954 /* 10.10.10.127 */
3955 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a7f),
3956 },
3957 };
3958
Neale Ranns81424992017-05-18 03:03:22 -07003959 fib_table_entry_path_add(fib_index,
3960 &pfx_10_10_10_127_s_32,
3961 FIB_SOURCE_ADJ,
3962 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07003963 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07003964 &pfx_10_10_10_127_s_32.fp_addr,
3965 tm->hw[1]->sw_if_index,
3966 ~0, // invalid fib index
3967 1,
3968 NULL,
3969 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns3983ac22017-03-10 11:53:27 -08003970
3971 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_127_s_32);
3972 dpo = fib_entry_contribute_ip_forwarding(fei);
3973 FIB_TEST(!dpo_id_is_valid(dpo),
3974 "wrong interface adj-fib fails refinement");
3975
3976 fib_table_entry_delete(fib_index,
3977 &pfx_10_10_10_127_s_32,
3978 FIB_SOURCE_ADJ);
Neale Ranns81424992017-05-18 03:03:22 -07003979
3980 /*
3981 * add a second path to an adj-fib
3982 * this is a sumiluation of another ARP entry created
3983 * on an interface on which the connected prefi does not exist.
3984 * The second path fails refinement. Expect to forward through the
3985 * first.
3986 */
3987 fib_prefix_t pfx_10_10_10_3_s_32 = {
3988 .fp_len = 32,
3989 .fp_proto = FIB_PROTOCOL_IP4,
3990 .fp_addr = {
3991 /* 10.10.10.3 */
3992 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a03),
3993 },
3994 };
3995
3996 ai_03 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
3997 VNET_LINK_IP4,
3998 &nh_10_10_10_3,
3999 tm->hw[0]->sw_if_index);
4000
4001 fib_test_lb_bucket_t ip_o_10_10_10_3 = {
4002 .type = FT_LB_ADJ,
4003 .adj = {
4004 .adj = ai_03,
4005 },
4006 };
4007 fei = fib_table_entry_path_add(fib_index,
4008 &pfx_10_10_10_3_s_32,
4009 FIB_SOURCE_ADJ,
4010 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07004011 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07004012 &nh_10_10_10_3,
4013 tm->hw[0]->sw_if_index,
4014 fib_index,
4015 1,
4016 NULL,
4017 FIB_ROUTE_PATH_FLAG_NONE);
4018 fei = fib_table_entry_path_add(fib_index,
4019 &pfx_10_10_10_3_s_32,
4020 FIB_SOURCE_ADJ,
4021 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07004022 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07004023 &nh_12_12_12_12,
4024 tm->hw[1]->sw_if_index,
4025 fib_index,
4026 1,
4027 NULL,
4028 FIB_ROUTE_PATH_FLAG_NONE);
4029 FIB_TEST(fib_test_validate_entry(fei,
4030 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
4031 1,
4032 &ip_o_10_10_10_3),
4033 "10.10.10.3 via 10.10.10.3/Eth0 only");
4034
4035 /*
4036 * remove the path that refines the cover, should go unresolved
4037 */
4038 fib_table_entry_path_remove(fib_index,
4039 &pfx_10_10_10_3_s_32,
4040 FIB_SOURCE_ADJ,
Neale Rannsda78f952017-05-24 09:15:43 -07004041 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07004042 &nh_10_10_10_3,
4043 tm->hw[0]->sw_if_index,
4044 fib_index,
4045 1,
4046 FIB_ROUTE_PATH_FLAG_NONE);
4047 dpo = fib_entry_contribute_ip_forwarding(fei);
4048 FIB_TEST(!dpo_id_is_valid(dpo),
4049 "wrong interface adj-fib fails refinement");
4050
4051 /*
4052 * add back the path that refines the cover
4053 */
4054 fei = fib_table_entry_path_add(fib_index,
4055 &pfx_10_10_10_3_s_32,
4056 FIB_SOURCE_ADJ,
4057 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07004058 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07004059 &nh_10_10_10_3,
4060 tm->hw[0]->sw_if_index,
4061 fib_index,
4062 1,
4063 NULL,
4064 FIB_ROUTE_PATH_FLAG_NONE);
4065 FIB_TEST(fib_test_validate_entry(fei,
4066 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
4067 1,
4068 &ip_o_10_10_10_3),
4069 "10.10.10.3 via 10.10.10.3/Eth0 only");
4070
4071 /*
4072 * remove the path that does not refine the cover
4073 */
4074 fib_table_entry_path_remove(fib_index,
4075 &pfx_10_10_10_3_s_32,
4076 FIB_SOURCE_ADJ,
Neale Rannsda78f952017-05-24 09:15:43 -07004077 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07004078 &nh_12_12_12_12,
4079 tm->hw[1]->sw_if_index,
4080 fib_index,
4081 1,
4082 FIB_ROUTE_PATH_FLAG_NONE);
4083 FIB_TEST(fib_test_validate_entry(fei,
4084 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
4085 1,
4086 &ip_o_10_10_10_3),
4087 "10.10.10.3 via 10.10.10.3/Eth0 only");
4088
4089 /*
4090 * remove the path that does refine, it's the last path, so
4091 * the entry should be gone
4092 */
4093 fib_table_entry_path_remove(fib_index,
4094 &pfx_10_10_10_3_s_32,
4095 FIB_SOURCE_ADJ,
Neale Rannsda78f952017-05-24 09:15:43 -07004096 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07004097 &nh_10_10_10_3,
4098 tm->hw[0]->sw_if_index,
4099 fib_index,
4100 1,
4101 FIB_ROUTE_PATH_FLAG_NONE);
4102 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_3_s_32);
4103 FIB_TEST((fei == FIB_NODE_INDEX_INVALID), "10.10.10.3 gone");
4104
4105 adj_unlock(ai_03);
4106
Neale Ranns227038a2017-04-21 01:07:59 -07004107 /*
4108 * change the table's flow-hash config - expect the update to propagete to
4109 * the entries' load-balance objects
4110 */
4111 flow_hash_config_t old_hash_config, new_hash_config;
4112
4113 old_hash_config = fib_table_get_flow_hash_config(fib_index,
4114 FIB_PROTOCOL_IP4);
4115 new_hash_config = (IP_FLOW_HASH_SRC_ADDR |
4116 IP_FLOW_HASH_DST_ADDR);
4117
4118 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
4119 dpo = fib_entry_contribute_ip_forwarding(fei);
4120 lb = load_balance_get(dpo->dpoi_index);
4121 FIB_TEST((lb->lb_hash_config == old_hash_config),
4122 "Table and LB hash config match: %U",
4123 format_ip_flow_hash_config, lb->lb_hash_config);
4124
4125 fib_table_set_flow_hash_config(fib_index, FIB_PROTOCOL_IP4, new_hash_config);
4126
4127 FIB_TEST((lb->lb_hash_config == new_hash_config),
4128 "Table and LB newhash config match: %U",
4129 format_ip_flow_hash_config, lb->lb_hash_config);
Neale Ranns3983ac22017-03-10 11:53:27 -08004130
4131 /*
Neale Rannsf068c3e2018-01-03 04:18:48 -08004132 * A route via DVR DPO
Neale Ranns6f631152017-10-03 08:20:21 -07004133 */
4134 fei = fib_table_entry_path_add(fib_index,
4135 &pfx_10_10_10_3_s_32,
4136 FIB_SOURCE_API,
4137 FIB_ENTRY_FLAG_NONE,
Neale Rannsf068c3e2018-01-03 04:18:48 -08004138 DPO_PROTO_IP4,
Neale Ranns6f631152017-10-03 08:20:21 -07004139 &zero_addr,
4140 tm->hw[0]->sw_if_index,
4141 ~0,
4142 1,
4143 NULL,
Neale Rannsf068c3e2018-01-03 04:18:48 -08004144 FIB_ROUTE_PATH_DVR);
4145 dpo_id_t dvr_dpo = DPO_INVALID;
4146 dvr_dpo_add_or_lock(tm->hw[0]->sw_if_index, DPO_PROTO_IP4, &dvr_dpo);
Neale Ranns6f631152017-10-03 08:20:21 -07004147 fib_test_lb_bucket_t ip_o_l2 = {
4148 .type = FT_LB_L2,
4149 .adj = {
Neale Rannsf068c3e2018-01-03 04:18:48 -08004150 .adj = dvr_dpo.dpoi_index,
Neale Ranns6f631152017-10-03 08:20:21 -07004151 },
4152 };
4153
4154 FIB_TEST(fib_test_validate_entry(fei,
4155 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
4156 1,
4157 &ip_o_l2),
4158 "10.10.10.3 via L2 on Eth0");
4159 fib_table_entry_path_remove(fib_index,
4160 &pfx_10_10_10_3_s_32,
4161 FIB_SOURCE_API,
Neale Rannsf068c3e2018-01-03 04:18:48 -08004162 DPO_PROTO_IP4,
Neale Ranns6f631152017-10-03 08:20:21 -07004163 &zero_addr,
4164 tm->hw[0]->sw_if_index,
4165 fib_index,
4166 1,
Neale Rannsf068c3e2018-01-03 04:18:48 -08004167 FIB_ROUTE_PATH_DVR);
4168 dpo_reset(&dvr_dpo);
Neale Ranns6f631152017-10-03 08:20:21 -07004169
4170 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004171 * CLEANUP
4172 * remove adj-fibs:
4173 */
4174 fib_table_entry_delete(fib_index,
4175 &pfx_10_10_10_1_s_32,
4176 FIB_SOURCE_ADJ);
4177 fib_table_entry_delete(fib_index,
4178 &pfx_10_10_10_2_s_32,
4179 FIB_SOURCE_ADJ);
4180 FIB_TEST(FIB_NODE_INDEX_INVALID ==
4181 fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32),
4182 "10.10.10.1/32 adj-fib removed");
4183 FIB_TEST(FIB_NODE_INDEX_INVALID ==
4184 fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_2_s_32),
4185 "10.10.10.2/32 adj-fib removed");
4186
4187 /*
4188 * -2 entries and -2 non-shared path-list
4189 */
4190 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
4191 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004192 FIB_TEST((PNBR+2 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004193 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004194 FIB_TEST((ENBR+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004195 fib_entry_pool_size());
4196
4197 /*
Neale Ranns3ee44042016-10-03 13:05:48 +01004198 * unlock the adjacencies for which this test provided a rewrite.
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004199 * These are the last locks on these adjs. they should thus go away.
4200 */
4201 adj_unlock(ai_02);
4202 adj_unlock(ai_01);
Neale Ranns3ee44042016-10-03 13:05:48 +01004203 adj_unlock(ai_12_12_12_12);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004204
4205 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
4206 adj_nbr_db_size());
Neale Ranns3dffb1e2016-11-01 20:38:53 +00004207
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004208 /*
4209 * CLEANUP
4210 * remove the interface prefixes
4211 */
4212 local_pfx.fp_len = 32;
4213 fib_table_entry_special_remove(fib_index, &local_pfx,
4214 FIB_SOURCE_INTERFACE);
4215 fei = fib_table_lookup(fib_index, &local_pfx);
4216
4217 FIB_TEST(FIB_NODE_INDEX_INVALID ==
4218 fib_table_lookup_exact_match(fib_index, &local_pfx),
4219 "10.10.10.10/32 adj-fib removed");
4220
4221 local_pfx.fp_len = 24;
4222 fib_table_entry_delete(fib_index, &local_pfx,
4223 FIB_SOURCE_INTERFACE);
4224
4225 FIB_TEST(FIB_NODE_INDEX_INVALID ==
4226 fib_table_lookup_exact_match(fib_index, &local_pfx),
4227 "10.10.10.10/24 adj-fib removed");
4228
4229 /*
4230 * -2 entries and -2 non-shared path-list
4231 */
Neale Rannsf12a83f2017-04-18 09:09:40 -07004232 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004233 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004234 FIB_TEST((PNBR == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004235 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004236 FIB_TEST((ENBR == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004237 fib_entry_pool_size());
4238
4239 /*
4240 * Last but not least, remove the VRF
4241 */
4242 FIB_TEST((0 == fib_table_get_num_entries(fib_index,
4243 FIB_PROTOCOL_IP4,
4244 FIB_SOURCE_API)),
4245 "NO API Source'd prefixes");
4246 FIB_TEST((0 == fib_table_get_num_entries(fib_index,
4247 FIB_PROTOCOL_IP4,
4248 FIB_SOURCE_RR)),
4249 "NO RR Source'd prefixes");
4250 FIB_TEST((0 == fib_table_get_num_entries(fib_index,
4251 FIB_PROTOCOL_IP4,
4252 FIB_SOURCE_INTERFACE)),
4253 "NO INterface Source'd prefixes");
4254
Neale Ranns15002542017-09-10 04:39:11 -07004255 fib_table_unlock(fib_index, FIB_PROTOCOL_IP4, FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004256
4257 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
4258 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004259 FIB_TEST((PNBR-5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004260 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004261 FIB_TEST((ENBR-5 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004262 fib_entry_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004263 FIB_TEST((ENBR-5 == pool_elts(fib_urpf_list_pool)), "uRPF pool size is %d",
Neale Ranns3ee44042016-10-03 13:05:48 +01004264 pool_elts(fib_urpf_list_pool));
Neale Ranns994dab42017-04-18 12:56:45 -07004265 FIB_TEST((0 == pool_elts(load_balance_map_pool)), "LB-map pool size is %d",
Neale Rannsf12a83f2017-04-18 09:09:40 -07004266 pool_elts(load_balance_map_pool));
Neale Ranns994dab42017-04-18 12:56:45 -07004267 FIB_TEST((lb_count == pool_elts(load_balance_pool)), "LB pool size is %d",
4268 pool_elts(load_balance_pool));
Neale Rannsf068c3e2018-01-03 04:18:48 -08004269 FIB_TEST((0 == pool_elts(dvr_dpo_pool)), "L2 DPO pool size is %d",
4270 pool_elts(dvr_dpo_pool));
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004271
Neale Ranns0ebe8d72016-12-08 19:48:11 +00004272 return 0;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004273}
4274
Neale Ranns0ebe8d72016-12-08 19:48:11 +00004275static int
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004276fib_test_v6 (void)
4277{
4278 /*
4279 * In the default table check for the presence and correct forwarding
4280 * of the special entries
4281 */
4282 fib_node_index_t dfrt, fei, ai, locked_ai, ai_01, ai_02;
4283 const dpo_id_t *dpo, *dpo_drop;
4284 const ip_adjacency_t *adj;
4285 const receive_dpo_t *rd;
4286 test_main_t *tm;
4287 u32 fib_index;
4288 int ii;
4289
4290 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
4291 adj_nbr_db_size());
4292
4293 /* via 2001:0:0:1::2 */
4294 ip46_address_t nh_2001_2 = {
4295 .ip6 = {
4296 .as_u64 = {
4297 [0] = clib_host_to_net_u64(0x2001000000000001),
4298 [1] = clib_host_to_net_u64(0x0000000000000002),
4299 },
4300 },
4301 };
4302
4303 tm = &test_main;
4304
4305 dpo_drop = drop_dpo_get(DPO_PROTO_IP6);
4306
4307 /* Find or create FIB table 11 */
Neale Ranns15002542017-09-10 04:39:11 -07004308 fib_index = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP6, 11,
4309 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004310
4311 for (ii = 0; ii < 4; ii++)
4312 {
4313 ip6_main.fib_index_by_sw_if_index[tm->hw[ii]->sw_if_index] = fib_index;
4314 }
4315
4316 fib_prefix_t pfx_0_0 = {
4317 .fp_len = 0,
4318 .fp_proto = FIB_PROTOCOL_IP6,
4319 .fp_addr = {
4320 .ip6 = {
4321 {0, 0},
4322 },
4323 },
4324 };
4325
4326 dfrt = fib_table_lookup(fib_index, &pfx_0_0);
4327 FIB_TEST((FIB_NODE_INDEX_INVALID != dfrt), "default route present");
4328 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(dfrt)),
4329 "Default route is DROP");
4330
4331 dpo = fib_entry_contribute_ip_forwarding(dfrt);
4332 FIB_TEST((dpo->dpoi_index == ip6_fib_table_fwding_lookup(
4333 &ip6_main,
4334 1,
4335 &pfx_0_0.fp_addr.ip6)),
4336 "default-route; fwd and non-fwd tables match");
4337
4338 // FIXME - check specials.
4339
4340 /*
4341 * At this stage there is one v4 FIB with 5 routes and two v6 FIBs
Neale Ranns32e1c012016-11-22 17:07:28 +00004342 * each with 2 entries and a v6 mfib with 4 path-lists.
4343 * All entries are special so no path-list sharing.
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004344 */
Neale Ranns32e1c012016-11-22 17:07:28 +00004345#define ENPS (5+4)
4346#define PNPS (5+4+4)
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004347 FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00004348 FIB_TEST((PNPS == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004349 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004350 FIB_TEST((ENPS == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004351 fib_entry_pool_size());
4352
4353 /*
4354 * add interface routes.
4355 * validate presence of /64 attached and /128 recieve.
4356 * test for the presence of the receive address in the glean and local adj
4357 *
4358 * receive on 2001:0:0:1::1/128
4359 */
4360 fib_prefix_t local_pfx = {
4361 .fp_len = 64,
4362 .fp_proto = FIB_PROTOCOL_IP6,
4363 .fp_addr = {
4364 .ip6 = {
4365 .as_u64 = {
4366 [0] = clib_host_to_net_u64(0x2001000000000001),
4367 [1] = clib_host_to_net_u64(0x0000000000000001),
4368 },
4369 },
4370 }
4371 };
4372
4373 fib_table_entry_update_one_path(fib_index, &local_pfx,
4374 FIB_SOURCE_INTERFACE,
4375 (FIB_ENTRY_FLAG_CONNECTED |
4376 FIB_ENTRY_FLAG_ATTACHED),
Neale Rannsda78f952017-05-24 09:15:43 -07004377 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004378 NULL,
4379 tm->hw[0]->sw_if_index,
4380 ~0,
4381 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00004382 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004383 FIB_ROUTE_PATH_FLAG_NONE);
4384 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4385
4386 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached interface route present");
4387
4388 ai = fib_entry_get_adj(fei);
4389 FIB_TEST((FIB_NODE_INDEX_INVALID != ai), "attached interface route adj present");
4390 adj = adj_get(ai);
4391 FIB_TEST((IP_LOOKUP_NEXT_GLEAN == adj->lookup_next_index),
4392 "attached interface adj is glean");
4393 FIB_TEST((0 == ip46_address_cmp(&local_pfx.fp_addr,
4394 &adj->sub_type.glean.receive_addr)),
4395 "attached interface adj is receive ok");
4396 dpo = fib_entry_contribute_ip_forwarding(fei);
4397 FIB_TEST((dpo->dpoi_index == ip6_fib_table_fwding_lookup(
4398 &ip6_main,
4399 1,
4400 &local_pfx.fp_addr.ip6)),
4401 "attached-route; fwd and non-fwd tables match");
4402
4403 local_pfx.fp_len = 128;
4404 fib_table_entry_update_one_path(fib_index, &local_pfx,
4405 FIB_SOURCE_INTERFACE,
4406 (FIB_ENTRY_FLAG_CONNECTED |
4407 FIB_ENTRY_FLAG_LOCAL),
Neale Rannsda78f952017-05-24 09:15:43 -07004408 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004409 NULL,
4410 tm->hw[0]->sw_if_index,
4411 ~0, // invalid fib index
4412 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00004413 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004414 FIB_ROUTE_PATH_FLAG_NONE);
4415 fei = fib_table_lookup(fib_index, &local_pfx);
4416
4417 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local interface route present");
4418
4419 dpo = fib_entry_contribute_ip_forwarding(fei);
4420 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
4421 FIB_TEST((DPO_RECEIVE == dpo->dpoi_type),
4422 "local interface adj is local");
4423 rd = receive_dpo_get(dpo->dpoi_index);
4424
4425 FIB_TEST((0 == ip46_address_cmp(&local_pfx.fp_addr,
4426 &rd->rd_addr)),
4427 "local interface adj is receive ok");
4428
4429 dpo = fib_entry_contribute_ip_forwarding(fei);
4430 FIB_TEST((dpo->dpoi_index == ip6_fib_table_fwding_lookup(
4431 &ip6_main,
4432 1,
4433 &local_pfx.fp_addr.ip6)),
4434 "local-route; fwd and non-fwd tables match");
4435
4436 /*
4437 * +2 entries. +2 unshared path-lists
4438 */
4439 FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00004440 FIB_TEST((PNPS+2 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004441 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004442 FIB_TEST((ENPS+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004443 fib_entry_pool_size());
4444
4445 /*
4446 * Modify the default route to be via an adj not yet known.
4447 * this sources the defalut route with the API source, which is
4448 * a higher preference to the DEFAULT_ROUTE source
4449 */
4450 fib_table_entry_path_add(fib_index, &pfx_0_0,
4451 FIB_SOURCE_API,
4452 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07004453 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004454 &nh_2001_2,
4455 tm->hw[0]->sw_if_index,
4456 ~0,
4457 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00004458 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004459 FIB_ROUTE_PATH_FLAG_NONE);
4460 fei = fib_table_lookup(fib_index, &pfx_0_0);
4461
4462 FIB_TEST((fei == dfrt), "default route same index");
4463 ai = fib_entry_get_adj(fei);
4464 FIB_TEST((FIB_NODE_INDEX_INVALID != ai), "default route adj present");
4465 adj = adj_get(ai);
4466 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
4467 "adj is incomplete");
4468 FIB_TEST((0 == ip46_address_cmp(&nh_2001_2, &adj->sub_type.nbr.next_hop)),
4469 "adj nbr next-hop ok");
4470
4471 /*
4472 * find the adj in the shared db
4473 */
4474 locked_ai = adj_nbr_add_or_lock(FIB_PROTOCOL_IP6,
Neale Ranns924d03a2016-10-19 08:25:46 +01004475 VNET_LINK_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004476 &nh_2001_2,
4477 tm->hw[0]->sw_if_index);
4478 FIB_TEST((locked_ai == ai), "ADJ NBR DB find");
4479 adj_unlock(locked_ai);
4480
4481 /*
4482 * no more entires. +1 shared path-list
4483 */
4484 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
4485 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004486 FIB_TEST((PNPS+3 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004487 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004488 FIB_TEST((ENPS+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004489 fib_entry_pool_size());
4490
4491 /*
4492 * remove the API source from the default route. We expected
4493 * the route to remain, sourced by DEFAULT_ROUTE, and hence a DROP
4494 */
4495 fib_table_entry_path_remove(fib_index, &pfx_0_0,
4496 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07004497 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004498 &nh_2001_2,
4499 tm->hw[0]->sw_if_index,
4500 ~0,
4501 1,
4502 FIB_ROUTE_PATH_FLAG_NONE);
4503 fei = fib_table_lookup(fib_index, &pfx_0_0);
4504
4505 FIB_TEST((fei == dfrt), "default route same index");
4506 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(dfrt)),
4507 "Default route is DROP");
4508
4509 /*
4510 * no more entires. -1 shared path-list
4511 */
4512 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
4513 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004514 FIB_TEST((PNPS+2 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004515 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004516 FIB_TEST((ENPS+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004517 fib_entry_pool_size());
4518
4519 /*
4520 * Add an 2 ARP entry => a complete ADJ plus adj-fib.
4521 */
4522 fib_prefix_t pfx_2001_1_2_s_128 = {
4523 .fp_len = 128,
4524 .fp_proto = FIB_PROTOCOL_IP6,
4525 .fp_addr = {
4526 .ip6 = {
4527 .as_u64 = {
4528 [0] = clib_host_to_net_u64(0x2001000000000001),
4529 [1] = clib_host_to_net_u64(0x0000000000000002),
4530 },
4531 },
4532 }
4533 };
4534 fib_prefix_t pfx_2001_1_3_s_128 = {
4535 .fp_len = 128,
4536 .fp_proto = FIB_PROTOCOL_IP6,
4537 .fp_addr = {
4538 .ip6 = {
4539 .as_u64 = {
4540 [0] = clib_host_to_net_u64(0x2001000000000001),
4541 [1] = clib_host_to_net_u64(0x0000000000000003),
4542 },
4543 },
4544 }
4545 };
4546 u8 eth_addr[] = {
4547 0xde, 0xde, 0xde, 0xba, 0xba, 0xba,
4548 };
4549
4550 ai_01 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP6,
Neale Ranns924d03a2016-10-19 08:25:46 +01004551 VNET_LINK_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004552 &pfx_2001_1_2_s_128.fp_addr,
4553 tm->hw[0]->sw_if_index);
4554 FIB_TEST((FIB_NODE_INDEX_INVALID != ai_01), "adj created");
4555 adj = adj_get(ai_01);
4556 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
4557 "adj is incomplete");
4558 FIB_TEST((0 == ip46_address_cmp(&pfx_2001_1_2_s_128.fp_addr,
4559 &adj->sub_type.nbr.next_hop)),
4560 "adj nbr next-hop ok");
4561
Neale Rannsb80c5362016-10-08 13:03:40 +01004562 adj_nbr_update_rewrite(ai_01, ADJ_NBR_REWRITE_FLAG_COMPLETE,
4563 fib_test_build_rewrite(eth_addr));
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004564 FIB_TEST((IP_LOOKUP_NEXT_REWRITE == adj->lookup_next_index),
4565 "adj is complete");
4566 FIB_TEST((0 == ip46_address_cmp(&pfx_2001_1_2_s_128.fp_addr,
4567 &adj->sub_type.nbr.next_hop)),
4568 "adj nbr next-hop ok");
4569
Neale Ranns81424992017-05-18 03:03:22 -07004570 fib_table_entry_path_add(fib_index,
4571 &pfx_2001_1_2_s_128,
4572 FIB_SOURCE_ADJ,
4573 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07004574 DPO_PROTO_IP6,
Neale Ranns81424992017-05-18 03:03:22 -07004575 &pfx_2001_1_2_s_128.fp_addr,
4576 tm->hw[0]->sw_if_index,
4577 ~0,
4578 1,
4579 NULL,
4580 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004581
4582 fei = fib_table_lookup(fib_index, &pfx_2001_1_2_s_128);
4583 ai = fib_entry_get_adj(fei);
4584 FIB_TEST((ai_01 == ai), "ADJ-FIB resolves via adj");
4585
4586 eth_addr[5] = 0xb2;
4587
4588 ai_02 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP6,
Neale Ranns924d03a2016-10-19 08:25:46 +01004589 VNET_LINK_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004590 &pfx_2001_1_3_s_128.fp_addr,
4591 tm->hw[0]->sw_if_index);
4592 FIB_TEST((FIB_NODE_INDEX_INVALID != ai_02), "adj created");
4593 adj = adj_get(ai_02);
4594 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
4595 "adj is incomplete");
4596 FIB_TEST((0 == ip46_address_cmp(&pfx_2001_1_3_s_128.fp_addr,
4597 &adj->sub_type.nbr.next_hop)),
4598 "adj nbr next-hop ok");
4599
Neale Rannsb80c5362016-10-08 13:03:40 +01004600 adj_nbr_update_rewrite(ai_02, ADJ_NBR_REWRITE_FLAG_COMPLETE,
4601 fib_test_build_rewrite(eth_addr));
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004602 FIB_TEST((IP_LOOKUP_NEXT_REWRITE == adj->lookup_next_index),
4603 "adj is complete");
4604 FIB_TEST((0 == ip46_address_cmp(&pfx_2001_1_3_s_128.fp_addr,
4605 &adj->sub_type.nbr.next_hop)),
4606 "adj nbr next-hop ok");
4607 FIB_TEST((ai_01 != ai_02), "ADJs are different");
4608
Neale Ranns81424992017-05-18 03:03:22 -07004609 fib_table_entry_path_add(fib_index,
4610 &pfx_2001_1_3_s_128,
4611 FIB_SOURCE_ADJ,
4612 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07004613 DPO_PROTO_IP6,
Neale Ranns81424992017-05-18 03:03:22 -07004614 &pfx_2001_1_3_s_128.fp_addr,
4615 tm->hw[0]->sw_if_index,
4616 ~0,
4617 1,
4618 NULL,
4619 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004620
4621 fei = fib_table_lookup(fib_index, &pfx_2001_1_3_s_128);
4622 ai = fib_entry_get_adj(fei);
4623 FIB_TEST((ai_02 == ai), "ADJ-FIB resolves via adj");
4624
4625 /*
4626 * +2 entries, +2 unshread path-lists.
4627 */
4628 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
4629 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004630 FIB_TEST((PNPS+4 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004631 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004632 FIB_TEST((ENPS+4 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004633 fib_entry_pool_size());
4634
4635 /*
4636 * Add a 2 routes via the first ADJ. ensure path-list sharing
4637 */
4638 fib_prefix_t pfx_2001_a_s_64 = {
4639 .fp_len = 64,
4640 .fp_proto = FIB_PROTOCOL_IP6,
4641 .fp_addr = {
4642 .ip6 = {
4643 .as_u64 = {
4644 [0] = clib_host_to_net_u64(0x200100000000000a),
4645 [1] = clib_host_to_net_u64(0x0000000000000000),
4646 },
4647 },
4648 }
4649 };
4650 fib_prefix_t pfx_2001_b_s_64 = {
4651 .fp_len = 64,
4652 .fp_proto = FIB_PROTOCOL_IP6,
4653 .fp_addr = {
4654 .ip6 = {
4655 .as_u64 = {
4656 [0] = clib_host_to_net_u64(0x200100000000000b),
4657 [1] = clib_host_to_net_u64(0x0000000000000000),
4658 },
4659 },
4660 }
4661 };
4662
4663 fib_table_entry_path_add(fib_index,
4664 &pfx_2001_a_s_64,
4665 FIB_SOURCE_API,
4666 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07004667 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004668 &nh_2001_2,
4669 tm->hw[0]->sw_if_index,
4670 ~0,
4671 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00004672 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004673 FIB_ROUTE_PATH_FLAG_NONE);
4674 fei = fib_table_lookup(fib_index, &pfx_2001_a_s_64);
4675 ai = fib_entry_get_adj(fei);
4676 FIB_TEST((ai_01 == ai), "2001::a/64 resolves via 2001:0:0:1::1");
4677 fib_table_entry_path_add(fib_index,
4678 &pfx_2001_b_s_64,
4679 FIB_SOURCE_API,
4680 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07004681 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004682 &nh_2001_2,
4683 tm->hw[0]->sw_if_index,
4684 ~0,
4685 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00004686 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004687 FIB_ROUTE_PATH_FLAG_NONE);
4688 fei = fib_table_lookup(fib_index, &pfx_2001_b_s_64);
4689 ai = fib_entry_get_adj(fei);
4690 FIB_TEST((ai_01 == ai), "2001::b/64 resolves via 2001:0:0:1::1");
4691
4692 /*
4693 * +2 entries, +1 shared path-list.
4694 */
4695 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
4696 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004697 FIB_TEST((PNPS+5 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004698 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004699 FIB_TEST((ENPS+6 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004700 fib_entry_pool_size());
4701
4702 /*
4703 * add a v4 prefix via a v6 next-hop
4704 */
4705 fib_prefix_t pfx_1_1_1_1_s_32 = {
4706 .fp_len = 32,
4707 .fp_proto = FIB_PROTOCOL_IP4,
4708 .fp_addr = {
4709 .ip4.as_u32 = 0x01010101,
4710 },
4711 };
4712 fei = fib_table_entry_path_add(0, // default table
4713 &pfx_1_1_1_1_s_32,
4714 FIB_SOURCE_API,
4715 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07004716 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004717 &nh_2001_2,
4718 tm->hw[0]->sw_if_index,
4719 ~0,
4720 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00004721 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004722 FIB_ROUTE_PATH_FLAG_NONE);
4723 FIB_TEST(fei == fib_table_lookup_exact_match(0, &pfx_1_1_1_1_s_32),
4724 "1.1.1.1/32 o v6 route present");
4725 ai = fib_entry_get_adj(fei);
4726 adj = adj_get(ai);
4727 FIB_TEST((adj->lookup_next_index == IP_LOOKUP_NEXT_ARP),
4728 "1.1.1.1/32 via ARP-adj");
Neale Ranns924d03a2016-10-19 08:25:46 +01004729 FIB_TEST((adj->ia_link == VNET_LINK_IP4),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004730 "1.1.1.1/32 ADJ-adj is link type v4");
4731 FIB_TEST((adj->ia_nh_proto == FIB_PROTOCOL_IP6),
4732 "1.1.1.1/32 ADJ-adj is NH proto v6");
4733 fib_table_entry_delete(0, &pfx_1_1_1_1_s_32, FIB_SOURCE_API);
4734
4735 /*
4736 * An attached route
4737 */
4738 fib_prefix_t pfx_2001_c_s_64 = {
4739 .fp_len = 64,
4740 .fp_proto = FIB_PROTOCOL_IP6,
4741 .fp_addr = {
4742 .ip6 = {
4743 .as_u64 = {
4744 [0] = clib_host_to_net_u64(0x200100000000000c),
4745 [1] = clib_host_to_net_u64(0x0000000000000000),
4746 },
4747 },
4748 }
4749 };
4750 fib_table_entry_path_add(fib_index,
4751 &pfx_2001_c_s_64,
4752 FIB_SOURCE_CLI,
4753 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07004754 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004755 NULL,
4756 tm->hw[0]->sw_if_index,
4757 ~0,
4758 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00004759 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004760 FIB_ROUTE_PATH_FLAG_NONE);
4761 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_c_s_64);
4762 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached route present");
4763 ai = fib_entry_get_adj(fei);
4764 adj = adj_get(ai);
4765 FIB_TEST((adj->lookup_next_index == IP_LOOKUP_NEXT_GLEAN),
4766 "2001:0:0:c/64 attached resolves via glean");
4767
4768 fib_table_entry_path_remove(fib_index,
4769 &pfx_2001_c_s_64,
4770 FIB_SOURCE_CLI,
Neale Rannsda78f952017-05-24 09:15:43 -07004771 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004772 NULL,
4773 tm->hw[0]->sw_if_index,
4774 ~0,
4775 1,
4776 FIB_ROUTE_PATH_FLAG_NONE);
4777 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_c_s_64);
4778 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "attached route removed");
4779
4780 /*
4781 * Shutdown the interface on which we have a connected and through
4782 * which the routes are reachable.
4783 * This will result in the connected, adj-fibs, and routes linking to drop
4784 * The local/for-us prefix continues to receive.
4785 */
4786 clib_error_t * error;
4787
4788 error = vnet_sw_interface_set_flags(vnet_get_main(),
4789 tm->hw[0]->sw_if_index,
4790 ~VNET_SW_INTERFACE_FLAG_ADMIN_UP);
4791 FIB_TEST((NULL == error), "Interface shutdown OK");
4792
4793 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
4794 dpo = fib_entry_contribute_ip_forwarding(fei);
4795 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4796 "2001::b/64 resolves via drop");
4797
4798 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
4799 dpo = fib_entry_contribute_ip_forwarding(fei);
4800 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4801 "2001::a/64 resolves via drop");
4802 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
4803 dpo = fib_entry_contribute_ip_forwarding(fei);
4804 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4805 "2001:0:0:1::3/64 resolves via drop");
4806 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
4807 dpo = fib_entry_contribute_ip_forwarding(fei);
4808 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4809 "2001:0:0:1::2/64 resolves via drop");
4810 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4811 dpo = fib_entry_contribute_ip_forwarding(fei);
4812 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4813 "2001:0:0:1::1/128 not drop");
4814 local_pfx.fp_len = 64;
4815 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4816 dpo = fib_entry_contribute_ip_forwarding(fei);
4817 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4818 "2001:0:0:1/64 resolves via drop");
4819
4820 /*
4821 * no change
4822 */
4823 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
4824 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004825 FIB_TEST((PNPS+5 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004826 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004827 FIB_TEST((ENPS+6 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004828 fib_entry_pool_size());
4829
4830 /*
4831 * shutdown one of the other interfaces, then add a connected.
4832 * and swap one of the routes to it.
4833 */
4834 error = vnet_sw_interface_set_flags(vnet_get_main(),
4835 tm->hw[1]->sw_if_index,
4836 ~VNET_SW_INTERFACE_FLAG_ADMIN_UP);
4837 FIB_TEST((NULL == error), "Interface 1 shutdown OK");
4838
4839 fib_prefix_t connected_pfx = {
4840 .fp_len = 64,
4841 .fp_proto = FIB_PROTOCOL_IP6,
4842 .fp_addr = {
4843 .ip6 = {
4844 /* 2001:0:0:2::1/64 */
4845 .as_u64 = {
4846 [0] = clib_host_to_net_u64(0x2001000000000002),
4847 [1] = clib_host_to_net_u64(0x0000000000000001),
4848 },
4849 },
4850 }
4851 };
4852 fib_table_entry_update_one_path(fib_index, &connected_pfx,
4853 FIB_SOURCE_INTERFACE,
4854 (FIB_ENTRY_FLAG_CONNECTED |
4855 FIB_ENTRY_FLAG_ATTACHED),
Neale Rannsda78f952017-05-24 09:15:43 -07004856 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004857 NULL,
4858 tm->hw[1]->sw_if_index,
4859 ~0,
4860 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00004861 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004862 FIB_ROUTE_PATH_FLAG_NONE);
4863 fei = fib_table_lookup_exact_match(fib_index, &connected_pfx);
4864 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached interface route present");
4865 dpo = fib_entry_contribute_ip_forwarding(fei);
4866 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
4867 FIB_TEST(!dpo_cmp(dpo, dpo_drop),
4868 "2001:0:0:2/64 not resolves via drop");
4869
4870 connected_pfx.fp_len = 128;
4871 fib_table_entry_update_one_path(fib_index, &connected_pfx,
4872 FIB_SOURCE_INTERFACE,
4873 (FIB_ENTRY_FLAG_CONNECTED |
4874 FIB_ENTRY_FLAG_LOCAL),
Neale Rannsda78f952017-05-24 09:15:43 -07004875 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004876 NULL,
4877 tm->hw[0]->sw_if_index,
4878 ~0, // invalid fib index
4879 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00004880 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004881 FIB_ROUTE_PATH_FLAG_NONE);
4882 fei = fib_table_lookup(fib_index, &connected_pfx);
4883
4884 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local interface route present");
4885 dpo = fib_entry_contribute_ip_forwarding(fei);
4886 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
4887 FIB_TEST((DPO_RECEIVE == dpo->dpoi_type),
4888 "local interface adj is local");
4889 rd = receive_dpo_get(dpo->dpoi_index);
4890 FIB_TEST((0 == ip46_address_cmp(&connected_pfx.fp_addr,
4891 &rd->rd_addr)),
4892 "local interface adj is receive ok");
4893
4894 /*
4895 * +2 entries, +2 unshared path-lists
4896 */
4897 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
4898 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004899 FIB_TEST((PNPS+7 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004900 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004901 FIB_TEST((ENPS+8 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004902 fib_entry_pool_size());
4903
4904
4905 /*
4906 * bring the interface back up. we expected the routes to return
4907 * to normal forwarding.
4908 */
4909 error = vnet_sw_interface_set_flags(vnet_get_main(),
4910 tm->hw[0]->sw_if_index,
4911 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
4912 FIB_TEST((NULL == error), "Interface bring-up OK");
4913 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
4914 ai = fib_entry_get_adj(fei);
4915 FIB_TEST((ai_01 == ai), "2001::a/64 resolves via 2001:0:0:1::1");
4916 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
4917 ai = fib_entry_get_adj(fei);
4918 FIB_TEST((ai_01 == ai), "2001::b/64 resolves via 2001:0:0:1::1");
4919 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
4920 ai = fib_entry_get_adj(fei);
4921 FIB_TEST((ai_02 == ai), "ADJ-FIB resolves via adj");
4922 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
4923 ai = fib_entry_get_adj(fei);
4924 FIB_TEST((ai_01 == ai), "ADJ-FIB resolves via adj");
4925 local_pfx.fp_len = 64;
4926 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4927 ai = fib_entry_get_adj(fei);
4928 adj = adj_get(ai);
4929 FIB_TEST((IP_LOOKUP_NEXT_GLEAN == adj->lookup_next_index),
4930 "attached interface adj is glean");
4931
4932 /*
Neale Ranns8b37b872016-11-21 12:25:22 +00004933 * Same test as above, but this time the HW interface goes down
4934 */
4935 error = vnet_hw_interface_set_flags(vnet_get_main(),
4936 tm->hw_if_indicies[0],
4937 ~VNET_HW_INTERFACE_FLAG_LINK_UP);
4938 FIB_TEST((NULL == error), "Interface shutdown OK");
4939
4940 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
4941 dpo = fib_entry_contribute_ip_forwarding(fei);
4942 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4943 "2001::b/64 resolves via drop");
4944 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
4945 dpo = fib_entry_contribute_ip_forwarding(fei);
4946 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4947 "2001::a/64 resolves via drop");
4948 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
4949 dpo = fib_entry_contribute_ip_forwarding(fei);
4950 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4951 "2001:0:0:1::3/128 resolves via drop");
4952 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
4953 dpo = fib_entry_contribute_ip_forwarding(fei);
4954 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4955 "2001:0:0:1::2/128 resolves via drop");
4956 local_pfx.fp_len = 128;
4957 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4958 dpo = fib_entry_contribute_ip_forwarding(fei);
4959 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4960 "2001:0:0:1::1/128 not drop");
4961 local_pfx.fp_len = 64;
4962 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4963 dpo = fib_entry_contribute_ip_forwarding(fei);
4964 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4965 "2001:0:0:1/64 resolves via drop");
4966
4967 error = vnet_hw_interface_set_flags(vnet_get_main(),
4968 tm->hw_if_indicies[0],
4969 VNET_HW_INTERFACE_FLAG_LINK_UP);
4970 FIB_TEST((NULL == error), "Interface bring-up OK");
4971 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
4972 ai = fib_entry_get_adj(fei);
4973 FIB_TEST((ai_01 == ai), "2001::a/64 resolves via 2001:0:0:1::1");
4974 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
4975 ai = fib_entry_get_adj(fei);
4976 FIB_TEST((ai_01 == ai), "2001::b/64 resolves via 2001:0:0:1::1");
4977 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
4978 ai = fib_entry_get_adj(fei);
4979 FIB_TEST((ai_02 == ai), "ADJ-FIB resolves via adj");
4980 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
4981 ai = fib_entry_get_adj(fei);
4982 FIB_TEST((ai_01 == ai), "ADJ-FIB resolves via adj");
4983 local_pfx.fp_len = 64;
4984 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4985 ai = fib_entry_get_adj(fei);
4986 adj = adj_get(ai);
4987 FIB_TEST((IP_LOOKUP_NEXT_GLEAN == adj->lookup_next_index),
4988 "attached interface adj is glean");
4989
4990 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004991 * Delete the interface that the routes reolve through.
4992 * Again no routes are removed. They all point to drop.
4993 *
4994 * This is considered an error case. The control plane should
4995 * not remove interfaces through which routes resolve, but
4996 * such things can happen. ALL affected routes will drop.
4997 */
4998 vnet_delete_hw_interface(vnet_get_main(), tm->hw_if_indicies[0]);
4999
5000 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
5001 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5002 "2001::b/64 resolves via drop");
5003 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
5004 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5005 "2001::b/64 resolves via drop");
5006 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
5007 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5008 "2001:0:0:1::3/64 resolves via drop");
5009 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
5010 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5011 "2001:0:0:1::2/64 resolves via drop");
5012 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5013 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5014 "2001:0:0:1::1/128 is drop");
5015 local_pfx.fp_len = 64;
5016 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5017 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5018 "2001:0:0:1/64 resolves via drop");
5019
5020 /*
5021 * no change
5022 */
5023 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
5024 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00005025 FIB_TEST((PNPS+7 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005026 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00005027 FIB_TEST((ENPS+8 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005028 fib_entry_pool_size());
5029
5030 /*
5031 * Add the interface back. routes stay unresolved.
5032 */
5033 error = ethernet_register_interface(vnet_get_main(),
5034 test_interface_device_class.index,
5035 0 /* instance */,
5036 hw_address,
5037 &tm->hw_if_indicies[0],
5038 /* flag change */ 0);
5039
5040 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
5041 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5042 "2001::b/64 resolves via drop");
5043 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
5044 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5045 "2001::b/64 resolves via drop");
5046 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
5047 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5048 "2001:0:0:1::3/64 resolves via drop");
5049 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
5050 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5051 "2001:0:0:1::2/64 resolves via drop");
5052 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5053 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5054 "2001:0:0:1::1/128 is drop");
5055 local_pfx.fp_len = 64;
5056 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5057 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5058 "2001:0:0:1/64 resolves via drop");
5059
5060 /*
5061 * CLEANUP ALL the routes
5062 */
5063 fib_table_entry_delete(fib_index,
5064 &pfx_2001_c_s_64,
5065 FIB_SOURCE_API);
5066 fib_table_entry_delete(fib_index,
5067 &pfx_2001_a_s_64,
5068 FIB_SOURCE_API);
5069 fib_table_entry_delete(fib_index,
5070 &pfx_2001_b_s_64,
5071 FIB_SOURCE_API);
5072 fib_table_entry_delete(fib_index,
5073 &pfx_2001_1_3_s_128,
5074 FIB_SOURCE_ADJ);
5075 fib_table_entry_delete(fib_index,
5076 &pfx_2001_1_2_s_128,
5077 FIB_SOURCE_ADJ);
5078 local_pfx.fp_len = 64;
5079 fib_table_entry_delete(fib_index, &local_pfx,
5080 FIB_SOURCE_INTERFACE);
5081 local_pfx.fp_len = 128;
5082 fib_table_entry_special_remove(fib_index, &local_pfx,
5083 FIB_SOURCE_INTERFACE);
5084 connected_pfx.fp_len = 64;
5085 fib_table_entry_delete(fib_index, &connected_pfx,
5086 FIB_SOURCE_INTERFACE);
5087 connected_pfx.fp_len = 128;
5088 fib_table_entry_special_remove(fib_index, &connected_pfx,
5089 FIB_SOURCE_INTERFACE);
5090
5091 FIB_TEST((FIB_NODE_INDEX_INVALID ==
5092 fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64)),
5093 "2001::a/64 removed");
5094 FIB_TEST((FIB_NODE_INDEX_INVALID ==
5095 fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64)),
5096 "2001::b/64 removed");
5097 FIB_TEST((FIB_NODE_INDEX_INVALID ==
5098 fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128)),
5099 "2001:0:0:1::3/128 removed");
5100 FIB_TEST((FIB_NODE_INDEX_INVALID ==
5101 fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128)),
5102 "2001:0:0:1::3/128 removed");
5103 local_pfx.fp_len = 64;
5104 FIB_TEST((FIB_NODE_INDEX_INVALID ==
5105 fib_table_lookup_exact_match(fib_index, &local_pfx)),
5106 "2001:0:0:1/64 removed");
5107 local_pfx.fp_len = 128;
5108 FIB_TEST((FIB_NODE_INDEX_INVALID ==
5109 fib_table_lookup_exact_match(fib_index, &local_pfx)),
5110 "2001:0:0:1::1/128 removed");
5111 connected_pfx.fp_len = 64;
5112 FIB_TEST((FIB_NODE_INDEX_INVALID ==
5113 fib_table_lookup_exact_match(fib_index, &connected_pfx)),
5114 "2001:0:0:2/64 removed");
5115 connected_pfx.fp_len = 128;
5116 FIB_TEST((FIB_NODE_INDEX_INVALID ==
5117 fib_table_lookup_exact_match(fib_index, &connected_pfx)),
5118 "2001:0:0:2::1/128 removed");
5119
5120 /*
5121 * -8 entries. -7 path-lists (1 was shared).
5122 */
5123 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
5124 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00005125 FIB_TEST((PNPS == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005126 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00005127 FIB_TEST((ENPS == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005128 fib_entry_pool_size());
5129
5130 /*
5131 * now remove the VRF
5132 */
Neale Ranns15002542017-09-10 04:39:11 -07005133 fib_table_unlock(fib_index, FIB_PROTOCOL_IP6, FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005134
5135 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
5136 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00005137 FIB_TEST((PNPS-2 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005138 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00005139 FIB_TEST((ENPS-2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005140 fib_entry_pool_size());
5141
5142 adj_unlock(ai_02);
5143 adj_unlock(ai_01);
5144
5145 /*
5146 * return the interfaces to up state
5147 */
5148 error = vnet_sw_interface_set_flags(vnet_get_main(),
5149 tm->hw[0]->sw_if_index,
5150 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
5151 error = vnet_sw_interface_set_flags(vnet_get_main(),
5152 tm->hw[1]->sw_if_index,
5153 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
5154
5155 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
5156 adj_nbr_db_size());
Neale Ranns0ebe8d72016-12-08 19:48:11 +00005157
5158 return (0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005159}
5160
5161/*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005162 * Test Attached Exports
5163 */
Neale Ranns0ebe8d72016-12-08 19:48:11 +00005164static int
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005165fib_test_ae (void)
5166{
5167 const dpo_id_t *dpo, *dpo_drop;
5168 const u32 fib_index = 0;
5169 fib_node_index_t fei;
5170 test_main_t *tm;
5171 ip4_main_t *im;
5172
5173 tm = &test_main;
5174 im = &ip4_main;
5175
5176 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
5177 adj_nbr_db_size());
5178
5179 /*
5180 * add interface routes. We'll assume this works. It's more rigorously
5181 * tested elsewhere.
5182 */
5183 fib_prefix_t local_pfx = {
5184 .fp_len = 24,
5185 .fp_proto = FIB_PROTOCOL_IP4,
5186 .fp_addr = {
5187 .ip4 = {
5188 /* 10.10.10.10 */
5189 .as_u32 = clib_host_to_net_u32(0x0a0a0a0a),
5190 },
5191 },
5192 };
5193
5194 vec_validate(im->fib_index_by_sw_if_index, tm->hw[0]->sw_if_index);
5195 im->fib_index_by_sw_if_index[tm->hw[0]->sw_if_index] = fib_index;
5196
5197 dpo_drop = drop_dpo_get(DPO_PROTO_IP4);
5198
5199 fib_table_entry_update_one_path(fib_index, &local_pfx,
5200 FIB_SOURCE_INTERFACE,
5201 (FIB_ENTRY_FLAG_CONNECTED |
5202 FIB_ENTRY_FLAG_ATTACHED),
Neale Rannsda78f952017-05-24 09:15:43 -07005203 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005204 NULL,
5205 tm->hw[0]->sw_if_index,
5206 ~0,
5207 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005208 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005209 FIB_ROUTE_PATH_FLAG_NONE);
5210 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5211 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
5212 "attached interface route present");
5213
5214 local_pfx.fp_len = 32;
5215 fib_table_entry_update_one_path(fib_index, &local_pfx,
5216 FIB_SOURCE_INTERFACE,
5217 (FIB_ENTRY_FLAG_CONNECTED |
5218 FIB_ENTRY_FLAG_LOCAL),
Neale Rannsda78f952017-05-24 09:15:43 -07005219 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005220 NULL,
5221 tm->hw[0]->sw_if_index,
5222 ~0, // invalid fib index
5223 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005224 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005225 FIB_ROUTE_PATH_FLAG_NONE);
5226 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5227
5228 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
5229 "local interface route present");
5230
5231 /*
5232 * Add an 2 ARP entry => a complete ADJ plus adj-fib.
5233 */
5234 fib_prefix_t pfx_10_10_10_1_s_32 = {
5235 .fp_len = 32,
5236 .fp_proto = FIB_PROTOCOL_IP4,
5237 .fp_addr = {
5238 /* 10.10.10.1 */
5239 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
5240 },
5241 };
5242 fib_node_index_t ai;
5243
Neale Ranns81424992017-05-18 03:03:22 -07005244 fib_table_entry_path_add(fib_index,
5245 &pfx_10_10_10_1_s_32,
5246 FIB_SOURCE_ADJ,
5247 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07005248 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07005249 &pfx_10_10_10_1_s_32.fp_addr,
5250 tm->hw[0]->sw_if_index,
5251 ~0, // invalid fib index
5252 1,
5253 NULL,
5254 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005255
5256 fei = fib_table_lookup(fib_index, &pfx_10_10_10_1_s_32);
5257 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 created");
5258 ai = fib_entry_get_adj(fei);
5259
5260 /*
5261 * create another FIB table into which routes will be imported
5262 */
5263 u32 import_fib_index1;
5264
Neale Ranns15002542017-09-10 04:39:11 -07005265 import_fib_index1 = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP4,
5266 11,
5267 FIB_SOURCE_CLI);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005268
5269 /*
5270 * Add an attached route in the import FIB
5271 */
5272 local_pfx.fp_len = 24;
5273 fib_table_entry_update_one_path(import_fib_index1,
5274 &local_pfx,
5275 FIB_SOURCE_API,
5276 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07005277 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005278 NULL,
5279 tm->hw[0]->sw_if_index,
5280 ~0, // invalid fib index
5281 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005282 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005283 FIB_ROUTE_PATH_FLAG_NONE);
5284 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5285 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached export created");
5286
5287 /*
5288 * check for the presence of the adj-fibs in the import table
5289 */
5290 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5291 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 imported");
5292 FIB_TEST((ai == fib_entry_get_adj(fei)),
5293 "adj-fib1 Import uses same adj as export");
5294
5295 /*
5296 * check for the presence of the local in the import table
5297 */
5298 local_pfx.fp_len = 32;
5299 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5300 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local imported");
5301
5302 /*
5303 * Add another adj-fin in the export table. Expect this
5304 * to get magically exported;
5305 */
5306 fib_prefix_t pfx_10_10_10_2_s_32 = {
5307 .fp_len = 32,
5308 .fp_proto = FIB_PROTOCOL_IP4,
5309 .fp_addr = {
5310 /* 10.10.10.2 */
5311 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02),
5312 },
5313 };
5314
Neale Ranns81424992017-05-18 03:03:22 -07005315 fib_table_entry_path_add(fib_index,
5316 &pfx_10_10_10_2_s_32,
5317 FIB_SOURCE_ADJ,
5318 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07005319 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07005320 &pfx_10_10_10_2_s_32.fp_addr,
5321 tm->hw[0]->sw_if_index,
5322 ~0, // invalid fib index
5323 1,
5324 NULL,
5325 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005326 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_2_s_32);
5327 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 present");
5328 ai = fib_entry_get_adj(fei);
5329
5330 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5331 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 imported");
5332 FIB_TEST((ai == fib_entry_get_adj(fei)),
5333 "Import uses same adj as export");
Neale Rannsfa0fb582016-12-10 21:59:14 +00005334 FIB_TEST((FIB_ENTRY_FLAG_ATTACHED & fib_entry_get_flags(fei)),
5335 "ADJ-fib2 imported flags %d",
5336 fib_entry_get_flags(fei));
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005337
5338 /*
5339 * create a 2nd FIB table into which routes will be imported
5340 */
5341 u32 import_fib_index2;
5342
Neale Ranns15002542017-09-10 04:39:11 -07005343 import_fib_index2 = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP4, 12,
5344 FIB_SOURCE_CLI);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005345
5346 /*
5347 * Add an attached route in the import FIB
5348 */
5349 local_pfx.fp_len = 24;
5350 fib_table_entry_update_one_path(import_fib_index2,
5351 &local_pfx,
5352 FIB_SOURCE_API,
5353 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07005354 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005355 NULL,
5356 tm->hw[0]->sw_if_index,
5357 ~0, // invalid fib index
5358 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005359 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005360 FIB_ROUTE_PATH_FLAG_NONE);
5361 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5362 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached export created");
5363
5364 /*
5365 * check for the presence of all the adj-fibs and local in the import table
5366 */
5367 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_1_s_32);
5368 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 imported");
5369 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_2_s_32);
5370 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 imported");
5371 local_pfx.fp_len = 32;
5372 fei = fib_table_lookup_exact_match(import_fib_index2, &local_pfx);
5373 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local imported");
5374
5375 /*
5376 * add a 3rd adj-fib. expect it to be exported to both tables.
5377 */
5378 fib_prefix_t pfx_10_10_10_3_s_32 = {
5379 .fp_len = 32,
5380 .fp_proto = FIB_PROTOCOL_IP4,
5381 .fp_addr = {
5382 /* 10.10.10.3 */
5383 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a03),
5384 },
5385 };
5386
Neale Ranns81424992017-05-18 03:03:22 -07005387 fib_table_entry_path_add(fib_index,
5388 &pfx_10_10_10_3_s_32,
5389 FIB_SOURCE_ADJ,
5390 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07005391 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07005392 &pfx_10_10_10_3_s_32.fp_addr,
5393 tm->hw[0]->sw_if_index,
5394 ~0, // invalid fib index
5395 1,
5396 NULL,
5397 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005398 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_3_s_32);
5399 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib3 present");
5400 ai = fib_entry_get_adj(fei);
5401
5402 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_3_s_32);
5403 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib3 imported to FIB1");
5404 FIB_TEST((ai == fib_entry_get_adj(fei)),
5405 "Import uses same adj as export");
5406 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_3_s_32);
5407 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib3 imported to FIB2");
5408 FIB_TEST((ai == fib_entry_get_adj(fei)),
5409 "Import uses same adj as export");
5410
5411 /*
5412 * remove the 3rd adj fib. we expect it to be removed from both FIBs
5413 */
5414 fib_table_entry_delete(fib_index,
5415 &pfx_10_10_10_3_s_32,
5416 FIB_SOURCE_ADJ);
5417
5418 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_3_s_32);
5419 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib3 remved");
5420
5421 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_3_s_32);
5422 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib3 removed from FIB1");
5423
5424 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_3_s_32);
5425 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib3 removed from FIB2");
5426
5427 /*
5428 * remove the attached route from the 2nd FIB. expect the imported
5429 * entires to be removed
5430 */
5431 local_pfx.fp_len = 24;
5432 fib_table_entry_delete(import_fib_index2,
5433 &local_pfx,
5434 FIB_SOURCE_API);
5435 fei = fib_table_lookup_exact_match(import_fib_index2, &local_pfx);
5436 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "attached export removed");
5437
5438 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_1_s_32);
5439 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib1 removed from FIB2");
5440 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_2_s_32);
5441 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib2 removed from FIB2");
5442 local_pfx.fp_len = 32;
5443 fei = fib_table_lookup_exact_match(import_fib_index2, &local_pfx);
5444 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "local removed from FIB2");
5445
5446 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5447 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 still in FIB1");
5448 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5449 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 still in FIB1");
5450 local_pfx.fp_len = 32;
5451 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5452 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local still in FIB1");
5453
5454 /*
5455 * modify the route in FIB1 so it is no longer attached. expect the imported
5456 * entires to be removed
5457 */
5458 local_pfx.fp_len = 24;
5459 fib_table_entry_update_one_path(import_fib_index1,
5460 &local_pfx,
5461 FIB_SOURCE_API,
5462 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07005463 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005464 &pfx_10_10_10_2_s_32.fp_addr,
5465 tm->hw[0]->sw_if_index,
5466 ~0, // invalid fib index
5467 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005468 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005469 FIB_ROUTE_PATH_FLAG_NONE);
5470 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5471 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib1 removed from FIB1");
5472 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5473 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib2 removed from FIB1");
5474 local_pfx.fp_len = 32;
5475 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5476 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "local removed from FIB1");
5477
5478 /*
5479 * modify it back to attached. expect the adj-fibs back
5480 */
5481 local_pfx.fp_len = 24;
5482 fib_table_entry_update_one_path(import_fib_index1,
5483 &local_pfx,
5484 FIB_SOURCE_API,
5485 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07005486 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005487 NULL,
5488 tm->hw[0]->sw_if_index,
5489 ~0, // invalid fib index
5490 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005491 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005492 FIB_ROUTE_PATH_FLAG_NONE);
5493 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5494 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 imported in FIB1");
5495 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5496 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 imported in FIB1");
5497 local_pfx.fp_len = 32;
5498 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5499 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local imported in FIB1");
5500
5501 /*
5502 * add a covering attached next-hop for the interface address, so we have
5503 * a valid adj to find when we check the forwarding tables
5504 */
5505 fib_prefix_t pfx_10_0_0_0_s_8 = {
5506 .fp_len = 8,
5507 .fp_proto = FIB_PROTOCOL_IP4,
5508 .fp_addr = {
5509 /* 10.0.0.0 */
5510 .ip4.as_u32 = clib_host_to_net_u32(0x0a000000),
5511 },
5512 };
5513
5514 fei = fib_table_entry_update_one_path(fib_index,
5515 &pfx_10_0_0_0_s_8,
5516 FIB_SOURCE_API,
5517 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07005518 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005519 &pfx_10_10_10_3_s_32.fp_addr,
5520 tm->hw[0]->sw_if_index,
5521 ~0, // invalid fib index
5522 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005523 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005524 FIB_ROUTE_PATH_FLAG_NONE);
5525 dpo = fib_entry_contribute_ip_forwarding(fei);
5526
5527 /*
5528 * remove the route in the export fib. expect the adj-fibs to be removed
5529 */
5530 local_pfx.fp_len = 24;
5531 fib_table_entry_delete(fib_index,
5532 &local_pfx,
5533 FIB_SOURCE_INTERFACE);
5534
5535 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5536 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "Delete export: ADJ-fib1 removed from FIB1");
5537 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5538 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib2 removed from FIB1");
5539 local_pfx.fp_len = 32;
5540 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5541 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "local removed from FIB1");
5542
5543 /*
5544 * the adj-fibs in the export VRF are present in the FIB table,
5545 * but not installed in forwarding, since they have no attached cover.
5546 * Consequently a lookup in the MTRIE gives the adj for the covering
5547 * route 10.0.0.0/8.
5548 */
5549 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
5550 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 in export");
5551
5552 index_t lbi;
5553 lbi = ip4_fib_forwarding_lookup(fib_index, &pfx_10_10_10_1_s_32.fp_addr.ip4);
5554 FIB_TEST(lbi == dpo->dpoi_index,
5555 "10.10.10.1 forwards on \n%U not \n%U",
5556 format_load_balance, lbi, 0,
5557 format_dpo_id, dpo, 0);
5558 lbi = ip4_fib_forwarding_lookup(fib_index, &pfx_10_10_10_2_s_32.fp_addr.ip4);
5559 FIB_TEST(lbi == dpo->dpoi_index,
5560 "10.10.10.2 forwards on %U", format_dpo_id, dpo, 0);
5561 lbi = ip4_fib_forwarding_lookup(fib_index, &pfx_10_10_10_3_s_32.fp_addr.ip4);
5562 FIB_TEST(lbi == dpo->dpoi_index,
5563 "10.10.10.3 forwards on %U", format_dpo_id, dpo, 0);
5564
5565 /*
5566 * add the export prefix back, but not as attached.
5567 * No adj-fibs in export nor import tables
5568 */
5569 local_pfx.fp_len = 24;
5570 fei = fib_table_entry_update_one_path(fib_index,
5571 &local_pfx,
5572 FIB_SOURCE_API,
5573 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07005574 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005575 &pfx_10_10_10_1_s_32.fp_addr,
5576 tm->hw[0]->sw_if_index,
5577 ~0, // invalid fib index
5578 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005579 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005580 FIB_ROUTE_PATH_FLAG_NONE);
5581 dpo = fib_entry_contribute_ip_forwarding(fei);
5582
5583 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
5584 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "non-attached in export: ADJ-fib1 in export");
5585 lbi = ip4_fib_forwarding_lookup(fib_index, &pfx_10_10_10_1_s_32.fp_addr.ip4);
5586 FIB_TEST(lbi == dpo->dpoi_index,
5587 "10.10.10.1 forwards on %U", format_dpo_id, dpo, 0);
5588 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
5589 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 in export");
5590 lbi = ip4_fib_forwarding_lookup(fib_index, &pfx_10_10_10_2_s_32.fp_addr.ip4);
5591 FIB_TEST(lbi == dpo->dpoi_index,
5592 "10.10.10.2 forwards on %U", format_dpo_id, dpo, 0);
5593
5594 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5595 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib1 removed from FIB1");
5596 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5597 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib2 removed from FIB1");
5598 local_pfx.fp_len = 32;
5599 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5600 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "local removed from FIB1");
5601
5602 /*
5603 * modify the export prefix so it is attached. expect all covereds to return
5604 */
5605 local_pfx.fp_len = 24;
5606 fib_table_entry_update_one_path(fib_index,
5607 &local_pfx,
5608 FIB_SOURCE_API,
5609 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07005610 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005611 NULL,
5612 tm->hw[0]->sw_if_index,
5613 ~0, // invalid fib index
5614 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005615 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005616 FIB_ROUTE_PATH_FLAG_NONE);
5617
5618 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
5619 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 reinstalled in export");
5620 dpo = fib_entry_contribute_ip_forwarding(fei);
5621 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
5622 "Adj-fib1 is not drop in export");
5623 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_2_s_32);
5624 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 reinstalled in export");
5625 local_pfx.fp_len = 32;
5626 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5627 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local reinstalled in export");
5628 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5629 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached in export: ADJ-fib1 imported");
5630 dpo = fib_entry_contribute_ip_forwarding(fei);
5631 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
5632 "Adj-fib1 is not drop in export");
5633 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5634 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 imported");
5635 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5636 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 imported");
5637 local_pfx.fp_len = 32;
5638 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5639 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local imported");
5640
5641 /*
5642 * modify the export prefix so connected. no change.
5643 */
5644 local_pfx.fp_len = 24;
5645 fib_table_entry_update_one_path(fib_index, &local_pfx,
5646 FIB_SOURCE_INTERFACE,
5647 (FIB_ENTRY_FLAG_CONNECTED |
5648 FIB_ENTRY_FLAG_ATTACHED),
Neale Rannsda78f952017-05-24 09:15:43 -07005649 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005650 NULL,
5651 tm->hw[0]->sw_if_index,
5652 ~0,
5653 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005654 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005655 FIB_ROUTE_PATH_FLAG_NONE);
5656
5657 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
5658 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 reinstalled in export");
5659 dpo = fib_entry_contribute_ip_forwarding(fei);
5660 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
5661 "Adj-fib1 is not drop in export");
5662 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_2_s_32);
5663 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 reinstalled in export");
5664 local_pfx.fp_len = 32;
5665 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5666 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local reinstalled in export");
5667 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5668 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached in export: ADJ-fib1 imported");
5669 dpo = fib_entry_contribute_ip_forwarding(fei);
5670 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
5671 "Adj-fib1 is not drop in export");
5672 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5673 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 imported");
5674 local_pfx.fp_len = 32;
5675 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5676 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local imported");
5677
5678 /*
5679 * CLEANUP
5680 */
5681 fib_table_entry_delete(fib_index,
5682 &pfx_10_0_0_0_s_8,
5683 FIB_SOURCE_API);
5684 fib_table_entry_delete(fib_index,
5685 &pfx_10_10_10_1_s_32,
5686 FIB_SOURCE_ADJ);
5687 fib_table_entry_delete(fib_index,
5688 &pfx_10_10_10_2_s_32,
5689 FIB_SOURCE_ADJ);
5690 local_pfx.fp_len = 32;
5691 fib_table_entry_delete(fib_index,
5692 &local_pfx,
5693 FIB_SOURCE_INTERFACE);
5694 local_pfx.fp_len = 24;
5695 fib_table_entry_delete(fib_index,
5696 &local_pfx,
5697 FIB_SOURCE_API);
5698 fib_table_entry_delete(fib_index,
5699 &local_pfx,
5700 FIB_SOURCE_INTERFACE);
5701 local_pfx.fp_len = 24;
5702 fib_table_entry_delete(import_fib_index1,
5703 &local_pfx,
5704 FIB_SOURCE_API);
5705
Neale Ranns15002542017-09-10 04:39:11 -07005706 fib_table_unlock(import_fib_index1, FIB_PROTOCOL_IP4, FIB_SOURCE_CLI);
5707 fib_table_unlock(import_fib_index2, FIB_PROTOCOL_IP4, FIB_SOURCE_CLI);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005708
5709 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
5710 adj_nbr_db_size());
Neale Ranns0ebe8d72016-12-08 19:48:11 +00005711
5712 return (0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005713}
5714
Neale Ranns57b58602017-07-15 07:37:25 -07005715/*
5716 * Test Path Preference
5717 */
5718static int
5719fib_test_pref (void)
5720{
5721 test_main_t *tm = &test_main;
5722
5723 const fib_prefix_t pfx_1_1_1_1_s_32 = {
5724 .fp_len = 32,
5725 .fp_proto = FIB_PROTOCOL_IP4,
5726 .fp_addr = {
5727 .ip4 = {
5728 .as_u32 = clib_host_to_net_u32(0x01010101),
5729 },
5730 },
5731 };
5732
5733 /*
5734 * 2 high, 2 medium and 2 low preference non-recursive paths
5735 */
5736 fib_route_path_t nr_path_hi_1 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005737 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005738 .frp_sw_if_index = tm->hw[0]->sw_if_index,
5739 .frp_fib_index = ~0,
5740 .frp_weight = 1,
5741 .frp_preference = 0,
5742 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5743 .frp_addr = {
5744 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
5745 },
5746 };
5747 fib_route_path_t nr_path_hi_2 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005748 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005749 .frp_sw_if_index = tm->hw[0]->sw_if_index,
5750 .frp_fib_index = ~0,
5751 .frp_weight = 1,
5752 .frp_preference = 0,
5753 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5754 .frp_addr = {
5755 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02),
5756 },
5757 };
5758 fib_route_path_t nr_path_med_1 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005759 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005760 .frp_sw_if_index = tm->hw[1]->sw_if_index,
5761 .frp_fib_index = ~0,
5762 .frp_weight = 1,
5763 .frp_preference = 1,
5764 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5765 .frp_addr = {
5766 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0c01),
5767 },
5768 };
5769 fib_route_path_t nr_path_med_2 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005770 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005771 .frp_sw_if_index = tm->hw[1]->sw_if_index,
5772 .frp_fib_index = ~0,
5773 .frp_weight = 1,
5774 .frp_preference = 1,
5775 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5776 .frp_addr = {
5777 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0c01),
5778 },
5779 };
5780 fib_route_path_t nr_path_low_1 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005781 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005782 .frp_sw_if_index = tm->hw[2]->sw_if_index,
5783 .frp_fib_index = ~0,
5784 .frp_weight = 1,
5785 .frp_preference = 2,
5786 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5787 .frp_addr = {
5788 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0b01),
5789 },
5790 };
5791 fib_route_path_t nr_path_low_2 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005792 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005793 .frp_sw_if_index = tm->hw[2]->sw_if_index,
5794 .frp_fib_index = ~0,
5795 .frp_weight = 1,
5796 .frp_preference = 2,
5797 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5798 .frp_addr = {
5799 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0b02),
5800 },
5801 };
5802 fib_route_path_t *nr_paths = NULL;
5803
5804 vec_add1(nr_paths, nr_path_hi_1);
5805 vec_add1(nr_paths, nr_path_hi_2);
5806 vec_add1(nr_paths, nr_path_med_1);
5807 vec_add1(nr_paths, nr_path_med_2);
5808 vec_add1(nr_paths, nr_path_low_1);
5809 vec_add1(nr_paths, nr_path_low_2);
5810
5811 adj_index_t ai_hi_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5812 VNET_LINK_IP4,
5813 &nr_path_hi_1.frp_addr,
5814 nr_path_hi_1.frp_sw_if_index);
5815 adj_index_t ai_hi_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5816 VNET_LINK_IP4,
5817 &nr_path_hi_2.frp_addr,
5818 nr_path_hi_2.frp_sw_if_index);
5819 adj_index_t ai_med_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5820 VNET_LINK_IP4,
5821 &nr_path_med_1.frp_addr,
5822 nr_path_med_1.frp_sw_if_index);
5823 adj_index_t ai_med_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5824 VNET_LINK_IP4,
5825 &nr_path_med_2.frp_addr,
5826 nr_path_med_2.frp_sw_if_index);
5827 adj_index_t ai_low_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5828 VNET_LINK_IP4,
5829 &nr_path_low_1.frp_addr,
5830 nr_path_low_1.frp_sw_if_index);
5831 adj_index_t ai_low_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5832 VNET_LINK_IP4,
5833 &nr_path_low_2.frp_addr,
5834 nr_path_low_2.frp_sw_if_index);
5835
5836 fib_test_lb_bucket_t ip_hi_1 = {
5837 .type = FT_LB_ADJ,
5838 .adj = {
5839 .adj = ai_hi_1,
5840 },
5841 };
5842 fib_test_lb_bucket_t ip_hi_2 = {
5843 .type = FT_LB_ADJ,
5844 .adj = {
5845 .adj = ai_hi_2,
5846 },
5847 };
5848 fib_test_lb_bucket_t ip_med_1 = {
5849 .type = FT_LB_ADJ,
5850 .adj = {
5851 .adj = ai_med_1,
5852 },
5853 };
5854 fib_test_lb_bucket_t ip_med_2 = {
5855 .type = FT_LB_ADJ,
5856 .adj = {
5857 .adj = ai_med_2,
5858 },
5859 };
5860 fib_test_lb_bucket_t ip_low_1 = {
5861 .type = FT_LB_ADJ,
5862 .adj = {
5863 .adj = ai_low_1,
5864 },
5865 };
5866 fib_test_lb_bucket_t ip_low_2 = {
5867 .type = FT_LB_ADJ,
5868 .adj = {
5869 .adj = ai_low_2,
5870 },
5871 };
5872
5873 fib_node_index_t fei;
5874
5875 fei = fib_table_entry_path_add2(0,
5876 &pfx_1_1_1_1_s_32,
5877 FIB_SOURCE_API,
5878 FIB_ENTRY_FLAG_NONE,
5879 nr_paths);
5880
5881 FIB_TEST(fib_test_validate_entry(fei,
5882 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5883 2,
5884 &ip_hi_1,
5885 &ip_hi_2),
5886 "1.1.1.1/32 via high preference paths");
5887
5888 /*
5889 * bring down the interface on which the high preference path lie
5890 */
5891 vnet_sw_interface_set_flags(vnet_get_main(),
5892 tm->hw[0]->sw_if_index,
5893 0);
5894
5895 FIB_TEST(fib_test_validate_entry(fei,
5896 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5897 2,
5898 &ip_med_1,
5899 &ip_med_2),
5900 "1.1.1.1/32 via medium preference paths");
5901
5902 /*
5903 * bring down the interface on which the medium preference path lie
5904 */
5905 vnet_sw_interface_set_flags(vnet_get_main(),
5906 tm->hw[1]->sw_if_index,
5907 0);
5908
5909 FIB_TEST(fib_test_validate_entry(fei,
5910 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5911 2,
5912 &ip_low_1,
5913 &ip_low_2),
5914 "1.1.1.1/32 via low preference paths");
5915
5916 /*
5917 * bring up the interface on which the high preference path lie
5918 */
5919 vnet_sw_interface_set_flags(vnet_get_main(),
5920 tm->hw[0]->sw_if_index,
5921 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
5922
5923 FIB_TEST(fib_test_validate_entry(fei,
5924 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5925 2,
5926 &ip_hi_1,
5927 &ip_hi_2),
5928 "1.1.1.1/32 via high preference paths");
5929
5930 /*
5931 * bring up the interface on which the medium preference path lie
5932 */
5933 vnet_sw_interface_set_flags(vnet_get_main(),
5934 tm->hw[1]->sw_if_index,
5935 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
5936
5937 FIB_TEST(fib_test_validate_entry(fei,
5938 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5939 2,
5940 &ip_hi_1,
5941 &ip_hi_2),
5942 "1.1.1.1/32 via high preference paths");
5943
5944 dpo_id_t ip_1_1_1_1 = DPO_INVALID;
5945 fib_entry_contribute_forwarding(fei,
5946 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5947 &ip_1_1_1_1);
5948
5949 /*
5950 * 3 recursive paths of different preference
5951 */
5952 const fib_prefix_t pfx_1_1_1_2_s_32 = {
5953 .fp_len = 32,
5954 .fp_proto = FIB_PROTOCOL_IP4,
5955 .fp_addr = {
5956 .ip4 = {
5957 .as_u32 = clib_host_to_net_u32(0x01010102),
5958 },
5959 },
5960 };
5961 const fib_prefix_t pfx_1_1_1_3_s_32 = {
5962 .fp_len = 32,
5963 .fp_proto = FIB_PROTOCOL_IP4,
5964 .fp_addr = {
5965 .ip4 = {
5966 .as_u32 = clib_host_to_net_u32(0x01010103),
5967 },
5968 },
5969 };
5970 fei = fib_table_entry_path_add2(0,
5971 &pfx_1_1_1_2_s_32,
5972 FIB_SOURCE_API,
5973 FIB_ENTRY_FLAG_NONE,
5974 nr_paths);
5975 dpo_id_t ip_1_1_1_2 = DPO_INVALID;
5976 fib_entry_contribute_forwarding(fei,
5977 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5978 &ip_1_1_1_2);
5979 fei = fib_table_entry_path_add2(0,
5980 &pfx_1_1_1_3_s_32,
5981 FIB_SOURCE_API,
5982 FIB_ENTRY_FLAG_NONE,
5983 nr_paths);
5984 dpo_id_t ip_1_1_1_3 = DPO_INVALID;
5985 fib_entry_contribute_forwarding(fei,
5986 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5987 &ip_1_1_1_3);
5988
5989 fib_test_lb_bucket_t ip_o_1_1_1_1 = {
5990 .type = FT_LB_O_LB,
5991 .lb = {
5992 .lb = ip_1_1_1_1.dpoi_index,
5993 },
5994 };
5995 fib_test_lb_bucket_t ip_o_1_1_1_2 = {
5996 .type = FT_LB_O_LB,
5997 .lb = {
5998 .lb = ip_1_1_1_2.dpoi_index,
5999 },
6000 };
6001 fib_test_lb_bucket_t ip_o_1_1_1_3 = {
6002 .type = FT_LB_O_LB,
6003 .lb = {
6004 .lb = ip_1_1_1_3.dpoi_index,
6005 },
6006 };
6007 fib_route_path_t r_path_hi = {
Neale Rannsda78f952017-05-24 09:15:43 -07006008 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07006009 .frp_sw_if_index = ~0,
6010 .frp_fib_index = 0,
6011 .frp_weight = 1,
6012 .frp_preference = 0,
6013 .frp_flags = FIB_ROUTE_PATH_RESOLVE_VIA_HOST,
6014 .frp_addr = pfx_1_1_1_1_s_32.fp_addr,
6015 };
6016 fib_route_path_t r_path_med = {
Neale Rannsda78f952017-05-24 09:15:43 -07006017 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07006018 .frp_sw_if_index = ~0,
6019 .frp_fib_index = 0,
6020 .frp_weight = 1,
6021 .frp_preference = 10,
6022 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
6023 .frp_addr = pfx_1_1_1_2_s_32.fp_addr,
6024 };
6025 fib_route_path_t r_path_low = {
Neale Rannsda78f952017-05-24 09:15:43 -07006026 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07006027 .frp_sw_if_index = ~0,
6028 .frp_fib_index = 0,
6029 .frp_weight = 1,
Neale Rannsa0a908f2017-08-01 11:40:03 -07006030 .frp_preference = 255,
Neale Ranns57b58602017-07-15 07:37:25 -07006031 .frp_flags = FIB_ROUTE_PATH_RESOLVE_VIA_HOST,
6032 .frp_addr = pfx_1_1_1_3_s_32.fp_addr,
6033 };
6034 fib_route_path_t *r_paths = NULL;
6035
6036 vec_add1(r_paths, r_path_hi);
6037 vec_add1(r_paths, r_path_low);
6038 vec_add1(r_paths, r_path_med);
6039
6040 /*
6041 * add many recursive so we get the LB MAp created
6042 */
6043 #define N_PFXS 64
6044 fib_prefix_t pfx_r[N_PFXS];
Marek Gradzkiaf095512017-08-15 07:38:26 +02006045 unsigned int n_pfxs;
Neale Ranns57b58602017-07-15 07:37:25 -07006046 for (n_pfxs = 0; n_pfxs < N_PFXS; n_pfxs++)
6047 {
6048 pfx_r[n_pfxs].fp_len = 32;
6049 pfx_r[n_pfxs].fp_proto = FIB_PROTOCOL_IP4;
6050 pfx_r[n_pfxs].fp_addr.ip4.as_u32 =
6051 clib_host_to_net_u32(0x02000000 + n_pfxs);
6052
6053 fei = fib_table_entry_path_add2(0,
6054 &pfx_r[n_pfxs],
6055 FIB_SOURCE_API,
6056 FIB_ENTRY_FLAG_NONE,
6057 r_paths);
6058
6059 FIB_TEST(fib_test_validate_entry(fei,
6060 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6061 1,
6062 &ip_o_1_1_1_1),
6063 "recursive via high preference paths");
6064
6065 /*
6066 * withdraw hig pref resolving entry
6067 */
6068 fib_table_entry_delete(0,
6069 &pfx_1_1_1_1_s_32,
6070 FIB_SOURCE_API);
6071
6072 /* suspend so the update walk kicks int */
6073 vlib_process_suspend(vlib_get_main(), 1e-5);
6074
6075 FIB_TEST(fib_test_validate_entry(fei,
6076 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6077 1,
6078 &ip_o_1_1_1_2),
6079 "recursive via medium preference paths");
6080
6081 /*
6082 * withdraw medium pref resolving entry
6083 */
6084 fib_table_entry_delete(0,
6085 &pfx_1_1_1_2_s_32,
6086 FIB_SOURCE_API);
6087
6088 /* suspend so the update walk kicks int */
6089 vlib_process_suspend(vlib_get_main(), 1e-5);
6090
6091 FIB_TEST(fib_test_validate_entry(fei,
6092 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6093 1,
6094 &ip_o_1_1_1_3),
6095 "recursive via low preference paths");
6096
6097 /*
6098 * add back paths for next iteration
6099 */
6100 fei = fib_table_entry_update(0,
6101 &pfx_1_1_1_2_s_32,
6102 FIB_SOURCE_API,
6103 FIB_ENTRY_FLAG_NONE,
6104 nr_paths);
6105 fei = fib_table_entry_update(0,
6106 &pfx_1_1_1_1_s_32,
6107 FIB_SOURCE_API,
6108 FIB_ENTRY_FLAG_NONE,
6109 nr_paths);
6110
6111 /* suspend so the update walk kicks int */
6112 vlib_process_suspend(vlib_get_main(), 1e-5);
6113
6114 fei = fib_table_lookup_exact_match(0, &pfx_r[n_pfxs]);
6115 FIB_TEST(fib_test_validate_entry(fei,
6116 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6117 1,
6118 &ip_o_1_1_1_1),
6119 "recursive via high preference paths");
6120 }
6121
6122
6123 fib_table_entry_delete(0,
6124 &pfx_1_1_1_1_s_32,
6125 FIB_SOURCE_API);
6126
6127 /* suspend so the update walk kicks int */
6128 vlib_process_suspend(vlib_get_main(), 1e-5);
6129
6130 for (n_pfxs = 0; n_pfxs < N_PFXS; n_pfxs++)
6131 {
6132 fei = fib_table_lookup_exact_match(0, &pfx_r[n_pfxs]);
6133
6134 FIB_TEST(fib_test_validate_entry(fei,
6135 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6136 1,
6137 &ip_o_1_1_1_2),
6138 "recursive via medium preference paths");
6139 }
6140 for (n_pfxs = 0; n_pfxs < N_PFXS; n_pfxs++)
6141 {
6142 fib_table_entry_delete(0,
6143 &pfx_r[n_pfxs],
6144 FIB_SOURCE_API);
6145 }
6146
6147 /*
6148 * Cleanup
6149 */
6150 fib_table_entry_delete(0,
6151 &pfx_1_1_1_2_s_32,
6152 FIB_SOURCE_API);
6153 fib_table_entry_delete(0,
6154 &pfx_1_1_1_3_s_32,
6155 FIB_SOURCE_API);
6156
6157 dpo_reset(&ip_1_1_1_1);
6158 dpo_reset(&ip_1_1_1_2);
6159 dpo_reset(&ip_1_1_1_3);
6160 adj_unlock(ai_low_2);
6161 adj_unlock(ai_low_1);
6162 adj_unlock(ai_med_2);
6163 adj_unlock(ai_med_1);
6164 adj_unlock(ai_hi_2);
6165 adj_unlock(ai_hi_1);
6166 return (0);
6167}
Neale Rannsad422ed2016-11-02 14:20:04 +00006168
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006169/*
6170 * Test the recursive route route handling for GRE tunnels
6171 */
Neale Ranns0ebe8d72016-12-08 19:48:11 +00006172static int
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006173fib_test_label (void)
6174{
6175 fib_node_index_t fei, ai_mpls_10_10_10_1, ai_v4_10_10_11_1, ai_v4_10_10_11_2, ai_mpls_10_10_11_2, ai_mpls_10_10_11_1;
6176 const u32 fib_index = 0;
6177 test_main_t *tm;
6178 ip4_main_t *im;
Neale Rannsad422ed2016-11-02 14:20:04 +00006179 int lb_count, ii;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006180
6181 lb_count = pool_elts(load_balance_pool);
6182 tm = &test_main;
6183 im = &ip4_main;
6184
6185 /*
6186 * add interface routes. We'll assume this works. It's more rigorously
6187 * tested elsewhere.
6188 */
6189 fib_prefix_t local0_pfx = {
6190 .fp_len = 24,
6191 .fp_proto = FIB_PROTOCOL_IP4,
6192 .fp_addr = {
6193 .ip4 = {
6194 /* 10.10.10.10 */
6195 .as_u32 = clib_host_to_net_u32(0x0a0a0a0a),
6196 },
6197 },
6198 };
6199
6200 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
6201 adj_nbr_db_size());
6202
6203 vec_validate(im->fib_index_by_sw_if_index, tm->hw[0]->sw_if_index);
6204 im->fib_index_by_sw_if_index[tm->hw[0]->sw_if_index] = fib_index;
6205
6206 fib_table_entry_update_one_path(fib_index, &local0_pfx,
6207 FIB_SOURCE_INTERFACE,
6208 (FIB_ENTRY_FLAG_CONNECTED |
6209 FIB_ENTRY_FLAG_ATTACHED),
Neale Rannsda78f952017-05-24 09:15:43 -07006210 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006211 NULL,
6212 tm->hw[0]->sw_if_index,
6213 ~0,
6214 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006215 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006216 FIB_ROUTE_PATH_FLAG_NONE);
6217 fei = fib_table_lookup_exact_match(fib_index, &local0_pfx);
6218 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
6219 "attached interface route present");
6220
6221 local0_pfx.fp_len = 32;
6222 fib_table_entry_update_one_path(fib_index, &local0_pfx,
6223 FIB_SOURCE_INTERFACE,
6224 (FIB_ENTRY_FLAG_CONNECTED |
6225 FIB_ENTRY_FLAG_LOCAL),
Neale Rannsda78f952017-05-24 09:15:43 -07006226 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006227 NULL,
6228 tm->hw[0]->sw_if_index,
6229 ~0, // invalid fib index
6230 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006231 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006232 FIB_ROUTE_PATH_FLAG_NONE);
6233 fei = fib_table_lookup_exact_match(fib_index, &local0_pfx);
6234
6235 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
6236 "local interface route present");
6237
6238 fib_prefix_t local1_pfx = {
6239 .fp_len = 24,
6240 .fp_proto = FIB_PROTOCOL_IP4,
6241 .fp_addr = {
6242 .ip4 = {
6243 /* 10.10.11.10 */
6244 .as_u32 = clib_host_to_net_u32(0x0a0a0b0a),
6245 },
6246 },
6247 };
6248
6249 vec_validate(im->fib_index_by_sw_if_index, tm->hw[1]->sw_if_index);
6250 im->fib_index_by_sw_if_index[tm->hw[1]->sw_if_index] = fib_index;
6251
6252 fib_table_entry_update_one_path(fib_index, &local1_pfx,
6253 FIB_SOURCE_INTERFACE,
6254 (FIB_ENTRY_FLAG_CONNECTED |
6255 FIB_ENTRY_FLAG_ATTACHED),
Neale Rannsda78f952017-05-24 09:15:43 -07006256 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006257 NULL,
6258 tm->hw[1]->sw_if_index,
6259 ~0,
6260 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006261 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006262 FIB_ROUTE_PATH_FLAG_NONE);
6263 fei = fib_table_lookup_exact_match(fib_index, &local1_pfx);
6264 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
6265 "attached interface route present");
6266
6267 local1_pfx.fp_len = 32;
6268 fib_table_entry_update_one_path(fib_index, &local1_pfx,
6269 FIB_SOURCE_INTERFACE,
6270 (FIB_ENTRY_FLAG_CONNECTED |
6271 FIB_ENTRY_FLAG_LOCAL),
Neale Rannsda78f952017-05-24 09:15:43 -07006272 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006273 NULL,
6274 tm->hw[1]->sw_if_index,
6275 ~0, // invalid fib index
6276 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006277 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006278 FIB_ROUTE_PATH_FLAG_NONE);
6279 fei = fib_table_lookup_exact_match(fib_index, &local1_pfx);
6280
6281 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
6282 "local interface route present");
6283
6284 ip46_address_t nh_10_10_10_1 = {
6285 .ip4 = {
6286 .as_u32 = clib_host_to_net_u32(0x0a0a0a01),
6287 },
6288 };
6289 ip46_address_t nh_10_10_11_1 = {
6290 .ip4 = {
6291 .as_u32 = clib_host_to_net_u32(0x0a0a0b01),
6292 },
6293 };
6294 ip46_address_t nh_10_10_11_2 = {
6295 .ip4 = {
6296 .as_u32 = clib_host_to_net_u32(0x0a0a0b02),
6297 },
6298 };
6299
6300 ai_v4_10_10_11_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01006301 VNET_LINK_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006302 &nh_10_10_11_1,
6303 tm->hw[1]->sw_if_index);
6304 ai_v4_10_10_11_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01006305 VNET_LINK_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006306 &nh_10_10_11_2,
6307 tm->hw[1]->sw_if_index);
6308 ai_mpls_10_10_10_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01006309 VNET_LINK_MPLS,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006310 &nh_10_10_10_1,
6311 tm->hw[0]->sw_if_index);
6312 ai_mpls_10_10_11_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01006313 VNET_LINK_MPLS,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006314 &nh_10_10_11_2,
6315 tm->hw[1]->sw_if_index);
6316 ai_mpls_10_10_11_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01006317 VNET_LINK_MPLS,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006318 &nh_10_10_11_1,
6319 tm->hw[1]->sw_if_index);
6320
6321 /*
6322 * Add an etry with one path with a real out-going label
6323 */
6324 fib_prefix_t pfx_1_1_1_1_s_32 = {
6325 .fp_len = 32,
6326 .fp_proto = FIB_PROTOCOL_IP4,
6327 .fp_addr = {
6328 .ip4.as_u32 = clib_host_to_net_u32(0x01010101),
6329 },
6330 };
6331 fib_test_lb_bucket_t l99_eos_o_10_10_10_1 = {
6332 .type = FT_LB_LABEL_O_ADJ,
6333 .label_o_adj = {
6334 .adj = ai_mpls_10_10_10_1,
6335 .label = 99,
6336 .eos = MPLS_EOS,
6337 },
6338 };
6339 fib_test_lb_bucket_t l99_neos_o_10_10_10_1 = {
6340 .type = FT_LB_LABEL_O_ADJ,
6341 .label_o_adj = {
6342 .adj = ai_mpls_10_10_10_1,
6343 .label = 99,
6344 .eos = MPLS_NON_EOS,
6345 },
6346 };
Neale Ranns31ed7442018-02-23 05:29:09 -08006347 fib_mpls_label_t *l99 = NULL, fml99 = {
6348 .fml_value = 99,
6349 };
6350 vec_add1(l99, fml99);
Neale Rannsad422ed2016-11-02 14:20:04 +00006351
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006352 fib_table_entry_update_one_path(fib_index,
6353 &pfx_1_1_1_1_s_32,
6354 FIB_SOURCE_API,
6355 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07006356 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006357 &nh_10_10_10_1,
6358 tm->hw[0]->sw_if_index,
6359 ~0, // invalid fib index
6360 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006361 l99,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006362 FIB_ROUTE_PATH_FLAG_NONE);
6363
6364 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
6365 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "1.1.1.1/32 created");
6366
6367 FIB_TEST(fib_test_validate_entry(fei,
6368 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6369 1,
6370 &l99_eos_o_10_10_10_1),
6371 "1.1.1.1/32 LB 1 bucket via label 99 over 10.10.10.1");
6372
6373 /*
6374 * add a path with an implicit NULL label
6375 */
6376 fib_test_lb_bucket_t a_o_10_10_11_1 = {
6377 .type = FT_LB_ADJ,
6378 .adj = {
6379 .adj = ai_v4_10_10_11_1,
6380 },
6381 };
6382 fib_test_lb_bucket_t a_mpls_o_10_10_11_1 = {
6383 .type = FT_LB_ADJ,
6384 .adj = {
6385 .adj = ai_mpls_10_10_11_1,
6386 },
6387 };
Neale Ranns31ed7442018-02-23 05:29:09 -08006388 fib_mpls_label_t *l_imp_null = NULL, fml_imp_null = {
6389 .fml_value = MPLS_IETF_IMPLICIT_NULL_LABEL,
6390 };
6391 vec_add1(l_imp_null, fml_imp_null);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006392
6393 fei = fib_table_entry_path_add(fib_index,
6394 &pfx_1_1_1_1_s_32,
6395 FIB_SOURCE_API,
6396 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07006397 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006398 &nh_10_10_11_1,
6399 tm->hw[1]->sw_if_index,
6400 ~0, // invalid fib index
6401 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006402 l_imp_null,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006403 FIB_ROUTE_PATH_FLAG_NONE);
6404
6405 FIB_TEST(fib_test_validate_entry(fei,
6406 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6407 2,
6408 &l99_eos_o_10_10_10_1,
6409 &a_o_10_10_11_1),
6410 "1.1.1.1/32 LB 2 buckets via: "
6411 "label 99 over 10.10.10.1, "
6412 "adj over 10.10.11.1");
6413
6414 /*
6415 * assign the route a local label
6416 */
6417 fib_table_entry_local_label_add(fib_index,
6418 &pfx_1_1_1_1_s_32,
6419 24001);
6420
6421 fib_prefix_t pfx_24001_eos = {
6422 .fp_proto = FIB_PROTOCOL_MPLS,
6423 .fp_label = 24001,
6424 .fp_eos = MPLS_EOS,
6425 };
6426 fib_prefix_t pfx_24001_neos = {
6427 .fp_proto = FIB_PROTOCOL_MPLS,
6428 .fp_label = 24001,
6429 .fp_eos = MPLS_NON_EOS,
6430 };
Neale Ranns62fe07c2017-10-31 12:28:22 -07006431 fib_test_lb_bucket_t disp_o_10_10_11_1 = {
Neale Ranns31ed7442018-02-23 05:29:09 -08006432 .type = FT_LB_MPLS_DISP_PIPE_O_ADJ,
Neale Ranns62fe07c2017-10-31 12:28:22 -07006433 .adj = {
6434 .adj = ai_v4_10_10_11_1,
6435 },
6436 };
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006437
6438 /*
6439 * The EOS entry should link to both the paths,
6440 * and use an ip adj for the imp-null
6441 * The NON-EOS entry should link to both the paths,
6442 * and use an mpls adj for the imp-null
6443 */
6444 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6445 &pfx_24001_eos);
6446 FIB_TEST(fib_test_validate_entry(fei,
6447 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6448 2,
6449 &l99_eos_o_10_10_10_1,
Neale Ranns62fe07c2017-10-31 12:28:22 -07006450 &disp_o_10_10_11_1),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006451 "24001/eos LB 2 buckets via: "
6452 "label 99 over 10.10.10.1, "
Neale Ranns62fe07c2017-10-31 12:28:22 -07006453 "mpls disp adj over 10.10.11.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006454
6455
6456 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6457 &pfx_24001_neos);
6458 FIB_TEST(fib_test_validate_entry(fei,
6459 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6460 2,
6461 &l99_neos_o_10_10_10_1,
6462 &a_mpls_o_10_10_11_1),
6463 "24001/neos LB 1 bucket via: "
6464 "label 99 over 10.10.10.1 ",
6465 "mpls-adj via 10.10.11.1");
6466
6467 /*
6468 * add an unlabelled path, this is excluded from the neos chains,
6469 */
6470 fib_test_lb_bucket_t adj_o_10_10_11_2 = {
6471 .type = FT_LB_ADJ,
6472 .adj = {
6473 .adj = ai_v4_10_10_11_2,
6474 },
6475 };
Neale Ranns62fe07c2017-10-31 12:28:22 -07006476 fib_test_lb_bucket_t disp_o_10_10_11_2 = {
Neale Ranns31ed7442018-02-23 05:29:09 -08006477 .type = FT_LB_MPLS_DISP_PIPE_O_ADJ,
Neale Ranns62fe07c2017-10-31 12:28:22 -07006478 .adj = {
6479 .adj = ai_v4_10_10_11_2,
6480 },
6481 };
6482
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006483
6484 fei = fib_table_entry_path_add(fib_index,
6485 &pfx_1_1_1_1_s_32,
6486 FIB_SOURCE_API,
6487 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07006488 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006489 &nh_10_10_11_2,
6490 tm->hw[1]->sw_if_index,
6491 ~0, // invalid fib index
6492 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006493 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006494 FIB_ROUTE_PATH_FLAG_NONE);
6495
6496 FIB_TEST(fib_test_validate_entry(fei,
6497 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6498 16, // 3 choices spread over 16 buckets
6499 &l99_eos_o_10_10_10_1,
6500 &l99_eos_o_10_10_10_1,
6501 &l99_eos_o_10_10_10_1,
6502 &l99_eos_o_10_10_10_1,
6503 &l99_eos_o_10_10_10_1,
6504 &l99_eos_o_10_10_10_1,
6505 &a_o_10_10_11_1,
6506 &a_o_10_10_11_1,
6507 &a_o_10_10_11_1,
6508 &a_o_10_10_11_1,
6509 &a_o_10_10_11_1,
6510 &adj_o_10_10_11_2,
6511 &adj_o_10_10_11_2,
6512 &adj_o_10_10_11_2,
6513 &adj_o_10_10_11_2,
6514 &adj_o_10_10_11_2),
6515 "1.1.1.1/32 LB 16 buckets via: "
6516 "label 99 over 10.10.10.1, "
6517 "adj over 10.10.11.1",
6518 "adj over 10.10.11.2");
6519
6520 /*
6521 * get and lock a reference to the non-eos of the via entry 1.1.1.1/32
6522 */
Neale Ranns948e00f2016-10-20 13:39:34 +01006523 dpo_id_t non_eos_1_1_1_1 = DPO_INVALID;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006524 fib_entry_contribute_forwarding(fei,
6525 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6526 &non_eos_1_1_1_1);
6527
6528 /*
6529 * n-eos has only the 2 labelled paths
6530 */
6531 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6532 &pfx_24001_neos);
6533
6534 FIB_TEST(fib_test_validate_entry(fei,
6535 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6536 2,
6537 &l99_neos_o_10_10_10_1,
6538 &a_mpls_o_10_10_11_1),
6539 "24001/neos LB 2 buckets via: "
6540 "label 99 over 10.10.10.1, "
6541 "adj-mpls over 10.10.11.2");
6542
6543 /*
6544 * A labelled recursive
6545 */
6546 fib_prefix_t pfx_2_2_2_2_s_32 = {
6547 .fp_len = 32,
6548 .fp_proto = FIB_PROTOCOL_IP4,
6549 .fp_addr = {
6550 .ip4.as_u32 = clib_host_to_net_u32(0x02020202),
6551 },
6552 };
6553 fib_test_lb_bucket_t l1600_eos_o_1_1_1_1 = {
6554 .type = FT_LB_LABEL_O_LB,
6555 .label_o_lb = {
6556 .lb = non_eos_1_1_1_1.dpoi_index,
6557 .label = 1600,
6558 .eos = MPLS_EOS,
Neale Ranns31ed7442018-02-23 05:29:09 -08006559 .mode = FIB_MPLS_LSP_MODE_UNIFORM,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006560 },
6561 };
Neale Ranns31ed7442018-02-23 05:29:09 -08006562 fib_mpls_label_t *l1600 = NULL, fml1600 = {
6563 .fml_value = 1600,
6564 .fml_mode = FIB_MPLS_LSP_MODE_UNIFORM,
6565 };
6566 vec_add1(l1600, fml1600);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006567
Neale Ranns31ed7442018-02-23 05:29:09 -08006568 fei = fib_table_entry_update_one_path(fib_index,
6569 &pfx_2_2_2_2_s_32,
6570 FIB_SOURCE_API,
6571 FIB_ENTRY_FLAG_NONE,
6572 DPO_PROTO_IP4,
6573 &pfx_1_1_1_1_s_32.fp_addr,
6574 ~0,
6575 fib_index,
6576 1,
6577 l1600,
6578 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006579
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006580 FIB_TEST(fib_test_validate_entry(fei,
6581 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6582 1,
6583 &l1600_eos_o_1_1_1_1),
6584 "2.2.2.2.2/32 LB 1 buckets via: "
6585 "label 1600 over 1.1.1.1");
6586
Neale Ranns948e00f2016-10-20 13:39:34 +01006587 dpo_id_t dpo_44 = DPO_INVALID;
Neale Ranns3ee44042016-10-03 13:05:48 +01006588 index_t urpfi;
6589
6590 fib_entry_contribute_forwarding(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, &dpo_44);
6591 urpfi = load_balance_get_urpf(dpo_44.dpoi_index);
6592
6593 FIB_TEST(fib_urpf_check(urpfi, tm->hw[0]->sw_if_index),
6594 "uRPF check for 2.2.2.2/32 on %d OK",
6595 tm->hw[0]->sw_if_index);
6596 FIB_TEST(fib_urpf_check(urpfi, tm->hw[1]->sw_if_index),
6597 "uRPF check for 2.2.2.2/32 on %d OK",
6598 tm->hw[1]->sw_if_index);
6599 FIB_TEST(!fib_urpf_check(urpfi, 99),
6600 "uRPF check for 2.2.2.2/32 on 99 not-OK",
6601 99);
6602
6603 fib_entry_contribute_forwarding(fei, FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS, &dpo_44);
6604 FIB_TEST(urpfi == load_balance_get_urpf(dpo_44.dpoi_index),
6605 "Shared uRPF on IP and non-EOS chain");
6606
6607 dpo_reset(&dpo_44);
6608
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006609 /*
6610 * we are holding a lock on the non-eos LB of the via-entry.
6611 * do a PIC-core failover by shutting the link of the via-entry.
6612 *
6613 * shut down the link with the valid label
6614 */
6615 vnet_sw_interface_set_flags(vnet_get_main(),
6616 tm->hw[0]->sw_if_index,
6617 0);
6618
6619 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
6620 FIB_TEST(fib_test_validate_entry(fei,
6621 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6622 2,
6623 &a_o_10_10_11_1,
6624 &adj_o_10_10_11_2),
6625 "1.1.1.1/32 LB 2 buckets via: "
6626 "adj over 10.10.11.1, ",
6627 "adj-v4 over 10.10.11.2");
6628
6629 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6630 &pfx_24001_eos);
6631 FIB_TEST(fib_test_validate_entry(fei,
6632 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6633 2,
Neale Ranns62fe07c2017-10-31 12:28:22 -07006634 &disp_o_10_10_11_1,
6635 &disp_o_10_10_11_2),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006636 "24001/eos LB 2 buckets via: "
Neale Ranns62fe07c2017-10-31 12:28:22 -07006637 "mpls-disp adj over 10.10.11.1, ",
6638 "mpls-disp adj-v4 over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006639
6640 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6641 &pfx_24001_neos);
6642 FIB_TEST(fib_test_validate_entry(fei,
6643 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6644 1,
6645 &a_mpls_o_10_10_11_1),
6646 "24001/neos LB 1 buckets via: "
6647 "adj-mpls over 10.10.11.2");
6648
6649 /*
6650 * test that the pre-failover load-balance has been in-place
6651 * modified
6652 */
Neale Ranns948e00f2016-10-20 13:39:34 +01006653 dpo_id_t current = DPO_INVALID;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006654 fib_entry_contribute_forwarding(fei,
6655 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6656 &current);
6657
6658 FIB_TEST(!dpo_cmp(&non_eos_1_1_1_1,
6659 &current),
6660 "PIC-core LB inplace modified %U %U",
6661 format_dpo_id, &non_eos_1_1_1_1, 0,
6662 format_dpo_id, &current, 0);
6663
6664 dpo_reset(&non_eos_1_1_1_1);
6665 dpo_reset(&current);
6666
6667 /*
6668 * no-shut the link with the valid label
6669 */
6670 vnet_sw_interface_set_flags(vnet_get_main(),
6671 tm->hw[0]->sw_if_index,
6672 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
6673
6674 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
6675 FIB_TEST(fib_test_validate_entry(fei,
6676 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6677 16, // 3 choices spread over 16 buckets
6678 &l99_eos_o_10_10_10_1,
6679 &l99_eos_o_10_10_10_1,
6680 &l99_eos_o_10_10_10_1,
6681 &l99_eos_o_10_10_10_1,
6682 &l99_eos_o_10_10_10_1,
6683 &l99_eos_o_10_10_10_1,
6684 &a_o_10_10_11_1,
6685 &a_o_10_10_11_1,
6686 &a_o_10_10_11_1,
6687 &a_o_10_10_11_1,
6688 &a_o_10_10_11_1,
6689 &adj_o_10_10_11_2,
6690 &adj_o_10_10_11_2,
6691 &adj_o_10_10_11_2,
6692 &adj_o_10_10_11_2,
6693 &adj_o_10_10_11_2),
6694 "1.1.1.1/32 LB 16 buckets via: "
6695 "label 99 over 10.10.10.1, "
6696 "adj over 10.10.11.1",
6697 "adj-v4 over 10.10.11.2");
6698
6699
6700 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6701 &pfx_24001_eos);
6702 FIB_TEST(fib_test_validate_entry(fei,
6703 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6704 16, // 3 choices spread over 16 buckets
6705 &l99_eos_o_10_10_10_1,
6706 &l99_eos_o_10_10_10_1,
6707 &l99_eos_o_10_10_10_1,
6708 &l99_eos_o_10_10_10_1,
6709 &l99_eos_o_10_10_10_1,
6710 &l99_eos_o_10_10_10_1,
Neale Ranns62fe07c2017-10-31 12:28:22 -07006711 &disp_o_10_10_11_1,
6712 &disp_o_10_10_11_1,
6713 &disp_o_10_10_11_1,
6714 &disp_o_10_10_11_1,
6715 &disp_o_10_10_11_1,
6716 &disp_o_10_10_11_2,
6717 &disp_o_10_10_11_2,
6718 &disp_o_10_10_11_2,
6719 &disp_o_10_10_11_2,
6720 &disp_o_10_10_11_2),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006721 "24001/eos LB 16 buckets via: "
6722 "label 99 over 10.10.10.1, "
Neale Ranns62fe07c2017-10-31 12:28:22 -07006723 "MPLS disp adj over 10.10.11.1",
6724 "MPLS disp adj-v4 over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006725
6726 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6727 &pfx_24001_neos);
6728 FIB_TEST(fib_test_validate_entry(fei,
6729 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6730 2,
6731 &l99_neos_o_10_10_10_1,
6732 &a_mpls_o_10_10_11_1),
6733 "24001/neos LB 2 buckets via: "
6734 "label 99 over 10.10.10.1, "
6735 "adj-mpls over 10.10.11.2");
6736
6737 /*
6738 * remove the first path with the valid label
6739 */
6740 fib_table_entry_path_remove(fib_index,
6741 &pfx_1_1_1_1_s_32,
6742 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07006743 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006744 &nh_10_10_10_1,
6745 tm->hw[0]->sw_if_index,
6746 ~0, // invalid fib index
6747 1,
6748 FIB_ROUTE_PATH_FLAG_NONE);
6749
6750 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
6751 FIB_TEST(fib_test_validate_entry(fei,
6752 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6753 2,
6754 &a_o_10_10_11_1,
6755 &adj_o_10_10_11_2),
6756 "1.1.1.1/32 LB 2 buckets via: "
Neale Rannsa3af3372017-03-28 03:49:52 -07006757 "adj over 10.10.11.1, "
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006758 "adj-v4 over 10.10.11.2");
6759
6760 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6761 &pfx_24001_eos);
6762 FIB_TEST(fib_test_validate_entry(fei,
6763 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6764 2,
Neale Ranns62fe07c2017-10-31 12:28:22 -07006765 &disp_o_10_10_11_1,
6766 &disp_o_10_10_11_2),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006767 "24001/eos LB 2 buckets via: "
Neale Ranns62fe07c2017-10-31 12:28:22 -07006768 "MPLS disp adj over 10.10.11.1, "
6769 "MPLS disp adj-v4 over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006770
6771 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6772 &pfx_24001_neos);
6773
6774 FIB_TEST(fib_test_validate_entry(fei,
6775 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6776 1,
6777 &a_mpls_o_10_10_11_1),
6778 "24001/neos LB 1 buckets via: "
6779 "adj-mpls over 10.10.11.2");
6780
6781 /*
6782 * remove the other path with a valid label
6783 */
6784 fib_test_lb_bucket_t bucket_drop = {
Neale Rannsd792d9c2017-10-21 10:53:20 -07006785 .type = FT_LB_DROP,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006786 };
Neale Rannsf12a83f2017-04-18 09:09:40 -07006787 fib_test_lb_bucket_t mpls_bucket_drop = {
Neale Rannsd792d9c2017-10-21 10:53:20 -07006788 .type = FT_LB_DROP,
Neale Rannsf12a83f2017-04-18 09:09:40 -07006789 .special = {
6790 .adj = DPO_PROTO_MPLS,
6791 },
6792 };
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006793
6794 fib_table_entry_path_remove(fib_index,
6795 &pfx_1_1_1_1_s_32,
6796 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07006797 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006798 &nh_10_10_11_1,
6799 tm->hw[1]->sw_if_index,
6800 ~0, // invalid fib index
6801 1,
6802 FIB_ROUTE_PATH_FLAG_NONE);
6803
6804 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
6805 FIB_TEST(fib_test_validate_entry(fei,
6806 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6807 1,
6808 &adj_o_10_10_11_2),
6809 "1.1.1.1/32 LB 1 buckets via: "
6810 "adj over 10.10.11.2");
6811
6812 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6813 &pfx_24001_eos);
6814 FIB_TEST(fib_test_validate_entry(fei,
6815 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6816 1,
Neale Ranns62fe07c2017-10-31 12:28:22 -07006817 &disp_o_10_10_11_2),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006818 "24001/eos LB 1 buckets via: "
Neale Ranns62fe07c2017-10-31 12:28:22 -07006819 "MPLS disp adj over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006820
6821 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6822 &pfx_24001_neos);
6823 FIB_TEST(fib_test_validate_entry(fei,
6824 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
Neale Rannsf12a83f2017-04-18 09:09:40 -07006825 1,
6826 &mpls_bucket_drop),
6827 "24001/neos LB 1 buckets via: DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006828
6829 /*
6830 * add back the path with the valid label
6831 */
Neale Rannsad422ed2016-11-02 14:20:04 +00006832 l99 = NULL;
Neale Ranns31ed7442018-02-23 05:29:09 -08006833 vec_add1(l99, fml99);
Neale Rannsad422ed2016-11-02 14:20:04 +00006834
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006835 fib_table_entry_path_add(fib_index,
6836 &pfx_1_1_1_1_s_32,
6837 FIB_SOURCE_API,
6838 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07006839 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006840 &nh_10_10_10_1,
6841 tm->hw[0]->sw_if_index,
6842 ~0, // invalid fib index
6843 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006844 l99,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006845 FIB_ROUTE_PATH_FLAG_NONE);
6846
6847 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
6848 FIB_TEST(fib_test_validate_entry(fei,
6849 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6850 2,
6851 &l99_eos_o_10_10_10_1,
6852 &adj_o_10_10_11_2),
6853 "1.1.1.1/32 LB 2 buckets via: "
6854 "label 99 over 10.10.10.1, "
6855 "adj over 10.10.11.2");
6856
6857 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6858 &pfx_24001_eos);
6859 FIB_TEST(fib_test_validate_entry(fei,
6860 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6861 2,
6862 &l99_eos_o_10_10_10_1,
Neale Ranns62fe07c2017-10-31 12:28:22 -07006863 &disp_o_10_10_11_2),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006864 "24001/eos LB 2 buckets via: "
6865 "label 99 over 10.10.10.1, "
Neale Ranns62fe07c2017-10-31 12:28:22 -07006866 "MPLS disp adj over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006867
6868 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6869 &pfx_24001_neos);
6870 FIB_TEST(fib_test_validate_entry(fei,
6871 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6872 1,
6873 &l99_neos_o_10_10_10_1),
6874 "24001/neos LB 1 buckets via: "
6875 "label 99 over 10.10.10.1");
6876
6877 /*
Neale Ranns1357f3b2016-10-16 12:01:42 -07006878 * change the local label
6879 */
6880 fib_table_entry_local_label_add(fib_index,
6881 &pfx_1_1_1_1_s_32,
6882 25005);
6883
6884 fib_prefix_t pfx_25005_eos = {
6885 .fp_proto = FIB_PROTOCOL_MPLS,
6886 .fp_label = 25005,
6887 .fp_eos = MPLS_EOS,
6888 };
6889 fib_prefix_t pfx_25005_neos = {
6890 .fp_proto = FIB_PROTOCOL_MPLS,
6891 .fp_label = 25005,
6892 .fp_eos = MPLS_NON_EOS,
6893 };
6894
6895 FIB_TEST((FIB_NODE_INDEX_INVALID ==
6896 fib_table_lookup(fib_index, &pfx_24001_eos)),
6897 "24001/eos removed after label change");
6898 FIB_TEST((FIB_NODE_INDEX_INVALID ==
6899 fib_table_lookup(fib_index, &pfx_24001_neos)),
6900 "24001/eos removed after label change");
6901
6902 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6903 &pfx_25005_eos);
6904 FIB_TEST(fib_test_validate_entry(fei,
6905 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6906 2,
6907 &l99_eos_o_10_10_10_1,
Neale Ranns62fe07c2017-10-31 12:28:22 -07006908 &disp_o_10_10_11_2),
Neale Ranns1357f3b2016-10-16 12:01:42 -07006909 "25005/eos LB 2 buckets via: "
6910 "label 99 over 10.10.10.1, "
Neale Ranns62fe07c2017-10-31 12:28:22 -07006911 "MPLS disp adj over 10.10.11.2");
Neale Ranns1357f3b2016-10-16 12:01:42 -07006912
6913 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6914 &pfx_25005_neos);
6915 FIB_TEST(fib_test_validate_entry(fei,
6916 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6917 1,
6918 &l99_neos_o_10_10_10_1),
6919 "25005/neos LB 1 buckets via: "
6920 "label 99 over 10.10.10.1");
6921
6922 /*
6923 * remove the local label.
6924 * the check that the MPLS entries are gone is done by the fact the
6925 * MPLS table is no longer present.
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006926 */
6927 fib_table_entry_local_label_remove(fib_index,
6928 &pfx_1_1_1_1_s_32,
Neale Ranns1357f3b2016-10-16 12:01:42 -07006929 25005);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006930
6931 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
6932 FIB_TEST(fib_test_validate_entry(fei,
6933 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6934 2,
6935 &l99_eos_o_10_10_10_1,
6936 &adj_o_10_10_11_2),
6937 "24001/eos LB 2 buckets via: "
6938 "label 99 over 10.10.10.1, "
6939 "adj over 10.10.11.2");
6940
6941 FIB_TEST((FIB_NODE_INDEX_INVALID ==
6942 mpls_fib_index_from_table_id(MPLS_FIB_DEFAULT_TABLE_ID)),
6943 "No more MPLS FIB entries => table removed");
6944
6945 /*
6946 * add another via-entry for the recursive
6947 */
6948 fib_prefix_t pfx_1_1_1_2_s_32 = {
6949 .fp_len = 32,
6950 .fp_proto = FIB_PROTOCOL_IP4,
6951 .fp_addr = {
6952 .ip4.as_u32 = clib_host_to_net_u32(0x01010102),
6953 },
6954 };
6955 fib_test_lb_bucket_t l101_eos_o_10_10_10_1 = {
6956 .type = FT_LB_LABEL_O_ADJ,
6957 .label_o_adj = {
6958 .adj = ai_mpls_10_10_10_1,
6959 .label = 101,
6960 .eos = MPLS_EOS,
6961 },
6962 };
Neale Ranns31ed7442018-02-23 05:29:09 -08006963 fib_mpls_label_t *l101 = NULL, fml101 = {
6964 .fml_value = 101,
6965 };
6966 vec_add1(l101, fml101);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006967
6968 fei = fib_table_entry_update_one_path(fib_index,
6969 &pfx_1_1_1_2_s_32,
6970 FIB_SOURCE_API,
6971 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07006972 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006973 &nh_10_10_10_1,
6974 tm->hw[0]->sw_if_index,
6975 ~0, // invalid fib index
6976 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006977 l101,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006978 FIB_ROUTE_PATH_FLAG_NONE);
6979
6980 FIB_TEST(fib_test_validate_entry(fei,
6981 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6982 1,
6983 &l101_eos_o_10_10_10_1),
6984 "1.1.1.2/32 LB 1 buckets via: "
6985 "label 101 over 10.10.10.1");
6986
Neale Ranns948e00f2016-10-20 13:39:34 +01006987 dpo_id_t non_eos_1_1_1_2 = DPO_INVALID;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006988 fib_entry_contribute_forwarding(fib_table_lookup(fib_index,
6989 &pfx_1_1_1_1_s_32),
6990 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6991 &non_eos_1_1_1_1);
6992 fib_entry_contribute_forwarding(fib_table_lookup(fib_index,
6993 &pfx_1_1_1_2_s_32),
6994 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6995 &non_eos_1_1_1_2);
6996
6997 fib_test_lb_bucket_t l1601_eos_o_1_1_1_2 = {
6998 .type = FT_LB_LABEL_O_LB,
6999 .label_o_lb = {
7000 .lb = non_eos_1_1_1_2.dpoi_index,
7001 .label = 1601,
7002 .eos = MPLS_EOS,
7003 },
7004 };
Neale Ranns31ed7442018-02-23 05:29:09 -08007005 fib_mpls_label_t *l1601 = NULL, fml1601 = {
7006 .fml_value = 1601,
7007 };
7008 vec_add1(l1601, fml1601);
Neale Rannsad422ed2016-11-02 14:20:04 +00007009
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007010 l1600_eos_o_1_1_1_1.label_o_lb.lb = non_eos_1_1_1_1.dpoi_index;
7011
7012 fei = fib_table_entry_path_add(fib_index,
7013 &pfx_2_2_2_2_s_32,
7014 FIB_SOURCE_API,
7015 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07007016 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007017 &pfx_1_1_1_2_s_32.fp_addr,
7018 ~0,
7019 fib_index,
7020 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00007021 l1601,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007022 FIB_ROUTE_PATH_FLAG_NONE);
7023
7024 FIB_TEST(fib_test_validate_entry(fei,
7025 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7026 2,
7027 &l1600_eos_o_1_1_1_1,
7028 &l1601_eos_o_1_1_1_2),
7029 "2.2.2.2/32 LB 2 buckets via: "
7030 "label 1600 via 1.1,1.1, "
7031 "label 16001 via 1.1.1.2");
7032
7033 /*
7034 * update the via-entry so it no longer has an imp-null path.
7035 * the LB for the recursive can use an imp-null
7036 */
Neale Rannsad422ed2016-11-02 14:20:04 +00007037 l_imp_null = NULL;
Neale Ranns31ed7442018-02-23 05:29:09 -08007038 vec_add1(l_imp_null, fml_imp_null);
Neale Rannsad422ed2016-11-02 14:20:04 +00007039
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007040 fei = fib_table_entry_update_one_path(fib_index,
7041 &pfx_1_1_1_2_s_32,
7042 FIB_SOURCE_API,
7043 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07007044 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007045 &nh_10_10_11_1,
7046 tm->hw[1]->sw_if_index,
7047 ~0, // invalid fib index
7048 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00007049 l_imp_null,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007050 FIB_ROUTE_PATH_FLAG_NONE);
7051
7052 FIB_TEST(fib_test_validate_entry(fei,
7053 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7054 1,
7055 &a_o_10_10_11_1),
7056 "1.1.1.2/32 LB 1 buckets via: "
7057 "adj 10.10.11.1");
7058
7059 fei = fib_table_lookup(fib_index, &pfx_2_2_2_2_s_32);
7060 FIB_TEST(fib_test_validate_entry(fei,
7061 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7062 2,
7063 &l1600_eos_o_1_1_1_1,
7064 &l1601_eos_o_1_1_1_2),
7065 "2.2.2.2/32 LB 2 buckets via: "
7066 "label 1600 via 1.1,1.1, "
7067 "label 16001 via 1.1.1.2");
7068
7069 /*
7070 * update the via-entry so it no longer has labelled paths.
7071 * the LB for the recursive should exclue this via form its LB
7072 */
7073 fei = fib_table_entry_update_one_path(fib_index,
7074 &pfx_1_1_1_2_s_32,
7075 FIB_SOURCE_API,
7076 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07007077 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007078 &nh_10_10_11_1,
7079 tm->hw[1]->sw_if_index,
7080 ~0, // invalid fib index
7081 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00007082 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007083 FIB_ROUTE_PATH_FLAG_NONE);
7084
7085 FIB_TEST(fib_test_validate_entry(fei,
7086 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7087 1,
7088 &a_o_10_10_11_1),
7089 "1.1.1.2/32 LB 1 buckets via: "
7090 "adj 10.10.11.1");
7091
7092 fei = fib_table_lookup(fib_index, &pfx_2_2_2_2_s_32);
7093 FIB_TEST(fib_test_validate_entry(fei,
7094 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7095 1,
7096 &l1600_eos_o_1_1_1_1),
7097 "2.2.2.2/32 LB 1 buckets via: "
7098 "label 1600 via 1.1,1.1");
7099
7100 dpo_reset(&non_eos_1_1_1_1);
7101 dpo_reset(&non_eos_1_1_1_2);
7102
7103 /*
7104 * Add a recursive with no out-labels. We expect to use the IP of the via
7105 */
7106 fib_prefix_t pfx_2_2_2_3_s_32 = {
7107 .fp_len = 32,
7108 .fp_proto = FIB_PROTOCOL_IP4,
7109 .fp_addr = {
7110 .ip4.as_u32 = clib_host_to_net_u32(0x02020203),
7111 },
7112 };
Neale Ranns948e00f2016-10-20 13:39:34 +01007113 dpo_id_t ip_1_1_1_1 = DPO_INVALID;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007114
7115 fib_table_entry_update_one_path(fib_index,
7116 &pfx_2_2_2_3_s_32,
7117 FIB_SOURCE_API,
7118 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07007119 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007120 &pfx_1_1_1_1_s_32.fp_addr,
7121 ~0,
7122 fib_index,
7123 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00007124 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007125 FIB_ROUTE_PATH_FLAG_NONE);
7126
7127 fib_entry_contribute_forwarding(fib_table_lookup(fib_index,
7128 &pfx_1_1_1_1_s_32),
7129 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7130 &ip_1_1_1_1);
7131
7132 fib_test_lb_bucket_t ip_o_1_1_1_1 = {
7133 .type = FT_LB_O_LB,
7134 .lb = {
7135 .lb = ip_1_1_1_1.dpoi_index,
7136 },
7137 };
7138
7139 fei = fib_table_lookup(fib_index, &pfx_2_2_2_3_s_32);
7140 FIB_TEST(fib_test_validate_entry(fei,
7141 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7142 1,
7143 &ip_o_1_1_1_1),
7144 "2.2.2.2.3/32 LB 1 buckets via: "
7145 "ip 1.1.1.1");
7146
7147 /*
7148 * Add a recursive with an imp-null out-label.
7149 * We expect to use the IP of the via
7150 */
7151 fib_prefix_t pfx_2_2_2_4_s_32 = {
7152 .fp_len = 32,
7153 .fp_proto = FIB_PROTOCOL_IP4,
7154 .fp_addr = {
7155 .ip4.as_u32 = clib_host_to_net_u32(0x02020204),
7156 },
7157 };
7158
7159 fib_table_entry_update_one_path(fib_index,
7160 &pfx_2_2_2_4_s_32,
7161 FIB_SOURCE_API,
7162 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07007163 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007164 &pfx_1_1_1_1_s_32.fp_addr,
7165 ~0,
7166 fib_index,
7167 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00007168 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007169 FIB_ROUTE_PATH_FLAG_NONE);
7170
7171 fei = fib_table_lookup(fib_index, &pfx_2_2_2_4_s_32);
7172 FIB_TEST(fib_test_validate_entry(fei,
7173 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7174 1,
7175 &ip_o_1_1_1_1),
7176 "2.2.2.2.4/32 LB 1 buckets via: "
7177 "ip 1.1.1.1");
7178
7179 dpo_reset(&ip_1_1_1_1);
7180
7181 /*
Neale Rannsad422ed2016-11-02 14:20:04 +00007182 * Create an entry with a deep label stack
7183 */
7184 fib_prefix_t pfx_2_2_5_5_s_32 = {
7185 .fp_len = 32,
7186 .fp_proto = FIB_PROTOCOL_IP4,
7187 .fp_addr = {
7188 .ip4.as_u32 = clib_host_to_net_u32(0x02020505),
7189 },
7190 };
7191 fib_test_lb_bucket_t ls_eos_o_10_10_10_1 = {
7192 .type = FT_LB_LABEL_STACK_O_ADJ,
7193 .label_stack_o_adj = {
7194 .adj = ai_mpls_10_10_11_1,
7195 .label_stack_size = 8,
7196 .label_stack = {
7197 200, 201, 202, 203, 204, 205, 206, 207
7198 },
7199 .eos = MPLS_EOS,
7200 },
7201 };
Neale Ranns31ed7442018-02-23 05:29:09 -08007202 fib_mpls_label_t *label_stack = NULL;
Neale Rannsad422ed2016-11-02 14:20:04 +00007203 vec_validate(label_stack, 7);
7204 for (ii = 0; ii < 8; ii++)
7205 {
Neale Ranns31ed7442018-02-23 05:29:09 -08007206 label_stack[ii].fml_value = ii + 200;
Neale Rannsad422ed2016-11-02 14:20:04 +00007207 }
7208
7209 fei = fib_table_entry_update_one_path(fib_index,
7210 &pfx_2_2_5_5_s_32,
7211 FIB_SOURCE_API,
7212 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07007213 DPO_PROTO_IP4,
Neale Rannsad422ed2016-11-02 14:20:04 +00007214 &nh_10_10_11_1,
7215 tm->hw[1]->sw_if_index,
7216 ~0, // invalid fib index
7217 1,
7218 label_stack,
7219 FIB_ROUTE_PATH_FLAG_NONE);
7220
7221 FIB_TEST(fib_test_validate_entry(fei,
7222 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7223 1,
7224 &ls_eos_o_10_10_10_1),
7225 "2.2.5.5/32 LB 1 buckets via: "
7226 "adj 10.10.11.1");
7227 fib_table_entry_delete_index(fei, FIB_SOURCE_API);
7228
7229 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007230 * cleanup
7231 */
7232 fib_table_entry_delete(fib_index,
7233 &pfx_1_1_1_2_s_32,
7234 FIB_SOURCE_API);
7235
7236 fei = fib_table_lookup(fib_index, &pfx_2_2_2_2_s_32);
7237 FIB_TEST(fib_test_validate_entry(fei,
7238 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7239 1,
7240 &l1600_eos_o_1_1_1_1),
7241 "2.2.2.2/32 LB 1 buckets via: "
7242 "label 1600 via 1.1,1.1");
7243
7244 fib_table_entry_delete(fib_index,
7245 &pfx_1_1_1_1_s_32,
7246 FIB_SOURCE_API);
7247
7248 FIB_TEST(fib_test_validate_entry(fei,
7249 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7250 1,
7251 &bucket_drop),
7252 "2.2.2.2/32 LB 1 buckets via: DROP");
7253
7254 fib_table_entry_delete(fib_index,
7255 &pfx_2_2_2_2_s_32,
7256 FIB_SOURCE_API);
7257 fib_table_entry_delete(fib_index,
7258 &pfx_2_2_2_3_s_32,
7259 FIB_SOURCE_API);
7260 fib_table_entry_delete(fib_index,
7261 &pfx_2_2_2_4_s_32,
7262 FIB_SOURCE_API);
7263
7264 adj_unlock(ai_mpls_10_10_10_1);
7265 adj_unlock(ai_mpls_10_10_11_2);
7266 adj_unlock(ai_v4_10_10_11_1);
7267 adj_unlock(ai_v4_10_10_11_2);
7268 adj_unlock(ai_mpls_10_10_11_1);
7269
7270 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
7271 adj_nbr_db_size());
7272
7273 local0_pfx.fp_len = 32;
7274 fib_table_entry_delete(fib_index,
7275 &local0_pfx,
7276 FIB_SOURCE_INTERFACE);
7277 local0_pfx.fp_len = 24;
7278 fib_table_entry_delete(fib_index,
7279 &local0_pfx,
7280 FIB_SOURCE_INTERFACE);
7281 local1_pfx.fp_len = 32;
7282 fib_table_entry_delete(fib_index,
7283 &local1_pfx,
7284 FIB_SOURCE_INTERFACE);
7285 local1_pfx.fp_len = 24;
7286 fib_table_entry_delete(fib_index,
7287 &local1_pfx,
7288 FIB_SOURCE_INTERFACE);
7289
7290 /*
7291 * +1 for the drop LB in the MPLS tables.
7292 */
7293 FIB_TEST(lb_count+1 == pool_elts(load_balance_pool),
7294 "Load-balance resources freed %d of %d",
7295 lb_count+1, pool_elts(load_balance_pool));
Neale Ranns0ebe8d72016-12-08 19:48:11 +00007296
7297 return (0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007298}
7299
7300#define N_TEST_CHILDREN 4
7301#define PARENT_INDEX 0
7302
7303typedef struct fib_node_test_t_
7304{
7305 fib_node_t node;
7306 u32 sibling;
7307 u32 index;
7308 fib_node_back_walk_ctx_t *ctxs;
7309 u32 destroyed;
7310} fib_node_test_t;
7311
7312static fib_node_test_t fib_test_nodes[N_TEST_CHILDREN+1];
7313
7314#define PARENT() (&fib_test_nodes[PARENT_INDEX].node)
7315
7316#define FOR_EACH_TEST_CHILD(_tc) \
7317 for (ii = 1, (_tc) = &fib_test_nodes[1]; \
7318 ii < N_TEST_CHILDREN+1; \
7319 ii++, (_tc) = &fib_test_nodes[ii])
7320
7321static fib_node_t *
7322fib_test_child_get_node (fib_node_index_t index)
7323{
7324 return (&fib_test_nodes[index].node);
7325}
7326
7327static int fib_test_walk_spawns_walks;
7328
7329static fib_node_back_walk_rc_t
7330fib_test_child_back_walk_notify (fib_node_t *node,
7331 fib_node_back_walk_ctx_t *ctx)
7332{
7333 fib_node_test_t *tc = (fib_node_test_t*) node;
7334
7335 vec_add1(tc->ctxs, *ctx);
7336
7337 if (1 == fib_test_walk_spawns_walks)
7338 fib_walk_sync(FIB_NODE_TYPE_TEST, tc->index, ctx);
7339 if (2 == fib_test_walk_spawns_walks)
7340 fib_walk_async(FIB_NODE_TYPE_TEST, tc->index,
7341 FIB_WALK_PRIORITY_HIGH, ctx);
7342
7343 return (FIB_NODE_BACK_WALK_CONTINUE);
7344}
7345
7346static void
7347fib_test_child_last_lock_gone (fib_node_t *node)
7348{
7349 fib_node_test_t *tc = (fib_node_test_t *)node;
7350
7351 tc->destroyed = 1;
7352}
7353
7354/**
7355 * The FIB walk's graph node virtual function table
7356 */
7357static const fib_node_vft_t fib_test_child_vft = {
7358 .fnv_get = fib_test_child_get_node,
7359 .fnv_last_lock = fib_test_child_last_lock_gone,
7360 .fnv_back_walk = fib_test_child_back_walk_notify,
7361};
7362
7363/*
7364 * the function (that should have been static but isn't so I can do this)
7365 * that processes the walk from the async queue,
7366 */
7367f64 fib_walk_process_queues(vlib_main_t * vm,
7368 const f64 quota);
7369u32 fib_walk_queue_get_size(fib_walk_priority_t prio);
7370
Neale Ranns0ebe8d72016-12-08 19:48:11 +00007371static int
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007372fib_test_walk (void)
7373{
7374 fib_node_back_walk_ctx_t high_ctx = {}, low_ctx = {};
7375 fib_node_test_t *tc;
7376 vlib_main_t *vm;
7377 u32 ii;
7378
7379 vm = vlib_get_main();
7380 fib_node_register_type(FIB_NODE_TYPE_TEST, &fib_test_child_vft);
7381
7382 /*
7383 * init a fake node on which we will add children
7384 */
7385 fib_node_init(&fib_test_nodes[PARENT_INDEX].node,
7386 FIB_NODE_TYPE_TEST);
7387
7388 FOR_EACH_TEST_CHILD(tc)
7389 {
7390 fib_node_init(&tc->node, FIB_NODE_TYPE_TEST);
7391 fib_node_lock(&tc->node);
7392 tc->ctxs = NULL;
7393 tc->index = ii;
7394 tc->sibling = fib_node_child_add(FIB_NODE_TYPE_TEST,
7395 PARENT_INDEX,
7396 FIB_NODE_TYPE_TEST, ii);
7397 }
7398
7399 /*
7400 * enqueue a walk across the parents children.
7401 */
Neale Ranns450cd302016-11-09 17:49:42 +00007402 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007403
7404 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7405 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7406 FIB_TEST(N_TEST_CHILDREN+1 == fib_node_list_get_size(PARENT()->fn_children),
7407 "Parent has %d children pre-walk",
7408 fib_node_list_get_size(PARENT()->fn_children));
7409
7410 /*
7411 * give the walk a large amount of time so it gets to the end
7412 */
7413 fib_walk_process_queues(vm, 1);
7414
7415 FOR_EACH_TEST_CHILD(tc)
7416 {
7417 FIB_TEST(1 == vec_len(tc->ctxs),
7418 "%d child visitsed %d times",
7419 ii, vec_len(tc->ctxs));
7420 vec_free(tc->ctxs);
7421 }
7422 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7423 "Queue is empty post walk");
7424 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7425 "Parent has %d children post walk",
7426 fib_node_list_get_size(PARENT()->fn_children));
7427
7428 /*
7429 * walk again. should be no increase in the number of visits, since
7430 * the walk will have terminated.
7431 */
7432 fib_walk_process_queues(vm, 1);
7433
7434 FOR_EACH_TEST_CHILD(tc)
7435 {
7436 FIB_TEST(0 == vec_len(tc->ctxs),
7437 "%d child visitsed %d times",
7438 ii, vec_len(tc->ctxs));
7439 }
7440
7441 /*
7442 * schedule a low and hig priority walk. expect the high to be performed
7443 * before the low.
7444 * schedule the high prio walk first so that it is further from the head
7445 * of the dependency list. that way it won't merge with the low one.
7446 */
7447 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
7448 low_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_ADJ_UPDATE;
7449
7450 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7451 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7452 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7453 FIB_WALK_PRIORITY_LOW, &low_ctx);
7454
7455 fib_walk_process_queues(vm, 1);
7456
7457 FOR_EACH_TEST_CHILD(tc)
7458 {
7459 FIB_TEST(high_ctx.fnbw_reason == tc->ctxs[0].fnbw_reason,
7460 "%d child visitsed by high prio walk", ii);
7461 FIB_TEST(low_ctx.fnbw_reason == tc->ctxs[1].fnbw_reason,
7462 "%d child visitsed by low prio walk", ii);
7463 vec_free(tc->ctxs);
7464 }
7465 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7466 "Queue is empty post prio walk");
7467 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7468 "Parent has %d children post prio walk",
7469 fib_node_list_get_size(PARENT()->fn_children));
7470
7471 /*
7472 * schedule 2 walks of the same priority that can be megred.
7473 * expect that each child is thus visited only once.
7474 */
7475 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
7476 low_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
7477
7478 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7479 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7480 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7481 FIB_WALK_PRIORITY_HIGH, &low_ctx);
7482
7483 fib_walk_process_queues(vm, 1);
7484
7485 FOR_EACH_TEST_CHILD(tc)
7486 {
7487 FIB_TEST(1 == vec_len(tc->ctxs),
7488 "%d child visitsed %d times during merge walk",
7489 ii, vec_len(tc->ctxs));
7490 vec_free(tc->ctxs);
7491 }
7492 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7493 "Queue is empty post merge walk");
7494 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7495 "Parent has %d children post merge walk",
7496 fib_node_list_get_size(PARENT()->fn_children));
7497
7498 /*
7499 * schedule 2 walks of the same priority that cannot be megred.
7500 * expect that each child is thus visited twice and in the order
7501 * in which the walks were scheduled.
7502 */
7503 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
7504 low_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_ADJ_UPDATE;
7505
7506 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7507 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7508 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7509 FIB_WALK_PRIORITY_HIGH, &low_ctx);
7510
7511 fib_walk_process_queues(vm, 1);
7512
7513 FOR_EACH_TEST_CHILD(tc)
7514 {
7515 FIB_TEST(high_ctx.fnbw_reason == tc->ctxs[0].fnbw_reason,
7516 "%d child visitsed by high prio walk", ii);
7517 FIB_TEST(low_ctx.fnbw_reason == tc->ctxs[1].fnbw_reason,
7518 "%d child visitsed by low prio walk", ii);
7519 vec_free(tc->ctxs);
7520 }
7521 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7522 "Queue is empty post no-merge walk");
7523 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7524 "Parent has %d children post no-merge walk",
7525 fib_node_list_get_size(PARENT()->fn_children));
7526
7527 /*
7528 * schedule a walk that makes one one child progress.
7529 * we do this by giving the queue draining process zero
7530 * time quanta. it's a do..while loop, so it does something.
7531 */
Neale Ranns450cd302016-11-09 17:49:42 +00007532 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007533
7534 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7535 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7536 fib_walk_process_queues(vm, 0);
7537
7538 FOR_EACH_TEST_CHILD(tc)
7539 {
7540 if (ii == N_TEST_CHILDREN)
7541 {
7542 FIB_TEST(1 == vec_len(tc->ctxs),
7543 "%d child visitsed %d times in zero quanta walk",
7544 ii, vec_len(tc->ctxs));
7545 }
7546 else
7547 {
7548 FIB_TEST(0 == vec_len(tc->ctxs),
7549 "%d child visitsed %d times in 0 quanta walk",
7550 ii, vec_len(tc->ctxs));
7551 }
7552 }
7553 FIB_TEST(1 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7554 "Queue is not empty post zero quanta walk");
7555 FIB_TEST(N_TEST_CHILDREN+1 == fib_node_list_get_size(PARENT()->fn_children),
7556 "Parent has %d children post zero qunta walk",
7557 fib_node_list_get_size(PARENT()->fn_children));
7558
7559 /*
7560 * another one step
7561 */
7562 fib_walk_process_queues(vm, 0);
7563
7564 FOR_EACH_TEST_CHILD(tc)
7565 {
7566 if (ii >= N_TEST_CHILDREN-1)
7567 {
7568 FIB_TEST(1 == vec_len(tc->ctxs),
7569 "%d child visitsed %d times in 2nd zero quanta walk",
7570 ii, vec_len(tc->ctxs));
7571 }
7572 else
7573 {
7574 FIB_TEST(0 == vec_len(tc->ctxs),
7575 "%d child visitsed %d times in 2nd 0 quanta walk",
7576 ii, vec_len(tc->ctxs));
7577 }
7578 }
7579 FIB_TEST(1 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7580 "Queue is not empty post zero quanta walk");
7581 FIB_TEST(N_TEST_CHILDREN+1 == fib_node_list_get_size(PARENT()->fn_children),
7582 "Parent has %d children post zero qunta walk",
7583 fib_node_list_get_size(PARENT()->fn_children));
7584
7585 /*
7586 * schedule another walk that will catch-up and merge.
7587 */
7588 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7589 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7590 fib_walk_process_queues(vm, 1);
7591
7592 FOR_EACH_TEST_CHILD(tc)
7593 {
7594 if (ii >= N_TEST_CHILDREN-1)
7595 {
7596 FIB_TEST(2 == vec_len(tc->ctxs),
7597 "%d child visitsed %d times in 2nd zero quanta merge walk",
7598 ii, vec_len(tc->ctxs));
7599 vec_free(tc->ctxs);
7600 }
7601 else
7602 {
7603 FIB_TEST(1 == vec_len(tc->ctxs),
7604 "%d child visitsed %d times in 2nd 0 quanta merge walk",
7605 ii, vec_len(tc->ctxs));
7606 vec_free(tc->ctxs);
7607 }
7608 }
7609 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7610 "Queue is not empty post 2nd zero quanta merge walk");
7611 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7612 "Parent has %d children post 2nd zero qunta merge walk",
7613 fib_node_list_get_size(PARENT()->fn_children));
7614
7615 /*
7616 * park a async walk in the middle of the list, then have an sync walk catch
7617 * it. same expectations as async catches async.
7618 */
Neale Ranns450cd302016-11-09 17:49:42 +00007619 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007620
7621 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7622 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7623
7624 fib_walk_process_queues(vm, 0);
7625 fib_walk_process_queues(vm, 0);
7626
7627 fib_walk_sync(FIB_NODE_TYPE_TEST, PARENT_INDEX, &high_ctx);
7628
7629 FOR_EACH_TEST_CHILD(tc)
7630 {
7631 if (ii >= N_TEST_CHILDREN-1)
7632 {
7633 FIB_TEST(2 == vec_len(tc->ctxs),
7634 "%d child visitsed %d times in sync catches async walk",
7635 ii, vec_len(tc->ctxs));
7636 vec_free(tc->ctxs);
7637 }
7638 else
7639 {
7640 FIB_TEST(1 == vec_len(tc->ctxs),
7641 "%d child visitsed %d times in sync catches async walk",
7642 ii, vec_len(tc->ctxs));
7643 vec_free(tc->ctxs);
7644 }
7645 }
7646 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7647 "Queue is not empty post 2nd zero quanta merge walk");
7648 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7649 "Parent has %d children post 2nd zero qunta merge walk",
7650 fib_node_list_get_size(PARENT()->fn_children));
7651
7652 /*
7653 * make the parent a child of one of its children, thus inducing a routing loop.
7654 */
7655 fib_test_nodes[PARENT_INDEX].sibling =
7656 fib_node_child_add(FIB_NODE_TYPE_TEST,
7657 1, // the first child
7658 FIB_NODE_TYPE_TEST,
7659 PARENT_INDEX);
7660
7661 /*
7662 * execute a sync walk from the parent. each child visited spawns more sync
7663 * walks. we expect the walk to terminate.
7664 */
7665 fib_test_walk_spawns_walks = 1;
7666
7667 fib_walk_sync(FIB_NODE_TYPE_TEST, PARENT_INDEX, &high_ctx);
7668
7669 FOR_EACH_TEST_CHILD(tc)
7670 {
7671 /*
7672 * child 1 - which is last in the list - has the loop.
7673 * the other children a re thus visitsed first. the we meet
7674 * child 1. we go round the loop again, visting the other children.
7675 * then we meet the walk in the dep list and bail. child 1 is not visitsed
7676 * again.
7677 */
7678 if (1 == ii)
7679 {
7680 FIB_TEST(1 == vec_len(tc->ctxs),
7681 "child %d visitsed %d times during looped sync walk",
7682 ii, vec_len(tc->ctxs));
7683 }
7684 else
7685 {
7686 FIB_TEST(2 == vec_len(tc->ctxs),
7687 "child %d visitsed %d times during looped sync walk",
7688 ii, vec_len(tc->ctxs));
7689 }
7690 vec_free(tc->ctxs);
7691 }
7692 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7693 "Parent has %d children post sync loop walk",
7694 fib_node_list_get_size(PARENT()->fn_children));
7695
7696 /*
7697 * the walk doesn't reach the max depth because the infra knows that sync
7698 * meets sync implies a loop and bails early.
7699 */
7700 FIB_TEST(high_ctx.fnbw_depth == 9,
7701 "Walk context depth %d post sync loop walk",
7702 high_ctx.fnbw_depth);
7703
7704 /*
7705 * execute an async walk of the graph loop, with each child spawns sync walks
7706 */
7707 high_ctx.fnbw_depth = 0;
7708 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7709 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7710
7711 fib_walk_process_queues(vm, 1);
7712
7713 FOR_EACH_TEST_CHILD(tc)
7714 {
7715 /*
7716 * we don't really care how many times the children are visisted, as long as
7717 * it is more than once.
7718 */
7719 FIB_TEST(1 <= vec_len(tc->ctxs),
7720 "child %d visitsed %d times during looped aync spawns sync walk",
7721 ii, vec_len(tc->ctxs));
7722 vec_free(tc->ctxs);
7723 }
7724
7725 /*
7726 * execute an async walk of the graph loop, with each child spawns async walks
7727 */
7728 fib_test_walk_spawns_walks = 2;
7729 high_ctx.fnbw_depth = 0;
7730 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7731 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7732
7733 fib_walk_process_queues(vm, 1);
7734
7735 FOR_EACH_TEST_CHILD(tc)
7736 {
7737 /*
7738 * we don't really care how many times the children are visisted, as long as
7739 * it is more than once.
7740 */
7741 FIB_TEST(1 <= vec_len(tc->ctxs),
7742 "child %d visitsed %d times during looped async spawns async walk",
7743 ii, vec_len(tc->ctxs));
7744 vec_free(tc->ctxs);
7745 }
7746
7747
7748 fib_node_child_remove(FIB_NODE_TYPE_TEST,
7749 1, // the first child
7750 fib_test_nodes[PARENT_INDEX].sibling);
7751
7752 /*
7753 * cleanup
7754 */
7755 FOR_EACH_TEST_CHILD(tc)
7756 {
7757 fib_node_child_remove(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7758 tc->sibling);
7759 fib_node_deinit(&tc->node);
7760 fib_node_unlock(&tc->node);
7761 }
7762 fib_node_deinit(PARENT());
7763
7764 /*
7765 * The parent will be destroyed when the last lock on it goes.
7766 * this test ensures all the walk objects are unlocking it.
7767 */
7768 FIB_TEST((1 == fib_test_nodes[PARENT_INDEX].destroyed),
7769 "Parent was destroyed");
Neale Ranns0ebe8d72016-12-08 19:48:11 +00007770
7771 return (0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007772}
7773
Neale Ranns88fc83e2017-04-05 08:11:14 -07007774/*
7775 * declaration of the otherwise static callback functions
7776 */
7777void fib_bfd_notify (bfd_listen_event_e event,
7778 const bfd_session_t *session);
7779void adj_bfd_notify (bfd_listen_event_e event,
7780 const bfd_session_t *session);
7781
7782/**
7783 * Test BFD session interaction with FIB
7784 */
7785static int
7786fib_test_bfd (void)
7787{
7788 fib_node_index_t fei;
7789 test_main_t *tm;
7790 int n_feis;
7791
7792 /* via 10.10.10.1 */
7793 ip46_address_t nh_10_10_10_1 = {
7794 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
7795 };
7796 /* via 10.10.10.2 */
7797 ip46_address_t nh_10_10_10_2 = {
7798 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02),
7799 };
7800 /* via 10.10.10.10 */
7801 ip46_address_t nh_10_10_10_10 = {
7802 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a0a),
7803 };
7804 n_feis = fib_entry_pool_size();
7805
7806 tm = &test_main;
7807
7808 /*
7809 * add interface routes. we'll assume this works. it's tested elsewhere
7810 */
7811 fib_prefix_t pfx_10_10_10_10_s_24 = {
7812 .fp_len = 24,
7813 .fp_proto = FIB_PROTOCOL_IP4,
7814 .fp_addr = nh_10_10_10_10,
7815 };
7816
7817 fib_table_entry_update_one_path(0, &pfx_10_10_10_10_s_24,
7818 FIB_SOURCE_INTERFACE,
7819 (FIB_ENTRY_FLAG_CONNECTED |
7820 FIB_ENTRY_FLAG_ATTACHED),
Neale Rannsda78f952017-05-24 09:15:43 -07007821 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07007822 NULL,
7823 tm->hw[0]->sw_if_index,
7824 ~0, // invalid fib index
7825 1, // weight
7826 NULL,
7827 FIB_ROUTE_PATH_FLAG_NONE);
7828
7829 fib_prefix_t pfx_10_10_10_10_s_32 = {
7830 .fp_len = 32,
7831 .fp_proto = FIB_PROTOCOL_IP4,
7832 .fp_addr = nh_10_10_10_10,
7833 };
7834 fib_table_entry_update_one_path(0, &pfx_10_10_10_10_s_32,
7835 FIB_SOURCE_INTERFACE,
7836 (FIB_ENTRY_FLAG_CONNECTED |
7837 FIB_ENTRY_FLAG_LOCAL),
Neale Rannsda78f952017-05-24 09:15:43 -07007838 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07007839 NULL,
7840 tm->hw[0]->sw_if_index,
7841 ~0, // invalid fib index
7842 1, // weight
7843 NULL,
7844 FIB_ROUTE_PATH_FLAG_NONE);
7845
7846 /*
7847 * A BFD session via a neighbour we do not yet know
7848 */
7849 bfd_session_t bfd_10_10_10_1 = {
7850 .udp = {
7851 .key = {
7852 .fib_index = 0,
7853 .peer_addr = nh_10_10_10_1,
7854 },
7855 },
7856 .hop_type = BFD_HOP_TYPE_MULTI,
7857 .local_state = BFD_STATE_init,
7858 };
7859
7860 fib_bfd_notify (BFD_LISTEN_EVENT_CREATE, &bfd_10_10_10_1);
7861
7862 /*
7863 * A new entry will be created that forwards via the adj
7864 */
7865 adj_index_t ai_10_10_10_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
7866 VNET_LINK_IP4,
7867 &nh_10_10_10_1,
7868 tm->hw[0]->sw_if_index);
7869 fib_prefix_t pfx_10_10_10_1_s_32 = {
7870 .fp_addr = nh_10_10_10_1,
7871 .fp_len = 32,
7872 .fp_proto = FIB_PROTOCOL_IP4,
7873 };
7874 fib_test_lb_bucket_t adj_o_10_10_10_1 = {
7875 .type = FT_LB_ADJ,
7876 .adj = {
7877 .adj = ai_10_10_10_1,
7878 },
7879 };
7880
7881 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_1_s_32);
7882 FIB_TEST(fib_test_validate_entry(fei,
7883 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7884 1,
7885 &adj_o_10_10_10_1),
7886 "BFD sourced %U via %U",
7887 format_fib_prefix, &pfx_10_10_10_1_s_32,
7888 format_ip_adjacency, ai_10_10_10_1, FORMAT_IP_ADJACENCY_NONE);
7889
7890 /*
7891 * Delete the BFD session. Expect the fib_entry to be removed
7892 */
7893 fib_bfd_notify (BFD_LISTEN_EVENT_DELETE, &bfd_10_10_10_1);
7894
7895 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_1_s_32);
7896 FIB_TEST(FIB_NODE_INDEX_INVALID == fei,
7897 "BFD sourced %U removed",
7898 format_fib_prefix, &pfx_10_10_10_1_s_32);
7899
7900 /*
7901 * Add the BFD source back
7902 */
7903 fib_bfd_notify (BFD_LISTEN_EVENT_CREATE, &bfd_10_10_10_1);
7904
7905 /*
7906 * source the entry via the ADJ fib
7907 */
Neale Ranns81424992017-05-18 03:03:22 -07007908 fei = fib_table_entry_path_add(0,
7909 &pfx_10_10_10_1_s_32,
7910 FIB_SOURCE_ADJ,
7911 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07007912 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07007913 &nh_10_10_10_1,
7914 tm->hw[0]->sw_if_index,
7915 ~0, // invalid fib index
7916 1,
7917 NULL,
7918 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns88fc83e2017-04-05 08:11:14 -07007919
7920 /*
7921 * Delete the BFD session. Expect the fib_entry to remain
7922 */
7923 fib_bfd_notify (BFD_LISTEN_EVENT_DELETE, &bfd_10_10_10_1);
7924
7925 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_1_s_32);
7926 FIB_TEST(fib_test_validate_entry(fei,
7927 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7928 1,
7929 &adj_o_10_10_10_1),
7930 "BFD sourced %U remains via %U",
7931 format_fib_prefix, &pfx_10_10_10_1_s_32,
7932 format_ip_adjacency, ai_10_10_10_1, FORMAT_IP_ADJACENCY_NONE);
7933
7934 /*
7935 * Add the BFD source back
7936 */
7937 fib_bfd_notify (BFD_LISTEN_EVENT_CREATE, &bfd_10_10_10_1);
7938
7939 /*
7940 * Create another ADJ FIB
7941 */
7942 fib_prefix_t pfx_10_10_10_2_s_32 = {
7943 .fp_addr = nh_10_10_10_2,
7944 .fp_len = 32,
7945 .fp_proto = FIB_PROTOCOL_IP4,
7946 };
Neale Ranns81424992017-05-18 03:03:22 -07007947 fib_table_entry_path_add(0,
7948 &pfx_10_10_10_2_s_32,
7949 FIB_SOURCE_ADJ,
7950 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07007951 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07007952 &nh_10_10_10_2,
7953 tm->hw[0]->sw_if_index,
7954 ~0, // invalid fib index
7955 1,
7956 NULL,
7957 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns88fc83e2017-04-05 08:11:14 -07007958 /*
7959 * A BFD session for the new ADJ FIB
7960 */
7961 bfd_session_t bfd_10_10_10_2 = {
7962 .udp = {
7963 .key = {
7964 .fib_index = 0,
7965 .peer_addr = nh_10_10_10_2,
7966 },
7967 },
7968 .hop_type = BFD_HOP_TYPE_MULTI,
7969 .local_state = BFD_STATE_init,
7970 };
7971
7972 fib_bfd_notify (BFD_LISTEN_EVENT_CREATE, &bfd_10_10_10_2);
7973
7974 /*
7975 * remove the adj-fib source whilst the session is present
7976 * then add it back
7977 */
7978 fib_table_entry_delete(0, &pfx_10_10_10_2_s_32, FIB_SOURCE_ADJ);
Neale Ranns81424992017-05-18 03:03:22 -07007979 fib_table_entry_path_add(0,
7980 &pfx_10_10_10_2_s_32,
7981 FIB_SOURCE_ADJ,
7982 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07007983 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07007984 &nh_10_10_10_2,
7985 tm->hw[0]->sw_if_index,
7986 ~0, // invalid fib index
7987 1,
7988 NULL,
7989 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns88fc83e2017-04-05 08:11:14 -07007990
7991 /*
7992 * Before adding a recursive via the BFD tracked ADJ-FIBs,
7993 * bring one of the sessions UP, leave the other down
7994 */
7995 bfd_10_10_10_1.local_state = BFD_STATE_up;
7996 fib_bfd_notify (BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_1);
7997 bfd_10_10_10_2.local_state = BFD_STATE_down;
7998 fib_bfd_notify (BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_2);
7999
8000 /*
8001 * A recursive prefix via both of the ADJ FIBs
8002 */
8003 fib_prefix_t pfx_200_0_0_0_s_24 = {
8004 .fp_proto = FIB_PROTOCOL_IP4,
8005 .fp_len = 32,
8006 .fp_addr = {
8007 .ip4.as_u32 = clib_host_to_net_u32(0xc8000000),
8008 },
8009 };
8010 const dpo_id_t *dpo_10_10_10_1, *dpo_10_10_10_2;
8011
8012 dpo_10_10_10_1 =
8013 fib_entry_contribute_ip_forwarding(
8014 fib_table_lookup_exact_match(0, &pfx_10_10_10_1_s_32));
8015 dpo_10_10_10_2 =
8016 fib_entry_contribute_ip_forwarding(
8017 fib_table_lookup_exact_match(0, &pfx_10_10_10_2_s_32));
8018
8019 fib_test_lb_bucket_t lb_o_10_10_10_1 = {
8020 .type = FT_LB_O_LB,
8021 .lb = {
8022 .lb = dpo_10_10_10_1->dpoi_index,
8023 },
8024 };
8025 fib_test_lb_bucket_t lb_o_10_10_10_2 = {
8026 .type = FT_LB_O_LB,
8027 .lb = {
8028 .lb = dpo_10_10_10_2->dpoi_index,
8029 },
8030 };
8031
8032 /*
8033 * A prefix via the adj-fib that is BFD down => DROP
8034 */
8035 fei = fib_table_entry_path_add(0,
8036 &pfx_200_0_0_0_s_24,
8037 FIB_SOURCE_API,
8038 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008039 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07008040 &nh_10_10_10_2,
8041 ~0, // recursive
8042 0, // default fib index
8043 1,
8044 NULL,
8045 FIB_ROUTE_PATH_FLAG_NONE);
8046 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
8047 "%U resolves via drop",
8048 format_fib_prefix, &pfx_200_0_0_0_s_24);
8049
8050 /*
8051 * add a path via the UP BFD adj-fib.
8052 * we expect that the DOWN BFD ADJ FIB is not used.
8053 */
8054 fei = fib_table_entry_path_add(0,
8055 &pfx_200_0_0_0_s_24,
8056 FIB_SOURCE_API,
8057 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008058 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07008059 &nh_10_10_10_1,
8060 ~0, // recursive
8061 0, // default fib index
8062 1,
8063 NULL,
8064 FIB_ROUTE_PATH_FLAG_NONE);
8065
8066 FIB_TEST(fib_test_validate_entry(fei,
8067 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8068 1,
8069 &lb_o_10_10_10_1),
8070 "Recursive %U only UP BFD adj-fibs",
8071 format_fib_prefix, &pfx_200_0_0_0_s_24);
8072
8073 /*
8074 * Send a BFD state change to UP - both sessions are now up
8075 * the recursive prefix should LB over both
8076 */
8077 bfd_10_10_10_2.local_state = BFD_STATE_up;
8078 fib_bfd_notify (BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_2);
8079
8080
8081 FIB_TEST(fib_test_validate_entry(fei,
8082 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8083 2,
8084 &lb_o_10_10_10_1,
8085 &lb_o_10_10_10_2),
8086 "Recursive %U via both UP BFD adj-fibs",
8087 format_fib_prefix, &pfx_200_0_0_0_s_24);
8088
8089 /*
8090 * Send a BFD state change to DOWN
8091 * the recursive prefix should exclude the down
8092 */
8093 bfd_10_10_10_2.local_state = BFD_STATE_down;
8094 fib_bfd_notify (BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_2);
8095
8096
8097 FIB_TEST(fib_test_validate_entry(fei,
8098 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8099 1,
8100 &lb_o_10_10_10_1),
8101 "Recursive %U via only UP",
8102 format_fib_prefix, &pfx_200_0_0_0_s_24);
8103
8104 /*
8105 * Delete the BFD session while it is in the DOWN state.
8106 * FIB should consider the entry's state as back up
8107 */
8108 fib_bfd_notify (BFD_LISTEN_EVENT_DELETE, &bfd_10_10_10_2);
8109
8110 FIB_TEST(fib_test_validate_entry(fei,
8111 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8112 2,
8113 &lb_o_10_10_10_1,
8114 &lb_o_10_10_10_2),
8115 "Recursive %U via both UP BFD adj-fibs post down session delete",
8116 format_fib_prefix, &pfx_200_0_0_0_s_24);
8117
8118 /*
8119 * Delete the BFD other session while it is in the UP state.
8120 */
8121 fib_bfd_notify (BFD_LISTEN_EVENT_DELETE, &bfd_10_10_10_1);
8122
8123 FIB_TEST(fib_test_validate_entry(fei,
8124 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8125 2,
8126 &lb_o_10_10_10_1,
8127 &lb_o_10_10_10_2),
8128 "Recursive %U via both UP BFD adj-fibs post up session delete",
8129 format_fib_prefix, &pfx_200_0_0_0_s_24);
8130
8131 /*
8132 * cleaup
8133 */
8134 fib_table_entry_delete(0, &pfx_200_0_0_0_s_24, FIB_SOURCE_API);
8135 fib_table_entry_delete(0, &pfx_10_10_10_1_s_32, FIB_SOURCE_ADJ);
8136 fib_table_entry_delete(0, &pfx_10_10_10_2_s_32, FIB_SOURCE_ADJ);
8137
8138 fib_table_entry_delete(0, &pfx_10_10_10_10_s_32, FIB_SOURCE_INTERFACE);
8139 fib_table_entry_delete(0, &pfx_10_10_10_10_s_24, FIB_SOURCE_INTERFACE);
8140
8141 adj_unlock(ai_10_10_10_1);
8142 /*
8143 * test no-one left behind
8144 */
8145 FIB_TEST((n_feis == fib_entry_pool_size()), "Entries gone");
8146 FIB_TEST(0 == adj_nbr_db_size(), "All adjacencies removed");
8147
8148 /*
8149 * Single-hop BFD tests
8150 */
8151 bfd_10_10_10_1.hop_type = BFD_HOP_TYPE_SINGLE;
8152 bfd_10_10_10_1.udp.key.sw_if_index = tm->hw[0]->sw_if_index;
8153
8154 adj_bfd_notify(BFD_LISTEN_EVENT_CREATE, &bfd_10_10_10_1);
8155
8156 ai_10_10_10_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
8157 VNET_LINK_IP4,
8158 &nh_10_10_10_1,
8159 tm->hw[0]->sw_if_index);
8160 /*
8161 * whilst the BFD session is not signalled, the adj is up
8162 */
8163 FIB_TEST(adj_is_up(ai_10_10_10_1), "Adj state up on uninit session");
8164
8165 /*
8166 * bring the BFD session up
8167 */
8168 bfd_10_10_10_1.local_state = BFD_STATE_up;
8169 adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_1);
8170 FIB_TEST(adj_is_up(ai_10_10_10_1), "Adj state up on UP session");
8171
8172 /*
8173 * bring the BFD session down
8174 */
8175 bfd_10_10_10_1.local_state = BFD_STATE_down;
8176 adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_1);
8177 FIB_TEST(!adj_is_up(ai_10_10_10_1), "Adj state down on DOWN session");
8178
8179
8180 /*
8181 * add an attached next hop FIB entry via the down adj
8182 */
8183 fib_prefix_t pfx_5_5_5_5_s_32 = {
8184 .fp_addr = {
8185 .ip4 = {
8186 .as_u32 = clib_host_to_net_u32(0x05050505),
8187 },
8188 },
8189 .fp_len = 32,
8190 .fp_proto = FIB_PROTOCOL_IP4,
8191 };
8192
8193 fei = fib_table_entry_path_add(0,
8194 &pfx_5_5_5_5_s_32,
8195 FIB_SOURCE_CLI,
8196 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008197 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07008198 &nh_10_10_10_1,
8199 tm->hw[0]->sw_if_index,
8200 ~0, // invalid fib index
8201 1,
8202 NULL,
8203 FIB_ROUTE_PATH_FLAG_NONE);
8204 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
8205 "%U resolves via drop",
8206 format_fib_prefix, &pfx_5_5_5_5_s_32);
8207
8208 /*
8209 * Add a path via an ADJ that is up
8210 */
8211 adj_index_t ai_10_10_10_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
8212 VNET_LINK_IP4,
8213 &nh_10_10_10_2,
8214 tm->hw[0]->sw_if_index);
8215
8216 fib_test_lb_bucket_t adj_o_10_10_10_2 = {
8217 .type = FT_LB_ADJ,
8218 .adj = {
8219 .adj = ai_10_10_10_2,
8220 },
8221 };
8222 adj_o_10_10_10_1.adj.adj = ai_10_10_10_1;
8223
8224 fei = fib_table_entry_path_add(0,
8225 &pfx_5_5_5_5_s_32,
8226 FIB_SOURCE_CLI,
8227 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008228 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07008229 &nh_10_10_10_2,
8230 tm->hw[0]->sw_if_index,
8231 ~0, // invalid fib index
8232 1,
8233 NULL,
8234 FIB_ROUTE_PATH_FLAG_NONE);
8235
8236 FIB_TEST(fib_test_validate_entry(fei,
8237 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8238 1,
8239 &adj_o_10_10_10_2),
8240 "BFD sourced %U via %U",
8241 format_fib_prefix, &pfx_5_5_5_5_s_32,
8242 format_ip_adjacency, ai_10_10_10_2, FORMAT_IP_ADJACENCY_NONE);
8243
8244 /*
8245 * Bring up the down session - should now LB
8246 */
8247 bfd_10_10_10_1.local_state = BFD_STATE_up;
8248 adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_1);
8249 FIB_TEST(fib_test_validate_entry(fei,
8250 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8251 2,
8252 &adj_o_10_10_10_1,
8253 &adj_o_10_10_10_2),
8254 "BFD sourced %U via noth adjs",
8255 format_fib_prefix, &pfx_5_5_5_5_s_32);
8256
8257 /*
8258 * remove the BFD session state from the adj
8259 */
8260 adj_bfd_notify(BFD_LISTEN_EVENT_DELETE, &bfd_10_10_10_1);
8261
8262 /*
8263 * clean-up
8264 */
8265 fib_table_entry_delete(0, &pfx_5_5_5_5_s_32, FIB_SOURCE_CLI);
8266 adj_unlock(ai_10_10_10_1);
8267 adj_unlock(ai_10_10_10_2);
8268
8269 /*
8270 * test no-one left behind
8271 */
8272 FIB_TEST((n_feis == fib_entry_pool_size()), "Entries gone");
8273 FIB_TEST(0 == adj_nbr_db_size(), "All adjacencies removed");
8274 return (0);
8275}
8276
Neale Ranns0ebe8d72016-12-08 19:48:11 +00008277static int
8278lfib_test (void)
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008279{
8280 const mpls_label_t deag_label = 50;
Neale Ranns31ed7442018-02-23 05:29:09 -08008281 dpo_id_t dpo = DPO_INVALID;
8282 const mpls_disp_dpo_t *mdd;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008283 const u32 lfib_index = 0;
8284 const u32 fib_index = 0;
Neale Ranns31ed7442018-02-23 05:29:09 -08008285 const lookup_dpo_t *lkd;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008286 const dpo_id_t *dpo1;
8287 fib_node_index_t lfe;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008288 test_main_t *tm;
8289 int lb_count;
Neale Rannsad422ed2016-11-02 14:20:04 +00008290 adj_index_t ai_mpls_10_10_10_1;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008291
8292 tm = &test_main;
8293 lb_count = pool_elts(load_balance_pool);
8294
8295 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
8296 adj_nbr_db_size());
8297
8298 /*
8299 * MPLS enable an interface so we get the MPLS table created
8300 */
Neale Ranns2297af02017-09-12 09:45:04 -07008301 mpls_table_create(MPLS_FIB_DEFAULT_TABLE_ID, FIB_SOURCE_API, NULL);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008302 mpls_sw_interface_enable_disable(&mpls_main,
8303 tm->hw[0]->sw_if_index,
Neale Ranns15002542017-09-10 04:39:11 -07008304 1, 1);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008305
Neale Rannsad422ed2016-11-02 14:20:04 +00008306 ip46_address_t nh_10_10_10_1 = {
8307 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
8308 };
8309 ai_mpls_10_10_10_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
8310 VNET_LINK_MPLS,
8311 &nh_10_10_10_1,
8312 tm->hw[0]->sw_if_index);
8313
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008314 /*
8315 * Test the specials stack properly.
8316 */
8317 fib_prefix_t exp_null_v6_pfx = {
8318 .fp_proto = FIB_PROTOCOL_MPLS,
8319 .fp_eos = MPLS_EOS,
8320 .fp_label = MPLS_IETF_IPV6_EXPLICIT_NULL_LABEL,
8321 .fp_payload_proto = DPO_PROTO_IP6,
8322 };
8323 lfe = fib_table_lookup(lfib_index, &exp_null_v6_pfx);
8324 FIB_TEST((FIB_NODE_INDEX_INVALID != lfe),
8325 "%U/%U present",
8326 format_mpls_unicast_label, MPLS_IETF_IPV6_EXPLICIT_NULL_LABEL,
8327 format_mpls_eos_bit, MPLS_EOS);
8328 fib_entry_contribute_forwarding(lfe,
8329 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8330 &dpo);
8331 dpo1 = load_balance_get_bucket(dpo.dpoi_index, 0);
8332 lkd = lookup_dpo_get(dpo1->dpoi_index);
8333
8334 FIB_TEST((fib_index == lkd->lkd_fib_index),
8335 "%U/%U is deag in %d %U",
8336 format_mpls_unicast_label, deag_label,
8337 format_mpls_eos_bit, MPLS_EOS,
8338 lkd->lkd_fib_index,
8339 format_dpo_id, &dpo, 0);
8340 FIB_TEST((LOOKUP_INPUT_DST_ADDR == lkd->lkd_input),
8341 "%U/%U is dst deag",
8342 format_mpls_unicast_label, deag_label,
8343 format_mpls_eos_bit, MPLS_EOS);
8344 FIB_TEST((LOOKUP_TABLE_FROM_INPUT_INTERFACE == lkd->lkd_table),
8345 "%U/%U is lookup in interface's table",
8346 format_mpls_unicast_label, deag_label,
8347 format_mpls_eos_bit, MPLS_EOS);
8348 FIB_TEST((DPO_PROTO_IP6 == lkd->lkd_proto),
8349 "%U/%U is %U dst deag",
8350 format_mpls_unicast_label, deag_label,
8351 format_mpls_eos_bit, MPLS_EOS,
8352 format_dpo_proto, lkd->lkd_proto);
8353
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008354 /*
8355 * A route deag route for EOS
8356 */
8357 fib_prefix_t pfx = {
8358 .fp_proto = FIB_PROTOCOL_MPLS,
8359 .fp_eos = MPLS_EOS,
8360 .fp_label = deag_label,
8361 .fp_payload_proto = DPO_PROTO_IP4,
8362 };
8363 lfe = fib_table_entry_path_add(lfib_index,
8364 &pfx,
8365 FIB_SOURCE_CLI,
8366 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008367 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008368 &zero_addr,
8369 ~0,
8370 fib_index,
8371 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00008372 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008373 FIB_ROUTE_PATH_FLAG_NONE);
8374
8375 FIB_TEST((lfe == fib_table_lookup(lfib_index, &pfx)),
8376 "%U/%U present",
8377 format_mpls_unicast_label, deag_label,
8378 format_mpls_eos_bit, MPLS_EOS);
8379
8380 fib_entry_contribute_forwarding(lfe,
8381 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8382 &dpo);
8383 dpo1 = load_balance_get_bucket(dpo.dpoi_index, 0);
Neale Ranns31ed7442018-02-23 05:29:09 -08008384 mdd = mpls_disp_dpo_get(dpo1->dpoi_index);
8385
8386 FIB_TEST((FIB_MPLS_LSP_MODE_PIPE == mdd->mdd_mode),
8387 "%U/%U disp is pipe mode",
8388 format_mpls_unicast_label, deag_label,
8389 format_mpls_eos_bit, MPLS_EOS);
8390
8391 lkd = lookup_dpo_get(mdd->mdd_dpo.dpoi_index);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008392
8393 FIB_TEST((fib_index == lkd->lkd_fib_index),
8394 "%U/%U is deag in %d %U",
8395 format_mpls_unicast_label, deag_label,
8396 format_mpls_eos_bit, MPLS_EOS,
8397 lkd->lkd_fib_index,
8398 format_dpo_id, &dpo, 0);
8399 FIB_TEST((LOOKUP_INPUT_DST_ADDR == lkd->lkd_input),
8400 "%U/%U is dst deag",
8401 format_mpls_unicast_label, deag_label,
8402 format_mpls_eos_bit, MPLS_EOS);
8403 FIB_TEST((DPO_PROTO_IP4 == lkd->lkd_proto),
8404 "%U/%U is %U dst deag",
8405 format_mpls_unicast_label, deag_label,
8406 format_mpls_eos_bit, MPLS_EOS,
8407 format_dpo_proto, lkd->lkd_proto);
8408
8409 fib_table_entry_delete_index(lfe, FIB_SOURCE_CLI);
8410
8411 FIB_TEST((FIB_NODE_INDEX_INVALID == fib_table_lookup(lfib_index,
8412 &pfx)),
8413 "%U/%U not present",
8414 format_mpls_unicast_label, deag_label,
8415 format_mpls_eos_bit, MPLS_EOS);
Neale Ranns31ed7442018-02-23 05:29:09 -08008416 dpo_reset(&dpo);
8417
8418 /*
8419 * A route deag route for EOS with LSP mode uniform
8420 */
8421 fib_mpls_label_t *l_pops = NULL, l_pop = {
8422 .fml_value = MPLS_LABEL_POP,
8423 .fml_mode = FIB_MPLS_LSP_MODE_UNIFORM,
8424 };
8425 vec_add1(l_pops, l_pop);
8426 lfe = fib_table_entry_path_add(lfib_index,
8427 &pfx,
8428 FIB_SOURCE_CLI,
8429 FIB_ENTRY_FLAG_NONE,
8430 DPO_PROTO_IP4,
8431 &zero_addr,
8432 ~0,
8433 fib_index,
8434 1,
8435 l_pops,
8436 FIB_ROUTE_PATH_FLAG_NONE);
8437
8438 FIB_TEST((lfe == fib_table_lookup(lfib_index, &pfx)),
8439 "%U/%U present",
8440 format_mpls_unicast_label, deag_label,
8441 format_mpls_eos_bit, MPLS_EOS);
8442
8443 fib_entry_contribute_forwarding(lfe,
8444 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8445 &dpo);
8446 dpo1 = load_balance_get_bucket(dpo.dpoi_index, 0);
8447 mdd = mpls_disp_dpo_get(dpo1->dpoi_index);
8448
8449 FIB_TEST((FIB_MPLS_LSP_MODE_UNIFORM == mdd->mdd_mode),
8450 "%U/%U disp is uniform mode",
8451 format_mpls_unicast_label, deag_label,
8452 format_mpls_eos_bit, MPLS_EOS);
8453
8454 lkd = lookup_dpo_get(mdd->mdd_dpo.dpoi_index);
8455
8456 FIB_TEST((fib_index == lkd->lkd_fib_index),
8457 "%U/%U is deag in %d %U",
8458 format_mpls_unicast_label, deag_label,
8459 format_mpls_eos_bit, MPLS_EOS,
8460 lkd->lkd_fib_index,
8461 format_dpo_id, &dpo, 0);
8462 FIB_TEST((LOOKUP_INPUT_DST_ADDR == lkd->lkd_input),
8463 "%U/%U is dst deag",
8464 format_mpls_unicast_label, deag_label,
8465 format_mpls_eos_bit, MPLS_EOS);
8466 FIB_TEST((DPO_PROTO_IP4 == lkd->lkd_proto),
8467 "%U/%U is %U dst deag",
8468 format_mpls_unicast_label, deag_label,
8469 format_mpls_eos_bit, MPLS_EOS,
8470 format_dpo_proto, lkd->lkd_proto);
8471
8472 fib_table_entry_delete_index(lfe, FIB_SOURCE_CLI);
8473
8474 FIB_TEST((FIB_NODE_INDEX_INVALID == fib_table_lookup(lfib_index,
8475 &pfx)),
8476 "%U/%U not present",
8477 format_mpls_unicast_label, deag_label,
8478 format_mpls_eos_bit, MPLS_EOS);
8479 dpo_reset(&dpo);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008480
8481 /*
8482 * A route deag route for non-EOS
8483 */
8484 pfx.fp_eos = MPLS_NON_EOS;
8485 lfe = fib_table_entry_path_add(lfib_index,
8486 &pfx,
8487 FIB_SOURCE_CLI,
8488 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008489 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008490 &zero_addr,
8491 ~0,
8492 lfib_index,
8493 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00008494 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008495 FIB_ROUTE_PATH_FLAG_NONE);
8496
8497 FIB_TEST((lfe == fib_table_lookup(lfib_index, &pfx)),
8498 "%U/%U present",
8499 format_mpls_unicast_label, deag_label,
8500 format_mpls_eos_bit, MPLS_NON_EOS);
8501
8502 fib_entry_contribute_forwarding(lfe,
8503 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
8504 &dpo);
8505 dpo1 = load_balance_get_bucket(dpo.dpoi_index, 0);
8506 lkd = lookup_dpo_get(dpo1->dpoi_index);
8507
8508 FIB_TEST((fib_index == lkd->lkd_fib_index),
8509 "%U/%U is deag in %d %U",
8510 format_mpls_unicast_label, deag_label,
8511 format_mpls_eos_bit, MPLS_NON_EOS,
8512 lkd->lkd_fib_index,
8513 format_dpo_id, &dpo, 0);
8514 FIB_TEST((LOOKUP_INPUT_DST_ADDR == lkd->lkd_input),
8515 "%U/%U is dst deag",
8516 format_mpls_unicast_label, deag_label,
8517 format_mpls_eos_bit, MPLS_NON_EOS);
8518
8519 FIB_TEST((DPO_PROTO_MPLS == lkd->lkd_proto),
8520 "%U/%U is %U dst deag",
8521 format_mpls_unicast_label, deag_label,
8522 format_mpls_eos_bit, MPLS_NON_EOS,
8523 format_dpo_proto, lkd->lkd_proto);
8524
8525 fib_table_entry_delete_index(lfe, FIB_SOURCE_CLI);
8526
8527 FIB_TEST((FIB_NODE_INDEX_INVALID == fib_table_lookup(lfib_index,
8528 &pfx)),
8529 "%U/%U not present",
8530 format_mpls_unicast_label, deag_label,
8531 format_mpls_eos_bit, MPLS_EOS);
8532
Neale Rannsad422ed2016-11-02 14:20:04 +00008533 dpo_reset(&dpo);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008534
Neale Rannsad422ed2016-11-02 14:20:04 +00008535 /*
8536 * An MPLS x-connect
8537 */
8538 fib_prefix_t pfx_1200 = {
8539 .fp_len = 21,
8540 .fp_proto = FIB_PROTOCOL_MPLS,
8541 .fp_label = 1200,
8542 .fp_eos = MPLS_NON_EOS,
8543 };
8544 fib_test_lb_bucket_t neos_o_10_10_10_1 = {
8545 .type = FT_LB_LABEL_STACK_O_ADJ,
8546 .label_stack_o_adj = {
8547 .adj = ai_mpls_10_10_10_1,
8548 .label_stack_size = 4,
8549 .label_stack = {
8550 200, 300, 400, 500,
8551 },
8552 .eos = MPLS_NON_EOS,
8553 },
8554 };
8555 dpo_id_t neos_1200 = DPO_INVALID;
8556 dpo_id_t ip_1200 = DPO_INVALID;
Neale Ranns31ed7442018-02-23 05:29:09 -08008557 fib_mpls_label_t *l200 = NULL;
8558 u32 ii;
8559 for (ii = 0; ii < 4; ii++)
8560 {
8561 fib_mpls_label_t fml = {
8562 .fml_value = 200 + (ii * 100),
8563 };
8564 vec_add1(l200, fml);
8565 };
Neale Rannsad422ed2016-11-02 14:20:04 +00008566
8567 lfe = fib_table_entry_update_one_path(fib_index,
8568 &pfx_1200,
8569 FIB_SOURCE_API,
8570 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008571 DPO_PROTO_IP4,
Neale Rannsad422ed2016-11-02 14:20:04 +00008572 &nh_10_10_10_1,
8573 tm->hw[0]->sw_if_index,
8574 ~0, // invalid fib index
8575 1,
8576 l200,
8577 FIB_ROUTE_PATH_FLAG_NONE);
8578
8579 FIB_TEST(fib_test_validate_entry(lfe,
8580 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
8581 1,
8582 &neos_o_10_10_10_1),
8583 "1200/0 LB 1 buckets via: "
8584 "adj 10.10.11.1");
8585
8586 /*
8587 * A recursive route via the MPLS x-connect
8588 */
8589 fib_prefix_t pfx_2_2_2_3_s_32 = {
8590 .fp_len = 32,
8591 .fp_proto = FIB_PROTOCOL_IP4,
8592 .fp_addr = {
8593 .ip4.as_u32 = clib_host_to_net_u32(0x02020203),
8594 },
8595 };
8596 fib_route_path_t *rpaths = NULL, rpath = {
Neale Rannsda78f952017-05-24 09:15:43 -07008597 .frp_proto = DPO_PROTO_MPLS,
Neale Rannsad422ed2016-11-02 14:20:04 +00008598 .frp_local_label = 1200,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008599 .frp_eos = MPLS_NON_EOS,
Neale Rannsad422ed2016-11-02 14:20:04 +00008600 .frp_sw_if_index = ~0, // recurive
8601 .frp_fib_index = 0, // Default MPLS fib
8602 .frp_weight = 1,
8603 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
8604 .frp_label_stack = NULL,
8605 };
8606 vec_add1(rpaths, rpath);
8607
8608 fib_table_entry_path_add2(fib_index,
8609 &pfx_2_2_2_3_s_32,
8610 FIB_SOURCE_API,
8611 FIB_ENTRY_FLAG_NONE,
8612 rpaths);
8613
8614 /*
8615 * A labelled recursive route via the MPLS x-connect
8616 */
8617 fib_prefix_t pfx_2_2_2_4_s_32 = {
8618 .fp_len = 32,
8619 .fp_proto = FIB_PROTOCOL_IP4,
8620 .fp_addr = {
8621 .ip4.as_u32 = clib_host_to_net_u32(0x02020204),
8622 },
8623 };
Neale Ranns31ed7442018-02-23 05:29:09 -08008624 fib_mpls_label_t *l999 = NULL, fml_999 = {
8625 .fml_value = 999,
8626 };
8627 vec_add1(l999, fml_999);
Neale Rannsad422ed2016-11-02 14:20:04 +00008628 rpaths[0].frp_label_stack = l999,
8629
8630 fib_table_entry_path_add2(fib_index,
8631 &pfx_2_2_2_4_s_32,
8632 FIB_SOURCE_API,
8633 FIB_ENTRY_FLAG_NONE,
8634 rpaths);
8635
8636 fib_entry_contribute_forwarding(fib_table_lookup(fib_index, &pfx_1200),
8637 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8638 &ip_1200);
8639 fib_entry_contribute_forwarding(fib_table_lookup(fib_index, &pfx_1200),
8640 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
8641 &neos_1200);
8642
8643 fib_test_lb_bucket_t ip_o_1200 = {
8644 .type = FT_LB_O_LB,
8645 .lb = {
8646 .lb = ip_1200.dpoi_index,
8647 },
8648 };
8649 fib_test_lb_bucket_t mpls_o_1200 = {
8650 .type = FT_LB_LABEL_O_LB,
8651 .label_o_lb = {
8652 .lb = neos_1200.dpoi_index,
8653 .label = 999,
8654 .eos = MPLS_EOS,
8655 },
8656 };
8657
8658 lfe = fib_table_lookup(fib_index, &pfx_2_2_2_3_s_32);
8659 FIB_TEST(fib_test_validate_entry(lfe,
8660 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8661 1,
8662 &ip_o_1200),
8663 "2.2.2.2.3/32 LB 1 buckets via: label 1200 EOS");
8664 lfe = fib_table_lookup(fib_index, &pfx_2_2_2_4_s_32);
8665 FIB_TEST(fib_test_validate_entry(lfe,
8666 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8667 1,
8668 &mpls_o_1200),
8669 "2.2.2.2.4/32 LB 1 buckets via: label 1200 non-EOS");
8670
8671 fib_table_entry_delete(fib_index, &pfx_1200, FIB_SOURCE_API);
8672 fib_table_entry_delete(fib_index, &pfx_2_2_2_3_s_32, FIB_SOURCE_API);
8673 fib_table_entry_delete(fib_index, &pfx_2_2_2_4_s_32, FIB_SOURCE_API);
8674
8675 dpo_reset(&neos_1200);
8676 dpo_reset(&ip_1200);
8677
8678 /*
8679 * A recursive via a label that does not exist
8680 */
8681 fib_test_lb_bucket_t bucket_drop = {
Neale Rannsd792d9c2017-10-21 10:53:20 -07008682 .type = FT_LB_DROP,
Neale Rannsad422ed2016-11-02 14:20:04 +00008683 .special = {
Neale Rannsf12a83f2017-04-18 09:09:40 -07008684 .adj = DPO_PROTO_IP4,
8685 },
8686 };
8687 fib_test_lb_bucket_t mpls_bucket_drop = {
Neale Rannsd792d9c2017-10-21 10:53:20 -07008688 .type = FT_LB_DROP,
Neale Rannsf12a83f2017-04-18 09:09:40 -07008689 .special = {
Neale Rannsad422ed2016-11-02 14:20:04 +00008690 .adj = DPO_PROTO_MPLS,
8691 },
8692 };
8693
8694 rpaths[0].frp_label_stack = NULL;
8695 lfe = fib_table_entry_path_add2(fib_index,
8696 &pfx_2_2_2_4_s_32,
8697 FIB_SOURCE_API,
8698 FIB_ENTRY_FLAG_NONE,
8699 rpaths);
8700
8701 fib_entry_contribute_forwarding(fib_table_lookup(fib_index, &pfx_1200),
8702 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8703 &ip_1200);
8704 ip_o_1200.lb.lb = ip_1200.dpoi_index;
8705
8706 FIB_TEST(fib_test_validate_entry(lfe,
8707 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8708 1,
Neale Ranns57b58602017-07-15 07:37:25 -07008709 &bucket_drop),
8710 "2.2.2.2.4/32 LB 1 buckets via: drop");
Neale Rannsad422ed2016-11-02 14:20:04 +00008711 lfe = fib_table_lookup(fib_index, &pfx_1200);
8712 FIB_TEST(fib_test_validate_entry(lfe,
8713 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8714 1,
8715 &bucket_drop),
Neale Rannsf12a83f2017-04-18 09:09:40 -07008716 "1200/neos LB 1 buckets via: ip4-DROP");
8717 FIB_TEST(fib_test_validate_entry(lfe,
8718 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
8719 1,
8720 &mpls_bucket_drop),
8721 "1200/neos LB 1 buckets via: mpls-DROP");
Neale Rannsad422ed2016-11-02 14:20:04 +00008722
8723 fib_table_entry_delete(fib_index, &pfx_2_2_2_4_s_32, FIB_SOURCE_API);
8724
8725 dpo_reset(&ip_1200);
8726
8727 /*
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008728 * An rx-interface route.
8729 * like the tail of an mcast LSP
8730 */
8731 dpo_id_t idpo = DPO_INVALID;
8732
Neale Ranns43161a82017-08-12 02:12:00 -07008733 interface_rx_dpo_add_or_lock(DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008734 tm->hw[0]->sw_if_index,
8735 &idpo);
8736
8737 fib_prefix_t pfx_2500 = {
8738 .fp_len = 21,
8739 .fp_proto = FIB_PROTOCOL_MPLS,
8740 .fp_label = 2500,
8741 .fp_eos = MPLS_EOS,
8742 .fp_payload_proto = DPO_PROTO_IP4,
8743 };
8744 fib_test_lb_bucket_t rx_intf_0 = {
8745 .type = FT_LB_INTF,
8746 .adj = {
8747 .adj = idpo.dpoi_index,
8748 },
8749 };
8750
8751 lfe = fib_table_entry_update_one_path(fib_index,
8752 &pfx_2500,
8753 FIB_SOURCE_API,
8754 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008755 DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008756 NULL,
8757 tm->hw[0]->sw_if_index,
8758 ~0, // invalid fib index
8759 0,
8760 NULL,
8761 FIB_ROUTE_PATH_INTF_RX);
8762 FIB_TEST(fib_test_validate_entry(lfe,
8763 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8764 1,
8765 &rx_intf_0),
8766 "2500 rx-interface 0");
8767 fib_table_entry_delete(fib_index, &pfx_2500, FIB_SOURCE_API);
8768
8769 /*
8770 * An MPLS mulicast entry
8771 */
8772 fib_prefix_t pfx_3500 = {
8773 .fp_len = 21,
8774 .fp_proto = FIB_PROTOCOL_MPLS,
8775 .fp_label = 3500,
8776 .fp_eos = MPLS_EOS,
8777 .fp_payload_proto = DPO_PROTO_IP4,
8778 };
8779 fib_test_rep_bucket_t mc_0 = {
8780 .type = FT_REP_LABEL_O_ADJ,
8781 .label_o_adj = {
8782 .adj = ai_mpls_10_10_10_1,
8783 .label = 3300,
8784 .eos = MPLS_EOS,
8785 },
8786 };
8787 fib_test_rep_bucket_t mc_intf_0 = {
8788 .type = FT_REP_INTF,
8789 .adj = {
8790 .adj = idpo.dpoi_index,
8791 },
8792 };
Neale Ranns31ed7442018-02-23 05:29:09 -08008793 fib_mpls_label_t *l3300 = NULL, fml_3300 = {
8794 .fml_value = 3300,
8795 };
8796 vec_add1(l3300, fml_3300);
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008797
8798 lfe = fib_table_entry_update_one_path(lfib_index,
8799 &pfx_3500,
8800 FIB_SOURCE_API,
8801 FIB_ENTRY_FLAG_MULTICAST,
Neale Rannsda78f952017-05-24 09:15:43 -07008802 DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008803 &nh_10_10_10_1,
8804 tm->hw[0]->sw_if_index,
8805 ~0, // invalid fib index
8806 1,
8807 l3300,
8808 FIB_ROUTE_PATH_FLAG_NONE);
8809 FIB_TEST(fib_test_validate_entry(lfe,
8810 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8811 1,
8812 &mc_0),
8813 "3500 via replicate over 10.10.10.1");
8814
8815 /*
8816 * MPLS Bud-node. Add a replication via an interface-receieve path
8817 */
8818 lfe = fib_table_entry_path_add(lfib_index,
8819 &pfx_3500,
8820 FIB_SOURCE_API,
8821 FIB_ENTRY_FLAG_MULTICAST,
Neale Rannsda78f952017-05-24 09:15:43 -07008822 DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008823 NULL,
8824 tm->hw[0]->sw_if_index,
8825 ~0, // invalid fib index
8826 0,
8827 NULL,
8828 FIB_ROUTE_PATH_INTF_RX);
8829 FIB_TEST(fib_test_validate_entry(lfe,
8830 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8831 2,
8832 &mc_0,
8833 &mc_intf_0),
8834 "3500 via replicate over 10.10.10.1 and interface-rx");
8835
8836 /*
8837 * Add a replication via an interface-free for-us path
8838 */
8839 fib_test_rep_bucket_t mc_disp = {
8840 .type = FT_REP_DISP_MFIB_LOOKUP,
8841 .adj = {
8842 .adj = idpo.dpoi_index,
8843 },
8844 };
8845 lfe = fib_table_entry_path_add(lfib_index,
8846 &pfx_3500,
8847 FIB_SOURCE_API,
8848 FIB_ENTRY_FLAG_MULTICAST,
Neale Rannsda78f952017-05-24 09:15:43 -07008849 DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008850 NULL,
8851 5, // rpf-id
8852 0, // default table
8853 0,
8854 NULL,
8855 FIB_ROUTE_PATH_RPF_ID);
8856 FIB_TEST(fib_test_validate_entry(lfe,
8857 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8858 3,
8859 &mc_0,
8860 &mc_disp,
8861 &mc_intf_0),
8862 "3500 via replicate over 10.10.10.1 and interface-rx");
8863
8864
8865
8866 fib_table_entry_delete(fib_index, &pfx_3500, FIB_SOURCE_API);
8867 dpo_reset(&idpo);
8868
8869 /*
Neale Rannsad422ed2016-11-02 14:20:04 +00008870 * cleanup
8871 */
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008872 mpls_sw_interface_enable_disable(&mpls_main,
8873 tm->hw[0]->sw_if_index,
Neale Ranns15002542017-09-10 04:39:11 -07008874 0, 1);
8875 mpls_table_delete(MPLS_FIB_DEFAULT_TABLE_ID, FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008876
Neale Ranns31ed7442018-02-23 05:29:09 -08008877 FIB_TEST(0 == pool_elts(mpls_disp_dpo_pool),
8878 "mpls_disp_dpo resources freed %d of %d",
8879 0, pool_elts(mpls_disp_dpo_pool));
Neale Rannsad422ed2016-11-02 14:20:04 +00008880 FIB_TEST(lb_count == pool_elts(load_balance_pool),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008881 "Load-balance resources freed %d of %d",
Neale Rannsad422ed2016-11-02 14:20:04 +00008882 lb_count, pool_elts(load_balance_pool));
Neale Ranns43161a82017-08-12 02:12:00 -07008883 FIB_TEST(0 == pool_elts(interface_rx_dpo_pool),
8884 "interface_rx_dpo resources freed %d of %d",
8885 0, pool_elts(interface_rx_dpo_pool));
Neale Ranns0ebe8d72016-12-08 19:48:11 +00008886
8887 return (0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008888}
8889
Neale Ranns89541992017-04-06 04:41:02 -07008890static int
8891fib_test_inherit (void)
8892{
8893 fib_node_index_t fei;
8894 test_main_t *tm;
8895 int n_feis;
8896
8897 n_feis = fib_entry_pool_size();
8898 tm = &test_main;
8899
8900 const ip46_address_t nh_10_10_10_1 = {
8901 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
8902 };
8903 const ip46_address_t nh_10_10_10_2 = {
8904 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02),
8905 };
8906 const ip46_address_t nh_10_10_10_16 = {
8907 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a10),
8908 };
8909 const ip46_address_t nh_10_10_10_20 = {
8910 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a14),
8911 };
8912 const ip46_address_t nh_10_10_10_21 = {
8913 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a15),
8914 };
8915 const ip46_address_t nh_10_10_10_22 = {
8916 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a16),
8917 };
8918 const ip46_address_t nh_10_10_10_255 = {
8919 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0aff),
8920 };
8921 const ip46_address_t nh_10_10_10_0 = {
8922 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a00),
8923 };
8924 const ip46_address_t nh_10_10_0_0 = {
8925 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0000),
8926 };
8927
8928 /*
8929 * prefixes at the base of a sub-tree
8930 */
8931 const fib_prefix_t pfx_10_10_10_21_s_32 = {
8932 .fp_len = 32,
8933 .fp_proto = FIB_PROTOCOL_IP4,
8934 .fp_addr = nh_10_10_10_21,
8935 };
8936 const fib_prefix_t pfx_10_10_10_22_s_32 = {
8937 .fp_len = 32,
8938 .fp_proto = FIB_PROTOCOL_IP4,
8939 .fp_addr = nh_10_10_10_22,
8940 };
8941 const fib_prefix_t pfx_10_10_10_255_s_32 = {
8942 .fp_len = 32,
8943 .fp_proto = FIB_PROTOCOL_IP4,
8944 .fp_addr = nh_10_10_10_255,
8945 };
8946
8947 fib_table_entry_special_add(0,
8948 &pfx_10_10_10_21_s_32,
8949 FIB_SOURCE_CLI,
8950 FIB_ENTRY_FLAG_DROP);
8951 fib_table_entry_special_add(0,
8952 &pfx_10_10_10_22_s_32,
8953 FIB_SOURCE_CLI,
8954 FIB_ENTRY_FLAG_DROP);
8955 fib_table_entry_special_add(0,
8956 &pfx_10_10_10_255_s_32,
8957 FIB_SOURCE_CLI,
8958 FIB_ENTRY_FLAG_DROP);
8959
8960 /*
8961 * source an entry that pushes its state down the sub-tree
8962 */
8963 const fib_prefix_t pfx_10_10_10_16_s_28 = {
8964 .fp_len = 28,
8965 .fp_proto = FIB_PROTOCOL_IP4,
8966 .fp_addr = nh_10_10_10_16,
8967 };
8968 fib_table_entry_update_one_path(0,
8969 &pfx_10_10_10_16_s_28,
8970 FIB_SOURCE_API,
8971 FIB_ENTRY_FLAG_COVERED_INHERIT,
8972 DPO_PROTO_IP4,
8973 &nh_10_10_10_1,
8974 tm->hw[0]->sw_if_index,
8975 ~0,
8976 1,
8977 NULL,
8978 FIB_ROUTE_PATH_FLAG_NONE);
8979
8980 /*
8981 * this covering entry and all those below it should have
8982 * the same forwarding information.
8983 */
8984 adj_index_t ai_10_10_10_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
8985 VNET_LINK_IP4,
8986 &nh_10_10_10_1,
8987 tm->hw[0]->sw_if_index);
8988 fib_test_lb_bucket_t adj_o_10_10_10_1 = {
8989 .type = FT_LB_ADJ,
8990 .adj = {
8991 .adj = ai_10_10_10_1,
8992 },
8993 };
8994
8995 fei = fib_table_lookup(0, &pfx_10_10_10_16_s_28);
8996 FIB_TEST(fib_test_validate_entry(fei,
8997 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8998 1,
8999 &adj_o_10_10_10_1),
9000 "%U via 10.10.10.1",
9001 format_fib_prefix, &pfx_10_10_10_16_s_28);
9002 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
9003 FIB_TEST(fib_test_validate_entry(fei,
9004 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9005 1,
9006 &adj_o_10_10_10_1),
9007 "%U via 10.10.10.1",
9008 format_fib_prefix, &pfx_10_10_10_21_s_32);
9009 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32);
9010 FIB_TEST(fib_test_validate_entry(fei,
9011 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9012 1,
9013 &adj_o_10_10_10_1),
9014 "%U via 10.10.10.1",
9015 format_fib_prefix, &pfx_10_10_10_22_s_32);
9016 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
9017 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
9018 "%U resolves via drop",
9019 format_fib_prefix, &pfx_10_10_10_255_s_32);
9020
9021 /*
9022 * remove the inherting cover - covereds go back to drop
9023 */
9024 fib_table_entry_delete(0, &pfx_10_10_10_16_s_28, FIB_SOURCE_API);
9025
9026 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
9027 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
9028 "%U resolves via drop",
9029 format_fib_prefix, &pfx_10_10_10_21_s_32);
9030
9031 /*
9032 * source an entry that pushes its state down the sub-tree
9033 */
9034 const fib_prefix_t pfx_10_10_10_0_s_24 = {
9035 .fp_len = 24,
9036 .fp_proto = FIB_PROTOCOL_IP4,
9037 .fp_addr = nh_10_10_10_0,
9038 };
9039 fib_table_entry_update_one_path(0,
9040 &pfx_10_10_10_0_s_24,
9041 FIB_SOURCE_API,
9042 FIB_ENTRY_FLAG_COVERED_INHERIT,
9043 DPO_PROTO_IP4,
9044 &nh_10_10_10_1,
9045 tm->hw[0]->sw_if_index,
9046 ~0,
9047 1,
9048 NULL,
9049 FIB_ROUTE_PATH_FLAG_NONE);
9050
9051 /*
9052 * whole sub-tree now covered
9053 */
9054 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
9055 FIB_TEST(fib_test_validate_entry(fei,
9056 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9057 1,
9058 &adj_o_10_10_10_1),
9059 "%U via 10.10.10.1",
9060 format_fib_prefix, &pfx_10_10_10_0_s_24);
9061 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
9062 FIB_TEST(fib_test_validate_entry(fei,
9063 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9064 1,
9065 &adj_o_10_10_10_1),
9066 "%U via 10.10.10.1",
9067 format_fib_prefix, &pfx_10_10_10_21_s_32);
9068 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32);
9069 FIB_TEST(fib_test_validate_entry(fei,
9070 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9071 1,
9072 &adj_o_10_10_10_1),
9073 "%U via 10.10.10.1",
9074 format_fib_prefix, &pfx_10_10_10_22_s_32);
9075 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
9076 FIB_TEST(fib_test_validate_entry(fei,
9077 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9078 1,
9079 &adj_o_10_10_10_1),
9080 "%U via 10.10.10.1",
9081 format_fib_prefix, &pfx_10_10_10_255_s_32);
9082
9083 /*
9084 * insert a more specific into the sub-tree - expect inheritance
9085 * this one is directly covered by the root
9086 */
9087 fib_table_entry_special_add(0,
9088 &pfx_10_10_10_16_s_28,
9089 FIB_SOURCE_CLI,
9090 FIB_ENTRY_FLAG_DROP);
9091 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_16_s_28);
9092 FIB_TEST(fib_test_validate_entry(fei,
9093 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9094 1,
9095 &adj_o_10_10_10_1),
9096 "%U via 10.10.10.1",
9097 format_fib_prefix, &pfx_10_10_10_16_s_28);
9098
9099 /*
9100 * insert a more specific into the sub-tree - expect inheritance
9101 * this one is indirectly covered by the root
9102 */
9103 const fib_prefix_t pfx_10_10_10_20_s_30 = {
9104 .fp_len = 30,
9105 .fp_proto = FIB_PROTOCOL_IP4,
9106 .fp_addr = nh_10_10_10_20,
9107 };
9108 fib_table_entry_special_add(0,
9109 &pfx_10_10_10_20_s_30,
9110 FIB_SOURCE_CLI,
9111 FIB_ENTRY_FLAG_DROP);
9112 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_20_s_30);
9113 FIB_TEST(fib_test_validate_entry(fei,
9114 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9115 1,
9116 &adj_o_10_10_10_1),
9117 "%U via 10.10.10.1",
9118 format_fib_prefix, &pfx_10_10_10_20_s_30);
9119
9120 /*
9121 * remove the prefix from the middle of the sub-tree
9122 * the inherited source will be the only one remaining - expect
9123 * it to be withdrawn and hence the prefix is removed.
9124 */
9125 fib_table_entry_special_remove(0,
9126 &pfx_10_10_10_20_s_30,
9127 FIB_SOURCE_CLI);
9128 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_20_s_30);
9129 FIB_TEST((FIB_NODE_INDEX_INVALID == fei),
9130 "%U gone",
9131 format_fib_prefix, &pfx_10_10_10_20_s_30);
9132
9133 /*
9134 * inheriting source is modifed - expect the modification to be present
9135 * throughout the sub-tree
9136 */
9137 adj_index_t ai_10_10_10_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
9138 VNET_LINK_IP4,
9139 &nh_10_10_10_2,
9140 tm->hw[0]->sw_if_index);
9141 fib_test_lb_bucket_t adj_o_10_10_10_2 = {
9142 .type = FT_LB_ADJ,
9143 .adj = {
9144 .adj = ai_10_10_10_2,
9145 },
9146 };
9147
9148 fib_table_entry_update_one_path(0,
9149 &pfx_10_10_10_0_s_24,
9150 FIB_SOURCE_API,
9151 FIB_ENTRY_FLAG_COVERED_INHERIT,
9152 DPO_PROTO_IP4,
9153 &nh_10_10_10_2,
9154 tm->hw[0]->sw_if_index,
9155 ~0,
9156 1,
9157 NULL,
9158 FIB_ROUTE_PATH_FLAG_NONE);
9159 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
9160 FIB_TEST(fib_test_validate_entry(fei,
9161 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9162 1,
9163 &adj_o_10_10_10_2),
9164 "%U via 10.10.10.2",
9165 format_fib_prefix, &pfx_10_10_10_21_s_32);
9166 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32);
9167 FIB_TEST(fib_test_validate_entry(fei,
9168 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9169 1,
9170 &adj_o_10_10_10_2),
9171 "%U via 10.10.10.2",
9172 format_fib_prefix, &pfx_10_10_10_22_s_32);
9173 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
9174 FIB_TEST(fib_test_validate_entry(fei,
9175 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9176 1,
9177 &adj_o_10_10_10_2),
9178 "%U via 10.10.10.2",
9179 format_fib_prefix, &pfx_10_10_10_255_s_32);
9180 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
9181 FIB_TEST(fib_test_validate_entry(fei,
9182 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9183 1,
9184 &adj_o_10_10_10_2),
9185 "%U via 10.10.10.2",
9186 format_fib_prefix, &pfx_10_10_10_0_s_24);
9187
9188 /*
9189 * add the source that replaces inherited state.
9190 * inheriting source is not the best, so it doesn't push state.
9191 */
9192 fib_table_entry_update_one_path(0,
9193 &pfx_10_10_10_0_s_24,
9194 FIB_SOURCE_PLUGIN_HI,
9195 FIB_ENTRY_FLAG_NONE,
9196 DPO_PROTO_IP4,
9197 &nh_10_10_10_1,
9198 tm->hw[0]->sw_if_index,
9199 ~0,
9200 1,
9201 NULL,
9202 FIB_ROUTE_PATH_FLAG_NONE);
9203 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
9204 FIB_TEST(fib_test_validate_entry(fei,
9205 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9206 1,
9207 &adj_o_10_10_10_1),
9208 "%U via 10.10.10.1",
9209 format_fib_prefix, &pfx_10_10_10_0_s_24);
9210
9211 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
9212 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
9213 "%U resolves via drop",
9214 format_fib_prefix, &pfx_10_10_10_21_s_32);
9215 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32);
9216 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
9217 "%U resolves via drop",
9218 format_fib_prefix, &pfx_10_10_10_22_s_32);
9219 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
9220 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
9221 "%U resolves via drop",
9222 format_fib_prefix, &pfx_10_10_10_255_s_32);
9223 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_16_s_28);
9224 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
9225 "%U resolves via drop",
9226 format_fib_prefix, &pfx_10_10_10_16_s_28);
9227
9228 /*
9229 * withdraw the higher priority source and expect the inherited to return
9230 * throughout the sub-tree
9231 */
9232 fib_table_entry_delete(0, &pfx_10_10_10_0_s_24, FIB_SOURCE_PLUGIN_HI);
9233
9234 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
9235 FIB_TEST(fib_test_validate_entry(fei,
9236 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9237 1,
9238 &adj_o_10_10_10_2),
9239 "%U via 10.10.10.2",
9240 format_fib_prefix, &pfx_10_10_10_21_s_32);
9241 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32);
9242 FIB_TEST(fib_test_validate_entry(fei,
9243 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9244 1,
9245 &adj_o_10_10_10_2),
9246 "%U via 10.10.10.2",
9247 format_fib_prefix, &pfx_10_10_10_22_s_32);
9248 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
9249 FIB_TEST(fib_test_validate_entry(fei,
9250 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9251 1,
9252 &adj_o_10_10_10_2),
9253 "%U via 10.10.10.2",
9254 format_fib_prefix, &pfx_10_10_10_255_s_32);
9255 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
9256 FIB_TEST(fib_test_validate_entry(fei,
9257 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9258 1,
9259 &adj_o_10_10_10_2),
9260 "%U via 10.10.10.2",
9261 format_fib_prefix, &pfx_10_10_10_0_s_24);
9262 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_16_s_28);
9263 FIB_TEST(fib_test_validate_entry(fei,
9264 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9265 1,
9266 &adj_o_10_10_10_2),
9267 "%U via 10.10.10.2",
9268 format_fib_prefix, &pfx_10_10_10_16_s_28);
9269
9270 /*
9271 * source a covered entry in the sub-tree with the same inherting source
9272 * - expect that it now owns the sub-tree and thus over-rides its cover
9273 */
9274 fib_table_entry_update_one_path(0,
9275 &pfx_10_10_10_16_s_28,
9276 FIB_SOURCE_API,
9277 FIB_ENTRY_FLAG_COVERED_INHERIT,
9278 DPO_PROTO_IP4,
9279 &nh_10_10_10_1,
9280 tm->hw[0]->sw_if_index,
9281 ~0,
9282 1,
9283 NULL,
9284 FIB_ROUTE_PATH_FLAG_NONE);
9285 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_16_s_28);
9286 FIB_TEST(fib_test_validate_entry(fei,
9287 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9288 1,
9289 &adj_o_10_10_10_1),
9290 "%U via 10.10.10.1",
9291 format_fib_prefix, &pfx_10_10_10_16_s_28);
9292 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32);
9293 FIB_TEST(fib_test_validate_entry(fei,
9294 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9295 1,
9296 &adj_o_10_10_10_1),
9297 "%U via 10.10.10.2",
9298 format_fib_prefix, &pfx_10_10_10_22_s_32);
9299 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
9300 FIB_TEST(fib_test_validate_entry(fei,
9301 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9302 1,
9303 &adj_o_10_10_10_1),
9304 "%U via 10.10.10.2",
9305 format_fib_prefix, &pfx_10_10_10_21_s_32);
9306
9307 /* these two unaffected by the sub-tree change */
9308 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
9309 FIB_TEST(fib_test_validate_entry(fei,
9310 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9311 1,
9312 &adj_o_10_10_10_2),
9313 "%U via 10.10.10.2",
9314 format_fib_prefix, &pfx_10_10_10_255_s_32);
9315 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
9316 FIB_TEST(fib_test_validate_entry(fei,
9317 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9318 1,
9319 &adj_o_10_10_10_2),
9320 "%U via 10.10.10.2",
9321 format_fib_prefix, &pfx_10_10_10_0_s_24);
9322
9323 /*
9324 * removes the more specific, expect the /24 to now re-owns the sub-tree
9325 */
9326 fib_table_entry_delete(0, &pfx_10_10_10_16_s_28, FIB_SOURCE_API);
9327
9328 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
9329 FIB_TEST(fib_test_validate_entry(fei,
9330 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9331 1,
9332 &adj_o_10_10_10_2),
9333 "%U via 10.10.10.2",
9334 format_fib_prefix, &pfx_10_10_10_16_s_28);
9335 FIB_TEST(fib_test_validate_entry(fei,
9336 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9337 1,
9338 &adj_o_10_10_10_2),
9339 "%U via 10.10.10.2",
9340 format_fib_prefix, &pfx_10_10_10_21_s_32);
9341 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32);
9342 FIB_TEST(fib_test_validate_entry(fei,
9343 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9344 1,
9345 &adj_o_10_10_10_2),
9346 "%U via 10.10.10.2",
9347 format_fib_prefix, &pfx_10_10_10_22_s_32);
9348 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
9349 FIB_TEST(fib_test_validate_entry(fei,
9350 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9351 1,
9352 &adj_o_10_10_10_2),
9353 "%U via 10.10.10.2",
9354 format_fib_prefix, &pfx_10_10_10_255_s_32);
9355 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
9356 FIB_TEST(fib_test_validate_entry(fei,
9357 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9358 1,
9359 &adj_o_10_10_10_2),
9360 "%U via 10.10.10.2",
9361 format_fib_prefix, &pfx_10_10_10_0_s_24);
9362 /*
9363 * modify the /24. expect the new forwarding to be pushed down
9364 */
9365 fib_table_entry_update_one_path(0,
9366 &pfx_10_10_10_0_s_24,
9367 FIB_SOURCE_API,
9368 FIB_ENTRY_FLAG_COVERED_INHERIT,
9369 DPO_PROTO_IP4,
9370 &nh_10_10_10_1,
9371 tm->hw[0]->sw_if_index,
9372 ~0,
9373 1,
9374 NULL,
9375 FIB_ROUTE_PATH_FLAG_NONE);
9376 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
9377 FIB_TEST(fib_test_validate_entry(fei,
9378 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9379 1,
9380 &adj_o_10_10_10_1),
9381 "%U via 10.10.10.1",
9382 format_fib_prefix, &pfx_10_10_10_16_s_28);
9383 FIB_TEST(fib_test_validate_entry(fei,
9384 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9385 1,
9386 &adj_o_10_10_10_1),
9387 "%U via 10.10.10.1",
9388 format_fib_prefix, &pfx_10_10_10_21_s_32);
9389 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32);
9390 FIB_TEST(fib_test_validate_entry(fei,
9391 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9392 1,
9393 &adj_o_10_10_10_1),
9394 "%U via 10.10.10.1",
9395 format_fib_prefix, &pfx_10_10_10_22_s_32);
9396 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
9397 FIB_TEST(fib_test_validate_entry(fei,
9398 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9399 1,
9400 &adj_o_10_10_10_1),
9401 "%U via 10.10.10.1",
9402 format_fib_prefix, &pfx_10_10_10_255_s_32);
9403 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
9404 FIB_TEST(fib_test_validate_entry(fei,
9405 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9406 1,
9407 &adj_o_10_10_10_1),
9408 "%U via 10.10.10.1",
9409 format_fib_prefix, &pfx_10_10_10_0_s_24);
9410
9411 /*
9412 * add an entry less specific to /24. it should not own the /24's tree
9413 */
9414 const fib_prefix_t pfx_10_10_0_0_s_16 = {
9415 .fp_len = 16,
9416 .fp_proto = FIB_PROTOCOL_IP4,
9417 .fp_addr = nh_10_10_0_0,
9418 };
9419 fib_table_entry_update_one_path(0,
9420 &pfx_10_10_0_0_s_16,
9421 FIB_SOURCE_API,
9422 FIB_ENTRY_FLAG_COVERED_INHERIT,
9423 DPO_PROTO_IP4,
9424 &nh_10_10_10_2,
9425 tm->hw[0]->sw_if_index,
9426 ~0,
9427 1,
9428 NULL,
9429 FIB_ROUTE_PATH_FLAG_NONE);
9430 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
9431 FIB_TEST(fib_test_validate_entry(fei,
9432 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9433 1,
9434 &adj_o_10_10_10_1),
9435 "%U via 10.10.10.1",
9436 format_fib_prefix, &pfx_10_10_10_16_s_28);
9437 FIB_TEST(fib_test_validate_entry(fei,
9438 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9439 1,
9440 &adj_o_10_10_10_1),
9441 "%U via 10.10.10.1",
9442 format_fib_prefix, &pfx_10_10_10_21_s_32);
9443 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32);
9444 FIB_TEST(fib_test_validate_entry(fei,
9445 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9446 1,
9447 &adj_o_10_10_10_1),
9448 "%U via 10.10.10.1",
9449 format_fib_prefix, &pfx_10_10_10_22_s_32);
9450 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
9451 FIB_TEST(fib_test_validate_entry(fei,
9452 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9453 1,
9454 &adj_o_10_10_10_1),
9455 "%U via 10.10.10.1",
9456 format_fib_prefix, &pfx_10_10_10_255_s_32);
9457 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
9458 FIB_TEST(fib_test_validate_entry(fei,
9459 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9460 1,
9461 &adj_o_10_10_10_1),
9462 "%U via 10.10.10.1",
9463 format_fib_prefix, &pfx_10_10_10_0_s_24);
9464 fei = fib_table_lookup_exact_match(0, &pfx_10_10_0_0_s_16);
9465 FIB_TEST(fib_test_validate_entry(fei,
9466 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9467 1,
9468 &adj_o_10_10_10_2),
9469 "%U via 10.10.10.2",
9470 format_fib_prefix, &pfx_10_10_0_0_s_16);
9471
9472 /*
9473 * cleanup
9474 */
9475 fib_table_entry_delete(0, &pfx_10_10_10_21_s_32, FIB_SOURCE_CLI);
9476 fib_table_entry_delete(0, &pfx_10_10_10_22_s_32, FIB_SOURCE_CLI);
9477 fib_table_entry_delete(0, &pfx_10_10_10_16_s_28, FIB_SOURCE_CLI);
9478 fib_table_entry_delete(0, &pfx_10_10_10_255_s_32, FIB_SOURCE_CLI);
9479 fib_table_entry_delete(0, &pfx_10_10_10_0_s_24, FIB_SOURCE_API);
9480 fib_table_entry_delete(0, &pfx_10_10_0_0_s_16, FIB_SOURCE_API);
9481 adj_unlock(ai_10_10_10_1);
9482 adj_unlock(ai_10_10_10_2);
9483
9484 /*
9485 * test the v6 tree walk.
9486 * a /64 that covers everytinhg. a /96 that covers one /128
9487 * a second /128 covered only by the /64.
9488 */
9489 const fib_prefix_t pfx_2001_s_64 = {
9490 .fp_len = 64,
9491 .fp_proto = FIB_PROTOCOL_IP6,
9492 .fp_addr = {
9493 .ip6 = {
9494 .as_u64 = {
9495 [0] = clib_host_to_net_u64(0x2001000000000000),
9496 [1] = clib_host_to_net_u64(0x0000000000000000),
9497 },
9498 },
9499 },
9500 };
9501 const fib_prefix_t pfx_2001_1_s_96 = {
9502 .fp_len = 96,
9503 .fp_proto = FIB_PROTOCOL_IP6,
9504 .fp_addr = {
9505 .ip6 = {
9506 .as_u64 = {
9507 [0] = clib_host_to_net_u64(0x2001000000000000),
9508 [1] = clib_host_to_net_u64(0x1000000000000000),
9509 },
9510 },
9511 },
9512 };
9513 const fib_prefix_t pfx_2001_1_1_s_128 = {
9514 .fp_len = 128,
9515 .fp_proto = FIB_PROTOCOL_IP6,
9516 .fp_addr = {
9517 .ip6 = {
9518 .as_u64 = {
9519 [0] = clib_host_to_net_u64(0x2001000000000000),
9520 [1] = clib_host_to_net_u64(0x1000000000000001),
9521 },
9522 },
9523 },
9524 };
9525 const fib_prefix_t pfx_2001_0_1_s_128 = {
9526 .fp_len = 128,
9527 .fp_proto = FIB_PROTOCOL_IP6,
9528 .fp_addr = {
9529 .ip6 = {
9530 .as_u64 = {
9531 [0] = clib_host_to_net_u64(0x2001000000000000),
9532 [1] = clib_host_to_net_u64(0x0000000000000001),
9533 },
9534 },
9535 },
9536 };
9537 const ip46_address_t nh_3000_1 = {
9538 .ip6 = {
9539 .as_u64 = {
9540 [0] = clib_host_to_net_u64(0x3000000000000000),
9541 [1] = clib_host_to_net_u64(0x0000000000000001),
9542 },
9543 },
9544 };
9545 const ip46_address_t nh_3000_2 = {
9546 .ip6 = {
9547 .as_u64 = {
9548 [0] = clib_host_to_net_u64(0x3000000000000000),
9549 [1] = clib_host_to_net_u64(0x0000000000000002),
9550 },
9551 },
9552 };
9553 adj_index_t ai_3000_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP6,
9554 VNET_LINK_IP6,
9555 &nh_3000_1,
9556 tm->hw[0]->sw_if_index);
9557 adj_index_t ai_3000_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP6,
9558 VNET_LINK_IP6,
9559 &nh_3000_2,
9560 tm->hw[0]->sw_if_index);
9561 fib_test_lb_bucket_t adj_o_3000_1 = {
9562 .type = FT_LB_ADJ,
9563 .adj = {
9564 .adj = ai_3000_1,
9565 },
9566 };
9567 fib_test_lb_bucket_t adj_o_3000_2 = {
9568 .type = FT_LB_ADJ,
9569 .adj = {
9570 .adj = ai_3000_2,
9571 },
9572 };
9573
9574 fib_table_entry_special_add(0,
9575 &pfx_2001_0_1_s_128,
9576 FIB_SOURCE_CLI,
9577 FIB_ENTRY_FLAG_DROP);
9578 fib_table_entry_special_add(0,
9579 &pfx_2001_1_1_s_128,
9580 FIB_SOURCE_CLI,
9581 FIB_ENTRY_FLAG_DROP);
9582
9583 /*
9584 * /96 has inherited forwarding pushed down to its covered /128
9585 */
9586 fib_table_entry_update_one_path(0,
9587 &pfx_2001_1_s_96,
9588 FIB_SOURCE_API,
9589 FIB_ENTRY_FLAG_COVERED_INHERIT,
9590 DPO_PROTO_IP6,
9591 &nh_3000_1,
9592 tm->hw[0]->sw_if_index,
9593 ~0,
9594 1,
9595 NULL,
9596 FIB_ROUTE_PATH_FLAG_NONE);
9597 fei = fib_table_lookup_exact_match(0, &pfx_2001_1_s_96);
9598 FIB_TEST(fib_test_validate_entry(fei,
9599 FIB_FORW_CHAIN_TYPE_UNICAST_IP6,
9600 1,
9601 &adj_o_3000_1),
9602 "%U via 3000::1",
9603 format_fib_prefix, &pfx_2001_1_s_96);
9604 fei = fib_table_lookup_exact_match(0, &pfx_2001_1_1_s_128);
9605 FIB_TEST(fib_test_validate_entry(fei,
9606 FIB_FORW_CHAIN_TYPE_UNICAST_IP6,
9607 1,
9608 &adj_o_3000_1),
9609 "%U via 3000::1",
9610 format_fib_prefix, &pfx_2001_1_1_s_128);
9611 fei = fib_table_lookup_exact_match(0, &pfx_2001_0_1_s_128);
9612 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
9613 "%U resolves via drop",
9614 format_fib_prefix, &pfx_2001_0_1_s_128);
9615
9616 /*
9617 * /64 has inherited forwarding pushed down to all, but the /96
9618 * and its sub-tree remain unaffected.
9619 */
9620 fib_table_entry_update_one_path(0,
9621 &pfx_2001_s_64,
9622 FIB_SOURCE_API,
9623 FIB_ENTRY_FLAG_COVERED_INHERIT,
9624 DPO_PROTO_IP6,
9625 &nh_3000_2,
9626 tm->hw[0]->sw_if_index,
9627 ~0,
9628 1,
9629 NULL,
9630 FIB_ROUTE_PATH_FLAG_NONE);
9631
9632 fei = fib_table_lookup_exact_match(0, &pfx_2001_s_64);
9633 FIB_TEST(fib_test_validate_entry(fei,
9634 FIB_FORW_CHAIN_TYPE_UNICAST_IP6,
9635 1,
9636 &adj_o_3000_2),
9637 "%U via 3000::2",
9638 format_fib_prefix, &pfx_2001_s_64);
9639 fei = fib_table_lookup_exact_match(0, &pfx_2001_0_1_s_128);
9640 FIB_TEST(fib_test_validate_entry(fei,
9641 FIB_FORW_CHAIN_TYPE_UNICAST_IP6,
9642 1,
9643 &adj_o_3000_2),
9644 "%U via 3000::1",
9645 format_fib_prefix, &pfx_2001_0_1_s_128);
9646
9647 fei = fib_table_lookup_exact_match(0, &pfx_2001_1_s_96);
9648 FIB_TEST(fib_test_validate_entry(fei,
9649 FIB_FORW_CHAIN_TYPE_UNICAST_IP6,
9650 1,
9651 &adj_o_3000_1),
9652 "%U via 3000::1",
9653 format_fib_prefix, &pfx_2001_1_s_96);
9654 fei = fib_table_lookup_exact_match(0, &pfx_2001_1_1_s_128);
9655 FIB_TEST(fib_test_validate_entry(fei,
9656 FIB_FORW_CHAIN_TYPE_UNICAST_IP6,
9657 1,
9658 &adj_o_3000_1),
9659 "%U via 3000::1",
9660 format_fib_prefix, &pfx_2001_1_1_s_128);
9661
9662 /*
9663 * Cleanup
9664 */
9665 fib_table_entry_delete(0, &pfx_2001_0_1_s_128, FIB_SOURCE_CLI);
9666 fib_table_entry_delete(0, &pfx_2001_1_1_s_128, FIB_SOURCE_CLI);
9667 fib_table_entry_delete(0, &pfx_2001_s_64, FIB_SOURCE_API);
9668 fib_table_entry_delete(0, &pfx_2001_1_s_96, FIB_SOURCE_API);
9669 adj_unlock(ai_3000_1);
9670 adj_unlock(ai_3000_2);
9671
9672 /*
9673 * test no-one left behind
9674 */
9675 FIB_TEST((n_feis == fib_entry_pool_size()), "Entries gone");
9676 FIB_TEST(0 == adj_nbr_db_size(), "All adjacencies removed");
9677 return (0);
9678}
9679
Neale Ranns0bfe5d82016-08-25 15:29:12 +01009680static clib_error_t *
9681fib_test (vlib_main_t * vm,
9682 unformat_input_t * input,
9683 vlib_cli_command_t * cmd_arg)
9684{
Neale Ranns0ebe8d72016-12-08 19:48:11 +00009685 int res;
9686
9687 res = 0;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01009688 fib_test_mk_intf(4);
9689
Neale Ranns88fc83e2017-04-05 08:11:14 -07009690 if (unformat (input, "debug"))
9691 {
9692 fib_test_do_debug = 1;
9693 }
9694
Neale Ranns0bfe5d82016-08-25 15:29:12 +01009695 if (unformat (input, "ip"))
9696 {
Neale Ranns0ebe8d72016-12-08 19:48:11 +00009697 res += fib_test_v4();
9698 res += fib_test_v6();
Neale Ranns0bfe5d82016-08-25 15:29:12 +01009699 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01009700 else if (unformat (input, "label"))
9701 {
Neale Ranns0ebe8d72016-12-08 19:48:11 +00009702 res += fib_test_label();
Neale Ranns0bfe5d82016-08-25 15:29:12 +01009703 }
9704 else if (unformat (input, "ae"))
9705 {
Neale Ranns0ebe8d72016-12-08 19:48:11 +00009706 res += fib_test_ae();
Neale Ranns0bfe5d82016-08-25 15:29:12 +01009707 }
Neale Ranns57b58602017-07-15 07:37:25 -07009708 else if (unformat (input, "pref"))
9709 {
9710 res += fib_test_pref();
9711 }
Neale Rannsad422ed2016-11-02 14:20:04 +00009712 else if (unformat (input, "lfib"))
9713 {
Neale Ranns0ebe8d72016-12-08 19:48:11 +00009714 res += lfib_test();
Neale Rannsad422ed2016-11-02 14:20:04 +00009715 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01009716 else if (unformat (input, "walk"))
9717 {
Neale Ranns0ebe8d72016-12-08 19:48:11 +00009718 res += fib_test_walk();
Neale Ranns0bfe5d82016-08-25 15:29:12 +01009719 }
Neale Ranns88fc83e2017-04-05 08:11:14 -07009720 else if (unformat (input, "bfd"))
9721 {
9722 res += fib_test_bfd();
9723 }
Neale Ranns89541992017-04-06 04:41:02 -07009724 else if (unformat (input, "inherit"))
9725 {
9726 res += fib_test_inherit();
9727 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01009728 else
9729 {
Neale Ranns0ebe8d72016-12-08 19:48:11 +00009730 res += fib_test_v4();
9731 res += fib_test_v6();
9732 res += fib_test_ae();
Neale Ranns88fc83e2017-04-05 08:11:14 -07009733 res += fib_test_bfd();
Neale Ranns57b58602017-07-15 07:37:25 -07009734 res += fib_test_pref();
Neale Ranns0ebe8d72016-12-08 19:48:11 +00009735 res += fib_test_label();
Neale Ranns89541992017-04-06 04:41:02 -07009736 res += fib_test_inherit();
Neale Ranns0ebe8d72016-12-08 19:48:11 +00009737 res += lfib_test();
Neale Rannsf12a83f2017-04-18 09:09:40 -07009738
9739 /*
9740 * fib-walk process must be disabled in order for the walk tests to work
9741 */
9742 fib_walk_process_disable();
9743 res += fib_test_walk();
9744 fib_walk_process_enable();
Neale Ranns0bfe5d82016-08-25 15:29:12 +01009745 }
9746
Neale Ranns0ebe8d72016-12-08 19:48:11 +00009747 if (res)
9748 {
9749 return clib_error_return(0, "FIB Unit Test Failed");
9750 }
9751 else
9752 {
9753 return (NULL);
9754 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01009755}
9756
9757VLIB_CLI_COMMAND (test_fib_command, static) = {
9758 .path = "test fib",
9759 .short_help = "fib unit tests - DO NOT RUN ON A LIVE SYSTEM",
9760 .function = fib_test,
9761};
9762
Neale Ranns0bfe5d82016-08-25 15:29:12 +01009763clib_error_t *
9764fib_test_init (vlib_main_t *vm)
9765{
9766 return 0;
9767}
9768
9769VLIB_INIT_FUNCTION (fib_test_init);