blob: 555196d00924dcba68c5746d24555607dd5b8cde [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 Ranns6f631152017-10-03 08:20:21 -070031#include <vnet/dpo/l2_bridge_dpo.h>
Neale Ranns62fe07c2017-10-31 12:28:22 -070032#include <vnet/dpo/mpls_disposition.h>
Neale Ranns0bfe5d82016-08-25 15:29:12 +010033
34#include <vnet/mpls/mpls.h>
35
Neale Ranns6f631152017-10-03 08:20:21 -070036#include <vnet/fib/fib_test.h>
Neale Ranns0bfe5d82016-08-25 15:29:12 +010037#include <vnet/fib/fib_path_list.h>
Neale Rannsad422ed2016-11-02 14:20:04 +000038#include <vnet/fib/fib_entry_src.h>
Neale Ranns0bfe5d82016-08-25 15:29:12 +010039#include <vnet/fib/fib_walk.h>
40#include <vnet/fib/fib_node_list.h>
Neale Ranns3ee44042016-10-03 13:05:48 +010041#include <vnet/fib/fib_urpf_list.h>
Neale Ranns0bfe5d82016-08-25 15:29:12 +010042
Neale Ranns88fc83e2017-04-05 08:11:14 -070043/*
44 * Add debugs for passing tests
45 */
46static int fib_test_do_debug;
47
Neale Ranns0bfe5d82016-08-25 15:29:12 +010048#define FIB_TEST_I(_cond, _comment, _args...) \
49({ \
50 int _evald = (_cond); \
51 if (!(_evald)) { \
52 fformat(stderr, "FAIL:%d: " _comment "\n", \
53 __LINE__, ##_args); \
54 } else { \
Neale Ranns88fc83e2017-04-05 08:11:14 -070055 if (fib_test_do_debug) \
56 fformat(stderr, "PASS:%d: " _comment "\n", \
57 __LINE__, ##_args); \
Neale Ranns0bfe5d82016-08-25 15:29:12 +010058 } \
59 _evald; \
60})
61#define FIB_TEST(_cond, _comment, _args...) \
62{ \
63 if (!FIB_TEST_I(_cond, _comment, ##_args)) { \
Neale Ranns0ebe8d72016-12-08 19:48:11 +000064 return 1; \
Neale Ranns0bfe5d82016-08-25 15:29:12 +010065 ASSERT(!("FAIL: " _comment)); \
66 } \
67}
68
69/**
70 * A 'i'm not fussed is this is not efficient' store of test data
71 */
72typedef struct test_main_t_ {
73 /**
74 * HW if indicies
75 */
76 u32 hw_if_indicies[4];
77 /**
78 * HW interfaces
79 */
80 vnet_hw_interface_t * hw[4];
81
82} test_main_t;
83static test_main_t test_main;
84
85/* fake ethernet device class, distinct from "fake-ethX" */
86static u8 * format_test_interface_name (u8 * s, va_list * args)
87{
88 u32 dev_instance = va_arg (*args, u32);
89 return format (s, "test-eth%d", dev_instance);
90}
91
92static uword dummy_interface_tx (vlib_main_t * vm,
93 vlib_node_runtime_t * node,
94 vlib_frame_t * frame)
95{
96 clib_warning ("you shouldn't be here, leaking buffers...");
97 return frame->n_vectors;
98}
99
Neale Ranns8b37b872016-11-21 12:25:22 +0000100static clib_error_t *
101test_interface_admin_up_down (vnet_main_t * vnm,
102 u32 hw_if_index,
103 u32 flags)
104{
105 u32 hw_flags = (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) ?
106 VNET_HW_INTERFACE_FLAG_LINK_UP : 0;
107 vnet_hw_interface_set_flags (vnm, hw_if_index, hw_flags);
108 return 0;
109}
110
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100111VNET_DEVICE_CLASS (test_interface_device_class,static) = {
112 .name = "Test interface",
113 .format_device_name = format_test_interface_name,
114 .tx_function = dummy_interface_tx,
Neale Ranns8b37b872016-11-21 12:25:22 +0000115 .admin_up_down_function = test_interface_admin_up_down,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100116};
117
118static u8 *hw_address;
119
Neale Ranns0ebe8d72016-12-08 19:48:11 +0000120static int
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100121fib_test_mk_intf (u32 ninterfaces)
122{
123 clib_error_t * error = NULL;
124 test_main_t *tm = &test_main;
125 u8 byte;
126 u32 i;
127
128 ASSERT(ninterfaces <= ARRAY_LEN(tm->hw_if_indicies));
129
130 for (i=0; i<6; i++)
131 {
132 byte = 0xd0+i;
133 vec_add1(hw_address, byte);
134 }
135
136 for (i = 0; i < ninterfaces; i++)
137 {
138 hw_address[5] = i;
139
140 error = ethernet_register_interface(vnet_get_main(),
Neale Ranns8b37b872016-11-21 12:25:22 +0000141 test_interface_device_class.index,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100142 i /* instance */,
143 hw_address,
144 &tm->hw_if_indicies[i],
145 /* flag change */ 0);
146
147 FIB_TEST((NULL == error), "ADD interface %d", i);
148
Neale Ranns8b37b872016-11-21 12:25:22 +0000149 error = vnet_hw_interface_set_flags(vnet_get_main(),
150 tm->hw_if_indicies[i],
151 VNET_HW_INTERFACE_FLAG_LINK_UP);
152 tm->hw[i] = vnet_get_hw_interface(vnet_get_main(),
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100153 tm->hw_if_indicies[i]);
Neale Ranns8b37b872016-11-21 12:25:22 +0000154 vec_validate (ip4_main.fib_index_by_sw_if_index,
155 tm->hw[i]->sw_if_index);
156 vec_validate (ip6_main.fib_index_by_sw_if_index,
157 tm->hw[i]->sw_if_index);
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100158 ip4_main.fib_index_by_sw_if_index[tm->hw[i]->sw_if_index] = 0;
159 ip6_main.fib_index_by_sw_if_index[tm->hw[i]->sw_if_index] = 0;
Neale Ranns8b37b872016-11-21 12:25:22 +0000160
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100161 error = vnet_sw_interface_set_flags(vnet_get_main(),
162 tm->hw[i]->sw_if_index,
163 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
164 FIB_TEST((NULL == error), "UP interface %d", i);
165 }
166 /*
167 * re-eval after the inevitable realloc
168 */
169 for (i = 0; i < ninterfaces; i++)
170 {
171 tm->hw[i] = vnet_get_hw_interface(vnet_get_main(),
172 tm->hw_if_indicies[i]);
173 }
Neale Ranns0ebe8d72016-12-08 19:48:11 +0000174
175 return (0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100176}
177
Neale Ranns3ee44042016-10-03 13:05:48 +0100178#define FIB_TEST_REC_FORW(_rec_prefix, _via_prefix, _bucket) \
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100179{ \
180 const dpo_id_t *_rec_dpo = fib_entry_contribute_ip_forwarding( \
181 fib_table_lookup_exact_match(fib_index, (_rec_prefix))); \
182 const dpo_id_t *_via_dpo = fib_entry_contribute_ip_forwarding( \
183 fib_table_lookup(fib_index, (_via_prefix))); \
184 FIB_TEST(!dpo_cmp(_via_dpo, \
Neale Ranns3ee44042016-10-03 13:05:48 +0100185 load_balance_get_bucket(_rec_dpo->dpoi_index, \
186 _bucket)), \
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100187 "%U is recursive via %U", \
188 format_fib_prefix, (_rec_prefix), \
189 format_fib_prefix, _via_prefix); \
190}
191
192#define FIB_TEST_LB_BUCKET_VIA_ADJ(_prefix, _bucket, _ai) \
193{ \
194 const dpo_id_t *_dpo = fib_entry_contribute_ip_forwarding( \
195 fib_table_lookup_exact_match(fib_index, (_prefix))); \
196 const dpo_id_t *_dpo1 = \
197 load_balance_get_bucket(_dpo->dpoi_index, _bucket); \
198 FIB_TEST(DPO_ADJACENCY == _dpo1->dpoi_type, "type is %U", \
199 format_dpo_type, _dpo1->dpoi_type); \
200 FIB_TEST((_ai == _dpo1->dpoi_index), \
201 "%U bucket %d resolves via %U", \
202 format_fib_prefix, (_prefix), \
203 _bucket, \
204 format_dpo_id, _dpo1, 0); \
205}
206
Neale Ranns3ee44042016-10-03 13:05:48 +0100207#define FIB_TEST_RPF(_cond, _comment, _args...) \
208{ \
209 if (!FIB_TEST_I(_cond, _comment, ##_args)) { \
210 return (0); \
211 } \
212}
213
214static int
215fib_test_urpf_is_equal (fib_node_index_t fei,
216 fib_forward_chain_type_t fct,
217 u32 num, ...)
218{
Neale Ranns948e00f2016-10-20 13:39:34 +0100219 dpo_id_t dpo = DPO_INVALID;
Neale Ranns3ee44042016-10-03 13:05:48 +0100220 fib_urpf_list_t *urpf;
221 index_t ui;
222 va_list ap;
223 int ii;
224
225 va_start(ap, num);
226
227 fib_entry_contribute_forwarding(fei, fct, &dpo);
228 ui = load_balance_get_urpf(dpo.dpoi_index);
229
230 urpf = fib_urpf_list_get(ui);
231
232 FIB_TEST_RPF(num == vec_len(urpf->furpf_itfs),
233 "RPF:%U len %d == %d",
234 format_fib_urpf_list, ui,
235 num, vec_len(urpf->furpf_itfs));
236 FIB_TEST_RPF(num == fib_urpf_check_size(ui),
237 "RPF:%U check-size %d == %d",
238 format_fib_urpf_list, ui,
239 num, vec_len(urpf->furpf_itfs));
240
241 for (ii = 0; ii < num; ii++)
242 {
243 adj_index_t ai = va_arg(ap, adj_index_t);
244
245 FIB_TEST_RPF(ai == urpf->furpf_itfs[ii],
246 "RPF:%d item:%d - %d == %d",
247 ui, ii, ai, urpf->furpf_itfs[ii]);
248 FIB_TEST_RPF(fib_urpf_check(ui, ai),
249 "RPF:%d %d found",
250 ui, ai);
251 }
252
253 dpo_reset(&dpo);
254
Neale Ranns5899fde2016-10-12 13:51:05 +0100255 va_end(ap);
256
Neale Ranns3ee44042016-10-03 13:05:48 +0100257 return (1);
258}
259
Neale Rannsb80c5362016-10-08 13:03:40 +0100260static u8*
261fib_test_build_rewrite (u8 *eth_addr)
262{
263 u8* rewrite = NULL;
264
265 vec_validate(rewrite, 13);
266
267 memcpy(rewrite, eth_addr, 6);
268 memcpy(rewrite+6, eth_addr, 6);
269
270 return (rewrite);
271}
272
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000273#define FIB_TEST_LB(_cond, _comment, _args...) \
274{ \
275 if (!FIB_TEST_I(_cond, _comment, ##_args)) { \
276 return (0); \
277 } \
278}
279
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800280int
281fib_test_validate_rep_v (const replicate_t *rep,
282 u16 n_buckets,
Christophe Fontained3c008d2017-10-02 18:10:54 +0200283 va_list *ap)
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800284{
285 const fib_test_rep_bucket_t *exp;
286 const dpo_id_t *dpo;
287 int bucket;
288
289 FIB_TEST_LB((n_buckets == rep->rep_n_buckets),
290 "n_buckets = %d", rep->rep_n_buckets);
291
292 for (bucket = 0; bucket < n_buckets; bucket++)
293 {
Christophe Fontained3c008d2017-10-02 18:10:54 +0200294 exp = va_arg(*ap, fib_test_rep_bucket_t*);
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800295
296 dpo = replicate_get_bucket_i(rep, bucket);
297
298 switch (exp->type)
299 {
300 case FT_REP_LABEL_O_ADJ:
301 {
302 const mpls_label_dpo_t *mld;
303 mpls_label_t hdr;
304 FIB_TEST_LB((DPO_MPLS_LABEL == dpo->dpoi_type),
305 "bucket %d stacks on %U",
306 bucket,
307 format_dpo_type, dpo->dpoi_type);
308
309 mld = mpls_label_dpo_get(dpo->dpoi_index);
310 hdr = clib_net_to_host_u32(mld->mld_hdr[0].label_exp_s_ttl);
311
312 FIB_TEST_LB((vnet_mpls_uc_get_label(hdr) ==
313 exp->label_o_adj.label),
314 "bucket %d stacks on label %d",
315 bucket,
316 exp->label_o_adj.label);
317
318 FIB_TEST_LB((vnet_mpls_uc_get_s(hdr) ==
319 exp->label_o_adj.eos),
320 "bucket %d stacks on label %d %U",
321 bucket,
322 exp->label_o_adj.label,
323 format_mpls_eos_bit, exp->label_o_adj.eos);
324
325 FIB_TEST_LB((DPO_ADJACENCY_INCOMPLETE == mld->mld_dpo.dpoi_type),
326 "bucket %d label stacks on %U",
327 bucket,
328 format_dpo_type, mld->mld_dpo.dpoi_type);
329
330 FIB_TEST_LB((exp->label_o_adj.adj == mld->mld_dpo.dpoi_index),
331 "bucket %d label stacks on adj %d",
332 bucket,
333 exp->label_o_adj.adj);
334 }
335 break;
336 case FT_REP_INTF:
Neale Ranns43161a82017-08-12 02:12:00 -0700337 FIB_TEST_LB((DPO_INTERFACE_RX == dpo->dpoi_type),
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800338 "bucket %d stacks on %U",
339 bucket,
340 format_dpo_type, dpo->dpoi_type);
341
342 FIB_TEST_LB((exp->adj.adj == dpo->dpoi_index),
343 "bucket %d stacks on adj %d",
344 bucket,
345 exp->adj.adj);
346 break;
347 case FT_REP_DISP_MFIB_LOOKUP:
348// ASSERT(0);
349 break;
350 }
351 }
352
353 return (!0);
354}
355
356int
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000357fib_test_validate_lb_v (const load_balance_t *lb,
358 u16 n_buckets,
Christophe Fontained3c008d2017-10-02 18:10:54 +0200359 va_list *ap)
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000360{
361 const dpo_id_t *dpo;
362 int bucket;
363
364 FIB_TEST_LB((n_buckets == lb->lb_n_buckets), "n_buckets = %d", lb->lb_n_buckets);
365
366 for (bucket = 0; bucket < n_buckets; bucket++)
367 {
368 const fib_test_lb_bucket_t *exp;
369
Christophe Fontained3c008d2017-10-02 18:10:54 +0200370 exp = va_arg(*ap, fib_test_lb_bucket_t*);
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000371 dpo = load_balance_get_bucket_i(lb, bucket);
372
373 switch (exp->type)
374 {
Neale Rannsad422ed2016-11-02 14:20:04 +0000375 case FT_LB_LABEL_STACK_O_ADJ:
376 {
377 const mpls_label_dpo_t *mld;
378 mpls_label_t hdr;
379 u32 ii;
380
381 FIB_TEST_LB((DPO_MPLS_LABEL == dpo->dpoi_type),
382 "bucket %d stacks on %U",
383 bucket,
384 format_dpo_type, dpo->dpoi_type);
385
386 mld = mpls_label_dpo_get(dpo->dpoi_index);
387
388 FIB_TEST_LB(exp->label_stack_o_adj.label_stack_size == mld->mld_n_labels,
389 "label stack size",
390 mld->mld_n_labels);
391
392 for (ii = 0; ii < mld->mld_n_labels; ii++)
393 {
394 hdr = clib_net_to_host_u32(mld->mld_hdr[ii].label_exp_s_ttl);
395 FIB_TEST_LB((vnet_mpls_uc_get_label(hdr) ==
396 exp->label_stack_o_adj.label_stack[ii]),
397 "bucket %d stacks on label %d",
398 bucket,
399 exp->label_stack_o_adj.label_stack[ii]);
400
401 if (ii == mld->mld_n_labels-1)
402 {
403 FIB_TEST_LB((vnet_mpls_uc_get_s(hdr) ==
404 exp->label_o_adj.eos),
405 "bucket %d stacks on label %d %U!=%U",
406 bucket,
407 exp->label_stack_o_adj.label_stack[ii],
408 format_mpls_eos_bit, exp->label_o_adj.eos,
409 format_mpls_eos_bit, vnet_mpls_uc_get_s(hdr));
410 }
411 else
412 {
413 FIB_TEST_LB((vnet_mpls_uc_get_s(hdr) == MPLS_NON_EOS),
414 "bucket %d stacks on label %d %U",
415 bucket,
416 exp->label_stack_o_adj.label_stack[ii],
417 format_mpls_eos_bit, vnet_mpls_uc_get_s(hdr));
418 }
419 }
420
421 FIB_TEST_LB((DPO_ADJACENCY_INCOMPLETE == mld->mld_dpo.dpoi_type),
422 "bucket %d label stacks on %U",
423 bucket,
424 format_dpo_type, mld->mld_dpo.dpoi_type);
425
426 FIB_TEST_LB((exp->label_stack_o_adj.adj == mld->mld_dpo.dpoi_index),
427 "bucket %d label stacks on adj %d",
428 bucket,
429 exp->label_stack_o_adj.adj);
430 }
431 break;
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000432 case FT_LB_LABEL_O_ADJ:
433 {
434 const mpls_label_dpo_t *mld;
435 mpls_label_t hdr;
436 FIB_TEST_LB((DPO_MPLS_LABEL == dpo->dpoi_type),
437 "bucket %d stacks on %U",
438 bucket,
439 format_dpo_type, dpo->dpoi_type);
440
441 mld = mpls_label_dpo_get(dpo->dpoi_index);
Neale Rannsad422ed2016-11-02 14:20:04 +0000442 hdr = clib_net_to_host_u32(mld->mld_hdr[0].label_exp_s_ttl);
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000443
444 FIB_TEST_LB((vnet_mpls_uc_get_label(hdr) ==
445 exp->label_o_adj.label),
446 "bucket %d stacks on label %d",
447 bucket,
448 exp->label_o_adj.label);
449
450 FIB_TEST_LB((vnet_mpls_uc_get_s(hdr) ==
451 exp->label_o_adj.eos),
452 "bucket %d stacks on label %d %U",
453 bucket,
454 exp->label_o_adj.label,
455 format_mpls_eos_bit, exp->label_o_adj.eos);
456
457 FIB_TEST_LB((DPO_ADJACENCY_INCOMPLETE == mld->mld_dpo.dpoi_type),
458 "bucket %d label stacks on %U",
459 bucket,
460 format_dpo_type, mld->mld_dpo.dpoi_type);
461
462 FIB_TEST_LB((exp->label_o_adj.adj == mld->mld_dpo.dpoi_index),
463 "bucket %d label stacks on adj %d",
464 bucket,
465 exp->label_o_adj.adj);
466 }
467 break;
468 case FT_LB_LABEL_O_LB:
469 {
470 const mpls_label_dpo_t *mld;
471 mpls_label_t hdr;
472
473 FIB_TEST_LB((DPO_MPLS_LABEL == dpo->dpoi_type),
474 "bucket %d stacks on %U",
475 bucket,
476 format_dpo_type, dpo->dpoi_type);
Neale Rannsad422ed2016-11-02 14:20:04 +0000477
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000478 mld = mpls_label_dpo_get(dpo->dpoi_index);
Neale Rannsad422ed2016-11-02 14:20:04 +0000479 hdr = clib_net_to_host_u32(mld->mld_hdr[0].label_exp_s_ttl);
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000480
Neale Rannsad422ed2016-11-02 14:20:04 +0000481 FIB_TEST_LB(1 == mld->mld_n_labels, "label stack size",
482 mld->mld_n_labels);
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000483 FIB_TEST_LB((vnet_mpls_uc_get_label(hdr) ==
484 exp->label_o_lb.label),
485 "bucket %d stacks on label %d",
486 bucket,
487 exp->label_o_lb.label);
488
489 FIB_TEST_LB((vnet_mpls_uc_get_s(hdr) ==
490 exp->label_o_lb.eos),
491 "bucket %d stacks on label %d %U",
492 bucket,
493 exp->label_o_lb.label,
494 format_mpls_eos_bit, exp->label_o_lb.eos);
495
496 FIB_TEST_LB((DPO_LOAD_BALANCE == mld->mld_dpo.dpoi_type),
497 "bucket %d label stacks on %U",
498 bucket,
499 format_dpo_type, mld->mld_dpo.dpoi_type);
500
501 FIB_TEST_LB((exp->label_o_lb.lb == mld->mld_dpo.dpoi_index),
502 "bucket %d label stacks on LB %d",
503 bucket,
504 exp->label_o_lb.lb);
505 }
506 break;
507 case FT_LB_ADJ:
508 FIB_TEST_I(((DPO_ADJACENCY == dpo->dpoi_type) ||
509 (DPO_ADJACENCY_INCOMPLETE == dpo->dpoi_type)),
510 "bucket %d stacks on %U",
511 bucket,
512 format_dpo_type, dpo->dpoi_type);
513 FIB_TEST_LB((exp->adj.adj == dpo->dpoi_index),
514 "bucket %d stacks on adj %d",
515 bucket,
516 exp->adj.adj);
517 break;
Neale Ranns62fe07c2017-10-31 12:28:22 -0700518 case FT_LB_MPLS_DISP_O_ADJ:
519 {
520 const mpls_disp_dpo_t *mdd;
521
522 FIB_TEST_I((DPO_MPLS_DISPOSITION == dpo->dpoi_type),
523 "bucket %d stacks on %U",
524 bucket,
525 format_dpo_type, dpo->dpoi_type);
526
527 mdd = mpls_disp_dpo_get(dpo->dpoi_index);
528
529 dpo = &mdd->mdd_dpo;
530
531 FIB_TEST_I(((DPO_ADJACENCY == dpo->dpoi_type) ||
532 (DPO_ADJACENCY_INCOMPLETE == dpo->dpoi_type)),
533 "bucket %d stacks on %U",
534 bucket,
535 format_dpo_type, dpo->dpoi_type);
536 FIB_TEST_LB((exp->adj.adj == dpo->dpoi_index),
537 "bucket %d stacks on adj %d",
538 bucket,
539 exp->adj.adj);
540 break;
541 }
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800542 case FT_LB_INTF:
Neale Ranns43161a82017-08-12 02:12:00 -0700543 FIB_TEST_I((DPO_INTERFACE_RX == dpo->dpoi_type),
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800544 "bucket %d stacks on %U",
545 bucket,
546 format_dpo_type, dpo->dpoi_type);
547 FIB_TEST_LB((exp->adj.adj == dpo->dpoi_index),
548 "bucket %d stacks on adj %d",
549 bucket,
550 exp->adj.adj);
551 break;
Neale Ranns6f631152017-10-03 08:20:21 -0700552 case FT_LB_L2:
553 FIB_TEST_I((DPO_L2_BRIDGE == dpo->dpoi_type),
554 "bucket %d stacks on %U",
555 bucket,
556 format_dpo_type, dpo->dpoi_type);
557 FIB_TEST_LB((exp->adj.adj == dpo->dpoi_index),
558 "bucket %d stacks on adj %d",
559 bucket,
560 exp->adj.adj);
561 break;
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000562 case FT_LB_O_LB:
563 FIB_TEST_I((DPO_LOAD_BALANCE == dpo->dpoi_type),
564 "bucket %d stacks on %U",
565 bucket,
566 format_dpo_type, dpo->dpoi_type);
567 FIB_TEST_LB((exp->lb.lb == dpo->dpoi_index),
Neale Ranns57b58602017-07-15 07:37:25 -0700568 "bucket %d stacks on lb %d not %d",
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000569 bucket,
Neale Ranns57b58602017-07-15 07:37:25 -0700570 dpo->dpoi_index,
571 exp->lb.lb);
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000572 break;
Neale Rannsd792d9c2017-10-21 10:53:20 -0700573 case FT_LB_BIER_TABLE:
574 FIB_TEST_LB((DPO_BIER_TABLE == dpo->dpoi_type),
575 "bucket %d stacks on %U",
576 bucket,
577 format_dpo_type, dpo->dpoi_type);
578 FIB_TEST_LB((exp->bier.table == dpo->dpoi_index),
579 "bucket %d stacks on lb %d",
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000580 bucket,
Neale Rannsd792d9c2017-10-21 10:53:20 -0700581 exp->bier.table);
582 break;
583 case FT_LB_BIER_FMASK:
584 FIB_TEST_LB((DPO_BIER_FMASK == dpo->dpoi_type),
585 "bucket %d stacks on %U",
586 bucket,
587 format_dpo_type, dpo->dpoi_type);
588 FIB_TEST_LB((exp->bier.fmask == dpo->dpoi_index),
589 "bucket %d stacks on lb %d",
590 bucket,
591 exp->bier.fmask);
592 break;
593 case FT_LB_DROP:
594 FIB_TEST_LB((DPO_DROP == dpo->dpoi_type),
595 "bucket %d stacks on %U",
596 bucket,
597 format_dpo_type, dpo->dpoi_type);
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000598 break;
599 }
600 }
601 return (!0);
602}
603
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800604int
Neale Rannsd792d9c2017-10-21 10:53:20 -0700605fib_test_validate_lb (const dpo_id_t *dpo,
606 u16 n_buckets,
607 ...)
608{
609 const load_balance_t *lb;
610 va_list ap;
611 int res;
612
613 va_start(ap, n_buckets);
614
Neale Ranns93149bb2017-11-15 10:44:07 -0800615 if (FIB_TEST_I((DPO_LOAD_BALANCE == dpo->dpoi_type),
616 "Entry links to %U",
617 format_dpo_type, dpo->dpoi_type))
618 {
619 lb = load_balance_get(dpo->dpoi_index);
Neale Rannsd792d9c2017-10-21 10:53:20 -0700620
Neale Ranns93149bb2017-11-15 10:44:07 -0800621 res = fib_test_validate_lb_v(lb, n_buckets, &ap);
622 }
623 else
624 {
625 res = !0;
626 }
Neale Rannsd792d9c2017-10-21 10:53:20 -0700627
628 va_end(ap);
629
630 return (res);
631}
632
633int
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000634fib_test_validate_entry (fib_node_index_t fei,
635 fib_forward_chain_type_t fct,
Gabriel Ganned71e0fc2017-10-26 10:35:28 +0200636 int n_buckets,
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000637 ...)
638{
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000639 dpo_id_t dpo = DPO_INVALID;
640 fib_prefix_t pfx;
641 index_t fw_lbi;
642 u32 fib_index;
643 va_list ap;
644 int res;
645
646 va_start(ap, n_buckets);
647
648 fib_entry_get_prefix(fei, &pfx);
649 fib_index = fib_entry_get_fib_index(fei);
650 fib_entry_contribute_forwarding(fei, fct, &dpo);
651
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800652 if (DPO_REPLICATE == dpo.dpoi_type)
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000653 {
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800654 const replicate_t *rep;
655
656 rep = replicate_get(dpo.dpoi_index);
Christophe Fontained3c008d2017-10-02 18:10:54 +0200657 res = fib_test_validate_rep_v(rep, n_buckets, &ap);
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800658 }
659 else
660 {
661 const load_balance_t *lb;
662
663 FIB_TEST_LB((DPO_LOAD_BALANCE == dpo.dpoi_type),
664 "Entry links to %U",
665 format_dpo_type, dpo.dpoi_type);
666
667 lb = load_balance_get(dpo.dpoi_index);
Christophe Fontained3c008d2017-10-02 18:10:54 +0200668 res = fib_test_validate_lb_v(lb, n_buckets, &ap);
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800669
670 /*
671 * ensure that the LB contributed by the entry is the
672 * same as the LB in the forwarding tables
673 */
674 if (fct == fib_entry_get_default_chain_type(fib_entry_get(fei)))
Neale Rannsad422ed2016-11-02 14:20:04 +0000675 {
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800676 switch (pfx.fp_proto)
Neale Rannsad422ed2016-11-02 14:20:04 +0000677 {
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800678 case FIB_PROTOCOL_IP4:
679 fw_lbi = ip4_fib_forwarding_lookup(fib_index, &pfx.fp_addr.ip4);
Neale Rannsad422ed2016-11-02 14:20:04 +0000680 break;
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800681 case FIB_PROTOCOL_IP6:
682 fw_lbi = ip6_fib_table_fwding_lookup(&ip6_main, fib_index, &pfx.fp_addr.ip6);
683 break;
684 case FIB_PROTOCOL_MPLS:
685 {
686 mpls_unicast_header_t hdr = {
687 .label_exp_s_ttl = 0,
688 };
689
690 vnet_mpls_uc_set_label(&hdr.label_exp_s_ttl, pfx.fp_label);
691 vnet_mpls_uc_set_s(&hdr.label_exp_s_ttl, pfx.fp_eos);
692 hdr.label_exp_s_ttl = clib_host_to_net_u32(hdr.label_exp_s_ttl);
693
694 fw_lbi = mpls_fib_table_forwarding_lookup(fib_index, &hdr);
695 break;
696 }
697 default:
698 fw_lbi = 0;
Neale Rannsad422ed2016-11-02 14:20:04 +0000699 }
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800700 FIB_TEST_LB((fw_lbi == dpo.dpoi_index),
701 "Contributed LB = FW LB: %U\n %U",
702 format_load_balance, fw_lbi, 0,
703 format_load_balance, dpo.dpoi_index, 0);
Neale Rannsad422ed2016-11-02 14:20:04 +0000704 }
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000705 }
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000706
707 dpo_reset(&dpo);
708
709 va_end(ap);
710
711 return (res);
712}
713
Neale Ranns0ebe8d72016-12-08 19:48:11 +0000714static int
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100715fib_test_v4 (void)
716{
717 /*
718 * In the default table check for the presence and correct forwarding
719 * of the special entries
720 */
721 fib_node_index_t dfrt, fei, ai, ai2, locked_ai, ai_01, ai_02, ai_03;
722 const dpo_id_t *dpo, *dpo1, *dpo2, *dpo_drop;
723 const ip_adjacency_t *adj;
724 const load_balance_t *lb;
725 test_main_t *tm;
726 u32 fib_index;
Neale Ranns994dab42017-04-18 12:56:45 -0700727 int lb_count;
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100728 int ii;
729
730 /* via 10.10.10.1 */
731 ip46_address_t nh_10_10_10_1 = {
732 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
733 };
734 /* via 10.10.10.2 */
735 ip46_address_t nh_10_10_10_2 = {
736 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02),
737 };
738
Neale Rannsf12a83f2017-04-18 09:09:40 -0700739 FIB_TEST((0 == pool_elts(load_balance_map_pool)), "LB-map pool size is %d",
740 pool_elts(load_balance_map_pool));
741
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100742 tm = &test_main;
743
Neale Ranns994dab42017-04-18 12:56:45 -0700744 /* record the nubmer of load-balances in use before we start */
745 lb_count = pool_elts(load_balance_pool);
746
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100747 /* Find or create FIB table 11 */
Neale Ranns15002542017-09-10 04:39:11 -0700748 fib_index = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP4, 11,
749 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100750
751 for (ii = 0; ii < 4; ii++)
752 {
753 ip4_main.fib_index_by_sw_if_index[tm->hw[ii]->sw_if_index] = fib_index;
754 }
755
756 fib_prefix_t pfx_0_0_0_0_s_0 = {
757 .fp_len = 0,
758 .fp_proto = FIB_PROTOCOL_IP4,
759 .fp_addr = {
760 .ip4 = {
761 {0}
762 },
763 },
764 };
765
766 fib_prefix_t pfx = {
767 .fp_len = 0,
768 .fp_proto = FIB_PROTOCOL_IP4,
769 .fp_addr = {
770 .ip4 = {
771 {0}
772 },
773 },
774 };
775
776 dpo_drop = drop_dpo_get(DPO_PROTO_IP4);
777
778 dfrt = fib_table_lookup(fib_index, &pfx_0_0_0_0_s_0);
779 FIB_TEST((FIB_NODE_INDEX_INVALID != dfrt), "default route present");
780 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(dfrt)),
781 "Default route is DROP");
782
783 pfx.fp_len = 32;
784 fei = fib_table_lookup(fib_index, &pfx);
785 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "all zeros route present");
786 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
787 "all 0s route is DROP");
788
789 pfx.fp_addr.ip4.as_u32 = clib_host_to_net_u32(0xffffffff);
790 pfx.fp_len = 32;
791 fei = fib_table_lookup(fib_index, &pfx);
792 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "all ones route present");
793 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
794 "all 1s route is DROP");
795
796 pfx.fp_addr.ip4.as_u32 = clib_host_to_net_u32(0xe0000000);
797 pfx.fp_len = 8;
798 fei = fib_table_lookup(fib_index, &pfx);
799 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "all-mcast route present");
800 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
801 "all-mcast route is DROP");
802
803 pfx.fp_addr.ip4.as_u32 = clib_host_to_net_u32(0xf0000000);
804 pfx.fp_len = 8;
805 fei = fib_table_lookup(fib_index, &pfx);
806 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "class-e route present");
807 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
808 "class-e route is DROP");
809
810 /*
811 * at this stage there are 5 entries in the test FIB (plus 5 in the default),
812 * all of which are special sourced and so none of which share path-lists.
Neale Ranns32e1c012016-11-22 17:07:28 +0000813 * There are also 2 entries, and 2 non-shared path-lists, in the v6 default
814 * table, and 4 path-lists in the v6 MFIB table
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100815 */
Neale Ranns32e1c012016-11-22 17:07:28 +0000816#define ENBR (5+5+2)
817#define PNBR (5+5+6)
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100818 FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +0000819 FIB_TEST((PNBR == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100820 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +0000821 FIB_TEST((ENBR == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100822 fib_entry_pool_size());
823
824 /*
825 * add interface routes.
826 * validate presence of /24 attached and /32 recieve.
827 * test for the presence of the receive address in the glean and local adj
828 */
829 fib_prefix_t local_pfx = {
830 .fp_len = 24,
831 .fp_proto = FIB_PROTOCOL_IP4,
832 .fp_addr = {
833 .ip4 = {
834 .as_u32 = clib_host_to_net_u32(0x0a0a0a0a),
835 },
836 },
837 };
838
839 fib_table_entry_update_one_path(fib_index, &local_pfx,
840 FIB_SOURCE_INTERFACE,
841 (FIB_ENTRY_FLAG_CONNECTED |
842 FIB_ENTRY_FLAG_ATTACHED),
Neale Rannsda78f952017-05-24 09:15:43 -0700843 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100844 NULL,
845 tm->hw[0]->sw_if_index,
846 ~0, // invalid fib index
847 1, // weight
Neale Rannsad422ed2016-11-02 14:20:04 +0000848 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100849 FIB_ROUTE_PATH_FLAG_NONE);
850 fei = fib_table_lookup(fib_index, &local_pfx);
851 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached interface route present");
852 FIB_TEST(((FIB_ENTRY_FLAG_ATTACHED | FIB_ENTRY_FLAG_CONNECTED) ==
853 fib_entry_get_flags(fei)),
854 "Flags set on attached interface");
855
856 ai = fib_entry_get_adj(fei);
Neale Ranns81424992017-05-18 03:03:22 -0700857 FIB_TEST((FIB_NODE_INDEX_INVALID != ai),
858 "attached interface route adj present %d", ai);
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100859 adj = adj_get(ai);
860 FIB_TEST((IP_LOOKUP_NEXT_GLEAN == adj->lookup_next_index),
861 "attached interface adj is glean");
862 FIB_TEST((0 == ip46_address_cmp(&local_pfx.fp_addr,
863 &adj->sub_type.glean.receive_addr)),
864 "attached interface adj is receive ok");
865
866 local_pfx.fp_len = 32;
867 fib_table_entry_update_one_path(fib_index, &local_pfx,
868 FIB_SOURCE_INTERFACE,
869 (FIB_ENTRY_FLAG_CONNECTED |
870 FIB_ENTRY_FLAG_LOCAL),
Neale Rannsda78f952017-05-24 09:15:43 -0700871 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100872 NULL,
873 tm->hw[0]->sw_if_index,
874 ~0, // invalid fib index
875 1, // weight
Neale Rannsad422ed2016-11-02 14:20:04 +0000876 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100877 FIB_ROUTE_PATH_FLAG_NONE);
878 fei = fib_table_lookup(fib_index, &local_pfx);
879 FIB_TEST(((FIB_ENTRY_FLAG_LOCAL | FIB_ENTRY_FLAG_CONNECTED) ==
880 fib_entry_get_flags(fei)),
881 "Flags set on local interface");
882
883 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local interface route present");
884
885 dpo = fib_entry_contribute_ip_forwarding(fei);
Neale Ranns3ee44042016-10-03 13:05:48 +0100886 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 0),
887 "RPF list for local length 0");
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100888 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
889 FIB_TEST((DPO_RECEIVE == dpo->dpoi_type),
890 "local interface adj is local");
891 receive_dpo_t *rd = receive_dpo_get(dpo->dpoi_index);
892
893 FIB_TEST((0 == ip46_address_cmp(&local_pfx.fp_addr,
894 &rd->rd_addr)),
895 "local interface adj is receive ok");
896
897 FIB_TEST((2 == fib_table_get_num_entries(fib_index,
898 FIB_PROTOCOL_IP4,
899 FIB_SOURCE_INTERFACE)),
900 "2 Interface Source'd prefixes");
901
902 /*
903 * +2 interface routes +2 non-shared path-lists
904 */
905 FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +0000906 FIB_TEST((PNBR+2 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100907 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +0000908 FIB_TEST((ENBR+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100909 fib_entry_pool_size());
910
911 /*
912 * Modify the default route to be via an adj not yet known.
913 * this sources the defalut route with the API source, which is
914 * a higher preference to the DEFAULT_ROUTE source
915 */
916 pfx.fp_addr.ip4.as_u32 = 0;
917 pfx.fp_len = 0;
918 fib_table_entry_path_add(fib_index, &pfx,
919 FIB_SOURCE_API,
920 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -0700921 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100922 &nh_10_10_10_1,
923 tm->hw[0]->sw_if_index,
924 ~0, // invalid fib index
925 1,
Neale Rannsad422ed2016-11-02 14:20:04 +0000926 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100927 FIB_ROUTE_PATH_FLAG_NONE);
928 fei = fib_table_lookup(fib_index, &pfx);
929 FIB_TEST((FIB_ENTRY_FLAG_NONE == fib_entry_get_flags(fei)),
930 "Flags set on API route");
931
932 FIB_TEST((fei == dfrt), "default route same index");
933 ai = fib_entry_get_adj(fei);
934 FIB_TEST((FIB_NODE_INDEX_INVALID != ai), "default route adj present");
935 adj = adj_get(ai);
936 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
937 "adj is incomplete");
938 FIB_TEST((0 == ip46_address_cmp(&nh_10_10_10_1, &adj->sub_type.nbr.next_hop)),
939 "adj nbr next-hop ok");
940 FIB_TEST((1 == fib_table_get_num_entries(fib_index,
941 FIB_PROTOCOL_IP4,
942 FIB_SOURCE_API)),
943 "1 API Source'd prefixes");
944
945 /*
946 * find the adj in the shared db
947 */
948 locked_ai = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +0100949 VNET_LINK_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100950 &nh_10_10_10_1,
951 tm->hw[0]->sw_if_index);
952 FIB_TEST((locked_ai == ai), "ADJ NBR DB find");
953 adj_unlock(locked_ai);
954
955 /*
956 * +1 shared path-list
957 */
958 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
959 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +0000960 FIB_TEST((PNBR+3 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100961 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +0000962 FIB_TEST((ENBR+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100963 fib_entry_pool_size());
964
965 /*
966 * remove the API source from the default route. We expected
967 * the route to remain, sourced by DEFAULT_ROUTE, and hence a DROP
968 */
969 pfx.fp_addr.ip4.as_u32 = 0;
970 pfx.fp_len = 0;
971 fib_table_entry_path_remove(fib_index, &pfx,
972 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -0700973 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100974 &nh_10_10_10_1,
975 tm->hw[0]->sw_if_index,
976 ~0, // non-recursive path, so no FIB index
977 1,
978 FIB_ROUTE_PATH_FLAG_NONE);
979
980 fei = fib_table_lookup(fib_index, &pfx);
981
982 FIB_TEST((fei == dfrt), "default route same index");
983 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
984 "Default route is DROP");
985
986 /*
987 * -1 shared-path-list
988 */
989 FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +0000990 FIB_TEST((PNBR+2 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100991 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +0000992 FIB_TEST((ENBR+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100993 fib_entry_pool_size());
994
995 /*
996 * Add an 2 ARP entry => a complete ADJ plus adj-fib.
997 */
998 fib_prefix_t pfx_10_10_10_1_s_32 = {
999 .fp_len = 32,
1000 .fp_proto = FIB_PROTOCOL_IP4,
1001 .fp_addr = {
1002 /* 10.10.10.1 */
1003 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
1004 },
1005 };
1006 fib_prefix_t pfx_10_10_10_2_s_32 = {
1007 .fp_len = 32,
1008 .fp_proto = FIB_PROTOCOL_IP4,
1009 .fp_addr = {
1010 /* 10.10.10.2 */
1011 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02),
1012 },
1013 };
1014 fib_prefix_t pfx_11_11_11_11_s_32 = {
1015 .fp_len = 32,
1016 .fp_proto = FIB_PROTOCOL_IP4,
1017 .fp_addr = {
1018 /* 11.11.11.11 */
1019 .ip4.as_u32 = clib_host_to_net_u32(0x0b0b0b0b),
1020 },
1021 };
1022 u8 eth_addr[] = {
1023 0xde, 0xde, 0xde, 0xba, 0xba, 0xba,
1024 };
Neale Rannsb80c5362016-10-08 13:03:40 +01001025
Neale Ranns3ee44042016-10-03 13:05:48 +01001026 ip46_address_t nh_12_12_12_12 = {
1027 .ip4.as_u32 = clib_host_to_net_u32(0x0c0c0c0c),
1028 };
1029 adj_index_t ai_12_12_12_12;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001030
1031 /*
1032 * Add a route via an incomplete ADJ. then complete the ADJ
1033 * Expect the route LB is updated to use complete adj type.
1034 */
1035 fei = fib_table_entry_update_one_path(fib_index,
1036 &pfx_11_11_11_11_s_32,
1037 FIB_SOURCE_API,
1038 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07001039 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001040 &pfx_10_10_10_1_s_32.fp_addr,
1041 tm->hw[0]->sw_if_index,
1042 ~0, // invalid fib index
1043 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001044 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001045 FIB_ROUTE_PATH_FLAG_NONE);
1046
1047 dpo = fib_entry_contribute_ip_forwarding(fei);
1048 dpo1 = load_balance_get_bucket(dpo->dpoi_index, 0);
1049 FIB_TEST(DPO_ADJACENCY_INCOMPLETE == dpo1->dpoi_type,
1050 "11.11.11.11/32 via incomplete adj");
1051
1052 ai_01 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01001053 VNET_LINK_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001054 &pfx_10_10_10_1_s_32.fp_addr,
1055 tm->hw[0]->sw_if_index);
1056 FIB_TEST((FIB_NODE_INDEX_INVALID != ai_01), "adj created");
1057 adj = adj_get(ai_01);
1058 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
1059 "adj is incomplete");
1060 FIB_TEST((0 == ip46_address_cmp(&pfx_10_10_10_1_s_32.fp_addr,
1061 &adj->sub_type.nbr.next_hop)),
1062 "adj nbr next-hop ok");
1063
Neale Rannsb80c5362016-10-08 13:03:40 +01001064 adj_nbr_update_rewrite(ai_01, ADJ_NBR_REWRITE_FLAG_COMPLETE,
1065 fib_test_build_rewrite(eth_addr));
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001066 FIB_TEST((IP_LOOKUP_NEXT_REWRITE == adj->lookup_next_index),
1067 "adj is complete");
1068 FIB_TEST((0 == ip46_address_cmp(&pfx_10_10_10_1_s_32.fp_addr,
1069 &adj->sub_type.nbr.next_hop)),
1070 "adj nbr next-hop ok");
1071 ai = fib_entry_get_adj(fei);
1072 FIB_TEST((ai_01 == ai), "ADJ-FIB resolves via adj");
1073
1074 dpo = fib_entry_contribute_ip_forwarding(fei);
1075 dpo1 = load_balance_get_bucket(dpo->dpoi_index, 0);
1076 FIB_TEST(DPO_ADJACENCY == dpo1->dpoi_type,
1077 "11.11.11.11/32 via complete adj");
Neale Ranns3ee44042016-10-03 13:05:48 +01001078 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 1,
1079 tm->hw[0]->sw_if_index),
1080 "RPF list for adj-fib contains adj");
1081
1082 ai_12_12_12_12 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01001083 VNET_LINK_IP4,
Neale Ranns3ee44042016-10-03 13:05:48 +01001084 &nh_12_12_12_12,
1085 tm->hw[1]->sw_if_index);
1086 FIB_TEST((FIB_NODE_INDEX_INVALID != ai_12_12_12_12), "adj created");
1087 adj = adj_get(ai_12_12_12_12);
1088 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
1089 "adj is incomplete");
1090 FIB_TEST((0 == ip46_address_cmp(&nh_12_12_12_12,
1091 &adj->sub_type.nbr.next_hop)),
1092 "adj nbr next-hop ok");
Neale Rannsb80c5362016-10-08 13:03:40 +01001093 adj_nbr_update_rewrite(ai_12_12_12_12, ADJ_NBR_REWRITE_FLAG_COMPLETE,
1094 fib_test_build_rewrite(eth_addr));
Neale Ranns3ee44042016-10-03 13:05:48 +01001095 FIB_TEST((IP_LOOKUP_NEXT_REWRITE == adj->lookup_next_index),
1096 "adj is complete");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001097
1098 /*
1099 * add the adj fib
1100 */
Neale Ranns81424992017-05-18 03:03:22 -07001101 fei = fib_table_entry_path_add(fib_index,
1102 &pfx_10_10_10_1_s_32,
1103 FIB_SOURCE_ADJ,
1104 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07001105 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07001106 &pfx_10_10_10_1_s_32.fp_addr,
1107 tm->hw[0]->sw_if_index,
1108 ~0, // invalid fib index
1109 1,
1110 NULL,
1111 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001112 FIB_TEST((FIB_ENTRY_FLAG_ATTACHED == fib_entry_get_flags(fei)),
1113 "Flags set on adj-fib");
1114 ai = fib_entry_get_adj(fei);
Neale Ranns81424992017-05-18 03:03:22 -07001115 FIB_TEST((ai_01 == ai), "ADJ-FIB resolves via adj, %d", ai);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001116
1117 fib_table_entry_path_remove(fib_index,
1118 &pfx_11_11_11_11_s_32,
1119 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07001120 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001121 &pfx_10_10_10_1_s_32.fp_addr,
1122 tm->hw[0]->sw_if_index,
1123 ~0, // invalid fib index
1124 1,
1125 FIB_ROUTE_PATH_FLAG_NONE);
1126
1127 eth_addr[5] = 0xb2;
1128
1129 ai_02 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01001130 VNET_LINK_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001131 &pfx_10_10_10_2_s_32.fp_addr,
1132 tm->hw[0]->sw_if_index);
1133 FIB_TEST((FIB_NODE_INDEX_INVALID != ai_02), "adj created");
1134 adj = adj_get(ai_02);
1135 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
1136 "adj is incomplete");
1137 FIB_TEST((0 == ip46_address_cmp(&pfx_10_10_10_2_s_32.fp_addr,
1138 &adj->sub_type.nbr.next_hop)),
1139 "adj nbr next-hop ok");
1140
Neale Rannsb80c5362016-10-08 13:03:40 +01001141 adj_nbr_update_rewrite(ai_02, ADJ_NBR_REWRITE_FLAG_COMPLETE,
1142 fib_test_build_rewrite(eth_addr));
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001143 FIB_TEST((IP_LOOKUP_NEXT_REWRITE == adj->lookup_next_index),
1144 "adj is complete");
1145 FIB_TEST((0 == ip46_address_cmp(&pfx_10_10_10_2_s_32.fp_addr,
1146 &adj->sub_type.nbr.next_hop)),
1147 "adj nbr next-hop ok");
1148 FIB_TEST((ai_01 != ai_02), "ADJs are different");
1149
Neale Ranns81424992017-05-18 03:03:22 -07001150 fib_table_entry_path_add(fib_index,
1151 &pfx_10_10_10_2_s_32,
1152 FIB_SOURCE_ADJ,
1153 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07001154 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07001155 &pfx_10_10_10_2_s_32.fp_addr,
1156 tm->hw[0]->sw_if_index,
1157 ~0, // invalid fib index
1158 1,
1159 NULL,
1160 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001161
1162 fei = fib_table_lookup(fib_index, &pfx_10_10_10_2_s_32);
1163 ai = fib_entry_get_adj(fei);
1164 FIB_TEST((ai_02 == ai), "ADJ-FIB resolves via adj");
1165
1166 /*
1167 * +2 adj-fibs, and their non-shared path-lists
1168 */
1169 FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00001170 FIB_TEST((PNBR+4 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001171 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001172 FIB_TEST((ENBR+4 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001173 fib_entry_pool_size());
1174
1175 /*
Neale Ranns3ee44042016-10-03 13:05:48 +01001176 * Add 2 routes via the first ADJ. ensure path-list sharing
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001177 */
1178 fib_prefix_t pfx_1_1_1_1_s_32 = {
1179 .fp_len = 32,
1180 .fp_proto = FIB_PROTOCOL_IP4,
1181 .fp_addr = {
1182 /* 1.1.1.1/32 */
1183 .ip4.as_u32 = clib_host_to_net_u32(0x01010101),
1184 },
1185 };
1186
1187 fib_table_entry_path_add(fib_index,
1188 &pfx_1_1_1_1_s_32,
1189 FIB_SOURCE_API,
1190 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001191 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001192 &nh_10_10_10_1,
1193 tm->hw[0]->sw_if_index,
1194 ~0, // invalid fib index
1195 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001196 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001197 FIB_ROUTE_PATH_FLAG_NONE);
1198 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
1199 ai = fib_entry_get_adj(fei);
1200 FIB_TEST((ai_01 == ai), "1.1.1.1 resolves via 10.10.10.1");
1201
1202 /*
1203 * +1 entry and a shared path-list
1204 */
1205 FIB_TEST((1 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00001206 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001207 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001208 FIB_TEST((ENBR+5 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001209 fib_entry_pool_size());
1210
1211 /* 1.1.2.0/24 */
1212 fib_prefix_t pfx_1_1_2_0_s_24 = {
1213 .fp_len = 24,
1214 .fp_proto = FIB_PROTOCOL_IP4,
1215 .fp_addr = {
1216 .ip4.as_u32 = clib_host_to_net_u32(0x01010200),
1217 }
1218 };
1219
1220 fib_table_entry_path_add(fib_index,
1221 &pfx_1_1_2_0_s_24,
1222 FIB_SOURCE_API,
1223 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001224 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001225 &nh_10_10_10_1,
1226 tm->hw[0]->sw_if_index,
1227 ~0, // invalid fib index
1228 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001229 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001230 FIB_ROUTE_PATH_FLAG_NONE);
1231 fei = fib_table_lookup(fib_index, &pfx_1_1_2_0_s_24);
1232 ai = fib_entry_get_adj(fei);
1233 FIB_TEST((ai_01 == ai), "1.1.2.0/24 resolves via 10.10.10.1");
1234
1235 /*
1236 * +1 entry only
1237 */
1238 FIB_TEST((1 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00001239 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001240 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001241 FIB_TEST((ENBR+6 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001242 fib_entry_pool_size());
1243
1244 /*
1245 * modify 1.1.2.0/24 to use multipath.
1246 */
1247 fib_table_entry_path_add(fib_index,
1248 &pfx_1_1_2_0_s_24,
1249 FIB_SOURCE_API,
1250 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001251 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001252 &nh_10_10_10_2,
1253 tm->hw[0]->sw_if_index,
1254 ~0, // invalid fib index
1255 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001256 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001257 FIB_ROUTE_PATH_FLAG_NONE);
1258 fei = fib_table_lookup(fib_index, &pfx_1_1_2_0_s_24);
1259 dpo = fib_entry_contribute_ip_forwarding(fei);
Neale Ranns3ee44042016-10-03 13:05:48 +01001260 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1261 1, tm->hw[0]->sw_if_index),
1262 "RPF list for 1.1.2.0/24 contains both adjs");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001263
1264 dpo1 = load_balance_get_bucket(dpo->dpoi_index, 0);
1265 FIB_TEST(DPO_ADJACENCY == dpo1->dpoi_type, "type is %d", dpo1->dpoi_type);
1266 FIB_TEST((ai_01 == dpo1->dpoi_index),
1267 "1.1.2.0/24 bucket 0 resolves via 10.10.10.1 (%d=%d)",
1268 ai_01, dpo1->dpoi_index);
1269
1270 dpo1 = load_balance_get_bucket(dpo->dpoi_index, 1);
1271 FIB_TEST(DPO_ADJACENCY == dpo1->dpoi_type, "type is %d", dpo1->dpoi_type);
1272 FIB_TEST((ai_02 == dpo1->dpoi_index),
1273 "1.1.2.0/24 bucket 1 resolves via 10.10.10.2");
1274
1275 /*
1276 * +1 shared-pathlist
1277 */
1278 FIB_TEST((2 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00001279 FIB_TEST((PNBR+6 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001280 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001281 FIB_TEST((ENBR+6 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001282 fib_entry_pool_size());
1283
1284 /*
1285 * revert the modify
1286 */
1287 fib_table_entry_path_remove(fib_index,
1288 &pfx_1_1_2_0_s_24,
1289 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07001290 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001291 &nh_10_10_10_2,
1292 tm->hw[0]->sw_if_index,
1293 ~0,
1294 1,
1295 FIB_ROUTE_PATH_FLAG_NONE);
1296 fei = fib_table_lookup(fib_index, &pfx_1_1_2_0_s_24);
Neale Ranns3ee44042016-10-03 13:05:48 +01001297 dpo = fib_entry_contribute_ip_forwarding(fei);
1298 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1299 1, tm->hw[0]->sw_if_index),
1300 "RPF list for 1.1.2.0/24 contains one adj");
1301
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001302 ai = fib_entry_get_adj(fei);
1303 FIB_TEST((ai_01 == ai), "1.1.2.0/24 resolves via 10.10.10.1");
1304
1305 /*
1306 * +1 shared-pathlist
1307 */
1308 FIB_TEST((1 == fib_path_list_db_size()), "path list DB is %d",
1309 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001310 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001311 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001312 FIB_TEST((ENBR+6 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001313 fib_entry_pool_size());
1314
1315 /*
1316 * Add 2 recursive routes:
1317 * 100.100.100.100/32 via 1.1.1.1/32 => the via entry is installed.
1318 * 100.100.100.101/32 via 1.1.1.1/32 => the via entry is installed.
1319 */
1320 fib_prefix_t bgp_100_pfx = {
1321 .fp_len = 32,
1322 .fp_proto = FIB_PROTOCOL_IP4,
1323 .fp_addr = {
1324 /* 100.100.100.100/32 */
1325 .ip4.as_u32 = clib_host_to_net_u32(0x64646464),
1326 },
1327 };
1328 /* via 1.1.1.1 */
1329 ip46_address_t nh_1_1_1_1 = {
1330 .ip4.as_u32 = clib_host_to_net_u32(0x01010101),
1331 };
1332
Neale Ranns3ee44042016-10-03 13:05:48 +01001333 fei = fib_table_entry_path_add(fib_index,
1334 &bgp_100_pfx,
1335 FIB_SOURCE_API,
1336 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001337 DPO_PROTO_IP4,
Neale Ranns3ee44042016-10-03 13:05:48 +01001338 &nh_1_1_1_1,
1339 ~0, // no index provided.
1340 fib_index, // nexthop in same fib as route
1341 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001342 NULL,
Neale Ranns3ee44042016-10-03 13:05:48 +01001343 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001344
Neale Ranns3ee44042016-10-03 13:05:48 +01001345 FIB_TEST_REC_FORW(&bgp_100_pfx, &pfx_1_1_1_1_s_32, 0);
1346 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 1,
1347 tm->hw[0]->sw_if_index),
1348 "RPF list for adj-fib contains adj");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001349
1350 /*
1351 * +1 entry and +1 shared-path-list
1352 */
1353 FIB_TEST((2 == fib_path_list_db_size()), "path list DB population:%d",
1354 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001355 FIB_TEST((PNBR+6 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001356 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001357 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001358 fib_entry_pool_size());
1359
1360 fib_prefix_t bgp_101_pfx = {
1361 .fp_len = 32,
1362 .fp_proto = FIB_PROTOCOL_IP4,
1363 .fp_addr = {
1364 /* 100.100.100.101/32 */
1365 .ip4.as_u32 = clib_host_to_net_u32(0x64646465),
1366 },
1367 };
1368
1369 fib_table_entry_path_add(fib_index,
1370 &bgp_101_pfx,
1371 FIB_SOURCE_API,
1372 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001373 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001374 &nh_1_1_1_1,
1375 ~0, // no index provided.
1376 fib_index, // nexthop in same fib as route
1377 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001378 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001379 FIB_ROUTE_PATH_FLAG_NONE);
1380
Neale Ranns3ee44042016-10-03 13:05:48 +01001381 FIB_TEST_REC_FORW(&bgp_101_pfx, &pfx_1_1_1_1_s_32, 0);
1382 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 1,
1383 tm->hw[0]->sw_if_index),
1384 "RPF list for adj-fib contains adj");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001385
1386 /*
1387 * +1 entry, but the recursive path-list is shared.
1388 */
1389 FIB_TEST((2 == fib_path_list_db_size()), "path list DB population:%d",
1390 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001391 FIB_TEST((PNBR+6 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001392 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001393 FIB_TEST((ENBR+8 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001394 fib_entry_pool_size());
1395
1396 /*
Neale Rannsa0558302017-04-13 00:44:52 -07001397 * An special route; one where the user (me) provides the
1398 * adjacency through which the route will resovle by setting the flags
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001399 */
1400 fib_prefix_t ex_pfx = {
1401 .fp_len = 32,
1402 .fp_proto = FIB_PROTOCOL_IP4,
1403 .fp_addr = {
1404 /* 4.4.4.4/32 */
1405 .ip4.as_u32 = clib_host_to_net_u32(0x04040404),
1406 },
1407 };
1408
1409 fib_table_entry_special_add(fib_index,
1410 &ex_pfx,
1411 FIB_SOURCE_SPECIAL,
Neale Rannsa0558302017-04-13 00:44:52 -07001412 FIB_ENTRY_FLAG_LOCAL);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001413 fei = fib_table_lookup_exact_match(fib_index, &ex_pfx);
Neale Rannsa0558302017-04-13 00:44:52 -07001414 dpo = fib_entry_contribute_ip_forwarding(fei);
1415 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
1416 FIB_TEST((DPO_RECEIVE == dpo->dpoi_type),
1417 "local interface adj is local");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001418
1419 fib_table_entry_special_remove(fib_index,
1420 &ex_pfx,
1421 FIB_SOURCE_SPECIAL);
1422 FIB_TEST(FIB_NODE_INDEX_INVALID ==
1423 fib_table_lookup_exact_match(fib_index, &ex_pfx),
1424 "Exclusive reoute removed");
1425
1426 /*
1427 * An EXCLUSIVE route; one where the user (me) provides the exclusive
1428 * adjacency through which the route will resovle
1429 */
Neale Ranns948e00f2016-10-20 13:39:34 +01001430 dpo_id_t ex_dpo = DPO_INVALID;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001431
1432 lookup_dpo_add_or_lock_w_fib_index(fib_index,
1433 DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001434 LOOKUP_UNICAST,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001435 LOOKUP_INPUT_DST_ADDR,
1436 LOOKUP_TABLE_FROM_CONFIG,
1437 &ex_dpo);
1438
1439 fib_table_entry_special_dpo_add(fib_index,
1440 &ex_pfx,
1441 FIB_SOURCE_SPECIAL,
1442 FIB_ENTRY_FLAG_EXCLUSIVE,
1443 &ex_dpo);
1444 fei = fib_table_lookup_exact_match(fib_index, &ex_pfx);
1445 dpo = fib_entry_contribute_ip_forwarding(fei);
1446 FIB_TEST(!dpo_cmp(&ex_dpo, load_balance_get_bucket(dpo->dpoi_index, 0)),
1447 "exclusive remote uses lookup DPO");
1448
Neale Ranns948e00f2016-10-20 13:39:34 +01001449 /*
1450 * update the exclusive to use a different DPO
1451 */
Neale Ranns450cd302016-11-09 17:49:42 +00001452 ip_null_dpo_add_and_lock(DPO_PROTO_IP4,
Neale Ranns948e00f2016-10-20 13:39:34 +01001453 IP_NULL_ACTION_SEND_ICMP_UNREACH,
1454 &ex_dpo);
1455 fib_table_entry_special_dpo_update(fib_index,
1456 &ex_pfx,
1457 FIB_SOURCE_SPECIAL,
1458 FIB_ENTRY_FLAG_EXCLUSIVE,
1459 &ex_dpo);
1460 dpo = fib_entry_contribute_ip_forwarding(fei);
1461 FIB_TEST(!dpo_cmp(&ex_dpo, load_balance_get_bucket(dpo->dpoi_index, 0)),
1462 "exclusive remote uses now uses NULL DPO");
1463
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001464 fib_table_entry_special_remove(fib_index,
1465 &ex_pfx,
1466 FIB_SOURCE_SPECIAL);
1467 FIB_TEST(FIB_NODE_INDEX_INVALID ==
1468 fib_table_lookup_exact_match(fib_index, &ex_pfx),
1469 "Exclusive reoute removed");
1470 dpo_reset(&ex_dpo);
1471
1472 /*
1473 * Add a recursive route:
1474 * 200.200.200.200/32 via 1.1.1.2/32 => the via entry is NOT installed.
1475 */
1476 fib_prefix_t bgp_200_pfx = {
1477 .fp_len = 32,
1478 .fp_proto = FIB_PROTOCOL_IP4,
1479 .fp_addr = {
1480 /* 200.200.200.200/32 */
1481 .ip4.as_u32 = clib_host_to_net_u32(0xc8c8c8c8),
1482 },
1483 };
1484 /* via 1.1.1.2 */
1485 fib_prefix_t pfx_1_1_1_2_s_32 = {
1486 .fp_len = 32,
1487 .fp_proto = FIB_PROTOCOL_IP4,
1488 .fp_addr = {
1489 .ip4.as_u32 = clib_host_to_net_u32(0x01010102),
1490 },
1491 };
1492
Neale Ranns57b58602017-07-15 07:37:25 -07001493 fei = fib_table_entry_path_add(fib_index,
1494 &bgp_200_pfx,
1495 FIB_SOURCE_API,
1496 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001497 DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07001498 &pfx_1_1_1_2_s_32.fp_addr,
1499 ~0, // no index provided.
1500 fib_index, // nexthop in same fib as route
1501 1,
1502 NULL,
1503 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001504
Neale Ranns57b58602017-07-15 07:37:25 -07001505 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
1506 "Recursive via unresolved is drop");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001507
1508 /*
1509 * the adj should be recursive via drop, since the route resolves via
1510 * the default route, which is itself a DROP
1511 */
1512 fei = fib_table_lookup(fib_index, &pfx_1_1_1_2_s_32);
1513 dpo1 = fib_entry_contribute_ip_forwarding(fei);
1514 FIB_TEST(load_balance_is_drop(dpo1), "1.1.1.2/32 is drop");
Neale Ranns3ee44042016-10-03 13:05:48 +01001515 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 0),
1516 "RPF list for 1.1.1.2/32 contains 0 adjs");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001517
1518 /*
1519 * +2 entry and +1 shared-path-list
1520 */
1521 FIB_TEST((3 == fib_path_list_db_size()), "path list DB population:%d",
1522 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001523 FIB_TEST((PNBR+7 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001524 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001525 FIB_TEST((ENBR+10 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001526 fib_entry_pool_size());
1527
1528 /*
1529 * Unequal Cost load-balance. 3:1 ratio. fits in a 4 bucket LB
Neale Ranns3ee44042016-10-03 13:05:48 +01001530 * The paths are sort by NH first. in this case the the path with greater
1531 * weight is first in the set. This ordering is to test the RPF sort|uniq logic
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001532 */
1533 fib_prefix_t pfx_1_2_3_4_s_32 = {
1534 .fp_len = 32,
1535 .fp_proto = FIB_PROTOCOL_IP4,
1536 .fp_addr = {
1537 .ip4.as_u32 = clib_host_to_net_u32(0x01020304),
1538 },
1539 };
1540 fib_table_entry_path_add(fib_index,
1541 &pfx_1_2_3_4_s_32,
1542 FIB_SOURCE_API,
1543 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001544 DPO_PROTO_IP4,
Neale Ranns3ee44042016-10-03 13:05:48 +01001545 &nh_10_10_10_1,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001546 tm->hw[0]->sw_if_index,
1547 ~0,
1548 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001549 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001550 FIB_ROUTE_PATH_FLAG_NONE);
1551 fei = fib_table_entry_path_add(fib_index,
1552 &pfx_1_2_3_4_s_32,
1553 FIB_SOURCE_API,
1554 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001555 DPO_PROTO_IP4,
Neale Ranns3ee44042016-10-03 13:05:48 +01001556 &nh_12_12_12_12,
1557 tm->hw[1]->sw_if_index,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001558 ~0,
1559 3,
Neale Rannsad422ed2016-11-02 14:20:04 +00001560 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001561 FIB_ROUTE_PATH_FLAG_NONE);
1562
1563 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "1.2.3.4/32 presnet");
1564 dpo = fib_entry_contribute_ip_forwarding(fei);
1565 lb = load_balance_get(dpo->dpoi_index);
1566 FIB_TEST((lb->lb_n_buckets == 4),
1567 "1.2.3.4/32 LB has %d bucket",
1568 lb->lb_n_buckets);
1569
Neale Ranns3ee44042016-10-03 13:05:48 +01001570 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_4_s_32, 0, ai_12_12_12_12);
1571 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_4_s_32, 1, ai_12_12_12_12);
1572 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_4_s_32, 2, ai_12_12_12_12);
1573 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_4_s_32, 3, ai_01);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001574
Neale Ranns3ee44042016-10-03 13:05:48 +01001575 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 2,
1576 tm->hw[0]->sw_if_index,
1577 tm->hw[1]->sw_if_index),
1578 "RPF list for 1.2.3.4/32 contains both adjs");
1579
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001580
1581 /*
1582 * Unequal Cost load-balance. 4:1 ratio.
1583 * fits in a 16 bucket LB with ratio 13:3
1584 */
1585 fib_prefix_t pfx_1_2_3_5_s_32 = {
1586 .fp_len = 32,
1587 .fp_proto = FIB_PROTOCOL_IP4,
1588 .fp_addr = {
1589 .ip4.as_u32 = clib_host_to_net_u32(0x01020305),
1590 },
1591 };
1592 fib_table_entry_path_add(fib_index,
1593 &pfx_1_2_3_5_s_32,
1594 FIB_SOURCE_API,
1595 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001596 DPO_PROTO_IP4,
Neale Ranns3ee44042016-10-03 13:05:48 +01001597 &nh_12_12_12_12,
1598 tm->hw[1]->sw_if_index,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001599 ~0,
1600 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001601 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001602 FIB_ROUTE_PATH_FLAG_NONE);
1603 fei = fib_table_entry_path_add(fib_index,
1604 &pfx_1_2_3_5_s_32,
1605 FIB_SOURCE_API,
1606 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001607 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001608 &nh_10_10_10_1,
1609 tm->hw[0]->sw_if_index,
1610 ~0,
1611 4,
Neale Rannsad422ed2016-11-02 14:20:04 +00001612 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001613 FIB_ROUTE_PATH_FLAG_NONE);
1614
1615 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "1.2.3.5/32 presnet");
1616 dpo = fib_entry_contribute_ip_forwarding(fei);
1617 lb = load_balance_get(dpo->dpoi_index);
1618 FIB_TEST((lb->lb_n_buckets == 16),
1619 "1.2.3.5/32 LB has %d bucket",
1620 lb->lb_n_buckets);
1621
1622 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 0, ai_01);
1623 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 1, ai_01);
1624 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 2, ai_01);
1625 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 3, ai_01);
1626 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 4, ai_01);
1627 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 5, ai_01);
1628 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 6, ai_01);
1629 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 7, ai_01);
1630 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 8, ai_01);
1631 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 9, ai_01);
1632 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 10, ai_01);
1633 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 11, ai_01);
1634 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 12, ai_01);
Neale Ranns3ee44042016-10-03 13:05:48 +01001635 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 13, ai_12_12_12_12);
1636 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 14, ai_12_12_12_12);
1637 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 15, ai_12_12_12_12);
1638
1639 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 2,
1640 tm->hw[0]->sw_if_index,
1641 tm->hw[1]->sw_if_index),
1642 "RPF list for 1.2.3.4/32 contains both adjs");
1643
1644 /*
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001645 * Test UCMP with a large weight skew - this produces load-balance objects with large
1646 * numbers of buckets to accommodate the skew. By updating said load-balances we are
1647 * laso testing the LB in placce modify code when number of buckets is large.
1648 */
1649 fib_prefix_t pfx_6_6_6_6_s_32 = {
1650 .fp_len = 32,
1651 .fp_proto = FIB_PROTOCOL_IP4,
1652 .fp_addr = {
1653 /* 1.1.1.1/32 */
1654 .ip4.as_u32 = clib_host_to_net_u32(0x06060606),
1655 },
1656 };
Neale Ranns81424992017-05-18 03:03:22 -07001657 fib_test_lb_bucket_t ip_o_10_10_10_1 = {
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001658 .type = FT_LB_ADJ,
1659 .adj = {
1660 .adj = ai_01,
1661 },
1662 };
Neale Ranns81424992017-05-18 03:03:22 -07001663 fib_test_lb_bucket_t ip_o_10_10_10_2 = {
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001664 .type = FT_LB_ADJ,
1665 .adj = {
1666 .adj = ai_02,
1667 },
1668 };
1669 fib_test_lb_bucket_t ip_6_6_6_6_o_12_12_12_12 = {
1670 .type = FT_LB_ADJ,
1671 .adj = {
1672 .adj = ai_12_12_12_12,
1673 },
1674 };
1675 fib_table_entry_update_one_path(fib_index,
1676 &pfx_6_6_6_6_s_32,
1677 FIB_SOURCE_API,
1678 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001679 DPO_PROTO_IP4,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001680 &nh_10_10_10_1,
1681 tm->hw[0]->sw_if_index,
1682 ~0, // invalid fib index
1683 0, // zero weigth
Neale Rannsad422ed2016-11-02 14:20:04 +00001684 NULL,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001685 FIB_ROUTE_PATH_FLAG_NONE);
1686
1687 fei = fib_table_lookup(fib_index, &pfx_6_6_6_6_s_32);
1688 FIB_TEST(fib_test_validate_entry(fei,
1689 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1690 1,
Neale Ranns81424992017-05-18 03:03:22 -07001691 &ip_o_10_10_10_1),
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001692 "6.6.6.6/32 via 10.10.10.1");
1693
1694 fib_table_entry_path_add(fib_index,
1695 &pfx_6_6_6_6_s_32,
1696 FIB_SOURCE_API,
1697 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001698 DPO_PROTO_IP4,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001699 &nh_10_10_10_2,
1700 tm->hw[0]->sw_if_index,
1701 ~0, // invalid fib index
1702 100,
Neale Rannsad422ed2016-11-02 14:20:04 +00001703 NULL,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001704 FIB_ROUTE_PATH_FLAG_NONE);
1705
1706 fei = fib_table_lookup(fib_index, &pfx_6_6_6_6_s_32);
1707 FIB_TEST(fib_test_validate_entry(fei,
1708 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1709 64,
Neale Ranns81424992017-05-18 03:03:22 -07001710 &ip_o_10_10_10_2,
1711 &ip_o_10_10_10_2,
1712 &ip_o_10_10_10_2,
1713 &ip_o_10_10_10_2,
1714 &ip_o_10_10_10_2,
1715 &ip_o_10_10_10_2,
1716 &ip_o_10_10_10_2,
1717 &ip_o_10_10_10_2,
1718 &ip_o_10_10_10_2,
1719 &ip_o_10_10_10_2,
1720 &ip_o_10_10_10_2,
1721 &ip_o_10_10_10_2,
1722 &ip_o_10_10_10_2,
1723 &ip_o_10_10_10_2,
1724 &ip_o_10_10_10_2,
1725 &ip_o_10_10_10_2,
1726 &ip_o_10_10_10_2,
1727 &ip_o_10_10_10_2,
1728 &ip_o_10_10_10_2,
1729 &ip_o_10_10_10_2,
1730 &ip_o_10_10_10_2,
1731 &ip_o_10_10_10_2,
1732 &ip_o_10_10_10_2,
1733 &ip_o_10_10_10_2,
1734 &ip_o_10_10_10_2,
1735 &ip_o_10_10_10_2,
1736 &ip_o_10_10_10_2,
1737 &ip_o_10_10_10_2,
1738 &ip_o_10_10_10_2,
1739 &ip_o_10_10_10_2,
1740 &ip_o_10_10_10_2,
1741 &ip_o_10_10_10_2,
1742 &ip_o_10_10_10_2,
1743 &ip_o_10_10_10_2,
1744 &ip_o_10_10_10_2,
1745 &ip_o_10_10_10_2,
1746 &ip_o_10_10_10_2,
1747 &ip_o_10_10_10_2,
1748 &ip_o_10_10_10_2,
1749 &ip_o_10_10_10_2,
1750 &ip_o_10_10_10_2,
1751 &ip_o_10_10_10_2,
1752 &ip_o_10_10_10_2,
1753 &ip_o_10_10_10_2,
1754 &ip_o_10_10_10_2,
1755 &ip_o_10_10_10_2,
1756 &ip_o_10_10_10_2,
1757 &ip_o_10_10_10_2,
1758 &ip_o_10_10_10_2,
1759 &ip_o_10_10_10_2,
1760 &ip_o_10_10_10_2,
1761 &ip_o_10_10_10_2,
1762 &ip_o_10_10_10_2,
1763 &ip_o_10_10_10_2,
1764 &ip_o_10_10_10_2,
1765 &ip_o_10_10_10_2,
1766 &ip_o_10_10_10_2,
1767 &ip_o_10_10_10_2,
1768 &ip_o_10_10_10_2,
1769 &ip_o_10_10_10_2,
1770 &ip_o_10_10_10_2,
1771 &ip_o_10_10_10_2,
1772 &ip_o_10_10_10_2,
1773 &ip_o_10_10_10_1),
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001774 "6.6.6.6/32 via 10.10.10.1 and 10.10.10.2 in 63:1 ratio");
1775
1776 fib_table_entry_path_add(fib_index,
1777 &pfx_6_6_6_6_s_32,
1778 FIB_SOURCE_API,
1779 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001780 DPO_PROTO_IP4,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001781 &nh_12_12_12_12,
1782 tm->hw[1]->sw_if_index,
1783 ~0, // invalid fib index
1784 100,
Neale Rannsad422ed2016-11-02 14:20:04 +00001785 NULL,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001786 FIB_ROUTE_PATH_FLAG_NONE);
1787
1788 fei = fib_table_lookup(fib_index, &pfx_6_6_6_6_s_32);
1789 FIB_TEST(fib_test_validate_entry(fei,
1790 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1791 128,
Neale Ranns81424992017-05-18 03:03:22 -07001792 &ip_o_10_10_10_1,
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_2,
1797 &ip_o_10_10_10_2,
1798 &ip_o_10_10_10_2,
1799 &ip_o_10_10_10_2,
1800 &ip_o_10_10_10_2,
1801 &ip_o_10_10_10_2,
1802 &ip_o_10_10_10_2,
1803 &ip_o_10_10_10_2,
1804 &ip_o_10_10_10_2,
1805 &ip_o_10_10_10_2,
1806 &ip_o_10_10_10_2,
1807 &ip_o_10_10_10_2,
1808 &ip_o_10_10_10_2,
1809 &ip_o_10_10_10_2,
1810 &ip_o_10_10_10_2,
1811 &ip_o_10_10_10_2,
1812 &ip_o_10_10_10_2,
1813 &ip_o_10_10_10_2,
1814 &ip_o_10_10_10_2,
1815 &ip_o_10_10_10_2,
1816 &ip_o_10_10_10_2,
1817 &ip_o_10_10_10_2,
1818 &ip_o_10_10_10_2,
1819 &ip_o_10_10_10_2,
1820 &ip_o_10_10_10_2,
1821 &ip_o_10_10_10_2,
1822 &ip_o_10_10_10_2,
1823 &ip_o_10_10_10_2,
1824 &ip_o_10_10_10_2,
1825 &ip_o_10_10_10_2,
1826 &ip_o_10_10_10_2,
1827 &ip_o_10_10_10_2,
1828 &ip_o_10_10_10_2,
1829 &ip_o_10_10_10_2,
1830 &ip_o_10_10_10_2,
1831 &ip_o_10_10_10_2,
1832 &ip_o_10_10_10_2,
1833 &ip_o_10_10_10_2,
1834 &ip_o_10_10_10_2,
1835 &ip_o_10_10_10_2,
1836 &ip_o_10_10_10_2,
1837 &ip_o_10_10_10_2,
1838 &ip_o_10_10_10_2,
1839 &ip_o_10_10_10_2,
1840 &ip_o_10_10_10_2,
1841 &ip_o_10_10_10_2,
1842 &ip_o_10_10_10_2,
1843 &ip_o_10_10_10_2,
1844 &ip_o_10_10_10_2,
1845 &ip_o_10_10_10_2,
1846 &ip_o_10_10_10_2,
1847 &ip_o_10_10_10_2,
1848 &ip_o_10_10_10_2,
1849 &ip_o_10_10_10_2,
1850 &ip_o_10_10_10_2,
1851 &ip_o_10_10_10_2,
1852 &ip_o_10_10_10_2,
1853 &ip_o_10_10_10_2,
1854 &ip_o_10_10_10_2,
1855 &ip_o_10_10_10_2,
1856 &ip_o_10_10_10_2,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001857 &ip_6_6_6_6_o_12_12_12_12,
1858 &ip_6_6_6_6_o_12_12_12_12,
1859 &ip_6_6_6_6_o_12_12_12_12,
1860 &ip_6_6_6_6_o_12_12_12_12,
1861 &ip_6_6_6_6_o_12_12_12_12,
1862 &ip_6_6_6_6_o_12_12_12_12,
1863 &ip_6_6_6_6_o_12_12_12_12,
1864 &ip_6_6_6_6_o_12_12_12_12,
1865 &ip_6_6_6_6_o_12_12_12_12,
1866 &ip_6_6_6_6_o_12_12_12_12,
1867 &ip_6_6_6_6_o_12_12_12_12,
1868 &ip_6_6_6_6_o_12_12_12_12,
1869 &ip_6_6_6_6_o_12_12_12_12,
1870 &ip_6_6_6_6_o_12_12_12_12,
1871 &ip_6_6_6_6_o_12_12_12_12,
1872 &ip_6_6_6_6_o_12_12_12_12,
1873 &ip_6_6_6_6_o_12_12_12_12,
1874 &ip_6_6_6_6_o_12_12_12_12,
1875 &ip_6_6_6_6_o_12_12_12_12,
1876 &ip_6_6_6_6_o_12_12_12_12,
1877 &ip_6_6_6_6_o_12_12_12_12,
1878 &ip_6_6_6_6_o_12_12_12_12,
1879 &ip_6_6_6_6_o_12_12_12_12,
1880 &ip_6_6_6_6_o_12_12_12_12,
1881 &ip_6_6_6_6_o_12_12_12_12,
1882 &ip_6_6_6_6_o_12_12_12_12,
1883 &ip_6_6_6_6_o_12_12_12_12,
1884 &ip_6_6_6_6_o_12_12_12_12,
1885 &ip_6_6_6_6_o_12_12_12_12,
1886 &ip_6_6_6_6_o_12_12_12_12,
1887 &ip_6_6_6_6_o_12_12_12_12,
1888 &ip_6_6_6_6_o_12_12_12_12,
1889 &ip_6_6_6_6_o_12_12_12_12,
1890 &ip_6_6_6_6_o_12_12_12_12,
1891 &ip_6_6_6_6_o_12_12_12_12,
1892 &ip_6_6_6_6_o_12_12_12_12,
1893 &ip_6_6_6_6_o_12_12_12_12,
1894 &ip_6_6_6_6_o_12_12_12_12,
1895 &ip_6_6_6_6_o_12_12_12_12,
1896 &ip_6_6_6_6_o_12_12_12_12,
1897 &ip_6_6_6_6_o_12_12_12_12,
1898 &ip_6_6_6_6_o_12_12_12_12,
1899 &ip_6_6_6_6_o_12_12_12_12,
1900 &ip_6_6_6_6_o_12_12_12_12,
1901 &ip_6_6_6_6_o_12_12_12_12,
1902 &ip_6_6_6_6_o_12_12_12_12,
1903 &ip_6_6_6_6_o_12_12_12_12,
1904 &ip_6_6_6_6_o_12_12_12_12,
1905 &ip_6_6_6_6_o_12_12_12_12,
1906 &ip_6_6_6_6_o_12_12_12_12,
1907 &ip_6_6_6_6_o_12_12_12_12,
1908 &ip_6_6_6_6_o_12_12_12_12,
1909 &ip_6_6_6_6_o_12_12_12_12,
1910 &ip_6_6_6_6_o_12_12_12_12,
1911 &ip_6_6_6_6_o_12_12_12_12,
1912 &ip_6_6_6_6_o_12_12_12_12,
1913 &ip_6_6_6_6_o_12_12_12_12,
1914 &ip_6_6_6_6_o_12_12_12_12,
1915 &ip_6_6_6_6_o_12_12_12_12,
1916 &ip_6_6_6_6_o_12_12_12_12,
1917 &ip_6_6_6_6_o_12_12_12_12,
1918 &ip_6_6_6_6_o_12_12_12_12,
1919 &ip_6_6_6_6_o_12_12_12_12),
1920 "6.6.6.6/32 via 10.10.10.1 and 10.10.10.2 in 63:1 ratio");
1921
1922 fib_table_entry_path_remove(fib_index,
1923 &pfx_6_6_6_6_s_32,
1924 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07001925 DPO_PROTO_IP4,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001926 &nh_12_12_12_12,
1927 tm->hw[1]->sw_if_index,
1928 ~0, // invalid fib index
1929 100,
1930 FIB_ROUTE_PATH_FLAG_NONE);
1931
1932 fei = fib_table_lookup(fib_index, &pfx_6_6_6_6_s_32);
1933 FIB_TEST(fib_test_validate_entry(fei,
1934 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1935 64,
Neale Ranns81424992017-05-18 03:03:22 -07001936 &ip_o_10_10_10_2,
1937 &ip_o_10_10_10_2,
1938 &ip_o_10_10_10_2,
1939 &ip_o_10_10_10_2,
1940 &ip_o_10_10_10_2,
1941 &ip_o_10_10_10_2,
1942 &ip_o_10_10_10_2,
1943 &ip_o_10_10_10_2,
1944 &ip_o_10_10_10_2,
1945 &ip_o_10_10_10_2,
1946 &ip_o_10_10_10_2,
1947 &ip_o_10_10_10_2,
1948 &ip_o_10_10_10_2,
1949 &ip_o_10_10_10_2,
1950 &ip_o_10_10_10_2,
1951 &ip_o_10_10_10_2,
1952 &ip_o_10_10_10_2,
1953 &ip_o_10_10_10_2,
1954 &ip_o_10_10_10_2,
1955 &ip_o_10_10_10_2,
1956 &ip_o_10_10_10_2,
1957 &ip_o_10_10_10_2,
1958 &ip_o_10_10_10_2,
1959 &ip_o_10_10_10_2,
1960 &ip_o_10_10_10_2,
1961 &ip_o_10_10_10_2,
1962 &ip_o_10_10_10_2,
1963 &ip_o_10_10_10_2,
1964 &ip_o_10_10_10_2,
1965 &ip_o_10_10_10_2,
1966 &ip_o_10_10_10_2,
1967 &ip_o_10_10_10_2,
1968 &ip_o_10_10_10_2,
1969 &ip_o_10_10_10_2,
1970 &ip_o_10_10_10_2,
1971 &ip_o_10_10_10_2,
1972 &ip_o_10_10_10_2,
1973 &ip_o_10_10_10_2,
1974 &ip_o_10_10_10_2,
1975 &ip_o_10_10_10_2,
1976 &ip_o_10_10_10_2,
1977 &ip_o_10_10_10_2,
1978 &ip_o_10_10_10_2,
1979 &ip_o_10_10_10_2,
1980 &ip_o_10_10_10_2,
1981 &ip_o_10_10_10_2,
1982 &ip_o_10_10_10_2,
1983 &ip_o_10_10_10_2,
1984 &ip_o_10_10_10_2,
1985 &ip_o_10_10_10_2,
1986 &ip_o_10_10_10_2,
1987 &ip_o_10_10_10_2,
1988 &ip_o_10_10_10_2,
1989 &ip_o_10_10_10_2,
1990 &ip_o_10_10_10_2,
1991 &ip_o_10_10_10_2,
1992 &ip_o_10_10_10_2,
1993 &ip_o_10_10_10_2,
1994 &ip_o_10_10_10_2,
1995 &ip_o_10_10_10_2,
1996 &ip_o_10_10_10_2,
1997 &ip_o_10_10_10_2,
1998 &ip_o_10_10_10_2,
1999 &ip_o_10_10_10_1),
Neale Ranns0bd36ea2016-11-16 11:47:44 +00002000 "6.6.6.6/32 via 10.10.10.1 and 10.10.10.2 in 63:1 ratio");
2001
2002 fib_table_entry_path_remove(fib_index,
2003 &pfx_6_6_6_6_s_32,
2004 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002005 DPO_PROTO_IP4,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00002006 &nh_10_10_10_2,
2007 tm->hw[0]->sw_if_index,
2008 ~0, // invalid fib index
2009 100,
2010 FIB_ROUTE_PATH_FLAG_NONE);
2011
2012 fei = fib_table_lookup(fib_index, &pfx_6_6_6_6_s_32);
2013 FIB_TEST(fib_test_validate_entry(fei,
2014 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
2015 1,
Neale Ranns81424992017-05-18 03:03:22 -07002016 &ip_o_10_10_10_1),
Neale Ranns0bd36ea2016-11-16 11:47:44 +00002017 "6.6.6.6/32 via 10.10.10.1");
2018
2019 fib_table_entry_delete(fib_index, &pfx_6_6_6_6_s_32, FIB_SOURCE_API);
2020
2021 /*
Neale Ranns3ee44042016-10-03 13:05:48 +01002022 * A recursive via the two unequal cost entries
2023 */
2024 fib_prefix_t bgp_44_s_32 = {
2025 .fp_len = 32,
2026 .fp_proto = FIB_PROTOCOL_IP4,
2027 .fp_addr = {
2028 /* 200.200.200.201/32 */
2029 .ip4.as_u32 = clib_host_to_net_u32(0x44444444),
2030 },
2031 };
2032 fei = fib_table_entry_path_add(fib_index,
2033 &bgp_44_s_32,
2034 FIB_SOURCE_API,
2035 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002036 DPO_PROTO_IP4,
Neale Ranns3ee44042016-10-03 13:05:48 +01002037 &pfx_1_2_3_4_s_32.fp_addr,
2038 ~0,
2039 fib_index,
2040 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002041 NULL,
Neale Ranns3ee44042016-10-03 13:05:48 +01002042 FIB_ROUTE_PATH_FLAG_NONE);
2043 fei = fib_table_entry_path_add(fib_index,
2044 &bgp_44_s_32,
2045 FIB_SOURCE_API,
2046 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002047 DPO_PROTO_IP4,
Neale Ranns3ee44042016-10-03 13:05:48 +01002048 &pfx_1_2_3_5_s_32.fp_addr,
2049 ~0,
2050 fib_index,
2051 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002052 NULL,
Neale Ranns3ee44042016-10-03 13:05:48 +01002053 FIB_ROUTE_PATH_FLAG_NONE);
2054
2055 FIB_TEST_REC_FORW(&bgp_44_s_32, &pfx_1_2_3_4_s_32, 0);
2056 FIB_TEST_REC_FORW(&bgp_44_s_32, &pfx_1_2_3_5_s_32, 1);
2057 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 2,
2058 tm->hw[0]->sw_if_index,
2059 tm->hw[1]->sw_if_index),
2060 "RPF list for 1.2.3.4/32 contains both adjs");
2061
2062 /*
2063 * test the uRPF check functions
2064 */
Neale Ranns948e00f2016-10-20 13:39:34 +01002065 dpo_id_t dpo_44 = DPO_INVALID;
Neale Ranns3ee44042016-10-03 13:05:48 +01002066 index_t urpfi;
2067
2068 fib_entry_contribute_forwarding(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, &dpo_44);
2069 urpfi = load_balance_get_urpf(dpo_44.dpoi_index);
2070
2071 FIB_TEST(fib_urpf_check(urpfi, tm->hw[0]->sw_if_index),
2072 "uRPF check for 68.68.68.68/32 on %d OK",
2073 tm->hw[0]->sw_if_index);
2074 FIB_TEST(fib_urpf_check(urpfi, tm->hw[1]->sw_if_index),
2075 "uRPF check for 68.68.68.68/32 on %d OK",
2076 tm->hw[1]->sw_if_index);
2077 FIB_TEST(!fib_urpf_check(urpfi, 99),
2078 "uRPF check for 68.68.68.68/32 on 99 not-OK",
2079 99);
2080 dpo_reset(&dpo_44);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002081
2082 fib_table_entry_delete(fib_index,
Neale Ranns3ee44042016-10-03 13:05:48 +01002083 &bgp_44_s_32,
2084 FIB_SOURCE_API);
2085 fib_table_entry_delete(fib_index,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002086 &pfx_1_2_3_5_s_32,
2087 FIB_SOURCE_API);
Neale Ranns3ee44042016-10-03 13:05:48 +01002088 fib_table_entry_delete(fib_index,
2089 &pfx_1_2_3_4_s_32,
2090 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002091
2092 /*
2093 * Add a recursive route:
2094 * 200.200.200.201/32 via 1.1.1.200/32 => the via entry is NOT installed.
2095 */
2096 fib_prefix_t bgp_201_pfx = {
2097 .fp_len = 32,
2098 .fp_proto = FIB_PROTOCOL_IP4,
2099 .fp_addr = {
2100 /* 200.200.200.201/32 */
2101 .ip4.as_u32 = clib_host_to_net_u32(0xc8c8c8c9),
2102 },
2103 };
2104 /* via 1.1.1.200 */
2105 fib_prefix_t pfx_1_1_1_200_s_32 = {
2106 .fp_len = 32,
2107 .fp_proto = FIB_PROTOCOL_IP4,
2108 .fp_addr = {
2109 .ip4.as_u32 = clib_host_to_net_u32(0x010101c8),
2110 },
2111 };
2112
Neale Ranns57b58602017-07-15 07:37:25 -07002113 fei = fib_table_entry_path_add(fib_index,
2114 &bgp_201_pfx,
2115 FIB_SOURCE_API,
2116 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002117 DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07002118 &pfx_1_1_1_200_s_32.fp_addr,
2119 ~0, // no index provided.
2120 fib_index, // nexthop in same fib as route
2121 1,
2122 NULL,
2123 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002124
Neale Ranns57b58602017-07-15 07:37:25 -07002125 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2126 "Recursive via unresolved is drop");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002127
2128 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_200_s_32);
2129 FIB_TEST((FIB_ENTRY_FLAG_NONE == fib_entry_get_flags(fei)),
2130 "Flags set on RR via non-attached");
Neale Ranns3ee44042016-10-03 13:05:48 +01002131 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 0),
2132 "RPF list for BGP route empty");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002133
2134 /*
2135 * +2 entry (BGP & RR) and +1 shared-path-list
2136 */
2137 FIB_TEST((4 == fib_path_list_db_size()), "path list DB population:%d",
2138 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002139 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002140 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002141 FIB_TEST((ENBR+12 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002142 fib_entry_pool_size());
2143
2144 /*
2145 * insert a route that covers the missing 1.1.1.2/32. we epxect
2146 * 200.200.200.200/32 and 200.200.200.201/32 to resolve through it.
2147 */
2148 fib_prefix_t pfx_1_1_1_0_s_24 = {
2149 .fp_len = 24,
2150 .fp_proto = FIB_PROTOCOL_IP4,
2151 .fp_addr = {
2152 /* 1.1.1.0/24 */
2153 .ip4.as_u32 = clib_host_to_net_u32(0x01010100),
2154 },
2155 };
2156
2157 fib_table_entry_path_add(fib_index,
2158 &pfx_1_1_1_0_s_24,
2159 FIB_SOURCE_API,
2160 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002161 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002162 &nh_10_10_10_1,
2163 tm->hw[0]->sw_if_index,
2164 ~0, // invalid fib index
2165 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002166 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002167 FIB_ROUTE_PATH_FLAG_NONE);
2168 fei = fib_table_lookup(fib_index, &pfx_1_1_1_0_s_24);
2169 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2170 ai = fib_entry_get_adj(fei);
2171 FIB_TEST((ai_01 == ai), "1.1.1.0/24 resolves via 10.10.10.1");
2172 fei = fib_table_lookup(fib_index, &pfx_1_1_1_2_s_32);
2173 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2174 ai = fib_entry_get_adj(fei);
2175 FIB_TEST((ai_01 == ai), "1.1.1.2/32 resolves via 10.10.10.1");
2176 fei = fib_table_lookup(fib_index, &pfx_1_1_1_200_s_32);
2177 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2178 ai = fib_entry_get_adj(fei);
2179 FIB_TEST((ai_01 == ai), "1.1.1.200/24 resolves via 10.10.10.1");
2180
2181 /*
2182 * +1 entry. 1.1.1.1/32 already uses 10.10.10.1 so no new pah-list
2183 */
2184 FIB_TEST((4 == fib_path_list_db_size()), "path list DB population:%d",
2185 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002186 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002187 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002188 FIB_TEST((ENBR+13 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002189 fib_entry_pool_size());
2190
2191 /*
2192 * the recursive adj for 200.200.200.200 should be updated.
2193 */
Neale Ranns3ee44042016-10-03 13:05:48 +01002194 FIB_TEST_REC_FORW(&bgp_201_pfx, &pfx_1_1_1_200_s_32, 0);
2195 FIB_TEST_REC_FORW(&bgp_200_pfx, &pfx_1_1_1_2_s_32, 0);
2196 fei = fib_table_lookup(fib_index, &bgp_200_pfx);
2197 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 1,
2198 tm->hw[0]->sw_if_index),
2199 "RPF list for BGP route has itf index 0");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002200
2201 /*
2202 * insert a more specific route than 1.1.1.0/24 that also covers the
2203 * missing 1.1.1.2/32, but not 1.1.1.200/32. we epxect
2204 * 200.200.200.200 to resolve through it.
2205 */
2206 fib_prefix_t pfx_1_1_1_0_s_28 = {
2207 .fp_len = 28,
2208 .fp_proto = FIB_PROTOCOL_IP4,
2209 .fp_addr = {
2210 /* 1.1.1.0/24 */
2211 .ip4.as_u32 = clib_host_to_net_u32(0x01010100),
2212 },
2213 };
2214
2215 fib_table_entry_path_add(fib_index,
2216 &pfx_1_1_1_0_s_28,
2217 FIB_SOURCE_API,
2218 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002219 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002220 &nh_10_10_10_2,
2221 tm->hw[0]->sw_if_index,
2222 ~0, // invalid fib index
2223 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002224 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002225 FIB_ROUTE_PATH_FLAG_NONE);
2226 fei = fib_table_lookup(fib_index, &pfx_1_1_1_0_s_28);
2227 dpo2 = fib_entry_contribute_ip_forwarding(fei);
2228 ai = fib_entry_get_adj(fei);
2229 FIB_TEST((ai_02 == ai), "1.1.1.0/24 resolves via 10.10.10.2");
2230
2231 /*
2232 * +1 entry. +1 shared path-list
2233 */
2234 FIB_TEST((5 == fib_path_list_db_size()), "path list DB population:%d",
2235 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002236 FIB_TEST((PNBR+9 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002237 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002238 FIB_TEST((ENBR+14 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002239 fib_entry_pool_size());
2240
2241 /*
2242 * the recursive adj for 200.200.200.200 should be updated.
2243 * 200.200.200.201 remains unchanged.
2244 */
Neale Ranns3ee44042016-10-03 13:05:48 +01002245 FIB_TEST_REC_FORW(&bgp_201_pfx, &pfx_1_1_1_200_s_32, 0);
2246 FIB_TEST_REC_FORW(&bgp_200_pfx, &pfx_1_1_1_2_s_32, 0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002247
2248 /*
2249 * remove this /28. 200.200.200.200/32 should revert back to via 1.1.1.0/24
2250 */
2251 fib_table_entry_path_remove(fib_index,
2252 &pfx_1_1_1_0_s_28,
2253 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002254 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002255 &nh_10_10_10_2,
2256 tm->hw[0]->sw_if_index,
2257 ~0,
2258 1,
2259 FIB_ROUTE_PATH_FLAG_NONE);
2260 FIB_TEST((fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_0_s_28) ==
2261 FIB_NODE_INDEX_INVALID),
2262 "1.1.1.0/28 removed");
2263 FIB_TEST((fib_table_lookup(fib_index, &pfx_1_1_1_0_s_28) ==
2264 fib_table_lookup(fib_index, &pfx_1_1_1_0_s_24)),
2265 "1.1.1.0/28 lookup via /24");
Neale Ranns3ee44042016-10-03 13:05:48 +01002266 FIB_TEST_REC_FORW(&bgp_201_pfx, &pfx_1_1_1_200_s_32, 0);
2267 FIB_TEST_REC_FORW(&bgp_200_pfx, &pfx_1_1_1_2_s_32, 0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002268
2269 /*
2270 * -1 entry. -1 shared path-list
2271 */
2272 FIB_TEST((4 == fib_path_list_db_size()), "path list DB population:%d",
2273 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002274 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002275 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002276 FIB_TEST((ENBR+13 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002277 fib_entry_pool_size());
2278
2279 /*
2280 * remove 1.1.1.0/24. 200.200.200.200/32 should revert back to via 0.0.0.0/0
2281 */
2282 fib_table_entry_path_remove(fib_index,
2283 &pfx_1_1_1_0_s_24,
2284 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002285 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002286 &nh_10_10_10_1,
2287 tm->hw[0]->sw_if_index,
2288 ~0,
2289 1,
2290 FIB_ROUTE_PATH_FLAG_NONE);
2291 FIB_TEST((fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_0_s_24) ==
2292 FIB_NODE_INDEX_INVALID),
2293 "1.1.1.0/24 removed");
2294
2295 fei = fib_table_lookup(fib_index, &pfx_1_1_1_2_s_32);
2296 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2297 "1.1.1.2/32 route is DROP");
Neale Ranns57b58602017-07-15 07:37:25 -07002298 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_200_s_32);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002299 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2300 "1.1.1.200/32 route is DROP");
2301
Neale Ranns57b58602017-07-15 07:37:25 -07002302 fei = fib_table_lookup_exact_match(fib_index, &bgp_201_pfx);
2303 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2304 "201 is drop");
2305 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
2306 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2307 "200 is drop");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002308
2309 /*
2310 * -1 entry
2311 */
2312 FIB_TEST((4 == fib_path_list_db_size()), "path list DB population:%d",
2313 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002314 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002315 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002316 FIB_TEST((ENBR+12 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002317 fib_entry_pool_size());
2318
2319 /*
2320 * insert the missing 1.1.1.2/32
2321 */
2322 fei = fib_table_entry_path_add(fib_index,
2323 &pfx_1_1_1_2_s_32,
2324 FIB_SOURCE_API,
2325 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002326 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002327 &nh_10_10_10_1,
2328 tm->hw[0]->sw_if_index,
2329 ~0, // invalid fib index
2330 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002331 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002332 FIB_ROUTE_PATH_FLAG_NONE);
2333 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2334 ai = fib_entry_get_adj(fei);
2335 FIB_TEST((ai = ai_01), "1.1.1.2/32 resolves via 10.10.10.1");
2336
Neale Ranns57b58602017-07-15 07:37:25 -07002337 fei = fib_table_lookup_exact_match(fib_index, &bgp_201_pfx);
2338 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2339 "201 is drop");
Neale Ranns3ee44042016-10-03 13:05:48 +01002340 FIB_TEST_REC_FORW(&bgp_200_pfx, &pfx_1_1_1_2_s_32, 0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002341
2342 /*
2343 * no change. 1.1.1.2/32 was already there RR sourced.
2344 */
2345 FIB_TEST((4 == fib_path_list_db_size()), "path list DB population:%d",
2346 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002347 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002348 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002349 FIB_TEST((ENBR+12 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002350 fib_entry_pool_size());
2351
2352 /*
Neale Ranns57b58602017-07-15 07:37:25 -07002353 * give 201 a resolved path.
2354 * it now has the unresolved 1.1.1.200 and the resolved 1.1.1.2,
2355 * only the latter contributes forwarding.
2356 */
2357 fei = fib_table_entry_path_add(fib_index,
2358 &bgp_201_pfx,
2359 FIB_SOURCE_API,
2360 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002361 DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07002362 &pfx_1_1_1_2_s_32.fp_addr,
2363 ~0,
2364 fib_index,
2365 1,
2366 NULL,
2367 FIB_ROUTE_PATH_FLAG_NONE);
2368 FIB_TEST_REC_FORW(&bgp_201_pfx, &pfx_1_1_1_2_s_32, 0);
2369 fib_table_entry_path_remove(fib_index,
2370 &bgp_201_pfx,
2371 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002372 DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07002373 &pfx_1_1_1_2_s_32.fp_addr,
2374 ~0,
2375 fib_index,
2376 1,
2377 FIB_ROUTE_PATH_FLAG_NONE);
2378
2379 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002380 * remove 200.200.200.201/32 which does not have a valid via FIB
2381 */
2382 fib_table_entry_path_remove(fib_index,
2383 &bgp_201_pfx,
2384 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002385 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002386 &pfx_1_1_1_200_s_32.fp_addr,
2387 ~0, // no index provided.
2388 fib_index,
2389 1,
2390 FIB_ROUTE_PATH_FLAG_NONE);
2391
2392 /*
2393 * -2 entries (BGP and RR). -1 shared path-list;
2394 */
2395 FIB_TEST((fib_table_lookup_exact_match(fib_index, &bgp_201_pfx) ==
2396 FIB_NODE_INDEX_INVALID),
2397 "200.200.200.201/32 removed");
2398 FIB_TEST((fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_200_s_32) ==
2399 FIB_NODE_INDEX_INVALID),
2400 "1.1.1.200/32 removed");
2401
2402 FIB_TEST((3 == fib_path_list_db_size()), "path list DB population:%d",
2403 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002404 FIB_TEST((PNBR+7 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002405 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002406 FIB_TEST((ENBR+10 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002407 fib_entry_pool_size());
2408
2409 /*
2410 * remove 200.200.200.200/32 which does have a valid via FIB
2411 */
2412 fib_table_entry_path_remove(fib_index,
2413 &bgp_200_pfx,
2414 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002415 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002416 &pfx_1_1_1_2_s_32.fp_addr,
2417 ~0, // no index provided.
2418 fib_index,
2419 1,
2420 FIB_ROUTE_PATH_FLAG_NONE);
2421
2422 FIB_TEST((fib_table_lookup_exact_match(fib_index, &bgp_200_pfx) ==
2423 FIB_NODE_INDEX_INVALID),
2424 "200.200.200.200/32 removed");
2425 FIB_TEST((fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_2_s_32) !=
2426 FIB_NODE_INDEX_INVALID),
2427 "1.1.1.2/32 still present");
2428
2429 /*
2430 * -1 entry (BGP, the RR source is also API sourced). -1 shared path-list;
2431 */
2432 FIB_TEST((2 == fib_path_list_db_size()), "path list DB population:%d",
2433 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002434 FIB_TEST((PNBR+6 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002435 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002436 FIB_TEST((ENBR+9 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002437 fib_entry_pool_size());
2438
2439 /*
2440 * A recursive prefix that has a 2 path load-balance.
2441 * It also shares a next-hop with other BGP prefixes and hence
2442 * test the ref counting of RR sourced prefixes and 2 level LB.
2443 */
2444 const fib_prefix_t bgp_102 = {
2445 .fp_len = 32,
2446 .fp_proto = FIB_PROTOCOL_IP4,
2447 .fp_addr = {
2448 /* 100.100.100.101/32 */
2449 .ip4.as_u32 = clib_host_to_net_u32(0x64646466),
2450 },
2451 };
2452 fib_table_entry_path_add(fib_index,
2453 &bgp_102,
2454 FIB_SOURCE_API,
2455 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002456 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002457 &pfx_1_1_1_1_s_32.fp_addr,
2458 ~0, // no index provided.
2459 fib_index, // same as route
2460 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002461 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002462 FIB_ROUTE_PATH_FLAG_NONE);
2463 fib_table_entry_path_add(fib_index,
2464 &bgp_102,
2465 FIB_SOURCE_API,
2466 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002467 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002468 &pfx_1_1_1_2_s_32.fp_addr,
2469 ~0, // no index provided.
2470 fib_index, // same as route's FIB
2471 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002472 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002473 FIB_ROUTE_PATH_FLAG_NONE);
2474 fei = fib_table_lookup_exact_match(fib_index, &bgp_102);
2475 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "100.100.100.102/32 presnet");
2476 dpo = fib_entry_contribute_ip_forwarding(fei);
2477
2478 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_1_s_32);
2479 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2480 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_2_s_32);
2481 dpo2 = fib_entry_contribute_ip_forwarding(fei);
2482
2483 lb = load_balance_get(dpo->dpoi_index);
2484 FIB_TEST((lb->lb_n_buckets == 2), "Recursive LB has %d bucket", lb->lb_n_buckets);
2485 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket(dpo->dpoi_index, 0)),
2486 "First via 10.10.10.1");
2487 FIB_TEST(!dpo_cmp(dpo2, load_balance_get_bucket(dpo->dpoi_index, 1)),
2488 "Second via 10.10.10.1");
2489
2490 fib_table_entry_path_remove(fib_index,
2491 &bgp_102,
2492 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002493 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002494 &pfx_1_1_1_1_s_32.fp_addr,
2495 ~0, // no index provided.
2496 fib_index, // same as route's FIB
2497 1,
2498 FIB_ROUTE_PATH_FLAG_NONE);
2499 fib_table_entry_path_remove(fib_index,
2500 &bgp_102,
2501 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002502 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002503 &pfx_1_1_1_2_s_32.fp_addr,
2504 ~0, // no index provided.
2505 fib_index, // same as route's FIB
2506 1,
2507 FIB_ROUTE_PATH_FLAG_NONE);
2508 fei = fib_table_lookup_exact_match(fib_index, &bgp_102);
2509 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "100.100.100.102/32 removed");
2510
2511 /*
2512 * remove the remaining recursives
2513 */
2514 fib_table_entry_path_remove(fib_index,
2515 &bgp_100_pfx,
2516 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002517 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002518 &pfx_1_1_1_1_s_32.fp_addr,
2519 ~0, // no index provided.
2520 fib_index, // same as route's FIB
2521 1,
2522 FIB_ROUTE_PATH_FLAG_NONE);
2523 fib_table_entry_path_remove(fib_index,
2524 &bgp_101_pfx,
2525 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002526 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002527 &pfx_1_1_1_1_s_32.fp_addr,
2528 ~0, // no index provided.
2529 fib_index, // same as route's FIB
2530 1,
2531 FIB_ROUTE_PATH_FLAG_NONE);
2532 FIB_TEST((fib_table_lookup_exact_match(fib_index, &bgp_100_pfx) ==
2533 FIB_NODE_INDEX_INVALID),
2534 "100.100.100.100/32 removed");
2535 FIB_TEST((fib_table_lookup_exact_match(fib_index, &bgp_101_pfx) ==
2536 FIB_NODE_INDEX_INVALID),
2537 "100.100.100.101/32 removed");
2538
2539 /*
2540 * -2 entry (2*BGP, the RR source is also API sourced). -1 shared path-list;
2541 */
2542 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
2543 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002544 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002545 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002546 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002547 fib_entry_pool_size());
2548
2549 /*
2550 * Add a recursive route via a connected cover, using an adj-fib that does exist
2551 */
2552 fib_table_entry_path_add(fib_index,
2553 &bgp_200_pfx,
2554 FIB_SOURCE_API,
2555 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002556 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002557 &nh_10_10_10_1,
2558 ~0, // no index provided.
2559 fib_index, // Same as route's FIB
2560 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002561 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002562 FIB_ROUTE_PATH_FLAG_NONE);
2563
2564 /*
2565 * +1 entry. +1 shared path-list (recursive via 10.10.10.1)
2566 */
2567 FIB_TEST((2 == fib_path_list_db_size()), "path list DB population:%d",
2568 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002569 FIB_TEST((PNBR+6 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002570 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002571 FIB_TEST((ENBR+8 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002572 fib_entry_pool_size());
2573
2574 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
2575 dpo = fib_entry_contribute_ip_forwarding(fei);
2576
2577 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
2578 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2579
2580 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket(dpo->dpoi_index, 0)),
2581 "200.200.200.200/32 is recursive via adj for 10.10.10.1");
2582
2583 FIB_TEST((FIB_ENTRY_FLAG_ATTACHED == fib_entry_get_flags(fei)),
2584 "Flags set on RR via existing attached");
2585
2586 /*
2587 * Add a recursive route via a connected cover, using and adj-fib that does
2588 * not exist
2589 */
2590 ip46_address_t nh_10_10_10_3 = {
2591 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a03),
2592 };
2593 fib_prefix_t pfx_10_10_10_3 = {
2594 .fp_len = 32,
2595 .fp_proto = FIB_PROTOCOL_IP4,
2596 .fp_addr = nh_10_10_10_3,
2597 };
2598
2599 fib_table_entry_path_add(fib_index,
2600 &bgp_201_pfx,
2601 FIB_SOURCE_API,
2602 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002603 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002604 &nh_10_10_10_3,
2605 ~0, // no index provided.
2606 fib_index,
2607 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002608 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002609 FIB_ROUTE_PATH_FLAG_NONE);
2610
2611 /*
2612 * +2 entries (BGP and RR). +1 shared path-list (recursive via 10.10.10.3) and
2613 * one unshared non-recursive via 10.10.10.3
2614 */
2615 FIB_TEST((3 == fib_path_list_db_size()), "path list DB population:%d",
2616 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002617 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002618 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002619 FIB_TEST((ENBR+10 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002620 fib_entry_pool_size());
2621
2622 ai_03 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01002623 VNET_LINK_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002624 &nh_10_10_10_3,
2625 tm->hw[0]->sw_if_index);
2626
2627 fei = fib_table_lookup_exact_match(fib_index, &bgp_201_pfx);
2628 dpo = fib_entry_contribute_ip_forwarding(fei);
2629 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_3);
2630 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2631
2632 ai = fib_entry_get_adj(fei);
2633 FIB_TEST((ai == ai_03), "adj for 10.10.10.3/32 is via adj for 10.10.10.3");
2634 FIB_TEST(((FIB_ENTRY_FLAG_ATTACHED | FIB_ENTRY_FLAG_CONNECTED) ==
2635 fib_entry_get_flags(fei)),
2636 "Flags set on RR via non-existing attached");
2637
2638 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket(dpo->dpoi_index, 0)),
2639 "adj for 200.200.200.200/32 is recursive via adj for 10.10.10.3");
2640
2641 adj_unlock(ai_03);
2642
2643 /*
2644 * remove the recursives
2645 */
2646 fib_table_entry_path_remove(fib_index,
2647 &bgp_200_pfx,
2648 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002649 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002650 &nh_10_10_10_1,
2651 ~0, // no index provided.
2652 fib_index, // same as route's FIB
2653 1,
2654 FIB_ROUTE_PATH_FLAG_NONE);
2655 fib_table_entry_path_remove(fib_index,
2656 &bgp_201_pfx,
2657 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002658 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002659 &nh_10_10_10_3,
2660 ~0, // no index provided.
2661 fib_index, // same as route's FIB
2662 1,
2663 FIB_ROUTE_PATH_FLAG_NONE);
2664
2665 FIB_TEST((fib_table_lookup_exact_match(fib_index, &bgp_201_pfx) ==
2666 FIB_NODE_INDEX_INVALID),
2667 "200.200.200.201/32 removed");
2668 FIB_TEST((fib_table_lookup_exact_match(fib_index, &bgp_200_pfx) ==
2669 FIB_NODE_INDEX_INVALID),
2670 "200.200.200.200/32 removed");
2671 FIB_TEST((fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_3) ==
2672 FIB_NODE_INDEX_INVALID),
2673 "10.10.10.3/32 removed");
2674
2675 /*
2676 * -3 entries (2*BGP and RR). -2 shared path-list (recursive via 10.10.10.3 &
2677 * 10.10.10.1) and one unshared non-recursive via 10.10.10.3
2678 */
2679 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
2680 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002681 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002682 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002683 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002684 fib_entry_pool_size());
2685
2686
2687 /*
2688 * RECURSION LOOPS
2689 * Add 5.5.5.5/32 -> 5.5.5.6/32 -> 5.5.5.7/32 -> 5.5.5.5/32
2690 */
2691 fib_prefix_t pfx_5_5_5_5_s_32 = {
2692 .fp_len = 32,
2693 .fp_proto = FIB_PROTOCOL_IP4,
2694 .fp_addr = {
2695 .ip4.as_u32 = clib_host_to_net_u32(0x05050505),
2696 },
2697 };
2698 fib_prefix_t pfx_5_5_5_6_s_32 = {
2699 .fp_len = 32,
2700 .fp_proto = FIB_PROTOCOL_IP4,
2701 .fp_addr = {
2702 .ip4.as_u32 = clib_host_to_net_u32(0x05050506),
2703 },
2704 };
2705 fib_prefix_t pfx_5_5_5_7_s_32 = {
2706 .fp_len = 32,
2707 .fp_proto = FIB_PROTOCOL_IP4,
2708 .fp_addr = {
2709 .ip4.as_u32 = clib_host_to_net_u32(0x05050507),
2710 },
2711 };
2712
2713 fib_table_entry_path_add(fib_index,
2714 &pfx_5_5_5_5_s_32,
2715 FIB_SOURCE_API,
2716 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002717 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002718 &pfx_5_5_5_6_s_32.fp_addr,
2719 ~0, // no index provided.
2720 fib_index,
2721 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002722 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002723 FIB_ROUTE_PATH_FLAG_NONE);
2724 fib_table_entry_path_add(fib_index,
2725 &pfx_5_5_5_6_s_32,
2726 FIB_SOURCE_API,
2727 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002728 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002729 &pfx_5_5_5_7_s_32.fp_addr,
2730 ~0, // no index provided.
2731 fib_index,
2732 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002733 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002734 FIB_ROUTE_PATH_FLAG_NONE);
2735 fib_table_entry_path_add(fib_index,
2736 &pfx_5_5_5_7_s_32,
2737 FIB_SOURCE_API,
2738 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002739 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002740 &pfx_5_5_5_5_s_32.fp_addr,
2741 ~0, // no index provided.
2742 fib_index,
2743 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002744 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002745 FIB_ROUTE_PATH_FLAG_NONE);
2746 /*
2747 * +3 entries, +3 shared path-list
2748 */
2749 FIB_TEST((4 == fib_path_list_db_size()), "path list DB population:%d",
2750 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002751 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002752 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002753 FIB_TEST((ENBR+10 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002754 fib_entry_pool_size());
2755
2756 /*
2757 * All the entries have only looped paths, so they are all drop
2758 */
2759 fei = fib_table_lookup(fib_index, &pfx_5_5_5_7_s_32);
2760 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2761 "LB for 5.5.5.7/32 is via adj for DROP");
2762 fei = fib_table_lookup(fib_index, &pfx_5_5_5_5_s_32);
2763 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2764 "LB for 5.5.5.5/32 is via adj for DROP");
2765 fei = fib_table_lookup(fib_index, &pfx_5_5_5_6_s_32);
2766 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2767 "LB for 5.5.5.6/32 is via adj for DROP");
2768
2769 /*
2770 * provide 5.5.5.6/32 with alternate path.
2771 * this will allow only 5.5.5.6/32 to forward with this path, the others
2772 * are still drop since the loop is still present.
2773 */
2774 fib_table_entry_path_add(fib_index,
2775 &pfx_5_5_5_6_s_32,
2776 FIB_SOURCE_API,
2777 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002778 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002779 &nh_10_10_10_1,
2780 tm->hw[0]->sw_if_index,
2781 ~0,
2782 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002783 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002784 FIB_ROUTE_PATH_FLAG_NONE);
2785
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002786 fei = fib_table_lookup(fib_index, &pfx_5_5_5_6_s_32);
2787 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2788
2789 lb = load_balance_get(dpo1->dpoi_index);
2790 FIB_TEST((lb->lb_n_buckets == 1), "5.5.5.6 LB has %d bucket", lb->lb_n_buckets);
2791
2792 dpo2 = load_balance_get_bucket(dpo1->dpoi_index, 0);
2793 FIB_TEST(DPO_ADJACENCY == dpo2->dpoi_type, "type is %d", dpo2->dpoi_type);
2794 FIB_TEST((ai_01 == dpo2->dpoi_index),
2795 "5.5.5.6 bucket 0 resolves via 10.10.10.2");
2796
2797 fei = fib_table_lookup(fib_index, &pfx_5_5_5_7_s_32);
2798 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2799 "LB for 5.5.5.7/32 is via adj for DROP");
2800 fei = fib_table_lookup(fib_index, &pfx_5_5_5_5_s_32);
2801 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2802 "LB for 5.5.5.5/32 is via adj for DROP");
2803
2804 /*
2805 * remove the alternate path for 5.5.5.6/32
2806 * back to all drop
2807 */
2808 fib_table_entry_path_remove(fib_index,
2809 &pfx_5_5_5_6_s_32,
2810 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002811 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002812 &nh_10_10_10_1,
2813 tm->hw[0]->sw_if_index,
2814 ~0,
2815 1,
2816 FIB_ROUTE_PATH_FLAG_NONE);
2817
2818 fei = fib_table_lookup(fib_index, &pfx_5_5_5_7_s_32);
2819 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2820 "LB for 5.5.5.7/32 is via adj for DROP");
2821 fei = fib_table_lookup(fib_index, &pfx_5_5_5_5_s_32);
2822 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2823 "LB for 5.5.5.5/32 is via adj for DROP");
2824 fei = fib_table_lookup(fib_index, &pfx_5_5_5_6_s_32);
2825 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2826 "LB for 5.5.5.6/32 is via adj for DROP");
2827
2828 /*
2829 * break the loop by giving 5.5.5.5/32 a new set of paths
2830 * expect all to forward via this new path.
2831 */
2832 fib_table_entry_update_one_path(fib_index,
2833 &pfx_5_5_5_5_s_32,
2834 FIB_SOURCE_API,
2835 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002836 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002837 &nh_10_10_10_1,
2838 tm->hw[0]->sw_if_index,
2839 ~0, // invalid fib index
2840 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002841 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002842 FIB_ROUTE_PATH_FLAG_NONE);
2843
2844 fei = fib_table_lookup(fib_index, &pfx_5_5_5_5_s_32);
2845 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2846 lb = load_balance_get(dpo1->dpoi_index);
2847 FIB_TEST((lb->lb_n_buckets == 1), "5.5.5.5 LB has %d bucket", lb->lb_n_buckets);
2848
2849 dpo2 = load_balance_get_bucket(dpo1->dpoi_index, 0);
2850 FIB_TEST(DPO_ADJACENCY == dpo2->dpoi_type, "type is %d", dpo2->dpoi_type);
2851 FIB_TEST((ai_01 == dpo2->dpoi_index),
2852 "5.5.5.5 bucket 0 resolves via 10.10.10.2");
2853
2854 fei = fib_table_lookup_exact_match(fib_index, &pfx_5_5_5_7_s_32);
2855 dpo2 = fib_entry_contribute_ip_forwarding(fei);
2856
2857 lb = load_balance_get(dpo2->dpoi_index);
2858 FIB_TEST((lb->lb_n_buckets == 1), "Recursive LB has %d bucket", lb->lb_n_buckets);
2859 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket(dpo2->dpoi_index, 0)),
2860 "5.5.5.5.7 via 5.5.5.5");
2861
2862 fei = fib_table_lookup_exact_match(fib_index, &pfx_5_5_5_6_s_32);
2863 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2864
2865 lb = load_balance_get(dpo1->dpoi_index);
2866 FIB_TEST((lb->lb_n_buckets == 1), "Recursive LB has %d bucket", lb->lb_n_buckets);
2867 FIB_TEST(!dpo_cmp(dpo2, load_balance_get_bucket(dpo1->dpoi_index, 0)),
2868 "5.5.5.5.6 via 5.5.5.7");
2869
2870 /*
2871 * revert back to the loop. so we can remove the prefixes with
2872 * the loop intact
2873 */
2874 fib_table_entry_update_one_path(fib_index,
2875 &pfx_5_5_5_5_s_32,
2876 FIB_SOURCE_API,
2877 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002878 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002879 &pfx_5_5_5_6_s_32.fp_addr,
2880 ~0, // no index provided.
2881 fib_index,
2882 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002883 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002884 FIB_ROUTE_PATH_FLAG_NONE);
2885
2886 fei = fib_table_lookup(fib_index, &pfx_5_5_5_7_s_32);
2887 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2888 "LB for 5.5.5.7/32 is via adj for DROP");
2889 fei = fib_table_lookup(fib_index, &pfx_5_5_5_5_s_32);
2890 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2891 "LB for 5.5.5.5/32 is via adj for DROP");
2892 fei = fib_table_lookup(fib_index, &pfx_5_5_5_6_s_32);
2893 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2894 "LB for 5.5.5.6/32 is via adj for DROP");
2895
2896 /*
2897 * remove all the 5.5.5.x/32 prefixes
2898 */
2899 fib_table_entry_path_remove(fib_index,
2900 &pfx_5_5_5_5_s_32,
2901 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002902 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002903 &pfx_5_5_5_6_s_32.fp_addr,
2904 ~0, // no index provided.
2905 fib_index, // same as route's FIB
2906 1,
2907 FIB_ROUTE_PATH_FLAG_NONE);
2908 fib_table_entry_path_remove(fib_index,
2909 &pfx_5_5_5_6_s_32,
2910 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002911 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002912 &pfx_5_5_5_7_s_32.fp_addr,
2913 ~0, // no index provided.
2914 fib_index, // same as route's FIB
2915 1,
2916 FIB_ROUTE_PATH_FLAG_NONE);
2917 fib_table_entry_path_remove(fib_index,
2918 &pfx_5_5_5_7_s_32,
2919 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002920 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002921 &pfx_5_5_5_5_s_32.fp_addr,
2922 ~0, // no index provided.
2923 fib_index, // same as route's FIB
2924 1,
2925 FIB_ROUTE_PATH_FLAG_NONE);
2926 fib_table_entry_path_remove(fib_index,
2927 &pfx_5_5_5_6_s_32,
2928 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002929 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002930 &nh_10_10_10_2,
2931 ~0, // no index provided.
2932 fib_index, // same as route's FIB
2933 1,
2934 FIB_ROUTE_PATH_FLAG_NONE);
2935
2936 /*
2937 * -3 entries, -3 shared path-list
2938 */
2939 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
2940 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002941 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002942 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002943 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002944 fib_entry_pool_size());
2945
2946 /*
2947 * Single level loop 5.5.5.5/32 via 5.5.5.5/32
2948 */
2949 fib_table_entry_path_add(fib_index,
2950 &pfx_5_5_5_6_s_32,
2951 FIB_SOURCE_API,
2952 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002953 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002954 &pfx_5_5_5_6_s_32.fp_addr,
2955 ~0, // no index provided.
2956 fib_index,
2957 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002958 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002959 FIB_ROUTE_PATH_FLAG_NONE);
2960 fei = fib_table_lookup(fib_index, &pfx_5_5_5_6_s_32);
2961 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2962 "1-level 5.5.5.6/32 loop is via adj for DROP");
2963
2964 fib_table_entry_path_remove(fib_index,
2965 &pfx_5_5_5_6_s_32,
2966 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002967 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002968 &pfx_5_5_5_6_s_32.fp_addr,
2969 ~0, // no index provided.
2970 fib_index, // same as route's FIB
2971 1,
2972 FIB_ROUTE_PATH_FLAG_NONE);
2973 FIB_TEST(FIB_NODE_INDEX_INVALID ==
2974 fib_table_lookup_exact_match(fib_index, &pfx_5_5_5_6_s_32),
2975 "1-level 5.5.5.6/32 loop is removed");
2976
2977 /*
Neale Ranns3dffb1e2016-11-01 20:38:53 +00002978 * A recursive route whose next-hop is covered by the prefix.
2979 * This would mean the via-fib, which inherits forwarding from its
2980 * cover, thus picks up forwarding from the prfix, which is via the
2981 * via-fib, and we have a loop.
2982 */
2983 fib_prefix_t pfx_23_23_23_0_s_24 = {
2984 .fp_len = 24,
2985 .fp_proto = FIB_PROTOCOL_IP4,
2986 .fp_addr = {
2987 .ip4.as_u32 = clib_host_to_net_u32(0x17171700),
2988 },
2989 };
2990 fib_prefix_t pfx_23_23_23_23_s_32 = {
2991 .fp_len = 32,
2992 .fp_proto = FIB_PROTOCOL_IP4,
2993 .fp_addr = {
2994 .ip4.as_u32 = clib_host_to_net_u32(0x17171717),
2995 },
2996 };
2997 fei = fib_table_entry_path_add(fib_index,
2998 &pfx_23_23_23_0_s_24,
2999 FIB_SOURCE_API,
3000 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003001 DPO_PROTO_IP4,
Neale Ranns3dffb1e2016-11-01 20:38:53 +00003002 &pfx_23_23_23_23_s_32.fp_addr,
3003 ~0, // recursive
3004 fib_index,
3005 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003006 NULL,
Neale Ranns3dffb1e2016-11-01 20:38:53 +00003007 FIB_ROUTE_PATH_FLAG_NONE);
3008 dpo = fib_entry_contribute_ip_forwarding(fei);
3009 FIB_TEST(load_balance_is_drop(dpo),
3010 "23.23.23.0/24 via covered is DROP");
3011 fib_table_entry_delete_index(fei, FIB_SOURCE_API);
3012
3013 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003014 * add-remove test. no change.
3015 */
3016 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
3017 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003018 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003019 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003020 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003021 fib_entry_pool_size());
3022
3023 /*
Neale Ranns08b16482017-05-13 05:52:58 -07003024 * Make the default route recursive via a unknown next-hop. Thus the
3025 * next hop's cover would be the default route
3026 */
3027 fei = fib_table_entry_path_add(fib_index,
3028 &pfx_0_0_0_0_s_0,
3029 FIB_SOURCE_API,
3030 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003031 DPO_PROTO_IP4,
Neale Ranns08b16482017-05-13 05:52:58 -07003032 &pfx_23_23_23_23_s_32.fp_addr,
3033 ~0, // recursive
3034 fib_index,
3035 1,
3036 NULL,
3037 FIB_ROUTE_PATH_FLAG_NONE);
3038 dpo = fib_entry_contribute_ip_forwarding(fei);
3039 FIB_TEST(load_balance_is_drop(dpo),
3040 "0.0.0.0.0/0 via is DROP");
3041 FIB_TEST((fib_entry_get_resolving_interface(fei) == ~0),
3042 "no resolving interface for looped 0.0.0.0/0");
3043
3044 fei = fib_table_lookup_exact_match(fib_index, &pfx_23_23_23_23_s_32);
3045 dpo = fib_entry_contribute_ip_forwarding(fei);
3046 FIB_TEST(load_balance_is_drop(dpo),
3047 "23.23.23.23/32 via is DROP");
3048 FIB_TEST((fib_entry_get_resolving_interface(fei) == ~0),
3049 "no resolving interface for looped 23.23.23.23/32");
3050
3051 fib_table_entry_delete(fib_index, &pfx_0_0_0_0_s_0, FIB_SOURCE_API);
3052
3053 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003054 * A recursive route with recursion constraints.
3055 * 200.200.200.200/32 via 1.1.1.1 is recurse via host constrained
3056 */
3057 fib_table_entry_path_add(fib_index,
3058 &bgp_200_pfx,
3059 FIB_SOURCE_API,
3060 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003061 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003062 &nh_1_1_1_1,
3063 ~0,
3064 fib_index,
3065 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003066 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003067 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
3068
3069 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_1_s_32);
3070 dpo2 = fib_entry_contribute_ip_forwarding(fei);
3071
3072 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
3073 dpo1 = fib_entry_contribute_ip_forwarding(fei);
3074
3075 FIB_TEST(!dpo_cmp(dpo2, load_balance_get_bucket(dpo1->dpoi_index, 0)),
3076 "adj for 200.200.200.200/32 is recursive via adj for 1.1.1.1");
3077
3078 /*
3079 * save the load-balance. we expect it to be inplace modified
3080 */
3081 lb = load_balance_get(dpo1->dpoi_index);
3082
3083 /*
3084 * add a covering prefix for the via fib that would otherwise serve
3085 * as the resolving route when the host is removed
3086 */
3087 fib_table_entry_path_add(fib_index,
3088 &pfx_1_1_1_0_s_28,
3089 FIB_SOURCE_API,
3090 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003091 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003092 &nh_10_10_10_1,
3093 tm->hw[0]->sw_if_index,
3094 ~0, // invalid fib index
3095 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003096 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003097 FIB_ROUTE_PATH_FLAG_NONE);
3098 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_0_s_28);
3099 ai = fib_entry_get_adj(fei);
3100 FIB_TEST((ai == ai_01),
3101 "adj for 1.1.1.0/28 is via adj for 1.1.1.1");
3102
3103 /*
3104 * remove the host via FIB - expect the BGP prefix to be drop
3105 */
3106 fib_table_entry_path_remove(fib_index,
3107 &pfx_1_1_1_1_s_32,
3108 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07003109 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003110 &nh_10_10_10_1,
3111 tm->hw[0]->sw_if_index,
3112 ~0, // invalid fib index
3113 1,
3114 FIB_ROUTE_PATH_FLAG_NONE);
3115
3116 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo1->dpoi_index, 0)),
3117 "adj for 200.200.200.200/32 is recursive via adj for DROP");
3118
3119 /*
3120 * add the via-entry host reoute back. expect to resolve again
3121 */
3122 fib_table_entry_path_add(fib_index,
3123 &pfx_1_1_1_1_s_32,
3124 FIB_SOURCE_API,
3125 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003126 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003127 &nh_10_10_10_1,
3128 tm->hw[0]->sw_if_index,
3129 ~0, // invalid fib index
3130 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003131 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003132 FIB_ROUTE_PATH_FLAG_NONE);
3133 FIB_TEST(!dpo_cmp(dpo2, load_balance_get_bucket(dpo1->dpoi_index, 0)),
3134 "adj for 200.200.200.200/32 is recursive via adj for 1.1.1.1");
3135
3136 /*
3137 * add another path for the recursive. it will then have 2.
3138 */
3139 fib_prefix_t pfx_1_1_1_3_s_32 = {
3140 .fp_len = 32,
3141 .fp_proto = FIB_PROTOCOL_IP4,
3142 .fp_addr = {
3143 .ip4.as_u32 = clib_host_to_net_u32(0x01010103),
3144 },
3145 };
3146 fib_table_entry_path_add(fib_index,
3147 &pfx_1_1_1_3_s_32,
3148 FIB_SOURCE_API,
3149 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003150 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003151 &nh_10_10_10_2,
3152 tm->hw[0]->sw_if_index,
3153 ~0, // invalid fib index
3154 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003155 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003156 FIB_ROUTE_PATH_FLAG_NONE);
3157
3158 fib_table_entry_path_add(fib_index,
3159 &bgp_200_pfx,
3160 FIB_SOURCE_API,
3161 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003162 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003163 &pfx_1_1_1_3_s_32.fp_addr,
3164 ~0,
3165 fib_index,
3166 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003167 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003168 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
3169
Neale Rannsf12a83f2017-04-18 09:09:40 -07003170 /*
3171 * add a bunch load more entries using this path combo so that we get
3172 * an LB-map created.
3173 */
3174#define N_P 128
3175 fib_prefix_t bgp_78s[N_P];
3176 for (ii = 0; ii < N_P; ii++)
3177 {
3178 bgp_78s[ii].fp_len = 32;
3179 bgp_78s[ii].fp_proto = FIB_PROTOCOL_IP4;
3180 bgp_78s[ii].fp_addr.ip4.as_u32 = clib_host_to_net_u32(0x4e000000+ii);
3181
3182
3183 fib_table_entry_path_add(fib_index,
3184 &bgp_78s[ii],
3185 FIB_SOURCE_API,
3186 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003187 DPO_PROTO_IP4,
Neale Rannsf12a83f2017-04-18 09:09:40 -07003188 &pfx_1_1_1_3_s_32.fp_addr,
3189 ~0,
3190 fib_index,
3191 1,
3192 NULL,
3193 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
3194 fib_table_entry_path_add(fib_index,
3195 &bgp_78s[ii],
3196 FIB_SOURCE_API,
3197 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003198 DPO_PROTO_IP4,
Neale Rannsf12a83f2017-04-18 09:09:40 -07003199 &nh_1_1_1_1,
3200 ~0,
3201 fib_index,
3202 1,
3203 NULL,
3204 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
3205 }
3206
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003207 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
3208 dpo = fib_entry_contribute_ip_forwarding(fei);
3209
3210 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_1_s_32);
3211 dpo2 = fib_entry_contribute_ip_forwarding(fei);
3212 FIB_TEST(!dpo_cmp(dpo2, load_balance_get_bucket(dpo->dpoi_index, 0)),
3213 "adj for 200.200.200.200/32 is recursive via adj for 1.1.1.1");
3214 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_3_s_32);
3215 dpo1 = fib_entry_contribute_ip_forwarding(fei);
3216 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket(dpo->dpoi_index, 1)),
3217 "adj for 200.200.200.200/32 is recursive via adj for 1.1.1.3");
3218
3219 /*
3220 * expect the lb-map used by the recursive's load-balance is using both buckets
3221 */
3222 load_balance_map_t *lbm;
3223 index_t lbmi;
3224
3225 lb = load_balance_get(dpo->dpoi_index);
3226 lbmi = lb->lb_map;
3227 load_balance_map_lock(lbmi);
3228 lbm = load_balance_map_get(lbmi);
3229
3230 FIB_TEST(lbm->lbm_buckets[0] == 0,
3231 "LB maps's bucket 0 is %d",
3232 lbm->lbm_buckets[0]);
3233 FIB_TEST(lbm->lbm_buckets[1] == 1,
3234 "LB maps's bucket 1 is %d",
3235 lbm->lbm_buckets[1]);
3236
3237 /*
3238 * withdraw one of the /32 via-entrys.
3239 * that ECMP path will be unresolved and forwarding should continue on the
3240 * other available path. this is an iBGP PIC edge failover.
3241 * Test the forwarding changes without re-fetching the adj from the
3242 * recursive entry. this ensures its the same one that is updated; i.e. an
3243 * inplace-modify.
3244 */
3245 fib_table_entry_path_remove(fib_index,
3246 &pfx_1_1_1_1_s_32,
3247 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07003248 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003249 &nh_10_10_10_1,
3250 tm->hw[0]->sw_if_index,
3251 ~0, // invalid fib index
3252 1,
3253 FIB_ROUTE_PATH_FLAG_NONE);
3254
Neale Rannsf12a83f2017-04-18 09:09:40 -07003255 /* suspend so the update walk kicks int */
3256 vlib_process_suspend(vlib_get_main(), 1e-5);
3257
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003258 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
3259 FIB_TEST(!dpo_cmp(dpo, fib_entry_contribute_ip_forwarding(fei)),
3260 "post PIC 200.200.200.200/32 was inplace modified");
3261
3262 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket_i(lb, 0)),
3263 "post PIC adj for 200.200.200.200/32 is recursive"
3264 " via adj for 1.1.1.3");
3265
3266 /*
3267 * the LB maps that was locked above should have been modified to remove
3268 * the path that was down, and thus its bucket points to a path that is
3269 * still up.
3270 */
3271 FIB_TEST(lbm->lbm_buckets[0] == 1,
3272 "LB maps's bucket 0 is %d",
3273 lbm->lbm_buckets[0]);
3274 FIB_TEST(lbm->lbm_buckets[1] == 1,
3275 "LB maps's bucket 1 is %d",
3276 lbm->lbm_buckets[1]);
3277
Neale Ranns994dab42017-04-18 12:56:45 -07003278 load_balance_map_unlock(lbmi);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003279
3280 /*
3281 * add it back. again
3282 */
3283 fib_table_entry_path_add(fib_index,
3284 &pfx_1_1_1_1_s_32,
3285 FIB_SOURCE_API,
3286 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003287 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003288 &nh_10_10_10_1,
3289 tm->hw[0]->sw_if_index,
3290 ~0, // invalid fib index
3291 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003292 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003293 FIB_ROUTE_PATH_FLAG_NONE);
3294
Neale Rannsf12a83f2017-04-18 09:09:40 -07003295 /* suspend so the update walk kicks in */
3296 vlib_process_suspend(vlib_get_main(), 1e-5);
3297
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003298 FIB_TEST(!dpo_cmp(dpo2, load_balance_get_bucket_i(lb, 0)),
3299 "post PIC recovery adj for 200.200.200.200/32 is recursive "
3300 "via adj for 1.1.1.1");
3301 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket_i(lb, 1)),
3302 "post PIC recovery adj for 200.200.200.200/32 is recursive "
3303 "via adj for 1.1.1.3");
3304
3305 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
3306 dpo = fib_entry_contribute_ip_forwarding(fei);
3307 FIB_TEST(lb == load_balance_get(dpo->dpoi_index),
3308 "post PIC 200.200.200.200/32 was inplace modified");
3309
3310 /*
3311 * add a 3rd path. this makes the LB 16 buckets.
3312 */
3313 fib_table_entry_path_add(fib_index,
3314 &bgp_200_pfx,
3315 FIB_SOURCE_API,
3316 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003317 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003318 &pfx_1_1_1_2_s_32.fp_addr,
3319 ~0,
3320 fib_index,
3321 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003322 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003323 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
Neale Rannsf12a83f2017-04-18 09:09:40 -07003324 for (ii = 0; ii < N_P; ii++)
3325 {
3326 fib_table_entry_path_add(fib_index,
3327 &bgp_78s[ii],
3328 FIB_SOURCE_API,
3329 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003330 DPO_PROTO_IP4,
Neale Rannsf12a83f2017-04-18 09:09:40 -07003331 &pfx_1_1_1_2_s_32.fp_addr,
3332 ~0,
3333 fib_index,
3334 1,
3335 NULL,
3336 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
3337 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003338
3339 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
3340 dpo = fib_entry_contribute_ip_forwarding(fei);
3341 FIB_TEST(lb == load_balance_get(dpo->dpoi_index),
3342 "200.200.200.200/32 was inplace modified for 3rd path");
3343 FIB_TEST(16 == lb->lb_n_buckets,
3344 "200.200.200.200/32 was inplace modified for 3rd path to 16 buckets");
3345
3346 lbmi = lb->lb_map;
3347 load_balance_map_lock(lbmi);
3348 lbm = load_balance_map_get(lbmi);
3349
3350 for (ii = 0; ii < 16; ii++)
3351 {
3352 FIB_TEST(lbm->lbm_buckets[ii] == ii,
3353 "LB Map for 200.200.200.200/32 at %d is %d",
3354 ii, lbm->lbm_buckets[ii]);
3355 }
3356
3357 /*
3358 * trigger PIC by removing the first via-entry
3359 * the first 6 buckets of the map should map to the next 6
3360 */
3361 fib_table_entry_path_remove(fib_index,
3362 &pfx_1_1_1_1_s_32,
3363 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07003364 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003365 &nh_10_10_10_1,
3366 tm->hw[0]->sw_if_index,
3367 ~0,
3368 1,
3369 FIB_ROUTE_PATH_FLAG_NONE);
Neale Rannsf12a83f2017-04-18 09:09:40 -07003370 /* suspend so the update walk kicks int */
3371 vlib_process_suspend(vlib_get_main(), 1e-5);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003372
3373 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
3374 dpo = fib_entry_contribute_ip_forwarding(fei);
3375 FIB_TEST(lb == load_balance_get(dpo->dpoi_index),
3376 "200.200.200.200/32 was inplace modified for 3rd path");
3377 FIB_TEST(2 == lb->lb_n_buckets,
3378 "200.200.200.200/32 was inplace modified for 3rd path remove to 2 buckets");
3379
3380 for (ii = 0; ii < 6; ii++)
3381 {
3382 FIB_TEST(lbm->lbm_buckets[ii] == ii+6,
3383 "LB Map for 200.200.200.200/32 at %d is %d",
3384 ii, lbm->lbm_buckets[ii]);
3385 }
3386 for (ii = 6; ii < 16; ii++)
3387 {
3388 FIB_TEST(lbm->lbm_buckets[ii] == ii,
3389 "LB Map for 200.200.200.200/32 at %d is %d",
3390 ii, lbm->lbm_buckets[ii]);
3391 }
Neale Ranns994dab42017-04-18 12:56:45 -07003392 load_balance_map_unlock(lbmi);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003393
3394 /*
3395 * tidy up
3396 */
3397 fib_table_entry_path_add(fib_index,
3398 &pfx_1_1_1_1_s_32,
3399 FIB_SOURCE_API,
3400 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003401 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003402 &nh_10_10_10_1,
3403 tm->hw[0]->sw_if_index,
3404 ~0,
3405 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003406 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003407 FIB_ROUTE_PATH_FLAG_NONE);
3408
Neale Rannsf12a83f2017-04-18 09:09:40 -07003409 for (ii = 0; ii < N_P; ii++)
3410 {
3411 fib_table_entry_delete(fib_index,
3412 &bgp_78s[ii],
3413 FIB_SOURCE_API);
3414 FIB_TEST((FIB_NODE_INDEX_INVALID ==
3415 fib_table_lookup_exact_match(fib_index, &bgp_78s[ii])),
3416 "%U removed",
3417 format_fib_prefix, &bgp_78s[ii]);
3418 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003419 fib_table_entry_path_remove(fib_index,
3420 &bgp_200_pfx,
3421 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07003422 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003423 &pfx_1_1_1_2_s_32.fp_addr,
3424 ~0,
3425 fib_index,
3426 1,
3427 MPLS_LABEL_INVALID);
3428 fib_table_entry_path_remove(fib_index,
3429 &bgp_200_pfx,
3430 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07003431 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003432 &nh_1_1_1_1,
3433 ~0,
3434 fib_index,
3435 1,
3436 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
3437 fib_table_entry_path_remove(fib_index,
3438 &bgp_200_pfx,
3439 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07003440 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003441 &pfx_1_1_1_3_s_32.fp_addr,
3442 ~0,
3443 fib_index,
3444 1,
3445 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
3446 fib_table_entry_delete(fib_index,
3447 &pfx_1_1_1_3_s_32,
3448 FIB_SOURCE_API);
3449 fib_table_entry_delete(fib_index,
3450 &pfx_1_1_1_0_s_28,
3451 FIB_SOURCE_API);
Neale Rannsf12a83f2017-04-18 09:09:40 -07003452 /* suspend so the update walk kicks int */
3453 vlib_process_suspend(vlib_get_main(), 1e-5);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003454 FIB_TEST((FIB_NODE_INDEX_INVALID ==
3455 fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_0_s_28)),
3456 "1.1.1.1/28 removed");
3457 FIB_TEST((FIB_NODE_INDEX_INVALID ==
3458 fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_3_s_32)),
3459 "1.1.1.3/32 removed");
3460 FIB_TEST((FIB_NODE_INDEX_INVALID ==
3461 fib_table_lookup_exact_match(fib_index, &bgp_200_pfx)),
3462 "200.200.200.200/32 removed");
3463
3464 /*
3465 * add-remove test. no change.
3466 */
3467 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
3468 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003469 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003470 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003471 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003472 fib_entry_pool_size());
3473
3474 /*
3475 * A route whose paths are built up iteratively and then removed
3476 * all at once
3477 */
3478 fib_prefix_t pfx_4_4_4_4_s_32 = {
3479 .fp_len = 32,
3480 .fp_proto = FIB_PROTOCOL_IP4,
3481 .fp_addr = {
3482 /* 4.4.4.4/32 */
3483 .ip4.as_u32 = clib_host_to_net_u32(0x04040404),
3484 },
3485 };
3486
3487 fib_table_entry_path_add(fib_index,
3488 &pfx_4_4_4_4_s_32,
3489 FIB_SOURCE_API,
3490 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003491 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003492 &nh_10_10_10_1,
3493 tm->hw[0]->sw_if_index,
3494 ~0,
3495 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003496 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003497 FIB_ROUTE_PATH_FLAG_NONE);
3498 fib_table_entry_path_add(fib_index,
3499 &pfx_4_4_4_4_s_32,
3500 FIB_SOURCE_API,
3501 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003502 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003503 &nh_10_10_10_2,
3504 tm->hw[0]->sw_if_index,
3505 ~0,
3506 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003507 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003508 FIB_ROUTE_PATH_FLAG_NONE);
3509 fib_table_entry_path_add(fib_index,
3510 &pfx_4_4_4_4_s_32,
3511 FIB_SOURCE_API,
3512 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003513 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003514 &nh_10_10_10_3,
3515 tm->hw[0]->sw_if_index,
3516 ~0,
3517 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003518 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003519 FIB_ROUTE_PATH_FLAG_NONE);
3520 FIB_TEST(FIB_NODE_INDEX_INVALID !=
3521 fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32),
3522 "4.4.4.4/32 present");
3523
3524 fib_table_entry_delete(fib_index,
3525 &pfx_4_4_4_4_s_32,
3526 FIB_SOURCE_API);
3527 FIB_TEST(FIB_NODE_INDEX_INVALID ==
3528 fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32),
3529 "4.4.4.4/32 removed");
3530
3531 /*
3532 * add-remove test. no change.
3533 */
3534 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
3535 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003536 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003537 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003538 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003539 fib_entry_pool_size());
3540
3541 /*
3542 * A route with multiple paths at once
3543 */
3544 fib_route_path_t *r_paths = NULL;
3545
3546 for (ii = 0; ii < 4; ii++)
3547 {
3548 fib_route_path_t r_path = {
Neale Rannsda78f952017-05-24 09:15:43 -07003549 .frp_proto = DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003550 .frp_addr = {
3551 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02 + ii),
3552 },
3553 .frp_sw_if_index = tm->hw[0]->sw_if_index,
3554 .frp_weight = 1,
3555 .frp_fib_index = ~0,
3556 };
3557 vec_add1(r_paths, r_path);
3558 }
3559
3560 fib_table_entry_update(fib_index,
3561 &pfx_4_4_4_4_s_32,
3562 FIB_SOURCE_API,
3563 FIB_ENTRY_FLAG_NONE,
3564 r_paths);
3565
3566 fei = fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32);
3567 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "4.4.4.4/32 present");
3568 dpo = fib_entry_contribute_ip_forwarding(fei);
3569
3570 lb = load_balance_get(dpo->dpoi_index);
3571 FIB_TEST((lb->lb_n_buckets == 4), "4.4.4.4/32 lb over %d paths", lb->lb_n_buckets);
3572
3573 fib_table_entry_delete(fib_index,
3574 &pfx_4_4_4_4_s_32,
3575 FIB_SOURCE_API);
3576 FIB_TEST(FIB_NODE_INDEX_INVALID ==
3577 fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32),
3578 "4.4.4.4/32 removed");
3579 vec_free(r_paths);
3580
3581 /*
3582 * add-remove test. no change.
3583 */
3584 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
3585 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003586 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003587 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003588 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003589 fib_entry_pool_size());
3590
3591 /*
3592 * A route deag route
3593 */
3594 fib_table_entry_path_add(fib_index,
3595 &pfx_4_4_4_4_s_32,
3596 FIB_SOURCE_API,
3597 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003598 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003599 &zero_addr,
3600 ~0,
3601 fib_index,
3602 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003603 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003604 FIB_ROUTE_PATH_FLAG_NONE);
3605
3606 fei = fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32);
3607 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "4.4.4.4/32 present");
3608
3609 dpo = fib_entry_contribute_ip_forwarding(fei);
3610 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
3611 lookup_dpo_t *lkd = lookup_dpo_get(dpo->dpoi_index);
3612
3613 FIB_TEST((fib_index == lkd->lkd_fib_index),
3614 "4.4.4.4/32 is deag in %d %U",
3615 lkd->lkd_fib_index,
3616 format_dpo_id, dpo, 0);
Neale Ranns054c03a2017-10-13 05:15:07 -07003617 FIB_TEST((LOOKUP_INPUT_DST_ADDR == lkd->lkd_input),
3618 "4.4.4.4/32 is source deag in %d %U",
3619 lkd->lkd_input,
3620 format_dpo_id, dpo, 0);
3621
3622 fib_table_entry_delete(fib_index,
3623 &pfx_4_4_4_4_s_32,
3624 FIB_SOURCE_API);
3625 FIB_TEST(FIB_NODE_INDEX_INVALID ==
3626 fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32),
3627 "4.4.4.4/32 removed");
3628 vec_free(r_paths);
3629
3630 /*
3631 * A route deag route in a source lookup table
3632 */
3633 fib_table_entry_path_add(fib_index,
3634 &pfx_4_4_4_4_s_32,
3635 FIB_SOURCE_API,
3636 FIB_ENTRY_FLAG_NONE,
3637 DPO_PROTO_IP4,
3638 &zero_addr,
3639 ~0,
3640 fib_index,
3641 1,
3642 NULL,
3643 FIB_ROUTE_PATH_SOURCE_LOOKUP);
3644
3645 fei = fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32);
3646 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "4.4.4.4/32 present");
3647
3648 dpo = fib_entry_contribute_ip_forwarding(fei);
3649 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
3650 lkd = lookup_dpo_get(dpo->dpoi_index);
3651
3652 FIB_TEST((fib_index == lkd->lkd_fib_index),
3653 "4.4.4.4/32 is deag in %d %U",
3654 lkd->lkd_fib_index,
3655 format_dpo_id, dpo, 0);
3656 FIB_TEST((LOOKUP_INPUT_SRC_ADDR == lkd->lkd_input),
3657 "4.4.4.4/32 is source deag in %d %U",
3658 lkd->lkd_input,
3659 format_dpo_id, dpo, 0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003660
3661 fib_table_entry_delete(fib_index,
3662 &pfx_4_4_4_4_s_32,
3663 FIB_SOURCE_API);
3664 FIB_TEST(FIB_NODE_INDEX_INVALID ==
3665 fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32),
3666 "4.4.4.4/32 removed");
3667 vec_free(r_paths);
3668
3669 /*
3670 * add-remove test. no change.
3671 */
3672 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
3673 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003674 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003675 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003676 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003677 fib_entry_pool_size());
3678
3679 /*
Neale Rannsbcc889c2016-11-03 14:15:28 -07003680 * Duplicate paths:
3681 * add a recursive with duplicate paths. Expect the duplicate to be ignored.
3682 */
3683 fib_prefix_t pfx_34_1_1_1_s_32 = {
3684 .fp_len = 32,
3685 .fp_proto = FIB_PROTOCOL_IP4,
3686 .fp_addr = {
3687 .ip4.as_u32 = clib_host_to_net_u32(0x22010101),
3688 },
3689 };
3690 fib_prefix_t pfx_34_34_1_1_s_32 = {
3691 .fp_len = 32,
3692 .fp_proto = FIB_PROTOCOL_IP4,
3693 .fp_addr = {
3694 .ip4.as_u32 = clib_host_to_net_u32(0x22220101),
3695 },
3696 };
3697 fei = fib_table_entry_path_add(fib_index,
Neale Ranns57b58602017-07-15 07:37:25 -07003698 &pfx_34_34_1_1_s_32,
3699 FIB_SOURCE_API,
3700 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003701 DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07003702 &nh_10_10_10_1,
3703 tm->hw[0]->sw_if_index,
3704 0,
3705 1,
3706 NULL,
3707 FIB_ROUTE_PATH_FLAG_NONE);
3708 fei = fib_table_entry_path_add(fib_index,
Neale Rannsbcc889c2016-11-03 14:15:28 -07003709 &pfx_34_1_1_1_s_32,
3710 FIB_SOURCE_API,
3711 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003712 DPO_PROTO_IP4,
Neale Rannsbcc889c2016-11-03 14:15:28 -07003713 &pfx_34_34_1_1_s_32.fp_addr,
3714 ~0,
3715 fib_index,
3716 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003717 NULL,
Neale Rannsbcc889c2016-11-03 14:15:28 -07003718 FIB_ROUTE_PATH_FLAG_NONE);
3719 fei = fib_table_entry_path_add(fib_index,
3720 &pfx_34_1_1_1_s_32,
3721 FIB_SOURCE_API,
3722 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003723 DPO_PROTO_IP4,
Neale Rannsbcc889c2016-11-03 14:15:28 -07003724 &pfx_34_34_1_1_s_32.fp_addr,
3725 ~0,
3726 fib_index,
3727 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003728 NULL,
Neale Rannsbcc889c2016-11-03 14:15:28 -07003729 FIB_ROUTE_PATH_FLAG_NONE);
3730 FIB_TEST_REC_FORW(&pfx_34_1_1_1_s_32, &pfx_34_34_1_1_s_32, 0);
3731 fib_table_entry_delete_index(fei, FIB_SOURCE_API);
Neale Ranns57b58602017-07-15 07:37:25 -07003732 fib_table_entry_delete(fib_index,
3733 &pfx_34_34_1_1_s_32,
3734 FIB_SOURCE_API);
Neale Rannsbcc889c2016-11-03 14:15:28 -07003735
3736 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003737 * CLEANUP
3738 * remove: 1.1.1.2/32, 1.1.2.0/24 and 1.1.1.1/32
3739 * all of which are via 10.10.10.1, Itf1
3740 */
3741 fib_table_entry_path_remove(fib_index,
3742 &pfx_1_1_1_2_s_32,
3743 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07003744 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003745 &nh_10_10_10_1,
3746 tm->hw[0]->sw_if_index,
3747 ~0,
3748 1,
3749 FIB_ROUTE_PATH_FLAG_NONE);
3750 fib_table_entry_path_remove(fib_index,
3751 &pfx_1_1_1_1_s_32,
3752 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07003753 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003754 &nh_10_10_10_1,
3755 tm->hw[0]->sw_if_index,
3756 ~0,
3757 1,
3758 FIB_ROUTE_PATH_FLAG_NONE);
3759 fib_table_entry_path_remove(fib_index,
3760 &pfx_1_1_2_0_s_24,
3761 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07003762 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003763 &nh_10_10_10_1,
3764 tm->hw[0]->sw_if_index,
3765 ~0,
3766 1,
3767 FIB_ROUTE_PATH_FLAG_NONE);
3768
3769 FIB_TEST(FIB_NODE_INDEX_INVALID ==
3770 fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_1_s_32),
3771 "1.1.1.1/32 removed");
3772 FIB_TEST(FIB_NODE_INDEX_INVALID ==
3773 fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_2_s_32),
3774 "1.1.1.2/32 removed");
3775 FIB_TEST(FIB_NODE_INDEX_INVALID ==
3776 fib_table_lookup_exact_match(fib_index, &pfx_1_1_2_0_s_24),
3777 "1.1.2.0/24 removed");
3778
3779 /*
3780 * -3 entries and -1 shared path-list
3781 */
3782 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
3783 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003784 FIB_TEST((PNBR+4 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003785 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003786 FIB_TEST((ENBR+4 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003787 fib_entry_pool_size());
3788
3789 /*
3790 * An attached-host route. Expect to link to the incomplete adj
3791 */
3792 fib_prefix_t pfx_4_1_1_1_s_32 = {
3793 .fp_len = 32,
3794 .fp_proto = FIB_PROTOCOL_IP4,
3795 .fp_addr = {
3796 /* 4.1.1.1/32 */
3797 .ip4.as_u32 = clib_host_to_net_u32(0x04010101),
3798 },
3799 };
3800 fib_table_entry_path_add(fib_index,
3801 &pfx_4_1_1_1_s_32,
3802 FIB_SOURCE_API,
3803 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003804 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003805 &zero_addr,
3806 tm->hw[0]->sw_if_index,
3807 fib_index,
3808 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003809 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003810 FIB_ROUTE_PATH_FLAG_NONE);
3811
3812 fei = fib_table_lookup_exact_match(fib_index, &pfx_4_1_1_1_s_32);
3813 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "4.1.1.1/32 present");
3814 ai = fib_entry_get_adj(fei);
3815
3816 ai2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01003817 VNET_LINK_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003818 &pfx_4_1_1_1_s_32.fp_addr,
3819 tm->hw[0]->sw_if_index);
3820 FIB_TEST((ai == ai2), "Attached-host link to incomplete ADJ");
3821 adj_unlock(ai2);
3822
3823 /*
3824 * +1 entry and +1 shared path-list
3825 */
3826 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
3827 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003828 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003829 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003830 FIB_TEST((ENBR+5 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003831 fib_entry_pool_size());
3832
3833 fib_table_entry_delete(fib_index,
3834 &pfx_4_1_1_1_s_32,
3835 FIB_SOURCE_API);
3836
3837 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
3838 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003839 FIB_TEST((PNBR+4 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003840 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003841 FIB_TEST((ENBR+4 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003842 fib_entry_pool_size());
3843
3844 /*
3845 * add a v6 prefix via v4 next-hops
3846 */
3847 fib_prefix_t pfx_2001_s_64 = {
3848 .fp_len = 64,
3849 .fp_proto = FIB_PROTOCOL_IP6,
3850 .fp_addr = {
3851 .ip6.as_u64[0] = clib_host_to_net_u64(0x2001000000000000),
3852 },
3853 };
3854 fei = fib_table_entry_path_add(0, //default v6 table
3855 &pfx_2001_s_64,
3856 FIB_SOURCE_API,
3857 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003858 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003859 &nh_10_10_10_1,
3860 tm->hw[0]->sw_if_index,
3861 fib_index,
3862 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003863 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003864 FIB_ROUTE_PATH_FLAG_NONE);
3865
3866 fei = fib_table_lookup_exact_match(0, &pfx_2001_s_64);
3867 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "2001::/64 present");
3868 ai = fib_entry_get_adj(fei);
3869 adj = adj_get(ai);
3870 FIB_TEST((adj->lookup_next_index == IP_LOOKUP_NEXT_ARP),
3871 "2001::/64 via ARP-adj");
Neale Ranns924d03a2016-10-19 08:25:46 +01003872 FIB_TEST((adj->ia_link == VNET_LINK_IP6),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003873 "2001::/64 is link type v6");
3874 FIB_TEST((adj->ia_nh_proto == FIB_PROTOCOL_IP4),
3875 "2001::/64 ADJ-adj is NH proto v4");
3876 fib_table_entry_delete(0, &pfx_2001_s_64, FIB_SOURCE_API);
3877
Neale Ranns3ee44042016-10-03 13:05:48 +01003878 /*
3879 * add a uRPF exempt prefix:
3880 * test:
3881 * - it's forwarding is drop
3882 * - it's uRPF list is not empty
3883 * - the uRPF list for the default route (it's cover) is empty
3884 */
3885 fei = fib_table_entry_special_add(fib_index,
3886 &pfx_4_1_1_1_s_32,
3887 FIB_SOURCE_URPF_EXEMPT,
Neale Rannsa0558302017-04-13 00:44:52 -07003888 FIB_ENTRY_FLAG_DROP);
Neale Ranns3ee44042016-10-03 13:05:48 +01003889 dpo = fib_entry_contribute_ip_forwarding(fei);
3890 FIB_TEST(load_balance_is_drop(dpo),
3891 "uRPF exempt 4.1.1.1/32 DROP");
3892 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 1, 0),
3893 "uRPF list for exempt prefix has itf index 0");
3894 fei = fib_table_lookup_exact_match(fib_index, &pfx_0_0_0_0_s_0);
3895 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 0),
3896 "uRPF list for 0.0.0.0/0 empty");
3897
3898 fib_table_entry_delete(fib_index, &pfx_4_1_1_1_s_32, FIB_SOURCE_URPF_EXEMPT);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003899
3900 /*
Neale Ranns3983ac22017-03-10 11:53:27 -08003901 * An adj-fib that fails the refinement criteria - no connected cover
3902 */
3903 fib_prefix_t pfx_12_10_10_2_s_32 = {
3904 .fp_len = 32,
3905 .fp_proto = FIB_PROTOCOL_IP4,
3906 .fp_addr = {
3907 /* 12.10.10.2 */
3908 .ip4.as_u32 = clib_host_to_net_u32(0x0c0a0a02),
3909 },
3910 };
3911
Neale Ranns81424992017-05-18 03:03:22 -07003912 fib_table_entry_path_add(fib_index,
3913 &pfx_12_10_10_2_s_32,
3914 FIB_SOURCE_ADJ,
3915 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07003916 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07003917 &pfx_12_10_10_2_s_32.fp_addr,
3918 tm->hw[0]->sw_if_index,
3919 ~0, // invalid fib index
3920 1,
3921 NULL,
3922 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns3983ac22017-03-10 11:53:27 -08003923
3924 fei = fib_table_lookup_exact_match(fib_index, &pfx_12_10_10_2_s_32);
3925 dpo = fib_entry_contribute_ip_forwarding(fei);
3926 FIB_TEST(!dpo_id_is_valid(dpo),
3927 "no connected cover adj-fib fails refinement");
3928
3929 fib_table_entry_delete(fib_index,
3930 &pfx_12_10_10_2_s_32,
3931 FIB_SOURCE_ADJ);
3932
3933 /*
3934 * An adj-fib that fails the refinement criteria - cover is connected
3935 * but on a different interface
3936 */
3937 fib_prefix_t pfx_10_10_10_127_s_32 = {
3938 .fp_len = 32,
3939 .fp_proto = FIB_PROTOCOL_IP4,
3940 .fp_addr = {
3941 /* 10.10.10.127 */
3942 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a7f),
3943 },
3944 };
3945
Neale Ranns81424992017-05-18 03:03:22 -07003946 fib_table_entry_path_add(fib_index,
3947 &pfx_10_10_10_127_s_32,
3948 FIB_SOURCE_ADJ,
3949 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07003950 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07003951 &pfx_10_10_10_127_s_32.fp_addr,
3952 tm->hw[1]->sw_if_index,
3953 ~0, // invalid fib index
3954 1,
3955 NULL,
3956 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns3983ac22017-03-10 11:53:27 -08003957
3958 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_127_s_32);
3959 dpo = fib_entry_contribute_ip_forwarding(fei);
3960 FIB_TEST(!dpo_id_is_valid(dpo),
3961 "wrong interface adj-fib fails refinement");
3962
3963 fib_table_entry_delete(fib_index,
3964 &pfx_10_10_10_127_s_32,
3965 FIB_SOURCE_ADJ);
Neale Ranns81424992017-05-18 03:03:22 -07003966
3967 /*
3968 * add a second path to an adj-fib
3969 * this is a sumiluation of another ARP entry created
3970 * on an interface on which the connected prefi does not exist.
3971 * The second path fails refinement. Expect to forward through the
3972 * first.
3973 */
3974 fib_prefix_t pfx_10_10_10_3_s_32 = {
3975 .fp_len = 32,
3976 .fp_proto = FIB_PROTOCOL_IP4,
3977 .fp_addr = {
3978 /* 10.10.10.3 */
3979 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a03),
3980 },
3981 };
3982
3983 ai_03 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
3984 VNET_LINK_IP4,
3985 &nh_10_10_10_3,
3986 tm->hw[0]->sw_if_index);
3987
3988 fib_test_lb_bucket_t ip_o_10_10_10_3 = {
3989 .type = FT_LB_ADJ,
3990 .adj = {
3991 .adj = ai_03,
3992 },
3993 };
3994 fei = fib_table_entry_path_add(fib_index,
3995 &pfx_10_10_10_3_s_32,
3996 FIB_SOURCE_ADJ,
3997 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003998 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07003999 &nh_10_10_10_3,
4000 tm->hw[0]->sw_if_index,
4001 fib_index,
4002 1,
4003 NULL,
4004 FIB_ROUTE_PATH_FLAG_NONE);
4005 fei = fib_table_entry_path_add(fib_index,
4006 &pfx_10_10_10_3_s_32,
4007 FIB_SOURCE_ADJ,
4008 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07004009 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07004010 &nh_12_12_12_12,
4011 tm->hw[1]->sw_if_index,
4012 fib_index,
4013 1,
4014 NULL,
4015 FIB_ROUTE_PATH_FLAG_NONE);
4016 FIB_TEST(fib_test_validate_entry(fei,
4017 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
4018 1,
4019 &ip_o_10_10_10_3),
4020 "10.10.10.3 via 10.10.10.3/Eth0 only");
4021
4022 /*
4023 * remove the path that refines the cover, should go unresolved
4024 */
4025 fib_table_entry_path_remove(fib_index,
4026 &pfx_10_10_10_3_s_32,
4027 FIB_SOURCE_ADJ,
Neale Rannsda78f952017-05-24 09:15:43 -07004028 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07004029 &nh_10_10_10_3,
4030 tm->hw[0]->sw_if_index,
4031 fib_index,
4032 1,
4033 FIB_ROUTE_PATH_FLAG_NONE);
4034 dpo = fib_entry_contribute_ip_forwarding(fei);
4035 FIB_TEST(!dpo_id_is_valid(dpo),
4036 "wrong interface adj-fib fails refinement");
4037
4038 /*
4039 * add back the path that refines the cover
4040 */
4041 fei = fib_table_entry_path_add(fib_index,
4042 &pfx_10_10_10_3_s_32,
4043 FIB_SOURCE_ADJ,
4044 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07004045 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07004046 &nh_10_10_10_3,
4047 tm->hw[0]->sw_if_index,
4048 fib_index,
4049 1,
4050 NULL,
4051 FIB_ROUTE_PATH_FLAG_NONE);
4052 FIB_TEST(fib_test_validate_entry(fei,
4053 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
4054 1,
4055 &ip_o_10_10_10_3),
4056 "10.10.10.3 via 10.10.10.3/Eth0 only");
4057
4058 /*
4059 * remove the path that does not refine the cover
4060 */
4061 fib_table_entry_path_remove(fib_index,
4062 &pfx_10_10_10_3_s_32,
4063 FIB_SOURCE_ADJ,
Neale Rannsda78f952017-05-24 09:15:43 -07004064 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07004065 &nh_12_12_12_12,
4066 tm->hw[1]->sw_if_index,
4067 fib_index,
4068 1,
4069 FIB_ROUTE_PATH_FLAG_NONE);
4070 FIB_TEST(fib_test_validate_entry(fei,
4071 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
4072 1,
4073 &ip_o_10_10_10_3),
4074 "10.10.10.3 via 10.10.10.3/Eth0 only");
4075
4076 /*
4077 * remove the path that does refine, it's the last path, so
4078 * the entry should be gone
4079 */
4080 fib_table_entry_path_remove(fib_index,
4081 &pfx_10_10_10_3_s_32,
4082 FIB_SOURCE_ADJ,
Neale Rannsda78f952017-05-24 09:15:43 -07004083 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07004084 &nh_10_10_10_3,
4085 tm->hw[0]->sw_if_index,
4086 fib_index,
4087 1,
4088 FIB_ROUTE_PATH_FLAG_NONE);
4089 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_3_s_32);
4090 FIB_TEST((fei == FIB_NODE_INDEX_INVALID), "10.10.10.3 gone");
4091
4092 adj_unlock(ai_03);
4093
Neale Ranns227038a2017-04-21 01:07:59 -07004094 /*
4095 * change the table's flow-hash config - expect the update to propagete to
4096 * the entries' load-balance objects
4097 */
4098 flow_hash_config_t old_hash_config, new_hash_config;
4099
4100 old_hash_config = fib_table_get_flow_hash_config(fib_index,
4101 FIB_PROTOCOL_IP4);
4102 new_hash_config = (IP_FLOW_HASH_SRC_ADDR |
4103 IP_FLOW_HASH_DST_ADDR);
4104
4105 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
4106 dpo = fib_entry_contribute_ip_forwarding(fei);
4107 lb = load_balance_get(dpo->dpoi_index);
4108 FIB_TEST((lb->lb_hash_config == old_hash_config),
4109 "Table and LB hash config match: %U",
4110 format_ip_flow_hash_config, lb->lb_hash_config);
4111
4112 fib_table_set_flow_hash_config(fib_index, FIB_PROTOCOL_IP4, new_hash_config);
4113
4114 FIB_TEST((lb->lb_hash_config == new_hash_config),
4115 "Table and LB newhash config match: %U",
4116 format_ip_flow_hash_config, lb->lb_hash_config);
Neale Ranns3983ac22017-03-10 11:53:27 -08004117
4118 /*
Neale Ranns6f631152017-10-03 08:20:21 -07004119 * A route via an L2 Bridge
4120 */
4121 fei = fib_table_entry_path_add(fib_index,
4122 &pfx_10_10_10_3_s_32,
4123 FIB_SOURCE_API,
4124 FIB_ENTRY_FLAG_NONE,
4125 DPO_PROTO_ETHERNET,
4126 &zero_addr,
4127 tm->hw[0]->sw_if_index,
4128 ~0,
4129 1,
4130 NULL,
4131 FIB_ROUTE_PATH_FLAG_NONE);
4132 dpo_id_t l2_dpo = DPO_INVALID;
4133 l2_bridge_dpo_add_or_lock(tm->hw[0]->sw_if_index, &l2_dpo);
4134 fib_test_lb_bucket_t ip_o_l2 = {
4135 .type = FT_LB_L2,
4136 .adj = {
4137 .adj = l2_dpo.dpoi_index,
4138 },
4139 };
4140
4141 FIB_TEST(fib_test_validate_entry(fei,
4142 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
4143 1,
4144 &ip_o_l2),
4145 "10.10.10.3 via L2 on Eth0");
4146 fib_table_entry_path_remove(fib_index,
4147 &pfx_10_10_10_3_s_32,
4148 FIB_SOURCE_API,
4149 DPO_PROTO_ETHERNET,
4150 &zero_addr,
4151 tm->hw[0]->sw_if_index,
4152 fib_index,
4153 1,
4154 FIB_ROUTE_PATH_FLAG_NONE);
4155 dpo_reset(&l2_dpo);
4156
4157 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004158 * CLEANUP
4159 * remove adj-fibs:
4160 */
4161 fib_table_entry_delete(fib_index,
4162 &pfx_10_10_10_1_s_32,
4163 FIB_SOURCE_ADJ);
4164 fib_table_entry_delete(fib_index,
4165 &pfx_10_10_10_2_s_32,
4166 FIB_SOURCE_ADJ);
4167 FIB_TEST(FIB_NODE_INDEX_INVALID ==
4168 fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32),
4169 "10.10.10.1/32 adj-fib removed");
4170 FIB_TEST(FIB_NODE_INDEX_INVALID ==
4171 fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_2_s_32),
4172 "10.10.10.2/32 adj-fib removed");
4173
4174 /*
4175 * -2 entries and -2 non-shared path-list
4176 */
4177 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
4178 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004179 FIB_TEST((PNBR+2 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004180 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004181 FIB_TEST((ENBR+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004182 fib_entry_pool_size());
4183
4184 /*
Neale Ranns3ee44042016-10-03 13:05:48 +01004185 * unlock the adjacencies for which this test provided a rewrite.
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004186 * These are the last locks on these adjs. they should thus go away.
4187 */
4188 adj_unlock(ai_02);
4189 adj_unlock(ai_01);
Neale Ranns3ee44042016-10-03 13:05:48 +01004190 adj_unlock(ai_12_12_12_12);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004191
4192 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
4193 adj_nbr_db_size());
Neale Ranns3dffb1e2016-11-01 20:38:53 +00004194
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004195 /*
4196 * CLEANUP
4197 * remove the interface prefixes
4198 */
4199 local_pfx.fp_len = 32;
4200 fib_table_entry_special_remove(fib_index, &local_pfx,
4201 FIB_SOURCE_INTERFACE);
4202 fei = fib_table_lookup(fib_index, &local_pfx);
4203
4204 FIB_TEST(FIB_NODE_INDEX_INVALID ==
4205 fib_table_lookup_exact_match(fib_index, &local_pfx),
4206 "10.10.10.10/32 adj-fib removed");
4207
4208 local_pfx.fp_len = 24;
4209 fib_table_entry_delete(fib_index, &local_pfx,
4210 FIB_SOURCE_INTERFACE);
4211
4212 FIB_TEST(FIB_NODE_INDEX_INVALID ==
4213 fib_table_lookup_exact_match(fib_index, &local_pfx),
4214 "10.10.10.10/24 adj-fib removed");
4215
4216 /*
4217 * -2 entries and -2 non-shared path-list
4218 */
Neale Rannsf12a83f2017-04-18 09:09:40 -07004219 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004220 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004221 FIB_TEST((PNBR == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004222 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004223 FIB_TEST((ENBR == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004224 fib_entry_pool_size());
4225
4226 /*
4227 * Last but not least, remove the VRF
4228 */
4229 FIB_TEST((0 == fib_table_get_num_entries(fib_index,
4230 FIB_PROTOCOL_IP4,
4231 FIB_SOURCE_API)),
4232 "NO API Source'd prefixes");
4233 FIB_TEST((0 == fib_table_get_num_entries(fib_index,
4234 FIB_PROTOCOL_IP4,
4235 FIB_SOURCE_RR)),
4236 "NO RR Source'd prefixes");
4237 FIB_TEST((0 == fib_table_get_num_entries(fib_index,
4238 FIB_PROTOCOL_IP4,
4239 FIB_SOURCE_INTERFACE)),
4240 "NO INterface Source'd prefixes");
4241
Neale Ranns15002542017-09-10 04:39:11 -07004242 fib_table_unlock(fib_index, FIB_PROTOCOL_IP4, FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004243
4244 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
4245 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004246 FIB_TEST((PNBR-5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004247 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004248 FIB_TEST((ENBR-5 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004249 fib_entry_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004250 FIB_TEST((ENBR-5 == pool_elts(fib_urpf_list_pool)), "uRPF pool size is %d",
Neale Ranns3ee44042016-10-03 13:05:48 +01004251 pool_elts(fib_urpf_list_pool));
Neale Ranns994dab42017-04-18 12:56:45 -07004252 FIB_TEST((0 == pool_elts(load_balance_map_pool)), "LB-map pool size is %d",
Neale Rannsf12a83f2017-04-18 09:09:40 -07004253 pool_elts(load_balance_map_pool));
Neale Ranns994dab42017-04-18 12:56:45 -07004254 FIB_TEST((lb_count == pool_elts(load_balance_pool)), "LB pool size is %d",
4255 pool_elts(load_balance_pool));
Neale Ranns6f631152017-10-03 08:20:21 -07004256 FIB_TEST((0 == pool_elts(l2_bridge_dpo_pool)), "L2 DPO pool size is %d",
4257 pool_elts(l2_bridge_dpo_pool));
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004258
Neale Ranns0ebe8d72016-12-08 19:48:11 +00004259 return 0;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004260}
4261
Neale Ranns0ebe8d72016-12-08 19:48:11 +00004262static int
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004263fib_test_v6 (void)
4264{
4265 /*
4266 * In the default table check for the presence and correct forwarding
4267 * of the special entries
4268 */
4269 fib_node_index_t dfrt, fei, ai, locked_ai, ai_01, ai_02;
4270 const dpo_id_t *dpo, *dpo_drop;
4271 const ip_adjacency_t *adj;
4272 const receive_dpo_t *rd;
4273 test_main_t *tm;
4274 u32 fib_index;
4275 int ii;
4276
4277 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
4278 adj_nbr_db_size());
4279
4280 /* via 2001:0:0:1::2 */
4281 ip46_address_t nh_2001_2 = {
4282 .ip6 = {
4283 .as_u64 = {
4284 [0] = clib_host_to_net_u64(0x2001000000000001),
4285 [1] = clib_host_to_net_u64(0x0000000000000002),
4286 },
4287 },
4288 };
4289
4290 tm = &test_main;
4291
4292 dpo_drop = drop_dpo_get(DPO_PROTO_IP6);
4293
4294 /* Find or create FIB table 11 */
Neale Ranns15002542017-09-10 04:39:11 -07004295 fib_index = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP6, 11,
4296 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004297
4298 for (ii = 0; ii < 4; ii++)
4299 {
4300 ip6_main.fib_index_by_sw_if_index[tm->hw[ii]->sw_if_index] = fib_index;
4301 }
4302
4303 fib_prefix_t pfx_0_0 = {
4304 .fp_len = 0,
4305 .fp_proto = FIB_PROTOCOL_IP6,
4306 .fp_addr = {
4307 .ip6 = {
4308 {0, 0},
4309 },
4310 },
4311 };
4312
4313 dfrt = fib_table_lookup(fib_index, &pfx_0_0);
4314 FIB_TEST((FIB_NODE_INDEX_INVALID != dfrt), "default route present");
4315 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(dfrt)),
4316 "Default route is DROP");
4317
4318 dpo = fib_entry_contribute_ip_forwarding(dfrt);
4319 FIB_TEST((dpo->dpoi_index == ip6_fib_table_fwding_lookup(
4320 &ip6_main,
4321 1,
4322 &pfx_0_0.fp_addr.ip6)),
4323 "default-route; fwd and non-fwd tables match");
4324
4325 // FIXME - check specials.
4326
4327 /*
4328 * At this stage there is one v4 FIB with 5 routes and two v6 FIBs
Neale Ranns32e1c012016-11-22 17:07:28 +00004329 * each with 2 entries and a v6 mfib with 4 path-lists.
4330 * All entries are special so no path-list sharing.
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004331 */
Neale Ranns32e1c012016-11-22 17:07:28 +00004332#define ENPS (5+4)
4333#define PNPS (5+4+4)
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004334 FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00004335 FIB_TEST((PNPS == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004336 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004337 FIB_TEST((ENPS == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004338 fib_entry_pool_size());
4339
4340 /*
4341 * add interface routes.
4342 * validate presence of /64 attached and /128 recieve.
4343 * test for the presence of the receive address in the glean and local adj
4344 *
4345 * receive on 2001:0:0:1::1/128
4346 */
4347 fib_prefix_t local_pfx = {
4348 .fp_len = 64,
4349 .fp_proto = FIB_PROTOCOL_IP6,
4350 .fp_addr = {
4351 .ip6 = {
4352 .as_u64 = {
4353 [0] = clib_host_to_net_u64(0x2001000000000001),
4354 [1] = clib_host_to_net_u64(0x0000000000000001),
4355 },
4356 },
4357 }
4358 };
4359
4360 fib_table_entry_update_one_path(fib_index, &local_pfx,
4361 FIB_SOURCE_INTERFACE,
4362 (FIB_ENTRY_FLAG_CONNECTED |
4363 FIB_ENTRY_FLAG_ATTACHED),
Neale Rannsda78f952017-05-24 09:15:43 -07004364 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004365 NULL,
4366 tm->hw[0]->sw_if_index,
4367 ~0,
4368 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00004369 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004370 FIB_ROUTE_PATH_FLAG_NONE);
4371 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4372
4373 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached interface route present");
4374
4375 ai = fib_entry_get_adj(fei);
4376 FIB_TEST((FIB_NODE_INDEX_INVALID != ai), "attached interface route adj present");
4377 adj = adj_get(ai);
4378 FIB_TEST((IP_LOOKUP_NEXT_GLEAN == adj->lookup_next_index),
4379 "attached interface adj is glean");
4380 FIB_TEST((0 == ip46_address_cmp(&local_pfx.fp_addr,
4381 &adj->sub_type.glean.receive_addr)),
4382 "attached interface adj is receive ok");
4383 dpo = fib_entry_contribute_ip_forwarding(fei);
4384 FIB_TEST((dpo->dpoi_index == ip6_fib_table_fwding_lookup(
4385 &ip6_main,
4386 1,
4387 &local_pfx.fp_addr.ip6)),
4388 "attached-route; fwd and non-fwd tables match");
4389
4390 local_pfx.fp_len = 128;
4391 fib_table_entry_update_one_path(fib_index, &local_pfx,
4392 FIB_SOURCE_INTERFACE,
4393 (FIB_ENTRY_FLAG_CONNECTED |
4394 FIB_ENTRY_FLAG_LOCAL),
Neale Rannsda78f952017-05-24 09:15:43 -07004395 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004396 NULL,
4397 tm->hw[0]->sw_if_index,
4398 ~0, // invalid fib index
4399 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00004400 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004401 FIB_ROUTE_PATH_FLAG_NONE);
4402 fei = fib_table_lookup(fib_index, &local_pfx);
4403
4404 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local interface route present");
4405
4406 dpo = fib_entry_contribute_ip_forwarding(fei);
4407 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
4408 FIB_TEST((DPO_RECEIVE == dpo->dpoi_type),
4409 "local interface adj is local");
4410 rd = receive_dpo_get(dpo->dpoi_index);
4411
4412 FIB_TEST((0 == ip46_address_cmp(&local_pfx.fp_addr,
4413 &rd->rd_addr)),
4414 "local interface adj is receive ok");
4415
4416 dpo = fib_entry_contribute_ip_forwarding(fei);
4417 FIB_TEST((dpo->dpoi_index == ip6_fib_table_fwding_lookup(
4418 &ip6_main,
4419 1,
4420 &local_pfx.fp_addr.ip6)),
4421 "local-route; fwd and non-fwd tables match");
4422
4423 /*
4424 * +2 entries. +2 unshared path-lists
4425 */
4426 FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00004427 FIB_TEST((PNPS+2 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004428 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004429 FIB_TEST((ENPS+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004430 fib_entry_pool_size());
4431
4432 /*
4433 * Modify the default route to be via an adj not yet known.
4434 * this sources the defalut route with the API source, which is
4435 * a higher preference to the DEFAULT_ROUTE source
4436 */
4437 fib_table_entry_path_add(fib_index, &pfx_0_0,
4438 FIB_SOURCE_API,
4439 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07004440 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004441 &nh_2001_2,
4442 tm->hw[0]->sw_if_index,
4443 ~0,
4444 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00004445 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004446 FIB_ROUTE_PATH_FLAG_NONE);
4447 fei = fib_table_lookup(fib_index, &pfx_0_0);
4448
4449 FIB_TEST((fei == dfrt), "default route same index");
4450 ai = fib_entry_get_adj(fei);
4451 FIB_TEST((FIB_NODE_INDEX_INVALID != ai), "default route adj present");
4452 adj = adj_get(ai);
4453 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
4454 "adj is incomplete");
4455 FIB_TEST((0 == ip46_address_cmp(&nh_2001_2, &adj->sub_type.nbr.next_hop)),
4456 "adj nbr next-hop ok");
4457
4458 /*
4459 * find the adj in the shared db
4460 */
4461 locked_ai = adj_nbr_add_or_lock(FIB_PROTOCOL_IP6,
Neale Ranns924d03a2016-10-19 08:25:46 +01004462 VNET_LINK_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004463 &nh_2001_2,
4464 tm->hw[0]->sw_if_index);
4465 FIB_TEST((locked_ai == ai), "ADJ NBR DB find");
4466 adj_unlock(locked_ai);
4467
4468 /*
4469 * no more entires. +1 shared path-list
4470 */
4471 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
4472 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004473 FIB_TEST((PNPS+3 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004474 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004475 FIB_TEST((ENPS+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004476 fib_entry_pool_size());
4477
4478 /*
4479 * remove the API source from the default route. We expected
4480 * the route to remain, sourced by DEFAULT_ROUTE, and hence a DROP
4481 */
4482 fib_table_entry_path_remove(fib_index, &pfx_0_0,
4483 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07004484 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004485 &nh_2001_2,
4486 tm->hw[0]->sw_if_index,
4487 ~0,
4488 1,
4489 FIB_ROUTE_PATH_FLAG_NONE);
4490 fei = fib_table_lookup(fib_index, &pfx_0_0);
4491
4492 FIB_TEST((fei == dfrt), "default route same index");
4493 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(dfrt)),
4494 "Default route is DROP");
4495
4496 /*
4497 * no more entires. -1 shared path-list
4498 */
4499 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
4500 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004501 FIB_TEST((PNPS+2 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004502 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004503 FIB_TEST((ENPS+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004504 fib_entry_pool_size());
4505
4506 /*
4507 * Add an 2 ARP entry => a complete ADJ plus adj-fib.
4508 */
4509 fib_prefix_t pfx_2001_1_2_s_128 = {
4510 .fp_len = 128,
4511 .fp_proto = FIB_PROTOCOL_IP6,
4512 .fp_addr = {
4513 .ip6 = {
4514 .as_u64 = {
4515 [0] = clib_host_to_net_u64(0x2001000000000001),
4516 [1] = clib_host_to_net_u64(0x0000000000000002),
4517 },
4518 },
4519 }
4520 };
4521 fib_prefix_t pfx_2001_1_3_s_128 = {
4522 .fp_len = 128,
4523 .fp_proto = FIB_PROTOCOL_IP6,
4524 .fp_addr = {
4525 .ip6 = {
4526 .as_u64 = {
4527 [0] = clib_host_to_net_u64(0x2001000000000001),
4528 [1] = clib_host_to_net_u64(0x0000000000000003),
4529 },
4530 },
4531 }
4532 };
4533 u8 eth_addr[] = {
4534 0xde, 0xde, 0xde, 0xba, 0xba, 0xba,
4535 };
4536
4537 ai_01 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP6,
Neale Ranns924d03a2016-10-19 08:25:46 +01004538 VNET_LINK_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004539 &pfx_2001_1_2_s_128.fp_addr,
4540 tm->hw[0]->sw_if_index);
4541 FIB_TEST((FIB_NODE_INDEX_INVALID != ai_01), "adj created");
4542 adj = adj_get(ai_01);
4543 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
4544 "adj is incomplete");
4545 FIB_TEST((0 == ip46_address_cmp(&pfx_2001_1_2_s_128.fp_addr,
4546 &adj->sub_type.nbr.next_hop)),
4547 "adj nbr next-hop ok");
4548
Neale Rannsb80c5362016-10-08 13:03:40 +01004549 adj_nbr_update_rewrite(ai_01, ADJ_NBR_REWRITE_FLAG_COMPLETE,
4550 fib_test_build_rewrite(eth_addr));
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004551 FIB_TEST((IP_LOOKUP_NEXT_REWRITE == adj->lookup_next_index),
4552 "adj is complete");
4553 FIB_TEST((0 == ip46_address_cmp(&pfx_2001_1_2_s_128.fp_addr,
4554 &adj->sub_type.nbr.next_hop)),
4555 "adj nbr next-hop ok");
4556
Neale Ranns81424992017-05-18 03:03:22 -07004557 fib_table_entry_path_add(fib_index,
4558 &pfx_2001_1_2_s_128,
4559 FIB_SOURCE_ADJ,
4560 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07004561 DPO_PROTO_IP6,
Neale Ranns81424992017-05-18 03:03:22 -07004562 &pfx_2001_1_2_s_128.fp_addr,
4563 tm->hw[0]->sw_if_index,
4564 ~0,
4565 1,
4566 NULL,
4567 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004568
4569 fei = fib_table_lookup(fib_index, &pfx_2001_1_2_s_128);
4570 ai = fib_entry_get_adj(fei);
4571 FIB_TEST((ai_01 == ai), "ADJ-FIB resolves via adj");
4572
4573 eth_addr[5] = 0xb2;
4574
4575 ai_02 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP6,
Neale Ranns924d03a2016-10-19 08:25:46 +01004576 VNET_LINK_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004577 &pfx_2001_1_3_s_128.fp_addr,
4578 tm->hw[0]->sw_if_index);
4579 FIB_TEST((FIB_NODE_INDEX_INVALID != ai_02), "adj created");
4580 adj = adj_get(ai_02);
4581 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
4582 "adj is incomplete");
4583 FIB_TEST((0 == ip46_address_cmp(&pfx_2001_1_3_s_128.fp_addr,
4584 &adj->sub_type.nbr.next_hop)),
4585 "adj nbr next-hop ok");
4586
Neale Rannsb80c5362016-10-08 13:03:40 +01004587 adj_nbr_update_rewrite(ai_02, ADJ_NBR_REWRITE_FLAG_COMPLETE,
4588 fib_test_build_rewrite(eth_addr));
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004589 FIB_TEST((IP_LOOKUP_NEXT_REWRITE == adj->lookup_next_index),
4590 "adj is complete");
4591 FIB_TEST((0 == ip46_address_cmp(&pfx_2001_1_3_s_128.fp_addr,
4592 &adj->sub_type.nbr.next_hop)),
4593 "adj nbr next-hop ok");
4594 FIB_TEST((ai_01 != ai_02), "ADJs are different");
4595
Neale Ranns81424992017-05-18 03:03:22 -07004596 fib_table_entry_path_add(fib_index,
4597 &pfx_2001_1_3_s_128,
4598 FIB_SOURCE_ADJ,
4599 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07004600 DPO_PROTO_IP6,
Neale Ranns81424992017-05-18 03:03:22 -07004601 &pfx_2001_1_3_s_128.fp_addr,
4602 tm->hw[0]->sw_if_index,
4603 ~0,
4604 1,
4605 NULL,
4606 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004607
4608 fei = fib_table_lookup(fib_index, &pfx_2001_1_3_s_128);
4609 ai = fib_entry_get_adj(fei);
4610 FIB_TEST((ai_02 == ai), "ADJ-FIB resolves via adj");
4611
4612 /*
4613 * +2 entries, +2 unshread path-lists.
4614 */
4615 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
4616 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004617 FIB_TEST((PNPS+4 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004618 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004619 FIB_TEST((ENPS+4 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004620 fib_entry_pool_size());
4621
4622 /*
4623 * Add a 2 routes via the first ADJ. ensure path-list sharing
4624 */
4625 fib_prefix_t pfx_2001_a_s_64 = {
4626 .fp_len = 64,
4627 .fp_proto = FIB_PROTOCOL_IP6,
4628 .fp_addr = {
4629 .ip6 = {
4630 .as_u64 = {
4631 [0] = clib_host_to_net_u64(0x200100000000000a),
4632 [1] = clib_host_to_net_u64(0x0000000000000000),
4633 },
4634 },
4635 }
4636 };
4637 fib_prefix_t pfx_2001_b_s_64 = {
4638 .fp_len = 64,
4639 .fp_proto = FIB_PROTOCOL_IP6,
4640 .fp_addr = {
4641 .ip6 = {
4642 .as_u64 = {
4643 [0] = clib_host_to_net_u64(0x200100000000000b),
4644 [1] = clib_host_to_net_u64(0x0000000000000000),
4645 },
4646 },
4647 }
4648 };
4649
4650 fib_table_entry_path_add(fib_index,
4651 &pfx_2001_a_s_64,
4652 FIB_SOURCE_API,
4653 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07004654 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004655 &nh_2001_2,
4656 tm->hw[0]->sw_if_index,
4657 ~0,
4658 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00004659 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004660 FIB_ROUTE_PATH_FLAG_NONE);
4661 fei = fib_table_lookup(fib_index, &pfx_2001_a_s_64);
4662 ai = fib_entry_get_adj(fei);
4663 FIB_TEST((ai_01 == ai), "2001::a/64 resolves via 2001:0:0:1::1");
4664 fib_table_entry_path_add(fib_index,
4665 &pfx_2001_b_s_64,
4666 FIB_SOURCE_API,
4667 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07004668 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004669 &nh_2001_2,
4670 tm->hw[0]->sw_if_index,
4671 ~0,
4672 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00004673 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004674 FIB_ROUTE_PATH_FLAG_NONE);
4675 fei = fib_table_lookup(fib_index, &pfx_2001_b_s_64);
4676 ai = fib_entry_get_adj(fei);
4677 FIB_TEST((ai_01 == ai), "2001::b/64 resolves via 2001:0:0:1::1");
4678
4679 /*
4680 * +2 entries, +1 shared path-list.
4681 */
4682 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
4683 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004684 FIB_TEST((PNPS+5 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004685 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004686 FIB_TEST((ENPS+6 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004687 fib_entry_pool_size());
4688
4689 /*
4690 * add a v4 prefix via a v6 next-hop
4691 */
4692 fib_prefix_t pfx_1_1_1_1_s_32 = {
4693 .fp_len = 32,
4694 .fp_proto = FIB_PROTOCOL_IP4,
4695 .fp_addr = {
4696 .ip4.as_u32 = 0x01010101,
4697 },
4698 };
4699 fei = fib_table_entry_path_add(0, // default table
4700 &pfx_1_1_1_1_s_32,
4701 FIB_SOURCE_API,
4702 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07004703 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004704 &nh_2001_2,
4705 tm->hw[0]->sw_if_index,
4706 ~0,
4707 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00004708 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004709 FIB_ROUTE_PATH_FLAG_NONE);
4710 FIB_TEST(fei == fib_table_lookup_exact_match(0, &pfx_1_1_1_1_s_32),
4711 "1.1.1.1/32 o v6 route present");
4712 ai = fib_entry_get_adj(fei);
4713 adj = adj_get(ai);
4714 FIB_TEST((adj->lookup_next_index == IP_LOOKUP_NEXT_ARP),
4715 "1.1.1.1/32 via ARP-adj");
Neale Ranns924d03a2016-10-19 08:25:46 +01004716 FIB_TEST((adj->ia_link == VNET_LINK_IP4),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004717 "1.1.1.1/32 ADJ-adj is link type v4");
4718 FIB_TEST((adj->ia_nh_proto == FIB_PROTOCOL_IP6),
4719 "1.1.1.1/32 ADJ-adj is NH proto v6");
4720 fib_table_entry_delete(0, &pfx_1_1_1_1_s_32, FIB_SOURCE_API);
4721
4722 /*
4723 * An attached route
4724 */
4725 fib_prefix_t pfx_2001_c_s_64 = {
4726 .fp_len = 64,
4727 .fp_proto = FIB_PROTOCOL_IP6,
4728 .fp_addr = {
4729 .ip6 = {
4730 .as_u64 = {
4731 [0] = clib_host_to_net_u64(0x200100000000000c),
4732 [1] = clib_host_to_net_u64(0x0000000000000000),
4733 },
4734 },
4735 }
4736 };
4737 fib_table_entry_path_add(fib_index,
4738 &pfx_2001_c_s_64,
4739 FIB_SOURCE_CLI,
4740 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07004741 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004742 NULL,
4743 tm->hw[0]->sw_if_index,
4744 ~0,
4745 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00004746 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004747 FIB_ROUTE_PATH_FLAG_NONE);
4748 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_c_s_64);
4749 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached route present");
4750 ai = fib_entry_get_adj(fei);
4751 adj = adj_get(ai);
4752 FIB_TEST((adj->lookup_next_index == IP_LOOKUP_NEXT_GLEAN),
4753 "2001:0:0:c/64 attached resolves via glean");
4754
4755 fib_table_entry_path_remove(fib_index,
4756 &pfx_2001_c_s_64,
4757 FIB_SOURCE_CLI,
Neale Rannsda78f952017-05-24 09:15:43 -07004758 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004759 NULL,
4760 tm->hw[0]->sw_if_index,
4761 ~0,
4762 1,
4763 FIB_ROUTE_PATH_FLAG_NONE);
4764 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_c_s_64);
4765 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "attached route removed");
4766
4767 /*
4768 * Shutdown the interface on which we have a connected and through
4769 * which the routes are reachable.
4770 * This will result in the connected, adj-fibs, and routes linking to drop
4771 * The local/for-us prefix continues to receive.
4772 */
4773 clib_error_t * error;
4774
4775 error = vnet_sw_interface_set_flags(vnet_get_main(),
4776 tm->hw[0]->sw_if_index,
4777 ~VNET_SW_INTERFACE_FLAG_ADMIN_UP);
4778 FIB_TEST((NULL == error), "Interface shutdown OK");
4779
4780 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
4781 dpo = fib_entry_contribute_ip_forwarding(fei);
4782 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4783 "2001::b/64 resolves via drop");
4784
4785 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
4786 dpo = fib_entry_contribute_ip_forwarding(fei);
4787 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4788 "2001::a/64 resolves via drop");
4789 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
4790 dpo = fib_entry_contribute_ip_forwarding(fei);
4791 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4792 "2001:0:0:1::3/64 resolves via drop");
4793 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
4794 dpo = fib_entry_contribute_ip_forwarding(fei);
4795 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4796 "2001:0:0:1::2/64 resolves via drop");
4797 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4798 dpo = fib_entry_contribute_ip_forwarding(fei);
4799 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4800 "2001:0:0:1::1/128 not drop");
4801 local_pfx.fp_len = 64;
4802 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4803 dpo = fib_entry_contribute_ip_forwarding(fei);
4804 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4805 "2001:0:0:1/64 resolves via drop");
4806
4807 /*
4808 * no change
4809 */
4810 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
4811 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004812 FIB_TEST((PNPS+5 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004813 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004814 FIB_TEST((ENPS+6 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004815 fib_entry_pool_size());
4816
4817 /*
4818 * shutdown one of the other interfaces, then add a connected.
4819 * and swap one of the routes to it.
4820 */
4821 error = vnet_sw_interface_set_flags(vnet_get_main(),
4822 tm->hw[1]->sw_if_index,
4823 ~VNET_SW_INTERFACE_FLAG_ADMIN_UP);
4824 FIB_TEST((NULL == error), "Interface 1 shutdown OK");
4825
4826 fib_prefix_t connected_pfx = {
4827 .fp_len = 64,
4828 .fp_proto = FIB_PROTOCOL_IP6,
4829 .fp_addr = {
4830 .ip6 = {
4831 /* 2001:0:0:2::1/64 */
4832 .as_u64 = {
4833 [0] = clib_host_to_net_u64(0x2001000000000002),
4834 [1] = clib_host_to_net_u64(0x0000000000000001),
4835 },
4836 },
4837 }
4838 };
4839 fib_table_entry_update_one_path(fib_index, &connected_pfx,
4840 FIB_SOURCE_INTERFACE,
4841 (FIB_ENTRY_FLAG_CONNECTED |
4842 FIB_ENTRY_FLAG_ATTACHED),
Neale Rannsda78f952017-05-24 09:15:43 -07004843 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004844 NULL,
4845 tm->hw[1]->sw_if_index,
4846 ~0,
4847 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00004848 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004849 FIB_ROUTE_PATH_FLAG_NONE);
4850 fei = fib_table_lookup_exact_match(fib_index, &connected_pfx);
4851 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached interface route present");
4852 dpo = fib_entry_contribute_ip_forwarding(fei);
4853 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
4854 FIB_TEST(!dpo_cmp(dpo, dpo_drop),
4855 "2001:0:0:2/64 not resolves via drop");
4856
4857 connected_pfx.fp_len = 128;
4858 fib_table_entry_update_one_path(fib_index, &connected_pfx,
4859 FIB_SOURCE_INTERFACE,
4860 (FIB_ENTRY_FLAG_CONNECTED |
4861 FIB_ENTRY_FLAG_LOCAL),
Neale Rannsda78f952017-05-24 09:15:43 -07004862 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004863 NULL,
4864 tm->hw[0]->sw_if_index,
4865 ~0, // invalid fib index
4866 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00004867 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004868 FIB_ROUTE_PATH_FLAG_NONE);
4869 fei = fib_table_lookup(fib_index, &connected_pfx);
4870
4871 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local interface route present");
4872 dpo = fib_entry_contribute_ip_forwarding(fei);
4873 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
4874 FIB_TEST((DPO_RECEIVE == dpo->dpoi_type),
4875 "local interface adj is local");
4876 rd = receive_dpo_get(dpo->dpoi_index);
4877 FIB_TEST((0 == ip46_address_cmp(&connected_pfx.fp_addr,
4878 &rd->rd_addr)),
4879 "local interface adj is receive ok");
4880
4881 /*
4882 * +2 entries, +2 unshared path-lists
4883 */
4884 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
4885 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004886 FIB_TEST((PNPS+7 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004887 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004888 FIB_TEST((ENPS+8 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004889 fib_entry_pool_size());
4890
4891
4892 /*
4893 * bring the interface back up. we expected the routes to return
4894 * to normal forwarding.
4895 */
4896 error = vnet_sw_interface_set_flags(vnet_get_main(),
4897 tm->hw[0]->sw_if_index,
4898 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
4899 FIB_TEST((NULL == error), "Interface bring-up OK");
4900 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
4901 ai = fib_entry_get_adj(fei);
4902 FIB_TEST((ai_01 == ai), "2001::a/64 resolves via 2001:0:0:1::1");
4903 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
4904 ai = fib_entry_get_adj(fei);
4905 FIB_TEST((ai_01 == ai), "2001::b/64 resolves via 2001:0:0:1::1");
4906 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
4907 ai = fib_entry_get_adj(fei);
4908 FIB_TEST((ai_02 == ai), "ADJ-FIB resolves via adj");
4909 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
4910 ai = fib_entry_get_adj(fei);
4911 FIB_TEST((ai_01 == ai), "ADJ-FIB resolves via adj");
4912 local_pfx.fp_len = 64;
4913 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4914 ai = fib_entry_get_adj(fei);
4915 adj = adj_get(ai);
4916 FIB_TEST((IP_LOOKUP_NEXT_GLEAN == adj->lookup_next_index),
4917 "attached interface adj is glean");
4918
4919 /*
Neale Ranns8b37b872016-11-21 12:25:22 +00004920 * Same test as above, but this time the HW interface goes down
4921 */
4922 error = vnet_hw_interface_set_flags(vnet_get_main(),
4923 tm->hw_if_indicies[0],
4924 ~VNET_HW_INTERFACE_FLAG_LINK_UP);
4925 FIB_TEST((NULL == error), "Interface shutdown OK");
4926
4927 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
4928 dpo = fib_entry_contribute_ip_forwarding(fei);
4929 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4930 "2001::b/64 resolves via drop");
4931 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
4932 dpo = fib_entry_contribute_ip_forwarding(fei);
4933 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4934 "2001::a/64 resolves via drop");
4935 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
4936 dpo = fib_entry_contribute_ip_forwarding(fei);
4937 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4938 "2001:0:0:1::3/128 resolves via drop");
4939 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
4940 dpo = fib_entry_contribute_ip_forwarding(fei);
4941 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4942 "2001:0:0:1::2/128 resolves via drop");
4943 local_pfx.fp_len = 128;
4944 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4945 dpo = fib_entry_contribute_ip_forwarding(fei);
4946 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4947 "2001:0:0:1::1/128 not drop");
4948 local_pfx.fp_len = 64;
4949 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4950 dpo = fib_entry_contribute_ip_forwarding(fei);
4951 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4952 "2001:0:0:1/64 resolves via drop");
4953
4954 error = vnet_hw_interface_set_flags(vnet_get_main(),
4955 tm->hw_if_indicies[0],
4956 VNET_HW_INTERFACE_FLAG_LINK_UP);
4957 FIB_TEST((NULL == error), "Interface bring-up OK");
4958 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
4959 ai = fib_entry_get_adj(fei);
4960 FIB_TEST((ai_01 == ai), "2001::a/64 resolves via 2001:0:0:1::1");
4961 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
4962 ai = fib_entry_get_adj(fei);
4963 FIB_TEST((ai_01 == ai), "2001::b/64 resolves via 2001:0:0:1::1");
4964 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
4965 ai = fib_entry_get_adj(fei);
4966 FIB_TEST((ai_02 == ai), "ADJ-FIB resolves via adj");
4967 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
4968 ai = fib_entry_get_adj(fei);
4969 FIB_TEST((ai_01 == ai), "ADJ-FIB resolves via adj");
4970 local_pfx.fp_len = 64;
4971 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4972 ai = fib_entry_get_adj(fei);
4973 adj = adj_get(ai);
4974 FIB_TEST((IP_LOOKUP_NEXT_GLEAN == adj->lookup_next_index),
4975 "attached interface adj is glean");
4976
4977 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004978 * Delete the interface that the routes reolve through.
4979 * Again no routes are removed. They all point to drop.
4980 *
4981 * This is considered an error case. The control plane should
4982 * not remove interfaces through which routes resolve, but
4983 * such things can happen. ALL affected routes will drop.
4984 */
4985 vnet_delete_hw_interface(vnet_get_main(), tm->hw_if_indicies[0]);
4986
4987 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
4988 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
4989 "2001::b/64 resolves via drop");
4990 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
4991 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
4992 "2001::b/64 resolves via drop");
4993 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
4994 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
4995 "2001:0:0:1::3/64 resolves via drop");
4996 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
4997 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
4998 "2001:0:0:1::2/64 resolves via drop");
4999 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5000 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5001 "2001:0:0:1::1/128 is drop");
5002 local_pfx.fp_len = 64;
5003 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5004 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5005 "2001:0:0:1/64 resolves via drop");
5006
5007 /*
5008 * no change
5009 */
5010 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
5011 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00005012 FIB_TEST((PNPS+7 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005013 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00005014 FIB_TEST((ENPS+8 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005015 fib_entry_pool_size());
5016
5017 /*
5018 * Add the interface back. routes stay unresolved.
5019 */
5020 error = ethernet_register_interface(vnet_get_main(),
5021 test_interface_device_class.index,
5022 0 /* instance */,
5023 hw_address,
5024 &tm->hw_if_indicies[0],
5025 /* flag change */ 0);
5026
5027 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
5028 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5029 "2001::b/64 resolves via drop");
5030 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
5031 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5032 "2001::b/64 resolves via drop");
5033 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
5034 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5035 "2001:0:0:1::3/64 resolves via drop");
5036 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
5037 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5038 "2001:0:0:1::2/64 resolves via drop");
5039 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5040 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5041 "2001:0:0:1::1/128 is drop");
5042 local_pfx.fp_len = 64;
5043 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5044 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5045 "2001:0:0:1/64 resolves via drop");
5046
5047 /*
5048 * CLEANUP ALL the routes
5049 */
5050 fib_table_entry_delete(fib_index,
5051 &pfx_2001_c_s_64,
5052 FIB_SOURCE_API);
5053 fib_table_entry_delete(fib_index,
5054 &pfx_2001_a_s_64,
5055 FIB_SOURCE_API);
5056 fib_table_entry_delete(fib_index,
5057 &pfx_2001_b_s_64,
5058 FIB_SOURCE_API);
5059 fib_table_entry_delete(fib_index,
5060 &pfx_2001_1_3_s_128,
5061 FIB_SOURCE_ADJ);
5062 fib_table_entry_delete(fib_index,
5063 &pfx_2001_1_2_s_128,
5064 FIB_SOURCE_ADJ);
5065 local_pfx.fp_len = 64;
5066 fib_table_entry_delete(fib_index, &local_pfx,
5067 FIB_SOURCE_INTERFACE);
5068 local_pfx.fp_len = 128;
5069 fib_table_entry_special_remove(fib_index, &local_pfx,
5070 FIB_SOURCE_INTERFACE);
5071 connected_pfx.fp_len = 64;
5072 fib_table_entry_delete(fib_index, &connected_pfx,
5073 FIB_SOURCE_INTERFACE);
5074 connected_pfx.fp_len = 128;
5075 fib_table_entry_special_remove(fib_index, &connected_pfx,
5076 FIB_SOURCE_INTERFACE);
5077
5078 FIB_TEST((FIB_NODE_INDEX_INVALID ==
5079 fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64)),
5080 "2001::a/64 removed");
5081 FIB_TEST((FIB_NODE_INDEX_INVALID ==
5082 fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64)),
5083 "2001::b/64 removed");
5084 FIB_TEST((FIB_NODE_INDEX_INVALID ==
5085 fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128)),
5086 "2001:0:0:1::3/128 removed");
5087 FIB_TEST((FIB_NODE_INDEX_INVALID ==
5088 fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128)),
5089 "2001:0:0:1::3/128 removed");
5090 local_pfx.fp_len = 64;
5091 FIB_TEST((FIB_NODE_INDEX_INVALID ==
5092 fib_table_lookup_exact_match(fib_index, &local_pfx)),
5093 "2001:0:0:1/64 removed");
5094 local_pfx.fp_len = 128;
5095 FIB_TEST((FIB_NODE_INDEX_INVALID ==
5096 fib_table_lookup_exact_match(fib_index, &local_pfx)),
5097 "2001:0:0:1::1/128 removed");
5098 connected_pfx.fp_len = 64;
5099 FIB_TEST((FIB_NODE_INDEX_INVALID ==
5100 fib_table_lookup_exact_match(fib_index, &connected_pfx)),
5101 "2001:0:0:2/64 removed");
5102 connected_pfx.fp_len = 128;
5103 FIB_TEST((FIB_NODE_INDEX_INVALID ==
5104 fib_table_lookup_exact_match(fib_index, &connected_pfx)),
5105 "2001:0:0:2::1/128 removed");
5106
5107 /*
5108 * -8 entries. -7 path-lists (1 was shared).
5109 */
5110 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
5111 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00005112 FIB_TEST((PNPS == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005113 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00005114 FIB_TEST((ENPS == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005115 fib_entry_pool_size());
5116
5117 /*
5118 * now remove the VRF
5119 */
Neale Ranns15002542017-09-10 04:39:11 -07005120 fib_table_unlock(fib_index, FIB_PROTOCOL_IP6, FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005121
5122 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
5123 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00005124 FIB_TEST((PNPS-2 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005125 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00005126 FIB_TEST((ENPS-2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005127 fib_entry_pool_size());
5128
5129 adj_unlock(ai_02);
5130 adj_unlock(ai_01);
5131
5132 /*
5133 * return the interfaces to up state
5134 */
5135 error = vnet_sw_interface_set_flags(vnet_get_main(),
5136 tm->hw[0]->sw_if_index,
5137 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
5138 error = vnet_sw_interface_set_flags(vnet_get_main(),
5139 tm->hw[1]->sw_if_index,
5140 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
5141
5142 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
5143 adj_nbr_db_size());
Neale Ranns0ebe8d72016-12-08 19:48:11 +00005144
5145 return (0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005146}
5147
5148/*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005149 * Test Attached Exports
5150 */
Neale Ranns0ebe8d72016-12-08 19:48:11 +00005151static int
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005152fib_test_ae (void)
5153{
5154 const dpo_id_t *dpo, *dpo_drop;
5155 const u32 fib_index = 0;
5156 fib_node_index_t fei;
5157 test_main_t *tm;
5158 ip4_main_t *im;
5159
5160 tm = &test_main;
5161 im = &ip4_main;
5162
5163 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
5164 adj_nbr_db_size());
5165
5166 /*
5167 * add interface routes. We'll assume this works. It's more rigorously
5168 * tested elsewhere.
5169 */
5170 fib_prefix_t local_pfx = {
5171 .fp_len = 24,
5172 .fp_proto = FIB_PROTOCOL_IP4,
5173 .fp_addr = {
5174 .ip4 = {
5175 /* 10.10.10.10 */
5176 .as_u32 = clib_host_to_net_u32(0x0a0a0a0a),
5177 },
5178 },
5179 };
5180
5181 vec_validate(im->fib_index_by_sw_if_index, tm->hw[0]->sw_if_index);
5182 im->fib_index_by_sw_if_index[tm->hw[0]->sw_if_index] = fib_index;
5183
5184 dpo_drop = drop_dpo_get(DPO_PROTO_IP4);
5185
5186 fib_table_entry_update_one_path(fib_index, &local_pfx,
5187 FIB_SOURCE_INTERFACE,
5188 (FIB_ENTRY_FLAG_CONNECTED |
5189 FIB_ENTRY_FLAG_ATTACHED),
Neale Rannsda78f952017-05-24 09:15:43 -07005190 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005191 NULL,
5192 tm->hw[0]->sw_if_index,
5193 ~0,
5194 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005195 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005196 FIB_ROUTE_PATH_FLAG_NONE);
5197 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5198 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
5199 "attached interface route present");
5200
5201 local_pfx.fp_len = 32;
5202 fib_table_entry_update_one_path(fib_index, &local_pfx,
5203 FIB_SOURCE_INTERFACE,
5204 (FIB_ENTRY_FLAG_CONNECTED |
5205 FIB_ENTRY_FLAG_LOCAL),
Neale Rannsda78f952017-05-24 09:15:43 -07005206 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005207 NULL,
5208 tm->hw[0]->sw_if_index,
5209 ~0, // invalid fib index
5210 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005211 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005212 FIB_ROUTE_PATH_FLAG_NONE);
5213 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5214
5215 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
5216 "local interface route present");
5217
5218 /*
5219 * Add an 2 ARP entry => a complete ADJ plus adj-fib.
5220 */
5221 fib_prefix_t pfx_10_10_10_1_s_32 = {
5222 .fp_len = 32,
5223 .fp_proto = FIB_PROTOCOL_IP4,
5224 .fp_addr = {
5225 /* 10.10.10.1 */
5226 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
5227 },
5228 };
5229 fib_node_index_t ai;
5230
Neale Ranns81424992017-05-18 03:03:22 -07005231 fib_table_entry_path_add(fib_index,
5232 &pfx_10_10_10_1_s_32,
5233 FIB_SOURCE_ADJ,
5234 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07005235 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07005236 &pfx_10_10_10_1_s_32.fp_addr,
5237 tm->hw[0]->sw_if_index,
5238 ~0, // invalid fib index
5239 1,
5240 NULL,
5241 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005242
5243 fei = fib_table_lookup(fib_index, &pfx_10_10_10_1_s_32);
5244 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 created");
5245 ai = fib_entry_get_adj(fei);
5246
5247 /*
5248 * create another FIB table into which routes will be imported
5249 */
5250 u32 import_fib_index1;
5251
Neale Ranns15002542017-09-10 04:39:11 -07005252 import_fib_index1 = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP4,
5253 11,
5254 FIB_SOURCE_CLI);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005255
5256 /*
5257 * Add an attached route in the import FIB
5258 */
5259 local_pfx.fp_len = 24;
5260 fib_table_entry_update_one_path(import_fib_index1,
5261 &local_pfx,
5262 FIB_SOURCE_API,
5263 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07005264 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005265 NULL,
5266 tm->hw[0]->sw_if_index,
5267 ~0, // invalid fib index
5268 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005269 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005270 FIB_ROUTE_PATH_FLAG_NONE);
5271 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5272 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached export created");
5273
5274 /*
5275 * check for the presence of the adj-fibs in the import table
5276 */
5277 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5278 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 imported");
5279 FIB_TEST((ai == fib_entry_get_adj(fei)),
5280 "adj-fib1 Import uses same adj as export");
5281
5282 /*
5283 * check for the presence of the local in the import table
5284 */
5285 local_pfx.fp_len = 32;
5286 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5287 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local imported");
5288
5289 /*
5290 * Add another adj-fin in the export table. Expect this
5291 * to get magically exported;
5292 */
5293 fib_prefix_t pfx_10_10_10_2_s_32 = {
5294 .fp_len = 32,
5295 .fp_proto = FIB_PROTOCOL_IP4,
5296 .fp_addr = {
5297 /* 10.10.10.2 */
5298 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02),
5299 },
5300 };
5301
Neale Ranns81424992017-05-18 03:03:22 -07005302 fib_table_entry_path_add(fib_index,
5303 &pfx_10_10_10_2_s_32,
5304 FIB_SOURCE_ADJ,
5305 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07005306 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07005307 &pfx_10_10_10_2_s_32.fp_addr,
5308 tm->hw[0]->sw_if_index,
5309 ~0, // invalid fib index
5310 1,
5311 NULL,
5312 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005313 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_2_s_32);
5314 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 present");
5315 ai = fib_entry_get_adj(fei);
5316
5317 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5318 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 imported");
5319 FIB_TEST((ai == fib_entry_get_adj(fei)),
5320 "Import uses same adj as export");
Neale Rannsfa0fb582016-12-10 21:59:14 +00005321 FIB_TEST((FIB_ENTRY_FLAG_ATTACHED & fib_entry_get_flags(fei)),
5322 "ADJ-fib2 imported flags %d",
5323 fib_entry_get_flags(fei));
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005324
5325 /*
5326 * create a 2nd FIB table into which routes will be imported
5327 */
5328 u32 import_fib_index2;
5329
Neale Ranns15002542017-09-10 04:39:11 -07005330 import_fib_index2 = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP4, 12,
5331 FIB_SOURCE_CLI);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005332
5333 /*
5334 * Add an attached route in the import FIB
5335 */
5336 local_pfx.fp_len = 24;
5337 fib_table_entry_update_one_path(import_fib_index2,
5338 &local_pfx,
5339 FIB_SOURCE_API,
5340 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07005341 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005342 NULL,
5343 tm->hw[0]->sw_if_index,
5344 ~0, // invalid fib index
5345 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005346 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005347 FIB_ROUTE_PATH_FLAG_NONE);
5348 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5349 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached export created");
5350
5351 /*
5352 * check for the presence of all the adj-fibs and local in the import table
5353 */
5354 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_1_s_32);
5355 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 imported");
5356 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_2_s_32);
5357 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 imported");
5358 local_pfx.fp_len = 32;
5359 fei = fib_table_lookup_exact_match(import_fib_index2, &local_pfx);
5360 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local imported");
5361
5362 /*
5363 * add a 3rd adj-fib. expect it to be exported to both tables.
5364 */
5365 fib_prefix_t pfx_10_10_10_3_s_32 = {
5366 .fp_len = 32,
5367 .fp_proto = FIB_PROTOCOL_IP4,
5368 .fp_addr = {
5369 /* 10.10.10.3 */
5370 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a03),
5371 },
5372 };
5373
Neale Ranns81424992017-05-18 03:03:22 -07005374 fib_table_entry_path_add(fib_index,
5375 &pfx_10_10_10_3_s_32,
5376 FIB_SOURCE_ADJ,
5377 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07005378 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07005379 &pfx_10_10_10_3_s_32.fp_addr,
5380 tm->hw[0]->sw_if_index,
5381 ~0, // invalid fib index
5382 1,
5383 NULL,
5384 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005385 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_3_s_32);
5386 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib3 present");
5387 ai = fib_entry_get_adj(fei);
5388
5389 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_3_s_32);
5390 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib3 imported to FIB1");
5391 FIB_TEST((ai == fib_entry_get_adj(fei)),
5392 "Import uses same adj as export");
5393 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_3_s_32);
5394 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib3 imported to FIB2");
5395 FIB_TEST((ai == fib_entry_get_adj(fei)),
5396 "Import uses same adj as export");
5397
5398 /*
5399 * remove the 3rd adj fib. we expect it to be removed from both FIBs
5400 */
5401 fib_table_entry_delete(fib_index,
5402 &pfx_10_10_10_3_s_32,
5403 FIB_SOURCE_ADJ);
5404
5405 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_3_s_32);
5406 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib3 remved");
5407
5408 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_3_s_32);
5409 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib3 removed from FIB1");
5410
5411 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_3_s_32);
5412 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib3 removed from FIB2");
5413
5414 /*
5415 * remove the attached route from the 2nd FIB. expect the imported
5416 * entires to be removed
5417 */
5418 local_pfx.fp_len = 24;
5419 fib_table_entry_delete(import_fib_index2,
5420 &local_pfx,
5421 FIB_SOURCE_API);
5422 fei = fib_table_lookup_exact_match(import_fib_index2, &local_pfx);
5423 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "attached export removed");
5424
5425 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_1_s_32);
5426 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib1 removed from FIB2");
5427 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_2_s_32);
5428 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib2 removed from FIB2");
5429 local_pfx.fp_len = 32;
5430 fei = fib_table_lookup_exact_match(import_fib_index2, &local_pfx);
5431 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "local removed from FIB2");
5432
5433 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5434 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 still in FIB1");
5435 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5436 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 still in FIB1");
5437 local_pfx.fp_len = 32;
5438 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5439 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local still in FIB1");
5440
5441 /*
5442 * modify the route in FIB1 so it is no longer attached. expect the imported
5443 * entires to be removed
5444 */
5445 local_pfx.fp_len = 24;
5446 fib_table_entry_update_one_path(import_fib_index1,
5447 &local_pfx,
5448 FIB_SOURCE_API,
5449 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07005450 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005451 &pfx_10_10_10_2_s_32.fp_addr,
5452 tm->hw[0]->sw_if_index,
5453 ~0, // invalid fib index
5454 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005455 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005456 FIB_ROUTE_PATH_FLAG_NONE);
5457 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5458 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib1 removed from FIB1");
5459 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5460 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib2 removed from FIB1");
5461 local_pfx.fp_len = 32;
5462 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5463 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "local removed from FIB1");
5464
5465 /*
5466 * modify it back to attached. expect the adj-fibs back
5467 */
5468 local_pfx.fp_len = 24;
5469 fib_table_entry_update_one_path(import_fib_index1,
5470 &local_pfx,
5471 FIB_SOURCE_API,
5472 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07005473 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005474 NULL,
5475 tm->hw[0]->sw_if_index,
5476 ~0, // invalid fib index
5477 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005478 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005479 FIB_ROUTE_PATH_FLAG_NONE);
5480 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5481 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 imported in FIB1");
5482 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5483 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 imported in FIB1");
5484 local_pfx.fp_len = 32;
5485 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5486 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local imported in FIB1");
5487
5488 /*
5489 * add a covering attached next-hop for the interface address, so we have
5490 * a valid adj to find when we check the forwarding tables
5491 */
5492 fib_prefix_t pfx_10_0_0_0_s_8 = {
5493 .fp_len = 8,
5494 .fp_proto = FIB_PROTOCOL_IP4,
5495 .fp_addr = {
5496 /* 10.0.0.0 */
5497 .ip4.as_u32 = clib_host_to_net_u32(0x0a000000),
5498 },
5499 };
5500
5501 fei = fib_table_entry_update_one_path(fib_index,
5502 &pfx_10_0_0_0_s_8,
5503 FIB_SOURCE_API,
5504 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07005505 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005506 &pfx_10_10_10_3_s_32.fp_addr,
5507 tm->hw[0]->sw_if_index,
5508 ~0, // invalid fib index
5509 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005510 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005511 FIB_ROUTE_PATH_FLAG_NONE);
5512 dpo = fib_entry_contribute_ip_forwarding(fei);
5513
5514 /*
5515 * remove the route in the export fib. expect the adj-fibs to be removed
5516 */
5517 local_pfx.fp_len = 24;
5518 fib_table_entry_delete(fib_index,
5519 &local_pfx,
5520 FIB_SOURCE_INTERFACE);
5521
5522 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5523 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "Delete export: ADJ-fib1 removed from FIB1");
5524 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5525 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib2 removed from FIB1");
5526 local_pfx.fp_len = 32;
5527 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5528 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "local removed from FIB1");
5529
5530 /*
5531 * the adj-fibs in the export VRF are present in the FIB table,
5532 * but not installed in forwarding, since they have no attached cover.
5533 * Consequently a lookup in the MTRIE gives the adj for the covering
5534 * route 10.0.0.0/8.
5535 */
5536 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
5537 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 in export");
5538
5539 index_t lbi;
5540 lbi = ip4_fib_forwarding_lookup(fib_index, &pfx_10_10_10_1_s_32.fp_addr.ip4);
5541 FIB_TEST(lbi == dpo->dpoi_index,
5542 "10.10.10.1 forwards on \n%U not \n%U",
5543 format_load_balance, lbi, 0,
5544 format_dpo_id, dpo, 0);
5545 lbi = ip4_fib_forwarding_lookup(fib_index, &pfx_10_10_10_2_s_32.fp_addr.ip4);
5546 FIB_TEST(lbi == dpo->dpoi_index,
5547 "10.10.10.2 forwards on %U", format_dpo_id, dpo, 0);
5548 lbi = ip4_fib_forwarding_lookup(fib_index, &pfx_10_10_10_3_s_32.fp_addr.ip4);
5549 FIB_TEST(lbi == dpo->dpoi_index,
5550 "10.10.10.3 forwards on %U", format_dpo_id, dpo, 0);
5551
5552 /*
5553 * add the export prefix back, but not as attached.
5554 * No adj-fibs in export nor import tables
5555 */
5556 local_pfx.fp_len = 24;
5557 fei = fib_table_entry_update_one_path(fib_index,
5558 &local_pfx,
5559 FIB_SOURCE_API,
5560 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07005561 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005562 &pfx_10_10_10_1_s_32.fp_addr,
5563 tm->hw[0]->sw_if_index,
5564 ~0, // invalid fib index
5565 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005566 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005567 FIB_ROUTE_PATH_FLAG_NONE);
5568 dpo = fib_entry_contribute_ip_forwarding(fei);
5569
5570 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
5571 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "non-attached in export: ADJ-fib1 in export");
5572 lbi = ip4_fib_forwarding_lookup(fib_index, &pfx_10_10_10_1_s_32.fp_addr.ip4);
5573 FIB_TEST(lbi == dpo->dpoi_index,
5574 "10.10.10.1 forwards on %U", format_dpo_id, dpo, 0);
5575 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
5576 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 in export");
5577 lbi = ip4_fib_forwarding_lookup(fib_index, &pfx_10_10_10_2_s_32.fp_addr.ip4);
5578 FIB_TEST(lbi == dpo->dpoi_index,
5579 "10.10.10.2 forwards on %U", format_dpo_id, dpo, 0);
5580
5581 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5582 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib1 removed from FIB1");
5583 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5584 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib2 removed from FIB1");
5585 local_pfx.fp_len = 32;
5586 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5587 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "local removed from FIB1");
5588
5589 /*
5590 * modify the export prefix so it is attached. expect all covereds to return
5591 */
5592 local_pfx.fp_len = 24;
5593 fib_table_entry_update_one_path(fib_index,
5594 &local_pfx,
5595 FIB_SOURCE_API,
5596 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07005597 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005598 NULL,
5599 tm->hw[0]->sw_if_index,
5600 ~0, // invalid fib index
5601 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005602 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005603 FIB_ROUTE_PATH_FLAG_NONE);
5604
5605 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
5606 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 reinstalled in export");
5607 dpo = fib_entry_contribute_ip_forwarding(fei);
5608 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
5609 "Adj-fib1 is not drop in export");
5610 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_2_s_32);
5611 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 reinstalled in export");
5612 local_pfx.fp_len = 32;
5613 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5614 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local reinstalled in export");
5615 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5616 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached in export: ADJ-fib1 imported");
5617 dpo = fib_entry_contribute_ip_forwarding(fei);
5618 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
5619 "Adj-fib1 is not drop in export");
5620 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5621 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 imported");
5622 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5623 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 imported");
5624 local_pfx.fp_len = 32;
5625 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5626 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local imported");
5627
5628 /*
5629 * modify the export prefix so connected. no change.
5630 */
5631 local_pfx.fp_len = 24;
5632 fib_table_entry_update_one_path(fib_index, &local_pfx,
5633 FIB_SOURCE_INTERFACE,
5634 (FIB_ENTRY_FLAG_CONNECTED |
5635 FIB_ENTRY_FLAG_ATTACHED),
Neale Rannsda78f952017-05-24 09:15:43 -07005636 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005637 NULL,
5638 tm->hw[0]->sw_if_index,
5639 ~0,
5640 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005641 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005642 FIB_ROUTE_PATH_FLAG_NONE);
5643
5644 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
5645 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 reinstalled in export");
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(fib_index, &pfx_10_10_10_2_s_32);
5650 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 reinstalled in export");
5651 local_pfx.fp_len = 32;
5652 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5653 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local reinstalled in export");
5654 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5655 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached in export: ADJ-fib1 imported");
5656 dpo = fib_entry_contribute_ip_forwarding(fei);
5657 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
5658 "Adj-fib1 is not drop in export");
5659 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5660 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 imported");
5661 local_pfx.fp_len = 32;
5662 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5663 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local imported");
5664
5665 /*
5666 * CLEANUP
5667 */
5668 fib_table_entry_delete(fib_index,
5669 &pfx_10_0_0_0_s_8,
5670 FIB_SOURCE_API);
5671 fib_table_entry_delete(fib_index,
5672 &pfx_10_10_10_1_s_32,
5673 FIB_SOURCE_ADJ);
5674 fib_table_entry_delete(fib_index,
5675 &pfx_10_10_10_2_s_32,
5676 FIB_SOURCE_ADJ);
5677 local_pfx.fp_len = 32;
5678 fib_table_entry_delete(fib_index,
5679 &local_pfx,
5680 FIB_SOURCE_INTERFACE);
5681 local_pfx.fp_len = 24;
5682 fib_table_entry_delete(fib_index,
5683 &local_pfx,
5684 FIB_SOURCE_API);
5685 fib_table_entry_delete(fib_index,
5686 &local_pfx,
5687 FIB_SOURCE_INTERFACE);
5688 local_pfx.fp_len = 24;
5689 fib_table_entry_delete(import_fib_index1,
5690 &local_pfx,
5691 FIB_SOURCE_API);
5692
Neale Ranns15002542017-09-10 04:39:11 -07005693 fib_table_unlock(import_fib_index1, FIB_PROTOCOL_IP4, FIB_SOURCE_CLI);
5694 fib_table_unlock(import_fib_index2, FIB_PROTOCOL_IP4, FIB_SOURCE_CLI);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005695
5696 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
5697 adj_nbr_db_size());
Neale Ranns0ebe8d72016-12-08 19:48:11 +00005698
5699 return (0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005700}
5701
Neale Ranns57b58602017-07-15 07:37:25 -07005702/*
5703 * Test Path Preference
5704 */
5705static int
5706fib_test_pref (void)
5707{
5708 test_main_t *tm = &test_main;
5709
5710 const fib_prefix_t pfx_1_1_1_1_s_32 = {
5711 .fp_len = 32,
5712 .fp_proto = FIB_PROTOCOL_IP4,
5713 .fp_addr = {
5714 .ip4 = {
5715 .as_u32 = clib_host_to_net_u32(0x01010101),
5716 },
5717 },
5718 };
5719
5720 /*
5721 * 2 high, 2 medium and 2 low preference non-recursive paths
5722 */
5723 fib_route_path_t nr_path_hi_1 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005724 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005725 .frp_sw_if_index = tm->hw[0]->sw_if_index,
5726 .frp_fib_index = ~0,
5727 .frp_weight = 1,
5728 .frp_preference = 0,
5729 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5730 .frp_addr = {
5731 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
5732 },
5733 };
5734 fib_route_path_t nr_path_hi_2 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005735 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005736 .frp_sw_if_index = tm->hw[0]->sw_if_index,
5737 .frp_fib_index = ~0,
5738 .frp_weight = 1,
5739 .frp_preference = 0,
5740 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5741 .frp_addr = {
5742 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02),
5743 },
5744 };
5745 fib_route_path_t nr_path_med_1 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005746 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005747 .frp_sw_if_index = tm->hw[1]->sw_if_index,
5748 .frp_fib_index = ~0,
5749 .frp_weight = 1,
5750 .frp_preference = 1,
5751 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5752 .frp_addr = {
5753 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0c01),
5754 },
5755 };
5756 fib_route_path_t nr_path_med_2 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005757 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005758 .frp_sw_if_index = tm->hw[1]->sw_if_index,
5759 .frp_fib_index = ~0,
5760 .frp_weight = 1,
5761 .frp_preference = 1,
5762 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5763 .frp_addr = {
5764 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0c01),
5765 },
5766 };
5767 fib_route_path_t nr_path_low_1 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005768 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005769 .frp_sw_if_index = tm->hw[2]->sw_if_index,
5770 .frp_fib_index = ~0,
5771 .frp_weight = 1,
5772 .frp_preference = 2,
5773 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5774 .frp_addr = {
5775 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0b01),
5776 },
5777 };
5778 fib_route_path_t nr_path_low_2 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005779 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005780 .frp_sw_if_index = tm->hw[2]->sw_if_index,
5781 .frp_fib_index = ~0,
5782 .frp_weight = 1,
5783 .frp_preference = 2,
5784 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5785 .frp_addr = {
5786 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0b02),
5787 },
5788 };
5789 fib_route_path_t *nr_paths = NULL;
5790
5791 vec_add1(nr_paths, nr_path_hi_1);
5792 vec_add1(nr_paths, nr_path_hi_2);
5793 vec_add1(nr_paths, nr_path_med_1);
5794 vec_add1(nr_paths, nr_path_med_2);
5795 vec_add1(nr_paths, nr_path_low_1);
5796 vec_add1(nr_paths, nr_path_low_2);
5797
5798 adj_index_t ai_hi_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5799 VNET_LINK_IP4,
5800 &nr_path_hi_1.frp_addr,
5801 nr_path_hi_1.frp_sw_if_index);
5802 adj_index_t ai_hi_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5803 VNET_LINK_IP4,
5804 &nr_path_hi_2.frp_addr,
5805 nr_path_hi_2.frp_sw_if_index);
5806 adj_index_t ai_med_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5807 VNET_LINK_IP4,
5808 &nr_path_med_1.frp_addr,
5809 nr_path_med_1.frp_sw_if_index);
5810 adj_index_t ai_med_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5811 VNET_LINK_IP4,
5812 &nr_path_med_2.frp_addr,
5813 nr_path_med_2.frp_sw_if_index);
5814 adj_index_t ai_low_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5815 VNET_LINK_IP4,
5816 &nr_path_low_1.frp_addr,
5817 nr_path_low_1.frp_sw_if_index);
5818 adj_index_t ai_low_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5819 VNET_LINK_IP4,
5820 &nr_path_low_2.frp_addr,
5821 nr_path_low_2.frp_sw_if_index);
5822
5823 fib_test_lb_bucket_t ip_hi_1 = {
5824 .type = FT_LB_ADJ,
5825 .adj = {
5826 .adj = ai_hi_1,
5827 },
5828 };
5829 fib_test_lb_bucket_t ip_hi_2 = {
5830 .type = FT_LB_ADJ,
5831 .adj = {
5832 .adj = ai_hi_2,
5833 },
5834 };
5835 fib_test_lb_bucket_t ip_med_1 = {
5836 .type = FT_LB_ADJ,
5837 .adj = {
5838 .adj = ai_med_1,
5839 },
5840 };
5841 fib_test_lb_bucket_t ip_med_2 = {
5842 .type = FT_LB_ADJ,
5843 .adj = {
5844 .adj = ai_med_2,
5845 },
5846 };
5847 fib_test_lb_bucket_t ip_low_1 = {
5848 .type = FT_LB_ADJ,
5849 .adj = {
5850 .adj = ai_low_1,
5851 },
5852 };
5853 fib_test_lb_bucket_t ip_low_2 = {
5854 .type = FT_LB_ADJ,
5855 .adj = {
5856 .adj = ai_low_2,
5857 },
5858 };
5859
5860 fib_node_index_t fei;
5861
5862 fei = fib_table_entry_path_add2(0,
5863 &pfx_1_1_1_1_s_32,
5864 FIB_SOURCE_API,
5865 FIB_ENTRY_FLAG_NONE,
5866 nr_paths);
5867
5868 FIB_TEST(fib_test_validate_entry(fei,
5869 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5870 2,
5871 &ip_hi_1,
5872 &ip_hi_2),
5873 "1.1.1.1/32 via high preference paths");
5874
5875 /*
5876 * bring down the interface on which the high preference path lie
5877 */
5878 vnet_sw_interface_set_flags(vnet_get_main(),
5879 tm->hw[0]->sw_if_index,
5880 0);
5881
5882 FIB_TEST(fib_test_validate_entry(fei,
5883 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5884 2,
5885 &ip_med_1,
5886 &ip_med_2),
5887 "1.1.1.1/32 via medium preference paths");
5888
5889 /*
5890 * bring down the interface on which the medium preference path lie
5891 */
5892 vnet_sw_interface_set_flags(vnet_get_main(),
5893 tm->hw[1]->sw_if_index,
5894 0);
5895
5896 FIB_TEST(fib_test_validate_entry(fei,
5897 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5898 2,
5899 &ip_low_1,
5900 &ip_low_2),
5901 "1.1.1.1/32 via low preference paths");
5902
5903 /*
5904 * bring up the interface on which the high preference path lie
5905 */
5906 vnet_sw_interface_set_flags(vnet_get_main(),
5907 tm->hw[0]->sw_if_index,
5908 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
5909
5910 FIB_TEST(fib_test_validate_entry(fei,
5911 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5912 2,
5913 &ip_hi_1,
5914 &ip_hi_2),
5915 "1.1.1.1/32 via high preference paths");
5916
5917 /*
5918 * bring up the interface on which the medium preference path lie
5919 */
5920 vnet_sw_interface_set_flags(vnet_get_main(),
5921 tm->hw[1]->sw_if_index,
5922 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
5923
5924 FIB_TEST(fib_test_validate_entry(fei,
5925 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5926 2,
5927 &ip_hi_1,
5928 &ip_hi_2),
5929 "1.1.1.1/32 via high preference paths");
5930
5931 dpo_id_t ip_1_1_1_1 = DPO_INVALID;
5932 fib_entry_contribute_forwarding(fei,
5933 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5934 &ip_1_1_1_1);
5935
5936 /*
5937 * 3 recursive paths of different preference
5938 */
5939 const fib_prefix_t pfx_1_1_1_2_s_32 = {
5940 .fp_len = 32,
5941 .fp_proto = FIB_PROTOCOL_IP4,
5942 .fp_addr = {
5943 .ip4 = {
5944 .as_u32 = clib_host_to_net_u32(0x01010102),
5945 },
5946 },
5947 };
5948 const fib_prefix_t pfx_1_1_1_3_s_32 = {
5949 .fp_len = 32,
5950 .fp_proto = FIB_PROTOCOL_IP4,
5951 .fp_addr = {
5952 .ip4 = {
5953 .as_u32 = clib_host_to_net_u32(0x01010103),
5954 },
5955 },
5956 };
5957 fei = fib_table_entry_path_add2(0,
5958 &pfx_1_1_1_2_s_32,
5959 FIB_SOURCE_API,
5960 FIB_ENTRY_FLAG_NONE,
5961 nr_paths);
5962 dpo_id_t ip_1_1_1_2 = DPO_INVALID;
5963 fib_entry_contribute_forwarding(fei,
5964 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5965 &ip_1_1_1_2);
5966 fei = fib_table_entry_path_add2(0,
5967 &pfx_1_1_1_3_s_32,
5968 FIB_SOURCE_API,
5969 FIB_ENTRY_FLAG_NONE,
5970 nr_paths);
5971 dpo_id_t ip_1_1_1_3 = DPO_INVALID;
5972 fib_entry_contribute_forwarding(fei,
5973 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5974 &ip_1_1_1_3);
5975
5976 fib_test_lb_bucket_t ip_o_1_1_1_1 = {
5977 .type = FT_LB_O_LB,
5978 .lb = {
5979 .lb = ip_1_1_1_1.dpoi_index,
5980 },
5981 };
5982 fib_test_lb_bucket_t ip_o_1_1_1_2 = {
5983 .type = FT_LB_O_LB,
5984 .lb = {
5985 .lb = ip_1_1_1_2.dpoi_index,
5986 },
5987 };
5988 fib_test_lb_bucket_t ip_o_1_1_1_3 = {
5989 .type = FT_LB_O_LB,
5990 .lb = {
5991 .lb = ip_1_1_1_3.dpoi_index,
5992 },
5993 };
5994 fib_route_path_t r_path_hi = {
Neale Rannsda78f952017-05-24 09:15:43 -07005995 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005996 .frp_sw_if_index = ~0,
5997 .frp_fib_index = 0,
5998 .frp_weight = 1,
5999 .frp_preference = 0,
6000 .frp_flags = FIB_ROUTE_PATH_RESOLVE_VIA_HOST,
6001 .frp_addr = pfx_1_1_1_1_s_32.fp_addr,
6002 };
6003 fib_route_path_t r_path_med = {
Neale Rannsda78f952017-05-24 09:15:43 -07006004 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07006005 .frp_sw_if_index = ~0,
6006 .frp_fib_index = 0,
6007 .frp_weight = 1,
6008 .frp_preference = 10,
6009 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
6010 .frp_addr = pfx_1_1_1_2_s_32.fp_addr,
6011 };
6012 fib_route_path_t r_path_low = {
Neale Rannsda78f952017-05-24 09:15:43 -07006013 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07006014 .frp_sw_if_index = ~0,
6015 .frp_fib_index = 0,
6016 .frp_weight = 1,
Neale Rannsa0a908f2017-08-01 11:40:03 -07006017 .frp_preference = 255,
Neale Ranns57b58602017-07-15 07:37:25 -07006018 .frp_flags = FIB_ROUTE_PATH_RESOLVE_VIA_HOST,
6019 .frp_addr = pfx_1_1_1_3_s_32.fp_addr,
6020 };
6021 fib_route_path_t *r_paths = NULL;
6022
6023 vec_add1(r_paths, r_path_hi);
6024 vec_add1(r_paths, r_path_low);
6025 vec_add1(r_paths, r_path_med);
6026
6027 /*
6028 * add many recursive so we get the LB MAp created
6029 */
6030 #define N_PFXS 64
6031 fib_prefix_t pfx_r[N_PFXS];
Marek Gradzkiaf095512017-08-15 07:38:26 +02006032 unsigned int n_pfxs;
Neale Ranns57b58602017-07-15 07:37:25 -07006033 for (n_pfxs = 0; n_pfxs < N_PFXS; n_pfxs++)
6034 {
6035 pfx_r[n_pfxs].fp_len = 32;
6036 pfx_r[n_pfxs].fp_proto = FIB_PROTOCOL_IP4;
6037 pfx_r[n_pfxs].fp_addr.ip4.as_u32 =
6038 clib_host_to_net_u32(0x02000000 + n_pfxs);
6039
6040 fei = fib_table_entry_path_add2(0,
6041 &pfx_r[n_pfxs],
6042 FIB_SOURCE_API,
6043 FIB_ENTRY_FLAG_NONE,
6044 r_paths);
6045
6046 FIB_TEST(fib_test_validate_entry(fei,
6047 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6048 1,
6049 &ip_o_1_1_1_1),
6050 "recursive via high preference paths");
6051
6052 /*
6053 * withdraw hig pref resolving entry
6054 */
6055 fib_table_entry_delete(0,
6056 &pfx_1_1_1_1_s_32,
6057 FIB_SOURCE_API);
6058
6059 /* suspend so the update walk kicks int */
6060 vlib_process_suspend(vlib_get_main(), 1e-5);
6061
6062 FIB_TEST(fib_test_validate_entry(fei,
6063 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6064 1,
6065 &ip_o_1_1_1_2),
6066 "recursive via medium preference paths");
6067
6068 /*
6069 * withdraw medium pref resolving entry
6070 */
6071 fib_table_entry_delete(0,
6072 &pfx_1_1_1_2_s_32,
6073 FIB_SOURCE_API);
6074
6075 /* suspend so the update walk kicks int */
6076 vlib_process_suspend(vlib_get_main(), 1e-5);
6077
6078 FIB_TEST(fib_test_validate_entry(fei,
6079 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6080 1,
6081 &ip_o_1_1_1_3),
6082 "recursive via low preference paths");
6083
6084 /*
6085 * add back paths for next iteration
6086 */
6087 fei = fib_table_entry_update(0,
6088 &pfx_1_1_1_2_s_32,
6089 FIB_SOURCE_API,
6090 FIB_ENTRY_FLAG_NONE,
6091 nr_paths);
6092 fei = fib_table_entry_update(0,
6093 &pfx_1_1_1_1_s_32,
6094 FIB_SOURCE_API,
6095 FIB_ENTRY_FLAG_NONE,
6096 nr_paths);
6097
6098 /* suspend so the update walk kicks int */
6099 vlib_process_suspend(vlib_get_main(), 1e-5);
6100
6101 fei = fib_table_lookup_exact_match(0, &pfx_r[n_pfxs]);
6102 FIB_TEST(fib_test_validate_entry(fei,
6103 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6104 1,
6105 &ip_o_1_1_1_1),
6106 "recursive via high preference paths");
6107 }
6108
6109
6110 fib_table_entry_delete(0,
6111 &pfx_1_1_1_1_s_32,
6112 FIB_SOURCE_API);
6113
6114 /* suspend so the update walk kicks int */
6115 vlib_process_suspend(vlib_get_main(), 1e-5);
6116
6117 for (n_pfxs = 0; n_pfxs < N_PFXS; n_pfxs++)
6118 {
6119 fei = fib_table_lookup_exact_match(0, &pfx_r[n_pfxs]);
6120
6121 FIB_TEST(fib_test_validate_entry(fei,
6122 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6123 1,
6124 &ip_o_1_1_1_2),
6125 "recursive via medium preference paths");
6126 }
6127 for (n_pfxs = 0; n_pfxs < N_PFXS; n_pfxs++)
6128 {
6129 fib_table_entry_delete(0,
6130 &pfx_r[n_pfxs],
6131 FIB_SOURCE_API);
6132 }
6133
6134 /*
6135 * Cleanup
6136 */
6137 fib_table_entry_delete(0,
6138 &pfx_1_1_1_2_s_32,
6139 FIB_SOURCE_API);
6140 fib_table_entry_delete(0,
6141 &pfx_1_1_1_3_s_32,
6142 FIB_SOURCE_API);
6143
6144 dpo_reset(&ip_1_1_1_1);
6145 dpo_reset(&ip_1_1_1_2);
6146 dpo_reset(&ip_1_1_1_3);
6147 adj_unlock(ai_low_2);
6148 adj_unlock(ai_low_1);
6149 adj_unlock(ai_med_2);
6150 adj_unlock(ai_med_1);
6151 adj_unlock(ai_hi_2);
6152 adj_unlock(ai_hi_1);
6153 return (0);
6154}
Neale Rannsad422ed2016-11-02 14:20:04 +00006155
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006156/*
6157 * Test the recursive route route handling for GRE tunnels
6158 */
Neale Ranns0ebe8d72016-12-08 19:48:11 +00006159static int
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006160fib_test_label (void)
6161{
6162 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;
6163 const u32 fib_index = 0;
6164 test_main_t *tm;
6165 ip4_main_t *im;
Neale Rannsad422ed2016-11-02 14:20:04 +00006166 int lb_count, ii;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006167
6168 lb_count = pool_elts(load_balance_pool);
6169 tm = &test_main;
6170 im = &ip4_main;
6171
6172 /*
6173 * add interface routes. We'll assume this works. It's more rigorously
6174 * tested elsewhere.
6175 */
6176 fib_prefix_t local0_pfx = {
6177 .fp_len = 24,
6178 .fp_proto = FIB_PROTOCOL_IP4,
6179 .fp_addr = {
6180 .ip4 = {
6181 /* 10.10.10.10 */
6182 .as_u32 = clib_host_to_net_u32(0x0a0a0a0a),
6183 },
6184 },
6185 };
6186
6187 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
6188 adj_nbr_db_size());
6189
6190 vec_validate(im->fib_index_by_sw_if_index, tm->hw[0]->sw_if_index);
6191 im->fib_index_by_sw_if_index[tm->hw[0]->sw_if_index] = fib_index;
6192
6193 fib_table_entry_update_one_path(fib_index, &local0_pfx,
6194 FIB_SOURCE_INTERFACE,
6195 (FIB_ENTRY_FLAG_CONNECTED |
6196 FIB_ENTRY_FLAG_ATTACHED),
Neale Rannsda78f952017-05-24 09:15:43 -07006197 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006198 NULL,
6199 tm->hw[0]->sw_if_index,
6200 ~0,
6201 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006202 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006203 FIB_ROUTE_PATH_FLAG_NONE);
6204 fei = fib_table_lookup_exact_match(fib_index, &local0_pfx);
6205 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
6206 "attached interface route present");
6207
6208 local0_pfx.fp_len = 32;
6209 fib_table_entry_update_one_path(fib_index, &local0_pfx,
6210 FIB_SOURCE_INTERFACE,
6211 (FIB_ENTRY_FLAG_CONNECTED |
6212 FIB_ENTRY_FLAG_LOCAL),
Neale Rannsda78f952017-05-24 09:15:43 -07006213 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006214 NULL,
6215 tm->hw[0]->sw_if_index,
6216 ~0, // invalid fib index
6217 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006218 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006219 FIB_ROUTE_PATH_FLAG_NONE);
6220 fei = fib_table_lookup_exact_match(fib_index, &local0_pfx);
6221
6222 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
6223 "local interface route present");
6224
6225 fib_prefix_t local1_pfx = {
6226 .fp_len = 24,
6227 .fp_proto = FIB_PROTOCOL_IP4,
6228 .fp_addr = {
6229 .ip4 = {
6230 /* 10.10.11.10 */
6231 .as_u32 = clib_host_to_net_u32(0x0a0a0b0a),
6232 },
6233 },
6234 };
6235
6236 vec_validate(im->fib_index_by_sw_if_index, tm->hw[1]->sw_if_index);
6237 im->fib_index_by_sw_if_index[tm->hw[1]->sw_if_index] = fib_index;
6238
6239 fib_table_entry_update_one_path(fib_index, &local1_pfx,
6240 FIB_SOURCE_INTERFACE,
6241 (FIB_ENTRY_FLAG_CONNECTED |
6242 FIB_ENTRY_FLAG_ATTACHED),
Neale Rannsda78f952017-05-24 09:15:43 -07006243 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006244 NULL,
6245 tm->hw[1]->sw_if_index,
6246 ~0,
6247 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006248 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006249 FIB_ROUTE_PATH_FLAG_NONE);
6250 fei = fib_table_lookup_exact_match(fib_index, &local1_pfx);
6251 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
6252 "attached interface route present");
6253
6254 local1_pfx.fp_len = 32;
6255 fib_table_entry_update_one_path(fib_index, &local1_pfx,
6256 FIB_SOURCE_INTERFACE,
6257 (FIB_ENTRY_FLAG_CONNECTED |
6258 FIB_ENTRY_FLAG_LOCAL),
Neale Rannsda78f952017-05-24 09:15:43 -07006259 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006260 NULL,
6261 tm->hw[1]->sw_if_index,
6262 ~0, // invalid fib index
6263 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006264 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006265 FIB_ROUTE_PATH_FLAG_NONE);
6266 fei = fib_table_lookup_exact_match(fib_index, &local1_pfx);
6267
6268 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
6269 "local interface route present");
6270
6271 ip46_address_t nh_10_10_10_1 = {
6272 .ip4 = {
6273 .as_u32 = clib_host_to_net_u32(0x0a0a0a01),
6274 },
6275 };
6276 ip46_address_t nh_10_10_11_1 = {
6277 .ip4 = {
6278 .as_u32 = clib_host_to_net_u32(0x0a0a0b01),
6279 },
6280 };
6281 ip46_address_t nh_10_10_11_2 = {
6282 .ip4 = {
6283 .as_u32 = clib_host_to_net_u32(0x0a0a0b02),
6284 },
6285 };
6286
6287 ai_v4_10_10_11_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01006288 VNET_LINK_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006289 &nh_10_10_11_1,
6290 tm->hw[1]->sw_if_index);
6291 ai_v4_10_10_11_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01006292 VNET_LINK_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006293 &nh_10_10_11_2,
6294 tm->hw[1]->sw_if_index);
6295 ai_mpls_10_10_10_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01006296 VNET_LINK_MPLS,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006297 &nh_10_10_10_1,
6298 tm->hw[0]->sw_if_index);
6299 ai_mpls_10_10_11_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01006300 VNET_LINK_MPLS,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006301 &nh_10_10_11_2,
6302 tm->hw[1]->sw_if_index);
6303 ai_mpls_10_10_11_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01006304 VNET_LINK_MPLS,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006305 &nh_10_10_11_1,
6306 tm->hw[1]->sw_if_index);
6307
6308 /*
6309 * Add an etry with one path with a real out-going label
6310 */
6311 fib_prefix_t pfx_1_1_1_1_s_32 = {
6312 .fp_len = 32,
6313 .fp_proto = FIB_PROTOCOL_IP4,
6314 .fp_addr = {
6315 .ip4.as_u32 = clib_host_to_net_u32(0x01010101),
6316 },
6317 };
6318 fib_test_lb_bucket_t l99_eos_o_10_10_10_1 = {
6319 .type = FT_LB_LABEL_O_ADJ,
6320 .label_o_adj = {
6321 .adj = ai_mpls_10_10_10_1,
6322 .label = 99,
6323 .eos = MPLS_EOS,
6324 },
6325 };
6326 fib_test_lb_bucket_t l99_neos_o_10_10_10_1 = {
6327 .type = FT_LB_LABEL_O_ADJ,
6328 .label_o_adj = {
6329 .adj = ai_mpls_10_10_10_1,
6330 .label = 99,
6331 .eos = MPLS_NON_EOS,
6332 },
6333 };
Neale Rannsad422ed2016-11-02 14:20:04 +00006334 mpls_label_t *l99 = NULL;
6335 vec_add1(l99, 99);
6336
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006337 fib_table_entry_update_one_path(fib_index,
6338 &pfx_1_1_1_1_s_32,
6339 FIB_SOURCE_API,
6340 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07006341 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006342 &nh_10_10_10_1,
6343 tm->hw[0]->sw_if_index,
6344 ~0, // invalid fib index
6345 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006346 l99,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006347 FIB_ROUTE_PATH_FLAG_NONE);
6348
6349 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
6350 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "1.1.1.1/32 created");
6351
6352 FIB_TEST(fib_test_validate_entry(fei,
6353 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6354 1,
6355 &l99_eos_o_10_10_10_1),
6356 "1.1.1.1/32 LB 1 bucket via label 99 over 10.10.10.1");
6357
6358 /*
6359 * add a path with an implicit NULL label
6360 */
6361 fib_test_lb_bucket_t a_o_10_10_11_1 = {
6362 .type = FT_LB_ADJ,
6363 .adj = {
6364 .adj = ai_v4_10_10_11_1,
6365 },
6366 };
6367 fib_test_lb_bucket_t a_mpls_o_10_10_11_1 = {
6368 .type = FT_LB_ADJ,
6369 .adj = {
6370 .adj = ai_mpls_10_10_11_1,
6371 },
6372 };
Neale Rannsad422ed2016-11-02 14:20:04 +00006373 mpls_label_t *l_imp_null = NULL;
6374 vec_add1(l_imp_null, MPLS_IETF_IMPLICIT_NULL_LABEL);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006375
6376 fei = fib_table_entry_path_add(fib_index,
6377 &pfx_1_1_1_1_s_32,
6378 FIB_SOURCE_API,
6379 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07006380 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006381 &nh_10_10_11_1,
6382 tm->hw[1]->sw_if_index,
6383 ~0, // invalid fib index
6384 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006385 l_imp_null,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006386 FIB_ROUTE_PATH_FLAG_NONE);
6387
6388 FIB_TEST(fib_test_validate_entry(fei,
6389 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6390 2,
6391 &l99_eos_o_10_10_10_1,
6392 &a_o_10_10_11_1),
6393 "1.1.1.1/32 LB 2 buckets via: "
6394 "label 99 over 10.10.10.1, "
6395 "adj over 10.10.11.1");
6396
6397 /*
6398 * assign the route a local label
6399 */
6400 fib_table_entry_local_label_add(fib_index,
6401 &pfx_1_1_1_1_s_32,
6402 24001);
6403
6404 fib_prefix_t pfx_24001_eos = {
6405 .fp_proto = FIB_PROTOCOL_MPLS,
6406 .fp_label = 24001,
6407 .fp_eos = MPLS_EOS,
6408 };
6409 fib_prefix_t pfx_24001_neos = {
6410 .fp_proto = FIB_PROTOCOL_MPLS,
6411 .fp_label = 24001,
6412 .fp_eos = MPLS_NON_EOS,
6413 };
Neale Ranns62fe07c2017-10-31 12:28:22 -07006414 fib_test_lb_bucket_t disp_o_10_10_11_1 = {
6415 .type = FT_LB_MPLS_DISP_O_ADJ,
6416 .adj = {
6417 .adj = ai_v4_10_10_11_1,
6418 },
6419 };
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006420
6421 /*
6422 * The EOS entry should link to both the paths,
6423 * and use an ip adj for the imp-null
6424 * The NON-EOS entry should link to both the paths,
6425 * and use an mpls adj for the imp-null
6426 */
6427 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6428 &pfx_24001_eos);
6429 FIB_TEST(fib_test_validate_entry(fei,
6430 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6431 2,
6432 &l99_eos_o_10_10_10_1,
Neale Ranns62fe07c2017-10-31 12:28:22 -07006433 &disp_o_10_10_11_1),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006434 "24001/eos LB 2 buckets via: "
6435 "label 99 over 10.10.10.1, "
Neale Ranns62fe07c2017-10-31 12:28:22 -07006436 "mpls disp adj over 10.10.11.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006437
6438
6439 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6440 &pfx_24001_neos);
6441 FIB_TEST(fib_test_validate_entry(fei,
6442 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6443 2,
6444 &l99_neos_o_10_10_10_1,
6445 &a_mpls_o_10_10_11_1),
6446 "24001/neos LB 1 bucket via: "
6447 "label 99 over 10.10.10.1 ",
6448 "mpls-adj via 10.10.11.1");
6449
6450 /*
6451 * add an unlabelled path, this is excluded from the neos chains,
6452 */
6453 fib_test_lb_bucket_t adj_o_10_10_11_2 = {
6454 .type = FT_LB_ADJ,
6455 .adj = {
6456 .adj = ai_v4_10_10_11_2,
6457 },
6458 };
Neale Ranns62fe07c2017-10-31 12:28:22 -07006459 fib_test_lb_bucket_t disp_o_10_10_11_2 = {
6460 .type = FT_LB_MPLS_DISP_O_ADJ,
6461 .adj = {
6462 .adj = ai_v4_10_10_11_2,
6463 },
6464 };
6465
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006466
6467 fei = fib_table_entry_path_add(fib_index,
6468 &pfx_1_1_1_1_s_32,
6469 FIB_SOURCE_API,
6470 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07006471 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006472 &nh_10_10_11_2,
6473 tm->hw[1]->sw_if_index,
6474 ~0, // invalid fib index
6475 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006476 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006477 FIB_ROUTE_PATH_FLAG_NONE);
6478
6479 FIB_TEST(fib_test_validate_entry(fei,
6480 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6481 16, // 3 choices spread over 16 buckets
6482 &l99_eos_o_10_10_10_1,
6483 &l99_eos_o_10_10_10_1,
6484 &l99_eos_o_10_10_10_1,
6485 &l99_eos_o_10_10_10_1,
6486 &l99_eos_o_10_10_10_1,
6487 &l99_eos_o_10_10_10_1,
6488 &a_o_10_10_11_1,
6489 &a_o_10_10_11_1,
6490 &a_o_10_10_11_1,
6491 &a_o_10_10_11_1,
6492 &a_o_10_10_11_1,
6493 &adj_o_10_10_11_2,
6494 &adj_o_10_10_11_2,
6495 &adj_o_10_10_11_2,
6496 &adj_o_10_10_11_2,
6497 &adj_o_10_10_11_2),
6498 "1.1.1.1/32 LB 16 buckets via: "
6499 "label 99 over 10.10.10.1, "
6500 "adj over 10.10.11.1",
6501 "adj over 10.10.11.2");
6502
6503 /*
6504 * get and lock a reference to the non-eos of the via entry 1.1.1.1/32
6505 */
Neale Ranns948e00f2016-10-20 13:39:34 +01006506 dpo_id_t non_eos_1_1_1_1 = DPO_INVALID;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006507 fib_entry_contribute_forwarding(fei,
6508 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6509 &non_eos_1_1_1_1);
6510
6511 /*
6512 * n-eos has only the 2 labelled paths
6513 */
6514 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6515 &pfx_24001_neos);
6516
6517 FIB_TEST(fib_test_validate_entry(fei,
6518 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6519 2,
6520 &l99_neos_o_10_10_10_1,
6521 &a_mpls_o_10_10_11_1),
6522 "24001/neos LB 2 buckets via: "
6523 "label 99 over 10.10.10.1, "
6524 "adj-mpls over 10.10.11.2");
6525
6526 /*
6527 * A labelled recursive
6528 */
6529 fib_prefix_t pfx_2_2_2_2_s_32 = {
6530 .fp_len = 32,
6531 .fp_proto = FIB_PROTOCOL_IP4,
6532 .fp_addr = {
6533 .ip4.as_u32 = clib_host_to_net_u32(0x02020202),
6534 },
6535 };
6536 fib_test_lb_bucket_t l1600_eos_o_1_1_1_1 = {
6537 .type = FT_LB_LABEL_O_LB,
6538 .label_o_lb = {
6539 .lb = non_eos_1_1_1_1.dpoi_index,
6540 .label = 1600,
6541 .eos = MPLS_EOS,
6542 },
6543 };
Neale Rannsad422ed2016-11-02 14:20:04 +00006544 mpls_label_t *l1600 = NULL;
6545 vec_add1(l1600, 1600);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006546
6547 fib_table_entry_update_one_path(fib_index,
6548 &pfx_2_2_2_2_s_32,
6549 FIB_SOURCE_API,
6550 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07006551 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006552 &pfx_1_1_1_1_s_32.fp_addr,
6553 ~0,
6554 fib_index,
6555 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006556 l1600,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006557 FIB_ROUTE_PATH_FLAG_NONE);
6558
6559 fei = fib_table_lookup(fib_index, &pfx_2_2_2_2_s_32);
6560 FIB_TEST(fib_test_validate_entry(fei,
6561 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6562 1,
6563 &l1600_eos_o_1_1_1_1),
6564 "2.2.2.2.2/32 LB 1 buckets via: "
6565 "label 1600 over 1.1.1.1");
6566
Neale Ranns948e00f2016-10-20 13:39:34 +01006567 dpo_id_t dpo_44 = DPO_INVALID;
Neale Ranns3ee44042016-10-03 13:05:48 +01006568 index_t urpfi;
6569
6570 fib_entry_contribute_forwarding(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, &dpo_44);
6571 urpfi = load_balance_get_urpf(dpo_44.dpoi_index);
6572
6573 FIB_TEST(fib_urpf_check(urpfi, tm->hw[0]->sw_if_index),
6574 "uRPF check for 2.2.2.2/32 on %d OK",
6575 tm->hw[0]->sw_if_index);
6576 FIB_TEST(fib_urpf_check(urpfi, tm->hw[1]->sw_if_index),
6577 "uRPF check for 2.2.2.2/32 on %d OK",
6578 tm->hw[1]->sw_if_index);
6579 FIB_TEST(!fib_urpf_check(urpfi, 99),
6580 "uRPF check for 2.2.2.2/32 on 99 not-OK",
6581 99);
6582
6583 fib_entry_contribute_forwarding(fei, FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS, &dpo_44);
6584 FIB_TEST(urpfi == load_balance_get_urpf(dpo_44.dpoi_index),
6585 "Shared uRPF on IP and non-EOS chain");
6586
6587 dpo_reset(&dpo_44);
6588
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006589 /*
6590 * we are holding a lock on the non-eos LB of the via-entry.
6591 * do a PIC-core failover by shutting the link of the via-entry.
6592 *
6593 * shut down the link with the valid label
6594 */
6595 vnet_sw_interface_set_flags(vnet_get_main(),
6596 tm->hw[0]->sw_if_index,
6597 0);
6598
6599 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
6600 FIB_TEST(fib_test_validate_entry(fei,
6601 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6602 2,
6603 &a_o_10_10_11_1,
6604 &adj_o_10_10_11_2),
6605 "1.1.1.1/32 LB 2 buckets via: "
6606 "adj over 10.10.11.1, ",
6607 "adj-v4 over 10.10.11.2");
6608
6609 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6610 &pfx_24001_eos);
6611 FIB_TEST(fib_test_validate_entry(fei,
6612 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6613 2,
Neale Ranns62fe07c2017-10-31 12:28:22 -07006614 &disp_o_10_10_11_1,
6615 &disp_o_10_10_11_2),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006616 "24001/eos LB 2 buckets via: "
Neale Ranns62fe07c2017-10-31 12:28:22 -07006617 "mpls-disp adj over 10.10.11.1, ",
6618 "mpls-disp adj-v4 over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006619
6620 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6621 &pfx_24001_neos);
6622 FIB_TEST(fib_test_validate_entry(fei,
6623 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6624 1,
6625 &a_mpls_o_10_10_11_1),
6626 "24001/neos LB 1 buckets via: "
6627 "adj-mpls over 10.10.11.2");
6628
6629 /*
6630 * test that the pre-failover load-balance has been in-place
6631 * modified
6632 */
Neale Ranns948e00f2016-10-20 13:39:34 +01006633 dpo_id_t current = DPO_INVALID;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006634 fib_entry_contribute_forwarding(fei,
6635 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6636 &current);
6637
6638 FIB_TEST(!dpo_cmp(&non_eos_1_1_1_1,
6639 &current),
6640 "PIC-core LB inplace modified %U %U",
6641 format_dpo_id, &non_eos_1_1_1_1, 0,
6642 format_dpo_id, &current, 0);
6643
6644 dpo_reset(&non_eos_1_1_1_1);
6645 dpo_reset(&current);
6646
6647 /*
6648 * no-shut the link with the valid label
6649 */
6650 vnet_sw_interface_set_flags(vnet_get_main(),
6651 tm->hw[0]->sw_if_index,
6652 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
6653
6654 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
6655 FIB_TEST(fib_test_validate_entry(fei,
6656 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6657 16, // 3 choices spread over 16 buckets
6658 &l99_eos_o_10_10_10_1,
6659 &l99_eos_o_10_10_10_1,
6660 &l99_eos_o_10_10_10_1,
6661 &l99_eos_o_10_10_10_1,
6662 &l99_eos_o_10_10_10_1,
6663 &l99_eos_o_10_10_10_1,
6664 &a_o_10_10_11_1,
6665 &a_o_10_10_11_1,
6666 &a_o_10_10_11_1,
6667 &a_o_10_10_11_1,
6668 &a_o_10_10_11_1,
6669 &adj_o_10_10_11_2,
6670 &adj_o_10_10_11_2,
6671 &adj_o_10_10_11_2,
6672 &adj_o_10_10_11_2,
6673 &adj_o_10_10_11_2),
6674 "1.1.1.1/32 LB 16 buckets via: "
6675 "label 99 over 10.10.10.1, "
6676 "adj over 10.10.11.1",
6677 "adj-v4 over 10.10.11.2");
6678
6679
6680 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6681 &pfx_24001_eos);
6682 FIB_TEST(fib_test_validate_entry(fei,
6683 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6684 16, // 3 choices spread over 16 buckets
6685 &l99_eos_o_10_10_10_1,
6686 &l99_eos_o_10_10_10_1,
6687 &l99_eos_o_10_10_10_1,
6688 &l99_eos_o_10_10_10_1,
6689 &l99_eos_o_10_10_10_1,
6690 &l99_eos_o_10_10_10_1,
Neale Ranns62fe07c2017-10-31 12:28:22 -07006691 &disp_o_10_10_11_1,
6692 &disp_o_10_10_11_1,
6693 &disp_o_10_10_11_1,
6694 &disp_o_10_10_11_1,
6695 &disp_o_10_10_11_1,
6696 &disp_o_10_10_11_2,
6697 &disp_o_10_10_11_2,
6698 &disp_o_10_10_11_2,
6699 &disp_o_10_10_11_2,
6700 &disp_o_10_10_11_2),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006701 "24001/eos LB 16 buckets via: "
6702 "label 99 over 10.10.10.1, "
Neale Ranns62fe07c2017-10-31 12:28:22 -07006703 "MPLS disp adj over 10.10.11.1",
6704 "MPLS disp adj-v4 over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006705
6706 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6707 &pfx_24001_neos);
6708 FIB_TEST(fib_test_validate_entry(fei,
6709 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6710 2,
6711 &l99_neos_o_10_10_10_1,
6712 &a_mpls_o_10_10_11_1),
6713 "24001/neos LB 2 buckets via: "
6714 "label 99 over 10.10.10.1, "
6715 "adj-mpls over 10.10.11.2");
6716
6717 /*
6718 * remove the first path with the valid label
6719 */
6720 fib_table_entry_path_remove(fib_index,
6721 &pfx_1_1_1_1_s_32,
6722 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07006723 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006724 &nh_10_10_10_1,
6725 tm->hw[0]->sw_if_index,
6726 ~0, // invalid fib index
6727 1,
6728 FIB_ROUTE_PATH_FLAG_NONE);
6729
6730 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
6731 FIB_TEST(fib_test_validate_entry(fei,
6732 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6733 2,
6734 &a_o_10_10_11_1,
6735 &adj_o_10_10_11_2),
6736 "1.1.1.1/32 LB 2 buckets via: "
Neale Rannsa3af3372017-03-28 03:49:52 -07006737 "adj over 10.10.11.1, "
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006738 "adj-v4 over 10.10.11.2");
6739
6740 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6741 &pfx_24001_eos);
6742 FIB_TEST(fib_test_validate_entry(fei,
6743 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6744 2,
Neale Ranns62fe07c2017-10-31 12:28:22 -07006745 &disp_o_10_10_11_1,
6746 &disp_o_10_10_11_2),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006747 "24001/eos LB 2 buckets via: "
Neale Ranns62fe07c2017-10-31 12:28:22 -07006748 "MPLS disp adj over 10.10.11.1, "
6749 "MPLS disp adj-v4 over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006750
6751 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6752 &pfx_24001_neos);
6753
6754 FIB_TEST(fib_test_validate_entry(fei,
6755 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6756 1,
6757 &a_mpls_o_10_10_11_1),
6758 "24001/neos LB 1 buckets via: "
6759 "adj-mpls over 10.10.11.2");
6760
6761 /*
6762 * remove the other path with a valid label
6763 */
6764 fib_test_lb_bucket_t bucket_drop = {
Neale Rannsd792d9c2017-10-21 10:53:20 -07006765 .type = FT_LB_DROP,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006766 };
Neale Rannsf12a83f2017-04-18 09:09:40 -07006767 fib_test_lb_bucket_t mpls_bucket_drop = {
Neale Rannsd792d9c2017-10-21 10:53:20 -07006768 .type = FT_LB_DROP,
Neale Rannsf12a83f2017-04-18 09:09:40 -07006769 .special = {
6770 .adj = DPO_PROTO_MPLS,
6771 },
6772 };
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006773
6774 fib_table_entry_path_remove(fib_index,
6775 &pfx_1_1_1_1_s_32,
6776 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07006777 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006778 &nh_10_10_11_1,
6779 tm->hw[1]->sw_if_index,
6780 ~0, // invalid fib index
6781 1,
6782 FIB_ROUTE_PATH_FLAG_NONE);
6783
6784 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
6785 FIB_TEST(fib_test_validate_entry(fei,
6786 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6787 1,
6788 &adj_o_10_10_11_2),
6789 "1.1.1.1/32 LB 1 buckets via: "
6790 "adj over 10.10.11.2");
6791
6792 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6793 &pfx_24001_eos);
6794 FIB_TEST(fib_test_validate_entry(fei,
6795 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6796 1,
Neale Ranns62fe07c2017-10-31 12:28:22 -07006797 &disp_o_10_10_11_2),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006798 "24001/eos LB 1 buckets via: "
Neale Ranns62fe07c2017-10-31 12:28:22 -07006799 "MPLS disp adj over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006800
6801 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6802 &pfx_24001_neos);
6803 FIB_TEST(fib_test_validate_entry(fei,
6804 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
Neale Rannsf12a83f2017-04-18 09:09:40 -07006805 1,
6806 &mpls_bucket_drop),
6807 "24001/neos LB 1 buckets via: DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006808
6809 /*
6810 * add back the path with the valid label
6811 */
Neale Rannsad422ed2016-11-02 14:20:04 +00006812 l99 = NULL;
6813 vec_add1(l99, 99);
6814
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006815 fib_table_entry_path_add(fib_index,
6816 &pfx_1_1_1_1_s_32,
6817 FIB_SOURCE_API,
6818 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07006819 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006820 &nh_10_10_10_1,
6821 tm->hw[0]->sw_if_index,
6822 ~0, // invalid fib index
6823 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006824 l99,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006825 FIB_ROUTE_PATH_FLAG_NONE);
6826
6827 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
6828 FIB_TEST(fib_test_validate_entry(fei,
6829 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6830 2,
6831 &l99_eos_o_10_10_10_1,
6832 &adj_o_10_10_11_2),
6833 "1.1.1.1/32 LB 2 buckets via: "
6834 "label 99 over 10.10.10.1, "
6835 "adj over 10.10.11.2");
6836
6837 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6838 &pfx_24001_eos);
6839 FIB_TEST(fib_test_validate_entry(fei,
6840 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6841 2,
6842 &l99_eos_o_10_10_10_1,
Neale Ranns62fe07c2017-10-31 12:28:22 -07006843 &disp_o_10_10_11_2),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006844 "24001/eos LB 2 buckets via: "
6845 "label 99 over 10.10.10.1, "
Neale Ranns62fe07c2017-10-31 12:28:22 -07006846 "MPLS disp adj over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006847
6848 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6849 &pfx_24001_neos);
6850 FIB_TEST(fib_test_validate_entry(fei,
6851 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6852 1,
6853 &l99_neos_o_10_10_10_1),
6854 "24001/neos LB 1 buckets via: "
6855 "label 99 over 10.10.10.1");
6856
6857 /*
Neale Ranns1357f3b2016-10-16 12:01:42 -07006858 * change the local label
6859 */
6860 fib_table_entry_local_label_add(fib_index,
6861 &pfx_1_1_1_1_s_32,
6862 25005);
6863
6864 fib_prefix_t pfx_25005_eos = {
6865 .fp_proto = FIB_PROTOCOL_MPLS,
6866 .fp_label = 25005,
6867 .fp_eos = MPLS_EOS,
6868 };
6869 fib_prefix_t pfx_25005_neos = {
6870 .fp_proto = FIB_PROTOCOL_MPLS,
6871 .fp_label = 25005,
6872 .fp_eos = MPLS_NON_EOS,
6873 };
6874
6875 FIB_TEST((FIB_NODE_INDEX_INVALID ==
6876 fib_table_lookup(fib_index, &pfx_24001_eos)),
6877 "24001/eos removed after label change");
6878 FIB_TEST((FIB_NODE_INDEX_INVALID ==
6879 fib_table_lookup(fib_index, &pfx_24001_neos)),
6880 "24001/eos removed after label change");
6881
6882 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6883 &pfx_25005_eos);
6884 FIB_TEST(fib_test_validate_entry(fei,
6885 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6886 2,
6887 &l99_eos_o_10_10_10_1,
Neale Ranns62fe07c2017-10-31 12:28:22 -07006888 &disp_o_10_10_11_2),
Neale Ranns1357f3b2016-10-16 12:01:42 -07006889 "25005/eos LB 2 buckets via: "
6890 "label 99 over 10.10.10.1, "
Neale Ranns62fe07c2017-10-31 12:28:22 -07006891 "MPLS disp adj over 10.10.11.2");
Neale Ranns1357f3b2016-10-16 12:01:42 -07006892
6893 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6894 &pfx_25005_neos);
6895 FIB_TEST(fib_test_validate_entry(fei,
6896 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6897 1,
6898 &l99_neos_o_10_10_10_1),
6899 "25005/neos LB 1 buckets via: "
6900 "label 99 over 10.10.10.1");
6901
6902 /*
6903 * remove the local label.
6904 * the check that the MPLS entries are gone is done by the fact the
6905 * MPLS table is no longer present.
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006906 */
6907 fib_table_entry_local_label_remove(fib_index,
6908 &pfx_1_1_1_1_s_32,
Neale Ranns1357f3b2016-10-16 12:01:42 -07006909 25005);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006910
6911 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
6912 FIB_TEST(fib_test_validate_entry(fei,
6913 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6914 2,
6915 &l99_eos_o_10_10_10_1,
6916 &adj_o_10_10_11_2),
6917 "24001/eos LB 2 buckets via: "
6918 "label 99 over 10.10.10.1, "
6919 "adj over 10.10.11.2");
6920
6921 FIB_TEST((FIB_NODE_INDEX_INVALID ==
6922 mpls_fib_index_from_table_id(MPLS_FIB_DEFAULT_TABLE_ID)),
6923 "No more MPLS FIB entries => table removed");
6924
6925 /*
6926 * add another via-entry for the recursive
6927 */
6928 fib_prefix_t pfx_1_1_1_2_s_32 = {
6929 .fp_len = 32,
6930 .fp_proto = FIB_PROTOCOL_IP4,
6931 .fp_addr = {
6932 .ip4.as_u32 = clib_host_to_net_u32(0x01010102),
6933 },
6934 };
6935 fib_test_lb_bucket_t l101_eos_o_10_10_10_1 = {
6936 .type = FT_LB_LABEL_O_ADJ,
6937 .label_o_adj = {
6938 .adj = ai_mpls_10_10_10_1,
6939 .label = 101,
6940 .eos = MPLS_EOS,
6941 },
6942 };
Neale Rannsad422ed2016-11-02 14:20:04 +00006943 mpls_label_t *l101 = NULL;
6944 vec_add1(l101, 101);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006945
6946 fei = fib_table_entry_update_one_path(fib_index,
6947 &pfx_1_1_1_2_s_32,
6948 FIB_SOURCE_API,
6949 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07006950 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006951 &nh_10_10_10_1,
6952 tm->hw[0]->sw_if_index,
6953 ~0, // invalid fib index
6954 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006955 l101,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006956 FIB_ROUTE_PATH_FLAG_NONE);
6957
6958 FIB_TEST(fib_test_validate_entry(fei,
6959 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6960 1,
6961 &l101_eos_o_10_10_10_1),
6962 "1.1.1.2/32 LB 1 buckets via: "
6963 "label 101 over 10.10.10.1");
6964
Neale Ranns948e00f2016-10-20 13:39:34 +01006965 dpo_id_t non_eos_1_1_1_2 = DPO_INVALID;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006966 fib_entry_contribute_forwarding(fib_table_lookup(fib_index,
6967 &pfx_1_1_1_1_s_32),
6968 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6969 &non_eos_1_1_1_1);
6970 fib_entry_contribute_forwarding(fib_table_lookup(fib_index,
6971 &pfx_1_1_1_2_s_32),
6972 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6973 &non_eos_1_1_1_2);
6974
6975 fib_test_lb_bucket_t l1601_eos_o_1_1_1_2 = {
6976 .type = FT_LB_LABEL_O_LB,
6977 .label_o_lb = {
6978 .lb = non_eos_1_1_1_2.dpoi_index,
6979 .label = 1601,
6980 .eos = MPLS_EOS,
6981 },
6982 };
Neale Rannsad422ed2016-11-02 14:20:04 +00006983 mpls_label_t *l1601 = NULL;
6984 vec_add1(l1601, 1601);
6985
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006986 l1600_eos_o_1_1_1_1.label_o_lb.lb = non_eos_1_1_1_1.dpoi_index;
6987
6988 fei = fib_table_entry_path_add(fib_index,
6989 &pfx_2_2_2_2_s_32,
6990 FIB_SOURCE_API,
6991 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07006992 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006993 &pfx_1_1_1_2_s_32.fp_addr,
6994 ~0,
6995 fib_index,
6996 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006997 l1601,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006998 FIB_ROUTE_PATH_FLAG_NONE);
6999
7000 FIB_TEST(fib_test_validate_entry(fei,
7001 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7002 2,
7003 &l1600_eos_o_1_1_1_1,
7004 &l1601_eos_o_1_1_1_2),
7005 "2.2.2.2/32 LB 2 buckets via: "
7006 "label 1600 via 1.1,1.1, "
7007 "label 16001 via 1.1.1.2");
7008
7009 /*
7010 * update the via-entry so it no longer has an imp-null path.
7011 * the LB for the recursive can use an imp-null
7012 */
Neale Rannsad422ed2016-11-02 14:20:04 +00007013 l_imp_null = NULL;
7014 vec_add1(l_imp_null, MPLS_IETF_IMPLICIT_NULL_LABEL);
7015
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007016 fei = fib_table_entry_update_one_path(fib_index,
7017 &pfx_1_1_1_2_s_32,
7018 FIB_SOURCE_API,
7019 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07007020 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007021 &nh_10_10_11_1,
7022 tm->hw[1]->sw_if_index,
7023 ~0, // invalid fib index
7024 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00007025 l_imp_null,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007026 FIB_ROUTE_PATH_FLAG_NONE);
7027
7028 FIB_TEST(fib_test_validate_entry(fei,
7029 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7030 1,
7031 &a_o_10_10_11_1),
7032 "1.1.1.2/32 LB 1 buckets via: "
7033 "adj 10.10.11.1");
7034
7035 fei = fib_table_lookup(fib_index, &pfx_2_2_2_2_s_32);
7036 FIB_TEST(fib_test_validate_entry(fei,
7037 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7038 2,
7039 &l1600_eos_o_1_1_1_1,
7040 &l1601_eos_o_1_1_1_2),
7041 "2.2.2.2/32 LB 2 buckets via: "
7042 "label 1600 via 1.1,1.1, "
7043 "label 16001 via 1.1.1.2");
7044
7045 /*
7046 * update the via-entry so it no longer has labelled paths.
7047 * the LB for the recursive should exclue this via form its LB
7048 */
7049 fei = fib_table_entry_update_one_path(fib_index,
7050 &pfx_1_1_1_2_s_32,
7051 FIB_SOURCE_API,
7052 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07007053 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007054 &nh_10_10_11_1,
7055 tm->hw[1]->sw_if_index,
7056 ~0, // invalid fib index
7057 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00007058 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007059 FIB_ROUTE_PATH_FLAG_NONE);
7060
7061 FIB_TEST(fib_test_validate_entry(fei,
7062 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7063 1,
7064 &a_o_10_10_11_1),
7065 "1.1.1.2/32 LB 1 buckets via: "
7066 "adj 10.10.11.1");
7067
7068 fei = fib_table_lookup(fib_index, &pfx_2_2_2_2_s_32);
7069 FIB_TEST(fib_test_validate_entry(fei,
7070 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7071 1,
7072 &l1600_eos_o_1_1_1_1),
7073 "2.2.2.2/32 LB 1 buckets via: "
7074 "label 1600 via 1.1,1.1");
7075
7076 dpo_reset(&non_eos_1_1_1_1);
7077 dpo_reset(&non_eos_1_1_1_2);
7078
7079 /*
7080 * Add a recursive with no out-labels. We expect to use the IP of the via
7081 */
7082 fib_prefix_t pfx_2_2_2_3_s_32 = {
7083 .fp_len = 32,
7084 .fp_proto = FIB_PROTOCOL_IP4,
7085 .fp_addr = {
7086 .ip4.as_u32 = clib_host_to_net_u32(0x02020203),
7087 },
7088 };
Neale Ranns948e00f2016-10-20 13:39:34 +01007089 dpo_id_t ip_1_1_1_1 = DPO_INVALID;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007090
7091 fib_table_entry_update_one_path(fib_index,
7092 &pfx_2_2_2_3_s_32,
7093 FIB_SOURCE_API,
7094 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07007095 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007096 &pfx_1_1_1_1_s_32.fp_addr,
7097 ~0,
7098 fib_index,
7099 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00007100 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007101 FIB_ROUTE_PATH_FLAG_NONE);
7102
7103 fib_entry_contribute_forwarding(fib_table_lookup(fib_index,
7104 &pfx_1_1_1_1_s_32),
7105 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7106 &ip_1_1_1_1);
7107
7108 fib_test_lb_bucket_t ip_o_1_1_1_1 = {
7109 .type = FT_LB_O_LB,
7110 .lb = {
7111 .lb = ip_1_1_1_1.dpoi_index,
7112 },
7113 };
7114
7115 fei = fib_table_lookup(fib_index, &pfx_2_2_2_3_s_32);
7116 FIB_TEST(fib_test_validate_entry(fei,
7117 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7118 1,
7119 &ip_o_1_1_1_1),
7120 "2.2.2.2.3/32 LB 1 buckets via: "
7121 "ip 1.1.1.1");
7122
7123 /*
7124 * Add a recursive with an imp-null out-label.
7125 * We expect to use the IP of the via
7126 */
7127 fib_prefix_t pfx_2_2_2_4_s_32 = {
7128 .fp_len = 32,
7129 .fp_proto = FIB_PROTOCOL_IP4,
7130 .fp_addr = {
7131 .ip4.as_u32 = clib_host_to_net_u32(0x02020204),
7132 },
7133 };
7134
7135 fib_table_entry_update_one_path(fib_index,
7136 &pfx_2_2_2_4_s_32,
7137 FIB_SOURCE_API,
7138 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07007139 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007140 &pfx_1_1_1_1_s_32.fp_addr,
7141 ~0,
7142 fib_index,
7143 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00007144 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007145 FIB_ROUTE_PATH_FLAG_NONE);
7146
7147 fei = fib_table_lookup(fib_index, &pfx_2_2_2_4_s_32);
7148 FIB_TEST(fib_test_validate_entry(fei,
7149 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7150 1,
7151 &ip_o_1_1_1_1),
7152 "2.2.2.2.4/32 LB 1 buckets via: "
7153 "ip 1.1.1.1");
7154
7155 dpo_reset(&ip_1_1_1_1);
7156
7157 /*
Neale Rannsad422ed2016-11-02 14:20:04 +00007158 * Create an entry with a deep label stack
7159 */
7160 fib_prefix_t pfx_2_2_5_5_s_32 = {
7161 .fp_len = 32,
7162 .fp_proto = FIB_PROTOCOL_IP4,
7163 .fp_addr = {
7164 .ip4.as_u32 = clib_host_to_net_u32(0x02020505),
7165 },
7166 };
7167 fib_test_lb_bucket_t ls_eos_o_10_10_10_1 = {
7168 .type = FT_LB_LABEL_STACK_O_ADJ,
7169 .label_stack_o_adj = {
7170 .adj = ai_mpls_10_10_11_1,
7171 .label_stack_size = 8,
7172 .label_stack = {
7173 200, 201, 202, 203, 204, 205, 206, 207
7174 },
7175 .eos = MPLS_EOS,
7176 },
7177 };
7178 mpls_label_t *label_stack = NULL;
7179 vec_validate(label_stack, 7);
7180 for (ii = 0; ii < 8; ii++)
7181 {
7182 label_stack[ii] = ii + 200;
7183 }
7184
7185 fei = fib_table_entry_update_one_path(fib_index,
7186 &pfx_2_2_5_5_s_32,
7187 FIB_SOURCE_API,
7188 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07007189 DPO_PROTO_IP4,
Neale Rannsad422ed2016-11-02 14:20:04 +00007190 &nh_10_10_11_1,
7191 tm->hw[1]->sw_if_index,
7192 ~0, // invalid fib index
7193 1,
7194 label_stack,
7195 FIB_ROUTE_PATH_FLAG_NONE);
7196
7197 FIB_TEST(fib_test_validate_entry(fei,
7198 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7199 1,
7200 &ls_eos_o_10_10_10_1),
7201 "2.2.5.5/32 LB 1 buckets via: "
7202 "adj 10.10.11.1");
7203 fib_table_entry_delete_index(fei, FIB_SOURCE_API);
7204
7205 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007206 * cleanup
7207 */
7208 fib_table_entry_delete(fib_index,
7209 &pfx_1_1_1_2_s_32,
7210 FIB_SOURCE_API);
7211
7212 fei = fib_table_lookup(fib_index, &pfx_2_2_2_2_s_32);
7213 FIB_TEST(fib_test_validate_entry(fei,
7214 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7215 1,
7216 &l1600_eos_o_1_1_1_1),
7217 "2.2.2.2/32 LB 1 buckets via: "
7218 "label 1600 via 1.1,1.1");
7219
7220 fib_table_entry_delete(fib_index,
7221 &pfx_1_1_1_1_s_32,
7222 FIB_SOURCE_API);
7223
7224 FIB_TEST(fib_test_validate_entry(fei,
7225 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7226 1,
7227 &bucket_drop),
7228 "2.2.2.2/32 LB 1 buckets via: DROP");
7229
7230 fib_table_entry_delete(fib_index,
7231 &pfx_2_2_2_2_s_32,
7232 FIB_SOURCE_API);
7233 fib_table_entry_delete(fib_index,
7234 &pfx_2_2_2_3_s_32,
7235 FIB_SOURCE_API);
7236 fib_table_entry_delete(fib_index,
7237 &pfx_2_2_2_4_s_32,
7238 FIB_SOURCE_API);
7239
7240 adj_unlock(ai_mpls_10_10_10_1);
7241 adj_unlock(ai_mpls_10_10_11_2);
7242 adj_unlock(ai_v4_10_10_11_1);
7243 adj_unlock(ai_v4_10_10_11_2);
7244 adj_unlock(ai_mpls_10_10_11_1);
7245
7246 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
7247 adj_nbr_db_size());
7248
7249 local0_pfx.fp_len = 32;
7250 fib_table_entry_delete(fib_index,
7251 &local0_pfx,
7252 FIB_SOURCE_INTERFACE);
7253 local0_pfx.fp_len = 24;
7254 fib_table_entry_delete(fib_index,
7255 &local0_pfx,
7256 FIB_SOURCE_INTERFACE);
7257 local1_pfx.fp_len = 32;
7258 fib_table_entry_delete(fib_index,
7259 &local1_pfx,
7260 FIB_SOURCE_INTERFACE);
7261 local1_pfx.fp_len = 24;
7262 fib_table_entry_delete(fib_index,
7263 &local1_pfx,
7264 FIB_SOURCE_INTERFACE);
7265
7266 /*
7267 * +1 for the drop LB in the MPLS tables.
7268 */
7269 FIB_TEST(lb_count+1 == pool_elts(load_balance_pool),
7270 "Load-balance resources freed %d of %d",
7271 lb_count+1, pool_elts(load_balance_pool));
Neale Ranns0ebe8d72016-12-08 19:48:11 +00007272
7273 return (0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007274}
7275
7276#define N_TEST_CHILDREN 4
7277#define PARENT_INDEX 0
7278
7279typedef struct fib_node_test_t_
7280{
7281 fib_node_t node;
7282 u32 sibling;
7283 u32 index;
7284 fib_node_back_walk_ctx_t *ctxs;
7285 u32 destroyed;
7286} fib_node_test_t;
7287
7288static fib_node_test_t fib_test_nodes[N_TEST_CHILDREN+1];
7289
7290#define PARENT() (&fib_test_nodes[PARENT_INDEX].node)
7291
7292#define FOR_EACH_TEST_CHILD(_tc) \
7293 for (ii = 1, (_tc) = &fib_test_nodes[1]; \
7294 ii < N_TEST_CHILDREN+1; \
7295 ii++, (_tc) = &fib_test_nodes[ii])
7296
7297static fib_node_t *
7298fib_test_child_get_node (fib_node_index_t index)
7299{
7300 return (&fib_test_nodes[index].node);
7301}
7302
7303static int fib_test_walk_spawns_walks;
7304
7305static fib_node_back_walk_rc_t
7306fib_test_child_back_walk_notify (fib_node_t *node,
7307 fib_node_back_walk_ctx_t *ctx)
7308{
7309 fib_node_test_t *tc = (fib_node_test_t*) node;
7310
7311 vec_add1(tc->ctxs, *ctx);
7312
7313 if (1 == fib_test_walk_spawns_walks)
7314 fib_walk_sync(FIB_NODE_TYPE_TEST, tc->index, ctx);
7315 if (2 == fib_test_walk_spawns_walks)
7316 fib_walk_async(FIB_NODE_TYPE_TEST, tc->index,
7317 FIB_WALK_PRIORITY_HIGH, ctx);
7318
7319 return (FIB_NODE_BACK_WALK_CONTINUE);
7320}
7321
7322static void
7323fib_test_child_last_lock_gone (fib_node_t *node)
7324{
7325 fib_node_test_t *tc = (fib_node_test_t *)node;
7326
7327 tc->destroyed = 1;
7328}
7329
7330/**
7331 * The FIB walk's graph node virtual function table
7332 */
7333static const fib_node_vft_t fib_test_child_vft = {
7334 .fnv_get = fib_test_child_get_node,
7335 .fnv_last_lock = fib_test_child_last_lock_gone,
7336 .fnv_back_walk = fib_test_child_back_walk_notify,
7337};
7338
7339/*
7340 * the function (that should have been static but isn't so I can do this)
7341 * that processes the walk from the async queue,
7342 */
7343f64 fib_walk_process_queues(vlib_main_t * vm,
7344 const f64 quota);
7345u32 fib_walk_queue_get_size(fib_walk_priority_t prio);
7346
Neale Ranns0ebe8d72016-12-08 19:48:11 +00007347static int
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007348fib_test_walk (void)
7349{
7350 fib_node_back_walk_ctx_t high_ctx = {}, low_ctx = {};
7351 fib_node_test_t *tc;
7352 vlib_main_t *vm;
7353 u32 ii;
7354
7355 vm = vlib_get_main();
7356 fib_node_register_type(FIB_NODE_TYPE_TEST, &fib_test_child_vft);
7357
7358 /*
7359 * init a fake node on which we will add children
7360 */
7361 fib_node_init(&fib_test_nodes[PARENT_INDEX].node,
7362 FIB_NODE_TYPE_TEST);
7363
7364 FOR_EACH_TEST_CHILD(tc)
7365 {
7366 fib_node_init(&tc->node, FIB_NODE_TYPE_TEST);
7367 fib_node_lock(&tc->node);
7368 tc->ctxs = NULL;
7369 tc->index = ii;
7370 tc->sibling = fib_node_child_add(FIB_NODE_TYPE_TEST,
7371 PARENT_INDEX,
7372 FIB_NODE_TYPE_TEST, ii);
7373 }
7374
7375 /*
7376 * enqueue a walk across the parents children.
7377 */
Neale Ranns450cd302016-11-09 17:49:42 +00007378 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007379
7380 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7381 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7382 FIB_TEST(N_TEST_CHILDREN+1 == fib_node_list_get_size(PARENT()->fn_children),
7383 "Parent has %d children pre-walk",
7384 fib_node_list_get_size(PARENT()->fn_children));
7385
7386 /*
7387 * give the walk a large amount of time so it gets to the end
7388 */
7389 fib_walk_process_queues(vm, 1);
7390
7391 FOR_EACH_TEST_CHILD(tc)
7392 {
7393 FIB_TEST(1 == vec_len(tc->ctxs),
7394 "%d child visitsed %d times",
7395 ii, vec_len(tc->ctxs));
7396 vec_free(tc->ctxs);
7397 }
7398 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7399 "Queue is empty post walk");
7400 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7401 "Parent has %d children post walk",
7402 fib_node_list_get_size(PARENT()->fn_children));
7403
7404 /*
7405 * walk again. should be no increase in the number of visits, since
7406 * the walk will have terminated.
7407 */
7408 fib_walk_process_queues(vm, 1);
7409
7410 FOR_EACH_TEST_CHILD(tc)
7411 {
7412 FIB_TEST(0 == vec_len(tc->ctxs),
7413 "%d child visitsed %d times",
7414 ii, vec_len(tc->ctxs));
7415 }
7416
7417 /*
7418 * schedule a low and hig priority walk. expect the high to be performed
7419 * before the low.
7420 * schedule the high prio walk first so that it is further from the head
7421 * of the dependency list. that way it won't merge with the low one.
7422 */
7423 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
7424 low_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_ADJ_UPDATE;
7425
7426 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7427 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7428 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7429 FIB_WALK_PRIORITY_LOW, &low_ctx);
7430
7431 fib_walk_process_queues(vm, 1);
7432
7433 FOR_EACH_TEST_CHILD(tc)
7434 {
7435 FIB_TEST(high_ctx.fnbw_reason == tc->ctxs[0].fnbw_reason,
7436 "%d child visitsed by high prio walk", ii);
7437 FIB_TEST(low_ctx.fnbw_reason == tc->ctxs[1].fnbw_reason,
7438 "%d child visitsed by low prio walk", ii);
7439 vec_free(tc->ctxs);
7440 }
7441 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7442 "Queue is empty post prio walk");
7443 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7444 "Parent has %d children post prio walk",
7445 fib_node_list_get_size(PARENT()->fn_children));
7446
7447 /*
7448 * schedule 2 walks of the same priority that can be megred.
7449 * expect that each child is thus visited only once.
7450 */
7451 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
7452 low_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
7453
7454 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7455 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7456 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7457 FIB_WALK_PRIORITY_HIGH, &low_ctx);
7458
7459 fib_walk_process_queues(vm, 1);
7460
7461 FOR_EACH_TEST_CHILD(tc)
7462 {
7463 FIB_TEST(1 == vec_len(tc->ctxs),
7464 "%d child visitsed %d times during merge walk",
7465 ii, vec_len(tc->ctxs));
7466 vec_free(tc->ctxs);
7467 }
7468 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7469 "Queue is empty post merge walk");
7470 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7471 "Parent has %d children post merge walk",
7472 fib_node_list_get_size(PARENT()->fn_children));
7473
7474 /*
7475 * schedule 2 walks of the same priority that cannot be megred.
7476 * expect that each child is thus visited twice and in the order
7477 * in which the walks were scheduled.
7478 */
7479 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
7480 low_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_ADJ_UPDATE;
7481
7482 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7483 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7484 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7485 FIB_WALK_PRIORITY_HIGH, &low_ctx);
7486
7487 fib_walk_process_queues(vm, 1);
7488
7489 FOR_EACH_TEST_CHILD(tc)
7490 {
7491 FIB_TEST(high_ctx.fnbw_reason == tc->ctxs[0].fnbw_reason,
7492 "%d child visitsed by high prio walk", ii);
7493 FIB_TEST(low_ctx.fnbw_reason == tc->ctxs[1].fnbw_reason,
7494 "%d child visitsed by low prio walk", ii);
7495 vec_free(tc->ctxs);
7496 }
7497 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7498 "Queue is empty post no-merge walk");
7499 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7500 "Parent has %d children post no-merge walk",
7501 fib_node_list_get_size(PARENT()->fn_children));
7502
7503 /*
7504 * schedule a walk that makes one one child progress.
7505 * we do this by giving the queue draining process zero
7506 * time quanta. it's a do..while loop, so it does something.
7507 */
Neale Ranns450cd302016-11-09 17:49:42 +00007508 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007509
7510 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7511 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7512 fib_walk_process_queues(vm, 0);
7513
7514 FOR_EACH_TEST_CHILD(tc)
7515 {
7516 if (ii == N_TEST_CHILDREN)
7517 {
7518 FIB_TEST(1 == vec_len(tc->ctxs),
7519 "%d child visitsed %d times in zero quanta walk",
7520 ii, vec_len(tc->ctxs));
7521 }
7522 else
7523 {
7524 FIB_TEST(0 == vec_len(tc->ctxs),
7525 "%d child visitsed %d times in 0 quanta walk",
7526 ii, vec_len(tc->ctxs));
7527 }
7528 }
7529 FIB_TEST(1 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7530 "Queue is not empty post zero quanta walk");
7531 FIB_TEST(N_TEST_CHILDREN+1 == fib_node_list_get_size(PARENT()->fn_children),
7532 "Parent has %d children post zero qunta walk",
7533 fib_node_list_get_size(PARENT()->fn_children));
7534
7535 /*
7536 * another one step
7537 */
7538 fib_walk_process_queues(vm, 0);
7539
7540 FOR_EACH_TEST_CHILD(tc)
7541 {
7542 if (ii >= N_TEST_CHILDREN-1)
7543 {
7544 FIB_TEST(1 == vec_len(tc->ctxs),
7545 "%d child visitsed %d times in 2nd zero quanta walk",
7546 ii, vec_len(tc->ctxs));
7547 }
7548 else
7549 {
7550 FIB_TEST(0 == vec_len(tc->ctxs),
7551 "%d child visitsed %d times in 2nd 0 quanta walk",
7552 ii, vec_len(tc->ctxs));
7553 }
7554 }
7555 FIB_TEST(1 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7556 "Queue is not empty post zero quanta walk");
7557 FIB_TEST(N_TEST_CHILDREN+1 == fib_node_list_get_size(PARENT()->fn_children),
7558 "Parent has %d children post zero qunta walk",
7559 fib_node_list_get_size(PARENT()->fn_children));
7560
7561 /*
7562 * schedule another walk that will catch-up and merge.
7563 */
7564 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7565 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7566 fib_walk_process_queues(vm, 1);
7567
7568 FOR_EACH_TEST_CHILD(tc)
7569 {
7570 if (ii >= N_TEST_CHILDREN-1)
7571 {
7572 FIB_TEST(2 == vec_len(tc->ctxs),
7573 "%d child visitsed %d times in 2nd zero quanta merge walk",
7574 ii, vec_len(tc->ctxs));
7575 vec_free(tc->ctxs);
7576 }
7577 else
7578 {
7579 FIB_TEST(1 == vec_len(tc->ctxs),
7580 "%d child visitsed %d times in 2nd 0 quanta merge walk",
7581 ii, vec_len(tc->ctxs));
7582 vec_free(tc->ctxs);
7583 }
7584 }
7585 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7586 "Queue is not empty post 2nd zero quanta merge walk");
7587 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7588 "Parent has %d children post 2nd zero qunta merge walk",
7589 fib_node_list_get_size(PARENT()->fn_children));
7590
7591 /*
7592 * park a async walk in the middle of the list, then have an sync walk catch
7593 * it. same expectations as async catches async.
7594 */
Neale Ranns450cd302016-11-09 17:49:42 +00007595 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007596
7597 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7598 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7599
7600 fib_walk_process_queues(vm, 0);
7601 fib_walk_process_queues(vm, 0);
7602
7603 fib_walk_sync(FIB_NODE_TYPE_TEST, PARENT_INDEX, &high_ctx);
7604
7605 FOR_EACH_TEST_CHILD(tc)
7606 {
7607 if (ii >= N_TEST_CHILDREN-1)
7608 {
7609 FIB_TEST(2 == vec_len(tc->ctxs),
7610 "%d child visitsed %d times in sync catches async walk",
7611 ii, vec_len(tc->ctxs));
7612 vec_free(tc->ctxs);
7613 }
7614 else
7615 {
7616 FIB_TEST(1 == vec_len(tc->ctxs),
7617 "%d child visitsed %d times in sync catches async walk",
7618 ii, vec_len(tc->ctxs));
7619 vec_free(tc->ctxs);
7620 }
7621 }
7622 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7623 "Queue is not empty post 2nd zero quanta merge walk");
7624 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7625 "Parent has %d children post 2nd zero qunta merge walk",
7626 fib_node_list_get_size(PARENT()->fn_children));
7627
7628 /*
7629 * make the parent a child of one of its children, thus inducing a routing loop.
7630 */
7631 fib_test_nodes[PARENT_INDEX].sibling =
7632 fib_node_child_add(FIB_NODE_TYPE_TEST,
7633 1, // the first child
7634 FIB_NODE_TYPE_TEST,
7635 PARENT_INDEX);
7636
7637 /*
7638 * execute a sync walk from the parent. each child visited spawns more sync
7639 * walks. we expect the walk to terminate.
7640 */
7641 fib_test_walk_spawns_walks = 1;
7642
7643 fib_walk_sync(FIB_NODE_TYPE_TEST, PARENT_INDEX, &high_ctx);
7644
7645 FOR_EACH_TEST_CHILD(tc)
7646 {
7647 /*
7648 * child 1 - which is last in the list - has the loop.
7649 * the other children a re thus visitsed first. the we meet
7650 * child 1. we go round the loop again, visting the other children.
7651 * then we meet the walk in the dep list and bail. child 1 is not visitsed
7652 * again.
7653 */
7654 if (1 == ii)
7655 {
7656 FIB_TEST(1 == vec_len(tc->ctxs),
7657 "child %d visitsed %d times during looped sync walk",
7658 ii, vec_len(tc->ctxs));
7659 }
7660 else
7661 {
7662 FIB_TEST(2 == vec_len(tc->ctxs),
7663 "child %d visitsed %d times during looped sync walk",
7664 ii, vec_len(tc->ctxs));
7665 }
7666 vec_free(tc->ctxs);
7667 }
7668 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7669 "Parent has %d children post sync loop walk",
7670 fib_node_list_get_size(PARENT()->fn_children));
7671
7672 /*
7673 * the walk doesn't reach the max depth because the infra knows that sync
7674 * meets sync implies a loop and bails early.
7675 */
7676 FIB_TEST(high_ctx.fnbw_depth == 9,
7677 "Walk context depth %d post sync loop walk",
7678 high_ctx.fnbw_depth);
7679
7680 /*
7681 * execute an async walk of the graph loop, with each child spawns sync walks
7682 */
7683 high_ctx.fnbw_depth = 0;
7684 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7685 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7686
7687 fib_walk_process_queues(vm, 1);
7688
7689 FOR_EACH_TEST_CHILD(tc)
7690 {
7691 /*
7692 * we don't really care how many times the children are visisted, as long as
7693 * it is more than once.
7694 */
7695 FIB_TEST(1 <= vec_len(tc->ctxs),
7696 "child %d visitsed %d times during looped aync spawns sync walk",
7697 ii, vec_len(tc->ctxs));
7698 vec_free(tc->ctxs);
7699 }
7700
7701 /*
7702 * execute an async walk of the graph loop, with each child spawns async walks
7703 */
7704 fib_test_walk_spawns_walks = 2;
7705 high_ctx.fnbw_depth = 0;
7706 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7707 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7708
7709 fib_walk_process_queues(vm, 1);
7710
7711 FOR_EACH_TEST_CHILD(tc)
7712 {
7713 /*
7714 * we don't really care how many times the children are visisted, as long as
7715 * it is more than once.
7716 */
7717 FIB_TEST(1 <= vec_len(tc->ctxs),
7718 "child %d visitsed %d times during looped async spawns async walk",
7719 ii, vec_len(tc->ctxs));
7720 vec_free(tc->ctxs);
7721 }
7722
7723
7724 fib_node_child_remove(FIB_NODE_TYPE_TEST,
7725 1, // the first child
7726 fib_test_nodes[PARENT_INDEX].sibling);
7727
7728 /*
7729 * cleanup
7730 */
7731 FOR_EACH_TEST_CHILD(tc)
7732 {
7733 fib_node_child_remove(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7734 tc->sibling);
7735 fib_node_deinit(&tc->node);
7736 fib_node_unlock(&tc->node);
7737 }
7738 fib_node_deinit(PARENT());
7739
7740 /*
7741 * The parent will be destroyed when the last lock on it goes.
7742 * this test ensures all the walk objects are unlocking it.
7743 */
7744 FIB_TEST((1 == fib_test_nodes[PARENT_INDEX].destroyed),
7745 "Parent was destroyed");
Neale Ranns0ebe8d72016-12-08 19:48:11 +00007746
7747 return (0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007748}
7749
Neale Ranns88fc83e2017-04-05 08:11:14 -07007750/*
7751 * declaration of the otherwise static callback functions
7752 */
7753void fib_bfd_notify (bfd_listen_event_e event,
7754 const bfd_session_t *session);
7755void adj_bfd_notify (bfd_listen_event_e event,
7756 const bfd_session_t *session);
7757
7758/**
7759 * Test BFD session interaction with FIB
7760 */
7761static int
7762fib_test_bfd (void)
7763{
7764 fib_node_index_t fei;
7765 test_main_t *tm;
7766 int n_feis;
7767
7768 /* via 10.10.10.1 */
7769 ip46_address_t nh_10_10_10_1 = {
7770 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
7771 };
7772 /* via 10.10.10.2 */
7773 ip46_address_t nh_10_10_10_2 = {
7774 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02),
7775 };
7776 /* via 10.10.10.10 */
7777 ip46_address_t nh_10_10_10_10 = {
7778 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a0a),
7779 };
7780 n_feis = fib_entry_pool_size();
7781
7782 tm = &test_main;
7783
7784 /*
7785 * add interface routes. we'll assume this works. it's tested elsewhere
7786 */
7787 fib_prefix_t pfx_10_10_10_10_s_24 = {
7788 .fp_len = 24,
7789 .fp_proto = FIB_PROTOCOL_IP4,
7790 .fp_addr = nh_10_10_10_10,
7791 };
7792
7793 fib_table_entry_update_one_path(0, &pfx_10_10_10_10_s_24,
7794 FIB_SOURCE_INTERFACE,
7795 (FIB_ENTRY_FLAG_CONNECTED |
7796 FIB_ENTRY_FLAG_ATTACHED),
Neale Rannsda78f952017-05-24 09:15:43 -07007797 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07007798 NULL,
7799 tm->hw[0]->sw_if_index,
7800 ~0, // invalid fib index
7801 1, // weight
7802 NULL,
7803 FIB_ROUTE_PATH_FLAG_NONE);
7804
7805 fib_prefix_t pfx_10_10_10_10_s_32 = {
7806 .fp_len = 32,
7807 .fp_proto = FIB_PROTOCOL_IP4,
7808 .fp_addr = nh_10_10_10_10,
7809 };
7810 fib_table_entry_update_one_path(0, &pfx_10_10_10_10_s_32,
7811 FIB_SOURCE_INTERFACE,
7812 (FIB_ENTRY_FLAG_CONNECTED |
7813 FIB_ENTRY_FLAG_LOCAL),
Neale Rannsda78f952017-05-24 09:15:43 -07007814 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07007815 NULL,
7816 tm->hw[0]->sw_if_index,
7817 ~0, // invalid fib index
7818 1, // weight
7819 NULL,
7820 FIB_ROUTE_PATH_FLAG_NONE);
7821
7822 /*
7823 * A BFD session via a neighbour we do not yet know
7824 */
7825 bfd_session_t bfd_10_10_10_1 = {
7826 .udp = {
7827 .key = {
7828 .fib_index = 0,
7829 .peer_addr = nh_10_10_10_1,
7830 },
7831 },
7832 .hop_type = BFD_HOP_TYPE_MULTI,
7833 .local_state = BFD_STATE_init,
7834 };
7835
7836 fib_bfd_notify (BFD_LISTEN_EVENT_CREATE, &bfd_10_10_10_1);
7837
7838 /*
7839 * A new entry will be created that forwards via the adj
7840 */
7841 adj_index_t ai_10_10_10_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
7842 VNET_LINK_IP4,
7843 &nh_10_10_10_1,
7844 tm->hw[0]->sw_if_index);
7845 fib_prefix_t pfx_10_10_10_1_s_32 = {
7846 .fp_addr = nh_10_10_10_1,
7847 .fp_len = 32,
7848 .fp_proto = FIB_PROTOCOL_IP4,
7849 };
7850 fib_test_lb_bucket_t adj_o_10_10_10_1 = {
7851 .type = FT_LB_ADJ,
7852 .adj = {
7853 .adj = ai_10_10_10_1,
7854 },
7855 };
7856
7857 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_1_s_32);
7858 FIB_TEST(fib_test_validate_entry(fei,
7859 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7860 1,
7861 &adj_o_10_10_10_1),
7862 "BFD sourced %U via %U",
7863 format_fib_prefix, &pfx_10_10_10_1_s_32,
7864 format_ip_adjacency, ai_10_10_10_1, FORMAT_IP_ADJACENCY_NONE);
7865
7866 /*
7867 * Delete the BFD session. Expect the fib_entry to be removed
7868 */
7869 fib_bfd_notify (BFD_LISTEN_EVENT_DELETE, &bfd_10_10_10_1);
7870
7871 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_1_s_32);
7872 FIB_TEST(FIB_NODE_INDEX_INVALID == fei,
7873 "BFD sourced %U removed",
7874 format_fib_prefix, &pfx_10_10_10_1_s_32);
7875
7876 /*
7877 * Add the BFD source back
7878 */
7879 fib_bfd_notify (BFD_LISTEN_EVENT_CREATE, &bfd_10_10_10_1);
7880
7881 /*
7882 * source the entry via the ADJ fib
7883 */
Neale Ranns81424992017-05-18 03:03:22 -07007884 fei = fib_table_entry_path_add(0,
7885 &pfx_10_10_10_1_s_32,
7886 FIB_SOURCE_ADJ,
7887 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07007888 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07007889 &nh_10_10_10_1,
7890 tm->hw[0]->sw_if_index,
7891 ~0, // invalid fib index
7892 1,
7893 NULL,
7894 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns88fc83e2017-04-05 08:11:14 -07007895
7896 /*
7897 * Delete the BFD session. Expect the fib_entry to remain
7898 */
7899 fib_bfd_notify (BFD_LISTEN_EVENT_DELETE, &bfd_10_10_10_1);
7900
7901 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_1_s_32);
7902 FIB_TEST(fib_test_validate_entry(fei,
7903 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7904 1,
7905 &adj_o_10_10_10_1),
7906 "BFD sourced %U remains via %U",
7907 format_fib_prefix, &pfx_10_10_10_1_s_32,
7908 format_ip_adjacency, ai_10_10_10_1, FORMAT_IP_ADJACENCY_NONE);
7909
7910 /*
7911 * Add the BFD source back
7912 */
7913 fib_bfd_notify (BFD_LISTEN_EVENT_CREATE, &bfd_10_10_10_1);
7914
7915 /*
7916 * Create another ADJ FIB
7917 */
7918 fib_prefix_t pfx_10_10_10_2_s_32 = {
7919 .fp_addr = nh_10_10_10_2,
7920 .fp_len = 32,
7921 .fp_proto = FIB_PROTOCOL_IP4,
7922 };
Neale Ranns81424992017-05-18 03:03:22 -07007923 fib_table_entry_path_add(0,
7924 &pfx_10_10_10_2_s_32,
7925 FIB_SOURCE_ADJ,
7926 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07007927 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07007928 &nh_10_10_10_2,
7929 tm->hw[0]->sw_if_index,
7930 ~0, // invalid fib index
7931 1,
7932 NULL,
7933 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns88fc83e2017-04-05 08:11:14 -07007934 /*
7935 * A BFD session for the new ADJ FIB
7936 */
7937 bfd_session_t bfd_10_10_10_2 = {
7938 .udp = {
7939 .key = {
7940 .fib_index = 0,
7941 .peer_addr = nh_10_10_10_2,
7942 },
7943 },
7944 .hop_type = BFD_HOP_TYPE_MULTI,
7945 .local_state = BFD_STATE_init,
7946 };
7947
7948 fib_bfd_notify (BFD_LISTEN_EVENT_CREATE, &bfd_10_10_10_2);
7949
7950 /*
7951 * remove the adj-fib source whilst the session is present
7952 * then add it back
7953 */
7954 fib_table_entry_delete(0, &pfx_10_10_10_2_s_32, FIB_SOURCE_ADJ);
Neale Ranns81424992017-05-18 03:03:22 -07007955 fib_table_entry_path_add(0,
7956 &pfx_10_10_10_2_s_32,
7957 FIB_SOURCE_ADJ,
7958 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07007959 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07007960 &nh_10_10_10_2,
7961 tm->hw[0]->sw_if_index,
7962 ~0, // invalid fib index
7963 1,
7964 NULL,
7965 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns88fc83e2017-04-05 08:11:14 -07007966
7967 /*
7968 * Before adding a recursive via the BFD tracked ADJ-FIBs,
7969 * bring one of the sessions UP, leave the other down
7970 */
7971 bfd_10_10_10_1.local_state = BFD_STATE_up;
7972 fib_bfd_notify (BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_1);
7973 bfd_10_10_10_2.local_state = BFD_STATE_down;
7974 fib_bfd_notify (BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_2);
7975
7976 /*
7977 * A recursive prefix via both of the ADJ FIBs
7978 */
7979 fib_prefix_t pfx_200_0_0_0_s_24 = {
7980 .fp_proto = FIB_PROTOCOL_IP4,
7981 .fp_len = 32,
7982 .fp_addr = {
7983 .ip4.as_u32 = clib_host_to_net_u32(0xc8000000),
7984 },
7985 };
7986 const dpo_id_t *dpo_10_10_10_1, *dpo_10_10_10_2;
7987
7988 dpo_10_10_10_1 =
7989 fib_entry_contribute_ip_forwarding(
7990 fib_table_lookup_exact_match(0, &pfx_10_10_10_1_s_32));
7991 dpo_10_10_10_2 =
7992 fib_entry_contribute_ip_forwarding(
7993 fib_table_lookup_exact_match(0, &pfx_10_10_10_2_s_32));
7994
7995 fib_test_lb_bucket_t lb_o_10_10_10_1 = {
7996 .type = FT_LB_O_LB,
7997 .lb = {
7998 .lb = dpo_10_10_10_1->dpoi_index,
7999 },
8000 };
8001 fib_test_lb_bucket_t lb_o_10_10_10_2 = {
8002 .type = FT_LB_O_LB,
8003 .lb = {
8004 .lb = dpo_10_10_10_2->dpoi_index,
8005 },
8006 };
8007
8008 /*
8009 * A prefix via the adj-fib that is BFD down => DROP
8010 */
8011 fei = fib_table_entry_path_add(0,
8012 &pfx_200_0_0_0_s_24,
8013 FIB_SOURCE_API,
8014 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008015 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07008016 &nh_10_10_10_2,
8017 ~0, // recursive
8018 0, // default fib index
8019 1,
8020 NULL,
8021 FIB_ROUTE_PATH_FLAG_NONE);
8022 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
8023 "%U resolves via drop",
8024 format_fib_prefix, &pfx_200_0_0_0_s_24);
8025
8026 /*
8027 * add a path via the UP BFD adj-fib.
8028 * we expect that the DOWN BFD ADJ FIB is not used.
8029 */
8030 fei = fib_table_entry_path_add(0,
8031 &pfx_200_0_0_0_s_24,
8032 FIB_SOURCE_API,
8033 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008034 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07008035 &nh_10_10_10_1,
8036 ~0, // recursive
8037 0, // default fib index
8038 1,
8039 NULL,
8040 FIB_ROUTE_PATH_FLAG_NONE);
8041
8042 FIB_TEST(fib_test_validate_entry(fei,
8043 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8044 1,
8045 &lb_o_10_10_10_1),
8046 "Recursive %U only UP BFD adj-fibs",
8047 format_fib_prefix, &pfx_200_0_0_0_s_24);
8048
8049 /*
8050 * Send a BFD state change to UP - both sessions are now up
8051 * the recursive prefix should LB over both
8052 */
8053 bfd_10_10_10_2.local_state = BFD_STATE_up;
8054 fib_bfd_notify (BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_2);
8055
8056
8057 FIB_TEST(fib_test_validate_entry(fei,
8058 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8059 2,
8060 &lb_o_10_10_10_1,
8061 &lb_o_10_10_10_2),
8062 "Recursive %U via both UP BFD adj-fibs",
8063 format_fib_prefix, &pfx_200_0_0_0_s_24);
8064
8065 /*
8066 * Send a BFD state change to DOWN
8067 * the recursive prefix should exclude the down
8068 */
8069 bfd_10_10_10_2.local_state = BFD_STATE_down;
8070 fib_bfd_notify (BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_2);
8071
8072
8073 FIB_TEST(fib_test_validate_entry(fei,
8074 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8075 1,
8076 &lb_o_10_10_10_1),
8077 "Recursive %U via only UP",
8078 format_fib_prefix, &pfx_200_0_0_0_s_24);
8079
8080 /*
8081 * Delete the BFD session while it is in the DOWN state.
8082 * FIB should consider the entry's state as back up
8083 */
8084 fib_bfd_notify (BFD_LISTEN_EVENT_DELETE, &bfd_10_10_10_2);
8085
8086 FIB_TEST(fib_test_validate_entry(fei,
8087 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8088 2,
8089 &lb_o_10_10_10_1,
8090 &lb_o_10_10_10_2),
8091 "Recursive %U via both UP BFD adj-fibs post down session delete",
8092 format_fib_prefix, &pfx_200_0_0_0_s_24);
8093
8094 /*
8095 * Delete the BFD other session while it is in the UP state.
8096 */
8097 fib_bfd_notify (BFD_LISTEN_EVENT_DELETE, &bfd_10_10_10_1);
8098
8099 FIB_TEST(fib_test_validate_entry(fei,
8100 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8101 2,
8102 &lb_o_10_10_10_1,
8103 &lb_o_10_10_10_2),
8104 "Recursive %U via both UP BFD adj-fibs post up session delete",
8105 format_fib_prefix, &pfx_200_0_0_0_s_24);
8106
8107 /*
8108 * cleaup
8109 */
8110 fib_table_entry_delete(0, &pfx_200_0_0_0_s_24, FIB_SOURCE_API);
8111 fib_table_entry_delete(0, &pfx_10_10_10_1_s_32, FIB_SOURCE_ADJ);
8112 fib_table_entry_delete(0, &pfx_10_10_10_2_s_32, FIB_SOURCE_ADJ);
8113
8114 fib_table_entry_delete(0, &pfx_10_10_10_10_s_32, FIB_SOURCE_INTERFACE);
8115 fib_table_entry_delete(0, &pfx_10_10_10_10_s_24, FIB_SOURCE_INTERFACE);
8116
8117 adj_unlock(ai_10_10_10_1);
8118 /*
8119 * test no-one left behind
8120 */
8121 FIB_TEST((n_feis == fib_entry_pool_size()), "Entries gone");
8122 FIB_TEST(0 == adj_nbr_db_size(), "All adjacencies removed");
8123
8124 /*
8125 * Single-hop BFD tests
8126 */
8127 bfd_10_10_10_1.hop_type = BFD_HOP_TYPE_SINGLE;
8128 bfd_10_10_10_1.udp.key.sw_if_index = tm->hw[0]->sw_if_index;
8129
8130 adj_bfd_notify(BFD_LISTEN_EVENT_CREATE, &bfd_10_10_10_1);
8131
8132 ai_10_10_10_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
8133 VNET_LINK_IP4,
8134 &nh_10_10_10_1,
8135 tm->hw[0]->sw_if_index);
8136 /*
8137 * whilst the BFD session is not signalled, the adj is up
8138 */
8139 FIB_TEST(adj_is_up(ai_10_10_10_1), "Adj state up on uninit session");
8140
8141 /*
8142 * bring the BFD session up
8143 */
8144 bfd_10_10_10_1.local_state = BFD_STATE_up;
8145 adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_1);
8146 FIB_TEST(adj_is_up(ai_10_10_10_1), "Adj state up on UP session");
8147
8148 /*
8149 * bring the BFD session down
8150 */
8151 bfd_10_10_10_1.local_state = BFD_STATE_down;
8152 adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_1);
8153 FIB_TEST(!adj_is_up(ai_10_10_10_1), "Adj state down on DOWN session");
8154
8155
8156 /*
8157 * add an attached next hop FIB entry via the down adj
8158 */
8159 fib_prefix_t pfx_5_5_5_5_s_32 = {
8160 .fp_addr = {
8161 .ip4 = {
8162 .as_u32 = clib_host_to_net_u32(0x05050505),
8163 },
8164 },
8165 .fp_len = 32,
8166 .fp_proto = FIB_PROTOCOL_IP4,
8167 };
8168
8169 fei = fib_table_entry_path_add(0,
8170 &pfx_5_5_5_5_s_32,
8171 FIB_SOURCE_CLI,
8172 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008173 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07008174 &nh_10_10_10_1,
8175 tm->hw[0]->sw_if_index,
8176 ~0, // invalid fib index
8177 1,
8178 NULL,
8179 FIB_ROUTE_PATH_FLAG_NONE);
8180 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
8181 "%U resolves via drop",
8182 format_fib_prefix, &pfx_5_5_5_5_s_32);
8183
8184 /*
8185 * Add a path via an ADJ that is up
8186 */
8187 adj_index_t ai_10_10_10_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
8188 VNET_LINK_IP4,
8189 &nh_10_10_10_2,
8190 tm->hw[0]->sw_if_index);
8191
8192 fib_test_lb_bucket_t adj_o_10_10_10_2 = {
8193 .type = FT_LB_ADJ,
8194 .adj = {
8195 .adj = ai_10_10_10_2,
8196 },
8197 };
8198 adj_o_10_10_10_1.adj.adj = ai_10_10_10_1;
8199
8200 fei = fib_table_entry_path_add(0,
8201 &pfx_5_5_5_5_s_32,
8202 FIB_SOURCE_CLI,
8203 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008204 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07008205 &nh_10_10_10_2,
8206 tm->hw[0]->sw_if_index,
8207 ~0, // invalid fib index
8208 1,
8209 NULL,
8210 FIB_ROUTE_PATH_FLAG_NONE);
8211
8212 FIB_TEST(fib_test_validate_entry(fei,
8213 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8214 1,
8215 &adj_o_10_10_10_2),
8216 "BFD sourced %U via %U",
8217 format_fib_prefix, &pfx_5_5_5_5_s_32,
8218 format_ip_adjacency, ai_10_10_10_2, FORMAT_IP_ADJACENCY_NONE);
8219
8220 /*
8221 * Bring up the down session - should now LB
8222 */
8223 bfd_10_10_10_1.local_state = BFD_STATE_up;
8224 adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_1);
8225 FIB_TEST(fib_test_validate_entry(fei,
8226 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8227 2,
8228 &adj_o_10_10_10_1,
8229 &adj_o_10_10_10_2),
8230 "BFD sourced %U via noth adjs",
8231 format_fib_prefix, &pfx_5_5_5_5_s_32);
8232
8233 /*
8234 * remove the BFD session state from the adj
8235 */
8236 adj_bfd_notify(BFD_LISTEN_EVENT_DELETE, &bfd_10_10_10_1);
8237
8238 /*
8239 * clean-up
8240 */
8241 fib_table_entry_delete(0, &pfx_5_5_5_5_s_32, FIB_SOURCE_CLI);
8242 adj_unlock(ai_10_10_10_1);
8243 adj_unlock(ai_10_10_10_2);
8244
8245 /*
8246 * test no-one left behind
8247 */
8248 FIB_TEST((n_feis == fib_entry_pool_size()), "Entries gone");
8249 FIB_TEST(0 == adj_nbr_db_size(), "All adjacencies removed");
8250 return (0);
8251}
8252
Neale Ranns0ebe8d72016-12-08 19:48:11 +00008253static int
8254lfib_test (void)
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008255{
8256 const mpls_label_t deag_label = 50;
8257 const u32 lfib_index = 0;
8258 const u32 fib_index = 0;
Neale Ranns948e00f2016-10-20 13:39:34 +01008259 dpo_id_t dpo = DPO_INVALID;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008260 const dpo_id_t *dpo1;
8261 fib_node_index_t lfe;
8262 lookup_dpo_t *lkd;
8263 test_main_t *tm;
8264 int lb_count;
Neale Rannsad422ed2016-11-02 14:20:04 +00008265 adj_index_t ai_mpls_10_10_10_1;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008266
8267 tm = &test_main;
8268 lb_count = pool_elts(load_balance_pool);
8269
8270 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
8271 adj_nbr_db_size());
8272
8273 /*
8274 * MPLS enable an interface so we get the MPLS table created
8275 */
Neale Ranns2297af02017-09-12 09:45:04 -07008276 mpls_table_create(MPLS_FIB_DEFAULT_TABLE_ID, FIB_SOURCE_API, NULL);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008277 mpls_sw_interface_enable_disable(&mpls_main,
8278 tm->hw[0]->sw_if_index,
Neale Ranns15002542017-09-10 04:39:11 -07008279 1, 1);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008280
Neale Rannsad422ed2016-11-02 14:20:04 +00008281 ip46_address_t nh_10_10_10_1 = {
8282 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
8283 };
8284 ai_mpls_10_10_10_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
8285 VNET_LINK_MPLS,
8286 &nh_10_10_10_1,
8287 tm->hw[0]->sw_if_index);
8288
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008289 /*
8290 * Test the specials stack properly.
8291 */
8292 fib_prefix_t exp_null_v6_pfx = {
8293 .fp_proto = FIB_PROTOCOL_MPLS,
8294 .fp_eos = MPLS_EOS,
8295 .fp_label = MPLS_IETF_IPV6_EXPLICIT_NULL_LABEL,
8296 .fp_payload_proto = DPO_PROTO_IP6,
8297 };
8298 lfe = fib_table_lookup(lfib_index, &exp_null_v6_pfx);
8299 FIB_TEST((FIB_NODE_INDEX_INVALID != lfe),
8300 "%U/%U present",
8301 format_mpls_unicast_label, MPLS_IETF_IPV6_EXPLICIT_NULL_LABEL,
8302 format_mpls_eos_bit, MPLS_EOS);
8303 fib_entry_contribute_forwarding(lfe,
8304 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8305 &dpo);
8306 dpo1 = load_balance_get_bucket(dpo.dpoi_index, 0);
8307 lkd = lookup_dpo_get(dpo1->dpoi_index);
8308
8309 FIB_TEST((fib_index == lkd->lkd_fib_index),
8310 "%U/%U is deag in %d %U",
8311 format_mpls_unicast_label, deag_label,
8312 format_mpls_eos_bit, MPLS_EOS,
8313 lkd->lkd_fib_index,
8314 format_dpo_id, &dpo, 0);
8315 FIB_TEST((LOOKUP_INPUT_DST_ADDR == lkd->lkd_input),
8316 "%U/%U is dst deag",
8317 format_mpls_unicast_label, deag_label,
8318 format_mpls_eos_bit, MPLS_EOS);
8319 FIB_TEST((LOOKUP_TABLE_FROM_INPUT_INTERFACE == lkd->lkd_table),
8320 "%U/%U is lookup in interface's table",
8321 format_mpls_unicast_label, deag_label,
8322 format_mpls_eos_bit, MPLS_EOS);
8323 FIB_TEST((DPO_PROTO_IP6 == lkd->lkd_proto),
8324 "%U/%U is %U dst deag",
8325 format_mpls_unicast_label, deag_label,
8326 format_mpls_eos_bit, MPLS_EOS,
8327 format_dpo_proto, lkd->lkd_proto);
8328
8329
8330 /*
8331 * A route deag route for EOS
8332 */
8333 fib_prefix_t pfx = {
8334 .fp_proto = FIB_PROTOCOL_MPLS,
8335 .fp_eos = MPLS_EOS,
8336 .fp_label = deag_label,
8337 .fp_payload_proto = DPO_PROTO_IP4,
8338 };
8339 lfe = fib_table_entry_path_add(lfib_index,
8340 &pfx,
8341 FIB_SOURCE_CLI,
8342 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008343 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008344 &zero_addr,
8345 ~0,
8346 fib_index,
8347 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00008348 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008349 FIB_ROUTE_PATH_FLAG_NONE);
8350
8351 FIB_TEST((lfe == fib_table_lookup(lfib_index, &pfx)),
8352 "%U/%U present",
8353 format_mpls_unicast_label, deag_label,
8354 format_mpls_eos_bit, MPLS_EOS);
8355
8356 fib_entry_contribute_forwarding(lfe,
8357 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8358 &dpo);
8359 dpo1 = load_balance_get_bucket(dpo.dpoi_index, 0);
8360 lkd = lookup_dpo_get(dpo1->dpoi_index);
8361
8362 FIB_TEST((fib_index == lkd->lkd_fib_index),
8363 "%U/%U is deag in %d %U",
8364 format_mpls_unicast_label, deag_label,
8365 format_mpls_eos_bit, MPLS_EOS,
8366 lkd->lkd_fib_index,
8367 format_dpo_id, &dpo, 0);
8368 FIB_TEST((LOOKUP_INPUT_DST_ADDR == lkd->lkd_input),
8369 "%U/%U is dst deag",
8370 format_mpls_unicast_label, deag_label,
8371 format_mpls_eos_bit, MPLS_EOS);
8372 FIB_TEST((DPO_PROTO_IP4 == lkd->lkd_proto),
8373 "%U/%U is %U dst deag",
8374 format_mpls_unicast_label, deag_label,
8375 format_mpls_eos_bit, MPLS_EOS,
8376 format_dpo_proto, lkd->lkd_proto);
8377
8378 fib_table_entry_delete_index(lfe, FIB_SOURCE_CLI);
8379
8380 FIB_TEST((FIB_NODE_INDEX_INVALID == fib_table_lookup(lfib_index,
8381 &pfx)),
8382 "%U/%U not present",
8383 format_mpls_unicast_label, deag_label,
8384 format_mpls_eos_bit, MPLS_EOS);
8385
8386 /*
8387 * A route deag route for non-EOS
8388 */
8389 pfx.fp_eos = MPLS_NON_EOS;
8390 lfe = fib_table_entry_path_add(lfib_index,
8391 &pfx,
8392 FIB_SOURCE_CLI,
8393 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008394 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008395 &zero_addr,
8396 ~0,
8397 lfib_index,
8398 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00008399 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008400 FIB_ROUTE_PATH_FLAG_NONE);
8401
8402 FIB_TEST((lfe == fib_table_lookup(lfib_index, &pfx)),
8403 "%U/%U present",
8404 format_mpls_unicast_label, deag_label,
8405 format_mpls_eos_bit, MPLS_NON_EOS);
8406
8407 fib_entry_contribute_forwarding(lfe,
8408 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
8409 &dpo);
8410 dpo1 = load_balance_get_bucket(dpo.dpoi_index, 0);
8411 lkd = lookup_dpo_get(dpo1->dpoi_index);
8412
8413 FIB_TEST((fib_index == lkd->lkd_fib_index),
8414 "%U/%U is deag in %d %U",
8415 format_mpls_unicast_label, deag_label,
8416 format_mpls_eos_bit, MPLS_NON_EOS,
8417 lkd->lkd_fib_index,
8418 format_dpo_id, &dpo, 0);
8419 FIB_TEST((LOOKUP_INPUT_DST_ADDR == lkd->lkd_input),
8420 "%U/%U is dst deag",
8421 format_mpls_unicast_label, deag_label,
8422 format_mpls_eos_bit, MPLS_NON_EOS);
8423
8424 FIB_TEST((DPO_PROTO_MPLS == lkd->lkd_proto),
8425 "%U/%U is %U dst deag",
8426 format_mpls_unicast_label, deag_label,
8427 format_mpls_eos_bit, MPLS_NON_EOS,
8428 format_dpo_proto, lkd->lkd_proto);
8429
8430 fib_table_entry_delete_index(lfe, FIB_SOURCE_CLI);
8431
8432 FIB_TEST((FIB_NODE_INDEX_INVALID == fib_table_lookup(lfib_index,
8433 &pfx)),
8434 "%U/%U not present",
8435 format_mpls_unicast_label, deag_label,
8436 format_mpls_eos_bit, MPLS_EOS);
8437
Neale Rannsad422ed2016-11-02 14:20:04 +00008438 dpo_reset(&dpo);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008439
Neale Rannsad422ed2016-11-02 14:20:04 +00008440 /*
8441 * An MPLS x-connect
8442 */
8443 fib_prefix_t pfx_1200 = {
8444 .fp_len = 21,
8445 .fp_proto = FIB_PROTOCOL_MPLS,
8446 .fp_label = 1200,
8447 .fp_eos = MPLS_NON_EOS,
8448 };
8449 fib_test_lb_bucket_t neos_o_10_10_10_1 = {
8450 .type = FT_LB_LABEL_STACK_O_ADJ,
8451 .label_stack_o_adj = {
8452 .adj = ai_mpls_10_10_10_1,
8453 .label_stack_size = 4,
8454 .label_stack = {
8455 200, 300, 400, 500,
8456 },
8457 .eos = MPLS_NON_EOS,
8458 },
8459 };
8460 dpo_id_t neos_1200 = DPO_INVALID;
8461 dpo_id_t ip_1200 = DPO_INVALID;
8462 mpls_label_t *l200 = NULL;
8463 vec_add1(l200, 200);
8464 vec_add1(l200, 300);
8465 vec_add1(l200, 400);
8466 vec_add1(l200, 500);
8467
8468 lfe = fib_table_entry_update_one_path(fib_index,
8469 &pfx_1200,
8470 FIB_SOURCE_API,
8471 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008472 DPO_PROTO_IP4,
Neale Rannsad422ed2016-11-02 14:20:04 +00008473 &nh_10_10_10_1,
8474 tm->hw[0]->sw_if_index,
8475 ~0, // invalid fib index
8476 1,
8477 l200,
8478 FIB_ROUTE_PATH_FLAG_NONE);
8479
8480 FIB_TEST(fib_test_validate_entry(lfe,
8481 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
8482 1,
8483 &neos_o_10_10_10_1),
8484 "1200/0 LB 1 buckets via: "
8485 "adj 10.10.11.1");
8486
8487 /*
8488 * A recursive route via the MPLS x-connect
8489 */
8490 fib_prefix_t pfx_2_2_2_3_s_32 = {
8491 .fp_len = 32,
8492 .fp_proto = FIB_PROTOCOL_IP4,
8493 .fp_addr = {
8494 .ip4.as_u32 = clib_host_to_net_u32(0x02020203),
8495 },
8496 };
8497 fib_route_path_t *rpaths = NULL, rpath = {
Neale Rannsda78f952017-05-24 09:15:43 -07008498 .frp_proto = DPO_PROTO_MPLS,
Neale Rannsad422ed2016-11-02 14:20:04 +00008499 .frp_local_label = 1200,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008500 .frp_eos = MPLS_NON_EOS,
Neale Rannsad422ed2016-11-02 14:20:04 +00008501 .frp_sw_if_index = ~0, // recurive
8502 .frp_fib_index = 0, // Default MPLS fib
8503 .frp_weight = 1,
8504 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
8505 .frp_label_stack = NULL,
8506 };
8507 vec_add1(rpaths, rpath);
8508
8509 fib_table_entry_path_add2(fib_index,
8510 &pfx_2_2_2_3_s_32,
8511 FIB_SOURCE_API,
8512 FIB_ENTRY_FLAG_NONE,
8513 rpaths);
8514
8515 /*
8516 * A labelled recursive route via the MPLS x-connect
8517 */
8518 fib_prefix_t pfx_2_2_2_4_s_32 = {
8519 .fp_len = 32,
8520 .fp_proto = FIB_PROTOCOL_IP4,
8521 .fp_addr = {
8522 .ip4.as_u32 = clib_host_to_net_u32(0x02020204),
8523 },
8524 };
8525 mpls_label_t *l999 = NULL;
8526 vec_add1(l999, 999);
8527 rpaths[0].frp_label_stack = l999,
8528
8529 fib_table_entry_path_add2(fib_index,
8530 &pfx_2_2_2_4_s_32,
8531 FIB_SOURCE_API,
8532 FIB_ENTRY_FLAG_NONE,
8533 rpaths);
8534
8535 fib_entry_contribute_forwarding(fib_table_lookup(fib_index, &pfx_1200),
8536 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8537 &ip_1200);
8538 fib_entry_contribute_forwarding(fib_table_lookup(fib_index, &pfx_1200),
8539 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
8540 &neos_1200);
8541
8542 fib_test_lb_bucket_t ip_o_1200 = {
8543 .type = FT_LB_O_LB,
8544 .lb = {
8545 .lb = ip_1200.dpoi_index,
8546 },
8547 };
8548 fib_test_lb_bucket_t mpls_o_1200 = {
8549 .type = FT_LB_LABEL_O_LB,
8550 .label_o_lb = {
8551 .lb = neos_1200.dpoi_index,
8552 .label = 999,
8553 .eos = MPLS_EOS,
8554 },
8555 };
8556
8557 lfe = fib_table_lookup(fib_index, &pfx_2_2_2_3_s_32);
8558 FIB_TEST(fib_test_validate_entry(lfe,
8559 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8560 1,
8561 &ip_o_1200),
8562 "2.2.2.2.3/32 LB 1 buckets via: label 1200 EOS");
8563 lfe = fib_table_lookup(fib_index, &pfx_2_2_2_4_s_32);
8564 FIB_TEST(fib_test_validate_entry(lfe,
8565 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8566 1,
8567 &mpls_o_1200),
8568 "2.2.2.2.4/32 LB 1 buckets via: label 1200 non-EOS");
8569
8570 fib_table_entry_delete(fib_index, &pfx_1200, FIB_SOURCE_API);
8571 fib_table_entry_delete(fib_index, &pfx_2_2_2_3_s_32, FIB_SOURCE_API);
8572 fib_table_entry_delete(fib_index, &pfx_2_2_2_4_s_32, FIB_SOURCE_API);
8573
8574 dpo_reset(&neos_1200);
8575 dpo_reset(&ip_1200);
8576
8577 /*
8578 * A recursive via a label that does not exist
8579 */
8580 fib_test_lb_bucket_t bucket_drop = {
Neale Rannsd792d9c2017-10-21 10:53:20 -07008581 .type = FT_LB_DROP,
Neale Rannsad422ed2016-11-02 14:20:04 +00008582 .special = {
Neale Rannsf12a83f2017-04-18 09:09:40 -07008583 .adj = DPO_PROTO_IP4,
8584 },
8585 };
8586 fib_test_lb_bucket_t mpls_bucket_drop = {
Neale Rannsd792d9c2017-10-21 10:53:20 -07008587 .type = FT_LB_DROP,
Neale Rannsf12a83f2017-04-18 09:09:40 -07008588 .special = {
Neale Rannsad422ed2016-11-02 14:20:04 +00008589 .adj = DPO_PROTO_MPLS,
8590 },
8591 };
8592
8593 rpaths[0].frp_label_stack = NULL;
8594 lfe = fib_table_entry_path_add2(fib_index,
8595 &pfx_2_2_2_4_s_32,
8596 FIB_SOURCE_API,
8597 FIB_ENTRY_FLAG_NONE,
8598 rpaths);
8599
8600 fib_entry_contribute_forwarding(fib_table_lookup(fib_index, &pfx_1200),
8601 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8602 &ip_1200);
8603 ip_o_1200.lb.lb = ip_1200.dpoi_index;
8604
8605 FIB_TEST(fib_test_validate_entry(lfe,
8606 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8607 1,
Neale Ranns57b58602017-07-15 07:37:25 -07008608 &bucket_drop),
8609 "2.2.2.2.4/32 LB 1 buckets via: drop");
Neale Rannsad422ed2016-11-02 14:20:04 +00008610 lfe = fib_table_lookup(fib_index, &pfx_1200);
8611 FIB_TEST(fib_test_validate_entry(lfe,
8612 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8613 1,
8614 &bucket_drop),
Neale Rannsf12a83f2017-04-18 09:09:40 -07008615 "1200/neos LB 1 buckets via: ip4-DROP");
8616 FIB_TEST(fib_test_validate_entry(lfe,
8617 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
8618 1,
8619 &mpls_bucket_drop),
8620 "1200/neos LB 1 buckets via: mpls-DROP");
Neale Rannsad422ed2016-11-02 14:20:04 +00008621
8622 fib_table_entry_delete(fib_index, &pfx_2_2_2_4_s_32, FIB_SOURCE_API);
8623
8624 dpo_reset(&ip_1200);
8625
8626 /*
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008627 * An rx-interface route.
8628 * like the tail of an mcast LSP
8629 */
8630 dpo_id_t idpo = DPO_INVALID;
8631
Neale Ranns43161a82017-08-12 02:12:00 -07008632 interface_rx_dpo_add_or_lock(DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008633 tm->hw[0]->sw_if_index,
8634 &idpo);
8635
8636 fib_prefix_t pfx_2500 = {
8637 .fp_len = 21,
8638 .fp_proto = FIB_PROTOCOL_MPLS,
8639 .fp_label = 2500,
8640 .fp_eos = MPLS_EOS,
8641 .fp_payload_proto = DPO_PROTO_IP4,
8642 };
8643 fib_test_lb_bucket_t rx_intf_0 = {
8644 .type = FT_LB_INTF,
8645 .adj = {
8646 .adj = idpo.dpoi_index,
8647 },
8648 };
8649
8650 lfe = fib_table_entry_update_one_path(fib_index,
8651 &pfx_2500,
8652 FIB_SOURCE_API,
8653 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008654 DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008655 NULL,
8656 tm->hw[0]->sw_if_index,
8657 ~0, // invalid fib index
8658 0,
8659 NULL,
8660 FIB_ROUTE_PATH_INTF_RX);
8661 FIB_TEST(fib_test_validate_entry(lfe,
8662 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8663 1,
8664 &rx_intf_0),
8665 "2500 rx-interface 0");
8666 fib_table_entry_delete(fib_index, &pfx_2500, FIB_SOURCE_API);
8667
8668 /*
8669 * An MPLS mulicast entry
8670 */
8671 fib_prefix_t pfx_3500 = {
8672 .fp_len = 21,
8673 .fp_proto = FIB_PROTOCOL_MPLS,
8674 .fp_label = 3500,
8675 .fp_eos = MPLS_EOS,
8676 .fp_payload_proto = DPO_PROTO_IP4,
8677 };
8678 fib_test_rep_bucket_t mc_0 = {
8679 .type = FT_REP_LABEL_O_ADJ,
8680 .label_o_adj = {
8681 .adj = ai_mpls_10_10_10_1,
8682 .label = 3300,
8683 .eos = MPLS_EOS,
8684 },
8685 };
8686 fib_test_rep_bucket_t mc_intf_0 = {
8687 .type = FT_REP_INTF,
8688 .adj = {
8689 .adj = idpo.dpoi_index,
8690 },
8691 };
8692 mpls_label_t *l3300 = NULL;
8693 vec_add1(l3300, 3300);
8694
8695 lfe = fib_table_entry_update_one_path(lfib_index,
8696 &pfx_3500,
8697 FIB_SOURCE_API,
8698 FIB_ENTRY_FLAG_MULTICAST,
Neale Rannsda78f952017-05-24 09:15:43 -07008699 DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008700 &nh_10_10_10_1,
8701 tm->hw[0]->sw_if_index,
8702 ~0, // invalid fib index
8703 1,
8704 l3300,
8705 FIB_ROUTE_PATH_FLAG_NONE);
8706 FIB_TEST(fib_test_validate_entry(lfe,
8707 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8708 1,
8709 &mc_0),
8710 "3500 via replicate over 10.10.10.1");
8711
8712 /*
8713 * MPLS Bud-node. Add a replication via an interface-receieve path
8714 */
8715 lfe = fib_table_entry_path_add(lfib_index,
8716 &pfx_3500,
8717 FIB_SOURCE_API,
8718 FIB_ENTRY_FLAG_MULTICAST,
Neale Rannsda78f952017-05-24 09:15:43 -07008719 DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008720 NULL,
8721 tm->hw[0]->sw_if_index,
8722 ~0, // invalid fib index
8723 0,
8724 NULL,
8725 FIB_ROUTE_PATH_INTF_RX);
8726 FIB_TEST(fib_test_validate_entry(lfe,
8727 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8728 2,
8729 &mc_0,
8730 &mc_intf_0),
8731 "3500 via replicate over 10.10.10.1 and interface-rx");
8732
8733 /*
8734 * Add a replication via an interface-free for-us path
8735 */
8736 fib_test_rep_bucket_t mc_disp = {
8737 .type = FT_REP_DISP_MFIB_LOOKUP,
8738 .adj = {
8739 .adj = idpo.dpoi_index,
8740 },
8741 };
8742 lfe = fib_table_entry_path_add(lfib_index,
8743 &pfx_3500,
8744 FIB_SOURCE_API,
8745 FIB_ENTRY_FLAG_MULTICAST,
Neale Rannsda78f952017-05-24 09:15:43 -07008746 DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008747 NULL,
8748 5, // rpf-id
8749 0, // default table
8750 0,
8751 NULL,
8752 FIB_ROUTE_PATH_RPF_ID);
8753 FIB_TEST(fib_test_validate_entry(lfe,
8754 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8755 3,
8756 &mc_0,
8757 &mc_disp,
8758 &mc_intf_0),
8759 "3500 via replicate over 10.10.10.1 and interface-rx");
8760
8761
8762
8763 fib_table_entry_delete(fib_index, &pfx_3500, FIB_SOURCE_API);
8764 dpo_reset(&idpo);
8765
8766 /*
Neale Rannsad422ed2016-11-02 14:20:04 +00008767 * cleanup
8768 */
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008769 mpls_sw_interface_enable_disable(&mpls_main,
8770 tm->hw[0]->sw_if_index,
Neale Ranns15002542017-09-10 04:39:11 -07008771 0, 1);
8772 mpls_table_delete(MPLS_FIB_DEFAULT_TABLE_ID, FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008773
Neale Rannsad422ed2016-11-02 14:20:04 +00008774 FIB_TEST(lb_count == pool_elts(load_balance_pool),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008775 "Load-balance resources freed %d of %d",
Neale Rannsad422ed2016-11-02 14:20:04 +00008776 lb_count, pool_elts(load_balance_pool));
Neale Ranns43161a82017-08-12 02:12:00 -07008777 FIB_TEST(0 == pool_elts(interface_rx_dpo_pool),
8778 "interface_rx_dpo resources freed %d of %d",
8779 0, pool_elts(interface_rx_dpo_pool));
Neale Ranns0ebe8d72016-12-08 19:48:11 +00008780
8781 return (0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008782}
8783
8784static clib_error_t *
8785fib_test (vlib_main_t * vm,
8786 unformat_input_t * input,
8787 vlib_cli_command_t * cmd_arg)
8788{
Neale Ranns0ebe8d72016-12-08 19:48:11 +00008789 int res;
8790
8791 res = 0;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008792 fib_test_mk_intf(4);
8793
Neale Ranns88fc83e2017-04-05 08:11:14 -07008794 if (unformat (input, "debug"))
8795 {
8796 fib_test_do_debug = 1;
8797 }
8798
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008799 if (unformat (input, "ip"))
8800 {
Neale Ranns0ebe8d72016-12-08 19:48:11 +00008801 res += fib_test_v4();
8802 res += fib_test_v6();
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008803 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008804 else if (unformat (input, "label"))
8805 {
Neale Ranns0ebe8d72016-12-08 19:48:11 +00008806 res += fib_test_label();
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008807 }
8808 else if (unformat (input, "ae"))
8809 {
Neale Ranns0ebe8d72016-12-08 19:48:11 +00008810 res += fib_test_ae();
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008811 }
Neale Ranns57b58602017-07-15 07:37:25 -07008812 else if (unformat (input, "pref"))
8813 {
8814 res += fib_test_pref();
8815 }
Neale Rannsad422ed2016-11-02 14:20:04 +00008816 else if (unformat (input, "lfib"))
8817 {
Neale Ranns0ebe8d72016-12-08 19:48:11 +00008818 res += lfib_test();
Neale Rannsad422ed2016-11-02 14:20:04 +00008819 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008820 else if (unformat (input, "walk"))
8821 {
Neale Ranns0ebe8d72016-12-08 19:48:11 +00008822 res += fib_test_walk();
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008823 }
Neale Ranns88fc83e2017-04-05 08:11:14 -07008824 else if (unformat (input, "bfd"))
8825 {
8826 res += fib_test_bfd();
8827 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008828 else
8829 {
Neale Ranns0ebe8d72016-12-08 19:48:11 +00008830 res += fib_test_v4();
8831 res += fib_test_v6();
8832 res += fib_test_ae();
Neale Ranns88fc83e2017-04-05 08:11:14 -07008833 res += fib_test_bfd();
Neale Ranns57b58602017-07-15 07:37:25 -07008834 res += fib_test_pref();
Neale Ranns0ebe8d72016-12-08 19:48:11 +00008835 res += fib_test_label();
8836 res += lfib_test();
Neale Rannsf12a83f2017-04-18 09:09:40 -07008837
8838 /*
8839 * fib-walk process must be disabled in order for the walk tests to work
8840 */
8841 fib_walk_process_disable();
8842 res += fib_test_walk();
8843 fib_walk_process_enable();
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008844 }
8845
Neale Ranns0ebe8d72016-12-08 19:48:11 +00008846 if (res)
8847 {
8848 return clib_error_return(0, "FIB Unit Test Failed");
8849 }
8850 else
8851 {
8852 return (NULL);
8853 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008854}
8855
8856VLIB_CLI_COMMAND (test_fib_command, static) = {
8857 .path = "test fib",
8858 .short_help = "fib unit tests - DO NOT RUN ON A LIVE SYSTEM",
8859 .function = fib_test,
8860};
8861
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008862clib_error_t *
8863fib_test_init (vlib_main_t *vm)
8864{
8865 return 0;
8866}
8867
8868VLIB_INIT_FUNCTION (fib_test_init);