blob: 2a30b3cd4cff66247873606aef8d6695e1de69b7 [file] [log] [blame]
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001/*
2 * Copyright (c) 2016 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
Neale Rannsd792d9c2017-10-21 10:53:20 -070016#include <vnet/fib/fib_test.h>
Neale Ranns0bfe5d82016-08-25 15:29:12 +010017#include <vnet/fib/ip6_fib.h>
18#include <vnet/fib/ip4_fib.h>
19#include <vnet/fib/mpls_fib.h>
20#include <vnet/adj/adj.h>
21#include <vnet/dpo/load_balance.h>
22#include <vnet/dpo/load_balance_map.h>
23#include <vnet/dpo/mpls_label_dpo.h>
24#include <vnet/dpo/lookup_dpo.h>
25#include <vnet/dpo/drop_dpo.h>
26#include <vnet/dpo/receive_dpo.h>
Neale Ranns948e00f2016-10-20 13:39:34 +010027#include <vnet/dpo/ip_null_dpo.h>
Neale Ranns88fc83e2017-04-05 08:11:14 -070028#include <vnet/bfd/bfd_main.h>
Neale Ranns43161a82017-08-12 02:12:00 -070029#include <vnet/dpo/interface_rx_dpo.h>
Neale Ranns0f26c5a2017-03-01 15:12:11 -080030#include <vnet/dpo/replicate_dpo.h>
Neale Rannsf068c3e2018-01-03 04:18:48 -080031#include <vnet/dpo/dvr_dpo.h>
Neale Ranns62fe07c2017-10-31 12:28:22 -070032#include <vnet/dpo/mpls_disposition.h>
Neale Ranns0bfe5d82016-08-25 15:29:12 +010033
34#include <vnet/mpls/mpls.h>
35
Neale Ranns6f631152017-10-03 08:20:21 -070036#include <vnet/fib/fib_test.h>
Neale Ranns0bfe5d82016-08-25 15:29:12 +010037#include <vnet/fib/fib_path_list.h>
Neale Rannsad422ed2016-11-02 14:20:04 +000038#include <vnet/fib/fib_entry_src.h>
Neale Ranns0bfe5d82016-08-25 15:29:12 +010039#include <vnet/fib/fib_walk.h>
40#include <vnet/fib/fib_node_list.h>
Neale Ranns3ee44042016-10-03 13:05:48 +010041#include <vnet/fib/fib_urpf_list.h>
Neale Ranns0bfe5d82016-08-25 15:29:12 +010042
Neale Ranns88fc83e2017-04-05 08:11:14 -070043/*
44 * Add debugs for passing tests
45 */
46static int fib_test_do_debug;
47
Neale Ranns0bfe5d82016-08-25 15:29:12 +010048#define FIB_TEST_I(_cond, _comment, _args...) \
49({ \
50 int _evald = (_cond); \
51 if (!(_evald)) { \
52 fformat(stderr, "FAIL:%d: " _comment "\n", \
53 __LINE__, ##_args); \
54 } else { \
Neale Ranns88fc83e2017-04-05 08:11:14 -070055 if (fib_test_do_debug) \
56 fformat(stderr, "PASS:%d: " _comment "\n", \
57 __LINE__, ##_args); \
Neale Ranns0bfe5d82016-08-25 15:29:12 +010058 } \
59 _evald; \
60})
61#define FIB_TEST(_cond, _comment, _args...) \
62{ \
63 if (!FIB_TEST_I(_cond, _comment, ##_args)) { \
Neale Ranns0ebe8d72016-12-08 19:48:11 +000064 return 1; \
Neale Ranns0bfe5d82016-08-25 15:29:12 +010065 ASSERT(!("FAIL: " _comment)); \
66 } \
67}
68
69/**
70 * A 'i'm not fussed is this is not efficient' store of test data
71 */
72typedef struct test_main_t_ {
73 /**
74 * HW if indicies
75 */
76 u32 hw_if_indicies[4];
77 /**
78 * HW interfaces
79 */
80 vnet_hw_interface_t * hw[4];
81
82} test_main_t;
83static test_main_t test_main;
84
85/* fake ethernet device class, distinct from "fake-ethX" */
86static u8 * format_test_interface_name (u8 * s, va_list * args)
87{
88 u32 dev_instance = va_arg (*args, u32);
89 return format (s, "test-eth%d", dev_instance);
90}
91
92static uword dummy_interface_tx (vlib_main_t * vm,
93 vlib_node_runtime_t * node,
94 vlib_frame_t * frame)
95{
96 clib_warning ("you shouldn't be here, leaking buffers...");
97 return frame->n_vectors;
98}
99
Neale Ranns8b37b872016-11-21 12:25:22 +0000100static clib_error_t *
101test_interface_admin_up_down (vnet_main_t * vnm,
102 u32 hw_if_index,
103 u32 flags)
104{
105 u32 hw_flags = (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) ?
106 VNET_HW_INTERFACE_FLAG_LINK_UP : 0;
107 vnet_hw_interface_set_flags (vnm, hw_if_index, hw_flags);
108 return 0;
109}
110
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100111VNET_DEVICE_CLASS (test_interface_device_class,static) = {
112 .name = "Test interface",
113 .format_device_name = format_test_interface_name,
114 .tx_function = dummy_interface_tx,
Neale Ranns8b37b872016-11-21 12:25:22 +0000115 .admin_up_down_function = test_interface_admin_up_down,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100116};
117
118static u8 *hw_address;
119
Neale Ranns0ebe8d72016-12-08 19:48:11 +0000120static int
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100121fib_test_mk_intf (u32 ninterfaces)
122{
123 clib_error_t * error = NULL;
124 test_main_t *tm = &test_main;
125 u8 byte;
126 u32 i;
127
128 ASSERT(ninterfaces <= ARRAY_LEN(tm->hw_if_indicies));
129
130 for (i=0; i<6; i++)
131 {
132 byte = 0xd0+i;
133 vec_add1(hw_address, byte);
134 }
135
136 for (i = 0; i < ninterfaces; i++)
137 {
138 hw_address[5] = i;
139
140 error = ethernet_register_interface(vnet_get_main(),
Neale Ranns8b37b872016-11-21 12:25:22 +0000141 test_interface_device_class.index,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100142 i /* instance */,
143 hw_address,
144 &tm->hw_if_indicies[i],
145 /* flag change */ 0);
146
147 FIB_TEST((NULL == error), "ADD interface %d", i);
148
Neale Ranns8b37b872016-11-21 12:25:22 +0000149 error = vnet_hw_interface_set_flags(vnet_get_main(),
150 tm->hw_if_indicies[i],
151 VNET_HW_INTERFACE_FLAG_LINK_UP);
152 tm->hw[i] = vnet_get_hw_interface(vnet_get_main(),
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100153 tm->hw_if_indicies[i]);
Neale Ranns8b37b872016-11-21 12:25:22 +0000154 vec_validate (ip4_main.fib_index_by_sw_if_index,
155 tm->hw[i]->sw_if_index);
156 vec_validate (ip6_main.fib_index_by_sw_if_index,
157 tm->hw[i]->sw_if_index);
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100158 ip4_main.fib_index_by_sw_if_index[tm->hw[i]->sw_if_index] = 0;
159 ip6_main.fib_index_by_sw_if_index[tm->hw[i]->sw_if_index] = 0;
Neale Ranns8b37b872016-11-21 12:25:22 +0000160
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100161 error = vnet_sw_interface_set_flags(vnet_get_main(),
162 tm->hw[i]->sw_if_index,
163 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
164 FIB_TEST((NULL == error), "UP interface %d", i);
165 }
166 /*
167 * re-eval after the inevitable realloc
168 */
169 for (i = 0; i < ninterfaces; i++)
170 {
171 tm->hw[i] = vnet_get_hw_interface(vnet_get_main(),
172 tm->hw_if_indicies[i]);
173 }
Neale Ranns0ebe8d72016-12-08 19:48:11 +0000174
175 return (0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100176}
177
Neale Ranns3ee44042016-10-03 13:05:48 +0100178#define FIB_TEST_REC_FORW(_rec_prefix, _via_prefix, _bucket) \
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100179{ \
180 const dpo_id_t *_rec_dpo = fib_entry_contribute_ip_forwarding( \
181 fib_table_lookup_exact_match(fib_index, (_rec_prefix))); \
182 const dpo_id_t *_via_dpo = fib_entry_contribute_ip_forwarding( \
183 fib_table_lookup(fib_index, (_via_prefix))); \
184 FIB_TEST(!dpo_cmp(_via_dpo, \
Neale Ranns3ee44042016-10-03 13:05:48 +0100185 load_balance_get_bucket(_rec_dpo->dpoi_index, \
186 _bucket)), \
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100187 "%U is recursive via %U", \
188 format_fib_prefix, (_rec_prefix), \
189 format_fib_prefix, _via_prefix); \
190}
191
192#define FIB_TEST_LB_BUCKET_VIA_ADJ(_prefix, _bucket, _ai) \
193{ \
194 const dpo_id_t *_dpo = fib_entry_contribute_ip_forwarding( \
195 fib_table_lookup_exact_match(fib_index, (_prefix))); \
196 const dpo_id_t *_dpo1 = \
197 load_balance_get_bucket(_dpo->dpoi_index, _bucket); \
198 FIB_TEST(DPO_ADJACENCY == _dpo1->dpoi_type, "type is %U", \
199 format_dpo_type, _dpo1->dpoi_type); \
200 FIB_TEST((_ai == _dpo1->dpoi_index), \
201 "%U bucket %d resolves via %U", \
202 format_fib_prefix, (_prefix), \
203 _bucket, \
204 format_dpo_id, _dpo1, 0); \
205}
206
Neale Ranns3ee44042016-10-03 13:05:48 +0100207#define FIB_TEST_RPF(_cond, _comment, _args...) \
208{ \
209 if (!FIB_TEST_I(_cond, _comment, ##_args)) { \
210 return (0); \
211 } \
212}
213
214static int
215fib_test_urpf_is_equal (fib_node_index_t fei,
216 fib_forward_chain_type_t fct,
217 u32 num, ...)
218{
Neale Ranns948e00f2016-10-20 13:39:34 +0100219 dpo_id_t dpo = DPO_INVALID;
Neale Ranns3ee44042016-10-03 13:05:48 +0100220 fib_urpf_list_t *urpf;
221 index_t ui;
222 va_list ap;
223 int ii;
224
225 va_start(ap, num);
226
227 fib_entry_contribute_forwarding(fei, fct, &dpo);
228 ui = load_balance_get_urpf(dpo.dpoi_index);
229
230 urpf = fib_urpf_list_get(ui);
231
232 FIB_TEST_RPF(num == vec_len(urpf->furpf_itfs),
233 "RPF:%U len %d == %d",
234 format_fib_urpf_list, ui,
235 num, vec_len(urpf->furpf_itfs));
236 FIB_TEST_RPF(num == fib_urpf_check_size(ui),
237 "RPF:%U check-size %d == %d",
238 format_fib_urpf_list, ui,
239 num, vec_len(urpf->furpf_itfs));
240
241 for (ii = 0; ii < num; ii++)
242 {
243 adj_index_t ai = va_arg(ap, adj_index_t);
244
245 FIB_TEST_RPF(ai == urpf->furpf_itfs[ii],
246 "RPF:%d item:%d - %d == %d",
247 ui, ii, ai, urpf->furpf_itfs[ii]);
248 FIB_TEST_RPF(fib_urpf_check(ui, ai),
249 "RPF:%d %d found",
250 ui, ai);
251 }
252
253 dpo_reset(&dpo);
254
Neale Ranns5899fde2016-10-12 13:51:05 +0100255 va_end(ap);
256
Neale Ranns3ee44042016-10-03 13:05:48 +0100257 return (1);
258}
259
Neale Rannsb80c5362016-10-08 13:03:40 +0100260static u8*
261fib_test_build_rewrite (u8 *eth_addr)
262{
263 u8* rewrite = NULL;
264
265 vec_validate(rewrite, 13);
266
267 memcpy(rewrite, eth_addr, 6);
268 memcpy(rewrite+6, eth_addr, 6);
269
270 return (rewrite);
271}
272
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000273#define FIB_TEST_LB(_cond, _comment, _args...) \
274{ \
275 if (!FIB_TEST_I(_cond, _comment, ##_args)) { \
276 return (0); \
277 } \
278}
279
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800280int
281fib_test_validate_rep_v (const replicate_t *rep,
282 u16 n_buckets,
Christophe Fontained3c008d2017-10-02 18:10:54 +0200283 va_list *ap)
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800284{
285 const fib_test_rep_bucket_t *exp;
286 const dpo_id_t *dpo;
287 int bucket;
288
289 FIB_TEST_LB((n_buckets == rep->rep_n_buckets),
290 "n_buckets = %d", rep->rep_n_buckets);
291
292 for (bucket = 0; bucket < n_buckets; bucket++)
293 {
Christophe Fontained3c008d2017-10-02 18:10:54 +0200294 exp = va_arg(*ap, fib_test_rep_bucket_t*);
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800295
296 dpo = replicate_get_bucket_i(rep, bucket);
297
298 switch (exp->type)
299 {
300 case FT_REP_LABEL_O_ADJ:
301 {
302 const mpls_label_dpo_t *mld;
303 mpls_label_t hdr;
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,
Damjan Marionbb17f3c2018-02-06 19:29:35 +0100358 int 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:
Neale Rannsf068c3e2018-01-03 04:18:48 -0800553 FIB_TEST_I((DPO_DVR == dpo->dpoi_type),
Neale Ranns6f631152017-10-03 08:20:21 -0700554 "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,
Damjan Marionbb17f3c2018-02-06 19:29:35 +0100606 int n_buckets,
Neale Rannsd792d9c2017-10-21 10:53:20 -0700607 ...)
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),
Neale Ranns89541992017-04-06 04:41:02 -0700664 "%U Entry links to %U",
665 format_fib_prefix, &pfx,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800666 format_dpo_type, dpo.dpoi_type);
667
668 lb = load_balance_get(dpo.dpoi_index);
Christophe Fontained3c008d2017-10-02 18:10:54 +0200669 res = fib_test_validate_lb_v(lb, n_buckets, &ap);
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800670
671 /*
672 * ensure that the LB contributed by the entry is the
673 * same as the LB in the forwarding tables
674 */
675 if (fct == fib_entry_get_default_chain_type(fib_entry_get(fei)))
Neale Rannsad422ed2016-11-02 14:20:04 +0000676 {
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800677 switch (pfx.fp_proto)
Neale Rannsad422ed2016-11-02 14:20:04 +0000678 {
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800679 case FIB_PROTOCOL_IP4:
680 fw_lbi = ip4_fib_forwarding_lookup(fib_index, &pfx.fp_addr.ip4);
Neale Rannsad422ed2016-11-02 14:20:04 +0000681 break;
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800682 case FIB_PROTOCOL_IP6:
683 fw_lbi = ip6_fib_table_fwding_lookup(&ip6_main, fib_index, &pfx.fp_addr.ip6);
684 break;
685 case FIB_PROTOCOL_MPLS:
686 {
687 mpls_unicast_header_t hdr = {
688 .label_exp_s_ttl = 0,
689 };
690
691 vnet_mpls_uc_set_label(&hdr.label_exp_s_ttl, pfx.fp_label);
692 vnet_mpls_uc_set_s(&hdr.label_exp_s_ttl, pfx.fp_eos);
693 hdr.label_exp_s_ttl = clib_host_to_net_u32(hdr.label_exp_s_ttl);
694
695 fw_lbi = mpls_fib_table_forwarding_lookup(fib_index, &hdr);
696 break;
697 }
698 default:
699 fw_lbi = 0;
Neale Rannsad422ed2016-11-02 14:20:04 +0000700 }
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800701 FIB_TEST_LB((fw_lbi == dpo.dpoi_index),
Neale Ranns89541992017-04-06 04:41:02 -0700702 "Contributed LB = FW LB:\n fwd:%U\n cont:%U",
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800703 format_load_balance, fw_lbi, 0,
704 format_load_balance, dpo.dpoi_index, 0);
Neale Rannsad422ed2016-11-02 14:20:04 +0000705 }
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000706 }
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000707
708 dpo_reset(&dpo);
709
710 va_end(ap);
711
712 return (res);
713}
714
Neale Ranns0ebe8d72016-12-08 19:48:11 +0000715static int
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100716fib_test_v4 (void)
717{
718 /*
719 * In the default table check for the presence and correct forwarding
720 * of the special entries
721 */
722 fib_node_index_t dfrt, fei, ai, ai2, locked_ai, ai_01, ai_02, ai_03;
723 const dpo_id_t *dpo, *dpo1, *dpo2, *dpo_drop;
724 const ip_adjacency_t *adj;
725 const load_balance_t *lb;
726 test_main_t *tm;
727 u32 fib_index;
Neale Ranns994dab42017-04-18 12:56:45 -0700728 int lb_count;
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100729 int ii;
730
731 /* via 10.10.10.1 */
732 ip46_address_t nh_10_10_10_1 = {
733 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
734 };
735 /* via 10.10.10.2 */
736 ip46_address_t nh_10_10_10_2 = {
737 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02),
738 };
739
Neale Rannsf12a83f2017-04-18 09:09:40 -0700740 FIB_TEST((0 == pool_elts(load_balance_map_pool)), "LB-map pool size is %d",
741 pool_elts(load_balance_map_pool));
742
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100743 tm = &test_main;
744
Neale Ranns994dab42017-04-18 12:56:45 -0700745 /* record the nubmer of load-balances in use before we start */
746 lb_count = pool_elts(load_balance_pool);
747
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100748 /* Find or create FIB table 11 */
Neale Ranns15002542017-09-10 04:39:11 -0700749 fib_index = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP4, 11,
750 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100751
752 for (ii = 0; ii < 4; ii++)
753 {
754 ip4_main.fib_index_by_sw_if_index[tm->hw[ii]->sw_if_index] = fib_index;
755 }
756
757 fib_prefix_t pfx_0_0_0_0_s_0 = {
758 .fp_len = 0,
759 .fp_proto = FIB_PROTOCOL_IP4,
760 .fp_addr = {
761 .ip4 = {
762 {0}
763 },
764 },
765 };
766
767 fib_prefix_t pfx = {
768 .fp_len = 0,
769 .fp_proto = FIB_PROTOCOL_IP4,
770 .fp_addr = {
771 .ip4 = {
772 {0}
773 },
774 },
775 };
776
777 dpo_drop = drop_dpo_get(DPO_PROTO_IP4);
778
779 dfrt = fib_table_lookup(fib_index, &pfx_0_0_0_0_s_0);
780 FIB_TEST((FIB_NODE_INDEX_INVALID != dfrt), "default route present");
781 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(dfrt)),
782 "Default route is DROP");
783
784 pfx.fp_len = 32;
785 fei = fib_table_lookup(fib_index, &pfx);
786 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "all zeros route present");
787 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
788 "all 0s route is DROP");
789
790 pfx.fp_addr.ip4.as_u32 = clib_host_to_net_u32(0xffffffff);
791 pfx.fp_len = 32;
792 fei = fib_table_lookup(fib_index, &pfx);
793 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "all ones route present");
794 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
795 "all 1s route is DROP");
796
797 pfx.fp_addr.ip4.as_u32 = clib_host_to_net_u32(0xe0000000);
798 pfx.fp_len = 8;
799 fei = fib_table_lookup(fib_index, &pfx);
800 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "all-mcast route present");
801 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
802 "all-mcast route is DROP");
803
804 pfx.fp_addr.ip4.as_u32 = clib_host_to_net_u32(0xf0000000);
805 pfx.fp_len = 8;
806 fei = fib_table_lookup(fib_index, &pfx);
807 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "class-e route present");
808 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
809 "class-e route is DROP");
810
811 /*
812 * at this stage there are 5 entries in the test FIB (plus 5 in the default),
813 * all of which are special sourced and so none of which share path-lists.
Neale Ranns32e1c012016-11-22 17:07:28 +0000814 * There are also 2 entries, and 2 non-shared path-lists, in the v6 default
815 * table, and 4 path-lists in the v6 MFIB table
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100816 */
Neale Ranns32e1c012016-11-22 17:07:28 +0000817#define ENBR (5+5+2)
818#define PNBR (5+5+6)
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100819 FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +0000820 FIB_TEST((PNBR == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100821 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +0000822 FIB_TEST((ENBR == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100823 fib_entry_pool_size());
824
825 /*
826 * add interface routes.
827 * validate presence of /24 attached and /32 recieve.
828 * test for the presence of the receive address in the glean and local adj
829 */
830 fib_prefix_t local_pfx = {
831 .fp_len = 24,
832 .fp_proto = FIB_PROTOCOL_IP4,
833 .fp_addr = {
834 .ip4 = {
835 .as_u32 = clib_host_to_net_u32(0x0a0a0a0a),
836 },
837 },
838 };
839
840 fib_table_entry_update_one_path(fib_index, &local_pfx,
841 FIB_SOURCE_INTERFACE,
842 (FIB_ENTRY_FLAG_CONNECTED |
843 FIB_ENTRY_FLAG_ATTACHED),
Neale Rannsda78f952017-05-24 09:15:43 -0700844 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100845 NULL,
846 tm->hw[0]->sw_if_index,
847 ~0, // invalid fib index
848 1, // weight
Neale Rannsad422ed2016-11-02 14:20:04 +0000849 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100850 FIB_ROUTE_PATH_FLAG_NONE);
851 fei = fib_table_lookup(fib_index, &local_pfx);
852 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached interface route present");
853 FIB_TEST(((FIB_ENTRY_FLAG_ATTACHED | FIB_ENTRY_FLAG_CONNECTED) ==
854 fib_entry_get_flags(fei)),
855 "Flags set on attached interface");
856
857 ai = fib_entry_get_adj(fei);
Neale Ranns81424992017-05-18 03:03:22 -0700858 FIB_TEST((FIB_NODE_INDEX_INVALID != ai),
859 "attached interface route adj present %d", ai);
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100860 adj = adj_get(ai);
861 FIB_TEST((IP_LOOKUP_NEXT_GLEAN == adj->lookup_next_index),
862 "attached interface adj is glean");
863 FIB_TEST((0 == ip46_address_cmp(&local_pfx.fp_addr,
864 &adj->sub_type.glean.receive_addr)),
865 "attached interface adj is receive ok");
866
867 local_pfx.fp_len = 32;
868 fib_table_entry_update_one_path(fib_index, &local_pfx,
869 FIB_SOURCE_INTERFACE,
870 (FIB_ENTRY_FLAG_CONNECTED |
871 FIB_ENTRY_FLAG_LOCAL),
Neale Rannsda78f952017-05-24 09:15:43 -0700872 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100873 NULL,
874 tm->hw[0]->sw_if_index,
875 ~0, // invalid fib index
876 1, // weight
Neale Rannsad422ed2016-11-02 14:20:04 +0000877 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100878 FIB_ROUTE_PATH_FLAG_NONE);
879 fei = fib_table_lookup(fib_index, &local_pfx);
880 FIB_TEST(((FIB_ENTRY_FLAG_LOCAL | FIB_ENTRY_FLAG_CONNECTED) ==
881 fib_entry_get_flags(fei)),
882 "Flags set on local interface");
883
884 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local interface route present");
885
886 dpo = fib_entry_contribute_ip_forwarding(fei);
Neale Ranns3ee44042016-10-03 13:05:48 +0100887 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 0),
888 "RPF list for local length 0");
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100889 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
890 FIB_TEST((DPO_RECEIVE == dpo->dpoi_type),
891 "local interface adj is local");
892 receive_dpo_t *rd = receive_dpo_get(dpo->dpoi_index);
893
894 FIB_TEST((0 == ip46_address_cmp(&local_pfx.fp_addr,
895 &rd->rd_addr)),
896 "local interface adj is receive ok");
897
898 FIB_TEST((2 == fib_table_get_num_entries(fib_index,
899 FIB_PROTOCOL_IP4,
900 FIB_SOURCE_INTERFACE)),
901 "2 Interface Source'd prefixes");
902
903 /*
904 * +2 interface routes +2 non-shared path-lists
905 */
906 FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +0000907 FIB_TEST((PNBR+2 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100908 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +0000909 FIB_TEST((ENBR+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100910 fib_entry_pool_size());
911
912 /*
913 * Modify the default route to be via an adj not yet known.
914 * this sources the defalut route with the API source, which is
915 * a higher preference to the DEFAULT_ROUTE source
916 */
917 pfx.fp_addr.ip4.as_u32 = 0;
918 pfx.fp_len = 0;
919 fib_table_entry_path_add(fib_index, &pfx,
920 FIB_SOURCE_API,
921 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -0700922 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100923 &nh_10_10_10_1,
924 tm->hw[0]->sw_if_index,
925 ~0, // invalid fib index
926 1,
Neale Rannsad422ed2016-11-02 14:20:04 +0000927 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100928 FIB_ROUTE_PATH_FLAG_NONE);
929 fei = fib_table_lookup(fib_index, &pfx);
930 FIB_TEST((FIB_ENTRY_FLAG_NONE == fib_entry_get_flags(fei)),
931 "Flags set on API route");
932
933 FIB_TEST((fei == dfrt), "default route same index");
934 ai = fib_entry_get_adj(fei);
935 FIB_TEST((FIB_NODE_INDEX_INVALID != ai), "default route adj present");
936 adj = adj_get(ai);
937 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
938 "adj is incomplete");
939 FIB_TEST((0 == ip46_address_cmp(&nh_10_10_10_1, &adj->sub_type.nbr.next_hop)),
940 "adj nbr next-hop ok");
941 FIB_TEST((1 == fib_table_get_num_entries(fib_index,
942 FIB_PROTOCOL_IP4,
943 FIB_SOURCE_API)),
944 "1 API Source'd prefixes");
945
946 /*
947 * find the adj in the shared db
948 */
949 locked_ai = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +0100950 VNET_LINK_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100951 &nh_10_10_10_1,
952 tm->hw[0]->sw_if_index);
953 FIB_TEST((locked_ai == ai), "ADJ NBR DB find");
954 adj_unlock(locked_ai);
955
956 /*
957 * +1 shared path-list
958 */
959 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
960 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +0000961 FIB_TEST((PNBR+3 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100962 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +0000963 FIB_TEST((ENBR+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100964 fib_entry_pool_size());
965
966 /*
967 * remove the API source from the default route. We expected
968 * the route to remain, sourced by DEFAULT_ROUTE, and hence a DROP
969 */
970 pfx.fp_addr.ip4.as_u32 = 0;
971 pfx.fp_len = 0;
972 fib_table_entry_path_remove(fib_index, &pfx,
973 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -0700974 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100975 &nh_10_10_10_1,
976 tm->hw[0]->sw_if_index,
977 ~0, // non-recursive path, so no FIB index
978 1,
979 FIB_ROUTE_PATH_FLAG_NONE);
980
981 fei = fib_table_lookup(fib_index, &pfx);
982
983 FIB_TEST((fei == dfrt), "default route same index");
984 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
985 "Default route is DROP");
986
987 /*
988 * -1 shared-path-list
989 */
990 FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +0000991 FIB_TEST((PNBR+2 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100992 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +0000993 FIB_TEST((ENBR+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100994 fib_entry_pool_size());
995
996 /*
997 * Add an 2 ARP entry => a complete ADJ plus adj-fib.
998 */
999 fib_prefix_t pfx_10_10_10_1_s_32 = {
1000 .fp_len = 32,
1001 .fp_proto = FIB_PROTOCOL_IP4,
1002 .fp_addr = {
1003 /* 10.10.10.1 */
1004 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
1005 },
1006 };
1007 fib_prefix_t pfx_10_10_10_2_s_32 = {
1008 .fp_len = 32,
1009 .fp_proto = FIB_PROTOCOL_IP4,
1010 .fp_addr = {
1011 /* 10.10.10.2 */
1012 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02),
1013 },
1014 };
1015 fib_prefix_t pfx_11_11_11_11_s_32 = {
1016 .fp_len = 32,
1017 .fp_proto = FIB_PROTOCOL_IP4,
1018 .fp_addr = {
1019 /* 11.11.11.11 */
1020 .ip4.as_u32 = clib_host_to_net_u32(0x0b0b0b0b),
1021 },
1022 };
1023 u8 eth_addr[] = {
1024 0xde, 0xde, 0xde, 0xba, 0xba, 0xba,
1025 };
Neale Rannsb80c5362016-10-08 13:03:40 +01001026
Neale Ranns3ee44042016-10-03 13:05:48 +01001027 ip46_address_t nh_12_12_12_12 = {
1028 .ip4.as_u32 = clib_host_to_net_u32(0x0c0c0c0c),
1029 };
1030 adj_index_t ai_12_12_12_12;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001031
1032 /*
1033 * Add a route via an incomplete ADJ. then complete the ADJ
1034 * Expect the route LB is updated to use complete adj type.
1035 */
1036 fei = fib_table_entry_update_one_path(fib_index,
1037 &pfx_11_11_11_11_s_32,
1038 FIB_SOURCE_API,
1039 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07001040 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001041 &pfx_10_10_10_1_s_32.fp_addr,
1042 tm->hw[0]->sw_if_index,
1043 ~0, // invalid fib index
1044 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001045 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001046 FIB_ROUTE_PATH_FLAG_NONE);
1047
1048 dpo = fib_entry_contribute_ip_forwarding(fei);
1049 dpo1 = load_balance_get_bucket(dpo->dpoi_index, 0);
1050 FIB_TEST(DPO_ADJACENCY_INCOMPLETE == dpo1->dpoi_type,
1051 "11.11.11.11/32 via incomplete adj");
1052
1053 ai_01 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01001054 VNET_LINK_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001055 &pfx_10_10_10_1_s_32.fp_addr,
1056 tm->hw[0]->sw_if_index);
1057 FIB_TEST((FIB_NODE_INDEX_INVALID != ai_01), "adj created");
1058 adj = adj_get(ai_01);
1059 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
1060 "adj is incomplete");
1061 FIB_TEST((0 == ip46_address_cmp(&pfx_10_10_10_1_s_32.fp_addr,
1062 &adj->sub_type.nbr.next_hop)),
1063 "adj nbr next-hop ok");
1064
Neale Rannsb80c5362016-10-08 13:03:40 +01001065 adj_nbr_update_rewrite(ai_01, ADJ_NBR_REWRITE_FLAG_COMPLETE,
1066 fib_test_build_rewrite(eth_addr));
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001067 FIB_TEST((IP_LOOKUP_NEXT_REWRITE == adj->lookup_next_index),
1068 "adj is complete");
1069 FIB_TEST((0 == ip46_address_cmp(&pfx_10_10_10_1_s_32.fp_addr,
1070 &adj->sub_type.nbr.next_hop)),
1071 "adj nbr next-hop ok");
1072 ai = fib_entry_get_adj(fei);
1073 FIB_TEST((ai_01 == ai), "ADJ-FIB resolves via adj");
1074
1075 dpo = fib_entry_contribute_ip_forwarding(fei);
1076 dpo1 = load_balance_get_bucket(dpo->dpoi_index, 0);
1077 FIB_TEST(DPO_ADJACENCY == dpo1->dpoi_type,
1078 "11.11.11.11/32 via complete adj");
Neale Ranns3ee44042016-10-03 13:05:48 +01001079 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 1,
1080 tm->hw[0]->sw_if_index),
1081 "RPF list for adj-fib contains adj");
1082
1083 ai_12_12_12_12 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01001084 VNET_LINK_IP4,
Neale Ranns3ee44042016-10-03 13:05:48 +01001085 &nh_12_12_12_12,
1086 tm->hw[1]->sw_if_index);
1087 FIB_TEST((FIB_NODE_INDEX_INVALID != ai_12_12_12_12), "adj created");
1088 adj = adj_get(ai_12_12_12_12);
1089 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
1090 "adj is incomplete");
1091 FIB_TEST((0 == ip46_address_cmp(&nh_12_12_12_12,
1092 &adj->sub_type.nbr.next_hop)),
1093 "adj nbr next-hop ok");
Neale Rannsb80c5362016-10-08 13:03:40 +01001094 adj_nbr_update_rewrite(ai_12_12_12_12, ADJ_NBR_REWRITE_FLAG_COMPLETE,
1095 fib_test_build_rewrite(eth_addr));
Neale Ranns3ee44042016-10-03 13:05:48 +01001096 FIB_TEST((IP_LOOKUP_NEXT_REWRITE == adj->lookup_next_index),
1097 "adj is complete");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001098
1099 /*
1100 * add the adj fib
1101 */
Neale Ranns81424992017-05-18 03:03:22 -07001102 fei = fib_table_entry_path_add(fib_index,
1103 &pfx_10_10_10_1_s_32,
1104 FIB_SOURCE_ADJ,
1105 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07001106 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07001107 &pfx_10_10_10_1_s_32.fp_addr,
1108 tm->hw[0]->sw_if_index,
1109 ~0, // invalid fib index
1110 1,
1111 NULL,
1112 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001113 FIB_TEST((FIB_ENTRY_FLAG_ATTACHED == fib_entry_get_flags(fei)),
1114 "Flags set on adj-fib");
1115 ai = fib_entry_get_adj(fei);
Neale Ranns81424992017-05-18 03:03:22 -07001116 FIB_TEST((ai_01 == ai), "ADJ-FIB resolves via adj, %d", ai);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001117
1118 fib_table_entry_path_remove(fib_index,
1119 &pfx_11_11_11_11_s_32,
1120 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07001121 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001122 &pfx_10_10_10_1_s_32.fp_addr,
1123 tm->hw[0]->sw_if_index,
1124 ~0, // invalid fib index
1125 1,
1126 FIB_ROUTE_PATH_FLAG_NONE);
1127
1128 eth_addr[5] = 0xb2;
1129
1130 ai_02 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01001131 VNET_LINK_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001132 &pfx_10_10_10_2_s_32.fp_addr,
1133 tm->hw[0]->sw_if_index);
1134 FIB_TEST((FIB_NODE_INDEX_INVALID != ai_02), "adj created");
1135 adj = adj_get(ai_02);
1136 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
1137 "adj is incomplete");
1138 FIB_TEST((0 == ip46_address_cmp(&pfx_10_10_10_2_s_32.fp_addr,
1139 &adj->sub_type.nbr.next_hop)),
1140 "adj nbr next-hop ok");
1141
Neale Rannsb80c5362016-10-08 13:03:40 +01001142 adj_nbr_update_rewrite(ai_02, ADJ_NBR_REWRITE_FLAG_COMPLETE,
1143 fib_test_build_rewrite(eth_addr));
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001144 FIB_TEST((IP_LOOKUP_NEXT_REWRITE == adj->lookup_next_index),
1145 "adj is complete");
1146 FIB_TEST((0 == ip46_address_cmp(&pfx_10_10_10_2_s_32.fp_addr,
1147 &adj->sub_type.nbr.next_hop)),
1148 "adj nbr next-hop ok");
1149 FIB_TEST((ai_01 != ai_02), "ADJs are different");
1150
Neale Ranns81424992017-05-18 03:03:22 -07001151 fib_table_entry_path_add(fib_index,
1152 &pfx_10_10_10_2_s_32,
1153 FIB_SOURCE_ADJ,
1154 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07001155 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07001156 &pfx_10_10_10_2_s_32.fp_addr,
1157 tm->hw[0]->sw_if_index,
1158 ~0, // invalid fib index
1159 1,
1160 NULL,
1161 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001162
1163 fei = fib_table_lookup(fib_index, &pfx_10_10_10_2_s_32);
1164 ai = fib_entry_get_adj(fei);
1165 FIB_TEST((ai_02 == ai), "ADJ-FIB resolves via adj");
1166
1167 /*
1168 * +2 adj-fibs, and their non-shared path-lists
1169 */
1170 FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00001171 FIB_TEST((PNBR+4 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001172 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001173 FIB_TEST((ENBR+4 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001174 fib_entry_pool_size());
1175
1176 /*
Neale Ranns3ee44042016-10-03 13:05:48 +01001177 * Add 2 routes via the first ADJ. ensure path-list sharing
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001178 */
1179 fib_prefix_t pfx_1_1_1_1_s_32 = {
1180 .fp_len = 32,
1181 .fp_proto = FIB_PROTOCOL_IP4,
1182 .fp_addr = {
1183 /* 1.1.1.1/32 */
1184 .ip4.as_u32 = clib_host_to_net_u32(0x01010101),
1185 },
1186 };
1187
1188 fib_table_entry_path_add(fib_index,
1189 &pfx_1_1_1_1_s_32,
1190 FIB_SOURCE_API,
1191 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001192 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001193 &nh_10_10_10_1,
1194 tm->hw[0]->sw_if_index,
1195 ~0, // invalid fib index
1196 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001197 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001198 FIB_ROUTE_PATH_FLAG_NONE);
1199 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
1200 ai = fib_entry_get_adj(fei);
1201 FIB_TEST((ai_01 == ai), "1.1.1.1 resolves via 10.10.10.1");
1202
1203 /*
1204 * +1 entry and a shared path-list
1205 */
1206 FIB_TEST((1 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00001207 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001208 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001209 FIB_TEST((ENBR+5 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001210 fib_entry_pool_size());
1211
1212 /* 1.1.2.0/24 */
1213 fib_prefix_t pfx_1_1_2_0_s_24 = {
1214 .fp_len = 24,
1215 .fp_proto = FIB_PROTOCOL_IP4,
1216 .fp_addr = {
1217 .ip4.as_u32 = clib_host_to_net_u32(0x01010200),
1218 }
1219 };
1220
1221 fib_table_entry_path_add(fib_index,
1222 &pfx_1_1_2_0_s_24,
1223 FIB_SOURCE_API,
1224 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001225 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001226 &nh_10_10_10_1,
1227 tm->hw[0]->sw_if_index,
1228 ~0, // invalid fib index
1229 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001230 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001231 FIB_ROUTE_PATH_FLAG_NONE);
1232 fei = fib_table_lookup(fib_index, &pfx_1_1_2_0_s_24);
1233 ai = fib_entry_get_adj(fei);
1234 FIB_TEST((ai_01 == ai), "1.1.2.0/24 resolves via 10.10.10.1");
1235
1236 /*
1237 * +1 entry only
1238 */
1239 FIB_TEST((1 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00001240 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001241 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001242 FIB_TEST((ENBR+6 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001243 fib_entry_pool_size());
1244
1245 /*
1246 * modify 1.1.2.0/24 to use multipath.
1247 */
1248 fib_table_entry_path_add(fib_index,
1249 &pfx_1_1_2_0_s_24,
1250 FIB_SOURCE_API,
1251 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001252 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001253 &nh_10_10_10_2,
1254 tm->hw[0]->sw_if_index,
1255 ~0, // invalid fib index
1256 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001257 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001258 FIB_ROUTE_PATH_FLAG_NONE);
1259 fei = fib_table_lookup(fib_index, &pfx_1_1_2_0_s_24);
1260 dpo = fib_entry_contribute_ip_forwarding(fei);
Neale Ranns3ee44042016-10-03 13:05:48 +01001261 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1262 1, tm->hw[0]->sw_if_index),
1263 "RPF list for 1.1.2.0/24 contains both adjs");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001264
1265 dpo1 = load_balance_get_bucket(dpo->dpoi_index, 0);
1266 FIB_TEST(DPO_ADJACENCY == dpo1->dpoi_type, "type is %d", dpo1->dpoi_type);
1267 FIB_TEST((ai_01 == dpo1->dpoi_index),
1268 "1.1.2.0/24 bucket 0 resolves via 10.10.10.1 (%d=%d)",
1269 ai_01, dpo1->dpoi_index);
1270
1271 dpo1 = load_balance_get_bucket(dpo->dpoi_index, 1);
1272 FIB_TEST(DPO_ADJACENCY == dpo1->dpoi_type, "type is %d", dpo1->dpoi_type);
1273 FIB_TEST((ai_02 == dpo1->dpoi_index),
1274 "1.1.2.0/24 bucket 1 resolves via 10.10.10.2");
1275
1276 /*
1277 * +1 shared-pathlist
1278 */
1279 FIB_TEST((2 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00001280 FIB_TEST((PNBR+6 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001281 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001282 FIB_TEST((ENBR+6 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001283 fib_entry_pool_size());
1284
1285 /*
1286 * revert the modify
1287 */
1288 fib_table_entry_path_remove(fib_index,
1289 &pfx_1_1_2_0_s_24,
1290 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07001291 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001292 &nh_10_10_10_2,
1293 tm->hw[0]->sw_if_index,
1294 ~0,
1295 1,
1296 FIB_ROUTE_PATH_FLAG_NONE);
1297 fei = fib_table_lookup(fib_index, &pfx_1_1_2_0_s_24);
Neale Ranns3ee44042016-10-03 13:05:48 +01001298 dpo = fib_entry_contribute_ip_forwarding(fei);
1299 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1300 1, tm->hw[0]->sw_if_index),
1301 "RPF list for 1.1.2.0/24 contains one adj");
1302
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001303 ai = fib_entry_get_adj(fei);
1304 FIB_TEST((ai_01 == ai), "1.1.2.0/24 resolves via 10.10.10.1");
1305
1306 /*
1307 * +1 shared-pathlist
1308 */
1309 FIB_TEST((1 == fib_path_list_db_size()), "path list DB is %d",
1310 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001311 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001312 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001313 FIB_TEST((ENBR+6 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001314 fib_entry_pool_size());
1315
1316 /*
1317 * Add 2 recursive routes:
1318 * 100.100.100.100/32 via 1.1.1.1/32 => the via entry is installed.
1319 * 100.100.100.101/32 via 1.1.1.1/32 => the via entry is installed.
1320 */
1321 fib_prefix_t bgp_100_pfx = {
1322 .fp_len = 32,
1323 .fp_proto = FIB_PROTOCOL_IP4,
1324 .fp_addr = {
1325 /* 100.100.100.100/32 */
1326 .ip4.as_u32 = clib_host_to_net_u32(0x64646464),
1327 },
1328 };
1329 /* via 1.1.1.1 */
1330 ip46_address_t nh_1_1_1_1 = {
1331 .ip4.as_u32 = clib_host_to_net_u32(0x01010101),
1332 };
1333
Neale Ranns3ee44042016-10-03 13:05:48 +01001334 fei = fib_table_entry_path_add(fib_index,
1335 &bgp_100_pfx,
1336 FIB_SOURCE_API,
1337 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001338 DPO_PROTO_IP4,
Neale Ranns3ee44042016-10-03 13:05:48 +01001339 &nh_1_1_1_1,
1340 ~0, // no index provided.
1341 fib_index, // nexthop in same fib as route
1342 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001343 NULL,
Neale Ranns3ee44042016-10-03 13:05:48 +01001344 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001345
Neale Ranns3ee44042016-10-03 13:05:48 +01001346 FIB_TEST_REC_FORW(&bgp_100_pfx, &pfx_1_1_1_1_s_32, 0);
1347 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 1,
1348 tm->hw[0]->sw_if_index),
1349 "RPF list for adj-fib contains adj");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001350
1351 /*
1352 * +1 entry and +1 shared-path-list
1353 */
1354 FIB_TEST((2 == fib_path_list_db_size()), "path list DB population:%d",
1355 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001356 FIB_TEST((PNBR+6 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001357 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001358 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001359 fib_entry_pool_size());
1360
1361 fib_prefix_t bgp_101_pfx = {
1362 .fp_len = 32,
1363 .fp_proto = FIB_PROTOCOL_IP4,
1364 .fp_addr = {
1365 /* 100.100.100.101/32 */
1366 .ip4.as_u32 = clib_host_to_net_u32(0x64646465),
1367 },
1368 };
1369
1370 fib_table_entry_path_add(fib_index,
1371 &bgp_101_pfx,
1372 FIB_SOURCE_API,
1373 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001374 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001375 &nh_1_1_1_1,
1376 ~0, // no index provided.
1377 fib_index, // nexthop in same fib as route
1378 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001379 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001380 FIB_ROUTE_PATH_FLAG_NONE);
1381
Neale Ranns3ee44042016-10-03 13:05:48 +01001382 FIB_TEST_REC_FORW(&bgp_101_pfx, &pfx_1_1_1_1_s_32, 0);
1383 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 1,
1384 tm->hw[0]->sw_if_index),
1385 "RPF list for adj-fib contains adj");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001386
1387 /*
1388 * +1 entry, but the recursive path-list is shared.
1389 */
1390 FIB_TEST((2 == fib_path_list_db_size()), "path list DB population:%d",
1391 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001392 FIB_TEST((PNBR+6 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001393 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001394 FIB_TEST((ENBR+8 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001395 fib_entry_pool_size());
1396
1397 /*
Neale Rannsa0558302017-04-13 00:44:52 -07001398 * An special route; one where the user (me) provides the
1399 * adjacency through which the route will resovle by setting the flags
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001400 */
1401 fib_prefix_t ex_pfx = {
1402 .fp_len = 32,
1403 .fp_proto = FIB_PROTOCOL_IP4,
1404 .fp_addr = {
1405 /* 4.4.4.4/32 */
1406 .ip4.as_u32 = clib_host_to_net_u32(0x04040404),
1407 },
1408 };
1409
1410 fib_table_entry_special_add(fib_index,
1411 &ex_pfx,
1412 FIB_SOURCE_SPECIAL,
Neale Rannsa0558302017-04-13 00:44:52 -07001413 FIB_ENTRY_FLAG_LOCAL);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001414 fei = fib_table_lookup_exact_match(fib_index, &ex_pfx);
Neale Rannsa0558302017-04-13 00:44:52 -07001415 dpo = fib_entry_contribute_ip_forwarding(fei);
1416 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
1417 FIB_TEST((DPO_RECEIVE == dpo->dpoi_type),
1418 "local interface adj is local");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001419
1420 fib_table_entry_special_remove(fib_index,
1421 &ex_pfx,
1422 FIB_SOURCE_SPECIAL);
1423 FIB_TEST(FIB_NODE_INDEX_INVALID ==
1424 fib_table_lookup_exact_match(fib_index, &ex_pfx),
1425 "Exclusive reoute removed");
1426
1427 /*
1428 * An EXCLUSIVE route; one where the user (me) provides the exclusive
1429 * adjacency through which the route will resovle
1430 */
Neale Ranns948e00f2016-10-20 13:39:34 +01001431 dpo_id_t ex_dpo = DPO_INVALID;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001432
1433 lookup_dpo_add_or_lock_w_fib_index(fib_index,
1434 DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001435 LOOKUP_UNICAST,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001436 LOOKUP_INPUT_DST_ADDR,
1437 LOOKUP_TABLE_FROM_CONFIG,
1438 &ex_dpo);
1439
1440 fib_table_entry_special_dpo_add(fib_index,
1441 &ex_pfx,
1442 FIB_SOURCE_SPECIAL,
1443 FIB_ENTRY_FLAG_EXCLUSIVE,
1444 &ex_dpo);
1445 fei = fib_table_lookup_exact_match(fib_index, &ex_pfx);
1446 dpo = fib_entry_contribute_ip_forwarding(fei);
1447 FIB_TEST(!dpo_cmp(&ex_dpo, load_balance_get_bucket(dpo->dpoi_index, 0)),
1448 "exclusive remote uses lookup DPO");
1449
Neale Ranns948e00f2016-10-20 13:39:34 +01001450 /*
1451 * update the exclusive to use a different DPO
1452 */
Neale Ranns450cd302016-11-09 17:49:42 +00001453 ip_null_dpo_add_and_lock(DPO_PROTO_IP4,
Neale Ranns948e00f2016-10-20 13:39:34 +01001454 IP_NULL_ACTION_SEND_ICMP_UNREACH,
1455 &ex_dpo);
1456 fib_table_entry_special_dpo_update(fib_index,
1457 &ex_pfx,
1458 FIB_SOURCE_SPECIAL,
1459 FIB_ENTRY_FLAG_EXCLUSIVE,
1460 &ex_dpo);
1461 dpo = fib_entry_contribute_ip_forwarding(fei);
1462 FIB_TEST(!dpo_cmp(&ex_dpo, load_balance_get_bucket(dpo->dpoi_index, 0)),
1463 "exclusive remote uses now uses NULL DPO");
1464
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001465 fib_table_entry_special_remove(fib_index,
1466 &ex_pfx,
1467 FIB_SOURCE_SPECIAL);
1468 FIB_TEST(FIB_NODE_INDEX_INVALID ==
1469 fib_table_lookup_exact_match(fib_index, &ex_pfx),
1470 "Exclusive reoute removed");
1471 dpo_reset(&ex_dpo);
1472
1473 /*
1474 * Add a recursive route:
1475 * 200.200.200.200/32 via 1.1.1.2/32 => the via entry is NOT installed.
1476 */
1477 fib_prefix_t bgp_200_pfx = {
1478 .fp_len = 32,
1479 .fp_proto = FIB_PROTOCOL_IP4,
1480 .fp_addr = {
1481 /* 200.200.200.200/32 */
1482 .ip4.as_u32 = clib_host_to_net_u32(0xc8c8c8c8),
1483 },
1484 };
1485 /* via 1.1.1.2 */
1486 fib_prefix_t pfx_1_1_1_2_s_32 = {
1487 .fp_len = 32,
1488 .fp_proto = FIB_PROTOCOL_IP4,
1489 .fp_addr = {
1490 .ip4.as_u32 = clib_host_to_net_u32(0x01010102),
1491 },
1492 };
1493
Neale Ranns57b58602017-07-15 07:37:25 -07001494 fei = fib_table_entry_path_add(fib_index,
1495 &bgp_200_pfx,
1496 FIB_SOURCE_API,
1497 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001498 DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07001499 &pfx_1_1_1_2_s_32.fp_addr,
1500 ~0, // no index provided.
1501 fib_index, // nexthop in same fib as route
1502 1,
1503 NULL,
1504 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001505
Neale Ranns57b58602017-07-15 07:37:25 -07001506 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
1507 "Recursive via unresolved is drop");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001508
1509 /*
1510 * the adj should be recursive via drop, since the route resolves via
1511 * the default route, which is itself a DROP
1512 */
1513 fei = fib_table_lookup(fib_index, &pfx_1_1_1_2_s_32);
1514 dpo1 = fib_entry_contribute_ip_forwarding(fei);
1515 FIB_TEST(load_balance_is_drop(dpo1), "1.1.1.2/32 is drop");
Neale Ranns3ee44042016-10-03 13:05:48 +01001516 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 0),
1517 "RPF list for 1.1.1.2/32 contains 0 adjs");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001518
1519 /*
1520 * +2 entry and +1 shared-path-list
1521 */
1522 FIB_TEST((3 == fib_path_list_db_size()), "path list DB population:%d",
1523 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001524 FIB_TEST((PNBR+7 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001525 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001526 FIB_TEST((ENBR+10 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001527 fib_entry_pool_size());
1528
1529 /*
1530 * Unequal Cost load-balance. 3:1 ratio. fits in a 4 bucket LB
Neale Ranns3ee44042016-10-03 13:05:48 +01001531 * The paths are sort by NH first. in this case the the path with greater
1532 * weight is first in the set. This ordering is to test the RPF sort|uniq logic
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001533 */
1534 fib_prefix_t pfx_1_2_3_4_s_32 = {
1535 .fp_len = 32,
1536 .fp_proto = FIB_PROTOCOL_IP4,
1537 .fp_addr = {
1538 .ip4.as_u32 = clib_host_to_net_u32(0x01020304),
1539 },
1540 };
1541 fib_table_entry_path_add(fib_index,
1542 &pfx_1_2_3_4_s_32,
1543 FIB_SOURCE_API,
1544 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001545 DPO_PROTO_IP4,
Neale Ranns3ee44042016-10-03 13:05:48 +01001546 &nh_10_10_10_1,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001547 tm->hw[0]->sw_if_index,
1548 ~0,
1549 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001550 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001551 FIB_ROUTE_PATH_FLAG_NONE);
1552 fei = fib_table_entry_path_add(fib_index,
1553 &pfx_1_2_3_4_s_32,
1554 FIB_SOURCE_API,
1555 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001556 DPO_PROTO_IP4,
Neale Ranns3ee44042016-10-03 13:05:48 +01001557 &nh_12_12_12_12,
1558 tm->hw[1]->sw_if_index,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001559 ~0,
1560 3,
Neale Rannsad422ed2016-11-02 14:20:04 +00001561 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001562 FIB_ROUTE_PATH_FLAG_NONE);
1563
1564 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "1.2.3.4/32 presnet");
1565 dpo = fib_entry_contribute_ip_forwarding(fei);
1566 lb = load_balance_get(dpo->dpoi_index);
1567 FIB_TEST((lb->lb_n_buckets == 4),
1568 "1.2.3.4/32 LB has %d bucket",
1569 lb->lb_n_buckets);
1570
Neale Ranns3ee44042016-10-03 13:05:48 +01001571 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_4_s_32, 0, ai_12_12_12_12);
1572 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_4_s_32, 1, ai_12_12_12_12);
1573 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_4_s_32, 2, ai_12_12_12_12);
1574 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_4_s_32, 3, ai_01);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001575
Neale Ranns3ee44042016-10-03 13:05:48 +01001576 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 2,
1577 tm->hw[0]->sw_if_index,
1578 tm->hw[1]->sw_if_index),
1579 "RPF list for 1.2.3.4/32 contains both adjs");
1580
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001581
1582 /*
1583 * Unequal Cost load-balance. 4:1 ratio.
1584 * fits in a 16 bucket LB with ratio 13:3
1585 */
1586 fib_prefix_t pfx_1_2_3_5_s_32 = {
1587 .fp_len = 32,
1588 .fp_proto = FIB_PROTOCOL_IP4,
1589 .fp_addr = {
1590 .ip4.as_u32 = clib_host_to_net_u32(0x01020305),
1591 },
1592 };
1593 fib_table_entry_path_add(fib_index,
1594 &pfx_1_2_3_5_s_32,
1595 FIB_SOURCE_API,
1596 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001597 DPO_PROTO_IP4,
Neale Ranns3ee44042016-10-03 13:05:48 +01001598 &nh_12_12_12_12,
1599 tm->hw[1]->sw_if_index,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001600 ~0,
1601 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001602 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001603 FIB_ROUTE_PATH_FLAG_NONE);
1604 fei = fib_table_entry_path_add(fib_index,
1605 &pfx_1_2_3_5_s_32,
1606 FIB_SOURCE_API,
1607 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001608 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001609 &nh_10_10_10_1,
1610 tm->hw[0]->sw_if_index,
1611 ~0,
1612 4,
Neale Rannsad422ed2016-11-02 14:20:04 +00001613 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001614 FIB_ROUTE_PATH_FLAG_NONE);
1615
1616 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "1.2.3.5/32 presnet");
1617 dpo = fib_entry_contribute_ip_forwarding(fei);
1618 lb = load_balance_get(dpo->dpoi_index);
1619 FIB_TEST((lb->lb_n_buckets == 16),
1620 "1.2.3.5/32 LB has %d bucket",
1621 lb->lb_n_buckets);
1622
1623 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 0, ai_01);
1624 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 1, ai_01);
1625 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 2, ai_01);
1626 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 3, ai_01);
1627 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 4, ai_01);
1628 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 5, ai_01);
1629 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 6, ai_01);
1630 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 7, ai_01);
1631 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 8, ai_01);
1632 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 9, ai_01);
1633 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 10, ai_01);
1634 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 11, ai_01);
1635 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 12, ai_01);
Neale Ranns3ee44042016-10-03 13:05:48 +01001636 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 13, ai_12_12_12_12);
1637 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 14, ai_12_12_12_12);
1638 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 15, ai_12_12_12_12);
1639
1640 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 2,
1641 tm->hw[0]->sw_if_index,
1642 tm->hw[1]->sw_if_index),
1643 "RPF list for 1.2.3.4/32 contains both adjs");
1644
1645 /*
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001646 * Test UCMP with a large weight skew - this produces load-balance objects with large
1647 * numbers of buckets to accommodate the skew. By updating said load-balances we are
1648 * laso testing the LB in placce modify code when number of buckets is large.
1649 */
1650 fib_prefix_t pfx_6_6_6_6_s_32 = {
1651 .fp_len = 32,
1652 .fp_proto = FIB_PROTOCOL_IP4,
1653 .fp_addr = {
1654 /* 1.1.1.1/32 */
1655 .ip4.as_u32 = clib_host_to_net_u32(0x06060606),
1656 },
1657 };
Neale Ranns81424992017-05-18 03:03:22 -07001658 fib_test_lb_bucket_t ip_o_10_10_10_1 = {
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001659 .type = FT_LB_ADJ,
1660 .adj = {
1661 .adj = ai_01,
1662 },
1663 };
Neale Ranns81424992017-05-18 03:03:22 -07001664 fib_test_lb_bucket_t ip_o_10_10_10_2 = {
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001665 .type = FT_LB_ADJ,
1666 .adj = {
1667 .adj = ai_02,
1668 },
1669 };
1670 fib_test_lb_bucket_t ip_6_6_6_6_o_12_12_12_12 = {
1671 .type = FT_LB_ADJ,
1672 .adj = {
1673 .adj = ai_12_12_12_12,
1674 },
1675 };
1676 fib_table_entry_update_one_path(fib_index,
1677 &pfx_6_6_6_6_s_32,
1678 FIB_SOURCE_API,
1679 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001680 DPO_PROTO_IP4,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001681 &nh_10_10_10_1,
1682 tm->hw[0]->sw_if_index,
1683 ~0, // invalid fib index
1684 0, // zero weigth
Neale Rannsad422ed2016-11-02 14:20:04 +00001685 NULL,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001686 FIB_ROUTE_PATH_FLAG_NONE);
1687
1688 fei = fib_table_lookup(fib_index, &pfx_6_6_6_6_s_32);
1689 FIB_TEST(fib_test_validate_entry(fei,
1690 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1691 1,
Neale Ranns81424992017-05-18 03:03:22 -07001692 &ip_o_10_10_10_1),
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001693 "6.6.6.6/32 via 10.10.10.1");
1694
1695 fib_table_entry_path_add(fib_index,
1696 &pfx_6_6_6_6_s_32,
1697 FIB_SOURCE_API,
1698 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001699 DPO_PROTO_IP4,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001700 &nh_10_10_10_2,
1701 tm->hw[0]->sw_if_index,
1702 ~0, // invalid fib index
1703 100,
Neale Rannsad422ed2016-11-02 14:20:04 +00001704 NULL,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001705 FIB_ROUTE_PATH_FLAG_NONE);
1706
1707 fei = fib_table_lookup(fib_index, &pfx_6_6_6_6_s_32);
1708 FIB_TEST(fib_test_validate_entry(fei,
1709 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1710 64,
Neale Ranns81424992017-05-18 03:03:22 -07001711 &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_2,
1774 &ip_o_10_10_10_1),
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001775 "6.6.6.6/32 via 10.10.10.1 and 10.10.10.2 in 63:1 ratio");
1776
1777 fib_table_entry_path_add(fib_index,
1778 &pfx_6_6_6_6_s_32,
1779 FIB_SOURCE_API,
1780 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001781 DPO_PROTO_IP4,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001782 &nh_12_12_12_12,
1783 tm->hw[1]->sw_if_index,
1784 ~0, // invalid fib index
1785 100,
Neale Rannsad422ed2016-11-02 14:20:04 +00001786 NULL,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001787 FIB_ROUTE_PATH_FLAG_NONE);
1788
1789 fei = fib_table_lookup(fib_index, &pfx_6_6_6_6_s_32);
1790 FIB_TEST(fib_test_validate_entry(fei,
1791 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1792 128,
Neale Ranns81424992017-05-18 03:03:22 -07001793 &ip_o_10_10_10_1,
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,
1857 &ip_o_10_10_10_2,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001858 &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 &ip_6_6_6_6_o_12_12_12_12),
1921 "6.6.6.6/32 via 10.10.10.1 and 10.10.10.2 in 63:1 ratio");
1922
1923 fib_table_entry_path_remove(fib_index,
1924 &pfx_6_6_6_6_s_32,
1925 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07001926 DPO_PROTO_IP4,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001927 &nh_12_12_12_12,
1928 tm->hw[1]->sw_if_index,
1929 ~0, // invalid fib index
1930 100,
1931 FIB_ROUTE_PATH_FLAG_NONE);
1932
1933 fei = fib_table_lookup(fib_index, &pfx_6_6_6_6_s_32);
1934 FIB_TEST(fib_test_validate_entry(fei,
1935 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1936 64,
Neale Ranns81424992017-05-18 03:03:22 -07001937 &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_2,
2000 &ip_o_10_10_10_1),
Neale Ranns0bd36ea2016-11-16 11:47:44 +00002001 "6.6.6.6/32 via 10.10.10.1 and 10.10.10.2 in 63:1 ratio");
2002
2003 fib_table_entry_path_remove(fib_index,
2004 &pfx_6_6_6_6_s_32,
2005 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002006 DPO_PROTO_IP4,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00002007 &nh_10_10_10_2,
2008 tm->hw[0]->sw_if_index,
2009 ~0, // invalid fib index
2010 100,
2011 FIB_ROUTE_PATH_FLAG_NONE);
2012
2013 fei = fib_table_lookup(fib_index, &pfx_6_6_6_6_s_32);
2014 FIB_TEST(fib_test_validate_entry(fei,
2015 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
2016 1,
Neale Ranns81424992017-05-18 03:03:22 -07002017 &ip_o_10_10_10_1),
Neale Ranns0bd36ea2016-11-16 11:47:44 +00002018 "6.6.6.6/32 via 10.10.10.1");
2019
2020 fib_table_entry_delete(fib_index, &pfx_6_6_6_6_s_32, FIB_SOURCE_API);
2021
2022 /*
Neale Ranns3ee44042016-10-03 13:05:48 +01002023 * A recursive via the two unequal cost entries
2024 */
2025 fib_prefix_t bgp_44_s_32 = {
2026 .fp_len = 32,
2027 .fp_proto = FIB_PROTOCOL_IP4,
2028 .fp_addr = {
2029 /* 200.200.200.201/32 */
2030 .ip4.as_u32 = clib_host_to_net_u32(0x44444444),
2031 },
2032 };
2033 fei = fib_table_entry_path_add(fib_index,
2034 &bgp_44_s_32,
2035 FIB_SOURCE_API,
2036 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002037 DPO_PROTO_IP4,
Neale Ranns3ee44042016-10-03 13:05:48 +01002038 &pfx_1_2_3_4_s_32.fp_addr,
2039 ~0,
2040 fib_index,
2041 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002042 NULL,
Neale Ranns3ee44042016-10-03 13:05:48 +01002043 FIB_ROUTE_PATH_FLAG_NONE);
2044 fei = fib_table_entry_path_add(fib_index,
2045 &bgp_44_s_32,
2046 FIB_SOURCE_API,
2047 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002048 DPO_PROTO_IP4,
Neale Ranns3ee44042016-10-03 13:05:48 +01002049 &pfx_1_2_3_5_s_32.fp_addr,
2050 ~0,
2051 fib_index,
2052 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002053 NULL,
Neale Ranns3ee44042016-10-03 13:05:48 +01002054 FIB_ROUTE_PATH_FLAG_NONE);
2055
2056 FIB_TEST_REC_FORW(&bgp_44_s_32, &pfx_1_2_3_4_s_32, 0);
2057 FIB_TEST_REC_FORW(&bgp_44_s_32, &pfx_1_2_3_5_s_32, 1);
2058 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 2,
2059 tm->hw[0]->sw_if_index,
2060 tm->hw[1]->sw_if_index),
2061 "RPF list for 1.2.3.4/32 contains both adjs");
2062
2063 /*
2064 * test the uRPF check functions
2065 */
Neale Ranns948e00f2016-10-20 13:39:34 +01002066 dpo_id_t dpo_44 = DPO_INVALID;
Neale Ranns3ee44042016-10-03 13:05:48 +01002067 index_t urpfi;
2068
2069 fib_entry_contribute_forwarding(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, &dpo_44);
2070 urpfi = load_balance_get_urpf(dpo_44.dpoi_index);
2071
2072 FIB_TEST(fib_urpf_check(urpfi, tm->hw[0]->sw_if_index),
2073 "uRPF check for 68.68.68.68/32 on %d OK",
2074 tm->hw[0]->sw_if_index);
2075 FIB_TEST(fib_urpf_check(urpfi, tm->hw[1]->sw_if_index),
2076 "uRPF check for 68.68.68.68/32 on %d OK",
2077 tm->hw[1]->sw_if_index);
2078 FIB_TEST(!fib_urpf_check(urpfi, 99),
2079 "uRPF check for 68.68.68.68/32 on 99 not-OK",
2080 99);
2081 dpo_reset(&dpo_44);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002082
2083 fib_table_entry_delete(fib_index,
Neale Ranns3ee44042016-10-03 13:05:48 +01002084 &bgp_44_s_32,
2085 FIB_SOURCE_API);
2086 fib_table_entry_delete(fib_index,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002087 &pfx_1_2_3_5_s_32,
2088 FIB_SOURCE_API);
Neale Ranns3ee44042016-10-03 13:05:48 +01002089 fib_table_entry_delete(fib_index,
2090 &pfx_1_2_3_4_s_32,
2091 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002092
2093 /*
2094 * Add a recursive route:
2095 * 200.200.200.201/32 via 1.1.1.200/32 => the via entry is NOT installed.
2096 */
2097 fib_prefix_t bgp_201_pfx = {
2098 .fp_len = 32,
2099 .fp_proto = FIB_PROTOCOL_IP4,
2100 .fp_addr = {
2101 /* 200.200.200.201/32 */
2102 .ip4.as_u32 = clib_host_to_net_u32(0xc8c8c8c9),
2103 },
2104 };
2105 /* via 1.1.1.200 */
2106 fib_prefix_t pfx_1_1_1_200_s_32 = {
2107 .fp_len = 32,
2108 .fp_proto = FIB_PROTOCOL_IP4,
2109 .fp_addr = {
2110 .ip4.as_u32 = clib_host_to_net_u32(0x010101c8),
2111 },
2112 };
2113
Neale Ranns57b58602017-07-15 07:37:25 -07002114 fei = fib_table_entry_path_add(fib_index,
2115 &bgp_201_pfx,
2116 FIB_SOURCE_API,
2117 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002118 DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07002119 &pfx_1_1_1_200_s_32.fp_addr,
2120 ~0, // no index provided.
2121 fib_index, // nexthop in same fib as route
2122 1,
2123 NULL,
2124 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002125
Neale Ranns57b58602017-07-15 07:37:25 -07002126 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2127 "Recursive via unresolved is drop");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002128
2129 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_200_s_32);
2130 FIB_TEST((FIB_ENTRY_FLAG_NONE == fib_entry_get_flags(fei)),
2131 "Flags set on RR via non-attached");
Neale Ranns3ee44042016-10-03 13:05:48 +01002132 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 0),
2133 "RPF list for BGP route empty");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002134
2135 /*
2136 * +2 entry (BGP & RR) and +1 shared-path-list
2137 */
2138 FIB_TEST((4 == fib_path_list_db_size()), "path list DB population:%d",
2139 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002140 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002141 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002142 FIB_TEST((ENBR+12 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002143 fib_entry_pool_size());
2144
2145 /*
2146 * insert a route that covers the missing 1.1.1.2/32. we epxect
2147 * 200.200.200.200/32 and 200.200.200.201/32 to resolve through it.
2148 */
2149 fib_prefix_t pfx_1_1_1_0_s_24 = {
2150 .fp_len = 24,
2151 .fp_proto = FIB_PROTOCOL_IP4,
2152 .fp_addr = {
2153 /* 1.1.1.0/24 */
2154 .ip4.as_u32 = clib_host_to_net_u32(0x01010100),
2155 },
2156 };
2157
2158 fib_table_entry_path_add(fib_index,
2159 &pfx_1_1_1_0_s_24,
2160 FIB_SOURCE_API,
2161 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002162 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002163 &nh_10_10_10_1,
2164 tm->hw[0]->sw_if_index,
2165 ~0, // invalid fib index
2166 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002167 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002168 FIB_ROUTE_PATH_FLAG_NONE);
2169 fei = fib_table_lookup(fib_index, &pfx_1_1_1_0_s_24);
2170 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2171 ai = fib_entry_get_adj(fei);
2172 FIB_TEST((ai_01 == ai), "1.1.1.0/24 resolves via 10.10.10.1");
2173 fei = fib_table_lookup(fib_index, &pfx_1_1_1_2_s_32);
2174 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2175 ai = fib_entry_get_adj(fei);
2176 FIB_TEST((ai_01 == ai), "1.1.1.2/32 resolves via 10.10.10.1");
2177 fei = fib_table_lookup(fib_index, &pfx_1_1_1_200_s_32);
2178 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2179 ai = fib_entry_get_adj(fei);
2180 FIB_TEST((ai_01 == ai), "1.1.1.200/24 resolves via 10.10.10.1");
2181
2182 /*
2183 * +1 entry. 1.1.1.1/32 already uses 10.10.10.1 so no new pah-list
2184 */
2185 FIB_TEST((4 == fib_path_list_db_size()), "path list DB population:%d",
2186 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002187 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002188 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002189 FIB_TEST((ENBR+13 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002190 fib_entry_pool_size());
2191
2192 /*
2193 * the recursive adj for 200.200.200.200 should be updated.
2194 */
Neale Ranns3ee44042016-10-03 13:05:48 +01002195 FIB_TEST_REC_FORW(&bgp_201_pfx, &pfx_1_1_1_200_s_32, 0);
2196 FIB_TEST_REC_FORW(&bgp_200_pfx, &pfx_1_1_1_2_s_32, 0);
2197 fei = fib_table_lookup(fib_index, &bgp_200_pfx);
2198 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 1,
2199 tm->hw[0]->sw_if_index),
2200 "RPF list for BGP route has itf index 0");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002201
2202 /*
2203 * insert a more specific route than 1.1.1.0/24 that also covers the
2204 * missing 1.1.1.2/32, but not 1.1.1.200/32. we epxect
2205 * 200.200.200.200 to resolve through it.
2206 */
2207 fib_prefix_t pfx_1_1_1_0_s_28 = {
2208 .fp_len = 28,
2209 .fp_proto = FIB_PROTOCOL_IP4,
2210 .fp_addr = {
2211 /* 1.1.1.0/24 */
2212 .ip4.as_u32 = clib_host_to_net_u32(0x01010100),
2213 },
2214 };
2215
2216 fib_table_entry_path_add(fib_index,
2217 &pfx_1_1_1_0_s_28,
2218 FIB_SOURCE_API,
2219 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002220 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002221 &nh_10_10_10_2,
2222 tm->hw[0]->sw_if_index,
2223 ~0, // invalid fib index
2224 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002225 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002226 FIB_ROUTE_PATH_FLAG_NONE);
2227 fei = fib_table_lookup(fib_index, &pfx_1_1_1_0_s_28);
2228 dpo2 = fib_entry_contribute_ip_forwarding(fei);
2229 ai = fib_entry_get_adj(fei);
2230 FIB_TEST((ai_02 == ai), "1.1.1.0/24 resolves via 10.10.10.2");
2231
2232 /*
2233 * +1 entry. +1 shared path-list
2234 */
2235 FIB_TEST((5 == fib_path_list_db_size()), "path list DB population:%d",
2236 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002237 FIB_TEST((PNBR+9 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002238 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002239 FIB_TEST((ENBR+14 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002240 fib_entry_pool_size());
2241
2242 /*
2243 * the recursive adj for 200.200.200.200 should be updated.
2244 * 200.200.200.201 remains unchanged.
2245 */
Neale Ranns3ee44042016-10-03 13:05:48 +01002246 FIB_TEST_REC_FORW(&bgp_201_pfx, &pfx_1_1_1_200_s_32, 0);
2247 FIB_TEST_REC_FORW(&bgp_200_pfx, &pfx_1_1_1_2_s_32, 0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002248
2249 /*
2250 * remove this /28. 200.200.200.200/32 should revert back to via 1.1.1.0/24
2251 */
2252 fib_table_entry_path_remove(fib_index,
2253 &pfx_1_1_1_0_s_28,
2254 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002255 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002256 &nh_10_10_10_2,
2257 tm->hw[0]->sw_if_index,
2258 ~0,
2259 1,
2260 FIB_ROUTE_PATH_FLAG_NONE);
2261 FIB_TEST((fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_0_s_28) ==
2262 FIB_NODE_INDEX_INVALID),
2263 "1.1.1.0/28 removed");
2264 FIB_TEST((fib_table_lookup(fib_index, &pfx_1_1_1_0_s_28) ==
2265 fib_table_lookup(fib_index, &pfx_1_1_1_0_s_24)),
2266 "1.1.1.0/28 lookup via /24");
Neale Ranns3ee44042016-10-03 13:05:48 +01002267 FIB_TEST_REC_FORW(&bgp_201_pfx, &pfx_1_1_1_200_s_32, 0);
2268 FIB_TEST_REC_FORW(&bgp_200_pfx, &pfx_1_1_1_2_s_32, 0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002269
2270 /*
2271 * -1 entry. -1 shared path-list
2272 */
2273 FIB_TEST((4 == fib_path_list_db_size()), "path list DB population:%d",
2274 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002275 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002276 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002277 FIB_TEST((ENBR+13 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002278 fib_entry_pool_size());
2279
2280 /*
2281 * remove 1.1.1.0/24. 200.200.200.200/32 should revert back to via 0.0.0.0/0
2282 */
2283 fib_table_entry_path_remove(fib_index,
2284 &pfx_1_1_1_0_s_24,
2285 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002286 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002287 &nh_10_10_10_1,
2288 tm->hw[0]->sw_if_index,
2289 ~0,
2290 1,
2291 FIB_ROUTE_PATH_FLAG_NONE);
2292 FIB_TEST((fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_0_s_24) ==
2293 FIB_NODE_INDEX_INVALID),
2294 "1.1.1.0/24 removed");
2295
2296 fei = fib_table_lookup(fib_index, &pfx_1_1_1_2_s_32);
2297 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2298 "1.1.1.2/32 route is DROP");
Neale Ranns57b58602017-07-15 07:37:25 -07002299 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_200_s_32);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002300 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2301 "1.1.1.200/32 route is DROP");
2302
Neale Ranns57b58602017-07-15 07:37:25 -07002303 fei = fib_table_lookup_exact_match(fib_index, &bgp_201_pfx);
2304 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2305 "201 is drop");
2306 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
2307 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2308 "200 is drop");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002309
2310 /*
2311 * -1 entry
2312 */
2313 FIB_TEST((4 == fib_path_list_db_size()), "path list DB population:%d",
2314 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002315 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002316 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002317 FIB_TEST((ENBR+12 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002318 fib_entry_pool_size());
2319
2320 /*
2321 * insert the missing 1.1.1.2/32
2322 */
2323 fei = fib_table_entry_path_add(fib_index,
2324 &pfx_1_1_1_2_s_32,
2325 FIB_SOURCE_API,
2326 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002327 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002328 &nh_10_10_10_1,
2329 tm->hw[0]->sw_if_index,
2330 ~0, // invalid fib index
2331 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002332 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002333 FIB_ROUTE_PATH_FLAG_NONE);
2334 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2335 ai = fib_entry_get_adj(fei);
2336 FIB_TEST((ai = ai_01), "1.1.1.2/32 resolves via 10.10.10.1");
2337
Neale Ranns57b58602017-07-15 07:37:25 -07002338 fei = fib_table_lookup_exact_match(fib_index, &bgp_201_pfx);
2339 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2340 "201 is drop");
Neale Ranns3ee44042016-10-03 13:05:48 +01002341 FIB_TEST_REC_FORW(&bgp_200_pfx, &pfx_1_1_1_2_s_32, 0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002342
2343 /*
2344 * no change. 1.1.1.2/32 was already there RR sourced.
2345 */
2346 FIB_TEST((4 == fib_path_list_db_size()), "path list DB population:%d",
2347 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002348 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002349 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002350 FIB_TEST((ENBR+12 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002351 fib_entry_pool_size());
2352
2353 /*
Neale Ranns57b58602017-07-15 07:37:25 -07002354 * give 201 a resolved path.
2355 * it now has the unresolved 1.1.1.200 and the resolved 1.1.1.2,
2356 * only the latter contributes forwarding.
2357 */
2358 fei = fib_table_entry_path_add(fib_index,
2359 &bgp_201_pfx,
2360 FIB_SOURCE_API,
2361 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002362 DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07002363 &pfx_1_1_1_2_s_32.fp_addr,
2364 ~0,
2365 fib_index,
2366 1,
2367 NULL,
2368 FIB_ROUTE_PATH_FLAG_NONE);
2369 FIB_TEST_REC_FORW(&bgp_201_pfx, &pfx_1_1_1_2_s_32, 0);
2370 fib_table_entry_path_remove(fib_index,
2371 &bgp_201_pfx,
2372 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002373 DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07002374 &pfx_1_1_1_2_s_32.fp_addr,
2375 ~0,
2376 fib_index,
2377 1,
2378 FIB_ROUTE_PATH_FLAG_NONE);
2379
2380 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002381 * remove 200.200.200.201/32 which does not have a valid via FIB
2382 */
2383 fib_table_entry_path_remove(fib_index,
2384 &bgp_201_pfx,
2385 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002386 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002387 &pfx_1_1_1_200_s_32.fp_addr,
2388 ~0, // no index provided.
2389 fib_index,
2390 1,
2391 FIB_ROUTE_PATH_FLAG_NONE);
2392
2393 /*
2394 * -2 entries (BGP and RR). -1 shared path-list;
2395 */
2396 FIB_TEST((fib_table_lookup_exact_match(fib_index, &bgp_201_pfx) ==
2397 FIB_NODE_INDEX_INVALID),
2398 "200.200.200.201/32 removed");
2399 FIB_TEST((fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_200_s_32) ==
2400 FIB_NODE_INDEX_INVALID),
2401 "1.1.1.200/32 removed");
2402
2403 FIB_TEST((3 == fib_path_list_db_size()), "path list DB population:%d",
2404 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002405 FIB_TEST((PNBR+7 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002406 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002407 FIB_TEST((ENBR+10 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002408 fib_entry_pool_size());
2409
2410 /*
2411 * remove 200.200.200.200/32 which does have a valid via FIB
2412 */
2413 fib_table_entry_path_remove(fib_index,
2414 &bgp_200_pfx,
2415 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002416 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002417 &pfx_1_1_1_2_s_32.fp_addr,
2418 ~0, // no index provided.
2419 fib_index,
2420 1,
2421 FIB_ROUTE_PATH_FLAG_NONE);
2422
2423 FIB_TEST((fib_table_lookup_exact_match(fib_index, &bgp_200_pfx) ==
2424 FIB_NODE_INDEX_INVALID),
2425 "200.200.200.200/32 removed");
2426 FIB_TEST((fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_2_s_32) !=
2427 FIB_NODE_INDEX_INVALID),
2428 "1.1.1.2/32 still present");
2429
2430 /*
2431 * -1 entry (BGP, the RR source is also API sourced). -1 shared path-list;
2432 */
2433 FIB_TEST((2 == fib_path_list_db_size()), "path list DB population:%d",
2434 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002435 FIB_TEST((PNBR+6 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002436 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002437 FIB_TEST((ENBR+9 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002438 fib_entry_pool_size());
2439
2440 /*
2441 * A recursive prefix that has a 2 path load-balance.
2442 * It also shares a next-hop with other BGP prefixes and hence
2443 * test the ref counting of RR sourced prefixes and 2 level LB.
2444 */
2445 const fib_prefix_t bgp_102 = {
2446 .fp_len = 32,
2447 .fp_proto = FIB_PROTOCOL_IP4,
2448 .fp_addr = {
2449 /* 100.100.100.101/32 */
2450 .ip4.as_u32 = clib_host_to_net_u32(0x64646466),
2451 },
2452 };
2453 fib_table_entry_path_add(fib_index,
2454 &bgp_102,
2455 FIB_SOURCE_API,
2456 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002457 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002458 &pfx_1_1_1_1_s_32.fp_addr,
2459 ~0, // no index provided.
2460 fib_index, // same as route
2461 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002462 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002463 FIB_ROUTE_PATH_FLAG_NONE);
2464 fib_table_entry_path_add(fib_index,
2465 &bgp_102,
2466 FIB_SOURCE_API,
2467 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002468 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002469 &pfx_1_1_1_2_s_32.fp_addr,
2470 ~0, // no index provided.
2471 fib_index, // same as route's FIB
2472 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002473 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002474 FIB_ROUTE_PATH_FLAG_NONE);
2475 fei = fib_table_lookup_exact_match(fib_index, &bgp_102);
2476 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "100.100.100.102/32 presnet");
2477 dpo = fib_entry_contribute_ip_forwarding(fei);
2478
2479 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_1_s_32);
2480 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2481 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_2_s_32);
2482 dpo2 = fib_entry_contribute_ip_forwarding(fei);
2483
2484 lb = load_balance_get(dpo->dpoi_index);
2485 FIB_TEST((lb->lb_n_buckets == 2), "Recursive LB has %d bucket", lb->lb_n_buckets);
2486 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket(dpo->dpoi_index, 0)),
2487 "First via 10.10.10.1");
2488 FIB_TEST(!dpo_cmp(dpo2, load_balance_get_bucket(dpo->dpoi_index, 1)),
2489 "Second via 10.10.10.1");
2490
2491 fib_table_entry_path_remove(fib_index,
2492 &bgp_102,
2493 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002494 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002495 &pfx_1_1_1_1_s_32.fp_addr,
2496 ~0, // no index provided.
2497 fib_index, // same as route's FIB
2498 1,
2499 FIB_ROUTE_PATH_FLAG_NONE);
2500 fib_table_entry_path_remove(fib_index,
2501 &bgp_102,
2502 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002503 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002504 &pfx_1_1_1_2_s_32.fp_addr,
2505 ~0, // no index provided.
2506 fib_index, // same as route's FIB
2507 1,
2508 FIB_ROUTE_PATH_FLAG_NONE);
2509 fei = fib_table_lookup_exact_match(fib_index, &bgp_102);
2510 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "100.100.100.102/32 removed");
2511
2512 /*
2513 * remove the remaining recursives
2514 */
2515 fib_table_entry_path_remove(fib_index,
2516 &bgp_100_pfx,
2517 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002518 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002519 &pfx_1_1_1_1_s_32.fp_addr,
2520 ~0, // no index provided.
2521 fib_index, // same as route's FIB
2522 1,
2523 FIB_ROUTE_PATH_FLAG_NONE);
2524 fib_table_entry_path_remove(fib_index,
2525 &bgp_101_pfx,
2526 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002527 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002528 &pfx_1_1_1_1_s_32.fp_addr,
2529 ~0, // no index provided.
2530 fib_index, // same as route's FIB
2531 1,
2532 FIB_ROUTE_PATH_FLAG_NONE);
2533 FIB_TEST((fib_table_lookup_exact_match(fib_index, &bgp_100_pfx) ==
2534 FIB_NODE_INDEX_INVALID),
2535 "100.100.100.100/32 removed");
2536 FIB_TEST((fib_table_lookup_exact_match(fib_index, &bgp_101_pfx) ==
2537 FIB_NODE_INDEX_INVALID),
2538 "100.100.100.101/32 removed");
2539
2540 /*
2541 * -2 entry (2*BGP, the RR source is also API sourced). -1 shared path-list;
2542 */
2543 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
2544 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002545 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002546 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002547 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002548 fib_entry_pool_size());
2549
2550 /*
2551 * Add a recursive route via a connected cover, using an adj-fib that does exist
2552 */
2553 fib_table_entry_path_add(fib_index,
2554 &bgp_200_pfx,
2555 FIB_SOURCE_API,
2556 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002557 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002558 &nh_10_10_10_1,
2559 ~0, // no index provided.
2560 fib_index, // Same as route's FIB
2561 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002562 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002563 FIB_ROUTE_PATH_FLAG_NONE);
2564
2565 /*
2566 * +1 entry. +1 shared path-list (recursive via 10.10.10.1)
2567 */
2568 FIB_TEST((2 == fib_path_list_db_size()), "path list DB population:%d",
2569 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002570 FIB_TEST((PNBR+6 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002571 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002572 FIB_TEST((ENBR+8 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002573 fib_entry_pool_size());
2574
2575 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
2576 dpo = fib_entry_contribute_ip_forwarding(fei);
2577
2578 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
2579 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2580
2581 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket(dpo->dpoi_index, 0)),
2582 "200.200.200.200/32 is recursive via adj for 10.10.10.1");
2583
2584 FIB_TEST((FIB_ENTRY_FLAG_ATTACHED == fib_entry_get_flags(fei)),
2585 "Flags set on RR via existing attached");
2586
2587 /*
2588 * Add a recursive route via a connected cover, using and adj-fib that does
2589 * not exist
2590 */
2591 ip46_address_t nh_10_10_10_3 = {
2592 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a03),
2593 };
2594 fib_prefix_t pfx_10_10_10_3 = {
2595 .fp_len = 32,
2596 .fp_proto = FIB_PROTOCOL_IP4,
2597 .fp_addr = nh_10_10_10_3,
2598 };
2599
2600 fib_table_entry_path_add(fib_index,
2601 &bgp_201_pfx,
2602 FIB_SOURCE_API,
2603 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002604 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002605 &nh_10_10_10_3,
2606 ~0, // no index provided.
2607 fib_index,
2608 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002609 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002610 FIB_ROUTE_PATH_FLAG_NONE);
2611
2612 /*
2613 * +2 entries (BGP and RR). +1 shared path-list (recursive via 10.10.10.3) and
2614 * one unshared non-recursive via 10.10.10.3
2615 */
2616 FIB_TEST((3 == fib_path_list_db_size()), "path list DB population:%d",
2617 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002618 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002619 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002620 FIB_TEST((ENBR+10 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002621 fib_entry_pool_size());
2622
2623 ai_03 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01002624 VNET_LINK_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002625 &nh_10_10_10_3,
2626 tm->hw[0]->sw_if_index);
2627
2628 fei = fib_table_lookup_exact_match(fib_index, &bgp_201_pfx);
2629 dpo = fib_entry_contribute_ip_forwarding(fei);
2630 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_3);
2631 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2632
2633 ai = fib_entry_get_adj(fei);
2634 FIB_TEST((ai == ai_03), "adj for 10.10.10.3/32 is via adj for 10.10.10.3");
2635 FIB_TEST(((FIB_ENTRY_FLAG_ATTACHED | FIB_ENTRY_FLAG_CONNECTED) ==
2636 fib_entry_get_flags(fei)),
2637 "Flags set on RR via non-existing attached");
2638
2639 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket(dpo->dpoi_index, 0)),
2640 "adj for 200.200.200.200/32 is recursive via adj for 10.10.10.3");
2641
2642 adj_unlock(ai_03);
2643
2644 /*
2645 * remove the recursives
2646 */
2647 fib_table_entry_path_remove(fib_index,
2648 &bgp_200_pfx,
2649 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002650 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002651 &nh_10_10_10_1,
2652 ~0, // no index provided.
2653 fib_index, // same as route's FIB
2654 1,
2655 FIB_ROUTE_PATH_FLAG_NONE);
2656 fib_table_entry_path_remove(fib_index,
2657 &bgp_201_pfx,
2658 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002659 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002660 &nh_10_10_10_3,
2661 ~0, // no index provided.
2662 fib_index, // same as route's FIB
2663 1,
2664 FIB_ROUTE_PATH_FLAG_NONE);
2665
2666 FIB_TEST((fib_table_lookup_exact_match(fib_index, &bgp_201_pfx) ==
2667 FIB_NODE_INDEX_INVALID),
2668 "200.200.200.201/32 removed");
2669 FIB_TEST((fib_table_lookup_exact_match(fib_index, &bgp_200_pfx) ==
2670 FIB_NODE_INDEX_INVALID),
2671 "200.200.200.200/32 removed");
2672 FIB_TEST((fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_3) ==
2673 FIB_NODE_INDEX_INVALID),
2674 "10.10.10.3/32 removed");
2675
2676 /*
2677 * -3 entries (2*BGP and RR). -2 shared path-list (recursive via 10.10.10.3 &
2678 * 10.10.10.1) and one unshared non-recursive via 10.10.10.3
2679 */
2680 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
2681 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002682 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002683 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002684 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002685 fib_entry_pool_size());
2686
2687
2688 /*
2689 * RECURSION LOOPS
2690 * Add 5.5.5.5/32 -> 5.5.5.6/32 -> 5.5.5.7/32 -> 5.5.5.5/32
2691 */
2692 fib_prefix_t pfx_5_5_5_5_s_32 = {
2693 .fp_len = 32,
2694 .fp_proto = FIB_PROTOCOL_IP4,
2695 .fp_addr = {
2696 .ip4.as_u32 = clib_host_to_net_u32(0x05050505),
2697 },
2698 };
2699 fib_prefix_t pfx_5_5_5_6_s_32 = {
2700 .fp_len = 32,
2701 .fp_proto = FIB_PROTOCOL_IP4,
2702 .fp_addr = {
2703 .ip4.as_u32 = clib_host_to_net_u32(0x05050506),
2704 },
2705 };
2706 fib_prefix_t pfx_5_5_5_7_s_32 = {
2707 .fp_len = 32,
2708 .fp_proto = FIB_PROTOCOL_IP4,
2709 .fp_addr = {
2710 .ip4.as_u32 = clib_host_to_net_u32(0x05050507),
2711 },
2712 };
2713
2714 fib_table_entry_path_add(fib_index,
2715 &pfx_5_5_5_5_s_32,
2716 FIB_SOURCE_API,
2717 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002718 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002719 &pfx_5_5_5_6_s_32.fp_addr,
2720 ~0, // no index provided.
2721 fib_index,
2722 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002723 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002724 FIB_ROUTE_PATH_FLAG_NONE);
2725 fib_table_entry_path_add(fib_index,
2726 &pfx_5_5_5_6_s_32,
2727 FIB_SOURCE_API,
2728 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002729 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002730 &pfx_5_5_5_7_s_32.fp_addr,
2731 ~0, // no index provided.
2732 fib_index,
2733 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002734 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002735 FIB_ROUTE_PATH_FLAG_NONE);
2736 fib_table_entry_path_add(fib_index,
2737 &pfx_5_5_5_7_s_32,
2738 FIB_SOURCE_API,
2739 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002740 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002741 &pfx_5_5_5_5_s_32.fp_addr,
2742 ~0, // no index provided.
2743 fib_index,
2744 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002745 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002746 FIB_ROUTE_PATH_FLAG_NONE);
2747 /*
2748 * +3 entries, +3 shared path-list
2749 */
2750 FIB_TEST((4 == fib_path_list_db_size()), "path list DB population:%d",
2751 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002752 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002753 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002754 FIB_TEST((ENBR+10 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002755 fib_entry_pool_size());
2756
2757 /*
2758 * All the entries have only looped paths, so they are all drop
2759 */
2760 fei = fib_table_lookup(fib_index, &pfx_5_5_5_7_s_32);
2761 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2762 "LB for 5.5.5.7/32 is via adj for DROP");
2763 fei = fib_table_lookup(fib_index, &pfx_5_5_5_5_s_32);
2764 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2765 "LB for 5.5.5.5/32 is via adj for DROP");
2766 fei = fib_table_lookup(fib_index, &pfx_5_5_5_6_s_32);
2767 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2768 "LB for 5.5.5.6/32 is via adj for DROP");
2769
2770 /*
2771 * provide 5.5.5.6/32 with alternate path.
2772 * this will allow only 5.5.5.6/32 to forward with this path, the others
2773 * are still drop since the loop is still present.
2774 */
2775 fib_table_entry_path_add(fib_index,
2776 &pfx_5_5_5_6_s_32,
2777 FIB_SOURCE_API,
2778 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002779 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002780 &nh_10_10_10_1,
2781 tm->hw[0]->sw_if_index,
2782 ~0,
2783 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002784 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002785 FIB_ROUTE_PATH_FLAG_NONE);
2786
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002787 fei = fib_table_lookup(fib_index, &pfx_5_5_5_6_s_32);
2788 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2789
2790 lb = load_balance_get(dpo1->dpoi_index);
2791 FIB_TEST((lb->lb_n_buckets == 1), "5.5.5.6 LB has %d bucket", lb->lb_n_buckets);
2792
2793 dpo2 = load_balance_get_bucket(dpo1->dpoi_index, 0);
2794 FIB_TEST(DPO_ADJACENCY == dpo2->dpoi_type, "type is %d", dpo2->dpoi_type);
2795 FIB_TEST((ai_01 == dpo2->dpoi_index),
2796 "5.5.5.6 bucket 0 resolves via 10.10.10.2");
2797
2798 fei = fib_table_lookup(fib_index, &pfx_5_5_5_7_s_32);
2799 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2800 "LB for 5.5.5.7/32 is via adj for DROP");
2801 fei = fib_table_lookup(fib_index, &pfx_5_5_5_5_s_32);
2802 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2803 "LB for 5.5.5.5/32 is via adj for DROP");
2804
2805 /*
2806 * remove the alternate path for 5.5.5.6/32
2807 * back to all drop
2808 */
2809 fib_table_entry_path_remove(fib_index,
2810 &pfx_5_5_5_6_s_32,
2811 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002812 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002813 &nh_10_10_10_1,
2814 tm->hw[0]->sw_if_index,
2815 ~0,
2816 1,
2817 FIB_ROUTE_PATH_FLAG_NONE);
2818
2819 fei = fib_table_lookup(fib_index, &pfx_5_5_5_7_s_32);
2820 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2821 "LB for 5.5.5.7/32 is via adj for DROP");
2822 fei = fib_table_lookup(fib_index, &pfx_5_5_5_5_s_32);
2823 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2824 "LB for 5.5.5.5/32 is via adj for DROP");
2825 fei = fib_table_lookup(fib_index, &pfx_5_5_5_6_s_32);
2826 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2827 "LB for 5.5.5.6/32 is via adj for DROP");
2828
2829 /*
2830 * break the loop by giving 5.5.5.5/32 a new set of paths
2831 * expect all to forward via this new path.
2832 */
2833 fib_table_entry_update_one_path(fib_index,
2834 &pfx_5_5_5_5_s_32,
2835 FIB_SOURCE_API,
2836 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002837 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002838 &nh_10_10_10_1,
2839 tm->hw[0]->sw_if_index,
2840 ~0, // invalid fib index
2841 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002842 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002843 FIB_ROUTE_PATH_FLAG_NONE);
2844
2845 fei = fib_table_lookup(fib_index, &pfx_5_5_5_5_s_32);
2846 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2847 lb = load_balance_get(dpo1->dpoi_index);
2848 FIB_TEST((lb->lb_n_buckets == 1), "5.5.5.5 LB has %d bucket", lb->lb_n_buckets);
2849
2850 dpo2 = load_balance_get_bucket(dpo1->dpoi_index, 0);
2851 FIB_TEST(DPO_ADJACENCY == dpo2->dpoi_type, "type is %d", dpo2->dpoi_type);
2852 FIB_TEST((ai_01 == dpo2->dpoi_index),
2853 "5.5.5.5 bucket 0 resolves via 10.10.10.2");
2854
2855 fei = fib_table_lookup_exact_match(fib_index, &pfx_5_5_5_7_s_32);
2856 dpo2 = fib_entry_contribute_ip_forwarding(fei);
2857
2858 lb = load_balance_get(dpo2->dpoi_index);
2859 FIB_TEST((lb->lb_n_buckets == 1), "Recursive LB has %d bucket", lb->lb_n_buckets);
2860 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket(dpo2->dpoi_index, 0)),
2861 "5.5.5.5.7 via 5.5.5.5");
2862
2863 fei = fib_table_lookup_exact_match(fib_index, &pfx_5_5_5_6_s_32);
2864 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2865
2866 lb = load_balance_get(dpo1->dpoi_index);
2867 FIB_TEST((lb->lb_n_buckets == 1), "Recursive LB has %d bucket", lb->lb_n_buckets);
2868 FIB_TEST(!dpo_cmp(dpo2, load_balance_get_bucket(dpo1->dpoi_index, 0)),
2869 "5.5.5.5.6 via 5.5.5.7");
2870
2871 /*
2872 * revert back to the loop. so we can remove the prefixes with
2873 * the loop intact
2874 */
2875 fib_table_entry_update_one_path(fib_index,
2876 &pfx_5_5_5_5_s_32,
2877 FIB_SOURCE_API,
2878 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002879 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002880 &pfx_5_5_5_6_s_32.fp_addr,
2881 ~0, // no index provided.
2882 fib_index,
2883 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002884 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002885 FIB_ROUTE_PATH_FLAG_NONE);
2886
2887 fei = fib_table_lookup(fib_index, &pfx_5_5_5_7_s_32);
2888 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2889 "LB for 5.5.5.7/32 is via adj for DROP");
2890 fei = fib_table_lookup(fib_index, &pfx_5_5_5_5_s_32);
2891 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2892 "LB for 5.5.5.5/32 is via adj for DROP");
2893 fei = fib_table_lookup(fib_index, &pfx_5_5_5_6_s_32);
2894 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2895 "LB for 5.5.5.6/32 is via adj for DROP");
2896
2897 /*
2898 * remove all the 5.5.5.x/32 prefixes
2899 */
2900 fib_table_entry_path_remove(fib_index,
2901 &pfx_5_5_5_5_s_32,
2902 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002903 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002904 &pfx_5_5_5_6_s_32.fp_addr,
2905 ~0, // no index provided.
2906 fib_index, // same as route's FIB
2907 1,
2908 FIB_ROUTE_PATH_FLAG_NONE);
2909 fib_table_entry_path_remove(fib_index,
2910 &pfx_5_5_5_6_s_32,
2911 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002912 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002913 &pfx_5_5_5_7_s_32.fp_addr,
2914 ~0, // no index provided.
2915 fib_index, // same as route's FIB
2916 1,
2917 FIB_ROUTE_PATH_FLAG_NONE);
2918 fib_table_entry_path_remove(fib_index,
2919 &pfx_5_5_5_7_s_32,
2920 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002921 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002922 &pfx_5_5_5_5_s_32.fp_addr,
2923 ~0, // no index provided.
2924 fib_index, // same as route's FIB
2925 1,
2926 FIB_ROUTE_PATH_FLAG_NONE);
2927 fib_table_entry_path_remove(fib_index,
2928 &pfx_5_5_5_6_s_32,
2929 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002930 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002931 &nh_10_10_10_2,
2932 ~0, // no index provided.
2933 fib_index, // same as route's FIB
2934 1,
2935 FIB_ROUTE_PATH_FLAG_NONE);
2936
2937 /*
2938 * -3 entries, -3 shared path-list
2939 */
2940 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
2941 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002942 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002943 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002944 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002945 fib_entry_pool_size());
2946
2947 /*
2948 * Single level loop 5.5.5.5/32 via 5.5.5.5/32
2949 */
2950 fib_table_entry_path_add(fib_index,
2951 &pfx_5_5_5_6_s_32,
2952 FIB_SOURCE_API,
2953 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002954 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002955 &pfx_5_5_5_6_s_32.fp_addr,
2956 ~0, // no index provided.
2957 fib_index,
2958 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002959 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002960 FIB_ROUTE_PATH_FLAG_NONE);
2961 fei = fib_table_lookup(fib_index, &pfx_5_5_5_6_s_32);
2962 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2963 "1-level 5.5.5.6/32 loop is via adj for DROP");
2964
2965 fib_table_entry_path_remove(fib_index,
2966 &pfx_5_5_5_6_s_32,
2967 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002968 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002969 &pfx_5_5_5_6_s_32.fp_addr,
2970 ~0, // no index provided.
2971 fib_index, // same as route's FIB
2972 1,
2973 FIB_ROUTE_PATH_FLAG_NONE);
2974 FIB_TEST(FIB_NODE_INDEX_INVALID ==
2975 fib_table_lookup_exact_match(fib_index, &pfx_5_5_5_6_s_32),
2976 "1-level 5.5.5.6/32 loop is removed");
2977
2978 /*
Neale Ranns3dffb1e2016-11-01 20:38:53 +00002979 * A recursive route whose next-hop is covered by the prefix.
2980 * This would mean the via-fib, which inherits forwarding from its
2981 * cover, thus picks up forwarding from the prfix, which is via the
2982 * via-fib, and we have a loop.
2983 */
2984 fib_prefix_t pfx_23_23_23_0_s_24 = {
2985 .fp_len = 24,
2986 .fp_proto = FIB_PROTOCOL_IP4,
2987 .fp_addr = {
2988 .ip4.as_u32 = clib_host_to_net_u32(0x17171700),
2989 },
2990 };
2991 fib_prefix_t pfx_23_23_23_23_s_32 = {
2992 .fp_len = 32,
2993 .fp_proto = FIB_PROTOCOL_IP4,
2994 .fp_addr = {
2995 .ip4.as_u32 = clib_host_to_net_u32(0x17171717),
2996 },
2997 };
2998 fei = fib_table_entry_path_add(fib_index,
2999 &pfx_23_23_23_0_s_24,
3000 FIB_SOURCE_API,
3001 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003002 DPO_PROTO_IP4,
Neale Ranns3dffb1e2016-11-01 20:38:53 +00003003 &pfx_23_23_23_23_s_32.fp_addr,
3004 ~0, // recursive
3005 fib_index,
3006 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003007 NULL,
Neale Ranns3dffb1e2016-11-01 20:38:53 +00003008 FIB_ROUTE_PATH_FLAG_NONE);
3009 dpo = fib_entry_contribute_ip_forwarding(fei);
3010 FIB_TEST(load_balance_is_drop(dpo),
3011 "23.23.23.0/24 via covered is DROP");
3012 fib_table_entry_delete_index(fei, FIB_SOURCE_API);
3013
3014 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003015 * add-remove test. no change.
3016 */
3017 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
3018 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003019 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003020 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003021 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003022 fib_entry_pool_size());
3023
3024 /*
Neale Ranns08b16482017-05-13 05:52:58 -07003025 * Make the default route recursive via a unknown next-hop. Thus the
3026 * next hop's cover would be the default route
3027 */
3028 fei = fib_table_entry_path_add(fib_index,
3029 &pfx_0_0_0_0_s_0,
3030 FIB_SOURCE_API,
3031 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003032 DPO_PROTO_IP4,
Neale Ranns08b16482017-05-13 05:52:58 -07003033 &pfx_23_23_23_23_s_32.fp_addr,
3034 ~0, // recursive
3035 fib_index,
3036 1,
3037 NULL,
3038 FIB_ROUTE_PATH_FLAG_NONE);
3039 dpo = fib_entry_contribute_ip_forwarding(fei);
3040 FIB_TEST(load_balance_is_drop(dpo),
3041 "0.0.0.0.0/0 via is DROP");
3042 FIB_TEST((fib_entry_get_resolving_interface(fei) == ~0),
3043 "no resolving interface for looped 0.0.0.0/0");
3044
3045 fei = fib_table_lookup_exact_match(fib_index, &pfx_23_23_23_23_s_32);
3046 dpo = fib_entry_contribute_ip_forwarding(fei);
3047 FIB_TEST(load_balance_is_drop(dpo),
3048 "23.23.23.23/32 via is DROP");
3049 FIB_TEST((fib_entry_get_resolving_interface(fei) == ~0),
3050 "no resolving interface for looped 23.23.23.23/32");
3051
3052 fib_table_entry_delete(fib_index, &pfx_0_0_0_0_s_0, FIB_SOURCE_API);
3053
3054 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003055 * A recursive route with recursion constraints.
3056 * 200.200.200.200/32 via 1.1.1.1 is recurse via host constrained
3057 */
3058 fib_table_entry_path_add(fib_index,
3059 &bgp_200_pfx,
3060 FIB_SOURCE_API,
3061 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003062 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003063 &nh_1_1_1_1,
3064 ~0,
3065 fib_index,
3066 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003067 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003068 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
3069
3070 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_1_s_32);
3071 dpo2 = fib_entry_contribute_ip_forwarding(fei);
3072
3073 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
3074 dpo1 = fib_entry_contribute_ip_forwarding(fei);
3075
3076 FIB_TEST(!dpo_cmp(dpo2, load_balance_get_bucket(dpo1->dpoi_index, 0)),
3077 "adj for 200.200.200.200/32 is recursive via adj for 1.1.1.1");
3078
3079 /*
3080 * save the load-balance. we expect it to be inplace modified
3081 */
3082 lb = load_balance_get(dpo1->dpoi_index);
3083
3084 /*
3085 * add a covering prefix for the via fib that would otherwise serve
3086 * as the resolving route when the host is removed
3087 */
3088 fib_table_entry_path_add(fib_index,
3089 &pfx_1_1_1_0_s_28,
3090 FIB_SOURCE_API,
3091 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003092 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003093 &nh_10_10_10_1,
3094 tm->hw[0]->sw_if_index,
3095 ~0, // invalid fib index
3096 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003097 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003098 FIB_ROUTE_PATH_FLAG_NONE);
3099 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_0_s_28);
3100 ai = fib_entry_get_adj(fei);
3101 FIB_TEST((ai == ai_01),
3102 "adj for 1.1.1.0/28 is via adj for 1.1.1.1");
3103
3104 /*
3105 * remove the host via FIB - expect the BGP prefix to be drop
3106 */
3107 fib_table_entry_path_remove(fib_index,
3108 &pfx_1_1_1_1_s_32,
3109 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07003110 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003111 &nh_10_10_10_1,
3112 tm->hw[0]->sw_if_index,
3113 ~0, // invalid fib index
3114 1,
3115 FIB_ROUTE_PATH_FLAG_NONE);
3116
3117 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo1->dpoi_index, 0)),
3118 "adj for 200.200.200.200/32 is recursive via adj for DROP");
3119
3120 /*
3121 * add the via-entry host reoute back. expect to resolve again
3122 */
3123 fib_table_entry_path_add(fib_index,
3124 &pfx_1_1_1_1_s_32,
3125 FIB_SOURCE_API,
3126 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003127 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003128 &nh_10_10_10_1,
3129 tm->hw[0]->sw_if_index,
3130 ~0, // invalid fib index
3131 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003132 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003133 FIB_ROUTE_PATH_FLAG_NONE);
3134 FIB_TEST(!dpo_cmp(dpo2, load_balance_get_bucket(dpo1->dpoi_index, 0)),
3135 "adj for 200.200.200.200/32 is recursive via adj for 1.1.1.1");
3136
3137 /*
3138 * add another path for the recursive. it will then have 2.
3139 */
3140 fib_prefix_t pfx_1_1_1_3_s_32 = {
3141 .fp_len = 32,
3142 .fp_proto = FIB_PROTOCOL_IP4,
3143 .fp_addr = {
3144 .ip4.as_u32 = clib_host_to_net_u32(0x01010103),
3145 },
3146 };
3147 fib_table_entry_path_add(fib_index,
3148 &pfx_1_1_1_3_s_32,
3149 FIB_SOURCE_API,
3150 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003151 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003152 &nh_10_10_10_2,
3153 tm->hw[0]->sw_if_index,
3154 ~0, // invalid fib index
3155 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003156 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003157 FIB_ROUTE_PATH_FLAG_NONE);
3158
3159 fib_table_entry_path_add(fib_index,
3160 &bgp_200_pfx,
3161 FIB_SOURCE_API,
3162 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003163 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003164 &pfx_1_1_1_3_s_32.fp_addr,
3165 ~0,
3166 fib_index,
3167 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003168 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003169 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
3170
Neale Rannsf12a83f2017-04-18 09:09:40 -07003171 /*
3172 * add a bunch load more entries using this path combo so that we get
3173 * an LB-map created.
3174 */
3175#define N_P 128
3176 fib_prefix_t bgp_78s[N_P];
3177 for (ii = 0; ii < N_P; ii++)
3178 {
3179 bgp_78s[ii].fp_len = 32;
3180 bgp_78s[ii].fp_proto = FIB_PROTOCOL_IP4;
3181 bgp_78s[ii].fp_addr.ip4.as_u32 = clib_host_to_net_u32(0x4e000000+ii);
3182
3183
3184 fib_table_entry_path_add(fib_index,
3185 &bgp_78s[ii],
3186 FIB_SOURCE_API,
3187 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003188 DPO_PROTO_IP4,
Neale Rannsf12a83f2017-04-18 09:09:40 -07003189 &pfx_1_1_1_3_s_32.fp_addr,
3190 ~0,
3191 fib_index,
3192 1,
3193 NULL,
3194 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
3195 fib_table_entry_path_add(fib_index,
3196 &bgp_78s[ii],
3197 FIB_SOURCE_API,
3198 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003199 DPO_PROTO_IP4,
Neale Rannsf12a83f2017-04-18 09:09:40 -07003200 &nh_1_1_1_1,
3201 ~0,
3202 fib_index,
3203 1,
3204 NULL,
3205 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
3206 }
3207
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003208 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
3209 dpo = fib_entry_contribute_ip_forwarding(fei);
3210
3211 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_1_s_32);
3212 dpo2 = fib_entry_contribute_ip_forwarding(fei);
3213 FIB_TEST(!dpo_cmp(dpo2, load_balance_get_bucket(dpo->dpoi_index, 0)),
3214 "adj for 200.200.200.200/32 is recursive via adj for 1.1.1.1");
3215 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_3_s_32);
3216 dpo1 = fib_entry_contribute_ip_forwarding(fei);
3217 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket(dpo->dpoi_index, 1)),
3218 "adj for 200.200.200.200/32 is recursive via adj for 1.1.1.3");
3219
3220 /*
3221 * expect the lb-map used by the recursive's load-balance is using both buckets
3222 */
3223 load_balance_map_t *lbm;
3224 index_t lbmi;
3225
3226 lb = load_balance_get(dpo->dpoi_index);
3227 lbmi = lb->lb_map;
3228 load_balance_map_lock(lbmi);
3229 lbm = load_balance_map_get(lbmi);
3230
3231 FIB_TEST(lbm->lbm_buckets[0] == 0,
3232 "LB maps's bucket 0 is %d",
3233 lbm->lbm_buckets[0]);
3234 FIB_TEST(lbm->lbm_buckets[1] == 1,
3235 "LB maps's bucket 1 is %d",
3236 lbm->lbm_buckets[1]);
3237
3238 /*
3239 * withdraw one of the /32 via-entrys.
3240 * that ECMP path will be unresolved and forwarding should continue on the
3241 * other available path. this is an iBGP PIC edge failover.
3242 * Test the forwarding changes without re-fetching the adj from the
3243 * recursive entry. this ensures its the same one that is updated; i.e. an
3244 * inplace-modify.
3245 */
3246 fib_table_entry_path_remove(fib_index,
3247 &pfx_1_1_1_1_s_32,
3248 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07003249 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003250 &nh_10_10_10_1,
3251 tm->hw[0]->sw_if_index,
3252 ~0, // invalid fib index
3253 1,
3254 FIB_ROUTE_PATH_FLAG_NONE);
3255
Neale Rannsf12a83f2017-04-18 09:09:40 -07003256 /* suspend so the update walk kicks int */
3257 vlib_process_suspend(vlib_get_main(), 1e-5);
3258
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003259 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
3260 FIB_TEST(!dpo_cmp(dpo, fib_entry_contribute_ip_forwarding(fei)),
3261 "post PIC 200.200.200.200/32 was inplace modified");
3262
3263 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket_i(lb, 0)),
3264 "post PIC adj for 200.200.200.200/32 is recursive"
3265 " via adj for 1.1.1.3");
3266
3267 /*
3268 * the LB maps that was locked above should have been modified to remove
3269 * the path that was down, and thus its bucket points to a path that is
3270 * still up.
3271 */
3272 FIB_TEST(lbm->lbm_buckets[0] == 1,
3273 "LB maps's bucket 0 is %d",
3274 lbm->lbm_buckets[0]);
3275 FIB_TEST(lbm->lbm_buckets[1] == 1,
3276 "LB maps's bucket 1 is %d",
3277 lbm->lbm_buckets[1]);
3278
Neale Ranns994dab42017-04-18 12:56:45 -07003279 load_balance_map_unlock(lbmi);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003280
3281 /*
3282 * add it back. again
3283 */
3284 fib_table_entry_path_add(fib_index,
3285 &pfx_1_1_1_1_s_32,
3286 FIB_SOURCE_API,
3287 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003288 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003289 &nh_10_10_10_1,
3290 tm->hw[0]->sw_if_index,
3291 ~0, // invalid fib index
3292 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003293 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003294 FIB_ROUTE_PATH_FLAG_NONE);
3295
Neale Rannsf12a83f2017-04-18 09:09:40 -07003296 /* suspend so the update walk kicks in */
3297 vlib_process_suspend(vlib_get_main(), 1e-5);
3298
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003299 FIB_TEST(!dpo_cmp(dpo2, load_balance_get_bucket_i(lb, 0)),
3300 "post PIC recovery adj for 200.200.200.200/32 is recursive "
3301 "via adj for 1.1.1.1");
3302 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket_i(lb, 1)),
3303 "post PIC recovery adj for 200.200.200.200/32 is recursive "
3304 "via adj for 1.1.1.3");
3305
3306 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
3307 dpo = fib_entry_contribute_ip_forwarding(fei);
3308 FIB_TEST(lb == load_balance_get(dpo->dpoi_index),
3309 "post PIC 200.200.200.200/32 was inplace modified");
3310
3311 /*
3312 * add a 3rd path. this makes the LB 16 buckets.
3313 */
3314 fib_table_entry_path_add(fib_index,
3315 &bgp_200_pfx,
3316 FIB_SOURCE_API,
3317 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003318 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003319 &pfx_1_1_1_2_s_32.fp_addr,
3320 ~0,
3321 fib_index,
3322 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003323 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003324 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
Neale Rannsf12a83f2017-04-18 09:09:40 -07003325 for (ii = 0; ii < N_P; ii++)
3326 {
3327 fib_table_entry_path_add(fib_index,
3328 &bgp_78s[ii],
3329 FIB_SOURCE_API,
3330 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003331 DPO_PROTO_IP4,
Neale Rannsf12a83f2017-04-18 09:09:40 -07003332 &pfx_1_1_1_2_s_32.fp_addr,
3333 ~0,
3334 fib_index,
3335 1,
3336 NULL,
3337 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
3338 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003339
3340 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
3341 dpo = fib_entry_contribute_ip_forwarding(fei);
3342 FIB_TEST(lb == load_balance_get(dpo->dpoi_index),
3343 "200.200.200.200/32 was inplace modified for 3rd path");
3344 FIB_TEST(16 == lb->lb_n_buckets,
3345 "200.200.200.200/32 was inplace modified for 3rd path to 16 buckets");
3346
3347 lbmi = lb->lb_map;
3348 load_balance_map_lock(lbmi);
3349 lbm = load_balance_map_get(lbmi);
3350
3351 for (ii = 0; ii < 16; ii++)
3352 {
3353 FIB_TEST(lbm->lbm_buckets[ii] == ii,
3354 "LB Map for 200.200.200.200/32 at %d is %d",
3355 ii, lbm->lbm_buckets[ii]);
3356 }
3357
3358 /*
3359 * trigger PIC by removing the first via-entry
3360 * the first 6 buckets of the map should map to the next 6
3361 */
3362 fib_table_entry_path_remove(fib_index,
3363 &pfx_1_1_1_1_s_32,
3364 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07003365 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003366 &nh_10_10_10_1,
3367 tm->hw[0]->sw_if_index,
3368 ~0,
3369 1,
3370 FIB_ROUTE_PATH_FLAG_NONE);
Neale Rannsf12a83f2017-04-18 09:09:40 -07003371 /* suspend so the update walk kicks int */
3372 vlib_process_suspend(vlib_get_main(), 1e-5);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003373
3374 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
3375 dpo = fib_entry_contribute_ip_forwarding(fei);
3376 FIB_TEST(lb == load_balance_get(dpo->dpoi_index),
3377 "200.200.200.200/32 was inplace modified for 3rd path");
3378 FIB_TEST(2 == lb->lb_n_buckets,
3379 "200.200.200.200/32 was inplace modified for 3rd path remove to 2 buckets");
3380
3381 for (ii = 0; ii < 6; ii++)
3382 {
3383 FIB_TEST(lbm->lbm_buckets[ii] == ii+6,
3384 "LB Map for 200.200.200.200/32 at %d is %d",
3385 ii, lbm->lbm_buckets[ii]);
3386 }
3387 for (ii = 6; ii < 16; ii++)
3388 {
3389 FIB_TEST(lbm->lbm_buckets[ii] == ii,
3390 "LB Map for 200.200.200.200/32 at %d is %d",
3391 ii, lbm->lbm_buckets[ii]);
3392 }
Neale Ranns994dab42017-04-18 12:56:45 -07003393 load_balance_map_unlock(lbmi);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003394
3395 /*
3396 * tidy up
3397 */
3398 fib_table_entry_path_add(fib_index,
3399 &pfx_1_1_1_1_s_32,
3400 FIB_SOURCE_API,
3401 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003402 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003403 &nh_10_10_10_1,
3404 tm->hw[0]->sw_if_index,
3405 ~0,
3406 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003407 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003408 FIB_ROUTE_PATH_FLAG_NONE);
3409
Neale Rannsf12a83f2017-04-18 09:09:40 -07003410 for (ii = 0; ii < N_P; ii++)
3411 {
3412 fib_table_entry_delete(fib_index,
3413 &bgp_78s[ii],
3414 FIB_SOURCE_API);
3415 FIB_TEST((FIB_NODE_INDEX_INVALID ==
3416 fib_table_lookup_exact_match(fib_index, &bgp_78s[ii])),
3417 "%U removed",
3418 format_fib_prefix, &bgp_78s[ii]);
3419 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003420 fib_table_entry_path_remove(fib_index,
3421 &bgp_200_pfx,
3422 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07003423 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003424 &pfx_1_1_1_2_s_32.fp_addr,
3425 ~0,
3426 fib_index,
3427 1,
3428 MPLS_LABEL_INVALID);
3429 fib_table_entry_path_remove(fib_index,
3430 &bgp_200_pfx,
3431 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07003432 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003433 &nh_1_1_1_1,
3434 ~0,
3435 fib_index,
3436 1,
3437 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
3438 fib_table_entry_path_remove(fib_index,
3439 &bgp_200_pfx,
3440 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07003441 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003442 &pfx_1_1_1_3_s_32.fp_addr,
3443 ~0,
3444 fib_index,
3445 1,
3446 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
3447 fib_table_entry_delete(fib_index,
3448 &pfx_1_1_1_3_s_32,
3449 FIB_SOURCE_API);
3450 fib_table_entry_delete(fib_index,
3451 &pfx_1_1_1_0_s_28,
3452 FIB_SOURCE_API);
Neale Rannsf12a83f2017-04-18 09:09:40 -07003453 /* suspend so the update walk kicks int */
3454 vlib_process_suspend(vlib_get_main(), 1e-5);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003455 FIB_TEST((FIB_NODE_INDEX_INVALID ==
3456 fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_0_s_28)),
3457 "1.1.1.1/28 removed");
3458 FIB_TEST((FIB_NODE_INDEX_INVALID ==
3459 fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_3_s_32)),
3460 "1.1.1.3/32 removed");
3461 FIB_TEST((FIB_NODE_INDEX_INVALID ==
3462 fib_table_lookup_exact_match(fib_index, &bgp_200_pfx)),
3463 "200.200.200.200/32 removed");
3464
3465 /*
3466 * add-remove test. no change.
3467 */
3468 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
3469 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003470 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003471 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003472 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003473 fib_entry_pool_size());
3474
3475 /*
3476 * A route whose paths are built up iteratively and then removed
3477 * all at once
3478 */
3479 fib_prefix_t pfx_4_4_4_4_s_32 = {
3480 .fp_len = 32,
3481 .fp_proto = FIB_PROTOCOL_IP4,
3482 .fp_addr = {
3483 /* 4.4.4.4/32 */
3484 .ip4.as_u32 = clib_host_to_net_u32(0x04040404),
3485 },
3486 };
3487
3488 fib_table_entry_path_add(fib_index,
3489 &pfx_4_4_4_4_s_32,
3490 FIB_SOURCE_API,
3491 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003492 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003493 &nh_10_10_10_1,
3494 tm->hw[0]->sw_if_index,
3495 ~0,
3496 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003497 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003498 FIB_ROUTE_PATH_FLAG_NONE);
3499 fib_table_entry_path_add(fib_index,
3500 &pfx_4_4_4_4_s_32,
3501 FIB_SOURCE_API,
3502 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003503 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003504 &nh_10_10_10_2,
3505 tm->hw[0]->sw_if_index,
3506 ~0,
3507 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003508 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003509 FIB_ROUTE_PATH_FLAG_NONE);
3510 fib_table_entry_path_add(fib_index,
3511 &pfx_4_4_4_4_s_32,
3512 FIB_SOURCE_API,
3513 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003514 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003515 &nh_10_10_10_3,
3516 tm->hw[0]->sw_if_index,
3517 ~0,
3518 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003519 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003520 FIB_ROUTE_PATH_FLAG_NONE);
3521 FIB_TEST(FIB_NODE_INDEX_INVALID !=
3522 fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32),
3523 "4.4.4.4/32 present");
3524
3525 fib_table_entry_delete(fib_index,
3526 &pfx_4_4_4_4_s_32,
3527 FIB_SOURCE_API);
3528 FIB_TEST(FIB_NODE_INDEX_INVALID ==
3529 fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32),
3530 "4.4.4.4/32 removed");
3531
3532 /*
3533 * add-remove test. no change.
3534 */
3535 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
3536 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003537 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003538 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003539 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003540 fib_entry_pool_size());
3541
3542 /*
3543 * A route with multiple paths at once
3544 */
3545 fib_route_path_t *r_paths = NULL;
3546
3547 for (ii = 0; ii < 4; ii++)
3548 {
3549 fib_route_path_t r_path = {
Neale Rannsda78f952017-05-24 09:15:43 -07003550 .frp_proto = DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003551 .frp_addr = {
3552 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02 + ii),
3553 },
3554 .frp_sw_if_index = tm->hw[0]->sw_if_index,
3555 .frp_weight = 1,
3556 .frp_fib_index = ~0,
3557 };
3558 vec_add1(r_paths, r_path);
3559 }
3560
3561 fib_table_entry_update(fib_index,
3562 &pfx_4_4_4_4_s_32,
3563 FIB_SOURCE_API,
3564 FIB_ENTRY_FLAG_NONE,
3565 r_paths);
3566
3567 fei = fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32);
3568 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "4.4.4.4/32 present");
3569 dpo = fib_entry_contribute_ip_forwarding(fei);
3570
3571 lb = load_balance_get(dpo->dpoi_index);
3572 FIB_TEST((lb->lb_n_buckets == 4), "4.4.4.4/32 lb over %d paths", lb->lb_n_buckets);
3573
3574 fib_table_entry_delete(fib_index,
3575 &pfx_4_4_4_4_s_32,
3576 FIB_SOURCE_API);
3577 FIB_TEST(FIB_NODE_INDEX_INVALID ==
3578 fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32),
3579 "4.4.4.4/32 removed");
3580 vec_free(r_paths);
3581
3582 /*
3583 * add-remove test. no change.
3584 */
3585 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
3586 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003587 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003588 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003589 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003590 fib_entry_pool_size());
3591
3592 /*
3593 * A route deag route
3594 */
3595 fib_table_entry_path_add(fib_index,
3596 &pfx_4_4_4_4_s_32,
3597 FIB_SOURCE_API,
3598 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003599 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003600 &zero_addr,
3601 ~0,
3602 fib_index,
3603 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003604 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003605 FIB_ROUTE_PATH_FLAG_NONE);
3606
3607 fei = fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32);
3608 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "4.4.4.4/32 present");
3609
3610 dpo = fib_entry_contribute_ip_forwarding(fei);
3611 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
3612 lookup_dpo_t *lkd = lookup_dpo_get(dpo->dpoi_index);
3613
3614 FIB_TEST((fib_index == lkd->lkd_fib_index),
3615 "4.4.4.4/32 is deag in %d %U",
3616 lkd->lkd_fib_index,
3617 format_dpo_id, dpo, 0);
Neale Ranns054c03a2017-10-13 05:15:07 -07003618 FIB_TEST((LOOKUP_INPUT_DST_ADDR == lkd->lkd_input),
3619 "4.4.4.4/32 is source deag in %d %U",
3620 lkd->lkd_input,
3621 format_dpo_id, dpo, 0);
3622
3623 fib_table_entry_delete(fib_index,
3624 &pfx_4_4_4_4_s_32,
3625 FIB_SOURCE_API);
3626 FIB_TEST(FIB_NODE_INDEX_INVALID ==
3627 fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32),
3628 "4.4.4.4/32 removed");
3629 vec_free(r_paths);
3630
3631 /*
3632 * A route deag route in a source lookup table
3633 */
3634 fib_table_entry_path_add(fib_index,
3635 &pfx_4_4_4_4_s_32,
3636 FIB_SOURCE_API,
3637 FIB_ENTRY_FLAG_NONE,
3638 DPO_PROTO_IP4,
3639 &zero_addr,
3640 ~0,
3641 fib_index,
3642 1,
3643 NULL,
3644 FIB_ROUTE_PATH_SOURCE_LOOKUP);
3645
3646 fei = fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32);
3647 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "4.4.4.4/32 present");
3648
3649 dpo = fib_entry_contribute_ip_forwarding(fei);
3650 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
3651 lkd = lookup_dpo_get(dpo->dpoi_index);
3652
3653 FIB_TEST((fib_index == lkd->lkd_fib_index),
3654 "4.4.4.4/32 is deag in %d %U",
3655 lkd->lkd_fib_index,
3656 format_dpo_id, dpo, 0);
3657 FIB_TEST((LOOKUP_INPUT_SRC_ADDR == lkd->lkd_input),
3658 "4.4.4.4/32 is source deag in %d %U",
3659 lkd->lkd_input,
3660 format_dpo_id, dpo, 0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003661
3662 fib_table_entry_delete(fib_index,
3663 &pfx_4_4_4_4_s_32,
3664 FIB_SOURCE_API);
3665 FIB_TEST(FIB_NODE_INDEX_INVALID ==
3666 fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32),
3667 "4.4.4.4/32 removed");
3668 vec_free(r_paths);
3669
3670 /*
3671 * add-remove test. no change.
3672 */
3673 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
3674 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003675 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003676 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003677 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003678 fib_entry_pool_size());
3679
3680 /*
Neale Rannsbcc889c2016-11-03 14:15:28 -07003681 * Duplicate paths:
3682 * add a recursive with duplicate paths. Expect the duplicate to be ignored.
3683 */
3684 fib_prefix_t pfx_34_1_1_1_s_32 = {
3685 .fp_len = 32,
3686 .fp_proto = FIB_PROTOCOL_IP4,
3687 .fp_addr = {
3688 .ip4.as_u32 = clib_host_to_net_u32(0x22010101),
3689 },
3690 };
3691 fib_prefix_t pfx_34_34_1_1_s_32 = {
3692 .fp_len = 32,
3693 .fp_proto = FIB_PROTOCOL_IP4,
3694 .fp_addr = {
3695 .ip4.as_u32 = clib_host_to_net_u32(0x22220101),
3696 },
3697 };
3698 fei = fib_table_entry_path_add(fib_index,
Neale Ranns57b58602017-07-15 07:37:25 -07003699 &pfx_34_34_1_1_s_32,
3700 FIB_SOURCE_API,
3701 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003702 DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07003703 &nh_10_10_10_1,
3704 tm->hw[0]->sw_if_index,
3705 0,
3706 1,
3707 NULL,
3708 FIB_ROUTE_PATH_FLAG_NONE);
3709 fei = fib_table_entry_path_add(fib_index,
Neale Rannsbcc889c2016-11-03 14:15:28 -07003710 &pfx_34_1_1_1_s_32,
3711 FIB_SOURCE_API,
3712 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003713 DPO_PROTO_IP4,
Neale Rannsbcc889c2016-11-03 14:15:28 -07003714 &pfx_34_34_1_1_s_32.fp_addr,
3715 ~0,
3716 fib_index,
3717 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003718 NULL,
Neale Rannsbcc889c2016-11-03 14:15:28 -07003719 FIB_ROUTE_PATH_FLAG_NONE);
3720 fei = fib_table_entry_path_add(fib_index,
3721 &pfx_34_1_1_1_s_32,
3722 FIB_SOURCE_API,
3723 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003724 DPO_PROTO_IP4,
Neale Rannsbcc889c2016-11-03 14:15:28 -07003725 &pfx_34_34_1_1_s_32.fp_addr,
3726 ~0,
3727 fib_index,
3728 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003729 NULL,
Neale Rannsbcc889c2016-11-03 14:15:28 -07003730 FIB_ROUTE_PATH_FLAG_NONE);
3731 FIB_TEST_REC_FORW(&pfx_34_1_1_1_s_32, &pfx_34_34_1_1_s_32, 0);
3732 fib_table_entry_delete_index(fei, FIB_SOURCE_API);
Neale Ranns57b58602017-07-15 07:37:25 -07003733 fib_table_entry_delete(fib_index,
3734 &pfx_34_34_1_1_s_32,
3735 FIB_SOURCE_API);
Neale Rannsbcc889c2016-11-03 14:15:28 -07003736
3737 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003738 * CLEANUP
3739 * remove: 1.1.1.2/32, 1.1.2.0/24 and 1.1.1.1/32
3740 * all of which are via 10.10.10.1, Itf1
3741 */
3742 fib_table_entry_path_remove(fib_index,
3743 &pfx_1_1_1_2_s_32,
3744 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07003745 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003746 &nh_10_10_10_1,
3747 tm->hw[0]->sw_if_index,
3748 ~0,
3749 1,
3750 FIB_ROUTE_PATH_FLAG_NONE);
3751 fib_table_entry_path_remove(fib_index,
3752 &pfx_1_1_1_1_s_32,
3753 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07003754 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003755 &nh_10_10_10_1,
3756 tm->hw[0]->sw_if_index,
3757 ~0,
3758 1,
3759 FIB_ROUTE_PATH_FLAG_NONE);
3760 fib_table_entry_path_remove(fib_index,
3761 &pfx_1_1_2_0_s_24,
3762 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07003763 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003764 &nh_10_10_10_1,
3765 tm->hw[0]->sw_if_index,
3766 ~0,
3767 1,
3768 FIB_ROUTE_PATH_FLAG_NONE);
3769
3770 FIB_TEST(FIB_NODE_INDEX_INVALID ==
3771 fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_1_s_32),
3772 "1.1.1.1/32 removed");
3773 FIB_TEST(FIB_NODE_INDEX_INVALID ==
3774 fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_2_s_32),
3775 "1.1.1.2/32 removed");
3776 FIB_TEST(FIB_NODE_INDEX_INVALID ==
3777 fib_table_lookup_exact_match(fib_index, &pfx_1_1_2_0_s_24),
3778 "1.1.2.0/24 removed");
3779
3780 /*
3781 * -3 entries and -1 shared path-list
3782 */
3783 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
3784 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003785 FIB_TEST((PNBR+4 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003786 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003787 FIB_TEST((ENBR+4 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003788 fib_entry_pool_size());
3789
3790 /*
3791 * An attached-host route. Expect to link to the incomplete adj
3792 */
3793 fib_prefix_t pfx_4_1_1_1_s_32 = {
3794 .fp_len = 32,
3795 .fp_proto = FIB_PROTOCOL_IP4,
3796 .fp_addr = {
3797 /* 4.1.1.1/32 */
3798 .ip4.as_u32 = clib_host_to_net_u32(0x04010101),
3799 },
3800 };
3801 fib_table_entry_path_add(fib_index,
3802 &pfx_4_1_1_1_s_32,
3803 FIB_SOURCE_API,
3804 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003805 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003806 &zero_addr,
3807 tm->hw[0]->sw_if_index,
3808 fib_index,
3809 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003810 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003811 FIB_ROUTE_PATH_FLAG_NONE);
3812
3813 fei = fib_table_lookup_exact_match(fib_index, &pfx_4_1_1_1_s_32);
3814 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "4.1.1.1/32 present");
3815 ai = fib_entry_get_adj(fei);
3816
3817 ai2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01003818 VNET_LINK_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003819 &pfx_4_1_1_1_s_32.fp_addr,
3820 tm->hw[0]->sw_if_index);
3821 FIB_TEST((ai == ai2), "Attached-host link to incomplete ADJ");
3822 adj_unlock(ai2);
3823
3824 /*
3825 * +1 entry and +1 shared path-list
3826 */
3827 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
3828 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003829 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003830 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003831 FIB_TEST((ENBR+5 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003832 fib_entry_pool_size());
3833
3834 fib_table_entry_delete(fib_index,
3835 &pfx_4_1_1_1_s_32,
3836 FIB_SOURCE_API);
3837
3838 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
3839 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003840 FIB_TEST((PNBR+4 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003841 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003842 FIB_TEST((ENBR+4 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003843 fib_entry_pool_size());
3844
3845 /*
3846 * add a v6 prefix via v4 next-hops
3847 */
3848 fib_prefix_t pfx_2001_s_64 = {
3849 .fp_len = 64,
3850 .fp_proto = FIB_PROTOCOL_IP6,
3851 .fp_addr = {
3852 .ip6.as_u64[0] = clib_host_to_net_u64(0x2001000000000000),
3853 },
3854 };
3855 fei = fib_table_entry_path_add(0, //default v6 table
3856 &pfx_2001_s_64,
3857 FIB_SOURCE_API,
3858 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003859 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003860 &nh_10_10_10_1,
3861 tm->hw[0]->sw_if_index,
3862 fib_index,
3863 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003864 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003865 FIB_ROUTE_PATH_FLAG_NONE);
3866
3867 fei = fib_table_lookup_exact_match(0, &pfx_2001_s_64);
3868 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "2001::/64 present");
3869 ai = fib_entry_get_adj(fei);
3870 adj = adj_get(ai);
3871 FIB_TEST((adj->lookup_next_index == IP_LOOKUP_NEXT_ARP),
3872 "2001::/64 via ARP-adj");
Neale Ranns924d03a2016-10-19 08:25:46 +01003873 FIB_TEST((adj->ia_link == VNET_LINK_IP6),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003874 "2001::/64 is link type v6");
3875 FIB_TEST((adj->ia_nh_proto == FIB_PROTOCOL_IP4),
3876 "2001::/64 ADJ-adj is NH proto v4");
3877 fib_table_entry_delete(0, &pfx_2001_s_64, FIB_SOURCE_API);
3878
Neale Ranns3ee44042016-10-03 13:05:48 +01003879 /*
3880 * add a uRPF exempt prefix:
3881 * test:
3882 * - it's forwarding is drop
3883 * - it's uRPF list is not empty
3884 * - the uRPF list for the default route (it's cover) is empty
3885 */
3886 fei = fib_table_entry_special_add(fib_index,
3887 &pfx_4_1_1_1_s_32,
3888 FIB_SOURCE_URPF_EXEMPT,
Neale Rannsa0558302017-04-13 00:44:52 -07003889 FIB_ENTRY_FLAG_DROP);
Neale Ranns3ee44042016-10-03 13:05:48 +01003890 dpo = fib_entry_contribute_ip_forwarding(fei);
3891 FIB_TEST(load_balance_is_drop(dpo),
3892 "uRPF exempt 4.1.1.1/32 DROP");
3893 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 1, 0),
3894 "uRPF list for exempt prefix has itf index 0");
3895 fei = fib_table_lookup_exact_match(fib_index, &pfx_0_0_0_0_s_0);
3896 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 0),
3897 "uRPF list for 0.0.0.0/0 empty");
3898
3899 fib_table_entry_delete(fib_index, &pfx_4_1_1_1_s_32, FIB_SOURCE_URPF_EXEMPT);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003900
3901 /*
Neale Ranns3983ac22017-03-10 11:53:27 -08003902 * An adj-fib that fails the refinement criteria - no connected cover
3903 */
3904 fib_prefix_t pfx_12_10_10_2_s_32 = {
3905 .fp_len = 32,
3906 .fp_proto = FIB_PROTOCOL_IP4,
3907 .fp_addr = {
3908 /* 12.10.10.2 */
3909 .ip4.as_u32 = clib_host_to_net_u32(0x0c0a0a02),
3910 },
3911 };
3912
Neale Ranns81424992017-05-18 03:03:22 -07003913 fib_table_entry_path_add(fib_index,
3914 &pfx_12_10_10_2_s_32,
3915 FIB_SOURCE_ADJ,
3916 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07003917 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07003918 &pfx_12_10_10_2_s_32.fp_addr,
3919 tm->hw[0]->sw_if_index,
3920 ~0, // invalid fib index
3921 1,
3922 NULL,
3923 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns3983ac22017-03-10 11:53:27 -08003924
3925 fei = fib_table_lookup_exact_match(fib_index, &pfx_12_10_10_2_s_32);
3926 dpo = fib_entry_contribute_ip_forwarding(fei);
3927 FIB_TEST(!dpo_id_is_valid(dpo),
3928 "no connected cover adj-fib fails refinement");
3929
3930 fib_table_entry_delete(fib_index,
3931 &pfx_12_10_10_2_s_32,
3932 FIB_SOURCE_ADJ);
3933
3934 /*
3935 * An adj-fib that fails the refinement criteria - cover is connected
3936 * but on a different interface
3937 */
3938 fib_prefix_t pfx_10_10_10_127_s_32 = {
3939 .fp_len = 32,
3940 .fp_proto = FIB_PROTOCOL_IP4,
3941 .fp_addr = {
3942 /* 10.10.10.127 */
3943 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a7f),
3944 },
3945 };
3946
Neale Ranns81424992017-05-18 03:03:22 -07003947 fib_table_entry_path_add(fib_index,
3948 &pfx_10_10_10_127_s_32,
3949 FIB_SOURCE_ADJ,
3950 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07003951 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07003952 &pfx_10_10_10_127_s_32.fp_addr,
3953 tm->hw[1]->sw_if_index,
3954 ~0, // invalid fib index
3955 1,
3956 NULL,
3957 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns3983ac22017-03-10 11:53:27 -08003958
3959 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_127_s_32);
3960 dpo = fib_entry_contribute_ip_forwarding(fei);
3961 FIB_TEST(!dpo_id_is_valid(dpo),
3962 "wrong interface adj-fib fails refinement");
3963
3964 fib_table_entry_delete(fib_index,
3965 &pfx_10_10_10_127_s_32,
3966 FIB_SOURCE_ADJ);
Neale Ranns81424992017-05-18 03:03:22 -07003967
3968 /*
3969 * add a second path to an adj-fib
3970 * this is a sumiluation of another ARP entry created
3971 * on an interface on which the connected prefi does not exist.
3972 * The second path fails refinement. Expect to forward through the
3973 * first.
3974 */
3975 fib_prefix_t pfx_10_10_10_3_s_32 = {
3976 .fp_len = 32,
3977 .fp_proto = FIB_PROTOCOL_IP4,
3978 .fp_addr = {
3979 /* 10.10.10.3 */
3980 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a03),
3981 },
3982 };
3983
3984 ai_03 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
3985 VNET_LINK_IP4,
3986 &nh_10_10_10_3,
3987 tm->hw[0]->sw_if_index);
3988
3989 fib_test_lb_bucket_t ip_o_10_10_10_3 = {
3990 .type = FT_LB_ADJ,
3991 .adj = {
3992 .adj = ai_03,
3993 },
3994 };
3995 fei = fib_table_entry_path_add(fib_index,
3996 &pfx_10_10_10_3_s_32,
3997 FIB_SOURCE_ADJ,
3998 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003999 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07004000 &nh_10_10_10_3,
4001 tm->hw[0]->sw_if_index,
4002 fib_index,
4003 1,
4004 NULL,
4005 FIB_ROUTE_PATH_FLAG_NONE);
4006 fei = fib_table_entry_path_add(fib_index,
4007 &pfx_10_10_10_3_s_32,
4008 FIB_SOURCE_ADJ,
4009 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07004010 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07004011 &nh_12_12_12_12,
4012 tm->hw[1]->sw_if_index,
4013 fib_index,
4014 1,
4015 NULL,
4016 FIB_ROUTE_PATH_FLAG_NONE);
4017 FIB_TEST(fib_test_validate_entry(fei,
4018 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
4019 1,
4020 &ip_o_10_10_10_3),
4021 "10.10.10.3 via 10.10.10.3/Eth0 only");
4022
4023 /*
4024 * remove the path that refines the cover, should go unresolved
4025 */
4026 fib_table_entry_path_remove(fib_index,
4027 &pfx_10_10_10_3_s_32,
4028 FIB_SOURCE_ADJ,
Neale Rannsda78f952017-05-24 09:15:43 -07004029 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07004030 &nh_10_10_10_3,
4031 tm->hw[0]->sw_if_index,
4032 fib_index,
4033 1,
4034 FIB_ROUTE_PATH_FLAG_NONE);
4035 dpo = fib_entry_contribute_ip_forwarding(fei);
4036 FIB_TEST(!dpo_id_is_valid(dpo),
4037 "wrong interface adj-fib fails refinement");
4038
4039 /*
4040 * add back the path that refines the cover
4041 */
4042 fei = fib_table_entry_path_add(fib_index,
4043 &pfx_10_10_10_3_s_32,
4044 FIB_SOURCE_ADJ,
4045 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07004046 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07004047 &nh_10_10_10_3,
4048 tm->hw[0]->sw_if_index,
4049 fib_index,
4050 1,
4051 NULL,
4052 FIB_ROUTE_PATH_FLAG_NONE);
4053 FIB_TEST(fib_test_validate_entry(fei,
4054 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
4055 1,
4056 &ip_o_10_10_10_3),
4057 "10.10.10.3 via 10.10.10.3/Eth0 only");
4058
4059 /*
4060 * remove the path that does not refine the cover
4061 */
4062 fib_table_entry_path_remove(fib_index,
4063 &pfx_10_10_10_3_s_32,
4064 FIB_SOURCE_ADJ,
Neale Rannsda78f952017-05-24 09:15:43 -07004065 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07004066 &nh_12_12_12_12,
4067 tm->hw[1]->sw_if_index,
4068 fib_index,
4069 1,
4070 FIB_ROUTE_PATH_FLAG_NONE);
4071 FIB_TEST(fib_test_validate_entry(fei,
4072 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
4073 1,
4074 &ip_o_10_10_10_3),
4075 "10.10.10.3 via 10.10.10.3/Eth0 only");
4076
4077 /*
4078 * remove the path that does refine, it's the last path, so
4079 * the entry should be gone
4080 */
4081 fib_table_entry_path_remove(fib_index,
4082 &pfx_10_10_10_3_s_32,
4083 FIB_SOURCE_ADJ,
Neale Rannsda78f952017-05-24 09:15:43 -07004084 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07004085 &nh_10_10_10_3,
4086 tm->hw[0]->sw_if_index,
4087 fib_index,
4088 1,
4089 FIB_ROUTE_PATH_FLAG_NONE);
4090 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_3_s_32);
4091 FIB_TEST((fei == FIB_NODE_INDEX_INVALID), "10.10.10.3 gone");
4092
4093 adj_unlock(ai_03);
4094
Neale Ranns227038a2017-04-21 01:07:59 -07004095 /*
4096 * change the table's flow-hash config - expect the update to propagete to
4097 * the entries' load-balance objects
4098 */
4099 flow_hash_config_t old_hash_config, new_hash_config;
4100
4101 old_hash_config = fib_table_get_flow_hash_config(fib_index,
4102 FIB_PROTOCOL_IP4);
4103 new_hash_config = (IP_FLOW_HASH_SRC_ADDR |
4104 IP_FLOW_HASH_DST_ADDR);
4105
4106 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
4107 dpo = fib_entry_contribute_ip_forwarding(fei);
4108 lb = load_balance_get(dpo->dpoi_index);
4109 FIB_TEST((lb->lb_hash_config == old_hash_config),
4110 "Table and LB hash config match: %U",
4111 format_ip_flow_hash_config, lb->lb_hash_config);
4112
4113 fib_table_set_flow_hash_config(fib_index, FIB_PROTOCOL_IP4, new_hash_config);
4114
4115 FIB_TEST((lb->lb_hash_config == new_hash_config),
4116 "Table and LB newhash config match: %U",
4117 format_ip_flow_hash_config, lb->lb_hash_config);
Neale Ranns3983ac22017-03-10 11:53:27 -08004118
4119 /*
Neale Rannsf068c3e2018-01-03 04:18:48 -08004120 * A route via DVR DPO
Neale Ranns6f631152017-10-03 08:20:21 -07004121 */
4122 fei = fib_table_entry_path_add(fib_index,
4123 &pfx_10_10_10_3_s_32,
4124 FIB_SOURCE_API,
4125 FIB_ENTRY_FLAG_NONE,
Neale Rannsf068c3e2018-01-03 04:18:48 -08004126 DPO_PROTO_IP4,
Neale Ranns6f631152017-10-03 08:20:21 -07004127 &zero_addr,
4128 tm->hw[0]->sw_if_index,
4129 ~0,
4130 1,
4131 NULL,
Neale Rannsf068c3e2018-01-03 04:18:48 -08004132 FIB_ROUTE_PATH_DVR);
4133 dpo_id_t dvr_dpo = DPO_INVALID;
4134 dvr_dpo_add_or_lock(tm->hw[0]->sw_if_index, DPO_PROTO_IP4, &dvr_dpo);
Neale Ranns6f631152017-10-03 08:20:21 -07004135 fib_test_lb_bucket_t ip_o_l2 = {
4136 .type = FT_LB_L2,
4137 .adj = {
Neale Rannsf068c3e2018-01-03 04:18:48 -08004138 .adj = dvr_dpo.dpoi_index,
Neale Ranns6f631152017-10-03 08:20:21 -07004139 },
4140 };
4141
4142 FIB_TEST(fib_test_validate_entry(fei,
4143 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
4144 1,
4145 &ip_o_l2),
4146 "10.10.10.3 via L2 on Eth0");
4147 fib_table_entry_path_remove(fib_index,
4148 &pfx_10_10_10_3_s_32,
4149 FIB_SOURCE_API,
Neale Rannsf068c3e2018-01-03 04:18:48 -08004150 DPO_PROTO_IP4,
Neale Ranns6f631152017-10-03 08:20:21 -07004151 &zero_addr,
4152 tm->hw[0]->sw_if_index,
4153 fib_index,
4154 1,
Neale Rannsf068c3e2018-01-03 04:18:48 -08004155 FIB_ROUTE_PATH_DVR);
4156 dpo_reset(&dvr_dpo);
Neale Ranns6f631152017-10-03 08:20:21 -07004157
4158 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004159 * CLEANUP
4160 * remove adj-fibs:
4161 */
4162 fib_table_entry_delete(fib_index,
4163 &pfx_10_10_10_1_s_32,
4164 FIB_SOURCE_ADJ);
4165 fib_table_entry_delete(fib_index,
4166 &pfx_10_10_10_2_s_32,
4167 FIB_SOURCE_ADJ);
4168 FIB_TEST(FIB_NODE_INDEX_INVALID ==
4169 fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32),
4170 "10.10.10.1/32 adj-fib removed");
4171 FIB_TEST(FIB_NODE_INDEX_INVALID ==
4172 fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_2_s_32),
4173 "10.10.10.2/32 adj-fib removed");
4174
4175 /*
4176 * -2 entries and -2 non-shared path-list
4177 */
4178 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
4179 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004180 FIB_TEST((PNBR+2 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004181 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004182 FIB_TEST((ENBR+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004183 fib_entry_pool_size());
4184
4185 /*
Neale Ranns3ee44042016-10-03 13:05:48 +01004186 * unlock the adjacencies for which this test provided a rewrite.
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004187 * These are the last locks on these adjs. they should thus go away.
4188 */
4189 adj_unlock(ai_02);
4190 adj_unlock(ai_01);
Neale Ranns3ee44042016-10-03 13:05:48 +01004191 adj_unlock(ai_12_12_12_12);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004192
4193 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
4194 adj_nbr_db_size());
Neale Ranns3dffb1e2016-11-01 20:38:53 +00004195
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004196 /*
4197 * CLEANUP
4198 * remove the interface prefixes
4199 */
4200 local_pfx.fp_len = 32;
4201 fib_table_entry_special_remove(fib_index, &local_pfx,
4202 FIB_SOURCE_INTERFACE);
4203 fei = fib_table_lookup(fib_index, &local_pfx);
4204
4205 FIB_TEST(FIB_NODE_INDEX_INVALID ==
4206 fib_table_lookup_exact_match(fib_index, &local_pfx),
4207 "10.10.10.10/32 adj-fib removed");
4208
4209 local_pfx.fp_len = 24;
4210 fib_table_entry_delete(fib_index, &local_pfx,
4211 FIB_SOURCE_INTERFACE);
4212
4213 FIB_TEST(FIB_NODE_INDEX_INVALID ==
4214 fib_table_lookup_exact_match(fib_index, &local_pfx),
4215 "10.10.10.10/24 adj-fib removed");
4216
4217 /*
4218 * -2 entries and -2 non-shared path-list
4219 */
Neale Rannsf12a83f2017-04-18 09:09:40 -07004220 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004221 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004222 FIB_TEST((PNBR == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004223 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004224 FIB_TEST((ENBR == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004225 fib_entry_pool_size());
4226
4227 /*
4228 * Last but not least, remove the VRF
4229 */
4230 FIB_TEST((0 == fib_table_get_num_entries(fib_index,
4231 FIB_PROTOCOL_IP4,
4232 FIB_SOURCE_API)),
4233 "NO API Source'd prefixes");
4234 FIB_TEST((0 == fib_table_get_num_entries(fib_index,
4235 FIB_PROTOCOL_IP4,
4236 FIB_SOURCE_RR)),
4237 "NO RR Source'd prefixes");
4238 FIB_TEST((0 == fib_table_get_num_entries(fib_index,
4239 FIB_PROTOCOL_IP4,
4240 FIB_SOURCE_INTERFACE)),
4241 "NO INterface Source'd prefixes");
4242
Neale Ranns15002542017-09-10 04:39:11 -07004243 fib_table_unlock(fib_index, FIB_PROTOCOL_IP4, FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004244
4245 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
4246 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004247 FIB_TEST((PNBR-5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004248 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004249 FIB_TEST((ENBR-5 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004250 fib_entry_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004251 FIB_TEST((ENBR-5 == pool_elts(fib_urpf_list_pool)), "uRPF pool size is %d",
Neale Ranns3ee44042016-10-03 13:05:48 +01004252 pool_elts(fib_urpf_list_pool));
Neale Ranns994dab42017-04-18 12:56:45 -07004253 FIB_TEST((0 == pool_elts(load_balance_map_pool)), "LB-map pool size is %d",
Neale Rannsf12a83f2017-04-18 09:09:40 -07004254 pool_elts(load_balance_map_pool));
Neale Ranns994dab42017-04-18 12:56:45 -07004255 FIB_TEST((lb_count == pool_elts(load_balance_pool)), "LB pool size is %d",
4256 pool_elts(load_balance_pool));
Neale Rannsf068c3e2018-01-03 04:18:48 -08004257 FIB_TEST((0 == pool_elts(dvr_dpo_pool)), "L2 DPO pool size is %d",
4258 pool_elts(dvr_dpo_pool));
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004259
Neale Ranns0ebe8d72016-12-08 19:48:11 +00004260 return 0;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004261}
4262
Neale Ranns0ebe8d72016-12-08 19:48:11 +00004263static int
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004264fib_test_v6 (void)
4265{
4266 /*
4267 * In the default table check for the presence and correct forwarding
4268 * of the special entries
4269 */
4270 fib_node_index_t dfrt, fei, ai, locked_ai, ai_01, ai_02;
4271 const dpo_id_t *dpo, *dpo_drop;
4272 const ip_adjacency_t *adj;
4273 const receive_dpo_t *rd;
4274 test_main_t *tm;
4275 u32 fib_index;
4276 int ii;
4277
4278 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
4279 adj_nbr_db_size());
4280
4281 /* via 2001:0:0:1::2 */
4282 ip46_address_t nh_2001_2 = {
4283 .ip6 = {
4284 .as_u64 = {
4285 [0] = clib_host_to_net_u64(0x2001000000000001),
4286 [1] = clib_host_to_net_u64(0x0000000000000002),
4287 },
4288 },
4289 };
4290
4291 tm = &test_main;
4292
4293 dpo_drop = drop_dpo_get(DPO_PROTO_IP6);
4294
4295 /* Find or create FIB table 11 */
Neale Ranns15002542017-09-10 04:39:11 -07004296 fib_index = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP6, 11,
4297 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004298
4299 for (ii = 0; ii < 4; ii++)
4300 {
4301 ip6_main.fib_index_by_sw_if_index[tm->hw[ii]->sw_if_index] = fib_index;
4302 }
4303
4304 fib_prefix_t pfx_0_0 = {
4305 .fp_len = 0,
4306 .fp_proto = FIB_PROTOCOL_IP6,
4307 .fp_addr = {
4308 .ip6 = {
4309 {0, 0},
4310 },
4311 },
4312 };
4313
4314 dfrt = fib_table_lookup(fib_index, &pfx_0_0);
4315 FIB_TEST((FIB_NODE_INDEX_INVALID != dfrt), "default route present");
4316 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(dfrt)),
4317 "Default route is DROP");
4318
4319 dpo = fib_entry_contribute_ip_forwarding(dfrt);
4320 FIB_TEST((dpo->dpoi_index == ip6_fib_table_fwding_lookup(
4321 &ip6_main,
4322 1,
4323 &pfx_0_0.fp_addr.ip6)),
4324 "default-route; fwd and non-fwd tables match");
4325
4326 // FIXME - check specials.
4327
4328 /*
4329 * At this stage there is one v4 FIB with 5 routes and two v6 FIBs
Neale Ranns32e1c012016-11-22 17:07:28 +00004330 * each with 2 entries and a v6 mfib with 4 path-lists.
4331 * All entries are special so no path-list sharing.
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004332 */
Neale Ranns32e1c012016-11-22 17:07:28 +00004333#define ENPS (5+4)
4334#define PNPS (5+4+4)
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004335 FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00004336 FIB_TEST((PNPS == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004337 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004338 FIB_TEST((ENPS == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004339 fib_entry_pool_size());
4340
4341 /*
4342 * add interface routes.
4343 * validate presence of /64 attached and /128 recieve.
4344 * test for the presence of the receive address in the glean and local adj
4345 *
4346 * receive on 2001:0:0:1::1/128
4347 */
4348 fib_prefix_t local_pfx = {
4349 .fp_len = 64,
4350 .fp_proto = FIB_PROTOCOL_IP6,
4351 .fp_addr = {
4352 .ip6 = {
4353 .as_u64 = {
4354 [0] = clib_host_to_net_u64(0x2001000000000001),
4355 [1] = clib_host_to_net_u64(0x0000000000000001),
4356 },
4357 },
4358 }
4359 };
4360
4361 fib_table_entry_update_one_path(fib_index, &local_pfx,
4362 FIB_SOURCE_INTERFACE,
4363 (FIB_ENTRY_FLAG_CONNECTED |
4364 FIB_ENTRY_FLAG_ATTACHED),
Neale Rannsda78f952017-05-24 09:15:43 -07004365 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004366 NULL,
4367 tm->hw[0]->sw_if_index,
4368 ~0,
4369 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00004370 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004371 FIB_ROUTE_PATH_FLAG_NONE);
4372 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4373
4374 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached interface route present");
4375
4376 ai = fib_entry_get_adj(fei);
4377 FIB_TEST((FIB_NODE_INDEX_INVALID != ai), "attached interface route adj present");
4378 adj = adj_get(ai);
4379 FIB_TEST((IP_LOOKUP_NEXT_GLEAN == adj->lookup_next_index),
4380 "attached interface adj is glean");
4381 FIB_TEST((0 == ip46_address_cmp(&local_pfx.fp_addr,
4382 &adj->sub_type.glean.receive_addr)),
4383 "attached interface adj is receive ok");
4384 dpo = fib_entry_contribute_ip_forwarding(fei);
4385 FIB_TEST((dpo->dpoi_index == ip6_fib_table_fwding_lookup(
4386 &ip6_main,
4387 1,
4388 &local_pfx.fp_addr.ip6)),
4389 "attached-route; fwd and non-fwd tables match");
4390
4391 local_pfx.fp_len = 128;
4392 fib_table_entry_update_one_path(fib_index, &local_pfx,
4393 FIB_SOURCE_INTERFACE,
4394 (FIB_ENTRY_FLAG_CONNECTED |
4395 FIB_ENTRY_FLAG_LOCAL),
Neale Rannsda78f952017-05-24 09:15:43 -07004396 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004397 NULL,
4398 tm->hw[0]->sw_if_index,
4399 ~0, // invalid fib index
4400 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00004401 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004402 FIB_ROUTE_PATH_FLAG_NONE);
4403 fei = fib_table_lookup(fib_index, &local_pfx);
4404
4405 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local interface route present");
4406
4407 dpo = fib_entry_contribute_ip_forwarding(fei);
4408 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
4409 FIB_TEST((DPO_RECEIVE == dpo->dpoi_type),
4410 "local interface adj is local");
4411 rd = receive_dpo_get(dpo->dpoi_index);
4412
4413 FIB_TEST((0 == ip46_address_cmp(&local_pfx.fp_addr,
4414 &rd->rd_addr)),
4415 "local interface adj is receive ok");
4416
4417 dpo = fib_entry_contribute_ip_forwarding(fei);
4418 FIB_TEST((dpo->dpoi_index == ip6_fib_table_fwding_lookup(
4419 &ip6_main,
4420 1,
4421 &local_pfx.fp_addr.ip6)),
4422 "local-route; fwd and non-fwd tables match");
4423
4424 /*
4425 * +2 entries. +2 unshared path-lists
4426 */
4427 FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00004428 FIB_TEST((PNPS+2 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004429 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004430 FIB_TEST((ENPS+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004431 fib_entry_pool_size());
4432
4433 /*
4434 * Modify the default route to be via an adj not yet known.
4435 * this sources the defalut route with the API source, which is
4436 * a higher preference to the DEFAULT_ROUTE source
4437 */
4438 fib_table_entry_path_add(fib_index, &pfx_0_0,
4439 FIB_SOURCE_API,
4440 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07004441 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004442 &nh_2001_2,
4443 tm->hw[0]->sw_if_index,
4444 ~0,
4445 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00004446 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004447 FIB_ROUTE_PATH_FLAG_NONE);
4448 fei = fib_table_lookup(fib_index, &pfx_0_0);
4449
4450 FIB_TEST((fei == dfrt), "default route same index");
4451 ai = fib_entry_get_adj(fei);
4452 FIB_TEST((FIB_NODE_INDEX_INVALID != ai), "default route adj present");
4453 adj = adj_get(ai);
4454 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
4455 "adj is incomplete");
4456 FIB_TEST((0 == ip46_address_cmp(&nh_2001_2, &adj->sub_type.nbr.next_hop)),
4457 "adj nbr next-hop ok");
4458
4459 /*
4460 * find the adj in the shared db
4461 */
4462 locked_ai = adj_nbr_add_or_lock(FIB_PROTOCOL_IP6,
Neale Ranns924d03a2016-10-19 08:25:46 +01004463 VNET_LINK_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004464 &nh_2001_2,
4465 tm->hw[0]->sw_if_index);
4466 FIB_TEST((locked_ai == ai), "ADJ NBR DB find");
4467 adj_unlock(locked_ai);
4468
4469 /*
4470 * no more entires. +1 shared path-list
4471 */
4472 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
4473 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004474 FIB_TEST((PNPS+3 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004475 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004476 FIB_TEST((ENPS+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004477 fib_entry_pool_size());
4478
4479 /*
4480 * remove the API source from the default route. We expected
4481 * the route to remain, sourced by DEFAULT_ROUTE, and hence a DROP
4482 */
4483 fib_table_entry_path_remove(fib_index, &pfx_0_0,
4484 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07004485 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004486 &nh_2001_2,
4487 tm->hw[0]->sw_if_index,
4488 ~0,
4489 1,
4490 FIB_ROUTE_PATH_FLAG_NONE);
4491 fei = fib_table_lookup(fib_index, &pfx_0_0);
4492
4493 FIB_TEST((fei == dfrt), "default route same index");
4494 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(dfrt)),
4495 "Default route is DROP");
4496
4497 /*
4498 * no more entires. -1 shared path-list
4499 */
4500 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
4501 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004502 FIB_TEST((PNPS+2 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004503 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004504 FIB_TEST((ENPS+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004505 fib_entry_pool_size());
4506
4507 /*
4508 * Add an 2 ARP entry => a complete ADJ plus adj-fib.
4509 */
4510 fib_prefix_t pfx_2001_1_2_s_128 = {
4511 .fp_len = 128,
4512 .fp_proto = FIB_PROTOCOL_IP6,
4513 .fp_addr = {
4514 .ip6 = {
4515 .as_u64 = {
4516 [0] = clib_host_to_net_u64(0x2001000000000001),
4517 [1] = clib_host_to_net_u64(0x0000000000000002),
4518 },
4519 },
4520 }
4521 };
4522 fib_prefix_t pfx_2001_1_3_s_128 = {
4523 .fp_len = 128,
4524 .fp_proto = FIB_PROTOCOL_IP6,
4525 .fp_addr = {
4526 .ip6 = {
4527 .as_u64 = {
4528 [0] = clib_host_to_net_u64(0x2001000000000001),
4529 [1] = clib_host_to_net_u64(0x0000000000000003),
4530 },
4531 },
4532 }
4533 };
4534 u8 eth_addr[] = {
4535 0xde, 0xde, 0xde, 0xba, 0xba, 0xba,
4536 };
4537
4538 ai_01 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP6,
Neale Ranns924d03a2016-10-19 08:25:46 +01004539 VNET_LINK_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004540 &pfx_2001_1_2_s_128.fp_addr,
4541 tm->hw[0]->sw_if_index);
4542 FIB_TEST((FIB_NODE_INDEX_INVALID != ai_01), "adj created");
4543 adj = adj_get(ai_01);
4544 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
4545 "adj is incomplete");
4546 FIB_TEST((0 == ip46_address_cmp(&pfx_2001_1_2_s_128.fp_addr,
4547 &adj->sub_type.nbr.next_hop)),
4548 "adj nbr next-hop ok");
4549
Neale Rannsb80c5362016-10-08 13:03:40 +01004550 adj_nbr_update_rewrite(ai_01, ADJ_NBR_REWRITE_FLAG_COMPLETE,
4551 fib_test_build_rewrite(eth_addr));
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004552 FIB_TEST((IP_LOOKUP_NEXT_REWRITE == adj->lookup_next_index),
4553 "adj is complete");
4554 FIB_TEST((0 == ip46_address_cmp(&pfx_2001_1_2_s_128.fp_addr,
4555 &adj->sub_type.nbr.next_hop)),
4556 "adj nbr next-hop ok");
4557
Neale Ranns81424992017-05-18 03:03:22 -07004558 fib_table_entry_path_add(fib_index,
4559 &pfx_2001_1_2_s_128,
4560 FIB_SOURCE_ADJ,
4561 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07004562 DPO_PROTO_IP6,
Neale Ranns81424992017-05-18 03:03:22 -07004563 &pfx_2001_1_2_s_128.fp_addr,
4564 tm->hw[0]->sw_if_index,
4565 ~0,
4566 1,
4567 NULL,
4568 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004569
4570 fei = fib_table_lookup(fib_index, &pfx_2001_1_2_s_128);
4571 ai = fib_entry_get_adj(fei);
4572 FIB_TEST((ai_01 == ai), "ADJ-FIB resolves via adj");
4573
4574 eth_addr[5] = 0xb2;
4575
4576 ai_02 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP6,
Neale Ranns924d03a2016-10-19 08:25:46 +01004577 VNET_LINK_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004578 &pfx_2001_1_3_s_128.fp_addr,
4579 tm->hw[0]->sw_if_index);
4580 FIB_TEST((FIB_NODE_INDEX_INVALID != ai_02), "adj created");
4581 adj = adj_get(ai_02);
4582 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
4583 "adj is incomplete");
4584 FIB_TEST((0 == ip46_address_cmp(&pfx_2001_1_3_s_128.fp_addr,
4585 &adj->sub_type.nbr.next_hop)),
4586 "adj nbr next-hop ok");
4587
Neale Rannsb80c5362016-10-08 13:03:40 +01004588 adj_nbr_update_rewrite(ai_02, ADJ_NBR_REWRITE_FLAG_COMPLETE,
4589 fib_test_build_rewrite(eth_addr));
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004590 FIB_TEST((IP_LOOKUP_NEXT_REWRITE == adj->lookup_next_index),
4591 "adj is complete");
4592 FIB_TEST((0 == ip46_address_cmp(&pfx_2001_1_3_s_128.fp_addr,
4593 &adj->sub_type.nbr.next_hop)),
4594 "adj nbr next-hop ok");
4595 FIB_TEST((ai_01 != ai_02), "ADJs are different");
4596
Neale Ranns81424992017-05-18 03:03:22 -07004597 fib_table_entry_path_add(fib_index,
4598 &pfx_2001_1_3_s_128,
4599 FIB_SOURCE_ADJ,
4600 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07004601 DPO_PROTO_IP6,
Neale Ranns81424992017-05-18 03:03:22 -07004602 &pfx_2001_1_3_s_128.fp_addr,
4603 tm->hw[0]->sw_if_index,
4604 ~0,
4605 1,
4606 NULL,
4607 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004608
4609 fei = fib_table_lookup(fib_index, &pfx_2001_1_3_s_128);
4610 ai = fib_entry_get_adj(fei);
4611 FIB_TEST((ai_02 == ai), "ADJ-FIB resolves via adj");
4612
4613 /*
4614 * +2 entries, +2 unshread path-lists.
4615 */
4616 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
4617 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004618 FIB_TEST((PNPS+4 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004619 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004620 FIB_TEST((ENPS+4 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004621 fib_entry_pool_size());
4622
4623 /*
4624 * Add a 2 routes via the first ADJ. ensure path-list sharing
4625 */
4626 fib_prefix_t pfx_2001_a_s_64 = {
4627 .fp_len = 64,
4628 .fp_proto = FIB_PROTOCOL_IP6,
4629 .fp_addr = {
4630 .ip6 = {
4631 .as_u64 = {
4632 [0] = clib_host_to_net_u64(0x200100000000000a),
4633 [1] = clib_host_to_net_u64(0x0000000000000000),
4634 },
4635 },
4636 }
4637 };
4638 fib_prefix_t pfx_2001_b_s_64 = {
4639 .fp_len = 64,
4640 .fp_proto = FIB_PROTOCOL_IP6,
4641 .fp_addr = {
4642 .ip6 = {
4643 .as_u64 = {
4644 [0] = clib_host_to_net_u64(0x200100000000000b),
4645 [1] = clib_host_to_net_u64(0x0000000000000000),
4646 },
4647 },
4648 }
4649 };
4650
4651 fib_table_entry_path_add(fib_index,
4652 &pfx_2001_a_s_64,
4653 FIB_SOURCE_API,
4654 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07004655 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004656 &nh_2001_2,
4657 tm->hw[0]->sw_if_index,
4658 ~0,
4659 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00004660 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004661 FIB_ROUTE_PATH_FLAG_NONE);
4662 fei = fib_table_lookup(fib_index, &pfx_2001_a_s_64);
4663 ai = fib_entry_get_adj(fei);
4664 FIB_TEST((ai_01 == ai), "2001::a/64 resolves via 2001:0:0:1::1");
4665 fib_table_entry_path_add(fib_index,
4666 &pfx_2001_b_s_64,
4667 FIB_SOURCE_API,
4668 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07004669 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004670 &nh_2001_2,
4671 tm->hw[0]->sw_if_index,
4672 ~0,
4673 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00004674 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004675 FIB_ROUTE_PATH_FLAG_NONE);
4676 fei = fib_table_lookup(fib_index, &pfx_2001_b_s_64);
4677 ai = fib_entry_get_adj(fei);
4678 FIB_TEST((ai_01 == ai), "2001::b/64 resolves via 2001:0:0:1::1");
4679
4680 /*
4681 * +2 entries, +1 shared path-list.
4682 */
4683 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
4684 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004685 FIB_TEST((PNPS+5 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004686 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004687 FIB_TEST((ENPS+6 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004688 fib_entry_pool_size());
4689
4690 /*
4691 * add a v4 prefix via a v6 next-hop
4692 */
4693 fib_prefix_t pfx_1_1_1_1_s_32 = {
4694 .fp_len = 32,
4695 .fp_proto = FIB_PROTOCOL_IP4,
4696 .fp_addr = {
4697 .ip4.as_u32 = 0x01010101,
4698 },
4699 };
4700 fei = fib_table_entry_path_add(0, // default table
4701 &pfx_1_1_1_1_s_32,
4702 FIB_SOURCE_API,
4703 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07004704 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004705 &nh_2001_2,
4706 tm->hw[0]->sw_if_index,
4707 ~0,
4708 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00004709 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004710 FIB_ROUTE_PATH_FLAG_NONE);
4711 FIB_TEST(fei == fib_table_lookup_exact_match(0, &pfx_1_1_1_1_s_32),
4712 "1.1.1.1/32 o v6 route present");
4713 ai = fib_entry_get_adj(fei);
4714 adj = adj_get(ai);
4715 FIB_TEST((adj->lookup_next_index == IP_LOOKUP_NEXT_ARP),
4716 "1.1.1.1/32 via ARP-adj");
Neale Ranns924d03a2016-10-19 08:25:46 +01004717 FIB_TEST((adj->ia_link == VNET_LINK_IP4),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004718 "1.1.1.1/32 ADJ-adj is link type v4");
4719 FIB_TEST((adj->ia_nh_proto == FIB_PROTOCOL_IP6),
4720 "1.1.1.1/32 ADJ-adj is NH proto v6");
4721 fib_table_entry_delete(0, &pfx_1_1_1_1_s_32, FIB_SOURCE_API);
4722
4723 /*
4724 * An attached route
4725 */
4726 fib_prefix_t pfx_2001_c_s_64 = {
4727 .fp_len = 64,
4728 .fp_proto = FIB_PROTOCOL_IP6,
4729 .fp_addr = {
4730 .ip6 = {
4731 .as_u64 = {
4732 [0] = clib_host_to_net_u64(0x200100000000000c),
4733 [1] = clib_host_to_net_u64(0x0000000000000000),
4734 },
4735 },
4736 }
4737 };
4738 fib_table_entry_path_add(fib_index,
4739 &pfx_2001_c_s_64,
4740 FIB_SOURCE_CLI,
4741 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07004742 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004743 NULL,
4744 tm->hw[0]->sw_if_index,
4745 ~0,
4746 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00004747 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004748 FIB_ROUTE_PATH_FLAG_NONE);
4749 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_c_s_64);
4750 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached route present");
4751 ai = fib_entry_get_adj(fei);
4752 adj = adj_get(ai);
4753 FIB_TEST((adj->lookup_next_index == IP_LOOKUP_NEXT_GLEAN),
4754 "2001:0:0:c/64 attached resolves via glean");
4755
4756 fib_table_entry_path_remove(fib_index,
4757 &pfx_2001_c_s_64,
4758 FIB_SOURCE_CLI,
Neale Rannsda78f952017-05-24 09:15:43 -07004759 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004760 NULL,
4761 tm->hw[0]->sw_if_index,
4762 ~0,
4763 1,
4764 FIB_ROUTE_PATH_FLAG_NONE);
4765 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_c_s_64);
4766 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "attached route removed");
4767
4768 /*
4769 * Shutdown the interface on which we have a connected and through
4770 * which the routes are reachable.
4771 * This will result in the connected, adj-fibs, and routes linking to drop
4772 * The local/for-us prefix continues to receive.
4773 */
4774 clib_error_t * error;
4775
4776 error = vnet_sw_interface_set_flags(vnet_get_main(),
4777 tm->hw[0]->sw_if_index,
4778 ~VNET_SW_INTERFACE_FLAG_ADMIN_UP);
4779 FIB_TEST((NULL == error), "Interface shutdown OK");
4780
4781 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
4782 dpo = fib_entry_contribute_ip_forwarding(fei);
4783 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4784 "2001::b/64 resolves via drop");
4785
4786 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
4787 dpo = fib_entry_contribute_ip_forwarding(fei);
4788 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4789 "2001::a/64 resolves via drop");
4790 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
4791 dpo = fib_entry_contribute_ip_forwarding(fei);
4792 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4793 "2001:0:0:1::3/64 resolves via drop");
4794 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
4795 dpo = fib_entry_contribute_ip_forwarding(fei);
4796 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4797 "2001:0:0:1::2/64 resolves via drop");
4798 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4799 dpo = fib_entry_contribute_ip_forwarding(fei);
4800 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4801 "2001:0:0:1::1/128 not drop");
4802 local_pfx.fp_len = 64;
4803 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4804 dpo = fib_entry_contribute_ip_forwarding(fei);
4805 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4806 "2001:0:0:1/64 resolves via drop");
4807
4808 /*
4809 * no change
4810 */
4811 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
4812 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004813 FIB_TEST((PNPS+5 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004814 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004815 FIB_TEST((ENPS+6 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004816 fib_entry_pool_size());
4817
4818 /*
4819 * shutdown one of the other interfaces, then add a connected.
4820 * and swap one of the routes to it.
4821 */
4822 error = vnet_sw_interface_set_flags(vnet_get_main(),
4823 tm->hw[1]->sw_if_index,
4824 ~VNET_SW_INTERFACE_FLAG_ADMIN_UP);
4825 FIB_TEST((NULL == error), "Interface 1 shutdown OK");
4826
4827 fib_prefix_t connected_pfx = {
4828 .fp_len = 64,
4829 .fp_proto = FIB_PROTOCOL_IP6,
4830 .fp_addr = {
4831 .ip6 = {
4832 /* 2001:0:0:2::1/64 */
4833 .as_u64 = {
4834 [0] = clib_host_to_net_u64(0x2001000000000002),
4835 [1] = clib_host_to_net_u64(0x0000000000000001),
4836 },
4837 },
4838 }
4839 };
4840 fib_table_entry_update_one_path(fib_index, &connected_pfx,
4841 FIB_SOURCE_INTERFACE,
4842 (FIB_ENTRY_FLAG_CONNECTED |
4843 FIB_ENTRY_FLAG_ATTACHED),
Neale Rannsda78f952017-05-24 09:15:43 -07004844 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004845 NULL,
4846 tm->hw[1]->sw_if_index,
4847 ~0,
4848 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00004849 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004850 FIB_ROUTE_PATH_FLAG_NONE);
4851 fei = fib_table_lookup_exact_match(fib_index, &connected_pfx);
4852 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached interface route present");
4853 dpo = fib_entry_contribute_ip_forwarding(fei);
4854 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
4855 FIB_TEST(!dpo_cmp(dpo, dpo_drop),
4856 "2001:0:0:2/64 not resolves via drop");
4857
4858 connected_pfx.fp_len = 128;
4859 fib_table_entry_update_one_path(fib_index, &connected_pfx,
4860 FIB_SOURCE_INTERFACE,
4861 (FIB_ENTRY_FLAG_CONNECTED |
4862 FIB_ENTRY_FLAG_LOCAL),
Neale Rannsda78f952017-05-24 09:15:43 -07004863 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004864 NULL,
4865 tm->hw[0]->sw_if_index,
4866 ~0, // invalid fib index
4867 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00004868 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004869 FIB_ROUTE_PATH_FLAG_NONE);
4870 fei = fib_table_lookup(fib_index, &connected_pfx);
4871
4872 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local interface route present");
4873 dpo = fib_entry_contribute_ip_forwarding(fei);
4874 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
4875 FIB_TEST((DPO_RECEIVE == dpo->dpoi_type),
4876 "local interface adj is local");
4877 rd = receive_dpo_get(dpo->dpoi_index);
4878 FIB_TEST((0 == ip46_address_cmp(&connected_pfx.fp_addr,
4879 &rd->rd_addr)),
4880 "local interface adj is receive ok");
4881
4882 /*
4883 * +2 entries, +2 unshared path-lists
4884 */
4885 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
4886 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004887 FIB_TEST((PNPS+7 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004888 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004889 FIB_TEST((ENPS+8 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004890 fib_entry_pool_size());
4891
4892
4893 /*
4894 * bring the interface back up. we expected the routes to return
4895 * to normal forwarding.
4896 */
4897 error = vnet_sw_interface_set_flags(vnet_get_main(),
4898 tm->hw[0]->sw_if_index,
4899 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
4900 FIB_TEST((NULL == error), "Interface bring-up OK");
4901 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
4902 ai = fib_entry_get_adj(fei);
4903 FIB_TEST((ai_01 == ai), "2001::a/64 resolves via 2001:0:0:1::1");
4904 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
4905 ai = fib_entry_get_adj(fei);
4906 FIB_TEST((ai_01 == ai), "2001::b/64 resolves via 2001:0:0:1::1");
4907 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
4908 ai = fib_entry_get_adj(fei);
4909 FIB_TEST((ai_02 == ai), "ADJ-FIB resolves via adj");
4910 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
4911 ai = fib_entry_get_adj(fei);
4912 FIB_TEST((ai_01 == ai), "ADJ-FIB resolves via adj");
4913 local_pfx.fp_len = 64;
4914 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4915 ai = fib_entry_get_adj(fei);
4916 adj = adj_get(ai);
4917 FIB_TEST((IP_LOOKUP_NEXT_GLEAN == adj->lookup_next_index),
4918 "attached interface adj is glean");
4919
4920 /*
Neale Ranns8b37b872016-11-21 12:25:22 +00004921 * Same test as above, but this time the HW interface goes down
4922 */
4923 error = vnet_hw_interface_set_flags(vnet_get_main(),
4924 tm->hw_if_indicies[0],
4925 ~VNET_HW_INTERFACE_FLAG_LINK_UP);
4926 FIB_TEST((NULL == error), "Interface shutdown OK");
4927
4928 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
4929 dpo = fib_entry_contribute_ip_forwarding(fei);
4930 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4931 "2001::b/64 resolves via drop");
4932 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
4933 dpo = fib_entry_contribute_ip_forwarding(fei);
4934 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4935 "2001::a/64 resolves via drop");
4936 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
4937 dpo = fib_entry_contribute_ip_forwarding(fei);
4938 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4939 "2001:0:0:1::3/128 resolves via drop");
4940 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
4941 dpo = fib_entry_contribute_ip_forwarding(fei);
4942 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4943 "2001:0:0:1::2/128 resolves via drop");
4944 local_pfx.fp_len = 128;
4945 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4946 dpo = fib_entry_contribute_ip_forwarding(fei);
4947 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4948 "2001:0:0:1::1/128 not drop");
4949 local_pfx.fp_len = 64;
4950 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4951 dpo = fib_entry_contribute_ip_forwarding(fei);
4952 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4953 "2001:0:0:1/64 resolves via drop");
4954
4955 error = vnet_hw_interface_set_flags(vnet_get_main(),
4956 tm->hw_if_indicies[0],
4957 VNET_HW_INTERFACE_FLAG_LINK_UP);
4958 FIB_TEST((NULL == error), "Interface bring-up OK");
4959 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
4960 ai = fib_entry_get_adj(fei);
4961 FIB_TEST((ai_01 == ai), "2001::a/64 resolves via 2001:0:0:1::1");
4962 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
4963 ai = fib_entry_get_adj(fei);
4964 FIB_TEST((ai_01 == ai), "2001::b/64 resolves via 2001:0:0:1::1");
4965 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
4966 ai = fib_entry_get_adj(fei);
4967 FIB_TEST((ai_02 == ai), "ADJ-FIB resolves via adj");
4968 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
4969 ai = fib_entry_get_adj(fei);
4970 FIB_TEST((ai_01 == ai), "ADJ-FIB resolves via adj");
4971 local_pfx.fp_len = 64;
4972 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4973 ai = fib_entry_get_adj(fei);
4974 adj = adj_get(ai);
4975 FIB_TEST((IP_LOOKUP_NEXT_GLEAN == adj->lookup_next_index),
4976 "attached interface adj is glean");
4977
4978 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004979 * Delete the interface that the routes reolve through.
4980 * Again no routes are removed. They all point to drop.
4981 *
4982 * This is considered an error case. The control plane should
4983 * not remove interfaces through which routes resolve, but
4984 * such things can happen. ALL affected routes will drop.
4985 */
4986 vnet_delete_hw_interface(vnet_get_main(), tm->hw_if_indicies[0]);
4987
4988 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
4989 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
4990 "2001::b/64 resolves via drop");
4991 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
4992 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
4993 "2001::b/64 resolves via drop");
4994 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
4995 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
4996 "2001:0:0:1::3/64 resolves via drop");
4997 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
4998 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
4999 "2001:0:0:1::2/64 resolves via drop");
5000 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5001 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5002 "2001:0:0:1::1/128 is drop");
5003 local_pfx.fp_len = 64;
5004 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5005 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5006 "2001:0:0:1/64 resolves via drop");
5007
5008 /*
5009 * no change
5010 */
5011 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
5012 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00005013 FIB_TEST((PNPS+7 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005014 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00005015 FIB_TEST((ENPS+8 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005016 fib_entry_pool_size());
5017
5018 /*
5019 * Add the interface back. routes stay unresolved.
5020 */
5021 error = ethernet_register_interface(vnet_get_main(),
5022 test_interface_device_class.index,
5023 0 /* instance */,
5024 hw_address,
5025 &tm->hw_if_indicies[0],
5026 /* flag change */ 0);
5027
5028 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
5029 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5030 "2001::b/64 resolves via drop");
5031 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
5032 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5033 "2001::b/64 resolves via drop");
5034 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
5035 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5036 "2001:0:0:1::3/64 resolves via drop");
5037 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
5038 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5039 "2001:0:0:1::2/64 resolves via drop");
5040 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5041 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5042 "2001:0:0:1::1/128 is drop");
5043 local_pfx.fp_len = 64;
5044 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5045 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5046 "2001:0:0:1/64 resolves via drop");
5047
5048 /*
5049 * CLEANUP ALL the routes
5050 */
5051 fib_table_entry_delete(fib_index,
5052 &pfx_2001_c_s_64,
5053 FIB_SOURCE_API);
5054 fib_table_entry_delete(fib_index,
5055 &pfx_2001_a_s_64,
5056 FIB_SOURCE_API);
5057 fib_table_entry_delete(fib_index,
5058 &pfx_2001_b_s_64,
5059 FIB_SOURCE_API);
5060 fib_table_entry_delete(fib_index,
5061 &pfx_2001_1_3_s_128,
5062 FIB_SOURCE_ADJ);
5063 fib_table_entry_delete(fib_index,
5064 &pfx_2001_1_2_s_128,
5065 FIB_SOURCE_ADJ);
5066 local_pfx.fp_len = 64;
5067 fib_table_entry_delete(fib_index, &local_pfx,
5068 FIB_SOURCE_INTERFACE);
5069 local_pfx.fp_len = 128;
5070 fib_table_entry_special_remove(fib_index, &local_pfx,
5071 FIB_SOURCE_INTERFACE);
5072 connected_pfx.fp_len = 64;
5073 fib_table_entry_delete(fib_index, &connected_pfx,
5074 FIB_SOURCE_INTERFACE);
5075 connected_pfx.fp_len = 128;
5076 fib_table_entry_special_remove(fib_index, &connected_pfx,
5077 FIB_SOURCE_INTERFACE);
5078
5079 FIB_TEST((FIB_NODE_INDEX_INVALID ==
5080 fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64)),
5081 "2001::a/64 removed");
5082 FIB_TEST((FIB_NODE_INDEX_INVALID ==
5083 fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64)),
5084 "2001::b/64 removed");
5085 FIB_TEST((FIB_NODE_INDEX_INVALID ==
5086 fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128)),
5087 "2001:0:0:1::3/128 removed");
5088 FIB_TEST((FIB_NODE_INDEX_INVALID ==
5089 fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128)),
5090 "2001:0:0:1::3/128 removed");
5091 local_pfx.fp_len = 64;
5092 FIB_TEST((FIB_NODE_INDEX_INVALID ==
5093 fib_table_lookup_exact_match(fib_index, &local_pfx)),
5094 "2001:0:0:1/64 removed");
5095 local_pfx.fp_len = 128;
5096 FIB_TEST((FIB_NODE_INDEX_INVALID ==
5097 fib_table_lookup_exact_match(fib_index, &local_pfx)),
5098 "2001:0:0:1::1/128 removed");
5099 connected_pfx.fp_len = 64;
5100 FIB_TEST((FIB_NODE_INDEX_INVALID ==
5101 fib_table_lookup_exact_match(fib_index, &connected_pfx)),
5102 "2001:0:0:2/64 removed");
5103 connected_pfx.fp_len = 128;
5104 FIB_TEST((FIB_NODE_INDEX_INVALID ==
5105 fib_table_lookup_exact_match(fib_index, &connected_pfx)),
5106 "2001:0:0:2::1/128 removed");
5107
5108 /*
5109 * -8 entries. -7 path-lists (1 was shared).
5110 */
5111 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
5112 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00005113 FIB_TEST((PNPS == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005114 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00005115 FIB_TEST((ENPS == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005116 fib_entry_pool_size());
5117
5118 /*
5119 * now remove the VRF
5120 */
Neale Ranns15002542017-09-10 04:39:11 -07005121 fib_table_unlock(fib_index, FIB_PROTOCOL_IP6, FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005122
5123 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
5124 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00005125 FIB_TEST((PNPS-2 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005126 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00005127 FIB_TEST((ENPS-2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005128 fib_entry_pool_size());
5129
5130 adj_unlock(ai_02);
5131 adj_unlock(ai_01);
5132
5133 /*
5134 * return the interfaces to up state
5135 */
5136 error = vnet_sw_interface_set_flags(vnet_get_main(),
5137 tm->hw[0]->sw_if_index,
5138 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
5139 error = vnet_sw_interface_set_flags(vnet_get_main(),
5140 tm->hw[1]->sw_if_index,
5141 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
5142
5143 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
5144 adj_nbr_db_size());
Neale Ranns0ebe8d72016-12-08 19:48:11 +00005145
5146 return (0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005147}
5148
5149/*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005150 * Test Attached Exports
5151 */
Neale Ranns0ebe8d72016-12-08 19:48:11 +00005152static int
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005153fib_test_ae (void)
5154{
5155 const dpo_id_t *dpo, *dpo_drop;
5156 const u32 fib_index = 0;
5157 fib_node_index_t fei;
5158 test_main_t *tm;
5159 ip4_main_t *im;
5160
5161 tm = &test_main;
5162 im = &ip4_main;
5163
5164 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
5165 adj_nbr_db_size());
5166
5167 /*
5168 * add interface routes. We'll assume this works. It's more rigorously
5169 * tested elsewhere.
5170 */
5171 fib_prefix_t local_pfx = {
5172 .fp_len = 24,
5173 .fp_proto = FIB_PROTOCOL_IP4,
5174 .fp_addr = {
5175 .ip4 = {
5176 /* 10.10.10.10 */
5177 .as_u32 = clib_host_to_net_u32(0x0a0a0a0a),
5178 },
5179 },
5180 };
5181
5182 vec_validate(im->fib_index_by_sw_if_index, tm->hw[0]->sw_if_index);
5183 im->fib_index_by_sw_if_index[tm->hw[0]->sw_if_index] = fib_index;
5184
5185 dpo_drop = drop_dpo_get(DPO_PROTO_IP4);
5186
5187 fib_table_entry_update_one_path(fib_index, &local_pfx,
5188 FIB_SOURCE_INTERFACE,
5189 (FIB_ENTRY_FLAG_CONNECTED |
5190 FIB_ENTRY_FLAG_ATTACHED),
Neale Rannsda78f952017-05-24 09:15:43 -07005191 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005192 NULL,
5193 tm->hw[0]->sw_if_index,
5194 ~0,
5195 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005196 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005197 FIB_ROUTE_PATH_FLAG_NONE);
5198 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5199 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
5200 "attached interface route present");
5201
5202 local_pfx.fp_len = 32;
5203 fib_table_entry_update_one_path(fib_index, &local_pfx,
5204 FIB_SOURCE_INTERFACE,
5205 (FIB_ENTRY_FLAG_CONNECTED |
5206 FIB_ENTRY_FLAG_LOCAL),
Neale Rannsda78f952017-05-24 09:15:43 -07005207 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005208 NULL,
5209 tm->hw[0]->sw_if_index,
5210 ~0, // invalid fib index
5211 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005212 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005213 FIB_ROUTE_PATH_FLAG_NONE);
5214 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5215
5216 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
5217 "local interface route present");
5218
5219 /*
5220 * Add an 2 ARP entry => a complete ADJ plus adj-fib.
5221 */
5222 fib_prefix_t pfx_10_10_10_1_s_32 = {
5223 .fp_len = 32,
5224 .fp_proto = FIB_PROTOCOL_IP4,
5225 .fp_addr = {
5226 /* 10.10.10.1 */
5227 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
5228 },
5229 };
5230 fib_node_index_t ai;
5231
Neale Ranns81424992017-05-18 03:03:22 -07005232 fib_table_entry_path_add(fib_index,
5233 &pfx_10_10_10_1_s_32,
5234 FIB_SOURCE_ADJ,
5235 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07005236 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07005237 &pfx_10_10_10_1_s_32.fp_addr,
5238 tm->hw[0]->sw_if_index,
5239 ~0, // invalid fib index
5240 1,
5241 NULL,
5242 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005243
5244 fei = fib_table_lookup(fib_index, &pfx_10_10_10_1_s_32);
5245 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 created");
5246 ai = fib_entry_get_adj(fei);
5247
5248 /*
5249 * create another FIB table into which routes will be imported
5250 */
5251 u32 import_fib_index1;
5252
Neale Ranns15002542017-09-10 04:39:11 -07005253 import_fib_index1 = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP4,
5254 11,
5255 FIB_SOURCE_CLI);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005256
5257 /*
5258 * Add an attached route in the import FIB
5259 */
5260 local_pfx.fp_len = 24;
5261 fib_table_entry_update_one_path(import_fib_index1,
5262 &local_pfx,
5263 FIB_SOURCE_API,
5264 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07005265 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005266 NULL,
5267 tm->hw[0]->sw_if_index,
5268 ~0, // invalid fib index
5269 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005270 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005271 FIB_ROUTE_PATH_FLAG_NONE);
5272 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5273 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached export created");
5274
5275 /*
5276 * check for the presence of the adj-fibs in the import table
5277 */
5278 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5279 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 imported");
5280 FIB_TEST((ai == fib_entry_get_adj(fei)),
5281 "adj-fib1 Import uses same adj as export");
5282
5283 /*
5284 * check for the presence of the local in the import table
5285 */
5286 local_pfx.fp_len = 32;
5287 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5288 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local imported");
5289
5290 /*
5291 * Add another adj-fin in the export table. Expect this
5292 * to get magically exported;
5293 */
5294 fib_prefix_t pfx_10_10_10_2_s_32 = {
5295 .fp_len = 32,
5296 .fp_proto = FIB_PROTOCOL_IP4,
5297 .fp_addr = {
5298 /* 10.10.10.2 */
5299 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02),
5300 },
5301 };
5302
Neale Ranns81424992017-05-18 03:03:22 -07005303 fib_table_entry_path_add(fib_index,
5304 &pfx_10_10_10_2_s_32,
5305 FIB_SOURCE_ADJ,
5306 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07005307 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07005308 &pfx_10_10_10_2_s_32.fp_addr,
5309 tm->hw[0]->sw_if_index,
5310 ~0, // invalid fib index
5311 1,
5312 NULL,
5313 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005314 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_2_s_32);
5315 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 present");
5316 ai = fib_entry_get_adj(fei);
5317
5318 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5319 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 imported");
5320 FIB_TEST((ai == fib_entry_get_adj(fei)),
5321 "Import uses same adj as export");
Neale Rannsfa0fb582016-12-10 21:59:14 +00005322 FIB_TEST((FIB_ENTRY_FLAG_ATTACHED & fib_entry_get_flags(fei)),
5323 "ADJ-fib2 imported flags %d",
5324 fib_entry_get_flags(fei));
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005325
5326 /*
5327 * create a 2nd FIB table into which routes will be imported
5328 */
5329 u32 import_fib_index2;
5330
Neale Ranns15002542017-09-10 04:39:11 -07005331 import_fib_index2 = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP4, 12,
5332 FIB_SOURCE_CLI);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005333
5334 /*
5335 * Add an attached route in the import FIB
5336 */
5337 local_pfx.fp_len = 24;
5338 fib_table_entry_update_one_path(import_fib_index2,
5339 &local_pfx,
5340 FIB_SOURCE_API,
5341 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07005342 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005343 NULL,
5344 tm->hw[0]->sw_if_index,
5345 ~0, // invalid fib index
5346 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005347 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005348 FIB_ROUTE_PATH_FLAG_NONE);
5349 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5350 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached export created");
5351
5352 /*
5353 * check for the presence of all the adj-fibs and local in the import table
5354 */
5355 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_1_s_32);
5356 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 imported");
5357 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_2_s_32);
5358 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 imported");
5359 local_pfx.fp_len = 32;
5360 fei = fib_table_lookup_exact_match(import_fib_index2, &local_pfx);
5361 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local imported");
5362
5363 /*
5364 * add a 3rd adj-fib. expect it to be exported to both tables.
5365 */
5366 fib_prefix_t pfx_10_10_10_3_s_32 = {
5367 .fp_len = 32,
5368 .fp_proto = FIB_PROTOCOL_IP4,
5369 .fp_addr = {
5370 /* 10.10.10.3 */
5371 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a03),
5372 },
5373 };
5374
Neale Ranns81424992017-05-18 03:03:22 -07005375 fib_table_entry_path_add(fib_index,
5376 &pfx_10_10_10_3_s_32,
5377 FIB_SOURCE_ADJ,
5378 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07005379 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07005380 &pfx_10_10_10_3_s_32.fp_addr,
5381 tm->hw[0]->sw_if_index,
5382 ~0, // invalid fib index
5383 1,
5384 NULL,
5385 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005386 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_3_s_32);
5387 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib3 present");
5388 ai = fib_entry_get_adj(fei);
5389
5390 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_3_s_32);
5391 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib3 imported to FIB1");
5392 FIB_TEST((ai == fib_entry_get_adj(fei)),
5393 "Import uses same adj as export");
5394 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_3_s_32);
5395 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib3 imported to FIB2");
5396 FIB_TEST((ai == fib_entry_get_adj(fei)),
5397 "Import uses same adj as export");
5398
5399 /*
5400 * remove the 3rd adj fib. we expect it to be removed from both FIBs
5401 */
5402 fib_table_entry_delete(fib_index,
5403 &pfx_10_10_10_3_s_32,
5404 FIB_SOURCE_ADJ);
5405
5406 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_3_s_32);
5407 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib3 remved");
5408
5409 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_3_s_32);
5410 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib3 removed from FIB1");
5411
5412 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_3_s_32);
5413 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib3 removed from FIB2");
5414
5415 /*
5416 * remove the attached route from the 2nd FIB. expect the imported
5417 * entires to be removed
5418 */
5419 local_pfx.fp_len = 24;
5420 fib_table_entry_delete(import_fib_index2,
5421 &local_pfx,
5422 FIB_SOURCE_API);
5423 fei = fib_table_lookup_exact_match(import_fib_index2, &local_pfx);
5424 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "attached export removed");
5425
5426 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_1_s_32);
5427 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib1 removed from FIB2");
5428 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_2_s_32);
5429 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib2 removed from FIB2");
5430 local_pfx.fp_len = 32;
5431 fei = fib_table_lookup_exact_match(import_fib_index2, &local_pfx);
5432 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "local removed from FIB2");
5433
5434 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5435 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 still in FIB1");
5436 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5437 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 still in FIB1");
5438 local_pfx.fp_len = 32;
5439 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5440 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local still in FIB1");
5441
5442 /*
5443 * modify the route in FIB1 so it is no longer attached. expect the imported
5444 * entires to be removed
5445 */
5446 local_pfx.fp_len = 24;
5447 fib_table_entry_update_one_path(import_fib_index1,
5448 &local_pfx,
5449 FIB_SOURCE_API,
5450 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07005451 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005452 &pfx_10_10_10_2_s_32.fp_addr,
5453 tm->hw[0]->sw_if_index,
5454 ~0, // invalid fib index
5455 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005456 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005457 FIB_ROUTE_PATH_FLAG_NONE);
5458 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5459 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib1 removed from FIB1");
5460 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5461 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib2 removed from FIB1");
5462 local_pfx.fp_len = 32;
5463 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5464 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "local removed from FIB1");
5465
5466 /*
5467 * modify it back to attached. expect the adj-fibs back
5468 */
5469 local_pfx.fp_len = 24;
5470 fib_table_entry_update_one_path(import_fib_index1,
5471 &local_pfx,
5472 FIB_SOURCE_API,
5473 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07005474 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005475 NULL,
5476 tm->hw[0]->sw_if_index,
5477 ~0, // invalid fib index
5478 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005479 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005480 FIB_ROUTE_PATH_FLAG_NONE);
5481 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5482 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 imported in FIB1");
5483 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5484 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 imported in FIB1");
5485 local_pfx.fp_len = 32;
5486 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5487 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local imported in FIB1");
5488
5489 /*
5490 * add a covering attached next-hop for the interface address, so we have
5491 * a valid adj to find when we check the forwarding tables
5492 */
5493 fib_prefix_t pfx_10_0_0_0_s_8 = {
5494 .fp_len = 8,
5495 .fp_proto = FIB_PROTOCOL_IP4,
5496 .fp_addr = {
5497 /* 10.0.0.0 */
5498 .ip4.as_u32 = clib_host_to_net_u32(0x0a000000),
5499 },
5500 };
5501
5502 fei = fib_table_entry_update_one_path(fib_index,
5503 &pfx_10_0_0_0_s_8,
5504 FIB_SOURCE_API,
5505 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07005506 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005507 &pfx_10_10_10_3_s_32.fp_addr,
5508 tm->hw[0]->sw_if_index,
5509 ~0, // invalid fib index
5510 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005511 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005512 FIB_ROUTE_PATH_FLAG_NONE);
5513 dpo = fib_entry_contribute_ip_forwarding(fei);
5514
5515 /*
5516 * remove the route in the export fib. expect the adj-fibs to be removed
5517 */
5518 local_pfx.fp_len = 24;
5519 fib_table_entry_delete(fib_index,
5520 &local_pfx,
5521 FIB_SOURCE_INTERFACE);
5522
5523 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5524 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "Delete export: ADJ-fib1 removed from FIB1");
5525 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5526 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib2 removed from FIB1");
5527 local_pfx.fp_len = 32;
5528 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5529 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "local removed from FIB1");
5530
5531 /*
5532 * the adj-fibs in the export VRF are present in the FIB table,
5533 * but not installed in forwarding, since they have no attached cover.
5534 * Consequently a lookup in the MTRIE gives the adj for the covering
5535 * route 10.0.0.0/8.
5536 */
5537 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
5538 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 in export");
5539
5540 index_t lbi;
5541 lbi = ip4_fib_forwarding_lookup(fib_index, &pfx_10_10_10_1_s_32.fp_addr.ip4);
5542 FIB_TEST(lbi == dpo->dpoi_index,
5543 "10.10.10.1 forwards on \n%U not \n%U",
5544 format_load_balance, lbi, 0,
5545 format_dpo_id, dpo, 0);
5546 lbi = ip4_fib_forwarding_lookup(fib_index, &pfx_10_10_10_2_s_32.fp_addr.ip4);
5547 FIB_TEST(lbi == dpo->dpoi_index,
5548 "10.10.10.2 forwards on %U", format_dpo_id, dpo, 0);
5549 lbi = ip4_fib_forwarding_lookup(fib_index, &pfx_10_10_10_3_s_32.fp_addr.ip4);
5550 FIB_TEST(lbi == dpo->dpoi_index,
5551 "10.10.10.3 forwards on %U", format_dpo_id, dpo, 0);
5552
5553 /*
5554 * add the export prefix back, but not as attached.
5555 * No adj-fibs in export nor import tables
5556 */
5557 local_pfx.fp_len = 24;
5558 fei = fib_table_entry_update_one_path(fib_index,
5559 &local_pfx,
5560 FIB_SOURCE_API,
5561 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07005562 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005563 &pfx_10_10_10_1_s_32.fp_addr,
5564 tm->hw[0]->sw_if_index,
5565 ~0, // invalid fib index
5566 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005567 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005568 FIB_ROUTE_PATH_FLAG_NONE);
5569 dpo = fib_entry_contribute_ip_forwarding(fei);
5570
5571 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
5572 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "non-attached in export: ADJ-fib1 in export");
5573 lbi = ip4_fib_forwarding_lookup(fib_index, &pfx_10_10_10_1_s_32.fp_addr.ip4);
5574 FIB_TEST(lbi == dpo->dpoi_index,
5575 "10.10.10.1 forwards on %U", format_dpo_id, dpo, 0);
5576 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
5577 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 in export");
5578 lbi = ip4_fib_forwarding_lookup(fib_index, &pfx_10_10_10_2_s_32.fp_addr.ip4);
5579 FIB_TEST(lbi == dpo->dpoi_index,
5580 "10.10.10.2 forwards on %U", format_dpo_id, dpo, 0);
5581
5582 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5583 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib1 removed from FIB1");
5584 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5585 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib2 removed from FIB1");
5586 local_pfx.fp_len = 32;
5587 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5588 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "local removed from FIB1");
5589
5590 /*
5591 * modify the export prefix so it is attached. expect all covereds to return
5592 */
5593 local_pfx.fp_len = 24;
5594 fib_table_entry_update_one_path(fib_index,
5595 &local_pfx,
5596 FIB_SOURCE_API,
5597 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07005598 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005599 NULL,
5600 tm->hw[0]->sw_if_index,
5601 ~0, // invalid fib index
5602 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005603 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005604 FIB_ROUTE_PATH_FLAG_NONE);
5605
5606 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
5607 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 reinstalled in export");
5608 dpo = fib_entry_contribute_ip_forwarding(fei);
5609 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
5610 "Adj-fib1 is not drop in export");
5611 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_2_s_32);
5612 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 reinstalled in export");
5613 local_pfx.fp_len = 32;
5614 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5615 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local reinstalled in export");
5616 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5617 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached in export: ADJ-fib1 imported");
5618 dpo = fib_entry_contribute_ip_forwarding(fei);
5619 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
5620 "Adj-fib1 is not drop in export");
5621 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5622 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 imported");
5623 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5624 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 imported");
5625 local_pfx.fp_len = 32;
5626 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5627 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local imported");
5628
5629 /*
5630 * modify the export prefix so connected. no change.
5631 */
5632 local_pfx.fp_len = 24;
5633 fib_table_entry_update_one_path(fib_index, &local_pfx,
5634 FIB_SOURCE_INTERFACE,
5635 (FIB_ENTRY_FLAG_CONNECTED |
5636 FIB_ENTRY_FLAG_ATTACHED),
Neale Rannsda78f952017-05-24 09:15:43 -07005637 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005638 NULL,
5639 tm->hw[0]->sw_if_index,
5640 ~0,
5641 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005642 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005643 FIB_ROUTE_PATH_FLAG_NONE);
5644
5645 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
5646 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 reinstalled in export");
5647 dpo = fib_entry_contribute_ip_forwarding(fei);
5648 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
5649 "Adj-fib1 is not drop in export");
5650 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_2_s_32);
5651 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 reinstalled in export");
5652 local_pfx.fp_len = 32;
5653 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5654 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local reinstalled in export");
5655 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5656 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached in export: ADJ-fib1 imported");
5657 dpo = fib_entry_contribute_ip_forwarding(fei);
5658 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
5659 "Adj-fib1 is not drop in export");
5660 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5661 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 imported");
5662 local_pfx.fp_len = 32;
5663 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5664 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local imported");
5665
5666 /*
5667 * CLEANUP
5668 */
5669 fib_table_entry_delete(fib_index,
5670 &pfx_10_0_0_0_s_8,
5671 FIB_SOURCE_API);
5672 fib_table_entry_delete(fib_index,
5673 &pfx_10_10_10_1_s_32,
5674 FIB_SOURCE_ADJ);
5675 fib_table_entry_delete(fib_index,
5676 &pfx_10_10_10_2_s_32,
5677 FIB_SOURCE_ADJ);
5678 local_pfx.fp_len = 32;
5679 fib_table_entry_delete(fib_index,
5680 &local_pfx,
5681 FIB_SOURCE_INTERFACE);
5682 local_pfx.fp_len = 24;
5683 fib_table_entry_delete(fib_index,
5684 &local_pfx,
5685 FIB_SOURCE_API);
5686 fib_table_entry_delete(fib_index,
5687 &local_pfx,
5688 FIB_SOURCE_INTERFACE);
5689 local_pfx.fp_len = 24;
5690 fib_table_entry_delete(import_fib_index1,
5691 &local_pfx,
5692 FIB_SOURCE_API);
5693
Neale Ranns15002542017-09-10 04:39:11 -07005694 fib_table_unlock(import_fib_index1, FIB_PROTOCOL_IP4, FIB_SOURCE_CLI);
5695 fib_table_unlock(import_fib_index2, FIB_PROTOCOL_IP4, FIB_SOURCE_CLI);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005696
5697 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
5698 adj_nbr_db_size());
Neale Ranns0ebe8d72016-12-08 19:48:11 +00005699
5700 return (0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005701}
5702
Neale Ranns57b58602017-07-15 07:37:25 -07005703/*
5704 * Test Path Preference
5705 */
5706static int
5707fib_test_pref (void)
5708{
5709 test_main_t *tm = &test_main;
5710
5711 const fib_prefix_t pfx_1_1_1_1_s_32 = {
5712 .fp_len = 32,
5713 .fp_proto = FIB_PROTOCOL_IP4,
5714 .fp_addr = {
5715 .ip4 = {
5716 .as_u32 = clib_host_to_net_u32(0x01010101),
5717 },
5718 },
5719 };
5720
5721 /*
5722 * 2 high, 2 medium and 2 low preference non-recursive paths
5723 */
5724 fib_route_path_t nr_path_hi_1 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005725 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005726 .frp_sw_if_index = tm->hw[0]->sw_if_index,
5727 .frp_fib_index = ~0,
5728 .frp_weight = 1,
5729 .frp_preference = 0,
5730 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5731 .frp_addr = {
5732 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
5733 },
5734 };
5735 fib_route_path_t nr_path_hi_2 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005736 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005737 .frp_sw_if_index = tm->hw[0]->sw_if_index,
5738 .frp_fib_index = ~0,
5739 .frp_weight = 1,
5740 .frp_preference = 0,
5741 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5742 .frp_addr = {
5743 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02),
5744 },
5745 };
5746 fib_route_path_t nr_path_med_1 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005747 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005748 .frp_sw_if_index = tm->hw[1]->sw_if_index,
5749 .frp_fib_index = ~0,
5750 .frp_weight = 1,
5751 .frp_preference = 1,
5752 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5753 .frp_addr = {
5754 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0c01),
5755 },
5756 };
5757 fib_route_path_t nr_path_med_2 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005758 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005759 .frp_sw_if_index = tm->hw[1]->sw_if_index,
5760 .frp_fib_index = ~0,
5761 .frp_weight = 1,
5762 .frp_preference = 1,
5763 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5764 .frp_addr = {
5765 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0c01),
5766 },
5767 };
5768 fib_route_path_t nr_path_low_1 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005769 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005770 .frp_sw_if_index = tm->hw[2]->sw_if_index,
5771 .frp_fib_index = ~0,
5772 .frp_weight = 1,
5773 .frp_preference = 2,
5774 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5775 .frp_addr = {
5776 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0b01),
5777 },
5778 };
5779 fib_route_path_t nr_path_low_2 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005780 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005781 .frp_sw_if_index = tm->hw[2]->sw_if_index,
5782 .frp_fib_index = ~0,
5783 .frp_weight = 1,
5784 .frp_preference = 2,
5785 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5786 .frp_addr = {
5787 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0b02),
5788 },
5789 };
5790 fib_route_path_t *nr_paths = NULL;
5791
5792 vec_add1(nr_paths, nr_path_hi_1);
5793 vec_add1(nr_paths, nr_path_hi_2);
5794 vec_add1(nr_paths, nr_path_med_1);
5795 vec_add1(nr_paths, nr_path_med_2);
5796 vec_add1(nr_paths, nr_path_low_1);
5797 vec_add1(nr_paths, nr_path_low_2);
5798
5799 adj_index_t ai_hi_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5800 VNET_LINK_IP4,
5801 &nr_path_hi_1.frp_addr,
5802 nr_path_hi_1.frp_sw_if_index);
5803 adj_index_t ai_hi_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5804 VNET_LINK_IP4,
5805 &nr_path_hi_2.frp_addr,
5806 nr_path_hi_2.frp_sw_if_index);
5807 adj_index_t ai_med_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5808 VNET_LINK_IP4,
5809 &nr_path_med_1.frp_addr,
5810 nr_path_med_1.frp_sw_if_index);
5811 adj_index_t ai_med_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5812 VNET_LINK_IP4,
5813 &nr_path_med_2.frp_addr,
5814 nr_path_med_2.frp_sw_if_index);
5815 adj_index_t ai_low_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5816 VNET_LINK_IP4,
5817 &nr_path_low_1.frp_addr,
5818 nr_path_low_1.frp_sw_if_index);
5819 adj_index_t ai_low_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5820 VNET_LINK_IP4,
5821 &nr_path_low_2.frp_addr,
5822 nr_path_low_2.frp_sw_if_index);
5823
5824 fib_test_lb_bucket_t ip_hi_1 = {
5825 .type = FT_LB_ADJ,
5826 .adj = {
5827 .adj = ai_hi_1,
5828 },
5829 };
5830 fib_test_lb_bucket_t ip_hi_2 = {
5831 .type = FT_LB_ADJ,
5832 .adj = {
5833 .adj = ai_hi_2,
5834 },
5835 };
5836 fib_test_lb_bucket_t ip_med_1 = {
5837 .type = FT_LB_ADJ,
5838 .adj = {
5839 .adj = ai_med_1,
5840 },
5841 };
5842 fib_test_lb_bucket_t ip_med_2 = {
5843 .type = FT_LB_ADJ,
5844 .adj = {
5845 .adj = ai_med_2,
5846 },
5847 };
5848 fib_test_lb_bucket_t ip_low_1 = {
5849 .type = FT_LB_ADJ,
5850 .adj = {
5851 .adj = ai_low_1,
5852 },
5853 };
5854 fib_test_lb_bucket_t ip_low_2 = {
5855 .type = FT_LB_ADJ,
5856 .adj = {
5857 .adj = ai_low_2,
5858 },
5859 };
5860
5861 fib_node_index_t fei;
5862
5863 fei = fib_table_entry_path_add2(0,
5864 &pfx_1_1_1_1_s_32,
5865 FIB_SOURCE_API,
5866 FIB_ENTRY_FLAG_NONE,
5867 nr_paths);
5868
5869 FIB_TEST(fib_test_validate_entry(fei,
5870 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5871 2,
5872 &ip_hi_1,
5873 &ip_hi_2),
5874 "1.1.1.1/32 via high preference paths");
5875
5876 /*
5877 * bring down the interface on which the high preference path lie
5878 */
5879 vnet_sw_interface_set_flags(vnet_get_main(),
5880 tm->hw[0]->sw_if_index,
5881 0);
5882
5883 FIB_TEST(fib_test_validate_entry(fei,
5884 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5885 2,
5886 &ip_med_1,
5887 &ip_med_2),
5888 "1.1.1.1/32 via medium preference paths");
5889
5890 /*
5891 * bring down the interface on which the medium preference path lie
5892 */
5893 vnet_sw_interface_set_flags(vnet_get_main(),
5894 tm->hw[1]->sw_if_index,
5895 0);
5896
5897 FIB_TEST(fib_test_validate_entry(fei,
5898 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5899 2,
5900 &ip_low_1,
5901 &ip_low_2),
5902 "1.1.1.1/32 via low preference paths");
5903
5904 /*
5905 * bring up the interface on which the high preference path lie
5906 */
5907 vnet_sw_interface_set_flags(vnet_get_main(),
5908 tm->hw[0]->sw_if_index,
5909 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
5910
5911 FIB_TEST(fib_test_validate_entry(fei,
5912 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5913 2,
5914 &ip_hi_1,
5915 &ip_hi_2),
5916 "1.1.1.1/32 via high preference paths");
5917
5918 /*
5919 * bring up the interface on which the medium preference path lie
5920 */
5921 vnet_sw_interface_set_flags(vnet_get_main(),
5922 tm->hw[1]->sw_if_index,
5923 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
5924
5925 FIB_TEST(fib_test_validate_entry(fei,
5926 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5927 2,
5928 &ip_hi_1,
5929 &ip_hi_2),
5930 "1.1.1.1/32 via high preference paths");
5931
5932 dpo_id_t ip_1_1_1_1 = DPO_INVALID;
5933 fib_entry_contribute_forwarding(fei,
5934 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5935 &ip_1_1_1_1);
5936
5937 /*
5938 * 3 recursive paths of different preference
5939 */
5940 const fib_prefix_t pfx_1_1_1_2_s_32 = {
5941 .fp_len = 32,
5942 .fp_proto = FIB_PROTOCOL_IP4,
5943 .fp_addr = {
5944 .ip4 = {
5945 .as_u32 = clib_host_to_net_u32(0x01010102),
5946 },
5947 },
5948 };
5949 const fib_prefix_t pfx_1_1_1_3_s_32 = {
5950 .fp_len = 32,
5951 .fp_proto = FIB_PROTOCOL_IP4,
5952 .fp_addr = {
5953 .ip4 = {
5954 .as_u32 = clib_host_to_net_u32(0x01010103),
5955 },
5956 },
5957 };
5958 fei = fib_table_entry_path_add2(0,
5959 &pfx_1_1_1_2_s_32,
5960 FIB_SOURCE_API,
5961 FIB_ENTRY_FLAG_NONE,
5962 nr_paths);
5963 dpo_id_t ip_1_1_1_2 = DPO_INVALID;
5964 fib_entry_contribute_forwarding(fei,
5965 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5966 &ip_1_1_1_2);
5967 fei = fib_table_entry_path_add2(0,
5968 &pfx_1_1_1_3_s_32,
5969 FIB_SOURCE_API,
5970 FIB_ENTRY_FLAG_NONE,
5971 nr_paths);
5972 dpo_id_t ip_1_1_1_3 = DPO_INVALID;
5973 fib_entry_contribute_forwarding(fei,
5974 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5975 &ip_1_1_1_3);
5976
5977 fib_test_lb_bucket_t ip_o_1_1_1_1 = {
5978 .type = FT_LB_O_LB,
5979 .lb = {
5980 .lb = ip_1_1_1_1.dpoi_index,
5981 },
5982 };
5983 fib_test_lb_bucket_t ip_o_1_1_1_2 = {
5984 .type = FT_LB_O_LB,
5985 .lb = {
5986 .lb = ip_1_1_1_2.dpoi_index,
5987 },
5988 };
5989 fib_test_lb_bucket_t ip_o_1_1_1_3 = {
5990 .type = FT_LB_O_LB,
5991 .lb = {
5992 .lb = ip_1_1_1_3.dpoi_index,
5993 },
5994 };
5995 fib_route_path_t r_path_hi = {
Neale Rannsda78f952017-05-24 09:15:43 -07005996 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005997 .frp_sw_if_index = ~0,
5998 .frp_fib_index = 0,
5999 .frp_weight = 1,
6000 .frp_preference = 0,
6001 .frp_flags = FIB_ROUTE_PATH_RESOLVE_VIA_HOST,
6002 .frp_addr = pfx_1_1_1_1_s_32.fp_addr,
6003 };
6004 fib_route_path_t r_path_med = {
Neale Rannsda78f952017-05-24 09:15:43 -07006005 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07006006 .frp_sw_if_index = ~0,
6007 .frp_fib_index = 0,
6008 .frp_weight = 1,
6009 .frp_preference = 10,
6010 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
6011 .frp_addr = pfx_1_1_1_2_s_32.fp_addr,
6012 };
6013 fib_route_path_t r_path_low = {
Neale Rannsda78f952017-05-24 09:15:43 -07006014 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07006015 .frp_sw_if_index = ~0,
6016 .frp_fib_index = 0,
6017 .frp_weight = 1,
Neale Rannsa0a908f2017-08-01 11:40:03 -07006018 .frp_preference = 255,
Neale Ranns57b58602017-07-15 07:37:25 -07006019 .frp_flags = FIB_ROUTE_PATH_RESOLVE_VIA_HOST,
6020 .frp_addr = pfx_1_1_1_3_s_32.fp_addr,
6021 };
6022 fib_route_path_t *r_paths = NULL;
6023
6024 vec_add1(r_paths, r_path_hi);
6025 vec_add1(r_paths, r_path_low);
6026 vec_add1(r_paths, r_path_med);
6027
6028 /*
6029 * add many recursive so we get the LB MAp created
6030 */
6031 #define N_PFXS 64
6032 fib_prefix_t pfx_r[N_PFXS];
Marek Gradzkiaf095512017-08-15 07:38:26 +02006033 unsigned int n_pfxs;
Neale Ranns57b58602017-07-15 07:37:25 -07006034 for (n_pfxs = 0; n_pfxs < N_PFXS; n_pfxs++)
6035 {
6036 pfx_r[n_pfxs].fp_len = 32;
6037 pfx_r[n_pfxs].fp_proto = FIB_PROTOCOL_IP4;
6038 pfx_r[n_pfxs].fp_addr.ip4.as_u32 =
6039 clib_host_to_net_u32(0x02000000 + n_pfxs);
6040
6041 fei = fib_table_entry_path_add2(0,
6042 &pfx_r[n_pfxs],
6043 FIB_SOURCE_API,
6044 FIB_ENTRY_FLAG_NONE,
6045 r_paths);
6046
6047 FIB_TEST(fib_test_validate_entry(fei,
6048 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6049 1,
6050 &ip_o_1_1_1_1),
6051 "recursive via high preference paths");
6052
6053 /*
6054 * withdraw hig pref resolving entry
6055 */
6056 fib_table_entry_delete(0,
6057 &pfx_1_1_1_1_s_32,
6058 FIB_SOURCE_API);
6059
6060 /* suspend so the update walk kicks int */
6061 vlib_process_suspend(vlib_get_main(), 1e-5);
6062
6063 FIB_TEST(fib_test_validate_entry(fei,
6064 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6065 1,
6066 &ip_o_1_1_1_2),
6067 "recursive via medium preference paths");
6068
6069 /*
6070 * withdraw medium pref resolving entry
6071 */
6072 fib_table_entry_delete(0,
6073 &pfx_1_1_1_2_s_32,
6074 FIB_SOURCE_API);
6075
6076 /* suspend so the update walk kicks int */
6077 vlib_process_suspend(vlib_get_main(), 1e-5);
6078
6079 FIB_TEST(fib_test_validate_entry(fei,
6080 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6081 1,
6082 &ip_o_1_1_1_3),
6083 "recursive via low preference paths");
6084
6085 /*
6086 * add back paths for next iteration
6087 */
6088 fei = fib_table_entry_update(0,
6089 &pfx_1_1_1_2_s_32,
6090 FIB_SOURCE_API,
6091 FIB_ENTRY_FLAG_NONE,
6092 nr_paths);
6093 fei = fib_table_entry_update(0,
6094 &pfx_1_1_1_1_s_32,
6095 FIB_SOURCE_API,
6096 FIB_ENTRY_FLAG_NONE,
6097 nr_paths);
6098
6099 /* suspend so the update walk kicks int */
6100 vlib_process_suspend(vlib_get_main(), 1e-5);
6101
6102 fei = fib_table_lookup_exact_match(0, &pfx_r[n_pfxs]);
6103 FIB_TEST(fib_test_validate_entry(fei,
6104 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6105 1,
6106 &ip_o_1_1_1_1),
6107 "recursive via high preference paths");
6108 }
6109
6110
6111 fib_table_entry_delete(0,
6112 &pfx_1_1_1_1_s_32,
6113 FIB_SOURCE_API);
6114
6115 /* suspend so the update walk kicks int */
6116 vlib_process_suspend(vlib_get_main(), 1e-5);
6117
6118 for (n_pfxs = 0; n_pfxs < N_PFXS; n_pfxs++)
6119 {
6120 fei = fib_table_lookup_exact_match(0, &pfx_r[n_pfxs]);
6121
6122 FIB_TEST(fib_test_validate_entry(fei,
6123 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6124 1,
6125 &ip_o_1_1_1_2),
6126 "recursive via medium preference paths");
6127 }
6128 for (n_pfxs = 0; n_pfxs < N_PFXS; n_pfxs++)
6129 {
6130 fib_table_entry_delete(0,
6131 &pfx_r[n_pfxs],
6132 FIB_SOURCE_API);
6133 }
6134
6135 /*
6136 * Cleanup
6137 */
6138 fib_table_entry_delete(0,
6139 &pfx_1_1_1_2_s_32,
6140 FIB_SOURCE_API);
6141 fib_table_entry_delete(0,
6142 &pfx_1_1_1_3_s_32,
6143 FIB_SOURCE_API);
6144
6145 dpo_reset(&ip_1_1_1_1);
6146 dpo_reset(&ip_1_1_1_2);
6147 dpo_reset(&ip_1_1_1_3);
6148 adj_unlock(ai_low_2);
6149 adj_unlock(ai_low_1);
6150 adj_unlock(ai_med_2);
6151 adj_unlock(ai_med_1);
6152 adj_unlock(ai_hi_2);
6153 adj_unlock(ai_hi_1);
6154 return (0);
6155}
Neale Rannsad422ed2016-11-02 14:20:04 +00006156
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006157/*
6158 * Test the recursive route route handling for GRE tunnels
6159 */
Neale Ranns0ebe8d72016-12-08 19:48:11 +00006160static int
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006161fib_test_label (void)
6162{
6163 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;
6164 const u32 fib_index = 0;
6165 test_main_t *tm;
6166 ip4_main_t *im;
Neale Rannsad422ed2016-11-02 14:20:04 +00006167 int lb_count, ii;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006168
6169 lb_count = pool_elts(load_balance_pool);
6170 tm = &test_main;
6171 im = &ip4_main;
6172
6173 /*
6174 * add interface routes. We'll assume this works. It's more rigorously
6175 * tested elsewhere.
6176 */
6177 fib_prefix_t local0_pfx = {
6178 .fp_len = 24,
6179 .fp_proto = FIB_PROTOCOL_IP4,
6180 .fp_addr = {
6181 .ip4 = {
6182 /* 10.10.10.10 */
6183 .as_u32 = clib_host_to_net_u32(0x0a0a0a0a),
6184 },
6185 },
6186 };
6187
6188 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
6189 adj_nbr_db_size());
6190
6191 vec_validate(im->fib_index_by_sw_if_index, tm->hw[0]->sw_if_index);
6192 im->fib_index_by_sw_if_index[tm->hw[0]->sw_if_index] = fib_index;
6193
6194 fib_table_entry_update_one_path(fib_index, &local0_pfx,
6195 FIB_SOURCE_INTERFACE,
6196 (FIB_ENTRY_FLAG_CONNECTED |
6197 FIB_ENTRY_FLAG_ATTACHED),
Neale Rannsda78f952017-05-24 09:15:43 -07006198 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006199 NULL,
6200 tm->hw[0]->sw_if_index,
6201 ~0,
6202 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006203 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006204 FIB_ROUTE_PATH_FLAG_NONE);
6205 fei = fib_table_lookup_exact_match(fib_index, &local0_pfx);
6206 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
6207 "attached interface route present");
6208
6209 local0_pfx.fp_len = 32;
6210 fib_table_entry_update_one_path(fib_index, &local0_pfx,
6211 FIB_SOURCE_INTERFACE,
6212 (FIB_ENTRY_FLAG_CONNECTED |
6213 FIB_ENTRY_FLAG_LOCAL),
Neale Rannsda78f952017-05-24 09:15:43 -07006214 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006215 NULL,
6216 tm->hw[0]->sw_if_index,
6217 ~0, // invalid fib index
6218 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006219 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006220 FIB_ROUTE_PATH_FLAG_NONE);
6221 fei = fib_table_lookup_exact_match(fib_index, &local0_pfx);
6222
6223 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
6224 "local interface route present");
6225
6226 fib_prefix_t local1_pfx = {
6227 .fp_len = 24,
6228 .fp_proto = FIB_PROTOCOL_IP4,
6229 .fp_addr = {
6230 .ip4 = {
6231 /* 10.10.11.10 */
6232 .as_u32 = clib_host_to_net_u32(0x0a0a0b0a),
6233 },
6234 },
6235 };
6236
6237 vec_validate(im->fib_index_by_sw_if_index, tm->hw[1]->sw_if_index);
6238 im->fib_index_by_sw_if_index[tm->hw[1]->sw_if_index] = fib_index;
6239
6240 fib_table_entry_update_one_path(fib_index, &local1_pfx,
6241 FIB_SOURCE_INTERFACE,
6242 (FIB_ENTRY_FLAG_CONNECTED |
6243 FIB_ENTRY_FLAG_ATTACHED),
Neale Rannsda78f952017-05-24 09:15:43 -07006244 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006245 NULL,
6246 tm->hw[1]->sw_if_index,
6247 ~0,
6248 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006249 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006250 FIB_ROUTE_PATH_FLAG_NONE);
6251 fei = fib_table_lookup_exact_match(fib_index, &local1_pfx);
6252 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
6253 "attached interface route present");
6254
6255 local1_pfx.fp_len = 32;
6256 fib_table_entry_update_one_path(fib_index, &local1_pfx,
6257 FIB_SOURCE_INTERFACE,
6258 (FIB_ENTRY_FLAG_CONNECTED |
6259 FIB_ENTRY_FLAG_LOCAL),
Neale Rannsda78f952017-05-24 09:15:43 -07006260 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006261 NULL,
6262 tm->hw[1]->sw_if_index,
6263 ~0, // invalid fib index
6264 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006265 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006266 FIB_ROUTE_PATH_FLAG_NONE);
6267 fei = fib_table_lookup_exact_match(fib_index, &local1_pfx);
6268
6269 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
6270 "local interface route present");
6271
6272 ip46_address_t nh_10_10_10_1 = {
6273 .ip4 = {
6274 .as_u32 = clib_host_to_net_u32(0x0a0a0a01),
6275 },
6276 };
6277 ip46_address_t nh_10_10_11_1 = {
6278 .ip4 = {
6279 .as_u32 = clib_host_to_net_u32(0x0a0a0b01),
6280 },
6281 };
6282 ip46_address_t nh_10_10_11_2 = {
6283 .ip4 = {
6284 .as_u32 = clib_host_to_net_u32(0x0a0a0b02),
6285 },
6286 };
6287
6288 ai_v4_10_10_11_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01006289 VNET_LINK_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006290 &nh_10_10_11_1,
6291 tm->hw[1]->sw_if_index);
6292 ai_v4_10_10_11_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01006293 VNET_LINK_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006294 &nh_10_10_11_2,
6295 tm->hw[1]->sw_if_index);
6296 ai_mpls_10_10_10_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01006297 VNET_LINK_MPLS,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006298 &nh_10_10_10_1,
6299 tm->hw[0]->sw_if_index);
6300 ai_mpls_10_10_11_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01006301 VNET_LINK_MPLS,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006302 &nh_10_10_11_2,
6303 tm->hw[1]->sw_if_index);
6304 ai_mpls_10_10_11_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01006305 VNET_LINK_MPLS,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006306 &nh_10_10_11_1,
6307 tm->hw[1]->sw_if_index);
6308
6309 /*
6310 * Add an etry with one path with a real out-going label
6311 */
6312 fib_prefix_t pfx_1_1_1_1_s_32 = {
6313 .fp_len = 32,
6314 .fp_proto = FIB_PROTOCOL_IP4,
6315 .fp_addr = {
6316 .ip4.as_u32 = clib_host_to_net_u32(0x01010101),
6317 },
6318 };
6319 fib_test_lb_bucket_t l99_eos_o_10_10_10_1 = {
6320 .type = FT_LB_LABEL_O_ADJ,
6321 .label_o_adj = {
6322 .adj = ai_mpls_10_10_10_1,
6323 .label = 99,
6324 .eos = MPLS_EOS,
6325 },
6326 };
6327 fib_test_lb_bucket_t l99_neos_o_10_10_10_1 = {
6328 .type = FT_LB_LABEL_O_ADJ,
6329 .label_o_adj = {
6330 .adj = ai_mpls_10_10_10_1,
6331 .label = 99,
6332 .eos = MPLS_NON_EOS,
6333 },
6334 };
Neale Rannsad422ed2016-11-02 14:20:04 +00006335 mpls_label_t *l99 = NULL;
6336 vec_add1(l99, 99);
6337
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006338 fib_table_entry_update_one_path(fib_index,
6339 &pfx_1_1_1_1_s_32,
6340 FIB_SOURCE_API,
6341 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07006342 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006343 &nh_10_10_10_1,
6344 tm->hw[0]->sw_if_index,
6345 ~0, // invalid fib index
6346 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006347 l99,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006348 FIB_ROUTE_PATH_FLAG_NONE);
6349
6350 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
6351 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "1.1.1.1/32 created");
6352
6353 FIB_TEST(fib_test_validate_entry(fei,
6354 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6355 1,
6356 &l99_eos_o_10_10_10_1),
6357 "1.1.1.1/32 LB 1 bucket via label 99 over 10.10.10.1");
6358
6359 /*
6360 * add a path with an implicit NULL label
6361 */
6362 fib_test_lb_bucket_t a_o_10_10_11_1 = {
6363 .type = FT_LB_ADJ,
6364 .adj = {
6365 .adj = ai_v4_10_10_11_1,
6366 },
6367 };
6368 fib_test_lb_bucket_t a_mpls_o_10_10_11_1 = {
6369 .type = FT_LB_ADJ,
6370 .adj = {
6371 .adj = ai_mpls_10_10_11_1,
6372 },
6373 };
Neale Rannsad422ed2016-11-02 14:20:04 +00006374 mpls_label_t *l_imp_null = NULL;
6375 vec_add1(l_imp_null, MPLS_IETF_IMPLICIT_NULL_LABEL);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006376
6377 fei = fib_table_entry_path_add(fib_index,
6378 &pfx_1_1_1_1_s_32,
6379 FIB_SOURCE_API,
6380 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07006381 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006382 &nh_10_10_11_1,
6383 tm->hw[1]->sw_if_index,
6384 ~0, // invalid fib index
6385 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006386 l_imp_null,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006387 FIB_ROUTE_PATH_FLAG_NONE);
6388
6389 FIB_TEST(fib_test_validate_entry(fei,
6390 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6391 2,
6392 &l99_eos_o_10_10_10_1,
6393 &a_o_10_10_11_1),
6394 "1.1.1.1/32 LB 2 buckets via: "
6395 "label 99 over 10.10.10.1, "
6396 "adj over 10.10.11.1");
6397
6398 /*
6399 * assign the route a local label
6400 */
6401 fib_table_entry_local_label_add(fib_index,
6402 &pfx_1_1_1_1_s_32,
6403 24001);
6404
6405 fib_prefix_t pfx_24001_eos = {
6406 .fp_proto = FIB_PROTOCOL_MPLS,
6407 .fp_label = 24001,
6408 .fp_eos = MPLS_EOS,
6409 };
6410 fib_prefix_t pfx_24001_neos = {
6411 .fp_proto = FIB_PROTOCOL_MPLS,
6412 .fp_label = 24001,
6413 .fp_eos = MPLS_NON_EOS,
6414 };
Neale Ranns62fe07c2017-10-31 12:28:22 -07006415 fib_test_lb_bucket_t disp_o_10_10_11_1 = {
6416 .type = FT_LB_MPLS_DISP_O_ADJ,
6417 .adj = {
6418 .adj = ai_v4_10_10_11_1,
6419 },
6420 };
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006421
6422 /*
6423 * The EOS entry should link to both the paths,
6424 * and use an ip adj for the imp-null
6425 * The NON-EOS entry should link to both the paths,
6426 * and use an mpls adj for the imp-null
6427 */
6428 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6429 &pfx_24001_eos);
6430 FIB_TEST(fib_test_validate_entry(fei,
6431 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6432 2,
6433 &l99_eos_o_10_10_10_1,
Neale Ranns62fe07c2017-10-31 12:28:22 -07006434 &disp_o_10_10_11_1),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006435 "24001/eos LB 2 buckets via: "
6436 "label 99 over 10.10.10.1, "
Neale Ranns62fe07c2017-10-31 12:28:22 -07006437 "mpls disp adj over 10.10.11.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006438
6439
6440 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6441 &pfx_24001_neos);
6442 FIB_TEST(fib_test_validate_entry(fei,
6443 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6444 2,
6445 &l99_neos_o_10_10_10_1,
6446 &a_mpls_o_10_10_11_1),
6447 "24001/neos LB 1 bucket via: "
6448 "label 99 over 10.10.10.1 ",
6449 "mpls-adj via 10.10.11.1");
6450
6451 /*
6452 * add an unlabelled path, this is excluded from the neos chains,
6453 */
6454 fib_test_lb_bucket_t adj_o_10_10_11_2 = {
6455 .type = FT_LB_ADJ,
6456 .adj = {
6457 .adj = ai_v4_10_10_11_2,
6458 },
6459 };
Neale Ranns62fe07c2017-10-31 12:28:22 -07006460 fib_test_lb_bucket_t disp_o_10_10_11_2 = {
6461 .type = FT_LB_MPLS_DISP_O_ADJ,
6462 .adj = {
6463 .adj = ai_v4_10_10_11_2,
6464 },
6465 };
6466
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006467
6468 fei = fib_table_entry_path_add(fib_index,
6469 &pfx_1_1_1_1_s_32,
6470 FIB_SOURCE_API,
6471 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07006472 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006473 &nh_10_10_11_2,
6474 tm->hw[1]->sw_if_index,
6475 ~0, // invalid fib index
6476 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006477 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006478 FIB_ROUTE_PATH_FLAG_NONE);
6479
6480 FIB_TEST(fib_test_validate_entry(fei,
6481 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6482 16, // 3 choices spread over 16 buckets
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 &l99_eos_o_10_10_10_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 &a_o_10_10_11_1,
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 &adj_o_10_10_11_2),
6499 "1.1.1.1/32 LB 16 buckets via: "
6500 "label 99 over 10.10.10.1, "
6501 "adj over 10.10.11.1",
6502 "adj over 10.10.11.2");
6503
6504 /*
6505 * get and lock a reference to the non-eos of the via entry 1.1.1.1/32
6506 */
Neale Ranns948e00f2016-10-20 13:39:34 +01006507 dpo_id_t non_eos_1_1_1_1 = DPO_INVALID;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006508 fib_entry_contribute_forwarding(fei,
6509 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6510 &non_eos_1_1_1_1);
6511
6512 /*
6513 * n-eos has only the 2 labelled paths
6514 */
6515 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6516 &pfx_24001_neos);
6517
6518 FIB_TEST(fib_test_validate_entry(fei,
6519 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6520 2,
6521 &l99_neos_o_10_10_10_1,
6522 &a_mpls_o_10_10_11_1),
6523 "24001/neos LB 2 buckets via: "
6524 "label 99 over 10.10.10.1, "
6525 "adj-mpls over 10.10.11.2");
6526
6527 /*
6528 * A labelled recursive
6529 */
6530 fib_prefix_t pfx_2_2_2_2_s_32 = {
6531 .fp_len = 32,
6532 .fp_proto = FIB_PROTOCOL_IP4,
6533 .fp_addr = {
6534 .ip4.as_u32 = clib_host_to_net_u32(0x02020202),
6535 },
6536 };
6537 fib_test_lb_bucket_t l1600_eos_o_1_1_1_1 = {
6538 .type = FT_LB_LABEL_O_LB,
6539 .label_o_lb = {
6540 .lb = non_eos_1_1_1_1.dpoi_index,
6541 .label = 1600,
6542 .eos = MPLS_EOS,
6543 },
6544 };
Neale Rannsad422ed2016-11-02 14:20:04 +00006545 mpls_label_t *l1600 = NULL;
6546 vec_add1(l1600, 1600);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006547
6548 fib_table_entry_update_one_path(fib_index,
6549 &pfx_2_2_2_2_s_32,
6550 FIB_SOURCE_API,
6551 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07006552 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006553 &pfx_1_1_1_1_s_32.fp_addr,
6554 ~0,
6555 fib_index,
6556 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006557 l1600,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006558 FIB_ROUTE_PATH_FLAG_NONE);
6559
6560 fei = fib_table_lookup(fib_index, &pfx_2_2_2_2_s_32);
6561 FIB_TEST(fib_test_validate_entry(fei,
6562 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6563 1,
6564 &l1600_eos_o_1_1_1_1),
6565 "2.2.2.2.2/32 LB 1 buckets via: "
6566 "label 1600 over 1.1.1.1");
6567
Neale Ranns948e00f2016-10-20 13:39:34 +01006568 dpo_id_t dpo_44 = DPO_INVALID;
Neale Ranns3ee44042016-10-03 13:05:48 +01006569 index_t urpfi;
6570
6571 fib_entry_contribute_forwarding(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, &dpo_44);
6572 urpfi = load_balance_get_urpf(dpo_44.dpoi_index);
6573
6574 FIB_TEST(fib_urpf_check(urpfi, tm->hw[0]->sw_if_index),
6575 "uRPF check for 2.2.2.2/32 on %d OK",
6576 tm->hw[0]->sw_if_index);
6577 FIB_TEST(fib_urpf_check(urpfi, tm->hw[1]->sw_if_index),
6578 "uRPF check for 2.2.2.2/32 on %d OK",
6579 tm->hw[1]->sw_if_index);
6580 FIB_TEST(!fib_urpf_check(urpfi, 99),
6581 "uRPF check for 2.2.2.2/32 on 99 not-OK",
6582 99);
6583
6584 fib_entry_contribute_forwarding(fei, FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS, &dpo_44);
6585 FIB_TEST(urpfi == load_balance_get_urpf(dpo_44.dpoi_index),
6586 "Shared uRPF on IP and non-EOS chain");
6587
6588 dpo_reset(&dpo_44);
6589
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006590 /*
6591 * we are holding a lock on the non-eos LB of the via-entry.
6592 * do a PIC-core failover by shutting the link of the via-entry.
6593 *
6594 * shut down the link with the valid label
6595 */
6596 vnet_sw_interface_set_flags(vnet_get_main(),
6597 tm->hw[0]->sw_if_index,
6598 0);
6599
6600 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
6601 FIB_TEST(fib_test_validate_entry(fei,
6602 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6603 2,
6604 &a_o_10_10_11_1,
6605 &adj_o_10_10_11_2),
6606 "1.1.1.1/32 LB 2 buckets via: "
6607 "adj over 10.10.11.1, ",
6608 "adj-v4 over 10.10.11.2");
6609
6610 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6611 &pfx_24001_eos);
6612 FIB_TEST(fib_test_validate_entry(fei,
6613 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6614 2,
Neale Ranns62fe07c2017-10-31 12:28:22 -07006615 &disp_o_10_10_11_1,
6616 &disp_o_10_10_11_2),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006617 "24001/eos LB 2 buckets via: "
Neale Ranns62fe07c2017-10-31 12:28:22 -07006618 "mpls-disp adj over 10.10.11.1, ",
6619 "mpls-disp adj-v4 over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006620
6621 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6622 &pfx_24001_neos);
6623 FIB_TEST(fib_test_validate_entry(fei,
6624 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6625 1,
6626 &a_mpls_o_10_10_11_1),
6627 "24001/neos LB 1 buckets via: "
6628 "adj-mpls over 10.10.11.2");
6629
6630 /*
6631 * test that the pre-failover load-balance has been in-place
6632 * modified
6633 */
Neale Ranns948e00f2016-10-20 13:39:34 +01006634 dpo_id_t current = DPO_INVALID;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006635 fib_entry_contribute_forwarding(fei,
6636 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6637 &current);
6638
6639 FIB_TEST(!dpo_cmp(&non_eos_1_1_1_1,
6640 &current),
6641 "PIC-core LB inplace modified %U %U",
6642 format_dpo_id, &non_eos_1_1_1_1, 0,
6643 format_dpo_id, &current, 0);
6644
6645 dpo_reset(&non_eos_1_1_1_1);
6646 dpo_reset(&current);
6647
6648 /*
6649 * no-shut the link with the valid label
6650 */
6651 vnet_sw_interface_set_flags(vnet_get_main(),
6652 tm->hw[0]->sw_if_index,
6653 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
6654
6655 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
6656 FIB_TEST(fib_test_validate_entry(fei,
6657 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6658 16, // 3 choices spread over 16 buckets
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 &l99_eos_o_10_10_10_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 &a_o_10_10_11_1,
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 &adj_o_10_10_11_2),
6675 "1.1.1.1/32 LB 16 buckets via: "
6676 "label 99 over 10.10.10.1, "
6677 "adj over 10.10.11.1",
6678 "adj-v4 over 10.10.11.2");
6679
6680
6681 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6682 &pfx_24001_eos);
6683 FIB_TEST(fib_test_validate_entry(fei,
6684 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6685 16, // 3 choices spread over 16 buckets
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,
6691 &l99_eos_o_10_10_10_1,
Neale Ranns62fe07c2017-10-31 12:28:22 -07006692 &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_1,
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,
6701 &disp_o_10_10_11_2),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006702 "24001/eos LB 16 buckets via: "
6703 "label 99 over 10.10.10.1, "
Neale Ranns62fe07c2017-10-31 12:28:22 -07006704 "MPLS disp adj over 10.10.11.1",
6705 "MPLS disp adj-v4 over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006706
6707 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6708 &pfx_24001_neos);
6709 FIB_TEST(fib_test_validate_entry(fei,
6710 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6711 2,
6712 &l99_neos_o_10_10_10_1,
6713 &a_mpls_o_10_10_11_1),
6714 "24001/neos LB 2 buckets via: "
6715 "label 99 over 10.10.10.1, "
6716 "adj-mpls over 10.10.11.2");
6717
6718 /*
6719 * remove the first path with the valid label
6720 */
6721 fib_table_entry_path_remove(fib_index,
6722 &pfx_1_1_1_1_s_32,
6723 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07006724 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006725 &nh_10_10_10_1,
6726 tm->hw[0]->sw_if_index,
6727 ~0, // invalid fib index
6728 1,
6729 FIB_ROUTE_PATH_FLAG_NONE);
6730
6731 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
6732 FIB_TEST(fib_test_validate_entry(fei,
6733 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6734 2,
6735 &a_o_10_10_11_1,
6736 &adj_o_10_10_11_2),
6737 "1.1.1.1/32 LB 2 buckets via: "
Neale Rannsa3af3372017-03-28 03:49:52 -07006738 "adj over 10.10.11.1, "
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006739 "adj-v4 over 10.10.11.2");
6740
6741 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6742 &pfx_24001_eos);
6743 FIB_TEST(fib_test_validate_entry(fei,
6744 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6745 2,
Neale Ranns62fe07c2017-10-31 12:28:22 -07006746 &disp_o_10_10_11_1,
6747 &disp_o_10_10_11_2),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006748 "24001/eos LB 2 buckets via: "
Neale Ranns62fe07c2017-10-31 12:28:22 -07006749 "MPLS disp adj over 10.10.11.1, "
6750 "MPLS disp adj-v4 over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006751
6752 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6753 &pfx_24001_neos);
6754
6755 FIB_TEST(fib_test_validate_entry(fei,
6756 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6757 1,
6758 &a_mpls_o_10_10_11_1),
6759 "24001/neos LB 1 buckets via: "
6760 "adj-mpls over 10.10.11.2");
6761
6762 /*
6763 * remove the other path with a valid label
6764 */
6765 fib_test_lb_bucket_t bucket_drop = {
Neale Rannsd792d9c2017-10-21 10:53:20 -07006766 .type = FT_LB_DROP,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006767 };
Neale Rannsf12a83f2017-04-18 09:09:40 -07006768 fib_test_lb_bucket_t mpls_bucket_drop = {
Neale Rannsd792d9c2017-10-21 10:53:20 -07006769 .type = FT_LB_DROP,
Neale Rannsf12a83f2017-04-18 09:09:40 -07006770 .special = {
6771 .adj = DPO_PROTO_MPLS,
6772 },
6773 };
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006774
6775 fib_table_entry_path_remove(fib_index,
6776 &pfx_1_1_1_1_s_32,
6777 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07006778 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006779 &nh_10_10_11_1,
6780 tm->hw[1]->sw_if_index,
6781 ~0, // invalid fib index
6782 1,
6783 FIB_ROUTE_PATH_FLAG_NONE);
6784
6785 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
6786 FIB_TEST(fib_test_validate_entry(fei,
6787 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6788 1,
6789 &adj_o_10_10_11_2),
6790 "1.1.1.1/32 LB 1 buckets via: "
6791 "adj over 10.10.11.2");
6792
6793 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6794 &pfx_24001_eos);
6795 FIB_TEST(fib_test_validate_entry(fei,
6796 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6797 1,
Neale Ranns62fe07c2017-10-31 12:28:22 -07006798 &disp_o_10_10_11_2),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006799 "24001/eos LB 1 buckets via: "
Neale Ranns62fe07c2017-10-31 12:28:22 -07006800 "MPLS disp adj over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006801
6802 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6803 &pfx_24001_neos);
6804 FIB_TEST(fib_test_validate_entry(fei,
6805 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
Neale Rannsf12a83f2017-04-18 09:09:40 -07006806 1,
6807 &mpls_bucket_drop),
6808 "24001/neos LB 1 buckets via: DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006809
6810 /*
6811 * add back the path with the valid label
6812 */
Neale Rannsad422ed2016-11-02 14:20:04 +00006813 l99 = NULL;
6814 vec_add1(l99, 99);
6815
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006816 fib_table_entry_path_add(fib_index,
6817 &pfx_1_1_1_1_s_32,
6818 FIB_SOURCE_API,
6819 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07006820 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006821 &nh_10_10_10_1,
6822 tm->hw[0]->sw_if_index,
6823 ~0, // invalid fib index
6824 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006825 l99,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006826 FIB_ROUTE_PATH_FLAG_NONE);
6827
6828 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
6829 FIB_TEST(fib_test_validate_entry(fei,
6830 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6831 2,
6832 &l99_eos_o_10_10_10_1,
6833 &adj_o_10_10_11_2),
6834 "1.1.1.1/32 LB 2 buckets via: "
6835 "label 99 over 10.10.10.1, "
6836 "adj over 10.10.11.2");
6837
6838 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6839 &pfx_24001_eos);
6840 FIB_TEST(fib_test_validate_entry(fei,
6841 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6842 2,
6843 &l99_eos_o_10_10_10_1,
Neale Ranns62fe07c2017-10-31 12:28:22 -07006844 &disp_o_10_10_11_2),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006845 "24001/eos LB 2 buckets via: "
6846 "label 99 over 10.10.10.1, "
Neale Ranns62fe07c2017-10-31 12:28:22 -07006847 "MPLS disp adj over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006848
6849 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6850 &pfx_24001_neos);
6851 FIB_TEST(fib_test_validate_entry(fei,
6852 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6853 1,
6854 &l99_neos_o_10_10_10_1),
6855 "24001/neos LB 1 buckets via: "
6856 "label 99 over 10.10.10.1");
6857
6858 /*
Neale Ranns1357f3b2016-10-16 12:01:42 -07006859 * change the local label
6860 */
6861 fib_table_entry_local_label_add(fib_index,
6862 &pfx_1_1_1_1_s_32,
6863 25005);
6864
6865 fib_prefix_t pfx_25005_eos = {
6866 .fp_proto = FIB_PROTOCOL_MPLS,
6867 .fp_label = 25005,
6868 .fp_eos = MPLS_EOS,
6869 };
6870 fib_prefix_t pfx_25005_neos = {
6871 .fp_proto = FIB_PROTOCOL_MPLS,
6872 .fp_label = 25005,
6873 .fp_eos = MPLS_NON_EOS,
6874 };
6875
6876 FIB_TEST((FIB_NODE_INDEX_INVALID ==
6877 fib_table_lookup(fib_index, &pfx_24001_eos)),
6878 "24001/eos removed after label change");
6879 FIB_TEST((FIB_NODE_INDEX_INVALID ==
6880 fib_table_lookup(fib_index, &pfx_24001_neos)),
6881 "24001/eos removed after label change");
6882
6883 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6884 &pfx_25005_eos);
6885 FIB_TEST(fib_test_validate_entry(fei,
6886 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6887 2,
6888 &l99_eos_o_10_10_10_1,
Neale Ranns62fe07c2017-10-31 12:28:22 -07006889 &disp_o_10_10_11_2),
Neale Ranns1357f3b2016-10-16 12:01:42 -07006890 "25005/eos LB 2 buckets via: "
6891 "label 99 over 10.10.10.1, "
Neale Ranns62fe07c2017-10-31 12:28:22 -07006892 "MPLS disp adj over 10.10.11.2");
Neale Ranns1357f3b2016-10-16 12:01:42 -07006893
6894 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6895 &pfx_25005_neos);
6896 FIB_TEST(fib_test_validate_entry(fei,
6897 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6898 1,
6899 &l99_neos_o_10_10_10_1),
6900 "25005/neos LB 1 buckets via: "
6901 "label 99 over 10.10.10.1");
6902
6903 /*
6904 * remove the local label.
6905 * the check that the MPLS entries are gone is done by the fact the
6906 * MPLS table is no longer present.
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006907 */
6908 fib_table_entry_local_label_remove(fib_index,
6909 &pfx_1_1_1_1_s_32,
Neale Ranns1357f3b2016-10-16 12:01:42 -07006910 25005);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006911
6912 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
6913 FIB_TEST(fib_test_validate_entry(fei,
6914 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6915 2,
6916 &l99_eos_o_10_10_10_1,
6917 &adj_o_10_10_11_2),
6918 "24001/eos LB 2 buckets via: "
6919 "label 99 over 10.10.10.1, "
6920 "adj over 10.10.11.2");
6921
6922 FIB_TEST((FIB_NODE_INDEX_INVALID ==
6923 mpls_fib_index_from_table_id(MPLS_FIB_DEFAULT_TABLE_ID)),
6924 "No more MPLS FIB entries => table removed");
6925
6926 /*
6927 * add another via-entry for the recursive
6928 */
6929 fib_prefix_t pfx_1_1_1_2_s_32 = {
6930 .fp_len = 32,
6931 .fp_proto = FIB_PROTOCOL_IP4,
6932 .fp_addr = {
6933 .ip4.as_u32 = clib_host_to_net_u32(0x01010102),
6934 },
6935 };
6936 fib_test_lb_bucket_t l101_eos_o_10_10_10_1 = {
6937 .type = FT_LB_LABEL_O_ADJ,
6938 .label_o_adj = {
6939 .adj = ai_mpls_10_10_10_1,
6940 .label = 101,
6941 .eos = MPLS_EOS,
6942 },
6943 };
Neale Rannsad422ed2016-11-02 14:20:04 +00006944 mpls_label_t *l101 = NULL;
6945 vec_add1(l101, 101);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006946
6947 fei = fib_table_entry_update_one_path(fib_index,
6948 &pfx_1_1_1_2_s_32,
6949 FIB_SOURCE_API,
6950 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07006951 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006952 &nh_10_10_10_1,
6953 tm->hw[0]->sw_if_index,
6954 ~0, // invalid fib index
6955 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006956 l101,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006957 FIB_ROUTE_PATH_FLAG_NONE);
6958
6959 FIB_TEST(fib_test_validate_entry(fei,
6960 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6961 1,
6962 &l101_eos_o_10_10_10_1),
6963 "1.1.1.2/32 LB 1 buckets via: "
6964 "label 101 over 10.10.10.1");
6965
Neale Ranns948e00f2016-10-20 13:39:34 +01006966 dpo_id_t non_eos_1_1_1_2 = DPO_INVALID;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006967 fib_entry_contribute_forwarding(fib_table_lookup(fib_index,
6968 &pfx_1_1_1_1_s_32),
6969 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6970 &non_eos_1_1_1_1);
6971 fib_entry_contribute_forwarding(fib_table_lookup(fib_index,
6972 &pfx_1_1_1_2_s_32),
6973 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6974 &non_eos_1_1_1_2);
6975
6976 fib_test_lb_bucket_t l1601_eos_o_1_1_1_2 = {
6977 .type = FT_LB_LABEL_O_LB,
6978 .label_o_lb = {
6979 .lb = non_eos_1_1_1_2.dpoi_index,
6980 .label = 1601,
6981 .eos = MPLS_EOS,
6982 },
6983 };
Neale Rannsad422ed2016-11-02 14:20:04 +00006984 mpls_label_t *l1601 = NULL;
6985 vec_add1(l1601, 1601);
6986
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006987 l1600_eos_o_1_1_1_1.label_o_lb.lb = non_eos_1_1_1_1.dpoi_index;
6988
6989 fei = fib_table_entry_path_add(fib_index,
6990 &pfx_2_2_2_2_s_32,
6991 FIB_SOURCE_API,
6992 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07006993 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006994 &pfx_1_1_1_2_s_32.fp_addr,
6995 ~0,
6996 fib_index,
6997 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006998 l1601,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006999 FIB_ROUTE_PATH_FLAG_NONE);
7000
7001 FIB_TEST(fib_test_validate_entry(fei,
7002 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7003 2,
7004 &l1600_eos_o_1_1_1_1,
7005 &l1601_eos_o_1_1_1_2),
7006 "2.2.2.2/32 LB 2 buckets via: "
7007 "label 1600 via 1.1,1.1, "
7008 "label 16001 via 1.1.1.2");
7009
7010 /*
7011 * update the via-entry so it no longer has an imp-null path.
7012 * the LB for the recursive can use an imp-null
7013 */
Neale Rannsad422ed2016-11-02 14:20:04 +00007014 l_imp_null = NULL;
7015 vec_add1(l_imp_null, MPLS_IETF_IMPLICIT_NULL_LABEL);
7016
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007017 fei = fib_table_entry_update_one_path(fib_index,
7018 &pfx_1_1_1_2_s_32,
7019 FIB_SOURCE_API,
7020 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07007021 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007022 &nh_10_10_11_1,
7023 tm->hw[1]->sw_if_index,
7024 ~0, // invalid fib index
7025 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00007026 l_imp_null,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007027 FIB_ROUTE_PATH_FLAG_NONE);
7028
7029 FIB_TEST(fib_test_validate_entry(fei,
7030 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7031 1,
7032 &a_o_10_10_11_1),
7033 "1.1.1.2/32 LB 1 buckets via: "
7034 "adj 10.10.11.1");
7035
7036 fei = fib_table_lookup(fib_index, &pfx_2_2_2_2_s_32);
7037 FIB_TEST(fib_test_validate_entry(fei,
7038 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7039 2,
7040 &l1600_eos_o_1_1_1_1,
7041 &l1601_eos_o_1_1_1_2),
7042 "2.2.2.2/32 LB 2 buckets via: "
7043 "label 1600 via 1.1,1.1, "
7044 "label 16001 via 1.1.1.2");
7045
7046 /*
7047 * update the via-entry so it no longer has labelled paths.
7048 * the LB for the recursive should exclue this via form its LB
7049 */
7050 fei = fib_table_entry_update_one_path(fib_index,
7051 &pfx_1_1_1_2_s_32,
7052 FIB_SOURCE_API,
7053 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07007054 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007055 &nh_10_10_11_1,
7056 tm->hw[1]->sw_if_index,
7057 ~0, // invalid fib index
7058 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00007059 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007060 FIB_ROUTE_PATH_FLAG_NONE);
7061
7062 FIB_TEST(fib_test_validate_entry(fei,
7063 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7064 1,
7065 &a_o_10_10_11_1),
7066 "1.1.1.2/32 LB 1 buckets via: "
7067 "adj 10.10.11.1");
7068
7069 fei = fib_table_lookup(fib_index, &pfx_2_2_2_2_s_32);
7070 FIB_TEST(fib_test_validate_entry(fei,
7071 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7072 1,
7073 &l1600_eos_o_1_1_1_1),
7074 "2.2.2.2/32 LB 1 buckets via: "
7075 "label 1600 via 1.1,1.1");
7076
7077 dpo_reset(&non_eos_1_1_1_1);
7078 dpo_reset(&non_eos_1_1_1_2);
7079
7080 /*
7081 * Add a recursive with no out-labels. We expect to use the IP of the via
7082 */
7083 fib_prefix_t pfx_2_2_2_3_s_32 = {
7084 .fp_len = 32,
7085 .fp_proto = FIB_PROTOCOL_IP4,
7086 .fp_addr = {
7087 .ip4.as_u32 = clib_host_to_net_u32(0x02020203),
7088 },
7089 };
Neale Ranns948e00f2016-10-20 13:39:34 +01007090 dpo_id_t ip_1_1_1_1 = DPO_INVALID;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007091
7092 fib_table_entry_update_one_path(fib_index,
7093 &pfx_2_2_2_3_s_32,
7094 FIB_SOURCE_API,
7095 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07007096 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007097 &pfx_1_1_1_1_s_32.fp_addr,
7098 ~0,
7099 fib_index,
7100 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00007101 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007102 FIB_ROUTE_PATH_FLAG_NONE);
7103
7104 fib_entry_contribute_forwarding(fib_table_lookup(fib_index,
7105 &pfx_1_1_1_1_s_32),
7106 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7107 &ip_1_1_1_1);
7108
7109 fib_test_lb_bucket_t ip_o_1_1_1_1 = {
7110 .type = FT_LB_O_LB,
7111 .lb = {
7112 .lb = ip_1_1_1_1.dpoi_index,
7113 },
7114 };
7115
7116 fei = fib_table_lookup(fib_index, &pfx_2_2_2_3_s_32);
7117 FIB_TEST(fib_test_validate_entry(fei,
7118 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7119 1,
7120 &ip_o_1_1_1_1),
7121 "2.2.2.2.3/32 LB 1 buckets via: "
7122 "ip 1.1.1.1");
7123
7124 /*
7125 * Add a recursive with an imp-null out-label.
7126 * We expect to use the IP of the via
7127 */
7128 fib_prefix_t pfx_2_2_2_4_s_32 = {
7129 .fp_len = 32,
7130 .fp_proto = FIB_PROTOCOL_IP4,
7131 .fp_addr = {
7132 .ip4.as_u32 = clib_host_to_net_u32(0x02020204),
7133 },
7134 };
7135
7136 fib_table_entry_update_one_path(fib_index,
7137 &pfx_2_2_2_4_s_32,
7138 FIB_SOURCE_API,
7139 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07007140 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007141 &pfx_1_1_1_1_s_32.fp_addr,
7142 ~0,
7143 fib_index,
7144 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00007145 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007146 FIB_ROUTE_PATH_FLAG_NONE);
7147
7148 fei = fib_table_lookup(fib_index, &pfx_2_2_2_4_s_32);
7149 FIB_TEST(fib_test_validate_entry(fei,
7150 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7151 1,
7152 &ip_o_1_1_1_1),
7153 "2.2.2.2.4/32 LB 1 buckets via: "
7154 "ip 1.1.1.1");
7155
7156 dpo_reset(&ip_1_1_1_1);
7157
7158 /*
Neale Rannsad422ed2016-11-02 14:20:04 +00007159 * Create an entry with a deep label stack
7160 */
7161 fib_prefix_t pfx_2_2_5_5_s_32 = {
7162 .fp_len = 32,
7163 .fp_proto = FIB_PROTOCOL_IP4,
7164 .fp_addr = {
7165 .ip4.as_u32 = clib_host_to_net_u32(0x02020505),
7166 },
7167 };
7168 fib_test_lb_bucket_t ls_eos_o_10_10_10_1 = {
7169 .type = FT_LB_LABEL_STACK_O_ADJ,
7170 .label_stack_o_adj = {
7171 .adj = ai_mpls_10_10_11_1,
7172 .label_stack_size = 8,
7173 .label_stack = {
7174 200, 201, 202, 203, 204, 205, 206, 207
7175 },
7176 .eos = MPLS_EOS,
7177 },
7178 };
7179 mpls_label_t *label_stack = NULL;
7180 vec_validate(label_stack, 7);
7181 for (ii = 0; ii < 8; ii++)
7182 {
7183 label_stack[ii] = ii + 200;
7184 }
7185
7186 fei = fib_table_entry_update_one_path(fib_index,
7187 &pfx_2_2_5_5_s_32,
7188 FIB_SOURCE_API,
7189 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07007190 DPO_PROTO_IP4,
Neale Rannsad422ed2016-11-02 14:20:04 +00007191 &nh_10_10_11_1,
7192 tm->hw[1]->sw_if_index,
7193 ~0, // invalid fib index
7194 1,
7195 label_stack,
7196 FIB_ROUTE_PATH_FLAG_NONE);
7197
7198 FIB_TEST(fib_test_validate_entry(fei,
7199 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7200 1,
7201 &ls_eos_o_10_10_10_1),
7202 "2.2.5.5/32 LB 1 buckets via: "
7203 "adj 10.10.11.1");
7204 fib_table_entry_delete_index(fei, FIB_SOURCE_API);
7205
7206 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007207 * cleanup
7208 */
7209 fib_table_entry_delete(fib_index,
7210 &pfx_1_1_1_2_s_32,
7211 FIB_SOURCE_API);
7212
7213 fei = fib_table_lookup(fib_index, &pfx_2_2_2_2_s_32);
7214 FIB_TEST(fib_test_validate_entry(fei,
7215 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7216 1,
7217 &l1600_eos_o_1_1_1_1),
7218 "2.2.2.2/32 LB 1 buckets via: "
7219 "label 1600 via 1.1,1.1");
7220
7221 fib_table_entry_delete(fib_index,
7222 &pfx_1_1_1_1_s_32,
7223 FIB_SOURCE_API);
7224
7225 FIB_TEST(fib_test_validate_entry(fei,
7226 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7227 1,
7228 &bucket_drop),
7229 "2.2.2.2/32 LB 1 buckets via: DROP");
7230
7231 fib_table_entry_delete(fib_index,
7232 &pfx_2_2_2_2_s_32,
7233 FIB_SOURCE_API);
7234 fib_table_entry_delete(fib_index,
7235 &pfx_2_2_2_3_s_32,
7236 FIB_SOURCE_API);
7237 fib_table_entry_delete(fib_index,
7238 &pfx_2_2_2_4_s_32,
7239 FIB_SOURCE_API);
7240
7241 adj_unlock(ai_mpls_10_10_10_1);
7242 adj_unlock(ai_mpls_10_10_11_2);
7243 adj_unlock(ai_v4_10_10_11_1);
7244 adj_unlock(ai_v4_10_10_11_2);
7245 adj_unlock(ai_mpls_10_10_11_1);
7246
7247 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
7248 adj_nbr_db_size());
7249
7250 local0_pfx.fp_len = 32;
7251 fib_table_entry_delete(fib_index,
7252 &local0_pfx,
7253 FIB_SOURCE_INTERFACE);
7254 local0_pfx.fp_len = 24;
7255 fib_table_entry_delete(fib_index,
7256 &local0_pfx,
7257 FIB_SOURCE_INTERFACE);
7258 local1_pfx.fp_len = 32;
7259 fib_table_entry_delete(fib_index,
7260 &local1_pfx,
7261 FIB_SOURCE_INTERFACE);
7262 local1_pfx.fp_len = 24;
7263 fib_table_entry_delete(fib_index,
7264 &local1_pfx,
7265 FIB_SOURCE_INTERFACE);
7266
7267 /*
7268 * +1 for the drop LB in the MPLS tables.
7269 */
7270 FIB_TEST(lb_count+1 == pool_elts(load_balance_pool),
7271 "Load-balance resources freed %d of %d",
7272 lb_count+1, pool_elts(load_balance_pool));
Neale Ranns0ebe8d72016-12-08 19:48:11 +00007273
7274 return (0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007275}
7276
7277#define N_TEST_CHILDREN 4
7278#define PARENT_INDEX 0
7279
7280typedef struct fib_node_test_t_
7281{
7282 fib_node_t node;
7283 u32 sibling;
7284 u32 index;
7285 fib_node_back_walk_ctx_t *ctxs;
7286 u32 destroyed;
7287} fib_node_test_t;
7288
7289static fib_node_test_t fib_test_nodes[N_TEST_CHILDREN+1];
7290
7291#define PARENT() (&fib_test_nodes[PARENT_INDEX].node)
7292
7293#define FOR_EACH_TEST_CHILD(_tc) \
7294 for (ii = 1, (_tc) = &fib_test_nodes[1]; \
7295 ii < N_TEST_CHILDREN+1; \
7296 ii++, (_tc) = &fib_test_nodes[ii])
7297
7298static fib_node_t *
7299fib_test_child_get_node (fib_node_index_t index)
7300{
7301 return (&fib_test_nodes[index].node);
7302}
7303
7304static int fib_test_walk_spawns_walks;
7305
7306static fib_node_back_walk_rc_t
7307fib_test_child_back_walk_notify (fib_node_t *node,
7308 fib_node_back_walk_ctx_t *ctx)
7309{
7310 fib_node_test_t *tc = (fib_node_test_t*) node;
7311
7312 vec_add1(tc->ctxs, *ctx);
7313
7314 if (1 == fib_test_walk_spawns_walks)
7315 fib_walk_sync(FIB_NODE_TYPE_TEST, tc->index, ctx);
7316 if (2 == fib_test_walk_spawns_walks)
7317 fib_walk_async(FIB_NODE_TYPE_TEST, tc->index,
7318 FIB_WALK_PRIORITY_HIGH, ctx);
7319
7320 return (FIB_NODE_BACK_WALK_CONTINUE);
7321}
7322
7323static void
7324fib_test_child_last_lock_gone (fib_node_t *node)
7325{
7326 fib_node_test_t *tc = (fib_node_test_t *)node;
7327
7328 tc->destroyed = 1;
7329}
7330
7331/**
7332 * The FIB walk's graph node virtual function table
7333 */
7334static const fib_node_vft_t fib_test_child_vft = {
7335 .fnv_get = fib_test_child_get_node,
7336 .fnv_last_lock = fib_test_child_last_lock_gone,
7337 .fnv_back_walk = fib_test_child_back_walk_notify,
7338};
7339
7340/*
7341 * the function (that should have been static but isn't so I can do this)
7342 * that processes the walk from the async queue,
7343 */
7344f64 fib_walk_process_queues(vlib_main_t * vm,
7345 const f64 quota);
7346u32 fib_walk_queue_get_size(fib_walk_priority_t prio);
7347
Neale Ranns0ebe8d72016-12-08 19:48:11 +00007348static int
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007349fib_test_walk (void)
7350{
7351 fib_node_back_walk_ctx_t high_ctx = {}, low_ctx = {};
7352 fib_node_test_t *tc;
7353 vlib_main_t *vm;
7354 u32 ii;
7355
7356 vm = vlib_get_main();
7357 fib_node_register_type(FIB_NODE_TYPE_TEST, &fib_test_child_vft);
7358
7359 /*
7360 * init a fake node on which we will add children
7361 */
7362 fib_node_init(&fib_test_nodes[PARENT_INDEX].node,
7363 FIB_NODE_TYPE_TEST);
7364
7365 FOR_EACH_TEST_CHILD(tc)
7366 {
7367 fib_node_init(&tc->node, FIB_NODE_TYPE_TEST);
7368 fib_node_lock(&tc->node);
7369 tc->ctxs = NULL;
7370 tc->index = ii;
7371 tc->sibling = fib_node_child_add(FIB_NODE_TYPE_TEST,
7372 PARENT_INDEX,
7373 FIB_NODE_TYPE_TEST, ii);
7374 }
7375
7376 /*
7377 * enqueue a walk across the parents children.
7378 */
Neale Ranns450cd302016-11-09 17:49:42 +00007379 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007380
7381 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7382 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7383 FIB_TEST(N_TEST_CHILDREN+1 == fib_node_list_get_size(PARENT()->fn_children),
7384 "Parent has %d children pre-walk",
7385 fib_node_list_get_size(PARENT()->fn_children));
7386
7387 /*
7388 * give the walk a large amount of time so it gets to the end
7389 */
7390 fib_walk_process_queues(vm, 1);
7391
7392 FOR_EACH_TEST_CHILD(tc)
7393 {
7394 FIB_TEST(1 == vec_len(tc->ctxs),
7395 "%d child visitsed %d times",
7396 ii, vec_len(tc->ctxs));
7397 vec_free(tc->ctxs);
7398 }
7399 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7400 "Queue is empty post walk");
7401 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7402 "Parent has %d children post walk",
7403 fib_node_list_get_size(PARENT()->fn_children));
7404
7405 /*
7406 * walk again. should be no increase in the number of visits, since
7407 * the walk will have terminated.
7408 */
7409 fib_walk_process_queues(vm, 1);
7410
7411 FOR_EACH_TEST_CHILD(tc)
7412 {
7413 FIB_TEST(0 == vec_len(tc->ctxs),
7414 "%d child visitsed %d times",
7415 ii, vec_len(tc->ctxs));
7416 }
7417
7418 /*
7419 * schedule a low and hig priority walk. expect the high to be performed
7420 * before the low.
7421 * schedule the high prio walk first so that it is further from the head
7422 * of the dependency list. that way it won't merge with the low one.
7423 */
7424 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
7425 low_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_ADJ_UPDATE;
7426
7427 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7428 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7429 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7430 FIB_WALK_PRIORITY_LOW, &low_ctx);
7431
7432 fib_walk_process_queues(vm, 1);
7433
7434 FOR_EACH_TEST_CHILD(tc)
7435 {
7436 FIB_TEST(high_ctx.fnbw_reason == tc->ctxs[0].fnbw_reason,
7437 "%d child visitsed by high prio walk", ii);
7438 FIB_TEST(low_ctx.fnbw_reason == tc->ctxs[1].fnbw_reason,
7439 "%d child visitsed by low prio walk", ii);
7440 vec_free(tc->ctxs);
7441 }
7442 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7443 "Queue is empty post prio walk");
7444 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7445 "Parent has %d children post prio walk",
7446 fib_node_list_get_size(PARENT()->fn_children));
7447
7448 /*
7449 * schedule 2 walks of the same priority that can be megred.
7450 * expect that each child is thus visited only once.
7451 */
7452 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
7453 low_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
7454
7455 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7456 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7457 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7458 FIB_WALK_PRIORITY_HIGH, &low_ctx);
7459
7460 fib_walk_process_queues(vm, 1);
7461
7462 FOR_EACH_TEST_CHILD(tc)
7463 {
7464 FIB_TEST(1 == vec_len(tc->ctxs),
7465 "%d child visitsed %d times during merge walk",
7466 ii, vec_len(tc->ctxs));
7467 vec_free(tc->ctxs);
7468 }
7469 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7470 "Queue is empty post merge walk");
7471 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7472 "Parent has %d children post merge walk",
7473 fib_node_list_get_size(PARENT()->fn_children));
7474
7475 /*
7476 * schedule 2 walks of the same priority that cannot be megred.
7477 * expect that each child is thus visited twice and in the order
7478 * in which the walks were scheduled.
7479 */
7480 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
7481 low_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_ADJ_UPDATE;
7482
7483 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7484 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7485 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7486 FIB_WALK_PRIORITY_HIGH, &low_ctx);
7487
7488 fib_walk_process_queues(vm, 1);
7489
7490 FOR_EACH_TEST_CHILD(tc)
7491 {
7492 FIB_TEST(high_ctx.fnbw_reason == tc->ctxs[0].fnbw_reason,
7493 "%d child visitsed by high prio walk", ii);
7494 FIB_TEST(low_ctx.fnbw_reason == tc->ctxs[1].fnbw_reason,
7495 "%d child visitsed by low prio walk", ii);
7496 vec_free(tc->ctxs);
7497 }
7498 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7499 "Queue is empty post no-merge walk");
7500 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7501 "Parent has %d children post no-merge walk",
7502 fib_node_list_get_size(PARENT()->fn_children));
7503
7504 /*
7505 * schedule a walk that makes one one child progress.
7506 * we do this by giving the queue draining process zero
7507 * time quanta. it's a do..while loop, so it does something.
7508 */
Neale Ranns450cd302016-11-09 17:49:42 +00007509 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007510
7511 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7512 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7513 fib_walk_process_queues(vm, 0);
7514
7515 FOR_EACH_TEST_CHILD(tc)
7516 {
7517 if (ii == N_TEST_CHILDREN)
7518 {
7519 FIB_TEST(1 == vec_len(tc->ctxs),
7520 "%d child visitsed %d times in zero quanta walk",
7521 ii, vec_len(tc->ctxs));
7522 }
7523 else
7524 {
7525 FIB_TEST(0 == vec_len(tc->ctxs),
7526 "%d child visitsed %d times in 0 quanta walk",
7527 ii, vec_len(tc->ctxs));
7528 }
7529 }
7530 FIB_TEST(1 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7531 "Queue is not empty post zero quanta walk");
7532 FIB_TEST(N_TEST_CHILDREN+1 == fib_node_list_get_size(PARENT()->fn_children),
7533 "Parent has %d children post zero qunta walk",
7534 fib_node_list_get_size(PARENT()->fn_children));
7535
7536 /*
7537 * another one step
7538 */
7539 fib_walk_process_queues(vm, 0);
7540
7541 FOR_EACH_TEST_CHILD(tc)
7542 {
7543 if (ii >= N_TEST_CHILDREN-1)
7544 {
7545 FIB_TEST(1 == vec_len(tc->ctxs),
7546 "%d child visitsed %d times in 2nd zero quanta walk",
7547 ii, vec_len(tc->ctxs));
7548 }
7549 else
7550 {
7551 FIB_TEST(0 == vec_len(tc->ctxs),
7552 "%d child visitsed %d times in 2nd 0 quanta walk",
7553 ii, vec_len(tc->ctxs));
7554 }
7555 }
7556 FIB_TEST(1 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7557 "Queue is not empty post zero quanta walk");
7558 FIB_TEST(N_TEST_CHILDREN+1 == fib_node_list_get_size(PARENT()->fn_children),
7559 "Parent has %d children post zero qunta walk",
7560 fib_node_list_get_size(PARENT()->fn_children));
7561
7562 /*
7563 * schedule another walk that will catch-up and merge.
7564 */
7565 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7566 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7567 fib_walk_process_queues(vm, 1);
7568
7569 FOR_EACH_TEST_CHILD(tc)
7570 {
7571 if (ii >= N_TEST_CHILDREN-1)
7572 {
7573 FIB_TEST(2 == vec_len(tc->ctxs),
7574 "%d child visitsed %d times in 2nd zero quanta merge walk",
7575 ii, vec_len(tc->ctxs));
7576 vec_free(tc->ctxs);
7577 }
7578 else
7579 {
7580 FIB_TEST(1 == vec_len(tc->ctxs),
7581 "%d child visitsed %d times in 2nd 0 quanta merge walk",
7582 ii, vec_len(tc->ctxs));
7583 vec_free(tc->ctxs);
7584 }
7585 }
7586 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7587 "Queue is not empty post 2nd zero quanta merge walk");
7588 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7589 "Parent has %d children post 2nd zero qunta merge walk",
7590 fib_node_list_get_size(PARENT()->fn_children));
7591
7592 /*
7593 * park a async walk in the middle of the list, then have an sync walk catch
7594 * it. same expectations as async catches async.
7595 */
Neale Ranns450cd302016-11-09 17:49:42 +00007596 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007597
7598 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7599 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7600
7601 fib_walk_process_queues(vm, 0);
7602 fib_walk_process_queues(vm, 0);
7603
7604 fib_walk_sync(FIB_NODE_TYPE_TEST, PARENT_INDEX, &high_ctx);
7605
7606 FOR_EACH_TEST_CHILD(tc)
7607 {
7608 if (ii >= N_TEST_CHILDREN-1)
7609 {
7610 FIB_TEST(2 == vec_len(tc->ctxs),
7611 "%d child visitsed %d times in sync catches async walk",
7612 ii, vec_len(tc->ctxs));
7613 vec_free(tc->ctxs);
7614 }
7615 else
7616 {
7617 FIB_TEST(1 == vec_len(tc->ctxs),
7618 "%d child visitsed %d times in sync catches async walk",
7619 ii, vec_len(tc->ctxs));
7620 vec_free(tc->ctxs);
7621 }
7622 }
7623 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7624 "Queue is not empty post 2nd zero quanta merge walk");
7625 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7626 "Parent has %d children post 2nd zero qunta merge walk",
7627 fib_node_list_get_size(PARENT()->fn_children));
7628
7629 /*
7630 * make the parent a child of one of its children, thus inducing a routing loop.
7631 */
7632 fib_test_nodes[PARENT_INDEX].sibling =
7633 fib_node_child_add(FIB_NODE_TYPE_TEST,
7634 1, // the first child
7635 FIB_NODE_TYPE_TEST,
7636 PARENT_INDEX);
7637
7638 /*
7639 * execute a sync walk from the parent. each child visited spawns more sync
7640 * walks. we expect the walk to terminate.
7641 */
7642 fib_test_walk_spawns_walks = 1;
7643
7644 fib_walk_sync(FIB_NODE_TYPE_TEST, PARENT_INDEX, &high_ctx);
7645
7646 FOR_EACH_TEST_CHILD(tc)
7647 {
7648 /*
7649 * child 1 - which is last in the list - has the loop.
7650 * the other children a re thus visitsed first. the we meet
7651 * child 1. we go round the loop again, visting the other children.
7652 * then we meet the walk in the dep list and bail. child 1 is not visitsed
7653 * again.
7654 */
7655 if (1 == ii)
7656 {
7657 FIB_TEST(1 == vec_len(tc->ctxs),
7658 "child %d visitsed %d times during looped sync walk",
7659 ii, vec_len(tc->ctxs));
7660 }
7661 else
7662 {
7663 FIB_TEST(2 == vec_len(tc->ctxs),
7664 "child %d visitsed %d times during looped sync walk",
7665 ii, vec_len(tc->ctxs));
7666 }
7667 vec_free(tc->ctxs);
7668 }
7669 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7670 "Parent has %d children post sync loop walk",
7671 fib_node_list_get_size(PARENT()->fn_children));
7672
7673 /*
7674 * the walk doesn't reach the max depth because the infra knows that sync
7675 * meets sync implies a loop and bails early.
7676 */
7677 FIB_TEST(high_ctx.fnbw_depth == 9,
7678 "Walk context depth %d post sync loop walk",
7679 high_ctx.fnbw_depth);
7680
7681 /*
7682 * execute an async walk of the graph loop, with each child spawns sync walks
7683 */
7684 high_ctx.fnbw_depth = 0;
7685 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7686 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7687
7688 fib_walk_process_queues(vm, 1);
7689
7690 FOR_EACH_TEST_CHILD(tc)
7691 {
7692 /*
7693 * we don't really care how many times the children are visisted, as long as
7694 * it is more than once.
7695 */
7696 FIB_TEST(1 <= vec_len(tc->ctxs),
7697 "child %d visitsed %d times during looped aync spawns sync walk",
7698 ii, vec_len(tc->ctxs));
7699 vec_free(tc->ctxs);
7700 }
7701
7702 /*
7703 * execute an async walk of the graph loop, with each child spawns async walks
7704 */
7705 fib_test_walk_spawns_walks = 2;
7706 high_ctx.fnbw_depth = 0;
7707 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7708 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7709
7710 fib_walk_process_queues(vm, 1);
7711
7712 FOR_EACH_TEST_CHILD(tc)
7713 {
7714 /*
7715 * we don't really care how many times the children are visisted, as long as
7716 * it is more than once.
7717 */
7718 FIB_TEST(1 <= vec_len(tc->ctxs),
7719 "child %d visitsed %d times during looped async spawns async walk",
7720 ii, vec_len(tc->ctxs));
7721 vec_free(tc->ctxs);
7722 }
7723
7724
7725 fib_node_child_remove(FIB_NODE_TYPE_TEST,
7726 1, // the first child
7727 fib_test_nodes[PARENT_INDEX].sibling);
7728
7729 /*
7730 * cleanup
7731 */
7732 FOR_EACH_TEST_CHILD(tc)
7733 {
7734 fib_node_child_remove(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7735 tc->sibling);
7736 fib_node_deinit(&tc->node);
7737 fib_node_unlock(&tc->node);
7738 }
7739 fib_node_deinit(PARENT());
7740
7741 /*
7742 * The parent will be destroyed when the last lock on it goes.
7743 * this test ensures all the walk objects are unlocking it.
7744 */
7745 FIB_TEST((1 == fib_test_nodes[PARENT_INDEX].destroyed),
7746 "Parent was destroyed");
Neale Ranns0ebe8d72016-12-08 19:48:11 +00007747
7748 return (0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007749}
7750
Neale Ranns88fc83e2017-04-05 08:11:14 -07007751/*
7752 * declaration of the otherwise static callback functions
7753 */
7754void fib_bfd_notify (bfd_listen_event_e event,
7755 const bfd_session_t *session);
7756void adj_bfd_notify (bfd_listen_event_e event,
7757 const bfd_session_t *session);
7758
7759/**
7760 * Test BFD session interaction with FIB
7761 */
7762static int
7763fib_test_bfd (void)
7764{
7765 fib_node_index_t fei;
7766 test_main_t *tm;
7767 int n_feis;
7768
7769 /* via 10.10.10.1 */
7770 ip46_address_t nh_10_10_10_1 = {
7771 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
7772 };
7773 /* via 10.10.10.2 */
7774 ip46_address_t nh_10_10_10_2 = {
7775 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02),
7776 };
7777 /* via 10.10.10.10 */
7778 ip46_address_t nh_10_10_10_10 = {
7779 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a0a),
7780 };
7781 n_feis = fib_entry_pool_size();
7782
7783 tm = &test_main;
7784
7785 /*
7786 * add interface routes. we'll assume this works. it's tested elsewhere
7787 */
7788 fib_prefix_t pfx_10_10_10_10_s_24 = {
7789 .fp_len = 24,
7790 .fp_proto = FIB_PROTOCOL_IP4,
7791 .fp_addr = nh_10_10_10_10,
7792 };
7793
7794 fib_table_entry_update_one_path(0, &pfx_10_10_10_10_s_24,
7795 FIB_SOURCE_INTERFACE,
7796 (FIB_ENTRY_FLAG_CONNECTED |
7797 FIB_ENTRY_FLAG_ATTACHED),
Neale Rannsda78f952017-05-24 09:15:43 -07007798 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07007799 NULL,
7800 tm->hw[0]->sw_if_index,
7801 ~0, // invalid fib index
7802 1, // weight
7803 NULL,
7804 FIB_ROUTE_PATH_FLAG_NONE);
7805
7806 fib_prefix_t pfx_10_10_10_10_s_32 = {
7807 .fp_len = 32,
7808 .fp_proto = FIB_PROTOCOL_IP4,
7809 .fp_addr = nh_10_10_10_10,
7810 };
7811 fib_table_entry_update_one_path(0, &pfx_10_10_10_10_s_32,
7812 FIB_SOURCE_INTERFACE,
7813 (FIB_ENTRY_FLAG_CONNECTED |
7814 FIB_ENTRY_FLAG_LOCAL),
Neale Rannsda78f952017-05-24 09:15:43 -07007815 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07007816 NULL,
7817 tm->hw[0]->sw_if_index,
7818 ~0, // invalid fib index
7819 1, // weight
7820 NULL,
7821 FIB_ROUTE_PATH_FLAG_NONE);
7822
7823 /*
7824 * A BFD session via a neighbour we do not yet know
7825 */
7826 bfd_session_t bfd_10_10_10_1 = {
7827 .udp = {
7828 .key = {
7829 .fib_index = 0,
7830 .peer_addr = nh_10_10_10_1,
7831 },
7832 },
7833 .hop_type = BFD_HOP_TYPE_MULTI,
7834 .local_state = BFD_STATE_init,
7835 };
7836
7837 fib_bfd_notify (BFD_LISTEN_EVENT_CREATE, &bfd_10_10_10_1);
7838
7839 /*
7840 * A new entry will be created that forwards via the adj
7841 */
7842 adj_index_t ai_10_10_10_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
7843 VNET_LINK_IP4,
7844 &nh_10_10_10_1,
7845 tm->hw[0]->sw_if_index);
7846 fib_prefix_t pfx_10_10_10_1_s_32 = {
7847 .fp_addr = nh_10_10_10_1,
7848 .fp_len = 32,
7849 .fp_proto = FIB_PROTOCOL_IP4,
7850 };
7851 fib_test_lb_bucket_t adj_o_10_10_10_1 = {
7852 .type = FT_LB_ADJ,
7853 .adj = {
7854 .adj = ai_10_10_10_1,
7855 },
7856 };
7857
7858 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_1_s_32);
7859 FIB_TEST(fib_test_validate_entry(fei,
7860 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7861 1,
7862 &adj_o_10_10_10_1),
7863 "BFD sourced %U via %U",
7864 format_fib_prefix, &pfx_10_10_10_1_s_32,
7865 format_ip_adjacency, ai_10_10_10_1, FORMAT_IP_ADJACENCY_NONE);
7866
7867 /*
7868 * Delete the BFD session. Expect the fib_entry to be removed
7869 */
7870 fib_bfd_notify (BFD_LISTEN_EVENT_DELETE, &bfd_10_10_10_1);
7871
7872 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_1_s_32);
7873 FIB_TEST(FIB_NODE_INDEX_INVALID == fei,
7874 "BFD sourced %U removed",
7875 format_fib_prefix, &pfx_10_10_10_1_s_32);
7876
7877 /*
7878 * Add the BFD source back
7879 */
7880 fib_bfd_notify (BFD_LISTEN_EVENT_CREATE, &bfd_10_10_10_1);
7881
7882 /*
7883 * source the entry via the ADJ fib
7884 */
Neale Ranns81424992017-05-18 03:03:22 -07007885 fei = fib_table_entry_path_add(0,
7886 &pfx_10_10_10_1_s_32,
7887 FIB_SOURCE_ADJ,
7888 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07007889 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07007890 &nh_10_10_10_1,
7891 tm->hw[0]->sw_if_index,
7892 ~0, // invalid fib index
7893 1,
7894 NULL,
7895 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns88fc83e2017-04-05 08:11:14 -07007896
7897 /*
7898 * Delete the BFD session. Expect the fib_entry to remain
7899 */
7900 fib_bfd_notify (BFD_LISTEN_EVENT_DELETE, &bfd_10_10_10_1);
7901
7902 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_1_s_32);
7903 FIB_TEST(fib_test_validate_entry(fei,
7904 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7905 1,
7906 &adj_o_10_10_10_1),
7907 "BFD sourced %U remains via %U",
7908 format_fib_prefix, &pfx_10_10_10_1_s_32,
7909 format_ip_adjacency, ai_10_10_10_1, FORMAT_IP_ADJACENCY_NONE);
7910
7911 /*
7912 * Add the BFD source back
7913 */
7914 fib_bfd_notify (BFD_LISTEN_EVENT_CREATE, &bfd_10_10_10_1);
7915
7916 /*
7917 * Create another ADJ FIB
7918 */
7919 fib_prefix_t pfx_10_10_10_2_s_32 = {
7920 .fp_addr = nh_10_10_10_2,
7921 .fp_len = 32,
7922 .fp_proto = FIB_PROTOCOL_IP4,
7923 };
Neale Ranns81424992017-05-18 03:03:22 -07007924 fib_table_entry_path_add(0,
7925 &pfx_10_10_10_2_s_32,
7926 FIB_SOURCE_ADJ,
7927 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07007928 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07007929 &nh_10_10_10_2,
7930 tm->hw[0]->sw_if_index,
7931 ~0, // invalid fib index
7932 1,
7933 NULL,
7934 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns88fc83e2017-04-05 08:11:14 -07007935 /*
7936 * A BFD session for the new ADJ FIB
7937 */
7938 bfd_session_t bfd_10_10_10_2 = {
7939 .udp = {
7940 .key = {
7941 .fib_index = 0,
7942 .peer_addr = nh_10_10_10_2,
7943 },
7944 },
7945 .hop_type = BFD_HOP_TYPE_MULTI,
7946 .local_state = BFD_STATE_init,
7947 };
7948
7949 fib_bfd_notify (BFD_LISTEN_EVENT_CREATE, &bfd_10_10_10_2);
7950
7951 /*
7952 * remove the adj-fib source whilst the session is present
7953 * then add it back
7954 */
7955 fib_table_entry_delete(0, &pfx_10_10_10_2_s_32, FIB_SOURCE_ADJ);
Neale Ranns81424992017-05-18 03:03:22 -07007956 fib_table_entry_path_add(0,
7957 &pfx_10_10_10_2_s_32,
7958 FIB_SOURCE_ADJ,
7959 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07007960 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07007961 &nh_10_10_10_2,
7962 tm->hw[0]->sw_if_index,
7963 ~0, // invalid fib index
7964 1,
7965 NULL,
7966 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns88fc83e2017-04-05 08:11:14 -07007967
7968 /*
7969 * Before adding a recursive via the BFD tracked ADJ-FIBs,
7970 * bring one of the sessions UP, leave the other down
7971 */
7972 bfd_10_10_10_1.local_state = BFD_STATE_up;
7973 fib_bfd_notify (BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_1);
7974 bfd_10_10_10_2.local_state = BFD_STATE_down;
7975 fib_bfd_notify (BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_2);
7976
7977 /*
7978 * A recursive prefix via both of the ADJ FIBs
7979 */
7980 fib_prefix_t pfx_200_0_0_0_s_24 = {
7981 .fp_proto = FIB_PROTOCOL_IP4,
7982 .fp_len = 32,
7983 .fp_addr = {
7984 .ip4.as_u32 = clib_host_to_net_u32(0xc8000000),
7985 },
7986 };
7987 const dpo_id_t *dpo_10_10_10_1, *dpo_10_10_10_2;
7988
7989 dpo_10_10_10_1 =
7990 fib_entry_contribute_ip_forwarding(
7991 fib_table_lookup_exact_match(0, &pfx_10_10_10_1_s_32));
7992 dpo_10_10_10_2 =
7993 fib_entry_contribute_ip_forwarding(
7994 fib_table_lookup_exact_match(0, &pfx_10_10_10_2_s_32));
7995
7996 fib_test_lb_bucket_t lb_o_10_10_10_1 = {
7997 .type = FT_LB_O_LB,
7998 .lb = {
7999 .lb = dpo_10_10_10_1->dpoi_index,
8000 },
8001 };
8002 fib_test_lb_bucket_t lb_o_10_10_10_2 = {
8003 .type = FT_LB_O_LB,
8004 .lb = {
8005 .lb = dpo_10_10_10_2->dpoi_index,
8006 },
8007 };
8008
8009 /*
8010 * A prefix via the adj-fib that is BFD down => DROP
8011 */
8012 fei = fib_table_entry_path_add(0,
8013 &pfx_200_0_0_0_s_24,
8014 FIB_SOURCE_API,
8015 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008016 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07008017 &nh_10_10_10_2,
8018 ~0, // recursive
8019 0, // default fib index
8020 1,
8021 NULL,
8022 FIB_ROUTE_PATH_FLAG_NONE);
8023 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
8024 "%U resolves via drop",
8025 format_fib_prefix, &pfx_200_0_0_0_s_24);
8026
8027 /*
8028 * add a path via the UP BFD adj-fib.
8029 * we expect that the DOWN BFD ADJ FIB is not used.
8030 */
8031 fei = fib_table_entry_path_add(0,
8032 &pfx_200_0_0_0_s_24,
8033 FIB_SOURCE_API,
8034 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008035 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07008036 &nh_10_10_10_1,
8037 ~0, // recursive
8038 0, // default fib index
8039 1,
8040 NULL,
8041 FIB_ROUTE_PATH_FLAG_NONE);
8042
8043 FIB_TEST(fib_test_validate_entry(fei,
8044 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8045 1,
8046 &lb_o_10_10_10_1),
8047 "Recursive %U only UP BFD adj-fibs",
8048 format_fib_prefix, &pfx_200_0_0_0_s_24);
8049
8050 /*
8051 * Send a BFD state change to UP - both sessions are now up
8052 * the recursive prefix should LB over both
8053 */
8054 bfd_10_10_10_2.local_state = BFD_STATE_up;
8055 fib_bfd_notify (BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_2);
8056
8057
8058 FIB_TEST(fib_test_validate_entry(fei,
8059 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8060 2,
8061 &lb_o_10_10_10_1,
8062 &lb_o_10_10_10_2),
8063 "Recursive %U via both UP BFD adj-fibs",
8064 format_fib_prefix, &pfx_200_0_0_0_s_24);
8065
8066 /*
8067 * Send a BFD state change to DOWN
8068 * the recursive prefix should exclude the down
8069 */
8070 bfd_10_10_10_2.local_state = BFD_STATE_down;
8071 fib_bfd_notify (BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_2);
8072
8073
8074 FIB_TEST(fib_test_validate_entry(fei,
8075 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8076 1,
8077 &lb_o_10_10_10_1),
8078 "Recursive %U via only UP",
8079 format_fib_prefix, &pfx_200_0_0_0_s_24);
8080
8081 /*
8082 * Delete the BFD session while it is in the DOWN state.
8083 * FIB should consider the entry's state as back up
8084 */
8085 fib_bfd_notify (BFD_LISTEN_EVENT_DELETE, &bfd_10_10_10_2);
8086
8087 FIB_TEST(fib_test_validate_entry(fei,
8088 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8089 2,
8090 &lb_o_10_10_10_1,
8091 &lb_o_10_10_10_2),
8092 "Recursive %U via both UP BFD adj-fibs post down session delete",
8093 format_fib_prefix, &pfx_200_0_0_0_s_24);
8094
8095 /*
8096 * Delete the BFD other session while it is in the UP state.
8097 */
8098 fib_bfd_notify (BFD_LISTEN_EVENT_DELETE, &bfd_10_10_10_1);
8099
8100 FIB_TEST(fib_test_validate_entry(fei,
8101 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8102 2,
8103 &lb_o_10_10_10_1,
8104 &lb_o_10_10_10_2),
8105 "Recursive %U via both UP BFD adj-fibs post up session delete",
8106 format_fib_prefix, &pfx_200_0_0_0_s_24);
8107
8108 /*
8109 * cleaup
8110 */
8111 fib_table_entry_delete(0, &pfx_200_0_0_0_s_24, FIB_SOURCE_API);
8112 fib_table_entry_delete(0, &pfx_10_10_10_1_s_32, FIB_SOURCE_ADJ);
8113 fib_table_entry_delete(0, &pfx_10_10_10_2_s_32, FIB_SOURCE_ADJ);
8114
8115 fib_table_entry_delete(0, &pfx_10_10_10_10_s_32, FIB_SOURCE_INTERFACE);
8116 fib_table_entry_delete(0, &pfx_10_10_10_10_s_24, FIB_SOURCE_INTERFACE);
8117
8118 adj_unlock(ai_10_10_10_1);
8119 /*
8120 * test no-one left behind
8121 */
8122 FIB_TEST((n_feis == fib_entry_pool_size()), "Entries gone");
8123 FIB_TEST(0 == adj_nbr_db_size(), "All adjacencies removed");
8124
8125 /*
8126 * Single-hop BFD tests
8127 */
8128 bfd_10_10_10_1.hop_type = BFD_HOP_TYPE_SINGLE;
8129 bfd_10_10_10_1.udp.key.sw_if_index = tm->hw[0]->sw_if_index;
8130
8131 adj_bfd_notify(BFD_LISTEN_EVENT_CREATE, &bfd_10_10_10_1);
8132
8133 ai_10_10_10_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
8134 VNET_LINK_IP4,
8135 &nh_10_10_10_1,
8136 tm->hw[0]->sw_if_index);
8137 /*
8138 * whilst the BFD session is not signalled, the adj is up
8139 */
8140 FIB_TEST(adj_is_up(ai_10_10_10_1), "Adj state up on uninit session");
8141
8142 /*
8143 * bring the BFD session up
8144 */
8145 bfd_10_10_10_1.local_state = BFD_STATE_up;
8146 adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_1);
8147 FIB_TEST(adj_is_up(ai_10_10_10_1), "Adj state up on UP session");
8148
8149 /*
8150 * bring the BFD session down
8151 */
8152 bfd_10_10_10_1.local_state = BFD_STATE_down;
8153 adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_1);
8154 FIB_TEST(!adj_is_up(ai_10_10_10_1), "Adj state down on DOWN session");
8155
8156
8157 /*
8158 * add an attached next hop FIB entry via the down adj
8159 */
8160 fib_prefix_t pfx_5_5_5_5_s_32 = {
8161 .fp_addr = {
8162 .ip4 = {
8163 .as_u32 = clib_host_to_net_u32(0x05050505),
8164 },
8165 },
8166 .fp_len = 32,
8167 .fp_proto = FIB_PROTOCOL_IP4,
8168 };
8169
8170 fei = fib_table_entry_path_add(0,
8171 &pfx_5_5_5_5_s_32,
8172 FIB_SOURCE_CLI,
8173 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008174 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07008175 &nh_10_10_10_1,
8176 tm->hw[0]->sw_if_index,
8177 ~0, // invalid fib index
8178 1,
8179 NULL,
8180 FIB_ROUTE_PATH_FLAG_NONE);
8181 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
8182 "%U resolves via drop",
8183 format_fib_prefix, &pfx_5_5_5_5_s_32);
8184
8185 /*
8186 * Add a path via an ADJ that is up
8187 */
8188 adj_index_t ai_10_10_10_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
8189 VNET_LINK_IP4,
8190 &nh_10_10_10_2,
8191 tm->hw[0]->sw_if_index);
8192
8193 fib_test_lb_bucket_t adj_o_10_10_10_2 = {
8194 .type = FT_LB_ADJ,
8195 .adj = {
8196 .adj = ai_10_10_10_2,
8197 },
8198 };
8199 adj_o_10_10_10_1.adj.adj = ai_10_10_10_1;
8200
8201 fei = fib_table_entry_path_add(0,
8202 &pfx_5_5_5_5_s_32,
8203 FIB_SOURCE_CLI,
8204 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008205 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07008206 &nh_10_10_10_2,
8207 tm->hw[0]->sw_if_index,
8208 ~0, // invalid fib index
8209 1,
8210 NULL,
8211 FIB_ROUTE_PATH_FLAG_NONE);
8212
8213 FIB_TEST(fib_test_validate_entry(fei,
8214 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8215 1,
8216 &adj_o_10_10_10_2),
8217 "BFD sourced %U via %U",
8218 format_fib_prefix, &pfx_5_5_5_5_s_32,
8219 format_ip_adjacency, ai_10_10_10_2, FORMAT_IP_ADJACENCY_NONE);
8220
8221 /*
8222 * Bring up the down session - should now LB
8223 */
8224 bfd_10_10_10_1.local_state = BFD_STATE_up;
8225 adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_1);
8226 FIB_TEST(fib_test_validate_entry(fei,
8227 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8228 2,
8229 &adj_o_10_10_10_1,
8230 &adj_o_10_10_10_2),
8231 "BFD sourced %U via noth adjs",
8232 format_fib_prefix, &pfx_5_5_5_5_s_32);
8233
8234 /*
8235 * remove the BFD session state from the adj
8236 */
8237 adj_bfd_notify(BFD_LISTEN_EVENT_DELETE, &bfd_10_10_10_1);
8238
8239 /*
8240 * clean-up
8241 */
8242 fib_table_entry_delete(0, &pfx_5_5_5_5_s_32, FIB_SOURCE_CLI);
8243 adj_unlock(ai_10_10_10_1);
8244 adj_unlock(ai_10_10_10_2);
8245
8246 /*
8247 * test no-one left behind
8248 */
8249 FIB_TEST((n_feis == fib_entry_pool_size()), "Entries gone");
8250 FIB_TEST(0 == adj_nbr_db_size(), "All adjacencies removed");
8251 return (0);
8252}
8253
Neale Ranns0ebe8d72016-12-08 19:48:11 +00008254static int
8255lfib_test (void)
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008256{
8257 const mpls_label_t deag_label = 50;
8258 const u32 lfib_index = 0;
8259 const u32 fib_index = 0;
Neale Ranns948e00f2016-10-20 13:39:34 +01008260 dpo_id_t dpo = DPO_INVALID;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008261 const dpo_id_t *dpo1;
8262 fib_node_index_t lfe;
8263 lookup_dpo_t *lkd;
8264 test_main_t *tm;
8265 int lb_count;
Neale Rannsad422ed2016-11-02 14:20:04 +00008266 adj_index_t ai_mpls_10_10_10_1;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008267
8268 tm = &test_main;
8269 lb_count = pool_elts(load_balance_pool);
8270
8271 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
8272 adj_nbr_db_size());
8273
8274 /*
8275 * MPLS enable an interface so we get the MPLS table created
8276 */
Neale Ranns2297af02017-09-12 09:45:04 -07008277 mpls_table_create(MPLS_FIB_DEFAULT_TABLE_ID, FIB_SOURCE_API, NULL);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008278 mpls_sw_interface_enable_disable(&mpls_main,
8279 tm->hw[0]->sw_if_index,
Neale Ranns15002542017-09-10 04:39:11 -07008280 1, 1);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008281
Neale Rannsad422ed2016-11-02 14:20:04 +00008282 ip46_address_t nh_10_10_10_1 = {
8283 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
8284 };
8285 ai_mpls_10_10_10_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
8286 VNET_LINK_MPLS,
8287 &nh_10_10_10_1,
8288 tm->hw[0]->sw_if_index);
8289
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008290 /*
8291 * Test the specials stack properly.
8292 */
8293 fib_prefix_t exp_null_v6_pfx = {
8294 .fp_proto = FIB_PROTOCOL_MPLS,
8295 .fp_eos = MPLS_EOS,
8296 .fp_label = MPLS_IETF_IPV6_EXPLICIT_NULL_LABEL,
8297 .fp_payload_proto = DPO_PROTO_IP6,
8298 };
8299 lfe = fib_table_lookup(lfib_index, &exp_null_v6_pfx);
8300 FIB_TEST((FIB_NODE_INDEX_INVALID != lfe),
8301 "%U/%U present",
8302 format_mpls_unicast_label, MPLS_IETF_IPV6_EXPLICIT_NULL_LABEL,
8303 format_mpls_eos_bit, MPLS_EOS);
8304 fib_entry_contribute_forwarding(lfe,
8305 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8306 &dpo);
8307 dpo1 = load_balance_get_bucket(dpo.dpoi_index, 0);
8308 lkd = lookup_dpo_get(dpo1->dpoi_index);
8309
8310 FIB_TEST((fib_index == lkd->lkd_fib_index),
8311 "%U/%U is deag in %d %U",
8312 format_mpls_unicast_label, deag_label,
8313 format_mpls_eos_bit, MPLS_EOS,
8314 lkd->lkd_fib_index,
8315 format_dpo_id, &dpo, 0);
8316 FIB_TEST((LOOKUP_INPUT_DST_ADDR == lkd->lkd_input),
8317 "%U/%U is dst deag",
8318 format_mpls_unicast_label, deag_label,
8319 format_mpls_eos_bit, MPLS_EOS);
8320 FIB_TEST((LOOKUP_TABLE_FROM_INPUT_INTERFACE == lkd->lkd_table),
8321 "%U/%U is lookup in interface's table",
8322 format_mpls_unicast_label, deag_label,
8323 format_mpls_eos_bit, MPLS_EOS);
8324 FIB_TEST((DPO_PROTO_IP6 == lkd->lkd_proto),
8325 "%U/%U is %U dst deag",
8326 format_mpls_unicast_label, deag_label,
8327 format_mpls_eos_bit, MPLS_EOS,
8328 format_dpo_proto, lkd->lkd_proto);
8329
8330
8331 /*
8332 * A route deag route for EOS
8333 */
8334 fib_prefix_t pfx = {
8335 .fp_proto = FIB_PROTOCOL_MPLS,
8336 .fp_eos = MPLS_EOS,
8337 .fp_label = deag_label,
8338 .fp_payload_proto = DPO_PROTO_IP4,
8339 };
8340 lfe = fib_table_entry_path_add(lfib_index,
8341 &pfx,
8342 FIB_SOURCE_CLI,
8343 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008344 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008345 &zero_addr,
8346 ~0,
8347 fib_index,
8348 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00008349 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008350 FIB_ROUTE_PATH_FLAG_NONE);
8351
8352 FIB_TEST((lfe == fib_table_lookup(lfib_index, &pfx)),
8353 "%U/%U present",
8354 format_mpls_unicast_label, deag_label,
8355 format_mpls_eos_bit, MPLS_EOS);
8356
8357 fib_entry_contribute_forwarding(lfe,
8358 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8359 &dpo);
8360 dpo1 = load_balance_get_bucket(dpo.dpoi_index, 0);
8361 lkd = lookup_dpo_get(dpo1->dpoi_index);
8362
8363 FIB_TEST((fib_index == lkd->lkd_fib_index),
8364 "%U/%U is deag in %d %U",
8365 format_mpls_unicast_label, deag_label,
8366 format_mpls_eos_bit, MPLS_EOS,
8367 lkd->lkd_fib_index,
8368 format_dpo_id, &dpo, 0);
8369 FIB_TEST((LOOKUP_INPUT_DST_ADDR == lkd->lkd_input),
8370 "%U/%U is dst deag",
8371 format_mpls_unicast_label, deag_label,
8372 format_mpls_eos_bit, MPLS_EOS);
8373 FIB_TEST((DPO_PROTO_IP4 == lkd->lkd_proto),
8374 "%U/%U is %U dst deag",
8375 format_mpls_unicast_label, deag_label,
8376 format_mpls_eos_bit, MPLS_EOS,
8377 format_dpo_proto, lkd->lkd_proto);
8378
8379 fib_table_entry_delete_index(lfe, FIB_SOURCE_CLI);
8380
8381 FIB_TEST((FIB_NODE_INDEX_INVALID == fib_table_lookup(lfib_index,
8382 &pfx)),
8383 "%U/%U not present",
8384 format_mpls_unicast_label, deag_label,
8385 format_mpls_eos_bit, MPLS_EOS);
8386
8387 /*
8388 * A route deag route for non-EOS
8389 */
8390 pfx.fp_eos = MPLS_NON_EOS;
8391 lfe = fib_table_entry_path_add(lfib_index,
8392 &pfx,
8393 FIB_SOURCE_CLI,
8394 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008395 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008396 &zero_addr,
8397 ~0,
8398 lfib_index,
8399 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00008400 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008401 FIB_ROUTE_PATH_FLAG_NONE);
8402
8403 FIB_TEST((lfe == fib_table_lookup(lfib_index, &pfx)),
8404 "%U/%U present",
8405 format_mpls_unicast_label, deag_label,
8406 format_mpls_eos_bit, MPLS_NON_EOS);
8407
8408 fib_entry_contribute_forwarding(lfe,
8409 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
8410 &dpo);
8411 dpo1 = load_balance_get_bucket(dpo.dpoi_index, 0);
8412 lkd = lookup_dpo_get(dpo1->dpoi_index);
8413
8414 FIB_TEST((fib_index == lkd->lkd_fib_index),
8415 "%U/%U is deag in %d %U",
8416 format_mpls_unicast_label, deag_label,
8417 format_mpls_eos_bit, MPLS_NON_EOS,
8418 lkd->lkd_fib_index,
8419 format_dpo_id, &dpo, 0);
8420 FIB_TEST((LOOKUP_INPUT_DST_ADDR == lkd->lkd_input),
8421 "%U/%U is dst deag",
8422 format_mpls_unicast_label, deag_label,
8423 format_mpls_eos_bit, MPLS_NON_EOS);
8424
8425 FIB_TEST((DPO_PROTO_MPLS == lkd->lkd_proto),
8426 "%U/%U is %U dst deag",
8427 format_mpls_unicast_label, deag_label,
8428 format_mpls_eos_bit, MPLS_NON_EOS,
8429 format_dpo_proto, lkd->lkd_proto);
8430
8431 fib_table_entry_delete_index(lfe, FIB_SOURCE_CLI);
8432
8433 FIB_TEST((FIB_NODE_INDEX_INVALID == fib_table_lookup(lfib_index,
8434 &pfx)),
8435 "%U/%U not present",
8436 format_mpls_unicast_label, deag_label,
8437 format_mpls_eos_bit, MPLS_EOS);
8438
Neale Rannsad422ed2016-11-02 14:20:04 +00008439 dpo_reset(&dpo);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008440
Neale Rannsad422ed2016-11-02 14:20:04 +00008441 /*
8442 * An MPLS x-connect
8443 */
8444 fib_prefix_t pfx_1200 = {
8445 .fp_len = 21,
8446 .fp_proto = FIB_PROTOCOL_MPLS,
8447 .fp_label = 1200,
8448 .fp_eos = MPLS_NON_EOS,
8449 };
8450 fib_test_lb_bucket_t neos_o_10_10_10_1 = {
8451 .type = FT_LB_LABEL_STACK_O_ADJ,
8452 .label_stack_o_adj = {
8453 .adj = ai_mpls_10_10_10_1,
8454 .label_stack_size = 4,
8455 .label_stack = {
8456 200, 300, 400, 500,
8457 },
8458 .eos = MPLS_NON_EOS,
8459 },
8460 };
8461 dpo_id_t neos_1200 = DPO_INVALID;
8462 dpo_id_t ip_1200 = DPO_INVALID;
8463 mpls_label_t *l200 = NULL;
8464 vec_add1(l200, 200);
8465 vec_add1(l200, 300);
8466 vec_add1(l200, 400);
8467 vec_add1(l200, 500);
8468
8469 lfe = fib_table_entry_update_one_path(fib_index,
8470 &pfx_1200,
8471 FIB_SOURCE_API,
8472 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008473 DPO_PROTO_IP4,
Neale Rannsad422ed2016-11-02 14:20:04 +00008474 &nh_10_10_10_1,
8475 tm->hw[0]->sw_if_index,
8476 ~0, // invalid fib index
8477 1,
8478 l200,
8479 FIB_ROUTE_PATH_FLAG_NONE);
8480
8481 FIB_TEST(fib_test_validate_entry(lfe,
8482 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
8483 1,
8484 &neos_o_10_10_10_1),
8485 "1200/0 LB 1 buckets via: "
8486 "adj 10.10.11.1");
8487
8488 /*
8489 * A recursive route via the MPLS x-connect
8490 */
8491 fib_prefix_t pfx_2_2_2_3_s_32 = {
8492 .fp_len = 32,
8493 .fp_proto = FIB_PROTOCOL_IP4,
8494 .fp_addr = {
8495 .ip4.as_u32 = clib_host_to_net_u32(0x02020203),
8496 },
8497 };
8498 fib_route_path_t *rpaths = NULL, rpath = {
Neale Rannsda78f952017-05-24 09:15:43 -07008499 .frp_proto = DPO_PROTO_MPLS,
Neale Rannsad422ed2016-11-02 14:20:04 +00008500 .frp_local_label = 1200,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008501 .frp_eos = MPLS_NON_EOS,
Neale Rannsad422ed2016-11-02 14:20:04 +00008502 .frp_sw_if_index = ~0, // recurive
8503 .frp_fib_index = 0, // Default MPLS fib
8504 .frp_weight = 1,
8505 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
8506 .frp_label_stack = NULL,
8507 };
8508 vec_add1(rpaths, rpath);
8509
8510 fib_table_entry_path_add2(fib_index,
8511 &pfx_2_2_2_3_s_32,
8512 FIB_SOURCE_API,
8513 FIB_ENTRY_FLAG_NONE,
8514 rpaths);
8515
8516 /*
8517 * A labelled recursive route via the MPLS x-connect
8518 */
8519 fib_prefix_t pfx_2_2_2_4_s_32 = {
8520 .fp_len = 32,
8521 .fp_proto = FIB_PROTOCOL_IP4,
8522 .fp_addr = {
8523 .ip4.as_u32 = clib_host_to_net_u32(0x02020204),
8524 },
8525 };
8526 mpls_label_t *l999 = NULL;
8527 vec_add1(l999, 999);
8528 rpaths[0].frp_label_stack = l999,
8529
8530 fib_table_entry_path_add2(fib_index,
8531 &pfx_2_2_2_4_s_32,
8532 FIB_SOURCE_API,
8533 FIB_ENTRY_FLAG_NONE,
8534 rpaths);
8535
8536 fib_entry_contribute_forwarding(fib_table_lookup(fib_index, &pfx_1200),
8537 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8538 &ip_1200);
8539 fib_entry_contribute_forwarding(fib_table_lookup(fib_index, &pfx_1200),
8540 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
8541 &neos_1200);
8542
8543 fib_test_lb_bucket_t ip_o_1200 = {
8544 .type = FT_LB_O_LB,
8545 .lb = {
8546 .lb = ip_1200.dpoi_index,
8547 },
8548 };
8549 fib_test_lb_bucket_t mpls_o_1200 = {
8550 .type = FT_LB_LABEL_O_LB,
8551 .label_o_lb = {
8552 .lb = neos_1200.dpoi_index,
8553 .label = 999,
8554 .eos = MPLS_EOS,
8555 },
8556 };
8557
8558 lfe = fib_table_lookup(fib_index, &pfx_2_2_2_3_s_32);
8559 FIB_TEST(fib_test_validate_entry(lfe,
8560 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8561 1,
8562 &ip_o_1200),
8563 "2.2.2.2.3/32 LB 1 buckets via: label 1200 EOS");
8564 lfe = fib_table_lookup(fib_index, &pfx_2_2_2_4_s_32);
8565 FIB_TEST(fib_test_validate_entry(lfe,
8566 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8567 1,
8568 &mpls_o_1200),
8569 "2.2.2.2.4/32 LB 1 buckets via: label 1200 non-EOS");
8570
8571 fib_table_entry_delete(fib_index, &pfx_1200, FIB_SOURCE_API);
8572 fib_table_entry_delete(fib_index, &pfx_2_2_2_3_s_32, FIB_SOURCE_API);
8573 fib_table_entry_delete(fib_index, &pfx_2_2_2_4_s_32, FIB_SOURCE_API);
8574
8575 dpo_reset(&neos_1200);
8576 dpo_reset(&ip_1200);
8577
8578 /*
8579 * A recursive via a label that does not exist
8580 */
8581 fib_test_lb_bucket_t bucket_drop = {
Neale Rannsd792d9c2017-10-21 10:53:20 -07008582 .type = FT_LB_DROP,
Neale Rannsad422ed2016-11-02 14:20:04 +00008583 .special = {
Neale Rannsf12a83f2017-04-18 09:09:40 -07008584 .adj = DPO_PROTO_IP4,
8585 },
8586 };
8587 fib_test_lb_bucket_t mpls_bucket_drop = {
Neale Rannsd792d9c2017-10-21 10:53:20 -07008588 .type = FT_LB_DROP,
Neale Rannsf12a83f2017-04-18 09:09:40 -07008589 .special = {
Neale Rannsad422ed2016-11-02 14:20:04 +00008590 .adj = DPO_PROTO_MPLS,
8591 },
8592 };
8593
8594 rpaths[0].frp_label_stack = NULL;
8595 lfe = fib_table_entry_path_add2(fib_index,
8596 &pfx_2_2_2_4_s_32,
8597 FIB_SOURCE_API,
8598 FIB_ENTRY_FLAG_NONE,
8599 rpaths);
8600
8601 fib_entry_contribute_forwarding(fib_table_lookup(fib_index, &pfx_1200),
8602 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8603 &ip_1200);
8604 ip_o_1200.lb.lb = ip_1200.dpoi_index;
8605
8606 FIB_TEST(fib_test_validate_entry(lfe,
8607 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8608 1,
Neale Ranns57b58602017-07-15 07:37:25 -07008609 &bucket_drop),
8610 "2.2.2.2.4/32 LB 1 buckets via: drop");
Neale Rannsad422ed2016-11-02 14:20:04 +00008611 lfe = fib_table_lookup(fib_index, &pfx_1200);
8612 FIB_TEST(fib_test_validate_entry(lfe,
8613 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8614 1,
8615 &bucket_drop),
Neale Rannsf12a83f2017-04-18 09:09:40 -07008616 "1200/neos LB 1 buckets via: ip4-DROP");
8617 FIB_TEST(fib_test_validate_entry(lfe,
8618 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
8619 1,
8620 &mpls_bucket_drop),
8621 "1200/neos LB 1 buckets via: mpls-DROP");
Neale Rannsad422ed2016-11-02 14:20:04 +00008622
8623 fib_table_entry_delete(fib_index, &pfx_2_2_2_4_s_32, FIB_SOURCE_API);
8624
8625 dpo_reset(&ip_1200);
8626
8627 /*
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008628 * An rx-interface route.
8629 * like the tail of an mcast LSP
8630 */
8631 dpo_id_t idpo = DPO_INVALID;
8632
Neale Ranns43161a82017-08-12 02:12:00 -07008633 interface_rx_dpo_add_or_lock(DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008634 tm->hw[0]->sw_if_index,
8635 &idpo);
8636
8637 fib_prefix_t pfx_2500 = {
8638 .fp_len = 21,
8639 .fp_proto = FIB_PROTOCOL_MPLS,
8640 .fp_label = 2500,
8641 .fp_eos = MPLS_EOS,
8642 .fp_payload_proto = DPO_PROTO_IP4,
8643 };
8644 fib_test_lb_bucket_t rx_intf_0 = {
8645 .type = FT_LB_INTF,
8646 .adj = {
8647 .adj = idpo.dpoi_index,
8648 },
8649 };
8650
8651 lfe = fib_table_entry_update_one_path(fib_index,
8652 &pfx_2500,
8653 FIB_SOURCE_API,
8654 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008655 DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008656 NULL,
8657 tm->hw[0]->sw_if_index,
8658 ~0, // invalid fib index
8659 0,
8660 NULL,
8661 FIB_ROUTE_PATH_INTF_RX);
8662 FIB_TEST(fib_test_validate_entry(lfe,
8663 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8664 1,
8665 &rx_intf_0),
8666 "2500 rx-interface 0");
8667 fib_table_entry_delete(fib_index, &pfx_2500, FIB_SOURCE_API);
8668
8669 /*
8670 * An MPLS mulicast entry
8671 */
8672 fib_prefix_t pfx_3500 = {
8673 .fp_len = 21,
8674 .fp_proto = FIB_PROTOCOL_MPLS,
8675 .fp_label = 3500,
8676 .fp_eos = MPLS_EOS,
8677 .fp_payload_proto = DPO_PROTO_IP4,
8678 };
8679 fib_test_rep_bucket_t mc_0 = {
8680 .type = FT_REP_LABEL_O_ADJ,
8681 .label_o_adj = {
8682 .adj = ai_mpls_10_10_10_1,
8683 .label = 3300,
8684 .eos = MPLS_EOS,
8685 },
8686 };
8687 fib_test_rep_bucket_t mc_intf_0 = {
8688 .type = FT_REP_INTF,
8689 .adj = {
8690 .adj = idpo.dpoi_index,
8691 },
8692 };
8693 mpls_label_t *l3300 = NULL;
8694 vec_add1(l3300, 3300);
8695
8696 lfe = fib_table_entry_update_one_path(lfib_index,
8697 &pfx_3500,
8698 FIB_SOURCE_API,
8699 FIB_ENTRY_FLAG_MULTICAST,
Neale Rannsda78f952017-05-24 09:15:43 -07008700 DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008701 &nh_10_10_10_1,
8702 tm->hw[0]->sw_if_index,
8703 ~0, // invalid fib index
8704 1,
8705 l3300,
8706 FIB_ROUTE_PATH_FLAG_NONE);
8707 FIB_TEST(fib_test_validate_entry(lfe,
8708 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8709 1,
8710 &mc_0),
8711 "3500 via replicate over 10.10.10.1");
8712
8713 /*
8714 * MPLS Bud-node. Add a replication via an interface-receieve path
8715 */
8716 lfe = fib_table_entry_path_add(lfib_index,
8717 &pfx_3500,
8718 FIB_SOURCE_API,
8719 FIB_ENTRY_FLAG_MULTICAST,
Neale Rannsda78f952017-05-24 09:15:43 -07008720 DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008721 NULL,
8722 tm->hw[0]->sw_if_index,
8723 ~0, // invalid fib index
8724 0,
8725 NULL,
8726 FIB_ROUTE_PATH_INTF_RX);
8727 FIB_TEST(fib_test_validate_entry(lfe,
8728 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8729 2,
8730 &mc_0,
8731 &mc_intf_0),
8732 "3500 via replicate over 10.10.10.1 and interface-rx");
8733
8734 /*
8735 * Add a replication via an interface-free for-us path
8736 */
8737 fib_test_rep_bucket_t mc_disp = {
8738 .type = FT_REP_DISP_MFIB_LOOKUP,
8739 .adj = {
8740 .adj = idpo.dpoi_index,
8741 },
8742 };
8743 lfe = fib_table_entry_path_add(lfib_index,
8744 &pfx_3500,
8745 FIB_SOURCE_API,
8746 FIB_ENTRY_FLAG_MULTICAST,
Neale Rannsda78f952017-05-24 09:15:43 -07008747 DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008748 NULL,
8749 5, // rpf-id
8750 0, // default table
8751 0,
8752 NULL,
8753 FIB_ROUTE_PATH_RPF_ID);
8754 FIB_TEST(fib_test_validate_entry(lfe,
8755 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8756 3,
8757 &mc_0,
8758 &mc_disp,
8759 &mc_intf_0),
8760 "3500 via replicate over 10.10.10.1 and interface-rx");
8761
8762
8763
8764 fib_table_entry_delete(fib_index, &pfx_3500, FIB_SOURCE_API);
8765 dpo_reset(&idpo);
8766
8767 /*
Neale Rannsad422ed2016-11-02 14:20:04 +00008768 * cleanup
8769 */
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008770 mpls_sw_interface_enable_disable(&mpls_main,
8771 tm->hw[0]->sw_if_index,
Neale Ranns15002542017-09-10 04:39:11 -07008772 0, 1);
8773 mpls_table_delete(MPLS_FIB_DEFAULT_TABLE_ID, FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008774
Neale Rannsad422ed2016-11-02 14:20:04 +00008775 FIB_TEST(lb_count == pool_elts(load_balance_pool),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008776 "Load-balance resources freed %d of %d",
Neale Rannsad422ed2016-11-02 14:20:04 +00008777 lb_count, pool_elts(load_balance_pool));
Neale Ranns43161a82017-08-12 02:12:00 -07008778 FIB_TEST(0 == pool_elts(interface_rx_dpo_pool),
8779 "interface_rx_dpo resources freed %d of %d",
8780 0, pool_elts(interface_rx_dpo_pool));
Neale Ranns0ebe8d72016-12-08 19:48:11 +00008781
8782 return (0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008783}
8784
Neale Ranns89541992017-04-06 04:41:02 -07008785static int
8786fib_test_inherit (void)
8787{
8788 fib_node_index_t fei;
8789 test_main_t *tm;
8790 int n_feis;
8791
8792 n_feis = fib_entry_pool_size();
8793 tm = &test_main;
8794
8795 const ip46_address_t nh_10_10_10_1 = {
8796 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
8797 };
8798 const ip46_address_t nh_10_10_10_2 = {
8799 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02),
8800 };
8801 const ip46_address_t nh_10_10_10_16 = {
8802 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a10),
8803 };
8804 const ip46_address_t nh_10_10_10_20 = {
8805 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a14),
8806 };
8807 const ip46_address_t nh_10_10_10_21 = {
8808 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a15),
8809 };
8810 const ip46_address_t nh_10_10_10_22 = {
8811 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a16),
8812 };
8813 const ip46_address_t nh_10_10_10_255 = {
8814 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0aff),
8815 };
8816 const ip46_address_t nh_10_10_10_0 = {
8817 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a00),
8818 };
8819 const ip46_address_t nh_10_10_0_0 = {
8820 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0000),
8821 };
8822
8823 /*
8824 * prefixes at the base of a sub-tree
8825 */
8826 const fib_prefix_t pfx_10_10_10_21_s_32 = {
8827 .fp_len = 32,
8828 .fp_proto = FIB_PROTOCOL_IP4,
8829 .fp_addr = nh_10_10_10_21,
8830 };
8831 const fib_prefix_t pfx_10_10_10_22_s_32 = {
8832 .fp_len = 32,
8833 .fp_proto = FIB_PROTOCOL_IP4,
8834 .fp_addr = nh_10_10_10_22,
8835 };
8836 const fib_prefix_t pfx_10_10_10_255_s_32 = {
8837 .fp_len = 32,
8838 .fp_proto = FIB_PROTOCOL_IP4,
8839 .fp_addr = nh_10_10_10_255,
8840 };
8841
8842 fib_table_entry_special_add(0,
8843 &pfx_10_10_10_21_s_32,
8844 FIB_SOURCE_CLI,
8845 FIB_ENTRY_FLAG_DROP);
8846 fib_table_entry_special_add(0,
8847 &pfx_10_10_10_22_s_32,
8848 FIB_SOURCE_CLI,
8849 FIB_ENTRY_FLAG_DROP);
8850 fib_table_entry_special_add(0,
8851 &pfx_10_10_10_255_s_32,
8852 FIB_SOURCE_CLI,
8853 FIB_ENTRY_FLAG_DROP);
8854
8855 /*
8856 * source an entry that pushes its state down the sub-tree
8857 */
8858 const fib_prefix_t pfx_10_10_10_16_s_28 = {
8859 .fp_len = 28,
8860 .fp_proto = FIB_PROTOCOL_IP4,
8861 .fp_addr = nh_10_10_10_16,
8862 };
8863 fib_table_entry_update_one_path(0,
8864 &pfx_10_10_10_16_s_28,
8865 FIB_SOURCE_API,
8866 FIB_ENTRY_FLAG_COVERED_INHERIT,
8867 DPO_PROTO_IP4,
8868 &nh_10_10_10_1,
8869 tm->hw[0]->sw_if_index,
8870 ~0,
8871 1,
8872 NULL,
8873 FIB_ROUTE_PATH_FLAG_NONE);
8874
8875 /*
8876 * this covering entry and all those below it should have
8877 * the same forwarding information.
8878 */
8879 adj_index_t ai_10_10_10_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
8880 VNET_LINK_IP4,
8881 &nh_10_10_10_1,
8882 tm->hw[0]->sw_if_index);
8883 fib_test_lb_bucket_t adj_o_10_10_10_1 = {
8884 .type = FT_LB_ADJ,
8885 .adj = {
8886 .adj = ai_10_10_10_1,
8887 },
8888 };
8889
8890 fei = fib_table_lookup(0, &pfx_10_10_10_16_s_28);
8891 FIB_TEST(fib_test_validate_entry(fei,
8892 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8893 1,
8894 &adj_o_10_10_10_1),
8895 "%U via 10.10.10.1",
8896 format_fib_prefix, &pfx_10_10_10_16_s_28);
8897 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
8898 FIB_TEST(fib_test_validate_entry(fei,
8899 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8900 1,
8901 &adj_o_10_10_10_1),
8902 "%U via 10.10.10.1",
8903 format_fib_prefix, &pfx_10_10_10_21_s_32);
8904 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32);
8905 FIB_TEST(fib_test_validate_entry(fei,
8906 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8907 1,
8908 &adj_o_10_10_10_1),
8909 "%U via 10.10.10.1",
8910 format_fib_prefix, &pfx_10_10_10_22_s_32);
8911 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
8912 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
8913 "%U resolves via drop",
8914 format_fib_prefix, &pfx_10_10_10_255_s_32);
8915
8916 /*
8917 * remove the inherting cover - covereds go back to drop
8918 */
8919 fib_table_entry_delete(0, &pfx_10_10_10_16_s_28, FIB_SOURCE_API);
8920
8921 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
8922 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
8923 "%U resolves via drop",
8924 format_fib_prefix, &pfx_10_10_10_21_s_32);
8925
8926 /*
8927 * source an entry that pushes its state down the sub-tree
8928 */
8929 const fib_prefix_t pfx_10_10_10_0_s_24 = {
8930 .fp_len = 24,
8931 .fp_proto = FIB_PROTOCOL_IP4,
8932 .fp_addr = nh_10_10_10_0,
8933 };
8934 fib_table_entry_update_one_path(0,
8935 &pfx_10_10_10_0_s_24,
8936 FIB_SOURCE_API,
8937 FIB_ENTRY_FLAG_COVERED_INHERIT,
8938 DPO_PROTO_IP4,
8939 &nh_10_10_10_1,
8940 tm->hw[0]->sw_if_index,
8941 ~0,
8942 1,
8943 NULL,
8944 FIB_ROUTE_PATH_FLAG_NONE);
8945
8946 /*
8947 * whole sub-tree now covered
8948 */
8949 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
8950 FIB_TEST(fib_test_validate_entry(fei,
8951 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8952 1,
8953 &adj_o_10_10_10_1),
8954 "%U via 10.10.10.1",
8955 format_fib_prefix, &pfx_10_10_10_0_s_24);
8956 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
8957 FIB_TEST(fib_test_validate_entry(fei,
8958 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8959 1,
8960 &adj_o_10_10_10_1),
8961 "%U via 10.10.10.1",
8962 format_fib_prefix, &pfx_10_10_10_21_s_32);
8963 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32);
8964 FIB_TEST(fib_test_validate_entry(fei,
8965 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8966 1,
8967 &adj_o_10_10_10_1),
8968 "%U via 10.10.10.1",
8969 format_fib_prefix, &pfx_10_10_10_22_s_32);
8970 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
8971 FIB_TEST(fib_test_validate_entry(fei,
8972 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8973 1,
8974 &adj_o_10_10_10_1),
8975 "%U via 10.10.10.1",
8976 format_fib_prefix, &pfx_10_10_10_255_s_32);
8977
8978 /*
8979 * insert a more specific into the sub-tree - expect inheritance
8980 * this one is directly covered by the root
8981 */
8982 fib_table_entry_special_add(0,
8983 &pfx_10_10_10_16_s_28,
8984 FIB_SOURCE_CLI,
8985 FIB_ENTRY_FLAG_DROP);
8986 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_16_s_28);
8987 FIB_TEST(fib_test_validate_entry(fei,
8988 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8989 1,
8990 &adj_o_10_10_10_1),
8991 "%U via 10.10.10.1",
8992 format_fib_prefix, &pfx_10_10_10_16_s_28);
8993
8994 /*
8995 * insert a more specific into the sub-tree - expect inheritance
8996 * this one is indirectly covered by the root
8997 */
8998 const fib_prefix_t pfx_10_10_10_20_s_30 = {
8999 .fp_len = 30,
9000 .fp_proto = FIB_PROTOCOL_IP4,
9001 .fp_addr = nh_10_10_10_20,
9002 };
9003 fib_table_entry_special_add(0,
9004 &pfx_10_10_10_20_s_30,
9005 FIB_SOURCE_CLI,
9006 FIB_ENTRY_FLAG_DROP);
9007 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_20_s_30);
9008 FIB_TEST(fib_test_validate_entry(fei,
9009 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9010 1,
9011 &adj_o_10_10_10_1),
9012 "%U via 10.10.10.1",
9013 format_fib_prefix, &pfx_10_10_10_20_s_30);
9014
9015 /*
9016 * remove the prefix from the middle of the sub-tree
9017 * the inherited source will be the only one remaining - expect
9018 * it to be withdrawn and hence the prefix is removed.
9019 */
9020 fib_table_entry_special_remove(0,
9021 &pfx_10_10_10_20_s_30,
9022 FIB_SOURCE_CLI);
9023 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_20_s_30);
9024 FIB_TEST((FIB_NODE_INDEX_INVALID == fei),
9025 "%U gone",
9026 format_fib_prefix, &pfx_10_10_10_20_s_30);
9027
9028 /*
9029 * inheriting source is modifed - expect the modification to be present
9030 * throughout the sub-tree
9031 */
9032 adj_index_t ai_10_10_10_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
9033 VNET_LINK_IP4,
9034 &nh_10_10_10_2,
9035 tm->hw[0]->sw_if_index);
9036 fib_test_lb_bucket_t adj_o_10_10_10_2 = {
9037 .type = FT_LB_ADJ,
9038 .adj = {
9039 .adj = ai_10_10_10_2,
9040 },
9041 };
9042
9043 fib_table_entry_update_one_path(0,
9044 &pfx_10_10_10_0_s_24,
9045 FIB_SOURCE_API,
9046 FIB_ENTRY_FLAG_COVERED_INHERIT,
9047 DPO_PROTO_IP4,
9048 &nh_10_10_10_2,
9049 tm->hw[0]->sw_if_index,
9050 ~0,
9051 1,
9052 NULL,
9053 FIB_ROUTE_PATH_FLAG_NONE);
9054 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
9055 FIB_TEST(fib_test_validate_entry(fei,
9056 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9057 1,
9058 &adj_o_10_10_10_2),
9059 "%U via 10.10.10.2",
9060 format_fib_prefix, &pfx_10_10_10_21_s_32);
9061 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32);
9062 FIB_TEST(fib_test_validate_entry(fei,
9063 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9064 1,
9065 &adj_o_10_10_10_2),
9066 "%U via 10.10.10.2",
9067 format_fib_prefix, &pfx_10_10_10_22_s_32);
9068 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
9069 FIB_TEST(fib_test_validate_entry(fei,
9070 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9071 1,
9072 &adj_o_10_10_10_2),
9073 "%U via 10.10.10.2",
9074 format_fib_prefix, &pfx_10_10_10_255_s_32);
9075 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
9076 FIB_TEST(fib_test_validate_entry(fei,
9077 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9078 1,
9079 &adj_o_10_10_10_2),
9080 "%U via 10.10.10.2",
9081 format_fib_prefix, &pfx_10_10_10_0_s_24);
9082
9083 /*
9084 * add the source that replaces inherited state.
9085 * inheriting source is not the best, so it doesn't push state.
9086 */
9087 fib_table_entry_update_one_path(0,
9088 &pfx_10_10_10_0_s_24,
9089 FIB_SOURCE_PLUGIN_HI,
9090 FIB_ENTRY_FLAG_NONE,
9091 DPO_PROTO_IP4,
9092 &nh_10_10_10_1,
9093 tm->hw[0]->sw_if_index,
9094 ~0,
9095 1,
9096 NULL,
9097 FIB_ROUTE_PATH_FLAG_NONE);
9098 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
9099 FIB_TEST(fib_test_validate_entry(fei,
9100 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9101 1,
9102 &adj_o_10_10_10_1),
9103 "%U via 10.10.10.1",
9104 format_fib_prefix, &pfx_10_10_10_0_s_24);
9105
9106 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
9107 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
9108 "%U resolves via drop",
9109 format_fib_prefix, &pfx_10_10_10_21_s_32);
9110 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32);
9111 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
9112 "%U resolves via drop",
9113 format_fib_prefix, &pfx_10_10_10_22_s_32);
9114 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
9115 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
9116 "%U resolves via drop",
9117 format_fib_prefix, &pfx_10_10_10_255_s_32);
9118 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_16_s_28);
9119 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
9120 "%U resolves via drop",
9121 format_fib_prefix, &pfx_10_10_10_16_s_28);
9122
9123 /*
9124 * withdraw the higher priority source and expect the inherited to return
9125 * throughout the sub-tree
9126 */
9127 fib_table_entry_delete(0, &pfx_10_10_10_0_s_24, FIB_SOURCE_PLUGIN_HI);
9128
9129 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
9130 FIB_TEST(fib_test_validate_entry(fei,
9131 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9132 1,
9133 &adj_o_10_10_10_2),
9134 "%U via 10.10.10.2",
9135 format_fib_prefix, &pfx_10_10_10_21_s_32);
9136 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32);
9137 FIB_TEST(fib_test_validate_entry(fei,
9138 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9139 1,
9140 &adj_o_10_10_10_2),
9141 "%U via 10.10.10.2",
9142 format_fib_prefix, &pfx_10_10_10_22_s_32);
9143 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
9144 FIB_TEST(fib_test_validate_entry(fei,
9145 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9146 1,
9147 &adj_o_10_10_10_2),
9148 "%U via 10.10.10.2",
9149 format_fib_prefix, &pfx_10_10_10_255_s_32);
9150 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
9151 FIB_TEST(fib_test_validate_entry(fei,
9152 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9153 1,
9154 &adj_o_10_10_10_2),
9155 "%U via 10.10.10.2",
9156 format_fib_prefix, &pfx_10_10_10_0_s_24);
9157 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_16_s_28);
9158 FIB_TEST(fib_test_validate_entry(fei,
9159 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9160 1,
9161 &adj_o_10_10_10_2),
9162 "%U via 10.10.10.2",
9163 format_fib_prefix, &pfx_10_10_10_16_s_28);
9164
9165 /*
9166 * source a covered entry in the sub-tree with the same inherting source
9167 * - expect that it now owns the sub-tree and thus over-rides its cover
9168 */
9169 fib_table_entry_update_one_path(0,
9170 &pfx_10_10_10_16_s_28,
9171 FIB_SOURCE_API,
9172 FIB_ENTRY_FLAG_COVERED_INHERIT,
9173 DPO_PROTO_IP4,
9174 &nh_10_10_10_1,
9175 tm->hw[0]->sw_if_index,
9176 ~0,
9177 1,
9178 NULL,
9179 FIB_ROUTE_PATH_FLAG_NONE);
9180 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_16_s_28);
9181 FIB_TEST(fib_test_validate_entry(fei,
9182 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9183 1,
9184 &adj_o_10_10_10_1),
9185 "%U via 10.10.10.1",
9186 format_fib_prefix, &pfx_10_10_10_16_s_28);
9187 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32);
9188 FIB_TEST(fib_test_validate_entry(fei,
9189 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9190 1,
9191 &adj_o_10_10_10_1),
9192 "%U via 10.10.10.2",
9193 format_fib_prefix, &pfx_10_10_10_22_s_32);
9194 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
9195 FIB_TEST(fib_test_validate_entry(fei,
9196 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9197 1,
9198 &adj_o_10_10_10_1),
9199 "%U via 10.10.10.2",
9200 format_fib_prefix, &pfx_10_10_10_21_s_32);
9201
9202 /* these two unaffected by the sub-tree change */
9203 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
9204 FIB_TEST(fib_test_validate_entry(fei,
9205 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9206 1,
9207 &adj_o_10_10_10_2),
9208 "%U via 10.10.10.2",
9209 format_fib_prefix, &pfx_10_10_10_255_s_32);
9210 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
9211 FIB_TEST(fib_test_validate_entry(fei,
9212 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9213 1,
9214 &adj_o_10_10_10_2),
9215 "%U via 10.10.10.2",
9216 format_fib_prefix, &pfx_10_10_10_0_s_24);
9217
9218 /*
9219 * removes the more specific, expect the /24 to now re-owns the sub-tree
9220 */
9221 fib_table_entry_delete(0, &pfx_10_10_10_16_s_28, FIB_SOURCE_API);
9222
9223 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
9224 FIB_TEST(fib_test_validate_entry(fei,
9225 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9226 1,
9227 &adj_o_10_10_10_2),
9228 "%U via 10.10.10.2",
9229 format_fib_prefix, &pfx_10_10_10_16_s_28);
9230 FIB_TEST(fib_test_validate_entry(fei,
9231 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9232 1,
9233 &adj_o_10_10_10_2),
9234 "%U via 10.10.10.2",
9235 format_fib_prefix, &pfx_10_10_10_21_s_32);
9236 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32);
9237 FIB_TEST(fib_test_validate_entry(fei,
9238 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9239 1,
9240 &adj_o_10_10_10_2),
9241 "%U via 10.10.10.2",
9242 format_fib_prefix, &pfx_10_10_10_22_s_32);
9243 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
9244 FIB_TEST(fib_test_validate_entry(fei,
9245 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9246 1,
9247 &adj_o_10_10_10_2),
9248 "%U via 10.10.10.2",
9249 format_fib_prefix, &pfx_10_10_10_255_s_32);
9250 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
9251 FIB_TEST(fib_test_validate_entry(fei,
9252 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9253 1,
9254 &adj_o_10_10_10_2),
9255 "%U via 10.10.10.2",
9256 format_fib_prefix, &pfx_10_10_10_0_s_24);
9257 /*
9258 * modify the /24. expect the new forwarding to be pushed down
9259 */
9260 fib_table_entry_update_one_path(0,
9261 &pfx_10_10_10_0_s_24,
9262 FIB_SOURCE_API,
9263 FIB_ENTRY_FLAG_COVERED_INHERIT,
9264 DPO_PROTO_IP4,
9265 &nh_10_10_10_1,
9266 tm->hw[0]->sw_if_index,
9267 ~0,
9268 1,
9269 NULL,
9270 FIB_ROUTE_PATH_FLAG_NONE);
9271 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
9272 FIB_TEST(fib_test_validate_entry(fei,
9273 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9274 1,
9275 &adj_o_10_10_10_1),
9276 "%U via 10.10.10.1",
9277 format_fib_prefix, &pfx_10_10_10_16_s_28);
9278 FIB_TEST(fib_test_validate_entry(fei,
9279 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9280 1,
9281 &adj_o_10_10_10_1),
9282 "%U via 10.10.10.1",
9283 format_fib_prefix, &pfx_10_10_10_21_s_32);
9284 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32);
9285 FIB_TEST(fib_test_validate_entry(fei,
9286 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9287 1,
9288 &adj_o_10_10_10_1),
9289 "%U via 10.10.10.1",
9290 format_fib_prefix, &pfx_10_10_10_22_s_32);
9291 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
9292 FIB_TEST(fib_test_validate_entry(fei,
9293 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9294 1,
9295 &adj_o_10_10_10_1),
9296 "%U via 10.10.10.1",
9297 format_fib_prefix, &pfx_10_10_10_255_s_32);
9298 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
9299 FIB_TEST(fib_test_validate_entry(fei,
9300 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9301 1,
9302 &adj_o_10_10_10_1),
9303 "%U via 10.10.10.1",
9304 format_fib_prefix, &pfx_10_10_10_0_s_24);
9305
9306 /*
9307 * add an entry less specific to /24. it should not own the /24's tree
9308 */
9309 const fib_prefix_t pfx_10_10_0_0_s_16 = {
9310 .fp_len = 16,
9311 .fp_proto = FIB_PROTOCOL_IP4,
9312 .fp_addr = nh_10_10_0_0,
9313 };
9314 fib_table_entry_update_one_path(0,
9315 &pfx_10_10_0_0_s_16,
9316 FIB_SOURCE_API,
9317 FIB_ENTRY_FLAG_COVERED_INHERIT,
9318 DPO_PROTO_IP4,
9319 &nh_10_10_10_2,
9320 tm->hw[0]->sw_if_index,
9321 ~0,
9322 1,
9323 NULL,
9324 FIB_ROUTE_PATH_FLAG_NONE);
9325 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
9326 FIB_TEST(fib_test_validate_entry(fei,
9327 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9328 1,
9329 &adj_o_10_10_10_1),
9330 "%U via 10.10.10.1",
9331 format_fib_prefix, &pfx_10_10_10_16_s_28);
9332 FIB_TEST(fib_test_validate_entry(fei,
9333 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9334 1,
9335 &adj_o_10_10_10_1),
9336 "%U via 10.10.10.1",
9337 format_fib_prefix, &pfx_10_10_10_21_s_32);
9338 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32);
9339 FIB_TEST(fib_test_validate_entry(fei,
9340 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9341 1,
9342 &adj_o_10_10_10_1),
9343 "%U via 10.10.10.1",
9344 format_fib_prefix, &pfx_10_10_10_22_s_32);
9345 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
9346 FIB_TEST(fib_test_validate_entry(fei,
9347 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9348 1,
9349 &adj_o_10_10_10_1),
9350 "%U via 10.10.10.1",
9351 format_fib_prefix, &pfx_10_10_10_255_s_32);
9352 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
9353 FIB_TEST(fib_test_validate_entry(fei,
9354 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9355 1,
9356 &adj_o_10_10_10_1),
9357 "%U via 10.10.10.1",
9358 format_fib_prefix, &pfx_10_10_10_0_s_24);
9359 fei = fib_table_lookup_exact_match(0, &pfx_10_10_0_0_s_16);
9360 FIB_TEST(fib_test_validate_entry(fei,
9361 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9362 1,
9363 &adj_o_10_10_10_2),
9364 "%U via 10.10.10.2",
9365 format_fib_prefix, &pfx_10_10_0_0_s_16);
9366
9367 /*
9368 * cleanup
9369 */
9370 fib_table_entry_delete(0, &pfx_10_10_10_21_s_32, FIB_SOURCE_CLI);
9371 fib_table_entry_delete(0, &pfx_10_10_10_22_s_32, FIB_SOURCE_CLI);
9372 fib_table_entry_delete(0, &pfx_10_10_10_16_s_28, FIB_SOURCE_CLI);
9373 fib_table_entry_delete(0, &pfx_10_10_10_255_s_32, FIB_SOURCE_CLI);
9374 fib_table_entry_delete(0, &pfx_10_10_10_0_s_24, FIB_SOURCE_API);
9375 fib_table_entry_delete(0, &pfx_10_10_0_0_s_16, FIB_SOURCE_API);
9376 adj_unlock(ai_10_10_10_1);
9377 adj_unlock(ai_10_10_10_2);
9378
9379 /*
9380 * test the v6 tree walk.
9381 * a /64 that covers everytinhg. a /96 that covers one /128
9382 * a second /128 covered only by the /64.
9383 */
9384 const fib_prefix_t pfx_2001_s_64 = {
9385 .fp_len = 64,
9386 .fp_proto = FIB_PROTOCOL_IP6,
9387 .fp_addr = {
9388 .ip6 = {
9389 .as_u64 = {
9390 [0] = clib_host_to_net_u64(0x2001000000000000),
9391 [1] = clib_host_to_net_u64(0x0000000000000000),
9392 },
9393 },
9394 },
9395 };
9396 const fib_prefix_t pfx_2001_1_s_96 = {
9397 .fp_len = 96,
9398 .fp_proto = FIB_PROTOCOL_IP6,
9399 .fp_addr = {
9400 .ip6 = {
9401 .as_u64 = {
9402 [0] = clib_host_to_net_u64(0x2001000000000000),
9403 [1] = clib_host_to_net_u64(0x1000000000000000),
9404 },
9405 },
9406 },
9407 };
9408 const fib_prefix_t pfx_2001_1_1_s_128 = {
9409 .fp_len = 128,
9410 .fp_proto = FIB_PROTOCOL_IP6,
9411 .fp_addr = {
9412 .ip6 = {
9413 .as_u64 = {
9414 [0] = clib_host_to_net_u64(0x2001000000000000),
9415 [1] = clib_host_to_net_u64(0x1000000000000001),
9416 },
9417 },
9418 },
9419 };
9420 const fib_prefix_t pfx_2001_0_1_s_128 = {
9421 .fp_len = 128,
9422 .fp_proto = FIB_PROTOCOL_IP6,
9423 .fp_addr = {
9424 .ip6 = {
9425 .as_u64 = {
9426 [0] = clib_host_to_net_u64(0x2001000000000000),
9427 [1] = clib_host_to_net_u64(0x0000000000000001),
9428 },
9429 },
9430 },
9431 };
9432 const ip46_address_t nh_3000_1 = {
9433 .ip6 = {
9434 .as_u64 = {
9435 [0] = clib_host_to_net_u64(0x3000000000000000),
9436 [1] = clib_host_to_net_u64(0x0000000000000001),
9437 },
9438 },
9439 };
9440 const ip46_address_t nh_3000_2 = {
9441 .ip6 = {
9442 .as_u64 = {
9443 [0] = clib_host_to_net_u64(0x3000000000000000),
9444 [1] = clib_host_to_net_u64(0x0000000000000002),
9445 },
9446 },
9447 };
9448 adj_index_t ai_3000_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP6,
9449 VNET_LINK_IP6,
9450 &nh_3000_1,
9451 tm->hw[0]->sw_if_index);
9452 adj_index_t ai_3000_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP6,
9453 VNET_LINK_IP6,
9454 &nh_3000_2,
9455 tm->hw[0]->sw_if_index);
9456 fib_test_lb_bucket_t adj_o_3000_1 = {
9457 .type = FT_LB_ADJ,
9458 .adj = {
9459 .adj = ai_3000_1,
9460 },
9461 };
9462 fib_test_lb_bucket_t adj_o_3000_2 = {
9463 .type = FT_LB_ADJ,
9464 .adj = {
9465 .adj = ai_3000_2,
9466 },
9467 };
9468
9469 fib_table_entry_special_add(0,
9470 &pfx_2001_0_1_s_128,
9471 FIB_SOURCE_CLI,
9472 FIB_ENTRY_FLAG_DROP);
9473 fib_table_entry_special_add(0,
9474 &pfx_2001_1_1_s_128,
9475 FIB_SOURCE_CLI,
9476 FIB_ENTRY_FLAG_DROP);
9477
9478 /*
9479 * /96 has inherited forwarding pushed down to its covered /128
9480 */
9481 fib_table_entry_update_one_path(0,
9482 &pfx_2001_1_s_96,
9483 FIB_SOURCE_API,
9484 FIB_ENTRY_FLAG_COVERED_INHERIT,
9485 DPO_PROTO_IP6,
9486 &nh_3000_1,
9487 tm->hw[0]->sw_if_index,
9488 ~0,
9489 1,
9490 NULL,
9491 FIB_ROUTE_PATH_FLAG_NONE);
9492 fei = fib_table_lookup_exact_match(0, &pfx_2001_1_s_96);
9493 FIB_TEST(fib_test_validate_entry(fei,
9494 FIB_FORW_CHAIN_TYPE_UNICAST_IP6,
9495 1,
9496 &adj_o_3000_1),
9497 "%U via 3000::1",
9498 format_fib_prefix, &pfx_2001_1_s_96);
9499 fei = fib_table_lookup_exact_match(0, &pfx_2001_1_1_s_128);
9500 FIB_TEST(fib_test_validate_entry(fei,
9501 FIB_FORW_CHAIN_TYPE_UNICAST_IP6,
9502 1,
9503 &adj_o_3000_1),
9504 "%U via 3000::1",
9505 format_fib_prefix, &pfx_2001_1_1_s_128);
9506 fei = fib_table_lookup_exact_match(0, &pfx_2001_0_1_s_128);
9507 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
9508 "%U resolves via drop",
9509 format_fib_prefix, &pfx_2001_0_1_s_128);
9510
9511 /*
9512 * /64 has inherited forwarding pushed down to all, but the /96
9513 * and its sub-tree remain unaffected.
9514 */
9515 fib_table_entry_update_one_path(0,
9516 &pfx_2001_s_64,
9517 FIB_SOURCE_API,
9518 FIB_ENTRY_FLAG_COVERED_INHERIT,
9519 DPO_PROTO_IP6,
9520 &nh_3000_2,
9521 tm->hw[0]->sw_if_index,
9522 ~0,
9523 1,
9524 NULL,
9525 FIB_ROUTE_PATH_FLAG_NONE);
9526
9527 fei = fib_table_lookup_exact_match(0, &pfx_2001_s_64);
9528 FIB_TEST(fib_test_validate_entry(fei,
9529 FIB_FORW_CHAIN_TYPE_UNICAST_IP6,
9530 1,
9531 &adj_o_3000_2),
9532 "%U via 3000::2",
9533 format_fib_prefix, &pfx_2001_s_64);
9534 fei = fib_table_lookup_exact_match(0, &pfx_2001_0_1_s_128);
9535 FIB_TEST(fib_test_validate_entry(fei,
9536 FIB_FORW_CHAIN_TYPE_UNICAST_IP6,
9537 1,
9538 &adj_o_3000_2),
9539 "%U via 3000::1",
9540 format_fib_prefix, &pfx_2001_0_1_s_128);
9541
9542 fei = fib_table_lookup_exact_match(0, &pfx_2001_1_s_96);
9543 FIB_TEST(fib_test_validate_entry(fei,
9544 FIB_FORW_CHAIN_TYPE_UNICAST_IP6,
9545 1,
9546 &adj_o_3000_1),
9547 "%U via 3000::1",
9548 format_fib_prefix, &pfx_2001_1_s_96);
9549 fei = fib_table_lookup_exact_match(0, &pfx_2001_1_1_s_128);
9550 FIB_TEST(fib_test_validate_entry(fei,
9551 FIB_FORW_CHAIN_TYPE_UNICAST_IP6,
9552 1,
9553 &adj_o_3000_1),
9554 "%U via 3000::1",
9555 format_fib_prefix, &pfx_2001_1_1_s_128);
9556
9557 /*
9558 * Cleanup
9559 */
9560 fib_table_entry_delete(0, &pfx_2001_0_1_s_128, FIB_SOURCE_CLI);
9561 fib_table_entry_delete(0, &pfx_2001_1_1_s_128, FIB_SOURCE_CLI);
9562 fib_table_entry_delete(0, &pfx_2001_s_64, FIB_SOURCE_API);
9563 fib_table_entry_delete(0, &pfx_2001_1_s_96, FIB_SOURCE_API);
9564 adj_unlock(ai_3000_1);
9565 adj_unlock(ai_3000_2);
9566
9567 /*
9568 * test no-one left behind
9569 */
9570 FIB_TEST((n_feis == fib_entry_pool_size()), "Entries gone");
9571 FIB_TEST(0 == adj_nbr_db_size(), "All adjacencies removed");
9572 return (0);
9573}
9574
Neale Ranns0bfe5d82016-08-25 15:29:12 +01009575static clib_error_t *
9576fib_test (vlib_main_t * vm,
9577 unformat_input_t * input,
9578 vlib_cli_command_t * cmd_arg)
9579{
Neale Ranns0ebe8d72016-12-08 19:48:11 +00009580 int res;
9581
9582 res = 0;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01009583 fib_test_mk_intf(4);
9584
Neale Ranns88fc83e2017-04-05 08:11:14 -07009585 if (unformat (input, "debug"))
9586 {
9587 fib_test_do_debug = 1;
9588 }
9589
Neale Ranns0bfe5d82016-08-25 15:29:12 +01009590 if (unformat (input, "ip"))
9591 {
Neale Ranns0ebe8d72016-12-08 19:48:11 +00009592 res += fib_test_v4();
9593 res += fib_test_v6();
Neale Ranns0bfe5d82016-08-25 15:29:12 +01009594 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01009595 else if (unformat (input, "label"))
9596 {
Neale Ranns0ebe8d72016-12-08 19:48:11 +00009597 res += fib_test_label();
Neale Ranns0bfe5d82016-08-25 15:29:12 +01009598 }
9599 else if (unformat (input, "ae"))
9600 {
Neale Ranns0ebe8d72016-12-08 19:48:11 +00009601 res += fib_test_ae();
Neale Ranns0bfe5d82016-08-25 15:29:12 +01009602 }
Neale Ranns57b58602017-07-15 07:37:25 -07009603 else if (unformat (input, "pref"))
9604 {
9605 res += fib_test_pref();
9606 }
Neale Rannsad422ed2016-11-02 14:20:04 +00009607 else if (unformat (input, "lfib"))
9608 {
Neale Ranns0ebe8d72016-12-08 19:48:11 +00009609 res += lfib_test();
Neale Rannsad422ed2016-11-02 14:20:04 +00009610 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01009611 else if (unformat (input, "walk"))
9612 {
Neale Ranns0ebe8d72016-12-08 19:48:11 +00009613 res += fib_test_walk();
Neale Ranns0bfe5d82016-08-25 15:29:12 +01009614 }
Neale Ranns88fc83e2017-04-05 08:11:14 -07009615 else if (unformat (input, "bfd"))
9616 {
9617 res += fib_test_bfd();
9618 }
Neale Ranns89541992017-04-06 04:41:02 -07009619 else if (unformat (input, "inherit"))
9620 {
9621 res += fib_test_inherit();
9622 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01009623 else
9624 {
Neale Ranns0ebe8d72016-12-08 19:48:11 +00009625 res += fib_test_v4();
9626 res += fib_test_v6();
9627 res += fib_test_ae();
Neale Ranns88fc83e2017-04-05 08:11:14 -07009628 res += fib_test_bfd();
Neale Ranns57b58602017-07-15 07:37:25 -07009629 res += fib_test_pref();
Neale Ranns0ebe8d72016-12-08 19:48:11 +00009630 res += fib_test_label();
Neale Ranns89541992017-04-06 04:41:02 -07009631 res += fib_test_inherit();
Neale Ranns0ebe8d72016-12-08 19:48:11 +00009632 res += lfib_test();
Neale Rannsf12a83f2017-04-18 09:09:40 -07009633
9634 /*
9635 * fib-walk process must be disabled in order for the walk tests to work
9636 */
9637 fib_walk_process_disable();
9638 res += fib_test_walk();
9639 fib_walk_process_enable();
Neale Ranns0bfe5d82016-08-25 15:29:12 +01009640 }
9641
Neale Ranns0ebe8d72016-12-08 19:48:11 +00009642 if (res)
9643 {
9644 return clib_error_return(0, "FIB Unit Test Failed");
9645 }
9646 else
9647 {
9648 return (NULL);
9649 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01009650}
9651
9652VLIB_CLI_COMMAND (test_fib_command, static) = {
9653 .path = "test fib",
9654 .short_help = "fib unit tests - DO NOT RUN ON A LIVE SYSTEM",
9655 .function = fib_test,
9656};
9657
Neale Ranns0bfe5d82016-08-25 15:29:12 +01009658clib_error_t *
9659fib_test_init (vlib_main_t *vm)
9660{
9661 return 0;
9662}
9663
9664VLIB_INIT_FUNCTION (fib_test_init);