blob: 61ba9348fd80d66050ee2a55ae8f6d169b6e6d34 [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
Jakub Grajciar7b867a82017-12-08 16:28:42 +010043#include <vlib/unix/plugin.h>
44
Neale Ranns88fc83e2017-04-05 08:11:14 -070045/*
46 * Add debugs for passing tests
47 */
48static int fib_test_do_debug;
49
Neale Ranns0bfe5d82016-08-25 15:29:12 +010050#define FIB_TEST_I(_cond, _comment, _args...) \
51({ \
52 int _evald = (_cond); \
53 if (!(_evald)) { \
54 fformat(stderr, "FAIL:%d: " _comment "\n", \
55 __LINE__, ##_args); \
56 } else { \
Neale Ranns88fc83e2017-04-05 08:11:14 -070057 if (fib_test_do_debug) \
58 fformat(stderr, "PASS:%d: " _comment "\n", \
59 __LINE__, ##_args); \
Neale Ranns0bfe5d82016-08-25 15:29:12 +010060 } \
61 _evald; \
62})
63#define FIB_TEST(_cond, _comment, _args...) \
64{ \
65 if (!FIB_TEST_I(_cond, _comment, ##_args)) { \
Neale Ranns0ebe8d72016-12-08 19:48:11 +000066 return 1; \
Neale Ranns0bfe5d82016-08-25 15:29:12 +010067 ASSERT(!("FAIL: " _comment)); \
68 } \
69}
70
71/**
72 * A 'i'm not fussed is this is not efficient' store of test data
73 */
74typedef struct test_main_t_ {
75 /**
76 * HW if indicies
77 */
78 u32 hw_if_indicies[4];
79 /**
80 * HW interfaces
81 */
82 vnet_hw_interface_t * hw[4];
83
84} test_main_t;
85static test_main_t test_main;
86
87/* fake ethernet device class, distinct from "fake-ethX" */
88static u8 * format_test_interface_name (u8 * s, va_list * args)
89{
90 u32 dev_instance = va_arg (*args, u32);
91 return format (s, "test-eth%d", dev_instance);
92}
93
94static uword dummy_interface_tx (vlib_main_t * vm,
95 vlib_node_runtime_t * node,
96 vlib_frame_t * frame)
97{
98 clib_warning ("you shouldn't be here, leaking buffers...");
99 return frame->n_vectors;
100}
101
Neale Ranns8b37b872016-11-21 12:25:22 +0000102static clib_error_t *
103test_interface_admin_up_down (vnet_main_t * vnm,
104 u32 hw_if_index,
105 u32 flags)
106{
107 u32 hw_flags = (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) ?
108 VNET_HW_INTERFACE_FLAG_LINK_UP : 0;
109 vnet_hw_interface_set_flags (vnm, hw_if_index, hw_flags);
110 return 0;
111}
112
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100113VNET_DEVICE_CLASS (test_interface_device_class,static) = {
114 .name = "Test interface",
115 .format_device_name = format_test_interface_name,
116 .tx_function = dummy_interface_tx,
Neale Ranns8b37b872016-11-21 12:25:22 +0000117 .admin_up_down_function = test_interface_admin_up_down,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100118};
119
120static u8 *hw_address;
121
Neale Ranns0ebe8d72016-12-08 19:48:11 +0000122static int
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100123fib_test_mk_intf (u32 ninterfaces)
124{
125 clib_error_t * error = NULL;
126 test_main_t *tm = &test_main;
127 u8 byte;
128 u32 i;
129
130 ASSERT(ninterfaces <= ARRAY_LEN(tm->hw_if_indicies));
131
132 for (i=0; i<6; i++)
133 {
134 byte = 0xd0+i;
135 vec_add1(hw_address, byte);
136 }
137
138 for (i = 0; i < ninterfaces; i++)
139 {
140 hw_address[5] = i;
141
142 error = ethernet_register_interface(vnet_get_main(),
Neale Ranns8b37b872016-11-21 12:25:22 +0000143 test_interface_device_class.index,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100144 i /* instance */,
145 hw_address,
146 &tm->hw_if_indicies[i],
147 /* flag change */ 0);
148
149 FIB_TEST((NULL == error), "ADD interface %d", i);
150
Neale Ranns8b37b872016-11-21 12:25:22 +0000151 error = vnet_hw_interface_set_flags(vnet_get_main(),
152 tm->hw_if_indicies[i],
153 VNET_HW_INTERFACE_FLAG_LINK_UP);
154 tm->hw[i] = vnet_get_hw_interface(vnet_get_main(),
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100155 tm->hw_if_indicies[i]);
Neale Ranns8b37b872016-11-21 12:25:22 +0000156 vec_validate (ip4_main.fib_index_by_sw_if_index,
157 tm->hw[i]->sw_if_index);
158 vec_validate (ip6_main.fib_index_by_sw_if_index,
159 tm->hw[i]->sw_if_index);
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100160 ip4_main.fib_index_by_sw_if_index[tm->hw[i]->sw_if_index] = 0;
161 ip6_main.fib_index_by_sw_if_index[tm->hw[i]->sw_if_index] = 0;
Neale Ranns8b37b872016-11-21 12:25:22 +0000162
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100163 error = vnet_sw_interface_set_flags(vnet_get_main(),
164 tm->hw[i]->sw_if_index,
165 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
166 FIB_TEST((NULL == error), "UP interface %d", i);
167 }
168 /*
169 * re-eval after the inevitable realloc
170 */
171 for (i = 0; i < ninterfaces; i++)
172 {
173 tm->hw[i] = vnet_get_hw_interface(vnet_get_main(),
174 tm->hw_if_indicies[i]);
175 }
Neale Ranns0ebe8d72016-12-08 19:48:11 +0000176
177 return (0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100178}
179
Neale Ranns3ee44042016-10-03 13:05:48 +0100180#define FIB_TEST_REC_FORW(_rec_prefix, _via_prefix, _bucket) \
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100181{ \
182 const dpo_id_t *_rec_dpo = fib_entry_contribute_ip_forwarding( \
183 fib_table_lookup_exact_match(fib_index, (_rec_prefix))); \
184 const dpo_id_t *_via_dpo = fib_entry_contribute_ip_forwarding( \
185 fib_table_lookup(fib_index, (_via_prefix))); \
186 FIB_TEST(!dpo_cmp(_via_dpo, \
Neale Ranns3ee44042016-10-03 13:05:48 +0100187 load_balance_get_bucket(_rec_dpo->dpoi_index, \
188 _bucket)), \
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100189 "%U is recursive via %U", \
190 format_fib_prefix, (_rec_prefix), \
191 format_fib_prefix, _via_prefix); \
192}
193
194#define FIB_TEST_LB_BUCKET_VIA_ADJ(_prefix, _bucket, _ai) \
195{ \
196 const dpo_id_t *_dpo = fib_entry_contribute_ip_forwarding( \
197 fib_table_lookup_exact_match(fib_index, (_prefix))); \
198 const dpo_id_t *_dpo1 = \
199 load_balance_get_bucket(_dpo->dpoi_index, _bucket); \
200 FIB_TEST(DPO_ADJACENCY == _dpo1->dpoi_type, "type is %U", \
201 format_dpo_type, _dpo1->dpoi_type); \
202 FIB_TEST((_ai == _dpo1->dpoi_index), \
203 "%U bucket %d resolves via %U", \
204 format_fib_prefix, (_prefix), \
205 _bucket, \
206 format_dpo_id, _dpo1, 0); \
207}
208
Neale Ranns3ee44042016-10-03 13:05:48 +0100209#define FIB_TEST_RPF(_cond, _comment, _args...) \
210{ \
211 if (!FIB_TEST_I(_cond, _comment, ##_args)) { \
212 return (0); \
213 } \
214}
215
216static int
217fib_test_urpf_is_equal (fib_node_index_t fei,
218 fib_forward_chain_type_t fct,
219 u32 num, ...)
220{
Neale Ranns948e00f2016-10-20 13:39:34 +0100221 dpo_id_t dpo = DPO_INVALID;
Neale Ranns3ee44042016-10-03 13:05:48 +0100222 fib_urpf_list_t *urpf;
223 index_t ui;
224 va_list ap;
225 int ii;
226
227 va_start(ap, num);
228
229 fib_entry_contribute_forwarding(fei, fct, &dpo);
230 ui = load_balance_get_urpf(dpo.dpoi_index);
231
232 urpf = fib_urpf_list_get(ui);
233
234 FIB_TEST_RPF(num == vec_len(urpf->furpf_itfs),
235 "RPF:%U len %d == %d",
236 format_fib_urpf_list, ui,
237 num, vec_len(urpf->furpf_itfs));
238 FIB_TEST_RPF(num == fib_urpf_check_size(ui),
239 "RPF:%U check-size %d == %d",
240 format_fib_urpf_list, ui,
241 num, vec_len(urpf->furpf_itfs));
242
243 for (ii = 0; ii < num; ii++)
244 {
245 adj_index_t ai = va_arg(ap, adj_index_t);
246
247 FIB_TEST_RPF(ai == urpf->furpf_itfs[ii],
248 "RPF:%d item:%d - %d == %d",
249 ui, ii, ai, urpf->furpf_itfs[ii]);
250 FIB_TEST_RPF(fib_urpf_check(ui, ai),
251 "RPF:%d %d found",
252 ui, ai);
253 }
254
255 dpo_reset(&dpo);
256
Neale Ranns5899fde2016-10-12 13:51:05 +0100257 va_end(ap);
258
Neale Ranns3ee44042016-10-03 13:05:48 +0100259 return (1);
260}
261
Neale Rannsb80c5362016-10-08 13:03:40 +0100262static u8*
263fib_test_build_rewrite (u8 *eth_addr)
264{
265 u8* rewrite = NULL;
266
267 vec_validate(rewrite, 13);
268
269 memcpy(rewrite, eth_addr, 6);
270 memcpy(rewrite+6, eth_addr, 6);
271
272 return (rewrite);
273}
274
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000275#define FIB_TEST_LB(_cond, _comment, _args...) \
276{ \
277 if (!FIB_TEST_I(_cond, _comment, ##_args)) { \
278 return (0); \
279 } \
280}
281
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800282int
283fib_test_validate_rep_v (const replicate_t *rep,
284 u16 n_buckets,
Christophe Fontained3c008d2017-10-02 18:10:54 +0200285 va_list *ap)
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800286{
287 const fib_test_rep_bucket_t *exp;
288 const dpo_id_t *dpo;
289 int bucket;
290
291 FIB_TEST_LB((n_buckets == rep->rep_n_buckets),
292 "n_buckets = %d", rep->rep_n_buckets);
293
294 for (bucket = 0; bucket < n_buckets; bucket++)
295 {
Christophe Fontained3c008d2017-10-02 18:10:54 +0200296 exp = va_arg(*ap, fib_test_rep_bucket_t*);
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800297
298 dpo = replicate_get_bucket_i(rep, bucket);
299
300 switch (exp->type)
301 {
302 case FT_REP_LABEL_O_ADJ:
303 {
304 const mpls_label_dpo_t *mld;
305 mpls_label_t hdr;
Neale Ranns31ed7442018-02-23 05:29:09 -0800306 FIB_TEST_LB((mpls_label_dpo_get_type(MPLS_LABEL_DPO_FLAG_NONE)
307 == dpo->dpoi_type),
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800308 "bucket %d stacks on %U",
309 bucket,
310 format_dpo_type, dpo->dpoi_type);
311
312 mld = mpls_label_dpo_get(dpo->dpoi_index);
313 hdr = clib_net_to_host_u32(mld->mld_hdr[0].label_exp_s_ttl);
314
315 FIB_TEST_LB((vnet_mpls_uc_get_label(hdr) ==
316 exp->label_o_adj.label),
317 "bucket %d stacks on label %d",
318 bucket,
319 exp->label_o_adj.label);
320
321 FIB_TEST_LB((vnet_mpls_uc_get_s(hdr) ==
322 exp->label_o_adj.eos),
323 "bucket %d stacks on label %d %U",
324 bucket,
325 exp->label_o_adj.label,
326 format_mpls_eos_bit, exp->label_o_adj.eos);
327
328 FIB_TEST_LB((DPO_ADJACENCY_INCOMPLETE == mld->mld_dpo.dpoi_type),
329 "bucket %d label stacks on %U",
330 bucket,
331 format_dpo_type, mld->mld_dpo.dpoi_type);
332
333 FIB_TEST_LB((exp->label_o_adj.adj == mld->mld_dpo.dpoi_index),
334 "bucket %d label stacks on adj %d",
335 bucket,
336 exp->label_o_adj.adj);
337 }
338 break;
339 case FT_REP_INTF:
Neale Ranns43161a82017-08-12 02:12:00 -0700340 FIB_TEST_LB((DPO_INTERFACE_RX == dpo->dpoi_type),
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800341 "bucket %d stacks on %U",
342 bucket,
343 format_dpo_type, dpo->dpoi_type);
344
345 FIB_TEST_LB((exp->adj.adj == dpo->dpoi_index),
346 "bucket %d stacks on adj %d",
347 bucket,
348 exp->adj.adj);
349 break;
350 case FT_REP_DISP_MFIB_LOOKUP:
351// ASSERT(0);
352 break;
353 }
354 }
355
356 return (!0);
357}
358
359int
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000360fib_test_validate_lb_v (const load_balance_t *lb,
Damjan Marionbb17f3c2018-02-06 19:29:35 +0100361 int n_buckets,
Christophe Fontained3c008d2017-10-02 18:10:54 +0200362 va_list *ap)
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000363{
364 const dpo_id_t *dpo;
365 int bucket;
366
367 FIB_TEST_LB((n_buckets == lb->lb_n_buckets), "n_buckets = %d", lb->lb_n_buckets);
368
369 for (bucket = 0; bucket < n_buckets; bucket++)
370 {
371 const fib_test_lb_bucket_t *exp;
372
Christophe Fontained3c008d2017-10-02 18:10:54 +0200373 exp = va_arg(*ap, fib_test_lb_bucket_t*);
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000374 dpo = load_balance_get_bucket_i(lb, bucket);
375
376 switch (exp->type)
377 {
Neale Rannsad422ed2016-11-02 14:20:04 +0000378 case FT_LB_LABEL_STACK_O_ADJ:
379 {
380 const mpls_label_dpo_t *mld;
Neale Ranns31ed7442018-02-23 05:29:09 -0800381 mpls_label_dpo_flags_t mf;
Neale Rannsad422ed2016-11-02 14:20:04 +0000382 mpls_label_t hdr;
383 u32 ii;
384
Neale Ranns31ed7442018-02-23 05:29:09 -0800385 mf = ((exp->label_stack_o_adj.mode ==
386 FIB_MPLS_LSP_MODE_UNIFORM) ?
387 MPLS_LABEL_DPO_FLAG_UNIFORM_MODE :
388 MPLS_LABEL_DPO_FLAG_NONE);
389 FIB_TEST_LB((mpls_label_dpo_get_type(mf) == dpo->dpoi_type),
Neale Rannsad422ed2016-11-02 14:20:04 +0000390 "bucket %d stacks on %U",
391 bucket,
392 format_dpo_type, dpo->dpoi_type);
Neale Ranns31ed7442018-02-23 05:29:09 -0800393
Neale Rannsad422ed2016-11-02 14:20:04 +0000394 mld = mpls_label_dpo_get(dpo->dpoi_index);
395
396 FIB_TEST_LB(exp->label_stack_o_adj.label_stack_size == mld->mld_n_labels,
397 "label stack size",
398 mld->mld_n_labels);
399
400 for (ii = 0; ii < mld->mld_n_labels; ii++)
401 {
402 hdr = clib_net_to_host_u32(mld->mld_hdr[ii].label_exp_s_ttl);
403 FIB_TEST_LB((vnet_mpls_uc_get_label(hdr) ==
404 exp->label_stack_o_adj.label_stack[ii]),
405 "bucket %d stacks on label %d",
406 bucket,
407 exp->label_stack_o_adj.label_stack[ii]);
408
409 if (ii == mld->mld_n_labels-1)
410 {
411 FIB_TEST_LB((vnet_mpls_uc_get_s(hdr) ==
412 exp->label_o_adj.eos),
413 "bucket %d stacks on label %d %U!=%U",
414 bucket,
415 exp->label_stack_o_adj.label_stack[ii],
416 format_mpls_eos_bit, exp->label_o_adj.eos,
417 format_mpls_eos_bit, vnet_mpls_uc_get_s(hdr));
418 }
419 else
420 {
421 FIB_TEST_LB((vnet_mpls_uc_get_s(hdr) == MPLS_NON_EOS),
422 "bucket %d stacks on label %d %U",
423 bucket,
424 exp->label_stack_o_adj.label_stack[ii],
425 format_mpls_eos_bit, vnet_mpls_uc_get_s(hdr));
426 }
427 }
428
429 FIB_TEST_LB((DPO_ADJACENCY_INCOMPLETE == mld->mld_dpo.dpoi_type),
430 "bucket %d label stacks on %U",
431 bucket,
432 format_dpo_type, mld->mld_dpo.dpoi_type);
433
434 FIB_TEST_LB((exp->label_stack_o_adj.adj == mld->mld_dpo.dpoi_index),
435 "bucket %d label stacks on adj %d",
436 bucket,
437 exp->label_stack_o_adj.adj);
438 }
439 break;
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000440 case FT_LB_LABEL_O_ADJ:
441 {
442 const mpls_label_dpo_t *mld;
443 mpls_label_t hdr;
Neale Ranns31ed7442018-02-23 05:29:09 -0800444 FIB_TEST_LB((mpls_label_dpo_get_type(MPLS_LABEL_DPO_FLAG_NONE)
445 == dpo->dpoi_type),
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000446 "bucket %d stacks on %U",
447 bucket,
448 format_dpo_type, dpo->dpoi_type);
449
450 mld = mpls_label_dpo_get(dpo->dpoi_index);
Neale Rannsad422ed2016-11-02 14:20:04 +0000451 hdr = clib_net_to_host_u32(mld->mld_hdr[0].label_exp_s_ttl);
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000452
453 FIB_TEST_LB((vnet_mpls_uc_get_label(hdr) ==
454 exp->label_o_adj.label),
455 "bucket %d stacks on label %d",
456 bucket,
457 exp->label_o_adj.label);
458
459 FIB_TEST_LB((vnet_mpls_uc_get_s(hdr) ==
460 exp->label_o_adj.eos),
461 "bucket %d stacks on label %d %U",
462 bucket,
463 exp->label_o_adj.label,
464 format_mpls_eos_bit, exp->label_o_adj.eos);
465
466 FIB_TEST_LB((DPO_ADJACENCY_INCOMPLETE == mld->mld_dpo.dpoi_type),
467 "bucket %d label stacks on %U",
468 bucket,
469 format_dpo_type, mld->mld_dpo.dpoi_type);
470
471 FIB_TEST_LB((exp->label_o_adj.adj == mld->mld_dpo.dpoi_index),
472 "bucket %d label stacks on adj %d",
473 bucket,
474 exp->label_o_adj.adj);
475 }
476 break;
477 case FT_LB_LABEL_O_LB:
478 {
479 const mpls_label_dpo_t *mld;
Neale Ranns31ed7442018-02-23 05:29:09 -0800480 mpls_label_dpo_flags_t mf;
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000481 mpls_label_t hdr;
482
Neale Ranns31ed7442018-02-23 05:29:09 -0800483 mf = ((exp->label_o_lb.mode ==
484 FIB_MPLS_LSP_MODE_UNIFORM) ?
485 MPLS_LABEL_DPO_FLAG_UNIFORM_MODE :
486 MPLS_LABEL_DPO_FLAG_NONE);
487 FIB_TEST_LB((mpls_label_dpo_get_type(mf) == dpo->dpoi_type),
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000488 "bucket %d stacks on %U",
489 bucket,
490 format_dpo_type, dpo->dpoi_type);
Neale Ranns31ed7442018-02-23 05:29:09 -0800491
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000492 mld = mpls_label_dpo_get(dpo->dpoi_index);
Neale Rannsad422ed2016-11-02 14:20:04 +0000493 hdr = clib_net_to_host_u32(mld->mld_hdr[0].label_exp_s_ttl);
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000494
Neale Rannsad422ed2016-11-02 14:20:04 +0000495 FIB_TEST_LB(1 == mld->mld_n_labels, "label stack size",
496 mld->mld_n_labels);
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000497 FIB_TEST_LB((vnet_mpls_uc_get_label(hdr) ==
498 exp->label_o_lb.label),
499 "bucket %d stacks on label %d",
500 bucket,
501 exp->label_o_lb.label);
502
503 FIB_TEST_LB((vnet_mpls_uc_get_s(hdr) ==
504 exp->label_o_lb.eos),
505 "bucket %d stacks on label %d %U",
506 bucket,
507 exp->label_o_lb.label,
508 format_mpls_eos_bit, exp->label_o_lb.eos);
509
510 FIB_TEST_LB((DPO_LOAD_BALANCE == mld->mld_dpo.dpoi_type),
511 "bucket %d label stacks on %U",
512 bucket,
513 format_dpo_type, mld->mld_dpo.dpoi_type);
514
515 FIB_TEST_LB((exp->label_o_lb.lb == mld->mld_dpo.dpoi_index),
516 "bucket %d label stacks on LB %d",
517 bucket,
518 exp->label_o_lb.lb);
519 }
520 break;
521 case FT_LB_ADJ:
522 FIB_TEST_I(((DPO_ADJACENCY == dpo->dpoi_type) ||
523 (DPO_ADJACENCY_INCOMPLETE == dpo->dpoi_type)),
524 "bucket %d stacks on %U",
525 bucket,
526 format_dpo_type, dpo->dpoi_type);
527 FIB_TEST_LB((exp->adj.adj == dpo->dpoi_index),
528 "bucket %d stacks on adj %d",
529 bucket,
530 exp->adj.adj);
531 break;
Neale Ranns31ed7442018-02-23 05:29:09 -0800532 case FT_LB_MPLS_DISP_PIPE_O_ADJ:
Neale Ranns62fe07c2017-10-31 12:28:22 -0700533 {
534 const mpls_disp_dpo_t *mdd;
535
Neale Ranns31ed7442018-02-23 05:29:09 -0800536 FIB_TEST_I((DPO_MPLS_DISPOSITION_PIPE == dpo->dpoi_type),
Neale Ranns62fe07c2017-10-31 12:28:22 -0700537 "bucket %d stacks on %U",
538 bucket,
539 format_dpo_type, dpo->dpoi_type);
Neale Ranns31ed7442018-02-23 05:29:09 -0800540
Neale Ranns62fe07c2017-10-31 12:28:22 -0700541 mdd = mpls_disp_dpo_get(dpo->dpoi_index);
542
543 dpo = &mdd->mdd_dpo;
544
545 FIB_TEST_I(((DPO_ADJACENCY == dpo->dpoi_type) ||
546 (DPO_ADJACENCY_INCOMPLETE == dpo->dpoi_type)),
547 "bucket %d stacks on %U",
548 bucket,
549 format_dpo_type, dpo->dpoi_type);
550 FIB_TEST_LB((exp->adj.adj == dpo->dpoi_index),
551 "bucket %d stacks on adj %d",
552 bucket,
553 exp->adj.adj);
554 break;
555 }
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800556 case FT_LB_INTF:
Neale Ranns43161a82017-08-12 02:12:00 -0700557 FIB_TEST_I((DPO_INTERFACE_RX == dpo->dpoi_type),
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800558 "bucket %d stacks on %U",
559 bucket,
560 format_dpo_type, dpo->dpoi_type);
561 FIB_TEST_LB((exp->adj.adj == dpo->dpoi_index),
562 "bucket %d stacks on adj %d",
563 bucket,
564 exp->adj.adj);
565 break;
Neale Ranns6f631152017-10-03 08:20:21 -0700566 case FT_LB_L2:
Neale Rannsf068c3e2018-01-03 04:18:48 -0800567 FIB_TEST_I((DPO_DVR == dpo->dpoi_type),
Neale Ranns6f631152017-10-03 08:20:21 -0700568 "bucket %d stacks on %U",
569 bucket,
570 format_dpo_type, dpo->dpoi_type);
571 FIB_TEST_LB((exp->adj.adj == dpo->dpoi_index),
572 "bucket %d stacks on adj %d",
573 bucket,
574 exp->adj.adj);
575 break;
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000576 case FT_LB_O_LB:
577 FIB_TEST_I((DPO_LOAD_BALANCE == dpo->dpoi_type),
578 "bucket %d stacks on %U",
579 bucket,
580 format_dpo_type, dpo->dpoi_type);
581 FIB_TEST_LB((exp->lb.lb == dpo->dpoi_index),
Neale Ranns57b58602017-07-15 07:37:25 -0700582 "bucket %d stacks on lb %d not %d",
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000583 bucket,
Neale Ranns57b58602017-07-15 07:37:25 -0700584 dpo->dpoi_index,
585 exp->lb.lb);
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000586 break;
Neale Rannsd792d9c2017-10-21 10:53:20 -0700587 case FT_LB_BIER_TABLE:
588 FIB_TEST_LB((DPO_BIER_TABLE == dpo->dpoi_type),
589 "bucket %d stacks on %U",
590 bucket,
591 format_dpo_type, dpo->dpoi_type);
592 FIB_TEST_LB((exp->bier.table == dpo->dpoi_index),
593 "bucket %d stacks on lb %d",
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000594 bucket,
Neale Rannsd792d9c2017-10-21 10:53:20 -0700595 exp->bier.table);
596 break;
597 case FT_LB_BIER_FMASK:
598 FIB_TEST_LB((DPO_BIER_FMASK == dpo->dpoi_type),
599 "bucket %d stacks on %U",
600 bucket,
601 format_dpo_type, dpo->dpoi_type);
602 FIB_TEST_LB((exp->bier.fmask == dpo->dpoi_index),
603 "bucket %d stacks on lb %d",
604 bucket,
605 exp->bier.fmask);
606 break;
607 case FT_LB_DROP:
608 FIB_TEST_LB((DPO_DROP == dpo->dpoi_type),
609 "bucket %d stacks on %U",
610 bucket,
611 format_dpo_type, dpo->dpoi_type);
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000612 break;
613 }
614 }
615 return (!0);
616}
617
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800618int
Neale Rannsd792d9c2017-10-21 10:53:20 -0700619fib_test_validate_lb (const dpo_id_t *dpo,
Damjan Marionbb17f3c2018-02-06 19:29:35 +0100620 int n_buckets,
Neale Rannsd792d9c2017-10-21 10:53:20 -0700621 ...)
622{
623 const load_balance_t *lb;
624 va_list ap;
625 int res;
626
627 va_start(ap, n_buckets);
628
Neale Ranns93149bb2017-11-15 10:44:07 -0800629 if (FIB_TEST_I((DPO_LOAD_BALANCE == dpo->dpoi_type),
630 "Entry links to %U",
631 format_dpo_type, dpo->dpoi_type))
632 {
633 lb = load_balance_get(dpo->dpoi_index);
Neale Rannsd792d9c2017-10-21 10:53:20 -0700634
Neale Ranns93149bb2017-11-15 10:44:07 -0800635 res = fib_test_validate_lb_v(lb, n_buckets, &ap);
636 }
637 else
638 {
639 res = !0;
640 }
Neale Rannsd792d9c2017-10-21 10:53:20 -0700641
642 va_end(ap);
643
644 return (res);
645}
646
647int
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000648fib_test_validate_entry (fib_node_index_t fei,
649 fib_forward_chain_type_t fct,
Gabriel Ganned71e0fc2017-10-26 10:35:28 +0200650 int n_buckets,
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000651 ...)
652{
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000653 dpo_id_t dpo = DPO_INVALID;
654 fib_prefix_t pfx;
655 index_t fw_lbi;
656 u32 fib_index;
657 va_list ap;
658 int res;
659
660 va_start(ap, n_buckets);
661
662 fib_entry_get_prefix(fei, &pfx);
663 fib_index = fib_entry_get_fib_index(fei);
664 fib_entry_contribute_forwarding(fei, fct, &dpo);
665
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800666 if (DPO_REPLICATE == dpo.dpoi_type)
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000667 {
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800668 const replicate_t *rep;
669
670 rep = replicate_get(dpo.dpoi_index);
Christophe Fontained3c008d2017-10-02 18:10:54 +0200671 res = fib_test_validate_rep_v(rep, n_buckets, &ap);
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800672 }
673 else
674 {
675 const load_balance_t *lb;
676
677 FIB_TEST_LB((DPO_LOAD_BALANCE == dpo.dpoi_type),
Neale Ranns89541992017-04-06 04:41:02 -0700678 "%U Entry links to %U",
679 format_fib_prefix, &pfx,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800680 format_dpo_type, dpo.dpoi_type);
681
682 lb = load_balance_get(dpo.dpoi_index);
Christophe Fontained3c008d2017-10-02 18:10:54 +0200683 res = fib_test_validate_lb_v(lb, n_buckets, &ap);
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800684
685 /*
686 * ensure that the LB contributed by the entry is the
687 * same as the LB in the forwarding tables
688 */
689 if (fct == fib_entry_get_default_chain_type(fib_entry_get(fei)))
Neale Rannsad422ed2016-11-02 14:20:04 +0000690 {
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800691 switch (pfx.fp_proto)
Neale Rannsad422ed2016-11-02 14:20:04 +0000692 {
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800693 case FIB_PROTOCOL_IP4:
694 fw_lbi = ip4_fib_forwarding_lookup(fib_index, &pfx.fp_addr.ip4);
Neale Rannsad422ed2016-11-02 14:20:04 +0000695 break;
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800696 case FIB_PROTOCOL_IP6:
697 fw_lbi = ip6_fib_table_fwding_lookup(&ip6_main, fib_index, &pfx.fp_addr.ip6);
698 break;
699 case FIB_PROTOCOL_MPLS:
700 {
701 mpls_unicast_header_t hdr = {
702 .label_exp_s_ttl = 0,
703 };
704
705 vnet_mpls_uc_set_label(&hdr.label_exp_s_ttl, pfx.fp_label);
706 vnet_mpls_uc_set_s(&hdr.label_exp_s_ttl, pfx.fp_eos);
707 hdr.label_exp_s_ttl = clib_host_to_net_u32(hdr.label_exp_s_ttl);
708
709 fw_lbi = mpls_fib_table_forwarding_lookup(fib_index, &hdr);
710 break;
711 }
712 default:
713 fw_lbi = 0;
Neale Rannsad422ed2016-11-02 14:20:04 +0000714 }
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800715 FIB_TEST_LB((fw_lbi == dpo.dpoi_index),
Neale Ranns89541992017-04-06 04:41:02 -0700716 "Contributed LB = FW LB:\n fwd:%U\n cont:%U",
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800717 format_load_balance, fw_lbi, 0,
718 format_load_balance, dpo.dpoi_index, 0);
Neale Rannsad422ed2016-11-02 14:20:04 +0000719 }
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000720 }
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000721
722 dpo_reset(&dpo);
723
724 va_end(ap);
725
726 return (res);
727}
728
Neale Ranns0ebe8d72016-12-08 19:48:11 +0000729static int
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100730fib_test_v4 (void)
731{
732 /*
733 * In the default table check for the presence and correct forwarding
734 * of the special entries
735 */
736 fib_node_index_t dfrt, fei, ai, ai2, locked_ai, ai_01, ai_02, ai_03;
737 const dpo_id_t *dpo, *dpo1, *dpo2, *dpo_drop;
738 const ip_adjacency_t *adj;
739 const load_balance_t *lb;
740 test_main_t *tm;
741 u32 fib_index;
Neale Ranns994dab42017-04-18 12:56:45 -0700742 int lb_count;
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100743 int ii;
744
745 /* via 10.10.10.1 */
746 ip46_address_t nh_10_10_10_1 = {
747 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
748 };
749 /* via 10.10.10.2 */
750 ip46_address_t nh_10_10_10_2 = {
751 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02),
752 };
753
Neale Rannsf12a83f2017-04-18 09:09:40 -0700754 FIB_TEST((0 == pool_elts(load_balance_map_pool)), "LB-map pool size is %d",
755 pool_elts(load_balance_map_pool));
756
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100757 tm = &test_main;
758
Neale Ranns994dab42017-04-18 12:56:45 -0700759 /* record the nubmer of load-balances in use before we start */
760 lb_count = pool_elts(load_balance_pool);
761
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100762 /* Find or create FIB table 11 */
Neale Ranns15002542017-09-10 04:39:11 -0700763 fib_index = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP4, 11,
764 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100765
766 for (ii = 0; ii < 4; ii++)
767 {
768 ip4_main.fib_index_by_sw_if_index[tm->hw[ii]->sw_if_index] = fib_index;
769 }
770
771 fib_prefix_t pfx_0_0_0_0_s_0 = {
772 .fp_len = 0,
773 .fp_proto = FIB_PROTOCOL_IP4,
774 .fp_addr = {
775 .ip4 = {
776 {0}
777 },
778 },
779 };
780
781 fib_prefix_t pfx = {
782 .fp_len = 0,
783 .fp_proto = FIB_PROTOCOL_IP4,
784 .fp_addr = {
785 .ip4 = {
786 {0}
787 },
788 },
789 };
790
791 dpo_drop = drop_dpo_get(DPO_PROTO_IP4);
792
793 dfrt = fib_table_lookup(fib_index, &pfx_0_0_0_0_s_0);
794 FIB_TEST((FIB_NODE_INDEX_INVALID != dfrt), "default route present");
795 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(dfrt)),
796 "Default route is DROP");
797
798 pfx.fp_len = 32;
799 fei = fib_table_lookup(fib_index, &pfx);
800 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "all zeros route present");
801 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
802 "all 0s route is DROP");
803
804 pfx.fp_addr.ip4.as_u32 = clib_host_to_net_u32(0xffffffff);
805 pfx.fp_len = 32;
806 fei = fib_table_lookup(fib_index, &pfx);
807 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "all ones route present");
808 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
809 "all 1s route is DROP");
810
811 pfx.fp_addr.ip4.as_u32 = clib_host_to_net_u32(0xe0000000);
812 pfx.fp_len = 8;
813 fei = fib_table_lookup(fib_index, &pfx);
814 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "all-mcast route present");
815 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
816 "all-mcast route is DROP");
817
818 pfx.fp_addr.ip4.as_u32 = clib_host_to_net_u32(0xf0000000);
819 pfx.fp_len = 8;
820 fei = fib_table_lookup(fib_index, &pfx);
821 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "class-e route present");
822 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
823 "class-e route is DROP");
824
825 /*
826 * at this stage there are 5 entries in the test FIB (plus 5 in the default),
827 * all of which are special sourced and so none of which share path-lists.
Neale Ranns32e1c012016-11-22 17:07:28 +0000828 * There are also 2 entries, and 2 non-shared path-lists, in the v6 default
829 * table, and 4 path-lists in the v6 MFIB table
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100830 */
Neale Ranns32e1c012016-11-22 17:07:28 +0000831#define ENBR (5+5+2)
Jakub Grajciar7b867a82017-12-08 16:28:42 +0100832
833 u32 PNBR = 5+5+2+4;
834
835 /*
836 * if the IGMP plugin is loaded this adds two more entries to the v4 MFIB
837 */
838 if (vlib_get_plugin_symbol("igmp_plugin.so", "igmp_listen"))
839 PNBR += 2;
840
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100841 FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +0000842 FIB_TEST((PNBR == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100843 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +0000844 FIB_TEST((ENBR == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100845 fib_entry_pool_size());
846
847 /*
848 * add interface routes.
849 * validate presence of /24 attached and /32 recieve.
850 * test for the presence of the receive address in the glean and local adj
851 */
852 fib_prefix_t local_pfx = {
853 .fp_len = 24,
854 .fp_proto = FIB_PROTOCOL_IP4,
855 .fp_addr = {
856 .ip4 = {
857 .as_u32 = clib_host_to_net_u32(0x0a0a0a0a),
858 },
859 },
860 };
861
862 fib_table_entry_update_one_path(fib_index, &local_pfx,
863 FIB_SOURCE_INTERFACE,
864 (FIB_ENTRY_FLAG_CONNECTED |
865 FIB_ENTRY_FLAG_ATTACHED),
Neale Rannsda78f952017-05-24 09:15:43 -0700866 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100867 NULL,
868 tm->hw[0]->sw_if_index,
869 ~0, // invalid fib index
870 1, // weight
Neale Rannsad422ed2016-11-02 14:20:04 +0000871 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100872 FIB_ROUTE_PATH_FLAG_NONE);
873 fei = fib_table_lookup(fib_index, &local_pfx);
874 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached interface route present");
875 FIB_TEST(((FIB_ENTRY_FLAG_ATTACHED | FIB_ENTRY_FLAG_CONNECTED) ==
876 fib_entry_get_flags(fei)),
877 "Flags set on attached interface");
878
879 ai = fib_entry_get_adj(fei);
Neale Ranns81424992017-05-18 03:03:22 -0700880 FIB_TEST((FIB_NODE_INDEX_INVALID != ai),
881 "attached interface route adj present %d", ai);
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100882 adj = adj_get(ai);
883 FIB_TEST((IP_LOOKUP_NEXT_GLEAN == adj->lookup_next_index),
884 "attached interface adj is glean");
885 FIB_TEST((0 == ip46_address_cmp(&local_pfx.fp_addr,
886 &adj->sub_type.glean.receive_addr)),
887 "attached interface adj is receive ok");
888
889 local_pfx.fp_len = 32;
890 fib_table_entry_update_one_path(fib_index, &local_pfx,
891 FIB_SOURCE_INTERFACE,
892 (FIB_ENTRY_FLAG_CONNECTED |
893 FIB_ENTRY_FLAG_LOCAL),
Neale Rannsda78f952017-05-24 09:15:43 -0700894 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100895 NULL,
896 tm->hw[0]->sw_if_index,
897 ~0, // invalid fib index
898 1, // weight
Neale Rannsad422ed2016-11-02 14:20:04 +0000899 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100900 FIB_ROUTE_PATH_FLAG_NONE);
901 fei = fib_table_lookup(fib_index, &local_pfx);
902 FIB_TEST(((FIB_ENTRY_FLAG_LOCAL | FIB_ENTRY_FLAG_CONNECTED) ==
903 fib_entry_get_flags(fei)),
904 "Flags set on local interface");
905
906 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local interface route present");
907
908 dpo = fib_entry_contribute_ip_forwarding(fei);
Neale Ranns3ee44042016-10-03 13:05:48 +0100909 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 0),
910 "RPF list for local length 0");
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100911 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
912 FIB_TEST((DPO_RECEIVE == dpo->dpoi_type),
913 "local interface adj is local");
914 receive_dpo_t *rd = receive_dpo_get(dpo->dpoi_index);
915
916 FIB_TEST((0 == ip46_address_cmp(&local_pfx.fp_addr,
917 &rd->rd_addr)),
918 "local interface adj is receive ok");
919
920 FIB_TEST((2 == fib_table_get_num_entries(fib_index,
921 FIB_PROTOCOL_IP4,
922 FIB_SOURCE_INTERFACE)),
923 "2 Interface Source'd prefixes");
924
925 /*
926 * +2 interface routes +2 non-shared path-lists
927 */
928 FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +0000929 FIB_TEST((PNBR+2 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100930 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +0000931 FIB_TEST((ENBR+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100932 fib_entry_pool_size());
933
934 /*
935 * Modify the default route to be via an adj not yet known.
936 * this sources the defalut route with the API source, which is
937 * a higher preference to the DEFAULT_ROUTE source
938 */
939 pfx.fp_addr.ip4.as_u32 = 0;
940 pfx.fp_len = 0;
941 fib_table_entry_path_add(fib_index, &pfx,
942 FIB_SOURCE_API,
943 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -0700944 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100945 &nh_10_10_10_1,
946 tm->hw[0]->sw_if_index,
947 ~0, // invalid fib index
948 1,
Neale Rannsad422ed2016-11-02 14:20:04 +0000949 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100950 FIB_ROUTE_PATH_FLAG_NONE);
951 fei = fib_table_lookup(fib_index, &pfx);
952 FIB_TEST((FIB_ENTRY_FLAG_NONE == fib_entry_get_flags(fei)),
953 "Flags set on API route");
954
955 FIB_TEST((fei == dfrt), "default route same index");
956 ai = fib_entry_get_adj(fei);
957 FIB_TEST((FIB_NODE_INDEX_INVALID != ai), "default route adj present");
958 adj = adj_get(ai);
959 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
960 "adj is incomplete");
961 FIB_TEST((0 == ip46_address_cmp(&nh_10_10_10_1, &adj->sub_type.nbr.next_hop)),
962 "adj nbr next-hop ok");
963 FIB_TEST((1 == fib_table_get_num_entries(fib_index,
964 FIB_PROTOCOL_IP4,
965 FIB_SOURCE_API)),
966 "1 API Source'd prefixes");
967
968 /*
969 * find the adj in the shared db
970 */
971 locked_ai = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +0100972 VNET_LINK_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100973 &nh_10_10_10_1,
974 tm->hw[0]->sw_if_index);
975 FIB_TEST((locked_ai == ai), "ADJ NBR DB find");
976 adj_unlock(locked_ai);
977
978 /*
979 * +1 shared path-list
980 */
981 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
982 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +0000983 FIB_TEST((PNBR+3 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100984 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +0000985 FIB_TEST((ENBR+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100986 fib_entry_pool_size());
987
988 /*
989 * remove the API source from the default route. We expected
990 * the route to remain, sourced by DEFAULT_ROUTE, and hence a DROP
991 */
992 pfx.fp_addr.ip4.as_u32 = 0;
993 pfx.fp_len = 0;
994 fib_table_entry_path_remove(fib_index, &pfx,
995 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -0700996 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100997 &nh_10_10_10_1,
998 tm->hw[0]->sw_if_index,
999 ~0, // non-recursive path, so no FIB index
1000 1,
1001 FIB_ROUTE_PATH_FLAG_NONE);
1002
1003 fei = fib_table_lookup(fib_index, &pfx);
1004
1005 FIB_TEST((fei == dfrt), "default route same index");
1006 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
1007 "Default route is DROP");
1008
1009 /*
1010 * -1 shared-path-list
1011 */
1012 FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00001013 FIB_TEST((PNBR+2 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001014 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001015 FIB_TEST((ENBR+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001016 fib_entry_pool_size());
1017
1018 /*
1019 * Add an 2 ARP entry => a complete ADJ plus adj-fib.
1020 */
1021 fib_prefix_t pfx_10_10_10_1_s_32 = {
1022 .fp_len = 32,
1023 .fp_proto = FIB_PROTOCOL_IP4,
1024 .fp_addr = {
1025 /* 10.10.10.1 */
1026 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
1027 },
1028 };
1029 fib_prefix_t pfx_10_10_10_2_s_32 = {
1030 .fp_len = 32,
1031 .fp_proto = FIB_PROTOCOL_IP4,
1032 .fp_addr = {
1033 /* 10.10.10.2 */
1034 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02),
1035 },
1036 };
1037 fib_prefix_t pfx_11_11_11_11_s_32 = {
1038 .fp_len = 32,
1039 .fp_proto = FIB_PROTOCOL_IP4,
1040 .fp_addr = {
1041 /* 11.11.11.11 */
1042 .ip4.as_u32 = clib_host_to_net_u32(0x0b0b0b0b),
1043 },
1044 };
1045 u8 eth_addr[] = {
1046 0xde, 0xde, 0xde, 0xba, 0xba, 0xba,
1047 };
Neale Rannsb80c5362016-10-08 13:03:40 +01001048
Neale Ranns3ee44042016-10-03 13:05:48 +01001049 ip46_address_t nh_12_12_12_12 = {
1050 .ip4.as_u32 = clib_host_to_net_u32(0x0c0c0c0c),
1051 };
1052 adj_index_t ai_12_12_12_12;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001053
1054 /*
1055 * Add a route via an incomplete ADJ. then complete the ADJ
1056 * Expect the route LB is updated to use complete adj type.
1057 */
1058 fei = fib_table_entry_update_one_path(fib_index,
1059 &pfx_11_11_11_11_s_32,
1060 FIB_SOURCE_API,
1061 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07001062 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001063 &pfx_10_10_10_1_s_32.fp_addr,
1064 tm->hw[0]->sw_if_index,
1065 ~0, // invalid fib index
1066 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001067 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001068 FIB_ROUTE_PATH_FLAG_NONE);
1069
1070 dpo = fib_entry_contribute_ip_forwarding(fei);
1071 dpo1 = load_balance_get_bucket(dpo->dpoi_index, 0);
1072 FIB_TEST(DPO_ADJACENCY_INCOMPLETE == dpo1->dpoi_type,
1073 "11.11.11.11/32 via incomplete adj");
1074
1075 ai_01 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01001076 VNET_LINK_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001077 &pfx_10_10_10_1_s_32.fp_addr,
1078 tm->hw[0]->sw_if_index);
1079 FIB_TEST((FIB_NODE_INDEX_INVALID != ai_01), "adj created");
1080 adj = adj_get(ai_01);
1081 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
1082 "adj is incomplete");
1083 FIB_TEST((0 == ip46_address_cmp(&pfx_10_10_10_1_s_32.fp_addr,
1084 &adj->sub_type.nbr.next_hop)),
1085 "adj nbr next-hop ok");
1086
Neale Rannsb80c5362016-10-08 13:03:40 +01001087 adj_nbr_update_rewrite(ai_01, ADJ_NBR_REWRITE_FLAG_COMPLETE,
1088 fib_test_build_rewrite(eth_addr));
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001089 FIB_TEST((IP_LOOKUP_NEXT_REWRITE == adj->lookup_next_index),
1090 "adj is complete");
1091 FIB_TEST((0 == ip46_address_cmp(&pfx_10_10_10_1_s_32.fp_addr,
1092 &adj->sub_type.nbr.next_hop)),
1093 "adj nbr next-hop ok");
1094 ai = fib_entry_get_adj(fei);
1095 FIB_TEST((ai_01 == ai), "ADJ-FIB resolves via adj");
1096
1097 dpo = fib_entry_contribute_ip_forwarding(fei);
1098 dpo1 = load_balance_get_bucket(dpo->dpoi_index, 0);
1099 FIB_TEST(DPO_ADJACENCY == dpo1->dpoi_type,
1100 "11.11.11.11/32 via complete adj");
Neale Ranns3ee44042016-10-03 13:05:48 +01001101 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 1,
1102 tm->hw[0]->sw_if_index),
1103 "RPF list for adj-fib contains adj");
1104
1105 ai_12_12_12_12 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01001106 VNET_LINK_IP4,
Neale Ranns3ee44042016-10-03 13:05:48 +01001107 &nh_12_12_12_12,
1108 tm->hw[1]->sw_if_index);
1109 FIB_TEST((FIB_NODE_INDEX_INVALID != ai_12_12_12_12), "adj created");
1110 adj = adj_get(ai_12_12_12_12);
1111 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
1112 "adj is incomplete");
1113 FIB_TEST((0 == ip46_address_cmp(&nh_12_12_12_12,
1114 &adj->sub_type.nbr.next_hop)),
1115 "adj nbr next-hop ok");
Neale Rannsb80c5362016-10-08 13:03:40 +01001116 adj_nbr_update_rewrite(ai_12_12_12_12, ADJ_NBR_REWRITE_FLAG_COMPLETE,
1117 fib_test_build_rewrite(eth_addr));
Neale Ranns3ee44042016-10-03 13:05:48 +01001118 FIB_TEST((IP_LOOKUP_NEXT_REWRITE == adj->lookup_next_index),
1119 "adj is complete");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001120
1121 /*
1122 * add the adj fib
1123 */
Neale Ranns81424992017-05-18 03:03:22 -07001124 fei = fib_table_entry_path_add(fib_index,
1125 &pfx_10_10_10_1_s_32,
1126 FIB_SOURCE_ADJ,
1127 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07001128 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07001129 &pfx_10_10_10_1_s_32.fp_addr,
1130 tm->hw[0]->sw_if_index,
1131 ~0, // invalid fib index
1132 1,
1133 NULL,
1134 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001135 FIB_TEST((FIB_ENTRY_FLAG_ATTACHED == fib_entry_get_flags(fei)),
1136 "Flags set on adj-fib");
1137 ai = fib_entry_get_adj(fei);
Neale Ranns81424992017-05-18 03:03:22 -07001138 FIB_TEST((ai_01 == ai), "ADJ-FIB resolves via adj, %d", ai);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001139
1140 fib_table_entry_path_remove(fib_index,
1141 &pfx_11_11_11_11_s_32,
1142 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07001143 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001144 &pfx_10_10_10_1_s_32.fp_addr,
1145 tm->hw[0]->sw_if_index,
1146 ~0, // invalid fib index
1147 1,
1148 FIB_ROUTE_PATH_FLAG_NONE);
1149
1150 eth_addr[5] = 0xb2;
1151
1152 ai_02 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01001153 VNET_LINK_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001154 &pfx_10_10_10_2_s_32.fp_addr,
1155 tm->hw[0]->sw_if_index);
1156 FIB_TEST((FIB_NODE_INDEX_INVALID != ai_02), "adj created");
1157 adj = adj_get(ai_02);
1158 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
1159 "adj is incomplete");
1160 FIB_TEST((0 == ip46_address_cmp(&pfx_10_10_10_2_s_32.fp_addr,
1161 &adj->sub_type.nbr.next_hop)),
1162 "adj nbr next-hop ok");
1163
Neale Rannsb80c5362016-10-08 13:03:40 +01001164 adj_nbr_update_rewrite(ai_02, ADJ_NBR_REWRITE_FLAG_COMPLETE,
1165 fib_test_build_rewrite(eth_addr));
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001166 FIB_TEST((IP_LOOKUP_NEXT_REWRITE == adj->lookup_next_index),
1167 "adj is complete");
1168 FIB_TEST((0 == ip46_address_cmp(&pfx_10_10_10_2_s_32.fp_addr,
1169 &adj->sub_type.nbr.next_hop)),
1170 "adj nbr next-hop ok");
1171 FIB_TEST((ai_01 != ai_02), "ADJs are different");
1172
Neale Ranns81424992017-05-18 03:03:22 -07001173 fib_table_entry_path_add(fib_index,
1174 &pfx_10_10_10_2_s_32,
1175 FIB_SOURCE_ADJ,
1176 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07001177 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07001178 &pfx_10_10_10_2_s_32.fp_addr,
1179 tm->hw[0]->sw_if_index,
1180 ~0, // invalid fib index
1181 1,
1182 NULL,
1183 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001184
1185 fei = fib_table_lookup(fib_index, &pfx_10_10_10_2_s_32);
1186 ai = fib_entry_get_adj(fei);
1187 FIB_TEST((ai_02 == ai), "ADJ-FIB resolves via adj");
1188
1189 /*
1190 * +2 adj-fibs, and their non-shared path-lists
1191 */
1192 FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00001193 FIB_TEST((PNBR+4 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001194 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001195 FIB_TEST((ENBR+4 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001196 fib_entry_pool_size());
1197
1198 /*
Neale Ranns3ee44042016-10-03 13:05:48 +01001199 * Add 2 routes via the first ADJ. ensure path-list sharing
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001200 */
1201 fib_prefix_t pfx_1_1_1_1_s_32 = {
1202 .fp_len = 32,
1203 .fp_proto = FIB_PROTOCOL_IP4,
1204 .fp_addr = {
1205 /* 1.1.1.1/32 */
1206 .ip4.as_u32 = clib_host_to_net_u32(0x01010101),
1207 },
1208 };
1209
1210 fib_table_entry_path_add(fib_index,
1211 &pfx_1_1_1_1_s_32,
1212 FIB_SOURCE_API,
1213 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001214 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001215 &nh_10_10_10_1,
1216 tm->hw[0]->sw_if_index,
1217 ~0, // invalid fib index
1218 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001219 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001220 FIB_ROUTE_PATH_FLAG_NONE);
1221 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
1222 ai = fib_entry_get_adj(fei);
1223 FIB_TEST((ai_01 == ai), "1.1.1.1 resolves via 10.10.10.1");
1224
1225 /*
1226 * +1 entry and a shared path-list
1227 */
1228 FIB_TEST((1 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00001229 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001230 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001231 FIB_TEST((ENBR+5 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001232 fib_entry_pool_size());
1233
1234 /* 1.1.2.0/24 */
1235 fib_prefix_t pfx_1_1_2_0_s_24 = {
1236 .fp_len = 24,
1237 .fp_proto = FIB_PROTOCOL_IP4,
1238 .fp_addr = {
1239 .ip4.as_u32 = clib_host_to_net_u32(0x01010200),
1240 }
1241 };
1242
1243 fib_table_entry_path_add(fib_index,
1244 &pfx_1_1_2_0_s_24,
1245 FIB_SOURCE_API,
1246 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001247 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001248 &nh_10_10_10_1,
1249 tm->hw[0]->sw_if_index,
1250 ~0, // invalid fib index
1251 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001252 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001253 FIB_ROUTE_PATH_FLAG_NONE);
1254 fei = fib_table_lookup(fib_index, &pfx_1_1_2_0_s_24);
1255 ai = fib_entry_get_adj(fei);
1256 FIB_TEST((ai_01 == ai), "1.1.2.0/24 resolves via 10.10.10.1");
1257
1258 /*
1259 * +1 entry only
1260 */
1261 FIB_TEST((1 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00001262 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001263 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001264 FIB_TEST((ENBR+6 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001265 fib_entry_pool_size());
1266
1267 /*
1268 * modify 1.1.2.0/24 to use multipath.
1269 */
1270 fib_table_entry_path_add(fib_index,
1271 &pfx_1_1_2_0_s_24,
1272 FIB_SOURCE_API,
1273 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001274 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001275 &nh_10_10_10_2,
1276 tm->hw[0]->sw_if_index,
1277 ~0, // invalid fib index
1278 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001279 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001280 FIB_ROUTE_PATH_FLAG_NONE);
1281 fei = fib_table_lookup(fib_index, &pfx_1_1_2_0_s_24);
1282 dpo = fib_entry_contribute_ip_forwarding(fei);
Neale Ranns3ee44042016-10-03 13:05:48 +01001283 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1284 1, tm->hw[0]->sw_if_index),
1285 "RPF list for 1.1.2.0/24 contains both adjs");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001286
1287 dpo1 = load_balance_get_bucket(dpo->dpoi_index, 0);
1288 FIB_TEST(DPO_ADJACENCY == dpo1->dpoi_type, "type is %d", dpo1->dpoi_type);
1289 FIB_TEST((ai_01 == dpo1->dpoi_index),
1290 "1.1.2.0/24 bucket 0 resolves via 10.10.10.1 (%d=%d)",
1291 ai_01, dpo1->dpoi_index);
1292
1293 dpo1 = load_balance_get_bucket(dpo->dpoi_index, 1);
1294 FIB_TEST(DPO_ADJACENCY == dpo1->dpoi_type, "type is %d", dpo1->dpoi_type);
1295 FIB_TEST((ai_02 == dpo1->dpoi_index),
1296 "1.1.2.0/24 bucket 1 resolves via 10.10.10.2");
1297
1298 /*
1299 * +1 shared-pathlist
1300 */
1301 FIB_TEST((2 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00001302 FIB_TEST((PNBR+6 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001303 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001304 FIB_TEST((ENBR+6 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001305 fib_entry_pool_size());
1306
1307 /*
1308 * revert the modify
1309 */
1310 fib_table_entry_path_remove(fib_index,
1311 &pfx_1_1_2_0_s_24,
1312 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07001313 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001314 &nh_10_10_10_2,
1315 tm->hw[0]->sw_if_index,
1316 ~0,
1317 1,
1318 FIB_ROUTE_PATH_FLAG_NONE);
1319 fei = fib_table_lookup(fib_index, &pfx_1_1_2_0_s_24);
Neale Ranns3ee44042016-10-03 13:05:48 +01001320 dpo = fib_entry_contribute_ip_forwarding(fei);
1321 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1322 1, tm->hw[0]->sw_if_index),
1323 "RPF list for 1.1.2.0/24 contains one adj");
1324
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001325 ai = fib_entry_get_adj(fei);
1326 FIB_TEST((ai_01 == ai), "1.1.2.0/24 resolves via 10.10.10.1");
1327
1328 /*
1329 * +1 shared-pathlist
1330 */
1331 FIB_TEST((1 == fib_path_list_db_size()), "path list DB is %d",
1332 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001333 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001334 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001335 FIB_TEST((ENBR+6 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001336 fib_entry_pool_size());
1337
1338 /*
1339 * Add 2 recursive routes:
1340 * 100.100.100.100/32 via 1.1.1.1/32 => the via entry is installed.
1341 * 100.100.100.101/32 via 1.1.1.1/32 => the via entry is installed.
1342 */
1343 fib_prefix_t bgp_100_pfx = {
1344 .fp_len = 32,
1345 .fp_proto = FIB_PROTOCOL_IP4,
1346 .fp_addr = {
1347 /* 100.100.100.100/32 */
1348 .ip4.as_u32 = clib_host_to_net_u32(0x64646464),
1349 },
1350 };
1351 /* via 1.1.1.1 */
1352 ip46_address_t nh_1_1_1_1 = {
1353 .ip4.as_u32 = clib_host_to_net_u32(0x01010101),
1354 };
1355
Neale Ranns3ee44042016-10-03 13:05:48 +01001356 fei = fib_table_entry_path_add(fib_index,
1357 &bgp_100_pfx,
1358 FIB_SOURCE_API,
1359 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001360 DPO_PROTO_IP4,
Neale Ranns3ee44042016-10-03 13:05:48 +01001361 &nh_1_1_1_1,
1362 ~0, // no index provided.
1363 fib_index, // nexthop in same fib as route
1364 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001365 NULL,
Neale Ranns3ee44042016-10-03 13:05:48 +01001366 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001367
Neale Ranns3ee44042016-10-03 13:05:48 +01001368 FIB_TEST_REC_FORW(&bgp_100_pfx, &pfx_1_1_1_1_s_32, 0);
1369 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 1,
1370 tm->hw[0]->sw_if_index),
1371 "RPF list for adj-fib contains adj");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001372
1373 /*
1374 * +1 entry and +1 shared-path-list
1375 */
1376 FIB_TEST((2 == fib_path_list_db_size()), "path list DB population:%d",
1377 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001378 FIB_TEST((PNBR+6 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001379 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001380 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001381 fib_entry_pool_size());
1382
1383 fib_prefix_t bgp_101_pfx = {
1384 .fp_len = 32,
1385 .fp_proto = FIB_PROTOCOL_IP4,
1386 .fp_addr = {
1387 /* 100.100.100.101/32 */
1388 .ip4.as_u32 = clib_host_to_net_u32(0x64646465),
1389 },
1390 };
1391
1392 fib_table_entry_path_add(fib_index,
1393 &bgp_101_pfx,
1394 FIB_SOURCE_API,
1395 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001396 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001397 &nh_1_1_1_1,
1398 ~0, // no index provided.
1399 fib_index, // nexthop in same fib as route
1400 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001401 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001402 FIB_ROUTE_PATH_FLAG_NONE);
1403
Neale Ranns3ee44042016-10-03 13:05:48 +01001404 FIB_TEST_REC_FORW(&bgp_101_pfx, &pfx_1_1_1_1_s_32, 0);
1405 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 1,
1406 tm->hw[0]->sw_if_index),
1407 "RPF list for adj-fib contains adj");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001408
1409 /*
1410 * +1 entry, but the recursive path-list is shared.
1411 */
1412 FIB_TEST((2 == fib_path_list_db_size()), "path list DB population:%d",
1413 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001414 FIB_TEST((PNBR+6 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001415 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001416 FIB_TEST((ENBR+8 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001417 fib_entry_pool_size());
1418
1419 /*
Neale Rannsa0558302017-04-13 00:44:52 -07001420 * An special route; one where the user (me) provides the
1421 * adjacency through which the route will resovle by setting the flags
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001422 */
1423 fib_prefix_t ex_pfx = {
1424 .fp_len = 32,
1425 .fp_proto = FIB_PROTOCOL_IP4,
1426 .fp_addr = {
1427 /* 4.4.4.4/32 */
1428 .ip4.as_u32 = clib_host_to_net_u32(0x04040404),
1429 },
1430 };
1431
1432 fib_table_entry_special_add(fib_index,
1433 &ex_pfx,
1434 FIB_SOURCE_SPECIAL,
Neale Rannsa0558302017-04-13 00:44:52 -07001435 FIB_ENTRY_FLAG_LOCAL);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001436 fei = fib_table_lookup_exact_match(fib_index, &ex_pfx);
Neale Rannsa0558302017-04-13 00:44:52 -07001437 dpo = fib_entry_contribute_ip_forwarding(fei);
1438 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
1439 FIB_TEST((DPO_RECEIVE == dpo->dpoi_type),
1440 "local interface adj is local");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001441
1442 fib_table_entry_special_remove(fib_index,
1443 &ex_pfx,
1444 FIB_SOURCE_SPECIAL);
1445 FIB_TEST(FIB_NODE_INDEX_INVALID ==
1446 fib_table_lookup_exact_match(fib_index, &ex_pfx),
1447 "Exclusive reoute removed");
1448
1449 /*
1450 * An EXCLUSIVE route; one where the user (me) provides the exclusive
1451 * adjacency through which the route will resovle
1452 */
Neale Ranns948e00f2016-10-20 13:39:34 +01001453 dpo_id_t ex_dpo = DPO_INVALID;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001454
1455 lookup_dpo_add_or_lock_w_fib_index(fib_index,
1456 DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001457 LOOKUP_UNICAST,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001458 LOOKUP_INPUT_DST_ADDR,
1459 LOOKUP_TABLE_FROM_CONFIG,
1460 &ex_dpo);
1461
1462 fib_table_entry_special_dpo_add(fib_index,
1463 &ex_pfx,
1464 FIB_SOURCE_SPECIAL,
1465 FIB_ENTRY_FLAG_EXCLUSIVE,
1466 &ex_dpo);
1467 fei = fib_table_lookup_exact_match(fib_index, &ex_pfx);
1468 dpo = fib_entry_contribute_ip_forwarding(fei);
1469 FIB_TEST(!dpo_cmp(&ex_dpo, load_balance_get_bucket(dpo->dpoi_index, 0)),
1470 "exclusive remote uses lookup DPO");
1471
Neale Ranns948e00f2016-10-20 13:39:34 +01001472 /*
1473 * update the exclusive to use a different DPO
1474 */
Neale Ranns450cd302016-11-09 17:49:42 +00001475 ip_null_dpo_add_and_lock(DPO_PROTO_IP4,
Neale Ranns948e00f2016-10-20 13:39:34 +01001476 IP_NULL_ACTION_SEND_ICMP_UNREACH,
1477 &ex_dpo);
1478 fib_table_entry_special_dpo_update(fib_index,
1479 &ex_pfx,
1480 FIB_SOURCE_SPECIAL,
1481 FIB_ENTRY_FLAG_EXCLUSIVE,
1482 &ex_dpo);
1483 dpo = fib_entry_contribute_ip_forwarding(fei);
1484 FIB_TEST(!dpo_cmp(&ex_dpo, load_balance_get_bucket(dpo->dpoi_index, 0)),
1485 "exclusive remote uses now uses NULL DPO");
1486
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001487 fib_table_entry_special_remove(fib_index,
1488 &ex_pfx,
1489 FIB_SOURCE_SPECIAL);
1490 FIB_TEST(FIB_NODE_INDEX_INVALID ==
1491 fib_table_lookup_exact_match(fib_index, &ex_pfx),
1492 "Exclusive reoute removed");
1493 dpo_reset(&ex_dpo);
1494
1495 /*
1496 * Add a recursive route:
1497 * 200.200.200.200/32 via 1.1.1.2/32 => the via entry is NOT installed.
1498 */
1499 fib_prefix_t bgp_200_pfx = {
1500 .fp_len = 32,
1501 .fp_proto = FIB_PROTOCOL_IP4,
1502 .fp_addr = {
1503 /* 200.200.200.200/32 */
1504 .ip4.as_u32 = clib_host_to_net_u32(0xc8c8c8c8),
1505 },
1506 };
1507 /* via 1.1.1.2 */
1508 fib_prefix_t pfx_1_1_1_2_s_32 = {
1509 .fp_len = 32,
1510 .fp_proto = FIB_PROTOCOL_IP4,
1511 .fp_addr = {
1512 .ip4.as_u32 = clib_host_to_net_u32(0x01010102),
1513 },
1514 };
1515
Neale Ranns57b58602017-07-15 07:37:25 -07001516 fei = fib_table_entry_path_add(fib_index,
1517 &bgp_200_pfx,
1518 FIB_SOURCE_API,
1519 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001520 DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07001521 &pfx_1_1_1_2_s_32.fp_addr,
1522 ~0, // no index provided.
1523 fib_index, // nexthop in same fib as route
1524 1,
1525 NULL,
1526 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001527
Neale Ranns57b58602017-07-15 07:37:25 -07001528 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
1529 "Recursive via unresolved is drop");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001530
1531 /*
1532 * the adj should be recursive via drop, since the route resolves via
1533 * the default route, which is itself a DROP
1534 */
1535 fei = fib_table_lookup(fib_index, &pfx_1_1_1_2_s_32);
1536 dpo1 = fib_entry_contribute_ip_forwarding(fei);
1537 FIB_TEST(load_balance_is_drop(dpo1), "1.1.1.2/32 is drop");
Neale Ranns3ee44042016-10-03 13:05:48 +01001538 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 0),
1539 "RPF list for 1.1.1.2/32 contains 0 adjs");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001540
1541 /*
1542 * +2 entry and +1 shared-path-list
1543 */
1544 FIB_TEST((3 == fib_path_list_db_size()), "path list DB population:%d",
1545 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001546 FIB_TEST((PNBR+7 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001547 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001548 FIB_TEST((ENBR+10 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001549 fib_entry_pool_size());
1550
1551 /*
1552 * Unequal Cost load-balance. 3:1 ratio. fits in a 4 bucket LB
Neale Ranns3ee44042016-10-03 13:05:48 +01001553 * The paths are sort by NH first. in this case the the path with greater
1554 * weight is first in the set. This ordering is to test the RPF sort|uniq logic
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001555 */
1556 fib_prefix_t pfx_1_2_3_4_s_32 = {
1557 .fp_len = 32,
1558 .fp_proto = FIB_PROTOCOL_IP4,
1559 .fp_addr = {
1560 .ip4.as_u32 = clib_host_to_net_u32(0x01020304),
1561 },
1562 };
1563 fib_table_entry_path_add(fib_index,
1564 &pfx_1_2_3_4_s_32,
1565 FIB_SOURCE_API,
1566 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001567 DPO_PROTO_IP4,
Neale Ranns3ee44042016-10-03 13:05:48 +01001568 &nh_10_10_10_1,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001569 tm->hw[0]->sw_if_index,
1570 ~0,
1571 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001572 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001573 FIB_ROUTE_PATH_FLAG_NONE);
1574 fei = fib_table_entry_path_add(fib_index,
1575 &pfx_1_2_3_4_s_32,
1576 FIB_SOURCE_API,
1577 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001578 DPO_PROTO_IP4,
Neale Ranns3ee44042016-10-03 13:05:48 +01001579 &nh_12_12_12_12,
1580 tm->hw[1]->sw_if_index,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001581 ~0,
1582 3,
Neale Rannsad422ed2016-11-02 14:20:04 +00001583 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001584 FIB_ROUTE_PATH_FLAG_NONE);
1585
1586 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "1.2.3.4/32 presnet");
1587 dpo = fib_entry_contribute_ip_forwarding(fei);
1588 lb = load_balance_get(dpo->dpoi_index);
1589 FIB_TEST((lb->lb_n_buckets == 4),
1590 "1.2.3.4/32 LB has %d bucket",
1591 lb->lb_n_buckets);
1592
Neale Ranns3ee44042016-10-03 13:05:48 +01001593 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_4_s_32, 0, ai_12_12_12_12);
1594 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_4_s_32, 1, ai_12_12_12_12);
1595 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_4_s_32, 2, ai_12_12_12_12);
1596 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_4_s_32, 3, ai_01);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001597
Neale Ranns3ee44042016-10-03 13:05:48 +01001598 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 2,
1599 tm->hw[0]->sw_if_index,
1600 tm->hw[1]->sw_if_index),
1601 "RPF list for 1.2.3.4/32 contains both adjs");
1602
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001603
1604 /*
1605 * Unequal Cost load-balance. 4:1 ratio.
1606 * fits in a 16 bucket LB with ratio 13:3
1607 */
1608 fib_prefix_t pfx_1_2_3_5_s_32 = {
1609 .fp_len = 32,
1610 .fp_proto = FIB_PROTOCOL_IP4,
1611 .fp_addr = {
1612 .ip4.as_u32 = clib_host_to_net_u32(0x01020305),
1613 },
1614 };
1615 fib_table_entry_path_add(fib_index,
1616 &pfx_1_2_3_5_s_32,
1617 FIB_SOURCE_API,
1618 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001619 DPO_PROTO_IP4,
Neale Ranns3ee44042016-10-03 13:05:48 +01001620 &nh_12_12_12_12,
1621 tm->hw[1]->sw_if_index,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001622 ~0,
1623 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001624 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001625 FIB_ROUTE_PATH_FLAG_NONE);
1626 fei = fib_table_entry_path_add(fib_index,
1627 &pfx_1_2_3_5_s_32,
1628 FIB_SOURCE_API,
1629 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001630 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001631 &nh_10_10_10_1,
1632 tm->hw[0]->sw_if_index,
1633 ~0,
1634 4,
Neale Rannsad422ed2016-11-02 14:20:04 +00001635 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001636 FIB_ROUTE_PATH_FLAG_NONE);
1637
1638 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "1.2.3.5/32 presnet");
1639 dpo = fib_entry_contribute_ip_forwarding(fei);
1640 lb = load_balance_get(dpo->dpoi_index);
1641 FIB_TEST((lb->lb_n_buckets == 16),
1642 "1.2.3.5/32 LB has %d bucket",
1643 lb->lb_n_buckets);
1644
1645 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 0, ai_01);
1646 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 1, ai_01);
1647 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 2, ai_01);
1648 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 3, ai_01);
1649 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 4, ai_01);
1650 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 5, ai_01);
1651 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 6, ai_01);
1652 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 7, ai_01);
1653 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 8, ai_01);
1654 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 9, ai_01);
1655 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 10, ai_01);
1656 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 11, ai_01);
1657 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 12, ai_01);
Neale Ranns3ee44042016-10-03 13:05:48 +01001658 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 13, ai_12_12_12_12);
1659 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 14, ai_12_12_12_12);
1660 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 15, ai_12_12_12_12);
1661
1662 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 2,
1663 tm->hw[0]->sw_if_index,
1664 tm->hw[1]->sw_if_index),
1665 "RPF list for 1.2.3.4/32 contains both adjs");
1666
1667 /*
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001668 * Test UCMP with a large weight skew - this produces load-balance objects with large
1669 * numbers of buckets to accommodate the skew. By updating said load-balances we are
1670 * laso testing the LB in placce modify code when number of buckets is large.
1671 */
1672 fib_prefix_t pfx_6_6_6_6_s_32 = {
1673 .fp_len = 32,
1674 .fp_proto = FIB_PROTOCOL_IP4,
1675 .fp_addr = {
1676 /* 1.1.1.1/32 */
1677 .ip4.as_u32 = clib_host_to_net_u32(0x06060606),
1678 },
1679 };
Neale Ranns81424992017-05-18 03:03:22 -07001680 fib_test_lb_bucket_t ip_o_10_10_10_1 = {
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001681 .type = FT_LB_ADJ,
1682 .adj = {
1683 .adj = ai_01,
1684 },
1685 };
Neale Ranns81424992017-05-18 03:03:22 -07001686 fib_test_lb_bucket_t ip_o_10_10_10_2 = {
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001687 .type = FT_LB_ADJ,
1688 .adj = {
1689 .adj = ai_02,
1690 },
1691 };
1692 fib_test_lb_bucket_t ip_6_6_6_6_o_12_12_12_12 = {
1693 .type = FT_LB_ADJ,
1694 .adj = {
1695 .adj = ai_12_12_12_12,
1696 },
1697 };
1698 fib_table_entry_update_one_path(fib_index,
1699 &pfx_6_6_6_6_s_32,
1700 FIB_SOURCE_API,
1701 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001702 DPO_PROTO_IP4,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001703 &nh_10_10_10_1,
1704 tm->hw[0]->sw_if_index,
1705 ~0, // invalid fib index
1706 0, // zero weigth
Neale Rannsad422ed2016-11-02 14:20:04 +00001707 NULL,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001708 FIB_ROUTE_PATH_FLAG_NONE);
1709
1710 fei = fib_table_lookup(fib_index, &pfx_6_6_6_6_s_32);
1711 FIB_TEST(fib_test_validate_entry(fei,
1712 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1713 1,
Neale Ranns81424992017-05-18 03:03:22 -07001714 &ip_o_10_10_10_1),
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001715 "6.6.6.6/32 via 10.10.10.1");
1716
1717 fib_table_entry_path_add(fib_index,
1718 &pfx_6_6_6_6_s_32,
1719 FIB_SOURCE_API,
1720 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001721 DPO_PROTO_IP4,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001722 &nh_10_10_10_2,
1723 tm->hw[0]->sw_if_index,
1724 ~0, // invalid fib index
1725 100,
Neale Rannsad422ed2016-11-02 14:20:04 +00001726 NULL,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001727 FIB_ROUTE_PATH_FLAG_NONE);
1728
1729 fei = fib_table_lookup(fib_index, &pfx_6_6_6_6_s_32);
1730 FIB_TEST(fib_test_validate_entry(fei,
1731 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1732 64,
Neale Ranns81424992017-05-18 03:03:22 -07001733 &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_2,
1787 &ip_o_10_10_10_2,
1788 &ip_o_10_10_10_2,
1789 &ip_o_10_10_10_2,
1790 &ip_o_10_10_10_2,
1791 &ip_o_10_10_10_2,
1792 &ip_o_10_10_10_2,
1793 &ip_o_10_10_10_2,
1794 &ip_o_10_10_10_2,
1795 &ip_o_10_10_10_2,
1796 &ip_o_10_10_10_1),
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001797 "6.6.6.6/32 via 10.10.10.1 and 10.10.10.2 in 63:1 ratio");
1798
1799 fib_table_entry_path_add(fib_index,
1800 &pfx_6_6_6_6_s_32,
1801 FIB_SOURCE_API,
1802 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001803 DPO_PROTO_IP4,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001804 &nh_12_12_12_12,
1805 tm->hw[1]->sw_if_index,
1806 ~0, // invalid fib index
1807 100,
Neale Rannsad422ed2016-11-02 14:20:04 +00001808 NULL,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001809 FIB_ROUTE_PATH_FLAG_NONE);
1810
1811 fei = fib_table_lookup(fib_index, &pfx_6_6_6_6_s_32);
1812 FIB_TEST(fib_test_validate_entry(fei,
1813 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1814 128,
Neale Ranns81424992017-05-18 03:03:22 -07001815 &ip_o_10_10_10_1,
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,
1870 &ip_o_10_10_10_2,
1871 &ip_o_10_10_10_2,
1872 &ip_o_10_10_10_2,
1873 &ip_o_10_10_10_2,
1874 &ip_o_10_10_10_2,
1875 &ip_o_10_10_10_2,
1876 &ip_o_10_10_10_2,
1877 &ip_o_10_10_10_2,
1878 &ip_o_10_10_10_2,
1879 &ip_o_10_10_10_2,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001880 &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 &ip_6_6_6_6_o_12_12_12_12,
1934 &ip_6_6_6_6_o_12_12_12_12,
1935 &ip_6_6_6_6_o_12_12_12_12,
1936 &ip_6_6_6_6_o_12_12_12_12,
1937 &ip_6_6_6_6_o_12_12_12_12,
1938 &ip_6_6_6_6_o_12_12_12_12,
1939 &ip_6_6_6_6_o_12_12_12_12,
1940 &ip_6_6_6_6_o_12_12_12_12,
1941 &ip_6_6_6_6_o_12_12_12_12,
1942 &ip_6_6_6_6_o_12_12_12_12),
1943 "6.6.6.6/32 via 10.10.10.1 and 10.10.10.2 in 63:1 ratio");
1944
1945 fib_table_entry_path_remove(fib_index,
1946 &pfx_6_6_6_6_s_32,
1947 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07001948 DPO_PROTO_IP4,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001949 &nh_12_12_12_12,
1950 tm->hw[1]->sw_if_index,
1951 ~0, // invalid fib index
1952 100,
1953 FIB_ROUTE_PATH_FLAG_NONE);
1954
1955 fei = fib_table_lookup(fib_index, &pfx_6_6_6_6_s_32);
1956 FIB_TEST(fib_test_validate_entry(fei,
1957 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1958 64,
Neale Ranns81424992017-05-18 03:03:22 -07001959 &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_2,
2013 &ip_o_10_10_10_2,
2014 &ip_o_10_10_10_2,
2015 &ip_o_10_10_10_2,
2016 &ip_o_10_10_10_2,
2017 &ip_o_10_10_10_2,
2018 &ip_o_10_10_10_2,
2019 &ip_o_10_10_10_2,
2020 &ip_o_10_10_10_2,
2021 &ip_o_10_10_10_2,
2022 &ip_o_10_10_10_1),
Neale Ranns0bd36ea2016-11-16 11:47:44 +00002023 "6.6.6.6/32 via 10.10.10.1 and 10.10.10.2 in 63:1 ratio");
2024
2025 fib_table_entry_path_remove(fib_index,
2026 &pfx_6_6_6_6_s_32,
2027 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002028 DPO_PROTO_IP4,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00002029 &nh_10_10_10_2,
2030 tm->hw[0]->sw_if_index,
2031 ~0, // invalid fib index
2032 100,
2033 FIB_ROUTE_PATH_FLAG_NONE);
2034
2035 fei = fib_table_lookup(fib_index, &pfx_6_6_6_6_s_32);
2036 FIB_TEST(fib_test_validate_entry(fei,
2037 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
2038 1,
Neale Ranns81424992017-05-18 03:03:22 -07002039 &ip_o_10_10_10_1),
Neale Ranns0bd36ea2016-11-16 11:47:44 +00002040 "6.6.6.6/32 via 10.10.10.1");
2041
2042 fib_table_entry_delete(fib_index, &pfx_6_6_6_6_s_32, FIB_SOURCE_API);
2043
2044 /*
Neale Ranns3ee44042016-10-03 13:05:48 +01002045 * A recursive via the two unequal cost entries
2046 */
2047 fib_prefix_t bgp_44_s_32 = {
2048 .fp_len = 32,
2049 .fp_proto = FIB_PROTOCOL_IP4,
2050 .fp_addr = {
2051 /* 200.200.200.201/32 */
2052 .ip4.as_u32 = clib_host_to_net_u32(0x44444444),
2053 },
2054 };
2055 fei = fib_table_entry_path_add(fib_index,
2056 &bgp_44_s_32,
2057 FIB_SOURCE_API,
2058 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002059 DPO_PROTO_IP4,
Neale Ranns3ee44042016-10-03 13:05:48 +01002060 &pfx_1_2_3_4_s_32.fp_addr,
2061 ~0,
2062 fib_index,
2063 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002064 NULL,
Neale Ranns3ee44042016-10-03 13:05:48 +01002065 FIB_ROUTE_PATH_FLAG_NONE);
2066 fei = fib_table_entry_path_add(fib_index,
2067 &bgp_44_s_32,
2068 FIB_SOURCE_API,
2069 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002070 DPO_PROTO_IP4,
Neale Ranns3ee44042016-10-03 13:05:48 +01002071 &pfx_1_2_3_5_s_32.fp_addr,
2072 ~0,
2073 fib_index,
2074 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002075 NULL,
Neale Ranns3ee44042016-10-03 13:05:48 +01002076 FIB_ROUTE_PATH_FLAG_NONE);
2077
2078 FIB_TEST_REC_FORW(&bgp_44_s_32, &pfx_1_2_3_4_s_32, 0);
2079 FIB_TEST_REC_FORW(&bgp_44_s_32, &pfx_1_2_3_5_s_32, 1);
2080 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 2,
2081 tm->hw[0]->sw_if_index,
2082 tm->hw[1]->sw_if_index),
2083 "RPF list for 1.2.3.4/32 contains both adjs");
2084
2085 /*
2086 * test the uRPF check functions
2087 */
Neale Ranns948e00f2016-10-20 13:39:34 +01002088 dpo_id_t dpo_44 = DPO_INVALID;
Neale Ranns3ee44042016-10-03 13:05:48 +01002089 index_t urpfi;
2090
2091 fib_entry_contribute_forwarding(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, &dpo_44);
2092 urpfi = load_balance_get_urpf(dpo_44.dpoi_index);
2093
2094 FIB_TEST(fib_urpf_check(urpfi, tm->hw[0]->sw_if_index),
2095 "uRPF check for 68.68.68.68/32 on %d OK",
2096 tm->hw[0]->sw_if_index);
2097 FIB_TEST(fib_urpf_check(urpfi, tm->hw[1]->sw_if_index),
2098 "uRPF check for 68.68.68.68/32 on %d OK",
2099 tm->hw[1]->sw_if_index);
2100 FIB_TEST(!fib_urpf_check(urpfi, 99),
2101 "uRPF check for 68.68.68.68/32 on 99 not-OK",
2102 99);
2103 dpo_reset(&dpo_44);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002104
2105 fib_table_entry_delete(fib_index,
Neale Ranns3ee44042016-10-03 13:05:48 +01002106 &bgp_44_s_32,
2107 FIB_SOURCE_API);
2108 fib_table_entry_delete(fib_index,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002109 &pfx_1_2_3_5_s_32,
2110 FIB_SOURCE_API);
Neale Ranns3ee44042016-10-03 13:05:48 +01002111 fib_table_entry_delete(fib_index,
2112 &pfx_1_2_3_4_s_32,
2113 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002114
2115 /*
2116 * Add a recursive route:
2117 * 200.200.200.201/32 via 1.1.1.200/32 => the via entry is NOT installed.
2118 */
2119 fib_prefix_t bgp_201_pfx = {
2120 .fp_len = 32,
2121 .fp_proto = FIB_PROTOCOL_IP4,
2122 .fp_addr = {
2123 /* 200.200.200.201/32 */
2124 .ip4.as_u32 = clib_host_to_net_u32(0xc8c8c8c9),
2125 },
2126 };
2127 /* via 1.1.1.200 */
2128 fib_prefix_t pfx_1_1_1_200_s_32 = {
2129 .fp_len = 32,
2130 .fp_proto = FIB_PROTOCOL_IP4,
2131 .fp_addr = {
2132 .ip4.as_u32 = clib_host_to_net_u32(0x010101c8),
2133 },
2134 };
2135
Neale Ranns57b58602017-07-15 07:37:25 -07002136 fei = fib_table_entry_path_add(fib_index,
2137 &bgp_201_pfx,
2138 FIB_SOURCE_API,
2139 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002140 DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07002141 &pfx_1_1_1_200_s_32.fp_addr,
2142 ~0, // no index provided.
2143 fib_index, // nexthop in same fib as route
2144 1,
2145 NULL,
2146 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002147
Neale Ranns57b58602017-07-15 07:37:25 -07002148 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2149 "Recursive via unresolved is drop");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002150
2151 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_200_s_32);
2152 FIB_TEST((FIB_ENTRY_FLAG_NONE == fib_entry_get_flags(fei)),
2153 "Flags set on RR via non-attached");
Neale Ranns3ee44042016-10-03 13:05:48 +01002154 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 0),
2155 "RPF list for BGP route empty");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002156
2157 /*
2158 * +2 entry (BGP & RR) and +1 shared-path-list
2159 */
2160 FIB_TEST((4 == fib_path_list_db_size()), "path list DB population:%d",
2161 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002162 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002163 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002164 FIB_TEST((ENBR+12 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002165 fib_entry_pool_size());
2166
2167 /*
2168 * insert a route that covers the missing 1.1.1.2/32. we epxect
2169 * 200.200.200.200/32 and 200.200.200.201/32 to resolve through it.
2170 */
2171 fib_prefix_t pfx_1_1_1_0_s_24 = {
2172 .fp_len = 24,
2173 .fp_proto = FIB_PROTOCOL_IP4,
2174 .fp_addr = {
2175 /* 1.1.1.0/24 */
2176 .ip4.as_u32 = clib_host_to_net_u32(0x01010100),
2177 },
2178 };
2179
2180 fib_table_entry_path_add(fib_index,
2181 &pfx_1_1_1_0_s_24,
2182 FIB_SOURCE_API,
2183 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002184 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002185 &nh_10_10_10_1,
2186 tm->hw[0]->sw_if_index,
2187 ~0, // invalid fib index
2188 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002189 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002190 FIB_ROUTE_PATH_FLAG_NONE);
2191 fei = fib_table_lookup(fib_index, &pfx_1_1_1_0_s_24);
2192 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2193 ai = fib_entry_get_adj(fei);
2194 FIB_TEST((ai_01 == ai), "1.1.1.0/24 resolves via 10.10.10.1");
2195 fei = fib_table_lookup(fib_index, &pfx_1_1_1_2_s_32);
2196 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2197 ai = fib_entry_get_adj(fei);
2198 FIB_TEST((ai_01 == ai), "1.1.1.2/32 resolves via 10.10.10.1");
2199 fei = fib_table_lookup(fib_index, &pfx_1_1_1_200_s_32);
2200 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2201 ai = fib_entry_get_adj(fei);
2202 FIB_TEST((ai_01 == ai), "1.1.1.200/24 resolves via 10.10.10.1");
2203
2204 /*
2205 * +1 entry. 1.1.1.1/32 already uses 10.10.10.1 so no new pah-list
2206 */
2207 FIB_TEST((4 == fib_path_list_db_size()), "path list DB population:%d",
2208 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002209 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002210 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002211 FIB_TEST((ENBR+13 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002212 fib_entry_pool_size());
2213
2214 /*
2215 * the recursive adj for 200.200.200.200 should be updated.
2216 */
Neale Ranns3ee44042016-10-03 13:05:48 +01002217 FIB_TEST_REC_FORW(&bgp_201_pfx, &pfx_1_1_1_200_s_32, 0);
2218 FIB_TEST_REC_FORW(&bgp_200_pfx, &pfx_1_1_1_2_s_32, 0);
2219 fei = fib_table_lookup(fib_index, &bgp_200_pfx);
2220 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 1,
2221 tm->hw[0]->sw_if_index),
2222 "RPF list for BGP route has itf index 0");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002223
2224 /*
2225 * insert a more specific route than 1.1.1.0/24 that also covers the
2226 * missing 1.1.1.2/32, but not 1.1.1.200/32. we epxect
2227 * 200.200.200.200 to resolve through it.
2228 */
2229 fib_prefix_t pfx_1_1_1_0_s_28 = {
2230 .fp_len = 28,
2231 .fp_proto = FIB_PROTOCOL_IP4,
2232 .fp_addr = {
2233 /* 1.1.1.0/24 */
2234 .ip4.as_u32 = clib_host_to_net_u32(0x01010100),
2235 },
2236 };
2237
2238 fib_table_entry_path_add(fib_index,
2239 &pfx_1_1_1_0_s_28,
2240 FIB_SOURCE_API,
2241 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002242 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002243 &nh_10_10_10_2,
2244 tm->hw[0]->sw_if_index,
2245 ~0, // invalid fib index
2246 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002247 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002248 FIB_ROUTE_PATH_FLAG_NONE);
2249 fei = fib_table_lookup(fib_index, &pfx_1_1_1_0_s_28);
2250 dpo2 = fib_entry_contribute_ip_forwarding(fei);
2251 ai = fib_entry_get_adj(fei);
2252 FIB_TEST((ai_02 == ai), "1.1.1.0/24 resolves via 10.10.10.2");
2253
2254 /*
2255 * +1 entry. +1 shared path-list
2256 */
2257 FIB_TEST((5 == fib_path_list_db_size()), "path list DB population:%d",
2258 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002259 FIB_TEST((PNBR+9 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002260 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002261 FIB_TEST((ENBR+14 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002262 fib_entry_pool_size());
2263
2264 /*
2265 * the recursive adj for 200.200.200.200 should be updated.
2266 * 200.200.200.201 remains unchanged.
2267 */
Neale Ranns3ee44042016-10-03 13:05:48 +01002268 FIB_TEST_REC_FORW(&bgp_201_pfx, &pfx_1_1_1_200_s_32, 0);
2269 FIB_TEST_REC_FORW(&bgp_200_pfx, &pfx_1_1_1_2_s_32, 0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002270
2271 /*
2272 * remove this /28. 200.200.200.200/32 should revert back to via 1.1.1.0/24
2273 */
2274 fib_table_entry_path_remove(fib_index,
2275 &pfx_1_1_1_0_s_28,
2276 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002277 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002278 &nh_10_10_10_2,
2279 tm->hw[0]->sw_if_index,
2280 ~0,
2281 1,
2282 FIB_ROUTE_PATH_FLAG_NONE);
2283 FIB_TEST((fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_0_s_28) ==
2284 FIB_NODE_INDEX_INVALID),
2285 "1.1.1.0/28 removed");
2286 FIB_TEST((fib_table_lookup(fib_index, &pfx_1_1_1_0_s_28) ==
2287 fib_table_lookup(fib_index, &pfx_1_1_1_0_s_24)),
2288 "1.1.1.0/28 lookup via /24");
Neale Ranns3ee44042016-10-03 13:05:48 +01002289 FIB_TEST_REC_FORW(&bgp_201_pfx, &pfx_1_1_1_200_s_32, 0);
2290 FIB_TEST_REC_FORW(&bgp_200_pfx, &pfx_1_1_1_2_s_32, 0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002291
2292 /*
2293 * -1 entry. -1 shared path-list
2294 */
2295 FIB_TEST((4 == fib_path_list_db_size()), "path list DB population:%d",
2296 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002297 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002298 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002299 FIB_TEST((ENBR+13 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002300 fib_entry_pool_size());
2301
2302 /*
2303 * remove 1.1.1.0/24. 200.200.200.200/32 should revert back to via 0.0.0.0/0
2304 */
2305 fib_table_entry_path_remove(fib_index,
2306 &pfx_1_1_1_0_s_24,
2307 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002308 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002309 &nh_10_10_10_1,
2310 tm->hw[0]->sw_if_index,
2311 ~0,
2312 1,
2313 FIB_ROUTE_PATH_FLAG_NONE);
2314 FIB_TEST((fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_0_s_24) ==
2315 FIB_NODE_INDEX_INVALID),
2316 "1.1.1.0/24 removed");
2317
2318 fei = fib_table_lookup(fib_index, &pfx_1_1_1_2_s_32);
2319 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2320 "1.1.1.2/32 route is DROP");
Neale Ranns57b58602017-07-15 07:37:25 -07002321 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_200_s_32);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002322 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2323 "1.1.1.200/32 route is DROP");
2324
Neale Ranns57b58602017-07-15 07:37:25 -07002325 fei = fib_table_lookup_exact_match(fib_index, &bgp_201_pfx);
2326 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2327 "201 is drop");
2328 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
2329 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2330 "200 is drop");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002331
2332 /*
2333 * -1 entry
2334 */
2335 FIB_TEST((4 == fib_path_list_db_size()), "path list DB population:%d",
2336 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002337 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002338 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002339 FIB_TEST((ENBR+12 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002340 fib_entry_pool_size());
2341
2342 /*
2343 * insert the missing 1.1.1.2/32
2344 */
2345 fei = fib_table_entry_path_add(fib_index,
2346 &pfx_1_1_1_2_s_32,
2347 FIB_SOURCE_API,
2348 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002349 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002350 &nh_10_10_10_1,
2351 tm->hw[0]->sw_if_index,
2352 ~0, // invalid fib index
2353 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002354 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002355 FIB_ROUTE_PATH_FLAG_NONE);
2356 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2357 ai = fib_entry_get_adj(fei);
2358 FIB_TEST((ai = ai_01), "1.1.1.2/32 resolves via 10.10.10.1");
2359
Neale Ranns57b58602017-07-15 07:37:25 -07002360 fei = fib_table_lookup_exact_match(fib_index, &bgp_201_pfx);
2361 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2362 "201 is drop");
Neale Ranns3ee44042016-10-03 13:05:48 +01002363 FIB_TEST_REC_FORW(&bgp_200_pfx, &pfx_1_1_1_2_s_32, 0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002364
2365 /*
2366 * no change. 1.1.1.2/32 was already there RR sourced.
2367 */
2368 FIB_TEST((4 == fib_path_list_db_size()), "path list DB population:%d",
2369 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002370 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002371 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002372 FIB_TEST((ENBR+12 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002373 fib_entry_pool_size());
2374
2375 /*
Neale Ranns57b58602017-07-15 07:37:25 -07002376 * give 201 a resolved path.
2377 * it now has the unresolved 1.1.1.200 and the resolved 1.1.1.2,
2378 * only the latter contributes forwarding.
2379 */
2380 fei = fib_table_entry_path_add(fib_index,
2381 &bgp_201_pfx,
2382 FIB_SOURCE_API,
2383 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002384 DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07002385 &pfx_1_1_1_2_s_32.fp_addr,
2386 ~0,
2387 fib_index,
2388 1,
2389 NULL,
2390 FIB_ROUTE_PATH_FLAG_NONE);
2391 FIB_TEST_REC_FORW(&bgp_201_pfx, &pfx_1_1_1_2_s_32, 0);
2392 fib_table_entry_path_remove(fib_index,
2393 &bgp_201_pfx,
2394 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002395 DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07002396 &pfx_1_1_1_2_s_32.fp_addr,
2397 ~0,
2398 fib_index,
2399 1,
2400 FIB_ROUTE_PATH_FLAG_NONE);
2401
2402 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002403 * remove 200.200.200.201/32 which does not have a valid via FIB
2404 */
2405 fib_table_entry_path_remove(fib_index,
2406 &bgp_201_pfx,
2407 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002408 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002409 &pfx_1_1_1_200_s_32.fp_addr,
2410 ~0, // no index provided.
2411 fib_index,
2412 1,
2413 FIB_ROUTE_PATH_FLAG_NONE);
2414
2415 /*
2416 * -2 entries (BGP and RR). -1 shared path-list;
2417 */
2418 FIB_TEST((fib_table_lookup_exact_match(fib_index, &bgp_201_pfx) ==
2419 FIB_NODE_INDEX_INVALID),
2420 "200.200.200.201/32 removed");
2421 FIB_TEST((fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_200_s_32) ==
2422 FIB_NODE_INDEX_INVALID),
2423 "1.1.1.200/32 removed");
2424
2425 FIB_TEST((3 == fib_path_list_db_size()), "path list DB population:%d",
2426 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002427 FIB_TEST((PNBR+7 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002428 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002429 FIB_TEST((ENBR+10 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002430 fib_entry_pool_size());
2431
2432 /*
2433 * remove 200.200.200.200/32 which does have a valid via FIB
2434 */
2435 fib_table_entry_path_remove(fib_index,
2436 &bgp_200_pfx,
2437 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002438 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002439 &pfx_1_1_1_2_s_32.fp_addr,
2440 ~0, // no index provided.
2441 fib_index,
2442 1,
2443 FIB_ROUTE_PATH_FLAG_NONE);
2444
2445 FIB_TEST((fib_table_lookup_exact_match(fib_index, &bgp_200_pfx) ==
2446 FIB_NODE_INDEX_INVALID),
2447 "200.200.200.200/32 removed");
2448 FIB_TEST((fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_2_s_32) !=
2449 FIB_NODE_INDEX_INVALID),
2450 "1.1.1.2/32 still present");
2451
2452 /*
2453 * -1 entry (BGP, the RR source is also API sourced). -1 shared path-list;
2454 */
2455 FIB_TEST((2 == fib_path_list_db_size()), "path list DB population:%d",
2456 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002457 FIB_TEST((PNBR+6 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002458 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002459 FIB_TEST((ENBR+9 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002460 fib_entry_pool_size());
2461
2462 /*
2463 * A recursive prefix that has a 2 path load-balance.
2464 * It also shares a next-hop with other BGP prefixes and hence
2465 * test the ref counting of RR sourced prefixes and 2 level LB.
2466 */
2467 const fib_prefix_t bgp_102 = {
2468 .fp_len = 32,
2469 .fp_proto = FIB_PROTOCOL_IP4,
2470 .fp_addr = {
2471 /* 100.100.100.101/32 */
2472 .ip4.as_u32 = clib_host_to_net_u32(0x64646466),
2473 },
2474 };
2475 fib_table_entry_path_add(fib_index,
2476 &bgp_102,
2477 FIB_SOURCE_API,
2478 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002479 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002480 &pfx_1_1_1_1_s_32.fp_addr,
2481 ~0, // no index provided.
2482 fib_index, // same as route
2483 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002484 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002485 FIB_ROUTE_PATH_FLAG_NONE);
2486 fib_table_entry_path_add(fib_index,
2487 &bgp_102,
2488 FIB_SOURCE_API,
2489 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002490 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002491 &pfx_1_1_1_2_s_32.fp_addr,
2492 ~0, // no index provided.
2493 fib_index, // same as route's FIB
2494 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002495 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002496 FIB_ROUTE_PATH_FLAG_NONE);
2497 fei = fib_table_lookup_exact_match(fib_index, &bgp_102);
2498 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "100.100.100.102/32 presnet");
2499 dpo = fib_entry_contribute_ip_forwarding(fei);
2500
2501 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_1_s_32);
2502 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2503 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_2_s_32);
2504 dpo2 = fib_entry_contribute_ip_forwarding(fei);
2505
2506 lb = load_balance_get(dpo->dpoi_index);
2507 FIB_TEST((lb->lb_n_buckets == 2), "Recursive LB has %d bucket", lb->lb_n_buckets);
2508 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket(dpo->dpoi_index, 0)),
2509 "First via 10.10.10.1");
2510 FIB_TEST(!dpo_cmp(dpo2, load_balance_get_bucket(dpo->dpoi_index, 1)),
2511 "Second via 10.10.10.1");
2512
2513 fib_table_entry_path_remove(fib_index,
2514 &bgp_102,
2515 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002516 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002517 &pfx_1_1_1_1_s_32.fp_addr,
2518 ~0, // no index provided.
2519 fib_index, // same as route's FIB
2520 1,
2521 FIB_ROUTE_PATH_FLAG_NONE);
2522 fib_table_entry_path_remove(fib_index,
2523 &bgp_102,
2524 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002525 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002526 &pfx_1_1_1_2_s_32.fp_addr,
2527 ~0, // no index provided.
2528 fib_index, // same as route's FIB
2529 1,
2530 FIB_ROUTE_PATH_FLAG_NONE);
2531 fei = fib_table_lookup_exact_match(fib_index, &bgp_102);
2532 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "100.100.100.102/32 removed");
2533
2534 /*
2535 * remove the remaining recursives
2536 */
2537 fib_table_entry_path_remove(fib_index,
2538 &bgp_100_pfx,
2539 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002540 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002541 &pfx_1_1_1_1_s_32.fp_addr,
2542 ~0, // no index provided.
2543 fib_index, // same as route's FIB
2544 1,
2545 FIB_ROUTE_PATH_FLAG_NONE);
2546 fib_table_entry_path_remove(fib_index,
2547 &bgp_101_pfx,
2548 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002549 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002550 &pfx_1_1_1_1_s_32.fp_addr,
2551 ~0, // no index provided.
2552 fib_index, // same as route's FIB
2553 1,
2554 FIB_ROUTE_PATH_FLAG_NONE);
2555 FIB_TEST((fib_table_lookup_exact_match(fib_index, &bgp_100_pfx) ==
2556 FIB_NODE_INDEX_INVALID),
2557 "100.100.100.100/32 removed");
2558 FIB_TEST((fib_table_lookup_exact_match(fib_index, &bgp_101_pfx) ==
2559 FIB_NODE_INDEX_INVALID),
2560 "100.100.100.101/32 removed");
2561
2562 /*
2563 * -2 entry (2*BGP, the RR source is also API sourced). -1 shared path-list;
2564 */
2565 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
2566 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002567 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002568 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002569 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002570 fib_entry_pool_size());
2571
2572 /*
2573 * Add a recursive route via a connected cover, using an adj-fib that does exist
2574 */
2575 fib_table_entry_path_add(fib_index,
2576 &bgp_200_pfx,
2577 FIB_SOURCE_API,
2578 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002579 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002580 &nh_10_10_10_1,
2581 ~0, // no index provided.
2582 fib_index, // Same as route's FIB
2583 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002584 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002585 FIB_ROUTE_PATH_FLAG_NONE);
2586
2587 /*
2588 * +1 entry. +1 shared path-list (recursive via 10.10.10.1)
2589 */
2590 FIB_TEST((2 == fib_path_list_db_size()), "path list DB population:%d",
2591 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002592 FIB_TEST((PNBR+6 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002593 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002594 FIB_TEST((ENBR+8 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002595 fib_entry_pool_size());
2596
2597 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
2598 dpo = fib_entry_contribute_ip_forwarding(fei);
2599
2600 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
2601 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2602
2603 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket(dpo->dpoi_index, 0)),
2604 "200.200.200.200/32 is recursive via adj for 10.10.10.1");
2605
2606 FIB_TEST((FIB_ENTRY_FLAG_ATTACHED == fib_entry_get_flags(fei)),
2607 "Flags set on RR via existing attached");
2608
2609 /*
2610 * Add a recursive route via a connected cover, using and adj-fib that does
2611 * not exist
2612 */
2613 ip46_address_t nh_10_10_10_3 = {
2614 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a03),
2615 };
2616 fib_prefix_t pfx_10_10_10_3 = {
2617 .fp_len = 32,
2618 .fp_proto = FIB_PROTOCOL_IP4,
2619 .fp_addr = nh_10_10_10_3,
2620 };
2621
2622 fib_table_entry_path_add(fib_index,
2623 &bgp_201_pfx,
2624 FIB_SOURCE_API,
2625 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002626 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002627 &nh_10_10_10_3,
2628 ~0, // no index provided.
2629 fib_index,
2630 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002631 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002632 FIB_ROUTE_PATH_FLAG_NONE);
2633
2634 /*
2635 * +2 entries (BGP and RR). +1 shared path-list (recursive via 10.10.10.3) and
2636 * one unshared non-recursive via 10.10.10.3
2637 */
2638 FIB_TEST((3 == fib_path_list_db_size()), "path list DB population:%d",
2639 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002640 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002641 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002642 FIB_TEST((ENBR+10 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002643 fib_entry_pool_size());
2644
2645 ai_03 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01002646 VNET_LINK_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002647 &nh_10_10_10_3,
2648 tm->hw[0]->sw_if_index);
2649
2650 fei = fib_table_lookup_exact_match(fib_index, &bgp_201_pfx);
2651 dpo = fib_entry_contribute_ip_forwarding(fei);
2652 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_3);
2653 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2654
2655 ai = fib_entry_get_adj(fei);
2656 FIB_TEST((ai == ai_03), "adj for 10.10.10.3/32 is via adj for 10.10.10.3");
2657 FIB_TEST(((FIB_ENTRY_FLAG_ATTACHED | FIB_ENTRY_FLAG_CONNECTED) ==
2658 fib_entry_get_flags(fei)),
2659 "Flags set on RR via non-existing attached");
2660
2661 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket(dpo->dpoi_index, 0)),
2662 "adj for 200.200.200.200/32 is recursive via adj for 10.10.10.3");
2663
2664 adj_unlock(ai_03);
2665
2666 /*
2667 * remove the recursives
2668 */
2669 fib_table_entry_path_remove(fib_index,
2670 &bgp_200_pfx,
2671 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002672 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002673 &nh_10_10_10_1,
2674 ~0, // no index provided.
2675 fib_index, // same as route's FIB
2676 1,
2677 FIB_ROUTE_PATH_FLAG_NONE);
2678 fib_table_entry_path_remove(fib_index,
2679 &bgp_201_pfx,
2680 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002681 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002682 &nh_10_10_10_3,
2683 ~0, // no index provided.
2684 fib_index, // same as route's FIB
2685 1,
2686 FIB_ROUTE_PATH_FLAG_NONE);
2687
2688 FIB_TEST((fib_table_lookup_exact_match(fib_index, &bgp_201_pfx) ==
2689 FIB_NODE_INDEX_INVALID),
2690 "200.200.200.201/32 removed");
2691 FIB_TEST((fib_table_lookup_exact_match(fib_index, &bgp_200_pfx) ==
2692 FIB_NODE_INDEX_INVALID),
2693 "200.200.200.200/32 removed");
2694 FIB_TEST((fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_3) ==
2695 FIB_NODE_INDEX_INVALID),
2696 "10.10.10.3/32 removed");
2697
2698 /*
2699 * -3 entries (2*BGP and RR). -2 shared path-list (recursive via 10.10.10.3 &
2700 * 10.10.10.1) and one unshared non-recursive via 10.10.10.3
2701 */
2702 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
2703 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002704 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002705 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002706 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002707 fib_entry_pool_size());
2708
2709
2710 /*
2711 * RECURSION LOOPS
2712 * Add 5.5.5.5/32 -> 5.5.5.6/32 -> 5.5.5.7/32 -> 5.5.5.5/32
2713 */
2714 fib_prefix_t pfx_5_5_5_5_s_32 = {
2715 .fp_len = 32,
2716 .fp_proto = FIB_PROTOCOL_IP4,
2717 .fp_addr = {
2718 .ip4.as_u32 = clib_host_to_net_u32(0x05050505),
2719 },
2720 };
2721 fib_prefix_t pfx_5_5_5_6_s_32 = {
2722 .fp_len = 32,
2723 .fp_proto = FIB_PROTOCOL_IP4,
2724 .fp_addr = {
2725 .ip4.as_u32 = clib_host_to_net_u32(0x05050506),
2726 },
2727 };
2728 fib_prefix_t pfx_5_5_5_7_s_32 = {
2729 .fp_len = 32,
2730 .fp_proto = FIB_PROTOCOL_IP4,
2731 .fp_addr = {
2732 .ip4.as_u32 = clib_host_to_net_u32(0x05050507),
2733 },
2734 };
2735
2736 fib_table_entry_path_add(fib_index,
2737 &pfx_5_5_5_5_s_32,
2738 FIB_SOURCE_API,
2739 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002740 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002741 &pfx_5_5_5_6_s_32.fp_addr,
2742 ~0, // no index provided.
2743 fib_index,
2744 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002745 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002746 FIB_ROUTE_PATH_FLAG_NONE);
2747 fib_table_entry_path_add(fib_index,
2748 &pfx_5_5_5_6_s_32,
2749 FIB_SOURCE_API,
2750 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002751 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002752 &pfx_5_5_5_7_s_32.fp_addr,
2753 ~0, // no index provided.
2754 fib_index,
2755 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002756 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002757 FIB_ROUTE_PATH_FLAG_NONE);
2758 fib_table_entry_path_add(fib_index,
2759 &pfx_5_5_5_7_s_32,
2760 FIB_SOURCE_API,
2761 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002762 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002763 &pfx_5_5_5_5_s_32.fp_addr,
2764 ~0, // no index provided.
2765 fib_index,
2766 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002767 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002768 FIB_ROUTE_PATH_FLAG_NONE);
2769 /*
2770 * +3 entries, +3 shared path-list
2771 */
2772 FIB_TEST((4 == fib_path_list_db_size()), "path list DB population:%d",
2773 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002774 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002775 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002776 FIB_TEST((ENBR+10 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002777 fib_entry_pool_size());
2778
2779 /*
2780 * All the entries have only looped paths, so they are all drop
2781 */
2782 fei = fib_table_lookup(fib_index, &pfx_5_5_5_7_s_32);
2783 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2784 "LB for 5.5.5.7/32 is via adj for DROP");
2785 fei = fib_table_lookup(fib_index, &pfx_5_5_5_5_s_32);
2786 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2787 "LB for 5.5.5.5/32 is via adj for DROP");
2788 fei = fib_table_lookup(fib_index, &pfx_5_5_5_6_s_32);
2789 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2790 "LB for 5.5.5.6/32 is via adj for DROP");
2791
2792 /*
2793 * provide 5.5.5.6/32 with alternate path.
2794 * this will allow only 5.5.5.6/32 to forward with this path, the others
2795 * are still drop since the loop is still present.
2796 */
2797 fib_table_entry_path_add(fib_index,
2798 &pfx_5_5_5_6_s_32,
2799 FIB_SOURCE_API,
2800 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002801 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002802 &nh_10_10_10_1,
2803 tm->hw[0]->sw_if_index,
2804 ~0,
2805 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002806 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002807 FIB_ROUTE_PATH_FLAG_NONE);
2808
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002809 fei = fib_table_lookup(fib_index, &pfx_5_5_5_6_s_32);
2810 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2811
2812 lb = load_balance_get(dpo1->dpoi_index);
2813 FIB_TEST((lb->lb_n_buckets == 1), "5.5.5.6 LB has %d bucket", lb->lb_n_buckets);
2814
2815 dpo2 = load_balance_get_bucket(dpo1->dpoi_index, 0);
2816 FIB_TEST(DPO_ADJACENCY == dpo2->dpoi_type, "type is %d", dpo2->dpoi_type);
2817 FIB_TEST((ai_01 == dpo2->dpoi_index),
2818 "5.5.5.6 bucket 0 resolves via 10.10.10.2");
2819
2820 fei = fib_table_lookup(fib_index, &pfx_5_5_5_7_s_32);
2821 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2822 "LB for 5.5.5.7/32 is via adj for DROP");
2823 fei = fib_table_lookup(fib_index, &pfx_5_5_5_5_s_32);
2824 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2825 "LB for 5.5.5.5/32 is via adj for DROP");
2826
2827 /*
2828 * remove the alternate path for 5.5.5.6/32
2829 * back to all drop
2830 */
2831 fib_table_entry_path_remove(fib_index,
2832 &pfx_5_5_5_6_s_32,
2833 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002834 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002835 &nh_10_10_10_1,
2836 tm->hw[0]->sw_if_index,
2837 ~0,
2838 1,
2839 FIB_ROUTE_PATH_FLAG_NONE);
2840
2841 fei = fib_table_lookup(fib_index, &pfx_5_5_5_7_s_32);
2842 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2843 "LB for 5.5.5.7/32 is via adj for DROP");
2844 fei = fib_table_lookup(fib_index, &pfx_5_5_5_5_s_32);
2845 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2846 "LB for 5.5.5.5/32 is via adj for DROP");
2847 fei = fib_table_lookup(fib_index, &pfx_5_5_5_6_s_32);
2848 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2849 "LB for 5.5.5.6/32 is via adj for DROP");
2850
2851 /*
2852 * break the loop by giving 5.5.5.5/32 a new set of paths
2853 * expect all to forward via this new path.
2854 */
2855 fib_table_entry_update_one_path(fib_index,
2856 &pfx_5_5_5_5_s_32,
2857 FIB_SOURCE_API,
2858 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002859 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002860 &nh_10_10_10_1,
2861 tm->hw[0]->sw_if_index,
2862 ~0, // invalid fib index
2863 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002864 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002865 FIB_ROUTE_PATH_FLAG_NONE);
2866
2867 fei = fib_table_lookup(fib_index, &pfx_5_5_5_5_s_32);
2868 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2869 lb = load_balance_get(dpo1->dpoi_index);
2870 FIB_TEST((lb->lb_n_buckets == 1), "5.5.5.5 LB has %d bucket", lb->lb_n_buckets);
2871
2872 dpo2 = load_balance_get_bucket(dpo1->dpoi_index, 0);
2873 FIB_TEST(DPO_ADJACENCY == dpo2->dpoi_type, "type is %d", dpo2->dpoi_type);
2874 FIB_TEST((ai_01 == dpo2->dpoi_index),
2875 "5.5.5.5 bucket 0 resolves via 10.10.10.2");
2876
2877 fei = fib_table_lookup_exact_match(fib_index, &pfx_5_5_5_7_s_32);
2878 dpo2 = fib_entry_contribute_ip_forwarding(fei);
2879
2880 lb = load_balance_get(dpo2->dpoi_index);
2881 FIB_TEST((lb->lb_n_buckets == 1), "Recursive LB has %d bucket", lb->lb_n_buckets);
2882 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket(dpo2->dpoi_index, 0)),
2883 "5.5.5.5.7 via 5.5.5.5");
2884
2885 fei = fib_table_lookup_exact_match(fib_index, &pfx_5_5_5_6_s_32);
2886 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2887
2888 lb = load_balance_get(dpo1->dpoi_index);
2889 FIB_TEST((lb->lb_n_buckets == 1), "Recursive LB has %d bucket", lb->lb_n_buckets);
2890 FIB_TEST(!dpo_cmp(dpo2, load_balance_get_bucket(dpo1->dpoi_index, 0)),
2891 "5.5.5.5.6 via 5.5.5.7");
2892
2893 /*
2894 * revert back to the loop. so we can remove the prefixes with
2895 * the loop intact
2896 */
2897 fib_table_entry_update_one_path(fib_index,
2898 &pfx_5_5_5_5_s_32,
2899 FIB_SOURCE_API,
2900 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002901 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002902 &pfx_5_5_5_6_s_32.fp_addr,
2903 ~0, // no index provided.
2904 fib_index,
2905 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002906 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002907 FIB_ROUTE_PATH_FLAG_NONE);
2908
2909 fei = fib_table_lookup(fib_index, &pfx_5_5_5_7_s_32);
2910 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2911 "LB for 5.5.5.7/32 is via adj for DROP");
2912 fei = fib_table_lookup(fib_index, &pfx_5_5_5_5_s_32);
2913 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2914 "LB for 5.5.5.5/32 is via adj for DROP");
2915 fei = fib_table_lookup(fib_index, &pfx_5_5_5_6_s_32);
2916 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2917 "LB for 5.5.5.6/32 is via adj for DROP");
2918
2919 /*
2920 * remove all the 5.5.5.x/32 prefixes
2921 */
2922 fib_table_entry_path_remove(fib_index,
2923 &pfx_5_5_5_5_s_32,
2924 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002925 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002926 &pfx_5_5_5_6_s_32.fp_addr,
2927 ~0, // no index provided.
2928 fib_index, // same as route's FIB
2929 1,
2930 FIB_ROUTE_PATH_FLAG_NONE);
2931 fib_table_entry_path_remove(fib_index,
2932 &pfx_5_5_5_6_s_32,
2933 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002934 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002935 &pfx_5_5_5_7_s_32.fp_addr,
2936 ~0, // no index provided.
2937 fib_index, // same as route's FIB
2938 1,
2939 FIB_ROUTE_PATH_FLAG_NONE);
2940 fib_table_entry_path_remove(fib_index,
2941 &pfx_5_5_5_7_s_32,
2942 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002943 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002944 &pfx_5_5_5_5_s_32.fp_addr,
2945 ~0, // no index provided.
2946 fib_index, // same as route's FIB
2947 1,
2948 FIB_ROUTE_PATH_FLAG_NONE);
2949 fib_table_entry_path_remove(fib_index,
2950 &pfx_5_5_5_6_s_32,
2951 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002952 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002953 &nh_10_10_10_2,
2954 ~0, // no index provided.
2955 fib_index, // same as route's FIB
2956 1,
2957 FIB_ROUTE_PATH_FLAG_NONE);
2958
2959 /*
2960 * -3 entries, -3 shared path-list
2961 */
2962 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
2963 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002964 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002965 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002966 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002967 fib_entry_pool_size());
2968
2969 /*
2970 * Single level loop 5.5.5.5/32 via 5.5.5.5/32
2971 */
2972 fib_table_entry_path_add(fib_index,
2973 &pfx_5_5_5_6_s_32,
2974 FIB_SOURCE_API,
2975 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002976 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002977 &pfx_5_5_5_6_s_32.fp_addr,
2978 ~0, // no index provided.
2979 fib_index,
2980 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002981 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002982 FIB_ROUTE_PATH_FLAG_NONE);
2983 fei = fib_table_lookup(fib_index, &pfx_5_5_5_6_s_32);
2984 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2985 "1-level 5.5.5.6/32 loop is via adj for DROP");
2986
2987 fib_table_entry_path_remove(fib_index,
2988 &pfx_5_5_5_6_s_32,
2989 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002990 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002991 &pfx_5_5_5_6_s_32.fp_addr,
2992 ~0, // no index provided.
2993 fib_index, // same as route's FIB
2994 1,
2995 FIB_ROUTE_PATH_FLAG_NONE);
2996 FIB_TEST(FIB_NODE_INDEX_INVALID ==
2997 fib_table_lookup_exact_match(fib_index, &pfx_5_5_5_6_s_32),
2998 "1-level 5.5.5.6/32 loop is removed");
2999
3000 /*
Neale Ranns3dffb1e2016-11-01 20:38:53 +00003001 * A recursive route whose next-hop is covered by the prefix.
3002 * This would mean the via-fib, which inherits forwarding from its
3003 * cover, thus picks up forwarding from the prfix, which is via the
3004 * via-fib, and we have a loop.
3005 */
3006 fib_prefix_t pfx_23_23_23_0_s_24 = {
3007 .fp_len = 24,
3008 .fp_proto = FIB_PROTOCOL_IP4,
3009 .fp_addr = {
3010 .ip4.as_u32 = clib_host_to_net_u32(0x17171700),
3011 },
3012 };
3013 fib_prefix_t pfx_23_23_23_23_s_32 = {
3014 .fp_len = 32,
3015 .fp_proto = FIB_PROTOCOL_IP4,
3016 .fp_addr = {
3017 .ip4.as_u32 = clib_host_to_net_u32(0x17171717),
3018 },
3019 };
3020 fei = fib_table_entry_path_add(fib_index,
3021 &pfx_23_23_23_0_s_24,
3022 FIB_SOURCE_API,
3023 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003024 DPO_PROTO_IP4,
Neale Ranns3dffb1e2016-11-01 20:38:53 +00003025 &pfx_23_23_23_23_s_32.fp_addr,
3026 ~0, // recursive
3027 fib_index,
3028 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003029 NULL,
Neale Ranns3dffb1e2016-11-01 20:38:53 +00003030 FIB_ROUTE_PATH_FLAG_NONE);
3031 dpo = fib_entry_contribute_ip_forwarding(fei);
3032 FIB_TEST(load_balance_is_drop(dpo),
3033 "23.23.23.0/24 via covered is DROP");
3034 fib_table_entry_delete_index(fei, FIB_SOURCE_API);
3035
3036 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003037 * add-remove test. no change.
3038 */
3039 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
3040 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003041 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003042 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003043 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003044 fib_entry_pool_size());
3045
3046 /*
Neale Ranns08b16482017-05-13 05:52:58 -07003047 * Make the default route recursive via a unknown next-hop. Thus the
3048 * next hop's cover would be the default route
3049 */
3050 fei = fib_table_entry_path_add(fib_index,
3051 &pfx_0_0_0_0_s_0,
3052 FIB_SOURCE_API,
3053 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003054 DPO_PROTO_IP4,
Neale Ranns08b16482017-05-13 05:52:58 -07003055 &pfx_23_23_23_23_s_32.fp_addr,
3056 ~0, // recursive
3057 fib_index,
3058 1,
3059 NULL,
3060 FIB_ROUTE_PATH_FLAG_NONE);
3061 dpo = fib_entry_contribute_ip_forwarding(fei);
3062 FIB_TEST(load_balance_is_drop(dpo),
3063 "0.0.0.0.0/0 via is DROP");
3064 FIB_TEST((fib_entry_get_resolving_interface(fei) == ~0),
3065 "no resolving interface for looped 0.0.0.0/0");
3066
3067 fei = fib_table_lookup_exact_match(fib_index, &pfx_23_23_23_23_s_32);
3068 dpo = fib_entry_contribute_ip_forwarding(fei);
3069 FIB_TEST(load_balance_is_drop(dpo),
3070 "23.23.23.23/32 via is DROP");
3071 FIB_TEST((fib_entry_get_resolving_interface(fei) == ~0),
3072 "no resolving interface for looped 23.23.23.23/32");
3073
3074 fib_table_entry_delete(fib_index, &pfx_0_0_0_0_s_0, FIB_SOURCE_API);
3075
3076 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003077 * A recursive route with recursion constraints.
3078 * 200.200.200.200/32 via 1.1.1.1 is recurse via host constrained
3079 */
3080 fib_table_entry_path_add(fib_index,
3081 &bgp_200_pfx,
3082 FIB_SOURCE_API,
3083 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003084 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003085 &nh_1_1_1_1,
3086 ~0,
3087 fib_index,
3088 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003089 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003090 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
3091
3092 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_1_s_32);
3093 dpo2 = fib_entry_contribute_ip_forwarding(fei);
3094
3095 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
3096 dpo1 = fib_entry_contribute_ip_forwarding(fei);
3097
3098 FIB_TEST(!dpo_cmp(dpo2, load_balance_get_bucket(dpo1->dpoi_index, 0)),
3099 "adj for 200.200.200.200/32 is recursive via adj for 1.1.1.1");
3100
3101 /*
3102 * save the load-balance. we expect it to be inplace modified
3103 */
3104 lb = load_balance_get(dpo1->dpoi_index);
3105
3106 /*
3107 * add a covering prefix for the via fib that would otherwise serve
3108 * as the resolving route when the host is removed
3109 */
3110 fib_table_entry_path_add(fib_index,
3111 &pfx_1_1_1_0_s_28,
3112 FIB_SOURCE_API,
3113 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003114 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003115 &nh_10_10_10_1,
3116 tm->hw[0]->sw_if_index,
3117 ~0, // invalid fib index
3118 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003119 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003120 FIB_ROUTE_PATH_FLAG_NONE);
3121 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_0_s_28);
3122 ai = fib_entry_get_adj(fei);
3123 FIB_TEST((ai == ai_01),
3124 "adj for 1.1.1.0/28 is via adj for 1.1.1.1");
3125
3126 /*
3127 * remove the host via FIB - expect the BGP prefix to be drop
3128 */
3129 fib_table_entry_path_remove(fib_index,
3130 &pfx_1_1_1_1_s_32,
3131 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07003132 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003133 &nh_10_10_10_1,
3134 tm->hw[0]->sw_if_index,
3135 ~0, // invalid fib index
3136 1,
3137 FIB_ROUTE_PATH_FLAG_NONE);
3138
3139 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo1->dpoi_index, 0)),
3140 "adj for 200.200.200.200/32 is recursive via adj for DROP");
3141
3142 /*
3143 * add the via-entry host reoute back. expect to resolve again
3144 */
3145 fib_table_entry_path_add(fib_index,
3146 &pfx_1_1_1_1_s_32,
3147 FIB_SOURCE_API,
3148 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003149 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003150 &nh_10_10_10_1,
3151 tm->hw[0]->sw_if_index,
3152 ~0, // invalid fib index
3153 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003154 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003155 FIB_ROUTE_PATH_FLAG_NONE);
3156 FIB_TEST(!dpo_cmp(dpo2, load_balance_get_bucket(dpo1->dpoi_index, 0)),
3157 "adj for 200.200.200.200/32 is recursive via adj for 1.1.1.1");
3158
3159 /*
3160 * add another path for the recursive. it will then have 2.
3161 */
3162 fib_prefix_t pfx_1_1_1_3_s_32 = {
3163 .fp_len = 32,
3164 .fp_proto = FIB_PROTOCOL_IP4,
3165 .fp_addr = {
3166 .ip4.as_u32 = clib_host_to_net_u32(0x01010103),
3167 },
3168 };
3169 fib_table_entry_path_add(fib_index,
3170 &pfx_1_1_1_3_s_32,
3171 FIB_SOURCE_API,
3172 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003173 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003174 &nh_10_10_10_2,
3175 tm->hw[0]->sw_if_index,
3176 ~0, // invalid fib index
3177 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003178 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003179 FIB_ROUTE_PATH_FLAG_NONE);
3180
3181 fib_table_entry_path_add(fib_index,
3182 &bgp_200_pfx,
3183 FIB_SOURCE_API,
3184 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003185 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003186 &pfx_1_1_1_3_s_32.fp_addr,
3187 ~0,
3188 fib_index,
3189 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003190 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003191 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
3192
Neale Rannsf12a83f2017-04-18 09:09:40 -07003193 /*
3194 * add a bunch load more entries using this path combo so that we get
3195 * an LB-map created.
3196 */
3197#define N_P 128
3198 fib_prefix_t bgp_78s[N_P];
3199 for (ii = 0; ii < N_P; ii++)
3200 {
3201 bgp_78s[ii].fp_len = 32;
3202 bgp_78s[ii].fp_proto = FIB_PROTOCOL_IP4;
3203 bgp_78s[ii].fp_addr.ip4.as_u32 = clib_host_to_net_u32(0x4e000000+ii);
3204
3205
3206 fib_table_entry_path_add(fib_index,
3207 &bgp_78s[ii],
3208 FIB_SOURCE_API,
3209 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003210 DPO_PROTO_IP4,
Neale Rannsf12a83f2017-04-18 09:09:40 -07003211 &pfx_1_1_1_3_s_32.fp_addr,
3212 ~0,
3213 fib_index,
3214 1,
3215 NULL,
3216 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
3217 fib_table_entry_path_add(fib_index,
3218 &bgp_78s[ii],
3219 FIB_SOURCE_API,
3220 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003221 DPO_PROTO_IP4,
Neale Rannsf12a83f2017-04-18 09:09:40 -07003222 &nh_1_1_1_1,
3223 ~0,
3224 fib_index,
3225 1,
3226 NULL,
3227 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
3228 }
3229
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003230 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
3231 dpo = fib_entry_contribute_ip_forwarding(fei);
3232
3233 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_1_s_32);
3234 dpo2 = fib_entry_contribute_ip_forwarding(fei);
3235 FIB_TEST(!dpo_cmp(dpo2, load_balance_get_bucket(dpo->dpoi_index, 0)),
3236 "adj for 200.200.200.200/32 is recursive via adj for 1.1.1.1");
3237 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_3_s_32);
3238 dpo1 = fib_entry_contribute_ip_forwarding(fei);
3239 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket(dpo->dpoi_index, 1)),
3240 "adj for 200.200.200.200/32 is recursive via adj for 1.1.1.3");
3241
3242 /*
3243 * expect the lb-map used by the recursive's load-balance is using both buckets
3244 */
3245 load_balance_map_t *lbm;
3246 index_t lbmi;
3247
3248 lb = load_balance_get(dpo->dpoi_index);
3249 lbmi = lb->lb_map;
3250 load_balance_map_lock(lbmi);
3251 lbm = load_balance_map_get(lbmi);
3252
3253 FIB_TEST(lbm->lbm_buckets[0] == 0,
3254 "LB maps's bucket 0 is %d",
3255 lbm->lbm_buckets[0]);
3256 FIB_TEST(lbm->lbm_buckets[1] == 1,
3257 "LB maps's bucket 1 is %d",
3258 lbm->lbm_buckets[1]);
3259
3260 /*
3261 * withdraw one of the /32 via-entrys.
3262 * that ECMP path will be unresolved and forwarding should continue on the
3263 * other available path. this is an iBGP PIC edge failover.
3264 * Test the forwarding changes without re-fetching the adj from the
3265 * recursive entry. this ensures its the same one that is updated; i.e. an
3266 * inplace-modify.
3267 */
3268 fib_table_entry_path_remove(fib_index,
3269 &pfx_1_1_1_1_s_32,
3270 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07003271 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003272 &nh_10_10_10_1,
3273 tm->hw[0]->sw_if_index,
3274 ~0, // invalid fib index
3275 1,
3276 FIB_ROUTE_PATH_FLAG_NONE);
3277
Neale Rannsf12a83f2017-04-18 09:09:40 -07003278 /* suspend so the update walk kicks int */
3279 vlib_process_suspend(vlib_get_main(), 1e-5);
3280
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003281 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
3282 FIB_TEST(!dpo_cmp(dpo, fib_entry_contribute_ip_forwarding(fei)),
3283 "post PIC 200.200.200.200/32 was inplace modified");
3284
3285 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket_i(lb, 0)),
3286 "post PIC adj for 200.200.200.200/32 is recursive"
3287 " via adj for 1.1.1.3");
3288
3289 /*
3290 * the LB maps that was locked above should have been modified to remove
3291 * the path that was down, and thus its bucket points to a path that is
3292 * still up.
3293 */
3294 FIB_TEST(lbm->lbm_buckets[0] == 1,
3295 "LB maps's bucket 0 is %d",
3296 lbm->lbm_buckets[0]);
3297 FIB_TEST(lbm->lbm_buckets[1] == 1,
3298 "LB maps's bucket 1 is %d",
3299 lbm->lbm_buckets[1]);
3300
Neale Ranns994dab42017-04-18 12:56:45 -07003301 load_balance_map_unlock(lbmi);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003302
3303 /*
3304 * add it back. again
3305 */
3306 fib_table_entry_path_add(fib_index,
3307 &pfx_1_1_1_1_s_32,
3308 FIB_SOURCE_API,
3309 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003310 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003311 &nh_10_10_10_1,
3312 tm->hw[0]->sw_if_index,
3313 ~0, // invalid fib index
3314 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003315 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003316 FIB_ROUTE_PATH_FLAG_NONE);
3317
Neale Rannsf12a83f2017-04-18 09:09:40 -07003318 /* suspend so the update walk kicks in */
3319 vlib_process_suspend(vlib_get_main(), 1e-5);
3320
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003321 FIB_TEST(!dpo_cmp(dpo2, load_balance_get_bucket_i(lb, 0)),
3322 "post PIC recovery adj for 200.200.200.200/32 is recursive "
3323 "via adj for 1.1.1.1");
3324 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket_i(lb, 1)),
3325 "post PIC recovery adj for 200.200.200.200/32 is recursive "
3326 "via adj for 1.1.1.3");
3327
3328 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
3329 dpo = fib_entry_contribute_ip_forwarding(fei);
3330 FIB_TEST(lb == load_balance_get(dpo->dpoi_index),
3331 "post PIC 200.200.200.200/32 was inplace modified");
3332
3333 /*
3334 * add a 3rd path. this makes the LB 16 buckets.
3335 */
3336 fib_table_entry_path_add(fib_index,
3337 &bgp_200_pfx,
3338 FIB_SOURCE_API,
3339 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003340 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003341 &pfx_1_1_1_2_s_32.fp_addr,
3342 ~0,
3343 fib_index,
3344 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003345 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003346 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
Neale Rannsf12a83f2017-04-18 09:09:40 -07003347 for (ii = 0; ii < N_P; ii++)
3348 {
3349 fib_table_entry_path_add(fib_index,
3350 &bgp_78s[ii],
3351 FIB_SOURCE_API,
3352 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003353 DPO_PROTO_IP4,
Neale Rannsf12a83f2017-04-18 09:09:40 -07003354 &pfx_1_1_1_2_s_32.fp_addr,
3355 ~0,
3356 fib_index,
3357 1,
3358 NULL,
3359 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
3360 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003361
3362 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
3363 dpo = fib_entry_contribute_ip_forwarding(fei);
3364 FIB_TEST(lb == load_balance_get(dpo->dpoi_index),
3365 "200.200.200.200/32 was inplace modified for 3rd path");
3366 FIB_TEST(16 == lb->lb_n_buckets,
3367 "200.200.200.200/32 was inplace modified for 3rd path to 16 buckets");
3368
3369 lbmi = lb->lb_map;
3370 load_balance_map_lock(lbmi);
3371 lbm = load_balance_map_get(lbmi);
3372
3373 for (ii = 0; ii < 16; ii++)
3374 {
3375 FIB_TEST(lbm->lbm_buckets[ii] == ii,
3376 "LB Map for 200.200.200.200/32 at %d is %d",
3377 ii, lbm->lbm_buckets[ii]);
3378 }
3379
3380 /*
3381 * trigger PIC by removing the first via-entry
3382 * the first 6 buckets of the map should map to the next 6
3383 */
3384 fib_table_entry_path_remove(fib_index,
3385 &pfx_1_1_1_1_s_32,
3386 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07003387 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003388 &nh_10_10_10_1,
3389 tm->hw[0]->sw_if_index,
3390 ~0,
3391 1,
3392 FIB_ROUTE_PATH_FLAG_NONE);
Neale Rannsf12a83f2017-04-18 09:09:40 -07003393 /* suspend so the update walk kicks int */
3394 vlib_process_suspend(vlib_get_main(), 1e-5);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003395
3396 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
3397 dpo = fib_entry_contribute_ip_forwarding(fei);
3398 FIB_TEST(lb == load_balance_get(dpo->dpoi_index),
3399 "200.200.200.200/32 was inplace modified for 3rd path");
3400 FIB_TEST(2 == lb->lb_n_buckets,
3401 "200.200.200.200/32 was inplace modified for 3rd path remove to 2 buckets");
3402
3403 for (ii = 0; ii < 6; ii++)
3404 {
3405 FIB_TEST(lbm->lbm_buckets[ii] == ii+6,
3406 "LB Map for 200.200.200.200/32 at %d is %d",
3407 ii, lbm->lbm_buckets[ii]);
3408 }
3409 for (ii = 6; ii < 16; ii++)
3410 {
3411 FIB_TEST(lbm->lbm_buckets[ii] == ii,
3412 "LB Map for 200.200.200.200/32 at %d is %d",
3413 ii, lbm->lbm_buckets[ii]);
3414 }
Neale Ranns994dab42017-04-18 12:56:45 -07003415 load_balance_map_unlock(lbmi);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003416
3417 /*
3418 * tidy up
3419 */
3420 fib_table_entry_path_add(fib_index,
3421 &pfx_1_1_1_1_s_32,
3422 FIB_SOURCE_API,
3423 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003424 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003425 &nh_10_10_10_1,
3426 tm->hw[0]->sw_if_index,
3427 ~0,
3428 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003429 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003430 FIB_ROUTE_PATH_FLAG_NONE);
3431
Neale Rannsf12a83f2017-04-18 09:09:40 -07003432 for (ii = 0; ii < N_P; ii++)
3433 {
3434 fib_table_entry_delete(fib_index,
3435 &bgp_78s[ii],
3436 FIB_SOURCE_API);
3437 FIB_TEST((FIB_NODE_INDEX_INVALID ==
3438 fib_table_lookup_exact_match(fib_index, &bgp_78s[ii])),
3439 "%U removed",
3440 format_fib_prefix, &bgp_78s[ii]);
3441 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003442 fib_table_entry_path_remove(fib_index,
3443 &bgp_200_pfx,
3444 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07003445 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003446 &pfx_1_1_1_2_s_32.fp_addr,
3447 ~0,
3448 fib_index,
3449 1,
3450 MPLS_LABEL_INVALID);
3451 fib_table_entry_path_remove(fib_index,
3452 &bgp_200_pfx,
3453 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07003454 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003455 &nh_1_1_1_1,
3456 ~0,
3457 fib_index,
3458 1,
3459 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
3460 fib_table_entry_path_remove(fib_index,
3461 &bgp_200_pfx,
3462 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07003463 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003464 &pfx_1_1_1_3_s_32.fp_addr,
3465 ~0,
3466 fib_index,
3467 1,
3468 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
3469 fib_table_entry_delete(fib_index,
3470 &pfx_1_1_1_3_s_32,
3471 FIB_SOURCE_API);
3472 fib_table_entry_delete(fib_index,
3473 &pfx_1_1_1_0_s_28,
3474 FIB_SOURCE_API);
Neale Rannsf12a83f2017-04-18 09:09:40 -07003475 /* suspend so the update walk kicks int */
3476 vlib_process_suspend(vlib_get_main(), 1e-5);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003477 FIB_TEST((FIB_NODE_INDEX_INVALID ==
3478 fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_0_s_28)),
3479 "1.1.1.1/28 removed");
3480 FIB_TEST((FIB_NODE_INDEX_INVALID ==
3481 fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_3_s_32)),
3482 "1.1.1.3/32 removed");
3483 FIB_TEST((FIB_NODE_INDEX_INVALID ==
3484 fib_table_lookup_exact_match(fib_index, &bgp_200_pfx)),
3485 "200.200.200.200/32 removed");
3486
3487 /*
3488 * add-remove test. no change.
3489 */
3490 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
3491 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003492 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003493 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003494 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003495 fib_entry_pool_size());
3496
3497 /*
3498 * A route whose paths are built up iteratively and then removed
3499 * all at once
3500 */
3501 fib_prefix_t pfx_4_4_4_4_s_32 = {
3502 .fp_len = 32,
3503 .fp_proto = FIB_PROTOCOL_IP4,
3504 .fp_addr = {
3505 /* 4.4.4.4/32 */
3506 .ip4.as_u32 = clib_host_to_net_u32(0x04040404),
3507 },
3508 };
3509
3510 fib_table_entry_path_add(fib_index,
3511 &pfx_4_4_4_4_s_32,
3512 FIB_SOURCE_API,
3513 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003514 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003515 &nh_10_10_10_1,
3516 tm->hw[0]->sw_if_index,
3517 ~0,
3518 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003519 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003520 FIB_ROUTE_PATH_FLAG_NONE);
3521 fib_table_entry_path_add(fib_index,
3522 &pfx_4_4_4_4_s_32,
3523 FIB_SOURCE_API,
3524 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003525 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003526 &nh_10_10_10_2,
3527 tm->hw[0]->sw_if_index,
3528 ~0,
3529 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003530 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003531 FIB_ROUTE_PATH_FLAG_NONE);
3532 fib_table_entry_path_add(fib_index,
3533 &pfx_4_4_4_4_s_32,
3534 FIB_SOURCE_API,
3535 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003536 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003537 &nh_10_10_10_3,
3538 tm->hw[0]->sw_if_index,
3539 ~0,
3540 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003541 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003542 FIB_ROUTE_PATH_FLAG_NONE);
3543 FIB_TEST(FIB_NODE_INDEX_INVALID !=
3544 fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32),
3545 "4.4.4.4/32 present");
3546
3547 fib_table_entry_delete(fib_index,
3548 &pfx_4_4_4_4_s_32,
3549 FIB_SOURCE_API);
3550 FIB_TEST(FIB_NODE_INDEX_INVALID ==
3551 fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32),
3552 "4.4.4.4/32 removed");
3553
3554 /*
3555 * add-remove test. no change.
3556 */
3557 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
3558 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003559 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003560 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003561 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003562 fib_entry_pool_size());
3563
3564 /*
3565 * A route with multiple paths at once
3566 */
3567 fib_route_path_t *r_paths = NULL;
3568
3569 for (ii = 0; ii < 4; ii++)
3570 {
3571 fib_route_path_t r_path = {
Neale Rannsda78f952017-05-24 09:15:43 -07003572 .frp_proto = DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003573 .frp_addr = {
3574 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02 + ii),
3575 },
3576 .frp_sw_if_index = tm->hw[0]->sw_if_index,
3577 .frp_weight = 1,
3578 .frp_fib_index = ~0,
3579 };
3580 vec_add1(r_paths, r_path);
3581 }
3582
3583 fib_table_entry_update(fib_index,
3584 &pfx_4_4_4_4_s_32,
3585 FIB_SOURCE_API,
3586 FIB_ENTRY_FLAG_NONE,
3587 r_paths);
3588
3589 fei = fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32);
3590 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "4.4.4.4/32 present");
3591 dpo = fib_entry_contribute_ip_forwarding(fei);
3592
3593 lb = load_balance_get(dpo->dpoi_index);
3594 FIB_TEST((lb->lb_n_buckets == 4), "4.4.4.4/32 lb over %d paths", lb->lb_n_buckets);
3595
3596 fib_table_entry_delete(fib_index,
3597 &pfx_4_4_4_4_s_32,
3598 FIB_SOURCE_API);
3599 FIB_TEST(FIB_NODE_INDEX_INVALID ==
3600 fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32),
3601 "4.4.4.4/32 removed");
3602 vec_free(r_paths);
3603
3604 /*
3605 * add-remove test. no change.
3606 */
3607 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
3608 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003609 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003610 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003611 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003612 fib_entry_pool_size());
3613
3614 /*
3615 * A route deag route
3616 */
3617 fib_table_entry_path_add(fib_index,
3618 &pfx_4_4_4_4_s_32,
3619 FIB_SOURCE_API,
3620 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003621 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003622 &zero_addr,
3623 ~0,
3624 fib_index,
3625 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003626 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003627 FIB_ROUTE_PATH_FLAG_NONE);
3628
3629 fei = fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32);
3630 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "4.4.4.4/32 present");
3631
3632 dpo = fib_entry_contribute_ip_forwarding(fei);
3633 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
3634 lookup_dpo_t *lkd = lookup_dpo_get(dpo->dpoi_index);
3635
3636 FIB_TEST((fib_index == lkd->lkd_fib_index),
3637 "4.4.4.4/32 is deag in %d %U",
3638 lkd->lkd_fib_index,
3639 format_dpo_id, dpo, 0);
Neale Ranns054c03a2017-10-13 05:15:07 -07003640 FIB_TEST((LOOKUP_INPUT_DST_ADDR == lkd->lkd_input),
3641 "4.4.4.4/32 is source deag in %d %U",
3642 lkd->lkd_input,
3643 format_dpo_id, dpo, 0);
3644
3645 fib_table_entry_delete(fib_index,
3646 &pfx_4_4_4_4_s_32,
3647 FIB_SOURCE_API);
3648 FIB_TEST(FIB_NODE_INDEX_INVALID ==
3649 fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32),
3650 "4.4.4.4/32 removed");
3651 vec_free(r_paths);
3652
3653 /*
3654 * A route deag route in a source lookup table
3655 */
3656 fib_table_entry_path_add(fib_index,
3657 &pfx_4_4_4_4_s_32,
3658 FIB_SOURCE_API,
3659 FIB_ENTRY_FLAG_NONE,
3660 DPO_PROTO_IP4,
3661 &zero_addr,
3662 ~0,
3663 fib_index,
3664 1,
3665 NULL,
3666 FIB_ROUTE_PATH_SOURCE_LOOKUP);
3667
3668 fei = fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32);
3669 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "4.4.4.4/32 present");
3670
3671 dpo = fib_entry_contribute_ip_forwarding(fei);
3672 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
3673 lkd = lookup_dpo_get(dpo->dpoi_index);
3674
3675 FIB_TEST((fib_index == lkd->lkd_fib_index),
3676 "4.4.4.4/32 is deag in %d %U",
3677 lkd->lkd_fib_index,
3678 format_dpo_id, dpo, 0);
3679 FIB_TEST((LOOKUP_INPUT_SRC_ADDR == lkd->lkd_input),
3680 "4.4.4.4/32 is source deag in %d %U",
3681 lkd->lkd_input,
3682 format_dpo_id, dpo, 0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003683
3684 fib_table_entry_delete(fib_index,
3685 &pfx_4_4_4_4_s_32,
3686 FIB_SOURCE_API);
3687 FIB_TEST(FIB_NODE_INDEX_INVALID ==
3688 fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32),
3689 "4.4.4.4/32 removed");
3690 vec_free(r_paths);
3691
3692 /*
3693 * add-remove test. no change.
3694 */
3695 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
3696 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003697 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003698 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003699 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003700 fib_entry_pool_size());
3701
3702 /*
Neale Rannsbcc889c2016-11-03 14:15:28 -07003703 * Duplicate paths:
3704 * add a recursive with duplicate paths. Expect the duplicate to be ignored.
3705 */
3706 fib_prefix_t pfx_34_1_1_1_s_32 = {
3707 .fp_len = 32,
3708 .fp_proto = FIB_PROTOCOL_IP4,
3709 .fp_addr = {
3710 .ip4.as_u32 = clib_host_to_net_u32(0x22010101),
3711 },
3712 };
3713 fib_prefix_t pfx_34_34_1_1_s_32 = {
3714 .fp_len = 32,
3715 .fp_proto = FIB_PROTOCOL_IP4,
3716 .fp_addr = {
3717 .ip4.as_u32 = clib_host_to_net_u32(0x22220101),
3718 },
3719 };
3720 fei = fib_table_entry_path_add(fib_index,
Neale Ranns57b58602017-07-15 07:37:25 -07003721 &pfx_34_34_1_1_s_32,
3722 FIB_SOURCE_API,
3723 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003724 DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07003725 &nh_10_10_10_1,
3726 tm->hw[0]->sw_if_index,
3727 0,
3728 1,
3729 NULL,
3730 FIB_ROUTE_PATH_FLAG_NONE);
3731 fei = fib_table_entry_path_add(fib_index,
Neale Rannsbcc889c2016-11-03 14:15:28 -07003732 &pfx_34_1_1_1_s_32,
3733 FIB_SOURCE_API,
3734 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003735 DPO_PROTO_IP4,
Neale Rannsbcc889c2016-11-03 14:15:28 -07003736 &pfx_34_34_1_1_s_32.fp_addr,
3737 ~0,
3738 fib_index,
3739 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003740 NULL,
Neale Rannsbcc889c2016-11-03 14:15:28 -07003741 FIB_ROUTE_PATH_FLAG_NONE);
3742 fei = fib_table_entry_path_add(fib_index,
3743 &pfx_34_1_1_1_s_32,
3744 FIB_SOURCE_API,
3745 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003746 DPO_PROTO_IP4,
Neale Rannsbcc889c2016-11-03 14:15:28 -07003747 &pfx_34_34_1_1_s_32.fp_addr,
3748 ~0,
3749 fib_index,
3750 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003751 NULL,
Neale Rannsbcc889c2016-11-03 14:15:28 -07003752 FIB_ROUTE_PATH_FLAG_NONE);
3753 FIB_TEST_REC_FORW(&pfx_34_1_1_1_s_32, &pfx_34_34_1_1_s_32, 0);
3754 fib_table_entry_delete_index(fei, FIB_SOURCE_API);
Neale Ranns57b58602017-07-15 07:37:25 -07003755 fib_table_entry_delete(fib_index,
3756 &pfx_34_34_1_1_s_32,
3757 FIB_SOURCE_API);
Neale Rannsbcc889c2016-11-03 14:15:28 -07003758
3759 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003760 * CLEANUP
3761 * remove: 1.1.1.2/32, 1.1.2.0/24 and 1.1.1.1/32
3762 * all of which are via 10.10.10.1, Itf1
3763 */
3764 fib_table_entry_path_remove(fib_index,
3765 &pfx_1_1_1_2_s_32,
3766 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07003767 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003768 &nh_10_10_10_1,
3769 tm->hw[0]->sw_if_index,
3770 ~0,
3771 1,
3772 FIB_ROUTE_PATH_FLAG_NONE);
3773 fib_table_entry_path_remove(fib_index,
3774 &pfx_1_1_1_1_s_32,
3775 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07003776 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003777 &nh_10_10_10_1,
3778 tm->hw[0]->sw_if_index,
3779 ~0,
3780 1,
3781 FIB_ROUTE_PATH_FLAG_NONE);
3782 fib_table_entry_path_remove(fib_index,
3783 &pfx_1_1_2_0_s_24,
3784 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07003785 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003786 &nh_10_10_10_1,
3787 tm->hw[0]->sw_if_index,
3788 ~0,
3789 1,
3790 FIB_ROUTE_PATH_FLAG_NONE);
3791
3792 FIB_TEST(FIB_NODE_INDEX_INVALID ==
3793 fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_1_s_32),
3794 "1.1.1.1/32 removed");
3795 FIB_TEST(FIB_NODE_INDEX_INVALID ==
3796 fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_2_s_32),
3797 "1.1.1.2/32 removed");
3798 FIB_TEST(FIB_NODE_INDEX_INVALID ==
3799 fib_table_lookup_exact_match(fib_index, &pfx_1_1_2_0_s_24),
3800 "1.1.2.0/24 removed");
3801
3802 /*
3803 * -3 entries and -1 shared path-list
3804 */
3805 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
3806 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003807 FIB_TEST((PNBR+4 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003808 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003809 FIB_TEST((ENBR+4 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003810 fib_entry_pool_size());
3811
3812 /*
3813 * An attached-host route. Expect to link to the incomplete adj
3814 */
3815 fib_prefix_t pfx_4_1_1_1_s_32 = {
3816 .fp_len = 32,
3817 .fp_proto = FIB_PROTOCOL_IP4,
3818 .fp_addr = {
3819 /* 4.1.1.1/32 */
3820 .ip4.as_u32 = clib_host_to_net_u32(0x04010101),
3821 },
3822 };
3823 fib_table_entry_path_add(fib_index,
3824 &pfx_4_1_1_1_s_32,
3825 FIB_SOURCE_API,
3826 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003827 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003828 &zero_addr,
3829 tm->hw[0]->sw_if_index,
3830 fib_index,
3831 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003832 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003833 FIB_ROUTE_PATH_FLAG_NONE);
3834
3835 fei = fib_table_lookup_exact_match(fib_index, &pfx_4_1_1_1_s_32);
3836 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "4.1.1.1/32 present");
3837 ai = fib_entry_get_adj(fei);
3838
3839 ai2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01003840 VNET_LINK_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003841 &pfx_4_1_1_1_s_32.fp_addr,
3842 tm->hw[0]->sw_if_index);
3843 FIB_TEST((ai == ai2), "Attached-host link to incomplete ADJ");
3844 adj_unlock(ai2);
3845
3846 /*
3847 * +1 entry and +1 shared path-list
3848 */
3849 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
3850 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003851 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003852 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003853 FIB_TEST((ENBR+5 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003854 fib_entry_pool_size());
3855
3856 fib_table_entry_delete(fib_index,
3857 &pfx_4_1_1_1_s_32,
3858 FIB_SOURCE_API);
3859
3860 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
3861 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003862 FIB_TEST((PNBR+4 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003863 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003864 FIB_TEST((ENBR+4 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003865 fib_entry_pool_size());
3866
3867 /*
3868 * add a v6 prefix via v4 next-hops
3869 */
3870 fib_prefix_t pfx_2001_s_64 = {
3871 .fp_len = 64,
3872 .fp_proto = FIB_PROTOCOL_IP6,
3873 .fp_addr = {
3874 .ip6.as_u64[0] = clib_host_to_net_u64(0x2001000000000000),
3875 },
3876 };
3877 fei = fib_table_entry_path_add(0, //default v6 table
3878 &pfx_2001_s_64,
3879 FIB_SOURCE_API,
3880 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003881 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003882 &nh_10_10_10_1,
3883 tm->hw[0]->sw_if_index,
3884 fib_index,
3885 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003886 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003887 FIB_ROUTE_PATH_FLAG_NONE);
3888
3889 fei = fib_table_lookup_exact_match(0, &pfx_2001_s_64);
3890 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "2001::/64 present");
3891 ai = fib_entry_get_adj(fei);
3892 adj = adj_get(ai);
3893 FIB_TEST((adj->lookup_next_index == IP_LOOKUP_NEXT_ARP),
3894 "2001::/64 via ARP-adj");
Neale Ranns924d03a2016-10-19 08:25:46 +01003895 FIB_TEST((adj->ia_link == VNET_LINK_IP6),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003896 "2001::/64 is link type v6");
3897 FIB_TEST((adj->ia_nh_proto == FIB_PROTOCOL_IP4),
3898 "2001::/64 ADJ-adj is NH proto v4");
3899 fib_table_entry_delete(0, &pfx_2001_s_64, FIB_SOURCE_API);
3900
Neale Ranns3ee44042016-10-03 13:05:48 +01003901 /*
3902 * add a uRPF exempt prefix:
3903 * test:
3904 * - it's forwarding is drop
3905 * - it's uRPF list is not empty
3906 * - the uRPF list for the default route (it's cover) is empty
3907 */
3908 fei = fib_table_entry_special_add(fib_index,
3909 &pfx_4_1_1_1_s_32,
3910 FIB_SOURCE_URPF_EXEMPT,
Neale Rannsa0558302017-04-13 00:44:52 -07003911 FIB_ENTRY_FLAG_DROP);
Neale Ranns3ee44042016-10-03 13:05:48 +01003912 dpo = fib_entry_contribute_ip_forwarding(fei);
3913 FIB_TEST(load_balance_is_drop(dpo),
3914 "uRPF exempt 4.1.1.1/32 DROP");
3915 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 1, 0),
3916 "uRPF list for exempt prefix has itf index 0");
3917 fei = fib_table_lookup_exact_match(fib_index, &pfx_0_0_0_0_s_0);
3918 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 0),
3919 "uRPF list for 0.0.0.0/0 empty");
3920
3921 fib_table_entry_delete(fib_index, &pfx_4_1_1_1_s_32, FIB_SOURCE_URPF_EXEMPT);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003922
3923 /*
Neale Ranns3983ac22017-03-10 11:53:27 -08003924 * An adj-fib that fails the refinement criteria - no connected cover
3925 */
3926 fib_prefix_t pfx_12_10_10_2_s_32 = {
3927 .fp_len = 32,
3928 .fp_proto = FIB_PROTOCOL_IP4,
3929 .fp_addr = {
3930 /* 12.10.10.2 */
3931 .ip4.as_u32 = clib_host_to_net_u32(0x0c0a0a02),
3932 },
3933 };
3934
Neale Ranns81424992017-05-18 03:03:22 -07003935 fib_table_entry_path_add(fib_index,
3936 &pfx_12_10_10_2_s_32,
3937 FIB_SOURCE_ADJ,
3938 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07003939 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07003940 &pfx_12_10_10_2_s_32.fp_addr,
3941 tm->hw[0]->sw_if_index,
3942 ~0, // invalid fib index
3943 1,
3944 NULL,
3945 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns3983ac22017-03-10 11:53:27 -08003946
3947 fei = fib_table_lookup_exact_match(fib_index, &pfx_12_10_10_2_s_32);
3948 dpo = fib_entry_contribute_ip_forwarding(fei);
3949 FIB_TEST(!dpo_id_is_valid(dpo),
3950 "no connected cover adj-fib fails refinement");
3951
3952 fib_table_entry_delete(fib_index,
3953 &pfx_12_10_10_2_s_32,
3954 FIB_SOURCE_ADJ);
3955
3956 /*
3957 * An adj-fib that fails the refinement criteria - cover is connected
3958 * but on a different interface
3959 */
3960 fib_prefix_t pfx_10_10_10_127_s_32 = {
3961 .fp_len = 32,
3962 .fp_proto = FIB_PROTOCOL_IP4,
3963 .fp_addr = {
3964 /* 10.10.10.127 */
3965 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a7f),
3966 },
3967 };
3968
Neale Ranns81424992017-05-18 03:03:22 -07003969 fib_table_entry_path_add(fib_index,
3970 &pfx_10_10_10_127_s_32,
3971 FIB_SOURCE_ADJ,
3972 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07003973 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07003974 &pfx_10_10_10_127_s_32.fp_addr,
3975 tm->hw[1]->sw_if_index,
3976 ~0, // invalid fib index
3977 1,
3978 NULL,
3979 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns3983ac22017-03-10 11:53:27 -08003980
3981 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_127_s_32);
3982 dpo = fib_entry_contribute_ip_forwarding(fei);
3983 FIB_TEST(!dpo_id_is_valid(dpo),
3984 "wrong interface adj-fib fails refinement");
3985
3986 fib_table_entry_delete(fib_index,
3987 &pfx_10_10_10_127_s_32,
3988 FIB_SOURCE_ADJ);
Neale Ranns81424992017-05-18 03:03:22 -07003989
3990 /*
3991 * add a second path to an adj-fib
3992 * this is a sumiluation of another ARP entry created
3993 * on an interface on which the connected prefi does not exist.
3994 * The second path fails refinement. Expect to forward through the
3995 * first.
3996 */
3997 fib_prefix_t pfx_10_10_10_3_s_32 = {
3998 .fp_len = 32,
3999 .fp_proto = FIB_PROTOCOL_IP4,
4000 .fp_addr = {
4001 /* 10.10.10.3 */
4002 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a03),
4003 },
4004 };
4005
4006 ai_03 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
4007 VNET_LINK_IP4,
4008 &nh_10_10_10_3,
4009 tm->hw[0]->sw_if_index);
4010
4011 fib_test_lb_bucket_t ip_o_10_10_10_3 = {
4012 .type = FT_LB_ADJ,
4013 .adj = {
4014 .adj = ai_03,
4015 },
4016 };
4017 fei = fib_table_entry_path_add(fib_index,
4018 &pfx_10_10_10_3_s_32,
4019 FIB_SOURCE_ADJ,
4020 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07004021 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07004022 &nh_10_10_10_3,
4023 tm->hw[0]->sw_if_index,
4024 fib_index,
4025 1,
4026 NULL,
4027 FIB_ROUTE_PATH_FLAG_NONE);
4028 fei = fib_table_entry_path_add(fib_index,
4029 &pfx_10_10_10_3_s_32,
4030 FIB_SOURCE_ADJ,
4031 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07004032 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07004033 &nh_12_12_12_12,
4034 tm->hw[1]->sw_if_index,
4035 fib_index,
4036 1,
4037 NULL,
4038 FIB_ROUTE_PATH_FLAG_NONE);
4039 FIB_TEST(fib_test_validate_entry(fei,
4040 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
4041 1,
4042 &ip_o_10_10_10_3),
4043 "10.10.10.3 via 10.10.10.3/Eth0 only");
4044
4045 /*
4046 * remove the path that refines the cover, should go unresolved
4047 */
4048 fib_table_entry_path_remove(fib_index,
4049 &pfx_10_10_10_3_s_32,
4050 FIB_SOURCE_ADJ,
Neale Rannsda78f952017-05-24 09:15:43 -07004051 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07004052 &nh_10_10_10_3,
4053 tm->hw[0]->sw_if_index,
4054 fib_index,
4055 1,
4056 FIB_ROUTE_PATH_FLAG_NONE);
4057 dpo = fib_entry_contribute_ip_forwarding(fei);
4058 FIB_TEST(!dpo_id_is_valid(dpo),
4059 "wrong interface adj-fib fails refinement");
4060
4061 /*
4062 * add back the path that refines the cover
4063 */
4064 fei = fib_table_entry_path_add(fib_index,
4065 &pfx_10_10_10_3_s_32,
4066 FIB_SOURCE_ADJ,
4067 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07004068 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07004069 &nh_10_10_10_3,
4070 tm->hw[0]->sw_if_index,
4071 fib_index,
4072 1,
4073 NULL,
4074 FIB_ROUTE_PATH_FLAG_NONE);
4075 FIB_TEST(fib_test_validate_entry(fei,
4076 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
4077 1,
4078 &ip_o_10_10_10_3),
4079 "10.10.10.3 via 10.10.10.3/Eth0 only");
4080
4081 /*
4082 * remove the path that does not refine the cover
4083 */
4084 fib_table_entry_path_remove(fib_index,
4085 &pfx_10_10_10_3_s_32,
4086 FIB_SOURCE_ADJ,
Neale Rannsda78f952017-05-24 09:15:43 -07004087 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07004088 &nh_12_12_12_12,
4089 tm->hw[1]->sw_if_index,
4090 fib_index,
4091 1,
4092 FIB_ROUTE_PATH_FLAG_NONE);
4093 FIB_TEST(fib_test_validate_entry(fei,
4094 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
4095 1,
4096 &ip_o_10_10_10_3),
4097 "10.10.10.3 via 10.10.10.3/Eth0 only");
4098
4099 /*
4100 * remove the path that does refine, it's the last path, so
4101 * the entry should be gone
4102 */
4103 fib_table_entry_path_remove(fib_index,
4104 &pfx_10_10_10_3_s_32,
4105 FIB_SOURCE_ADJ,
Neale Rannsda78f952017-05-24 09:15:43 -07004106 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07004107 &nh_10_10_10_3,
4108 tm->hw[0]->sw_if_index,
4109 fib_index,
4110 1,
4111 FIB_ROUTE_PATH_FLAG_NONE);
4112 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_3_s_32);
4113 FIB_TEST((fei == FIB_NODE_INDEX_INVALID), "10.10.10.3 gone");
4114
4115 adj_unlock(ai_03);
4116
Neale Ranns227038a2017-04-21 01:07:59 -07004117 /*
4118 * change the table's flow-hash config - expect the update to propagete to
4119 * the entries' load-balance objects
4120 */
4121 flow_hash_config_t old_hash_config, new_hash_config;
4122
4123 old_hash_config = fib_table_get_flow_hash_config(fib_index,
4124 FIB_PROTOCOL_IP4);
4125 new_hash_config = (IP_FLOW_HASH_SRC_ADDR |
4126 IP_FLOW_HASH_DST_ADDR);
4127
4128 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
4129 dpo = fib_entry_contribute_ip_forwarding(fei);
4130 lb = load_balance_get(dpo->dpoi_index);
4131 FIB_TEST((lb->lb_hash_config == old_hash_config),
4132 "Table and LB hash config match: %U",
4133 format_ip_flow_hash_config, lb->lb_hash_config);
4134
4135 fib_table_set_flow_hash_config(fib_index, FIB_PROTOCOL_IP4, new_hash_config);
4136
4137 FIB_TEST((lb->lb_hash_config == new_hash_config),
4138 "Table and LB newhash config match: %U",
4139 format_ip_flow_hash_config, lb->lb_hash_config);
Neale Ranns3983ac22017-03-10 11:53:27 -08004140
4141 /*
Neale Rannsf068c3e2018-01-03 04:18:48 -08004142 * A route via DVR DPO
Neale Ranns6f631152017-10-03 08:20:21 -07004143 */
4144 fei = fib_table_entry_path_add(fib_index,
4145 &pfx_10_10_10_3_s_32,
4146 FIB_SOURCE_API,
4147 FIB_ENTRY_FLAG_NONE,
Neale Rannsf068c3e2018-01-03 04:18:48 -08004148 DPO_PROTO_IP4,
Neale Ranns6f631152017-10-03 08:20:21 -07004149 &zero_addr,
4150 tm->hw[0]->sw_if_index,
4151 ~0,
4152 1,
4153 NULL,
Neale Rannsf068c3e2018-01-03 04:18:48 -08004154 FIB_ROUTE_PATH_DVR);
4155 dpo_id_t dvr_dpo = DPO_INVALID;
4156 dvr_dpo_add_or_lock(tm->hw[0]->sw_if_index, DPO_PROTO_IP4, &dvr_dpo);
Neale Ranns6f631152017-10-03 08:20:21 -07004157 fib_test_lb_bucket_t ip_o_l2 = {
4158 .type = FT_LB_L2,
4159 .adj = {
Neale Rannsf068c3e2018-01-03 04:18:48 -08004160 .adj = dvr_dpo.dpoi_index,
Neale Ranns6f631152017-10-03 08:20:21 -07004161 },
4162 };
4163
4164 FIB_TEST(fib_test_validate_entry(fei,
4165 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
4166 1,
4167 &ip_o_l2),
4168 "10.10.10.3 via L2 on Eth0");
4169 fib_table_entry_path_remove(fib_index,
4170 &pfx_10_10_10_3_s_32,
4171 FIB_SOURCE_API,
Neale Rannsf068c3e2018-01-03 04:18:48 -08004172 DPO_PROTO_IP4,
Neale Ranns6f631152017-10-03 08:20:21 -07004173 &zero_addr,
4174 tm->hw[0]->sw_if_index,
4175 fib_index,
4176 1,
Neale Rannsf068c3e2018-01-03 04:18:48 -08004177 FIB_ROUTE_PATH_DVR);
4178 dpo_reset(&dvr_dpo);
Neale Ranns6f631152017-10-03 08:20:21 -07004179
4180 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004181 * CLEANUP
4182 * remove adj-fibs:
4183 */
4184 fib_table_entry_delete(fib_index,
4185 &pfx_10_10_10_1_s_32,
4186 FIB_SOURCE_ADJ);
4187 fib_table_entry_delete(fib_index,
4188 &pfx_10_10_10_2_s_32,
4189 FIB_SOURCE_ADJ);
4190 FIB_TEST(FIB_NODE_INDEX_INVALID ==
4191 fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32),
4192 "10.10.10.1/32 adj-fib removed");
4193 FIB_TEST(FIB_NODE_INDEX_INVALID ==
4194 fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_2_s_32),
4195 "10.10.10.2/32 adj-fib removed");
4196
4197 /*
4198 * -2 entries and -2 non-shared path-list
4199 */
4200 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
4201 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004202 FIB_TEST((PNBR+2 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004203 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004204 FIB_TEST((ENBR+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004205 fib_entry_pool_size());
4206
4207 /*
Neale Ranns3ee44042016-10-03 13:05:48 +01004208 * unlock the adjacencies for which this test provided a rewrite.
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004209 * These are the last locks on these adjs. they should thus go away.
4210 */
4211 adj_unlock(ai_02);
4212 adj_unlock(ai_01);
Neale Ranns3ee44042016-10-03 13:05:48 +01004213 adj_unlock(ai_12_12_12_12);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004214
4215 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
4216 adj_nbr_db_size());
Neale Ranns3dffb1e2016-11-01 20:38:53 +00004217
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004218 /*
4219 * CLEANUP
4220 * remove the interface prefixes
4221 */
4222 local_pfx.fp_len = 32;
4223 fib_table_entry_special_remove(fib_index, &local_pfx,
4224 FIB_SOURCE_INTERFACE);
4225 fei = fib_table_lookup(fib_index, &local_pfx);
4226
4227 FIB_TEST(FIB_NODE_INDEX_INVALID ==
4228 fib_table_lookup_exact_match(fib_index, &local_pfx),
4229 "10.10.10.10/32 adj-fib removed");
4230
4231 local_pfx.fp_len = 24;
4232 fib_table_entry_delete(fib_index, &local_pfx,
4233 FIB_SOURCE_INTERFACE);
4234
4235 FIB_TEST(FIB_NODE_INDEX_INVALID ==
4236 fib_table_lookup_exact_match(fib_index, &local_pfx),
4237 "10.10.10.10/24 adj-fib removed");
4238
4239 /*
4240 * -2 entries and -2 non-shared path-list
4241 */
Neale Rannsf12a83f2017-04-18 09:09:40 -07004242 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004243 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004244 FIB_TEST((PNBR == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004245 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004246 FIB_TEST((ENBR == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004247 fib_entry_pool_size());
4248
4249 /*
4250 * Last but not least, remove the VRF
4251 */
4252 FIB_TEST((0 == fib_table_get_num_entries(fib_index,
4253 FIB_PROTOCOL_IP4,
4254 FIB_SOURCE_API)),
4255 "NO API Source'd prefixes");
4256 FIB_TEST((0 == fib_table_get_num_entries(fib_index,
4257 FIB_PROTOCOL_IP4,
4258 FIB_SOURCE_RR)),
4259 "NO RR Source'd prefixes");
4260 FIB_TEST((0 == fib_table_get_num_entries(fib_index,
4261 FIB_PROTOCOL_IP4,
4262 FIB_SOURCE_INTERFACE)),
4263 "NO INterface Source'd prefixes");
4264
Neale Ranns15002542017-09-10 04:39:11 -07004265 fib_table_unlock(fib_index, FIB_PROTOCOL_IP4, FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004266
4267 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
4268 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004269 FIB_TEST((PNBR-5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004270 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004271 FIB_TEST((ENBR-5 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004272 fib_entry_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004273 FIB_TEST((ENBR-5 == pool_elts(fib_urpf_list_pool)), "uRPF pool size is %d",
Neale Ranns3ee44042016-10-03 13:05:48 +01004274 pool_elts(fib_urpf_list_pool));
Neale Ranns994dab42017-04-18 12:56:45 -07004275 FIB_TEST((0 == pool_elts(load_balance_map_pool)), "LB-map pool size is %d",
Neale Rannsf12a83f2017-04-18 09:09:40 -07004276 pool_elts(load_balance_map_pool));
Neale Ranns994dab42017-04-18 12:56:45 -07004277 FIB_TEST((lb_count == pool_elts(load_balance_pool)), "LB pool size is %d",
4278 pool_elts(load_balance_pool));
Neale Rannsf068c3e2018-01-03 04:18:48 -08004279 FIB_TEST((0 == pool_elts(dvr_dpo_pool)), "L2 DPO pool size is %d",
4280 pool_elts(dvr_dpo_pool));
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004281
Neale Ranns0ebe8d72016-12-08 19:48:11 +00004282 return 0;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004283}
4284
Neale Ranns0ebe8d72016-12-08 19:48:11 +00004285static int
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004286fib_test_v6 (void)
4287{
4288 /*
4289 * In the default table check for the presence and correct forwarding
4290 * of the special entries
4291 */
4292 fib_node_index_t dfrt, fei, ai, locked_ai, ai_01, ai_02;
4293 const dpo_id_t *dpo, *dpo_drop;
4294 const ip_adjacency_t *adj;
4295 const receive_dpo_t *rd;
4296 test_main_t *tm;
4297 u32 fib_index;
4298 int ii;
4299
4300 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
4301 adj_nbr_db_size());
4302
4303 /* via 2001:0:0:1::2 */
4304 ip46_address_t nh_2001_2 = {
4305 .ip6 = {
4306 .as_u64 = {
4307 [0] = clib_host_to_net_u64(0x2001000000000001),
4308 [1] = clib_host_to_net_u64(0x0000000000000002),
4309 },
4310 },
4311 };
4312
4313 tm = &test_main;
4314
4315 dpo_drop = drop_dpo_get(DPO_PROTO_IP6);
4316
4317 /* Find or create FIB table 11 */
Neale Ranns15002542017-09-10 04:39:11 -07004318 fib_index = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP6, 11,
4319 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004320
4321 for (ii = 0; ii < 4; ii++)
4322 {
4323 ip6_main.fib_index_by_sw_if_index[tm->hw[ii]->sw_if_index] = fib_index;
4324 }
4325
4326 fib_prefix_t pfx_0_0 = {
4327 .fp_len = 0,
4328 .fp_proto = FIB_PROTOCOL_IP6,
4329 .fp_addr = {
4330 .ip6 = {
4331 {0, 0},
4332 },
4333 },
4334 };
4335
4336 dfrt = fib_table_lookup(fib_index, &pfx_0_0);
4337 FIB_TEST((FIB_NODE_INDEX_INVALID != dfrt), "default route present");
4338 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(dfrt)),
4339 "Default route is DROP");
4340
4341 dpo = fib_entry_contribute_ip_forwarding(dfrt);
4342 FIB_TEST((dpo->dpoi_index == ip6_fib_table_fwding_lookup(
4343 &ip6_main,
4344 1,
4345 &pfx_0_0.fp_addr.ip6)),
4346 "default-route; fwd and non-fwd tables match");
4347
4348 // FIXME - check specials.
4349
4350 /*
4351 * At this stage there is one v4 FIB with 5 routes and two v6 FIBs
Neale Ranns32e1c012016-11-22 17:07:28 +00004352 * each with 2 entries and a v6 mfib with 4 path-lists.
4353 * All entries are special so no path-list sharing.
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004354 */
Neale Ranns32e1c012016-11-22 17:07:28 +00004355#define ENPS (5+4)
Jakub Grajciar7b867a82017-12-08 16:28:42 +01004356 u32 PNPS = (5+4+4);
4357 /*
4358 * if the IGMP plugin is loaded this adds two more entries to the v4 MFIB
4359 */
4360 if (vlib_get_plugin_symbol("igmp_plugin.so", "igmp_listen"))
4361 PNPS += 2;
4362
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004363 FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00004364 FIB_TEST((PNPS == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004365 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004366 FIB_TEST((ENPS == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004367 fib_entry_pool_size());
4368
4369 /*
4370 * add interface routes.
4371 * validate presence of /64 attached and /128 recieve.
4372 * test for the presence of the receive address in the glean and local adj
4373 *
4374 * receive on 2001:0:0:1::1/128
4375 */
4376 fib_prefix_t local_pfx = {
4377 .fp_len = 64,
4378 .fp_proto = FIB_PROTOCOL_IP6,
4379 .fp_addr = {
4380 .ip6 = {
4381 .as_u64 = {
4382 [0] = clib_host_to_net_u64(0x2001000000000001),
4383 [1] = clib_host_to_net_u64(0x0000000000000001),
4384 },
4385 },
4386 }
4387 };
4388
4389 fib_table_entry_update_one_path(fib_index, &local_pfx,
4390 FIB_SOURCE_INTERFACE,
4391 (FIB_ENTRY_FLAG_CONNECTED |
4392 FIB_ENTRY_FLAG_ATTACHED),
Neale Rannsda78f952017-05-24 09:15:43 -07004393 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004394 NULL,
4395 tm->hw[0]->sw_if_index,
4396 ~0,
4397 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00004398 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004399 FIB_ROUTE_PATH_FLAG_NONE);
4400 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4401
4402 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached interface route present");
4403
4404 ai = fib_entry_get_adj(fei);
4405 FIB_TEST((FIB_NODE_INDEX_INVALID != ai), "attached interface route adj present");
4406 adj = adj_get(ai);
4407 FIB_TEST((IP_LOOKUP_NEXT_GLEAN == adj->lookup_next_index),
4408 "attached interface adj is glean");
4409 FIB_TEST((0 == ip46_address_cmp(&local_pfx.fp_addr,
4410 &adj->sub_type.glean.receive_addr)),
4411 "attached interface adj is receive ok");
4412 dpo = fib_entry_contribute_ip_forwarding(fei);
4413 FIB_TEST((dpo->dpoi_index == ip6_fib_table_fwding_lookup(
4414 &ip6_main,
4415 1,
4416 &local_pfx.fp_addr.ip6)),
4417 "attached-route; fwd and non-fwd tables match");
4418
4419 local_pfx.fp_len = 128;
4420 fib_table_entry_update_one_path(fib_index, &local_pfx,
4421 FIB_SOURCE_INTERFACE,
4422 (FIB_ENTRY_FLAG_CONNECTED |
4423 FIB_ENTRY_FLAG_LOCAL),
Neale Rannsda78f952017-05-24 09:15:43 -07004424 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004425 NULL,
4426 tm->hw[0]->sw_if_index,
4427 ~0, // invalid fib index
4428 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00004429 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004430 FIB_ROUTE_PATH_FLAG_NONE);
4431 fei = fib_table_lookup(fib_index, &local_pfx);
4432
4433 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local interface route present");
4434
4435 dpo = fib_entry_contribute_ip_forwarding(fei);
4436 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
4437 FIB_TEST((DPO_RECEIVE == dpo->dpoi_type),
4438 "local interface adj is local");
4439 rd = receive_dpo_get(dpo->dpoi_index);
4440
4441 FIB_TEST((0 == ip46_address_cmp(&local_pfx.fp_addr,
4442 &rd->rd_addr)),
4443 "local interface adj is receive ok");
4444
4445 dpo = fib_entry_contribute_ip_forwarding(fei);
4446 FIB_TEST((dpo->dpoi_index == ip6_fib_table_fwding_lookup(
4447 &ip6_main,
4448 1,
4449 &local_pfx.fp_addr.ip6)),
4450 "local-route; fwd and non-fwd tables match");
4451
4452 /*
4453 * +2 entries. +2 unshared path-lists
4454 */
4455 FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00004456 FIB_TEST((PNPS+2 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004457 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004458 FIB_TEST((ENPS+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004459 fib_entry_pool_size());
4460
4461 /*
4462 * Modify the default route to be via an adj not yet known.
4463 * this sources the defalut route with the API source, which is
4464 * a higher preference to the DEFAULT_ROUTE source
4465 */
4466 fib_table_entry_path_add(fib_index, &pfx_0_0,
4467 FIB_SOURCE_API,
4468 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07004469 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004470 &nh_2001_2,
4471 tm->hw[0]->sw_if_index,
4472 ~0,
4473 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00004474 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004475 FIB_ROUTE_PATH_FLAG_NONE);
4476 fei = fib_table_lookup(fib_index, &pfx_0_0);
4477
4478 FIB_TEST((fei == dfrt), "default route same index");
4479 ai = fib_entry_get_adj(fei);
4480 FIB_TEST((FIB_NODE_INDEX_INVALID != ai), "default route adj present");
4481 adj = adj_get(ai);
4482 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
4483 "adj is incomplete");
4484 FIB_TEST((0 == ip46_address_cmp(&nh_2001_2, &adj->sub_type.nbr.next_hop)),
4485 "adj nbr next-hop ok");
4486
4487 /*
4488 * find the adj in the shared db
4489 */
4490 locked_ai = adj_nbr_add_or_lock(FIB_PROTOCOL_IP6,
Neale Ranns924d03a2016-10-19 08:25:46 +01004491 VNET_LINK_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004492 &nh_2001_2,
4493 tm->hw[0]->sw_if_index);
4494 FIB_TEST((locked_ai == ai), "ADJ NBR DB find");
4495 adj_unlock(locked_ai);
4496
4497 /*
4498 * no more entires. +1 shared path-list
4499 */
4500 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
4501 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004502 FIB_TEST((PNPS+3 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004503 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004504 FIB_TEST((ENPS+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004505 fib_entry_pool_size());
4506
4507 /*
4508 * remove the API source from the default route. We expected
4509 * the route to remain, sourced by DEFAULT_ROUTE, and hence a DROP
4510 */
4511 fib_table_entry_path_remove(fib_index, &pfx_0_0,
4512 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07004513 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004514 &nh_2001_2,
4515 tm->hw[0]->sw_if_index,
4516 ~0,
4517 1,
4518 FIB_ROUTE_PATH_FLAG_NONE);
4519 fei = fib_table_lookup(fib_index, &pfx_0_0);
4520
4521 FIB_TEST((fei == dfrt), "default route same index");
4522 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(dfrt)),
4523 "Default route is DROP");
4524
4525 /*
4526 * no more entires. -1 shared path-list
4527 */
4528 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
4529 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004530 FIB_TEST((PNPS+2 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004531 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004532 FIB_TEST((ENPS+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004533 fib_entry_pool_size());
4534
4535 /*
4536 * Add an 2 ARP entry => a complete ADJ plus adj-fib.
4537 */
4538 fib_prefix_t pfx_2001_1_2_s_128 = {
4539 .fp_len = 128,
4540 .fp_proto = FIB_PROTOCOL_IP6,
4541 .fp_addr = {
4542 .ip6 = {
4543 .as_u64 = {
4544 [0] = clib_host_to_net_u64(0x2001000000000001),
4545 [1] = clib_host_to_net_u64(0x0000000000000002),
4546 },
4547 },
4548 }
4549 };
4550 fib_prefix_t pfx_2001_1_3_s_128 = {
4551 .fp_len = 128,
4552 .fp_proto = FIB_PROTOCOL_IP6,
4553 .fp_addr = {
4554 .ip6 = {
4555 .as_u64 = {
4556 [0] = clib_host_to_net_u64(0x2001000000000001),
4557 [1] = clib_host_to_net_u64(0x0000000000000003),
4558 },
4559 },
4560 }
4561 };
4562 u8 eth_addr[] = {
4563 0xde, 0xde, 0xde, 0xba, 0xba, 0xba,
4564 };
4565
4566 ai_01 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP6,
Neale Ranns924d03a2016-10-19 08:25:46 +01004567 VNET_LINK_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004568 &pfx_2001_1_2_s_128.fp_addr,
4569 tm->hw[0]->sw_if_index);
4570 FIB_TEST((FIB_NODE_INDEX_INVALID != ai_01), "adj created");
4571 adj = adj_get(ai_01);
4572 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
4573 "adj is incomplete");
4574 FIB_TEST((0 == ip46_address_cmp(&pfx_2001_1_2_s_128.fp_addr,
4575 &adj->sub_type.nbr.next_hop)),
4576 "adj nbr next-hop ok");
4577
Neale Rannsb80c5362016-10-08 13:03:40 +01004578 adj_nbr_update_rewrite(ai_01, ADJ_NBR_REWRITE_FLAG_COMPLETE,
4579 fib_test_build_rewrite(eth_addr));
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004580 FIB_TEST((IP_LOOKUP_NEXT_REWRITE == adj->lookup_next_index),
4581 "adj is complete");
4582 FIB_TEST((0 == ip46_address_cmp(&pfx_2001_1_2_s_128.fp_addr,
4583 &adj->sub_type.nbr.next_hop)),
4584 "adj nbr next-hop ok");
4585
Neale Ranns81424992017-05-18 03:03:22 -07004586 fib_table_entry_path_add(fib_index,
4587 &pfx_2001_1_2_s_128,
4588 FIB_SOURCE_ADJ,
4589 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07004590 DPO_PROTO_IP6,
Neale Ranns81424992017-05-18 03:03:22 -07004591 &pfx_2001_1_2_s_128.fp_addr,
4592 tm->hw[0]->sw_if_index,
4593 ~0,
4594 1,
4595 NULL,
4596 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004597
4598 fei = fib_table_lookup(fib_index, &pfx_2001_1_2_s_128);
4599 ai = fib_entry_get_adj(fei);
4600 FIB_TEST((ai_01 == ai), "ADJ-FIB resolves via adj");
4601
4602 eth_addr[5] = 0xb2;
4603
4604 ai_02 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP6,
Neale Ranns924d03a2016-10-19 08:25:46 +01004605 VNET_LINK_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004606 &pfx_2001_1_3_s_128.fp_addr,
4607 tm->hw[0]->sw_if_index);
4608 FIB_TEST((FIB_NODE_INDEX_INVALID != ai_02), "adj created");
4609 adj = adj_get(ai_02);
4610 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
4611 "adj is incomplete");
4612 FIB_TEST((0 == ip46_address_cmp(&pfx_2001_1_3_s_128.fp_addr,
4613 &adj->sub_type.nbr.next_hop)),
4614 "adj nbr next-hop ok");
4615
Neale Rannsb80c5362016-10-08 13:03:40 +01004616 adj_nbr_update_rewrite(ai_02, ADJ_NBR_REWRITE_FLAG_COMPLETE,
4617 fib_test_build_rewrite(eth_addr));
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004618 FIB_TEST((IP_LOOKUP_NEXT_REWRITE == adj->lookup_next_index),
4619 "adj is complete");
4620 FIB_TEST((0 == ip46_address_cmp(&pfx_2001_1_3_s_128.fp_addr,
4621 &adj->sub_type.nbr.next_hop)),
4622 "adj nbr next-hop ok");
4623 FIB_TEST((ai_01 != ai_02), "ADJs are different");
4624
Neale Ranns81424992017-05-18 03:03:22 -07004625 fib_table_entry_path_add(fib_index,
4626 &pfx_2001_1_3_s_128,
4627 FIB_SOURCE_ADJ,
4628 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07004629 DPO_PROTO_IP6,
Neale Ranns81424992017-05-18 03:03:22 -07004630 &pfx_2001_1_3_s_128.fp_addr,
4631 tm->hw[0]->sw_if_index,
4632 ~0,
4633 1,
4634 NULL,
4635 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004636
4637 fei = fib_table_lookup(fib_index, &pfx_2001_1_3_s_128);
4638 ai = fib_entry_get_adj(fei);
4639 FIB_TEST((ai_02 == ai), "ADJ-FIB resolves via adj");
4640
4641 /*
4642 * +2 entries, +2 unshread path-lists.
4643 */
4644 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
4645 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004646 FIB_TEST((PNPS+4 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004647 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004648 FIB_TEST((ENPS+4 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004649 fib_entry_pool_size());
4650
4651 /*
4652 * Add a 2 routes via the first ADJ. ensure path-list sharing
4653 */
4654 fib_prefix_t pfx_2001_a_s_64 = {
4655 .fp_len = 64,
4656 .fp_proto = FIB_PROTOCOL_IP6,
4657 .fp_addr = {
4658 .ip6 = {
4659 .as_u64 = {
4660 [0] = clib_host_to_net_u64(0x200100000000000a),
4661 [1] = clib_host_to_net_u64(0x0000000000000000),
4662 },
4663 },
4664 }
4665 };
4666 fib_prefix_t pfx_2001_b_s_64 = {
4667 .fp_len = 64,
4668 .fp_proto = FIB_PROTOCOL_IP6,
4669 .fp_addr = {
4670 .ip6 = {
4671 .as_u64 = {
4672 [0] = clib_host_to_net_u64(0x200100000000000b),
4673 [1] = clib_host_to_net_u64(0x0000000000000000),
4674 },
4675 },
4676 }
4677 };
4678
4679 fib_table_entry_path_add(fib_index,
4680 &pfx_2001_a_s_64,
4681 FIB_SOURCE_API,
4682 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07004683 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004684 &nh_2001_2,
4685 tm->hw[0]->sw_if_index,
4686 ~0,
4687 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00004688 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004689 FIB_ROUTE_PATH_FLAG_NONE);
4690 fei = fib_table_lookup(fib_index, &pfx_2001_a_s_64);
4691 ai = fib_entry_get_adj(fei);
4692 FIB_TEST((ai_01 == ai), "2001::a/64 resolves via 2001:0:0:1::1");
4693 fib_table_entry_path_add(fib_index,
4694 &pfx_2001_b_s_64,
4695 FIB_SOURCE_API,
4696 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07004697 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004698 &nh_2001_2,
4699 tm->hw[0]->sw_if_index,
4700 ~0,
4701 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00004702 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004703 FIB_ROUTE_PATH_FLAG_NONE);
4704 fei = fib_table_lookup(fib_index, &pfx_2001_b_s_64);
4705 ai = fib_entry_get_adj(fei);
4706 FIB_TEST((ai_01 == ai), "2001::b/64 resolves via 2001:0:0:1::1");
4707
4708 /*
4709 * +2 entries, +1 shared path-list.
4710 */
4711 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
4712 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004713 FIB_TEST((PNPS+5 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004714 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004715 FIB_TEST((ENPS+6 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004716 fib_entry_pool_size());
4717
4718 /*
4719 * add a v4 prefix via a v6 next-hop
4720 */
4721 fib_prefix_t pfx_1_1_1_1_s_32 = {
4722 .fp_len = 32,
4723 .fp_proto = FIB_PROTOCOL_IP4,
4724 .fp_addr = {
4725 .ip4.as_u32 = 0x01010101,
4726 },
4727 };
4728 fei = fib_table_entry_path_add(0, // default table
4729 &pfx_1_1_1_1_s_32,
4730 FIB_SOURCE_API,
4731 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07004732 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004733 &nh_2001_2,
4734 tm->hw[0]->sw_if_index,
4735 ~0,
4736 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00004737 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004738 FIB_ROUTE_PATH_FLAG_NONE);
4739 FIB_TEST(fei == fib_table_lookup_exact_match(0, &pfx_1_1_1_1_s_32),
4740 "1.1.1.1/32 o v6 route present");
4741 ai = fib_entry_get_adj(fei);
4742 adj = adj_get(ai);
4743 FIB_TEST((adj->lookup_next_index == IP_LOOKUP_NEXT_ARP),
4744 "1.1.1.1/32 via ARP-adj");
Neale Ranns924d03a2016-10-19 08:25:46 +01004745 FIB_TEST((adj->ia_link == VNET_LINK_IP4),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004746 "1.1.1.1/32 ADJ-adj is link type v4");
4747 FIB_TEST((adj->ia_nh_proto == FIB_PROTOCOL_IP6),
4748 "1.1.1.1/32 ADJ-adj is NH proto v6");
4749 fib_table_entry_delete(0, &pfx_1_1_1_1_s_32, FIB_SOURCE_API);
4750
4751 /*
4752 * An attached route
4753 */
4754 fib_prefix_t pfx_2001_c_s_64 = {
4755 .fp_len = 64,
4756 .fp_proto = FIB_PROTOCOL_IP6,
4757 .fp_addr = {
4758 .ip6 = {
4759 .as_u64 = {
4760 [0] = clib_host_to_net_u64(0x200100000000000c),
4761 [1] = clib_host_to_net_u64(0x0000000000000000),
4762 },
4763 },
4764 }
4765 };
4766 fib_table_entry_path_add(fib_index,
4767 &pfx_2001_c_s_64,
4768 FIB_SOURCE_CLI,
4769 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07004770 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004771 NULL,
4772 tm->hw[0]->sw_if_index,
4773 ~0,
4774 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00004775 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004776 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 present");
4779 ai = fib_entry_get_adj(fei);
4780 adj = adj_get(ai);
4781 FIB_TEST((adj->lookup_next_index == IP_LOOKUP_NEXT_GLEAN),
4782 "2001:0:0:c/64 attached resolves via glean");
4783
4784 fib_table_entry_path_remove(fib_index,
4785 &pfx_2001_c_s_64,
4786 FIB_SOURCE_CLI,
Neale Rannsda78f952017-05-24 09:15:43 -07004787 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004788 NULL,
4789 tm->hw[0]->sw_if_index,
4790 ~0,
4791 1,
4792 FIB_ROUTE_PATH_FLAG_NONE);
4793 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_c_s_64);
4794 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "attached route removed");
4795
4796 /*
4797 * Shutdown the interface on which we have a connected and through
4798 * which the routes are reachable.
4799 * This will result in the connected, adj-fibs, and routes linking to drop
4800 * The local/for-us prefix continues to receive.
4801 */
4802 clib_error_t * error;
4803
4804 error = vnet_sw_interface_set_flags(vnet_get_main(),
4805 tm->hw[0]->sw_if_index,
4806 ~VNET_SW_INTERFACE_FLAG_ADMIN_UP);
4807 FIB_TEST((NULL == error), "Interface shutdown OK");
4808
4809 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
4810 dpo = fib_entry_contribute_ip_forwarding(fei);
4811 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4812 "2001::b/64 resolves via drop");
4813
4814 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
4815 dpo = fib_entry_contribute_ip_forwarding(fei);
4816 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4817 "2001::a/64 resolves via drop");
4818 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
4819 dpo = fib_entry_contribute_ip_forwarding(fei);
4820 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4821 "2001:0:0:1::3/64 resolves via drop");
4822 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
4823 dpo = fib_entry_contribute_ip_forwarding(fei);
4824 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4825 "2001:0:0:1::2/64 resolves via drop");
4826 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4827 dpo = fib_entry_contribute_ip_forwarding(fei);
4828 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4829 "2001:0:0:1::1/128 not drop");
4830 local_pfx.fp_len = 64;
4831 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4832 dpo = fib_entry_contribute_ip_forwarding(fei);
4833 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4834 "2001:0:0:1/64 resolves via drop");
4835
4836 /*
4837 * no change
4838 */
4839 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
4840 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004841 FIB_TEST((PNPS+5 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004842 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004843 FIB_TEST((ENPS+6 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004844 fib_entry_pool_size());
4845
4846 /*
4847 * shutdown one of the other interfaces, then add a connected.
4848 * and swap one of the routes to it.
4849 */
4850 error = vnet_sw_interface_set_flags(vnet_get_main(),
4851 tm->hw[1]->sw_if_index,
4852 ~VNET_SW_INTERFACE_FLAG_ADMIN_UP);
4853 FIB_TEST((NULL == error), "Interface 1 shutdown OK");
4854
4855 fib_prefix_t connected_pfx = {
4856 .fp_len = 64,
4857 .fp_proto = FIB_PROTOCOL_IP6,
4858 .fp_addr = {
4859 .ip6 = {
4860 /* 2001:0:0:2::1/64 */
4861 .as_u64 = {
4862 [0] = clib_host_to_net_u64(0x2001000000000002),
4863 [1] = clib_host_to_net_u64(0x0000000000000001),
4864 },
4865 },
4866 }
4867 };
4868 fib_table_entry_update_one_path(fib_index, &connected_pfx,
4869 FIB_SOURCE_INTERFACE,
4870 (FIB_ENTRY_FLAG_CONNECTED |
4871 FIB_ENTRY_FLAG_ATTACHED),
Neale Rannsda78f952017-05-24 09:15:43 -07004872 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004873 NULL,
4874 tm->hw[1]->sw_if_index,
4875 ~0,
4876 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00004877 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004878 FIB_ROUTE_PATH_FLAG_NONE);
4879 fei = fib_table_lookup_exact_match(fib_index, &connected_pfx);
4880 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached interface route present");
4881 dpo = fib_entry_contribute_ip_forwarding(fei);
4882 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
4883 FIB_TEST(!dpo_cmp(dpo, dpo_drop),
4884 "2001:0:0:2/64 not resolves via drop");
4885
4886 connected_pfx.fp_len = 128;
4887 fib_table_entry_update_one_path(fib_index, &connected_pfx,
4888 FIB_SOURCE_INTERFACE,
4889 (FIB_ENTRY_FLAG_CONNECTED |
4890 FIB_ENTRY_FLAG_LOCAL),
Neale Rannsda78f952017-05-24 09:15:43 -07004891 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004892 NULL,
4893 tm->hw[0]->sw_if_index,
4894 ~0, // invalid fib index
4895 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00004896 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004897 FIB_ROUTE_PATH_FLAG_NONE);
4898 fei = fib_table_lookup(fib_index, &connected_pfx);
4899
4900 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local interface route present");
4901 dpo = fib_entry_contribute_ip_forwarding(fei);
4902 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
4903 FIB_TEST((DPO_RECEIVE == dpo->dpoi_type),
4904 "local interface adj is local");
4905 rd = receive_dpo_get(dpo->dpoi_index);
4906 FIB_TEST((0 == ip46_address_cmp(&connected_pfx.fp_addr,
4907 &rd->rd_addr)),
4908 "local interface adj is receive ok");
4909
4910 /*
4911 * +2 entries, +2 unshared path-lists
4912 */
4913 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
4914 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004915 FIB_TEST((PNPS+7 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004916 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004917 FIB_TEST((ENPS+8 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004918 fib_entry_pool_size());
4919
4920
4921 /*
4922 * bring the interface back up. we expected the routes to return
4923 * to normal forwarding.
4924 */
4925 error = vnet_sw_interface_set_flags(vnet_get_main(),
4926 tm->hw[0]->sw_if_index,
4927 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
4928 FIB_TEST((NULL == error), "Interface bring-up OK");
4929 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
4930 ai = fib_entry_get_adj(fei);
4931 FIB_TEST((ai_01 == ai), "2001::a/64 resolves via 2001:0:0:1::1");
4932 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
4933 ai = fib_entry_get_adj(fei);
4934 FIB_TEST((ai_01 == ai), "2001::b/64 resolves via 2001:0:0:1::1");
4935 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
4936 ai = fib_entry_get_adj(fei);
4937 FIB_TEST((ai_02 == ai), "ADJ-FIB resolves via adj");
4938 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
4939 ai = fib_entry_get_adj(fei);
4940 FIB_TEST((ai_01 == ai), "ADJ-FIB resolves via adj");
4941 local_pfx.fp_len = 64;
4942 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4943 ai = fib_entry_get_adj(fei);
4944 adj = adj_get(ai);
4945 FIB_TEST((IP_LOOKUP_NEXT_GLEAN == adj->lookup_next_index),
4946 "attached interface adj is glean");
4947
4948 /*
Neale Ranns8b37b872016-11-21 12:25:22 +00004949 * Same test as above, but this time the HW interface goes down
4950 */
4951 error = vnet_hw_interface_set_flags(vnet_get_main(),
4952 tm->hw_if_indicies[0],
4953 ~VNET_HW_INTERFACE_FLAG_LINK_UP);
4954 FIB_TEST((NULL == error), "Interface shutdown OK");
4955
4956 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
4957 dpo = fib_entry_contribute_ip_forwarding(fei);
4958 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4959 "2001::b/64 resolves via drop");
4960 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
4961 dpo = fib_entry_contribute_ip_forwarding(fei);
4962 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4963 "2001::a/64 resolves via drop");
4964 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
4965 dpo = fib_entry_contribute_ip_forwarding(fei);
4966 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4967 "2001:0:0:1::3/128 resolves via drop");
4968 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
4969 dpo = fib_entry_contribute_ip_forwarding(fei);
4970 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4971 "2001:0:0:1::2/128 resolves via drop");
4972 local_pfx.fp_len = 128;
4973 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4974 dpo = fib_entry_contribute_ip_forwarding(fei);
4975 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4976 "2001:0:0:1::1/128 not drop");
4977 local_pfx.fp_len = 64;
4978 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4979 dpo = fib_entry_contribute_ip_forwarding(fei);
4980 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4981 "2001:0:0:1/64 resolves via drop");
4982
4983 error = vnet_hw_interface_set_flags(vnet_get_main(),
4984 tm->hw_if_indicies[0],
4985 VNET_HW_INTERFACE_FLAG_LINK_UP);
4986 FIB_TEST((NULL == error), "Interface bring-up OK");
4987 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
4988 ai = fib_entry_get_adj(fei);
4989 FIB_TEST((ai_01 == ai), "2001::a/64 resolves via 2001:0:0:1::1");
4990 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
4991 ai = fib_entry_get_adj(fei);
4992 FIB_TEST((ai_01 == ai), "2001::b/64 resolves via 2001:0:0:1::1");
4993 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
4994 ai = fib_entry_get_adj(fei);
4995 FIB_TEST((ai_02 == ai), "ADJ-FIB resolves via adj");
4996 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
4997 ai = fib_entry_get_adj(fei);
4998 FIB_TEST((ai_01 == ai), "ADJ-FIB resolves via adj");
4999 local_pfx.fp_len = 64;
5000 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5001 ai = fib_entry_get_adj(fei);
5002 adj = adj_get(ai);
5003 FIB_TEST((IP_LOOKUP_NEXT_GLEAN == adj->lookup_next_index),
5004 "attached interface adj is glean");
5005
5006 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005007 * Delete the interface that the routes reolve through.
5008 * Again no routes are removed. They all point to drop.
5009 *
5010 * This is considered an error case. The control plane should
5011 * not remove interfaces through which routes resolve, but
5012 * such things can happen. ALL affected routes will drop.
5013 */
5014 vnet_delete_hw_interface(vnet_get_main(), tm->hw_if_indicies[0]);
5015
5016 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
5017 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5018 "2001::b/64 resolves via drop");
5019 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
5020 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5021 "2001::b/64 resolves via drop");
5022 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
5023 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5024 "2001:0:0:1::3/64 resolves via drop");
5025 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
5026 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5027 "2001:0:0:1::2/64 resolves via drop");
5028 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5029 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5030 "2001:0:0:1::1/128 is drop");
5031 local_pfx.fp_len = 64;
5032 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5033 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5034 "2001:0:0:1/64 resolves via drop");
5035
5036 /*
5037 * no change
5038 */
5039 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
5040 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00005041 FIB_TEST((PNPS+7 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005042 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00005043 FIB_TEST((ENPS+8 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005044 fib_entry_pool_size());
5045
5046 /*
5047 * Add the interface back. routes stay unresolved.
5048 */
5049 error = ethernet_register_interface(vnet_get_main(),
5050 test_interface_device_class.index,
5051 0 /* instance */,
5052 hw_address,
5053 &tm->hw_if_indicies[0],
5054 /* flag change */ 0);
5055
5056 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
5057 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5058 "2001::b/64 resolves via drop");
5059 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
5060 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5061 "2001::b/64 resolves via drop");
5062 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
5063 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5064 "2001:0:0:1::3/64 resolves via drop");
5065 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
5066 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5067 "2001:0:0:1::2/64 resolves via drop");
5068 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5069 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5070 "2001:0:0:1::1/128 is drop");
5071 local_pfx.fp_len = 64;
5072 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5073 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5074 "2001:0:0:1/64 resolves via drop");
5075
5076 /*
5077 * CLEANUP ALL the routes
5078 */
5079 fib_table_entry_delete(fib_index,
5080 &pfx_2001_c_s_64,
5081 FIB_SOURCE_API);
5082 fib_table_entry_delete(fib_index,
5083 &pfx_2001_a_s_64,
5084 FIB_SOURCE_API);
5085 fib_table_entry_delete(fib_index,
5086 &pfx_2001_b_s_64,
5087 FIB_SOURCE_API);
5088 fib_table_entry_delete(fib_index,
5089 &pfx_2001_1_3_s_128,
5090 FIB_SOURCE_ADJ);
5091 fib_table_entry_delete(fib_index,
5092 &pfx_2001_1_2_s_128,
5093 FIB_SOURCE_ADJ);
5094 local_pfx.fp_len = 64;
5095 fib_table_entry_delete(fib_index, &local_pfx,
5096 FIB_SOURCE_INTERFACE);
5097 local_pfx.fp_len = 128;
5098 fib_table_entry_special_remove(fib_index, &local_pfx,
5099 FIB_SOURCE_INTERFACE);
5100 connected_pfx.fp_len = 64;
5101 fib_table_entry_delete(fib_index, &connected_pfx,
5102 FIB_SOURCE_INTERFACE);
5103 connected_pfx.fp_len = 128;
5104 fib_table_entry_special_remove(fib_index, &connected_pfx,
5105 FIB_SOURCE_INTERFACE);
5106
5107 FIB_TEST((FIB_NODE_INDEX_INVALID ==
5108 fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64)),
5109 "2001::a/64 removed");
5110 FIB_TEST((FIB_NODE_INDEX_INVALID ==
5111 fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64)),
5112 "2001::b/64 removed");
5113 FIB_TEST((FIB_NODE_INDEX_INVALID ==
5114 fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128)),
5115 "2001:0:0:1::3/128 removed");
5116 FIB_TEST((FIB_NODE_INDEX_INVALID ==
5117 fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128)),
5118 "2001:0:0:1::3/128 removed");
5119 local_pfx.fp_len = 64;
5120 FIB_TEST((FIB_NODE_INDEX_INVALID ==
5121 fib_table_lookup_exact_match(fib_index, &local_pfx)),
5122 "2001:0:0:1/64 removed");
5123 local_pfx.fp_len = 128;
5124 FIB_TEST((FIB_NODE_INDEX_INVALID ==
5125 fib_table_lookup_exact_match(fib_index, &local_pfx)),
5126 "2001:0:0:1::1/128 removed");
5127 connected_pfx.fp_len = 64;
5128 FIB_TEST((FIB_NODE_INDEX_INVALID ==
5129 fib_table_lookup_exact_match(fib_index, &connected_pfx)),
5130 "2001:0:0:2/64 removed");
5131 connected_pfx.fp_len = 128;
5132 FIB_TEST((FIB_NODE_INDEX_INVALID ==
5133 fib_table_lookup_exact_match(fib_index, &connected_pfx)),
5134 "2001:0:0:2::1/128 removed");
5135
5136 /*
5137 * -8 entries. -7 path-lists (1 was shared).
5138 */
5139 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
5140 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00005141 FIB_TEST((PNPS == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005142 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00005143 FIB_TEST((ENPS == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005144 fib_entry_pool_size());
5145
5146 /*
5147 * now remove the VRF
5148 */
Neale Ranns15002542017-09-10 04:39:11 -07005149 fib_table_unlock(fib_index, FIB_PROTOCOL_IP6, FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005150
5151 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
5152 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00005153 FIB_TEST((PNPS-2 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005154 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00005155 FIB_TEST((ENPS-2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005156 fib_entry_pool_size());
5157
5158 adj_unlock(ai_02);
5159 adj_unlock(ai_01);
5160
5161 /*
5162 * return the interfaces to up state
5163 */
5164 error = vnet_sw_interface_set_flags(vnet_get_main(),
5165 tm->hw[0]->sw_if_index,
5166 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
5167 error = vnet_sw_interface_set_flags(vnet_get_main(),
5168 tm->hw[1]->sw_if_index,
5169 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
5170
5171 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
5172 adj_nbr_db_size());
Neale Ranns0ebe8d72016-12-08 19:48:11 +00005173
5174 return (0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005175}
5176
5177/*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005178 * Test Attached Exports
5179 */
Neale Ranns0ebe8d72016-12-08 19:48:11 +00005180static int
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005181fib_test_ae (void)
5182{
5183 const dpo_id_t *dpo, *dpo_drop;
5184 const u32 fib_index = 0;
5185 fib_node_index_t fei;
5186 test_main_t *tm;
5187 ip4_main_t *im;
5188
5189 tm = &test_main;
5190 im = &ip4_main;
5191
5192 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
5193 adj_nbr_db_size());
5194
5195 /*
5196 * add interface routes. We'll assume this works. It's more rigorously
5197 * tested elsewhere.
5198 */
5199 fib_prefix_t local_pfx = {
5200 .fp_len = 24,
5201 .fp_proto = FIB_PROTOCOL_IP4,
5202 .fp_addr = {
5203 .ip4 = {
5204 /* 10.10.10.10 */
5205 .as_u32 = clib_host_to_net_u32(0x0a0a0a0a),
5206 },
5207 },
5208 };
5209
5210 vec_validate(im->fib_index_by_sw_if_index, tm->hw[0]->sw_if_index);
5211 im->fib_index_by_sw_if_index[tm->hw[0]->sw_if_index] = fib_index;
5212
5213 dpo_drop = drop_dpo_get(DPO_PROTO_IP4);
5214
5215 fib_table_entry_update_one_path(fib_index, &local_pfx,
5216 FIB_SOURCE_INTERFACE,
5217 (FIB_ENTRY_FLAG_CONNECTED |
5218 FIB_ENTRY_FLAG_ATTACHED),
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,
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 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
5228 "attached interface route present");
5229
5230 local_pfx.fp_len = 32;
5231 fib_table_entry_update_one_path(fib_index, &local_pfx,
5232 FIB_SOURCE_INTERFACE,
5233 (FIB_ENTRY_FLAG_CONNECTED |
5234 FIB_ENTRY_FLAG_LOCAL),
Neale Rannsda78f952017-05-24 09:15:43 -07005235 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005236 NULL,
5237 tm->hw[0]->sw_if_index,
5238 ~0, // invalid fib index
5239 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005240 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005241 FIB_ROUTE_PATH_FLAG_NONE);
5242 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5243
5244 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
5245 "local interface route present");
5246
5247 /*
5248 * Add an 2 ARP entry => a complete ADJ plus adj-fib.
5249 */
5250 fib_prefix_t pfx_10_10_10_1_s_32 = {
5251 .fp_len = 32,
5252 .fp_proto = FIB_PROTOCOL_IP4,
5253 .fp_addr = {
5254 /* 10.10.10.1 */
5255 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
5256 },
5257 };
5258 fib_node_index_t ai;
5259
Neale Ranns81424992017-05-18 03:03:22 -07005260 fib_table_entry_path_add(fib_index,
5261 &pfx_10_10_10_1_s_32,
5262 FIB_SOURCE_ADJ,
5263 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07005264 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07005265 &pfx_10_10_10_1_s_32.fp_addr,
5266 tm->hw[0]->sw_if_index,
5267 ~0, // invalid fib index
5268 1,
5269 NULL,
5270 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005271
5272 fei = fib_table_lookup(fib_index, &pfx_10_10_10_1_s_32);
5273 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 created");
5274 ai = fib_entry_get_adj(fei);
5275
5276 /*
5277 * create another FIB table into which routes will be imported
5278 */
5279 u32 import_fib_index1;
5280
Neale Ranns15002542017-09-10 04:39:11 -07005281 import_fib_index1 = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP4,
5282 11,
5283 FIB_SOURCE_CLI);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005284
5285 /*
5286 * Add an attached route in the import FIB
5287 */
5288 local_pfx.fp_len = 24;
5289 fib_table_entry_update_one_path(import_fib_index1,
5290 &local_pfx,
5291 FIB_SOURCE_API,
5292 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07005293 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005294 NULL,
5295 tm->hw[0]->sw_if_index,
5296 ~0, // invalid fib index
5297 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005298 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005299 FIB_ROUTE_PATH_FLAG_NONE);
5300 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5301 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached export created");
5302
5303 /*
5304 * check for the presence of the adj-fibs in the import table
5305 */
5306 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5307 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 imported");
5308 FIB_TEST((ai == fib_entry_get_adj(fei)),
5309 "adj-fib1 Import uses same adj as export");
5310
5311 /*
5312 * check for the presence of the local in the import table
5313 */
5314 local_pfx.fp_len = 32;
5315 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5316 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local imported");
5317
5318 /*
5319 * Add another adj-fin in the export table. Expect this
5320 * to get magically exported;
5321 */
5322 fib_prefix_t pfx_10_10_10_2_s_32 = {
5323 .fp_len = 32,
5324 .fp_proto = FIB_PROTOCOL_IP4,
5325 .fp_addr = {
5326 /* 10.10.10.2 */
5327 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02),
5328 },
5329 };
5330
Neale Ranns81424992017-05-18 03:03:22 -07005331 fib_table_entry_path_add(fib_index,
5332 &pfx_10_10_10_2_s_32,
5333 FIB_SOURCE_ADJ,
5334 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07005335 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07005336 &pfx_10_10_10_2_s_32.fp_addr,
5337 tm->hw[0]->sw_if_index,
5338 ~0, // invalid fib index
5339 1,
5340 NULL,
5341 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005342 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_2_s_32);
5343 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 present");
5344 ai = fib_entry_get_adj(fei);
5345
5346 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5347 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 imported");
5348 FIB_TEST((ai == fib_entry_get_adj(fei)),
5349 "Import uses same adj as export");
Neale Rannsfa0fb582016-12-10 21:59:14 +00005350 FIB_TEST((FIB_ENTRY_FLAG_ATTACHED & fib_entry_get_flags(fei)),
5351 "ADJ-fib2 imported flags %d",
5352 fib_entry_get_flags(fei));
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005353
5354 /*
5355 * create a 2nd FIB table into which routes will be imported
5356 */
5357 u32 import_fib_index2;
5358
Neale Ranns15002542017-09-10 04:39:11 -07005359 import_fib_index2 = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP4, 12,
5360 FIB_SOURCE_CLI);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005361
5362 /*
5363 * Add an attached route in the import FIB
5364 */
5365 local_pfx.fp_len = 24;
5366 fib_table_entry_update_one_path(import_fib_index2,
5367 &local_pfx,
5368 FIB_SOURCE_API,
5369 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07005370 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005371 NULL,
5372 tm->hw[0]->sw_if_index,
5373 ~0, // invalid fib index
5374 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005375 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005376 FIB_ROUTE_PATH_FLAG_NONE);
5377 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5378 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached export created");
5379
5380 /*
5381 * check for the presence of all the adj-fibs and local in the import table
5382 */
5383 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_1_s_32);
5384 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 imported");
5385 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_2_s_32);
5386 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 imported");
5387 local_pfx.fp_len = 32;
5388 fei = fib_table_lookup_exact_match(import_fib_index2, &local_pfx);
5389 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local imported");
5390
5391 /*
5392 * add a 3rd adj-fib. expect it to be exported to both tables.
5393 */
5394 fib_prefix_t pfx_10_10_10_3_s_32 = {
5395 .fp_len = 32,
5396 .fp_proto = FIB_PROTOCOL_IP4,
5397 .fp_addr = {
5398 /* 10.10.10.3 */
5399 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a03),
5400 },
5401 };
5402
Neale Ranns81424992017-05-18 03:03:22 -07005403 fib_table_entry_path_add(fib_index,
5404 &pfx_10_10_10_3_s_32,
5405 FIB_SOURCE_ADJ,
5406 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07005407 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07005408 &pfx_10_10_10_3_s_32.fp_addr,
5409 tm->hw[0]->sw_if_index,
5410 ~0, // invalid fib index
5411 1,
5412 NULL,
5413 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005414 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_3_s_32);
5415 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib3 present");
5416 ai = fib_entry_get_adj(fei);
5417
5418 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_3_s_32);
5419 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib3 imported to FIB1");
5420 FIB_TEST((ai == fib_entry_get_adj(fei)),
5421 "Import uses same adj as export");
5422 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_3_s_32);
5423 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib3 imported to FIB2");
5424 FIB_TEST((ai == fib_entry_get_adj(fei)),
5425 "Import uses same adj as export");
5426
5427 /*
5428 * remove the 3rd adj fib. we expect it to be removed from both FIBs
5429 */
5430 fib_table_entry_delete(fib_index,
5431 &pfx_10_10_10_3_s_32,
5432 FIB_SOURCE_ADJ);
5433
5434 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_3_s_32);
5435 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib3 remved");
5436
5437 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_3_s_32);
5438 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib3 removed from FIB1");
5439
5440 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_3_s_32);
5441 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib3 removed from FIB2");
5442
5443 /*
5444 * remove the attached route from the 2nd FIB. expect the imported
5445 * entires to be removed
5446 */
5447 local_pfx.fp_len = 24;
5448 fib_table_entry_delete(import_fib_index2,
5449 &local_pfx,
5450 FIB_SOURCE_API);
5451 fei = fib_table_lookup_exact_match(import_fib_index2, &local_pfx);
5452 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "attached export removed");
5453
5454 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_1_s_32);
5455 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib1 removed from FIB2");
5456 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_2_s_32);
5457 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib2 removed from FIB2");
5458 local_pfx.fp_len = 32;
5459 fei = fib_table_lookup_exact_match(import_fib_index2, &local_pfx);
5460 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "local removed from FIB2");
5461
5462 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5463 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 still in FIB1");
5464 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5465 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 still in FIB1");
5466 local_pfx.fp_len = 32;
5467 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5468 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local still in FIB1");
5469
5470 /*
5471 * modify the route in FIB1 so it is no longer attached. expect the imported
5472 * entires to be removed
5473 */
5474 local_pfx.fp_len = 24;
5475 fib_table_entry_update_one_path(import_fib_index1,
5476 &local_pfx,
5477 FIB_SOURCE_API,
5478 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07005479 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005480 &pfx_10_10_10_2_s_32.fp_addr,
5481 tm->hw[0]->sw_if_index,
5482 ~0, // invalid fib index
5483 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005484 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005485 FIB_ROUTE_PATH_FLAG_NONE);
5486 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5487 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib1 removed from FIB1");
5488 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5489 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib2 removed from FIB1");
5490 local_pfx.fp_len = 32;
5491 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5492 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "local removed from FIB1");
5493
5494 /*
5495 * modify it back to attached. expect the adj-fibs back
5496 */
5497 local_pfx.fp_len = 24;
5498 fib_table_entry_update_one_path(import_fib_index1,
5499 &local_pfx,
5500 FIB_SOURCE_API,
5501 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07005502 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005503 NULL,
5504 tm->hw[0]->sw_if_index,
5505 ~0, // invalid fib index
5506 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005507 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005508 FIB_ROUTE_PATH_FLAG_NONE);
5509 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5510 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 imported in FIB1");
5511 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5512 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 imported in FIB1");
5513 local_pfx.fp_len = 32;
5514 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5515 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local imported in FIB1");
5516
5517 /*
5518 * add a covering attached next-hop for the interface address, so we have
5519 * a valid adj to find when we check the forwarding tables
5520 */
5521 fib_prefix_t pfx_10_0_0_0_s_8 = {
5522 .fp_len = 8,
5523 .fp_proto = FIB_PROTOCOL_IP4,
5524 .fp_addr = {
5525 /* 10.0.0.0 */
5526 .ip4.as_u32 = clib_host_to_net_u32(0x0a000000),
5527 },
5528 };
5529
5530 fei = fib_table_entry_update_one_path(fib_index,
5531 &pfx_10_0_0_0_s_8,
5532 FIB_SOURCE_API,
5533 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07005534 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005535 &pfx_10_10_10_3_s_32.fp_addr,
5536 tm->hw[0]->sw_if_index,
5537 ~0, // invalid fib index
5538 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005539 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005540 FIB_ROUTE_PATH_FLAG_NONE);
5541 dpo = fib_entry_contribute_ip_forwarding(fei);
5542
5543 /*
5544 * remove the route in the export fib. expect the adj-fibs to be removed
5545 */
5546 local_pfx.fp_len = 24;
5547 fib_table_entry_delete(fib_index,
5548 &local_pfx,
5549 FIB_SOURCE_INTERFACE);
5550
5551 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5552 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "Delete export: ADJ-fib1 removed from FIB1");
5553 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5554 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib2 removed from FIB1");
5555 local_pfx.fp_len = 32;
5556 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5557 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "local removed from FIB1");
5558
5559 /*
5560 * the adj-fibs in the export VRF are present in the FIB table,
5561 * but not installed in forwarding, since they have no attached cover.
5562 * Consequently a lookup in the MTRIE gives the adj for the covering
5563 * route 10.0.0.0/8.
5564 */
5565 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
5566 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 in export");
5567
5568 index_t lbi;
5569 lbi = ip4_fib_forwarding_lookup(fib_index, &pfx_10_10_10_1_s_32.fp_addr.ip4);
5570 FIB_TEST(lbi == dpo->dpoi_index,
5571 "10.10.10.1 forwards on \n%U not \n%U",
5572 format_load_balance, lbi, 0,
5573 format_dpo_id, dpo, 0);
5574 lbi = ip4_fib_forwarding_lookup(fib_index, &pfx_10_10_10_2_s_32.fp_addr.ip4);
5575 FIB_TEST(lbi == dpo->dpoi_index,
5576 "10.10.10.2 forwards on %U", format_dpo_id, dpo, 0);
5577 lbi = ip4_fib_forwarding_lookup(fib_index, &pfx_10_10_10_3_s_32.fp_addr.ip4);
5578 FIB_TEST(lbi == dpo->dpoi_index,
5579 "10.10.10.3 forwards on %U", format_dpo_id, dpo, 0);
5580
5581 /*
5582 * add the export prefix back, but not as attached.
5583 * No adj-fibs in export nor import tables
5584 */
5585 local_pfx.fp_len = 24;
5586 fei = fib_table_entry_update_one_path(fib_index,
5587 &local_pfx,
5588 FIB_SOURCE_API,
5589 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07005590 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005591 &pfx_10_10_10_1_s_32.fp_addr,
5592 tm->hw[0]->sw_if_index,
5593 ~0, // invalid fib index
5594 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005595 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005596 FIB_ROUTE_PATH_FLAG_NONE);
5597 dpo = fib_entry_contribute_ip_forwarding(fei);
5598
5599 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
5600 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "non-attached in export: ADJ-fib1 in export");
5601 lbi = ip4_fib_forwarding_lookup(fib_index, &pfx_10_10_10_1_s_32.fp_addr.ip4);
5602 FIB_TEST(lbi == dpo->dpoi_index,
5603 "10.10.10.1 forwards on %U", format_dpo_id, dpo, 0);
5604 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
5605 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 in export");
5606 lbi = ip4_fib_forwarding_lookup(fib_index, &pfx_10_10_10_2_s_32.fp_addr.ip4);
5607 FIB_TEST(lbi == dpo->dpoi_index,
5608 "10.10.10.2 forwards on %U", format_dpo_id, dpo, 0);
5609
5610 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5611 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib1 removed from FIB1");
5612 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5613 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib2 removed from FIB1");
5614 local_pfx.fp_len = 32;
5615 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5616 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "local removed from FIB1");
5617
5618 /*
5619 * modify the export prefix so it is attached. expect all covereds to return
5620 */
5621 local_pfx.fp_len = 24;
5622 fib_table_entry_update_one_path(fib_index,
5623 &local_pfx,
5624 FIB_SOURCE_API,
5625 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07005626 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005627 NULL,
5628 tm->hw[0]->sw_if_index,
5629 ~0, // invalid fib index
5630 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005631 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005632 FIB_ROUTE_PATH_FLAG_NONE);
5633
5634 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
5635 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 reinstalled in export");
5636 dpo = fib_entry_contribute_ip_forwarding(fei);
5637 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
5638 "Adj-fib1 is not drop in export");
5639 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_2_s_32);
5640 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 reinstalled in export");
5641 local_pfx.fp_len = 32;
5642 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5643 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local reinstalled in export");
5644 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5645 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached in export: ADJ-fib1 imported");
5646 dpo = fib_entry_contribute_ip_forwarding(fei);
5647 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
5648 "Adj-fib1 is not drop in export");
5649 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5650 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 imported");
5651 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5652 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 imported");
5653 local_pfx.fp_len = 32;
5654 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5655 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local imported");
5656
5657 /*
5658 * modify the export prefix so connected. no change.
5659 */
5660 local_pfx.fp_len = 24;
5661 fib_table_entry_update_one_path(fib_index, &local_pfx,
5662 FIB_SOURCE_INTERFACE,
5663 (FIB_ENTRY_FLAG_CONNECTED |
5664 FIB_ENTRY_FLAG_ATTACHED),
Neale Rannsda78f952017-05-24 09:15:43 -07005665 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005666 NULL,
5667 tm->hw[0]->sw_if_index,
5668 ~0,
5669 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005670 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005671 FIB_ROUTE_PATH_FLAG_NONE);
5672
5673 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
5674 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 reinstalled in export");
5675 dpo = fib_entry_contribute_ip_forwarding(fei);
5676 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
5677 "Adj-fib1 is not drop in export");
5678 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_2_s_32);
5679 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 reinstalled in export");
5680 local_pfx.fp_len = 32;
5681 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5682 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local reinstalled in export");
5683 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5684 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached in export: ADJ-fib1 imported");
5685 dpo = fib_entry_contribute_ip_forwarding(fei);
5686 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
5687 "Adj-fib1 is not drop in export");
5688 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5689 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 imported");
5690 local_pfx.fp_len = 32;
5691 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5692 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local imported");
5693
5694 /*
5695 * CLEANUP
5696 */
5697 fib_table_entry_delete(fib_index,
5698 &pfx_10_0_0_0_s_8,
5699 FIB_SOURCE_API);
5700 fib_table_entry_delete(fib_index,
5701 &pfx_10_10_10_1_s_32,
5702 FIB_SOURCE_ADJ);
5703 fib_table_entry_delete(fib_index,
5704 &pfx_10_10_10_2_s_32,
5705 FIB_SOURCE_ADJ);
5706 local_pfx.fp_len = 32;
5707 fib_table_entry_delete(fib_index,
5708 &local_pfx,
5709 FIB_SOURCE_INTERFACE);
5710 local_pfx.fp_len = 24;
5711 fib_table_entry_delete(fib_index,
5712 &local_pfx,
5713 FIB_SOURCE_API);
5714 fib_table_entry_delete(fib_index,
5715 &local_pfx,
5716 FIB_SOURCE_INTERFACE);
5717 local_pfx.fp_len = 24;
5718 fib_table_entry_delete(import_fib_index1,
5719 &local_pfx,
5720 FIB_SOURCE_API);
5721
Neale Ranns15002542017-09-10 04:39:11 -07005722 fib_table_unlock(import_fib_index1, FIB_PROTOCOL_IP4, FIB_SOURCE_CLI);
5723 fib_table_unlock(import_fib_index2, FIB_PROTOCOL_IP4, FIB_SOURCE_CLI);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005724
5725 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
5726 adj_nbr_db_size());
Neale Ranns0ebe8d72016-12-08 19:48:11 +00005727
5728 return (0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005729}
5730
Neale Ranns57b58602017-07-15 07:37:25 -07005731/*
5732 * Test Path Preference
5733 */
5734static int
5735fib_test_pref (void)
5736{
5737 test_main_t *tm = &test_main;
5738
5739 const fib_prefix_t pfx_1_1_1_1_s_32 = {
5740 .fp_len = 32,
5741 .fp_proto = FIB_PROTOCOL_IP4,
5742 .fp_addr = {
5743 .ip4 = {
5744 .as_u32 = clib_host_to_net_u32(0x01010101),
5745 },
5746 },
5747 };
5748
5749 /*
5750 * 2 high, 2 medium and 2 low preference non-recursive paths
5751 */
5752 fib_route_path_t nr_path_hi_1 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005753 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005754 .frp_sw_if_index = tm->hw[0]->sw_if_index,
5755 .frp_fib_index = ~0,
5756 .frp_weight = 1,
5757 .frp_preference = 0,
5758 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5759 .frp_addr = {
5760 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
5761 },
5762 };
5763 fib_route_path_t nr_path_hi_2 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005764 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005765 .frp_sw_if_index = tm->hw[0]->sw_if_index,
5766 .frp_fib_index = ~0,
5767 .frp_weight = 1,
5768 .frp_preference = 0,
5769 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5770 .frp_addr = {
5771 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02),
5772 },
5773 };
5774 fib_route_path_t nr_path_med_1 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005775 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005776 .frp_sw_if_index = tm->hw[1]->sw_if_index,
5777 .frp_fib_index = ~0,
5778 .frp_weight = 1,
5779 .frp_preference = 1,
5780 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5781 .frp_addr = {
5782 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0c01),
5783 },
5784 };
5785 fib_route_path_t nr_path_med_2 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005786 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005787 .frp_sw_if_index = tm->hw[1]->sw_if_index,
5788 .frp_fib_index = ~0,
5789 .frp_weight = 1,
5790 .frp_preference = 1,
5791 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5792 .frp_addr = {
5793 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0c01),
5794 },
5795 };
5796 fib_route_path_t nr_path_low_1 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005797 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005798 .frp_sw_if_index = tm->hw[2]->sw_if_index,
5799 .frp_fib_index = ~0,
5800 .frp_weight = 1,
5801 .frp_preference = 2,
5802 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5803 .frp_addr = {
5804 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0b01),
5805 },
5806 };
5807 fib_route_path_t nr_path_low_2 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005808 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005809 .frp_sw_if_index = tm->hw[2]->sw_if_index,
5810 .frp_fib_index = ~0,
5811 .frp_weight = 1,
5812 .frp_preference = 2,
5813 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5814 .frp_addr = {
5815 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0b02),
5816 },
5817 };
5818 fib_route_path_t *nr_paths = NULL;
5819
5820 vec_add1(nr_paths, nr_path_hi_1);
5821 vec_add1(nr_paths, nr_path_hi_2);
5822 vec_add1(nr_paths, nr_path_med_1);
5823 vec_add1(nr_paths, nr_path_med_2);
5824 vec_add1(nr_paths, nr_path_low_1);
5825 vec_add1(nr_paths, nr_path_low_2);
5826
5827 adj_index_t ai_hi_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5828 VNET_LINK_IP4,
5829 &nr_path_hi_1.frp_addr,
5830 nr_path_hi_1.frp_sw_if_index);
5831 adj_index_t ai_hi_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5832 VNET_LINK_IP4,
5833 &nr_path_hi_2.frp_addr,
5834 nr_path_hi_2.frp_sw_if_index);
5835 adj_index_t ai_med_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5836 VNET_LINK_IP4,
5837 &nr_path_med_1.frp_addr,
5838 nr_path_med_1.frp_sw_if_index);
5839 adj_index_t ai_med_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5840 VNET_LINK_IP4,
5841 &nr_path_med_2.frp_addr,
5842 nr_path_med_2.frp_sw_if_index);
5843 adj_index_t ai_low_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5844 VNET_LINK_IP4,
5845 &nr_path_low_1.frp_addr,
5846 nr_path_low_1.frp_sw_if_index);
5847 adj_index_t ai_low_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5848 VNET_LINK_IP4,
5849 &nr_path_low_2.frp_addr,
5850 nr_path_low_2.frp_sw_if_index);
5851
5852 fib_test_lb_bucket_t ip_hi_1 = {
5853 .type = FT_LB_ADJ,
5854 .adj = {
5855 .adj = ai_hi_1,
5856 },
5857 };
5858 fib_test_lb_bucket_t ip_hi_2 = {
5859 .type = FT_LB_ADJ,
5860 .adj = {
5861 .adj = ai_hi_2,
5862 },
5863 };
5864 fib_test_lb_bucket_t ip_med_1 = {
5865 .type = FT_LB_ADJ,
5866 .adj = {
5867 .adj = ai_med_1,
5868 },
5869 };
5870 fib_test_lb_bucket_t ip_med_2 = {
5871 .type = FT_LB_ADJ,
5872 .adj = {
5873 .adj = ai_med_2,
5874 },
5875 };
5876 fib_test_lb_bucket_t ip_low_1 = {
5877 .type = FT_LB_ADJ,
5878 .adj = {
5879 .adj = ai_low_1,
5880 },
5881 };
5882 fib_test_lb_bucket_t ip_low_2 = {
5883 .type = FT_LB_ADJ,
5884 .adj = {
5885 .adj = ai_low_2,
5886 },
5887 };
5888
5889 fib_node_index_t fei;
5890
5891 fei = fib_table_entry_path_add2(0,
5892 &pfx_1_1_1_1_s_32,
5893 FIB_SOURCE_API,
5894 FIB_ENTRY_FLAG_NONE,
5895 nr_paths);
5896
5897 FIB_TEST(fib_test_validate_entry(fei,
5898 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5899 2,
5900 &ip_hi_1,
5901 &ip_hi_2),
5902 "1.1.1.1/32 via high preference paths");
5903
5904 /*
5905 * bring down the interface on which the high preference path lie
5906 */
5907 vnet_sw_interface_set_flags(vnet_get_main(),
5908 tm->hw[0]->sw_if_index,
5909 0);
5910
5911 FIB_TEST(fib_test_validate_entry(fei,
5912 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5913 2,
5914 &ip_med_1,
5915 &ip_med_2),
5916 "1.1.1.1/32 via medium preference paths");
5917
5918 /*
5919 * bring down the interface on which the medium preference path lie
5920 */
5921 vnet_sw_interface_set_flags(vnet_get_main(),
5922 tm->hw[1]->sw_if_index,
5923 0);
5924
5925 FIB_TEST(fib_test_validate_entry(fei,
5926 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5927 2,
5928 &ip_low_1,
5929 &ip_low_2),
5930 "1.1.1.1/32 via low preference paths");
5931
5932 /*
5933 * bring up the interface on which the high preference path lie
5934 */
5935 vnet_sw_interface_set_flags(vnet_get_main(),
5936 tm->hw[0]->sw_if_index,
5937 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
5938
5939 FIB_TEST(fib_test_validate_entry(fei,
5940 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5941 2,
5942 &ip_hi_1,
5943 &ip_hi_2),
5944 "1.1.1.1/32 via high preference paths");
5945
5946 /*
5947 * bring up the interface on which the medium preference path lie
5948 */
5949 vnet_sw_interface_set_flags(vnet_get_main(),
5950 tm->hw[1]->sw_if_index,
5951 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
5952
5953 FIB_TEST(fib_test_validate_entry(fei,
5954 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5955 2,
5956 &ip_hi_1,
5957 &ip_hi_2),
5958 "1.1.1.1/32 via high preference paths");
5959
5960 dpo_id_t ip_1_1_1_1 = DPO_INVALID;
5961 fib_entry_contribute_forwarding(fei,
5962 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5963 &ip_1_1_1_1);
5964
5965 /*
5966 * 3 recursive paths of different preference
5967 */
5968 const fib_prefix_t pfx_1_1_1_2_s_32 = {
5969 .fp_len = 32,
5970 .fp_proto = FIB_PROTOCOL_IP4,
5971 .fp_addr = {
5972 .ip4 = {
5973 .as_u32 = clib_host_to_net_u32(0x01010102),
5974 },
5975 },
5976 };
5977 const fib_prefix_t pfx_1_1_1_3_s_32 = {
5978 .fp_len = 32,
5979 .fp_proto = FIB_PROTOCOL_IP4,
5980 .fp_addr = {
5981 .ip4 = {
5982 .as_u32 = clib_host_to_net_u32(0x01010103),
5983 },
5984 },
5985 };
5986 fei = fib_table_entry_path_add2(0,
5987 &pfx_1_1_1_2_s_32,
5988 FIB_SOURCE_API,
5989 FIB_ENTRY_FLAG_NONE,
5990 nr_paths);
5991 dpo_id_t ip_1_1_1_2 = DPO_INVALID;
5992 fib_entry_contribute_forwarding(fei,
5993 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5994 &ip_1_1_1_2);
5995 fei = fib_table_entry_path_add2(0,
5996 &pfx_1_1_1_3_s_32,
5997 FIB_SOURCE_API,
5998 FIB_ENTRY_FLAG_NONE,
5999 nr_paths);
6000 dpo_id_t ip_1_1_1_3 = DPO_INVALID;
6001 fib_entry_contribute_forwarding(fei,
6002 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6003 &ip_1_1_1_3);
6004
6005 fib_test_lb_bucket_t ip_o_1_1_1_1 = {
6006 .type = FT_LB_O_LB,
6007 .lb = {
6008 .lb = ip_1_1_1_1.dpoi_index,
6009 },
6010 };
6011 fib_test_lb_bucket_t ip_o_1_1_1_2 = {
6012 .type = FT_LB_O_LB,
6013 .lb = {
6014 .lb = ip_1_1_1_2.dpoi_index,
6015 },
6016 };
6017 fib_test_lb_bucket_t ip_o_1_1_1_3 = {
6018 .type = FT_LB_O_LB,
6019 .lb = {
6020 .lb = ip_1_1_1_3.dpoi_index,
6021 },
6022 };
6023 fib_route_path_t r_path_hi = {
Neale Rannsda78f952017-05-24 09:15:43 -07006024 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07006025 .frp_sw_if_index = ~0,
6026 .frp_fib_index = 0,
6027 .frp_weight = 1,
6028 .frp_preference = 0,
6029 .frp_flags = FIB_ROUTE_PATH_RESOLVE_VIA_HOST,
6030 .frp_addr = pfx_1_1_1_1_s_32.fp_addr,
6031 };
6032 fib_route_path_t r_path_med = {
Neale Rannsda78f952017-05-24 09:15:43 -07006033 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07006034 .frp_sw_if_index = ~0,
6035 .frp_fib_index = 0,
6036 .frp_weight = 1,
6037 .frp_preference = 10,
6038 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
6039 .frp_addr = pfx_1_1_1_2_s_32.fp_addr,
6040 };
6041 fib_route_path_t r_path_low = {
Neale Rannsda78f952017-05-24 09:15:43 -07006042 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07006043 .frp_sw_if_index = ~0,
6044 .frp_fib_index = 0,
6045 .frp_weight = 1,
Neale Rannsa0a908f2017-08-01 11:40:03 -07006046 .frp_preference = 255,
Neale Ranns57b58602017-07-15 07:37:25 -07006047 .frp_flags = FIB_ROUTE_PATH_RESOLVE_VIA_HOST,
6048 .frp_addr = pfx_1_1_1_3_s_32.fp_addr,
6049 };
6050 fib_route_path_t *r_paths = NULL;
6051
6052 vec_add1(r_paths, r_path_hi);
6053 vec_add1(r_paths, r_path_low);
6054 vec_add1(r_paths, r_path_med);
6055
6056 /*
6057 * add many recursive so we get the LB MAp created
6058 */
6059 #define N_PFXS 64
6060 fib_prefix_t pfx_r[N_PFXS];
Marek Gradzkiaf095512017-08-15 07:38:26 +02006061 unsigned int n_pfxs;
Neale Ranns57b58602017-07-15 07:37:25 -07006062 for (n_pfxs = 0; n_pfxs < N_PFXS; n_pfxs++)
6063 {
6064 pfx_r[n_pfxs].fp_len = 32;
6065 pfx_r[n_pfxs].fp_proto = FIB_PROTOCOL_IP4;
6066 pfx_r[n_pfxs].fp_addr.ip4.as_u32 =
6067 clib_host_to_net_u32(0x02000000 + n_pfxs);
6068
6069 fei = fib_table_entry_path_add2(0,
6070 &pfx_r[n_pfxs],
6071 FIB_SOURCE_API,
6072 FIB_ENTRY_FLAG_NONE,
6073 r_paths);
6074
6075 FIB_TEST(fib_test_validate_entry(fei,
6076 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6077 1,
6078 &ip_o_1_1_1_1),
6079 "recursive via high preference paths");
6080
6081 /*
6082 * withdraw hig pref resolving entry
6083 */
6084 fib_table_entry_delete(0,
6085 &pfx_1_1_1_1_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_2),
6095 "recursive via medium preference paths");
6096
6097 /*
6098 * withdraw medium pref resolving entry
6099 */
6100 fib_table_entry_delete(0,
6101 &pfx_1_1_1_2_s_32,
6102 FIB_SOURCE_API);
6103
6104 /* suspend so the update walk kicks int */
6105 vlib_process_suspend(vlib_get_main(), 1e-5);
6106
6107 FIB_TEST(fib_test_validate_entry(fei,
6108 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6109 1,
6110 &ip_o_1_1_1_3),
6111 "recursive via low preference paths");
6112
6113 /*
6114 * add back paths for next iteration
6115 */
6116 fei = fib_table_entry_update(0,
6117 &pfx_1_1_1_2_s_32,
6118 FIB_SOURCE_API,
6119 FIB_ENTRY_FLAG_NONE,
6120 nr_paths);
6121 fei = fib_table_entry_update(0,
6122 &pfx_1_1_1_1_s_32,
6123 FIB_SOURCE_API,
6124 FIB_ENTRY_FLAG_NONE,
6125 nr_paths);
6126
6127 /* suspend so the update walk kicks int */
6128 vlib_process_suspend(vlib_get_main(), 1e-5);
6129
6130 fei = fib_table_lookup_exact_match(0, &pfx_r[n_pfxs]);
6131 FIB_TEST(fib_test_validate_entry(fei,
6132 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6133 1,
6134 &ip_o_1_1_1_1),
6135 "recursive via high preference paths");
6136 }
6137
6138
6139 fib_table_entry_delete(0,
6140 &pfx_1_1_1_1_s_32,
6141 FIB_SOURCE_API);
6142
6143 /* suspend so the update walk kicks int */
6144 vlib_process_suspend(vlib_get_main(), 1e-5);
6145
6146 for (n_pfxs = 0; n_pfxs < N_PFXS; n_pfxs++)
6147 {
6148 fei = fib_table_lookup_exact_match(0, &pfx_r[n_pfxs]);
6149
6150 FIB_TEST(fib_test_validate_entry(fei,
6151 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6152 1,
6153 &ip_o_1_1_1_2),
6154 "recursive via medium preference paths");
6155 }
6156 for (n_pfxs = 0; n_pfxs < N_PFXS; n_pfxs++)
6157 {
6158 fib_table_entry_delete(0,
6159 &pfx_r[n_pfxs],
6160 FIB_SOURCE_API);
6161 }
6162
6163 /*
6164 * Cleanup
6165 */
6166 fib_table_entry_delete(0,
6167 &pfx_1_1_1_2_s_32,
6168 FIB_SOURCE_API);
6169 fib_table_entry_delete(0,
6170 &pfx_1_1_1_3_s_32,
6171 FIB_SOURCE_API);
6172
6173 dpo_reset(&ip_1_1_1_1);
6174 dpo_reset(&ip_1_1_1_2);
6175 dpo_reset(&ip_1_1_1_3);
6176 adj_unlock(ai_low_2);
6177 adj_unlock(ai_low_1);
6178 adj_unlock(ai_med_2);
6179 adj_unlock(ai_med_1);
6180 adj_unlock(ai_hi_2);
6181 adj_unlock(ai_hi_1);
6182 return (0);
6183}
Neale Rannsad422ed2016-11-02 14:20:04 +00006184
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006185/*
6186 * Test the recursive route route handling for GRE tunnels
6187 */
Neale Ranns0ebe8d72016-12-08 19:48:11 +00006188static int
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006189fib_test_label (void)
6190{
6191 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;
6192 const u32 fib_index = 0;
6193 test_main_t *tm;
6194 ip4_main_t *im;
Neale Rannsad422ed2016-11-02 14:20:04 +00006195 int lb_count, ii;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006196
6197 lb_count = pool_elts(load_balance_pool);
6198 tm = &test_main;
6199 im = &ip4_main;
6200
6201 /*
6202 * add interface routes. We'll assume this works. It's more rigorously
6203 * tested elsewhere.
6204 */
6205 fib_prefix_t local0_pfx = {
6206 .fp_len = 24,
6207 .fp_proto = FIB_PROTOCOL_IP4,
6208 .fp_addr = {
6209 .ip4 = {
6210 /* 10.10.10.10 */
6211 .as_u32 = clib_host_to_net_u32(0x0a0a0a0a),
6212 },
6213 },
6214 };
6215
6216 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
6217 adj_nbr_db_size());
6218
6219 vec_validate(im->fib_index_by_sw_if_index, tm->hw[0]->sw_if_index);
6220 im->fib_index_by_sw_if_index[tm->hw[0]->sw_if_index] = fib_index;
6221
6222 fib_table_entry_update_one_path(fib_index, &local0_pfx,
6223 FIB_SOURCE_INTERFACE,
6224 (FIB_ENTRY_FLAG_CONNECTED |
6225 FIB_ENTRY_FLAG_ATTACHED),
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,
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 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
6235 "attached interface route present");
6236
6237 local0_pfx.fp_len = 32;
6238 fib_table_entry_update_one_path(fib_index, &local0_pfx,
6239 FIB_SOURCE_INTERFACE,
6240 (FIB_ENTRY_FLAG_CONNECTED |
6241 FIB_ENTRY_FLAG_LOCAL),
Neale Rannsda78f952017-05-24 09:15:43 -07006242 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006243 NULL,
6244 tm->hw[0]->sw_if_index,
6245 ~0, // invalid fib index
6246 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006247 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006248 FIB_ROUTE_PATH_FLAG_NONE);
6249 fei = fib_table_lookup_exact_match(fib_index, &local0_pfx);
6250
6251 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
6252 "local interface route present");
6253
6254 fib_prefix_t local1_pfx = {
6255 .fp_len = 24,
6256 .fp_proto = FIB_PROTOCOL_IP4,
6257 .fp_addr = {
6258 .ip4 = {
6259 /* 10.10.11.10 */
6260 .as_u32 = clib_host_to_net_u32(0x0a0a0b0a),
6261 },
6262 },
6263 };
6264
6265 vec_validate(im->fib_index_by_sw_if_index, tm->hw[1]->sw_if_index);
6266 im->fib_index_by_sw_if_index[tm->hw[1]->sw_if_index] = fib_index;
6267
6268 fib_table_entry_update_one_path(fib_index, &local1_pfx,
6269 FIB_SOURCE_INTERFACE,
6270 (FIB_ENTRY_FLAG_CONNECTED |
6271 FIB_ENTRY_FLAG_ATTACHED),
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,
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 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
6281 "attached interface route present");
6282
6283 local1_pfx.fp_len = 32;
6284 fib_table_entry_update_one_path(fib_index, &local1_pfx,
6285 FIB_SOURCE_INTERFACE,
6286 (FIB_ENTRY_FLAG_CONNECTED |
6287 FIB_ENTRY_FLAG_LOCAL),
Neale Rannsda78f952017-05-24 09:15:43 -07006288 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006289 NULL,
6290 tm->hw[1]->sw_if_index,
6291 ~0, // invalid fib index
6292 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006293 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006294 FIB_ROUTE_PATH_FLAG_NONE);
6295 fei = fib_table_lookup_exact_match(fib_index, &local1_pfx);
6296
6297 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
6298 "local interface route present");
6299
6300 ip46_address_t nh_10_10_10_1 = {
6301 .ip4 = {
6302 .as_u32 = clib_host_to_net_u32(0x0a0a0a01),
6303 },
6304 };
6305 ip46_address_t nh_10_10_11_1 = {
6306 .ip4 = {
6307 .as_u32 = clib_host_to_net_u32(0x0a0a0b01),
6308 },
6309 };
6310 ip46_address_t nh_10_10_11_2 = {
6311 .ip4 = {
6312 .as_u32 = clib_host_to_net_u32(0x0a0a0b02),
6313 },
6314 };
6315
6316 ai_v4_10_10_11_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01006317 VNET_LINK_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006318 &nh_10_10_11_1,
6319 tm->hw[1]->sw_if_index);
6320 ai_v4_10_10_11_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01006321 VNET_LINK_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006322 &nh_10_10_11_2,
6323 tm->hw[1]->sw_if_index);
6324 ai_mpls_10_10_10_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01006325 VNET_LINK_MPLS,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006326 &nh_10_10_10_1,
6327 tm->hw[0]->sw_if_index);
6328 ai_mpls_10_10_11_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01006329 VNET_LINK_MPLS,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006330 &nh_10_10_11_2,
6331 tm->hw[1]->sw_if_index);
6332 ai_mpls_10_10_11_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01006333 VNET_LINK_MPLS,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006334 &nh_10_10_11_1,
6335 tm->hw[1]->sw_if_index);
6336
6337 /*
6338 * Add an etry with one path with a real out-going label
6339 */
6340 fib_prefix_t pfx_1_1_1_1_s_32 = {
6341 .fp_len = 32,
6342 .fp_proto = FIB_PROTOCOL_IP4,
6343 .fp_addr = {
6344 .ip4.as_u32 = clib_host_to_net_u32(0x01010101),
6345 },
6346 };
6347 fib_test_lb_bucket_t l99_eos_o_10_10_10_1 = {
6348 .type = FT_LB_LABEL_O_ADJ,
6349 .label_o_adj = {
6350 .adj = ai_mpls_10_10_10_1,
6351 .label = 99,
6352 .eos = MPLS_EOS,
6353 },
6354 };
6355 fib_test_lb_bucket_t l99_neos_o_10_10_10_1 = {
6356 .type = FT_LB_LABEL_O_ADJ,
6357 .label_o_adj = {
6358 .adj = ai_mpls_10_10_10_1,
6359 .label = 99,
6360 .eos = MPLS_NON_EOS,
6361 },
6362 };
Neale Ranns31ed7442018-02-23 05:29:09 -08006363 fib_mpls_label_t *l99 = NULL, fml99 = {
6364 .fml_value = 99,
6365 };
6366 vec_add1(l99, fml99);
Neale Rannsad422ed2016-11-02 14:20:04 +00006367
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006368 fib_table_entry_update_one_path(fib_index,
6369 &pfx_1_1_1_1_s_32,
6370 FIB_SOURCE_API,
6371 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07006372 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006373 &nh_10_10_10_1,
6374 tm->hw[0]->sw_if_index,
6375 ~0, // invalid fib index
6376 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006377 l99,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006378 FIB_ROUTE_PATH_FLAG_NONE);
6379
6380 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
6381 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "1.1.1.1/32 created");
6382
6383 FIB_TEST(fib_test_validate_entry(fei,
6384 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6385 1,
6386 &l99_eos_o_10_10_10_1),
6387 "1.1.1.1/32 LB 1 bucket via label 99 over 10.10.10.1");
6388
6389 /*
6390 * add a path with an implicit NULL label
6391 */
6392 fib_test_lb_bucket_t a_o_10_10_11_1 = {
6393 .type = FT_LB_ADJ,
6394 .adj = {
6395 .adj = ai_v4_10_10_11_1,
6396 },
6397 };
6398 fib_test_lb_bucket_t a_mpls_o_10_10_11_1 = {
6399 .type = FT_LB_ADJ,
6400 .adj = {
6401 .adj = ai_mpls_10_10_11_1,
6402 },
6403 };
Neale Ranns31ed7442018-02-23 05:29:09 -08006404 fib_mpls_label_t *l_imp_null = NULL, fml_imp_null = {
6405 .fml_value = MPLS_IETF_IMPLICIT_NULL_LABEL,
6406 };
6407 vec_add1(l_imp_null, fml_imp_null);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006408
6409 fei = fib_table_entry_path_add(fib_index,
6410 &pfx_1_1_1_1_s_32,
6411 FIB_SOURCE_API,
6412 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07006413 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006414 &nh_10_10_11_1,
6415 tm->hw[1]->sw_if_index,
6416 ~0, // invalid fib index
6417 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006418 l_imp_null,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006419 FIB_ROUTE_PATH_FLAG_NONE);
6420
6421 FIB_TEST(fib_test_validate_entry(fei,
6422 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6423 2,
6424 &l99_eos_o_10_10_10_1,
6425 &a_o_10_10_11_1),
6426 "1.1.1.1/32 LB 2 buckets via: "
6427 "label 99 over 10.10.10.1, "
6428 "adj over 10.10.11.1");
6429
6430 /*
6431 * assign the route a local label
6432 */
6433 fib_table_entry_local_label_add(fib_index,
6434 &pfx_1_1_1_1_s_32,
6435 24001);
6436
6437 fib_prefix_t pfx_24001_eos = {
6438 .fp_proto = FIB_PROTOCOL_MPLS,
6439 .fp_label = 24001,
6440 .fp_eos = MPLS_EOS,
6441 };
6442 fib_prefix_t pfx_24001_neos = {
6443 .fp_proto = FIB_PROTOCOL_MPLS,
6444 .fp_label = 24001,
6445 .fp_eos = MPLS_NON_EOS,
6446 };
Neale Ranns62fe07c2017-10-31 12:28:22 -07006447 fib_test_lb_bucket_t disp_o_10_10_11_1 = {
Neale Ranns31ed7442018-02-23 05:29:09 -08006448 .type = FT_LB_MPLS_DISP_PIPE_O_ADJ,
Neale Ranns62fe07c2017-10-31 12:28:22 -07006449 .adj = {
6450 .adj = ai_v4_10_10_11_1,
6451 },
6452 };
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006453
6454 /*
6455 * The EOS entry should link to both the paths,
6456 * and use an ip adj for the imp-null
6457 * The NON-EOS entry should link to both the paths,
6458 * and use an mpls adj for the imp-null
6459 */
6460 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6461 &pfx_24001_eos);
6462 FIB_TEST(fib_test_validate_entry(fei,
6463 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6464 2,
6465 &l99_eos_o_10_10_10_1,
Neale Ranns62fe07c2017-10-31 12:28:22 -07006466 &disp_o_10_10_11_1),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006467 "24001/eos LB 2 buckets via: "
6468 "label 99 over 10.10.10.1, "
Neale Ranns62fe07c2017-10-31 12:28:22 -07006469 "mpls disp adj over 10.10.11.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006470
6471
6472 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6473 &pfx_24001_neos);
6474 FIB_TEST(fib_test_validate_entry(fei,
6475 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6476 2,
6477 &l99_neos_o_10_10_10_1,
6478 &a_mpls_o_10_10_11_1),
6479 "24001/neos LB 1 bucket via: "
6480 "label 99 over 10.10.10.1 ",
6481 "mpls-adj via 10.10.11.1");
6482
6483 /*
6484 * add an unlabelled path, this is excluded from the neos chains,
6485 */
6486 fib_test_lb_bucket_t adj_o_10_10_11_2 = {
6487 .type = FT_LB_ADJ,
6488 .adj = {
6489 .adj = ai_v4_10_10_11_2,
6490 },
6491 };
Neale Ranns62fe07c2017-10-31 12:28:22 -07006492 fib_test_lb_bucket_t disp_o_10_10_11_2 = {
Neale Ranns31ed7442018-02-23 05:29:09 -08006493 .type = FT_LB_MPLS_DISP_PIPE_O_ADJ,
Neale Ranns62fe07c2017-10-31 12:28:22 -07006494 .adj = {
6495 .adj = ai_v4_10_10_11_2,
6496 },
6497 };
6498
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006499
6500 fei = fib_table_entry_path_add(fib_index,
6501 &pfx_1_1_1_1_s_32,
6502 FIB_SOURCE_API,
6503 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07006504 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006505 &nh_10_10_11_2,
6506 tm->hw[1]->sw_if_index,
6507 ~0, // invalid fib index
6508 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006509 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006510 FIB_ROUTE_PATH_FLAG_NONE);
6511
6512 FIB_TEST(fib_test_validate_entry(fei,
6513 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6514 16, // 3 choices spread over 16 buckets
6515 &l99_eos_o_10_10_10_1,
6516 &l99_eos_o_10_10_10_1,
6517 &l99_eos_o_10_10_10_1,
6518 &l99_eos_o_10_10_10_1,
6519 &l99_eos_o_10_10_10_1,
6520 &l99_eos_o_10_10_10_1,
6521 &a_o_10_10_11_1,
6522 &a_o_10_10_11_1,
6523 &a_o_10_10_11_1,
6524 &a_o_10_10_11_1,
6525 &a_o_10_10_11_1,
6526 &adj_o_10_10_11_2,
6527 &adj_o_10_10_11_2,
6528 &adj_o_10_10_11_2,
6529 &adj_o_10_10_11_2,
6530 &adj_o_10_10_11_2),
6531 "1.1.1.1/32 LB 16 buckets via: "
6532 "label 99 over 10.10.10.1, "
6533 "adj over 10.10.11.1",
6534 "adj over 10.10.11.2");
6535
6536 /*
6537 * get and lock a reference to the non-eos of the via entry 1.1.1.1/32
6538 */
Neale Ranns948e00f2016-10-20 13:39:34 +01006539 dpo_id_t non_eos_1_1_1_1 = DPO_INVALID;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006540 fib_entry_contribute_forwarding(fei,
6541 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6542 &non_eos_1_1_1_1);
6543
6544 /*
6545 * n-eos has only the 2 labelled paths
6546 */
6547 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6548 &pfx_24001_neos);
6549
6550 FIB_TEST(fib_test_validate_entry(fei,
6551 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6552 2,
6553 &l99_neos_o_10_10_10_1,
6554 &a_mpls_o_10_10_11_1),
6555 "24001/neos LB 2 buckets via: "
6556 "label 99 over 10.10.10.1, "
6557 "adj-mpls over 10.10.11.2");
6558
6559 /*
6560 * A labelled recursive
6561 */
6562 fib_prefix_t pfx_2_2_2_2_s_32 = {
6563 .fp_len = 32,
6564 .fp_proto = FIB_PROTOCOL_IP4,
6565 .fp_addr = {
6566 .ip4.as_u32 = clib_host_to_net_u32(0x02020202),
6567 },
6568 };
6569 fib_test_lb_bucket_t l1600_eos_o_1_1_1_1 = {
6570 .type = FT_LB_LABEL_O_LB,
6571 .label_o_lb = {
6572 .lb = non_eos_1_1_1_1.dpoi_index,
6573 .label = 1600,
6574 .eos = MPLS_EOS,
Neale Ranns31ed7442018-02-23 05:29:09 -08006575 .mode = FIB_MPLS_LSP_MODE_UNIFORM,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006576 },
6577 };
Neale Ranns31ed7442018-02-23 05:29:09 -08006578 fib_mpls_label_t *l1600 = NULL, fml1600 = {
6579 .fml_value = 1600,
6580 .fml_mode = FIB_MPLS_LSP_MODE_UNIFORM,
6581 };
6582 vec_add1(l1600, fml1600);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006583
Neale Ranns31ed7442018-02-23 05:29:09 -08006584 fei = fib_table_entry_update_one_path(fib_index,
6585 &pfx_2_2_2_2_s_32,
6586 FIB_SOURCE_API,
6587 FIB_ENTRY_FLAG_NONE,
6588 DPO_PROTO_IP4,
6589 &pfx_1_1_1_1_s_32.fp_addr,
6590 ~0,
6591 fib_index,
6592 1,
6593 l1600,
6594 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006595
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006596 FIB_TEST(fib_test_validate_entry(fei,
6597 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6598 1,
6599 &l1600_eos_o_1_1_1_1),
6600 "2.2.2.2.2/32 LB 1 buckets via: "
6601 "label 1600 over 1.1.1.1");
6602
Neale Ranns948e00f2016-10-20 13:39:34 +01006603 dpo_id_t dpo_44 = DPO_INVALID;
Neale Ranns3ee44042016-10-03 13:05:48 +01006604 index_t urpfi;
6605
6606 fib_entry_contribute_forwarding(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, &dpo_44);
6607 urpfi = load_balance_get_urpf(dpo_44.dpoi_index);
6608
6609 FIB_TEST(fib_urpf_check(urpfi, tm->hw[0]->sw_if_index),
6610 "uRPF check for 2.2.2.2/32 on %d OK",
6611 tm->hw[0]->sw_if_index);
6612 FIB_TEST(fib_urpf_check(urpfi, tm->hw[1]->sw_if_index),
6613 "uRPF check for 2.2.2.2/32 on %d OK",
6614 tm->hw[1]->sw_if_index);
6615 FIB_TEST(!fib_urpf_check(urpfi, 99),
6616 "uRPF check for 2.2.2.2/32 on 99 not-OK",
6617 99);
6618
6619 fib_entry_contribute_forwarding(fei, FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS, &dpo_44);
6620 FIB_TEST(urpfi == load_balance_get_urpf(dpo_44.dpoi_index),
6621 "Shared uRPF on IP and non-EOS chain");
6622
6623 dpo_reset(&dpo_44);
6624
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006625 /*
6626 * we are holding a lock on the non-eos LB of the via-entry.
6627 * do a PIC-core failover by shutting the link of the via-entry.
6628 *
6629 * shut down the link with the valid label
6630 */
6631 vnet_sw_interface_set_flags(vnet_get_main(),
6632 tm->hw[0]->sw_if_index,
6633 0);
6634
6635 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
6636 FIB_TEST(fib_test_validate_entry(fei,
6637 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6638 2,
6639 &a_o_10_10_11_1,
6640 &adj_o_10_10_11_2),
6641 "1.1.1.1/32 LB 2 buckets via: "
6642 "adj over 10.10.11.1, ",
6643 "adj-v4 over 10.10.11.2");
6644
6645 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6646 &pfx_24001_eos);
6647 FIB_TEST(fib_test_validate_entry(fei,
6648 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6649 2,
Neale Ranns62fe07c2017-10-31 12:28:22 -07006650 &disp_o_10_10_11_1,
6651 &disp_o_10_10_11_2),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006652 "24001/eos LB 2 buckets via: "
Neale Ranns62fe07c2017-10-31 12:28:22 -07006653 "mpls-disp adj over 10.10.11.1, ",
6654 "mpls-disp adj-v4 over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006655
6656 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6657 &pfx_24001_neos);
6658 FIB_TEST(fib_test_validate_entry(fei,
6659 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6660 1,
6661 &a_mpls_o_10_10_11_1),
6662 "24001/neos LB 1 buckets via: "
6663 "adj-mpls over 10.10.11.2");
6664
6665 /*
6666 * test that the pre-failover load-balance has been in-place
6667 * modified
6668 */
Neale Ranns948e00f2016-10-20 13:39:34 +01006669 dpo_id_t current = DPO_INVALID;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006670 fib_entry_contribute_forwarding(fei,
6671 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6672 &current);
6673
6674 FIB_TEST(!dpo_cmp(&non_eos_1_1_1_1,
6675 &current),
6676 "PIC-core LB inplace modified %U %U",
6677 format_dpo_id, &non_eos_1_1_1_1, 0,
6678 format_dpo_id, &current, 0);
6679
6680 dpo_reset(&non_eos_1_1_1_1);
6681 dpo_reset(&current);
6682
6683 /*
6684 * no-shut the link with the valid label
6685 */
6686 vnet_sw_interface_set_flags(vnet_get_main(),
6687 tm->hw[0]->sw_if_index,
6688 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
6689
6690 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
6691 FIB_TEST(fib_test_validate_entry(fei,
6692 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6693 16, // 3 choices spread over 16 buckets
6694 &l99_eos_o_10_10_10_1,
6695 &l99_eos_o_10_10_10_1,
6696 &l99_eos_o_10_10_10_1,
6697 &l99_eos_o_10_10_10_1,
6698 &l99_eos_o_10_10_10_1,
6699 &l99_eos_o_10_10_10_1,
6700 &a_o_10_10_11_1,
6701 &a_o_10_10_11_1,
6702 &a_o_10_10_11_1,
6703 &a_o_10_10_11_1,
6704 &a_o_10_10_11_1,
6705 &adj_o_10_10_11_2,
6706 &adj_o_10_10_11_2,
6707 &adj_o_10_10_11_2,
6708 &adj_o_10_10_11_2,
6709 &adj_o_10_10_11_2),
6710 "1.1.1.1/32 LB 16 buckets via: "
6711 "label 99 over 10.10.10.1, "
6712 "adj over 10.10.11.1",
6713 "adj-v4 over 10.10.11.2");
6714
6715
6716 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6717 &pfx_24001_eos);
6718 FIB_TEST(fib_test_validate_entry(fei,
6719 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6720 16, // 3 choices spread over 16 buckets
6721 &l99_eos_o_10_10_10_1,
6722 &l99_eos_o_10_10_10_1,
6723 &l99_eos_o_10_10_10_1,
6724 &l99_eos_o_10_10_10_1,
6725 &l99_eos_o_10_10_10_1,
6726 &l99_eos_o_10_10_10_1,
Neale Ranns62fe07c2017-10-31 12:28:22 -07006727 &disp_o_10_10_11_1,
6728 &disp_o_10_10_11_1,
6729 &disp_o_10_10_11_1,
6730 &disp_o_10_10_11_1,
6731 &disp_o_10_10_11_1,
6732 &disp_o_10_10_11_2,
6733 &disp_o_10_10_11_2,
6734 &disp_o_10_10_11_2,
6735 &disp_o_10_10_11_2,
6736 &disp_o_10_10_11_2),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006737 "24001/eos LB 16 buckets via: "
6738 "label 99 over 10.10.10.1, "
Neale Ranns62fe07c2017-10-31 12:28:22 -07006739 "MPLS disp adj over 10.10.11.1",
6740 "MPLS disp adj-v4 over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006741
6742 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6743 &pfx_24001_neos);
6744 FIB_TEST(fib_test_validate_entry(fei,
6745 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6746 2,
6747 &l99_neos_o_10_10_10_1,
6748 &a_mpls_o_10_10_11_1),
6749 "24001/neos LB 2 buckets via: "
6750 "label 99 over 10.10.10.1, "
6751 "adj-mpls over 10.10.11.2");
6752
6753 /*
6754 * remove the first path with the valid label
6755 */
6756 fib_table_entry_path_remove(fib_index,
6757 &pfx_1_1_1_1_s_32,
6758 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07006759 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006760 &nh_10_10_10_1,
6761 tm->hw[0]->sw_if_index,
6762 ~0, // invalid fib index
6763 1,
6764 FIB_ROUTE_PATH_FLAG_NONE);
6765
6766 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
6767 FIB_TEST(fib_test_validate_entry(fei,
6768 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6769 2,
6770 &a_o_10_10_11_1,
6771 &adj_o_10_10_11_2),
6772 "1.1.1.1/32 LB 2 buckets via: "
Neale Rannsa3af3372017-03-28 03:49:52 -07006773 "adj over 10.10.11.1, "
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006774 "adj-v4 over 10.10.11.2");
6775
6776 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6777 &pfx_24001_eos);
6778 FIB_TEST(fib_test_validate_entry(fei,
6779 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6780 2,
Neale Ranns62fe07c2017-10-31 12:28:22 -07006781 &disp_o_10_10_11_1,
6782 &disp_o_10_10_11_2),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006783 "24001/eos LB 2 buckets via: "
Neale Ranns62fe07c2017-10-31 12:28:22 -07006784 "MPLS disp adj over 10.10.11.1, "
6785 "MPLS disp adj-v4 over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006786
6787 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6788 &pfx_24001_neos);
6789
6790 FIB_TEST(fib_test_validate_entry(fei,
6791 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6792 1,
6793 &a_mpls_o_10_10_11_1),
6794 "24001/neos LB 1 buckets via: "
6795 "adj-mpls over 10.10.11.2");
6796
6797 /*
6798 * remove the other path with a valid label
6799 */
6800 fib_test_lb_bucket_t bucket_drop = {
Neale Rannsd792d9c2017-10-21 10:53:20 -07006801 .type = FT_LB_DROP,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006802 };
Neale Rannsf12a83f2017-04-18 09:09:40 -07006803 fib_test_lb_bucket_t mpls_bucket_drop = {
Neale Rannsd792d9c2017-10-21 10:53:20 -07006804 .type = FT_LB_DROP,
Neale Rannsf12a83f2017-04-18 09:09:40 -07006805 .special = {
6806 .adj = DPO_PROTO_MPLS,
6807 },
6808 };
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006809
6810 fib_table_entry_path_remove(fib_index,
6811 &pfx_1_1_1_1_s_32,
6812 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07006813 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006814 &nh_10_10_11_1,
6815 tm->hw[1]->sw_if_index,
6816 ~0, // invalid fib index
6817 1,
6818 FIB_ROUTE_PATH_FLAG_NONE);
6819
6820 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
6821 FIB_TEST(fib_test_validate_entry(fei,
6822 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6823 1,
6824 &adj_o_10_10_11_2),
6825 "1.1.1.1/32 LB 1 buckets via: "
6826 "adj over 10.10.11.2");
6827
6828 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6829 &pfx_24001_eos);
6830 FIB_TEST(fib_test_validate_entry(fei,
6831 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6832 1,
Neale Ranns62fe07c2017-10-31 12:28:22 -07006833 &disp_o_10_10_11_2),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006834 "24001/eos LB 1 buckets via: "
Neale Ranns62fe07c2017-10-31 12:28:22 -07006835 "MPLS disp adj over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006836
6837 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6838 &pfx_24001_neos);
6839 FIB_TEST(fib_test_validate_entry(fei,
6840 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
Neale Rannsf12a83f2017-04-18 09:09:40 -07006841 1,
6842 &mpls_bucket_drop),
6843 "24001/neos LB 1 buckets via: DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006844
6845 /*
6846 * add back the path with the valid label
6847 */
Neale Rannsad422ed2016-11-02 14:20:04 +00006848 l99 = NULL;
Neale Ranns31ed7442018-02-23 05:29:09 -08006849 vec_add1(l99, fml99);
Neale Rannsad422ed2016-11-02 14:20:04 +00006850
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006851 fib_table_entry_path_add(fib_index,
6852 &pfx_1_1_1_1_s_32,
6853 FIB_SOURCE_API,
6854 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07006855 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006856 &nh_10_10_10_1,
6857 tm->hw[0]->sw_if_index,
6858 ~0, // invalid fib index
6859 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006860 l99,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006861 FIB_ROUTE_PATH_FLAG_NONE);
6862
6863 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
6864 FIB_TEST(fib_test_validate_entry(fei,
6865 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6866 2,
6867 &l99_eos_o_10_10_10_1,
6868 &adj_o_10_10_11_2),
6869 "1.1.1.1/32 LB 2 buckets via: "
6870 "label 99 over 10.10.10.1, "
6871 "adj over 10.10.11.2");
6872
6873 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6874 &pfx_24001_eos);
6875 FIB_TEST(fib_test_validate_entry(fei,
6876 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6877 2,
6878 &l99_eos_o_10_10_10_1,
Neale Ranns62fe07c2017-10-31 12:28:22 -07006879 &disp_o_10_10_11_2),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006880 "24001/eos LB 2 buckets via: "
6881 "label 99 over 10.10.10.1, "
Neale Ranns62fe07c2017-10-31 12:28:22 -07006882 "MPLS disp adj over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006883
6884 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6885 &pfx_24001_neos);
6886 FIB_TEST(fib_test_validate_entry(fei,
6887 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6888 1,
6889 &l99_neos_o_10_10_10_1),
6890 "24001/neos LB 1 buckets via: "
6891 "label 99 over 10.10.10.1");
6892
6893 /*
Neale Ranns1357f3b2016-10-16 12:01:42 -07006894 * change the local label
6895 */
6896 fib_table_entry_local_label_add(fib_index,
6897 &pfx_1_1_1_1_s_32,
6898 25005);
6899
6900 fib_prefix_t pfx_25005_eos = {
6901 .fp_proto = FIB_PROTOCOL_MPLS,
6902 .fp_label = 25005,
6903 .fp_eos = MPLS_EOS,
6904 };
6905 fib_prefix_t pfx_25005_neos = {
6906 .fp_proto = FIB_PROTOCOL_MPLS,
6907 .fp_label = 25005,
6908 .fp_eos = MPLS_NON_EOS,
6909 };
6910
6911 FIB_TEST((FIB_NODE_INDEX_INVALID ==
6912 fib_table_lookup(fib_index, &pfx_24001_eos)),
6913 "24001/eos removed after label change");
6914 FIB_TEST((FIB_NODE_INDEX_INVALID ==
6915 fib_table_lookup(fib_index, &pfx_24001_neos)),
6916 "24001/eos removed after label change");
6917
6918 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6919 &pfx_25005_eos);
6920 FIB_TEST(fib_test_validate_entry(fei,
6921 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6922 2,
6923 &l99_eos_o_10_10_10_1,
Neale Ranns62fe07c2017-10-31 12:28:22 -07006924 &disp_o_10_10_11_2),
Neale Ranns1357f3b2016-10-16 12:01:42 -07006925 "25005/eos LB 2 buckets via: "
6926 "label 99 over 10.10.10.1, "
Neale Ranns62fe07c2017-10-31 12:28:22 -07006927 "MPLS disp adj over 10.10.11.2");
Neale Ranns1357f3b2016-10-16 12:01:42 -07006928
6929 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6930 &pfx_25005_neos);
6931 FIB_TEST(fib_test_validate_entry(fei,
6932 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6933 1,
6934 &l99_neos_o_10_10_10_1),
6935 "25005/neos LB 1 buckets via: "
6936 "label 99 over 10.10.10.1");
6937
6938 /*
6939 * remove the local label.
6940 * the check that the MPLS entries are gone is done by the fact the
6941 * MPLS table is no longer present.
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006942 */
6943 fib_table_entry_local_label_remove(fib_index,
6944 &pfx_1_1_1_1_s_32,
Neale Ranns1357f3b2016-10-16 12:01:42 -07006945 25005);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006946
6947 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
6948 FIB_TEST(fib_test_validate_entry(fei,
6949 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6950 2,
6951 &l99_eos_o_10_10_10_1,
6952 &adj_o_10_10_11_2),
6953 "24001/eos LB 2 buckets via: "
6954 "label 99 over 10.10.10.1, "
6955 "adj over 10.10.11.2");
6956
6957 FIB_TEST((FIB_NODE_INDEX_INVALID ==
6958 mpls_fib_index_from_table_id(MPLS_FIB_DEFAULT_TABLE_ID)),
6959 "No more MPLS FIB entries => table removed");
6960
6961 /*
6962 * add another via-entry for the recursive
6963 */
6964 fib_prefix_t pfx_1_1_1_2_s_32 = {
6965 .fp_len = 32,
6966 .fp_proto = FIB_PROTOCOL_IP4,
6967 .fp_addr = {
6968 .ip4.as_u32 = clib_host_to_net_u32(0x01010102),
6969 },
6970 };
6971 fib_test_lb_bucket_t l101_eos_o_10_10_10_1 = {
6972 .type = FT_LB_LABEL_O_ADJ,
6973 .label_o_adj = {
6974 .adj = ai_mpls_10_10_10_1,
6975 .label = 101,
6976 .eos = MPLS_EOS,
6977 },
6978 };
Neale Ranns31ed7442018-02-23 05:29:09 -08006979 fib_mpls_label_t *l101 = NULL, fml101 = {
6980 .fml_value = 101,
6981 };
6982 vec_add1(l101, fml101);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006983
6984 fei = fib_table_entry_update_one_path(fib_index,
6985 &pfx_1_1_1_2_s_32,
6986 FIB_SOURCE_API,
6987 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07006988 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006989 &nh_10_10_10_1,
6990 tm->hw[0]->sw_if_index,
6991 ~0, // invalid fib index
6992 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006993 l101,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006994 FIB_ROUTE_PATH_FLAG_NONE);
6995
6996 FIB_TEST(fib_test_validate_entry(fei,
6997 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6998 1,
6999 &l101_eos_o_10_10_10_1),
7000 "1.1.1.2/32 LB 1 buckets via: "
7001 "label 101 over 10.10.10.1");
7002
Neale Ranns948e00f2016-10-20 13:39:34 +01007003 dpo_id_t non_eos_1_1_1_2 = DPO_INVALID;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007004 fib_entry_contribute_forwarding(fib_table_lookup(fib_index,
7005 &pfx_1_1_1_1_s_32),
7006 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
7007 &non_eos_1_1_1_1);
7008 fib_entry_contribute_forwarding(fib_table_lookup(fib_index,
7009 &pfx_1_1_1_2_s_32),
7010 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
7011 &non_eos_1_1_1_2);
7012
7013 fib_test_lb_bucket_t l1601_eos_o_1_1_1_2 = {
7014 .type = FT_LB_LABEL_O_LB,
7015 .label_o_lb = {
7016 .lb = non_eos_1_1_1_2.dpoi_index,
7017 .label = 1601,
7018 .eos = MPLS_EOS,
7019 },
7020 };
Neale Ranns31ed7442018-02-23 05:29:09 -08007021 fib_mpls_label_t *l1601 = NULL, fml1601 = {
7022 .fml_value = 1601,
7023 };
7024 vec_add1(l1601, fml1601);
Neale Rannsad422ed2016-11-02 14:20:04 +00007025
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007026 l1600_eos_o_1_1_1_1.label_o_lb.lb = non_eos_1_1_1_1.dpoi_index;
7027
7028 fei = fib_table_entry_path_add(fib_index,
7029 &pfx_2_2_2_2_s_32,
7030 FIB_SOURCE_API,
7031 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07007032 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007033 &pfx_1_1_1_2_s_32.fp_addr,
7034 ~0,
7035 fib_index,
7036 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00007037 l1601,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007038 FIB_ROUTE_PATH_FLAG_NONE);
7039
7040 FIB_TEST(fib_test_validate_entry(fei,
7041 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7042 2,
7043 &l1600_eos_o_1_1_1_1,
7044 &l1601_eos_o_1_1_1_2),
7045 "2.2.2.2/32 LB 2 buckets via: "
7046 "label 1600 via 1.1,1.1, "
7047 "label 16001 via 1.1.1.2");
7048
7049 /*
7050 * update the via-entry so it no longer has an imp-null path.
7051 * the LB for the recursive can use an imp-null
7052 */
Neale Rannsad422ed2016-11-02 14:20:04 +00007053 l_imp_null = NULL;
Neale Ranns31ed7442018-02-23 05:29:09 -08007054 vec_add1(l_imp_null, fml_imp_null);
Neale Rannsad422ed2016-11-02 14:20:04 +00007055
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007056 fei = fib_table_entry_update_one_path(fib_index,
7057 &pfx_1_1_1_2_s_32,
7058 FIB_SOURCE_API,
7059 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07007060 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007061 &nh_10_10_11_1,
7062 tm->hw[1]->sw_if_index,
7063 ~0, // invalid fib index
7064 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00007065 l_imp_null,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007066 FIB_ROUTE_PATH_FLAG_NONE);
7067
7068 FIB_TEST(fib_test_validate_entry(fei,
7069 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7070 1,
7071 &a_o_10_10_11_1),
7072 "1.1.1.2/32 LB 1 buckets via: "
7073 "adj 10.10.11.1");
7074
7075 fei = fib_table_lookup(fib_index, &pfx_2_2_2_2_s_32);
7076 FIB_TEST(fib_test_validate_entry(fei,
7077 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7078 2,
7079 &l1600_eos_o_1_1_1_1,
7080 &l1601_eos_o_1_1_1_2),
7081 "2.2.2.2/32 LB 2 buckets via: "
7082 "label 1600 via 1.1,1.1, "
7083 "label 16001 via 1.1.1.2");
7084
7085 /*
7086 * update the via-entry so it no longer has labelled paths.
7087 * the LB for the recursive should exclue this via form its LB
7088 */
7089 fei = fib_table_entry_update_one_path(fib_index,
7090 &pfx_1_1_1_2_s_32,
7091 FIB_SOURCE_API,
7092 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07007093 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007094 &nh_10_10_11_1,
7095 tm->hw[1]->sw_if_index,
7096 ~0, // invalid fib index
7097 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00007098 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007099 FIB_ROUTE_PATH_FLAG_NONE);
7100
7101 FIB_TEST(fib_test_validate_entry(fei,
7102 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7103 1,
7104 &a_o_10_10_11_1),
7105 "1.1.1.2/32 LB 1 buckets via: "
7106 "adj 10.10.11.1");
7107
7108 fei = fib_table_lookup(fib_index, &pfx_2_2_2_2_s_32);
7109 FIB_TEST(fib_test_validate_entry(fei,
7110 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7111 1,
7112 &l1600_eos_o_1_1_1_1),
7113 "2.2.2.2/32 LB 1 buckets via: "
7114 "label 1600 via 1.1,1.1");
7115
7116 dpo_reset(&non_eos_1_1_1_1);
7117 dpo_reset(&non_eos_1_1_1_2);
7118
7119 /*
7120 * Add a recursive with no out-labels. We expect to use the IP of the via
7121 */
7122 fib_prefix_t pfx_2_2_2_3_s_32 = {
7123 .fp_len = 32,
7124 .fp_proto = FIB_PROTOCOL_IP4,
7125 .fp_addr = {
7126 .ip4.as_u32 = clib_host_to_net_u32(0x02020203),
7127 },
7128 };
Neale Ranns948e00f2016-10-20 13:39:34 +01007129 dpo_id_t ip_1_1_1_1 = DPO_INVALID;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007130
7131 fib_table_entry_update_one_path(fib_index,
7132 &pfx_2_2_2_3_s_32,
7133 FIB_SOURCE_API,
7134 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07007135 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007136 &pfx_1_1_1_1_s_32.fp_addr,
7137 ~0,
7138 fib_index,
7139 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00007140 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007141 FIB_ROUTE_PATH_FLAG_NONE);
7142
7143 fib_entry_contribute_forwarding(fib_table_lookup(fib_index,
7144 &pfx_1_1_1_1_s_32),
7145 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7146 &ip_1_1_1_1);
7147
7148 fib_test_lb_bucket_t ip_o_1_1_1_1 = {
7149 .type = FT_LB_O_LB,
7150 .lb = {
7151 .lb = ip_1_1_1_1.dpoi_index,
7152 },
7153 };
7154
7155 fei = fib_table_lookup(fib_index, &pfx_2_2_2_3_s_32);
7156 FIB_TEST(fib_test_validate_entry(fei,
7157 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7158 1,
7159 &ip_o_1_1_1_1),
7160 "2.2.2.2.3/32 LB 1 buckets via: "
7161 "ip 1.1.1.1");
7162
7163 /*
7164 * Add a recursive with an imp-null out-label.
7165 * We expect to use the IP of the via
7166 */
7167 fib_prefix_t pfx_2_2_2_4_s_32 = {
7168 .fp_len = 32,
7169 .fp_proto = FIB_PROTOCOL_IP4,
7170 .fp_addr = {
7171 .ip4.as_u32 = clib_host_to_net_u32(0x02020204),
7172 },
7173 };
7174
7175 fib_table_entry_update_one_path(fib_index,
7176 &pfx_2_2_2_4_s_32,
7177 FIB_SOURCE_API,
7178 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07007179 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007180 &pfx_1_1_1_1_s_32.fp_addr,
7181 ~0,
7182 fib_index,
7183 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00007184 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007185 FIB_ROUTE_PATH_FLAG_NONE);
7186
7187 fei = fib_table_lookup(fib_index, &pfx_2_2_2_4_s_32);
7188 FIB_TEST(fib_test_validate_entry(fei,
7189 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7190 1,
7191 &ip_o_1_1_1_1),
7192 "2.2.2.2.4/32 LB 1 buckets via: "
7193 "ip 1.1.1.1");
7194
7195 dpo_reset(&ip_1_1_1_1);
7196
7197 /*
Neale Rannsad422ed2016-11-02 14:20:04 +00007198 * Create an entry with a deep label stack
7199 */
7200 fib_prefix_t pfx_2_2_5_5_s_32 = {
7201 .fp_len = 32,
7202 .fp_proto = FIB_PROTOCOL_IP4,
7203 .fp_addr = {
7204 .ip4.as_u32 = clib_host_to_net_u32(0x02020505),
7205 },
7206 };
7207 fib_test_lb_bucket_t ls_eos_o_10_10_10_1 = {
7208 .type = FT_LB_LABEL_STACK_O_ADJ,
7209 .label_stack_o_adj = {
7210 .adj = ai_mpls_10_10_11_1,
7211 .label_stack_size = 8,
7212 .label_stack = {
7213 200, 201, 202, 203, 204, 205, 206, 207
7214 },
7215 .eos = MPLS_EOS,
7216 },
7217 };
Neale Ranns31ed7442018-02-23 05:29:09 -08007218 fib_mpls_label_t *label_stack = NULL;
Neale Rannsad422ed2016-11-02 14:20:04 +00007219 vec_validate(label_stack, 7);
7220 for (ii = 0; ii < 8; ii++)
7221 {
Neale Ranns31ed7442018-02-23 05:29:09 -08007222 label_stack[ii].fml_value = ii + 200;
Neale Rannsad422ed2016-11-02 14:20:04 +00007223 }
7224
7225 fei = fib_table_entry_update_one_path(fib_index,
7226 &pfx_2_2_5_5_s_32,
7227 FIB_SOURCE_API,
7228 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07007229 DPO_PROTO_IP4,
Neale Rannsad422ed2016-11-02 14:20:04 +00007230 &nh_10_10_11_1,
7231 tm->hw[1]->sw_if_index,
7232 ~0, // invalid fib index
7233 1,
7234 label_stack,
7235 FIB_ROUTE_PATH_FLAG_NONE);
7236
7237 FIB_TEST(fib_test_validate_entry(fei,
7238 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7239 1,
7240 &ls_eos_o_10_10_10_1),
7241 "2.2.5.5/32 LB 1 buckets via: "
7242 "adj 10.10.11.1");
7243 fib_table_entry_delete_index(fei, FIB_SOURCE_API);
7244
7245 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007246 * cleanup
7247 */
7248 fib_table_entry_delete(fib_index,
7249 &pfx_1_1_1_2_s_32,
7250 FIB_SOURCE_API);
7251
7252 fei = fib_table_lookup(fib_index, &pfx_2_2_2_2_s_32);
7253 FIB_TEST(fib_test_validate_entry(fei,
7254 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7255 1,
7256 &l1600_eos_o_1_1_1_1),
7257 "2.2.2.2/32 LB 1 buckets via: "
7258 "label 1600 via 1.1,1.1");
7259
7260 fib_table_entry_delete(fib_index,
7261 &pfx_1_1_1_1_s_32,
7262 FIB_SOURCE_API);
7263
7264 FIB_TEST(fib_test_validate_entry(fei,
7265 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7266 1,
7267 &bucket_drop),
7268 "2.2.2.2/32 LB 1 buckets via: DROP");
7269
7270 fib_table_entry_delete(fib_index,
7271 &pfx_2_2_2_2_s_32,
7272 FIB_SOURCE_API);
7273 fib_table_entry_delete(fib_index,
7274 &pfx_2_2_2_3_s_32,
7275 FIB_SOURCE_API);
7276 fib_table_entry_delete(fib_index,
7277 &pfx_2_2_2_4_s_32,
7278 FIB_SOURCE_API);
7279
7280 adj_unlock(ai_mpls_10_10_10_1);
7281 adj_unlock(ai_mpls_10_10_11_2);
7282 adj_unlock(ai_v4_10_10_11_1);
7283 adj_unlock(ai_v4_10_10_11_2);
7284 adj_unlock(ai_mpls_10_10_11_1);
7285
7286 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
7287 adj_nbr_db_size());
7288
7289 local0_pfx.fp_len = 32;
7290 fib_table_entry_delete(fib_index,
7291 &local0_pfx,
7292 FIB_SOURCE_INTERFACE);
7293 local0_pfx.fp_len = 24;
7294 fib_table_entry_delete(fib_index,
7295 &local0_pfx,
7296 FIB_SOURCE_INTERFACE);
7297 local1_pfx.fp_len = 32;
7298 fib_table_entry_delete(fib_index,
7299 &local1_pfx,
7300 FIB_SOURCE_INTERFACE);
7301 local1_pfx.fp_len = 24;
7302 fib_table_entry_delete(fib_index,
7303 &local1_pfx,
7304 FIB_SOURCE_INTERFACE);
7305
7306 /*
7307 * +1 for the drop LB in the MPLS tables.
7308 */
7309 FIB_TEST(lb_count+1 == pool_elts(load_balance_pool),
7310 "Load-balance resources freed %d of %d",
7311 lb_count+1, pool_elts(load_balance_pool));
Neale Ranns0ebe8d72016-12-08 19:48:11 +00007312
7313 return (0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007314}
7315
7316#define N_TEST_CHILDREN 4
7317#define PARENT_INDEX 0
7318
7319typedef struct fib_node_test_t_
7320{
7321 fib_node_t node;
7322 u32 sibling;
7323 u32 index;
7324 fib_node_back_walk_ctx_t *ctxs;
7325 u32 destroyed;
7326} fib_node_test_t;
7327
7328static fib_node_test_t fib_test_nodes[N_TEST_CHILDREN+1];
7329
7330#define PARENT() (&fib_test_nodes[PARENT_INDEX].node)
7331
7332#define FOR_EACH_TEST_CHILD(_tc) \
7333 for (ii = 1, (_tc) = &fib_test_nodes[1]; \
7334 ii < N_TEST_CHILDREN+1; \
7335 ii++, (_tc) = &fib_test_nodes[ii])
7336
7337static fib_node_t *
7338fib_test_child_get_node (fib_node_index_t index)
7339{
7340 return (&fib_test_nodes[index].node);
7341}
7342
7343static int fib_test_walk_spawns_walks;
7344
7345static fib_node_back_walk_rc_t
7346fib_test_child_back_walk_notify (fib_node_t *node,
7347 fib_node_back_walk_ctx_t *ctx)
7348{
7349 fib_node_test_t *tc = (fib_node_test_t*) node;
7350
7351 vec_add1(tc->ctxs, *ctx);
7352
7353 if (1 == fib_test_walk_spawns_walks)
7354 fib_walk_sync(FIB_NODE_TYPE_TEST, tc->index, ctx);
7355 if (2 == fib_test_walk_spawns_walks)
7356 fib_walk_async(FIB_NODE_TYPE_TEST, tc->index,
7357 FIB_WALK_PRIORITY_HIGH, ctx);
7358
7359 return (FIB_NODE_BACK_WALK_CONTINUE);
7360}
7361
7362static void
7363fib_test_child_last_lock_gone (fib_node_t *node)
7364{
7365 fib_node_test_t *tc = (fib_node_test_t *)node;
7366
7367 tc->destroyed = 1;
7368}
7369
7370/**
7371 * The FIB walk's graph node virtual function table
7372 */
7373static const fib_node_vft_t fib_test_child_vft = {
7374 .fnv_get = fib_test_child_get_node,
7375 .fnv_last_lock = fib_test_child_last_lock_gone,
7376 .fnv_back_walk = fib_test_child_back_walk_notify,
7377};
7378
7379/*
7380 * the function (that should have been static but isn't so I can do this)
7381 * that processes the walk from the async queue,
7382 */
7383f64 fib_walk_process_queues(vlib_main_t * vm,
7384 const f64 quota);
7385u32 fib_walk_queue_get_size(fib_walk_priority_t prio);
7386
Neale Ranns0ebe8d72016-12-08 19:48:11 +00007387static int
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007388fib_test_walk (void)
7389{
7390 fib_node_back_walk_ctx_t high_ctx = {}, low_ctx = {};
7391 fib_node_test_t *tc;
7392 vlib_main_t *vm;
7393 u32 ii;
7394
7395 vm = vlib_get_main();
7396 fib_node_register_type(FIB_NODE_TYPE_TEST, &fib_test_child_vft);
7397
7398 /*
7399 * init a fake node on which we will add children
7400 */
7401 fib_node_init(&fib_test_nodes[PARENT_INDEX].node,
7402 FIB_NODE_TYPE_TEST);
7403
7404 FOR_EACH_TEST_CHILD(tc)
7405 {
7406 fib_node_init(&tc->node, FIB_NODE_TYPE_TEST);
7407 fib_node_lock(&tc->node);
7408 tc->ctxs = NULL;
7409 tc->index = ii;
7410 tc->sibling = fib_node_child_add(FIB_NODE_TYPE_TEST,
7411 PARENT_INDEX,
7412 FIB_NODE_TYPE_TEST, ii);
7413 }
7414
7415 /*
7416 * enqueue a walk across the parents children.
7417 */
Neale Ranns450cd302016-11-09 17:49:42 +00007418 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007419
7420 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7421 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7422 FIB_TEST(N_TEST_CHILDREN+1 == fib_node_list_get_size(PARENT()->fn_children),
7423 "Parent has %d children pre-walk",
7424 fib_node_list_get_size(PARENT()->fn_children));
7425
7426 /*
7427 * give the walk a large amount of time so it gets to the end
7428 */
7429 fib_walk_process_queues(vm, 1);
7430
7431 FOR_EACH_TEST_CHILD(tc)
7432 {
7433 FIB_TEST(1 == vec_len(tc->ctxs),
7434 "%d child visitsed %d times",
7435 ii, vec_len(tc->ctxs));
7436 vec_free(tc->ctxs);
7437 }
7438 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7439 "Queue is empty post walk");
7440 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7441 "Parent has %d children post walk",
7442 fib_node_list_get_size(PARENT()->fn_children));
7443
7444 /*
7445 * walk again. should be no increase in the number of visits, since
7446 * the walk will have terminated.
7447 */
7448 fib_walk_process_queues(vm, 1);
7449
7450 FOR_EACH_TEST_CHILD(tc)
7451 {
7452 FIB_TEST(0 == vec_len(tc->ctxs),
7453 "%d child visitsed %d times",
7454 ii, vec_len(tc->ctxs));
7455 }
7456
7457 /*
7458 * schedule a low and hig priority walk. expect the high to be performed
7459 * before the low.
7460 * schedule the high prio walk first so that it is further from the head
7461 * of the dependency list. that way it won't merge with the low one.
7462 */
7463 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
7464 low_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_ADJ_UPDATE;
7465
7466 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7467 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7468 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7469 FIB_WALK_PRIORITY_LOW, &low_ctx);
7470
7471 fib_walk_process_queues(vm, 1);
7472
7473 FOR_EACH_TEST_CHILD(tc)
7474 {
7475 FIB_TEST(high_ctx.fnbw_reason == tc->ctxs[0].fnbw_reason,
7476 "%d child visitsed by high prio walk", ii);
7477 FIB_TEST(low_ctx.fnbw_reason == tc->ctxs[1].fnbw_reason,
7478 "%d child visitsed by low prio walk", ii);
7479 vec_free(tc->ctxs);
7480 }
7481 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7482 "Queue is empty post prio walk");
7483 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7484 "Parent has %d children post prio walk",
7485 fib_node_list_get_size(PARENT()->fn_children));
7486
7487 /*
7488 * schedule 2 walks of the same priority that can be megred.
7489 * expect that each child is thus visited only once.
7490 */
7491 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
7492 low_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
7493
7494 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7495 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7496 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7497 FIB_WALK_PRIORITY_HIGH, &low_ctx);
7498
7499 fib_walk_process_queues(vm, 1);
7500
7501 FOR_EACH_TEST_CHILD(tc)
7502 {
7503 FIB_TEST(1 == vec_len(tc->ctxs),
7504 "%d child visitsed %d times during merge walk",
7505 ii, vec_len(tc->ctxs));
7506 vec_free(tc->ctxs);
7507 }
7508 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7509 "Queue is empty post merge walk");
7510 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7511 "Parent has %d children post merge walk",
7512 fib_node_list_get_size(PARENT()->fn_children));
7513
7514 /*
7515 * schedule 2 walks of the same priority that cannot be megred.
7516 * expect that each child is thus visited twice and in the order
7517 * in which the walks were scheduled.
7518 */
7519 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
7520 low_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_ADJ_UPDATE;
7521
7522 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7523 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7524 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7525 FIB_WALK_PRIORITY_HIGH, &low_ctx);
7526
7527 fib_walk_process_queues(vm, 1);
7528
7529 FOR_EACH_TEST_CHILD(tc)
7530 {
7531 FIB_TEST(high_ctx.fnbw_reason == tc->ctxs[0].fnbw_reason,
7532 "%d child visitsed by high prio walk", ii);
7533 FIB_TEST(low_ctx.fnbw_reason == tc->ctxs[1].fnbw_reason,
7534 "%d child visitsed by low prio walk", ii);
7535 vec_free(tc->ctxs);
7536 }
7537 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7538 "Queue is empty post no-merge walk");
7539 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7540 "Parent has %d children post no-merge walk",
7541 fib_node_list_get_size(PARENT()->fn_children));
7542
7543 /*
7544 * schedule a walk that makes one one child progress.
7545 * we do this by giving the queue draining process zero
7546 * time quanta. it's a do..while loop, so it does something.
7547 */
Neale Ranns450cd302016-11-09 17:49:42 +00007548 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007549
7550 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7551 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7552 fib_walk_process_queues(vm, 0);
7553
7554 FOR_EACH_TEST_CHILD(tc)
7555 {
7556 if (ii == N_TEST_CHILDREN)
7557 {
7558 FIB_TEST(1 == vec_len(tc->ctxs),
7559 "%d child visitsed %d times in zero quanta walk",
7560 ii, vec_len(tc->ctxs));
7561 }
7562 else
7563 {
7564 FIB_TEST(0 == vec_len(tc->ctxs),
7565 "%d child visitsed %d times in 0 quanta walk",
7566 ii, vec_len(tc->ctxs));
7567 }
7568 }
7569 FIB_TEST(1 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7570 "Queue is not empty post zero quanta walk");
7571 FIB_TEST(N_TEST_CHILDREN+1 == fib_node_list_get_size(PARENT()->fn_children),
7572 "Parent has %d children post zero qunta walk",
7573 fib_node_list_get_size(PARENT()->fn_children));
7574
7575 /*
7576 * another one step
7577 */
7578 fib_walk_process_queues(vm, 0);
7579
7580 FOR_EACH_TEST_CHILD(tc)
7581 {
7582 if (ii >= N_TEST_CHILDREN-1)
7583 {
7584 FIB_TEST(1 == vec_len(tc->ctxs),
7585 "%d child visitsed %d times in 2nd zero quanta walk",
7586 ii, vec_len(tc->ctxs));
7587 }
7588 else
7589 {
7590 FIB_TEST(0 == vec_len(tc->ctxs),
7591 "%d child visitsed %d times in 2nd 0 quanta walk",
7592 ii, vec_len(tc->ctxs));
7593 }
7594 }
7595 FIB_TEST(1 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7596 "Queue is not empty post zero quanta walk");
7597 FIB_TEST(N_TEST_CHILDREN+1 == fib_node_list_get_size(PARENT()->fn_children),
7598 "Parent has %d children post zero qunta walk",
7599 fib_node_list_get_size(PARENT()->fn_children));
7600
7601 /*
7602 * schedule another walk that will catch-up and merge.
7603 */
7604 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7605 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7606 fib_walk_process_queues(vm, 1);
7607
7608 FOR_EACH_TEST_CHILD(tc)
7609 {
7610 if (ii >= N_TEST_CHILDREN-1)
7611 {
7612 FIB_TEST(2 == vec_len(tc->ctxs),
7613 "%d child visitsed %d times in 2nd zero quanta merge walk",
7614 ii, vec_len(tc->ctxs));
7615 vec_free(tc->ctxs);
7616 }
7617 else
7618 {
7619 FIB_TEST(1 == vec_len(tc->ctxs),
7620 "%d child visitsed %d times in 2nd 0 quanta merge walk",
7621 ii, vec_len(tc->ctxs));
7622 vec_free(tc->ctxs);
7623 }
7624 }
7625 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7626 "Queue is not empty post 2nd zero quanta merge walk");
7627 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7628 "Parent has %d children post 2nd zero qunta merge walk",
7629 fib_node_list_get_size(PARENT()->fn_children));
7630
7631 /*
7632 * park a async walk in the middle of the list, then have an sync walk catch
7633 * it. same expectations as async catches async.
7634 */
Neale Ranns450cd302016-11-09 17:49:42 +00007635 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007636
7637 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7638 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7639
7640 fib_walk_process_queues(vm, 0);
7641 fib_walk_process_queues(vm, 0);
7642
7643 fib_walk_sync(FIB_NODE_TYPE_TEST, PARENT_INDEX, &high_ctx);
7644
7645 FOR_EACH_TEST_CHILD(tc)
7646 {
7647 if (ii >= N_TEST_CHILDREN-1)
7648 {
7649 FIB_TEST(2 == vec_len(tc->ctxs),
7650 "%d child visitsed %d times in sync catches async walk",
7651 ii, vec_len(tc->ctxs));
7652 vec_free(tc->ctxs);
7653 }
7654 else
7655 {
7656 FIB_TEST(1 == vec_len(tc->ctxs),
7657 "%d child visitsed %d times in sync catches async walk",
7658 ii, vec_len(tc->ctxs));
7659 vec_free(tc->ctxs);
7660 }
7661 }
7662 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7663 "Queue is not empty post 2nd zero quanta merge walk");
7664 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7665 "Parent has %d children post 2nd zero qunta merge walk",
7666 fib_node_list_get_size(PARENT()->fn_children));
7667
7668 /*
7669 * make the parent a child of one of its children, thus inducing a routing loop.
7670 */
7671 fib_test_nodes[PARENT_INDEX].sibling =
7672 fib_node_child_add(FIB_NODE_TYPE_TEST,
7673 1, // the first child
7674 FIB_NODE_TYPE_TEST,
7675 PARENT_INDEX);
7676
7677 /*
7678 * execute a sync walk from the parent. each child visited spawns more sync
7679 * walks. we expect the walk to terminate.
7680 */
7681 fib_test_walk_spawns_walks = 1;
7682
7683 fib_walk_sync(FIB_NODE_TYPE_TEST, PARENT_INDEX, &high_ctx);
7684
7685 FOR_EACH_TEST_CHILD(tc)
7686 {
7687 /*
7688 * child 1 - which is last in the list - has the loop.
7689 * the other children a re thus visitsed first. the we meet
7690 * child 1. we go round the loop again, visting the other children.
7691 * then we meet the walk in the dep list and bail. child 1 is not visitsed
7692 * again.
7693 */
7694 if (1 == ii)
7695 {
7696 FIB_TEST(1 == vec_len(tc->ctxs),
7697 "child %d visitsed %d times during looped sync walk",
7698 ii, vec_len(tc->ctxs));
7699 }
7700 else
7701 {
7702 FIB_TEST(2 == vec_len(tc->ctxs),
7703 "child %d visitsed %d times during looped sync walk",
7704 ii, vec_len(tc->ctxs));
7705 }
7706 vec_free(tc->ctxs);
7707 }
7708 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7709 "Parent has %d children post sync loop walk",
7710 fib_node_list_get_size(PARENT()->fn_children));
7711
7712 /*
7713 * the walk doesn't reach the max depth because the infra knows that sync
7714 * meets sync implies a loop and bails early.
7715 */
7716 FIB_TEST(high_ctx.fnbw_depth == 9,
7717 "Walk context depth %d post sync loop walk",
7718 high_ctx.fnbw_depth);
7719
7720 /*
7721 * execute an async walk of the graph loop, with each child spawns sync walks
7722 */
7723 high_ctx.fnbw_depth = 0;
7724 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7725 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7726
7727 fib_walk_process_queues(vm, 1);
7728
7729 FOR_EACH_TEST_CHILD(tc)
7730 {
7731 /*
7732 * we don't really care how many times the children are visisted, as long as
7733 * it is more than once.
7734 */
7735 FIB_TEST(1 <= vec_len(tc->ctxs),
7736 "child %d visitsed %d times during looped aync spawns sync walk",
7737 ii, vec_len(tc->ctxs));
7738 vec_free(tc->ctxs);
7739 }
7740
7741 /*
7742 * execute an async walk of the graph loop, with each child spawns async walks
7743 */
7744 fib_test_walk_spawns_walks = 2;
7745 high_ctx.fnbw_depth = 0;
7746 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7747 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7748
7749 fib_walk_process_queues(vm, 1);
7750
7751 FOR_EACH_TEST_CHILD(tc)
7752 {
7753 /*
7754 * we don't really care how many times the children are visisted, as long as
7755 * it is more than once.
7756 */
7757 FIB_TEST(1 <= vec_len(tc->ctxs),
7758 "child %d visitsed %d times during looped async spawns async walk",
7759 ii, vec_len(tc->ctxs));
7760 vec_free(tc->ctxs);
7761 }
7762
7763
7764 fib_node_child_remove(FIB_NODE_TYPE_TEST,
7765 1, // the first child
7766 fib_test_nodes[PARENT_INDEX].sibling);
7767
7768 /*
7769 * cleanup
7770 */
7771 FOR_EACH_TEST_CHILD(tc)
7772 {
7773 fib_node_child_remove(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7774 tc->sibling);
7775 fib_node_deinit(&tc->node);
7776 fib_node_unlock(&tc->node);
7777 }
7778 fib_node_deinit(PARENT());
7779
7780 /*
7781 * The parent will be destroyed when the last lock on it goes.
7782 * this test ensures all the walk objects are unlocking it.
7783 */
7784 FIB_TEST((1 == fib_test_nodes[PARENT_INDEX].destroyed),
7785 "Parent was destroyed");
Neale Ranns0ebe8d72016-12-08 19:48:11 +00007786
7787 return (0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007788}
7789
Neale Ranns88fc83e2017-04-05 08:11:14 -07007790/*
7791 * declaration of the otherwise static callback functions
7792 */
7793void fib_bfd_notify (bfd_listen_event_e event,
7794 const bfd_session_t *session);
7795void adj_bfd_notify (bfd_listen_event_e event,
7796 const bfd_session_t *session);
7797
7798/**
7799 * Test BFD session interaction with FIB
7800 */
7801static int
7802fib_test_bfd (void)
7803{
7804 fib_node_index_t fei;
7805 test_main_t *tm;
7806 int n_feis;
7807
7808 /* via 10.10.10.1 */
7809 ip46_address_t nh_10_10_10_1 = {
7810 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
7811 };
7812 /* via 10.10.10.2 */
7813 ip46_address_t nh_10_10_10_2 = {
7814 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02),
7815 };
7816 /* via 10.10.10.10 */
7817 ip46_address_t nh_10_10_10_10 = {
7818 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a0a),
7819 };
7820 n_feis = fib_entry_pool_size();
7821
7822 tm = &test_main;
7823
7824 /*
7825 * add interface routes. we'll assume this works. it's tested elsewhere
7826 */
7827 fib_prefix_t pfx_10_10_10_10_s_24 = {
7828 .fp_len = 24,
7829 .fp_proto = FIB_PROTOCOL_IP4,
7830 .fp_addr = nh_10_10_10_10,
7831 };
7832
7833 fib_table_entry_update_one_path(0, &pfx_10_10_10_10_s_24,
7834 FIB_SOURCE_INTERFACE,
7835 (FIB_ENTRY_FLAG_CONNECTED |
7836 FIB_ENTRY_FLAG_ATTACHED),
Neale Rannsda78f952017-05-24 09:15:43 -07007837 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07007838 NULL,
7839 tm->hw[0]->sw_if_index,
7840 ~0, // invalid fib index
7841 1, // weight
7842 NULL,
7843 FIB_ROUTE_PATH_FLAG_NONE);
7844
7845 fib_prefix_t pfx_10_10_10_10_s_32 = {
7846 .fp_len = 32,
7847 .fp_proto = FIB_PROTOCOL_IP4,
7848 .fp_addr = nh_10_10_10_10,
7849 };
7850 fib_table_entry_update_one_path(0, &pfx_10_10_10_10_s_32,
7851 FIB_SOURCE_INTERFACE,
7852 (FIB_ENTRY_FLAG_CONNECTED |
7853 FIB_ENTRY_FLAG_LOCAL),
Neale Rannsda78f952017-05-24 09:15:43 -07007854 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07007855 NULL,
7856 tm->hw[0]->sw_if_index,
7857 ~0, // invalid fib index
7858 1, // weight
7859 NULL,
7860 FIB_ROUTE_PATH_FLAG_NONE);
7861
7862 /*
7863 * A BFD session via a neighbour we do not yet know
7864 */
7865 bfd_session_t bfd_10_10_10_1 = {
7866 .udp = {
7867 .key = {
7868 .fib_index = 0,
7869 .peer_addr = nh_10_10_10_1,
7870 },
7871 },
7872 .hop_type = BFD_HOP_TYPE_MULTI,
7873 .local_state = BFD_STATE_init,
7874 };
7875
7876 fib_bfd_notify (BFD_LISTEN_EVENT_CREATE, &bfd_10_10_10_1);
7877
7878 /*
7879 * A new entry will be created that forwards via the adj
7880 */
7881 adj_index_t ai_10_10_10_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
7882 VNET_LINK_IP4,
7883 &nh_10_10_10_1,
7884 tm->hw[0]->sw_if_index);
7885 fib_prefix_t pfx_10_10_10_1_s_32 = {
7886 .fp_addr = nh_10_10_10_1,
7887 .fp_len = 32,
7888 .fp_proto = FIB_PROTOCOL_IP4,
7889 };
7890 fib_test_lb_bucket_t adj_o_10_10_10_1 = {
7891 .type = FT_LB_ADJ,
7892 .adj = {
7893 .adj = ai_10_10_10_1,
7894 },
7895 };
7896
7897 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_1_s_32);
7898 FIB_TEST(fib_test_validate_entry(fei,
7899 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7900 1,
7901 &adj_o_10_10_10_1),
7902 "BFD sourced %U via %U",
7903 format_fib_prefix, &pfx_10_10_10_1_s_32,
7904 format_ip_adjacency, ai_10_10_10_1, FORMAT_IP_ADJACENCY_NONE);
7905
7906 /*
7907 * Delete the BFD session. Expect the fib_entry to be removed
7908 */
7909 fib_bfd_notify (BFD_LISTEN_EVENT_DELETE, &bfd_10_10_10_1);
7910
7911 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_1_s_32);
7912 FIB_TEST(FIB_NODE_INDEX_INVALID == fei,
7913 "BFD sourced %U removed",
7914 format_fib_prefix, &pfx_10_10_10_1_s_32);
7915
7916 /*
7917 * Add the BFD source back
7918 */
7919 fib_bfd_notify (BFD_LISTEN_EVENT_CREATE, &bfd_10_10_10_1);
7920
7921 /*
7922 * source the entry via the ADJ fib
7923 */
Neale Ranns81424992017-05-18 03:03:22 -07007924 fei = fib_table_entry_path_add(0,
7925 &pfx_10_10_10_1_s_32,
7926 FIB_SOURCE_ADJ,
7927 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07007928 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07007929 &nh_10_10_10_1,
7930 tm->hw[0]->sw_if_index,
7931 ~0, // invalid fib index
7932 1,
7933 NULL,
7934 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns88fc83e2017-04-05 08:11:14 -07007935
7936 /*
7937 * Delete the BFD session. Expect the fib_entry to remain
7938 */
7939 fib_bfd_notify (BFD_LISTEN_EVENT_DELETE, &bfd_10_10_10_1);
7940
7941 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_1_s_32);
7942 FIB_TEST(fib_test_validate_entry(fei,
7943 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7944 1,
7945 &adj_o_10_10_10_1),
7946 "BFD sourced %U remains via %U",
7947 format_fib_prefix, &pfx_10_10_10_1_s_32,
7948 format_ip_adjacency, ai_10_10_10_1, FORMAT_IP_ADJACENCY_NONE);
7949
7950 /*
7951 * Add the BFD source back
7952 */
7953 fib_bfd_notify (BFD_LISTEN_EVENT_CREATE, &bfd_10_10_10_1);
7954
7955 /*
7956 * Create another ADJ FIB
7957 */
7958 fib_prefix_t pfx_10_10_10_2_s_32 = {
7959 .fp_addr = nh_10_10_10_2,
7960 .fp_len = 32,
7961 .fp_proto = FIB_PROTOCOL_IP4,
7962 };
Neale Ranns81424992017-05-18 03:03:22 -07007963 fib_table_entry_path_add(0,
7964 &pfx_10_10_10_2_s_32,
7965 FIB_SOURCE_ADJ,
7966 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07007967 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07007968 &nh_10_10_10_2,
7969 tm->hw[0]->sw_if_index,
7970 ~0, // invalid fib index
7971 1,
7972 NULL,
7973 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns88fc83e2017-04-05 08:11:14 -07007974 /*
7975 * A BFD session for the new ADJ FIB
7976 */
7977 bfd_session_t bfd_10_10_10_2 = {
7978 .udp = {
7979 .key = {
7980 .fib_index = 0,
7981 .peer_addr = nh_10_10_10_2,
7982 },
7983 },
7984 .hop_type = BFD_HOP_TYPE_MULTI,
7985 .local_state = BFD_STATE_init,
7986 };
7987
7988 fib_bfd_notify (BFD_LISTEN_EVENT_CREATE, &bfd_10_10_10_2);
7989
7990 /*
7991 * remove the adj-fib source whilst the session is present
7992 * then add it back
7993 */
7994 fib_table_entry_delete(0, &pfx_10_10_10_2_s_32, FIB_SOURCE_ADJ);
Neale Ranns81424992017-05-18 03:03:22 -07007995 fib_table_entry_path_add(0,
7996 &pfx_10_10_10_2_s_32,
7997 FIB_SOURCE_ADJ,
7998 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07007999 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07008000 &nh_10_10_10_2,
8001 tm->hw[0]->sw_if_index,
8002 ~0, // invalid fib index
8003 1,
8004 NULL,
8005 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns88fc83e2017-04-05 08:11:14 -07008006
8007 /*
8008 * Before adding a recursive via the BFD tracked ADJ-FIBs,
8009 * bring one of the sessions UP, leave the other down
8010 */
8011 bfd_10_10_10_1.local_state = BFD_STATE_up;
8012 fib_bfd_notify (BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_1);
8013 bfd_10_10_10_2.local_state = BFD_STATE_down;
8014 fib_bfd_notify (BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_2);
8015
8016 /*
8017 * A recursive prefix via both of the ADJ FIBs
8018 */
8019 fib_prefix_t pfx_200_0_0_0_s_24 = {
8020 .fp_proto = FIB_PROTOCOL_IP4,
8021 .fp_len = 32,
8022 .fp_addr = {
8023 .ip4.as_u32 = clib_host_to_net_u32(0xc8000000),
8024 },
8025 };
8026 const dpo_id_t *dpo_10_10_10_1, *dpo_10_10_10_2;
8027
8028 dpo_10_10_10_1 =
8029 fib_entry_contribute_ip_forwarding(
8030 fib_table_lookup_exact_match(0, &pfx_10_10_10_1_s_32));
8031 dpo_10_10_10_2 =
8032 fib_entry_contribute_ip_forwarding(
8033 fib_table_lookup_exact_match(0, &pfx_10_10_10_2_s_32));
8034
8035 fib_test_lb_bucket_t lb_o_10_10_10_1 = {
8036 .type = FT_LB_O_LB,
8037 .lb = {
8038 .lb = dpo_10_10_10_1->dpoi_index,
8039 },
8040 };
8041 fib_test_lb_bucket_t lb_o_10_10_10_2 = {
8042 .type = FT_LB_O_LB,
8043 .lb = {
8044 .lb = dpo_10_10_10_2->dpoi_index,
8045 },
8046 };
8047
8048 /*
8049 * A prefix via the adj-fib that is BFD down => DROP
8050 */
8051 fei = fib_table_entry_path_add(0,
8052 &pfx_200_0_0_0_s_24,
8053 FIB_SOURCE_API,
8054 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008055 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07008056 &nh_10_10_10_2,
8057 ~0, // recursive
8058 0, // default fib index
8059 1,
8060 NULL,
8061 FIB_ROUTE_PATH_FLAG_NONE);
8062 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
8063 "%U resolves via drop",
8064 format_fib_prefix, &pfx_200_0_0_0_s_24);
8065
8066 /*
8067 * add a path via the UP BFD adj-fib.
8068 * we expect that the DOWN BFD ADJ FIB is not used.
8069 */
8070 fei = fib_table_entry_path_add(0,
8071 &pfx_200_0_0_0_s_24,
8072 FIB_SOURCE_API,
8073 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008074 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07008075 &nh_10_10_10_1,
8076 ~0, // recursive
8077 0, // default fib index
8078 1,
8079 NULL,
8080 FIB_ROUTE_PATH_FLAG_NONE);
8081
8082 FIB_TEST(fib_test_validate_entry(fei,
8083 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8084 1,
8085 &lb_o_10_10_10_1),
8086 "Recursive %U only UP BFD adj-fibs",
8087 format_fib_prefix, &pfx_200_0_0_0_s_24);
8088
8089 /*
8090 * Send a BFD state change to UP - both sessions are now up
8091 * the recursive prefix should LB over both
8092 */
8093 bfd_10_10_10_2.local_state = BFD_STATE_up;
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 2,
8100 &lb_o_10_10_10_1,
8101 &lb_o_10_10_10_2),
8102 "Recursive %U via both UP BFD adj-fibs",
8103 format_fib_prefix, &pfx_200_0_0_0_s_24);
8104
8105 /*
8106 * Send a BFD state change to DOWN
8107 * the recursive prefix should exclude the down
8108 */
8109 bfd_10_10_10_2.local_state = BFD_STATE_down;
8110 fib_bfd_notify (BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_2);
8111
8112
8113 FIB_TEST(fib_test_validate_entry(fei,
8114 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8115 1,
8116 &lb_o_10_10_10_1),
8117 "Recursive %U via only UP",
8118 format_fib_prefix, &pfx_200_0_0_0_s_24);
8119
8120 /*
8121 * Delete the BFD session while it is in the DOWN state.
8122 * FIB should consider the entry's state as back up
8123 */
8124 fib_bfd_notify (BFD_LISTEN_EVENT_DELETE, &bfd_10_10_10_2);
8125
8126 FIB_TEST(fib_test_validate_entry(fei,
8127 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8128 2,
8129 &lb_o_10_10_10_1,
8130 &lb_o_10_10_10_2),
8131 "Recursive %U via both UP BFD adj-fibs post down session delete",
8132 format_fib_prefix, &pfx_200_0_0_0_s_24);
8133
8134 /*
8135 * Delete the BFD other session while it is in the UP state.
8136 */
8137 fib_bfd_notify (BFD_LISTEN_EVENT_DELETE, &bfd_10_10_10_1);
8138
8139 FIB_TEST(fib_test_validate_entry(fei,
8140 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8141 2,
8142 &lb_o_10_10_10_1,
8143 &lb_o_10_10_10_2),
8144 "Recursive %U via both UP BFD adj-fibs post up session delete",
8145 format_fib_prefix, &pfx_200_0_0_0_s_24);
8146
8147 /*
8148 * cleaup
8149 */
8150 fib_table_entry_delete(0, &pfx_200_0_0_0_s_24, FIB_SOURCE_API);
8151 fib_table_entry_delete(0, &pfx_10_10_10_1_s_32, FIB_SOURCE_ADJ);
8152 fib_table_entry_delete(0, &pfx_10_10_10_2_s_32, FIB_SOURCE_ADJ);
8153
8154 fib_table_entry_delete(0, &pfx_10_10_10_10_s_32, FIB_SOURCE_INTERFACE);
8155 fib_table_entry_delete(0, &pfx_10_10_10_10_s_24, FIB_SOURCE_INTERFACE);
8156
8157 adj_unlock(ai_10_10_10_1);
8158 /*
8159 * test no-one left behind
8160 */
8161 FIB_TEST((n_feis == fib_entry_pool_size()), "Entries gone");
8162 FIB_TEST(0 == adj_nbr_db_size(), "All adjacencies removed");
8163
8164 /*
8165 * Single-hop BFD tests
8166 */
8167 bfd_10_10_10_1.hop_type = BFD_HOP_TYPE_SINGLE;
8168 bfd_10_10_10_1.udp.key.sw_if_index = tm->hw[0]->sw_if_index;
8169
8170 adj_bfd_notify(BFD_LISTEN_EVENT_CREATE, &bfd_10_10_10_1);
8171
8172 ai_10_10_10_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
8173 VNET_LINK_IP4,
8174 &nh_10_10_10_1,
8175 tm->hw[0]->sw_if_index);
8176 /*
8177 * whilst the BFD session is not signalled, the adj is up
8178 */
8179 FIB_TEST(adj_is_up(ai_10_10_10_1), "Adj state up on uninit session");
8180
8181 /*
8182 * bring the BFD session up
8183 */
8184 bfd_10_10_10_1.local_state = BFD_STATE_up;
8185 adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_1);
8186 FIB_TEST(adj_is_up(ai_10_10_10_1), "Adj state up on UP session");
8187
8188 /*
8189 * bring the BFD session down
8190 */
8191 bfd_10_10_10_1.local_state = BFD_STATE_down;
8192 adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_1);
8193 FIB_TEST(!adj_is_up(ai_10_10_10_1), "Adj state down on DOWN session");
8194
8195
8196 /*
8197 * add an attached next hop FIB entry via the down adj
8198 */
8199 fib_prefix_t pfx_5_5_5_5_s_32 = {
8200 .fp_addr = {
8201 .ip4 = {
8202 .as_u32 = clib_host_to_net_u32(0x05050505),
8203 },
8204 },
8205 .fp_len = 32,
8206 .fp_proto = FIB_PROTOCOL_IP4,
8207 };
8208
8209 fei = fib_table_entry_path_add(0,
8210 &pfx_5_5_5_5_s_32,
8211 FIB_SOURCE_CLI,
8212 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008213 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07008214 &nh_10_10_10_1,
8215 tm->hw[0]->sw_if_index,
8216 ~0, // invalid fib index
8217 1,
8218 NULL,
8219 FIB_ROUTE_PATH_FLAG_NONE);
8220 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
8221 "%U resolves via drop",
8222 format_fib_prefix, &pfx_5_5_5_5_s_32);
8223
8224 /*
8225 * Add a path via an ADJ that is up
8226 */
8227 adj_index_t ai_10_10_10_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
8228 VNET_LINK_IP4,
8229 &nh_10_10_10_2,
8230 tm->hw[0]->sw_if_index);
8231
8232 fib_test_lb_bucket_t adj_o_10_10_10_2 = {
8233 .type = FT_LB_ADJ,
8234 .adj = {
8235 .adj = ai_10_10_10_2,
8236 },
8237 };
8238 adj_o_10_10_10_1.adj.adj = ai_10_10_10_1;
8239
8240 fei = fib_table_entry_path_add(0,
8241 &pfx_5_5_5_5_s_32,
8242 FIB_SOURCE_CLI,
8243 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008244 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07008245 &nh_10_10_10_2,
8246 tm->hw[0]->sw_if_index,
8247 ~0, // invalid fib index
8248 1,
8249 NULL,
8250 FIB_ROUTE_PATH_FLAG_NONE);
8251
8252 FIB_TEST(fib_test_validate_entry(fei,
8253 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8254 1,
8255 &adj_o_10_10_10_2),
8256 "BFD sourced %U via %U",
8257 format_fib_prefix, &pfx_5_5_5_5_s_32,
8258 format_ip_adjacency, ai_10_10_10_2, FORMAT_IP_ADJACENCY_NONE);
8259
8260 /*
8261 * Bring up the down session - should now LB
8262 */
8263 bfd_10_10_10_1.local_state = BFD_STATE_up;
8264 adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_1);
8265 FIB_TEST(fib_test_validate_entry(fei,
8266 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8267 2,
8268 &adj_o_10_10_10_1,
8269 &adj_o_10_10_10_2),
8270 "BFD sourced %U via noth adjs",
8271 format_fib_prefix, &pfx_5_5_5_5_s_32);
8272
8273 /*
8274 * remove the BFD session state from the adj
8275 */
8276 adj_bfd_notify(BFD_LISTEN_EVENT_DELETE, &bfd_10_10_10_1);
8277
8278 /*
8279 * clean-up
8280 */
8281 fib_table_entry_delete(0, &pfx_5_5_5_5_s_32, FIB_SOURCE_CLI);
8282 adj_unlock(ai_10_10_10_1);
8283 adj_unlock(ai_10_10_10_2);
8284
8285 /*
8286 * test no-one left behind
8287 */
8288 FIB_TEST((n_feis == fib_entry_pool_size()), "Entries gone");
8289 FIB_TEST(0 == adj_nbr_db_size(), "All adjacencies removed");
8290 return (0);
8291}
8292
Neale Ranns0ebe8d72016-12-08 19:48:11 +00008293static int
8294lfib_test (void)
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008295{
8296 const mpls_label_t deag_label = 50;
Neale Ranns31ed7442018-02-23 05:29:09 -08008297 dpo_id_t dpo = DPO_INVALID;
8298 const mpls_disp_dpo_t *mdd;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008299 const u32 lfib_index = 0;
8300 const u32 fib_index = 0;
Neale Ranns31ed7442018-02-23 05:29:09 -08008301 const lookup_dpo_t *lkd;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008302 const dpo_id_t *dpo1;
8303 fib_node_index_t lfe;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008304 test_main_t *tm;
8305 int lb_count;
Neale Rannsad422ed2016-11-02 14:20:04 +00008306 adj_index_t ai_mpls_10_10_10_1;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008307
8308 tm = &test_main;
8309 lb_count = pool_elts(load_balance_pool);
8310
8311 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
8312 adj_nbr_db_size());
8313
8314 /*
8315 * MPLS enable an interface so we get the MPLS table created
8316 */
Neale Ranns2297af02017-09-12 09:45:04 -07008317 mpls_table_create(MPLS_FIB_DEFAULT_TABLE_ID, FIB_SOURCE_API, NULL);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008318 mpls_sw_interface_enable_disable(&mpls_main,
8319 tm->hw[0]->sw_if_index,
Neale Ranns15002542017-09-10 04:39:11 -07008320 1, 1);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008321
Neale Rannsad422ed2016-11-02 14:20:04 +00008322 ip46_address_t nh_10_10_10_1 = {
8323 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
8324 };
8325 ai_mpls_10_10_10_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
8326 VNET_LINK_MPLS,
8327 &nh_10_10_10_1,
8328 tm->hw[0]->sw_if_index);
8329
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008330 /*
8331 * Test the specials stack properly.
8332 */
8333 fib_prefix_t exp_null_v6_pfx = {
8334 .fp_proto = FIB_PROTOCOL_MPLS,
8335 .fp_eos = MPLS_EOS,
8336 .fp_label = MPLS_IETF_IPV6_EXPLICIT_NULL_LABEL,
8337 .fp_payload_proto = DPO_PROTO_IP6,
8338 };
8339 lfe = fib_table_lookup(lfib_index, &exp_null_v6_pfx);
8340 FIB_TEST((FIB_NODE_INDEX_INVALID != lfe),
8341 "%U/%U present",
8342 format_mpls_unicast_label, MPLS_IETF_IPV6_EXPLICIT_NULL_LABEL,
8343 format_mpls_eos_bit, MPLS_EOS);
8344 fib_entry_contribute_forwarding(lfe,
8345 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8346 &dpo);
8347 dpo1 = load_balance_get_bucket(dpo.dpoi_index, 0);
8348 lkd = lookup_dpo_get(dpo1->dpoi_index);
8349
8350 FIB_TEST((fib_index == lkd->lkd_fib_index),
8351 "%U/%U is deag in %d %U",
8352 format_mpls_unicast_label, deag_label,
8353 format_mpls_eos_bit, MPLS_EOS,
8354 lkd->lkd_fib_index,
8355 format_dpo_id, &dpo, 0);
8356 FIB_TEST((LOOKUP_INPUT_DST_ADDR == lkd->lkd_input),
8357 "%U/%U is dst deag",
8358 format_mpls_unicast_label, deag_label,
8359 format_mpls_eos_bit, MPLS_EOS);
8360 FIB_TEST((LOOKUP_TABLE_FROM_INPUT_INTERFACE == lkd->lkd_table),
8361 "%U/%U is lookup in interface's table",
8362 format_mpls_unicast_label, deag_label,
8363 format_mpls_eos_bit, MPLS_EOS);
8364 FIB_TEST((DPO_PROTO_IP6 == lkd->lkd_proto),
8365 "%U/%U is %U dst deag",
8366 format_mpls_unicast_label, deag_label,
8367 format_mpls_eos_bit, MPLS_EOS,
8368 format_dpo_proto, lkd->lkd_proto);
8369
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008370 /*
8371 * A route deag route for EOS
8372 */
8373 fib_prefix_t pfx = {
8374 .fp_proto = FIB_PROTOCOL_MPLS,
8375 .fp_eos = MPLS_EOS,
8376 .fp_label = deag_label,
8377 .fp_payload_proto = DPO_PROTO_IP4,
8378 };
8379 lfe = fib_table_entry_path_add(lfib_index,
8380 &pfx,
8381 FIB_SOURCE_CLI,
8382 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008383 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008384 &zero_addr,
8385 ~0,
8386 fib_index,
8387 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00008388 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008389 FIB_ROUTE_PATH_FLAG_NONE);
8390
8391 FIB_TEST((lfe == fib_table_lookup(lfib_index, &pfx)),
8392 "%U/%U present",
8393 format_mpls_unicast_label, deag_label,
8394 format_mpls_eos_bit, MPLS_EOS);
8395
8396 fib_entry_contribute_forwarding(lfe,
8397 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8398 &dpo);
8399 dpo1 = load_balance_get_bucket(dpo.dpoi_index, 0);
Neale Ranns31ed7442018-02-23 05:29:09 -08008400 mdd = mpls_disp_dpo_get(dpo1->dpoi_index);
8401
8402 FIB_TEST((FIB_MPLS_LSP_MODE_PIPE == mdd->mdd_mode),
8403 "%U/%U disp is pipe mode",
8404 format_mpls_unicast_label, deag_label,
8405 format_mpls_eos_bit, MPLS_EOS);
8406
8407 lkd = lookup_dpo_get(mdd->mdd_dpo.dpoi_index);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008408
8409 FIB_TEST((fib_index == lkd->lkd_fib_index),
8410 "%U/%U is deag in %d %U",
8411 format_mpls_unicast_label, deag_label,
8412 format_mpls_eos_bit, MPLS_EOS,
8413 lkd->lkd_fib_index,
8414 format_dpo_id, &dpo, 0);
8415 FIB_TEST((LOOKUP_INPUT_DST_ADDR == lkd->lkd_input),
8416 "%U/%U is dst deag",
8417 format_mpls_unicast_label, deag_label,
8418 format_mpls_eos_bit, MPLS_EOS);
8419 FIB_TEST((DPO_PROTO_IP4 == lkd->lkd_proto),
8420 "%U/%U is %U dst deag",
8421 format_mpls_unicast_label, deag_label,
8422 format_mpls_eos_bit, MPLS_EOS,
8423 format_dpo_proto, lkd->lkd_proto);
8424
8425 fib_table_entry_delete_index(lfe, FIB_SOURCE_CLI);
8426
8427 FIB_TEST((FIB_NODE_INDEX_INVALID == fib_table_lookup(lfib_index,
8428 &pfx)),
8429 "%U/%U not present",
8430 format_mpls_unicast_label, deag_label,
8431 format_mpls_eos_bit, MPLS_EOS);
Neale Ranns31ed7442018-02-23 05:29:09 -08008432 dpo_reset(&dpo);
8433
8434 /*
8435 * A route deag route for EOS with LSP mode uniform
8436 */
8437 fib_mpls_label_t *l_pops = NULL, l_pop = {
8438 .fml_value = MPLS_LABEL_POP,
8439 .fml_mode = FIB_MPLS_LSP_MODE_UNIFORM,
8440 };
8441 vec_add1(l_pops, l_pop);
8442 lfe = fib_table_entry_path_add(lfib_index,
8443 &pfx,
8444 FIB_SOURCE_CLI,
8445 FIB_ENTRY_FLAG_NONE,
8446 DPO_PROTO_IP4,
8447 &zero_addr,
8448 ~0,
8449 fib_index,
8450 1,
8451 l_pops,
8452 FIB_ROUTE_PATH_FLAG_NONE);
8453
8454 FIB_TEST((lfe == fib_table_lookup(lfib_index, &pfx)),
8455 "%U/%U present",
8456 format_mpls_unicast_label, deag_label,
8457 format_mpls_eos_bit, MPLS_EOS);
8458
8459 fib_entry_contribute_forwarding(lfe,
8460 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8461 &dpo);
8462 dpo1 = load_balance_get_bucket(dpo.dpoi_index, 0);
8463 mdd = mpls_disp_dpo_get(dpo1->dpoi_index);
8464
8465 FIB_TEST((FIB_MPLS_LSP_MODE_UNIFORM == mdd->mdd_mode),
8466 "%U/%U disp is uniform mode",
8467 format_mpls_unicast_label, deag_label,
8468 format_mpls_eos_bit, MPLS_EOS);
8469
8470 lkd = lookup_dpo_get(mdd->mdd_dpo.dpoi_index);
8471
8472 FIB_TEST((fib_index == lkd->lkd_fib_index),
8473 "%U/%U is deag in %d %U",
8474 format_mpls_unicast_label, deag_label,
8475 format_mpls_eos_bit, MPLS_EOS,
8476 lkd->lkd_fib_index,
8477 format_dpo_id, &dpo, 0);
8478 FIB_TEST((LOOKUP_INPUT_DST_ADDR == lkd->lkd_input),
8479 "%U/%U is dst deag",
8480 format_mpls_unicast_label, deag_label,
8481 format_mpls_eos_bit, MPLS_EOS);
8482 FIB_TEST((DPO_PROTO_IP4 == lkd->lkd_proto),
8483 "%U/%U is %U dst deag",
8484 format_mpls_unicast_label, deag_label,
8485 format_mpls_eos_bit, MPLS_EOS,
8486 format_dpo_proto, lkd->lkd_proto);
8487
8488 fib_table_entry_delete_index(lfe, FIB_SOURCE_CLI);
8489
8490 FIB_TEST((FIB_NODE_INDEX_INVALID == fib_table_lookup(lfib_index,
8491 &pfx)),
8492 "%U/%U not present",
8493 format_mpls_unicast_label, deag_label,
8494 format_mpls_eos_bit, MPLS_EOS);
8495 dpo_reset(&dpo);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008496
8497 /*
8498 * A route deag route for non-EOS
8499 */
8500 pfx.fp_eos = MPLS_NON_EOS;
8501 lfe = fib_table_entry_path_add(lfib_index,
8502 &pfx,
8503 FIB_SOURCE_CLI,
8504 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008505 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008506 &zero_addr,
8507 ~0,
8508 lfib_index,
8509 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00008510 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008511 FIB_ROUTE_PATH_FLAG_NONE);
8512
8513 FIB_TEST((lfe == fib_table_lookup(lfib_index, &pfx)),
8514 "%U/%U present",
8515 format_mpls_unicast_label, deag_label,
8516 format_mpls_eos_bit, MPLS_NON_EOS);
8517
8518 fib_entry_contribute_forwarding(lfe,
8519 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
8520 &dpo);
8521 dpo1 = load_balance_get_bucket(dpo.dpoi_index, 0);
8522 lkd = lookup_dpo_get(dpo1->dpoi_index);
8523
8524 FIB_TEST((fib_index == lkd->lkd_fib_index),
8525 "%U/%U is deag in %d %U",
8526 format_mpls_unicast_label, deag_label,
8527 format_mpls_eos_bit, MPLS_NON_EOS,
8528 lkd->lkd_fib_index,
8529 format_dpo_id, &dpo, 0);
8530 FIB_TEST((LOOKUP_INPUT_DST_ADDR == lkd->lkd_input),
8531 "%U/%U is dst deag",
8532 format_mpls_unicast_label, deag_label,
8533 format_mpls_eos_bit, MPLS_NON_EOS);
8534
8535 FIB_TEST((DPO_PROTO_MPLS == lkd->lkd_proto),
8536 "%U/%U is %U dst deag",
8537 format_mpls_unicast_label, deag_label,
8538 format_mpls_eos_bit, MPLS_NON_EOS,
8539 format_dpo_proto, lkd->lkd_proto);
8540
8541 fib_table_entry_delete_index(lfe, FIB_SOURCE_CLI);
8542
8543 FIB_TEST((FIB_NODE_INDEX_INVALID == fib_table_lookup(lfib_index,
8544 &pfx)),
8545 "%U/%U not present",
8546 format_mpls_unicast_label, deag_label,
8547 format_mpls_eos_bit, MPLS_EOS);
8548
Neale Rannsad422ed2016-11-02 14:20:04 +00008549 dpo_reset(&dpo);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008550
Neale Rannsad422ed2016-11-02 14:20:04 +00008551 /*
8552 * An MPLS x-connect
8553 */
8554 fib_prefix_t pfx_1200 = {
8555 .fp_len = 21,
8556 .fp_proto = FIB_PROTOCOL_MPLS,
8557 .fp_label = 1200,
8558 .fp_eos = MPLS_NON_EOS,
8559 };
8560 fib_test_lb_bucket_t neos_o_10_10_10_1 = {
8561 .type = FT_LB_LABEL_STACK_O_ADJ,
8562 .label_stack_o_adj = {
8563 .adj = ai_mpls_10_10_10_1,
8564 .label_stack_size = 4,
8565 .label_stack = {
8566 200, 300, 400, 500,
8567 },
8568 .eos = MPLS_NON_EOS,
8569 },
8570 };
8571 dpo_id_t neos_1200 = DPO_INVALID;
8572 dpo_id_t ip_1200 = DPO_INVALID;
Neale Ranns31ed7442018-02-23 05:29:09 -08008573 fib_mpls_label_t *l200 = NULL;
8574 u32 ii;
8575 for (ii = 0; ii < 4; ii++)
8576 {
8577 fib_mpls_label_t fml = {
8578 .fml_value = 200 + (ii * 100),
8579 };
8580 vec_add1(l200, fml);
8581 };
Neale Rannsad422ed2016-11-02 14:20:04 +00008582
8583 lfe = fib_table_entry_update_one_path(fib_index,
8584 &pfx_1200,
8585 FIB_SOURCE_API,
8586 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008587 DPO_PROTO_IP4,
Neale Rannsad422ed2016-11-02 14:20:04 +00008588 &nh_10_10_10_1,
8589 tm->hw[0]->sw_if_index,
8590 ~0, // invalid fib index
8591 1,
8592 l200,
8593 FIB_ROUTE_PATH_FLAG_NONE);
8594
8595 FIB_TEST(fib_test_validate_entry(lfe,
8596 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
8597 1,
8598 &neos_o_10_10_10_1),
8599 "1200/0 LB 1 buckets via: "
8600 "adj 10.10.11.1");
8601
8602 /*
8603 * A recursive route via the MPLS x-connect
8604 */
8605 fib_prefix_t pfx_2_2_2_3_s_32 = {
8606 .fp_len = 32,
8607 .fp_proto = FIB_PROTOCOL_IP4,
8608 .fp_addr = {
8609 .ip4.as_u32 = clib_host_to_net_u32(0x02020203),
8610 },
8611 };
8612 fib_route_path_t *rpaths = NULL, rpath = {
Neale Rannsda78f952017-05-24 09:15:43 -07008613 .frp_proto = DPO_PROTO_MPLS,
Neale Rannsad422ed2016-11-02 14:20:04 +00008614 .frp_local_label = 1200,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008615 .frp_eos = MPLS_NON_EOS,
Neale Rannsad422ed2016-11-02 14:20:04 +00008616 .frp_sw_if_index = ~0, // recurive
8617 .frp_fib_index = 0, // Default MPLS fib
8618 .frp_weight = 1,
8619 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
8620 .frp_label_stack = NULL,
8621 };
8622 vec_add1(rpaths, rpath);
8623
8624 fib_table_entry_path_add2(fib_index,
8625 &pfx_2_2_2_3_s_32,
8626 FIB_SOURCE_API,
8627 FIB_ENTRY_FLAG_NONE,
8628 rpaths);
8629
8630 /*
8631 * A labelled recursive route via the MPLS x-connect
8632 */
8633 fib_prefix_t pfx_2_2_2_4_s_32 = {
8634 .fp_len = 32,
8635 .fp_proto = FIB_PROTOCOL_IP4,
8636 .fp_addr = {
8637 .ip4.as_u32 = clib_host_to_net_u32(0x02020204),
8638 },
8639 };
Neale Ranns31ed7442018-02-23 05:29:09 -08008640 fib_mpls_label_t *l999 = NULL, fml_999 = {
8641 .fml_value = 999,
8642 };
8643 vec_add1(l999, fml_999);
Neale Rannsad422ed2016-11-02 14:20:04 +00008644 rpaths[0].frp_label_stack = l999,
8645
8646 fib_table_entry_path_add2(fib_index,
8647 &pfx_2_2_2_4_s_32,
8648 FIB_SOURCE_API,
8649 FIB_ENTRY_FLAG_NONE,
8650 rpaths);
8651
8652 fib_entry_contribute_forwarding(fib_table_lookup(fib_index, &pfx_1200),
8653 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8654 &ip_1200);
8655 fib_entry_contribute_forwarding(fib_table_lookup(fib_index, &pfx_1200),
8656 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
8657 &neos_1200);
8658
8659 fib_test_lb_bucket_t ip_o_1200 = {
8660 .type = FT_LB_O_LB,
8661 .lb = {
8662 .lb = ip_1200.dpoi_index,
8663 },
8664 };
8665 fib_test_lb_bucket_t mpls_o_1200 = {
8666 .type = FT_LB_LABEL_O_LB,
8667 .label_o_lb = {
8668 .lb = neos_1200.dpoi_index,
8669 .label = 999,
8670 .eos = MPLS_EOS,
8671 },
8672 };
8673
8674 lfe = fib_table_lookup(fib_index, &pfx_2_2_2_3_s_32);
8675 FIB_TEST(fib_test_validate_entry(lfe,
8676 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8677 1,
8678 &ip_o_1200),
8679 "2.2.2.2.3/32 LB 1 buckets via: label 1200 EOS");
8680 lfe = fib_table_lookup(fib_index, &pfx_2_2_2_4_s_32);
8681 FIB_TEST(fib_test_validate_entry(lfe,
8682 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8683 1,
8684 &mpls_o_1200),
8685 "2.2.2.2.4/32 LB 1 buckets via: label 1200 non-EOS");
8686
8687 fib_table_entry_delete(fib_index, &pfx_1200, FIB_SOURCE_API);
8688 fib_table_entry_delete(fib_index, &pfx_2_2_2_3_s_32, FIB_SOURCE_API);
8689 fib_table_entry_delete(fib_index, &pfx_2_2_2_4_s_32, FIB_SOURCE_API);
8690
8691 dpo_reset(&neos_1200);
8692 dpo_reset(&ip_1200);
8693
8694 /*
8695 * A recursive via a label that does not exist
8696 */
8697 fib_test_lb_bucket_t bucket_drop = {
Neale Rannsd792d9c2017-10-21 10:53:20 -07008698 .type = FT_LB_DROP,
Neale Rannsad422ed2016-11-02 14:20:04 +00008699 .special = {
Neale Rannsf12a83f2017-04-18 09:09:40 -07008700 .adj = DPO_PROTO_IP4,
8701 },
8702 };
8703 fib_test_lb_bucket_t mpls_bucket_drop = {
Neale Rannsd792d9c2017-10-21 10:53:20 -07008704 .type = FT_LB_DROP,
Neale Rannsf12a83f2017-04-18 09:09:40 -07008705 .special = {
Neale Rannsad422ed2016-11-02 14:20:04 +00008706 .adj = DPO_PROTO_MPLS,
8707 },
8708 };
8709
8710 rpaths[0].frp_label_stack = NULL;
8711 lfe = fib_table_entry_path_add2(fib_index,
8712 &pfx_2_2_2_4_s_32,
8713 FIB_SOURCE_API,
8714 FIB_ENTRY_FLAG_NONE,
8715 rpaths);
8716
8717 fib_entry_contribute_forwarding(fib_table_lookup(fib_index, &pfx_1200),
8718 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8719 &ip_1200);
8720 ip_o_1200.lb.lb = ip_1200.dpoi_index;
8721
8722 FIB_TEST(fib_test_validate_entry(lfe,
8723 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8724 1,
Neale Ranns57b58602017-07-15 07:37:25 -07008725 &bucket_drop),
8726 "2.2.2.2.4/32 LB 1 buckets via: drop");
Neale Rannsad422ed2016-11-02 14:20:04 +00008727 lfe = fib_table_lookup(fib_index, &pfx_1200);
8728 FIB_TEST(fib_test_validate_entry(lfe,
8729 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8730 1,
8731 &bucket_drop),
Neale Rannsf12a83f2017-04-18 09:09:40 -07008732 "1200/neos LB 1 buckets via: ip4-DROP");
8733 FIB_TEST(fib_test_validate_entry(lfe,
8734 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
8735 1,
8736 &mpls_bucket_drop),
8737 "1200/neos LB 1 buckets via: mpls-DROP");
Neale Rannsad422ed2016-11-02 14:20:04 +00008738
8739 fib_table_entry_delete(fib_index, &pfx_2_2_2_4_s_32, FIB_SOURCE_API);
8740
8741 dpo_reset(&ip_1200);
8742
8743 /*
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008744 * An rx-interface route.
8745 * like the tail of an mcast LSP
8746 */
8747 dpo_id_t idpo = DPO_INVALID;
8748
Neale Ranns43161a82017-08-12 02:12:00 -07008749 interface_rx_dpo_add_or_lock(DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008750 tm->hw[0]->sw_if_index,
8751 &idpo);
8752
8753 fib_prefix_t pfx_2500 = {
8754 .fp_len = 21,
8755 .fp_proto = FIB_PROTOCOL_MPLS,
8756 .fp_label = 2500,
8757 .fp_eos = MPLS_EOS,
8758 .fp_payload_proto = DPO_PROTO_IP4,
8759 };
8760 fib_test_lb_bucket_t rx_intf_0 = {
8761 .type = FT_LB_INTF,
8762 .adj = {
8763 .adj = idpo.dpoi_index,
8764 },
8765 };
8766
8767 lfe = fib_table_entry_update_one_path(fib_index,
8768 &pfx_2500,
8769 FIB_SOURCE_API,
8770 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008771 DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008772 NULL,
8773 tm->hw[0]->sw_if_index,
8774 ~0, // invalid fib index
8775 0,
8776 NULL,
8777 FIB_ROUTE_PATH_INTF_RX);
8778 FIB_TEST(fib_test_validate_entry(lfe,
8779 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8780 1,
8781 &rx_intf_0),
8782 "2500 rx-interface 0");
8783 fib_table_entry_delete(fib_index, &pfx_2500, FIB_SOURCE_API);
8784
8785 /*
8786 * An MPLS mulicast entry
8787 */
8788 fib_prefix_t pfx_3500 = {
8789 .fp_len = 21,
8790 .fp_proto = FIB_PROTOCOL_MPLS,
8791 .fp_label = 3500,
8792 .fp_eos = MPLS_EOS,
8793 .fp_payload_proto = DPO_PROTO_IP4,
8794 };
8795 fib_test_rep_bucket_t mc_0 = {
8796 .type = FT_REP_LABEL_O_ADJ,
8797 .label_o_adj = {
8798 .adj = ai_mpls_10_10_10_1,
8799 .label = 3300,
8800 .eos = MPLS_EOS,
8801 },
8802 };
8803 fib_test_rep_bucket_t mc_intf_0 = {
8804 .type = FT_REP_INTF,
8805 .adj = {
8806 .adj = idpo.dpoi_index,
8807 },
8808 };
Neale Ranns31ed7442018-02-23 05:29:09 -08008809 fib_mpls_label_t *l3300 = NULL, fml_3300 = {
8810 .fml_value = 3300,
8811 };
8812 vec_add1(l3300, fml_3300);
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008813
8814 lfe = fib_table_entry_update_one_path(lfib_index,
8815 &pfx_3500,
8816 FIB_SOURCE_API,
8817 FIB_ENTRY_FLAG_MULTICAST,
Neale Rannsda78f952017-05-24 09:15:43 -07008818 DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008819 &nh_10_10_10_1,
8820 tm->hw[0]->sw_if_index,
8821 ~0, // invalid fib index
8822 1,
8823 l3300,
8824 FIB_ROUTE_PATH_FLAG_NONE);
8825 FIB_TEST(fib_test_validate_entry(lfe,
8826 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8827 1,
8828 &mc_0),
8829 "3500 via replicate over 10.10.10.1");
8830
8831 /*
8832 * MPLS Bud-node. Add a replication via an interface-receieve path
8833 */
8834 lfe = fib_table_entry_path_add(lfib_index,
8835 &pfx_3500,
8836 FIB_SOURCE_API,
8837 FIB_ENTRY_FLAG_MULTICAST,
Neale Rannsda78f952017-05-24 09:15:43 -07008838 DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008839 NULL,
8840 tm->hw[0]->sw_if_index,
8841 ~0, // invalid fib index
8842 0,
8843 NULL,
8844 FIB_ROUTE_PATH_INTF_RX);
8845 FIB_TEST(fib_test_validate_entry(lfe,
8846 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8847 2,
8848 &mc_0,
8849 &mc_intf_0),
8850 "3500 via replicate over 10.10.10.1 and interface-rx");
8851
8852 /*
8853 * Add a replication via an interface-free for-us path
8854 */
8855 fib_test_rep_bucket_t mc_disp = {
8856 .type = FT_REP_DISP_MFIB_LOOKUP,
8857 .adj = {
8858 .adj = idpo.dpoi_index,
8859 },
8860 };
8861 lfe = fib_table_entry_path_add(lfib_index,
8862 &pfx_3500,
8863 FIB_SOURCE_API,
8864 FIB_ENTRY_FLAG_MULTICAST,
Neale Rannsda78f952017-05-24 09:15:43 -07008865 DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008866 NULL,
8867 5, // rpf-id
8868 0, // default table
8869 0,
8870 NULL,
8871 FIB_ROUTE_PATH_RPF_ID);
8872 FIB_TEST(fib_test_validate_entry(lfe,
8873 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8874 3,
8875 &mc_0,
8876 &mc_disp,
8877 &mc_intf_0),
8878 "3500 via replicate over 10.10.10.1 and interface-rx");
8879
8880
8881
8882 fib_table_entry_delete(fib_index, &pfx_3500, FIB_SOURCE_API);
8883 dpo_reset(&idpo);
8884
8885 /*
Neale Rannsad422ed2016-11-02 14:20:04 +00008886 * cleanup
8887 */
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008888 mpls_sw_interface_enable_disable(&mpls_main,
8889 tm->hw[0]->sw_if_index,
Neale Ranns15002542017-09-10 04:39:11 -07008890 0, 1);
8891 mpls_table_delete(MPLS_FIB_DEFAULT_TABLE_ID, FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008892
Neale Ranns31ed7442018-02-23 05:29:09 -08008893 FIB_TEST(0 == pool_elts(mpls_disp_dpo_pool),
8894 "mpls_disp_dpo resources freed %d of %d",
8895 0, pool_elts(mpls_disp_dpo_pool));
Neale Rannsad422ed2016-11-02 14:20:04 +00008896 FIB_TEST(lb_count == pool_elts(load_balance_pool),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008897 "Load-balance resources freed %d of %d",
Neale Rannsad422ed2016-11-02 14:20:04 +00008898 lb_count, pool_elts(load_balance_pool));
Neale Ranns43161a82017-08-12 02:12:00 -07008899 FIB_TEST(0 == pool_elts(interface_rx_dpo_pool),
8900 "interface_rx_dpo resources freed %d of %d",
8901 0, pool_elts(interface_rx_dpo_pool));
Neale Ranns0ebe8d72016-12-08 19:48:11 +00008902
8903 return (0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008904}
8905
Neale Ranns89541992017-04-06 04:41:02 -07008906static int
8907fib_test_inherit (void)
8908{
8909 fib_node_index_t fei;
8910 test_main_t *tm;
8911 int n_feis;
8912
8913 n_feis = fib_entry_pool_size();
8914 tm = &test_main;
8915
8916 const ip46_address_t nh_10_10_10_1 = {
8917 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
8918 };
8919 const ip46_address_t nh_10_10_10_2 = {
8920 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02),
8921 };
8922 const ip46_address_t nh_10_10_10_16 = {
8923 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a10),
8924 };
8925 const ip46_address_t nh_10_10_10_20 = {
8926 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a14),
8927 };
8928 const ip46_address_t nh_10_10_10_21 = {
8929 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a15),
8930 };
8931 const ip46_address_t nh_10_10_10_22 = {
8932 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a16),
8933 };
8934 const ip46_address_t nh_10_10_10_255 = {
8935 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0aff),
8936 };
8937 const ip46_address_t nh_10_10_10_0 = {
8938 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a00),
8939 };
8940 const ip46_address_t nh_10_10_0_0 = {
8941 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0000),
8942 };
8943
8944 /*
8945 * prefixes at the base of a sub-tree
8946 */
8947 const fib_prefix_t pfx_10_10_10_21_s_32 = {
8948 .fp_len = 32,
8949 .fp_proto = FIB_PROTOCOL_IP4,
8950 .fp_addr = nh_10_10_10_21,
8951 };
8952 const fib_prefix_t pfx_10_10_10_22_s_32 = {
8953 .fp_len = 32,
8954 .fp_proto = FIB_PROTOCOL_IP4,
8955 .fp_addr = nh_10_10_10_22,
8956 };
8957 const fib_prefix_t pfx_10_10_10_255_s_32 = {
8958 .fp_len = 32,
8959 .fp_proto = FIB_PROTOCOL_IP4,
8960 .fp_addr = nh_10_10_10_255,
8961 };
8962
8963 fib_table_entry_special_add(0,
8964 &pfx_10_10_10_21_s_32,
8965 FIB_SOURCE_CLI,
8966 FIB_ENTRY_FLAG_DROP);
8967 fib_table_entry_special_add(0,
8968 &pfx_10_10_10_22_s_32,
8969 FIB_SOURCE_CLI,
8970 FIB_ENTRY_FLAG_DROP);
8971 fib_table_entry_special_add(0,
8972 &pfx_10_10_10_255_s_32,
8973 FIB_SOURCE_CLI,
8974 FIB_ENTRY_FLAG_DROP);
8975
8976 /*
8977 * source an entry that pushes its state down the sub-tree
8978 */
8979 const fib_prefix_t pfx_10_10_10_16_s_28 = {
8980 .fp_len = 28,
8981 .fp_proto = FIB_PROTOCOL_IP4,
8982 .fp_addr = nh_10_10_10_16,
8983 };
8984 fib_table_entry_update_one_path(0,
8985 &pfx_10_10_10_16_s_28,
8986 FIB_SOURCE_API,
8987 FIB_ENTRY_FLAG_COVERED_INHERIT,
8988 DPO_PROTO_IP4,
8989 &nh_10_10_10_1,
8990 tm->hw[0]->sw_if_index,
8991 ~0,
8992 1,
8993 NULL,
8994 FIB_ROUTE_PATH_FLAG_NONE);
8995
8996 /*
8997 * this covering entry and all those below it should have
8998 * the same forwarding information.
8999 */
9000 adj_index_t ai_10_10_10_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
9001 VNET_LINK_IP4,
9002 &nh_10_10_10_1,
9003 tm->hw[0]->sw_if_index);
9004 fib_test_lb_bucket_t adj_o_10_10_10_1 = {
9005 .type = FT_LB_ADJ,
9006 .adj = {
9007 .adj = ai_10_10_10_1,
9008 },
9009 };
9010
9011 fei = fib_table_lookup(0, &pfx_10_10_10_16_s_28);
9012 FIB_TEST(fib_test_validate_entry(fei,
9013 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9014 1,
9015 &adj_o_10_10_10_1),
9016 "%U via 10.10.10.1",
9017 format_fib_prefix, &pfx_10_10_10_16_s_28);
9018 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
9019 FIB_TEST(fib_test_validate_entry(fei,
9020 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9021 1,
9022 &adj_o_10_10_10_1),
9023 "%U via 10.10.10.1",
9024 format_fib_prefix, &pfx_10_10_10_21_s_32);
9025 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32);
9026 FIB_TEST(fib_test_validate_entry(fei,
9027 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9028 1,
9029 &adj_o_10_10_10_1),
9030 "%U via 10.10.10.1",
9031 format_fib_prefix, &pfx_10_10_10_22_s_32);
9032 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
9033 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
9034 "%U resolves via drop",
9035 format_fib_prefix, &pfx_10_10_10_255_s_32);
9036
9037 /*
9038 * remove the inherting cover - covereds go back to drop
9039 */
9040 fib_table_entry_delete(0, &pfx_10_10_10_16_s_28, FIB_SOURCE_API);
9041
9042 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
9043 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
9044 "%U resolves via drop",
9045 format_fib_prefix, &pfx_10_10_10_21_s_32);
9046
9047 /*
9048 * source an entry that pushes its state down the sub-tree
9049 */
9050 const fib_prefix_t pfx_10_10_10_0_s_24 = {
9051 .fp_len = 24,
9052 .fp_proto = FIB_PROTOCOL_IP4,
9053 .fp_addr = nh_10_10_10_0,
9054 };
9055 fib_table_entry_update_one_path(0,
9056 &pfx_10_10_10_0_s_24,
9057 FIB_SOURCE_API,
9058 FIB_ENTRY_FLAG_COVERED_INHERIT,
9059 DPO_PROTO_IP4,
9060 &nh_10_10_10_1,
9061 tm->hw[0]->sw_if_index,
9062 ~0,
9063 1,
9064 NULL,
9065 FIB_ROUTE_PATH_FLAG_NONE);
9066
9067 /*
9068 * whole sub-tree now covered
9069 */
9070 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
9071 FIB_TEST(fib_test_validate_entry(fei,
9072 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9073 1,
9074 &adj_o_10_10_10_1),
9075 "%U via 10.10.10.1",
9076 format_fib_prefix, &pfx_10_10_10_0_s_24);
9077 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
9078 FIB_TEST(fib_test_validate_entry(fei,
9079 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9080 1,
9081 &adj_o_10_10_10_1),
9082 "%U via 10.10.10.1",
9083 format_fib_prefix, &pfx_10_10_10_21_s_32);
9084 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32);
9085 FIB_TEST(fib_test_validate_entry(fei,
9086 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9087 1,
9088 &adj_o_10_10_10_1),
9089 "%U via 10.10.10.1",
9090 format_fib_prefix, &pfx_10_10_10_22_s_32);
9091 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
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_255_s_32);
9098
9099 /*
9100 * insert a more specific into the sub-tree - expect inheritance
9101 * this one is directly covered by the root
9102 */
9103 fib_table_entry_special_add(0,
9104 &pfx_10_10_10_16_s_28,
9105 FIB_SOURCE_CLI,
9106 FIB_ENTRY_FLAG_DROP);
9107 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_16_s_28);
9108 FIB_TEST(fib_test_validate_entry(fei,
9109 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9110 1,
9111 &adj_o_10_10_10_1),
9112 "%U via 10.10.10.1",
9113 format_fib_prefix, &pfx_10_10_10_16_s_28);
9114
9115 /*
9116 * insert a more specific into the sub-tree - expect inheritance
9117 * this one is indirectly covered by the root
9118 */
9119 const fib_prefix_t pfx_10_10_10_20_s_30 = {
9120 .fp_len = 30,
9121 .fp_proto = FIB_PROTOCOL_IP4,
9122 .fp_addr = nh_10_10_10_20,
9123 };
9124 fib_table_entry_special_add(0,
9125 &pfx_10_10_10_20_s_30,
9126 FIB_SOURCE_CLI,
9127 FIB_ENTRY_FLAG_DROP);
9128 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_20_s_30);
9129 FIB_TEST(fib_test_validate_entry(fei,
9130 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9131 1,
9132 &adj_o_10_10_10_1),
9133 "%U via 10.10.10.1",
9134 format_fib_prefix, &pfx_10_10_10_20_s_30);
9135
9136 /*
9137 * remove the prefix from the middle of the sub-tree
9138 * the inherited source will be the only one remaining - expect
9139 * it to be withdrawn and hence the prefix is removed.
9140 */
9141 fib_table_entry_special_remove(0,
9142 &pfx_10_10_10_20_s_30,
9143 FIB_SOURCE_CLI);
9144 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_20_s_30);
9145 FIB_TEST((FIB_NODE_INDEX_INVALID == fei),
9146 "%U gone",
9147 format_fib_prefix, &pfx_10_10_10_20_s_30);
9148
9149 /*
9150 * inheriting source is modifed - expect the modification to be present
9151 * throughout the sub-tree
9152 */
9153 adj_index_t ai_10_10_10_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
9154 VNET_LINK_IP4,
9155 &nh_10_10_10_2,
9156 tm->hw[0]->sw_if_index);
9157 fib_test_lb_bucket_t adj_o_10_10_10_2 = {
9158 .type = FT_LB_ADJ,
9159 .adj = {
9160 .adj = ai_10_10_10_2,
9161 },
9162 };
9163
9164 fib_table_entry_update_one_path(0,
9165 &pfx_10_10_10_0_s_24,
9166 FIB_SOURCE_API,
9167 FIB_ENTRY_FLAG_COVERED_INHERIT,
9168 DPO_PROTO_IP4,
9169 &nh_10_10_10_2,
9170 tm->hw[0]->sw_if_index,
9171 ~0,
9172 1,
9173 NULL,
9174 FIB_ROUTE_PATH_FLAG_NONE);
9175 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
9176 FIB_TEST(fib_test_validate_entry(fei,
9177 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9178 1,
9179 &adj_o_10_10_10_2),
9180 "%U via 10.10.10.2",
9181 format_fib_prefix, &pfx_10_10_10_21_s_32);
9182 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32);
9183 FIB_TEST(fib_test_validate_entry(fei,
9184 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9185 1,
9186 &adj_o_10_10_10_2),
9187 "%U via 10.10.10.2",
9188 format_fib_prefix, &pfx_10_10_10_22_s_32);
9189 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
9190 FIB_TEST(fib_test_validate_entry(fei,
9191 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9192 1,
9193 &adj_o_10_10_10_2),
9194 "%U via 10.10.10.2",
9195 format_fib_prefix, &pfx_10_10_10_255_s_32);
9196 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
9197 FIB_TEST(fib_test_validate_entry(fei,
9198 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9199 1,
9200 &adj_o_10_10_10_2),
9201 "%U via 10.10.10.2",
9202 format_fib_prefix, &pfx_10_10_10_0_s_24);
9203
9204 /*
9205 * add the source that replaces inherited state.
9206 * inheriting source is not the best, so it doesn't push state.
9207 */
9208 fib_table_entry_update_one_path(0,
9209 &pfx_10_10_10_0_s_24,
9210 FIB_SOURCE_PLUGIN_HI,
9211 FIB_ENTRY_FLAG_NONE,
9212 DPO_PROTO_IP4,
9213 &nh_10_10_10_1,
9214 tm->hw[0]->sw_if_index,
9215 ~0,
9216 1,
9217 NULL,
9218 FIB_ROUTE_PATH_FLAG_NONE);
9219 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
9220 FIB_TEST(fib_test_validate_entry(fei,
9221 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9222 1,
9223 &adj_o_10_10_10_1),
9224 "%U via 10.10.10.1",
9225 format_fib_prefix, &pfx_10_10_10_0_s_24);
9226
9227 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
9228 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
9229 "%U resolves via drop",
9230 format_fib_prefix, &pfx_10_10_10_21_s_32);
9231 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32);
9232 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
9233 "%U resolves via drop",
9234 format_fib_prefix, &pfx_10_10_10_22_s_32);
9235 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
9236 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
9237 "%U resolves via drop",
9238 format_fib_prefix, &pfx_10_10_10_255_s_32);
9239 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_16_s_28);
9240 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
9241 "%U resolves via drop",
9242 format_fib_prefix, &pfx_10_10_10_16_s_28);
9243
9244 /*
9245 * withdraw the higher priority source and expect the inherited to return
9246 * throughout the sub-tree
9247 */
9248 fib_table_entry_delete(0, &pfx_10_10_10_0_s_24, FIB_SOURCE_PLUGIN_HI);
9249
9250 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
9251 FIB_TEST(fib_test_validate_entry(fei,
9252 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9253 1,
9254 &adj_o_10_10_10_2),
9255 "%U via 10.10.10.2",
9256 format_fib_prefix, &pfx_10_10_10_21_s_32);
9257 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32);
9258 FIB_TEST(fib_test_validate_entry(fei,
9259 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9260 1,
9261 &adj_o_10_10_10_2),
9262 "%U via 10.10.10.2",
9263 format_fib_prefix, &pfx_10_10_10_22_s_32);
9264 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
9265 FIB_TEST(fib_test_validate_entry(fei,
9266 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9267 1,
9268 &adj_o_10_10_10_2),
9269 "%U via 10.10.10.2",
9270 format_fib_prefix, &pfx_10_10_10_255_s_32);
9271 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
9272 FIB_TEST(fib_test_validate_entry(fei,
9273 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9274 1,
9275 &adj_o_10_10_10_2),
9276 "%U via 10.10.10.2",
9277 format_fib_prefix, &pfx_10_10_10_0_s_24);
9278 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_16_s_28);
9279 FIB_TEST(fib_test_validate_entry(fei,
9280 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9281 1,
9282 &adj_o_10_10_10_2),
9283 "%U via 10.10.10.2",
9284 format_fib_prefix, &pfx_10_10_10_16_s_28);
9285
9286 /*
9287 * source a covered entry in the sub-tree with the same inherting source
9288 * - expect that it now owns the sub-tree and thus over-rides its cover
9289 */
9290 fib_table_entry_update_one_path(0,
9291 &pfx_10_10_10_16_s_28,
9292 FIB_SOURCE_API,
9293 FIB_ENTRY_FLAG_COVERED_INHERIT,
9294 DPO_PROTO_IP4,
9295 &nh_10_10_10_1,
9296 tm->hw[0]->sw_if_index,
9297 ~0,
9298 1,
9299 NULL,
9300 FIB_ROUTE_PATH_FLAG_NONE);
9301 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_16_s_28);
9302 FIB_TEST(fib_test_validate_entry(fei,
9303 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9304 1,
9305 &adj_o_10_10_10_1),
9306 "%U via 10.10.10.1",
9307 format_fib_prefix, &pfx_10_10_10_16_s_28);
9308 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_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_1),
9313 "%U via 10.10.10.2",
9314 format_fib_prefix, &pfx_10_10_10_22_s_32);
9315 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
9316 FIB_TEST(fib_test_validate_entry(fei,
9317 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9318 1,
9319 &adj_o_10_10_10_1),
9320 "%U via 10.10.10.2",
9321 format_fib_prefix, &pfx_10_10_10_21_s_32);
9322
9323 /* these two unaffected by the sub-tree change */
9324 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
9325 FIB_TEST(fib_test_validate_entry(fei,
9326 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9327 1,
9328 &adj_o_10_10_10_2),
9329 "%U via 10.10.10.2",
9330 format_fib_prefix, &pfx_10_10_10_255_s_32);
9331 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
9332 FIB_TEST(fib_test_validate_entry(fei,
9333 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9334 1,
9335 &adj_o_10_10_10_2),
9336 "%U via 10.10.10.2",
9337 format_fib_prefix, &pfx_10_10_10_0_s_24);
9338
9339 /*
9340 * removes the more specific, expect the /24 to now re-owns the sub-tree
9341 */
9342 fib_table_entry_delete(0, &pfx_10_10_10_16_s_28, FIB_SOURCE_API);
9343
9344 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
9345 FIB_TEST(fib_test_validate_entry(fei,
9346 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9347 1,
9348 &adj_o_10_10_10_2),
9349 "%U via 10.10.10.2",
9350 format_fib_prefix, &pfx_10_10_10_16_s_28);
9351 FIB_TEST(fib_test_validate_entry(fei,
9352 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9353 1,
9354 &adj_o_10_10_10_2),
9355 "%U via 10.10.10.2",
9356 format_fib_prefix, &pfx_10_10_10_21_s_32);
9357 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32);
9358 FIB_TEST(fib_test_validate_entry(fei,
9359 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9360 1,
9361 &adj_o_10_10_10_2),
9362 "%U via 10.10.10.2",
9363 format_fib_prefix, &pfx_10_10_10_22_s_32);
9364 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
9365 FIB_TEST(fib_test_validate_entry(fei,
9366 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9367 1,
9368 &adj_o_10_10_10_2),
9369 "%U via 10.10.10.2",
9370 format_fib_prefix, &pfx_10_10_10_255_s_32);
9371 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
9372 FIB_TEST(fib_test_validate_entry(fei,
9373 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9374 1,
9375 &adj_o_10_10_10_2),
9376 "%U via 10.10.10.2",
9377 format_fib_prefix, &pfx_10_10_10_0_s_24);
9378 /*
9379 * modify the /24. expect the new forwarding to be pushed down
9380 */
9381 fib_table_entry_update_one_path(0,
9382 &pfx_10_10_10_0_s_24,
9383 FIB_SOURCE_API,
9384 FIB_ENTRY_FLAG_COVERED_INHERIT,
9385 DPO_PROTO_IP4,
9386 &nh_10_10_10_1,
9387 tm->hw[0]->sw_if_index,
9388 ~0,
9389 1,
9390 NULL,
9391 FIB_ROUTE_PATH_FLAG_NONE);
9392 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
9393 FIB_TEST(fib_test_validate_entry(fei,
9394 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9395 1,
9396 &adj_o_10_10_10_1),
9397 "%U via 10.10.10.1",
9398 format_fib_prefix, &pfx_10_10_10_16_s_28);
9399 FIB_TEST(fib_test_validate_entry(fei,
9400 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9401 1,
9402 &adj_o_10_10_10_1),
9403 "%U via 10.10.10.1",
9404 format_fib_prefix, &pfx_10_10_10_21_s_32);
9405 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32);
9406 FIB_TEST(fib_test_validate_entry(fei,
9407 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9408 1,
9409 &adj_o_10_10_10_1),
9410 "%U via 10.10.10.1",
9411 format_fib_prefix, &pfx_10_10_10_22_s_32);
9412 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
9413 FIB_TEST(fib_test_validate_entry(fei,
9414 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9415 1,
9416 &adj_o_10_10_10_1),
9417 "%U via 10.10.10.1",
9418 format_fib_prefix, &pfx_10_10_10_255_s_32);
9419 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
9420 FIB_TEST(fib_test_validate_entry(fei,
9421 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9422 1,
9423 &adj_o_10_10_10_1),
9424 "%U via 10.10.10.1",
9425 format_fib_prefix, &pfx_10_10_10_0_s_24);
9426
9427 /*
9428 * add an entry less specific to /24. it should not own the /24's tree
9429 */
9430 const fib_prefix_t pfx_10_10_0_0_s_16 = {
9431 .fp_len = 16,
9432 .fp_proto = FIB_PROTOCOL_IP4,
9433 .fp_addr = nh_10_10_0_0,
9434 };
9435 fib_table_entry_update_one_path(0,
9436 &pfx_10_10_0_0_s_16,
9437 FIB_SOURCE_API,
9438 FIB_ENTRY_FLAG_COVERED_INHERIT,
9439 DPO_PROTO_IP4,
9440 &nh_10_10_10_2,
9441 tm->hw[0]->sw_if_index,
9442 ~0,
9443 1,
9444 NULL,
9445 FIB_ROUTE_PATH_FLAG_NONE);
9446 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
9447 FIB_TEST(fib_test_validate_entry(fei,
9448 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9449 1,
9450 &adj_o_10_10_10_1),
9451 "%U via 10.10.10.1",
9452 format_fib_prefix, &pfx_10_10_10_16_s_28);
9453 FIB_TEST(fib_test_validate_entry(fei,
9454 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9455 1,
9456 &adj_o_10_10_10_1),
9457 "%U via 10.10.10.1",
9458 format_fib_prefix, &pfx_10_10_10_21_s_32);
9459 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32);
9460 FIB_TEST(fib_test_validate_entry(fei,
9461 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9462 1,
9463 &adj_o_10_10_10_1),
9464 "%U via 10.10.10.1",
9465 format_fib_prefix, &pfx_10_10_10_22_s_32);
9466 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
9467 FIB_TEST(fib_test_validate_entry(fei,
9468 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9469 1,
9470 &adj_o_10_10_10_1),
9471 "%U via 10.10.10.1",
9472 format_fib_prefix, &pfx_10_10_10_255_s_32);
9473 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
9474 FIB_TEST(fib_test_validate_entry(fei,
9475 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9476 1,
9477 &adj_o_10_10_10_1),
9478 "%U via 10.10.10.1",
9479 format_fib_prefix, &pfx_10_10_10_0_s_24);
9480 fei = fib_table_lookup_exact_match(0, &pfx_10_10_0_0_s_16);
9481 FIB_TEST(fib_test_validate_entry(fei,
9482 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9483 1,
9484 &adj_o_10_10_10_2),
9485 "%U via 10.10.10.2",
9486 format_fib_prefix, &pfx_10_10_0_0_s_16);
9487
9488 /*
9489 * cleanup
9490 */
9491 fib_table_entry_delete(0, &pfx_10_10_10_21_s_32, FIB_SOURCE_CLI);
9492 fib_table_entry_delete(0, &pfx_10_10_10_22_s_32, FIB_SOURCE_CLI);
9493 fib_table_entry_delete(0, &pfx_10_10_10_16_s_28, FIB_SOURCE_CLI);
9494 fib_table_entry_delete(0, &pfx_10_10_10_255_s_32, FIB_SOURCE_CLI);
9495 fib_table_entry_delete(0, &pfx_10_10_10_0_s_24, FIB_SOURCE_API);
9496 fib_table_entry_delete(0, &pfx_10_10_0_0_s_16, FIB_SOURCE_API);
9497 adj_unlock(ai_10_10_10_1);
9498 adj_unlock(ai_10_10_10_2);
9499
9500 /*
9501 * test the v6 tree walk.
9502 * a /64 that covers everytinhg. a /96 that covers one /128
9503 * a second /128 covered only by the /64.
9504 */
9505 const fib_prefix_t pfx_2001_s_64 = {
9506 .fp_len = 64,
9507 .fp_proto = FIB_PROTOCOL_IP6,
9508 .fp_addr = {
9509 .ip6 = {
9510 .as_u64 = {
9511 [0] = clib_host_to_net_u64(0x2001000000000000),
9512 [1] = clib_host_to_net_u64(0x0000000000000000),
9513 },
9514 },
9515 },
9516 };
9517 const fib_prefix_t pfx_2001_1_s_96 = {
9518 .fp_len = 96,
9519 .fp_proto = FIB_PROTOCOL_IP6,
9520 .fp_addr = {
9521 .ip6 = {
9522 .as_u64 = {
9523 [0] = clib_host_to_net_u64(0x2001000000000000),
9524 [1] = clib_host_to_net_u64(0x1000000000000000),
9525 },
9526 },
9527 },
9528 };
9529 const fib_prefix_t pfx_2001_1_1_s_128 = {
9530 .fp_len = 128,
9531 .fp_proto = FIB_PROTOCOL_IP6,
9532 .fp_addr = {
9533 .ip6 = {
9534 .as_u64 = {
9535 [0] = clib_host_to_net_u64(0x2001000000000000),
9536 [1] = clib_host_to_net_u64(0x1000000000000001),
9537 },
9538 },
9539 },
9540 };
9541 const fib_prefix_t pfx_2001_0_1_s_128 = {
9542 .fp_len = 128,
9543 .fp_proto = FIB_PROTOCOL_IP6,
9544 .fp_addr = {
9545 .ip6 = {
9546 .as_u64 = {
9547 [0] = clib_host_to_net_u64(0x2001000000000000),
9548 [1] = clib_host_to_net_u64(0x0000000000000001),
9549 },
9550 },
9551 },
9552 };
9553 const ip46_address_t nh_3000_1 = {
9554 .ip6 = {
9555 .as_u64 = {
9556 [0] = clib_host_to_net_u64(0x3000000000000000),
9557 [1] = clib_host_to_net_u64(0x0000000000000001),
9558 },
9559 },
9560 };
9561 const ip46_address_t nh_3000_2 = {
9562 .ip6 = {
9563 .as_u64 = {
9564 [0] = clib_host_to_net_u64(0x3000000000000000),
9565 [1] = clib_host_to_net_u64(0x0000000000000002),
9566 },
9567 },
9568 };
9569 adj_index_t ai_3000_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP6,
9570 VNET_LINK_IP6,
9571 &nh_3000_1,
9572 tm->hw[0]->sw_if_index);
9573 adj_index_t ai_3000_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP6,
9574 VNET_LINK_IP6,
9575 &nh_3000_2,
9576 tm->hw[0]->sw_if_index);
9577 fib_test_lb_bucket_t adj_o_3000_1 = {
9578 .type = FT_LB_ADJ,
9579 .adj = {
9580 .adj = ai_3000_1,
9581 },
9582 };
9583 fib_test_lb_bucket_t adj_o_3000_2 = {
9584 .type = FT_LB_ADJ,
9585 .adj = {
9586 .adj = ai_3000_2,
9587 },
9588 };
9589
9590 fib_table_entry_special_add(0,
9591 &pfx_2001_0_1_s_128,
9592 FIB_SOURCE_CLI,
9593 FIB_ENTRY_FLAG_DROP);
9594 fib_table_entry_special_add(0,
9595 &pfx_2001_1_1_s_128,
9596 FIB_SOURCE_CLI,
9597 FIB_ENTRY_FLAG_DROP);
9598
9599 /*
9600 * /96 has inherited forwarding pushed down to its covered /128
9601 */
9602 fib_table_entry_update_one_path(0,
9603 &pfx_2001_1_s_96,
9604 FIB_SOURCE_API,
9605 FIB_ENTRY_FLAG_COVERED_INHERIT,
9606 DPO_PROTO_IP6,
9607 &nh_3000_1,
9608 tm->hw[0]->sw_if_index,
9609 ~0,
9610 1,
9611 NULL,
9612 FIB_ROUTE_PATH_FLAG_NONE);
9613 fei = fib_table_lookup_exact_match(0, &pfx_2001_1_s_96);
9614 FIB_TEST(fib_test_validate_entry(fei,
9615 FIB_FORW_CHAIN_TYPE_UNICAST_IP6,
9616 1,
9617 &adj_o_3000_1),
9618 "%U via 3000::1",
9619 format_fib_prefix, &pfx_2001_1_s_96);
9620 fei = fib_table_lookup_exact_match(0, &pfx_2001_1_1_s_128);
9621 FIB_TEST(fib_test_validate_entry(fei,
9622 FIB_FORW_CHAIN_TYPE_UNICAST_IP6,
9623 1,
9624 &adj_o_3000_1),
9625 "%U via 3000::1",
9626 format_fib_prefix, &pfx_2001_1_1_s_128);
9627 fei = fib_table_lookup_exact_match(0, &pfx_2001_0_1_s_128);
9628 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
9629 "%U resolves via drop",
9630 format_fib_prefix, &pfx_2001_0_1_s_128);
9631
9632 /*
9633 * /64 has inherited forwarding pushed down to all, but the /96
9634 * and its sub-tree remain unaffected.
9635 */
9636 fib_table_entry_update_one_path(0,
9637 &pfx_2001_s_64,
9638 FIB_SOURCE_API,
9639 FIB_ENTRY_FLAG_COVERED_INHERIT,
9640 DPO_PROTO_IP6,
9641 &nh_3000_2,
9642 tm->hw[0]->sw_if_index,
9643 ~0,
9644 1,
9645 NULL,
9646 FIB_ROUTE_PATH_FLAG_NONE);
9647
9648 fei = fib_table_lookup_exact_match(0, &pfx_2001_s_64);
9649 FIB_TEST(fib_test_validate_entry(fei,
9650 FIB_FORW_CHAIN_TYPE_UNICAST_IP6,
9651 1,
9652 &adj_o_3000_2),
9653 "%U via 3000::2",
9654 format_fib_prefix, &pfx_2001_s_64);
9655 fei = fib_table_lookup_exact_match(0, &pfx_2001_0_1_s_128);
9656 FIB_TEST(fib_test_validate_entry(fei,
9657 FIB_FORW_CHAIN_TYPE_UNICAST_IP6,
9658 1,
9659 &adj_o_3000_2),
9660 "%U via 3000::1",
9661 format_fib_prefix, &pfx_2001_0_1_s_128);
9662
9663 fei = fib_table_lookup_exact_match(0, &pfx_2001_1_s_96);
9664 FIB_TEST(fib_test_validate_entry(fei,
9665 FIB_FORW_CHAIN_TYPE_UNICAST_IP6,
9666 1,
9667 &adj_o_3000_1),
9668 "%U via 3000::1",
9669 format_fib_prefix, &pfx_2001_1_s_96);
9670 fei = fib_table_lookup_exact_match(0, &pfx_2001_1_1_s_128);
9671 FIB_TEST(fib_test_validate_entry(fei,
9672 FIB_FORW_CHAIN_TYPE_UNICAST_IP6,
9673 1,
9674 &adj_o_3000_1),
9675 "%U via 3000::1",
9676 format_fib_prefix, &pfx_2001_1_1_s_128);
9677
9678 /*
9679 * Cleanup
9680 */
9681 fib_table_entry_delete(0, &pfx_2001_0_1_s_128, FIB_SOURCE_CLI);
9682 fib_table_entry_delete(0, &pfx_2001_1_1_s_128, FIB_SOURCE_CLI);
9683 fib_table_entry_delete(0, &pfx_2001_s_64, FIB_SOURCE_API);
9684 fib_table_entry_delete(0, &pfx_2001_1_s_96, FIB_SOURCE_API);
9685 adj_unlock(ai_3000_1);
9686 adj_unlock(ai_3000_2);
9687
9688 /*
9689 * test no-one left behind
9690 */
9691 FIB_TEST((n_feis == fib_entry_pool_size()), "Entries gone");
9692 FIB_TEST(0 == adj_nbr_db_size(), "All adjacencies removed");
9693 return (0);
9694}
9695
Neale Ranns0bfe5d82016-08-25 15:29:12 +01009696static clib_error_t *
9697fib_test (vlib_main_t * vm,
9698 unformat_input_t * input,
9699 vlib_cli_command_t * cmd_arg)
9700{
Neale Ranns0ebe8d72016-12-08 19:48:11 +00009701 int res;
9702
9703 res = 0;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01009704 fib_test_mk_intf(4);
9705
Neale Ranns88fc83e2017-04-05 08:11:14 -07009706 if (unformat (input, "debug"))
9707 {
9708 fib_test_do_debug = 1;
9709 }
9710
Neale Ranns0bfe5d82016-08-25 15:29:12 +01009711 if (unformat (input, "ip"))
9712 {
Neale Ranns0ebe8d72016-12-08 19:48:11 +00009713 res += fib_test_v4();
9714 res += fib_test_v6();
Neale Ranns0bfe5d82016-08-25 15:29:12 +01009715 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01009716 else if (unformat (input, "label"))
9717 {
Neale Ranns0ebe8d72016-12-08 19:48:11 +00009718 res += fib_test_label();
Neale Ranns0bfe5d82016-08-25 15:29:12 +01009719 }
9720 else if (unformat (input, "ae"))
9721 {
Neale Ranns0ebe8d72016-12-08 19:48:11 +00009722 res += fib_test_ae();
Neale Ranns0bfe5d82016-08-25 15:29:12 +01009723 }
Neale Ranns57b58602017-07-15 07:37:25 -07009724 else if (unformat (input, "pref"))
9725 {
9726 res += fib_test_pref();
9727 }
Neale Rannsad422ed2016-11-02 14:20:04 +00009728 else if (unformat (input, "lfib"))
9729 {
Neale Ranns0ebe8d72016-12-08 19:48:11 +00009730 res += lfib_test();
Neale Rannsad422ed2016-11-02 14:20:04 +00009731 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01009732 else if (unformat (input, "walk"))
9733 {
Neale Ranns0ebe8d72016-12-08 19:48:11 +00009734 res += fib_test_walk();
Neale Ranns0bfe5d82016-08-25 15:29:12 +01009735 }
Neale Ranns88fc83e2017-04-05 08:11:14 -07009736 else if (unformat (input, "bfd"))
9737 {
9738 res += fib_test_bfd();
9739 }
Neale Ranns89541992017-04-06 04:41:02 -07009740 else if (unformat (input, "inherit"))
9741 {
9742 res += fib_test_inherit();
9743 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01009744 else
9745 {
Neale Ranns0ebe8d72016-12-08 19:48:11 +00009746 res += fib_test_v4();
9747 res += fib_test_v6();
9748 res += fib_test_ae();
Neale Ranns88fc83e2017-04-05 08:11:14 -07009749 res += fib_test_bfd();
Neale Ranns57b58602017-07-15 07:37:25 -07009750 res += fib_test_pref();
Neale Ranns0ebe8d72016-12-08 19:48:11 +00009751 res += fib_test_label();
Neale Ranns89541992017-04-06 04:41:02 -07009752 res += fib_test_inherit();
Neale Ranns0ebe8d72016-12-08 19:48:11 +00009753 res += lfib_test();
Neale Rannsf12a83f2017-04-18 09:09:40 -07009754
9755 /*
9756 * fib-walk process must be disabled in order for the walk tests to work
9757 */
9758 fib_walk_process_disable();
9759 res += fib_test_walk();
9760 fib_walk_process_enable();
Neale Ranns0bfe5d82016-08-25 15:29:12 +01009761 }
9762
Neale Ranns0ebe8d72016-12-08 19:48:11 +00009763 if (res)
9764 {
9765 return clib_error_return(0, "FIB Unit Test Failed");
9766 }
9767 else
9768 {
9769 return (NULL);
9770 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01009771}
9772
9773VLIB_CLI_COMMAND (test_fib_command, static) = {
9774 .path = "test fib",
9775 .short_help = "fib unit tests - DO NOT RUN ON A LIVE SYSTEM",
9776 .function = fib_test,
9777};
9778
Neale Ranns0bfe5d82016-08-25 15:29:12 +01009779clib_error_t *
9780fib_test_init (vlib_main_t *vm)
9781{
9782 return 0;
9783}
9784
9785VLIB_INIT_FUNCTION (fib_test_init);